From 017c48346f1579f93064a6e9e2df2df7a1f37580 Mon Sep 17 00:00:00 2001 From: chirac Date: Sun, 17 Jul 2016 20:08:56 +0200 Subject: [PATCH] Vue pour controle de factures, et modification de la relation facture-vente --- cotisations/admin.py | 6 +-- .../migrations/0016_auto_20160715_0110.py | 34 +++++++++++++++ cotisations/models.py | 21 ++++++--- .../templates/cotisations/control.html | 43 +++++++++++++++++++ .../templates/cotisations/facture.html | 1 + .../templates/cotisations/sidebar.html | 3 +- cotisations/urls.py | 1 + cotisations/views.py | 25 +++++++---- 8 files changed, 116 insertions(+), 18 deletions(-) create mode 100644 cotisations/migrations/0016_auto_20160715_0110.py create mode 100644 cotisations/templates/cotisations/control.html diff --git a/cotisations/admin.py b/cotisations/admin.py index 58d62fa6..8a17c89a 100644 --- a/cotisations/admin.py +++ b/cotisations/admin.py @@ -6,10 +6,10 @@ class FactureAdmin(admin.ModelAdmin): list_display = ('user','paiement','date','valid','control') class VenteAdmin(admin.ModelAdmin): - list_display = ('facture','name','prix','number','cotisation','duration') + list_display = ('facture','name','prix','number','iscotisation','duration') class ArticleAdmin(admin.ModelAdmin): - list_display = ('name','prix','cotisation','duration') + list_display = ('name','prix','iscotisation','duration') class BanqueAdmin(admin.ModelAdmin): list_display = ('name',) @@ -21,7 +21,7 @@ class PaiementAdmin(admin.ModelAdmin): list_display = ('moyen',) class CotisationAdmin(admin.ModelAdmin): - list_display = ('facture','date_start','date_end') + list_display = ('vente','date_start','date_end') admin.site.register(Facture, FactureAdmin) admin.site.register(Article, ArticleAdmin) diff --git a/cotisations/migrations/0016_auto_20160715_0110.py b/cotisations/migrations/0016_auto_20160715_0110.py new file mode 100644 index 00000000..2dd26439 --- /dev/null +++ b/cotisations/migrations/0016_auto_20160715_0110.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('cotisations', '0015_auto_20160714_2142'), + ] + + operations = [ + migrations.RenameField( + model_name='article', + old_name='cotisation', + new_name='iscotisation', + ), + migrations.RenameField( + model_name='vente', + old_name='cotisation', + new_name='iscotisation', + ), + migrations.RemoveField( + model_name='cotisation', + name='facture', + ), + migrations.AddField( + model_name='cotisation', + name='vente', + field=models.OneToOneField(to='cotisations.Vente', null=True), + preserve_default=False, + ), + ] diff --git a/cotisations/models.py b/cotisations/models.py index 71513a42..658f4536 100644 --- a/cotisations/models.py +++ b/cotisations/models.py @@ -1,5 +1,7 @@ from django.db import models +from dateutil.relativedelta import relativedelta +from django.core.validators import MinValueValidator class Facture(models.Model): user = models.ForeignKey('users.User', on_delete=models.PROTECT) @@ -8,6 +10,7 @@ class Facture(models.Model): cheque = models.CharField(max_length=255, blank=True) date = models.DateTimeField(auto_now_add=True) valid = models.BooleanField(default=True) + control = models.BooleanField(default=False) def prix(self): prix = Vente.objects.all().filter(facture=self).aggregate(models.Sum('prix'))['prix__sum'] @@ -24,23 +27,29 @@ class Facture(models.Model): return str(self.date) + ' ' + str(self.user) class Vente(models.Model): - facture = models.ForeignKey('Facture', on_delete=models.PROTECT) - number = models.IntegerField() + facture = models.ForeignKey('Facture', on_delete=models.CASCADE) + number = models.IntegerField(validators=[MinValueValidator(1)]) name = models.CharField(max_length=255) prix = models.DecimalField(max_digits=5, decimal_places=2) - cotisation = models.BooleanField() + iscotisation = models.BooleanField() 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 clean(self): + if hasattr(self, 'cotisation'): + cotisation = self.cotisation + cotisation.date_end = cotisation.date_start + relativedelta(months=self.duration*self.number) + cotisation.save() + def __str__(self): return str(self.name) + ' ' + str(self.facture) class Article(models.Model): name = models.CharField(max_length=255) prix = models.DecimalField(max_digits=5, decimal_places=2) - cotisation = models.BooleanField() + iscotisation = models.BooleanField() duration = models.IntegerField(help_text="Durée exprimée en mois entiers", blank=True, null=True) def __str__(self): @@ -59,10 +68,10 @@ class Paiement(models.Model): return self.moyen class Cotisation(models.Model): - facture = models.OneToOneField('Facture', on_delete=models.PROTECT) + vente = models.OneToOneField('Vente', on_delete=models.CASCADE, null=True) date_start = models.DateTimeField() date_end = models.DateTimeField() def __str__(self): - return str(self.facture) + return str(self.vente) diff --git a/cotisations/templates/cotisations/control.html b/cotisations/templates/cotisations/control.html new file mode 100644 index 00000000..02c6ee41 --- /dev/null +++ b/cotisations/templates/cotisations/control.html @@ -0,0 +1,43 @@ +{% extends "cotisations/sidebar.html" %} +{% load bootstrap3 %} +{% load staticfiles%} + +{% block title %}Controle des factures{% endblock %} + +{% block content %} +

Controle et validité des factures

+
+ {% csrf_token %} + {{ controlform.management_form }} + + + + + + + + + + + + + {% for form in controlform.forms %} + {% bootstrap_form_errors form %} + + + + + + + + + {% for hidden in form.hidden_fields %} + {{ hidden }} + {% endfor %} + + {% endfor %} +
UtilisateurDesignationPrix totalMoyen de paiementDateValiditéControle trésorier
{{ form.instance.user }}{{ form.instance.name }}{{ form.instance.prix_total }}{{ form.instance.paiement }}{{ form.instance.date }}{{ form.valid }}{{ form.control }}
+ {% bootstrap_button "Modifier" button_type="submit" icon="star" %} +
+ +{% endblock %} diff --git a/cotisations/templates/cotisations/facture.html b/cotisations/templates/cotisations/facture.html index 59c6b2c0..7b9bc89e 100644 --- a/cotisations/templates/cotisations/facture.html +++ b/cotisations/templates/cotisations/facture.html @@ -12,6 +12,7 @@ {% bootstrap_form factureform %} {{ venteform.management_form }} {% for form in venteform.forms %} + {% bootstrap_form_errors form %} {{ form.as_p }} {% endfor %} {% bootstrap_button "Créer ou modifier" button_type="submit" icon="star" %} diff --git a/cotisations/templates/cotisations/sidebar.html b/cotisations/templates/cotisations/sidebar.html index 42a627ec..11475ceb 100644 --- a/cotisations/templates/cotisations/sidebar.html +++ b/cotisations/templates/cotisations/sidebar.html @@ -5,5 +5,6 @@

Liste des articles en vente

Liste des banques

Liste des moyens de paiement

- {% if is_trez %}

Créer une nouvelle facture

{% endif %} + {% if is_trez %}

Controler les factures

+

Créer une nouvelle facture

{% endif %} {% endblock %} diff --git a/cotisations/urls.py b/cotisations/urls.py index 5587d4c3..4b320bb0 100644 --- a/cotisations/urls.py +++ b/cotisations/urls.py @@ -20,6 +20,7 @@ urlpatterns = [ url(r'^index_article/$', views.index_article, name='index-article'), url(r'^index_banque/$', views.index_banque, name='index-banque'), url(r'^index_paiement/$', views.index_paiement, name='index-paiement'), + url(r'^control/$', views.control, name='control'), url(r'^$', views.index, name='index'), ] diff --git a/cotisations/views.py b/cotisations/views.py index 6b9e86cb..b12248bd 100644 --- a/cotisations/views.py +++ b/cotisations/views.py @@ -26,9 +26,9 @@ def form(ctx, template, request): c.update(csrf(request)) return render_to_response(template, c, context_instance=RequestContext(request)) -def create_cotis(facture, user, duration): +def create_cotis(vente, user, duration): """ Update et crée l'objet cotisation associé à une facture, prend en argument l'user, la facture pour la quantitéi, et l'article pour la durée""" - cotisation=Cotisation(facture=facture) + cotisation=Cotisation(vente=vente) date_max = user.end_adhesion() or timezone.now() if date_max < timezone.now(): datemax = timezone.now() @@ -57,17 +57,15 @@ def new_facture(request, userid): # Si au moins un article est rempli if any(art.cleaned_data for art in articles): new_facture.save() - duration = 0 for art_item in articles: 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 = Vente.objects.create(facture=new_facture, name=article.name, prix=article.prix, iscotisation=article.iscotisation, duration=article.duration, number=quantity) new_vente.save() - if art_item.cleaned_data['article'].cotisation: - duration += art_item.cleaned_data['article'].duration*art_item.cleaned_data['quantity'] - if duration: - create_cotis(new_facture, user, duration) + if art_item.cleaned_data['article'].iscotisation: + create_cotis(new_vente, user, art_item.cleaned_data['article'].duration*art_item.cleaned_data['quantity']) + if any(art_item.cleaned_data['article'].iscotisation for art_item in articles if art_item.cleaned_data): messages.success(request, "La cotisation a été prolongée pour l'adhérent %s jusqu'au %s" % (user.name, user.end_adhesion()) ) else: messages.success(request, "La facture a été crée") @@ -269,6 +267,17 @@ def del_banque(request): return redirect("/cotisations/index_banque/") return form({'factureform': banque}, 'cotisations/facture.html', request) +@login_required +@permission_required('trésorier') +def control(request): + facture_list = Facture.objects.order_by('date').reverse() + controlform_set = modelformset_factory(Facture, fields=('control','valid'), extra=0) + controlform = controlform_set(request.POST or None, queryset=facture_list) + if controlform.is_valid(): + controlform.save() + return redirect("/cotisations/control/") + return render(request, 'cotisations/control.html', {'controlform': controlform}) + @login_required @permission_required('cableur') def index_article(request):