lingo/tests/pricing/manager/test_agenda_pricing.py

1547 lines
62 KiB
Python

import datetime
from decimal import Decimal
from unittest import mock
import pytest
from django.utils.timezone import now
from lingo.agendas.chrono import ChronoError
from lingo.agendas.models import Agenda, CheckType, CheckTypeGroup
from lingo.pricing.models import AgendaPricing, BillingDate, Criteria, CriteriaCategory, Pricing, PricingError
from tests.utils import login
pytestmark = pytest.mark.django_db
def test_add_agenda_pricing(app, admin_user):
pricing = Pricing.objects.create(label='Model')
app = login(app)
resp = app.get('/manage/pricing/')
resp = resp.click(href='/manage/pricing/agenda-pricings/')
resp = resp.click('New pricing')
# first pricing, starts on today
assert resp.form['date_start'].value == now().strftime('%Y-%m-%d')
resp.form['label'] = 'Pricing for lunch'
resp.form['pricing'] = pricing.pk
resp.form['date_start'] = '2021-09-01'
resp.form['date_end'] = '2021-09-01'
resp.form['flat_fee_schedule'] = False
resp.form['subscription_required'] = False
resp = resp.form.submit()
assert resp.context['form'].errors['date_end'] == ['End date must be greater than start date.']
resp.form['date_end'] = '2022-09-01'
resp = resp.form.submit()
agenda_pricing = AgendaPricing.objects.latest('pk')
assert resp.location.endswith('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
assert agenda_pricing.label == 'Pricing for lunch'
assert agenda_pricing.slug == 'pricing-for-lunch'
assert agenda_pricing.pricing == pricing
assert list(agenda_pricing.agendas.all()) == []
assert agenda_pricing.date_start == datetime.date(2021, 9, 1)
assert agenda_pricing.date_end == datetime.date(2022, 9, 1)
assert agenda_pricing.flat_fee_schedule is False
assert agenda_pricing.subscription_required is True
resp = app.get('/manage/pricing/agenda-pricing/add/')
# starts on last date_end
assert resp.form['date_start'].value == '2022-09-01'
resp.form['label'] = 'Pricing for lunch'
resp.form['pricing'] = pricing.pk
resp.form['date_end'] = '2023-09-01'
resp.form['flat_fee_schedule'] = True
resp.form['subscription_required'] = False
resp.form.submit()
agenda_pricing = AgendaPricing.objects.latest('pk')
assert agenda_pricing.flat_fee_schedule is True
assert agenda_pricing.subscription_required is False
def test_edit_agenda_pricing(app, admin_user):
pricing = Pricing.objects.create(label='Model')
pricing2 = Pricing.objects.create(label='Model 2')
agenda_pricing = AgendaPricing.objects.create(
label='Foo Bar',
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2022, month=9, day=1),
)
agenda_pricing2 = AgendaPricing.objects.create(
label='Foo Baz',
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2022, month=9, day=1),
)
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
resp = resp.click(href='/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing.pk)
assert resp.form['date_start'].value == '2021-09-01'
resp.form['label'] = 'Foo Baz'
resp.form['slug'] = agenda_pricing2.slug
resp.form['pricing'] = pricing2.pk
resp.form['date_start'] = '2021-09-01'
resp.form['date_end'] = '2021-09-01'
resp.form['flat_fee_schedule'] = False
resp.form['subscription_required'] = False
resp = resp.form.submit()
assert resp.context['form'].errors['slug'] == ['Another pricing exists with the same identifier.']
assert resp.context['form'].errors['date_end'] == ['End date must be greater than start date.']
resp.form['slug'] = 'foo-bazz'
resp.form['date_start'] = '2021-08-01'
resp.form['date_end'] = '2022-09-01'
resp = resp.form.submit()
assert resp.location.endswith('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
agenda_pricing.refresh_from_db()
assert agenda_pricing.slug == 'foo-bazz'
assert agenda_pricing.pricing == pricing2
assert agenda_pricing.date_start == datetime.date(2021, 8, 1)
assert agenda_pricing.date_end == datetime.date(2022, 9, 1)
assert agenda_pricing.flat_fee_schedule is False
assert agenda_pricing.subscription_required is True
resp = app.get('/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing.pk)
resp.form['flat_fee_schedule'] = True
resp.form['subscription_required'] = False
resp.form.submit()
agenda_pricing.refresh_from_db()
assert agenda_pricing.flat_fee_schedule is True
assert agenda_pricing.subscription_required is False
agenda = Agenda.objects.create(label='Foo bar')
agenda_pricing.agendas.add(agenda)
agenda_pricing.subscription_required = True
agenda_pricing.save()
resp = app.get('/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing.pk)
resp.form['subscription_required'] = False
resp = resp.form.submit()
assert resp.context['form'].errors['subscription_required'] == [
'Some agendas are linked to this pricing; please unlink them first.'
]
agenda_pricing.subscription_required = False
agenda_pricing.save()
resp = app.get('/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing.pk)
resp = resp.form.submit()
assert resp.location.endswith('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
agenda_pricing.flat_fee_schedule = True
agenda_pricing.save()
agenda_pricing.billingdates.create(
date_start=datetime.date(year=2021, month=9, day=1),
label='Foo',
)
resp = app.get('/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing.pk)
resp.form['flat_fee_schedule'] = False
resp = resp.form.submit()
assert resp.context['form'].errors['flat_fee_schedule'] == [
'Some billing dates are are defined for this pricing; please delete them first.'
]
def test_edit_agenda_pricing_overlapping_flat_fee_schedule(app, admin_user):
agenda1 = Agenda.objects.create(label='Foo bar 1')
agenda2 = Agenda.objects.create(label='Foo bar 2')
pricing = Pricing.objects.create(label='Model')
agenda_pricing1 = AgendaPricing.objects.create(
label='Foo Bar',
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2022, month=9, day=1),
)
agenda_pricing1.agendas.add(agenda1, agenda2)
agenda_pricing2 = AgendaPricing.objects.create(
label='Foo Bar',
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2022, month=9, day=1),
)
agenda_pricing2.agendas.add(agenda1, agenda2)
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing1.pk)
# ok, flat_fee_schedule has not changed
resp.form.submit().follow()
resp = app.get('/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing1.pk)
# ok, flat_fee_schedule is different
resp.form['flat_fee_schedule'] = True
resp.form.submit().follow()
resp = app.get('/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing1.pk)
resp.form['flat_fee_schedule'] = False
resp = resp.form.submit()
assert resp.context['form'].non_field_errors() == [
'Agenda "Foo bar 1" has already a pricing overlapping this period.',
'Agenda "Foo bar 2" has already a pricing overlapping this period.',
]
agenda_pricing2.agendas.remove(agenda1)
resp = resp.form.submit()
assert resp.context['form'].non_field_errors() == [
'Agenda "Foo bar 2" has already a pricing overlapping this period.'
]
agenda_pricing2.agendas.remove(agenda2)
# ok
resp.form.submit().follow()
def test_edit_agenda_pricing_overlapping_date_start(app, admin_user):
agenda1 = Agenda.objects.create(label='Foo bar 1')
agenda2 = Agenda.objects.create(label='Foo bar 2')
pricing = Pricing.objects.create(label='Model')
agenda_pricing1 = AgendaPricing.objects.create(
label='Foo Bar',
pricing=pricing,
date_start=datetime.date(year=2021, month=10, day=1),
date_end=datetime.date(year=2022, month=10, day=1),
)
agenda_pricing1.agendas.add(agenda1, agenda2)
agenda_pricing2 = AgendaPricing.objects.create(
label='Foo Bar',
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2022, month=9, day=1),
)
agenda_pricing2.agendas.add(agenda1, agenda2)
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing1.pk)
# ok, date_start has not changed
resp.form.submit().follow()
resp = app.get('/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing1.pk)
# ok, no overlapping
resp.form['date_start'] = '2022-09-01'
resp.form.submit().follow()
resp = app.get('/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing1.pk)
resp.form['date_start'] = '2021-10-01'
resp = resp.form.submit()
assert resp.context['form'].non_field_errors() == [
'Agenda "Foo bar 1" has already a pricing overlapping this period.',
'Agenda "Foo bar 2" has already a pricing overlapping this period.',
]
agenda_pricing2.agendas.remove(agenda1)
resp = resp.form.submit()
assert resp.context['form'].non_field_errors() == [
'Agenda "Foo bar 2" has already a pricing overlapping this period.'
]
agenda_pricing2.agendas.remove(agenda2)
# ok
resp.form.submit().follow()
def test_edit_agenda_pricing_overlapping_date_end(app, admin_user):
agenda1 = Agenda.objects.create(label='Foo bar 1')
agenda2 = Agenda.objects.create(label='Foo bar 2')
pricing = Pricing.objects.create(label='Model')
agenda_pricing1 = AgendaPricing.objects.create(
label='Foo Bar',
pricing=pricing,
date_start=datetime.date(year=2021, month=8, day=1),
date_end=datetime.date(year=2022, month=8, day=1),
)
agenda_pricing1.agendas.add(agenda1, agenda2)
agenda_pricing2 = AgendaPricing.objects.create(
label='Foo Bar',
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2022, month=9, day=1),
)
agenda_pricing2.agendas.add(agenda1, agenda2)
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing1.pk)
# ok, date_end has not changed
resp.form.submit().follow()
resp = app.get('/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing1.pk)
# ok, no overlapping
resp.form['date_end'] = '2021-09-01'
resp.form.submit().follow()
resp = app.get('/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing1.pk)
resp.form['date_end'] = '2022-08-01'
resp = resp.form.submit()
assert resp.context['form'].non_field_errors() == [
'Agenda "Foo bar 1" has already a pricing overlapping this period.',
'Agenda "Foo bar 2" has already a pricing overlapping this period.',
]
agenda_pricing2.agendas.remove(agenda1)
resp = resp.form.submit()
assert resp.context['form'].non_field_errors() == [
'Agenda "Foo bar 2" has already a pricing overlapping this period.'
]
agenda_pricing2.agendas.remove(agenda2)
# ok
resp.form.submit().follow()
def test_edit_agenda_pricing_billing_date_start(app, admin_user):
pricing = Pricing.objects.create(label='Model')
agenda_pricing = AgendaPricing.objects.create(
label='Foo Bar',
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2022, month=9, day=1),
flat_fee_schedule=True,
)
agenda_pricing.billingdates.create(
date_start=datetime.date(year=2021, month=9, day=1),
label='Foo',
)
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing.pk)
# ok, date_start has not changed
resp.form.submit().follow()
resp = app.get('/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing.pk)
# ok, billing date inside period
resp.form['date_start'] = '2021-08-31'
resp.form.submit().follow()
resp = app.get('/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing.pk)
resp.form['date_start'] = '2021-09-02'
resp = resp.form.submit()
assert resp.context['form'].non_field_errors() == ['Some billing dates are outside the pricing period.']
# but don't check billing dates if not flat_fee_schedule
agenda_pricing.flat_fee_schedule = False
agenda_pricing.save()
# ok
resp = app.get('/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing.pk)
resp.form.submit().follow()
def test_edit_agenda_pricing_billing_date_end(app, admin_user):
pricing = Pricing.objects.create(label='Model')
agenda_pricing = AgendaPricing.objects.create(
label='Foo Bar',
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2022, month=9, day=1),
flat_fee_schedule=True,
)
agenda_pricing.billingdates.create(
date_start=datetime.date(year=2022, month=9, day=1),
label='Foo',
)
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing.pk)
# ok, date_end has not changed
resp.form.submit().follow()
resp = app.get('/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing.pk)
# ok, billing date inside period
resp.form['date_end'] = '2022-09-02'
resp.form.submit().follow()
resp = app.get('/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing.pk)
resp.form['date_end'] = '2022-09-01'
resp = resp.form.submit()
assert resp.context['form'].non_field_errors() == ['Some billing dates are outside the pricing period.']
# but don't check billing dates if not flat_fee_schedule
agenda_pricing.flat_fee_schedule = False
agenda_pricing.save()
# ok
resp = app.get('/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing.pk)
resp.form.submit().follow()
def test_detail_agenda_pricing(app, admin_user):
pricing = Pricing.objects.create(label='Model')
agenda_pricing = AgendaPricing.objects.create(
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
app = login(app)
resp = app.get('/manage/pricing/agenda-pricings/')
resp = resp.click(href='/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
app.get('/manage/pricing/agenda-pricing/%s/' % 0, status=404)
def test_delete_agenda_pricing(app, admin_user):
pricing = Pricing.objects.create(label='Model')
agenda_pricing = AgendaPricing.objects.create(
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2022, month=9, day=1),
)
app = login(app)
app.get('/manage/pricing/agenda-pricing/%s/delete/' % 0, status=404)
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
resp = resp.click(href='/manage/pricing/agenda-pricing/%s/delete/' % agenda_pricing.pk)
resp = resp.form.submit()
assert resp.location.endswith('/manage/pricing/agenda-pricings/')
assert AgendaPricing.objects.exists() is False
def test_agenda_pricing_add_agenda(app, admin_user):
pricing = Pricing.objects.create(label='Model')
agenda_pricing = AgendaPricing.objects.create(
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2022, month=9, day=1),
)
agenda1 = Agenda.objects.create(label='Foo bar 1')
agenda2 = Agenda.objects.create(label='Foo bar 2')
agenda3 = Agenda.objects.create(label='Foo bar 3')
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
resp = resp.click(href='/manage/pricing/agenda-pricing/%s/agenda/add/' % agenda_pricing.pk)
assert list(resp.context['form'].fields['agenda'].queryset) == [
agenda1,
agenda2,
agenda3,
]
resp.form['agenda'] = agenda1.pk
resp = resp.form.submit()
assert resp.location.endswith('/manage/pricing/agenda-pricing/%s/#open:agendas' % agenda_pricing.pk)
resp = resp.follow()
assert list(agenda_pricing.agendas.all()) == [agenda1]
resp = app.get('/manage/pricing/agenda-pricing/%s/agenda/add/' % agenda_pricing.pk)
assert list(resp.context['form'].fields['agenda'].queryset) == [
agenda2,
agenda3,
]
resp.form['agenda'] = agenda2.pk
resp = resp.form.submit().follow()
assert list(agenda_pricing.agendas.all()) == [agenda1, agenda2]
agenda_pricing2 = AgendaPricing.objects.create(
pricing=pricing,
date_start=datetime.date(year=2021, month=11, day=1),
date_end=datetime.date(year=2022, month=11, day=1),
)
resp = app.get('/manage/pricing/agenda-pricing/%s/agenda/add/' % agenda_pricing2.pk)
assert list(resp.context['form'].fields['agenda'].queryset) == [
agenda1,
agenda2,
agenda3,
]
resp.form['agenda'] = agenda1.pk
resp = resp.form.submit()
assert resp.context['form'].errors['agenda'] == [
'This agendas has already a pricing overlapping this period.'
]
resp.form['agenda'] = agenda3.pk
resp.form.submit().follow()
assert list(agenda_pricing2.agendas.all()) == [agenda3]
agenda_pricing.flat_fee_schedule = True
agenda_pricing.save()
resp = app.get('/manage/pricing/agenda-pricing/%s/agenda/add/' % agenda_pricing2.pk)
assert list(resp.context['form'].fields['agenda'].queryset) == [
agenda1,
agenda2,
]
resp.form['agenda'] = agenda1.pk
resp.form.submit()
assert list(agenda_pricing2.agendas.all()) == [agenda1, agenda3]
agenda_pricing.subscription_required = False
agenda_pricing.save()
app.get('/manage/pricing/agenda-pricing/%s/agenda/add/' % agenda_pricing.pk, status=404)
def test_agenda_pricing_delete_agenda(app, admin_user):
pricing = Pricing.objects.create(label='Model')
agenda_pricing = AgendaPricing.objects.create(
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2022, month=9, day=1),
)
agenda1 = Agenda.objects.create(label='Foo bar 1')
agenda2 = Agenda.objects.create(label='Foo bar 2')
Agenda.objects.create(label='Foo bar 3')
agenda_pricing.agendas.add(agenda1, agenda2)
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
resp = resp.click(
href='/manage/pricing/agenda-pricing/%s/agenda/%s/delete/' % (agenda_pricing.pk, agenda1.pk)
)
resp = resp.form.submit()
assert resp.location.endswith('/manage/pricing/agenda-pricing/%s/#open:agendas' % agenda_pricing.pk)
resp = resp.follow()
assert list(agenda_pricing.agendas.all()) == [agenda2]
# not linked
app.get(
'/manage/pricing/agenda-pricing/%s/agenda/%s/delete/' % (agenda_pricing.pk, agenda1.pk), status=404
)
# unknown
app.get('/manage/pricing/agenda-pricing/%s/agenda/%s/delete/' % (agenda_pricing.pk, 0), status=404)
agenda_pricing.subscription_required = False
agenda_pricing.save()
app.get(
'/manage/pricing/agenda-pricing/%s/agenda/%s/delete/' % (agenda_pricing.pk, agenda2.pk), status=404
)
def test_agenda_pricing_add_billing_date(app, admin_user):
pricing = Pricing.objects.create(label='Model')
agenda_pricing = AgendaPricing.objects.create(
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2022, month=9, day=1),
flat_fee_schedule=True,
)
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
resp = resp.click(href='/manage/pricing/agenda-pricing/%s/billing-date/add/' % agenda_pricing.pk)
resp.form['date_start'] = '2021-08-31'
resp.form['label'] = 'Foo'
resp = resp.form.submit()
assert resp.context['form'].errors['date_start'] == [
'The billing start date must be within the period of the pricing.'
]
resp.form['date_start'] = '2022-09-01'
resp = resp.form.submit()
assert resp.context['form'].errors['date_start'] == [
'The billing start date must be within the period of the pricing.'
]
resp.form['date_start'] = '2022-08-31'
resp = resp.form.submit()
assert resp.location.endswith('/manage/pricing/agenda-pricing/%s/#open:billing-dates' % agenda_pricing.pk)
assert agenda_pricing.billingdates.count() == 1
billing_date = BillingDate.objects.latest('pk')
assert billing_date.date_start == datetime.date(2022, 8, 31)
assert billing_date.label == 'Foo'
agenda_pricing.flat_fee_schedule = False
agenda_pricing.save()
app.get('/manage/pricing/agenda-pricing/%s/billing-date/add/' % agenda_pricing.pk, status=404)
def test_agenda_pricing_edit_billing_date(app, admin_user):
pricing = Pricing.objects.create(label='Model')
agenda_pricing = AgendaPricing.objects.create(
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2022, month=9, day=1),
flat_fee_schedule=True,
)
billing_date = agenda_pricing.billingdates.create(
date_start=datetime.date(year=2021, month=8, day=31),
label='Foo',
)
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
resp = resp.click(
href=r'/manage/pricing/agenda-pricing/%s/billing-date/%s/$' % (agenda_pricing.pk, billing_date.pk)
)
resp.form['label'] = 'Bar'
resp = resp.form.submit()
assert resp.context['form'].errors['date_start'] == [
'The billing start date must be within the period of the pricing.'
]
resp.form['date_start'] = '2022-09-01'
resp = resp.form.submit()
assert resp.context['form'].errors['date_start'] == [
'The billing start date must be within the period of the pricing.'
]
resp.form['date_start'] = '2022-08-31'
resp = resp.form.submit()
assert resp.location.endswith('/manage/pricing/agenda-pricing/%s/#open:billing-dates' % agenda_pricing.pk)
assert agenda_pricing.billingdates.count() == 1
billing_date.refresh_from_db()
assert billing_date.date_start == datetime.date(2022, 8, 31)
assert billing_date.label == 'Bar'
agenda_pricing.flat_fee_schedule = False
agenda_pricing.save()
app.get(
'/manage/pricing/agenda-pricing/%s/billing-date/%s/' % (agenda_pricing.pk, billing_date.pk),
status=404,
)
def test_agenda_pricing_delete_billing_date(app, admin_user):
pricing = Pricing.objects.create(label='Model')
agenda_pricing = AgendaPricing.objects.create(
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2022, month=9, day=1),
flat_fee_schedule=True,
)
billing_date1 = agenda_pricing.billingdates.create(
date_start=datetime.date(year=2021, month=9, day=1),
label='Foo',
)
billing_date2 = agenda_pricing.billingdates.create(
date_start=datetime.date(year=2021, month=9, day=1),
label='Bar',
)
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
resp = resp.click(
href='/manage/pricing/agenda-pricing/%s/billing-date/%s/delete'
% (agenda_pricing.pk, billing_date1.pk)
)
resp = resp.form.submit()
assert resp.location.endswith('/manage/pricing/agenda-pricing/%s/#open:billing-dates' % agenda_pricing.pk)
assert agenda_pricing.billingdates.count() == 1
agenda_pricing.flat_fee_schedule = False
agenda_pricing.save()
app.get(
'/manage/pricing/agenda-pricing/%s/billing-date/%s/' % (agenda_pricing.pk, billing_date2.pk),
status=404,
)
agenda_pricing2 = AgendaPricing.objects.create(
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2022, month=9, day=1),
)
app.get(
'/manage/pricing/agenda-pricing/%s/billing-date/%s/' % (agenda_pricing2.pk, billing_date2.pk),
status=404,
)
app.get('/manage/pricing/agenda-pricing/%s/billing-date/%s/' % (0, billing_date2.pk), status=404)
def test_detail_agenda_pricing_3_categories(app, admin_user):
category1 = CriteriaCategory.objects.create(label='Cat 1')
Criteria.objects.create(label='Crit 1-1', slug='crit-1-1', category=category1, order=1)
Criteria.objects.create(label='Crit 1-2', slug='crit-1-2', category=category1, order=2)
category2 = CriteriaCategory.objects.create(label='Cat 2')
Criteria.objects.create(label='Crit 2-1', slug='crit-2-1', category=category2, order=1)
Criteria.objects.create(label='Crit 2-2', slug='crit-2-2', category=category2, order=2)
Criteria.objects.create(label='Crit 2-3', slug='crit-2-3', category=category2, order=3)
category3 = CriteriaCategory.objects.create(label='Cat 3')
Criteria.objects.create(label='Crit 3-1', slug='crit-3-1', category=category3, order=1)
Criteria.objects.create(label='Crit 3-3', slug='crit-3-3', category=category3, order=3)
Criteria.objects.create(label='Crit 3-4', slug='crit-3-4', category=category3, order=4)
Criteria.objects.create(label='Crit 3-2', slug='crit-3-2', category=category3, order=2)
pricing = Pricing.objects.create(label='Foo bar')
pricing.categories.add(category1, through_defaults={'order': 1})
pricing.categories.add(category2, through_defaults={'order': 2})
pricing.categories.add(category3, through_defaults={'order': 3})
pricing.criterias.set(Criteria.objects.all())
agenda_pricing = AgendaPricing.objects.create(
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
pricing_data={
'cat-1:crit-1-1': {
'cat-2:crit-2-1': {
'cat-3:crit-3-1': 111,
'cat-3:crit-3-3': 'not-a-decimal',
'cat-3:crit-3-4': 114,
},
'cat-2:crit-2-3': {
'cat-3:crit-3-2': 132,
},
},
'cat-1:crit-1-2': {
'cat-2:crit-2-2': {
'cat-3:crit-3-3': 223,
},
},
},
)
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
assert '>Pricings - Crit 1-1</button>' in resp
ths = resp.pyquery.find('table.pricing-matrix-crit-1-1 thead th')
assert len(ths) == 4
assert ths[0].text is None
assert ths[1].text == 'Crit 2-1'
assert ths[2].text == 'Crit 2-2'
assert ths[3].text == 'Crit 2-3'
assert resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-1 th')[0].text == 'Crit 3-1'
assert resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-2 th')[0].text == 'Crit 3-2'
assert resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-3 th')[0].text == 'Crit 3-3'
assert resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-4 th')[0].text == 'Crit 3-4'
assert (
resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-1 td.pricing-cell-crit-2-1')[
0
].text
== '111.00'
)
assert (
resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-2 td.pricing-cell-crit-2-1')[
0
].text
is None
) # not defined
assert (
resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-3 td.pricing-cell-crit-2-1')[
0
].text
is None
) # wrong value
assert (
resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-4 td.pricing-cell-crit-2-1')[
0
].text
== '114.00'
)
assert (
resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-2 td.pricing-cell-crit-2-3')[
0
].text
== '132.00'
)
assert '>Pricings - Crit 1-2</button>' in resp
ths = resp.pyquery.find('table.pricing-matrix-crit-1-2 thead th')
assert len(ths) == 4
assert ths[0].text is None
assert ths[1].text == 'Crit 2-1'
assert ths[2].text == 'Crit 2-2'
assert ths[3].text == 'Crit 2-3'
assert resp.pyquery.find('table.pricing-matrix-crit-1-2 tr.pricing-row-crit-3-1 th')[0].text == 'Crit 3-1'
assert resp.pyquery.find('table.pricing-matrix-crit-1-2 tr.pricing-row-crit-3-2 th')[0].text == 'Crit 3-2'
assert resp.pyquery.find('table.pricing-matrix-crit-1-2 tr.pricing-row-crit-3-3 th')[0].text == 'Crit 3-3'
assert resp.pyquery.find('table.pricing-matrix-crit-1-2 tr.pricing-row-crit-3-4 th')[0].text == 'Crit 3-4'
assert (
resp.pyquery.find('table.pricing-matrix-crit-1-2 tr.pricing-row-crit-3-2 td.pricing-cell-crit-2-2')[
0
].text
is None
) # not defined
assert (
resp.pyquery.find('table.pricing-matrix-crit-1-2 tr.pricing-row-crit-3-3 td.pricing-cell-crit-2-2')[
0
].text
== '223.00'
)
def test_detail_agenda_pricing_2_categories(app, admin_user):
category2 = CriteriaCategory.objects.create(label='Cat 2')
Criteria.objects.create(label='Crit 2-1', slug='crit-2-1', category=category2, order=1)
Criteria.objects.create(label='Crit 2-2', slug='crit-2-2', category=category2, order=2)
Criteria.objects.create(label='Crit 2-3', slug='crit-2-3', category=category2, order=3)
category3 = CriteriaCategory.objects.create(label='Cat 3')
Criteria.objects.create(label='Crit 3-1', slug='crit-3-1', category=category3, order=1)
Criteria.objects.create(label='Crit 3-3', slug='crit-3-3', category=category3, order=3)
Criteria.objects.create(label='Crit 3-4', slug='crit-3-4', category=category3, order=4)
Criteria.objects.create(label='Crit 3-2', slug='crit-3-2', category=category3, order=2)
pricing = Pricing.objects.create(label='Foo bar')
pricing.categories.add(category2, through_defaults={'order': 1})
pricing.categories.add(category3, through_defaults={'order': 2})
pricing.criterias.set(Criteria.objects.all())
agenda_pricing = AgendaPricing.objects.create(
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
pricing_data={
'cat-2:crit-2-1': {
'cat-3:crit-3-1': 111,
'cat-3:crit-3-3': 'not-a-decimal',
'cat-3:crit-3-4': 114,
},
'cat-2:crit-2-3': {
'cat-3:crit-3-2': 132,
},
},
)
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
assert len(resp.pyquery.find('div.section.prixing-matrix h3')) == 0
ths = resp.pyquery.find('table thead th')
assert len(ths) == 4
assert ths[0].text is None
assert ths[1].text == 'Crit 2-1'
assert ths[2].text == 'Crit 2-2'
assert ths[3].text == 'Crit 2-3'
assert resp.pyquery.find('table tr.pricing-row-crit-3-1 th')[0].text == 'Crit 3-1'
assert resp.pyquery.find('table tr.pricing-row-crit-3-2 th')[0].text == 'Crit 3-2'
assert resp.pyquery.find('table tr.pricing-row-crit-3-3 th')[0].text == 'Crit 3-3'
assert resp.pyquery.find('table tr.pricing-row-crit-3-4 th')[0].text == 'Crit 3-4'
assert resp.pyquery.find('table tr.pricing-row-crit-3-1 td.pricing-cell-crit-2-1')[0].text == '111.00'
assert (
resp.pyquery.find('table tr.pricing-row-crit-3-2 td.pricing-cell-crit-2-1')[0].text is None
) # not defined
assert (
resp.pyquery.find('table tr.pricing-row-crit-3-3 td.pricing-cell-crit-2-1')[0].text is None
) # wrong value
assert resp.pyquery.find('table tr.pricing-row-crit-3-4 td.pricing-cell-crit-2-1')[0].text == '114.00'
assert resp.pyquery.find('table tr.pricing-row-crit-3-2 td.pricing-cell-crit-2-3')[0].text == '132.00'
def test_detail_agenda_pricing_1_category(app, admin_user):
category3 = CriteriaCategory.objects.create(label='Cat 3')
Criteria.objects.create(label='Crit 3-1', slug='crit-3-1', category=category3, order=1)
Criteria.objects.create(label='Crit 3-3', slug='crit-3-3', category=category3, order=3)
Criteria.objects.create(label='Crit 3-4', slug='crit-3-4', category=category3, order=4)
Criteria.objects.create(label='Crit 3-2', slug='crit-3-2', category=category3, order=2)
pricing = Pricing.objects.create(label='Foo bar')
pricing.categories.add(category3, through_defaults={'order': 3})
pricing.criterias.set(Criteria.objects.all())
agenda_pricing = AgendaPricing.objects.create(
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
pricing_data={
'cat-3:crit-3-1': 111,
'cat-3:crit-3-3': 'not-a-decimal',
'cat-3:crit-3-4': 114,
},
)
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
assert len(resp.pyquery.find('div.section.prixing-matrix h3')) == 0
ths = resp.pyquery.find('table thead')
assert len(ths) == 0
assert resp.pyquery.find('table tr.pricing-row-crit-3-1 th')[0].text == 'Crit 3-1'
assert resp.pyquery.find('table tr.pricing-row-crit-3-2 th')[0].text == 'Crit 3-2'
assert resp.pyquery.find('table tr.pricing-row-crit-3-3 th')[0].text == 'Crit 3-3'
assert resp.pyquery.find('table tr.pricing-row-crit-3-4 th')[0].text == 'Crit 3-4'
assert resp.pyquery.find('table tr.pricing-row-crit-3-1 td')[0].text == '111.00'
assert resp.pyquery.find('table tr.pricing-row-crit-3-2 td')[0].text is None # not defined
assert resp.pyquery.find('table tr.pricing-row-crit-3-3 td')[0].text is None # wrong value
assert resp.pyquery.find('table tr.pricing-row-crit-3-4 td')[0].text == '114.00'
@mock.patch('lingo.pricing.forms.get_event')
@mock.patch('lingo.pricing.forms.get_subscriptions')
@mock.patch('lingo.pricing.models.AgendaPricing.get_pricing_data_for_event')
def test_detail_agenda_pricing_test_tool_for_event(
mock_pricing_data_event, mock_subscriptions, mock_event, app, admin_user
):
agenda = Agenda.objects.create(label='Foo bar')
pricing = Pricing.objects.create(label='Foo bar')
agenda_pricing = AgendaPricing.objects.create(
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
agenda_pricing.agendas.add(agenda)
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
assert 'billing_date' not in resp.context['test_tool_form'].fields
assert 'Computed pricing data' not in resp
# check event date
mock_event.return_value = {'start_datetime': '2021-08-31T12:00:00+02:00'}
resp.form['agenda'] = agenda.pk
resp.form['event_slug'] = 'foo'
resp.form['user_external_id'] = 'user:1'
resp.form['adult_external_id'] = 'adult:1'
resp.form['booking_status'] = 'presence'
resp = resp.form.submit().follow()
assert 'Computed pricing data' not in resp
assert resp.context['test_tool_form'].errors['event_slug'] == [
'This event takes place outside the period covered by this pricing'
]
assert mock_pricing_data_event.call_args_list == []
mock_event.return_value = {'start_datetime': '2021-10-01T12:00:00+02:00'}
resp = resp.form.submit().follow()
assert 'Computed pricing data' not in resp
assert resp.context['test_tool_form'].errors['event_slug'] == [
'This event takes place outside the period covered by this pricing'
]
mock_event.return_value = {'start_datetime': '2021-09-01T12:00:00+02:00'}
# check subscriptions dates
mock_subscriptions.return_value = []
mock_event.reset_mock()
resp = resp.form.submit().follow()
assert mock_pricing_data_event.call_args_list == []
assert 'Computed pricing data' not in resp
assert resp.context['test_tool_form'].errors['user_external_id'] == [
'No subscription found for this event'
]
mock_subscriptions.return_value = [
{
'date_start': '2021-08-01',
'date_end': '2021-09-01',
},
{
'date_start': '2021-09-02',
'date_end': '2021-09-03',
},
]
resp = resp.form.submit().follow()
assert 'Computed pricing data' not in resp
assert resp.context['test_tool_form'].errors['user_external_id'] == [
'No subscription found for this event'
]
mock_subscriptions.return_value = [
{
'date_start': '2021-08-01',
'date_end': '2021-09-01',
},
{
'date_start': '2021-09-01',
'date_end': '2021-09-02',
},
{
'date_start': '2021-09-02',
'date_end': '2021-09-03',
},
]
mock_pricing_data_event.return_value = {'foo': 'bar', 'pricing': Decimal('42')}
resp = resp.form.submit().follow()
assert 'Computed pricing data' in resp
assert mock_pricing_data_event.call_args_list == [
mock.call(
request=mock.ANY,
agenda=agenda,
event={'start_datetime': '2021-09-01T12:00:00+02:00'},
subscription={'date_start': '2021-09-01', 'date_end': '2021-09-02'},
check_status={'status': 'presence', 'check_type': None},
booking={},
user_external_id='user:1',
adult_external_id='adult:1',
)
]
assert '<p>Pricing: 42.00</p>' in resp
assert '<pre>{&#39;foo&#39;: &#39;bar&#39;, &#39;pricing&#39;: Decimal(&#39;42&#39;)}</pre>' in resp
mock_pricing_data_event.side_effect = PricingError(details={'foo': 'error'})
resp = resp.form.submit().follow()
assert 'Computed pricing data' in resp
assert '&#39;error&#39;: &lt;class &#39;lingo.pricing.models.PricingError&#39;&gt;' in resp
assert '&#39;error_details&#39;: {&#39;foo&#39;: &#39;error&#39;}' in resp
@mock.patch('lingo.pricing.forms.get_event')
@mock.patch('lingo.pricing.forms.get_subscriptions')
def test_detail_agenda_pricing_test_tool_for_event_event_error(
mock_subscriptions, mock_event, app, admin_user
):
agenda = Agenda.objects.create(label='Foo bar')
pricing = Pricing.objects.create(label='Foo bar')
agenda_pricing = AgendaPricing.objects.create(
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
agenda_pricing.agendas.add(agenda)
mock_event.side_effect = ChronoError('foo bar foo-event')
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
resp.form['agenda'] = agenda.pk
resp.form['event_slug'] = 'foo-event'
resp.form['user_external_id'] = 'user:1'
resp.form['adult_external_id'] = 'adult:1'
resp.form['booking_status'] = 'presence'
resp = resp.form.submit().follow()
assert resp.context['test_tool_form'].errors['event_slug'] == ['foo bar foo-event']
@mock.patch('lingo.pricing.forms.get_event')
@mock.patch('lingo.pricing.forms.get_subscriptions')
def test_detail_agenda_pricing_test_tool_for_event_subscription_error(
mock_subscriptions, mock_event, app, admin_user
):
agenda = Agenda.objects.create(label='Foo bar')
pricing = Pricing.objects.create(label='Foo bar')
agenda_pricing = AgendaPricing.objects.create(
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
agenda_pricing.agendas.add(agenda)
mock_event.return_value = {'start_datetime': '2021-09-01T12:00:00+02:00'}
mock_subscriptions.side_effect = ChronoError('foo bar')
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
resp.form['agenda'] = agenda.pk
resp.form['event_slug'] = 'foo-bar@foo-event'
resp.form['user_external_id'] = 'user:1'
resp.form['adult_external_id'] = 'adult:1'
resp.form['booking_status'] = 'presence'
resp = resp.form.submit().follow()
assert resp.context['test_tool_form'].errors['user_external_id'] == ['foo bar']
@mock.patch('lingo.pricing.forms.get_event')
@mock.patch('lingo.pricing.forms.get_subscriptions')
@mock.patch('lingo.pricing.models.AgendaPricing.get_pricing_data_for_event')
def test_detail_agenda_pricing_test_tool_for_event_booking_status(
mock_pricing_data_event, mock_subscriptions, mock_event, app, admin_user
):
agenda = Agenda.objects.create(label='Foo bar')
pricing = Pricing.objects.create(label='Foo bar')
agenda_pricing = AgendaPricing.objects.create(
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
agenda_pricing.agendas.add(agenda)
mock_event.return_value = {'start_datetime': '2021-09-01T12:00:00+02:00'}
mock_subscriptions.return_value = [
{
'date_start': '2021-09-01',
'date_end': '2021-09-02',
},
]
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
assert resp.form['booking_status'].options == [
('presence', False, 'Presence'),
('absence', False, 'Absence'),
]
group = CheckTypeGroup.objects.create(label='Foo bar')
CheckType.objects.create(label='Foo presence reason', group=group, kind='presence')
CheckType.objects.create(label='Foo absence reason', group=group, kind='absence')
agenda.check_type_group = group
agenda.save()
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
assert resp.form['booking_status'].options == [
('presence', False, 'Presence'),
('absence', False, 'Absence'),
]
resp.form['agenda'] = agenda.pk
resp.form['event_slug'] = 'foo'
resp.form['user_external_id'] = 'user:1'
resp.form['adult_external_id'] = 'adult:1'
resp.form['booking_status'] = 'presence'
resp = resp.form.submit().follow()
assert resp.form['booking_status'].options == [
('presence', True, 'Presence'),
('presence::foo-presence-reason', False, 'Presence (Foo presence reason)'),
('absence', False, 'Absence'),
('absence::foo-absence-reason', False, 'Absence (Foo absence reason)'),
]
assert mock_pricing_data_event.call_args_list[0][1]['check_status'] == {
'check_type': None,
'status': 'presence',
}
mock_pricing_data_event.reset_mock()
resp.form['booking_status'] = 'presence::foo-presence-reason'
resp = resp.form.submit().follow()
assert mock_pricing_data_event.call_args_list[0][1]['check_status'] == {
'check_type': 'foo-presence-reason',
'status': 'presence',
}
mock_pricing_data_event.reset_mock()
resp.form['booking_status'] = 'absence'
resp = resp.form.submit().follow()
assert mock_pricing_data_event.call_args_list[0][1]['check_status'] == {
'check_type': None,
'status': 'absence',
}
mock_pricing_data_event.reset_mock()
resp.form['booking_status'] = 'absence::foo-absence-reason'
resp = resp.form.submit().follow()
assert mock_pricing_data_event.call_args_list[0][1]['check_status'] == {
'check_type': 'foo-absence-reason',
'status': 'absence',
}
@mock.patch('lingo.pricing.forms.get_subscriptions')
@mock.patch('lingo.pricing.models.AgendaPricing.get_pricing_data')
def test_detail_agenda_pricing_test_tool_for_flat_fee_schedule(
mock_pricing_data, mock_subscriptions, app, admin_user
):
agenda = Agenda.objects.create(label='Foo bar')
pricing = Pricing.objects.create(label='Foo bar')
agenda_pricing = AgendaPricing.objects.create(
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
flat_fee_schedule=True,
subscription_required=True,
)
agenda_pricing.agendas.add(agenda)
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
assert 'event_slug' not in resp.context['test_tool_form'].fields
assert 'booking_status' not in resp.context['test_tool_form'].fields
assert 'billing_date' not in resp.context['test_tool_form'].fields
assert 'Computed pricing data' not in resp
# check subscriptions dates
mock_subscriptions.return_value = []
resp.form['agenda'] = agenda.pk
resp.form['user_external_id'] = 'user:1'
resp.form['adult_external_id'] = 'adult:1'
resp = resp.form.submit().follow()
assert mock_pricing_data.call_args_list == []
assert 'Computed pricing data' not in resp
assert resp.context['test_tool_form'].errors['user_external_id'] == [
'No subscription found for this period'
]
mock_subscriptions.return_value = [
{
'date_start': '2021-08-01',
'date_end': '2021-09-01',
},
{
'date_start': '2021-10-01',
'date_end': '2021-11-01',
},
]
resp = resp.form.submit().follow()
assert 'Computed pricing data' not in resp
assert resp.context['test_tool_form'].errors['user_external_id'] == [
'No subscription found for this period'
]
mock_subscriptions.return_value = [
{
'date_start': '2021-08-01',
'date_end': '2021-09-01',
},
{
'date_start': '2021-09-02',
'date_end': '2021-09-03',
},
{
'date_start': '2021-10-01',
'date_end': '2021-11-01',
},
]
mock_pricing_data.return_value = {'foo': 'bar', 'pricing': Decimal('42')}
resp = resp.form.submit().follow()
assert 'Computed pricing data' in resp
assert mock_pricing_data.call_args_list == [
mock.call(
request=mock.ANY,
subscription={'date_start': '2021-09-02', 'date_end': '2021-09-03'},
user_external_id='user:1',
adult_external_id='adult:1',
)
]
assert '<p>Pricing: 42.00</p>' in resp
assert '<pre>{&#39;foo&#39;: &#39;bar&#39;, &#39;pricing&#39;: Decimal(&#39;42&#39;)}</pre>' in resp
mock_pricing_data.side_effect = PricingError(details={'foo': 'error'})
resp = resp.form.submit().follow()
assert 'Computed pricing data' in resp
assert '&#39;error&#39;: &lt;class &#39;lingo.pricing.models.PricingError&#39;&gt;' in resp
assert '&#39;error_details&#39;: {&#39;foo&#39;: &#39;error&#39;}' in resp
billing_date1 = agenda_pricing.billingdates.create(
date_start=datetime.date(2021, 9, 1),
label='Foo 1',
)
billing_date2 = agenda_pricing.billingdates.create(
date_start=datetime.date(2021, 9, 15),
label='Foo 2',
)
# check with billing dates
mock_pricing_data.reset_mock()
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
resp.form['agenda'] = agenda.pk
resp.form['billing_date'] = billing_date1.pk
resp.form['user_external_id'] = 'user:1'
resp.form['adult_external_id'] = 'adult:1'
resp = resp.form.submit().follow()
assert mock_pricing_data.call_args_list == [
mock.call(
request=mock.ANY,
subscription={'date_start': '2021-09-02', 'date_end': '2021-09-03'},
user_external_id='user:1',
adult_external_id='adult:1',
)
]
mock_pricing_data.reset_mock()
resp.form['billing_date'] = billing_date2.pk
resp = resp.form.submit().follow()
assert mock_pricing_data.call_args_list == []
mock_subscriptions.return_value = [
{
'date_start': '2021-09-01',
'date_end': '2021-09-15',
},
]
mock_pricing_data.reset_mock()
resp = resp.form.submit().follow()
assert mock_pricing_data.call_args_list == []
mock_subscriptions.return_value = [
{
'date_start': '2021-09-15',
'date_end': '2021-09-16',
},
]
mock_pricing_data.reset_mock()
resp = resp.form.submit().follow()
assert mock_pricing_data.call_args_list == [
mock.call(
request=mock.ANY,
subscription={'date_start': '2021-09-15', 'date_end': '2021-09-16'},
user_external_id='user:1',
adult_external_id='adult:1',
)
]
mock_subscriptions.return_value = [
{
'date_start': '2021-09-30',
'date_end': '2021-10-01',
},
]
mock_pricing_data.reset_mock()
resp = resp.form.submit().follow()
assert mock_pricing_data.call_args_list == [
mock.call(
request=mock.ANY,
subscription={'date_start': '2021-09-30', 'date_end': '2021-10-01'},
user_external_id='user:1',
adult_external_id='adult:1',
)
]
# check with subscription_required False
agenda_pricing.subscription_required = False
agenda_pricing.save()
mock_pricing_data.reset_mock()
mock_subscriptions.reset_mock()
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
assert 'agenda' not in resp.context['test_tool_form'].fields
resp.form['billing_date'] = billing_date1.pk
resp.form['user_external_id'] = 'user:1'
resp.form['adult_external_id'] = 'adult:1'
resp = resp.form.submit().follow()
assert mock_subscriptions.call_args_list == []
assert mock_pricing_data.call_args_list == [
mock.call(
request=mock.ANY,
subscription=None,
user_external_id='user:1',
adult_external_id='adult:1',
)
]
@mock.patch('lingo.pricing.forms.get_subscriptions')
def test_detail_agenda_pricing_test_tool_for_flat_fee_schedule_subscription_error(
mock_subscriptions, app, admin_user
):
agenda = Agenda.objects.create(label='Foo bar')
pricing = Pricing.objects.create(label='Foo bar')
agenda_pricing = AgendaPricing.objects.create(
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
flat_fee_schedule=True,
)
agenda_pricing.agendas.add(agenda)
mock_subscriptions.side_effect = ChronoError('foo bar')
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
resp.form['agenda'] = agenda.pk
resp.form['user_external_id'] = 'user:1'
resp.form['adult_external_id'] = 'adult:1'
resp = resp.form.submit().follow()
assert resp.context['test_tool_form'].errors['user_external_id'] == ['foo bar']
def test_edit_agenda_pricing_matrix_3_categories(app, admin_user):
category1 = CriteriaCategory.objects.create(label='Cat 1')
criteria11 = Criteria.objects.create(label='Crit 1-1', slug='crit-1-1', category=category1, order=1)
criteria12 = Criteria.objects.create(label='Crit 1-2', slug='crit-1-2', category=category1, order=2)
category2 = CriteriaCategory.objects.create(label='Cat 2')
criteria21 = Criteria.objects.create(label='Crit 2-1', slug='crit-2-1', category=category2, order=1)
Criteria.objects.create(label='Crit 2-2', slug='crit-2-2', category=category2, order=2)
Criteria.objects.create(label='Crit 2-3', slug='crit-2-3', category=category2, order=3)
category3 = CriteriaCategory.objects.create(label='Cat 3')
criteria31 = Criteria.objects.create(label='Crit 3-1', slug='crit-3-1', category=category3, order=1)
Criteria.objects.create(label='Crit 3-3', slug='crit-3-3', category=category3, order=3)
Criteria.objects.create(label='Crit 3-4', slug='crit-3-4', category=category3, order=4)
Criteria.objects.create(label='Crit 3-2', slug='crit-3-2', category=category3, order=2)
pricing = Pricing.objects.create(label='Foo bar')
pricing.categories.add(category1, through_defaults={'order': 1})
pricing.categories.add(category2, through_defaults={'order': 2})
pricing.categories.add(category3, through_defaults={'order': 3})
pricing.criterias.set(Criteria.objects.all())
agenda_pricing = AgendaPricing.objects.create(
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
pricing_data={
'cat-1:crit-1-1': {
'cat-2:crit-2-1': {
'cat-3:crit-3-1': 111,
'cat-3:crit-3-3': 'not-a-decimal',
'cat-3:crit-3-4': 114,
},
'cat-2:crit-2-3': {
'cat-3:crit-3-2': 132,
},
},
'cat-1:crit-1-2': {
'cat-2:crit-2-2': {
'cat-3:crit-3-3': 223,
},
},
},
)
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
resp = resp.click(
href='/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (agenda_pricing.pk, criteria11.slug)
)
assert resp.form['form-0-crit_0'].value == '111'
assert resp.form['form-0-crit_1'].value == ''
assert resp.form['form-0-crit_2'].value == ''
assert resp.form['form-1-crit_0'].value == ''
assert resp.form['form-1-crit_1'].value == ''
assert resp.form['form-1-crit_2'].value == '132'
assert resp.form['form-2-crit_0'].value == ''
assert resp.form['form-2-crit_1'].value == ''
assert resp.form['form-2-crit_2'].value == ''
assert resp.form['form-3-crit_0'].value == '114'
assert resp.form['form-3-crit_1'].value == ''
assert resp.form['form-3-crit_2'].value == ''
resp.form['form-0-crit_1'] = '121'
resp.form['form-0-crit_2'] = '131'
resp.form['form-1-crit_0'] = '112'
resp.form['form-1-crit_1'] = '122'
resp.form['form-1-crit_2'] = '132.5'
resp.form['form-2-crit_0'] = '113'
resp.form['form-2-crit_1'] = '123'
resp.form['form-2-crit_2'] = '133'
resp.form['form-3-crit_0'] = '914'
resp.form['form-3-crit_1'] = '124'
resp.form['form-3-crit_2'] = '134'
resp = resp.form.submit()
assert resp.location.endswith(
'/manage/pricing/agenda-pricing/%s/#open:matrix-crit-1-1' % agenda_pricing.pk
)
agenda_pricing.refresh_from_db()
assert agenda_pricing.pricing_data == {
'cat-1:crit-1-1': {
'cat-2:crit-2-1': {
'cat-3:crit-3-1': 111,
'cat-3:crit-3-2': 112,
'cat-3:crit-3-3': 113,
'cat-3:crit-3-4': 914,
},
'cat-2:crit-2-2': {
'cat-3:crit-3-1': 121,
'cat-3:crit-3-2': 122,
'cat-3:crit-3-3': 123,
'cat-3:crit-3-4': 124,
},
'cat-2:crit-2-3': {
'cat-3:crit-3-1': 131,
'cat-3:crit-3-2': 132.5,
'cat-3:crit-3-3': 133,
'cat-3:crit-3-4': 134,
},
},
'cat-1:crit-1-2': {
'cat-2:crit-2-2': {
'cat-3:crit-3-3': 223,
},
},
}
app.get(
'/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (agenda_pricing.pk, criteria12.slug),
status=200,
)
app.get('/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (0, criteria11.slug), status=404)
app.get(
'/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (agenda_pricing.pk, 'unknown'),
status=404,
)
app.get(
'/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (agenda_pricing.pk, criteria21.slug),
status=404,
)
app.get(
'/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (agenda_pricing.pk, criteria31.slug),
status=404,
)
app.get('/manage/pricing/agenda-pricing/%s/matrix/edit/' % agenda_pricing.pk, status=404)
def test_edit_agenda_pricing_matrix_2_categories(app, admin_user):
category2 = CriteriaCategory.objects.create(label='Cat 2')
criteria21 = Criteria.objects.create(label='Crit 2-1', slug='crit-2-1', category=category2, order=1)
Criteria.objects.create(label='Crit 2-2', slug='crit-2-2', category=category2, order=2)
Criteria.objects.create(label='Crit 2-3', slug='crit-2-3', category=category2, order=3)
category3 = CriteriaCategory.objects.create(label='Cat 3')
criteria31 = Criteria.objects.create(label='Crit 3-1', slug='crit-3-1', category=category3, order=1)
Criteria.objects.create(label='Crit 3-3', slug='crit-3-3', category=category3, order=3)
Criteria.objects.create(label='Crit 3-4', slug='crit-3-4', category=category3, order=4)
Criteria.objects.create(label='Crit 3-2', slug='crit-3-2', category=category3, order=2)
pricing = Pricing.objects.create(label='Foo bar')
pricing.categories.add(category2, through_defaults={'order': 1})
pricing.categories.add(category3, through_defaults={'order': 2})
pricing.criterias.set(Criteria.objects.all())
agenda_pricing = AgendaPricing.objects.create(
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
pricing_data={
'cat-2:crit-2-1': {
'cat-3:crit-3-1': 111,
'cat-3:crit-3-3': 'not-a-decimal',
'cat-3:crit-3-4': 114,
},
'cat-2:crit-2-3': {
'cat-3:crit-3-2': 132,
},
},
)
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
resp = resp.click(href='/manage/pricing/agenda-pricing/%s/matrix/edit/' % agenda_pricing.pk)
assert resp.form['form-0-crit_0'].value == '111'
assert resp.form['form-0-crit_1'].value == ''
assert resp.form['form-0-crit_2'].value == ''
assert resp.form['form-1-crit_0'].value == ''
assert resp.form['form-1-crit_1'].value == ''
assert resp.form['form-1-crit_2'].value == '132'
assert resp.form['form-2-crit_0'].value == ''
assert resp.form['form-2-crit_1'].value == ''
assert resp.form['form-2-crit_2'].value == ''
assert resp.form['form-3-crit_0'].value == '114'
assert resp.form['form-3-crit_1'].value == ''
assert resp.form['form-3-crit_2'].value == ''
resp.form['form-0-crit_1'] = '121'
resp.form['form-0-crit_2'] = '131'
resp.form['form-1-crit_0'] = '112'
resp.form['form-1-crit_1'] = '122'
resp.form['form-1-crit_2'] = '132.5'
resp.form['form-2-crit_0'] = '113'
resp.form['form-2-crit_1'] = '123'
resp.form['form-2-crit_2'] = '133'
resp.form['form-3-crit_0'] = '914'
resp.form['form-3-crit_1'] = '124'
resp.form['form-3-crit_2'] = '134'
resp = resp.form.submit()
assert resp.location.endswith('/manage/pricing/agenda-pricing/%s/#open:matrix-' % agenda_pricing.pk)
agenda_pricing.refresh_from_db()
assert agenda_pricing.pricing_data == {
'cat-2:crit-2-1': {
'cat-3:crit-3-1': 111,
'cat-3:crit-3-2': 112,
'cat-3:crit-3-3': 113,
'cat-3:crit-3-4': 914,
},
'cat-2:crit-2-2': {
'cat-3:crit-3-1': 121,
'cat-3:crit-3-2': 122,
'cat-3:crit-3-3': 123,
'cat-3:crit-3-4': 124,
},
'cat-2:crit-2-3': {
'cat-3:crit-3-1': 131,
'cat-3:crit-3-2': 132.5,
'cat-3:crit-3-3': 133,
'cat-3:crit-3-4': 134,
},
}
app.get('/manage/pricing/agenda-pricing/%s/matrix/edit/' % 0, status=404)
app.get(
'/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (agenda_pricing.pk, criteria21.slug),
status=404,
)
app.get(
'/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (agenda_pricing.pk, criteria31.slug),
status=404,
)
def test_edit_agenda_pricing_matrix_1_category(app, admin_user):
category3 = CriteriaCategory.objects.create(label='Cat 3')
criteria31 = Criteria.objects.create(label='Crit 3-1', slug='crit-3-1', category=category3, order=1)
Criteria.objects.create(label='Crit 3-3', slug='crit-3-3', category=category3, order=3)
Criteria.objects.create(label='Crit 3-4', slug='crit-3-4', category=category3, order=4)
Criteria.objects.create(label='Crit 3-2', slug='crit-3-2', category=category3, order=2)
pricing = Pricing.objects.create(label='Foo bar')
pricing.categories.add(category3, through_defaults={'order': 3})
pricing.criterias.set(Criteria.objects.all())
agenda_pricing = AgendaPricing.objects.create(
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
pricing_data={
'cat-3:crit-3-1': 111,
'cat-3:crit-3-3': 'not-a-decimal',
'cat-3:crit-3-4': 114,
},
)
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
resp = resp.click(href='/manage/pricing/agenda-pricing/%s/matrix/edit/' % agenda_pricing.pk)
assert resp.form['form-0-crit_0'].value == '111'
assert resp.form['form-1-crit_0'].value == ''
assert resp.form['form-2-crit_0'].value == ''
assert resp.form['form-3-crit_0'].value == '114'
resp.form['form-1-crit_0'] = '112.5'
resp.form['form-2-crit_0'] = '113'
resp.form['form-3-crit_0'] = '914'
resp = resp.form.submit()
assert resp.location.endswith('/manage/pricing/agenda-pricing/%s/#open:matrix-' % agenda_pricing.pk)
agenda_pricing.refresh_from_db()
assert agenda_pricing.pricing_data == {
'cat-3:crit-3-1': 111,
'cat-3:crit-3-2': 112.5,
'cat-3:crit-3-3': 113,
'cat-3:crit-3-4': 914,
}
app.get('/manage/pricing/agenda-pricing/%s/matrix/edit/' % 0, status=404)
app.get(
'/manage/pricing/agenda-pricing/%s/matrix/%s/edit/' % (agenda_pricing.pk, criteria31.slug),
status=404,
)
def test_edit_agenda_pricing_matrix_empty(app, admin_user):
pricing = Pricing.objects.create(label='Foo bar')
agenda_pricing = AgendaPricing.objects.create(
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
)
app = login(app)
app.get('/manage/pricing/agenda-pricing/%s/matrix/edit/' % agenda_pricing.pk, status=404)