forked from DGNum/gestioCOF
New account manager logic
This commit is contained in:
parent
c10e5fe45c
commit
17d96f1775
2 changed files with 235 additions and 76 deletions
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* Fonctions d'aide à la gestion de trigrammes
|
||||
*/
|
||||
|
||||
String.prototype.format_trigramme = function () {
|
||||
return this.toUpperCase().substr(0, 3)
|
||||
}
|
||||
|
||||
String.prototype.is_valid_tri = function () {
|
||||
var pattern = /^[^a-z]{3}$/;
|
||||
return pattern.test(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* CSRF Token
|
||||
*/
|
||||
|
@ -14,7 +28,7 @@ function csrfSafeMethod(method) {
|
|||
}
|
||||
|
||||
$.ajaxSetup({
|
||||
beforeSend: function(xhr, settings) {
|
||||
beforeSend: function (xhr, settings) {
|
||||
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
|
||||
xhr.setRequestHeader("X-CSRFToken", csrftoken);
|
||||
}
|
||||
|
@ -23,7 +37,7 @@ $.ajaxSetup({
|
|||
|
||||
function add_csrf_form($form) {
|
||||
$form.append(
|
||||
$('<input>', {'name': 'csrfmiddlewaretoken', 'value': csrftoken})
|
||||
$('<input>', { 'name': 'csrfmiddlewaretoken', 'value': csrftoken })
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -66,7 +80,7 @@ class KfetWebsocket {
|
|||
var that = this;
|
||||
this.socket = new ReconnectingWebSocket(this.url);
|
||||
|
||||
this.socket.onmessage = function(e) {
|
||||
this.socket.onmessage = function (e) {
|
||||
var data = $.extend({}, that.default_msg, JSON.parse(e.data));
|
||||
for (let handler of that.handlers) {
|
||||
handler(data);
|
||||
|
@ -77,26 +91,21 @@ class KfetWebsocket {
|
|||
|
||||
var OperationWebSocket = new KfetWebsocket({
|
||||
'relative_url': 'k-psul/',
|
||||
'default_msg': {'opegroups':[],'opes':[],'checkouts':[],'articles':[]},
|
||||
'default_msg': { 'opegroups': [], 'opes': [], 'checkouts': [], 'articles': [] },
|
||||
});
|
||||
|
||||
function amountDisplay(amount, is_cof=false, tri='') {
|
||||
function amountDisplay(amount, is_cof = false, tri = '') {
|
||||
if (tri == 'LIQ')
|
||||
return (- amount).toFixed(2) +'€';
|
||||
return (- amount).toFixed(2) + '€';
|
||||
return amountToUKF(amount, is_cof);
|
||||
}
|
||||
|
||||
function amountToUKF(amount, is_cof=false, account=false) {
|
||||
var rounding = account ? Math.floor : Math.round ;
|
||||
function amountToUKF(amount, is_cof = false, account = false) {
|
||||
var rounding = account ? Math.floor : Math.round;
|
||||
var coef_cof = is_cof ? 1 + settings['subvention_cof'] / 100 : 1;
|
||||
return rounding(amount * coef_cof * 10);
|
||||
}
|
||||
|
||||
function isValidTrigramme(trigramme) {
|
||||
var pattern = /^[^a-z]{3}$/;
|
||||
return trigramme.match(pattern);
|
||||
}
|
||||
|
||||
function getErrorsHtml(data) {
|
||||
var content = '';
|
||||
if (!data)
|
||||
|
@ -113,8 +122,8 @@ function getErrorsHtml(data) {
|
|||
if ('missing_perms' in data['errors']) {
|
||||
content += 'Permissions manquantes';
|
||||
content += '<ul>';
|
||||
for (var i=0; i<data['errors']['missing_perms'].length; i++)
|
||||
content += '<li>'+data['errors']['missing_perms'][i]+'</li>';
|
||||
for (var i = 0; i < data['errors']['missing_perms'].length; i++)
|
||||
content += '<li>' + data['errors']['missing_perms'][i] + '</li>';
|
||||
content += '</ul>';
|
||||
}
|
||||
if ('negative' in data['errors']) {
|
||||
|
@ -123,8 +132,8 @@ function getErrorsHtml(data) {
|
|||
} else {
|
||||
var url_base = '/k-fet/accounts/';
|
||||
}
|
||||
for (var i=0; i<data['errors']['negative'].length; i++) {
|
||||
content += '<a class="btn btn-primary" href="'+url_base+data['errors']['negative'][i]+'/edit" target="_blank" style="width:100%">Autorisation de négatif requise pour '+data['errors']['negative'][i]+'</a>';
|
||||
for (var i = 0; i < data['errors']['negative'].length; i++) {
|
||||
content += '<a class="btn btn-primary" href="' + url_base + data['errors']['negative'][i] + '/edit" target="_blank" style="width:100%">Autorisation de négatif requise pour ' + data['errors']['negative'][i] + '</a>';
|
||||
}
|
||||
}
|
||||
if ('addcost' in data['errors']) {
|
||||
|
@ -138,7 +147,7 @@ function getErrorsHtml(data) {
|
|||
if ('account' in data['errors']) {
|
||||
content += 'Général';
|
||||
content += '<ul>';
|
||||
content += '<li>Opération invalide sur le compte '+data['errors']['account']+'</li>';
|
||||
content += '<li>Opération invalide sur le compte ' + data['errors']['account'] + '</li>';
|
||||
content += '</ul>';
|
||||
}
|
||||
return content;
|
||||
|
@ -147,54 +156,54 @@ function getErrorsHtml(data) {
|
|||
function requestAuth(data, callback, focus_next = null) {
|
||||
var content = getErrorsHtml(data);
|
||||
content += '<div class="capslock"><span class="glyphicon glyphicon-lock"></span><input type="password" name="password" autofocus><div>',
|
||||
$.confirm({
|
||||
title: 'Authentification requise',
|
||||
content: content,
|
||||
backgroundDismiss: true,
|
||||
animation:'top',
|
||||
closeAnimation:'bottom',
|
||||
keyboardEnabled: true,
|
||||
confirm: function() {
|
||||
var password = this.$content.find('input').val();
|
||||
callback(password);
|
||||
},
|
||||
onOpen: function() {
|
||||
var that = this;
|
||||
var capslock = -1 ; // 1 -> caps on ; 0 -> caps off ; -1 or 2 -> unknown
|
||||
this.$content.find('input').on('keypress', function(e) {
|
||||
if (e.keyCode == 13)
|
||||
that.$confirmButton.click();
|
||||
$.confirm({
|
||||
title: 'Authentification requise',
|
||||
content: content,
|
||||
backgroundDismiss: true,
|
||||
animation: 'top',
|
||||
closeAnimation: 'bottom',
|
||||
keyboardEnabled: true,
|
||||
confirm: function () {
|
||||
var password = this.$content.find('input').val();
|
||||
callback(password);
|
||||
},
|
||||
onOpen: function () {
|
||||
var that = this;
|
||||
var capslock = -1; // 1 -> caps on ; 0 -> caps off ; -1 or 2 -> unknown
|
||||
this.$content.find('input').on('keypress', function (e) {
|
||||
if (e.keyCode == 13)
|
||||
that.$confirmButton.click();
|
||||
|
||||
var s = String.fromCharCode(e.which);
|
||||
if ((s.toUpperCase() === s && s.toLowerCase() !== s && !e.shiftKey)|| //caps on, shift off
|
||||
(s.toUpperCase() !== s && s.toLowerCase() === s && e.shiftKey)) { //caps on, shift on
|
||||
capslock = 1 ;
|
||||
} else if ((s.toLowerCase() === s && s.toUpperCase() !== s && !e.shiftKey)|| //caps off, shift off
|
||||
(s.toLowerCase() !== s && s.toUpperCase() === s && e.shiftKey)) { //caps off, shift on
|
||||
capslock = 0 ;
|
||||
}
|
||||
if (capslock == 1)
|
||||
$('.capslock .glyphicon').show() ;
|
||||
else if (capslock == 0)
|
||||
$('.capslock .glyphicon').hide() ;
|
||||
});
|
||||
// Capslock key is not detected by keypress
|
||||
this.$content.find('input').on('keydown', function(e) {
|
||||
if (e.which == 20) {
|
||||
capslock = 1-capslock ;
|
||||
}
|
||||
if (capslock == 1)
|
||||
$('.capslock .glyphicon').show() ;
|
||||
else if (capslock == 0)
|
||||
$('.capslock .glyphicon').hide() ;
|
||||
});
|
||||
},
|
||||
onClose: function() {
|
||||
if (focus_next)
|
||||
this._lastFocused = focus_next;
|
||||
}
|
||||
var s = String.fromCharCode(e.which);
|
||||
if ((s.toUpperCase() === s && s.toLowerCase() !== s && !e.shiftKey) || //caps on, shift off
|
||||
(s.toUpperCase() !== s && s.toLowerCase() === s && e.shiftKey)) { //caps on, shift on
|
||||
capslock = 1;
|
||||
} else if ((s.toLowerCase() === s && s.toUpperCase() !== s && !e.shiftKey) || //caps off, shift off
|
||||
(s.toLowerCase() !== s && s.toUpperCase() === s && e.shiftKey)) { //caps off, shift on
|
||||
capslock = 0;
|
||||
}
|
||||
if (capslock == 1)
|
||||
$('.capslock .glyphicon').show();
|
||||
else if (capslock == 0)
|
||||
$('.capslock .glyphicon').hide();
|
||||
});
|
||||
// Capslock key is not detected by keypress
|
||||
this.$content.find('input').on('keydown', function (e) {
|
||||
if (e.which == 20) {
|
||||
capslock = 1 - capslock;
|
||||
}
|
||||
if (capslock == 1)
|
||||
$('.capslock .glyphicon').show();
|
||||
else if (capslock == 0)
|
||||
$('.capslock .glyphicon').hide();
|
||||
});
|
||||
},
|
||||
onClose: function () {
|
||||
if (focus_next)
|
||||
this._lastFocused = focus_next;
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -249,7 +258,7 @@ function submit_url(el) {
|
|||
function registerBoolParser(id, true_str, false_str) {
|
||||
$.tablesorter.addParser({
|
||||
id: id,
|
||||
format: function(s) {
|
||||
format: function (s) {
|
||||
return s.toLowerCase()
|
||||
.replace(true_str, 1)
|
||||
.replace(false_str, 0);
|
||||
|
@ -270,9 +279,9 @@ registerBoolParser('article__hidden', 'caché', 'affiché');
|
|||
$.extend(true, $.tablesorter.defaults, {
|
||||
headerTemplate: '{content} {icon}',
|
||||
|
||||
cssIconAsc : 'glyphicon glyphicon-chevron-up',
|
||||
cssIconDesc : 'glyphicon glyphicon-chevron-down',
|
||||
cssIconNone : 'glyphicon glyphicon-resize-vertical',
|
||||
cssIconAsc: 'glyphicon glyphicon-chevron-up',
|
||||
cssIconDesc: 'glyphicon glyphicon-chevron-down',
|
||||
cssIconNone: 'glyphicon glyphicon-resize-vertical',
|
||||
|
||||
// Only four-digits format year is handled by the builtin parser
|
||||
// 'shortDate'.
|
||||
|
@ -292,16 +301,16 @@ $.extend(true, $.tablesorter.defaults, {
|
|||
|
||||
// https://mottie.github.io/tablesorter/docs/index.html#variable-language
|
||||
$.extend($.tablesorter.language, {
|
||||
sortAsc : 'Trié par ordre croissant, ',
|
||||
sortDesc : 'Trié par ordre décroissant, ',
|
||||
sortNone : 'Non trié, ',
|
||||
sortDisabled : 'tri désactivé et/ou non-modifiable',
|
||||
nextAsc : 'cliquer pour trier par ordre croissant',
|
||||
nextDesc : 'cliquer pour trier par ordre décroissant',
|
||||
nextNone : 'cliquer pour retirer le tri'
|
||||
sortAsc: 'Trié par ordre croissant, ',
|
||||
sortDesc: 'Trié par ordre décroissant, ',
|
||||
sortNone: 'Non trié, ',
|
||||
sortDisabled: 'tri désactivé et/ou non-modifiable',
|
||||
nextAsc: 'cliquer pour trier par ordre croissant',
|
||||
nextDesc: 'cliquer pour trier par ordre décroissant',
|
||||
nextNone: 'cliquer pour retirer le tri'
|
||||
});
|
||||
|
||||
|
||||
$( function() {
|
||||
$(function () {
|
||||
$('.sortable').tablesorter();
|
||||
});
|
||||
|
|
150
kfet/static/kfet/js/kpsul.js
Normal file
150
kfet/static/kfet/js/kpsul.js
Normal file
|
@ -0,0 +1,150 @@
|
|||
class AccountManager {
|
||||
// Classe pour gérer la partie "compte" de K-Psul
|
||||
// Devrait être la seule interface entre le JS de K-Psul et la logique des comptes.
|
||||
constructor() {
|
||||
// jQuery elements
|
||||
this._$input = $("#id_trigramme");
|
||||
this._$container = $("#account");
|
||||
this._$article_select = $("#article_autocomplete")
|
||||
|
||||
// Subordinated classes
|
||||
this.account = new Account({ "trigramme": "" });
|
||||
this.search = new AccountSearch(this)
|
||||
|
||||
// Initialization
|
||||
this._init_events();
|
||||
}
|
||||
|
||||
get data() {
|
||||
return this.account.toJSON();
|
||||
}
|
||||
|
||||
_init_events() {
|
||||
var that = this;
|
||||
|
||||
// L'input change ; on met à jour le compte
|
||||
this._$input.on("input", () => this.update())
|
||||
|
||||
// Raccourci LIQ
|
||||
this._$input.on("keydown", function (e) {
|
||||
// keycode 40: Down Arrow
|
||||
if (e.keyCode == 40) {
|
||||
that.set("LIQ")
|
||||
}
|
||||
})
|
||||
|
||||
// Fonction de recherche
|
||||
this._$container.on('click', '.search', function () {
|
||||
that.search.open();
|
||||
});
|
||||
|
||||
this._$container.on('keydown', function (e) {
|
||||
if (e.which == 70 && e.ctrlKey) {
|
||||
// Ctrl + F : universal search shortcut
|
||||
that.search.open();
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
set(trigramme) {
|
||||
this._$input.val(trigramme);
|
||||
this.update();
|
||||
}
|
||||
|
||||
update() {
|
||||
var trigramme = this._$input.val().format_trigramme();
|
||||
this.account.set({ "trigramme": trigramme })
|
||||
if (trigramme.is_valid_tri()) {
|
||||
this.account.fetch({
|
||||
"success": this._on_success.bind(this),
|
||||
"error": this.reset.bind(this, false),
|
||||
})
|
||||
} else {
|
||||
this.reset()
|
||||
}
|
||||
}
|
||||
|
||||
_on_success() {
|
||||
// On utilise l'objet global window pour accéder aux fonctions nécessaires
|
||||
this.account.render();
|
||||
this._$article_select.focus();
|
||||
window.updateBasketAmount();
|
||||
window.updateBasketRel();
|
||||
}
|
||||
|
||||
reset(hard_reset = false) {
|
||||
this.account.reset();
|
||||
this.account.render();
|
||||
|
||||
if (hard_reset) {
|
||||
this._$input.val("");
|
||||
this.update()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AccountSearch {
|
||||
|
||||
constructor(manager) {
|
||||
this.manager = manager;
|
||||
|
||||
this._content = '<input type="text" name="q" id="search_autocomplete" autocomplete="off" spellcheck="false" autofocus><div id="account_results"></div>';
|
||||
this._input = '#search_autocomplete';
|
||||
this._results_container = '#account_results';
|
||||
|
||||
}
|
||||
|
||||
open() {
|
||||
var that = this;
|
||||
this._$dialog = $.dialog({
|
||||
title: 'Recherche de compte',
|
||||
content: this._content,
|
||||
backgroundDismiss: true,
|
||||
animation: 'top',
|
||||
closeAnimation: 'bottom',
|
||||
keyboardEnabled: true,
|
||||
onOpen: function () {
|
||||
that._$input = $(that._input);
|
||||
that._$results_container = $(that._results_container);
|
||||
that._init_form()
|
||||
._init_events();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
_init_form() {
|
||||
var that = this;
|
||||
|
||||
this._$input.yourlabsAutocomplete({
|
||||
url: django_urls['kfet.account.search.autocomplete'](),
|
||||
minimumCharacters: 2,
|
||||
id: 'search_autocomplete',
|
||||
choiceSelector: '.choice',
|
||||
placeholder: "Chercher un utilisateur K-Fêt",
|
||||
container: that._$results_container,
|
||||
box: that._$results_container,
|
||||
fixPosition: function () { },
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
_init_events() {
|
||||
this._$input.bind('selectChoice',
|
||||
(e, choice, autocomplete) => this._on_select(e, choice, autocomplete)
|
||||
);
|
||||
return this;
|
||||
}
|
||||
|
||||
_on_select(e, choice, autocomplete) {
|
||||
this.manager.set(choice.find('.trigramme').text());
|
||||
this.close();
|
||||
}
|
||||
|
||||
close() {
|
||||
if (this._$dialog !== undefined) {
|
||||
this._$dialog.close();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue