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
3e6db516aa
commit
14f76ceab4
5 changed files with 125 additions and 1 deletions
|
@ -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):
|
||||
|
@ -36,3 +39,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)
|
||||
|
|
|
@ -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 %}
|
||||
|
|
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(),
|
||||
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(),
|
||||
|
|
|
@ -186,6 +186,67 @@ 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_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):
|
||||
model = ClubBudgetLine
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue