mirror of
				https://github.com/ae-utbm/sith.git
				synced 2025-10-26 14:43:55 +00:00 
			
		
		
		
	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:
		| @@ -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 | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								com/tests.py
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								com/tests.py
									
									
									
									
									
								
							| @@ -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): | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								core/static/core/js/vue.global.prod.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								core/static/core/js/vue.global.prod.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -1125,7 +1125,7 @@ u, .underline { | |||||||
|   overflow: auto; |   overflow: auto; | ||||||
| } | } | ||||||
|  |  | ||||||
| #bar_ui { | #click_form { | ||||||
|   float: left; |   float: left; | ||||||
|   min-width: 57%; |   min-width: 57%; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -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 #} | ||||||
|   | |||||||
| @@ -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"> | ||||||
|   | |||||||
| @@ -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> | ||||||
|   | |||||||
| @@ -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> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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> | ||||||
|   | |||||||
| @@ -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) | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
| @@ -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) | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user