mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-12-27 01:13:46 +00:00
Ajout d'articles mutliples en quantité différente et un peu de js pour un formulaire dynamique
This commit is contained in:
parent
3ab552b257
commit
ec8721321c
6 changed files with 85 additions and 28 deletions
|
@ -3,10 +3,10 @@ from django.contrib import admin
|
||||||
from .models import Facture, Article, Banque, Paiement, Cotisation, Vente
|
from .models import Facture, Article, Banque, Paiement, Cotisation, Vente
|
||||||
|
|
||||||
class FactureAdmin(admin.ModelAdmin):
|
class FactureAdmin(admin.ModelAdmin):
|
||||||
list_display = ('user','paiement','number', 'date','valid')
|
list_display = ('user','paiement','date','valid')
|
||||||
|
|
||||||
class VenteAdmin(admin.ModelAdmin):
|
class VenteAdmin(admin.ModelAdmin):
|
||||||
list_display = ('facture','name','prix','cotisation','duration')
|
list_display = ('facture','name','prix','number','cotisation','duration')
|
||||||
|
|
||||||
class ArticleAdmin(admin.ModelAdmin):
|
class ArticleAdmin(admin.ModelAdmin):
|
||||||
list_display = ('name','prix','cotisation','duration')
|
list_display = ('name','prix','cotisation','duration')
|
||||||
|
|
|
@ -4,8 +4,6 @@ from django import forms
|
||||||
from .models import Article, Paiement, Facture, Banque, Vente
|
from .models import Article, Paiement, Facture, Banque, Vente
|
||||||
|
|
||||||
class NewFactureForm(ModelForm):
|
class NewFactureForm(ModelForm):
|
||||||
article = forms.ModelMultipleChoiceField(queryset=Article.objects.all(), label="Article", widget=forms.CheckboxSelectMultiple())
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(NewFactureForm, self).__init__(*args, **kwargs)
|
super(NewFactureForm, self).__init__(*args, **kwargs)
|
||||||
self.fields['cheque'].required = False
|
self.fields['cheque'].required = False
|
||||||
|
@ -23,13 +21,15 @@ class NewFactureForm(ModelForm):
|
||||||
paiement = cleaned_data.get("paiement")
|
paiement = cleaned_data.get("paiement")
|
||||||
cheque = cleaned_data.get("cheque")
|
cheque = cleaned_data.get("cheque")
|
||||||
banque = cleaned_data.get("banque")
|
banque = cleaned_data.get("banque")
|
||||||
if paiement.moyen=="chèque" and not (cheque and banque):
|
if not paiement:
|
||||||
|
raise forms.ValidationError("Le moyen de paiement est obligatoire")
|
||||||
|
elif paiement.moyen=="chèque" and not (cheque and banque):
|
||||||
raise forms.ValidationError("Le numero de chèque et la banque sont obligatoires")
|
raise forms.ValidationError("Le numero de chèque et la banque sont obligatoires")
|
||||||
return cleaned_data
|
return cleaned_data
|
||||||
|
|
||||||
class SelectArticleForm(Form):
|
class SelectArticleForm(Form):
|
||||||
article = forms.ModelChoiceField(queryset=Article.objects.all(), label="Article")
|
article = forms.ModelChoiceField(queryset=Article.objects.all(), label="Article", required=True)
|
||||||
quantity = forms.IntegerField(label="Quantité")
|
quantity = forms.IntegerField(label="Quantité", required=True)
|
||||||
|
|
||||||
class NewFactureFormPdf(Form):
|
class NewFactureFormPdf(Form):
|
||||||
article = forms.ModelMultipleChoiceField(queryset=Article.objects.all(), label="Article")
|
article = forms.ModelMultipleChoiceField(queryset=Article.objects.all(), label="Article")
|
||||||
|
|
24
cotisations/migrations/0014_auto_20160712_0245.py
Normal file
24
cotisations/migrations/0014_auto_20160712_0245.py
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('cotisations', '0013_auto_20160711_2240'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='facture',
|
||||||
|
name='number',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='vente',
|
||||||
|
name='number',
|
||||||
|
field=models.IntegerField(default=1),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
]
|
|
@ -6,7 +6,6 @@ class Facture(models.Model):
|
||||||
paiement = models.ForeignKey('Paiement', on_delete=models.PROTECT)
|
paiement = models.ForeignKey('Paiement', on_delete=models.PROTECT)
|
||||||
banque = models.ForeignKey('Banque', on_delete=models.PROTECT, blank=True, null=True)
|
banque = models.ForeignKey('Banque', on_delete=models.PROTECT, blank=True, null=True)
|
||||||
cheque = models.CharField(max_length=255, blank=True)
|
cheque = models.CharField(max_length=255, blank=True)
|
||||||
number = models.IntegerField()
|
|
||||||
date = models.DateTimeField(auto_now_add=True)
|
date = models.DateTimeField(auto_now_add=True)
|
||||||
valid = models.BooleanField(default=True)
|
valid = models.BooleanField(default=True)
|
||||||
|
|
||||||
|
@ -15,7 +14,7 @@ class Facture(models.Model):
|
||||||
return prix
|
return prix
|
||||||
|
|
||||||
def prix_total(self):
|
def prix_total(self):
|
||||||
return self.prix()*self.number
|
return Vente.objects.all().filter(facture=self).aggregate(total=models.Sum(models.F('prix')*models.F('number'), output_field=models.FloatField()))['total']
|
||||||
|
|
||||||
def name(self):
|
def name(self):
|
||||||
name = ' - '.join(vente.name for vente in Vente.objects.all().filter(facture=self))
|
name = ' - '.join(vente.name for vente in Vente.objects.all().filter(facture=self))
|
||||||
|
@ -26,11 +25,15 @@ class Facture(models.Model):
|
||||||
|
|
||||||
class Vente(models.Model):
|
class Vente(models.Model):
|
||||||
facture = models.ForeignKey('Facture', on_delete=models.PROTECT)
|
facture = models.ForeignKey('Facture', on_delete=models.PROTECT)
|
||||||
|
number = models.IntegerField()
|
||||||
name = models.CharField(max_length=255)
|
name = models.CharField(max_length=255)
|
||||||
prix = models.DecimalField(max_digits=5, decimal_places=2)
|
prix = models.DecimalField(max_digits=5, decimal_places=2)
|
||||||
cotisation = models.BooleanField()
|
cotisation = models.BooleanField()
|
||||||
duration = models.IntegerField(help_text="Durée exprimée en mois entiers", blank=True, null=True)
|
duration = models.IntegerField(help_text="Durée exprimée en mois entiers", blank=True, null=True)
|
||||||
|
|
||||||
|
def prix_total(self):
|
||||||
|
return self.prix*self.number
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.name) + ' ' + str(self.facture)
|
return str(self.name) + ' ' + str(self.facture)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{% extends "cotisations/sidebar.html" %}
|
{% extends "cotisations/sidebar.html" %}
|
||||||
{% load bootstrap3 %}
|
{% load bootstrap3 %}
|
||||||
|
{% load staticfiles%}
|
||||||
|
|
||||||
{% block title %}Création et modification de factures{% endblock %}
|
{% block title %}Création et modification de factures{% endblock %}
|
||||||
|
|
||||||
|
@ -9,10 +10,33 @@
|
||||||
<form class="form" method="post">
|
<form class="form" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% bootstrap_form factureform %}
|
{% bootstrap_form factureform %}
|
||||||
{% for vente in venteform %}
|
|
||||||
{% bootstrap_form vente %}
|
|
||||||
{% endfor %}
|
|
||||||
{{ venteform.management_form }}
|
{{ venteform.management_form }}
|
||||||
|
<div id="form_set">
|
||||||
|
{% for form in venteform.forms %}
|
||||||
|
{{ form.as_p }}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<input class="btn btn-primary btn-sm" role="button" value="Ajouter un article" id="add_one">
|
||||||
|
<input class="btn btn-primary btn-sm" role="button" value="Supprimer un article" id="del_one">
|
||||||
{% bootstrap_button "Créer ou modifier" button_type="submit" icon="star" %}
|
{% bootstrap_button "Créer ou modifier" button_type="submit" icon="star" %}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<div id="empty_form" style="display:none">
|
||||||
|
<table class='no_error'>
|
||||||
|
{{ venteform.empty_form.as_p }}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$('#add_one').click(function() {
|
||||||
|
var form_idx = $('#id_form-TOTAL_FORMS').val();
|
||||||
|
$('#form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx));
|
||||||
|
$('#id_form-TOTAL_FORMS').val(parseInt(form_idx) + 1);
|
||||||
|
});
|
||||||
|
$('#del_one').click(function() {
|
||||||
|
var forms = $('.dynamic-form');
|
||||||
|
$('#id_form-TOTAL_FORMS').val(forms.length);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -12,7 +12,7 @@ from django.forms import modelformset_factory, formset_factory
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from .models import Facture, Article, Vente, Cotisation, Paiement, Banque
|
from .models import Facture, Article, Vente, Cotisation, Paiement, Banque
|
||||||
from .forms import NewFactureForm, EditFactureForm, ArticleForm, DelArticleForm, PaiementForm, DelPaiementForm, BanqueForm, DelBanqueForm, NewFactureFormPdf
|
from .forms import NewFactureForm, EditFactureForm, ArticleForm, DelArticleForm, PaiementForm, DelPaiementForm, BanqueForm, DelBanqueForm, NewFactureFormPdf, SelectArticleForm
|
||||||
from users.models import User
|
from users.models import User
|
||||||
from .tex import render_tex
|
from .tex import render_tex
|
||||||
from re2o.settings_local import ASSO_NAME, ASSO_ADDRESS_LINE1, ASSO_ADDRESS_LINE2, ASSO_SIRET, ASSO_EMAIL, ASSO_PHONE, LOGO_PATH
|
from re2o.settings_local import ASSO_NAME, ASSO_ADDRESS_LINE1, ASSO_ADDRESS_LINE2, ASSO_SIRET, ASSO_EMAIL, ASSO_PHONE, LOGO_PATH
|
||||||
|
@ -47,22 +47,28 @@ def new_facture(request, userid):
|
||||||
return redirect("/cotisations/")
|
return redirect("/cotisations/")
|
||||||
facture = Facture(user=user)
|
facture = Facture(user=user)
|
||||||
facture_form = NewFactureForm(request.POST or None, instance=facture)
|
facture_form = NewFactureForm(request.POST or None, instance=facture)
|
||||||
ArticleFormSet = formset_factory(ArticleForm)
|
article_formset = formset_factory(SelectArticleForm)
|
||||||
if facture_form.is_valid():
|
article_formset = article_formset(request.POST or None)
|
||||||
|
if facture_form.is_valid() and article_formset.is_valid():
|
||||||
new_facture = facture_form.save(commit=False)
|
new_facture = facture_form.save(commit=False)
|
||||||
article = facture_form.cleaned_data['article']
|
articles = article_formset
|
||||||
|
if any(art.cleaned_data for art in articles):
|
||||||
new_facture.save()
|
new_facture.save()
|
||||||
for art in article:
|
for art_item in articles:
|
||||||
new_vente = Vente.objects.create(facture=new_facture, name=art.name, prix=art.prix, cotisation=art.cotisation, duration=art.duration, number=1)
|
if art_item.cleaned_data:
|
||||||
|
article = art_item.cleaned_data['article']
|
||||||
|
quantity = art_item.cleaned_data['quantity']
|
||||||
|
new_vente = Vente.objects.create(facture=new_facture, name=article.name, prix=article.prix, cotisation=article.cotisation, duration=article.duration, number=quantity)
|
||||||
new_vente.save()
|
new_vente.save()
|
||||||
if any(art.cotisation for art in article):
|
if any(art.cleaned_data['article'].cotisation for art in articles):
|
||||||
duration = sum(art.duration for art in article if art.cotisation)
|
duration = sum(art.cleaned_data['article'].duration*art.cleaned_data['quantity'] for art in articles if art.cleaned_data['article'].cotisation)
|
||||||
create_cotis(new_facture, user, duration)
|
create_cotis(new_facture, user, duration)
|
||||||
messages.success(request, "La cotisation a été prolongée pour l'adhérent %s " % user.name )
|
messages.success(request, "La cotisation a été prolongée pour l'adhérent %s " % user.name )
|
||||||
else:
|
else:
|
||||||
messages.success(request, "La facture a été crée")
|
messages.success(request, "La facture a été crée")
|
||||||
return redirect("/users/profil/" + userid)
|
return redirect("/users/profil/" + userid)
|
||||||
return form({'factureform': facture_form}, 'cotisations/facture.html', request)
|
messages.error(request, u"Il faut au moins un article valide pour créer une facture" )
|
||||||
|
return form({'factureform': facture_form, 'venteform': article_formset}, 'cotisations/facture.html', request)
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@permission_required('trésorier')
|
@permission_required('trésorier')
|
||||||
|
|
Loading…
Reference in a new issue