Merge branch 'devalidation_reason' into 'master'

Motif de dévalidation

See merge request bde/nk20!67
This commit is contained in:
Pierre-antoine Comby 2020-03-27 13:56:39 +01:00
commit ed746f39b2
8 changed files with 342 additions and 103 deletions

View File

@ -2,6 +2,7 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from django.db import models from django.db import models
from django.db.models import F
from django.urls import reverse from django.urls import reverse
from django.utils import timezone from django.utils import timezone
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -93,12 +94,26 @@ class Transaction(PolymorphicModel):
related_name='+', related_name='+',
verbose_name=_('source'), verbose_name=_('source'),
) )
source_alias = models.CharField(
max_length=255,
default="", # Will be remplaced by the name of the note on save
verbose_name=_('used alias'),
)
destination = models.ForeignKey( destination = models.ForeignKey(
Note, Note,
on_delete=models.PROTECT, on_delete=models.PROTECT,
related_name='+', related_name='+',
verbose_name=_('destination'), verbose_name=_('destination'),
) )
destination_alias = models.CharField(
max_length=255,
default="", # Will be remplaced by the name of the note on save
verbose_name=_('used alias'),
)
created_at = models.DateTimeField( created_at = models.DateTimeField(
verbose_name=_('created at'), verbose_name=_('created at'),
default=timezone.now, default=timezone.now,
@ -115,11 +130,19 @@ class Transaction(PolymorphicModel):
verbose_name=_('reason'), verbose_name=_('reason'),
max_length=255, max_length=255,
) )
valid = models.BooleanField( valid = models.BooleanField(
verbose_name=_('valid'), verbose_name=_('valid'),
default=True, default=True,
) )
invalidity_reason = models.CharField(
verbose_name=_('invalidity reason'),
max_length=255,
default=None,
null=True,
)
class Meta: class Meta:
verbose_name = _("transaction") verbose_name = _("transaction")
verbose_name_plural = _("transactions") verbose_name_plural = _("transactions")
@ -134,6 +157,13 @@ class Transaction(PolymorphicModel):
When saving, also transfer money between two notes When saving, also transfer money between two notes
""" """
# If the aliases are not entered, we assume that the used alias is the name of the note
if not self.source_alias:
self.source_alias = str(self.source)
if not self.destination_alias:
self.destination_alias = str(self.destination)
if self.source.pk == self.destination.pk: if self.source.pk == self.destination.pk:
# When source == destination, no money is transfered # When source == destination, no money is transfered
super().save(*args, **kwargs) super().save(*args, **kwargs)
@ -152,6 +182,10 @@ class Transaction(PolymorphicModel):
self.source.balance -= to_transfer self.source.balance -= to_transfer
self.destination.balance += to_transfer self.destination.balance += to_transfer
# When a transaction is declared valid, we ensure that the invalidity reason is null, if it was
# previously invalid
self.invalidity_reason = None
# We save first the transaction, in case of the user has no right to transfer money # We save first the transaction, in case of the user has no right to transfer money
super().save(*args, **kwargs) super().save(*args, **kwargs)

View File

@ -5,6 +5,7 @@ import html
import django_tables2 as tables import django_tables2 as tables
from django.db.models import F from django.db.models import F
from django.utils.html import format_html
from django_tables2.utils import A from django_tables2.utils import A
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -20,19 +21,48 @@ class HistoryTable(tables.Table):
'table table-condensed table-striped table-hover' 'table table-condensed table-striped table-hover'
} }
model = Transaction model = Transaction
exclude = ("id", "polymorphic_ctype", ) exclude = ("id", "polymorphic_ctype", "invalidity_reason", "source_alias", "destination_alias",)
template_name = 'django_tables2/bootstrap4.html' template_name = 'django_tables2/bootstrap4.html'
sequence = ('...', 'type', 'total', 'valid', ) sequence = ('...', 'type', 'total', 'valid',)
orderable = False orderable = False
source = tables.Column(
attrs={
"td": {
"data-toggle": "tooltip",
"title": lambda record: _("used alias").capitalize() + " : " + record.source_alias,
}
}
)
destination = tables.Column(
attrs={
"td": {
"data-toggle": "tooltip",
"title": lambda record: _("used alias").capitalize() + " : " + record.destination_alias,
}
}
)
type = tables.Column() type = tables.Column()
total = tables.Column() # will use Transaction.total() !! total = tables.Column() # will use Transaction.total() !!
valid = tables.Column(attrs={"td": {"id": lambda record: "validate_" + str(record.id), valid = tables.Column(
"class": lambda record: str(record.valid).lower() + ' validate', attrs={
"onclick": lambda record: 'de_validate(' + str(record.id) + ', ' "td": {
+ str(record.valid).lower() + ')'}}) "id": lambda record: "validate_" + str(record.id),
"class": lambda record: str(record.valid).lower() + ' validate',
"data-toggle": "tooltip",
"title": lambda record: _("Click to invalidate") if record.valid else _("Click to validate"),
"onclick": lambda record: 'in_validate(' + str(record.id) + ', ' + str(record.valid).lower() + ')',
"onmouseover": lambda record: '$("#invalidity_reason_'
+ str(record.id) + '").show();$("#invalidity_reason_'
+ str(record.id) + '").focus();',
"onmouseout": lambda record: '$("#invalidity_reason_' + str(record.id) + '").hide()',
}
}
)
def order_total(self, queryset, is_descending): def order_total(self, queryset, is_descending):
# needed for rendering # needed for rendering
@ -53,8 +83,18 @@ class HistoryTable(tables.Table):
def render_reason(self, value): def render_reason(self, value):
return html.unescape(value) return html.unescape(value)
def render_valid(self, value): def render_valid(self, value, record):
return "" if value else "" """
When the validation status is hovered, an input field is displayed to let the user specify an invalidity reason
"""
val = "" if value else ""
val += "<input type='text' class='form-control' id='invalidity_reason_" + str(record.id) \
+ "' value='" + (html.escape(record.invalidity_reason)
if record.invalidity_reason else ("" if value else str(_("No reason specified")))) \
+ "'" + ("" if value else " disabled") \
+ " placeholder='" + html.escape(_("invalidity reason").capitalize()) + "'" \
+ " style='position: absolute; width: 15em; margin-left: -15.5em; margin-top: -2em; display: none;'>"
return format_html(val)
# function delete_button(id) provided in template file # function delete_button(id) provided in template file

View File

@ -327,7 +327,7 @@
"note", "note",
"transaction" "transaction"
], ],
"query": "[\"AND\", {\"source\": [\"user\", \"note\"]}, {\"amount__lte\": [\"user\", \"note\", \"balance\"]}]", "query": "[\"AND\", {\"source\": [\"user\", \"note\"]}, [\"OR\", {\"amount__lte\": [\"user\", \"note\", \"balance\"]}, {\"valid\": false}]]",
"type": "add", "type": "add",
"mask": 1, "mask": 1,
"field": "", "field": "",
@ -387,7 +387,7 @@
"note", "note",
"recurrenttransaction" "recurrenttransaction"
], ],
"query": "[\"AND\", {\"destination\": [\"club\", \"note\"]}, {\"amount__lte\": {\"F\": [\"ADD\", [\"F\", \"source__balance\"], 5000]}}]", "query": "[\"AND\", {\"destination\": [\"club\", \"note\"]}, [\"OR\", {\"amount__lte\": {\"F\": [\"ADD\", [\"F\", \"source__balance\"], 5000]}}, {\"valid\": false}]]",
"type": "add", "type": "add",
"mask": 2, "mask": 2,
"field": "", "field": "",

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-03-24 15:49+0100\n" "POT-Creation-Date: 2020-03-26 14:40+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -24,8 +24,8 @@ msgstr ""
#: apps/activity/models.py:19 apps/activity/models.py:44 #: apps/activity/models.py:19 apps/activity/models.py:44
#: apps/member/models.py:63 apps/member/models.py:114 #: apps/member/models.py:63 apps/member/models.py:114
#: apps/note/models/notes.py:188 apps/note/models/transactions.py:24 #: apps/note/models/notes.py:188 apps/note/models/transactions.py:25
#: apps/note/models/transactions.py:44 apps/note/models/transactions.py:198 #: apps/note/models/transactions.py:45 apps/note/models/transactions.py:232
#: templates/member/profile_detail.html:15 #: templates/member/profile_detail.html:15
msgid "name" msgid "name"
msgstr "" msgstr ""
@ -46,13 +46,13 @@ msgstr ""
msgid "activity types" msgid "activity types"
msgstr "" msgstr ""
#: apps/activity/models.py:48 apps/note/models/transactions.py:69 #: apps/activity/models.py:48 apps/note/models/transactions.py:70
#: apps/permission/models.py:90 #: apps/permission/models.py:91
msgid "description" msgid "description"
msgstr "" msgstr ""
#: apps/activity/models.py:54 apps/note/models/notes.py:164 #: apps/activity/models.py:54 apps/note/models/notes.py:164
#: apps/note/models/transactions.py:62 #: apps/note/models/transactions.py:63
msgid "type" msgid "type"
msgstr "" msgstr ""
@ -120,11 +120,11 @@ msgstr ""
msgid "create" msgid "create"
msgstr "" msgstr ""
#: apps/logs/models.py:61 #: apps/logs/models.py:61 apps/note/tables.py:147
msgid "edit" msgid "edit"
msgstr "" msgstr ""
#: apps/logs/models.py:62 #: apps/logs/models.py:62 apps/note/tables.py:151
msgid "delete" msgid "delete"
msgstr "" msgstr ""
@ -210,7 +210,7 @@ msgstr ""
msgid "clubs" msgid "clubs"
msgstr "" msgstr ""
#: apps/member/models.py:120 apps/permission/models.py:275 #: apps/member/models.py:120 apps/permission/models.py:276
msgid "role" msgid "role"
msgstr "" msgstr ""
@ -255,12 +255,12 @@ msgstr ""
msgid "Alias successfully deleted" msgid "Alias successfully deleted"
msgstr "" msgstr ""
#: apps/note/admin.py:120 apps/note/models/transactions.py:94 #: apps/note/admin.py:120 apps/note/models/transactions.py:95
msgid "source" msgid "source"
msgstr "" msgstr ""
#: apps/note/admin.py:128 apps/note/admin.py:156 #: apps/note/admin.py:128 apps/note/admin.py:156
#: apps/note/models/transactions.py:53 apps/note/models/transactions.py:100 #: apps/note/models/transactions.py:54 apps/note/models/transactions.py:108
msgid "destination" msgid "destination"
msgstr "" msgstr ""
@ -310,7 +310,7 @@ msgstr ""
msgid "display image" msgid "display image"
msgstr "" msgstr ""
#: apps/note/models/notes.py:53 apps/note/models/transactions.py:103 #: apps/note/models/notes.py:53 apps/note/models/transactions.py:118
msgid "created at" msgid "created at"
msgstr "" msgstr ""
@ -384,55 +384,64 @@ msgstr ""
msgid "You can't delete your main alias." msgid "You can't delete your main alias."
msgstr "" msgstr ""
#: apps/note/models/transactions.py:30 #: apps/note/models/transactions.py:31
msgid "transaction category" msgid "transaction category"
msgstr "" msgstr ""
#: apps/note/models/transactions.py:31 #: apps/note/models/transactions.py:32
msgid "transaction categories" msgid "transaction categories"
msgstr "" msgstr ""
#: apps/note/models/transactions.py:47 #: apps/note/models/transactions.py:48
msgid "A template with this name already exist" msgid "A template with this name already exist"
msgstr "" msgstr ""
#: apps/note/models/transactions.py:56 apps/note/models/transactions.py:111 #: apps/note/models/transactions.py:57 apps/note/models/transactions.py:126
msgid "amount" msgid "amount"
msgstr "" msgstr ""
#: apps/note/models/transactions.py:57 #: apps/note/models/transactions.py:58
msgid "in centimes" msgid "in centimes"
msgstr "" msgstr ""
#: apps/note/models/transactions.py:75 #: apps/note/models/transactions.py:76
msgid "transaction template" msgid "transaction template"
msgstr "" msgstr ""
#: apps/note/models/transactions.py:76 #: apps/note/models/transactions.py:77
msgid "transaction templates" msgid "transaction templates"
msgstr "" msgstr ""
#: apps/note/models/transactions.py:107 #: apps/note/models/transactions.py:101 apps/note/models/transactions.py:114
#: apps/note/tables.py:33 apps/note/tables.py:42
msgid "used alias"
msgstr ""
#: apps/note/models/transactions.py:122
msgid "quantity" msgid "quantity"
msgstr "" msgstr ""
#: apps/note/models/transactions.py:115 #: apps/note/models/transactions.py:130
msgid "reason" msgid "reason"
msgstr "" msgstr ""
#: apps/note/models/transactions.py:119 #: apps/note/models/transactions.py:135
msgid "valid" msgid "valid"
msgstr "" msgstr ""
#: apps/note/models/transactions.py:124 #: apps/note/models/transactions.py:140 apps/note/tables.py:95
msgid "invalidity reason"
msgstr ""
#: apps/note/models/transactions.py:147
msgid "transaction" msgid "transaction"
msgstr "" msgstr ""
#: apps/note/models/transactions.py:125 #: apps/note/models/transactions.py:148
msgid "transactions" msgid "transactions"
msgstr "" msgstr ""
#: apps/note/models/transactions.py:168 templates/base.html:98 #: apps/note/models/transactions.py:202 templates/base.html:83
#: templates/note/transaction_form.html:19 #: templates/note/transaction_form.html:19
#: templates/note/transaction_form.html:145 #: templates/note/transaction_form.html:145
msgid "Transfer" msgid "Transfer"
@ -634,15 +643,15 @@ msgid ""
"again unless your session expires or you logout." "again unless your session expires or you logout."
msgstr "" msgstr ""
#: note_kfet/settings/base.py:153 #: note_kfet/settings/base.py:151
msgid "German" msgid "German"
msgstr "" msgstr ""
#: note_kfet/settings/base.py:154 #: note_kfet/settings/base.py:152
msgid "English" msgid "English"
msgstr "" msgstr ""
#: note_kfet/settings/base.py:155 #: note_kfet/settings/base.py:153
msgid "French" msgid "French"
msgstr "" msgstr ""
@ -650,18 +659,14 @@ msgstr ""
msgid "The ENS Paris-Saclay BDE note." msgid "The ENS Paris-Saclay BDE note."
msgstr "" msgstr ""
#: templates/base.html:84 #: templates/base.html:87
msgid "Clubs" msgid "Clubs"
msgstr "" msgstr ""
#: templates/base.html:89 #: templates/base.html:92
msgid "Activities" msgid "Activities"
msgstr "" msgstr ""
#: templates/base.html:94
msgid "Buttons"
msgstr ""
#: templates/cas_server/base.html:7 #: templates/cas_server/base.html:7
msgid "Central Authentication Service" msgid "Central Authentication Service"
msgstr "" msgstr ""
@ -798,7 +803,7 @@ msgstr ""
msgid "Sign up" msgid "Sign up"
msgstr "" msgstr ""
#: templates/note/conso_form.html:28 templates/note/transaction_form.html:40 #: templates/note/conso_form.html:28 templates/note/transaction_form.html:50
msgid "Select emitters" msgid "Select emitters"
msgstr "" msgstr ""
@ -842,12 +847,28 @@ msgstr ""
msgid "Transfer type" msgid "Transfer type"
msgstr "" msgstr ""
#: templates/note/transaction_form.html:86
msgid "Name"
msgstr ""
#: templates/note/transaction_form.html:92
msgid "First name"
msgstr ""
#: templates/note/transaction_form.html:98
msgid "Bank"
msgstr ""
#: templates/note/transaction_form.html:111 #: templates/note/transaction_form.html:111
#: templates/note/transaction_form.html:169 #: templates/note/transaction_form.html:169
#: templates/note/transaction_form.html:176 #: templates/note/transaction_form.html:176
msgid "Select receivers" msgid "Select receivers"
msgstr "" msgstr ""
#: templates/note/transaction_form.html:128
msgid "Amount"
msgstr ""
#: templates/note/transaction_form.html:138 #: templates/note/transaction_form.html:138
msgid "Reason" msgid "Reason"
msgstr "" msgstr ""
@ -864,6 +885,22 @@ msgstr ""
msgid "Buttons list" msgid "Buttons list"
msgstr "" msgstr ""
#: templates/note/transactiontemplate_list.html:9
msgid "search button"
msgstr ""
#: templates/note/transactiontemplate_list.html:20
msgid "buttons listing "
msgstr ""
#: templates/note/transactiontemplate_list.html:71
msgid "button successfully deleted "
msgstr ""
#: templates/note/transactiontemplate_list.html:75
msgid "Unable to delete button "
msgstr ""
#: templates/registration/logged_out.html:8 #: templates/registration/logged_out.html:8
msgid "Thanks for spending some quality time with the Web site today." msgid "Thanks for spending some quality time with the Web site today."
msgstr "" msgstr ""
@ -873,7 +910,7 @@ msgid "Log in again"
msgstr "" msgstr ""
#: templates/registration/login.html:7 templates/registration/login.html:8 #: templates/registration/login.html:7 templates/registration/login.html:8
#: templates/registration/login.html:26 #: templates/registration/login.html:28
#: templates/registration/password_reset_complete.html:10 #: templates/registration/password_reset_complete.html:10
msgid "Log in" msgid "Log in"
msgstr "" msgstr ""
@ -885,7 +922,15 @@ msgid ""
"page. Would you like to login to a different account?" "page. Would you like to login to a different account?"
msgstr "" msgstr ""
#: templates/registration/login.html:27 #: templates/registration/login.html:22
msgid "You can also register via the central authentification server "
msgstr ""
#: templates/registration/login.html:23
msgid "using this link "
msgstr ""
#: templates/registration/login.html:29
msgid "Forgotten your password or username?" msgid "Forgotten your password or username?"
msgstr "" msgstr ""

View File

@ -3,7 +3,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-03-24 15:49+0100\n" "POT-Creation-Date: 2020-03-26 14:40+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -19,8 +19,8 @@ msgstr "activité"
#: apps/activity/models.py:19 apps/activity/models.py:44 #: apps/activity/models.py:19 apps/activity/models.py:44
#: apps/member/models.py:63 apps/member/models.py:114 #: apps/member/models.py:63 apps/member/models.py:114
#: apps/note/models/notes.py:188 apps/note/models/transactions.py:24 #: apps/note/models/notes.py:188 apps/note/models/transactions.py:25
#: apps/note/models/transactions.py:44 apps/note/models/transactions.py:198 #: apps/note/models/transactions.py:45 apps/note/models/transactions.py:232
#: templates/member/profile_detail.html:15 #: templates/member/profile_detail.html:15
msgid "name" msgid "name"
msgstr "nom" msgstr "nom"
@ -41,13 +41,13 @@ msgstr "type d'activité"
msgid "activity types" msgid "activity types"
msgstr "types d'activité" msgstr "types d'activité"
#: apps/activity/models.py:48 apps/note/models/transactions.py:69 #: apps/activity/models.py:48 apps/note/models/transactions.py:70
#: apps/permission/models.py:90 #: apps/permission/models.py:91
msgid "description" msgid "description"
msgstr "description" msgstr "description"
#: apps/activity/models.py:54 apps/note/models/notes.py:164 #: apps/activity/models.py:54 apps/note/models/notes.py:164
#: apps/note/models/transactions.py:62 #: apps/note/models/transactions.py:63
msgid "type" msgid "type"
msgstr "type" msgstr "type"
@ -115,11 +115,11 @@ msgstr "Nouvelles données"
msgid "create" msgid "create"
msgstr "Créer" msgstr "Créer"
#: apps/logs/models.py:61 #: apps/logs/models.py:61 apps/note/tables.py:147
msgid "edit" msgid "edit"
msgstr "Modifier" msgstr "Modifier"
#: apps/logs/models.py:62 #: apps/logs/models.py:62 apps/note/tables.py:151
msgid "delete" msgid "delete"
msgstr "Supprimer" msgstr "Supprimer"
@ -209,7 +209,7 @@ msgstr "club"
msgid "clubs" msgid "clubs"
msgstr "clubs" msgstr "clubs"
#: apps/member/models.py:120 apps/permission/models.py:275 #: apps/member/models.py:120 apps/permission/models.py:276
msgid "role" msgid "role"
msgstr "rôle" msgstr "rôle"
@ -254,12 +254,12 @@ msgstr "Compte n°%(id)s : %(username)s"
msgid "Alias successfully deleted" msgid "Alias successfully deleted"
msgstr "L'alias a bien été supprimé" msgstr "L'alias a bien été supprimé"
#: apps/note/admin.py:120 apps/note/models/transactions.py:94 #: apps/note/admin.py:120 apps/note/models/transactions.py:95
msgid "source" msgid "source"
msgstr "source" msgstr "source"
#: apps/note/admin.py:128 apps/note/admin.py:156 #: apps/note/admin.py:128 apps/note/admin.py:156
#: apps/note/models/transactions.py:53 apps/note/models/transactions.py:100 #: apps/note/models/transactions.py:54 apps/note/models/transactions.py:108
msgid "destination" msgid "destination"
msgstr "destination" msgstr "destination"
@ -310,7 +310,7 @@ msgstr ""
msgid "display image" msgid "display image"
msgstr "image affichée" msgstr "image affichée"
#: apps/note/models/notes.py:53 apps/note/models/transactions.py:103 #: apps/note/models/notes.py:53 apps/note/models/transactions.py:118
msgid "created at" msgid "created at"
msgstr "créée le" msgstr "créée le"
@ -384,35 +384,40 @@ msgstr "Un alias avec un nom similaire existe déjà : {}"
msgid "You can't delete your main alias." msgid "You can't delete your main alias."
msgstr "Vous ne pouvez pas supprimer votre alias principal." msgstr "Vous ne pouvez pas supprimer votre alias principal."
#: apps/note/models/transactions.py:30 #: apps/note/models/transactions.py:31
msgid "transaction category" msgid "transaction category"
msgstr "catégorie de transaction" msgstr "catégorie de transaction"
#: apps/note/models/transactions.py:31 #: apps/note/models/transactions.py:32
msgid "transaction categories" msgid "transaction categories"
msgstr "catégories de transaction" msgstr "catégories de transaction"
#: apps/note/models/transactions.py:47 #: apps/note/models/transactions.py:48
msgid "A template with this name already exist" msgid "A template with this name already exist"
msgstr "Un modèle de transaction avec un nom similaire existe déjà." msgstr "Un modèle de transaction avec un nom similaire existe déjà."
#: apps/note/models/transactions.py:56 apps/note/models/transactions.py:111 #: apps/note/models/transactions.py:57 apps/note/models/transactions.py:126
msgid "amount" msgid "amount"
msgstr "montant" msgstr "montant"
#: apps/note/models/transactions.py:57 #: apps/note/models/transactions.py:58
msgid "in centimes" msgid "in centimes"
msgstr "en centimes" msgstr "en centimes"
#: apps/note/models/transactions.py:75 #: apps/note/models/transactions.py:76
msgid "transaction template" msgid "transaction template"
msgstr "modèle de transaction" msgstr "modèle de transaction"
#: apps/note/models/transactions.py:76 #: apps/note/models/transactions.py:77
msgid "transaction templates" msgid "transaction templates"
msgstr "modèles de transaction" msgstr "modèles de transaction"
#: apps/note/models/transactions.py:107 #: apps/note/models/transactions.py:101 apps/note/models/transactions.py:114
#: apps/note/tables.py:33 apps/note/tables.py:42
msgid "used alias"
msgstr "alias utilisé"
#: apps/note/models/transactions.py:122
msgid "quantity" msgid "quantity"
msgstr "quantité" msgstr "quantité"
@ -634,15 +639,15 @@ msgid ""
"again unless your session expires or you logout." "again unless your session expires or you logout."
msgstr "" msgstr ""
#: note_kfet/settings/base.py:153 #: note_kfet/settings/base.py:151
msgid "German" msgid "German"
msgstr "" msgstr ""
#: note_kfet/settings/base.py:154 #: note_kfet/settings/base.py:152
msgid "English" msgid "English"
msgstr "" msgstr ""
#: note_kfet/settings/base.py:155 #: note_kfet/settings/base.py:153
msgid "French" msgid "French"
msgstr "" msgstr ""
@ -650,18 +655,14 @@ msgstr ""
msgid "The ENS Paris-Saclay BDE note." msgid "The ENS Paris-Saclay BDE note."
msgstr "La note du BDE de l'ENS Paris-Saclay." msgstr "La note du BDE de l'ENS Paris-Saclay."
#: templates/base.html:84 #: templates/base.html:87
msgid "Clubs" msgid "Clubs"
msgstr "Clubs" msgstr "Clubs"
#: templates/base.html:89 #: templates/base.html:92
msgid "Activities" msgid "Activities"
msgstr "Activités" msgstr "Activités"
#: templates/base.html:94
msgid "Buttons"
msgstr "Boutons"
#: templates/cas_server/base.html:7 #: templates/cas_server/base.html:7
msgid "Central Authentication Service" msgid "Central Authentication Service"
msgstr "" msgstr ""
@ -800,7 +801,7 @@ msgstr "Sauvegarder les changements"
msgid "Sign up" msgid "Sign up"
msgstr "Inscription" msgstr "Inscription"
#: templates/note/conso_form.html:28 templates/note/transaction_form.html:40 #: templates/note/conso_form.html:28 templates/note/transaction_form.html:50
msgid "Select emitters" msgid "Select emitters"
msgstr "Sélection des émetteurs" msgstr "Sélection des émetteurs"
@ -844,12 +845,28 @@ msgstr "Paiement externe"
msgid "Transfer type" msgid "Transfer type"
msgstr "Type de transfert" msgstr "Type de transfert"
#: templates/note/transaction_form.html:86
msgid "Name"
msgstr "Nom"
#: templates/note/transaction_form.html:92
msgid "First name"
msgstr "Prénom"
#: templates/note/transaction_form.html:98
msgid "Bank"
msgstr "Banque"
#: templates/note/transaction_form.html:111 #: templates/note/transaction_form.html:111
#: templates/note/transaction_form.html:169 #: templates/note/transaction_form.html:169
#: templates/note/transaction_form.html:176 #: templates/note/transaction_form.html:176
msgid "Select receivers" msgid "Select receivers"
msgstr "Sélection des destinataires" msgstr "Sélection des destinataires"
#: templates/note/transaction_form.html:128
msgid "Amount"
msgstr "Montant"
#: templates/note/transaction_form.html:138 #: templates/note/transaction_form.html:138
msgid "Reason" msgid "Reason"
msgstr "Raison" msgstr "Raison"
@ -866,6 +883,22 @@ msgstr "Note à débiter"
msgid "Buttons list" msgid "Buttons list"
msgstr "Liste des boutons" msgstr "Liste des boutons"
#: templates/note/transactiontemplate_list.html:9
msgid "search button"
msgstr "Chercher un bouton"
#: templates/note/transactiontemplate_list.html:20
msgid "buttons listing "
msgstr "Liste des boutons"
#: templates/note/transactiontemplate_list.html:71
msgid "button successfully deleted "
msgstr "Le bouton a bien été supprimé"
#: templates/note/transactiontemplate_list.html:75
msgid "Unable to delete button "
msgstr "Impossible de supprimer le bouton "
#: templates/registration/logged_out.html:8 #: templates/registration/logged_out.html:8
msgid "Thanks for spending some quality time with the Web site today." msgid "Thanks for spending some quality time with the Web site today."
msgstr "" msgstr ""
@ -875,7 +908,7 @@ msgid "Log in again"
msgstr "" msgstr ""
#: templates/registration/login.html:7 templates/registration/login.html:8 #: templates/registration/login.html:7 templates/registration/login.html:8
#: templates/registration/login.html:26 #: templates/registration/login.html:28
#: templates/registration/password_reset_complete.html:10 #: templates/registration/password_reset_complete.html:10
msgid "Log in" msgid "Log in"
msgstr "" msgstr ""
@ -887,7 +920,15 @@ msgid ""
"page. Would you like to login to a different account?" "page. Would you like to login to a different account?"
msgstr "" msgstr ""
#: templates/registration/login.html:27 #: templates/registration/login.html:22
msgid "You can also register via the central authentification server "
msgstr ""
#: templates/registration/login.html:23
msgid "using this link "
msgstr ""
#: templates/registration/login.html:29
msgid "Forgotten your password or username?" msgid "Forgotten your password or username?"
msgstr "" msgstr ""

View File

@ -265,7 +265,16 @@ function autoCompleteNote(field_id, alias_matched_id, note_list_id, notes, notes
} }
// When a validate button is clicked, we switch the validation status // When a validate button is clicked, we switch the validation status
function de_validate(id, validated) { function in_validate(id, validated) {
let invalidity_reason;
let reason_obj = $("#invalidity_reason_" + id);
if (validated)
invalidity_reason = reason_obj.val();
else
invalidity_reason = null;
$("#validate_" + id).html("<strong style=\"font-size: 16pt;\">⟳ ...</strong>"); $("#validate_" + id).html("<strong style=\"font-size: 16pt;\">⟳ ...</strong>");
// Perform a PATCH request to the API in order to update the transaction // Perform a PATCH request to the API in order to update the transaction
@ -278,12 +287,13 @@ function de_validate(id, validated) {
"X-CSRFTOKEN": CSRF_TOKEN "X-CSRFTOKEN": CSRF_TOKEN
}, },
data: { data: {
"resourcetype": "RecurrentTransaction", resourcetype: "RecurrentTransaction",
valid: !validated valid: !validated,
invalidity_reason: invalidity_reason,
}, },
success: function () { success: function () {
// Refresh jQuery objects // Refresh jQuery objects
$(".validate").click(de_validate); $(".validate").click(in_validate);
refreshBalance(); refreshBalance();
// error if this method doesn't exist. Please define it. // error if this method doesn't exist. Please define it.

View File

@ -167,7 +167,7 @@ function reset() {
function consumeAll() { function consumeAll() {
notes_display.forEach(function(note_display) { notes_display.forEach(function(note_display) {
buttons.forEach(function(button) { buttons.forEach(function(button) {
consume(note_display.id, button.dest, button.quantity * note_display.quantity, button.amount, consume(note_display.id, note_display.name, button.dest, button.quantity * note_display.quantity, button.amount,
button.name + " (" + button.category_name + ")", button.type, button.category_id, button.id); button.name + " (" + button.category_name + ")", button.type, button.category_id, button.id);
}); });
}); });
@ -176,6 +176,7 @@ function consumeAll() {
/** /**
* Create a new transaction from a button through the API. * Create a new transaction from a button through the API.
* @param source The note that paid the item (type: int) * @param source The note that paid the item (type: int)
* @param source_alias The alias used for the source (type: str)
* @param dest The note that sold the item (type: int) * @param dest The note that sold the item (type: int)
* @param quantity The quantity sold (type: int) * @param quantity The quantity sold (type: int)
* @param amount The price of one item, in cents (type: int) * @param amount The price of one item, in cents (type: int)
@ -184,7 +185,7 @@ function consumeAll() {
* @param category The category id of the button (type: int) * @param category The category id of the button (type: int)
* @param template The button id (type: int) * @param template The button id (type: int)
*/ */
function consume(source, dest, quantity, amount, reason, type, category, template) { function consume(source, source_alias, dest, quantity, amount, reason, type, category, template) {
$.post("/api/note/transaction/transaction/", $.post("/api/note/transaction/transaction/",
{ {
"csrfmiddlewaretoken": CSRF_TOKEN, "csrfmiddlewaretoken": CSRF_TOKEN,
@ -195,12 +196,32 @@ function consume(source, dest, quantity, amount, reason, type, category, templat
"polymorphic_ctype": type, "polymorphic_ctype": type,
"resourcetype": "RecurrentTransaction", "resourcetype": "RecurrentTransaction",
"source": source, "source": source,
"source_alias": source_alias,
"destination": dest, "destination": dest,
"category": category, "category": category,
"template": template "template": template
}, reset).fail(function (e) { }, reset).fail(function (e) {
reset(); $.post("/api/note/transaction/transaction/",
{
addMsg("Une erreur est survenue lors de la transaction : " + e.responseText, "danger"); "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,
"category": category,
"template": template
}).done(function() {
reset();
addMsg("La transaction n'a pas pu être validée pour cause de solde insuffisant.", "danger");
}).fail(function () {
reset();
addMsg("Une erreur est survenue lors de la transaction : " + e.responseText, "danger");
});
}); });
} }

View File

@ -83,19 +83,41 @@ $("#transfer").click(function() {
"polymorphic_ctype": TRANSFER_POLYMORPHIC_CTYPE, "polymorphic_ctype": TRANSFER_POLYMORPHIC_CTYPE,
"resourcetype": "Transaction", "resourcetype": "Transaction",
"source": user_id, "source": user_id,
"destination": dest.id "destination": dest.id,
}, function () { "destination_alias": dest.name
}).done(function () {
addMsg("Le transfert de " addMsg("Le transfert de "
+ pretty_money(dest.quantity * 100 * $("#amount").val()) + " de votre note " + pretty_money(dest.quantity * 100 * $("#amount").val()) + " de votre note "
+ " vers la note " + dest.name + " a été fait avec succès !", "success"); + " vers la note " + dest.name + " a été fait avec succès !", "success");
reset(); reset();
}).fail(function (err) { }).fail(function () {
addMsg("Le transfert de " $.post("/api/note/transaction/transaction/",
+ pretty_money(dest.quantity * 100 * $("#amount").val()) + " de votre note " {
+ " vers la note " + dest.name + " a échoué : " + err.responseText, "danger"); "csrfmiddlewaretoken": CSRF_TOKEN,
"quantity": dest.quantity,
"amount": 100 * $("#amount").val(),
"reason": $("#reason").val(),
"valid": false,
"invalidity_reason": "Solde insuffisant",
"polymorphic_ctype": TRANSFER_POLYMORPHIC_CTYPE,
"resourcetype": "Transaction",
"source": user_id,
"destination": dest.id,
"destination_alias": dest.name
}).done(function () {
addMsg("Le transfert de "
+ pretty_money(dest.quantity * 100 * $("#amount").val()) + " de votre note "
+ " vers la note " + dest.name + " a échoué : Solde insuffisant", "danger");
reset(); reset();
}).fail(function (err) {
addMsg("Le transfert de "
+ pretty_money(dest.quantity * 100 * $("#amount").val()) + " de votre note "
+ " vers la note " + dest.name + " a échoué : " + err.responseText, "danger");
reset();
});
}); });
}); });
} }
@ -112,19 +134,43 @@ $("#transfer").click(function() {
"polymorphic_ctype": TRANSFER_POLYMORPHIC_CTYPE, "polymorphic_ctype": TRANSFER_POLYMORPHIC_CTYPE,
"resourcetype": "Transaction", "resourcetype": "Transaction",
"source": source.id, "source": source.id,
"destination": dest.id "source_alias": source.name,
}, function () { "destination": dest.id,
"destination_alias": dest.name
}).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 * 100 * $("#amount").val()) + " de la note " + source.name
+ " vers la note " + dest.name + " a été fait avec succès !", "success"); + " vers la note " + dest.name + " a été fait avec succès !", "success");
reset(); reset();
}).fail(function (err) { }).fail(function (err) {
addMsg("Le transfert de " $.post("/api/note/transaction/transaction/",
+ pretty_money(source.quantity * dest.quantity * 100 * $("#amount").val()) + " de la note " + source.name {
+ " vers la note " + dest.name + " a échoué : " + err.responseText, "danger"); "csrfmiddlewaretoken": CSRF_TOKEN,
"quantity": source.quantity * dest.quantity,
"amount": 100 * $("#amount").val(),
"reason": $("#reason").val(),
"valid": false,
"invalidity_reason": "Solde insuffisant",
"polymorphic_ctype": TRANSFER_POLYMORPHIC_CTYPE,
"resourcetype": "Transaction",
"source": source.id,
"source_alias": source.name,
"destination": dest.id,
"destination_alias": dest.name
}).done(function () {
addMsg("Le transfert de "
+ pretty_money(source.quantity * dest.quantity * 100 * $("#amount").val()) + " de la note " + source.name
+ " vers la note " + dest.name + " a échoué : Solde insuffisant", "danger");
reset(); reset();
}).fail(function (err) {
addMsg("Le transfert de "
+ pretty_money(source.quantity * dest.quantity * 100 * $("#amount").val()) + " de la note " + source.name
+ " vers la note " + dest.name + " a échoué : " + err.responseText, "danger");
reset();
});
}); });
}); });
}); });
@ -157,15 +203,17 @@ $("#transfer").click(function() {
"polymorphic_ctype": SPECIAL_TRANSFER_POLYMORPHIC_CTYPE, "polymorphic_ctype": SPECIAL_TRANSFER_POLYMORPHIC_CTYPE,
"resourcetype": "SpecialTransaction", "resourcetype": "SpecialTransaction",
"source": source, "source": source,
"source_alias": source.name,
"destination": dest, "destination": dest,
"destination_alias": dest.name,
"last_name": $("#last_name").val(), "last_name": $("#last_name").val(),
"first_name": $("#first_name").val(), "first_name": $("#first_name").val(),
"bank": $("#bank").val() "bank": $("#bank").val()
}, function () { }).done(function () {
addMsg("Le crédit/retrait a bien été effectué !", "success"); addMsg("Le crédit/retrait a bien été effectué !", "success");
reset(); reset();
}).fail(function (err) { }).fail(function (err) {
addMsg("Le crédit/transfert a échoué : " + err.responseText, "danger"); addMsg("Le crédit/retrait a échoué : " + err.responseText, "danger");
reset(); reset();
}); });
} }