Compare commits

..

5 Commits

Author SHA1 Message Date
Yohann D'ANELLO ad59b5c81e Change help text in membership fields in club form 2020-08-07 14:20:34 +02:00
Yohann D'ANELLO 88917dde23 Some memberships were detected twice 2020-08-07 14:00:54 +02:00
Yohann D'ANELLO aab194b987 Import Société générale credits 2020-08-07 13:19:00 +02:00
Yohann D'ANELLO 9751a5ad92 🐛 Fix pagination in transaction page 2020-08-07 12:55:07 +02:00
Yohann D'ANELLO 679ac3a652 Lock invoices, delete them 2020-08-07 11:04:54 +02:00
13 changed files with 383 additions and 217 deletions

View File

@ -216,17 +216,14 @@ class Club(models.Model):
blank=True,
null=True,
verbose_name=_('membership start'),
help_text=_('How long after January 1st the members can renew '
'their membership.'),
help_text=_('Date from which the members can renew their membership.'),
)
membership_end = models.DateField(
blank=True,
null=True,
verbose_name=_('membership end'),
help_text=_('How long the membership can last after January 1st '
'of the next year after members can renew their '
'membership.'),
help_text=_('Maximal date of a membership, after which members must renew it.'),
)
def update_membership_dates(self):

View File

@ -214,7 +214,7 @@ class TransactionSearchView(ProtectQuerysetMixin, LoginRequiredMixin, DetailView
transactions = transactions.filter(created_at__lte=data["created_before"])
table = HistoryTable(transactions)
table.paginate(per_page=100)
table.paginate(per_page=100, page=self.request.GET.get("page", 1))
context["table"] = table
return context

View File

@ -2359,6 +2359,22 @@
"description": "Voir toutes les notes"
}
},
{
"model": "permission.permission",
"pk": 151,
"fields": {
"model": [
"treasury",
"invoice"
],
"query": "{}",
"type": "delete",
"mask": 3,
"field": "",
"permanent": false,
"description": "Supprimer une facture"
}
},
{
"model": "permission.role",
"pk": 1,
@ -2539,7 +2555,8 @@
143,
146,
147,
150
150,
151
]
}
},
@ -2695,7 +2712,8 @@
147,
148,
149,
150
150,
151
]
}
},

@ -1 +1 @@
Subproject commit 4984159a61642a0d3668e85daf39472b59b86447
Subproject commit 53098f8adcf085fdb0e8ff058a3035bd2d4977a3

View File

@ -4,9 +4,8 @@
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
from django import forms
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from note_kfet.inputs import DatePickerInput, AmountInput
from note_kfet.inputs import AmountInput
from .models import Invoice, Product, Remittance, SpecialTransactionProxy
@ -16,19 +15,25 @@ class InvoiceForm(forms.ModelForm):
Create and generate invoices.
"""
# Django forms don't support date fields. We have to add it manually
date = forms.DateField(
initial=timezone.now,
widget=DatePickerInput(),
)
def clean(self):
if self.instance and self.instance.locked:
for field_name in self.fields:
self.cleaned_data[field_name] = getattr(self.instance, field_name)
self.errors.clear()
return self.cleaned_data
return super().clean()
def clean_date(self):
self.instance.date = self.data.get("date")
return self.instance.date
def save(self, commit=True):
"""
If the invoice is locked, don't save it
"""
if not self.instance.locked:
super().save(commit)
return self.instance
class Meta:
model = Invoice
exclude = ('bde', 'tex', )
exclude = ('bde', 'date', 'tex', )
class ProductForm(forms.ModelForm):

View File

@ -61,6 +61,13 @@ class Invoice(models.Model):
acquitted = models.BooleanField(
verbose_name=_("Acquitted"),
default=False,
)
locked = models.BooleanField(
verbose_name=_("Locked"),
help_text=_("An invoice can't be edited when it is locked."),
default=False,
)
tex = models.TextField(
@ -74,6 +81,12 @@ class Invoice(models.Model):
The advantage is to never change the template.
Warning: editing this model regenerate the tex source, so be careful.
"""
old_invoice = Invoice.objects.filter(id=self.id)
if old_invoice.exists():
if old_invoice.get().locked:
raise ValidationError(_("This invoice is locked and can no longer be edited."))
products = self.products.all()
self.place = "Gif-sur-Yvette"
@ -103,7 +116,7 @@ class Product(models.Model):
invoice = models.ForeignKey(
Invoice,
on_delete=models.PROTECT,
on_delete=models.CASCADE,
related_name="products",
verbose_name=_("invoice"),
)

View File

@ -14,11 +14,14 @@ class InvoiceTable(tables.Table):
"""
List all invoices.
"""
id = tables.LinkColumn("treasury:invoice_update",
id = tables.LinkColumn(
"treasury:invoice_update",
args=[A("pk")],
text=lambda record: _("Invoice #{:d}").format(record.id), )
text=lambda record: _("Invoice #{:d}").format(record.id),
)
invoice = tables.LinkColumn("treasury:invoice_render",
invoice = tables.LinkColumn(
"treasury:invoice_render",
verbose_name=_("Invoice"),
args=[A("pk")],
accessor="pk",
@ -26,7 +29,24 @@ class InvoiceTable(tables.Table):
attrs={
'a': {'class': 'fa fa-file-pdf-o'},
'td': {'data-turbolinks': 'false'}
})
}
)
delete = tables.LinkColumn(
'treasury:invoice_delete',
args=[A('pk')],
verbose_name=_("delete"),
text=_("Delete"),
attrs={
'th': {
'id': 'delete-membership-header'
},
'a': {
'class': 'btn btn-danger',
'data-type': 'delete-membership'
}
},
)
class Meta:
attrs = {

View File

@ -3,9 +3,9 @@
from django.urls import path
from .views import InvoiceCreateView, InvoiceListView, InvoiceUpdateView, InvoiceRenderView, RemittanceListView,\
RemittanceCreateView, RemittanceUpdateView, LinkTransactionToRemittanceView, UnlinkTransactionToRemittanceView,\
SogeCreditListView, SogeCreditManageView
from .views import InvoiceCreateView, InvoiceListView, InvoiceUpdateView, InvoiceDeleteView, InvoiceRenderView,\
RemittanceListView, RemittanceCreateView, RemittanceUpdateView, LinkTransactionToRemittanceView,\
UnlinkTransactionToRemittanceView, SogeCreditListView, SogeCreditManageView
app_name = 'treasury'
urlpatterns = [
@ -13,6 +13,7 @@ urlpatterns = [
path('invoice/', InvoiceListView.as_view(), name='invoice_list'),
path('invoice/create/', InvoiceCreateView.as_view(), name='invoice_create'),
path('invoice/<int:pk>/', InvoiceUpdateView.as_view(), name='invoice_update'),
path('invoice/<int:pk>/delete/', InvoiceDeleteView.as_view(), name='invoice_delete'),
path('invoice/render/<int:pk>/', InvoiceRenderView.as_view(), name='invoice_render'),
# Remittance app paths

View File

@ -18,7 +18,7 @@ from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _
from django.views.generic import CreateView, UpdateView, DetailView
from django.views.generic.base import View, TemplateView
from django.views.generic.edit import BaseFormView
from django.views.generic.edit import BaseFormView, DeleteView
from django_tables2 import SingleTableView
from note.models import SpecialTransaction, NoteSpecial, Alias
from note_kfet.settings.base import BASE_DIR
@ -97,14 +97,20 @@ class InvoiceUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
form.helper = FormHelper()
# Remove form tag on the generation of the form in the template (already present on the template)
form.helper.form_tag = False
# Fill the intial value for the date field, with the initial date of the model instance
form.fields['date'].initial = form.instance.date
# The formset handles the set of the products
form_set = ProductFormSet(instance=form.instance)
form_set = ProductFormSet(instance=self.object)
context['formset'] = form_set
context['helper'] = ProductFormSetHelper()
context['no_cache'] = True
if self.object.locked:
for field_name in form.fields:
form.fields[field_name].disabled = True
for f in form_set.forms:
for field_name in f.fields:
f.fields[field_name].disabled = True
return context
def form_valid(self, form):
@ -131,6 +137,17 @@ class InvoiceUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, UpdateView):
return reverse_lazy('treasury:invoice_list')
class InvoiceDeleteView(ProtectQuerysetMixin, LoginRequiredMixin, DeleteView):
"""
Delete a non-validated WEI registration
"""
model = Invoice
extra_context = {"title": _("Delete invoice")}
def get_success_url(self):
return reverse_lazy('treasury:invoice_list')
class InvoiceRenderView(LoginRequiredMixin, View):
"""
Render Invoice as a generated PDF with the given information and a LaTeX template

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-08-06 22:27+0200\n"
"POT-Creation-Date: 2020-08-07 14:17+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -95,8 +95,8 @@ msgstr ""
msgid "type"
msgstr ""
#: apps/activity/models.py:87 apps/logs/models.py:22 apps/member/models.py:280
#: apps/note/models/notes.py:126 apps/treasury/models.py:253
#: apps/activity/models.py:87 apps/logs/models.py:22 apps/member/models.py:277
#: apps/note/models/notes.py:126 apps/treasury/models.py:266
#: apps/wei/models.py:160 templates/treasury/sogecredit_detail.html:14
#: templates/wei/survey.html:16
msgid "user"
@ -194,18 +194,18 @@ msgstr ""
msgid "remove"
msgstr ""
#: apps/activity/tables.py:79 apps/note/forms.py:76 apps/treasury/models.py:172
#: apps/activity/tables.py:79 apps/note/forms.py:76 apps/treasury/models.py:185
msgid "Type"
msgstr ""
#: apps/activity/tables.py:81 apps/member/forms.py:106
#: apps/registration/forms.py:70 apps/treasury/forms.py:130
#: apps/registration/forms.py:70 apps/treasury/forms.py:135
#: apps/wei/forms/registration.py:94
msgid "Last name"
msgstr ""
#: apps/activity/tables.py:83 apps/member/forms.py:111
#: apps/registration/forms.py:75 apps/treasury/forms.py:132
#: apps/registration/forms.py:75 apps/treasury/forms.py:137
#: apps/wei/forms/registration.py:99 templates/note/transaction_form.html:131
msgid "First name"
msgstr ""
@ -280,7 +280,8 @@ msgid "edit"
msgstr ""
#: apps/logs/models.py:63 apps/note/tables.py:137 apps/note/tables.py:165
#: apps/permission/models.py:129 apps/wei/tables.py:73
#: apps/permission/models.py:129 apps/treasury/tables.py:38
#: apps/wei/tables.py:73
msgid "delete"
msgstr ""
@ -314,11 +315,11 @@ msgstr ""
msgid "membership fee (unpaid students)"
msgstr ""
#: apps/member/admin.py:67 apps/member/models.py:291
#: apps/member/admin.py:67 apps/member/models.py:288
msgid "roles"
msgstr ""
#: apps/member/admin.py:68 apps/member/models.py:305
#: apps/member/admin.py:68 apps/member/models.py:302
msgid "fee"
msgstr ""
@ -367,7 +368,7 @@ msgid "Credit amount"
msgstr ""
#: apps/member/forms.py:116 apps/registration/forms.py:80
#: apps/treasury/forms.py:134 apps/wei/forms/registration.py:104
#: apps/treasury/forms.py:139 apps/wei/forms/registration.py:104
#: templates/note/transaction_form.html:137
msgid "Bank"
msgstr ""
@ -543,59 +544,57 @@ msgid "membership start"
msgstr ""
#: apps/member/models.py:219
msgid "How long after January 1st the members can renew their membership."
msgid "Date from which the members can renew their membership."
msgstr ""
#: apps/member/models.py:226 templates/member/club_info.html:28
#: apps/member/models.py:225 templates/member/club_info.html:28
msgid "membership end"
msgstr ""
#: apps/member/models.py:227
msgid ""
"How long the membership can last after January 1st of the next year after "
"members can renew their membership."
#: apps/member/models.py:226
msgid "Maximal date of a membership, after which members must renew it."
msgstr ""
#: apps/member/models.py:261 apps/member/models.py:286
#: apps/member/models.py:258 apps/member/models.py:283
#: apps/note/models/notes.py:163
msgid "club"
msgstr ""
#: apps/member/models.py:262
#: apps/member/models.py:259
msgid "clubs"
msgstr ""
#: apps/member/models.py:296
#: apps/member/models.py:293
msgid "membership starts on"
msgstr ""
#: apps/member/models.py:300
#: apps/member/models.py:297
msgid "membership ends on"
msgstr ""
#: apps/member/models.py:351
#: apps/member/models.py:348
#, python-brace-format
msgid "The role {role} does not apply to the club {club}."
msgstr ""
#: apps/member/models.py:362 apps/member/views.py:592
#: apps/member/models.py:359 apps/member/views.py:592
msgid "User is already a member of the club"
msgstr ""
#: apps/member/models.py:409
#: apps/member/models.py:406
msgid "User is not a member of the parent club"
msgstr ""
#: apps/member/models.py:462
#: apps/member/models.py:459
#, python-brace-format
msgid "Membership of {user} for the club {club}"
msgstr ""
#: apps/member/models.py:465
#: apps/member/models.py:462
msgid "membership"
msgstr ""
#: apps/member/models.py:466
#: apps/member/models.py:463
msgid "memberships"
msgstr ""
@ -715,7 +714,7 @@ msgstr ""
msgid "Reason"
msgstr ""
#: apps/note/forms.py:87 apps/treasury/tables.py:119
#: apps/note/forms.py:87 apps/treasury/tables.py:139
msgid "Valid"
msgstr ""
@ -960,7 +959,7 @@ msgstr ""
msgid "membership transaction"
msgstr ""
#: apps/note/models/transactions.py:344 apps/treasury/models.py:259
#: apps/note/models/transactions.py:344 apps/treasury/models.py:272
msgid "membership transactions"
msgstr ""
@ -976,8 +975,10 @@ msgstr ""
msgid "No reason specified"
msgstr ""
#: apps/note/tables.py:139 apps/note/tables.py:167 apps/wei/tables.py:74
#: apps/wei/tables.py:100 templates/treasury/sogecredit_detail.html:59
#: apps/note/tables.py:139 apps/note/tables.py:167 apps/treasury/tables.py:39
#: apps/wei/tables.py:74 apps/wei/tables.py:100
#: templates/treasury/invoice_confirm_delete.html:28
#: templates/treasury/sogecredit_detail.html:59
#: templates/wei/weiregistration_confirm_delete.html:32
msgid "Delete"
msgstr ""
@ -1197,44 +1198,44 @@ msgstr ""
msgid "Treasury"
msgstr ""
#: apps/treasury/forms.py:88 apps/treasury/forms.py:142
#: apps/treasury/forms.py:93 apps/treasury/forms.py:147
#: templates/activity/activity_form.html:9
#: templates/activity/activity_invite.html:8
#: templates/django_filters/rest_framework/form.html:5
#: templates/member/add_members.html:31 templates/member/club_form.html:9
#: templates/note/transactiontemplate_form.html:15
#: templates/treasury/invoice_form.html:56 templates/wei/bus_form.html:13
#: templates/treasury/invoice_form.html:64 templates/wei/bus_form.html:13
#: templates/wei/busteam_form.html:13 templates/wei/weiclub_form.html:15
#: templates/wei/weiregistration_form.html:14
msgid "Submit"
msgstr ""
#: apps/treasury/forms.py:90
#: apps/treasury/forms.py:95
msgid "Close"
msgstr ""
#: apps/treasury/forms.py:99
#: apps/treasury/forms.py:104
msgid "Remittance is already closed."
msgstr ""
#: apps/treasury/forms.py:104
#: apps/treasury/forms.py:109
msgid "You can't change the type of the remittance."
msgstr ""
#: apps/treasury/forms.py:124 apps/treasury/models.py:238
#: apps/treasury/tables.py:77 apps/treasury/tables.py:85
#: apps/treasury/forms.py:129 apps/treasury/models.py:251
#: apps/treasury/tables.py:97 apps/treasury/tables.py:105
#: templates/treasury/invoice_list.html:13
#: templates/treasury/remittance_list.html:13
#: templates/treasury/sogecredit_list.html:13
msgid "Remittance"
msgstr ""
#: apps/treasury/forms.py:125
#: apps/treasury/forms.py:130
msgid "No attached remittance"
msgstr ""
#: apps/treasury/forms.py:136 apps/treasury/tables.py:47
#: apps/treasury/tables.py:115 templates/note/transaction_form.html:99
#: apps/treasury/forms.py:141 apps/treasury/tables.py:67
#: apps/treasury/tables.py:135 templates/note/transaction_form.html:99
#: templates/treasury/remittance_form.html:18
msgid "Amount"
msgstr ""
@ -1263,7 +1264,7 @@ msgstr ""
msgid "Address"
msgstr ""
#: apps/treasury/models.py:59 apps/treasury/models.py:166
#: apps/treasury/models.py:59 apps/treasury/models.py:179
msgid "Date"
msgstr ""
@ -1272,122 +1273,134 @@ msgid "Acquitted"
msgstr ""
#: apps/treasury/models.py:68
msgid "Locked"
msgstr ""
#: apps/treasury/models.py:69
msgid "An invoice can't be edited when it is locked."
msgstr ""
#: apps/treasury/models.py:75
msgid "tex source"
msgstr ""
#: apps/treasury/models.py:95 apps/treasury/models.py:108
#: apps/treasury/models.py:88 templates/treasury/invoice_form.html:17
msgid "This invoice is locked and can no longer be edited."
msgstr ""
#: apps/treasury/models.py:108 apps/treasury/models.py:121
msgid "invoice"
msgstr ""
#: apps/treasury/models.py:96
#: apps/treasury/models.py:109
msgid "invoices"
msgstr ""
#: apps/treasury/models.py:113
#: apps/treasury/models.py:126
msgid "Designation"
msgstr ""
#: apps/treasury/models.py:117
#: apps/treasury/models.py:130
msgid "Quantity"
msgstr ""
#: apps/treasury/models.py:121
#: apps/treasury/models.py:134
msgid "Unit price"
msgstr ""
#: apps/treasury/models.py:137
#: apps/treasury/models.py:150
msgid "product"
msgstr ""
#: apps/treasury/models.py:138
#: apps/treasury/models.py:151
msgid "products"
msgstr ""
#: apps/treasury/models.py:155
#: apps/treasury/models.py:168
msgid "remittance type"
msgstr ""
#: apps/treasury/models.py:156
#: apps/treasury/models.py:169
msgid "remittance types"
msgstr ""
#: apps/treasury/models.py:177
#: apps/treasury/models.py:190
msgid "Comment"
msgstr ""
#: apps/treasury/models.py:182
#: apps/treasury/models.py:195
msgid "Closed"
msgstr ""
#: apps/treasury/models.py:186
#: apps/treasury/models.py:199
msgid "remittance"
msgstr ""
#: apps/treasury/models.py:187
#: apps/treasury/models.py:200
msgid "remittances"
msgstr ""
#: apps/treasury/models.py:219
#: apps/treasury/models.py:232
msgid "Remittance #{:d}: {}"
msgstr ""
#: apps/treasury/models.py:242
#: apps/treasury/models.py:255
msgid "special transaction proxy"
msgstr ""
#: apps/treasury/models.py:243
#: apps/treasury/models.py:256
msgid "special transaction proxies"
msgstr ""
#: apps/treasury/models.py:265
#: apps/treasury/models.py:278
msgid "credit transaction"
msgstr ""
#: apps/treasury/models.py:328
#: apps/treasury/models.py:341
msgid ""
"This user doesn't have enough money to pay the memberships with its note. "
"Please ask her/him to credit the note before invalidating this credit."
msgstr ""
#: apps/treasury/models.py:340 templates/treasury/sogecredit_detail.html:10
#: apps/treasury/models.py:353 templates/treasury/sogecredit_detail.html:10
msgid "Credit from the Société générale"
msgstr ""
#: apps/treasury/models.py:341
#: apps/treasury/models.py:354
msgid "Credits from the Société générale"
msgstr ""
#: apps/treasury/tables.py:19
#: apps/treasury/tables.py:20
msgid "Invoice #{:d}"
msgstr ""
#: apps/treasury/tables.py:22 templates/treasury/invoice_list.html:10
#: apps/treasury/tables.py:25 templates/treasury/invoice_list.html:10
#: templates/treasury/remittance_list.html:10
#: templates/treasury/sogecredit_list.html:10
msgid "Invoice"
msgstr ""
#: apps/treasury/tables.py:45
#: apps/treasury/tables.py:65
msgid "Transaction count"
msgstr ""
#: apps/treasury/tables.py:50 apps/treasury/tables.py:52
#: apps/treasury/tables.py:70 apps/treasury/tables.py:72
msgid "View"
msgstr ""
#: apps/treasury/tables.py:79
#: apps/treasury/tables.py:99
msgid "Add"
msgstr ""
#: apps/treasury/tables.py:87
#: apps/treasury/tables.py:107
msgid "Remove"
msgstr ""
#: apps/treasury/tables.py:126
#: apps/treasury/tables.py:146
msgid "Yes"
msgstr ""
#: apps/treasury/tables.py:126
#: apps/treasury/tables.py:146
msgid "No"
msgstr ""
@ -1403,28 +1416,32 @@ msgstr ""
msgid "Update an invoice"
msgstr ""
#: apps/treasury/views.py:188
#: apps/treasury/views.py:145 templates/treasury/invoice_confirm_delete.html:8
msgid "Delete invoice"
msgstr ""
#: apps/treasury/views.py:205
msgid "Create a new remittance"
msgstr ""
#: apps/treasury/views.py:209 templates/treasury/remittance_form.html:9
#: apps/treasury/views.py:226 templates/treasury/remittance_form.html:9
#: templates/treasury/specialtransactionproxy_form.html:7
msgid "Remittances list"
msgstr ""
#: apps/treasury/views.py:259
#: apps/treasury/views.py:276
msgid "Update a remittance"
msgstr ""
#: apps/treasury/views.py:282
#: apps/treasury/views.py:299
msgid "Attach a transaction to a remittance"
msgstr ""
#: apps/treasury/views.py:326
#: apps/treasury/views.py:343
msgid "List of credits from the Société générale"
msgstr ""
#: apps/treasury/views.py:360
#: apps/treasury/views.py:377
msgid "Manage credits from the Société générale"
msgstr ""
@ -2365,17 +2382,30 @@ msgid ""
"by following the link you received."
msgstr ""
#: templates/treasury/invoice_confirm_delete.html:13
msgid "This invoice is locked and can't be deleted."
msgstr ""
#: templates/treasury/invoice_confirm_delete.html:19
msgid ""
"Are you sure you want to delete this invoice? This action can't be undone."
msgstr ""
#: templates/treasury/invoice_confirm_delete.html:26
msgid "Return to invoices list"
msgstr ""
#: templates/treasury/invoice_form.html:10
msgid ""
"Warning: the LaTeX template is saved with this object. Updating the invoice "
"implies regenerate it. Be careful if you manipulate old invoices."
msgstr ""
#: templates/treasury/invoice_form.html:51
#: templates/treasury/invoice_form.html:58
msgid "Add product"
msgstr ""
#: templates/treasury/invoice_form.html:52
#: templates/treasury/invoice_form.html:59
msgid "Remove product"
msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-08-06 22:27+0200\n"
"POT-Creation-Date: 2020-08-07 14:17+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -96,8 +96,8 @@ msgstr "lieu"
msgid "type"
msgstr "type"
#: apps/activity/models.py:87 apps/logs/models.py:22 apps/member/models.py:280
#: apps/note/models/notes.py:126 apps/treasury/models.py:253
#: apps/activity/models.py:87 apps/logs/models.py:22 apps/member/models.py:277
#: apps/note/models/notes.py:126 apps/treasury/models.py:266
#: apps/wei/models.py:160 templates/treasury/sogecredit_detail.html:14
#: templates/wei/survey.html:16
msgid "user"
@ -195,18 +195,18 @@ msgstr "Entré le "
msgid "remove"
msgstr "supprimer"
#: apps/activity/tables.py:79 apps/note/forms.py:76 apps/treasury/models.py:172
#: apps/activity/tables.py:79 apps/note/forms.py:76 apps/treasury/models.py:185
msgid "Type"
msgstr "Type"
#: apps/activity/tables.py:81 apps/member/forms.py:106
#: apps/registration/forms.py:70 apps/treasury/forms.py:130
#: apps/registration/forms.py:70 apps/treasury/forms.py:135
#: apps/wei/forms/registration.py:94
msgid "Last name"
msgstr "Nom de famille"
#: apps/activity/tables.py:83 apps/member/forms.py:111
#: apps/registration/forms.py:75 apps/treasury/forms.py:132
#: apps/registration/forms.py:75 apps/treasury/forms.py:137
#: apps/wei/forms/registration.py:99 templates/note/transaction_form.html:131
msgid "First name"
msgstr "Prénom"
@ -281,7 +281,8 @@ msgid "edit"
msgstr "Modifier"
#: apps/logs/models.py:63 apps/note/tables.py:137 apps/note/tables.py:165
#: apps/permission/models.py:129 apps/wei/tables.py:73
#: apps/permission/models.py:129 apps/treasury/tables.py:38
#: apps/wei/tables.py:73
msgid "delete"
msgstr "Supprimer"
@ -315,11 +316,11 @@ msgstr "cotisation pour adhérer (normalien élève)"
msgid "membership fee (unpaid students)"
msgstr "cotisation pour adhérer (normalien étudiant)"
#: apps/member/admin.py:67 apps/member/models.py:291
#: apps/member/admin.py:67 apps/member/models.py:288
msgid "roles"
msgstr "rôles"
#: apps/member/admin.py:68 apps/member/models.py:305
#: apps/member/admin.py:68 apps/member/models.py:302
msgid "fee"
msgstr "cotisation"
@ -368,7 +369,7 @@ msgid "Credit amount"
msgstr "Montant à créditer"
#: apps/member/forms.py:116 apps/registration/forms.py:80
#: apps/treasury/forms.py:134 apps/wei/forms/registration.py:104
#: apps/treasury/forms.py:139 apps/wei/forms/registration.py:104
#: templates/note/transaction_form.html:137
msgid "Bank"
msgstr "Banque"
@ -544,63 +545,59 @@ msgid "membership start"
msgstr "début de l'adhésion"
#: apps/member/models.py:219
msgid "How long after January 1st the members can renew their membership."
msgid "Date from which the members can renew their membership."
msgstr ""
"Combien de temps après le 1er Janvier les adhérents peuvent renouveler leur "
"Date à partir de laquelle les adhérents peuvent renouveler leur "
"adhésion."
#: apps/member/models.py:226 templates/member/club_info.html:28
#: apps/member/models.py:225 templates/member/club_info.html:28
msgid "membership end"
msgstr "fin de l'adhésion"
#: apps/member/models.py:227
msgid ""
"How long the membership can last after January 1st of the next year after "
"members can renew their membership."
msgstr ""
"Combien de temps l'adhésion peut durer après le 1er Janvier de l'année "
"suivante avant que les adhérents peuvent renouveler leur adhésion."
#: apps/member/models.py:226
msgid "Maximal date of a membership, after which members must renew it."
msgstr "Date maximale d'une fin d'adhésion, après laquelle les adhérents doivent la renouveler."
#: apps/member/models.py:261 apps/member/models.py:286
#: apps/member/models.py:258 apps/member/models.py:283
#: apps/note/models/notes.py:163
msgid "club"
msgstr "club"
#: apps/member/models.py:262
#: apps/member/models.py:259
msgid "clubs"
msgstr "clubs"
#: apps/member/models.py:296
#: apps/member/models.py:293
msgid "membership starts on"
msgstr "l'adhésion commence le"
#: apps/member/models.py:300
#: apps/member/models.py:297
msgid "membership ends on"
msgstr "l'adhésion finit le"
#: apps/member/models.py:351
#: apps/member/models.py:348
#, python-brace-format
msgid "The role {role} does not apply to the club {club}."
msgstr "Le rôle {role} ne s'applique pas au club {club}."
#: apps/member/models.py:362 apps/member/views.py:592
#: apps/member/models.py:359 apps/member/views.py:592
msgid "User is already a member of the club"
msgstr "L'utilisateur est déjà membre du club"
#: apps/member/models.py:409
#: apps/member/models.py:406
msgid "User is not a member of the parent club"
msgstr "L'utilisateur n'est pas membre du club parent"
#: apps/member/models.py:462
#: apps/member/models.py:459
#, python-brace-format
msgid "Membership of {user} for the club {club}"
msgstr "Adhésion de {user} pour le club {club}"
#: apps/member/models.py:465
#: apps/member/models.py:462
msgid "membership"
msgstr "adhésion"
#: apps/member/models.py:466
#: apps/member/models.py:463
msgid "memberships"
msgstr "adhésions"
@ -722,7 +719,7 @@ msgstr "Destination"
msgid "Reason"
msgstr "Raison"
#: apps/note/forms.py:87 apps/treasury/tables.py:119
#: apps/note/forms.py:87 apps/treasury/tables.py:139
msgid "Valid"
msgstr "Valide"
@ -974,7 +971,7 @@ msgstr "Transactions de crédit/retrait"
msgid "membership transaction"
msgstr "Transaction d'adhésion"
#: apps/note/models/transactions.py:344 apps/treasury/models.py:259
#: apps/note/models/transactions.py:344 apps/treasury/models.py:272
msgid "membership transactions"
msgstr "Transactions d'adhésion"
@ -990,8 +987,10 @@ msgstr "Cliquez pour valider"
msgid "No reason specified"
msgstr "Pas de motif spécifié"
#: apps/note/tables.py:139 apps/note/tables.py:167 apps/wei/tables.py:74
#: apps/wei/tables.py:100 templates/treasury/sogecredit_detail.html:59
#: apps/note/tables.py:139 apps/note/tables.py:167 apps/treasury/tables.py:39
#: apps/wei/tables.py:74 apps/wei/tables.py:100
#: templates/treasury/invoice_confirm_delete.html:28
#: templates/treasury/sogecredit_detail.html:59
#: templates/wei/weiregistration_confirm_delete.html:32
msgid "Delete"
msgstr "Supprimer"
@ -1226,44 +1225,44 @@ msgstr "Invalider l'inscription"
msgid "Treasury"
msgstr "Trésorerie"
#: apps/treasury/forms.py:88 apps/treasury/forms.py:142
#: apps/treasury/forms.py:93 apps/treasury/forms.py:147
#: templates/activity/activity_form.html:9
#: templates/activity/activity_invite.html:8
#: templates/django_filters/rest_framework/form.html:5
#: templates/member/add_members.html:31 templates/member/club_form.html:9
#: templates/note/transactiontemplate_form.html:15
#: templates/treasury/invoice_form.html:56 templates/wei/bus_form.html:13
#: templates/treasury/invoice_form.html:64 templates/wei/bus_form.html:13
#: templates/wei/busteam_form.html:13 templates/wei/weiclub_form.html:15
#: templates/wei/weiregistration_form.html:14
msgid "Submit"
msgstr "Envoyer"
#: apps/treasury/forms.py:90
#: apps/treasury/forms.py:95
msgid "Close"
msgstr "Fermer"
#: apps/treasury/forms.py:99
#: apps/treasury/forms.py:104
msgid "Remittance is already closed."
msgstr "La remise est déjà fermée."
#: apps/treasury/forms.py:104
#: apps/treasury/forms.py:109
msgid "You can't change the type of the remittance."
msgstr "Vous ne pouvez pas changer le type de la remise."
#: apps/treasury/forms.py:124 apps/treasury/models.py:238
#: apps/treasury/tables.py:77 apps/treasury/tables.py:85
#: apps/treasury/forms.py:129 apps/treasury/models.py:251
#: apps/treasury/tables.py:97 apps/treasury/tables.py:105
#: templates/treasury/invoice_list.html:13
#: templates/treasury/remittance_list.html:13
#: templates/treasury/sogecredit_list.html:13
msgid "Remittance"
msgstr "Remise"
#: apps/treasury/forms.py:125
#: apps/treasury/forms.py:130
msgid "No attached remittance"
msgstr "Pas de remise associée"
#: apps/treasury/forms.py:136 apps/treasury/tables.py:47
#: apps/treasury/tables.py:115 templates/note/transaction_form.html:99
#: apps/treasury/forms.py:141 apps/treasury/tables.py:67
#: apps/treasury/tables.py:135 templates/note/transaction_form.html:99
#: templates/treasury/remittance_form.html:18
msgid "Amount"
msgstr "Montant"
@ -1292,7 +1291,7 @@ msgstr "Nom"
msgid "Address"
msgstr "Adresse"
#: apps/treasury/models.py:59 apps/treasury/models.py:166
#: apps/treasury/models.py:59 apps/treasury/models.py:179
msgid "Date"
msgstr "Date"
@ -1301,80 +1300,90 @@ msgid "Acquitted"
msgstr "Acquittée"
#: apps/treasury/models.py:68
#, fuzzy
#| msgid "source"
msgid "tex source"
msgstr "source"
msgid "Locked"
msgstr "Verrouillée"
#: apps/treasury/models.py:95 apps/treasury/models.py:108
#: apps/treasury/models.py:69
msgid "An invoice can't be edited when it is locked."
msgstr "Une facture ne peut plus être modifiée si elle est verrouillée."
#: apps/treasury/models.py:75
msgid "tex source"
msgstr "Fichier TeX source"
#: apps/treasury/models.py:88 templates/treasury/invoice_form.html:17
msgid "This invoice is locked and can no longer be edited."
msgstr "Cette facture est verrouillée et ne peut plus être éditée."
#: apps/treasury/models.py:108 apps/treasury/models.py:121
msgid "invoice"
msgstr "facture"
#: apps/treasury/models.py:96
#: apps/treasury/models.py:109
msgid "invoices"
msgstr "factures"
#: apps/treasury/models.py:113
#: apps/treasury/models.py:126
msgid "Designation"
msgstr "Désignation"
#: apps/treasury/models.py:117
#: apps/treasury/models.py:130
msgid "Quantity"
msgstr "Quantité"
#: apps/treasury/models.py:121
#: apps/treasury/models.py:134
msgid "Unit price"
msgstr "Prix unitaire"
#: apps/treasury/models.py:137
#: apps/treasury/models.py:150
msgid "product"
msgstr "produit"
#: apps/treasury/models.py:138
#: apps/treasury/models.py:151
msgid "products"
msgstr "produits"
#: apps/treasury/models.py:155
#: apps/treasury/models.py:168
msgid "remittance type"
msgstr "type de remise"
#: apps/treasury/models.py:156
#: apps/treasury/models.py:169
msgid "remittance types"
msgstr "types de remises"
#: apps/treasury/models.py:177
#: apps/treasury/models.py:190
msgid "Comment"
msgstr "Commentaire"
#: apps/treasury/models.py:182
#: apps/treasury/models.py:195
msgid "Closed"
msgstr "Fermée"
#: apps/treasury/models.py:186
#: apps/treasury/models.py:199
msgid "remittance"
msgstr "remise"
#: apps/treasury/models.py:187
#: apps/treasury/models.py:200
msgid "remittances"
msgstr "remises"
#: apps/treasury/models.py:219
#: apps/treasury/models.py:232
msgid "Remittance #{:d}: {}"
msgstr "Remise n°{:d} : {}"
#: apps/treasury/models.py:242
#: apps/treasury/models.py:255
msgid "special transaction proxy"
msgstr "Proxy de transaction spéciale"
#: apps/treasury/models.py:243
#: apps/treasury/models.py:256
msgid "special transaction proxies"
msgstr "Proxys de transactions spéciales"
#: apps/treasury/models.py:265
#: apps/treasury/models.py:278
msgid "credit transaction"
msgstr "transaction de crédit"
#: apps/treasury/models.py:328
#: apps/treasury/models.py:341
msgid ""
"This user doesn't have enough money to pay the memberships with its note. "
"Please ask her/him to credit the note before invalidating this credit."
@ -1382,45 +1391,45 @@ msgstr ""
"Cet utilisateur n'a pas assez d'argent pour payer les adhésions avec sa "
"note. Merci de lui demander de recharger sa note avant d'invalider ce crédit."
#: apps/treasury/models.py:340 templates/treasury/sogecredit_detail.html:10
#: apps/treasury/models.py:353 templates/treasury/sogecredit_detail.html:10
msgid "Credit from the Société générale"
msgstr "Crédit de la Société générale"
#: apps/treasury/models.py:341
#: apps/treasury/models.py:354
msgid "Credits from the Société générale"
msgstr "Crédits de la Société générale"
#: apps/treasury/tables.py:19
#: apps/treasury/tables.py:20
msgid "Invoice #{:d}"
msgstr "Facture n°{:d}"
#: apps/treasury/tables.py:22 templates/treasury/invoice_list.html:10
#: apps/treasury/tables.py:25 templates/treasury/invoice_list.html:10
#: templates/treasury/remittance_list.html:10
#: templates/treasury/sogecredit_list.html:10
msgid "Invoice"
msgstr "Facture"
#: apps/treasury/tables.py:45
#: apps/treasury/tables.py:65
msgid "Transaction count"
msgstr "Nombre de transactions"
#: apps/treasury/tables.py:50 apps/treasury/tables.py:52
#: apps/treasury/tables.py:70 apps/treasury/tables.py:72
msgid "View"
msgstr "Voir"
#: apps/treasury/tables.py:79
#: apps/treasury/tables.py:99
msgid "Add"
msgstr "Ajouter"
#: apps/treasury/tables.py:87
#: apps/treasury/tables.py:107
msgid "Remove"
msgstr "supprimer"
#: apps/treasury/tables.py:126
#: apps/treasury/tables.py:146
msgid "Yes"
msgstr "Oui"
#: apps/treasury/tables.py:126
#: apps/treasury/tables.py:146
msgid "No"
msgstr "Non"
@ -1436,28 +1445,32 @@ msgstr "Liste des factures"
msgid "Update an invoice"
msgstr "Modifier la facture"
#: apps/treasury/views.py:188
#: apps/treasury/views.py:145 templates/treasury/invoice_confirm_delete.html:8
msgid "Delete invoice"
msgstr "Supprimer la facture"
#: apps/treasury/views.py:205
msgid "Create a new remittance"
msgstr "Créer une nouvelle remise"
#: apps/treasury/views.py:209 templates/treasury/remittance_form.html:9
#: apps/treasury/views.py:226 templates/treasury/remittance_form.html:9
#: templates/treasury/specialtransactionproxy_form.html:7
msgid "Remittances list"
msgstr "Liste des remises"
#: apps/treasury/views.py:259
#: apps/treasury/views.py:276
msgid "Update a remittance"
msgstr "Modifier la remise"
#: apps/treasury/views.py:282
#: apps/treasury/views.py:299
msgid "Attach a transaction to a remittance"
msgstr "Joindre une transaction à une remise"
#: apps/treasury/views.py:326
#: apps/treasury/views.py:343
msgid "List of credits from the Société générale"
msgstr "Liste des crédits de la Société générale"
#: apps/treasury/views.py:360
#: apps/treasury/views.py:377
msgid "Manage credits from the Société générale"
msgstr "Gérer les crédits de la Société générale"
@ -2469,6 +2482,20 @@ msgstr ""
"d'adhésion. Vous devez également valider votre adresse email en suivant le "
"lien que vous avez reçu."
#: templates/treasury/invoice_confirm_delete.html:13
msgid "This invoice is locked and can't be deleted."
msgstr "Cette facture est verrouillée et ne peut pas être supprimée."
#: templates/treasury/invoice_confirm_delete.html:19
msgid ""
"Are you sure you want to delete this invoice? This action can't be undone."
msgstr ""
"Êtes-vous sûr de vouloir supprimer cette facture ? Cette action ne pourra pas être annulée."
#: templates/treasury/invoice_confirm_delete.html:26
msgid "Return to invoices list"
msgstr "Retour à la liste des factures"
#: templates/treasury/invoice_form.html:10
msgid ""
"Warning: the LaTeX template is saved with this object. Updating the invoice "
@ -2478,11 +2505,11 @@ msgstr ""
"facture implique la regénérer. Faites attention si vous manipulez de "
"vieilles factures."
#: templates/treasury/invoice_form.html:51
#: templates/treasury/invoice_form.html:58
msgid "Add product"
msgstr "Ajouter produit"
#: templates/treasury/invoice_form.html:52
#: templates/treasury/invoice_form.html:59
msgid "Remove product"
msgstr "Retirer produit"
@ -2819,6 +2846,3 @@ msgstr "Il n'y a pas de pré-inscription en attente avec cette entrée."
#: templates/wei/weiregistration_list.html:24
msgid "View validated memberships..."
msgstr "Voir les adhésions validées ..."
#~ msgid "Place"
#~ msgstr "Lieu"

View File

@ -0,0 +1,33 @@
{% extends "base.html" %}
{% load i18n %}
{% load crispy_forms_tags %}
{% block content %}
<div class="card bg-light shadow">
<div class="card-header text-center">
<h4>{% trans "Delete invoice" %}</h4>
</div>
{% if object.locked %}
<div class="card-body">
<div class="alert alert-danger">
{% blocktrans %}This invoice is locked and can't be deleted.{% endblocktrans %}
</div>
</div>
{% else %}
<div class="card-body">
<div class="alert alert-warning">
{% blocktrans %}Are you sure you want to delete this invoice? This action can't be undone.{% endblocktrans %}
</div>
</div>
{% endif %}
<div class="card-footer text-center">
<form method="post">
{% csrf_token %}
<a class="btn btn-primary" href="{% url 'treasury:invoice_list' %}">{% trans "Return to invoices list" %}</a>
{% if not object.locked %}
<button class="btn btn-danger" type="submit">{% trans "Delete" %}</button>
{% endif %}
</form>
</div>
</div>
{% endblock %}

View File

@ -5,13 +5,19 @@
{% block content %}
<p><a class="btn btn-default" href="{% url 'treasury:invoice_list' %}">{% trans "Invoices list" %}</a></p>
{% if not object.pk %}
{% if object.pk and not object.locked %}
<div class="alert alert-info">
{% blocktrans trimmed %}
Warning: the LaTeX template is saved with this object. Updating the invoice implies regenerate it.
Be careful if you manipulate old invoices.
{% endblocktrans %}
</div>
{% elif object.locked %}
<div class="alert alert-info">
{% blocktrans trimmed %}
This invoice is locked and can no longer be edited.
{% endblocktrans %}
</div>
{% endif %}
<form method="post" action="">
@ -47,10 +53,12 @@
</table>
{# Display buttons to add and remove products #}
{% if not object.locked %}
<div class="btn-group btn-block" role="group">
<button type="button" id="add_more" class="btn btn-primary">{% trans "Add product" %}</button>
<button type="button" id="remove_one" class="btn btn-danger">{% trans "Remove product" %}</button>
</div>
{% endif %}
<div class="btn-block">
<button type="submit" class="btn btn-block btn-primary">{% trans "Submit" %}</button>
@ -78,21 +86,21 @@
{# Script that handles add and remove lines #}
IDS = {};
$("#id_product_set-TOTAL_FORMS").val($(".row-formset").length - 1);
$("#id_products-TOTAL_FORMS").val($(".row-formset").length - 1);
$('#add_more').click(function () {
var form_idx = $('#id_product_set-TOTAL_FORMS').val();
let form_idx = $('#id_products-TOTAL_FORMS').val();
$('#form_body').append($('#for_real').html().replace(/__prefix__/g, form_idx));
$('#id_product_set-TOTAL_FORMS').val(parseInt(form_idx) + 1);
$('#id_product_set-' + parseInt(form_idx) + '-id').val(IDS[parseInt(form_idx)]);
$('#id_products-TOTAL_FORMS').val(parseInt(form_idx) + 1);
$('#id_products-' + parseInt(form_idx) + '-id').val(IDS[parseInt(form_idx)]);
});
$('#remove_one').click(function () {
let form_idx = $('#id_product_set-TOTAL_FORMS').val();
let form_idx = $('#id_products-TOTAL_FORMS').val();
if (form_idx > 0) {
IDS[parseInt(form_idx) - 1] = $('#id_product_set-' + (parseInt(form_idx) - 1) + '-id').val();
IDS[parseInt(form_idx) - 1] = $('#id_products-' + (parseInt(form_idx) - 1) + '-id').val();
$('#form_body tr:last-child').remove();
$('#id_product_set-TOTAL_FORMS').val(parseInt(form_idx) - 1);
$('#id_products-TOTAL_FORMS').val(parseInt(form_idx) - 1);
}
});
</script>