pricing: flat fee schedule & overlapping (#67675)
This commit is contained in:
parent
e313095863
commit
a1eff5cb91
|
@ -187,6 +187,41 @@ class AgendaPricingForm(NewAgendaPricingForm):
|
|||
)
|
||||
return subscription_required
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super().clean()
|
||||
if (
|
||||
'date_start' in cleaned_data
|
||||
and 'date_end' in cleaned_data
|
||||
and 'flat_fee_schedule' in cleaned_data
|
||||
):
|
||||
old_date_start = self.instance.date_start
|
||||
old_date_end = self.instance.date_end
|
||||
old_flat_fee_schedule = self.instance.flat_fee_schedule
|
||||
new_date_start = cleaned_data['date_start']
|
||||
new_date_end = cleaned_data['date_end']
|
||||
new_flat_fee_schedule = cleaned_data['flat_fee_schedule']
|
||||
if (
|
||||
old_date_start != new_date_start
|
||||
or old_date_end != new_date_end
|
||||
or old_flat_fee_schedule != new_flat_fee_schedule
|
||||
):
|
||||
overlapping_qs = (
|
||||
AgendaPricing.objects.filter(flat_fee_schedule=new_flat_fee_schedule)
|
||||
.exclude(pk=self.instance.pk)
|
||||
.extra(
|
||||
where=["(date_start, date_end) OVERLAPS (%s, %s)"],
|
||||
params=[new_date_start, new_date_end],
|
||||
)
|
||||
)
|
||||
for agenda in self.instance.agendas.all():
|
||||
if overlapping_qs.filter(agendas=agenda).exists():
|
||||
self.add_error(
|
||||
None,
|
||||
_('Agenda "%s" has already a pricing overlapping this period.') % agenda.label,
|
||||
)
|
||||
|
||||
return cleaned_data
|
||||
|
||||
|
||||
class AgendaPricingAgendaAddForm(forms.Form):
|
||||
agenda = forms.ModelChoiceField(label=_('Agenda to add'), queryset=Agenda.objects.none(), required=True)
|
||||
|
@ -198,7 +233,9 @@ class AgendaPricingAgendaAddForm(forms.Form):
|
|||
|
||||
def clean_agenda(self):
|
||||
agenda = self.cleaned_data['agenda']
|
||||
overlapping_qs = AgendaPricing.objects.filter(agendas=agenda).extra(
|
||||
overlapping_qs = AgendaPricing.objects.filter(
|
||||
flat_fee_schedule=self.agenda_pricing.flat_fee_schedule, agendas=agenda
|
||||
).extra(
|
||||
where=["(date_start, date_end) OVERLAPS (%s, %s)"],
|
||||
params=[self.agenda_pricing.date_start, self.agenda_pricing.date_end],
|
||||
)
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
<div class="pk-tabs--container">
|
||||
|
||||
<div aria-labelledby="tab-pricings" id="panel-pricings" role="tabpanel" tabindex="0">
|
||||
<h3>{% trans "Pricings" context 'agenda pricing' %}</h3>
|
||||
{% if agenda_pricings %}
|
||||
<ul class="objects-list single-links">
|
||||
{% for agenda_pricing in agenda_pricings %}
|
||||
|
@ -42,6 +43,23 @@
|
|||
{% endblocktrans %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<h3>{% trans "Flat fee schedule pricings" %}</h3>
|
||||
{% if agenda_pricings_flat %}
|
||||
<ul class="objects-list single-links">
|
||||
{% for agenda_pricing in agenda_pricings_flat %}
|
||||
<li>
|
||||
<a href="{% url 'lingo-manager-agenda-pricing-detail' agenda_pricing.pk %}">{{ agenda_pricing.pricing }} ({{ agenda_pricing.date_start|date:'d/m/Y' }} - {{ agenda_pricing.date_end|date:'d/m/Y' }})</a>
|
||||
<a href="{% url 'lingo-manager-pricing-detail' agenda_pricing.pricing.pk %}" class="link-action-icon link">{% trans "see" %}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<div class="big-msg-info">
|
||||
{% blocktrans %}
|
||||
This agenda doesn't have any flat fee schedule pricing defined yet.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div aria-labelledby="tab-check" hidden="" id="panel-check" role="tabpanel" tabindex="0">
|
||||
|
|
|
@ -683,7 +683,12 @@ class AgendaDetailView(AgendaMixin, DetailView):
|
|||
|
||||
def get_context_data(self, **kwargs):
|
||||
kwargs['agenda_pricings'] = (
|
||||
AgendaPricing.objects.filter(agendas=self.agenda)
|
||||
AgendaPricing.objects.filter(agendas=self.agenda, flat_fee_schedule=False)
|
||||
.select_related('pricing')
|
||||
.order_by('date_start', 'date_end')
|
||||
)
|
||||
kwargs['agenda_pricings_flat'] = (
|
||||
AgendaPricing.objects.filter(agendas=self.agenda, flat_fee_schedule=True)
|
||||
.select_related('pricing')
|
||||
.order_by('date_start', 'date_end')
|
||||
)
|
||||
|
|
|
@ -125,6 +125,144 @@ def test_edit_agenda_pricing(app, admin_user):
|
|||
assert resp.location.endswith('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
|
||||
|
||||
|
||||
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_detail_agenda_pricing(app, admin_user):
|
||||
pricing = Pricing.objects.create(label='Model')
|
||||
agenda_pricing = AgendaPricing.objects.create(
|
||||
|
@ -209,9 +347,20 @@ def test_agenda_pricing_add_agenda(app, admin_user):
|
|||
'This agendas has already a pricing overlapping this period.'
|
||||
]
|
||||
resp.form['agenda'] = agenda3.pk
|
||||
resp = resp.form.submit().follow()
|
||||
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)
|
||||
|
|
Loading…
Reference in New Issue