Improve transfer UI

This commit is contained in:
Yohann D'ANELLO 2020-07-31 21:24:23 +02:00
parent 932a546213
commit dca655949e
5 changed files with 71 additions and 17 deletions

View File

@ -4,6 +4,7 @@
import functools import functools
import json import json
import operator import operator
from time import sleep
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
@ -44,6 +45,14 @@ class InstancedPermission:
else: else:
oldpk = obj.pk oldpk = obj.pk
# Ensure previous models are deleted # Ensure previous models are deleted
count = 0
while count < 1000:
if self.model.model_class().objects.filter(pk=obj.pk).exists():
# If the object exists, that means that one permission is currently checked.
# We wait before the other permission, at most 1 second.
sleep(1)
continue
break
for o in self.model.model_class().objects.filter(pk=obj.pk).all(): for o in self.model.model_class().objects.filter(pk=obj.pk).all():
o._force_delete = True o._force_delete = True
Model.delete(o) Model.delete(o)

View File

@ -17,6 +17,7 @@ from django.http import HttpResponse
from django.shortcuts import redirect from django.shortcuts import redirect
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.utils import timezone
from django.views import View from django.views import View
from django.views.generic import DetailView, UpdateView, CreateView, RedirectView, TemplateView from django.views.generic import DetailView, UpdateView, CreateView, RedirectView, TemplateView
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -56,7 +57,11 @@ class WEIListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context["can_create_wei"] = PermissionBackend.check_perm(self.request.user, "wei.add_weiclub", WEIClub()) context["can_create_wei"] = PermissionBackend.check_perm(self.request.user, "wei.add_weiclub", WEIClub(
year=0,
date_start=timezone.now().date(),
date_end=timezone.now().date(),
))
return context return context

View File

@ -14,8 +14,14 @@ function reset(refresh=true) {
dests.length = 0; dests.length = 0;
$("#source_note_list").html(""); $("#source_note_list").html("");
$("#dest_note_list").html(""); $("#dest_note_list").html("");
$("#amount").val(""); let amount_field = $("#amount");
$("#reason").val(""); 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(""); $("#last_name").val("");
$("#first_name").val(""); $("#first_name").val("");
$("#bank").val(""); $("#bank").val("");
@ -140,7 +146,9 @@ $(document).ready(function() {
$("#source_me").click(function() { $("#source_me").click(function() {
// Shortcut to set the current user as the only emitter // Shortcut to set the current user as the only emitter
reset(false); sources_notes_display.length = 0;
sources.length = 0;
$("#source_note_list").html("");
let source_note = $("#source_note"); let source_note = $("#source_note");
source_note.focus(); source_note.focus();
@ -170,15 +178,45 @@ $(document).ready(function() {
}); });
$("#btn_transfer").click(function() { $("#btn_transfer").click(function() {
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("<strong>Ce champ est requis et doit comporter un nombre décimal strictement positif.</strong>");
error = true;
}
if (!reason_field.val()) {
reason_field.addClass('is-invalid');
$("#reason-required").html("<strong>Ce champ est requis.</strong>");
error = true;
}
if (error)
return;
let amount = 100 * amount_field.val();
let reason = reason_field.val();
if ($("#type_transfer").is(':checked')) { if ($("#type_transfer").is(':checked')) {
sources_notes_display.forEach(function (source) {
dests_notes_display.forEach(function (dest) { // 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) {
$.post("/api/note/transaction/transaction/", $.post("/api/note/transaction/transaction/",
{ {
"csrfmiddlewaretoken": CSRF_TOKEN, "csrfmiddlewaretoken": CSRF_TOKEN,
"quantity": source.quantity * dest.quantity, "quantity": source.quantity * dest.quantity,
"amount": 100 * $("#amount").val(), "amount": amount,
"reason": $("#reason").val(), "reason": reason,
"valid": true, "valid": true,
"polymorphic_ctype": TRANSFER_POLYMORPHIC_CTYPE, "polymorphic_ctype": TRANSFER_POLYMORPHIC_CTYPE,
"resourcetype": "Transaction", "resourcetype": "Transaction",
@ -188,7 +226,7 @@ $("#btn_transfer").click(function() {
"destination_alias": dest.name "destination_alias": dest.name
}).done(function () { }).done(function () {
addMsg("Le transfert de " addMsg("Le transfert de "
+ pretty_money(source.quantity * dest.quantity * 100 * $("#amount").val()) + " de la note " + source.name + 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); + " vers la note " + dest.name + " a été fait avec succès !", "success", 10000);
reset(); reset();
@ -197,8 +235,8 @@ $("#btn_transfer").click(function() {
{ {
"csrfmiddlewaretoken": CSRF_TOKEN, "csrfmiddlewaretoken": CSRF_TOKEN,
"quantity": source.quantity * dest.quantity, "quantity": source.quantity * dest.quantity,
"amount": 100 * $("#amount").val(), "amount": amount,
"reason": $("#reason").val(), "reason": reason,
"valid": false, "valid": false,
"invalidity_reason": "Solde insuffisant", "invalidity_reason": "Solde insuffisant",
"polymorphic_ctype": TRANSFER_POLYMORPHIC_CTYPE, "polymorphic_ctype": TRANSFER_POLYMORPHIC_CTYPE,
@ -209,12 +247,12 @@ $("#btn_transfer").click(function() {
"destination_alias": dest.name "destination_alias": dest.name
}).done(function () { }).done(function () {
addMsg("Le transfert de " addMsg("Le transfert de "
+ pretty_money(source.quantity * dest.quantity * 100 * $("#amount").val()) + " de la note " + source.name + pretty_money(source.quantity * dest.quantity * amount) + " de la note " + source.name
+ " vers la note " + dest.name + " a échoué : Solde insuffisant", "danger", 10000); + " vers la note " + dest.name + " a échoué : Solde insuffisant", "danger", 10000);
}).fail(function (err) { }).fail(function (err) {
addMsg("Le transfert de " addMsg("Le transfert de "
+ pretty_money(source.quantity * dest.quantity * 100 * $("#amount").val()) + " de la note " + source.name + pretty_money(source.quantity * dest.quantity * amount) + " de la note " + source.name
+ " vers la note " + dest.name + " a échoué : " + JSON.parse(err.responseText)["detail"], "danger", 10000); + " vers la note " + dest.name + " a échoué : " + err.responseText, "danger");
}); });
}); });
}); });
@ -222,7 +260,7 @@ $("#btn_transfer").click(function() {
} else if ($("#type_credit").is(':checked') || $("#type_debit").is(':checked')) { } else if ($("#type_credit").is(':checked') || $("#type_debit").is(':checked')) {
let special_note = $("#credit_type").val(); let special_note = $("#credit_type").val();
let user_note; let user_note;
let given_reason = $("#reason").val(); let given_reason = reason;
let source, dest, reason; let source, dest, reason;
if ($("#type_credit").is(':checked')) { if ($("#type_credit").is(':checked')) {
user_note = dests_notes_display[0].note.id; user_note = dests_notes_display[0].note.id;
@ -244,7 +282,7 @@ $("#btn_transfer").click(function() {
{ {
"csrfmiddlewaretoken": CSRF_TOKEN, "csrfmiddlewaretoken": CSRF_TOKEN,
"quantity": 1, "quantity": 1,
"amount": 100 * $("#amount").val(), "amount": amount,
"reason": reason, "reason": reason,
"valid": true, "valid": true,
"polymorphic_ctype": SPECIAL_TRANSFER_POLYMORPHIC_CTYPE, "polymorphic_ctype": SPECIAL_TRANSFER_POLYMORPHIC_CTYPE,

View File

@ -8,4 +8,5 @@
<div class="input-group-append"> <div class="input-group-append">
<span class="input-group-text"></span> <span class="input-group-text"></span>
</div> </div>
<p id="amount-required" class="invalid-feedback"></p>
</div> </div>

View File

@ -100,7 +100,8 @@ SPDX-License-Identifier: GPL-2.0-or-later
<div class="form-row"> <div class="form-row">
<div class="col-md-12"> <div class="col-md-12">
<label for="reason">{% trans "Reason" %} :</label> <label for="reason">{% trans "Reason" %} :</label>
<input class="form-control mx-auto d-block" type="text" id="reason" required /> <input class="form-control mx-auto d-block" type="text" id="reason" />
<p id="reason-required" class="invalid-feedback"></p>
</div> </div>
</div> </div>