chrono/tests/manager/test_event_timesheet.py

1557 lines
55 KiB
Python

import datetime
import itertools
import pytest
from django.db import connection
from django.test.utils import CaptureQueriesContext
from chrono.agendas.models import Agenda, Booking, Event, Subscription
from chrono.utils.timezone import make_aware, now
from tests.utils import login
pytestmark = pytest.mark.django_db
def test_events_timesheet_link(app, admin_user):
agenda = Agenda.objects.create(label='Events', kind='events')
event = Event.objects.create(label='event', start_datetime=now(), places=10, agenda=agenda)
login(app)
# agenda without subscription
resp = app.get('/manage/agendas/%s/month/' % agenda.pk).follow()
assert '/manage/agendas/%s/events/timesheet' % agenda.pk not in resp
resp = app.get('/manage/agendas/%s/day/' % agenda.pk).follow()
assert '/manage/agendas/%s/events/timesheet' % agenda.pk not in resp
resp = app.get('/manage/agendas/%s/events/open/' % agenda.pk)
assert '/manage/agendas/%s/events/timesheet' % agenda.pk not in resp
resp = app.get('/manage/agendas/%s/events/%s/' % (agenda.pk, event.pk))
assert '/manage/agendas/%s/events/%s/timesheet' % (agenda.pk, event.pk) not in resp
# agenda with subscription
Subscription.objects.create(
agenda=agenda,
user_external_id='user:1',
user_first_name='Subscription',
user_last_name='42',
date_start=now(),
date_end=now(),
)
resp = app.get('/manage/agendas/%s/month/' % agenda.pk).follow()
assert '/manage/agendas/%s/events/timesheet' % agenda.pk in resp
resp = app.get('/manage/agendas/%s/day/' % agenda.pk).follow()
assert '/manage/agendas/%s/events/timesheet' % agenda.pk in resp
resp = app.get('/manage/agendas/%s/events/open/' % agenda.pk)
assert '/manage/agendas/%s/events/timesheet' % agenda.pk in resp
resp = app.get('/manage/agendas/%s/events/%s/' % (agenda.pk, event.pk))
assert '/manage/agendas/%s/events/%s/timesheet' % (agenda.pk, event.pk) in resp
def test_events_timesheet_wrong_kind(app, admin_user):
agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
app = login(app)
app.get('/manage/agendas/%s/events/timesheet' % agenda.id, status=404)
agenda.kind = 'virtual'
agenda.save()
app.get('/manage/agendas/%s/events/timesheet' % agenda.id, status=404)
def test_events_timesheet_form(app, admin_user):
agenda = Agenda.objects.create(label='Events', kind='events')
login(app)
resp = app.get('/manage/agendas/%s/events/timesheet' % agenda.pk)
resp.form['date_start'] = '2022-01-01'
resp.form['date_end'] = '2021-12-31'
resp = resp.form.submit()
assert resp.context['form'].errors['date_end'] == ['End date must be greater than start date.']
resp.form['date_end'] = '2022-04-02'
resp = resp.form.submit()
assert resp.context['form'].errors['date_end'] == ['Please select an interval of no more than 3 months.']
resp.form['date_end'] = '2022-04-01'
resp = resp.form.submit()
assert resp.context['form'].errors == {}
@pytest.mark.freeze_time('2022-02-15')
def test_events_timesheet_slots(app, admin_user):
start, end = (
now() - datetime.timedelta(days=15),
now() + datetime.timedelta(days=14),
) # 2022-02-31, 2022-03-01
agenda = Agenda.objects.create(label='Events', kind='events')
Event.objects.create(label='event 1', start_datetime=start, places=10, agenda=agenda)
event2 = Event.objects.create(
label='event 2', start_datetime=start + datetime.timedelta(days=1), places=10, agenda=agenda
)
event3 = Event.objects.create(label='event 3', start_datetime=now(), places=10, agenda=agenda)
Event.objects.create(
label='event cancelled',
start_datetime=now() + datetime.timedelta(days=4),
places=10,
agenda=agenda,
cancelled=True,
)
event4 = Event.objects.create(
label='event 4', start_datetime=end - datetime.timedelta(days=1), places=10, agenda=agenda
)
Event.objects.create(label='event 5', start_datetime=end, places=10, agenda=agenda)
Subscription.objects.create(
agenda=agenda,
user_external_id='user:1',
user_first_name='Subscription',
user_last_name='42',
date_start=start,
date_end=end + datetime.timedelta(days=1),
)
recurring_event1 = Event.objects.create(
label='recurring 1',
start_datetime=start,
places=10,
agenda=agenda,
recurrence_days=[1, 2],
recurrence_end_date=end,
)
recurring_event1.create_all_recurrences()
recurring_event2 = Event.objects.create(
label='recurring 2',
start_datetime=start,
places=10,
agenda=agenda,
recurrence_days=[2, 3],
recurrence_end_date=end,
)
recurring_event2.create_all_recurrences()
login(app)
resp = app.get('/manage/agendas/%s/events/timesheet' % agenda.pk)
resp.form['date_start'] = '2022-02-01'
resp.form['date_end'] = '2022-02-28'
with CaptureQueriesContext(connection) as ctx:
resp = resp.form.submit()
assert len(ctx.captured_queries) == 7
slots = resp.context['form'].get_slots()
assert len(slots['dates']) == 1
assert [d[0] for d in slots['dates'][0]] == [
datetime.date(2022, 2, 1),
datetime.date(2022, 2, 2),
datetime.date(2022, 2, 7),
datetime.date(2022, 2, 8),
datetime.date(2022, 2, 9),
datetime.date(2022, 2, 14),
datetime.date(2022, 2, 15),
datetime.date(2022, 2, 16),
datetime.date(2022, 2, 21),
datetime.date(2022, 2, 22),
datetime.date(2022, 2, 23),
datetime.date(2022, 2, 28),
]
assert slots['events'] == [
event2,
recurring_event1,
recurring_event2,
event3,
event4,
]
assert slots['users'][0]['users'] == [
{
'user_id': 'user:1',
'user_first_name': 'Subscription',
'user_last_name': '42',
'extra_data': {},
'events': [
{
'event': event2,
'dates': {
date: False for date, events in slots['dates'][0] if date == datetime.date(2022, 2, 1)
},
},
{
'event': recurring_event1,
'dates': {date: False for date, events in slots['dates'][0] if date.weekday() in [0, 1]},
},
{
'event': recurring_event2,
'dates': {date: False for date, events in slots['dates'][0] if date.weekday() in [1, 2]},
},
{
'event': event3,
'dates': {
date: False
for date, events in slots['dates'][0]
if date == datetime.date(2022, 2, 15)
},
},
{
'event': event4,
'dates': {
date: False
for date, events in slots['dates'][0]
if date == datetime.date(2022, 2, 28)
},
},
],
},
]
assert slots['extra_data'] == []
@pytest.mark.freeze_time('2022-02-15')
def test_events_timesheet_subscription_limits(app, admin_user):
agenda = Agenda.objects.create(label='Events', kind='events')
event1 = Event.objects.create(
start_datetime=make_aware(datetime.datetime(2022, 2, 1, 17, 0)), places=10, agenda=agenda
)
event2 = Event.objects.create(
start_datetime=make_aware(datetime.datetime(2022, 2, 15, 17, 0)), places=10, agenda=agenda
)
event3 = Event.objects.create(
start_datetime=make_aware(datetime.datetime(2022, 2, 28, 17, 0)), places=10, agenda=agenda
)
dates = [
('2022-01-31', '2022-02-01'),
('2022-02-01', '2022-02-02'),
('2022-02-01', '2022-02-15'),
('2022-02-01', '2022-02-16'),
('2022-02-15', '2022-02-28'),
('2022-02-15', '2022-03-01'),
('2022-02-16', '2022-03-01'),
('2022-02-01', '2022-03-01'),
('2022-02-28', '2022-03-01'),
('2022-03-01', '2022-03-02'),
]
for start, end in dates:
Subscription.objects.create(
agenda=agenda,
user_external_id='user:%s-%s' % (start, end),
user_first_name='Subscription',
user_last_name='%s - %s' % (start, end),
date_start=datetime.datetime.strptime(start, '%Y-%m-%d'),
date_end=datetime.datetime.strptime(end, '%Y-%m-%d'),
)
login(app)
resp = app.get('/manage/agendas/%s/events/timesheet' % agenda.pk)
resp.form['date_start'] = '2022-02-01'
resp.form['date_end'] = '2022-02-28'
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert len(slots['dates']) == 1
assert [d[0] for d in slots['dates'][0]] == [
datetime.date(2022, 2, 1),
datetime.date(2022, 2, 15),
datetime.date(2022, 2, 28),
]
assert slots['events'] == [
event1,
event2,
event3,
]
users = slots['users'][0]['users']
assert len(users) == 8
assert users[0]['user_id'] == 'user:2022-02-01-2022-02-02'
assert users[1]['user_id'] == 'user:2022-02-01-2022-02-15'
assert users[2]['user_id'] == 'user:2022-02-01-2022-02-16'
assert users[3]['user_id'] == 'user:2022-02-01-2022-03-01'
assert users[4]['user_id'] == 'user:2022-02-15-2022-02-28'
assert users[5]['user_id'] == 'user:2022-02-15-2022-03-01'
assert users[6]['user_id'] == 'user:2022-02-16-2022-03-01'
assert users[7]['user_id'] == 'user:2022-02-28-2022-03-01'
@pytest.mark.freeze_time('2022-02-15')
def test_events_timesheet_filter_with_booking(app, admin_user):
agenda = Agenda.objects.create(label='Events', kind='events')
event1 = Event.objects.create(
start_datetime=make_aware(datetime.datetime(2022, 2, 1, 17, 0)), places=10, agenda=agenda
)
event2 = Event.objects.create(
start_datetime=make_aware(datetime.datetime(2022, 2, 15, 17, 0)), places=10, agenda=agenda
)
event3 = Event.objects.create(
start_datetime=make_aware(datetime.datetime(2022, 2, 28, 17, 0)), places=10, agenda=agenda
)
Booking.objects.create(
event=event1, user_external_id='user:1', user_first_name='User', user_last_name='1'
)
Booking.objects.create(
event=event1, user_external_id='user:2', user_first_name='User', user_last_name='2'
)
Booking.objects.create(
event=event2, user_external_id='user:2', user_first_name='User', user_last_name='2'
)
login(app)
resp = app.get('/manage/agendas/%s/events/timesheet' % agenda.pk)
assert 'booking_filter' not in resp.context['form'].fields
start = datetime.date(2022, 2, 1)
end = datetime.date(2022, 3, 1)
for user_id in [1, 2, 3, 4, 5, 6]:
Subscription.objects.create(
agenda=agenda,
user_external_id='user:%s' % user_id,
user_first_name='Subscription',
user_last_name=str(user_id),
date_start=start,
date_end=end,
)
resp = app.get('/manage/agendas/%s/events/timesheet' % agenda.pk)
resp.form['date_start'] = '2022-02-01'
resp.form['date_end'] = '2022-02-28'
assert resp.form['booking_filter'].value == 'all'
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert len(slots['dates']) == 1
assert [d[0] for d in slots['dates'][0]] == [
datetime.date(2022, 2, 1),
datetime.date(2022, 2, 15),
datetime.date(2022, 2, 28),
]
assert slots['events'] == [
event1,
event2,
event3,
]
users = slots['users'][0]['users']
assert len(users) == 6
assert users[0]['user_id'] == 'user:1'
assert users[1]['user_id'] == 'user:2'
assert users[2]['user_id'] == 'user:3'
assert users[3]['user_id'] == 'user:4'
assert users[4]['user_id'] == 'user:5'
assert users[5]['user_id'] == 'user:6'
resp.form['booking_filter'] = 'with_booking'
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert len(slots['dates']) == 1
assert [d[0] for d in slots['dates'][0]] == [
datetime.date(2022, 2, 1),
datetime.date(2022, 2, 15),
datetime.date(2022, 2, 28),
]
assert slots['events'] == [
event1,
event2,
event3,
]
users = slots['users'][0]['users']
assert len(users) == 2
assert users[0]['user_id'] == 'user:1'
assert users[1]['user_id'] == 'user:2'
resp.form['booking_filter'] = 'without_booking'
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert len(slots['dates']) == 1
assert [d[0] for d in slots['dates'][0]] == [
datetime.date(2022, 2, 1),
datetime.date(2022, 2, 15),
datetime.date(2022, 2, 28),
]
assert slots['events'] == [
event1,
event2,
event3,
]
users = slots['users'][0]['users']
assert len(users) == 4
assert users[0]['user_id'] == 'user:3'
assert users[1]['user_id'] == 'user:4'
assert users[2]['user_id'] == 'user:5'
assert users[3]['user_id'] == 'user:6'
def test_events_timesheet_users(app, admin_user):
agenda = Agenda.objects.create(label='Events', kind='events')
event = Event.objects.create(
start_datetime=make_aware(datetime.datetime(2022, 2, 15, 17, 0)), places=10, agenda=agenda
)
booking1 = Booking.objects.create(
event=event, user_external_id='user:1', user_first_name='User', user_last_name='42'
)
Booking.objects.create(
event=event, user_external_id='user:2', user_first_name='User', user_last_name='01'
)
Booking.objects.create(
event=event, user_external_id='user:3', user_first_name='User', user_last_name='17'
)
Booking.objects.create(
event=event, user_external_id='user:4', user_first_name='User', user_last_name='35'
)
Booking.objects.create(
event=event, user_external_id='user:5', user_first_name='User', user_last_name='05'
)
booking6 = Booking.objects.create(
event=event, user_external_id='user:6', user_first_name='User', user_last_name='12 Cancelled'
)
booking6.cancel()
Booking.objects.create(
event=event,
user_external_id='user:7',
user_first_name='User',
user_last_name='Waiting',
in_waiting_list=True,
)
booking8 = Booking.objects.create(
event=event,
user_external_id='user:8',
user_first_name='User',
user_last_name='Waiting and Cancelled',
in_waiting_list=True,
)
booking8.cancel()
Booking.objects.create(
event=event,
user_external_id='user:1',
user_first_name='User',
user_last_name='Secondary',
primary_booking=booking1,
)
login(app)
resp = app.get('/manage/agendas/%s/events/timesheet' % agenda.pk)
resp.form['date_start'] = '2022-02-01'
resp.form['date_end'] = '2022-02-28'
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert [u['user_id'] for u in slots['users'][0]['users']] == [
'user:2',
'user:5',
'user:3',
'user:4',
'user:1',
]
start = datetime.date(2022, 2, 1)
end = datetime.date(2022, 3, 1)
Subscription.objects.create(
agenda=agenda,
user_external_id='user:1',
user_first_name='Subscription',
user_last_name='42',
date_start=start,
date_end=end,
)
Subscription.objects.create(
agenda=agenda,
user_external_id='user:9',
user_first_name='Subscription',
user_last_name='43',
date_start=start,
date_end=end,
)
Subscription.objects.create(
agenda=agenda,
user_external_id='user:10',
user_first_name='Subscription',
user_last_name='14',
date_start=start,
date_end=end,
)
Subscription.objects.create(
agenda=agenda,
user_external_id='user:7',
user_first_name='Subscription',
user_last_name='Waiting',
date_start=start,
date_end=end,
)
Subscription.objects.create(
agenda=agenda,
user_external_id='user:42',
user_first_name='Subscription',
user_last_name='Too soon',
date_start=start - datetime.timedelta(days=1),
date_end=start,
)
Subscription.objects.create(
agenda=agenda,
user_external_id='user:43',
user_first_name='Subscription',
user_last_name='Too late',
date_start=end + datetime.timedelta(days=1),
date_end=end + datetime.timedelta(days=2),
)
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert [u['user_id'] for u in slots['users'][0]['users']] == [
'user:2',
'user:5',
'user:6',
'user:10',
'user:3',
'user:4',
'user:1',
'user:9',
'user:7',
]
def test_events_timesheet_user_ids(app, admin_user):
agenda = Agenda.objects.create(label='Events', kind='events')
event = Event.objects.create(
start_datetime=make_aware(datetime.datetime(2022, 2, 15, 17, 0)), places=10, agenda=agenda
)
booking = Booking.objects.create(event=event, user_first_name='User', user_last_name='42')
login(app)
resp = app.get('/manage/agendas/%s/events/timesheet' % agenda.pk)
resp.form['date_start'] = '2022-02-01'
resp.form['date_end'] = '2022-02-28'
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
# no user_id found
assert [u['user_id'] for u in slots['users'][0]['users']] == []
assert [u['user_first_name'] for u in slots['users'][0]['users']] == []
assert [u['user_last_name'] for u in slots['users'][0]['users']] == []
booking.user_external_id = 'user:1'
booking.save()
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert [u['user_id'] for u in slots['users'][0]['users']] == [
'user:1',
]
assert [u['user_first_name'] for u in slots['users'][0]['users']] == ['User']
assert [u['user_last_name'] for u in slots['users'][0]['users']] == ['42']
Subscription.objects.create(
agenda=agenda,
user_external_id='user:1',
user_first_name='Subscription',
user_last_name='41',
date_start=datetime.date(2022, 2, 1),
date_end=datetime.date(2022, 3, 1),
)
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert [u['user_id'] for u in slots['users'][0]['users']] == [
'user:1',
]
assert [u['user_first_name'] for u in slots['users'][0]['users']] == [
'Subscription',
]
assert [u['user_last_name'] for u in slots['users'][0]['users']] == [
'41',
]
@pytest.mark.freeze_time('2022-02-01')
def test_events_timesheet_booked(app, admin_user):
agenda = Agenda.objects.create(label='Events', kind='events')
event_date = make_aware(datetime.datetime(2022, 2, 15, 17, 0))
event1 = Event.objects.create(label='event 1', start_datetime=event_date, places=10, agenda=agenda)
event2 = Event.objects.create(label='event 2', start_datetime=event_date, places=10, agenda=agenda)
event3 = Event.objects.create(label='event 3', start_datetime=event_date, places=10, agenda=agenda)
recurring_event1 = Event.objects.create(
label='recurring 1',
start_datetime=event_date,
places=10,
agenda=agenda,
recurrence_days=[2],
recurrence_end_date=event_date + datetime.timedelta(days=1),
)
recurring_event1.create_all_recurrences()
recurring_event1_occurence = recurring_event1.recurrences.first()
recurring_event2 = Event.objects.create(
label='recurring 2',
start_datetime=event_date,
places=10,
agenda=agenda,
recurrence_days=[2],
recurrence_end_date=event_date + datetime.timedelta(days=1),
)
recurring_event2.create_all_recurrences()
recurring_event2_occurence = recurring_event2.recurrences.first()
Subscription.objects.create(
agenda=agenda,
user_external_id='user:1',
user_first_name='Subscription',
user_last_name='42',
date_start=datetime.date(2022, 2, 1),
date_end=datetime.date(2022, 3, 1),
)
Booking.objects.create(
event=event1,
user_external_id='user:1',
user_first_name='User',
user_last_name='42',
)
Booking.objects.create(
event=event2,
user_external_id='user:1',
user_first_name='User',
user_last_name='42',
cancellation_datetime=now(),
)
Booking.objects.create(
event=recurring_event1_occurence,
user_external_id='user:1',
user_first_name='User',
user_last_name='42',
)
Booking.objects.create(
event=recurring_event2_occurence,
user_external_id='user:1',
user_first_name='User',
user_last_name='42',
cancellation_datetime=now(),
)
login(app)
resp = app.get('/manage/agendas/%s/events/timesheet' % agenda.pk)
resp.form['date_start'] = '2022-02-01'
resp.form['date_end'] = '2022-02-28'
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert slots['events'] == [
event1,
event2,
event3,
recurring_event1,
recurring_event2,
]
assert len(slots['users'][0]['users']) == 1
assert slots['users'][0]['users'][0]['events'] == [
{
'event': event1,
'dates': {datetime.date(2022, 2, 15): True},
},
{
'event': event2,
'dates': {datetime.date(2022, 2, 15): False},
},
{
'event': event3,
'dates': {datetime.date(2022, 2, 15): False},
},
{
'event': recurring_event1,
'dates': {datetime.date(2022, 2, 15): True},
},
{
'event': recurring_event2,
'dates': {datetime.date(2022, 2, 15): False},
},
]
assert resp.pyquery.find('h4')[0].text == 'Timesheet from Feb. 1, 2022 to Feb. 28, 2022'
# activity_display: row
assert len(resp.pyquery.find('th.activity')) == 1
assert resp.pyquery.find('th.activity')[0].text == 'Activity'
assert len(resp.pyquery.find('th.date')) == 1
assert len(resp.pyquery.find('th.date-event')) == 0
assert resp.pyquery.find('th.date[data-id="15-02"]')[0].text == 'Tue 15/02'
assert len(resp.pyquery.find('td.activity')) == 5
assert resp.pyquery.find('td.activity')[0].text == 'event 1'
assert resp.pyquery.find('td.activity')[1].text == 'event 2'
assert resp.pyquery.find('td.activity')[2].text == 'event 3'
assert resp.pyquery.find('td.activity')[3].text == 'recurring 1'
assert resp.pyquery.find('td.activity')[4].text == 'recurring 2'
assert len(resp.pyquery.find('td.date')) == 5
assert resp.pyquery.find('td.date[data-id="15-02:event-1:user:1"]')[0].text == ''
assert resp.pyquery.find('td.date[data-id="15-02:event-2:user:1"]')[0].text is None
assert resp.pyquery.find('td.date[data-id="15-02:event-3:user:1"]')[0].text is None
assert resp.pyquery.find('td.date[data-id="15-02:recurring-1:user:1"]')[0].text == ''
assert resp.pyquery.find('td.date[data-id="15-02:recurring-2:user:1"]')[0].text is None
# activity_display: col
resp.form['activity_display'] = 'col'
resp = resp.form.submit()
new_slots = resp.context['form'].get_slots()
assert new_slots == slots
assert len(resp.pyquery.find('th.activity')) == 0
assert len(resp.pyquery.find('th.date')) == 0
assert len(resp.pyquery.find('th.date-event')) == 5
assert resp.pyquery.find('th.date-event[data-id="15-02:event-1"]')[0].text == 'event 1 of 15/02'
assert resp.pyquery.find('th.date-event[data-id="15-02:event-2"]')[0].text == 'event 2 of 15/02'
assert resp.pyquery.find('th.date-event[data-id="15-02:event-3"]')[0].text == 'event 3 of 15/02'
assert resp.pyquery.find('th.date-event[data-id="15-02:recurring-1"]')[0].text == 'recurring 1 of 15/02'
assert resp.pyquery.find('th.date-event[data-id="15-02:recurring-2"]')[0].text == 'recurring 2 of 15/02'
assert len(resp.pyquery.find('td.date')) == 5
assert resp.pyquery.find('td.date[data-id="15-02:event-1:user:1"]')[0].text == ''
assert resp.pyquery.find('td.date[data-id="15-02:event-2:user:1"]')[0].text is None
assert resp.pyquery.find('td.date[data-id="15-02:event-3:user:1"]')[0].text is None
assert resp.pyquery.find('td.date[data-id="15-02:recurring-1:user:1"]')[0].text == ''
assert resp.pyquery.find('td.date[data-id="15-02:recurring-2:user:1"]')[0].text is None
def test_events_timesheet_extra_data(app, admin_user):
agenda = Agenda.objects.create(label='Events', kind='events')
event = Event.objects.create(
start_datetime=make_aware(datetime.datetime(2022, 2, 15, 17, 0)), places=10, agenda=agenda
)
Booking.objects.create(
event=event,
user_first_name='User',
user_last_name='42',
user_external_id='user:1',
extra_data={'foo': 'bar', 'baz': 'blah'},
)
login(app)
resp = app.get('/manage/agendas/%s/events/timesheet' % agenda.pk)
resp.form['date_start'] = '2022-02-01'
resp.form['date_end'] = '2022-02-28'
resp.form['extra_data'] = ' foo '
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert resp.text.count('<div class="page_break">') == 0
assert len(slots['users']) == 1
assert slots['users'][0]['grouper'] == ''
assert len(slots['users'][0]['users']) == 1
assert slots['extra_data'] == ['foo']
assert slots['users'][0]['users'][0]['extra_data']['foo'] == 'bar'
resp.form['extra_data'] = ' foo ,baz,,'
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert len(slots['users'][0]['users']) == 1
assert slots['extra_data'] == ['foo', 'baz']
assert slots['users'][0]['users'][0]['extra_data']['foo'] == 'bar'
assert slots['users'][0]['users'][0]['extra_data']['baz'] == 'blah'
resp.form['extra_data'] = 'unknown'
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert len(slots['users'][0]['users']) == 1
assert slots['extra_data'] == ['unknown']
assert slots['users'][0]['users'][0]['extra_data']['unknown'] == ''
Subscription.objects.create(
agenda=agenda,
user_external_id='user:1',
user_first_name='Subscription',
user_last_name='41',
date_start=datetime.date(2022, 2, 1),
date_end=datetime.date(2022, 3, 1),
extra_data={'foo': 'baz'},
)
resp.form['extra_data'] = ' foo '
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert len(slots['users'][0]['users']) == 1
assert slots['extra_data'] == ['foo']
assert slots['users'][0]['users'][0]['extra_data']['foo'] == 'baz'
resp.form['extra_data'] = ' foo ,baz,,'
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert len(slots['users'][0]['users']) == 1
assert slots['extra_data'] == ['foo', 'baz']
assert slots['users'][0]['users'][0]['extra_data']['foo'] == 'baz'
assert slots['users'][0]['users'][0]['extra_data']['baz'] == ''
Booking.objects.create(
event=event,
user_first_name='User',
user_last_name='43',
user_external_id='user:2',
extra_data={'foo': 'bar', 'baz': 'aa'},
)
Booking.objects.create(
event=event,
user_first_name='User',
user_last_name='44',
user_external_id='user:3',
extra_data={'foo': 'bar2', 'baz': 'aa'},
)
resp.form['extra_data'] = ''
resp.form['group_by'] = 'foo'
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert resp.text.count('<div class="page_break">') == 0
assert len(slots['users']) == 3
assert slots['users'][0]['grouper'] == 'bar'
assert len(slots['users'][0]['users']) == 1
assert slots['users'][0]['users'][0]['user_id'] == 'user:2'
assert slots['users'][1]['grouper'] == 'bar2'
assert len(slots['users'][1]['users']) == 1
assert slots['users'][1]['users'][0]['user_id'] == 'user:3'
assert slots['users'][2]['grouper'] == 'baz'
assert len(slots['users'][2]['users']) == 1
assert slots['users'][2]['users'][0]['user_id'] == 'user:1'
resp.form['with_page_break'] = True
resp = resp.form.submit()
assert resp.text.count('<div class="page_break">') == 2
resp.form['group_by'] = 'baz'
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert len(slots['users']) == 2
assert slots['users'][0]['grouper'] == 'aa'
assert len(slots['users'][0]['users']) == 2
assert slots['users'][0]['users'][0]['user_id'] == 'user:2'
assert slots['users'][0]['users'][1]['user_id'] == 'user:3'
assert slots['users'][1]['grouper'] == ''
assert len(slots['users'][1]['users']) == 1
assert slots['users'][1]['users'][0]['user_id'] == 'user:1'
Subscription.objects.update(extra_data={'foo': 'baz', 'baz': 'blah'})
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert len(slots['users']) == 2
assert slots['users'][0]['grouper'] == 'aa'
assert len(slots['users'][0]['users']) == 2
assert slots['users'][0]['users'][0]['user_id'] == 'user:2'
assert slots['users'][0]['users'][1]['user_id'] == 'user:3'
assert slots['users'][1]['grouper'] == 'blah'
assert len(slots['users'][1]['users']) == 1
assert slots['users'][1]['users'][0]['user_id'] == 'user:1'
resp.form['group_by'] = 'unknown'
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert len(slots['users']) == 1
assert slots['users'][0]['grouper'] == ''
assert len(slots['users'][0]['users']) == 3
def test_events_timesheet_ordering(app, admin_user):
agenda = Agenda.objects.create(label='Events', kind='events')
event = Event.objects.create(
start_datetime=make_aware(datetime.datetime(2022, 2, 15, 17, 0)), places=10, agenda=agenda
)
Booking.objects.create(
event=event,
user_first_name='BB',
user_last_name='XX',
user_external_id='user:1',
)
Booking.objects.create(
event=event,
user_first_name='AA',
user_last_name='YY',
user_external_id='user:2',
cancellation_datetime=now(),
)
Subscription.objects.create(
agenda=agenda,
user_first_name='CC',
user_last_name='WW',
user_external_id='user:3',
date_start=datetime.date(2022, 2, 1),
date_end=datetime.date(2022, 3, 1),
)
login(app)
resp = app.get('/manage/agendas/%s/events/timesheet' % agenda.pk)
resp.form['date_start'] = '2022-02-01'
resp.form['date_end'] = '2022-02-28'
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert slots['users'][0]['users'][0]['user_id'] == 'user:3'
assert slots['users'][0]['users'][1]['user_id'] == 'user:1'
assert slots['users'][0]['users'][2]['user_id'] == 'user:2'
resp.form['sort'] = 'lastname,firstname'
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert slots['users'][0]['users'][0]['user_id'] == 'user:3'
assert slots['users'][0]['users'][1]['user_id'] == 'user:1'
assert slots['users'][0]['users'][2]['user_id'] == 'user:2'
resp.form['sort'] = 'firstname,lastname'
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert slots['users'][0]['users'][0]['user_id'] == 'user:2'
assert slots['users'][0]['users'][1]['user_id'] == 'user:1'
assert slots['users'][0]['users'][2]['user_id'] == 'user:3'
@pytest.mark.freeze_time('2022-04-01')
def test_events_timesheet_date_display(app, admin_user):
agenda = Agenda.objects.create(label='Events', kind='events')
recurring_event = Event.objects.create(
label='recurring 1',
start_datetime=make_aware(datetime.datetime(2022, 1, 1, 12, 0)),
places=10,
agenda=agenda,
recurrence_days=[1],
recurrence_end_date=datetime.date(2022, 4, 1),
)
recurring_event.create_all_recurrences()
Subscription.objects.create(
agenda=agenda,
user_external_id='user:1',
user_first_name='Subscription',
user_last_name='42',
date_start=datetime.date(2022, 1, 1),
date_end=datetime.date(2022, 4, 1),
extra_data={'foo': 'bar'},
)
login(app)
resp = app.get('/manage/agendas/%s/events/timesheet' % agenda.pk)
resp.form['date_start'] = '2022-01-01'
resp.form['date_end'] = '2022-03-31'
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert len(slots['dates']) == 1
assert [d[0] for d in slots['dates'][0]] == [
datetime.date(2022, 1, 3),
datetime.date(2022, 1, 10),
datetime.date(2022, 1, 17),
datetime.date(2022, 1, 24),
datetime.date(2022, 1, 31),
datetime.date(2022, 2, 7),
datetime.date(2022, 2, 14),
datetime.date(2022, 2, 21),
datetime.date(2022, 2, 28),
datetime.date(2022, 3, 7),
datetime.date(2022, 3, 14),
datetime.date(2022, 3, 21),
datetime.date(2022, 3, 28),
]
resp.form['date_display'] = 'month'
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert len(slots['dates']) == 3
assert [d[0] for d in slots['dates'][0]] == [
datetime.date(2022, 1, 3),
datetime.date(2022, 1, 10),
datetime.date(2022, 1, 17),
datetime.date(2022, 1, 24),
datetime.date(2022, 1, 31),
]
assert [d[0] for d in slots['dates'][1]] == [
datetime.date(2022, 2, 7),
datetime.date(2022, 2, 14),
datetime.date(2022, 2, 21),
datetime.date(2022, 2, 28),
]
assert [d[0] for d in slots['dates'][2]] == [
datetime.date(2022, 3, 7),
datetime.date(2022, 3, 14),
datetime.date(2022, 3, 21),
datetime.date(2022, 3, 28),
]
resp.form['date_display'] = 'week'
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert resp.text.count('<div class="page_break">') == 12
assert len(slots['dates']) == 13
assert [d[0] for d in itertools.chain(*slots['dates'])] == [
datetime.date(2022, 1, 3),
datetime.date(2022, 1, 10),
datetime.date(2022, 1, 17),
datetime.date(2022, 1, 24),
datetime.date(2022, 1, 31),
datetime.date(2022, 2, 7),
datetime.date(2022, 2, 14),
datetime.date(2022, 2, 21),
datetime.date(2022, 2, 28),
datetime.date(2022, 3, 7),
datetime.date(2022, 3, 14),
datetime.date(2022, 3, 21),
datetime.date(2022, 3, 28),
]
resp.form['date_display'] = 'custom'
resp = resp.form.submit()
assert resp.context['form'].errors['custom_nb_dates_per_page'] == ['This field is required.']
resp.form['custom_nb_dates_per_page'] = 10
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert len(slots['dates']) == 2
assert [d[0] for d in slots['dates'][0]] == [
datetime.date(2022, 1, 3),
datetime.date(2022, 1, 10),
datetime.date(2022, 1, 17),
datetime.date(2022, 1, 24),
datetime.date(2022, 1, 31),
datetime.date(2022, 2, 7),
datetime.date(2022, 2, 14),
datetime.date(2022, 2, 21),
datetime.date(2022, 2, 28),
datetime.date(2022, 3, 7),
]
assert [d[0] for d in slots['dates'][1]] == [
datetime.date(2022, 3, 14),
datetime.date(2022, 3, 21),
datetime.date(2022, 3, 28),
]
resp.form['custom_nb_dates_per_page'] = 3
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert len(slots['dates']) == 5
assert [d[0] for d in slots['dates'][0]] == [
datetime.date(2022, 1, 3),
datetime.date(2022, 1, 10),
datetime.date(2022, 1, 17),
]
assert [d[0] for d in slots['dates'][1]] == [
datetime.date(2022, 1, 24),
datetime.date(2022, 1, 31),
datetime.date(2022, 2, 7),
]
assert [d[0] for d in slots['dates'][2]] == [
datetime.date(2022, 2, 14),
datetime.date(2022, 2, 21),
datetime.date(2022, 2, 28),
]
assert [d[0] for d in slots['dates'][3]] == [
datetime.date(2022, 3, 7),
datetime.date(2022, 3, 14),
datetime.date(2022, 3, 21),
]
assert [d[0] for d in slots['dates'][4]] == [
datetime.date(2022, 3, 28),
]
Subscription.objects.create(
agenda=agenda,
user_external_id='user:2',
user_first_name='Subscription',
user_last_name='43',
date_start=datetime.date(2022, 1, 1),
date_end=datetime.date(2022, 4, 1),
extra_data={'foo': 'baz'},
)
resp.form['date_display'] = 'week'
resp.form['group_by'] = 'foo'
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert resp.text.count('<div class="page_break">') == 12
resp.form['with_page_break'] = True
resp = resp.form.submit()
assert resp.text.count('<div class="page_break">') == 25
def test_events_timesheet_pdf(app, admin_user):
agenda = Agenda.objects.create(label='Events', kind='events')
login(app)
resp = app.get(
'/manage/agendas/%s/events/timesheet?pdf=&date_start=2022-02-01&date_end=2022-02-28&sort=lastname,firstname'
'&date_display=all&activity_display=row&orientation=portrait&booking_filter=all' % agenda.pk
)
assert resp.headers['Content-Type'] == 'application/pdf'
assert (
resp.headers['Content-Disposition']
== 'attachment; filename="timesheet_events_2022-02-01_2022-02-28.pdf"'
)
# form invalid
resp = app.get(
'/manage/agendas/%s/events/timesheet?pdf=&date_start=2022-02-01&date_end=2022-02-28&sort=lastname,firstname&date_display=all'
'&activity_display=row&booking_filter=all' % agenda.pk
)
assert resp.context['form'].errors['orientation'] == ['This field is required.']
def test_events_timesheet_csv(app, admin_user):
agenda = Agenda.objects.create(label='Events', kind='events')
login(app)
resp = app.get(
'/manage/agendas/%s/events/timesheet?csv=&date_start=2022-02-01&date_end=2022-02-28&sort=lastname,firstname'
'&date_display=all&activity_display=row&orientation=portrait&booking_filter=all' % agenda.pk
)
assert resp.headers['Content-Type'] == 'text/csv'
assert (
resp.headers['Content-Disposition']
== 'attachment; filename="timesheet_events_2022-02-01_2022-02-28.csv"'
)
# form invalid
resp = app.get(
'/manage/agendas/%s/events/timesheet?csv=&date_start=2022-02-01&date_end=2022-02-28&sort=lastname,firstname&date_display=all'
'&activity_display=row&booking_filter=all' % agenda.pk
)
assert resp.context['form'].errors['orientation'] == ['This field is required.']
# only one event
recurring_event = Event.objects.create(
label='recurring 1',
start_datetime=make_aware(datetime.datetime(2022, 2, 1, 12, 0)),
places=10,
agenda=agenda,
recurrence_days=[1],
recurrence_end_date=datetime.date(2022, 4, 1),
)
recurring_event.create_all_recurrences()
recurring_event_occurence = recurring_event.recurrences.first()
Subscription.objects.create(
agenda=agenda,
user_external_id='user:1',
user_first_name='Subscription',
user_last_name='01',
date_start=datetime.date(2022, 1, 1),
date_end=datetime.date(2022, 4, 1),
extra_data={'foo': 'bar'},
)
Subscription.objects.create(
agenda=agenda,
user_external_id='user:2',
user_first_name='Subscription',
user_last_name='02',
date_start=datetime.date(2022, 1, 1),
date_end=datetime.date(2022, 4, 1),
extra_data={'foo': 'bar'},
)
Booking.objects.create(
event=recurring_event_occurence,
user_external_id='user:2',
user_first_name='User',
user_last_name='02',
)
# display row
resp = app.get(
'/manage/agendas/%s/events/timesheet?csv=&date_start=2022-02-01&date_end=2022-02-28&sort=lastname,firstname'
'&date_display=all&activity_display=row&orientation=portrait&booking_filter=all' % agenda.pk
)
assert resp.text == (
'First name,Last name,Mon 07/02,Mon 14/02,Mon 21/02,Mon 28/02\r\n'
'Subscription,01,,,,\r\n'
'Subscription,02,☐,,,\r\n'
)
# display col
resp = app.get(
'/manage/agendas/%s/events/timesheet?csv=&date_start=2022-02-01&date_end=2022-02-28&sort=lastname,firstname'
'&date_display=all&activity_display=col&orientation=portrait&booking_filter=all' % agenda.pk
)
assert resp.text == (
'First name,Last name,recurring 1 of 07-02,recurring 1 of 14-02,recurring 1 of 21-02,recurring 1 of 28-02\r\n'
'Subscription,01,,,,\r\n'
'Subscription,02,☐,,,\r\n'
)
# more than one event
event = Event.objects.create(
start_datetime=make_aware(datetime.datetime(2022, 2, 15, 17, 0)),
places=10,
agenda=agenda,
)
Booking.objects.create(
event=event,
user_external_id='user:1',
user_first_name='User',
user_last_name='01',
)
# display row
resp = app.get(
'/manage/agendas/%s/events/timesheet?csv=&date_start=2022-02-01&date_end=2022-02-28&sort=lastname,firstname'
'&date_display=all&activity_display=row&orientation=portrait&booking_filter=all' % agenda.pk
)
assert resp.text == (
'First name,Last name,Activity,Mon 07/02,Mon 14/02,Tue 15/02,Mon 21/02,Mon 28/02\r\n'
'Subscription,01,recurring 1,,,-,,\r\n'
',,"Feb. 15, 2022, 5 p.m.",-,-,☐,-,-\r\n'
'Subscription,02,recurring 1,☐,,-,,\r\n'
',,"Feb. 15, 2022, 5 p.m.",-,-,,-,-\r\n'
)
# display col
resp = app.get(
'/manage/agendas/%s/events/timesheet?csv=&date_start=2022-02-01&date_end=2022-02-28&sort=lastname,firstname'
'&date_display=all&activity_display=col&orientation=portrait&booking_filter=all' % agenda.pk
)
assert resp.text == (
'First name,Last name,recurring 1 of 07-02,recurring 1 of 14-02,"Feb. 15, 2022, 5 p.m. of 15-02",recurring 1 of 21-02,recurring 1 of 28-02\r\n'
'Subscription,01,,,☐,,\r\n'
'Subscription,02,☐,,,,\r\n'
)
# with extra_data and grouper
# display row
resp = app.get(
'/manage/agendas/%s/events/timesheet?csv=&date_start=2022-02-01&date_end=2022-02-28&sort=lastname,firstname'
'&date_display=all&activity_display=row&orientation=portrait&booking_filter=all&extra_data=foo&group_by=foo'
% agenda.pk
)
assert resp.text == (
'foo: bar\r\n'
'First name,Last name,foo,Activity,Mon 07/02,Mon 14/02,Tue 15/02,Mon 21/02,Mon 28/02\r\n'
'Subscription,01,bar,recurring 1,,,-,,\r\n'
',,,"Feb. 15, 2022, 5 p.m.",-,-,☐,-,-\r\n'
'Subscription,02,bar,recurring 1,☐,,-,,\r\n'
',,,"Feb. 15, 2022, 5 p.m.",-,-,,-,-\r\n'
)
# display col
resp = app.get(
'/manage/agendas/%s/events/timesheet?csv=&date_start=2022-02-01&date_end=2022-02-28&sort=lastname,firstname'
'&date_display=all&activity_display=col&orientation=portrait&booking_filter=all&extra_data=foo&group_by=foo'
% agenda.pk
)
assert resp.text == (
'foo: bar\r\n'
'First name,Last name,foo,recurring 1 of 07-02,recurring 1 of 14-02,"Feb. 15, 2022, 5 p.m. of 15-02",recurring 1 of 21-02,recurring 1 of 28-02\r\n'
'Subscription,01,bar,,,☐,,\r\n'
'Subscription,02,bar,☐,,,,\r\n'
)
def test_event_timesheet_wrong_kind(app, admin_user):
agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
event = Event.objects.create(
start_datetime=make_aware(datetime.datetime(2022, 2, 15, 17, 0)), places=10, agenda=agenda
)
app = login(app)
app.get('/manage/agendas/%s/events/%s/timesheet' % (agenda.pk, event.pk), status=404)
agenda.kind = 'virtual'
agenda.save()
app.get('/manage/agendas/%s/events/%s/timesheet' % (agenda.pk, event.pk), status=404)
def test_event_timesheet_wrong_event(app, admin_user):
agenda = Agenda.objects.create(label='Events', kind='events')
agenda2 = Agenda.objects.create(label='Events', kind='events')
event = Event.objects.create(
start_datetime=make_aware(datetime.datetime(2022, 2, 15, 17, 0)),
places=10,
agenda=agenda,
cancelled=True,
)
app = login(app)
app.get('/manage/agendas/%s/events/%s/timesheet' % (agenda.pk, event.pk), status=404)
event.cancelled = False
event.recurrence_days = [2]
event.save()
app.get('/manage/agendas/%s/events/%s/timesheet' % (agenda.pk, event.pk), status=404)
event.recurrence_days = None
event.save()
app.get('/manage/agendas/%s/events/%s/timesheet' % (agenda.pk, event.pk), status=200)
app.get('/manage/agendas/%s/events/%s/timesheet' % (agenda2.pk, event.pk), status=404)
app.get('/manage/agendas/%s/events/%s/timesheet' % (agenda.pk, 0), status=404)
def test_event_timesheet_form(app, admin_user):
agenda = Agenda.objects.create(label='Events', kind='events')
event = Event.objects.create(
start_datetime=make_aware(datetime.datetime(2022, 2, 15, 17, 0)), places=10, agenda=agenda
)
app = login(app)
resp = app.get('/manage/agendas/%s/events/%s/timesheet' % (agenda.pk, event.pk))
assert 'date_start' not in resp.context['form'].fields
assert 'date_end' not in resp.context['form'].fields
assert 'date_display' not in resp.context['form'].fields
assert 'custom_nb_dates_per_page' not in resp.context['form'].fields
assert 'activity_display' not in resp.context['form'].fields
assert resp.context['form'].errors == {}
def test_event_timesheet_slots(app, admin_user):
agenda = Agenda.objects.create(label='Events', kind='events')
event = Event.objects.create(
label='My event',
start_datetime=make_aware(datetime.datetime(2022, 2, 15, 17, 0)),
places=10,
agenda=agenda,
)
Subscription.objects.create(
agenda=agenda,
user_external_id='user:1',
user_first_name='Subscription',
user_last_name='42',
date_start=datetime.date(2022, 2, 15),
date_end=datetime.date(2022, 2, 16),
)
Booking.objects.create(
event=event,
user_external_id='user:1',
user_first_name='User',
user_last_name='42',
)
login(app)
resp = app.get('/manage/agendas/%s/events/%s/timesheet' % (agenda.pk, event.pk))
with CaptureQueriesContext(connection) as ctx:
resp = resp.form.submit()
assert len(ctx.captured_queries) == 7
slots = resp.context['form'].get_slots()
assert (
resp.pyquery.find('h4')[0].text.strip()
== 'Timesheet - My event - Feb. 15, 2022, 5 p.m. (1 participant)'
)
slots = resp.context['form'].get_slots()
assert len(slots['dates']) == 1
assert [d[0] for d in slots['dates'][0]] == [
datetime.date(2022, 2, 15),
]
assert slots['events'] == [event]
assert slots['users'][0]['users'] == [
{
'user_id': 'user:1',
'user_first_name': 'Subscription',
'user_last_name': '42',
'extra_data': {},
'events': [
{
'event': event,
'dates': {datetime.date(2022, 2, 15): True},
},
],
},
]
assert slots['extra_data'] == []
def test_event_timesheet_subscription_limits(app, admin_user):
agenda = Agenda.objects.create(label='Events', kind='events')
event = Event.objects.create(
start_datetime=make_aware(datetime.datetime(2022, 2, 15, 17, 0)), places=10, agenda=agenda
)
dates = [
('2022-01-31', '2022-02-01'),
('2022-02-01', '2022-02-02'),
('2022-02-01', '2022-02-15'),
('2022-02-01', '2022-02-16'),
('2022-02-15', '2022-02-28'),
('2022-02-15', '2022-03-01'),
('2022-02-16', '2022-03-01'),
('2022-02-01', '2022-03-01'),
('2022-02-28', '2022-03-01'),
('2022-03-01', '2022-03-02'),
]
for start, end in dates:
Subscription.objects.create(
agenda=agenda,
user_external_id='user:%s-%s' % (start, end),
user_first_name='Subscription',
user_last_name='%s - %s' % (start, end),
date_start=datetime.datetime.strptime(start, '%Y-%m-%d'),
date_end=datetime.datetime.strptime(end, '%Y-%m-%d'),
)
login(app)
resp = app.get('/manage/agendas/%s/events/%s/timesheet' % (agenda.pk, event.pk))
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert len(slots['dates']) == 1
assert [d[0] for d in slots['dates'][0]] == [
datetime.date(2022, 2, 15),
]
assert slots['events'] == [
event,
]
users = slots['users'][0]['users']
assert len(users) == 4
assert users[0]['user_id'] == 'user:2022-02-01-2022-02-16'
assert users[1]['user_id'] == 'user:2022-02-01-2022-03-01'
assert users[2]['user_id'] == 'user:2022-02-15-2022-02-28'
assert users[3]['user_id'] == 'user:2022-02-15-2022-03-01'
@pytest.mark.freeze_time('2022-02-15')
def test_event_timesheet_filter_with_booking(app, admin_user):
agenda = Agenda.objects.create(label='Events', kind='events')
event = Event.objects.create(
start_datetime=make_aware(datetime.datetime(2022, 2, 15, 17, 0)), places=10, agenda=agenda
)
Booking.objects.create(event=event, user_external_id='user:1', user_first_name='User', user_last_name='1')
Booking.objects.create(event=event, user_external_id='user:2', user_first_name='User', user_last_name='2')
login(app)
resp = app.get('/manage/agendas/%s/events/%s/timesheet' % (agenda.pk, event.pk))
assert 'booking_filter' not in resp.context['form'].fields
start = datetime.date(2022, 2, 1)
end = datetime.date(2022, 3, 1)
for user_id in [1, 2, 3, 4, 5, 6]:
Subscription.objects.create(
agenda=agenda,
user_external_id='user:%s' % user_id,
user_first_name='Subscription',
user_last_name=str(user_id),
date_start=start,
date_end=end,
)
resp = app.get('/manage/agendas/%s/events/%s/timesheet' % (agenda.pk, event.pk))
assert resp.form['booking_filter'].value == 'all'
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert len(slots['dates']) == 1
assert [d[0] for d in slots['dates'][0]] == [
datetime.date(2022, 2, 15),
]
assert slots['events'] == [
event,
]
users = slots['users'][0]['users']
assert len(users) == 6
assert users[0]['user_id'] == 'user:1'
assert users[1]['user_id'] == 'user:2'
assert users[2]['user_id'] == 'user:3'
assert users[3]['user_id'] == 'user:4'
assert users[4]['user_id'] == 'user:5'
assert users[5]['user_id'] == 'user:6'
resp.form['booking_filter'] = 'with_booking'
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert len(slots['dates']) == 1
assert [d[0] for d in slots['dates'][0]] == [
datetime.date(2022, 2, 15),
]
assert slots['events'] == [
event,
]
users = slots['users'][0]['users']
assert len(users) == 2
assert users[0]['user_id'] == 'user:1'
assert users[1]['user_id'] == 'user:2'
resp.form['booking_filter'] = 'without_booking'
resp = resp.form.submit()
slots = resp.context['form'].get_slots()
assert len(slots['dates']) == 1
assert [d[0] for d in slots['dates'][0]] == [
datetime.date(2022, 2, 15),
]
assert slots['events'] == [
event,
]
users = slots['users'][0]['users']
assert len(users) == 4
assert users[0]['user_id'] == 'user:3'
assert users[1]['user_id'] == 'user:4'
assert users[2]['user_id'] == 'user:5'
assert users[3]['user_id'] == 'user:6'
def test_event_timesheet_pdf(app, admin_user):
agenda = Agenda.objects.create(label='Foo', kind='events')
event = Event.objects.create(
label='Bar',
start_datetime=make_aware(datetime.datetime(2022, 2, 15, 17, 0)),
places=10,
agenda=agenda,
)
login(app)
resp = app.get(
'/manage/agendas/%s/events/%s/timesheet?pdf=&sort=lastname,firstname&date_display=all&orientation=portrait&booking_filter=all'
% (agenda.pk, event.pk)
)
assert resp.headers['Content-Type'] == 'application/pdf'
assert resp.headers['Content-Disposition'] == 'attachment; filename="timesheet_foo_bar.pdf"'
# form invalid
resp = app.get(
'/manage/agendas/%s/events/%s/timesheet?pdf=&sort=lastname,firstname&date_display=all&booking_filter=all'
% (agenda.pk, event.pk)
)
assert resp.context['form'].errors['orientation'] == ['This field is required.']
def test_event_timesheet_csv(app, admin_user):
agenda = Agenda.objects.create(label='Events', kind='events')
event = Event.objects.create(
label='Bar',
start_datetime=make_aware(datetime.datetime(2022, 2, 15, 17, 0)),
places=10,
agenda=agenda,
)
login(app)
resp = app.get(
'/manage/agendas/%s/events/%s/timesheet?csv=&sort=lastname,firstname&date_display=all&orientation=portrait&booking_filter=all'
% (agenda.pk, event.pk)
)
assert resp.headers['Content-Type'] == 'text/csv'
assert resp.headers['Content-Disposition'] == 'attachment; filename="timesheet_events_bar.csv"'
# form invalid
resp = app.get(
'/manage/agendas/%s/events/%s/timesheet?csv=&sort=lastname,firstname&date_display=all&booking_filter=all'
% (agenda.pk, event.pk)
)
assert resp.context['form'].errors['orientation'] == ['This field is required.']
Subscription.objects.create(
agenda=agenda,
user_external_id='user:1',
user_first_name='Subscription',
user_last_name='01',
date_start=datetime.date(2022, 1, 1),
date_end=datetime.date(2022, 4, 1),
extra_data={'foo': 'bar'},
)
Subscription.objects.create(
agenda=agenda,
user_external_id='user:2',
user_first_name='Subscription',
user_last_name='02',
date_start=datetime.date(2022, 1, 1),
date_end=datetime.date(2022, 4, 1),
extra_data={'foo': 'bar'},
)
Booking.objects.create(
event=event,
user_external_id='user:2',
user_first_name='User',
user_last_name='02',
)
resp = app.get(
'/manage/agendas/%s/events/%s/timesheet?csv=&sort=lastname,firstname&date_display=all&orientation=portrait&booking_filter=all'
% (agenda.pk, event.pk)
)
assert resp.text == ('First name,Last name,Tue 15/02\r\n' 'Subscription,01,\r\n' 'Subscription,02,☐\r\n')
resp = app.get(
'/manage/agendas/%s/events/%s/timesheet?csv=&sort=lastname,firstname&date_display=all&orientation=portrait'
'&booking_filter=all&extra_data=foo&group_by=foo' % (agenda.pk, event.pk)
)
assert resp.text == (
'foo: bar\r\n'
'First name,Last name,foo,Tue 15/02\r\n'
'Subscription,01,bar,\r\n'
'Subscription,02,bar,☐\r\n'
)