diff --git a/kfet/static/kfet/js/kpsul.js b/kfet/static/kfet/js/kpsul.js
index 9dd6ae19..238a40a6 100644
--- a/kfet/static/kfet/js/kpsul.js
+++ b/kfet/static/kfet/js/kpsul.js
@@ -4,6 +4,7 @@ class KPsulManager {
this._env = env;
this.account_manager = new AccountManager(this);
this.checkout_manager = new CheckoutManager(this);
+ this.article_manager = new ArticleManager(this);
}
reset(soft) {
@@ -367,3 +368,228 @@ class CheckoutSelection {
}
}
+class ArticleManager {
+
+ constructor(env) {
+ this._env = env; // Global K-Psul Manager
+
+ this._$container = $('#articles_data tbody');
+ this._$input = $('#article_autocomplete');
+ this._$nb = $('#article_number');
+ this.templates = {'category': '
|
',
+ 'article' : ' | | |
'}
+
+ this.selected = new Article() ;
+ this.list = new ArticleList() ;
+ this.autocomplete = new ArticleAutocomplete(this);
+
+ this._init_events();
+ }
+
+ get nb() {
+ return this._$nb.val() ;
+ }
+
+ display_list() {
+ this.list.display(this._$container, this.templates) ;
+ }
+
+ validate(article) {
+ this.selected.from(article) ;
+ this._$input.val(article.name);
+ this._$nb.val('1');
+ this._$nb.focus().select();
+ }
+
+ unset() {
+ this.selected.clear();
+ }
+
+ is_empty() {
+ return this.selected.is_empty();
+ }
+
+ reset_data() {
+ this._$container.find('tr').remove();
+ this.list.clear();
+ this.list.fromAPI({}, this.display_list.bind(this), $.noop) ;
+ }
+
+ update_data(data) {
+ for (let article_dict of data) {
+ article = this.list.find(Article, {'id': article_dict['id']});
+
+ // For now, article additions are disregarded
+ if (article) {
+ article.stock = article_dict['stock'];
+ this._$container.find('#data-article-'+article_dict['id']+' .stock')
+ .text(article_dict['stock']);
+ }
+ }
+ }
+
+ reset() {
+ this.unset() ;
+ this._$nb.val('');
+ this._$input.val('');
+ this.autocomplete.showAll() ;
+ }
+
+ _init_events() {
+ var that = this;
+
+ // 8:Backspace|9:Tab|13:Enter|46:DEL|112-117:F1-6|119-123:F8-F12
+ var normalKeys = /^(8|9|13|46|112|113|114|115|116|117|119|120|121|122|123)$/;
+ var arrowKeys = /^(37|38|39|40)$/;
+
+ //Global input event (to merge ?)
+ this._$input.on('keydown', function(e) {
+ if (e.keyCode == 13 && that._$input.val() == '') {
+ kpsul._env.performOperations();
+ }
+ });
+
+ this._$container.on('click', '.article', function() {
+ var id = $(this).attr('data-article-id') ;
+ var article = that.list.find(Article, { 'id': intCheck(id) });
+ if (article)
+ that.validate(article);
+ });
+
+ this._$nb.on('keydown', function(e) {
+ if (e.keyCode == 13 && that.constructor.check_nb(that.nb) && !that.is_empty()) {
+ kpsul._env.addPurchase(that.selected, that.nb);
+ that.reset();
+ that.focus();
+ }
+ if (normalKeys.test(e.keyCode) || arrowKeys.test(e.KeyCode) || e.ctrlKey) {
+ if (e.ctrlKey && e.charCode == 65)
+ that._$nb.val('');
+ return true ;
+ }
+ if (that.constructor.check_nb(that.nb+e.key))
+ return true;
+ return false;
+
+ });
+ }
+
+ focus() {
+ this._$input.focus();
+ return this;
+ }
+
+ static check_nb(nb) {
+ return /^[0-9]+$/.test(nb) && nb > 0 && nb <= 24 ;
+ }
+}
+
+class ArticleAutocomplete {
+
+ constructor(article_manager) {
+ this.manager = article_manager;
+ this.matching = [];
+ this.active_categories = [];
+ this._$container = article_manager._$container ;
+ this._$input = $('#article_autocomplete');
+
+ this.showAll() ;
+ this._init_events();
+ }
+
+ _init_events() {
+ var that = this ;
+
+ // 8:Backspace|9:Tab|13:Enter|46:DEL|112-117:F1-6|119-123:F8-F12
+ var normalKeys = /^(8|9|13|46|112|113|114|115|116|117|119|120|121|122|123)$/;
+
+ this._$input
+ .on('keydown', function(e) {
+ var text = that._$input.val() ;
+ if (normalKeys.test(e.keyCode) || e.ctrlKey) {
+ // For the backspace key, we suppose the cursor is at the very end
+ if(e.keyCode == 8) {
+ that.update(text.substring(0, text.length-1), true);
+ }
+ return true ;
+ }
+ that.update(text+e.key, false);
+
+ return false ;
+
+ });
+
+ }
+
+ update(prefix, backspace) {
+
+ var article_list = this.manager.list ;
+ var lower = prefix.toLowerCase() ;
+ var that = this ;
+ this.matching = article_list.data['article']
+ .filter(function(article) {
+ return article.name.toLowerCase()
+ .indexOf(lower) === 0 ;
+ });
+
+ this.active_categories = article_list.data['category']
+ .filter(function(category) {
+ return that.matching.find(function(article) {
+ return article.category === category ;
+ });
+ });
+
+ if (this.matching.length == 1) {
+ if (!backspace) {
+ this.manager.validate(this.matching[0]) ;
+ this.showAll() ;
+ } else {
+ this.manager.unset();
+ this.updateDisplay();
+ }
+ } else if (this.matching.length > 1) {
+ this.manager.unset();
+ this.updateDisplay() ;
+ if (!backspace)
+ this.updatePrefix();
+ }
+ }
+
+ updateDisplay() {
+ var article_list = this.manager.list ;
+ for (let article of article_list.data['article']) {
+ if (this.matching.indexOf(article) > -1) {
+ this._$container.find('[data-article-id='+article.id+']').show();
+ } else {
+ this._$container.find('[data-article-id='+article.id+']').hide();
+ }
+ }
+
+ for (let category of article_list.data['category']) {
+ if (this.active_categories.indexOf(category) > -1) {
+ this._$container.find('[data-category-id='+category.id+']').show();
+ } else {
+ this._$container.find('[data-category-id='+category.id+']').hide();
+ }
+ }
+ }
+
+ updatePrefix() {
+ var lower = this.matching.map(function (article) {
+ return article.name.toLowerCase() ;
+ });
+
+ lower.sort() ;
+ var first = lower[0], last = lower[lower.length-1],
+ length = first.length, i = 0;
+ while (i < length && first.charAt(i) === last.charAt(i)) i++;
+
+ this._$input.val(first.substring(0,i)) ;
+ }
+
+ showAll() {
+ this.matching = this.manager.list.data['article'];
+ this.active_categories = this.manager.list.data['category'];
+ this.updateDisplay();
+ }
+}
diff --git a/kfet/templates/kfet/kpsul.html b/kfet/templates/kfet/kpsul.html
index 6454afa9..05dff009 100644
--- a/kfet/templates/kfet/kpsul.html
+++ b/kfet/templates/kfet/kpsul.html
@@ -195,398 +195,6 @@ function functionCheck(v) {
return function(){};
}
-function restrict(obj, attr_list) {
- var restricted = {} ;
- for (let attr of attr_list) {
- restricted[attr] = obj[attr] ;
- }
- return restricted ;
-}
-
-class ArticleCategory {
-
- constructor(id, name) {
- this.id = id;
- this.name = name;
- }
-
- get id() { return this._id; }
-
- set id(v) { this._id = intCheck(v); }
-
- html(template) {
- var $template = $(template)
- $template.attr('id', 'data-category-'+this.id);
- $template.find('td').text(this.name);
- return $template ;
- }
-
- static compare(a, b) {
- return a.name.localeCompare(b.name) ;
- }
-}
-
-class Article {
-
- constructor () {
- $.extend(this, this.constructor.default_data);
- }
-
- static get default_data() {
- return {
- 'id': 0, 'name': '', 'price': 0, 'stock': 0,
- 'category': new ArticleCategory(),
- };
- }
-
- get id() { return this._id; }
- get price() { return this._price; }
- get stock() { return this._stock; }
-
- set id(v) { this._id = intCheck(v); }
- set price(v) { this._price = floatCheck(v); }
- set stock(v) { this._stock = intCheck(v); }
-
- get str_price_ukf() {
- return amountToUKF(this.price, false);
- }
-
- static get _data_stock_ok() { return ''; }
- static get _data_stock_low() { return 'low'; }
- static get _data_stock_neg() { return 'neg'; }
-
- get data_stock() {
- var stock = this.stock ;
- if (stock >= 5) { return this.constructor._data_stock_ok; }
- else if (stock >= -5) { return this.constructor._data_stock_low; }
- else /* stock < -5 */ { return this.constructor._data_stock_neg; }
- }
-
- from(data) {
- $.extend(this, this.constructor.default_data, data);
- }
-
- html(template) {
- var $template = $(template);
- $template
- .find('.name').text(this.name).end()
- .find('.price').text(this.str_price_ukf).end()
- .find('.stock').text(this.stock).end();
- $template.attr('id', 'data-article-'+this.id);
- $template.attr('data-stock', this.data_stock);
- return $template ;
- }
-
- static compare(a, b) {
- return a.name.localeCompare(b.name) ;
- }
-
- reset() {
- this.from({});
- }
-}
-
-class ArticleList {
- constructor() {
- this.articles = [];
- this.categories = [];
- }
-
- get_or_create(id, name) {
- var category = this.categories.find(c => c.id === id);
- if (!category) {
- category = new ArticleCategory(id, name);
- this.categories.push(category);
- }
- return category;
- }
-
- from(data, callback) {
- callback = functionCheck(callback);
-
- for (let article_data of data['articles']) {
- var category = this.get_or_create(article_data['category_id'], article_data['category__name']) ;
- article_data = restrict(article_data, ['name', 'price', 'stock', 'id']) ;
- article_data['category'] = category ;
-
- var article = new Article() ;
- article.from(article_data) ;
- this.articles.push(article) ;
- }
-
- callback() ;
- }
-
- fromAPI(on_success, on_error) {
- on_error = functionCheck(on_error);
- var that = this ;
- $.ajax({
- dataType: "json",
- url : "{% url 'kfet.kpsul.articles_data' %}",
- method : "GET",
- })
- .done((data) => this.from(data, on_success))
- .fail(on_error);
- }
-
- display($container, $article_template, $category_template) {
- this.categories.sort(ArticleCategory.compare) ;
- for (let cat of this.categories) {
- var cat_articles = this.articles.filter(a => a.category.id === cat.id) ;
- cat_articles.sort(Article.compare);
-
- $container.append(cat.html($category_template)) ;
- for (let art of cat_articles) {
- $container.append(art.html($article_template)) ;
- }
- }
- }
-
- clear() {
- this.articles = [];
- this.categories = [] ;
- }
-
- find_by_id(name) {
- return this.articles.find(function(a) {
- return a.name === name ;
- });
- }
-
- get_from_elt($elt) {
- var id = $elt.attr('id').split('-')[2];
-
- return this.articles.find(function(article) {
- return (article.id == id) ;
- });
- }
-}
-
-class ArticleManager {
-
- constructor(env) {
- this._env = env; // Global K-Psul Manager
-
- this._$container = $('#articles_data tbody');
- this._$input = $('#article_autocomplete');
- this._$nb = $('#article_number');
- this._category_template = ' |
';
- this._article_template = ' | | |
';
-
- this.selected = new Article() ;
- this.list = new ArticleList() ;
- this.autocomplete = new ArticleAutocomplete(this);
-
- this._init_events();
- }
-
- get nb() {
- return this._$nb.val() ;
- }
-
- display_list() {
- this.list.display(this._$container, this._article_template, this._category_template) ;
- }
-
- validate(article) {
- this.selected.from(article) ;
- this._$input.val(article.name);
- this._$nb.val('1');
- this._$nb.focus().select();
- }
-
- unset() {
- this.selected.reset();
- }
-
- is_empty() {
- return this.selected.id == 0 ;
- }
-
- reset_data() {
- this._$container.find('tr').remove();
- this.list.clear();
- this.list.fromAPI(this.display_list.bind(this)) ;
- }
-
- update_data(data) {
- for (let article_dict of data) {
- var article = this.list.articles.find(function(art) {
- return (art.id == article_dict['id']);
- });
-
- // For now, article additions are disregarded
- if (article) {
- article.stock = article_dict['stock'];
- this._$container.find('#data-article-'+article_dict['id']+' .stock')
- .text(article_dict['stock']);
- }
- }
- }
-
- reset() {
- this.unset() ;
- this._$nb.val('');
- this._$input.val('');
- this.autocomplete.showAll() ;
- }
-
- _init_events() {
- var that = this;
-
- // 8:Backspace|9:Tab|13:Enter|46:DEL|112-117:F1-6|119-123:F8-F12
- var normalKeys = /^(8|9|13|46|112|113|114|115|116|117|119|120|121|122|123)$/;
- var arrowKeys = /^(37|38|39|40)$/;
-
- //Global input event (to merge ?)
- this._$input.on('keydown', function(e) {
- if (e.keyCode == 13 && that._$input.val() == '') {
- that._env.performOperations();
- }
- });
-
- this._$container.on('click', '.article', function() {
- var article = that.list.get_from_elt($(this)) ;
- that.validate(article);
- });
-
- this._$nb.on('keydown', function(e) {
- if (e.keyCode == 13 && ArticleManager.check_nb(that.nb) && !that.is_empty()) {
- that._env.addPurchase(that.selected, that.nb);
- that.reset();
- that.focus();
- }
- if (normalKeys.test(e.keyCode) || arrowKeys.test(e.KeyCode) || e.ctrlKey) {
- if (e.ctrlKey && e.charCode == 65)
- that._$nb.val('');
- return true ;
- }
- if (ArticleManager.check_nb(that.nb+e.key))
- return true;
- return false;
-
- });
- }
-
- focus() {
- this._$input.focus();
- return this;
- }
-
- static check_nb(nb) {
- return /^[0-9]+$/.test(nb) && nb > 0 && nb <= 24 ;
- }
-}
-
-class ArticleAutocomplete {
-
- constructor(article_manager) {
- this.manager = article_manager;
- this.matching = [];
- this.active_categories = [];
- this._$container = article_manager._$container ;
- this._$input = $('#article_autocomplete');
-
- this.showAll() ;
- this._init_events();
- }
-
- _init_events() {
- var that = this ;
-
- // 8:Backspace|9:Tab|13:Enter|46:DEL|112-117:F1-6|119-123:F8-F12
- var normalKeys = /^(8|9|13|46|112|113|114|115|116|117|119|120|121|122|123)$/;
-
- this._$input
- .on('keydown', function(e) {
- var text = that._$input.val() ;
- if (normalKeys.test(e.keyCode) || e.ctrlKey) {
- // For the backspace key, we suppose the cursor is at the very end
- if(e.keyCode == 8) {
- that.update(text.substring(0, text.length-1), true);
- }
- return true ;
- }
- that.update(text+e.key, false);
-
- return false ;
-
- });
-
- }
-
- update(prefix, backspace) {
-
- var article_list = this.manager.list ;
- var lower = prefix.toLowerCase() ;
- var that = this ;
- this.matching = article_list.articles.filter(function(article) {
- return article.name.toLowerCase()
- .indexOf(lower) === 0 ;
- });
-
- this.active_categories = article_list.categories.filter(function(category) {
- return that.matching.find(function(article) {
- return article.category === category ;
- });
- });
-
- if (this.matching.length == 1) {
- if (!backspace) {
- this.manager.validate(this.matching[0]) ;
- this.showAll() ;
- } else {
- this.manager.unset();
- this.updateDisplay();
- }
- } else if (this.matching.length > 1) {
- this.manager.unset();
- this.updateDisplay() ;
- if (!backspace)
- this.updatePrefix();
- }
- }
-
- updateDisplay() {
- var article_list = this.manager.list ;
- for (let article of article_list.articles) {
- if (this.matching.indexOf(article) > -1) {
- this._$container.find('#data-article-'+article.id).show();
- } else {
- this._$container.find('#data-article-'+article.id).hide();
- }
- }
-
- for (let category of article_list.categories) {
- if (this.active_categories.indexOf(category) > -1) {
- this._$container.find('#data-category-'+category.id).show();
- } else {
- this._$container.find('#data-category-'+category.id).hide();
- }
- }
- }
-
- updatePrefix() {
- var lower = this.matching.map(function (article) {
- return article.name.toLowerCase() ;
- });
-
- lower.sort() ;
- var first = lower[0], last = lower[lower.length-1],
- length = first.length, i = 0;
- while (i < length && first.charAt(i) === last.charAt(i)) i++;
-
- this._$input.val(first.substring(0,i)) ;
- }
-
- showAll() {
- this.matching = this.manager.list.articles;
- this.active_categories = this.manager.list.categories;
- this.updateDisplay();
- }
-}
-
-
$(document).ready(function() {
'use strict';
// -----
@@ -748,206 +356,11 @@ $(document).ready(function() {
// Articles data
// -----
- var articles_container = $('#articles_data tbody');
- var article_category_default_html = ' |
';
- var article_default_html = ' | | |
';
-
- function addArticle(article) {
- var article_html = $(article_default_html);
- article_html.attr('id', 'data-article-'+article['id']);
- article_html.addClass('data-category-'+article['category_id']);
- for (var elem in article) {
- article_html.find('.'+elem).text(article[elem])
- }
- article_html.find('.price').text(amountToUKF(article['price'], false));
- var category_html = articles_container
- .find('#data-category-'+article['category_id']);
- if (category_html.length == 0) {
- category_html = $(article_category_default_html);
- category_html.attr('id', 'data-category-'+article['category_id']);
- category_html.find('td').text(article['category__name']);
- var added = false;
- articles_container.find('.category').each(function() {
- if (article['category__name'].toLowerCase() < $(this).text().toLowerCase()) {
- $(this).before(category_html);
- added = true;
- return false;
- }
- });
- if (!added) articles_container.append(category_html);
- }
- var $after = articles_container.find('#data-category-'+article['category_id']);
- articles_container
- .find('.article.data-category-'+article['category_id']).each(function() {
- if (article['name'].toLowerCase < $('.name', this).text().toLowerCase())
- return false;
- $after = $(this);
- });
- $after.after(article_html);
- // Pour l'autocomplétion
- articlesList.push([article['name'],article['id'],article['category_id'],article['price']]);
- }
-
- function getArticles() {
- $.ajax({
- dataType: "json",
- url : "{% url 'kfet.kpsul.articles_data' %}",
- method : "GET",
- })
- .done(function(data) {
- for (var i=0; i -1) {
- articles_container.find('#data-article-'+articlesList[i][1]).show();
- if (categories_to_display.indexOf(articlesList[i][2]) == -1)
- categories_to_display.push(articlesList[i][2]);
- } else {
- articles_container.find('#data-article-'+articlesList[i][1]).hide();
- }
- }
- articles_container.find('.category').hide();
- for (var i=0; i 1) {
- articleId.val(0);
- if (commit)
- articleSelect.val(sharedPrefix(articlesMatch));
- displayMatchedArticles(articlesMatch);
- }
- return false;
- }
-
- // A utiliser après la sélection d'un article
- function goToArticleNb() {
- articleNb.val('1');
- articleNb.focus().select();
- }
-
- articleSelect.on('keydown', function(e) {
- var text = articleSelect.val();
- // Comportement normal pour ces touches
- if (normalKeys.test(e.keyCode) || e.ctrlKey) {
- if (text == '' && e.keyCode == 13)
- performOperations();
- if (e.keyCode == 8)
- updateMatchedArticles(text.substring(0,text.length-1), false);
- if (e.charCode == 65 && e.ctrlKey) {
- articleId.val(0);
- articleSelect.val('');
- }
- return true;
- }
- if (updateMatchedArticles(text+e.key))
- goToArticleNb();
- return false;
- });
-
- function getArticleId($article) {
- return $article.attr('id').split('-')[2];
- }
-
- function getArticleName($article) {
- return $article.find('.name').text();
- }
-
- // Sélection des articles à la souris/tactile
- articles_container.on('click', '.article', function() {
- articleId.val(getArticleId($(this)));
- articleSelect.val(getArticleName($(this)));
- displayMatchedArticles(articlesList);
- goToArticleNb();
- });
-
- function is_nb_ok(nb) {
- return /^[0-9]+$/.test(nb) && nb > 0 && nb <= 24;
- }
-
- articleNb.on('keydown', function(e) {
- if (e.keyCode == 13 && is_nb_ok(articleNb.val()) && articleId.val() > 0) {
- addPurchase(articleId.val(), articleNb.val());
- articleSelect.val('');
- articleNb.val('');
- articleSelect.focus();
- displayMatchedArticles(articlesList);
- return false;
- }
- if (normalKeys.test(e.keyCode) || arrowKeys.test(e.keyCode) || e.keyCode == 8 || e.ctrlKey) {
- if (e.ctrlKey && e.charCode == 65)
- articleNb.val('');
- return true;
- }
- var nb = articleNb.val()+e.key;
- if (is_nb_ok(nb))
- return true;
- return false;
- });
-
// -----
// Basket
// -----
@@ -956,8 +369,8 @@ $(document).ready(function() {
var basket_container = $('#basket table');
var arrowKeys = /^(37|38|39|40)$/;
- function amountEuroPurchase(article_data, nb) {
- var amount_euro = - article_data[3] * nb ;
+ function amountEuroPurchase(article, nb) {
+ var amount_euro = - article.price * nb ;
if (Config.get('addcost_for') && Config.get('addcost_amount') && account_manager.account.trigramme != Config.get('addcost_for'))
amount_euro -= Config.get('addcost_amount') * nb;
var reduc_divisor = 1;
@@ -966,19 +379,15 @@ $(document).ready(function() {
return amount_euro / reduc_divisor;
}
- function addPurchase(id, nb) {
+ function addPurchase(article, nb) {
- var i = 0;
- while (i