Merge branch 'skia/counter_rework' into 'master'

counter: make click page dynamic to avoid repetitive loading

See merge request ae/Sith!278
This commit is contained in:
Skia 2021-09-27 19:21:28 +00:00
commit cb3307509d
15 changed files with 288 additions and 164 deletions

View File

@ -496,7 +496,7 @@ class OperationCreateView(CanCreateMixin, CreateView):
return ret return ret
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
""" Add journal to the context """ """Add journal to the context"""
kwargs = super(OperationCreateView, self).get_context_data(**kwargs) kwargs = super(OperationCreateView, self).get_context_data(**kwargs)
if self.journal: if self.journal:
kwargs["object"] = self.journal kwargs["object"] = self.journal
@ -514,7 +514,7 @@ class OperationEditView(CanEditMixin, UpdateView):
template_name = "accounting/operation_edit.jinja" template_name = "accounting/operation_edit.jinja"
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
""" Add journal to the context """ """Add journal to the context"""
kwargs = super(OperationEditView, self).get_context_data(**kwargs) kwargs = super(OperationEditView, self).get_context_data(**kwargs)
kwargs["object"] = self.object.journal kwargs["object"] = self.object.journal
return kwargs return kwargs
@ -735,7 +735,7 @@ class JournalNatureStatementView(JournalTabsMixin, CanViewMixin, DetailView):
return statement return statement
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
""" Add infos to the context """ """Add infos to the context"""
kwargs = super(JournalNatureStatementView, self).get_context_data(**kwargs) kwargs = super(JournalNatureStatementView, self).get_context_data(**kwargs)
kwargs["statement"] = self.big_statement() kwargs["statement"] = self.big_statement()
return kwargs return kwargs
@ -774,7 +774,7 @@ class JournalPersonStatementView(JournalTabsMixin, CanViewMixin, DetailView):
return sum(self.statement(movement_type).values()) return sum(self.statement(movement_type).values())
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
""" Add journal to the context """ """Add journal to the context"""
kwargs = super(JournalPersonStatementView, self).get_context_data(**kwargs) kwargs = super(JournalPersonStatementView, self).get_context_data(**kwargs)
kwargs["credit_statement"] = self.statement("CREDIT") kwargs["credit_statement"] = self.statement("CREDIT")
kwargs["debit_statement"] = self.statement("DEBIT") kwargs["debit_statement"] = self.statement("DEBIT")
@ -804,7 +804,7 @@ class JournalAccountingStatementView(JournalTabsMixin, CanViewMixin, DetailView)
return statement return statement
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
""" Add journal to the context """ """Add journal to the context"""
kwargs = super(JournalAccountingStatementView, self).get_context_data(**kwargs) kwargs = super(JournalAccountingStatementView, self).get_context_data(**kwargs)
kwargs["statement"] = self.statement() kwargs["statement"] = self.statement()
return kwargs return kwargs

View File

@ -79,9 +79,11 @@ class ComTest(TestCase):
) )
r = self.client.get(reverse("core:index")) r = self.client.get(reverse("core:index"))
self.assertTrue(r.status_code == 200) self.assertTrue(r.status_code == 200)
self.assertTrue( self.assertContains(
"""<div id="alert_box">\\n <div class="markdown"><h3>ALERTE!</h3>\\n<p><strong>Caaaataaaapuuuulte!!!!</strong></p>""" r,
in str(r.content) """<div id="alert_box">
<div class="markdown"><h3>ALERTE!</h3>
<p><strong>Caaaataaaapuuuulte!!!!</strong></p>""",
) )
def test_info_msg(self): def test_info_msg(self):
@ -95,9 +97,10 @@ class ComTest(TestCase):
) )
r = self.client.get(reverse("core:index")) r = self.client.get(reverse("core:index"))
self.assertTrue(r.status_code == 200) self.assertTrue(r.status_code == 200)
self.assertTrue( self.assertContains(
"""<div id="info_box">\\n <div class="markdown"><h3>INFO: <strong>Caaaataaaapuuuulte!!!!</strong></h3>""" r,
in str(r.content) """<div id="info_box">
<div class="markdown"><h3>INFO: <strong>Caaaataaaapuuuulte!!!!</strong></h3>""",
) )
def test_birthday_non_subscribed_user(self): def test_birthday_non_subscribed_user(self):

View File

@ -534,7 +534,7 @@ class WeekmailEditView(ComTabsMixin, QuickNotifMixin, CanEditPropMixin, UpdateVi
return super(WeekmailEditView, self).get(request, *args, **kwargs) return super(WeekmailEditView, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
"""Add orphan articles """ """Add orphan articles"""
kwargs = super(WeekmailEditView, self).get_context_data(**kwargs) kwargs = super(WeekmailEditView, self).get_context_data(**kwargs)
kwargs["orphans"] = WeekmailArticle.objects.filter(weekmail=None) kwargs["orphans"] = WeekmailArticle.objects.filter(weekmail=None)
return kwargs return kwargs

File diff suppressed because one or more lines are too long

View File

@ -1125,7 +1125,7 @@ u, .underline {
overflow: auto; overflow: auto;
} }
#bar_ui { #click_form {
float: left; float: left;
min-width: 57%; min-width: 57%;
} }

View File

@ -126,6 +126,7 @@
</header> </header>
<div id="info_boxes"> <div id="info_boxes">
{% block info_boxes %}
{% set sith = get_sith() %} {% set sith = get_sith() %}
{% if sith.alert_msg %} {% if sith.alert_msg %}
<div id="alert_box"> <div id="alert_box">
@ -137,6 +138,7 @@
{{ sith.info_msg|markdown }} {{ sith.info_msg|markdown }}
</div> </div>
{% endif %} {% endif %}
{% endblock %}
</div> </div>
{% else %}{# if not popup #} {% else %}{# if not popup #}

View File

@ -4,6 +4,12 @@
{% trans obj=object %}Edit {{ obj }}{% endtrans %} {% trans obj=object %}Edit {{ obj }}{% endtrans %}
{% endblock %} {% endblock %}
{% block info_boxes %}
{% endblock %}
{% block nav %}
{% endblock %}
{% block content %} {% block content %}
<h2>{% trans %}Make a cash register summary{% endtrans %}</h2> <h2>{% trans %}Make a cash register summary{% endtrans %}</h2>
<form action="" method="post" id="cash_summary_form"> <form action="" method="post" id="cash_summary_form">

View File

@ -1,27 +1,16 @@
{% extends "core/base.jinja" %} {% extends "core/base.jinja" %}
{% from "core/macros.jinja" import user_mini_profile, user_subscription %} {% from "core/macros.jinja" import user_mini_profile, user_subscription %}
{% macro add_product(id, content, class="") %}
<form method="post" action="{{ url('counter:click', counter_id=counter.id, user_id=customer.user.id) }}" class="{{ class }}">
{% csrf_token %}
<input type="hidden" name="action" value="add_product">
<button type="submit" name="product_id" value="{{ id }}"> {{ content|safe }} </button>
</form>
{% endmacro %}
{% macro del_product(id, content, class="") %}
<form method="post" action="{{ url('counter:click', counter_id=counter.id, user_id=customer.user.id) }}" class="{{ class }}">
{% csrf_token %}
<input type="hidden" name="action" value="del_product">
<button type="submit" name="product_id" value="{{ id }}"> {{ content }} </button>
</form>
{% endmacro %}
{% block title %} {% block title %}
{{ counter }} {{ counter }}
{% endblock %} {% endblock %}
{% block info_boxes %}
{% endblock %}
{% block nav %}
{% endblock %}
{% block content %} {% block content %}
<h4 id="click_interface">{{ counter }}</h4> <h4 id="click_interface">{{ counter }}</h4>
@ -52,56 +41,57 @@
{% endif %} {% endif %}
</div> </div>
<div id="bar_ui"> <div id="bar_ui">
<noscript>
<p class="important">Javascript is required for the counter UI.</p>
</noscript>
<div id="click_form">
<h5>{% trans %}Selling{% endtrans %}</h5> <h5>{% trans %}Selling{% endtrans %}</h5>
<div> <div>
<div class="important"> <div class="important">
{% if request.session['too_young'] %} <p v-for="error in errors"><strong>{{ error }}</strong></p>
<p><strong>{% trans %}Too young for that product{% endtrans %}</strong></p>
{% endif %}
{% if request.session['not_allowed'] %}
<p><strong>{% trans %}Not allowed for that product{% endtrans %}</strong></p>
{% endif %}
{% if request.session['no_age'] %}
<p><strong>{% trans %}No date of birth provided{% endtrans %}</strong></p>
{% endif %}
{% if request.session['not_enough'] %}
<p><strong>{% trans %}Not enough money{% endtrans %}</strong></p>
{% endif %}
</div> </div>
<form method="post" action="{{ url('counter:click', counter_id=counter.id, user_id=customer.user.id) }}">
<form method="post" action="{{ url('counter:click', counter_id=counter.id, user_id=customer.user.id) }}" class="code_form" @submit.prevent="handle_code">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="action" value="code"> <input type="hidden" name="action" value="code">
<input type="input" name="code" value="" class="focus" id="code_field"/> <input type="input" name="code" value="" class="focus" id="code_field"/>
<input type="submit" value="{% trans %}Go{% endtrans %}" /> <input type="submit" value="{% trans %}Go{% endtrans %}" />
</form> </form>
<p>{% trans %}Basket: {% endtrans %}</p> <p>{% trans %}Basket: {% endtrans %}</p>
{% raw %}
<ul> <ul>
{% for id,infos in request.session['basket']|dictsort %} <li v-for="p_info,p_id in basket">
{% set product = counter.products.filter(id=id).first() %}
{% set s = infos['qty'] * infos['price'] / 100 %} <form method="post" action="" class="inline del_product_form" @submit.prevent="handle_action">
<li>{{ del_product(id, '-', "inline") }} {{ infos['qty'] + infos['bonus_qty'] }} {{ add_product(id, '+', "inline") }} <input type="hidden" name="csrfmiddlewaretoken" v-bind:value="js_csrf_token">
{{ product.name }}: {{ "%0.2f"|format(s) }} <input type="hidden" name="action" value="del_product">
{% if infos['bonus_qty'] %} <input type="hidden" name="product_id" v-bind:value="p_id">
P <button type="submit"> - </button>
{% endif %} </form>
{{ p_info["qty"] + p_info["bonus_qty"] }}
<form method="post" action="" class="inline add_product_form" @submit.prevent="handle_action">
<input type="hidden" name="csrfmiddlewaretoken" v-bind:value="js_csrf_token">
<input type="hidden" name="action" value="add_product">
<input type="hidden" name="product_id" v-bind:value="p_id">
<button type="submit"> + </button>
</form>
{{ products[p_id].name }}: {{ (p_info["qty"]*p_info["price"]/100).toLocaleString(undefined, { minimumFractionDigits: 2 }) }} € <span v-if="p_info['bonus_qty'] > 0">P</span>
</li> </li>
{% endfor %}
</ul> </ul>
<p><strong>{% trans %}Total: {% endtrans %}{{ "%0.2f"|format(basket_total) }} €</strong></p> <p>
<strong>Total: {{ sum_basket().toLocaleString(undefined, { minimumFractionDigits: 2 }) }} €</strong>
</p>
{% endraw %}
<div class="important"> <div class="important">
{% if request.session['too_young'] %} <p v-for="error in errors"><strong>{{ error }}</strong></p>
<p><strong>{% trans %}Too young for that product{% endtrans %}</strong></p>
{% endif %}
{% if request.session['not_allowed'] %}
<p><strong>{% trans %}Not allowed for that product{% endtrans %}</strong></p>
{% endif %}
{% if request.session['no_age'] %}
<p><strong>{% trans %}No date of birth provided{% endtrans %}</strong></p>
{% endif %}
{% if request.session['not_enough'] %}
<p><strong>{% trans %}Not enough money{% endtrans %}</strong></p>
{% endif %}
</div> </div>
<form method="post" action="{{ url('counter:click', counter_id=counter.id, user_id=customer.user.id) }}"> <form method="post" action="{{ url('counter:click', counter_id=counter.id, user_id=customer.user.id) }}">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="action" value="finish"> <input type="hidden" name="action" value="finish">
@ -124,8 +114,8 @@
</form> </form>
</div> </div>
{% endif %} {% endif %}
</div> </div>
<div id="products"> <div id="products">
<ul> <ul>
{% for category in categories.keys() -%} {% for category in categories.keys() -%}
<li><a href="#cat_{{ category|slugify }}">{{ category }}</a></li> <li><a href="#cat_{{ category|slugify }}">{{ category }}</a></li>
@ -141,23 +131,89 @@
{% else %} {% else %}
{% set file = static('core/img/na.gif') %} {% set file = static('core/img/na.gif') %}
{% endif %} {% endif %}
{% set prod = '<strong>%s</strong><hr><img src="%s" /><span>%s €<br>%s</span>' % (p.name, file, p.selling_price, p.code) %} <form method="post" action="{{ url('counter:click', counter_id=counter.id, user_id=customer.user.id) }}" class="form_button add_product_form" @submit.prevent="handle_action">
{{ add_product(p.id, prod, "form_button") }} {% csrf_token %}
<input type="hidden" name="action" value="add_product">
<input type="hidden" name="product_id" value="{{ p.id }}">
<button type="submit"><strong>{{ p.name }}</strong><hr><img src="{{ file }}" /><span>{{ p.selling_price }} €<br>{{ p.code }}</span></button>
</form>
{%- endfor %} {%- endfor %}
</div> </div>
{%- endfor %} {%- endfor %}
</div>
</div> </div>
{% endblock %} {% endblock %}
{% block script %} {% block script %}
<script>
document.getElementById("click_interface").scrollIntoView();
</script>
{{ super() }} {{ super() }}
<script src="{{ static('core/js/vue.global.prod.js') }}"></script>
<script> <script>
$( function() { $( function() {
var products = [ /* Vue.JS dynamic form */
const click_form_vue = Vue.createApp({
data() {
return {
js_csrf_token: "{{ csrf_token }}",
products: {
{% for p in products -%}
{{ p.id }}: {
code: "{{ p.code }}",
name: "{{ p.name }}",
selling_price: "{{ p.selling_price }}",
special_selling_price: "{{ p.special_selling_price }}",
},
{%- endfor %}
},
basket: {{ request.session["basket"]|tojson }},
errors: [],
}
},
methods: {
sum_basket() {
var vm = this;
var total = 0;
for(idx in vm.basket) {
var item = vm.basket[idx];
console.log(item);
total += item["qty"] * item["price"];
}
return total / 100;
},
handle_code(event) {
var vm = this;
var code = $(event.target).find("#code_field").val().toUpperCase();
console.log("Code:");
console.log(code);
if(code == "{% trans %}END{% endtrans %}" || code == "{% trans %}CAN{% endtrans %}") {
$(event.target).submit();
} else {
vm.handle_action(event);
}
},
handle_action(event) {
var vm = this;
var payload = $(event.target).serialize();
$.ajax({
type: 'post',
dataType: 'json',
data: payload,
success: function(response) {
vm.basket = response.basket;
vm.errors = [];
},
error: function(error) {
vm.basket = error.responseJSON.basket;
vm.errors = error.responseJSON.errors;
}
});
$('form.code_form #code_field').val("").focus();
}
}
}).mount('#bar_ui');
/* Autocompletion in the code field */
var products_autocomplete = [
{% for p in products -%} {% for p in products -%}
{ {
value: "{{ p.code }}", value: "{{ p.code }}",
@ -166,6 +222,7 @@ $( function() {
}, },
{%- endfor %} {%- endfor %}
]; ];
var quantity = ""; var quantity = "";
var search = ""; var search = "";
var pattern = /^(\d+x)?(.*)/i; var pattern = /^(\d+x)?(.*)/i;
@ -183,21 +240,22 @@ $( function() {
quantity = res[1] || ""; quantity = res[1] || "";
search = res[2]; search = res[2];
var matcher = new RegExp( $.ui.autocomplete.escapeRegex( search ), "i" ); var matcher = new RegExp( $.ui.autocomplete.escapeRegex( search ), "i" );
response($.grep( products, function( value ) { response($.grep( products_autocomplete, function( value ) {
value = value.tags; value = value.tags;
return matcher.test( value ); return matcher.test( value );
})); }));
}, },
}); });
});
$( function() { /* Accordion UI between basket and refills */
$("#bar_ui").accordion({ $("#click_form").accordion({
heightStyle: "content", heightStyle: "content",
activate: function(event, ui){ activate: function(event, ui){
$(".focus").focus(); $(".focus").focus();
} }
}); });
$("#products").tabs(); $("#products").tabs();
$("#code_field").focus(); $("#code_field").focus();
}); });
</script> </script>

View File

@ -12,6 +12,12 @@
{% trans counter_name=counter %}{{ counter_name }} counter{% endtrans %} {% trans counter_name=counter %}{{ counter_name }} counter{% endtrans %}
{% endblock %} {% endblock %}
{% block info_boxes %}
{% endblock %}
{% block nav %}
{% endblock %}
{% block content %} {% block content %}
<h3>{% trans counter_name=counter %}{{ counter_name }} counter{% endtrans %}</h3> <h3>{% trans counter_name=counter %}{{ counter_name }} counter{% endtrans %}</h3>

View File

@ -5,6 +5,12 @@
{% trans counter_name=counter %}{{ counter_name }} last operations{% endtrans %} {% trans counter_name=counter %}{{ counter_name }} last operations{% endtrans %}
{% endblock %} {% endblock %}
{% block info_boxes %}
{% endblock %}
{% block nav %}
{% endblock %}
{% block content %} {% block content %}
<h3>{% trans counter_name=counter %}{{ counter_name }} last operations{% endtrans %}</h3> <h3>{% trans counter_name=counter %}{{ counter_name }} last operations{% endtrans %}</h3>
<h4>{% trans %}Refillings{% endtrans %}</h4> <h4>{% trans %}Refillings{% endtrans %}</h4>

View File

@ -68,18 +68,29 @@ class CounterTest(TestCase):
location, location,
{ {
"action": "refill", "action": "refill",
"amount": "10", "amount": "5",
"payment_method": "CASH", "payment_method": "CASH",
"bank": "OTHER", "bank": "OTHER",
}, },
) )
response = self.client.post(location, {"action": "code", "code": "BARB"}) response = self.client.post(location, {"action": "code", "code": "BARB"})
response = self.client.post(
location, {"action": "add_product", "product_id": "4"}
)
response = self.client.post(
location, {"action": "del_product", "product_id": "4"}
)
response = self.client.post(location, {"action": "code", "code": "2xdeco"})
response = self.client.post(location, {"action": "code", "code": "1xbarb"})
response = self.client.post(location, {"action": "code", "code": "fin"}) response = self.client.post(location, {"action": "code", "code": "fin"})
response_get = self.client.get(response.get("location")) response_get = self.client.get(response.get("location"))
response_content = response_get.content.decode("utf-8")
self.assertTrue("<li>2 x Barbar" in str(response_content))
self.assertTrue("<li>2 x Déconsigne Eco-cup" in str(response_content))
self.assertTrue( self.assertTrue(
"<p>Client : Richard Batsbak - Nouveau montant : 8.30" "<p>Client : Richard Batsbak - Nouveau montant : 3.60"
in str(response_get.content) in str(response_content)
) )

View File

@ -38,7 +38,7 @@ from django.views.generic.edit import (
from django.forms.models import modelform_factory from django.forms.models import modelform_factory
from django.forms import CheckboxSelectMultiple from django.forms import CheckboxSelectMultiple
from django.urls import reverse_lazy, reverse from django.urls import reverse_lazy, reverse
from django.http import HttpResponseRedirect, HttpResponse from django.http import HttpResponseRedirect, HttpResponse, JsonResponse
from django.utils import timezone from django.utils import timezone
from django import forms from django import forms
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@ -48,6 +48,7 @@ from django.db import DataError, transaction, models
import re import re
import pytz import pytz
from datetime import date, timedelta, datetime from datetime import date, timedelta, datetime
from http import HTTPStatus
from ajax_select.fields import AutoCompleteSelectField, AutoCompleteSelectMultipleField from ajax_select.fields import AutoCompleteSelectField, AutoCompleteSelectMultipleField
from ajax_select import make_ajax_field from ajax_select import make_ajax_field
@ -357,6 +358,34 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
pk_url_kwarg = "counter_id" pk_url_kwarg = "counter_id"
current_tab = "counter" current_tab = "counter"
def render_to_response(self, *args, **kwargs):
if self.request.is_ajax(): # JSON response for AJAX requests
response = {"errors": []}
status = HTTPStatus.OK
if self.request.session["too_young"]:
response["errors"].append(_("Too young for that product"))
status = HTTPStatus.UNAVAILABLE_FOR_LEGAL_REASONS
if self.request.session["not_allowed"]:
response["errors"].append(_("Not allowed for that product"))
status = HTTPStatus.FORBIDDEN
if self.request.session["no_age"]:
response["errors"].append(_("No date of birth provided"))
status = HTTPStatus.UNAVAILABLE_FOR_LEGAL_REASONS
if self.request.session["not_enough"]:
response["errors"].append(_("Not enough money"))
status = HTTPStatus.PAYMENT_REQUIRED
if len(response["errors"]) > 1:
status = HTTPStatus.BAD_REQUEST
response["basket"] = self.request.session["basket"]
return JsonResponse(response, status=status)
else: # Standard HTML page
return super().render_to_response(*args, **kwargs)
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
self.customer = get_object_or_404(Customer, user__id=self.kwargs["user_id"]) self.customer = get_object_or_404(Customer, user__id=self.kwargs["user_id"])
obj = self.get_object() obj = self.get_object()
@ -370,7 +399,9 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
) )
or len(obj.get_barmen_list()) < 1 or len(obj.get_barmen_list()) < 1
): ):
raise PermissionDenied return HttpResponseRedirect(
reverse_lazy("counter:details", kwargs={"counter_id": obj.id})
)
else: else:
if not request.user.is_authenticated: if not request.user.is_authenticated:
raise PermissionDenied raise PermissionDenied
@ -394,7 +425,7 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
return ret return ret
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
""" Handle the many possibilities of the post request """ """Handle the many possibilities of the post request"""
self.object = self.get_object() self.object = self.get_object()
self.refill_form = None self.refill_form = None
if (self.object.type != "BAR" and not request.user.is_authenticated) or ( if (self.object.type != "BAR" and not request.user.is_authenticated) or (
@ -590,7 +621,7 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
return True return True
def del_product(self, request): def del_product(self, request):
""" Delete a product from the basket """ """Delete a product from the basket"""
pid = str(request.POST["product_id"]) pid = str(request.POST["product_id"])
product = self.get_product(pid) product = self.get_product(pid)
if pid in request.session["basket"]: if pid in request.session["basket"]:
@ -632,7 +663,7 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
return self.render_to_response(context) return self.render_to_response(context)
def finish(self, request): def finish(self, request):
""" Finish the click session, and validate the basket """ """Finish the click session, and validate the basket"""
with transaction.atomic(): with transaction.atomic():
request.session["last_basket"] = [] request.session["last_basket"] = []
if self.sum_basket(request) > self.customer.amount: if self.sum_basket(request) > self.customer.amount:
@ -684,7 +715,7 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
) )
def cancel(self, request): def cancel(self, request):
""" Cancel the click session """ """Cancel the click session"""
kwargs = {"counter_id": self.object.id} kwargs = {"counter_id": self.object.id}
request.session.pop("basket", None) request.session.pop("basket", None)
return HttpResponseRedirect( return HttpResponseRedirect(
@ -706,7 +737,7 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
raise PermissionDenied raise PermissionDenied
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
""" Add customer to the context """ """Add customer to the context"""
kwargs = super(CounterClick, self).get_context_data(**kwargs) kwargs = super(CounterClick, self).get_context_data(**kwargs)
kwargs["products"] = self.object.products.select_related("product_type") kwargs["products"] = self.object.products.select_related("product_type")
kwargs["categories"] = {} kwargs["categories"] = {}
@ -1360,7 +1391,7 @@ class CounterLastOperationsView(CounterTabsMixin, CanViewMixin, DetailView):
) )
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
"""Add form to the context """ """Add form to the context"""
kwargs = super(CounterLastOperationsView, self).get_context_data(**kwargs) kwargs = super(CounterLastOperationsView, self).get_context_data(**kwargs)
threshold = timezone.now() - timedelta( threshold = timezone.now() - timedelta(
minutes=settings.SITH_LAST_OPERATIONS_LIMIT minutes=settings.SITH_LAST_OPERATIONS_LIMIT
@ -1422,7 +1453,7 @@ class CounterCashSummaryView(CounterTabsMixin, CanViewMixin, DetailView):
return reverse_lazy("counter:details", kwargs={"counter_id": self.object.id}) return reverse_lazy("counter:details", kwargs={"counter_id": self.object.id})
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
""" Add form to the context """ """Add form to the context"""
kwargs = super(CounterCashSummaryView, self).get_context_data(**kwargs) kwargs = super(CounterCashSummaryView, self).get_context_data(**kwargs)
kwargs["form"] = self.form kwargs["form"] = self.form
return kwargs return kwargs
@ -1448,7 +1479,7 @@ class CounterStatView(DetailView, CounterAdminMixin):
template_name = "counter/stats.jinja" template_name = "counter/stats.jinja"
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
""" Add stats to the context """ """Add stats to the context"""
from django.db.models import Sum, Case, When, F, DecimalField from django.db.models import Sum, Case, When, F, DecimalField
kwargs = super(CounterStatView, self).get_context_data(**kwargs) kwargs = super(CounterStatView, self).get_context_data(**kwargs)
@ -1578,7 +1609,7 @@ class CashSummaryListView(CounterAdminTabsMixin, CounterAdminMixin, ListView):
paginate_by = settings.SITH_COUNTER_CASH_SUMMARY_LENGTH paginate_by = settings.SITH_COUNTER_CASH_SUMMARY_LENGTH
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
""" Add sums to the context """ """Add sums to the context"""
kwargs = super(CashSummaryListView, self).get_context_data(**kwargs) kwargs = super(CashSummaryListView, self).get_context_data(**kwargs)
form = CashSummaryFormBase(self.request.GET) form = CashSummaryFormBase(self.request.GET)
kwargs["form"] = form kwargs["form"] = form
@ -1629,7 +1660,7 @@ class InvoiceCallView(CounterAdminTabsMixin, CounterAdminMixin, TemplateView):
current_tab = "invoices_call" current_tab = "invoices_call"
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
""" Add sums to the context """ """Add sums to the context"""
kwargs = super(InvoiceCallView, self).get_context_data(**kwargs) kwargs = super(InvoiceCallView, self).get_context_data(**kwargs)
kwargs["months"] = Selling.objects.datetimes("date", "month", order="DESC") kwargs["months"] = Selling.objects.datetimes("date", "month", order="DESC")
start_date = None start_date = None

View File

@ -82,7 +82,7 @@ class EbouticMain(TemplateView):
return self.render_to_response(self.get_context_data(**kwargs)) return self.render_to_response(self.get_context_data(**kwargs))
def add_product(self, request): def add_product(self, request):
""" Add a product to the basket """ """Add a product to the basket"""
try: try:
p = self.object.products.filter(id=int(request.POST["product_id"])).first() p = self.object.products.filter(id=int(request.POST["product_id"])).first()
if not p.buying_groups.exists(): if not p.buying_groups.exists():
@ -95,7 +95,7 @@ class EbouticMain(TemplateView):
pass pass
def del_product(self, request): def del_product(self, request):
""" Delete a product from the basket """ """Delete a product from the basket"""
try: try:
p = self.object.products.filter(id=int(request.POST["product_id"])).first() p = self.object.products.filter(id=int(request.POST["product_id"])).first()
self.basket.del_product(p) self.basket.del_product(p)

View File

@ -49,7 +49,7 @@ class LimitedCheckboxField(forms.ModelMultipleChoiceField):
class CandidateForm(forms.ModelForm): class CandidateForm(forms.ModelForm):
""" Form to candidate """ """Form to candidate"""
class Meta: class Meta:
model = Candidature model = Candidature
@ -95,7 +95,7 @@ class VoteForm(forms.Form):
class RoleForm(forms.ModelForm): class RoleForm(forms.ModelForm):
""" Form for creating a role """ """Form for creating a role"""
class Meta: class Meta:
model = Role model = Role
@ -261,7 +261,7 @@ class ElectionDetailView(CanViewMixin, DetailView):
return r return r
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
""" Add additionnal data to the template """ """Add additionnal data to the template"""
kwargs = super(ElectionDetailView, self).get_context_data(**kwargs) kwargs = super(ElectionDetailView, self).get_context_data(**kwargs)
kwargs["election_form"] = VoteForm(self.object, self.request.user) kwargs["election_form"] = VoteForm(self.object, self.request.user)
kwargs["election_results"] = self.object.results kwargs["election_results"] = self.object.results
@ -322,7 +322,7 @@ class VoteFormView(CanCreateMixin, FormView):
return reverse_lazy("election:detail", kwargs={"election_id": self.election.id}) return reverse_lazy("election:detail", kwargs={"election_id": self.election.id})
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
""" Add additionnal data to the template """ """Add additionnal data to the template"""
kwargs = super(VoteFormView, self).get_context_data(**kwargs) kwargs = super(VoteFormView, self).get_context_data(**kwargs)
kwargs["object"] = self.election kwargs["object"] = self.election
kwargs["election"] = self.election kwargs["election"] = self.election

View File

@ -52,7 +52,7 @@ class LaunderetteMainView(TemplateView):
template_name = "launderette/launderette_main.jinja" template_name = "launderette/launderette_main.jinja"
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
""" Add page to the context """ """Add page to the context"""
kwargs = super(LaunderetteMainView, self).get_context_data(**kwargs) kwargs = super(LaunderetteMainView, self).get_context_data(**kwargs)
kwargs["page"] = Page.objects.filter(name="launderette").first() kwargs["page"] = Page.objects.filter(name="launderette").first()
return kwargs return kwargs
@ -142,7 +142,7 @@ class LaunderetteBookView(CanViewMixin, DetailView):
currentDate += delta currentDate += delta
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
""" Add page to the context """ """Add page to the context"""
kwargs = super(LaunderetteBookView, self).get_context_data(**kwargs) kwargs = super(LaunderetteBookView, self).get_context_data(**kwargs)
kwargs["planning"] = OrderedDict() kwargs["planning"] = OrderedDict()
kwargs["slot_type"] = self.slot_type kwargs["slot_type"] = self.slot_type
@ -481,7 +481,7 @@ class LaunderetteClickView(CanEditMixin, DetailView, BaseFormView):
return super(LaunderetteClickView, self).get(request, *args, **kwargs) return super(LaunderetteClickView, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
""" Handle the many possibilities of the post request """ """Handle the many possibilities of the post request"""
self.object = self.get_object() self.object = self.get_object()
self.customer = Customer.objects.filter(user__id=self.kwargs["user_id"]).first() self.customer = Customer.objects.filter(user__id=self.kwargs["user_id"]).first()
self.subscriber = self.customer.user self.subscriber = self.customer.user