pricing: adapt test tool to agendas M2M (#67196)

This commit is contained in:
Lauréline Guérin 2022-07-21 20:59:41 +02:00
parent dc39fc0b1d
commit 67d95d3bef
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
3 changed files with 67 additions and 26 deletions

View File

@ -200,7 +200,9 @@ class PricingTestToolForm(forms.Form):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request')
self.agenda_pricing = kwargs.pop('agenda_pricing')
self.agenda = self.agenda_pricing.agendas.first()
self.agenda = None
if kwargs['data'] and kwargs['data'].get('event_slug'):
self.init_agenda(kwargs['data']['event_slug'])
self.serialized_event = None
self.serialized_subscription = None
self.check_type_slug = None
@ -228,24 +230,30 @@ class PricingTestToolForm(forms.Form):
]
self.fields['booking_status'].choices = status_choices
def init_agenda(self, event_slug):
agenda_slug = event_slug.split('@')[0]
try:
self.agenda = self.agenda_pricing.agendas.get(slug=agenda_slug)
except Agenda.DoesNotExist:
pass
def clean_event_slug(self):
original_event_slug = self.cleaned_data['event_slug']
event_slug = original_event_slug
event_slug = self.cleaned_data['event_slug']
if '@' not in event_slug:
# chrono's endpoint takes event ids like '<agenda_slug>@<event_slug>'
event_slug = '%s@%s' % (self.agenda.slug, event_slug)
elif event_slug.split('@')[0] != self.agenda.slug:
raise ValidationError(_('The agenda identifier is wrong (%s)') % event_slug.split('@')[0])
raise ValidationError(_('Missing agenda identifier'))
agenda_slug = event_slug.split('@')[0]
if not self.agenda:
raise ValidationError(_('The agenda identifier is wrong (%s)') % agenda_slug)
try:
self.serialized_event = get_event(event_slug)
except ChronoError as e:
raise forms.ValidationError(str(e).replace(event_slug, original_event_slug))
raise forms.ValidationError(e)
event_date = datetime.datetime.fromisoformat(self.serialized_event['start_datetime']).date()
if event_date < self.agenda_pricing.date_start or event_date >= self.agenda_pricing.date_end:
raise ValidationError(_('This event takes place outside the period covered by this pricing'))
return original_event_slug
return event_slug
def clean_booking_status(self):
original_booking_status = self.cleaned_data['booking_status']

View File

@ -22,7 +22,7 @@
{% endblock %}
{% block content %}
{% with iter_matrix=object.iter_pricing_matrix|list %}
{% with iter_matrix=object.iter_pricing_matrix|list agendas=object.agendas.all %}
<div class="section">
<div class="pk-tabs">
<div class="pk-tabs--tab-list" role="tablist">
@ -46,7 +46,7 @@
<div aria-labelledby="tab-agendas" hidden id="panel-agendas" role="tabpanel" tabindex="0">
<ul class="objects-list single-links">
{% for agenda in object.agendas.all %}
{% for agenda in agendas %}
<li>
<a href="{% url 'lingo-manager-agenda-detail' pk=agenda.pk %}">
{{ agenda.label }}
@ -63,6 +63,41 @@
<div aria-labelledby="tab-debug" hidden id="panel-debug" role="tabpanel" tabindex="0">
<form method="get" enctype="multipart/form-data" action="{% url 'lingo-manager-agenda-pricing-test-tool' object.pk %}">
{{ test_tool_form.as_p }}
<script>
$(function() {
var presences = {};
var absences = {};
{% for agenda in agendas %}
presences['{{ agenda.slug }}'] = [];
absences['{{ agenda.slug }}'] = [];
{% for check_type in agenda.check_type_group.check_types.all %}
{% if check_type.kind == "presence" %}
presences['{{ agenda.slug }}'].push({slug: '{{ check_type.slug }}', label: '{{ check_type.label }}'});
{% else %}
absences['{{ agenda.slug }}'].push({slug: '{{ check_type.slug }}', label: '{{ check_type.label }}'});
{% endif %}
{% endfor %}
{% endfor %}
$('#id_event_slug').on('change', function() {
var agenda_slug = $(this).val().split('@')[0];
var $select = $('#id_booking_status');
var current_value = $select.val();
$select.find('option').remove().end().append('<option value="presence">' + '{% trans "Presence" %}' + '</option>');
if (presences[agenda_slug]) {
$.each(presences[agenda_slug], function(index, value) {
$select.append('<option value="presence::' + value.slug + '">' + '{% trans "Presence" %} (' + value.label + ')</option>');
});
}
$select.append('<option value="absence">' + '{% trans "Absence" %}' + '</option>');
if (absences[agenda_slug]) {
$.each(absences[agenda_slug], function(index, value) {
$select.append('<option value="absence::' + value.slug + '">' + '{% trans "Absence" %} (' + value.label + ')</option>');
});
}
$select.val(current_value);
});
});
</script>
<div class="buttons">
<button class="submit-button">{% trans "Compute" %}</button>
</div>

View File

@ -422,7 +422,7 @@ def test_detail_agenda_pricing_test_tool(mock_pricing_data, mock_subscriptions,
# check event date
mock_event.return_value = {'start_datetime': '2021-08-31T12:00:00+02:00'}
resp.form['event_slug'] = 'foo'
resp.form['event_slug'] = 'foo-bar@foo'
resp.form['user_external_id'] = 'user:1'
resp.form['adult_external_id'] = 'adult:1'
resp.form['booking_status'] = 'presence'
@ -431,7 +431,6 @@ def test_detail_agenda_pricing_test_tool(mock_pricing_data, mock_subscriptions,
assert resp.context['test_tool_form'].errors['event_slug'] == [
'This event takes place outside the period covered by this pricing'
]
assert mock_event.call_args_list == [mock.call('foo-bar@foo')]
assert mock_pricing_data.call_args_list == []
mock_event.return_value = {'start_datetime': '2021-10-01T12:00:00+02:00'}
resp = resp.form.submit().follow()
@ -443,6 +442,9 @@ def test_detail_agenda_pricing_test_tool(mock_pricing_data, mock_subscriptions,
mock_event.return_value = {'start_datetime': '2021-09-01T12:00:00+02:00'}
# check event_slug & agenda
resp.form['event_slug'] = 'foo'
resp = resp.form.submit().follow()
assert resp.context['test_tool_form'].errors['event_slug'] == ['Missing agenda identifier']
resp.form['event_slug'] = 'foo@foo'
resp = resp.form.submit().follow()
assert resp.context['test_tool_form'].errors['event_slug'] == ['The agenda identifier is wrong (foo)']
@ -452,7 +454,6 @@ def test_detail_agenda_pricing_test_tool(mock_pricing_data, mock_subscriptions,
mock_event.reset_mock()
resp.form['event_slug'] = 'foo-bar@foo'
resp = resp.form.submit().follow()
assert mock_event.call_args_list == [mock.call('foo-bar@foo')]
assert mock_pricing_data.call_args_list == []
assert 'Computed pricing data' not in resp
assert resp.context['test_tool_form'].errors['user_external_id'] == [
@ -530,17 +531,10 @@ def test_detail_agenda_pricing_test_tool_event_error(mock_subscriptions, mock_ev
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
resp.form['event_slug'] = 'foo-event'
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'
# agenda slug is removed from error message
resp = resp.form.submit().follow()
assert resp.context['test_tool_form'].errors['event_slug'] == ['foo bar foo-event']
# except it was included in event_slug
resp.form['event_slug'] = 'foo-bar@foo-event'
resp = resp.form.submit().follow()
assert resp.context['test_tool_form'].errors['event_slug'] == ['foo bar foo-bar@foo-event']
@ -562,7 +556,7 @@ def test_detail_agenda_pricing_test_tool_subscription_error(mock_subscriptions,
app = login(app)
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
resp.form['event_slug'] = 'foo-event'
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'
@ -609,15 +603,19 @@ def test_detail_agenda_pricing_test_tool_booking_status(
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
assert resp.form['booking_status'].options == [
('presence', False, 'Presence'),
('presence::foo-presence-reason', False, 'Presence (Foo presence reason)'),
('absence', False, 'Absence'),
('absence::foo-absence-reason', False, 'Absence (Foo absence reason)'),
]
resp.form['event_slug'] = 'foo'
resp.form['event_slug'] = 'foo-bar@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.call_args_list[0][1]['check_status'] == {
'check_type': None,
'status': 'presence',