feat: Mass add transactions

fix: Add a link to budget line mass-create page
This commit is contained in:
sinavir 2025-03-17 13:59:26 +01:00 committed by catvayor
parent ba43c70df6
commit 8fdd8abd69
Signed by: lbailly
GPG key ID: CE3E645251AC63F3
5 changed files with 120 additions and 1 deletions

View file

@ -1,7 +1,10 @@
from datetime import datetime
from django import forms
from django.forms import Form, modelformset_factory
from django.utils.translation import gettext_lazy as _
from .models import Club, ClubBudgetLine
from .models import Club, ClubBudgetAccountingPeriod, ClubBudgetLine
class ClubBudgetLineForm(forms.ModelForm):
@ -29,3 +32,22 @@ class ClubsForm(forms.Form):
widget=forms.CheckboxSelectMultiple,
required=False,
)
ClubBudgetLineFormSet = modelformset_factory(
ClubBudgetLine, fields=["club", "amount"], extra=10
)
class ClubBudgetLineCommonForm(Form):
date = forms.DateTimeField(
label="Date",
initial=datetime.now,
widget=forms.DateInput(attrs={"type": "date"}, format="%Y-%m-%d"),
)
accounting_period = forms.ModelChoiceField(
label="Exercice comptable",
queryset=ClubBudgetAccountingPeriod.objects.filter(is_archived=False),
)
label = forms.CharField(label="Libellé", max_length=1000)
posted = forms.BooleanField(label="Transactions validées par la trez", initial=True)

View file

@ -56,8 +56,12 @@
<a class="button is-warning" href="{% url 'cof_clubs:acct-period-create' %}">
Créer un exercice comptable
</a>
<a class="button is-warning" href="{% url 'cof_clubs:budget-line-mass-create' %}">
Ajouter des budgets en masse (AGB)
</a>
</div>
{% endif %}
</div>
</div>
{% endblock content %}

View file

@ -0,0 +1,32 @@
{% extends "cof_clubs/base.html" %}
{% load i18n %}
{% block content %}
<section class="section">
<h1 class="title">{% trans "Création/Modification de ligne de budget" %}</h1>
<form action="" method="post">
{% csrf_token %}
{% include "bulma/form.html" with errors=True form=common_form %}
<hr/>
{{ form.management_form }}
{% for f in form %}
<div class="field is-grouped">
{% include "bulma/form.html" with errors=True form=f %}
</div>
{% endfor %}
<div class="field is-grouped">
<div class="control">
<button class="button is-primary" type="submit">
<span>{% trans "Enregister" %}</span>
</button>
</div>
</div>
</form>
</section>
{% endblock %}

View file

@ -22,6 +22,11 @@ urlpatterns = [
views.BudgetLineCreate.as_view(),
name="budget-line-create",
),
path(
"line/mass-add",
views.BudgetLineMassCreate.as_view(),
name="budget-line-mass-create",
),
path(
"line/<int:pk>/delete",
views.BudgetLineDelete.as_view(),

View file

@ -181,6 +181,62 @@ class BudgetLineFullUpdate(BuroRequiredMixin, UpdateView):
return reverse("cof_clubs:club-detail", kwargs={"pk": self.object.club.id})
class BudgetLineMassCreate(BuroRequiredMixin, FormView):
form_class = ClubBudgetLineFormSet
template_name = "cof_clubs/clubbudgetline_mass_form.html"
success_url = reverse_lazy("cof_clubs:club-list")
def get_common_form(self):
kwargs = {
"prefix": "common",
}
if self.request.method in ("POST", "PUT"):
kwargs.update(
{
"data": self.request.POST,
"files": self.request.FILES,
}
)
return ClubBudgetLineCommonForm(**kwargs)
def post(self, request, *args, **kwargs):
"""
Handle POST requests: instantiate a form instance with the passed
POST variables and then check if it's valid.
"""
form = self.get_form()
common_form = self.get_common_form()
if common_form.is_valid() and form.is_valid():
return self.form_valid(form, common_form)
else:
return self.form_invalid(form, common_form)
def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
data.setdefault("common_form", self.get_common_form())
return data
def form_valid(self, form, common_form):
instances = form.save(commit=False)
with transaction.atomic():
for i in instances:
i.label = common_form.cleaned_data["label"]
i.date = common_form.cleaned_data["date"]
i.accounting_period = common_form.cleaned_data["accounting_period"]
i.posted = common_form.cleaned_data["posted"]
i.save()
return HttpResponseRedirect(self.get_success_url())
def form_invalid(self, form, common_form):
"""If the form is invalid, render the invalid form."""
return self.render_to_response(
self.get_context_data(form=form, common_form=common_form)
)
class BudgetLineDelete(BudgetLineAccessMixin, DeleteView):
model = ClubBudgetLine