From 05156f37c659239a123e36091bee3a8a273f68ed Mon Sep 17 00:00:00 2001 From: Ludovic Stephan Date: Tue, 4 Apr 2017 19:34:22 -0300 Subject: [PATCH 01/12] Update addExistingPurchase --- kfet/static/kfet/js/kpsul.js | 13 ++++++++----- kfet/templates/kfet/kpsul.html | 15 ++++++--------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/kfet/static/kfet/js/kpsul.js b/kfet/static/kfet/js/kpsul.js index f8270855..374068f3 100644 --- a/kfet/static/kfet/js/kpsul.js +++ b/kfet/static/kfet/js/kpsul.js @@ -417,16 +417,19 @@ class ArticleManager { this.list.fromAPI({}, this.display_list.bind(this), $.noop) ; } - //TODO: filter articles before ? + get_article(id) { + return this.list.find('article', id).content; + } + update_data(data) { for (let article_dict of data.articles) { - var article = this.list.find('article', article_dict['id']); + var article = this.get_article(article_dict.id); // For now, article additions are disregarded if (article) { - article.stock = article_dict['stock']; - this._$container.find('#article-'+article_dict['id']+' .stock') - .text(article_dict['stock']); + article.stock = article_dict.stock; + this._$container.find('#article-'+article.id+' .stock') + .text(article.stock); } } } diff --git a/kfet/templates/kfet/kpsul.html b/kfet/templates/kfet/kpsul.html index 493a9e97..dd7d4cdb 100644 --- a/kfet/templates/kfet/kpsul.html +++ b/kfet/templates/kfet/kpsul.html @@ -464,15 +464,12 @@ $(document).ready(function() { function addExistingPurchase(opeindex, nb) { var type = formset_container.find("#id_form-"+opeindex+"-type").val(); var id = formset_container.find("#id_form-"+opeindex+"-article").val(); + var article = kpsul.article_manager.get_article(parseInt(id)); var nb_before = formset_container.find("#id_form-"+opeindex+"-article_nb").val(); var nb_after = parseInt(nb_before) + parseInt(nb); - var amountEuro_after = amountEuroPurchase(id, nb_after); + var amountEuro_after = amountEuroPurchase(article, nb_after); var amountUKF_after = amountToUKF(amountEuro_after, kpsul.account_manager.account.is_cof, false); - var i = 0; - while (i 0) { var article_html = basket_container.find('[data-opeindex='+opeindex+']'); article_html.find('.amount').text(amountUKF_after).end() - .find('.number').text('('+nb_after+'/'+article_data[4]+')').end() ; + .find('.number').text('('+nb_after+'/'+article.stock+')').end() ; } else { article_html = $(item_basket_default_html); article_html .attr('data-opeindex', opeindex) - .find('.number').text('('+nb_after+'/'+article_data[4]+')').end() - .find('.name').text(article_data[0]).end() + .find('.number').text('('+nb_after+'/'+article.stock+')').end() + .find('.name').text(article.name).end() .find('.amount').text(amountUKF_after); basket_container.prepend(article_basket_html); } - if (is_low_stock(id, nb_after)) + if (is_low_stock(article, nb_after)) article_html.find('.lowstock') .show(); else From e5791efe4df211fdac77f43c43c3ca2a5a824fa1 Mon Sep 17 00:00:00 2001 From: Ludovic Stephan Date: Tue, 4 Apr 2017 19:41:15 -0300 Subject: [PATCH 02/12] Remove last traces of old articles --- kfet/static/kfet/js/kpsul.js | 10 +++++++--- kfet/templates/kfet/kpsul.html | 27 ++++++--------------------- 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/kfet/static/kfet/js/kpsul.js b/kfet/static/kfet/js/kpsul.js index 374068f3..12a80d94 100644 --- a/kfet/static/kfet/js/kpsul.js +++ b/kfet/static/kfet/js/kpsul.js @@ -85,7 +85,7 @@ class AccountManager { $('#id_on_acc').val(this.account.id); this.display(); - kpsul._env.articleSelect.focus(); + kpsul.article_manager.focus(); kpsul._env.updateBasketAmount(); kpsul._env.updateBasketRel(); } @@ -268,7 +268,7 @@ class CheckoutManager { if (kpsul.account_manager.is_empty()) { kpsul.account_manager.focus(); } else { - kpsul._env.articleSelect.focus().select(); + kpsul.article_manager.focus(); } } @@ -482,7 +482,11 @@ class ArticleManager { } focus() { - this._$input.focus(); + if this.is_empty() + this._$input.focus(); + else + this._$nb.focus(); + return this; } diff --git a/kfet/templates/kfet/kpsul.html b/kfet/templates/kfet/kpsul.html index dd7d4cdb..283c4692 100644 --- a/kfet/templates/kfet/kpsul.html +++ b/kfet/templates/kfet/kpsul.html @@ -191,7 +191,7 @@ $(document).ready(function() { commentDialog.open({ callback: confirm_callback, - next_focus: articleSelect + next_focus: kpsul.article_manager; }); } @@ -237,7 +237,7 @@ $(document).ready(function() { else displayErrors(getErrorsHtml(response)); }, - next_focus: articleSelect, + next_focus: kpsul.article_manager, }); } @@ -273,15 +273,6 @@ $(document).ready(function() { cancelOperations(); }); - // ----- - // Articles data - // ----- - - var articleSelect = $('#article_autocomplete'); - var articleId = $('#article_id'); - var articleNb = $('#article_number'); - var articlesList = []; - // ----- // Basket // ----- @@ -527,11 +518,9 @@ $(document).ready(function() { addDeposit(amount); } - var next_focus = articleSelect.val() ? articleNb : articleSelect ; - depositDialog.open({ callback: callback, - next_focus: next_focus, + next_focus: kpsul.article_manager, }); } @@ -547,11 +536,9 @@ $(document).ready(function() { addEdit(amount); } - var next_focus = articleSelect.val() ? articleNb : articleSelect ; - editDialog.open({ callback: callback, - next_focus: next_focus, + next_focus: kpsul.article_manager, }); } @@ -567,11 +554,9 @@ $(document).ready(function() { addWithdraw(amount); } - var next_focus = articleSelect.val() ? articleNb : articleSelect ; - withdrawDialog.open({ callback: callback, - next_focus: next_focus, + next_focus: kpsul.article_manager, }); } @@ -862,7 +847,7 @@ $(document).ready(function() { } else { // F2 - Basket reset resetBasket(); - articleSelect.focus(); + kpsul.article_manager.focus(); } return false; case 114: From cb28b928c42f68f146ce484e1e21aa5fd1b3ab11 Mon Sep 17 00:00:00 2001 From: Ludovic Stephan Date: Tue, 4 Apr 2017 19:42:30 -0300 Subject: [PATCH 03/12] Remove articleSelect from _env --- kfet/templates/kfet/kpsul.html | 1 - 1 file changed, 1 deletion(-) diff --git a/kfet/templates/kfet/kpsul.html b/kfet/templates/kfet/kpsul.html index 283c4692..2db6a54e 100644 --- a/kfet/templates/kfet/kpsul.html +++ b/kfet/templates/kfet/kpsul.html @@ -879,7 +879,6 @@ $(document).ready(function() { // ----- var env = { - articleSelect: articleSelect, addPurchase: addPurchase, updateBasketAmount: updateBasketAmount, updateBasketRel: updateBasketRel, From 021937a38e86791d11e5e5f83a932c5d8eca1bad Mon Sep 17 00:00:00 2001 From: Ludovic Stephan Date: Tue, 4 Apr 2017 19:52:12 -0300 Subject: [PATCH 04/12] Small bugfixes --- kfet/static/kfet/js/kpsul.js | 2 +- kfet/templates/kfet/kpsul.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kfet/static/kfet/js/kpsul.js b/kfet/static/kfet/js/kpsul.js index 12a80d94..30197b9f 100644 --- a/kfet/static/kfet/js/kpsul.js +++ b/kfet/static/kfet/js/kpsul.js @@ -482,7 +482,7 @@ class ArticleManager { } focus() { - if this.is_empty() + if (this.is_empty()) this._$input.focus(); else this._$nb.focus(); diff --git a/kfet/templates/kfet/kpsul.html b/kfet/templates/kfet/kpsul.html index 2db6a54e..c1243d4a 100644 --- a/kfet/templates/kfet/kpsul.html +++ b/kfet/templates/kfet/kpsul.html @@ -191,7 +191,7 @@ $(document).ready(function() { commentDialog.open({ callback: confirm_callback, - next_focus: kpsul.article_manager; + next_focus: kpsul.article_manager, }); } From 9c559d9ec33d630627486e2d3a7a8c32df81509e Mon Sep 17 00:00:00 2001 From: Ludovic Stephan Date: Tue, 4 Apr 2017 19:54:03 -0300 Subject: [PATCH 05/12] Add articles reset to kpsul.reset --- kfet/static/kfet/js/kpsul.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kfet/static/kfet/js/kpsul.js b/kfet/static/kfet/js/kpsul.js index 30197b9f..972f93c3 100644 --- a/kfet/static/kfet/js/kpsul.js +++ b/kfet/static/kfet/js/kpsul.js @@ -11,9 +11,11 @@ class KPsulManager { soft = soft || false; this.account_manager.reset(); + this.article_manager.reset(); if (!soft) { this.checkout_manager.reset(); + this.article_manager.reset_data(); } } From 3b9affb3f32e9a6e08866962be53d95f47f1081e Mon Sep 17 00:00:00 2001 From: Ludovic Stephan Date: Tue, 4 Apr 2017 20:18:53 -0300 Subject: [PATCH 06/12] Add focus methods --- kfet/static/kfet/js/kpsul.js | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/kfet/static/kfet/js/kpsul.js b/kfet/static/kfet/js/kpsul.js index 972f93c3..0027543e 100644 --- a/kfet/static/kfet/js/kpsul.js +++ b/kfet/static/kfet/js/kpsul.js @@ -19,6 +19,17 @@ class KPsulManager { } } + focus() { + if (this.checkout_manager.is_empty()) + this.checkout_manager.focus(); + else if (this.account_manager.is_empty()) + this.account_manager.focus(); + else + this.article_manager.focus(); + + return this; + } + } @@ -267,11 +278,7 @@ class CheckoutManager { (data) => this._update_on_success(data), () => this.reset_data()); - if (kpsul.account_manager.is_empty()) { - kpsul.account_manager.focus(); - } else { - kpsul.article_manager.focus(); - } + kpsul.focus(); } _update_on_success(data) { @@ -336,6 +343,11 @@ class CheckoutManager { this.display(); } + + focus() { + this.selection.focus(); + return this; + } } @@ -368,6 +380,11 @@ class CheckoutSelection { reset() { this._$input.find('option:first').prop('selected', true); } + + focus() { + this._$input.focus(); + return this; + } } class ArticleManager { From efbcde163b661b47f083df679f8843959a30ef3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Delobelle?= Date: Wed, 5 Apr 2017 03:43:51 +0200 Subject: [PATCH 07/12] clean some js - clean buttons code on account and checkout - merge CheckoutRead and kpsul_checkout_data views (the first won) APIModelObject interface - add url_create, url_update, url_update_for - rename url_object_for and url_object to url_read_for and url_read --- kfet/static/kfet/js/kfet.api.js | 54 +++++++++++++---- kfet/static/kfet/js/kfet.js | 23 +++++++ kfet/static/kfet/js/kpsul.js | 51 +++++++++++----- kfet/templates/kfet/kpsul.html | 2 - kfet/urls.py | 2 - kfet/views.py | 104 +++++++++++++++++--------------- 6 files changed, 155 insertions(+), 81 deletions(-) diff --git a/kfet/static/kfet/js/kfet.api.js b/kfet/static/kfet/js/kfet.api.js index 6b1f8fe3..2418195d 100644 --- a/kfet/static/kfet/js/kfet.api.js +++ b/kfet/static/kfet/js/kfet.api.js @@ -130,13 +130,28 @@ class APIModelObject extends ModelObject { */ static get url_model() {} + /** + * Request url to create an instance. + * @abstract + * @type {string} + */ + static url_create() {} + + /** + * Request url to edit an instance of this model. + * @abstract + * @param {*} api_pk - Identifier of a model instance. + * @type {string} + */ + static url_update_for(api_pk) {} + /** * Request url to get a single model instance data. * @abstract - * @param {*} api_pk - Identifier of a model instance in api requests. + * @param {*} api_pk - Identifier of a model instance. * @return {string} */ - static url_object_for(api_pk) {} + static url_read_for(api_pk) {} /** * See {@link Models.ModelObject|new ModelObject(data)}. @@ -158,17 +173,17 @@ class APIModelObject extends ModelObject { /** * Request url used to get current instance data. */ - get url_object() { + get url_read() { if (this._url_object === undefined) - return this.is_empty() ? '' : this.constructor.url_object_for(this.api_pk); + return this.is_empty() ? '' : this.constructor.url_read_for(this.api_pk); return this._url_object; } - set url_object(v) { this._url_object = v; } + set url_read(v) { this._url_object = v; } /** * Get data of a distant model instance. It sends a GET HTTP request to - * {@link Models.APIModelObject#url_object}. + * {@link Models.APIModelObject#url_read}. * @param {object} [api_options] Additional data appended to the request. * @param {jQueryAjaxSuccess} [on_success] A function to be called if the request succeeds. * @param {jQueryAjaxError} [on_error] A function to be called if the request fails. @@ -182,7 +197,7 @@ class APIModelObject extends ModelObject { api_options['format'] = 'json'; - $.getJSON(this.url_object, api_options) + $.getJSON(this.url_read, api_options) .done(function (json, textStatus, jqXHR) { that.from(json); on_success(json, textStatus, jqXHR); @@ -199,7 +214,7 @@ class APIModelObject extends ModelObject { * @see {@link Models.APIModelObject#fromAPI|fromAPI} */ get_by_apipk(api_pk, api_options, on_success, on_error) { - this.url_object = this.constructor.url_object_for(api_pk); + this.url_read = this.constructor.url_read_for(api_pk); this.fromAPI(api_options, on_success, on_error); } @@ -260,12 +275,21 @@ class Account extends APIModelObject { */ static get url_model() { return Urls['kfet.account'](); } + static url_create(trigramme) { + var url = Urls['kfet.account.create'](); + if (trigramme) { + var trigramme_url = encodeURIComponent(trigramme); + url += `?trigramme=${trigramme_url}` + } + return url; + } + /** * @default django-js-reverse('kfet.account.read')(trigramme) * @param {string} trigramme - * @see {@link Models.APIModelObject.url_object_for|APIModelObject.url_object_for} + * @see {@link Models.APIModelObject.url_read_for|APIModelObject.url_read_for} */ - static url_object_for(trigramme) { + static url_read_for(trigramme) { var trigramme_url = encodeURIComponent(trigramme); return Urls['kfet.account.read'](trigramme_url); } @@ -332,10 +356,10 @@ class Checkout extends APIModelObject { /** * @default django-js-reverse('kfet.kpsul.checkout_data.read')(pk) * @param {string} api_pk - a checkout id - * @see {@link Models.APIModelObject.url_object_for|APIModelObject.url_object_for} + * @see {@link Models.APIModelObject.url_read_for|APIModelObject.url_read_for} */ - static url_object_for(api_pk) { - return Urls['kfet.kpsul.checkout_data.read'](api_pk); + static url_read_for(api_pk) { + return Urls['kfet.checkout.read'](api_pk); } /** @@ -381,6 +405,10 @@ class Statement extends ModelObject { }; } + static url_create(checkout_pk) { + return Urls['kfet.checkoutstatement.create'](checkout_pk); + } + /** * @default {@link Formatters.StatementFormatter} */ diff --git a/kfet/static/kfet/js/kfet.js b/kfet/static/kfet/js/kfet.js index 6155d3ed..63f9b939 100644 --- a/kfet/static/kfet/js/kfet.js +++ b/kfet/static/kfet/js/kfet.js @@ -40,6 +40,29 @@ function booleanCheck(v) { } +/** + * Short: Equivalent to python str format. + * Source: [MDN]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals}. + * @example + * var t1Closure = template`${0}${1}${0}!`; + * t1Closure('Y', 'A'); // "YAY!" + * @example + * var t2Closure = template`${0} ${'foo'}!`; + * t2Closure('Hello', {foo: 'World'}); // "Hello World!" + */ +function template(strings, ...keys) { + return (function(...values) { + var dict = values[values.length - 1] || {}; + var result = [strings[0]]; + keys.forEach(function(key, i) { + var value = Number.isInteger(key) ? values[key] : dict[key]; + result.push(value, strings[i + 1]); + }); + return result.join(''); + }); +} + + /** * Get and store K-Psul config from API. *

diff --git a/kfet/static/kfet/js/kpsul.js b/kfet/static/kfet/js/kpsul.js index 6052ad56..1917c53e 100644 --- a/kfet/static/kfet/js/kpsul.js +++ b/kfet/static/kfet/js/kpsul.js @@ -1,3 +1,10 @@ +/** + * @file K-Psul JS + * @copyright 2017 cof-geek + * @license MIT + */ + + class KPsulManager { constructor(env) { @@ -27,6 +34,15 @@ class AccountManager { this.account = new Account(); this.selection = new AccountSelection(this); this.search = new AccountSearch(this); + + // buttons: search, read or create + this.$buttons_container = this._$container.find('.buttons'); + this.buttons_templates = { + create: template``, + read: template``, + search: template``, + } + } is_empty() { return this.account.is_empty(); } @@ -43,25 +59,22 @@ class AccountManager { } _display_buttons() { - // dirty - - var buttons = ''; + var buttons; if (this.is_empty()) { var trigramme = this.selection.get(); if (trigramme.isValidTri()) { - var url_base = Urls['kfet.account.create'](); - var url = url_base + '?trigramme=' + encodeURIComponent(trigramme); - buttons += ''; + var url = Account.url_create(trigramme); + buttons = this.buttons_templates.create({url: url}); } else { /* trigramme input is empty or invalid */ - buttons += ''; + buttons = this.buttons_templates.search(); } } else { /* an account is loaded */ - var url = this.account.url_object; - buttons += ''; + var url = this.account.url_read; + buttons = this.buttons_templates.read({url: url}); } - this._$container.find('.buttons').html(buttons); + this.$buttons_container.html(buttons); } update(trigramme) { @@ -248,6 +261,12 @@ class CheckoutManager { this._$laststatement_container = $('#last_statement'); this.laststatement = new Statement(); this.laststatement_display_prefix = '#checkout-last_statement_'; + + this.$buttons_container = this._$container.find('.buttons'); + this.buttons_templates = { + read: template``, + statement_create: template``, + } } update(id) { @@ -308,13 +327,13 @@ class CheckoutManager { _display_buttons() { var buttons = ''; if (!this.is_empty()) { - var id = this.checkout.id; - var url_details = Urls['kfet.checkout.read'](id); - var url_newcheckout = Urls['kfet.checkoutstatement.create'](id); - buttons += ''; - buttons += ''; + var url_newcheckout = Statement.url_create(this.checkout.id); + buttons += this.buttons_templates.statement_create({ + url: url_newcheckout}); + var url_read = this.checkout.url_read; + buttons += this.buttons_templates.read({url: url_read}); } - this._$container.find('.buttons').html(buttons); + this.$buttons_container.html(buttons); } reset() { diff --git a/kfet/templates/kfet/kpsul.html b/kfet/templates/kfet/kpsul.html index 8e010396..7b74021f 100644 --- a/kfet/templates/kfet/kpsul.html +++ b/kfet/templates/kfet/kpsul.html @@ -529,9 +529,7 @@ $(document).ready(function() { }); if (!existing) { var amount_euro = amountEuroPurchase(id, nb).toFixed(2); - console.log(amount_euro); var index = addPurchaseToFormset(article_data[1], nb, amount_euro); - console.log(index); var article_basket_html = $(item_basket_default_html); article_basket_html .attr('data-opeindex', index) diff --git a/kfet/urls.py b/kfet/urls.py index bec39516..60f6545b 100644 --- a/kfet/urls.py +++ b/kfet/urls.py @@ -169,8 +169,6 @@ urlpatterns = [ # ----- url('^k-psul/$', views.kpsul, name='kfet.kpsul'), - url(r'^k-psul/checkout_data/(?P\d+)$', views.kpsul_checkout_data, - name='kfet.kpsul.checkout_data.read'), url('^k-psul/perform_operations$', views.kpsul_perform_operations, name='kfet.kpsul.perform_operations'), url('^k-psul/cancel_operations$', views.kpsul_cancel_operations, diff --git a/kfet/views.py b/kfet/views.py index 1545f76d..cc69dcda 100644 --- a/kfet/views.py +++ b/kfet/views.py @@ -52,6 +52,33 @@ from .statistic import daynames, monthnames, weeknames, \ this_morning, this_monday_morning, this_first_month_day, \ tot_ventes + +# source : docs.djangoproject.com/fr/1.10/topics/class-based-views/mixins/ +class JSONResponseMixin(object): + """ + A mixin that can be used to render a JSON response. + """ + def render_to_json_response(self, context, **response_kwargs): + """ + Returns a JSON response, transforming 'context' to make the payload. + """ + print(context) + return JsonResponse( + self.get_data(context), + **response_kwargs + ) + + def get_data(self, context): + """ + Returns an object that will be serialized as JSON by json.dumps(). + """ + # Note: This is *EXTREMELY* naive; in reality, you'll need + # to do much more complex handling to ensure that arbitrary + # objects -- such as Django model instances or querysets + # -- can be serialized as JSON. + return context + + class Home(TemplateView): template_name = "kfet/home.html" @@ -618,18 +645,44 @@ class CheckoutCreate(SuccessMessageMixin, CreateView): return super(CheckoutCreate, self).form_valid(form) + # Checkout - Read -class CheckoutRead(DetailView): +class CheckoutRead(JSONResponseMixin, DetailView): model = Checkout template_name = 'kfet/checkout_read.html' context_object_name = 'checkout' def get_context_data(self, **kwargs): - context = super(CheckoutRead, self).get_context_data(**kwargs) - context['statements'] = context['checkout'].statements.order_by('-at') + context = super().get_context_data(**kwargs) + checkout = self.object + if self.request.GET.get('last_statement'): + context['laststatement'] = checkout.statements.latest('at') + else: + context['statements'] = checkout.statements.order_by('-at') return context + def render_to_response(self, context, **kwargs): + if self.request.GET.get('format') == 'json': + data = model_to_dict( + context['checkout'], + fields=['id', 'name', 'balance', 'valid_from', 'valid_to'] + ) + if 'laststatement' in context: + last_statement = context['laststatement'] + last_statement_data = model_to_dict( + last_statement, + fields=['id', 'at', 'balance_new', 'balance_old', 'by'] + ) + last_statement_data['by'] = str(last_statement.by) + # ``at`` is not editable, so skipped by ``model_to_dict`` + last_statement_data['at'] = last_statement.at + data['laststatement'] = last_statement_data + return self.render_to_json_response(data) + else: + return super().render_to_response(context, **kwargs) + + # Checkout - Update class CheckoutUpdate(SuccessMessageMixin, UpdateView): @@ -897,28 +950,6 @@ def kpsul_get_settings(request): return JsonResponse(data) -@teamkfet_required -def kpsul_checkout_data(request, pk): - checkout = get_object_or_404(Checkout, pk=pk) - data = model_to_dict( - checkout, - fields=['id', 'name', 'balance', 'valid_from', 'valid_to'] - ) - - if request.GET.get('last_statement'): - last_statement = checkout.statements.latest('at') - last_statement_data = model_to_dict( - last_statement, - fields=['id', 'at', 'balance_new', 'balance_old', 'by'] - ) - last_statement_data['by'] = str(last_statement.by) - # ``at`` is not editable, so skipped by ``model_to_dict`` - last_statement_data['at'] = last_statement.at - data['laststatement'] = last_statement_data - - return JsonResponse(data) - - @teamkfet_required def kpsul_update_addcost(request): addcost_form = AddcostForm(request.POST) @@ -2003,29 +2034,6 @@ class SupplierUpdate(SuccessMessageMixin, UpdateView): # --------------- # Vues génériques # --------------- -# source : docs.djangoproject.com/fr/1.10/topics/class-based-views/mixins/ -class JSONResponseMixin(object): - """ - A mixin that can be used to render a JSON response. - """ - def render_to_json_response(self, context, **response_kwargs): - """ - Returns a JSON response, transforming 'context' to make the payload. - """ - return JsonResponse( - self.get_data(context), - **response_kwargs - ) - - def get_data(self, context): - """ - Returns an object that will be serialized as JSON by json.dumps(). - """ - # Note: This is *EXTREMELY* naive; in reality, you'll need - # to do much more complex handling to ensure that arbitrary - # objects -- such as Django model instances or querysets - # -- can be serialized as JSON. - return context class JSONDetailView(JSONResponseMixin, From f1aaad7317b554d7813f2cf9b076ff96768d818f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Delobelle?= Date: Wed, 5 Apr 2017 04:05:31 +0200 Subject: [PATCH 08/12] Better jquery ajax calls management It becomes the same as the original jQuery ajax object. For example, callbacks can be queued. get_by_apipk and from_API of ModelObject returns the ajax object. Example (js): Account.get_by_apipk('AAA') .done(function (data) { console.log(data) }) .fail( () => console.log('cool') ) ... .done( ... --- kfet/static/kfet/js/kfet.api.js | 20 +++++--------------- kfet/static/kfet/js/kpsul.js | 13 ++++++------- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/kfet/static/kfet/js/kfet.api.js b/kfet/static/kfet/js/kfet.api.js index 2418195d..bfadc4dd 100644 --- a/kfet/static/kfet/js/kfet.api.js +++ b/kfet/static/kfet/js/kfet.api.js @@ -185,24 +185,14 @@ class APIModelObject extends ModelObject { * Get data of a distant model instance. It sends a GET HTTP request to * {@link Models.APIModelObject#url_read}. * @param {object} [api_options] Additional data appended to the request. - * @param {jQueryAjaxSuccess} [on_success] A function to be called if the request succeeds. - * @param {jQueryAjaxError} [on_error] A function to be called if the request fails. */ - fromAPI(api_options, on_success, on_error) { - var that = this; - + fromAPI(api_options) { api_options = api_options || {}; - on_success = on_success || $.noop; - on_error = on_error || $.noop; api_options['format'] = 'json'; - $.getJSON(this.url_read, api_options) - .done(function (json, textStatus, jqXHR) { - that.from(json); - on_success(json, textStatus, jqXHR); - }) - .fail(on_error); + return $.getJSON(this.url_read, api_options) + .done( (json) => this.from(json) ); } /** @@ -213,9 +203,9 @@ class APIModelObject extends ModelObject { * @param {jQueryAjaxError} [on_error] * @see {@link Models.APIModelObject#fromAPI|fromAPI} */ - get_by_apipk(api_pk, api_options, on_success, on_error) { + get_by_apipk(api_pk, api_options) { this.url_read = this.constructor.url_read_for(api_pk); - this.fromAPI(api_options, on_success, on_error); + return this.fromAPI(api_options); } /** diff --git a/kfet/static/kfet/js/kpsul.js b/kfet/static/kfet/js/kpsul.js index 1917c53e..f9aa8e23 100644 --- a/kfet/static/kfet/js/kpsul.js +++ b/kfet/static/kfet/js/kpsul.js @@ -84,10 +84,9 @@ class AccountManager { trigramme = trigramme || this.selection.get(); if (trigramme.isValidTri()) { - this.account.get_by_apipk(trigramme, {}, - () => this._update_on_success(), - () => this.reset_data() - ); + this.account.get_by_apipk(trigramme) + .done( () => this._update_on_success() ) + .fail( () => this.reset_data() ); } else { this.reset_data(); } @@ -279,9 +278,9 @@ class CheckoutManager { 'last_statement': true, }; - this.checkout.get_by_apipk(id, api_options, - (data) => this._update_on_success(data), - () => this.reset_data()); + this.checkout.get_by_apipk(id, api_options) + .done( (data) => this._update_on_success(data) ) + .fail( () => this.reset_data() ); if (kpsul.account_manager.is_empty()) { kpsul.account_manager.focus(); From 6be6202b3fe9c3dc1e6d377f240d52941b15a281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Delobelle?= Date: Wed, 5 Apr 2017 04:26:50 +0200 Subject: [PATCH 09/12] few cleans --- kfet/static/kfet/js/kfet.api.js | 9 +++++++++ kfet/static/kfet/js/kpsul.js | 22 +++++++++++----------- kfet/views.py | 1 - 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/kfet/static/kfet/js/kfet.api.js b/kfet/static/kfet/js/kfet.api.js index bfadc4dd..dd5d011b 100644 --- a/kfet/static/kfet/js/kfet.api.js +++ b/kfet/static/kfet/js/kfet.api.js @@ -284,6 +284,11 @@ class Account extends APIModelObject { return Urls['kfet.account.read'](trigramme_url); } + static url_update_for(trigramme) { + var trigramme_url = encodeURIComponent(trigramme); + return Urls['kfet.account.update'](trigramme_url); + } + /** * @default this.trigramme */ @@ -352,6 +357,10 @@ class Checkout extends APIModelObject { return Urls['kfet.checkout.read'](api_pk); } + static url_update_for(api_pk) { + return Urls['kfet.checkout.update'](api_pk); + } + /** * @default {@link Formatters.CheckoutFormatter} */ diff --git a/kfet/static/kfet/js/kpsul.js b/kfet/static/kfet/js/kpsul.js index f9aa8e23..c4052d73 100644 --- a/kfet/static/kfet/js/kpsul.js +++ b/kfet/static/kfet/js/kpsul.js @@ -36,8 +36,8 @@ class AccountManager { this.search = new AccountSearch(this); // buttons: search, read or create - this.$buttons_container = this._$container.find('.buttons'); - this.buttons_templates = { + this._$buttons_container = this._$container.find('.buttons'); + this._buttons_templates = { create: template``, read: template``, search: template``, @@ -65,16 +65,16 @@ class AccountManager { var trigramme = this.selection.get(); if (trigramme.isValidTri()) { var url = Account.url_create(trigramme); - buttons = this.buttons_templates.create({url: url}); + buttons = this._buttons_templates['create']({url: url}); } else { /* trigramme input is empty or invalid */ - buttons = this.buttons_templates.search(); + buttons = this._buttons_templates['search'](); } } else { /* an account is loaded */ var url = this.account.url_read; - buttons = this.buttons_templates.read({url: url}); + buttons = this._buttons_templates['read']({url: url}); } - this.$buttons_container.html(buttons); + this._$buttons_container.html(buttons); } update(trigramme) { @@ -261,8 +261,8 @@ class CheckoutManager { this.laststatement = new Statement(); this.laststatement_display_prefix = '#checkout-last_statement_'; - this.$buttons_container = this._$container.find('.buttons'); - this.buttons_templates = { + this._$buttons_container = this._$container.find('.buttons'); + this._buttons_templates = { read: template``, statement_create: template``, } @@ -327,12 +327,12 @@ class CheckoutManager { var buttons = ''; if (!this.is_empty()) { var url_newcheckout = Statement.url_create(this.checkout.id); - buttons += this.buttons_templates.statement_create({ + buttons += this._buttons_templates['statement_create']({ url: url_newcheckout}); var url_read = this.checkout.url_read; - buttons += this.buttons_templates.read({url: url_read}); + buttons += this._buttons_templates['read']({url: url_read}); } - this.$buttons_container.html(buttons); + this._$buttons_container.html(buttons); } reset() { diff --git a/kfet/views.py b/kfet/views.py index cc69dcda..a2e4ca17 100644 --- a/kfet/views.py +++ b/kfet/views.py @@ -62,7 +62,6 @@ class JSONResponseMixin(object): """ Returns a JSON response, transforming 'context' to make the payload. """ - print(context) return JsonResponse( self.get_data(context), **response_kwargs From 2e0de75471a53c799d5c8153177eef7c40225c8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Delobelle?= Date: Wed, 5 Apr 2017 13:18:01 +0200 Subject: [PATCH 10/12] kpsul - fix account balance ukf --- kfet/static/kfet/js/kfet.api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kfet/static/kfet/js/kfet.api.js b/kfet/static/kfet/js/kfet.api.js index dd5d011b..6adc1133 100644 --- a/kfet/static/kfet/js/kfet.api.js +++ b/kfet/static/kfet/js/kfet.api.js @@ -309,7 +309,7 @@ class Account extends APIModelObject { /** * Balance converted to UKF according to cof status. */ - get balance_ukf() { return amountToUKF(this.balance, this.is_cof); } + get balance_ukf() { return amountToUKF(this.balance, this.is_cof, true); } } From a29de134f165be6ca072f70fbcd62663c5444bcf Mon Sep 17 00:00:00 2001 From: Ludovic Stephan Date: Wed, 5 Apr 2017 08:58:46 -0300 Subject: [PATCH 11/12] Move focus ; move is_low_stock to method --- kfet/static/kfet/js/kfet.api.js | 4 ++++ kfet/static/kfet/js/kpsul.js | 2 +- kfet/templates/kfet/kpsul.html | 12 ++++-------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/kfet/static/kfet/js/kfet.api.js b/kfet/static/kfet/js/kfet.api.js index 293ff6a2..3fb3860e 100644 --- a/kfet/static/kfet/js/kfet.api.js +++ b/kfet/static/kfet/js/kfet.api.js @@ -502,6 +502,10 @@ class Article extends ModelObject { // API currently returns a string object (serialization of Decimal type within Django) get price() { return this._price; } set price(v) { this._price = floatCheck(v); } + + is_low_stock(nb) { + return (-5 <= this.stock - nb && this.stock - nb <= 5); + } } diff --git a/kfet/static/kfet/js/kpsul.js b/kfet/static/kfet/js/kpsul.js index 0027543e..9474e46f 100644 --- a/kfet/static/kfet/js/kpsul.js +++ b/kfet/static/kfet/js/kpsul.js @@ -98,7 +98,7 @@ class AccountManager { $('#id_on_acc').val(this.account.id); this.display(); - kpsul.article_manager.focus(); + kpsul.focus(); kpsul._env.updateBasketAmount(); kpsul._env.updateBasketRel(); } diff --git a/kfet/templates/kfet/kpsul.html b/kfet/templates/kfet/kpsul.html index c1243d4a..38a9e323 100644 --- a/kfet/templates/kfet/kpsul.html +++ b/kfet/templates/kfet/kpsul.html @@ -191,7 +191,7 @@ $(document).ready(function() { commentDialog.open({ callback: confirm_callback, - next_focus: kpsul.article_manager, + next_focus: kpsul, }); } @@ -237,7 +237,7 @@ $(document).ready(function() { else displayErrors(getErrorsHtml(response)); }, - next_focus: kpsul.article_manager, + next_focus: kpsul, }); } @@ -312,17 +312,13 @@ $(document).ready(function() { .find('.name').text(article.name).end() .find('.amount').text(amountToUKF(amount_euro, kpsul.account_manager.account.is_cof)); basket_container.prepend(article_basket_html); - if (is_low_stock(article, nb)) + if (article.is_low_stock(nb)) article_basket_html.find('.lowstock') .show(); updateBasketRel(); } } - function is_low_stock(article, nb) { - return (-5 <= article.stock - nb && article.stock - nb <= 5); - } - function addDeposit(amount) { var deposit_basket_html = $(item_basket_default_html); var amount = parseFloat(amount).toFixed(2); @@ -481,7 +477,7 @@ $(document).ready(function() { } - if (is_low_stock(article, nb_after)) + if (article.is_low_stock(nb_after)) article_html.find('.lowstock') .show(); else From 1761c5f1bdca39de20707b9034369ad867899847 Mon Sep 17 00:00:00 2001 From: Ludovic Stephan Date: Wed, 5 Apr 2017 09:13:00 -0300 Subject: [PATCH 12/12] Change fromAPI logic --- kfet/static/kfet/js/kfet.api.js | 18 ++++-------------- kfet/static/kfet/js/kpsul.js | 3 ++- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/kfet/static/kfet/js/kfet.api.js b/kfet/static/kfet/js/kfet.api.js index ab6cc7ab..9d805fdc 100644 --- a/kfet/static/kfet/js/kfet.api.js +++ b/kfet/static/kfet/js/kfet.api.js @@ -754,24 +754,14 @@ class APIModelForest extends ModelForest { * Fills the instance with distant data. It sends a GET HTTP request to * {@link Models.APIModelForest#url_model}. * @param {object} [api_options] Additional data appended to the request. - * @param {jQueryAjaxSuccess} [on_success] A function to be called if the request succeeds. - * @param {jQueryAjaxError} [on_error] A function to be called if the request fails. */ - fromAPI(api_options, on_success, on_error) { - var that = this; - - api_options = api_options || {} - on_success = on_success || $.noop; - on_error = on_error || $.noop; + fromAPI(api_options) { + api_options = api_options || {}; api_options['format'] = 'json'; - $.getJSON(this.constructor.url_model, api_options) - .done(function(json, textStatus, jqXHR) { - that.from(json); - on_success(json, textStatus, jqXHR); - }) - .fail(on_error); + return $.getJSON(this.constructor.url_model, api_options) + .done( (json) => this.from(json) ); } } diff --git a/kfet/static/kfet/js/kpsul.js b/kfet/static/kfet/js/kpsul.js index 703b15b2..e6784f7e 100644 --- a/kfet/static/kfet/js/kpsul.js +++ b/kfet/static/kfet/js/kpsul.js @@ -451,7 +451,8 @@ class ArticleManager { reset_data() { this._$container.html(''); this.list.clear(); - this.list.fromAPI({}, this.display_list.bind(this), $.noop) ; + this.list.fromAPI() + .done( () => this.display_list() ); } get_article(id) {