mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-23 20:03:11 +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')
|
||||
|
||||
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)
|
||||
|
|
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 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)
|
||||
|
||||
|
|
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 %}
|
||||
{{ 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" %}
|
||||
|
|
|
@ -5,5 +5,6 @@
|
|||
<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-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 %}
|
||||
|
|
|
@ -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'),
|
||||
]
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Reference in a new issue