mirror of
https://github.com/ae-utbm/sith.git
synced 2024-11-16 19:23:27 +00:00
268 lines
10 KiB
Django/Jinja
268 lines
10 KiB
Django/Jinja
{% extends "core/base.jinja" %}
|
|
{% from "core/macros.jinja" import user_mini_profile, user_subscription %}
|
|
|
|
{% block title %}
|
|
{{ counter }}
|
|
{% endblock %}
|
|
|
|
{% block info_boxes %}
|
|
{% endblock %}
|
|
|
|
{% block nav %}
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<h4 id="click_interface">{{ counter }}</h4>
|
|
|
|
<div id="bar_ui">
|
|
<noscript>
|
|
<p class="important">Javascript is required for the counter UI.</p>
|
|
</noscript>
|
|
|
|
<div id="user_info">
|
|
<h5>{% trans %}Customer{% endtrans %}</h5>
|
|
{{ user_mini_profile(customer.user) }}
|
|
{{ user_subscription(customer.user) }}
|
|
<p>{% trans %}Amount: {% endtrans %}{{ customer.amount }} €</p>
|
|
<form method="post" action="{{ url('counter:click', counter_id=counter.id, user_id=customer.user.id) }}">
|
|
{% csrf_token %}
|
|
<input type="hidden" name="action" value="add_student_card">
|
|
{% trans %}Add a student card{% endtrans %}
|
|
<input type="input" name="student_card_uid" />
|
|
{% if request.session['not_valid_student_card_uid'] %}
|
|
<p><strong>{% trans %}This is not a valid student card UID{% endtrans %}</strong></p>
|
|
{% endif %}
|
|
<input type="submit" value="{% trans %}Go{% endtrans %}" />
|
|
</form>
|
|
<h6>{% trans %}Registered cards{% endtrans %}</h6>
|
|
{% if customer.student_cards.exists() %}
|
|
<ul>
|
|
{% for card in customer.student_cards.all() %}
|
|
<li>{{ card.uid }}</li>
|
|
{% endfor %}
|
|
</ul>
|
|
{% else %}
|
|
{% trans %}No card registered{% endtrans %}
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div id="click_form">
|
|
<h5>{% trans %}Selling{% endtrans %}</h5>
|
|
<div>
|
|
|
|
{% raw %}
|
|
<div class="important">
|
|
<p v-for="error in errors"><strong>{{ error }}</strong></p>
|
|
</div>
|
|
{% endraw %}
|
|
|
|
<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 %}
|
|
<input type="hidden" name="action" value="code">
|
|
<input type="input" name="code" value="" class="focus" id="code_field"/>
|
|
<input type="submit" value="{% trans %}Go{% endtrans %}" />
|
|
</form>
|
|
<p>{% trans %}Basket: {% endtrans %}</p>
|
|
|
|
{% raw %}
|
|
<ul>
|
|
<li v-for="p_info,p_id in basket">
|
|
|
|
<form method="post" action="" class="inline del_product_form" @submit.prevent="handle_action">
|
|
<input type="hidden" name="csrfmiddlewaretoken" v-bind:value="js_csrf_token">
|
|
<input type="hidden" name="action" value="del_product">
|
|
<input type="hidden" name="product_id" v-bind:value="p_id">
|
|
<button type="submit"> - </button>
|
|
</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>
|
|
</ul>
|
|
<p>
|
|
<strong>Total: {{ sum_basket().toLocaleString(undefined, { minimumFractionDigits: 2 }) }} €</strong>
|
|
</p>
|
|
|
|
<div class="important">
|
|
<p v-for="error in errors"><strong>{{ error }}</strong></p>
|
|
</div>
|
|
{% endraw %}
|
|
|
|
<form method="post" action="{{ url('counter:click', counter_id=counter.id, user_id=customer.user.id) }}">
|
|
{% csrf_token %}
|
|
<input type="hidden" name="action" value="finish">
|
|
<input type="submit" value="{% trans %}Finish{% endtrans %}" />
|
|
</form>
|
|
<form method="post" action="{{ url('counter:click', counter_id=counter.id, user_id=customer.user.id) }}">
|
|
{% csrf_token %}
|
|
<input type="hidden" name="action" value="cancel">
|
|
<input type="submit" value="{% trans %}Cancel{% endtrans %}" />
|
|
</form>
|
|
</div>
|
|
{% if (counter.type == 'BAR' and barmens_can_refill) %}
|
|
<h5>{% trans %}Refilling{% endtrans %}</h5>
|
|
<div>
|
|
<form method="post" action="{{ url('counter:click', counter_id=counter.id, user_id=customer.user.id) }}">
|
|
{% csrf_token %}
|
|
{{ refill_form.as_p() }}
|
|
<input type="hidden" name="action" value="refill">
|
|
<input type="submit" value="{% trans %}Go{% endtrans %}" />
|
|
</form>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div id="products">
|
|
<ul>
|
|
{% for category in categories.keys() -%}
|
|
<li><a href="#cat_{{ category|slugify }}">{{ category }}</a></li>
|
|
{%- endfor %}
|
|
</ul>
|
|
{% for category in categories.keys() -%}
|
|
<div id="cat_{{ category|slugify }}">
|
|
<h5>{{ category }}</h5>
|
|
{% for p in categories[category] -%}
|
|
{% set file = None %}
|
|
{% if p.icon %}
|
|
{% set file = p.icon.url %}
|
|
{% else %}
|
|
{% set file = static('core/img/na.gif') %}
|
|
{% endif %}
|
|
<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">
|
|
{% 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 %}
|
|
</div>
|
|
{%- endfor %}
|
|
</div>
|
|
</div>
|
|
|
|
{% endblock %}
|
|
|
|
{% block script %}
|
|
{{ super() }}
|
|
<script src="{{ static('core/js/vue.global.prod.js') }}"></script>
|
|
<script>
|
|
$( function() {
|
|
/* 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 -%}
|
|
{
|
|
value: "{{ p.code }}",
|
|
label: "{{ p.name }}",
|
|
tags: "{{ p.code }} {{ p.name }}",
|
|
},
|
|
{%- endfor %}
|
|
];
|
|
|
|
var quantity = "";
|
|
var search = "";
|
|
var pattern = /^(\d+x)?(.*)/i;
|
|
$( "#code_field" ).autocomplete({
|
|
select: function (event, ui) {
|
|
event.preventDefault();
|
|
$("#code_field").val(quantity + ui.item.value);
|
|
},
|
|
focus: function (event, ui) {
|
|
event.preventDefault();
|
|
$("#code_field").val(quantity + ui.item.value);
|
|
},
|
|
source: function( request, response ) {
|
|
var res = pattern.exec(request.term);
|
|
quantity = res[1] || "";
|
|
search = res[2];
|
|
var matcher = new RegExp( $.ui.autocomplete.escapeRegex( search ), "i" );
|
|
response($.grep( products_autocomplete, function( value ) {
|
|
value = value.tags;
|
|
return matcher.test( value );
|
|
}));
|
|
},
|
|
});
|
|
|
|
/* Accordion UI between basket and refills */
|
|
$("#click_form").accordion({
|
|
heightStyle: "content",
|
|
activate: function(event, ui){
|
|
$(".focus").focus();
|
|
}
|
|
});
|
|
$("#products").tabs();
|
|
|
|
$("#code_field").focus();
|
|
});
|
|
</script>
|
|
{% endblock %}
|