mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-27 15:12:25 +00:00
Vue pour controle de factures, et modification de la relation facture-vente
This commit is contained in:
parent
f08a42a326
commit
017c48346f
8 changed files with 116 additions and 18 deletions
|
@ -6,10 +6,10 @@ class FactureAdmin(admin.ModelAdmin):
|
||||||
list_display = ('user','paiement','date','valid','control')
|
list_display = ('user','paiement','date','valid','control')
|
||||||
|
|
||||||
class VenteAdmin(admin.ModelAdmin):
|
class VenteAdmin(admin.ModelAdmin):
|
||||||
list_display = ('facture','name','prix','number','cotisation','duration')
|
list_display = ('facture','name','prix','number','iscotisation','duration')
|
||||||
|
|
||||||
class ArticleAdmin(admin.ModelAdmin):
|
class ArticleAdmin(admin.ModelAdmin):
|
||||||
list_display = ('name','prix','cotisation','duration')
|
list_display = ('name','prix','iscotisation','duration')
|
||||||
|
|
||||||
class BanqueAdmin(admin.ModelAdmin):
|
class BanqueAdmin(admin.ModelAdmin):
|
||||||
list_display = ('name',)
|
list_display = ('name',)
|
||||||
|
@ -21,7 +21,7 @@ class PaiementAdmin(admin.ModelAdmin):
|
||||||
list_display = ('moyen',)
|
list_display = ('moyen',)
|
||||||
|
|
||||||
class CotisationAdmin(admin.ModelAdmin):
|
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(Facture, FactureAdmin)
|
||||||
admin.site.register(Article, ArticleAdmin)
|
admin.site.register(Article, ArticleAdmin)
|
||||||
|
|
34
cotisations/migrations/0016_auto_20160715_0110.py
Normal file
34
cotisations/migrations/0016_auto_20160715_0110.py
Normal file
|
@ -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,
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,5 +1,7 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
from dateutil.relativedelta import relativedelta
|
||||||
|
from django.core.validators import MinValueValidator
|
||||||
|
|
||||||
class Facture(models.Model):
|
class Facture(models.Model):
|
||||||
user = models.ForeignKey('users.User', on_delete=models.PROTECT)
|
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)
|
cheque = models.CharField(max_length=255, blank=True)
|
||||||
date = models.DateTimeField(auto_now_add=True)
|
date = models.DateTimeField(auto_now_add=True)
|
||||||
valid = models.BooleanField(default=True)
|
valid = models.BooleanField(default=True)
|
||||||
|
control = models.BooleanField(default=False)
|
||||||
|
|
||||||
def prix(self):
|
def prix(self):
|
||||||
prix = Vente.objects.all().filter(facture=self).aggregate(models.Sum('prix'))['prix__sum']
|
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)
|
return str(self.date) + ' ' + str(self.user)
|
||||||
|
|
||||||
class Vente(models.Model):
|
class Vente(models.Model):
|
||||||
facture = models.ForeignKey('Facture', on_delete=models.PROTECT)
|
facture = models.ForeignKey('Facture', on_delete=models.CASCADE)
|
||||||
number = models.IntegerField()
|
number = models.IntegerField(validators=[MinValueValidator(1)])
|
||||||
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()
|
iscotisation = 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):
|
def prix_total(self):
|
||||||
return self.prix*self.number
|
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):
|
def __str__(self):
|
||||||
return str(self.name) + ' ' + str(self.facture)
|
return str(self.name) + ' ' + str(self.facture)
|
||||||
|
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
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()
|
iscotisation = 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 __str__(self):
|
def __str__(self):
|
||||||
|
@ -59,10 +68,10 @@ class Paiement(models.Model):
|
||||||
return self.moyen
|
return self.moyen
|
||||||
|
|
||||||
class Cotisation(models.Model):
|
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_start = models.DateTimeField()
|
||||||
date_end = models.DateTimeField()
|
date_end = models.DateTimeField()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.facture)
|
return str(self.vente)
|
||||||
|
|
||||||
|
|
43
cotisations/templates/cotisations/control.html
Normal file
43
cotisations/templates/cotisations/control.html
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
{% extends "cotisations/sidebar.html" %}
|
||||||
|
{% load bootstrap3 %}
|
||||||
|
{% load staticfiles%}
|
||||||
|
|
||||||
|
{% block title %}Controle des factures{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>Controle et validité des factures</h2>
|
||||||
|
<form class="form" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ controlform.management_form }}
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Utilisateur</th>
|
||||||
|
<th>Designation</th>
|
||||||
|
<th>Prix total</th>
|
||||||
|
<th>Moyen de paiement</th>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>Validité</th>
|
||||||
|
<th>Controle trésorier</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
{% for form in controlform.forms %}
|
||||||
|
{% bootstrap_form_errors form %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ form.instance.user }}</td>
|
||||||
|
<td>{{ form.instance.name }}</td>
|
||||||
|
<td>{{ form.instance.prix_total }}</td>
|
||||||
|
<td>{{ form.instance.paiement }}</td>
|
||||||
|
<td>{{ form.instance.date }}</td>
|
||||||
|
<td>{{ form.valid }}</td>
|
||||||
|
<td>{{ form.control }}</td>
|
||||||
|
{% for hidden in form.hidden_fields %}
|
||||||
|
{{ hidden }}
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
{% bootstrap_button "Modifier" button_type="submit" icon="star" %}
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -12,6 +12,7 @@
|
||||||
{% bootstrap_form factureform %}
|
{% bootstrap_form factureform %}
|
||||||
{{ venteform.management_form }}
|
{{ venteform.management_form }}
|
||||||
{% for form in venteform.forms %}
|
{% for form in venteform.forms %}
|
||||||
|
{% bootstrap_form_errors form %}
|
||||||
{{ form.as_p }}
|
{{ form.as_p }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% bootstrap_button "Créer ou modifier" button_type="submit" icon="star" %}
|
{% bootstrap_button "Créer ou modifier" button_type="submit" icon="star" %}
|
||||||
|
|
|
@ -5,5 +5,6 @@
|
||||||
<p><a href="{% url "cotisations:index-article" %}">Liste des articles en vente</a></p>
|
<p><a href="{% url "cotisations:index-article" %}">Liste des articles en vente</a></p>
|
||||||
<p><a href="{% url "cotisations:index-banque" %}">Liste des banques</a></p>
|
<p><a href="{% url "cotisations:index-banque" %}">Liste des banques</a></p>
|
||||||
<p><a href="{% url "cotisations:index-paiement" %}">Liste des moyens de paiement</a></p>
|
<p><a href="{% url "cotisations:index-paiement" %}">Liste des moyens de paiement</a></p>
|
||||||
{% if is_trez %}<p><a href="{% url "cotisations:new-facture-pdf" %}">Créer une nouvelle facture</a></p>{% endif %}
|
{% if is_trez %}<p><a href="{% url "cotisations:control" %}">Controler les factures</a></p>
|
||||||
|
<p><a href="{% url "cotisations:new-facture-pdf" %}">Créer une nouvelle facture</a></p>{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -20,6 +20,7 @@ urlpatterns = [
|
||||||
url(r'^index_article/$', views.index_article, name='index-article'),
|
url(r'^index_article/$', views.index_article, name='index-article'),
|
||||||
url(r'^index_banque/$', views.index_banque, name='index-banque'),
|
url(r'^index_banque/$', views.index_banque, name='index-banque'),
|
||||||
url(r'^index_paiement/$', views.index_paiement, name='index-paiement'),
|
url(r'^index_paiement/$', views.index_paiement, name='index-paiement'),
|
||||||
|
url(r'^control/$', views.control, name='control'),
|
||||||
url(r'^$', views.index, name='index'),
|
url(r'^$', views.index, name='index'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -26,9 +26,9 @@ def form(ctx, template, request):
|
||||||
c.update(csrf(request))
|
c.update(csrf(request))
|
||||||
return render_to_response(template, c, context_instance=RequestContext(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"""
|
""" 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()
|
date_max = user.end_adhesion() or timezone.now()
|
||||||
if date_max < timezone.now():
|
if date_max < timezone.now():
|
||||||
datemax = timezone.now()
|
datemax = timezone.now()
|
||||||
|
@ -57,17 +57,15 @@ def new_facture(request, userid):
|
||||||
# Si au moins un article est rempli
|
# Si au moins un article est rempli
|
||||||
if any(art.cleaned_data for art in articles):
|
if any(art.cleaned_data for art in articles):
|
||||||
new_facture.save()
|
new_facture.save()
|
||||||
duration = 0
|
|
||||||
for art_item in articles:
|
for art_item in articles:
|
||||||
if art_item.cleaned_data:
|
if art_item.cleaned_data:
|
||||||
article = art_item.cleaned_data['article']
|
article = art_item.cleaned_data['article']
|
||||||
quantity = art_item.cleaned_data['quantity']
|
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()
|
new_vente.save()
|
||||||
if art_item.cleaned_data['article'].cotisation:
|
if art_item.cleaned_data['article'].iscotisation:
|
||||||
duration += art_item.cleaned_data['article'].duration*art_item.cleaned_data['quantity']
|
create_cotis(new_vente, user, art_item.cleaned_data['article'].duration*art_item.cleaned_data['quantity'])
|
||||||
if duration:
|
if any(art_item.cleaned_data['article'].iscotisation for art_item in articles if art_item.cleaned_data):
|
||||||
create_cotis(new_facture, user, duration)
|
|
||||||
messages.success(request, "La cotisation a été prolongée pour l'adhérent %s jusqu'au %s" % (user.name, user.end_adhesion()) )
|
messages.success(request, "La cotisation a été prolongée pour l'adhérent %s jusqu'au %s" % (user.name, user.end_adhesion()) )
|
||||||
else:
|
else:
|
||||||
messages.success(request, "La facture a été crée")
|
messages.success(request, "La facture a été crée")
|
||||||
|
@ -269,6 +267,17 @@ def del_banque(request):
|
||||||
return redirect("/cotisations/index_banque/")
|
return redirect("/cotisations/index_banque/")
|
||||||
return form({'factureform': banque}, 'cotisations/facture.html', request)
|
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
|
@login_required
|
||||||
@permission_required('cableur')
|
@permission_required('cableur')
|
||||||
def index_article(request):
|
def index_article(request):
|
||||||
|
|
Loading…
Reference in a new issue