feat: Mass add transactions
fix: Add a link to budget line mass-create page fix: Do not fill budget line creation formset with already existing objects
This commit is contained in:
parent
ba43c70df6
commit
c703f8f47c
5 changed files with 125 additions and 1 deletions
|
@ -1,7 +1,10 @@
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from django.forms import Form, modelformset_factory
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from .models import Club, ClubBudgetLine
|
from .models import Club, ClubBudgetAccountingPeriod, ClubBudgetLine
|
||||||
|
|
||||||
|
|
||||||
class ClubBudgetLineForm(forms.ModelForm):
|
class ClubBudgetLineForm(forms.ModelForm):
|
||||||
|
@ -29,3 +32,22 @@ class ClubsForm(forms.Form):
|
||||||
widget=forms.CheckboxSelectMultiple,
|
widget=forms.CheckboxSelectMultiple,
|
||||||
required=False,
|
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)
|
||||||
|
|
|
@ -56,8 +56,12 @@
|
||||||
<a class="button is-warning" href="{% url 'cof_clubs:acct-period-create' %}">
|
<a class="button is-warning" href="{% url 'cof_clubs:acct-period-create' %}">
|
||||||
Créer un exercice comptable
|
Créer un exercice comptable
|
||||||
</a>
|
</a>
|
||||||
|
<a class="button is-warning" href="{% url 'cof_clubs:budget-line-mass-create' %}">
|
||||||
|
Ajouter des budgets en masse (AGB)
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
32
cof_clubs/templates/cof_clubs/clubbudgetline_mass_form.html
Normal file
32
cof_clubs/templates/cof_clubs/clubbudgetline_mass_form.html
Normal 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 %}
|
|
@ -22,6 +22,11 @@ urlpatterns = [
|
||||||
views.BudgetLineCreate.as_view(),
|
views.BudgetLineCreate.as_view(),
|
||||||
name="budget-line-create",
|
name="budget-line-create",
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
"line/mass-add",
|
||||||
|
views.BudgetLineMassCreate.as_view(),
|
||||||
|
name="budget-line-mass-create",
|
||||||
|
),
|
||||||
path(
|
path(
|
||||||
"line/<int:pk>/delete",
|
"line/<int:pk>/delete",
|
||||||
views.BudgetLineDelete.as_view(),
|
views.BudgetLineDelete.as_view(),
|
||||||
|
|
|
@ -181,6 +181,67 @@ class BudgetLineFullUpdate(BuroRequiredMixin, UpdateView):
|
||||||
return reverse("cof_clubs:club-detail", kwargs={"pk": self.object.club.id})
|
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_form_kwargs(self):
|
||||||
|
kwargs = super().get_form_kwargs()
|
||||||
|
kwargs["queryset"] = ClubBudgetLine.objects.none()
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
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):
|
class BudgetLineDelete(BudgetLineAccessMixin, DeleteView):
|
||||||
model = ClubBudgetLine
|
model = ClubBudgetLine
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue