'
- // Show tooltip
- field.attr('data-original-title', aliases_matched_html).tooltip('show');
+ // Show tooltip
+ field.attr('data-original-title', aliases_matched_html).tooltip('show')
- consumers.results.forEach(function (consumer) {
- let consumer_obj = $("#" + alias_prefix + "_" + consumer.id);
- consumer_obj.hover(function () {
- displayNote(consumer.note, consumer.name, user_note_field, profile_pic_field)
- });
- consumer_obj.click(function () {
- var disp = null;
- notes_display.forEach(function (d) {
- // We compare the alias ids
- if (d.id === consumer.id) {
- d.quantity += 1;
- disp = d;
- }
- });
- // In the other case, we add a new emitter
- if (disp == null) {
- disp = {
- name: consumer.name,
- id: consumer.id,
- note: consumer.note,
- quantity: 1
- };
- notes_display.push(disp);
- }
+ consumers.results.forEach(function (consumer) {
+ const consumer_obj = $('#' + alias_prefix + '_' + consumer.id)
+ consumer_obj.hover(function () {
+ displayNote(consumer.note, consumer.name, user_note_field, profile_pic_field)
+ })
+ consumer_obj.click(function () {
+ var disp = null
+ notes_display.forEach(function (d) {
+ // We compare the alias ids
+ if (d.id === consumer.id) {
+ d.quantity += 1
+ disp = d
+ }
+ })
+ // In the other case, we add a new emitter
+ if (disp == null) {
+ disp = {
+ name: consumer.name,
+ id: consumer.id,
+ note: consumer.note,
+ quantity: 1
+ }
+ notes_display.push(disp)
+ }
- // If the function alias_click exists, it is called. If it doesn't return true, then the notes are
- // note displayed. Useful for a consumption when a button is already clicked
- if (alias_click && !alias_click())
- return;
+ // If the function alias_click exists, it is called. If it doesn't return true, then the notes are
+ // note displayed. Useful for a consumption when a button is already clicked
+ if (alias_click && !alias_click()) { return }
- let note_list = $("#" + note_list_id);
- let html = "";
- notes_display.forEach(function (disp) {
- html += li(note_prefix + "_" + disp.id,
- disp.name
- + ""
- + disp.quantity + "",
- displayStyle(disp.note));
- });
+ const note_list = $('#' + note_list_id)
+ let html = ''
+ notes_display.forEach(function (disp) {
+ html += li(note_prefix + '_' + disp.id,
+ disp.name +
+ '' +
+ disp.quantity + '',
+ displayStyle(disp.note))
+ })
- // Emitters are displayed
- note_list.html(html);
+ // Emitters are displayed
+ note_list.html(html)
- // Update tooltip position
- field.tooltip('update');
+ // Update tooltip position
+ field.tooltip('update')
- notes_display.forEach(function (disp) {
- let line_obj = $("#" + note_prefix + "_" + disp.id);
- // Hover an emitter display also the profile picture
- line_obj.hover(function () {
- displayNote(disp.note, disp.name, user_note_field, profile_pic_field);
- });
+ notes_display.forEach(function (disp) {
+ const line_obj = $('#' + note_prefix + '_' + disp.id)
+ // Hover an emitter display also the profile picture
+ line_obj.hover(function () {
+ displayNote(disp.note, disp.name, user_note_field, profile_pic_field)
+ })
- // When an emitter is clicked, it is removed
- line_obj.click(removeNote(disp, note_prefix, notes_display, note_list_id, user_note_field,
- profile_pic_field));
- });
- })
- });
-
- });// end getJSON alias
- });
+ // When an emitter is clicked, it is removed
+ line_obj.click(removeNote(disp, note_prefix, notes_display, note_list_id, user_note_field,
+ profile_pic_field))
+ })
+ })
+ })
+ })// end getJSON alias
+ })
}// end function autocomplete
-
// When a validate button is clicked, we switch the validation status
function de_validate (id, validated, resourcetype) {
- let validate_obj = $("#validate_" + id);
+ const validate_obj = $('#validate_' + id)
- if (validate_obj.data("pending"))
- // The button is already clicked
- return;
+ if (validate_obj.data('pending'))
+ // The button is already clicked
+ { return }
- let invalidity_reason = $("#invalidity_reason_" + id).val();
- validate_obj.html("⟳");
- validate_obj.data("pending", true);
+ const invalidity_reason = $('#invalidity_reason_' + id).val()
+ validate_obj.html('⟳')
+ validate_obj.data('pending', true)
- // Perform a PATCH request to the API in order to update the transaction
- // If the user has insufficient rights, an error message will appear
- $.ajax({
- "url": "/api/note/transaction/transaction/" + id + "/",
- type: "PATCH",
- dataType: "json",
- headers: {
- "X-CSRFTOKEN": CSRF_TOKEN
- },
- data: {
- "resourcetype": resourcetype,
- "valid": !validated,
- "invalidity_reason": invalidity_reason,
- },
- success: function () {
- refreshBalance();
- // error if this method doesn't exist. Please define it.
- refreshHistory();
- },
- error: function (err) {
- let errObj = JSON.parse(err.responseText);
- let error = errObj["detail"] ? errObj["detail"] : errObj["non_field_errors"];
- if (!error)
- error = err.responseText;
- addMsg("Une erreur est survenue lors de la validation/dévalidation " +
- "de cette transaction : " + error, "danger");
+ // Perform a PATCH request to the API in order to update the transaction
+ // If the user has insufficient rights, an error message will appear
+ $.ajax({
+ url: '/api/note/transaction/transaction/' + id + '/',
+ type: 'PATCH',
+ dataType: 'json',
+ headers: {
+ 'X-CSRFTOKEN': CSRF_TOKEN
+ },
+ data: {
+ resourcetype: resourcetype,
+ valid: !validated,
+ invalidity_reason: invalidity_reason
+ },
+ success: function () {
+ refreshBalance()
+ // error if this method doesn't exist. Please define it.
+ refreshHistory()
+ },
+ error: function (err) {
+ const errObj = JSON.parse(err.responseText)
+ let error = errObj.detail ? errObj.detail : errObj.non_field_errors
+ if (!error) { error = err.responseText }
+ addMsg('Une erreur est survenue lors de la validation/dévalidation ' +
+ 'de cette transaction : ' + error, 'danger')
- refreshBalance();
- // error if this method doesn't exist. Please define it.
- refreshHistory();
- }
- });
+ refreshBalance()
+ // error if this method doesn't exist. Please define it.
+ refreshHistory()
+ }
+ })
}
/**
@@ -404,10 +379,10 @@ function de_validate (id, validated, resourcetype) {
* @param wait Debounced milliseconds
*/
function debounce (callback, wait) {
- let timeout;
- return (...args) => {
- const context = this;
- clearTimeout(timeout);
- timeout = setTimeout(() => callback.apply(context, args), wait);
- };
+ let timeout
+ return (...args) => {
+ const context = this
+ clearTimeout(timeout)
+ timeout = setTimeout(() => callback.apply(context, args), wait)
+ }
}
diff --git a/note_kfet/static/js/consos.js b/note_kfet/static/js/consos.js
index 25e8113e..5a7e6144 100644
--- a/note_kfet/static/js/consos.js
+++ b/note_kfet/static/js/consos.js
@@ -2,95 +2,92 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// When a transaction is performed, lock the interface to prevent spam clicks.
-var LOCK = false;
+var LOCK = false
/**
* Refresh the history table on the consumptions page.
*/
-function refreshHistory() {
- $("#history").load("/note/consos/ #history");
- $("#most_used").load("/note/consos/ #most_used");
+function refreshHistory () {
+ $('#history').load('/note/consos/ #history')
+ $('#most_used').load('/note/consos/ #most_used')
}
-$(document).ready(function() {
- // If hash of a category in the URL, then select this category
- // else select the first one
- if (location.hash) {
- $("a[href='" + location.hash + "']").tab("show");
- } else {
- $("a[data-toggle='tab']").first().tab("show");
+$(document).ready(function () {
+ // If hash of a category in the URL, then select this category
+ // else select the first one
+ if (location.hash) {
+ $("a[href='" + location.hash + "']").tab('show')
+ } else {
+ $("a[data-toggle='tab']").first().tab('show')
+ }
+
+ // When selecting a category, change URL
+ $(document.body).on('click', "a[data-toggle='tab']", function () {
+ location.hash = this.getAttribute('href')
+ })
+
+ // Switching in double consumptions mode should update the layout
+ $('#double_conso').change(function () {
+ $('#consos_list_div').removeClass('d-none')
+ $('#user_select_div').attr('class', 'col-xl-4')
+ $('#infos_div').attr('class', 'col-sm-5 col-xl-6')
+
+ const note_list_obj = $('#note_list')
+ if (buttons.length > 0 && note_list_obj.text().length > 0) {
+ $('#consos_list').html(note_list_obj.html())
+ note_list_obj.html('')
+
+ buttons.forEach(function (button) {
+ $('#conso_button_' + button.id).click(function () {
+ if (LOCK) { return }
+ removeNote(button, 'conso_button', buttons, 'consos_list')()
+ })
+ })
}
+ })
- // When selecting a category, change URL
- $(document.body).on("click", "a[data-toggle='tab']", function() {
- location.hash = this.getAttribute("href");
- });
+ $('#single_conso').change(function () {
+ $('#consos_list_div').addClass('d-none')
+ $('#user_select_div').attr('class', 'col-xl-7')
+ $('#infos_div').attr('class', 'col-sm-5 col-md-4')
- // Switching in double consumptions mode should update the layout
- $("#double_conso").change(function() {
- $("#consos_list_div").removeClass('d-none');
- $("#user_select_div").attr('class', 'col-xl-4');
- $("#infos_div").attr('class', 'col-sm-5 col-xl-6');
+ const consos_list_obj = $('#consos_list')
+ if (buttons.length > 0) {
+ if (notes_display.length === 0 && consos_list_obj.text().length > 0) {
+ $('#note_list').html(consos_list_obj.html())
+ consos_list_obj.html('')
+ buttons.forEach(function (button) {
+ $('#conso_button_' + button.id).click(function () {
+ if (LOCK) { return }
+ removeNote(button, 'conso_button', buttons, 'note_list')()
+ })
+ })
+ } else {
+ buttons.length = 0
+ consos_list_obj.html('')
+ }
+ }
+ })
- let note_list_obj = $("#note_list");
- if (buttons.length > 0 && note_list_obj.text().length > 0) {
- $("#consos_list").html(note_list_obj.html());
- note_list_obj.html("");
+ // Ensure we begin in single consumption. Fix issue with TurboLinks and BootstrapJS
+ $("label[for='double_conso']").removeClass('active')
- buttons.forEach(function(button) {
- $("#conso_button_" + button.id).click(function() {
- if (LOCK)
- return;
- removeNote(button, "conso_button", buttons,"consos_list")();
- });
- });
- }
- });
+ $('#consume_all').click(consumeAll)
+})
- $("#single_conso").change(function() {
- $("#consos_list_div").addClass('d-none');
- $("#user_select_div").attr('class', 'col-xl-7');
- $("#infos_div").attr('class', 'col-sm-5 col-md-4');
-
- let consos_list_obj = $("#consos_list");
- if (buttons.length > 0) {
- if (notes_display.length === 0 && consos_list_obj.text().length > 0) {
- $("#note_list").html(consos_list_obj.html());
- consos_list_obj.html("");
- buttons.forEach(function(button) {
- $("#conso_button_" + button.id).click(function() {
- if (LOCK)
- return;
- removeNote(button, "conso_button", buttons,"note_list")();
- });
- });
- }
- else {
- buttons.length = 0;
- consos_list_obj.html("");
- }
- }
- });
-
- // Ensure we begin in single consumption. Fix issue with TurboLinks and BootstrapJS
- $("label[for='double_conso']").removeClass('active');
-
- $("#consume_all").click(consumeAll);
-});
-
-notes = [];
-notes_display = [];
-buttons = [];
+notes = []
+notes_display = []
+buttons = []
// When the user searches an alias, we update the auto-completion
-autoCompleteNote("note", "note_list", notes, notes_display,
- "alias", "note", "user_note", "profile_pic", function() {
- if (buttons.length > 0 && $("#single_conso").is(":checked")) {
- consumeAll();
- return false;
- }
- return true;
- });
+autoCompleteNote('note', 'note_list', notes, notes_display,
+ 'alias', 'note', 'user_note', 'profile_pic', function () {
+ if (buttons.length > 0 && $('#single_conso').is(':checked')) {
+ consumeAll()
+ return false
+ }
+ return true
+ })
/**
* Add a transaction from a button.
@@ -102,103 +99,98 @@ autoCompleteNote("note", "note_list", notes, notes_display,
* @param template_id The identifier of the button
* @param template_name The name of the button
*/
-function addConso(dest, amount, type, category_id, category_name, template_id, template_name) {
- var button = null;
- buttons.forEach(function(b) {
- if (b.id === template_id) {
- b.quantity += 1;
- button = b;
- }
- });
- if (button == null) {
- button = {
- id: template_id,
- name: template_name,
- dest: dest,
- quantity: 1,
- amount: amount,
- type: type,
- category_id: category_id,
- category_name: category_name
- };
- buttons.push(button);
+function addConso (dest, amount, type, category_id, category_name, template_id, template_name) {
+ var button = null
+ buttons.forEach(function (b) {
+ if (b.id === template_id) {
+ b.quantity += 1
+ button = b
}
-
- let dc_obj = $("#double_conso");
- if (dc_obj.is(":checked") || notes_display.length === 0) {
- let list = dc_obj.is(":checked") ? "consos_list" : "note_list";
- let html = "";
- buttons.forEach(function(button) {
- html += li("conso_button_" + button.id, button.name
- + "" + button.quantity + "");
- });
-
- $("#" + list).html(html);
-
- buttons.forEach(function(button) {
- $("#conso_button_" + button.id).click(function() {
- if (LOCK)
- return;
- removeNote(button, "conso_button", buttons, list)();
- });
- });
+ })
+ if (button == null) {
+ button = {
+ id: template_id,
+ name: template_name,
+ dest: dest,
+ quantity: 1,
+ amount: amount,
+ type: type,
+ category_id: category_id,
+ category_name: category_name
}
- else
- consumeAll();
+ buttons.push(button)
+ }
+
+ const dc_obj = $('#double_conso')
+ if (dc_obj.is(':checked') || notes_display.length === 0) {
+ const list = dc_obj.is(':checked') ? 'consos_list' : 'note_list'
+ let html = ''
+ buttons.forEach(function (button) {
+ html += li('conso_button_' + button.id, button.name +
+ '' + button.quantity + '')
+ })
+
+ $('#' + list).html(html)
+
+ buttons.forEach(function (button) {
+ $('#conso_button_' + button.id).click(function () {
+ if (LOCK) { return }
+ removeNote(button, 'conso_button', buttons, list)()
+ })
+ })
+ } else { consumeAll() }
}
/**
* Reset the page as its initial state.
*/
-function reset() {
- notes_display.length = 0;
- notes.length = 0;
- buttons.length = 0;
- $("#note_list").html("");
- $("#consos_list").html("");
- $("#note").val("");
- $("#note").attr("data-original-title", "").tooltip("hide");
- $("#profile_pic").attr("src", "/static/member/img/default_picture.png");
- $("#profile_pic_link").attr("href", "#");
- refreshHistory();
- refreshBalance();
- LOCK = false;
+function reset () {
+ notes_display.length = 0
+ notes.length = 0
+ buttons.length = 0
+ $('#note_list').html('')
+ $('#consos_list').html('')
+ $('#note').val('')
+ $('#note').attr('data-original-title', '').tooltip('hide')
+ $('#profile_pic').attr('src', '/static/member/img/default_picture.png')
+ $('#profile_pic_link').attr('href', '#')
+ refreshHistory()
+ refreshBalance()
+ LOCK = false
}
-
/**
* Apply all transactions: all notes in `notes` buy each item in `buttons`
*/
-function consumeAll() {
- if (LOCK)
- return;
+function consumeAll () {
+ if (LOCK) { return }
- LOCK = true;
+ LOCK = true
- let error = false;
+ let error = false
- if (notes_display.length === 0) {
- $("#note").addClass('is-invalid');
- $("#note_list").html(li("", "Ajoutez des émetteurs.", "text-danger"));
- error = true;
- }
+ if (notes_display.length === 0) {
+ $('#note').addClass('is-invalid')
+ $('#note_list').html(li('', 'Ajoutez des émetteurs.', 'text-danger'))
+ error = true
+ }
- if (buttons.length === 0) {
- $("#consos_list").html(li("", "Ajoutez des consommations.", "text-danger"));
- error = true;
- }
+ if (buttons.length === 0) {
+ $('#consos_list').html(li('', 'Ajoutez des consommations.', 'text-danger'))
+ error = true
+ }
- if (error) {
- LOCK = false;
- return;
- }
+ if (error) {
+ LOCK = false
+ return
+ }
- notes_display.forEach(function(note_display) {
- buttons.forEach(function(button) {
- consume(note_display.note, note_display.name, button.dest, button.quantity * note_display.quantity, button.amount,
- button.name + " (" + button.category_name + ")", button.type, button.category_id, button.id);
- });
- });
+ notes_display.forEach(function (note_display) {
+ buttons.forEach(function (button) {
+ consume(note_display.note, note_display.name, button.dest, button.quantity * note_display.quantity, button.amount,
+ button.name + ' (' + button.category_name + ')', button.type, button.category_id, button.id)
+ })
+ })
}
/**
@@ -213,58 +205,60 @@ function consumeAll() {
* @param category The category id of the button (type: int)
* @param template The button id (type: int)
*/
-function consume(source, source_alias, dest, quantity, amount, reason, type, category, template) {
- $.post("/api/note/transaction/transaction/",
+function consume (source, source_alias, dest, quantity, amount, reason, type, category, template) {
+ $.post('/api/note/transaction/transaction/',
+ {
+ csrfmiddlewaretoken: CSRF_TOKEN,
+ quantity: quantity,
+ amount: amount,
+ reason: reason,
+ valid: true,
+ polymorphic_ctype: type,
+ resourcetype: 'RecurrentTransaction',
+ source: source.id,
+ source_alias: source_alias,
+ destination: dest,
+ template: template
+ })
+ .done(function () {
+ if (!isNaN(source.balance)) {
+ const newBalance = source.balance - quantity * amount
+ if (newBalance <= -5000) {
+ addMsg('Attention, La transaction depuis la note ' + source_alias + ' a été réalisée avec ' +
+ 'succès, mais la note émettrice ' + source_alias + ' est en négatif sévère.',
+ 'danger', 30000)
+ } else if (newBalance < 0) {
+ addMsg('Attention, La transaction depuis la note ' + source_alias + ' a été réalisée avec ' +
+ 'succès, mais la note émettrice ' + source_alias + ' est en négatif.',
+ 'warning', 30000)
+ }
+ if (source.membership && source.membership.date_end < new Date().toISOString()) {
+ addMsg('Attention : la note émettrice ' + source.name + " n'est plus adhérente.",
+ 'danger', 30000)
+ }
+ }
+ reset()
+ }).fail(function (e) {
+ $.post('/api/note/transaction/transaction/',
{
- "csrfmiddlewaretoken": CSRF_TOKEN,
- "quantity": quantity,
- "amount": amount,
- "reason": reason,
- "valid": true,
- "polymorphic_ctype": type,
- "resourcetype": "RecurrentTransaction",
- "source": source.id,
- "source_alias": source_alias,
- "destination": dest,
- "template": template
- })
- .done(function () {
- if (!isNaN(source.balance)) {
- let newBalance = source.balance - quantity * amount;
- if (newBalance <= -5000)
- addMsg("Attention, La transaction depuis la note " + source_alias + " a été réalisée avec " +
- "succès, mais la note émettrice " + source_alias + " est en négatif sévère.",
- "danger", 30000);
- else if (newBalance < 0)
- addMsg("Attention, La transaction depuis la note " + source_alias + " a été réalisée avec " +
- "succès, mais la note émettrice " + source_alias + " est en négatif.",
- "warning", 30000);
- if (source.membership && source.membership.date_end < new Date().toISOString())
- addMsg("Attention : la note émettrice " + source.name + " n'est plus adhérente.",
- "danger", 30000);
- }
- reset();
- }).fail(function (e) {
- $.post("/api/note/transaction/transaction/",
- {
- "csrfmiddlewaretoken": CSRF_TOKEN,
- "quantity": quantity,
- "amount": amount,
- "reason": reason,
- "valid": false,
- "invalidity_reason": "Solde insuffisant",
- "polymorphic_ctype": type,
- "resourcetype": "RecurrentTransaction",
- "source": source,
- "source_alias": source_alias,
- "destination": dest,
- "template": template
- }).done(function() {
- reset();
- addMsg("La transaction n'a pas pu être validée pour cause de solde insuffisant.", "danger", 10000);
- }).fail(function () {
- reset();
- errMsg(e.responseJSON);
- });
- });
+ csrfmiddlewaretoken: CSRF_TOKEN,
+ quantity: quantity,
+ amount: amount,
+ reason: reason,
+ valid: false,
+ invalidity_reason: 'Solde insuffisant',
+ polymorphic_ctype: type,
+ resourcetype: 'RecurrentTransaction',
+ source: source,
+ source_alias: source_alias,
+ destination: dest,
+ template: template
+ }).done(function () {
+ reset()
+ addMsg("La transaction n'a pas pu être validée pour cause de solde insuffisant.", 'danger', 10000)
+ }).fail(function () {
+ reset()
+ errMsg(e.responseJSON)
+ })
+ })
}
diff --git a/note_kfet/static/js/dynamic-formset.js b/note_kfet/static/js/dynamic-formset.js
index c6ff3328..cb6151df 100644
--- a/note_kfet/static/js/dynamic-formset.js
+++ b/note_kfet/static/js/dynamic-formset.js
@@ -9,241 +9,240 @@
* Licensed under the New BSD License
* See: http://www.opensource.org/licenses/bsd-license.php
*/
-;(function($) {
- $.fn.formset = function(opts)
- {
- var options = $.extend({}, $.fn.formset.defaults, opts),
- flatExtraClasses = options.extraClasses.join(' '),
- totalForms = $('#id_' + options.prefix + '-TOTAL_FORMS'),
- maxForms = $('#id_' + options.prefix + '-MAX_NUM_FORMS'),
- minForms = $('#id_' + options.prefix + '-MIN_NUM_FORMS'),
- childElementSelector = 'input,select,textarea,label,div',
- $$ = $(this),
+;(function ($) {
+ $.fn.formset = function (opts) {
+ var options = $.extend({}, $.fn.formset.defaults, opts)
+ var flatExtraClasses = options.extraClasses.join(' ')
+ var totalForms = $('#id_' + options.prefix + '-TOTAL_FORMS')
+ var maxForms = $('#id_' + options.prefix + '-MAX_NUM_FORMS')
+ var minForms = $('#id_' + options.prefix + '-MIN_NUM_FORMS')
+ var childElementSelector = 'input,select,textarea,label,div'
+ var $$ = $(this)
- applyExtraClasses = function(row, ndx) {
- if (options.extraClasses) {
- row.removeClass(flatExtraClasses);
- row.addClass(options.extraClasses[ndx % options.extraClasses.length]);
- }
- },
+ var applyExtraClasses = function (row, ndx) {
+ if (options.extraClasses) {
+ row.removeClass(flatExtraClasses)
+ row.addClass(options.extraClasses[ndx % options.extraClasses.length])
+ }
+ }
- updateElementIndex = function(elem, prefix, ndx) {
- var idRegex = new RegExp(prefix + '-(\\d+|__prefix__)-'),
- replacement = prefix + '-' + ndx + '-';
- if (elem.attr("for")) elem.attr("for", elem.attr("for").replace(idRegex, replacement));
- if (elem.attr('id')) elem.attr('id', elem.attr('id').replace(idRegex, replacement));
- if (elem.attr('name')) elem.attr('name', elem.attr('name').replace(idRegex, replacement));
- },
+ var updateElementIndex = function (elem, prefix, ndx) {
+ var idRegex = new RegExp(prefix + '-(\\d+|__prefix__)-')
+ var replacement = prefix + '-' + ndx + '-'
+ if (elem.attr('for')) elem.attr('for', elem.attr('for').replace(idRegex, replacement))
+ if (elem.attr('id')) elem.attr('id', elem.attr('id').replace(idRegex, replacement))
+ if (elem.attr('name')) elem.attr('name', elem.attr('name').replace(idRegex, replacement))
+ }
- hasChildElements = function(row) {
- return row.find(childElementSelector).length > 0;
- },
+ var hasChildElements = function (row) {
+ return row.find(childElementSelector).length > 0
+ }
- showAddButton = function() {
- return maxForms.length == 0 || // For Django versions pre 1.2
- (maxForms.val() == '' || (maxForms.val() - totalForms.val() > 0));
- },
+ var showAddButton = function () {
+ return maxForms.length == 0 || // For Django versions pre 1.2
+ (maxForms.val() == '' || (maxForms.val() - totalForms.val() > 0))
+ }
- /**
+ /**
* Indicates whether delete link(s) can be displayed - when total forms > min forms
*/
- showDeleteLinks = function() {
- return minForms.length == 0 || // For Django versions pre 1.7
- (minForms.val() == '' || (totalForms.val() - minForms.val() > 0));
- },
+ var showDeleteLinks = function () {
+ return minForms.length == 0 || // For Django versions pre 1.7
+ (minForms.val() == '' || (totalForms.val() - minForms.val() > 0))
+ }
- insertDeleteLink = function(row) {
- var delCssSelector = $.trim(options.deleteCssClass).replace(/\s+/g, '.'),
- addCssSelector = $.trim(options.addCssClass).replace(/\s+/g, '.');
+ var insertDeleteLink = function (row) {
+ var delCssSelector = $.trim(options.deleteCssClass).replace(/\s+/g, '.')
+ var addCssSelector = $.trim(options.addCssClass).replace(/\s+/g, '.')
- var delButtonHTML = '' + options.deleteText +'';
- if (options.deleteContainerClass) {
- // If we have a specific container for the remove button,
- // place it as the last child of that container:
- row.find('[class*="' + options.deleteContainerClass + '"]').append(delButtonHTML);
- } else if (row.is('TR')) {
- // If the forms are laid out in table rows, insert
- // the remove button into the last table cell:
- row.children('td:last').append(delButtonHTML);
- } else if (row.is('UL') || row.is('OL')) {
- // If they're laid out as an ordered/unordered list,
- // insert an
after the last list item:
- row.append('
' + delButtonHTML + '
');
- } else {
- // Otherwise, just insert the remove button as the
- // last child element of the form's container:
- row.append(delButtonHTML);
- }
+ var delButtonHTML = '' + options.deleteText + ''
+ if (options.deleteContainerClass) {
+ // If we have a specific container for the remove button,
+ // place it as the last child of that container:
+ row.find('[class*="' + options.deleteContainerClass + '"]').append(delButtonHTML)
+ } else if (row.is('TR')) {
+ // If the forms are laid out in table rows, insert
+ // the remove button into the last table cell:
+ row.children('td:last').append(delButtonHTML)
+ } else if (row.is('UL') || row.is('OL')) {
+ // If they're laid out as an ordered/unordered list,
+ // insert an
after the last list item:
+ row.append('
' + delButtonHTML + '
')
+ } else {
+ // Otherwise, just insert the remove button as the
+ // last child element of the form's container:
+ row.append(delButtonHTML)
+ }
- // Check if we're under the minimum number of forms - not to display delete link at rendering
- if (!showDeleteLinks()){
- row.find('a.' + delCssSelector).hide();
- }
+ // Check if we're under the minimum number of forms - not to display delete link at rendering
+ if (!showDeleteLinks()) {
+ row.find('a.' + delCssSelector).hide()
+ }
- row.find('a.' + delCssSelector).click(function() {
- var row = $(this).parents('.' + options.formCssClass),
- del = row.find('input:hidden[id $= "-DELETE"]'),
- buttonRow = row.siblings("a." + addCssSelector + ', .' + options.formCssClass + '-add'),
- forms;
- if (del.length) {
- // We're dealing with an inline formset.
- // Rather than remove this form from the DOM, we'll mark it as deleted
- // and hide it, then let Django handle the deleting:
- del.val('on');
- row.hide();
- forms = $('.' + options.formCssClass).not(':hidden');
- } else {
- row.remove();
- // Update the TOTAL_FORMS count:
- forms = $('.' + options.formCssClass).not('.formset-custom-template');
- totalForms.val(forms.length);
- }
- for (var i=0, formCount=forms.length; i');
- row.hide();
- } else {
- del.before('');
- }
- // Hide any labels associated with the DELETE checkbox:
- $('label[for="' + del.attr('id') + '"]').hide();
- del.remove();
- }
- if (hasChildElements(row)) {
- row.addClass(options.formCssClass);
- if (row.is(':visible')) {
- insertDeleteLink(row);
- applyExtraClasses(row, i);
- }
- }
- });
-
- if ($$.length) {
- var hideAddButton = !showAddButton(),
- addButton, template;
- if (options.formTemplate) {
- // If a form template was specified, we'll clone it to generate new form instances:
- template = (options.formTemplate instanceof $) ? options.formTemplate : $(options.formTemplate);
- template.removeAttr('id').addClass(options.formCssClass + ' formset-custom-template');
- template.find(childElementSelector).each(function() {
- updateElementIndex($(this), options.prefix, '__prefix__');
- });
- insertDeleteLink(template);
- } else {
- // Otherwise, use the last form in the formset; this works much better if you've got
- // extra (>= 1) forms (thnaks to justhamade for pointing this out):
- if (options.hideLastAddForm) $('.' + options.formCssClass + ':last').hide();
- template = $('.' + options.formCssClass + ':last').clone(true).removeAttr('id');
- template.find('input:hidden[id $= "-DELETE"]').remove();
- // Clear all cloned fields, except those the user wants to keep (thanks to brunogola for the suggestion):
- template.find(childElementSelector).not(options.keepFieldValues).each(function() {
- var elem = $(this);
- // If this is a checkbox or radiobutton, uncheck it.
- // This fixes Issue 1, reported by Wilson.Andrew.J:
- if (elem.is('input:checkbox') || elem.is('input:radio')) {
- elem.attr('checked', false);
- } else {
- elem.val('');
- }
- });
- }
- // FIXME: Perhaps using $.data would be a better idea?
- options.formTemplate = template;
-
- var addButtonHTML = '' + options.addText + '';
- if (options.addContainerClass) {
- // If we have a specific container for the "add" button,
- // place it as the last child of that container:
- var addContainer = $('[class*="' + options.addContainerClass + '"');
- addContainer.append(addButtonHTML);
- addButton = addContainer.find('[class="' + options.addCssClass + '"]');
- } else if ($$.is('TR')) {
- // If forms are laid out as table rows, insert the
- // "add" button in a new table row:
- var numCols = $$.eq(0).children().length, // This is a bit of an assumption :|
- buttonRow = $('
' + addButtonHTML + '
').addClass(options.formCssClass + '-add');
- $$.parent().append(buttonRow);
- addButton = buttonRow.find('a');
- } else {
- // Otherwise, insert it immediately after the last form:
- $$.filter(':last').after(addButtonHTML);
- addButton = $$.filter(':last').next();
- }
-
- if (hideAddButton) addButton.hide();
-
- addButton.click(function() {
- var formCount = parseInt(totalForms.val()),
- row = options.formTemplate.clone(true).removeClass('formset-custom-template'),
- buttonRow = $($(this).parents('tr.' + options.formCssClass + '-add').get(0) || this),
- delCssSelector = $.trim(options.deleteCssClass).replace(/\s+/g, '.');
- applyExtraClasses(row, formCount);
- row.insertBefore(buttonRow).show();
- row.find(childElementSelector).each(function() {
- updateElementIndex($(this), options.prefix, formCount);
- });
- totalForms.val(formCount + 1);
- // Check if we're above the minimum allowed number of forms -> show all delete link(s)
- if (showDeleteLinks()){
- $('a.' + delCssSelector).each(function(){$(this).show();});
- }
- // Check if we've exceeded the maximum allowed number of forms:
- if (!showAddButton()) buttonRow.hide();
- // If a post-add callback was supplied, call it with the added form:
- if (options.added) options.added(row);
- return false;
- });
+ row.find('a.' + delCssSelector).click(function () {
+ var row = $(this).parents('.' + options.formCssClass)
+ var del = row.find('input:hidden[id $= "-DELETE"]')
+ var buttonRow = row.siblings('a.' + addCssSelector + ', .' + options.formCssClass + '-add')
+ var forms
+ if (del.length) {
+ // We're dealing with an inline formset.
+ // Rather than remove this form from the DOM, we'll mark it as deleted
+ // and hide it, then let Django handle the deleting:
+ del.val('on')
+ row.hide()
+ forms = $('.' + options.formCssClass).not(':hidden')
+ } else {
+ row.remove()
+ // Update the TOTAL_FORMS count:
+ forms = $('.' + options.formCssClass).not('.formset-custom-template')
+ totalForms.val(forms.length)
}
+ for (var i = 0, formCount = forms.length; i < formCount; i++) {
+ // Apply `extraClasses` to form rows so they're nicely alternating:
+ applyExtraClasses(forms.eq(i), i)
+ if (!del.length) {
+ // Also update names and IDs for all child controls (if this isn't
+ // a delete-able inline formset) so they remain in sequence:
+ forms.eq(i).find(childElementSelector).each(function () {
+ updateElementIndex($(this), options.prefix, i)
+ })
+ }
+ }
+ // Check if we've reached the minimum number of forms - hide all delete link(s)
+ if (!showDeleteLinks()) {
+ $('a.' + delCssSelector).each(function () { $(this).hide() })
+ }
+ // Check if we need to show the add button:
+ if (buttonRow.is(':hidden') && showAddButton()) buttonRow.show()
+ // If a post-delete callback was provided, call it with the deleted form:
+ if (options.removed) options.removed(row)
+ return false
+ })
+ }
- return $$;
- };
+ $$.each(function (i) {
+ var row = $(this)
+ var del = row.find('input:checkbox[id $= "-DELETE"]')
+ if (del.length) {
+ // If you specify "can_delete = True" when creating an inline formset,
+ // Django adds a checkbox to each form in the formset.
+ // Replace the default checkbox with a hidden field:
+ if (del.is(':checked')) {
+ // If an inline formset containing deleted forms fails validation, make sure
+ // we keep the forms hidden (thanks for the bug report and suggested fix Mike)
+ del.before('')
+ row.hide()
+ } else {
+ del.before('')
+ }
+ // Hide any labels associated with the DELETE checkbox:
+ $('label[for="' + del.attr('id') + '"]').hide()
+ del.remove()
+ }
+ if (hasChildElements(row)) {
+ row.addClass(options.formCssClass)
+ if (row.is(':visible')) {
+ insertDeleteLink(row)
+ applyExtraClasses(row, i)
+ }
+ }
+ })
- /* Setup plugin defaults */
- $.fn.formset.defaults = {
- prefix: 'form', // The form prefix for your django formset
- formTemplate: null, // The jQuery selection cloned to generate new form instances
- addText: 'add another', // Text for the add link
- deleteText: 'remove', // Text for the delete link
- addContainerClass: null, // Container CSS class for the add link
- deleteContainerClass: null, // Container CSS class for the delete link
- addCssClass: 'add-row', // CSS class applied to the add link
- deleteCssClass: 'delete-row', // CSS class applied to the delete link
- formCssClass: 'dynamic-form', // CSS class applied to each form in a formset
- extraClasses: [], // Additional CSS classes, which will be applied to each form in turn
- keepFieldValues: '', // jQuery selector for fields whose values should be kept when the form is cloned
- added: null, // Function called each time a new form is added
- removed: null, // Function called each time a form is deleted
- hideLastAddForm: false // When set to true, hide last empty add form (becomes visible when clicking on add button)
- };
-})(jQuery);
+ if ($$.length) {
+ var hideAddButton = !showAddButton()
+ var addButton; var template
+ if (options.formTemplate) {
+ // If a form template was specified, we'll clone it to generate new form instances:
+ template = (options.formTemplate instanceof $) ? options.formTemplate : $(options.formTemplate)
+ template.removeAttr('id').addClass(options.formCssClass + ' formset-custom-template')
+ template.find(childElementSelector).each(function () {
+ updateElementIndex($(this), options.prefix, '__prefix__')
+ })
+ insertDeleteLink(template)
+ } else {
+ // Otherwise, use the last form in the formset; this works much better if you've got
+ // extra (>= 1) forms (thnaks to justhamade for pointing this out):
+ if (options.hideLastAddForm) $('.' + options.formCssClass + ':last').hide()
+ template = $('.' + options.formCssClass + ':last').clone(true).removeAttr('id')
+ template.find('input:hidden[id $= "-DELETE"]').remove()
+ // Clear all cloned fields, except those the user wants to keep (thanks to brunogola for the suggestion):
+ template.find(childElementSelector).not(options.keepFieldValues).each(function () {
+ var elem = $(this)
+ // If this is a checkbox or radiobutton, uncheck it.
+ // This fixes Issue 1, reported by Wilson.Andrew.J:
+ if (elem.is('input:checkbox') || elem.is('input:radio')) {
+ elem.attr('checked', false)
+ } else {
+ elem.val('')
+ }
+ })
+ }
+ // FIXME: Perhaps using $.data would be a better idea?
+ options.formTemplate = template
+
+ var addButtonHTML = '' + options.addText + ''
+ if (options.addContainerClass) {
+ // If we have a specific container for the "add" button,
+ // place it as the last child of that container:
+ var addContainer = $('[class*="' + options.addContainerClass + '"')
+ addContainer.append(addButtonHTML)
+ addButton = addContainer.find('[class="' + options.addCssClass + '"]')
+ } else if ($$.is('TR')) {
+ // If forms are laid out as table rows, insert the
+ // "add" button in a new table row:
+ var numCols = $$.eq(0).children().length // This is a bit of an assumption :|
+ var buttonRow = $('
' + addButtonHTML + '
').addClass(options.formCssClass + '-add')
+ $$.parent().append(buttonRow)
+ addButton = buttonRow.find('a')
+ } else {
+ // Otherwise, insert it immediately after the last form:
+ $$.filter(':last').after(addButtonHTML)
+ addButton = $$.filter(':last').next()
+ }
+
+ if (hideAddButton) addButton.hide()
+
+ addButton.click(function () {
+ var formCount = parseInt(totalForms.val())
+ var row = options.formTemplate.clone(true).removeClass('formset-custom-template')
+ var buttonRow = $($(this).parents('tr.' + options.formCssClass + '-add').get(0) || this)
+ var delCssSelector = $.trim(options.deleteCssClass).replace(/\s+/g, '.')
+ applyExtraClasses(row, formCount)
+ row.insertBefore(buttonRow).show()
+ row.find(childElementSelector).each(function () {
+ updateElementIndex($(this), options.prefix, formCount)
+ })
+ totalForms.val(formCount + 1)
+ // Check if we're above the minimum allowed number of forms -> show all delete link(s)
+ if (showDeleteLinks()) {
+ $('a.' + delCssSelector).each(function () { $(this).show() })
+ }
+ // Check if we've exceeded the maximum allowed number of forms:
+ if (!showAddButton()) buttonRow.hide()
+ // If a post-add callback was supplied, call it with the added form:
+ if (options.added) options.added(row)
+ return false
+ })
+ }
+
+ return $$
+ }
+
+ /* Setup plugin defaults */
+ $.fn.formset.defaults = {
+ prefix: 'form', // The form prefix for your django formset
+ formTemplate: null, // The jQuery selection cloned to generate new form instances
+ addText: 'add another', // Text for the add link
+ deleteText: 'remove', // Text for the delete link
+ addContainerClass: null, // Container CSS class for the add link
+ deleteContainerClass: null, // Container CSS class for the delete link
+ addCssClass: 'add-row', // CSS class applied to the add link
+ deleteCssClass: 'delete-row', // CSS class applied to the delete link
+ formCssClass: 'dynamic-form', // CSS class applied to each form in a formset
+ extraClasses: [], // Additional CSS classes, which will be applied to each form in turn
+ keepFieldValues: '', // jQuery selector for fields whose values should be kept when the form is cloned
+ added: null, // Function called each time a new form is added
+ removed: null, // Function called each time a form is deleted
+ hideLastAddForm: false // When set to true, hide last empty add form (becomes visible when clicking on add button)
+ }
+})(jQuery)
diff --git a/note_kfet/static/js/konami.js b/note_kfet/static/js/konami.js
index a430a4b6..2b399b14 100644
--- a/note_kfet/static/js/konami.js
+++ b/note_kfet/static/js/konami.js
@@ -6,40 +6,40 @@
let cursor = 0
const KONAMI_CODE = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65]
-function afterKonami() {
- // Load Rythm.js
- var rythmScript = document.createElement('script')
- rythmScript.setAttribute('src','//unpkg.com/rythm.js@2.2.5/rythm.min.js')
- document.head.appendChild(rythmScript)
+function afterKonami () {
+ // Load Rythm.js
+ var rythmScript = document.createElement('script')
+ rythmScript.setAttribute('src', '//unpkg.com/rythm.js@2.2.5/rythm.min.js')
+ document.head.appendChild(rythmScript)
- rythmScript.addEventListener('load', function() {
- // Ker-Lyon audio courtesy of @adalan, ker-lyon.fr
- const audioElement = new Audio('/static/song/konami.ogg')
- audioElement.loop = true
- audioElement.play()
+ rythmScript.addEventListener('load', function () {
+ // Ker-Lyon audio courtesy of @adalan, ker-lyon.fr
+ const audioElement = new Audio('/static/song/konami.ogg')
+ audioElement.loop = true
+ audioElement.play()
- const rythm = new Rythm()
- rythm.connectExternalAudioElement(audioElement)
- rythm.addRythm('card', 'pulse', 50, 50, {
- min: 1,
- max: 1.1
- })
- rythm.addRythm('d-flex', 'color', 50, 50, {
- from: [64,64,64],
- to:[128,64,128]
- })
- rythm.addRythm('nav-link', 'jump', 150, 50, {
- min: 0,
- max: 10
- })
- rythm.start()
- });
+ const rythm = new Rythm()
+ rythm.connectExternalAudioElement(audioElement)
+ rythm.addRythm('card', 'pulse', 50, 50, {
+ min: 1,
+ max: 1.1
+ })
+ rythm.addRythm('d-flex', 'color', 50, 50, {
+ from: [64, 64, 64],
+ to: [128, 64, 128]
+ })
+ rythm.addRythm('nav-link', 'jump', 150, 50, {
+ min: 0,
+ max: 10
+ })
+ rythm.start()
+ })
}
// Register custom event
document.addEventListener('keydown', (e) => {
- cursor = (e.keyCode == KONAMI_CODE[cursor]) ? cursor + 1 : 0;
- if (cursor == KONAMI_CODE.length) {
- afterKonami()
- }
-});
+ cursor = (e.keyCode == KONAMI_CODE[cursor]) ? cursor + 1 : 0
+ if (cursor == KONAMI_CODE.length) {
+ afterKonami()
+ }
+})
diff --git a/note_kfet/static/js/transfer.js b/note_kfet/static/js/transfer.js
index e22d2b3f..db9cf9ac 100644
--- a/note_kfet/static/js/transfer.js
+++ b/note_kfet/static/js/transfer.js
@@ -1,440 +1,422 @@
-var LOCK = false;
+var LOCK = false
-sources = [];
-sources_notes_display = [];
-dests = [];
-dests_notes_display = [];
+sources = []
+sources_notes_display = []
+dests = []
+dests_notes_display = []
-function refreshHistory() {
- $("#history").load("/note/transfer/ #history");
+function refreshHistory () {
+ $('#history').load('/note/transfer/ #history')
}
-function reset(refresh=true) {
- sources_notes_display.length = 0;
- sources.length = 0;
- dests_notes_display.length = 0;
- dests.length = 0;
- $("#source_note_list").html("");
- $("#dest_note_list").html("");
- let source_field = $("#source_note");
- source_field.val("");
- let event = jQuery.Event("keyup");
- event.originalEvent = {charCode: 97};
- source_field.trigger(event);
- source_field.removeClass('is-invalid');
- source_field.attr("data-original-title", "").tooltip("hide");
- let dest_field = $("#dest_note");
- dest_field.val("");
- dest_field.trigger(event);
- dest_field.removeClass('is-invalid');
- dest_field.attr("data-original-title", "").tooltip("hide");
- let amount_field = $("#amount");
- amount_field.val("");
- amount_field.removeClass('is-invalid');
- $("#amount-required").html("");
- let reason_field = $("#reason");
- reason_field.val("");
- reason_field.removeClass('is-invalid');
- $("#reason-required").html("");
- $("#last_name").val("");
- $("#first_name").val("");
- $("#bank").val("");
- $("#user_note").val("");
- $("#profile_pic").attr("src", "/static/member/img/default_picture.png");
- $("#profile_pic_link").attr("href", "#");
- if (refresh) {
- refreshBalance();
- refreshHistory();
- }
+function reset (refresh = true) {
+ sources_notes_display.length = 0
+ sources.length = 0
+ dests_notes_display.length = 0
+ dests.length = 0
+ $('#source_note_list').html('')
+ $('#dest_note_list').html('')
+ const source_field = $('#source_note')
+ source_field.val('')
+ const event = jQuery.Event('keyup')
+ event.originalEvent = { charCode: 97 }
+ source_field.trigger(event)
+ source_field.removeClass('is-invalid')
+ source_field.attr('data-original-title', '').tooltip('hide')
+ const dest_field = $('#dest_note')
+ dest_field.val('')
+ dest_field.trigger(event)
+ dest_field.removeClass('is-invalid')
+ dest_field.attr('data-original-title', '').tooltip('hide')
+ const amount_field = $('#amount')
+ amount_field.val('')
+ amount_field.removeClass('is-invalid')
+ $('#amount-required').html('')
+ const reason_field = $('#reason')
+ reason_field.val('')
+ reason_field.removeClass('is-invalid')
+ $('#reason-required').html('')
+ $('#last_name').val('')
+ $('#first_name').val('')
+ $('#bank').val('')
+ $('#user_note').val('')
+ $('#profile_pic').attr('src', '/static/member/img/default_picture.png')
+ $('#profile_pic_link').attr('href', '#')
+ if (refresh) {
+ refreshBalance()
+ refreshHistory()
+ }
- LOCK = false;
+ LOCK = false
}
-$(document).ready(function() {
- /**
+$(document).ready(function () {
+ /**
* If we are in credit/debit mode, check that only one note is entered.
* More over, get first name and last name to autocomplete fields.
*/
- function checkUniqueNote() {
- if ($("#type_credit").is(":checked") || $("#type_debit").is(":checked")) {
- let arr = $("#type_credit").is(":checked") ? dests_notes_display : sources_notes_display;
+ function checkUniqueNote () {
+ if ($('#type_credit').is(':checked') || $('#type_debit').is(':checked')) {
+ const arr = $('#type_credit').is(':checked') ? dests_notes_display : sources_notes_display
- if (arr.length === 0)
- return;
+ if (arr.length === 0) { return }
- let last = arr[arr.length - 1];
- arr.length = 0;
- arr.push(last);
+ const last = arr[arr.length - 1]
+ arr.length = 0
+ arr.push(last)
- last.quantity = 1;
+ last.quantity = 1
- if (!last.note.user) {
- $.getJSON("/api/note/note/" + last.note.id + "/?format=json", function(note) {
- last.note.user = note.user;
- $.getJSON("/api/user/" + last.note.user + "/", function(user) {
- $("#last_name").val(user.last_name);
- $("#first_name").val(user.first_name);
- });
- });
+ if (!last.note.user) {
+ $.getJSON('/api/note/note/' + last.note.id + '/?format=json', function (note) {
+ last.note.user = note.user
+ $.getJSON('/api/user/' + last.note.user + '/', function (user) {
+ $('#last_name').val(user.last_name)
+ $('#first_name').val(user.first_name)
+ })
+ })
+ } else {
+ $.getJSON('/api/user/' + last.note.user + '/', function (user) {
+ $('#last_name').val(user.last_name)
+ $('#first_name').val(user.first_name)
+ })
+ }
+ }
+
+ return true
+ }
+
+ autoCompleteNote('source_note', 'source_note_list', sources, sources_notes_display,
+ 'source_alias', 'source_note', 'user_note', 'profile_pic', checkUniqueNote)
+ autoCompleteNote('dest_note', 'dest_note_list', dests, dests_notes_display,
+ 'dest_alias', 'dest_note', 'user_note', 'profile_pic', checkUniqueNote)
+
+ const source = $('#source_note')
+ const dest = $('#dest_note')
+
+ $('#type_transfer').change(function () {
+ if (LOCK) { return }
+
+ $('#source_me_div').removeClass('d-none')
+ $('#source_note').removeClass('is-invalid')
+ $('#dest_note').removeClass('is-invalid')
+ $('#special_transaction_div').addClass('d-none')
+ source.removeClass('d-none')
+ $('#source_note_list').removeClass('d-none')
+ $('#credit_type').addClass('d-none')
+ dest.removeClass('d-none')
+ $('#dest_note_list').removeClass('d-none')
+ $('#debit_type').addClass('d-none')
+
+ $('#source_note_label').text(select_emitters_label)
+ $('#dest_note_label').text(select_receveirs_label)
+
+ location.hash = 'transfer'
+ })
+
+ $('#type_credit').change(function () {
+ if (LOCK) { return }
+
+ $('#source_me_div').addClass('d-none')
+ $('#source_note').removeClass('is-invalid')
+ $('#dest_note').removeClass('is-invalid')
+ $('#special_transaction_div').removeClass('d-none')
+ $('#source_note_list').addClass('d-none')
+ $('#dest_note_list').removeClass('d-none')
+ source.addClass('d-none')
+ source.tooltip('hide')
+ $('#credit_type').removeClass('d-none')
+ dest.removeClass('d-none')
+ dest.val('')
+ dest.tooltip('hide')
+ $('#debit_type').addClass('d-none')
+
+ $('#source_note_label').text(transfer_type_label)
+ $('#dest_note_label').text(select_receveir_label)
+
+ if (dests_notes_display.length > 1) {
+ $('#dest_note_list').html('')
+ dests_notes_display.length = 0
+ }
+
+ location.hash = 'credit'
+ })
+
+ $('#type_debit').change(function () {
+ if (LOCK) { return }
+
+ $('#source_me_div').addClass('d-none')
+ $('#source_note').removeClass('is-invalid')
+ $('#dest_note').removeClass('is-invalid')
+ $('#special_transaction_div').removeClass('d-none')
+ $('#source_note_list').removeClass('d-none')
+ $('#dest_note_list').addClass('d-none')
+ source.removeClass('d-none')
+ source.val('')
+ source.tooltip('hide')
+ $('#credit_type').addClass('d-none')
+ dest.addClass('d-none')
+ dest.tooltip('hide')
+ $('#debit_type').removeClass('d-none')
+
+ $('#source_note_label').text(select_emitter_label)
+ $('#dest_note_label').text(transfer_type_label)
+
+ if (sources_notes_display.length > 1) {
+ $('#source_note_list').html('')
+ sources_notes_display.length = 0
+ }
+
+ location.hash = 'debit'
+ })
+
+ $('#credit_type').change(function () {
+ const type = $('#credit_type option:selected').text()
+ if ($('#type_credit').is(':checked')) { source.val(type) } else { dest.val(type) }
+ })
+
+ // Ensure we begin in transfer mode. Removing these lines may cause problems when reloading.
+ const type_transfer = $('#type_transfer') // Default mode
+ type_transfer.removeAttr('checked')
+ $('#type_credit').removeAttr('checked')
+ $('#type_debit').removeAttr('checked')
+
+ if (location.hash) { $('#type_' + location.hash.substr(1)).click() } else { type_transfer.click() }
+
+ $('#source_me').click(function () {
+ if (LOCK) { return }
+
+ // Shortcut to set the current user as the only emitter
+ sources_notes_display.length = 0
+ sources.length = 0
+ $('#source_note_list').html('')
+
+ const source_note = $('#source_note')
+ source_note.focus()
+ source_note.val('')
+ let event = jQuery.Event('keyup')
+ event.originalEvent = { charCode: 97 }
+ source_note.trigger(event)
+ source_note.val(username)
+ event = jQuery.Event('keyup')
+ event.originalEvent = { charCode: 97 }
+ source_note.trigger(event)
+ const fill_note = function () {
+ if (sources.length === 0) {
+ setTimeout(fill_note, 100)
+ return
+ }
+ event = jQuery.Event('keypress')
+ event.originalEvent = { charCode: 13 }
+ source_note.trigger(event)
+
+ source_note.tooltip('hide')
+ source_note.val('')
+ $('#dest_note').focus()
+ }
+ fill_note()
+ })
+})
+
+$('#btn_transfer').click(function () {
+ if (LOCK) { return }
+
+ LOCK = true
+
+ let error = false
+
+ const amount_field = $('#amount')
+ amount_field.removeClass('is-invalid')
+ $('#amount-required').html('')
+
+ const reason_field = $('#reason')
+ reason_field.removeClass('is-invalid')
+ $('#reason-required').html('')
+
+ if (!amount_field.val() || isNaN(amount_field.val()) || amount_field.val() <= 0) {
+ amount_field.addClass('is-invalid')
+ $('#amount-required').html('Ce champ est requis et doit comporter un nombre décimal strictement positif.')
+ error = true
+ }
+
+ const amount = Math.floor(100 * amount_field.val())
+ if (amount > 2147483647) {
+ amount_field.addClass('is-invalid')
+ $('#amount-required').html('Le montant ne doit pas excéder 21474836.47 €.')
+ error = true
+ }
+
+ if (!reason_field.val()) {
+ reason_field.addClass('is-invalid')
+ $('#reason-required').html('Ce champ est requis.')
+ error = true
+ }
+
+ if (!sources_notes_display.length && !$('#type_credit').is(':checked')) {
+ $('#source_note').addClass('is-invalid')
+ error = true
+ }
+
+ if (!dests_notes_display.length && !$('#type_debit').is(':checked')) {
+ $('#dest_note').addClass('is-invalid')
+ error = true
+ }
+
+ if (error) {
+ LOCK = false
+ return
+ }
+
+ let reason = reason_field.val()
+
+ if ($('#type_transfer').is(':checked')) {
+ // We copy the arrays to ensure that transactions are well-processed even if the form is reset
+ [...sources_notes_display].forEach(function (source) {
+ [...dests_notes_display].forEach(function (dest) {
+ if (source.note.id === dest.note.id) {
+ addMsg('Attention : la transaction de ' + pretty_money(amount) + ' de la note ' + source.name +
+ ' vers la note ' + dest.name + " n'a pas été faite car il s'agit de la même note au départ" +
+ " et à l'arrivée.", 'warning', 10000)
+ LOCK = false
+ return
+ }
+
+ $.post('/api/note/transaction/transaction/',
+ {
+ csrfmiddlewaretoken: CSRF_TOKEN,
+ quantity: source.quantity * dest.quantity,
+ amount: amount,
+ reason: reason,
+ valid: true,
+ polymorphic_ctype: TRANSFER_POLYMORPHIC_CTYPE,
+ resourcetype: 'Transaction',
+ source: source.note.id,
+ source_alias: source.name,
+ destination: dest.note.id,
+ destination_alias: dest.name
+ }).done(function () {
+ if (source.note.membership && source.note.membership.date_end < new Date().toISOString()) {
+ addMsg('Attention : la note émettrice ' + source.name + " n'est plus adhérente.",
+ 'danger', 30000)
+ }
+ if (dest.note.membership && dest.note.membership.date_end < new Date().toISOString()) {
+ addMsg('Attention : la note destination ' + dest.name + " n'est plus adhérente.",
+ 'danger', 30000)
+ }
+
+ if (!isNaN(source.note.balance)) {
+ const newBalance = source.note.balance - source.quantity * dest.quantity * amount
+ if (newBalance <= -5000) {
+ addMsg('Le transfert de ' +
+ pretty_money(source.quantity * dest.quantity * amount) + ' de la note ' +
+ source.name + ' vers la note ' + dest.name + ' a été fait avec succès, ' +
+ 'mais la note émettrice est en négatif sévère.', 'danger', 10000)
+ reset()
+ return
+ } else if (newBalance < 0) {
+ addMsg('Le transfert de ' +
+ pretty_money(source.quantity * dest.quantity * amount) + ' de la note ' +
+ source.name + ' vers la note ' + dest.name + ' a été fait avec succès, ' +
+ 'mais la note émettrice est en négatif.', 'warning', 10000)
+ reset()
+ return
}
- else {
- $.getJSON("/api/user/" + last.note.user + "/", function(user) {
- $("#last_name").val(user.last_name);
- $("#first_name").val(user.first_name);
- });
- }
- }
+ }
+ addMsg('Le transfert de ' +
+ pretty_money(source.quantity * dest.quantity * amount) + ' de la note ' + source.name +
+ ' vers la note ' + dest.name + ' a été fait avec succès !', 'success', 10000)
- return true;
- }
+ reset()
+ }).fail(function (err) { // do it again but valid = false
+ const errObj = JSON.parse(err.responseText)
+ if (errObj.non_field_errors) {
+ addMsg('Le transfert de ' +
+ pretty_money(source.quantity * dest.quantity * amount) + ' de la note ' + source.name +
+ ' vers la note ' + dest.name + ' a échoué : ' + errObj.non_field_errors, 'danger')
+ LOCK = false
+ return
+ }
- autoCompleteNote("source_note", "source_note_list", sources, sources_notes_display,
- "source_alias", "source_note", "user_note", "profile_pic", checkUniqueNote);
- autoCompleteNote("dest_note", "dest_note_list", dests, dests_notes_display,
- "dest_alias", "dest_note", "user_note", "profile_pic", checkUniqueNote);
-
- let source = $("#source_note");
- let dest = $("#dest_note");
-
- $("#type_transfer").change(function() {
- if (LOCK)
- return;
-
- $("#source_me_div").removeClass('d-none');
- $("#source_note").removeClass('is-invalid');
- $("#dest_note").removeClass('is-invalid');
- $("#special_transaction_div").addClass('d-none');
- source.removeClass('d-none');
- $("#source_note_list").removeClass('d-none');
- $("#credit_type").addClass('d-none');
- dest.removeClass('d-none');
- $("#dest_note_list").removeClass('d-none');
- $("#debit_type").addClass('d-none');
-
- $("#source_note_label").text(select_emitters_label);
- $("#dest_note_label").text(select_receveirs_label);
-
- location.hash = "transfer";
- });
-
- $("#type_credit").change(function() {
- if (LOCK)
- return;
-
- $("#source_me_div").addClass('d-none');
- $("#source_note").removeClass('is-invalid');
- $("#dest_note").removeClass('is-invalid');
- $("#special_transaction_div").removeClass('d-none');
- $("#source_note_list").addClass('d-none');
- $("#dest_note_list").removeClass('d-none');
- source.addClass('d-none');
- source.tooltip('hide');
- $("#credit_type").removeClass('d-none');
- dest.removeClass('d-none');
- dest.val('');
- dest.tooltip('hide');
- $("#debit_type").addClass('d-none');
-
- $("#source_note_label").text(transfer_type_label);
- $("#dest_note_label").text(select_receveir_label);
-
- if (dests_notes_display.length > 1) {
- $("#dest_note_list").html('');
- dests_notes_display.length = 0;
- }
-
- location.hash = "credit";
- });
-
- $("#type_debit").change(function() {
- if (LOCK)
- return;
-
- $("#source_me_div").addClass('d-none');
- $("#source_note").removeClass('is-invalid');
- $("#dest_note").removeClass('is-invalid');
- $("#special_transaction_div").removeClass('d-none');
- $("#source_note_list").removeClass('d-none');
- $("#dest_note_list").addClass('d-none');
- source.removeClass('d-none');
- source.val('');
- source.tooltip('hide');
- $("#credit_type").addClass('d-none');
- dest.addClass('d-none');
- dest.tooltip('hide');
- $("#debit_type").removeClass('d-none');
-
- $("#source_note_label").text(select_emitter_label);
- $("#dest_note_label").text(transfer_type_label);
-
- if (sources_notes_display.length > 1) {
- $("#source_note_list").html('');
- sources_notes_display.length = 0;
- }
-
- location.hash = "debit";
- });
-
- $("#credit_type").change(function() {
- let type = $("#credit_type option:selected").text();
- if ($("#type_credit").is(":checked"))
- source.val(type);
- else
- dest.val(type);
- });
-
- // Ensure we begin in transfer mode. Removing these lines may cause problems when reloading.
- let type_transfer = $("#type_transfer"); // Default mode
- type_transfer.removeAttr('checked');
- $("#type_credit").removeAttr('checked');
- $("#type_debit").removeAttr('checked');
-
- if (location.hash)
- $("#type_" + location.hash.substr(1)).click();
- else
- type_transfer.click();
-
- $("#source_me").click(function() {
- if (LOCK)
- return;
-
- // Shortcut to set the current user as the only emitter
- sources_notes_display.length = 0;
- sources.length = 0;
- $("#source_note_list").html("");
-
- let source_note = $("#source_note");
- source_note.focus();
- source_note.val("");
- let event = jQuery.Event("keyup");
- event.originalEvent = {charCode: 97};
- source_note.trigger(event);
- source_note.val(username);
- event = jQuery.Event("keyup");
- event.originalEvent = {charCode: 97};
- source_note.trigger(event);
- let fill_note = function() {
- if (sources.length === 0) {
- setTimeout(fill_note, 100);
- return;
- }
- event = jQuery.Event("keypress");
- event.originalEvent = {charCode: 13};
- source_note.trigger(event);
-
- source_note.tooltip('hide');
- source_note.val('');
- $("#dest_note").focus();
- };
- fill_note();
- });
-});
-
-$("#btn_transfer").click(function() {
- if (LOCK)
- return;
-
- LOCK = true;
-
- let error = false;
-
- let amount_field = $("#amount");
- amount_field.removeClass('is-invalid');
- $("#amount-required").html("");
-
- let reason_field = $("#reason");
- reason_field.removeClass('is-invalid');
- $("#reason-required").html("");
-
- if (!amount_field.val() || isNaN(amount_field.val()) || amount_field.val() <= 0) {
- amount_field.addClass('is-invalid');
- $("#amount-required").html("Ce champ est requis et doit comporter un nombre décimal strictement positif.");
- error = true;
- }
-
- let amount = Math.floor(100 * amount_field.val());
- if (amount > 2147483647) {
- amount_field.addClass('is-invalid');
- $("#amount-required").html("Le montant ne doit pas excéder 21474836.47 €.");
- error = true;
- }
-
- if (!reason_field.val()) {
- reason_field.addClass('is-invalid');
- $("#reason-required").html("Ce champ est requis.");
- error = true;
- }
-
- if (!sources_notes_display.length && !$("#type_credit").is(':checked')) {
- $("#source_note").addClass('is-invalid');
- error = true;
- }
-
- if (!dests_notes_display.length && !$("#type_debit").is(':checked')) {
- $("#dest_note").addClass('is-invalid');
- error = true;
- }
-
- if (error) {
- LOCK = false;
- return;
- }
-
- let reason = reason_field.val();
-
- if ($("#type_transfer").is(':checked')) {
- // We copy the arrays to ensure that transactions are well-processed even if the form is reset
- [...sources_notes_display].forEach(function (source) {
- [...dests_notes_display].forEach(function (dest) {
- if (source.note.id === dest.note.id) {
- addMsg("Attention : la transaction de " + pretty_money(amount) + " de la note " + source.name
- + " vers la note " + dest.name + " n'a pas été faite car il s'agit de la même note au départ" +
- " et à l'arrivée.","warning", 10000);
- LOCK = false;
- return;
- }
-
- $.post("/api/note/transaction/transaction/",
- {
- "csrfmiddlewaretoken": CSRF_TOKEN,
- "quantity": source.quantity * dest.quantity,
- "amount": amount,
- "reason": reason,
- "valid": true,
- "polymorphic_ctype": TRANSFER_POLYMORPHIC_CTYPE,
- "resourcetype": "Transaction",
- "source": source.note.id,
- "source_alias": source.name,
- "destination": dest.note.id,
- "destination_alias": dest.name
- }).done(function () {
- if (source.note.membership && source.note.membership.date_end < new Date().toISOString())
- addMsg("Attention : la note émettrice " + source.name + " n'est plus adhérente.",
- "danger", 30000);
- if (dest.note.membership && dest.note.membership.date_end < new Date().toISOString())
- addMsg("Attention : la note destination " + dest.name + " n'est plus adhérente.",
- "danger", 30000);
-
- if (!isNaN(source.note.balance)) {
- let newBalance = source.note.balance - source.quantity * dest.quantity * amount;
- if (newBalance <= -5000) {
- addMsg("Le transfert de "
- + pretty_money(source.quantity * dest.quantity * amount) + " de la note "
- + source.name + " vers la note " + dest.name + " a été fait avec succès, " +
- "mais la note émettrice est en négatif sévère.", "danger", 10000);
- reset();
- return;
- }
- else if (newBalance < 0) {
- addMsg("Le transfert de "
- + pretty_money(source.quantity * dest.quantity * amount) + " de la note "
- + source.name + " vers la note " + dest.name + " a été fait avec succès, " +
- "mais la note émettrice est en négatif.", "warning", 10000);
- reset();
- return;
- }
- }
- addMsg("Le transfert de "
- + pretty_money(source.quantity * dest.quantity * amount) + " de la note " + source.name
- + " vers la note " + dest.name + " a été fait avec succès !", "success", 10000);
-
- reset();
- }).fail(function (err) { // do it again but valid = false
- let errObj = JSON.parse(err.responseText);
- if (errObj["non_field_errors"]) {
- addMsg("Le transfert de "
- + pretty_money(source.quantity * dest.quantity * amount) + " de la note " + source.name
- + " vers la note " + dest.name + " a échoué : " + errObj["non_field_errors"], "danger");
- LOCK = false;
- return;
- }
-
- $.post("/api/note/transaction/transaction/",
- {
- "csrfmiddlewaretoken": CSRF_TOKEN,
- "quantity": source.quantity * dest.quantity,
- "amount": amount,
- "reason": reason,
- "valid": false,
- "invalidity_reason": "Solde insuffisant",
- "polymorphic_ctype": TRANSFER_POLYMORPHIC_CTYPE,
- "resourcetype": "Transaction",
- "source": source.note.id,
- "source_alias": source.name,
- "destination": dest.note.id,
- "destination_alias": dest.name
- }).done(function () {
- addMsg("Le transfert de "
- + pretty_money(source.quantity * dest.quantity * amount) + " de la note " + source.name
- + " vers la note " + dest.name + " a échoué : Solde insuffisant", "danger", 10000);
- reset();
- }).fail(function (err) {
- let errObj = JSON.parse(err.responseText);
- let error = errObj["detail"] ? errObj["detail"] : errObj["non_field_errors"]
- if (!error)
- error = err.responseText;
- addMsg("Le transfert de "
- + pretty_money(source.quantity * dest.quantity * amount) + " de la note " + source.name
- + " vers la note " + dest.name + " a échoué : " + error, "danger");
- LOCK = false;
- });
- });
- });
- });
- } else if ($("#type_credit").is(':checked') || $("#type_debit").is(':checked')) {
- let special_note;
- let user_note;
- let alias;
- let given_reason = reason;
- let source_id, dest_id;
- if ($("#type_credit").is(':checked')) {
- special_note = $("#credit_type").val();
- user_note = dests_notes_display[0].note;
- alias = dests_notes_display[0].name;
- source_id = special_note;
- dest_id = user_note.id;
- reason = "Crédit " + $("#credit_type option:selected").text().toLowerCase();
- if (given_reason.length > 0)
- reason += " (" + given_reason + ")";
- }
- else {
- special_note = $("#debit_type").val();
- user_note = sources_notes_display[0].note;
- alias = sources_notes_display[0].name;
- source_id = user_note.id;
- dest_id = special_note;
- reason = "Retrait " + $("#credit_type option:selected").text().toLowerCase();
- if (given_reason.length > 0)
- reason += " (" + given_reason + ")";
- }
- $.post("/api/note/transaction/transaction/",
+ $.post('/api/note/transaction/transaction/',
{
- "csrfmiddlewaretoken": CSRF_TOKEN,
- "quantity": 1,
- "amount": amount,
- "reason": reason,
- "valid": true,
- "polymorphic_ctype": SPECIAL_TRANSFER_POLYMORPHIC_CTYPE,
- "resourcetype": "SpecialTransaction",
- "source": source_id,
- "source_alias": sources_notes_display.length ? alias : null,
- "destination": dest_id,
- "destination_alias": dests_notes_display.length ? alias : null,
- "last_name": $("#last_name").val(),
- "first_name": $("#first_name").val(),
- "bank": $("#bank").val()
+ csrfmiddlewaretoken: CSRF_TOKEN,
+ quantity: source.quantity * dest.quantity,
+ amount: amount,
+ reason: reason,
+ valid: false,
+ invalidity_reason: 'Solde insuffisant',
+ polymorphic_ctype: TRANSFER_POLYMORPHIC_CTYPE,
+ resourcetype: 'Transaction',
+ source: source.note.id,
+ source_alias: source.name,
+ destination: dest.note.id,
+ destination_alias: dest.name
}).done(function () {
- addMsg("Le crédit/retrait a bien été effectué !", "success", 10000);
- if (user_note.membership && user_note.membership.date_end < new Date().toISOString())
- addMsg("Attention : la note " + alias + " n'est plus adhérente.", "danger", 10000);
- reset();
- }).fail(function (err) {
- let errObj = JSON.parse(err.responseText);
- let error = errObj["detail"] ? errObj["detail"] : errObj["non_field_errors"]
- if (!error)
- error = err.responseText;
- addMsg("Le crédit/retrait a échoué : " + error, "danger", 10000);
- LOCK = false;
- });
+ addMsg('Le transfert de ' +
+ pretty_money(source.quantity * dest.quantity * amount) + ' de la note ' + source.name +
+ ' vers la note ' + dest.name + ' a échoué : Solde insuffisant', 'danger', 10000)
+ reset()
+ }).fail(function (err) {
+ const errObj = JSON.parse(err.responseText)
+ let error = errObj.detail ? errObj.detail : errObj.non_field_errors
+ if (!error) { error = err.responseText }
+ addMsg('Le transfert de ' +
+ pretty_money(source.quantity * dest.quantity * amount) + ' de la note ' + source.name +
+ ' vers la note ' + dest.name + ' a échoué : ' + error, 'danger')
+ LOCK = false
+ })
+ })
+ })
+ })
+ } else if ($('#type_credit').is(':checked') || $('#type_debit').is(':checked')) {
+ let special_note
+ let user_note
+ let alias
+ const given_reason = reason
+ let source_id, dest_id
+ if ($('#type_credit').is(':checked')) {
+ special_note = $('#credit_type').val()
+ user_note = dests_notes_display[0].note
+ alias = dests_notes_display[0].name
+ source_id = special_note
+ dest_id = user_note.id
+ reason = 'Crédit ' + $('#credit_type option:selected').text().toLowerCase()
+ if (given_reason.length > 0) { reason += ' (' + given_reason + ')' }
+ } else {
+ special_note = $('#debit_type').val()
+ user_note = sources_notes_display[0].note
+ alias = sources_notes_display[0].name
+ source_id = user_note.id
+ dest_id = special_note
+ reason = 'Retrait ' + $('#credit_type option:selected').text().toLowerCase()
+ if (given_reason.length > 0) { reason += ' (' + given_reason + ')' }
}
-});
+ $.post('/api/note/transaction/transaction/',
+ {
+ csrfmiddlewaretoken: CSRF_TOKEN,
+ quantity: 1,
+ amount: amount,
+ reason: reason,
+ valid: true,
+ polymorphic_ctype: SPECIAL_TRANSFER_POLYMORPHIC_CTYPE,
+ resourcetype: 'SpecialTransaction',
+ source: source_id,
+ source_alias: sources_notes_display.length ? alias : null,
+ destination: dest_id,
+ destination_alias: dests_notes_display.length ? alias : null,
+ last_name: $('#last_name').val(),
+ first_name: $('#first_name').val(),
+ bank: $('#bank').val()
+ }).done(function () {
+ addMsg('Le crédit/retrait a bien été effectué !', 'success', 10000)
+ if (user_note.membership && user_note.membership.date_end < new Date().toISOString()) { addMsg('Attention : la note ' + alias + " n'est plus adhérente.", 'danger', 10000) }
+ reset()
+ }).fail(function (err) {
+ const errObj = JSON.parse(err.responseText)
+ let error = errObj.detail ? errObj.detail : errObj.non_field_errors
+ if (!error) { error = err.responseText }
+ addMsg('Le crédit/retrait a échoué : ' + error, 'danger', 10000)
+ LOCK = false
+ })
+ }
+})