diff --git a/kfet/static/kfet/css/history.css b/kfet/static/kfet/css/history.css index 9cd4cd28..42e73527 100644 --- a/kfet/static/kfet/css/history.css +++ b/kfet/static/kfet/css/history.css @@ -20,7 +20,7 @@ z-index:10; } -#history .opegroup { +#history .group { height:30px; line-height:30px; background-color: #c63b52; @@ -30,29 +30,29 @@ overflow:auto; } -#history .opegroup .time { +#history .group .time { width:70px; } -#history .opegroup .trigramme { +#history .group .trigramme { width:55px; text-align:right; } -#history .opegroup .amount { +#history .group .amount { text-align:right; width:90px; } -#history .opegroup .valid_by { +#history .group .valid_by { padding-left:20px } -#history .opegroup .comment { +#history .group .comment { padding-left:20px; } -#history .ope { +#history .entry { position:relative; height:25px; line-height:24px; @@ -61,38 +61,38 @@ overflow:auto; } -#history .ope .amount { +#history .entry .amount { width:50px; text-align:right; } -#history .ope .infos1 { +#history .entry .infos1 { width:80px; text-align:right; } -#history .ope .infos2 { +#history .entry .infos2 { padding-left:15px; } -#history .ope .addcost { +#history .entry .addcost { padding-left:20px; } -#history .ope .canceled { +#history .entry .canceled { padding-left:20px; } -#history div.ope.ui-selected, #history div.ope.ui-selecting { +#history div.entry.ui-selected, #history div.entry.ui-selecting { background-color:rgba(200,16,46,0.6); color:#FFF; } -#history .ope.canceled, #history .transfer.canceled { +#history .entry.canceled { color:#444; } -#history .ope.canceled::before, #history.transfer.canceled::before { +#history .entry.canceled::before { position: absolute; content: ' '; width:100%; @@ -101,10 +101,11 @@ border-top: 1px solid rgba(200,16,46,0.5); } -#history .transfer .amount { - width:80px; +#history .group .infos { + text-align:center; + width:145px; } -#history .transfer .from_acc { - padding-left:10px; +#history .entry .glyphicon { + padding-left:15px; } diff --git a/kfet/static/kfet/js/history.js b/kfet/static/kfet/js/history.js index a7372b87..540c8239 100644 --- a/kfet/static/kfet/js/history.js +++ b/kfet/static/kfet/js/history.js @@ -2,31 +2,59 @@ function dateUTCToParis(date) { return moment.tz(date, 'UTC').tz('Europe/Paris'); } +// TODO : classifier (later) function KHistory(options = {}) { $.extend(this, KHistory.default_options, options); this.$container = $(this.container); + this.$container.selectable({ + filter: 'div.group, div.entry', + selected: function (e, ui) { + $(ui.selected).each(function () { + if ($(this).hasClass('group')) { + var id = $(this).data('id'); + $(this).siblings('.entry').filter(function () { + return $(this).data('group_id') == id + }).addClass('ui-selected'); + } + }); + }, + }); + this.reset = function () { this.$container.html(''); }; - this.addOpeGroup = function (opegroup) { - var $day = this._getOrCreateDay(opegroup['at']); - var $opegroup = this._opeGroupHtml(opegroup); + this.add_history_group = function (group) { + var $day = this._get_or_create_day(group['at']); + var $group = this._group_html(group); - $day.after($opegroup); + $day.after($group); - var trigramme = opegroup['on_acc_trigramme']; - var is_cof = opegroup['is_cof']; - for (var i = 0; i < opegroup['opes'].length; i++) { - var $ope = this._opeHtml(opegroup['opes'][i], is_cof, trigramme); - $ope.data('opegroup', opegroup['id']); - $opegroup.after($ope); + var trigramme = group['on_acc_trigramme']; + var is_cof = group['is_cof']; + var type = group['type'] + // TODO : simplifier ça ? + switch (type) { + case 'operation': + for (let ope of group['entries']) { + var $ope = this._ope_html(ope, is_cof, trigramme); + $ope.data('group_id', group['id']); + $group.after($ope); + } + break; + case 'transfer': + for (let transfer of group['entries']) { + var $transfer = this._transfer_html(transfer); + $transfer.data('group_id', group['id']); + $group.after($transfer); + } + break; } } - this._opeHtml = function (ope, is_cof, trigramme) { + this._ope_html = function (ope, is_cof, trigramme) { var $ope_html = $(this.template_ope); var parsed_amount = parseFloat(ope['amount']); var amount = amountDisplay(parsed_amount, is_cof, trigramme); @@ -54,7 +82,8 @@ function KHistory(options = {}) { } $ope_html - .data('ope', ope['id']) + .data('type', 'operation') + .data('id', ope['id']) .find('.amount').text(amount).end() .find('.infos1').text(infos1).end() .find('.infos2').text(infos2).end(); @@ -62,54 +91,89 @@ function KHistory(options = {}) { var addcost_for = ope['addcost_for__trigramme']; if (addcost_for) { var addcost_amount = parseFloat(ope['addcost_amount']); - $ope_html.find('.addcost').text('(' + amountDisplay(addcost_amount, is_cof) + 'UKF pour ' + addcost_for + ')'); + $ope_html.find('.addcost').text('(' + amountDisplay(addcost_amount, is_cof) + ' UKF pour ' + addcost_for + ')'); } if (ope['canceled_at']) - this.cancelOpe(ope, $ope_html); + this.cancel_entry(ope, $ope_html); return $ope_html; } - this.cancelOpe = function (ope, $ope = null) { - if (!$ope) - $ope = this.findOpe(ope['id']); + this._transfer_html = function (transfer) { + var $transfer_html = $(this.template_transfer); + var parsed_amount = parseFloat(transfer['amount']); + var amount = parsed_amount.toFixed(2) + '€'; - var cancel = 'Annulé'; - var canceled_at = dateUTCToParis(ope['canceled_at']); - if (ope['canceled_by__trigramme']) - cancel += ' par ' + ope['canceled_by__trigramme']; - cancel += ' le ' + canceled_at.format('DD/MM/YY à HH:mm:ss'); + $transfer_html + .data('type', 'transfer') + .data('id', transfer['id']) + .find('.amount').text(amount).end() + .find('.infos1').text(transfer['from_acc']).end() + .find('.infos2').text(transfer['to_acc']).end(); - $ope.addClass('canceled').find('.canceled').text(cancel); + if (transfer['canceled_at']) + this.cancel_entry(transfer, $transfer_html); + + return $transfer_html; } - this._opeGroupHtml = function (opegroup) { - var $opegroup_html = $(this.template_opegroup); - var at = dateUTCToParis(opegroup['at']).format('HH:mm:ss'); - var trigramme = opegroup['on_acc__trigramme']; - var amount = amountDisplay( - parseFloat(opegroup['amount']), opegroup['is_cof'], trigramme); - var comment = opegroup['comment'] || ''; + this.cancel_entry = function (entry, $entry = null) { + if (!$entry) + $entry = this.find_entry(entry["id"], entry["type"]); - $opegroup_html - .data('opegroup', opegroup['id']) + var cancel = 'Annulé'; + var canceled_at = dateUTCToParis(entry['canceled_at']); + if (entry['canceled_by__trigramme']) + cancel += ' par ' + entry['canceled_by__trigramme']; + cancel += ' le ' + canceled_at.format('DD/MM/YY à HH:mm:ss'); + + $entry.addClass('canceled').find('.canceled').text(cancel); + } + + this._group_html = function (group) { + var type = group['type']; + + + switch (type) { + case 'operation': + var $group_html = $(this.template_opegroup); + var trigramme = group['on_acc__trigramme']; + var amount = amountDisplay( + parseFloat(group['amount']), group['is_cof'], trigramme); + break; + case 'transfer': + var $group_html = $(this.template_transfergroup); + $group_html.find('.infos').text('Transferts').end() + var trigramme = ''; + var amount = ''; + break; + } + + + var at = dateUTCToParis(group['at']).format('HH:mm:ss'); + var comment = group['comment'] || ''; + + $group_html + .data('type', type) + .data('id', group['id']) .find('.time').text(at).end() .find('.amount').text(amount).end() .find('.comment').text(comment).end() .find('.trigramme').text(trigramme).end(); if (!this.display_trigramme) - $opegroup_html.find('.trigramme').remove(); + $group_html.find('.trigramme').remove(); + $group_html.find('.info').remove(); - if (opegroup['valid_by__trigramme']) - $opegroup_html.find('.valid_by').text('Par ' + opegroup['valid_by__trigramme']); + if (group['valid_by__trigramme']) + $group_html.find('.valid_by').text('Par ' + group['valid_by__trigramme']); - return $opegroup_html; + return $group_html; } - this._getOrCreateDay = function (date) { + this._get_or_create_day = function (date) { var at = dateUTCToParis(date); var at_ser = at.format('YYYY-MM-DD'); var $day = this.$container.find('.day').filter(function () { @@ -118,35 +182,123 @@ function KHistory(options = {}) { if ($day.length == 1) return $day; var $day = $(this.template_day).prependTo(this.$container); - return $day.data('date', at_ser).text(at.format('D MMMM')); + return $day.data('date', at_ser).text(at.format('D MMMM YYYY')); } - this.findOpeGroup = function (id) { - return this.$container.find('.opegroup').filter(function () { - return $(this).data('opegroup') == id + this.find_group = function (id, type = "operation") { + return this.$container.find('.group').filter(function () { + return ($(this).data('id') == id && $(this).data("type") == type) }); } - this.findOpe = function (id) { - return this.$container.find('.ope').filter(function () { - return $(this).data('ope') == id + this.find_entry = function (id, type = 'operation') { + return this.$container.find('.entry').filter(function () { + return ($(this).data('id') == id && $(this).data('type') == type) }); } - this.cancelOpeGroup = function (opegroup) { - var $opegroup = this.findOpeGroup(opegroup['id']); - var trigramme = $opegroup.find('.trigramme').text(); + this.update_opegroup = function (group, type = "operation") { + var $group = this.find_group(group['id'], type); + var trigramme = $group.find('.trigramme').text(); var amount = amountDisplay( - parseFloat(opegroup['amount']), opegroup['is_cof'], trigramme); - $opegroup.find('.amount').text(amount); + parseFloat(group['amount']), group['is_cof'], trigramme); + $group.find('.amount').text(amount); } + this.fetch = function (fetch_options) { + options = $.extend({}, this.fetch_options, fetch_options); + var that = this; + return $.ajax({ + dataType: "json", + url: django_urls["kfet.history.json"](), + method: "POST", + data: options, + }).done(function (data) { + for (let group of data['groups']) { + that.add_history_group(group); + } + }); + } + + this._cancel = function (type, opes, password = "") { + if (window.lock == 1) + return false + window.lock = 1; + var that = this; + return $.ajax({ + dataType: "json", + url: django_urls[`kfet.${type}s.cancel`](), + method: "POST", + data: opes, + beforeSend: function ($xhr) { + $xhr.setRequestHeader("X-CSRFToken", csrftoken); + if (password != '') + $xhr.setRequestHeader("KFetPassword", password); + }, + + }).done(function (data) { + window.lock = 0; + that.$container.find('.ui-selected').removeClass('ui-selected'); + for (let entry of data["canceled"]) { + entry["type"] = type; + that.cancel_entry(entry); + } + if (type == "operation") { + for (let opegroup of data["opegroups_to_update"]) { + that.update_opegroup(opegroup) + } + } + }).fail(function ($xhr) { + var data = $xhr.responseJSON; + switch ($xhr.status) { + case 403: + requestAuth(data, function (password) { + this.cancel(opes, password); + }); + break; + case 400: + displayErrors(getErrorsHtml(data)); + break; + } + window.lock = 0; + }); + } + + this.cancel_selected = function () { + var opes_to_cancel = { + "transfers": [], + "operations": [], + } + this.$container.find('.entry.ui-selected').each(function () { + type = $(this).data("type"); + opes_to_cancel[`${type}s`].push($(this).data("id")); + }); + if (opes_to_cancel["transfers"].length > 0 && opes_to_cancel["operations"].length > 0) { + // Lancer 2 requêtes AJAX et gérer tous les cas d'erreurs possibles est trop complexe + $.alert({ + title: 'Erreur', + content: "Impossible de supprimer des transferts et des opérations en même temps !", + backgroundDismiss: true, + animation: 'top', + closeAnimation: 'bottom', + keyboardEnabled: true, + }); + } else if (opes_to_cancel["transfers"].length > 0) { + delete opes_to_cancel["operations"]; + this._cancel("transfer", opes_to_cancel); + } else if (opes_to_cancel["operations"].length > 0) { + delete opes_to_cancel["transfers"]; + this._cancel("operation", opes_to_cancel); + } + } } KHistory.default_options = { container: '#history', template_day: '
', - template_opegroup: '