pricing: use sidetabs on agenda, pricing & agenda pricing pages (#67196)
This commit is contained in:
parent
2f66bc9e1a
commit
0c4ae4e39b
|
@ -22,6 +22,7 @@ from .models import Agenda
|
|||
|
||||
class AgendaMixin:
|
||||
agenda = None
|
||||
tab_anchor = None
|
||||
|
||||
def set_agenda(self, **kwargs):
|
||||
self.agenda = get_object_or_404(Agenda, id=kwargs.get('pk'))
|
||||
|
@ -43,4 +44,7 @@ class AgendaMixin:
|
|||
return kwargs
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('lingo-manager-agenda-detail', kwargs={'pk': self.agenda.pk})
|
||||
url = reverse('lingo-manager-agenda-detail', kwargs={'pk': self.agenda.pk})
|
||||
if self.tab_anchor:
|
||||
url += '#open:%s' % self.tab_anchor
|
||||
return url
|
||||
|
|
|
@ -94,3 +94,12 @@ div.test-tool-result .infonotice h3 {
|
|||
margin-top: 0;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.pk-tabs--container {
|
||||
& > div {
|
||||
padding: 1ex;
|
||||
.panel--buttons a.button {
|
||||
line-height: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,4 +31,12 @@ $(function() {
|
|||
});
|
||||
}
|
||||
});
|
||||
|
||||
/* focus tab from #open:<tab slug> anchor, to point to open panel */
|
||||
if (document.location.hash && document.location.hash.indexOf('#open:') == 0) {
|
||||
const $tab_button = $('#tab-' + document.location.hash.substring(6) + '[role=tab]');
|
||||
if ($tab_button.length) {
|
||||
$('.pk-tabs')[0].tabs.selectTab($tab_button[0]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -18,60 +18,67 @@
|
|||
|
||||
{% block content %}
|
||||
<div class="section">
|
||||
<h3>{% trans "Pricing" context 'pricing' %}</h3>
|
||||
<div>
|
||||
{% if agenda_pricings %}
|
||||
<ul class="objects-list single-links">
|
||||
{% for agenda_pricing in agenda_pricings %}
|
||||
<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 pricing defined yet.
|
||||
{% endblocktrans %}
|
||||
<div class="pk-tabs">
|
||||
<div class="pk-tabs--tab-list" role="tablist">
|
||||
<button aria-controls="panel-pricings" aria-selected="true" id="tab-pricings" role="tab" tabindex="0">{% trans "Pricings" context 'agenda pricing' %}</button>
|
||||
<button aria-controls="panel-check" aria-selected="false" id="tab-check" role="tab" tabindex="-1">{% trans "Booking check options" %}</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="pk-tabs--container">
|
||||
|
||||
<div class="section">
|
||||
<h3>{% trans "Booking check options" %}
|
||||
<a rel="popup" class="button" href="{% url 'lingo-manager-agenda-booking-check-settings' pk=object.pk %}">{% trans 'Configure' %}</a>
|
||||
</h3>
|
||||
<div>
|
||||
<ul>
|
||||
{% if agenda.check_type_group %}
|
||||
<li>{% trans "Check type group:" %} {{ agenda.check_type_group }}
|
||||
<ul>
|
||||
<li>{% trans "Absences:" %}
|
||||
<ul>
|
||||
{% for check_type in agenda.check_type_group.check_types.absences %}
|
||||
<li>{{ check_type }}</li>
|
||||
{% empty %}
|
||||
<li>({% trans "No absence check type defined" %})</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
<li>{% trans "Presences:" %}
|
||||
<ul>
|
||||
{% for check_type in agenda.check_type_group.check_types.presences %}
|
||||
<li>{{ check_type }}</li>
|
||||
{% empty %}
|
||||
<li>({% trans "No presence check type defined" %})</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
{% else %}
|
||||
<li>{% trans "No check types configured for this agenda." %}</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
<div aria-labelledby="tab-pricings" id="panel-pricings" role="tabpanel" tabindex="0">
|
||||
{% if agenda_pricings %}
|
||||
<ul class="objects-list single-links">
|
||||
{% for agenda_pricing in agenda_pricings %}
|
||||
<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 pricing defined yet.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div aria-labelledby="tab-check" hidden="" id="panel-check" role="tabpanel" tabindex="0">
|
||||
<ul>
|
||||
{% if agenda.check_type_group %}
|
||||
<li>{% trans "Check type group:" %} {{ agenda.check_type_group }}
|
||||
<ul>
|
||||
<li>{% trans "Absences:" %}
|
||||
<ul>
|
||||
{% for check_type in agenda.check_type_group.check_types.absences %}
|
||||
<li>{{ check_type }}</li>
|
||||
{% empty %}
|
||||
<li>({% trans "No absence check type defined" %})</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
<li>{% trans "Presences:" %}
|
||||
<ul>
|
||||
{% for check_type in agenda.check_type_group.check_types.presences %}
|
||||
<li>{{ check_type }}</li>
|
||||
{% empty %}
|
||||
<li>({% trans "No presence check type defined" %})</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
{% else %}
|
||||
<li>{% trans "No check types configured for this agenda." %}</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
<div class="panel--buttons">
|
||||
<a rel="popup" class="button" href="{% url 'lingo-manager-agenda-booking-check-settings' pk=object.pk %}">{% trans 'Configure' %}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -22,71 +22,83 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% with iter_matrix=object.iter_pricing_matrix|list %}
|
||||
<div class="section">
|
||||
<h3>{% trans "Options" %}</h3>
|
||||
<div>
|
||||
<ul>
|
||||
<li>{% trans "Pricing model:" %} <a href="{% url 'lingo-manager-pricing-detail' object.pricing.pk %}">{{ object.pricing }}</a></li>
|
||||
<li>{% blocktrans with start=object.date_start|date:'d/m/Y' end=object.date_end|date:'d/m/Y' %}From {{ start }} to {{ end }}{% endblocktrans %}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h3>{% trans "Test tool" %}</h3>
|
||||
<div>
|
||||
<form method="get" enctype="multipart/form-data">
|
||||
{{ test_tool_form.as_p }}
|
||||
<div class="buttons">
|
||||
<button class="submit-button">{% trans "Compute" %}</button>
|
||||
</div>
|
||||
</form>
|
||||
{% if request.GET and test_tool_form.is_valid %}
|
||||
{% with test_tool_form.compute as pricing_data %}
|
||||
<div class="test-tool-result">
|
||||
<div class="infonotice">
|
||||
<h3>{% trans "Computed pricing data" %}</h3>
|
||||
{% if pricing_data.pricing is not None %}<p>{% trans "Pricing:" %} {{ pricing_data.pricing|stringformat:".2f" }}</p>{% endif %}
|
||||
<pre>{{ pricing_data|pprint }}</pre>
|
||||
</div>
|
||||
<div class="pk-tabs">
|
||||
<div class="pk-tabs--tab-list" role="tablist">
|
||||
<button aria-controls="panel-options" aria-selected="true" id="tab-options" role="tab" tabindex="0">{% trans "Options" %}</button>
|
||||
<button aria-controls="panel-debug" aria-selected="false" id="tab-debug" role="tab" tabindex="0">{% trans "Test tool" %}</button>
|
||||
{% for matrix in iter_matrix %}
|
||||
<button aria-controls="panel-matrix-{{ matrix.criteria.slug }}" aria-selected="false" id="tab-matrix-{{ matrix.criteria.slug }}" role="tab" tabindex="-1">{% trans "Pricings" context 'amount' %}{% if matrix.criteria %} - {{ matrix.criteria.label }}{% endif %}</button>
|
||||
{% empty %}
|
||||
<button aria-controls="panel-matrix" aria-selected="false" id="tab-matrix" role="tab" tabindex="-1">{% trans "Pricings" context 'amount' %}</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="pk-tabs--container">
|
||||
|
||||
<div aria-labelledby="tab-options" id="panel-options" role="tabpanel" tabindex="0">
|
||||
<ul>
|
||||
<li>{% trans "Pricing model:" %} <a href="{% url 'lingo-manager-pricing-detail' object.pricing.pk %}">{{ object.pricing }}</a></li>
|
||||
<li>{% blocktrans with start=object.date_start|date:'d/m/Y' end=object.date_end|date:'d/m/Y' %}From {{ start }} to {{ end }}{% endblocktrans %}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<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 }}
|
||||
<div class="buttons">
|
||||
<button class="submit-button">{% trans "Compute" %}</button>
|
||||
</div>
|
||||
</form>
|
||||
{% if request.GET and test_tool_form.is_valid %}
|
||||
{% with test_tool_form.compute as pricing_data %}
|
||||
<div class="test-tool-result">
|
||||
<div class="infonotice">
|
||||
<h3>{% trans "Computed pricing data" %}</h3>
|
||||
{% if pricing_data.pricing is not None %}<p>{% trans "Pricing:" %} {{ pricing_data.pricing|stringformat:".2f" }}</p>{% endif %}
|
||||
<pre>{{ pricing_data|pprint }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% for matrix in object.iter_pricing_matrix %}
|
||||
<div class="section pricing-matrix">
|
||||
{% if matrix.criteria %}<h3>{{ matrix.criteria.label }}</h3>{% endif %}
|
||||
<div>
|
||||
<table class="main pricing-matrix-{{ matrix.criteria.slug }}">
|
||||
{% if matrix.rows.0.cells.0.criteria %}
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
{% for cell in matrix.rows.0.cells %}<th scope="col">{{ cell.criteria.label }}</th>{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
{% endif %}
|
||||
<tbody>
|
||||
{% for row in matrix.rows %}
|
||||
<tr class="pricing-row-{{ row.criteria.slug }}">
|
||||
<th scope="row">{{ row.criteria.label }}</th>
|
||||
{% for cell in row.cells %}<td class="pricing-cell-{{ cell.criteria.slug }}">{{ cell.value|floatformat:"2"|default_if_none:"" }}</td>{% endfor %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<p>
|
||||
<a class="pk-button" href="{% if matrix.criteria %}{% url 'lingo-manager-agenda-pricing-matrix-slug-edit' object.pk matrix.criteria.slug %}{% else %}{% url 'lingo-manager-agenda-pricing-matrix-edit' object.pk %}{% endif %}">{% trans "Edit pricing" %}</a>
|
||||
</p>
|
||||
{% for matrix in iter_matrix %}
|
||||
<div aria-labelledby="tab-matrix-{{ matrix.criteria.slug }}" hidden="" id="panel-matrix-{{ matrix.criteria.slug }}" role="tabpanel" tabindex="0">
|
||||
<table class="main pricing-matrix-{{ matrix.criteria.slug }}">
|
||||
{% if matrix.rows.0.cells.0.criteria %}
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
{% for cell in matrix.rows.0.cells %}<th scope="col">{{ cell.criteria.label }}</th>{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
{% endif %}
|
||||
<tbody>
|
||||
{% for row in matrix.rows %}
|
||||
<tr class="pricing-row-{{ row.criteria.slug }}">
|
||||
<th scope="row">{{ row.criteria.label }}</th>
|
||||
{% for cell in row.cells %}<td class="pricing-cell-{{ cell.criteria.slug }}">{{ cell.value|floatformat:"2"|default_if_none:"" }}</td>{% endfor %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="panel--buttons">
|
||||
<a class="pk-button" href="{% if matrix.criteria %}{% url 'lingo-manager-agenda-pricing-matrix-slug-edit' object.pk matrix.criteria.slug %}{% else %}{% url 'lingo-manager-agenda-pricing-matrix-edit' object.pk %}{% endif %}">{% trans "Edit pricing" %}</a>
|
||||
</div>
|
||||
</div>
|
||||
{% empty %}
|
||||
<div aria-labelledby="tab-matrix" hidden="" id="panel-matrix" role="tabpanel" tabindex="0">
|
||||
<div class="big-msg-info">
|
||||
{% blocktrans %}
|
||||
This pricing model is misconfigured.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% empty %}
|
||||
<div class="big-msg-info">
|
||||
{% blocktrans %}
|
||||
This pricing model is misconfigured.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endwith %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -24,74 +24,79 @@
|
|||
|
||||
{% block content %}
|
||||
<div class="section">
|
||||
<h3>{% trans "Variables" %}</h3>
|
||||
|
||||
<div>
|
||||
{% if object.extra_variables %}
|
||||
<p>
|
||||
<label>{% trans 'Extra variables:' %}</label>
|
||||
{% for key in object.get_extra_variables_keys %}<i>{{ key }}</i>{% if not forloop.last %}, {% endif %}{% endfor %}
|
||||
</p>
|
||||
{% endif %}
|
||||
<a class="pk-button" rel="popup" href="{% url 'lingo-manager-pricing-variable-edit' pk=object.pk %}">{% trans 'Define variables' %}</a>
|
||||
<div class="pk-tabs">
|
||||
<div class="pk-tabs--tab-list" role="tablist">
|
||||
<button aria-controls="panel-variables" aria-selected="true" id="tab-variables" role="tab" tabindex="0">{% trans "Variables" %}</button>
|
||||
<button aria-controls="panel-criterias" aria-selected="false" id="tab-criterias" role="tab" tabindex="-1">{% trans "Criterias" %}</button>
|
||||
<button aria-controls="panel-usage" aria-selected="false" id="tab-usage" role="tab" tabindex="-1">{% trans "Used in agendas" %}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pk-tabs--container">
|
||||
|
||||
<div class="section">
|
||||
<h3>{% trans "Criterias" %}</h3>
|
||||
{% with criterias=object.criterias.all categories=object.categories.all %}
|
||||
{% if categories %}
|
||||
<div>
|
||||
{% blocktrans %}Use drag and drop with the ⣿ handles to reorder categories.{% endblocktrans %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="sortable" data-order-url="{% url 'lingo-manager-pricing-criteria-category-order' object.pk %}">
|
||||
{% for category in categories %}
|
||||
<div class="paragraph sortable-item" data-item-id="{{ category.pk }}">
|
||||
<h4><span class="handle">⣿</span>{% trans "Category:" %} {{ category }}</h4>
|
||||
<p>{% trans "Selected criterias:" %}</p>
|
||||
<ul>
|
||||
{% for criteria in criterias %}
|
||||
{% if criteria.category == category %}
|
||||
<li>{{ criteria }}</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<p>
|
||||
<a rel="popup" class="pk-button" href="{% url 'lingo-manager-pricing-criteria-category-edit' pk=object.pk category_pk=category.pk %}">{% trans "Change criterias selection" %}</a>
|
||||
<a rel="popup" class="pk-button" href="{% url 'lingo-manager-pricing-criteria-category-delete' pk=object.pk category_pk=category.pk %}">{% trans "Remove this category" %}</a>
|
||||
</p>
|
||||
<div aria-labelledby="tab-variables" id="panel-variables" role="tabpanel" tabindex="0">
|
||||
{% if object.extra_variables %}
|
||||
<label>{% trans 'Extra variables:' %}</label>
|
||||
{% for key in object.get_extra_variables_keys %}<i>{{ key }}</i>{% if not forloop.last %}, {% endif %}{% endfor %}
|
||||
{% endif %}
|
||||
<div class="panel--buttons">
|
||||
<a class="pk-button" rel="popup" href="{% url 'lingo-manager-pricing-variable-edit' pk=object.pk %}">{% trans 'Define variables' %}</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% if object.categories.count < 3 %}
|
||||
<p>
|
||||
<a rel="popup" class="pk-button" href="{% url 'lingo-manager-pricing-criteria-category-add' pk=object.pk %}">{% trans "Add a category" %} <span class="extra-info">({% trans "max 3 categories" %})</span></a>
|
||||
</p>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
<div aria-labelledby="tab-criterias" hidden="" id="panel-criterias" role="tabpanel" tabindex="0">
|
||||
{% with criterias=object.criterias.all categories=object.categories.all %}
|
||||
{% if categories %}
|
||||
<div>
|
||||
{% blocktrans %}Use drag and drop with the ⣿ handles to reorder categories.{% endblocktrans %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="sortable" data-order-url="{% url 'lingo-manager-pricing-criteria-category-order' object.pk %}">
|
||||
{% for category in categories %}
|
||||
<div class="paragraph sortable-item" data-item-id="{{ category.pk }}">
|
||||
<h4><span class="handle">⣿</span>{% trans "Category:" %} {{ category }}</h4>
|
||||
<p>{% trans "Selected criterias:" %}</p>
|
||||
<ul>
|
||||
{% for criteria in criterias %}
|
||||
{% if criteria.category == category %}
|
||||
<li>{{ criteria }}</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<p>
|
||||
<a rel="popup" class="pk-button" href="{% url 'lingo-manager-pricing-criteria-category-edit' pk=object.pk category_pk=category.pk %}">{% trans "Change criterias selection" %}</a>
|
||||
<a rel="popup" class="pk-button" href="{% url 'lingo-manager-pricing-criteria-category-delete' pk=object.pk category_pk=category.pk %}">{% trans "Remove this category" %}</a>
|
||||
</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% if object.categories.count < 3 %}
|
||||
<div class="panel--buttons">
|
||||
<a rel="popup" class="pk-button" href="{% url 'lingo-manager-pricing-criteria-category-add' pk=object.pk %}">{% trans "Add a category" %} <span class="extra-info">({% trans "max 3 categories" %})</span></a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endwith %}
|
||||
</div>
|
||||
|
||||
<div aria-labelledby="tab-usage" hidden="" id="panel-usage" role="tabpanel" tabindex="0">
|
||||
{% if agendas %}
|
||||
<ul class="objects-list single-links">
|
||||
{% for agenda in agendas %}
|
||||
<li>
|
||||
<a href="{% url 'lingo-manager-agenda-detail' pk=agenda.pk %}">
|
||||
{{ agenda.label }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<div class="big-msg-info">
|
||||
{% blocktrans %}
|
||||
This Pricing model is not used yet.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h3>{% trans "Used in agendas" %}</h3>
|
||||
<div>
|
||||
{% if agendas %}
|
||||
<ul class="objects-list single-links">
|
||||
{% for agenda in agendas %}
|
||||
<li>
|
||||
<a href="{% url 'lingo-manager-agenda-detail' pk=agenda.pk %}">
|
||||
{{ agenda.label }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<div class="big-msg-info">
|
||||
{% blocktrans %}
|
||||
This Pricing model is not used yet.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -183,6 +183,11 @@ urlpatterns = [
|
|||
views.agenda_pricing_export,
|
||||
name='lingo-manager-agenda-pricing-export',
|
||||
),
|
||||
url(
|
||||
r'^agenda-pricing/(?P<pk>\d+)/test-tool/$',
|
||||
views.agenda_pricing_test_tool,
|
||||
name='lingo-manager-agenda-pricing-test-tool',
|
||||
),
|
||||
url(
|
||||
r'^agenda-pricing/(?P<pk>\d+)/matrix/edit/$',
|
||||
views.agenda_pricing_matrix_edit,
|
||||
|
|
|
@ -426,7 +426,7 @@ class PricingCriteriaCategoryAddView(FormView):
|
|||
return super().form_valid(form)
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('lingo-manager-pricing-detail', args=[self.object.pk])
|
||||
return '%s#open:criterias' % reverse('lingo-manager-pricing-detail', args=[self.object.pk])
|
||||
|
||||
|
||||
pricing_criteria_category_add = PricingCriteriaCategoryAddView.as_view()
|
||||
|
@ -462,7 +462,7 @@ class PricingCriteriaCategoryEditView(FormView):
|
|||
return super().form_valid(form)
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('lingo-manager-pricing-detail', args=[self.object.pk])
|
||||
return '%s#open:criterias' % reverse('lingo-manager-pricing-detail', args=[self.object.pk])
|
||||
|
||||
|
||||
pricing_criteria_category_edit = PricingCriteriaCategoryEditView.as_view()
|
||||
|
@ -487,7 +487,7 @@ class PricingCriteriaCategoryDeleteView(DeleteView):
|
|||
return HttpResponseRedirect(self.get_success_url())
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('lingo-manager-pricing-detail', args=[self.pricing.pk])
|
||||
return '%s#open:criterias' % reverse('lingo-manager-pricing-detail', args=[self.pricing.pk])
|
||||
|
||||
|
||||
pricing_criteria_category_delete = PricingCriteriaCategoryDeleteView.as_view()
|
||||
|
@ -721,6 +721,7 @@ class AgendaBookingCheckSettingsView(AgendaMixin, UpdateView):
|
|||
template_name = 'lingo/pricing/manager_agenda_form.html'
|
||||
model = Agenda
|
||||
fields = ['check_type_group']
|
||||
tab_anchor = 'check'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
@ -775,6 +776,17 @@ class AgendaPricingDetailView(DetailView):
|
|||
agenda_pricing_detail = AgendaPricingDetailView.as_view()
|
||||
|
||||
|
||||
class AgendaPricingTestToolView(RedirectView):
|
||||
def get_redirect_url(self, *args, **kwargs):
|
||||
return '%s?%s#open:debug' % (
|
||||
reverse('lingo-manager-agenda-pricing-detail', args=[kwargs['pk']]),
|
||||
self.request.GET.urlencode(),
|
||||
)
|
||||
|
||||
|
||||
agenda_pricing_test_tool = AgendaPricingTestToolView.as_view()
|
||||
|
||||
|
||||
class AgendaPricingEditView(UpdateView):
|
||||
template_name = 'lingo/pricing/manager_agenda_pricing_form.html'
|
||||
model = AgendaPricing
|
||||
|
@ -888,7 +900,10 @@ class AgendaPricingMatrixEdit(FormView):
|
|||
return self.form_invalid(form)
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('lingo-manager-agenda-pricing-detail', args=[self.object.pk])
|
||||
return '%s#open:matrix-%s' % (
|
||||
reverse('lingo-manager-agenda-pricing-detail', args=[self.object.pk]),
|
||||
self.kwargs.get('slug') or '',
|
||||
)
|
||||
|
||||
|
||||
agenda_pricing_matrix_edit = AgendaPricingMatrixEdit.as_view()
|
||||
|
|
|
@ -161,7 +161,7 @@ def test_detail_agenda_pricing_3_categories(app, admin_user):
|
|||
|
||||
app = login(app)
|
||||
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
|
||||
assert '<h3>Crit 1-1</h3>' in resp
|
||||
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
|
||||
|
@ -202,7 +202,7 @@ def test_detail_agenda_pricing_3_categories(app, admin_user):
|
|||
].text
|
||||
== '132.00'
|
||||
)
|
||||
assert '<h3>Crit 1-2</h3>' in resp
|
||||
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
|
||||
|
@ -341,7 +341,7 @@ def test_detail_agenda_pricing_test_tool(mock_pricing_data, mock_subscriptions,
|
|||
resp.form['user_external_id'] = 'user:1'
|
||||
resp.form['adult_external_id'] = 'adult:1'
|
||||
resp.form['booking_status'] = 'presence'
|
||||
resp = resp.form.submit()
|
||||
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'
|
||||
|
@ -349,7 +349,7 @@ def test_detail_agenda_pricing_test_tool(mock_pricing_data, mock_subscriptions,
|
|||
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()
|
||||
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'
|
||||
|
@ -359,14 +359,14 @@ def test_detail_agenda_pricing_test_tool(mock_pricing_data, mock_subscriptions,
|
|||
|
||||
# check event_slug & agenda
|
||||
resp.form['event_slug'] = 'foo@foo'
|
||||
resp = resp.form.submit()
|
||||
resp = resp.form.submit().follow()
|
||||
assert resp.context['test_tool_form'].errors['event_slug'] == ['The agenda identifier is wrong (foo)']
|
||||
|
||||
# check subscriptions dates
|
||||
mock_subscriptions.return_value = []
|
||||
mock_event.reset_mock()
|
||||
resp.form['event_slug'] = 'foo-bar@foo'
|
||||
resp = resp.form.submit()
|
||||
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
|
||||
|
@ -384,7 +384,7 @@ def test_detail_agenda_pricing_test_tool(mock_pricing_data, mock_subscriptions,
|
|||
'date_end': '2021-09-03',
|
||||
},
|
||||
]
|
||||
resp = resp.form.submit()
|
||||
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'
|
||||
|
@ -405,7 +405,7 @@ def test_detail_agenda_pricing_test_tool(mock_pricing_data, mock_subscriptions,
|
|||
},
|
||||
]
|
||||
mock_pricing_data.return_value = {'foo': 'bar', 'pricing': Decimal('42')}
|
||||
resp = resp.form.submit()
|
||||
resp = resp.form.submit().follow()
|
||||
assert 'Computed pricing data' in resp
|
||||
assert mock_pricing_data.call_args_list == [
|
||||
mock.call(
|
||||
|
@ -424,7 +424,7 @@ def test_detail_agenda_pricing_test_tool(mock_pricing_data, mock_subscriptions,
|
|||
assert '<pre>{'foo': 'bar', 'pricing': Decimal('42')}</pre>' in resp
|
||||
|
||||
mock_pricing_data.side_effect = PricingError(details={'foo': 'error'})
|
||||
resp = resp.form.submit()
|
||||
resp = resp.form.submit().follow()
|
||||
assert 'Computed pricing data' in resp
|
||||
assert '<pre>{'error': {'foo': 'error'}}</pre>' in resp
|
||||
|
||||
|
@ -451,12 +451,12 @@ def test_detail_agenda_pricing_test_tool_event_error(mock_subscriptions, mock_ev
|
|||
resp.form['booking_status'] = 'presence'
|
||||
|
||||
# agenda slug is removed from error message
|
||||
resp = resp.form.submit()
|
||||
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()
|
||||
resp = resp.form.submit().follow()
|
||||
assert resp.context['test_tool_form'].errors['event_slug'] == ['foo bar foo-bar@foo-event']
|
||||
|
||||
|
||||
|
@ -481,7 +481,7 @@ def test_detail_agenda_pricing_test_tool_subscription_error(mock_subscriptions,
|
|||
resp.form['user_external_id'] = 'user:1'
|
||||
resp.form['adult_external_id'] = 'adult:1'
|
||||
resp.form['booking_status'] = 'presence'
|
||||
resp = resp.form.submit()
|
||||
resp = resp.form.submit().follow()
|
||||
assert resp.context['test_tool_form'].errors['user_external_id'] == ['foo bar']
|
||||
|
||||
|
||||
|
@ -532,7 +532,7 @@ def test_detail_agenda_pricing_test_tool_booking_status(
|
|||
resp.form['user_external_id'] = 'user:1'
|
||||
resp.form['adult_external_id'] = 'adult:1'
|
||||
resp.form['booking_status'] = 'presence'
|
||||
resp = resp.form.submit()
|
||||
resp = resp.form.submit().follow()
|
||||
assert mock_pricing_data.call_args_list[0][1]['check_status'] == {
|
||||
'check_type': None,
|
||||
'status': 'presence',
|
||||
|
@ -540,7 +540,7 @@ def test_detail_agenda_pricing_test_tool_booking_status(
|
|||
|
||||
mock_pricing_data.reset_mock()
|
||||
resp.form['booking_status'] = 'presence::foo-presence-reason'
|
||||
resp = resp.form.submit()
|
||||
resp = resp.form.submit().follow()
|
||||
assert mock_pricing_data.call_args_list[0][1]['check_status'] == {
|
||||
'check_type': 'foo-presence-reason',
|
||||
'status': 'presence',
|
||||
|
@ -548,12 +548,12 @@ def test_detail_agenda_pricing_test_tool_booking_status(
|
|||
|
||||
mock_pricing_data.reset_mock()
|
||||
resp.form['booking_status'] = 'absence'
|
||||
resp = resp.form.submit()
|
||||
resp = resp.form.submit().follow()
|
||||
assert mock_pricing_data.call_args_list[0][1]['check_status'] == {'check_type': None, 'status': 'absence'}
|
||||
|
||||
mock_pricing_data.reset_mock()
|
||||
resp.form['booking_status'] = 'absence::foo-absence-reason'
|
||||
resp = resp.form.submit()
|
||||
resp = resp.form.submit().follow()
|
||||
assert mock_pricing_data.call_args_list[0][1]['check_status'] == {
|
||||
'check_type': 'foo-absence-reason',
|
||||
'status': 'absence',
|
||||
|
@ -631,7 +631,9 @@ def test_edit_agenda_pricing_matrix_3_categories(app, admin_user):
|
|||
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/' % agenda_pricing.pk)
|
||||
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': {
|
||||
|
@ -739,7 +741,7 @@ def test_edit_agenda_pricing_matrix_2_categories(app, admin_user):
|
|||
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/' % agenda_pricing.pk)
|
||||
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': {
|
||||
|
@ -805,7 +807,7 @@ def test_edit_agenda_pricing_matrix_1_category(app, admin_user):
|
|||
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/' % agenda_pricing.pk)
|
||||
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,
|
||||
|
|
|
@ -173,7 +173,7 @@ def test_pricing_add_category(app, admin_user):
|
|||
]
|
||||
resp.form['category'] = category1.pk
|
||||
resp = resp.form.submit()
|
||||
assert resp.location.endswith('/manage/pricing/model/%s/' % pricing.pk)
|
||||
assert resp.location.endswith('/manage/pricing/model/%s/#open:criterias' % pricing.pk)
|
||||
resp = resp.follow()
|
||||
assert '/manage/pricing/model/%s/category/add/' % pricing.pk in resp
|
||||
assert list(
|
||||
|
@ -236,7 +236,7 @@ def test_pricing_edit_category(app, admin_user):
|
|||
assert list(resp.context['form'].initial['criterias']) == []
|
||||
resp.form['criterias'] = [criteria1.pk, criteria3.pk]
|
||||
resp = resp.form.submit()
|
||||
assert resp.location.endswith('/manage/pricing/model/%s/' % pricing.pk)
|
||||
assert resp.location.endswith('/manage/pricing/model/%s/#open:criterias' % pricing.pk)
|
||||
resp = resp.follow()
|
||||
assert list(pricing.criterias.order_by('pk')) == [criteria1, criteria3]
|
||||
|
||||
|
@ -268,7 +268,7 @@ def test_pricing_delete_category(app, admin_user):
|
|||
resp = app.get('/manage/pricing/model/%s/' % pricing.pk)
|
||||
resp = resp.click(href='/manage/pricing/model/%s/category/%s/delete/' % (pricing.pk, category1.pk))
|
||||
resp = resp.form.submit()
|
||||
assert resp.location.endswith('/manage/pricing/model/%s/' % pricing.pk)
|
||||
assert resp.location.endswith('/manage/pricing/model/%s/#open:criterias' % pricing.pk)
|
||||
resp = resp.follow()
|
||||
assert list(pricing.categories.all()) == [category2]
|
||||
assert list(pricing.criterias.all()) == [criteria2]
|
||||
|
|
Loading…
Reference in New Issue