Commit 527f1b9f authored by Dalahro's avatar Dalahro

Pdf pour les factures

parent 61733e99
......@@ -15,6 +15,8 @@ Dépendances :
* django-bootstrap3 (pip install)
* python3-django-macaddress (stretch)
* python3-dateutil (jessie-backports)
* texlive-latex-base
* texlive-fonts-recommended
Moteur de db conseillé (mysql), postgresql fonctionne également.
Pour mysql, il faut installer :
......
from django import forms
from django.forms import ModelForm, Form
from .models import Article, Paiement, Facture, Banque
from django import forms
from .models import Article, Paiement, Facture, Banque, Vente
class NewFactureForm(ModelForm):
article = forms.ModelMultipleChoiceField(queryset=Article.objects.all(), label="Article")
article = forms.ModelMultipleChoiceField(queryset=Article.objects.all(), label="Article", widget=forms.CheckboxSelectMultiple())
def __init__(self, *args, **kwargs):
super(NewFactureForm, self).__init__(*args, **kwargs)
self.fields['number'].label = 'Quantité'
self.fields['cheque'].required = False
self.fields['banque'].required = False
self.fields['cheque'].label = 'Numero de chèque'
......@@ -16,7 +16,7 @@ class NewFactureForm(ModelForm):
class Meta:
model = Facture
fields = ['paiement','banque','cheque','number']
fields = ['paiement','banque','cheque']
def clean(self):
cleaned_data=super(NewFactureForm, self).clean()
......@@ -27,13 +27,17 @@ class NewFactureForm(ModelForm):
raise forms.ValidationError("Le numero de chèque et la banque sont obligatoires")
return cleaned_data
class SelectArticleForm(Form):
article = forms.ModelChoiceField(queryset=Article.objects.all(), label="Article")
quantity = forms.IntegerField(label="Quantité")
class NewFactureFormPdf(Form):
article = forms.ModelMultipleChoiceField(queryset=Article.objects.all(), label="Article")
number = forms.IntegerField(label="Quantité")
paid = forms.BooleanField(label="Payé", required=False)
dest = forms.CharField(required=True, max_length=255, label="Destinataire")
obj = forms.CharField(required=False, label="Objet")
detail = forms.CharField(required=False, max_length=255, label="Détails")
chambre = forms.CharField(required=False, max_length=10, label="Adresse")
fid = forms.CharField(required=True, max_length=10, label="Numéro de la facture")
class EditFactureForm(NewFactureForm):
class Meta(NewFactureForm.Meta):
......
......@@ -3,8 +3,7 @@
<tr>
<th>Utilisateur</th>
<th>Designation</th>
<th>Nombre</th>
<th>Prix unitaire</th>
<th>Prix total</th>
<th>Moyen de paiement</th>
<th>Date</th>
<th></th>
......@@ -15,8 +14,7 @@
<tr>
<td>{{ facture.user }}</td>
<td>{{ facture.name }}</td>
<td>{{ facture.number }}</td>
<td>{{ facture.prix }}</td>
<td>{{ facture.prix_total }}</td>
<td>{{ facture.paiement }}</td>
<td>{{ facture.date }}</td>
<td>{% if is_cableur %}<a class="btn btn-primary btn-sm" role="button" href="{% url 'cotisations:edit-facture' facture.id %}"><i class="glyphicon glyphicon-bitcoin"></i> Editer</a>{% endif %}</td>
......
......@@ -9,6 +9,10 @@
<form class="form" method="post">
{% csrf_token %}
{% bootstrap_form factureform %}
{% for vente in venteform %}
{% bootstrap_form vente %}
{% endfor %}
{{ venteform.management_form }}
{% bootstrap_button "Créer ou modifier" button_type="submit" icon="star" %}
</form>
{% endblock %}
......@@ -34,6 +34,7 @@
\usepackage{graphicx}
\usepackage{calc}
\usepackage{tabularx}
\usepackage{eurosym}
\pagestyle{empty} % No page numbers
\linespread{1.5} % Line spacing
......@@ -52,12 +53,8 @@
%----------------------------------------------------------------------------------------
% HEADING SECTION
%----------------------------------------------------------------------------------------
\begin{titlepage}
%\begin{textblock}{4cm}(20mm,5mm)
%\includegraphics[scale=0.3]{/static_files/rezo-logo.png}
%\end{textblock}
\end{titlepage}
\hfil{\Huge\bf {{asso_name}} }\hfil % Company providing the invoice
\includegraphics[width=3.5cm]{% templatetag openbrace %}{{ tpl_path }}}
\tab \tab \tab \tab \tab {\Huge\bf {{asso_name}} }\hfil % Company providing the invoice
\bigskip\break % Whitespace
\hrule % Horizontal line \\
\vspace{0.5cm}
......@@ -66,7 +63,7 @@
Siret : {{siret}}
\\ \\
{\bf À :} \tab {{dest.name}} {{dest.surname}} \\ % Invoice recipient
{\bf Chambre :} \tab {% if dest.room = None %} Aucune chambre {% else %}{{dest.room}}{% endif %} \\
{\bf Adresse :} \tab {% if dest.room = None %} Aucune adresse renseignée {% else %}{{dest.room}}{% endif %} \\
{\bf Date:} \tab {{DATE}} \\ % Invoice date
......@@ -77,29 +74,27 @@ Siret : {{siret}}
\begin{tabularx}{\textwidth}{|X|r|r|r|}
\hline
\textbf{Désignation} & \textbf{Prix Unit.} & \textbf{Quantité} & \textbf{Prix total} \\
\textbf{Désignation} & \textbf{Prix Unit.} \euro & \textbf{Quantité} & \textbf{Prix total} \euro\\
\hline
{% for a in article %}
\hline
{{a.0.name}} & {{a.0.prix}} & {{a.1}} & {{a.2}}\\
{{a.0.name}} & {{a.0.prix}} \euro & {{a.1}} & {{a.2}} \euro\\
\hline
{% endfor %}
\hline
\end{tabularx}
%\setcounter{paid}{0}
%\setcounter{topay}{\real{\value{total}}-\value{paid}}
\vspace{1cm}
\hfill
\begin{tabular}{|l|r|}
\hline
\textbf{Total} & {{total|floatformat:2}} \\
\textbf{Votre règlement} & {% if paid %}{{total|floatformat:2}}{% else %} 00,00 {% endif %} \\
\textbf{Total} & {{total|floatformat:2}} \euro \\
\textbf{Votre règlement} & {% if paid %}{{total|floatformat:2}}{% else %} 00,00 {% endif %} \euro \\
\hline
\textbf{À PAYER} & {% if not paid %}{{total|floatformat:2}}{% else %} 00,00 {% endif %}\\
\textbf{À PAYER} & {% if not paid %}{{total|floatformat:2}}{% else %} 00,00 {% endif %} \euro\\
\hline
\hline
......
......@@ -5,4 +5,5 @@
<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 %}
{% endblock %}
......@@ -8,12 +8,15 @@ from django.template import Context, RequestContext, loader
from django.contrib.auth.decorators import login_required, permission_required
from django.contrib import messages
from django.db.models import Max, ProtectedError
from django.forms import modelformset_factory, formset_factory
import os
from .models import Facture, Article, Vente, Cotisation, Paiement, Banque
from .forms import NewFactureForm, EditFactureForm, ArticleForm, DelArticleForm, PaiementForm, DelPaiementForm, BanqueForm, DelBanqueForm, NewFactureFormPdf
from users.models import User
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 import settings
from dateutil.relativedelta import relativedelta
from django.utils import timezone
......@@ -44,15 +47,16 @@ def new_facture(request, userid):
return redirect("/cotisations/")
facture = Facture(user=user)
facture_form = NewFactureForm(request.POST or None, instance=facture)
ArticleFormSet = formset_factory(ArticleForm)
if facture_form.is_valid():
new_facture = facture_form.save(commit=False)
article = facture_form.cleaned_data['article']
new_facture.save()
for art in article:
new_vente = Vente.objects.create(facture=new_facture, name=art.name, prix=art.prix, cotisation=art.cotisation, duration=art.duration)
new_vente = Vente.objects.create(facture=new_facture, name=art.name, prix=art.prix, cotisation=art.cotisation, duration=art.duration, number=1)
new_vente.save()
if any(art.cotisation for art in article):
duration = sum(art.duration*facture.number for art in article if art.cotisation)
duration = sum(art.duration for art in article if art.cotisation)
create_cotis(new_facture, user, duration)
messages.success(request, "La cotisation a été prolongée pour l'adhérent %s " % user.name )
else:
......@@ -61,7 +65,7 @@ def new_facture(request, userid):
return form({'factureform': facture_form}, 'cotisations/facture.html', request)
@login_required
@permission_required('cableur')
@permission_required('trésorier')
def new_facture_pdf(request):
facture_form = NewFactureFormPdf(request.POST or None)
if facture_form.is_valid():
......@@ -70,12 +74,13 @@ def new_facture_pdf(request):
quantite = facture_form.cleaned_data['number']
paid = facture_form.cleaned_data['paid']
destinataire = facture_form.cleaned_data['dest']
objet = facture_form.cleaned_data['obj']
detail = facture_form.cleaned_data['detail']
chambre = facture_form.cleaned_data['chambre']
fid = facture_form.cleaned_data['fid']
for a in article:
tbl.append([a, quantite, a.prix * quantite])
prix_total = sum(a[2] for a in tbl)
return render_tex(request, 'cotisations/factures.tex', {'DATE' : timezone.now(),'dest':destinataire, 'obj':objet, 'detail':detail, 'article':tbl, 'total':prix_total, 'paid':paid, 'asso_name':ASSO_NAME, 'line1':ASSO_ADDRESS_LINE1, 'line2':ASSO_ADDRESS_LINE2, 'siret':ASSO_SIRET, 'email':ASSO_EMAIL, 'phone':ASSO_PHONE})
user = {'name':destinataire, 'room':chambre}
return render_tex(request, 'cotisations/factures.tex', {'DATE' : timezone.now(),'dest':user,'fid':fid, 'article':tbl, 'total':prix_total, 'paid':paid, 'asso_name':ASSO_NAME, 'line1':ASSO_ADDRESS_LINE1, 'line2':ASSO_ADDRESS_LINE2, 'siret':ASSO_SIRET, 'email':ASSO_EMAIL, 'phone':ASSO_PHONE, 'tpl_path': os.path.join(settings.BASE_DIR, LOGO_PATH)})
return form({'factureform': facture_form}, 'cotisations/facture.html', request)
@login_required
......@@ -91,9 +96,10 @@ def facture_pdf(request, factureid):
vente = Vente.objects.all().filter(facture=facture)
ventes = []
for v in vente:
ventes.append([v, facture.number, v.prix * facture.number])
return render_tex(request, 'cotisations/factures.tex', {'paid':True, 'fid':facture.id, 'DATE':facture.date,'dest':facture.user, 'article':ventes, 'total': facture.prix_total(), 'asso_name':ASSO_NAME, 'line1': ASSO_ADDRESS_LINE1, 'line2':ASSO_ADDRESS_LINE2, 'siret':ASSO_SIRET, 'email':ASSO_EMAIL, 'phone':ASSO_PHONE, 'tpl_path':LOGO_PATH})
ventes.append([v, v.number, v.prix_total])
return render_tex(request, 'cotisations/factures.tex', {'paid':True, 'fid':facture.id, 'DATE':facture.date,'dest':facture.user, 'article':ventes, 'total': facture.prix_total(), 'asso_name':ASSO_NAME, 'line1': ASSO_ADDRESS_LINE1, 'line2':ASSO_ADDRESS_LINE2, 'siret':ASSO_SIRET, 'email':ASSO_EMAIL, 'phone':ASSO_PHONE, 'tpl_path':os.path.join(settings.BASE_DIR, LOGO_PATH)})
@login_required
@permission_required('cableur')
def edit_facture(request, factureid):
try:
......@@ -102,11 +108,15 @@ def edit_facture(request, factureid):
messages.error(request, u"Facture inexistante" )
return redirect("/cotisations/")
facture_form = EditFactureForm(request.POST or None, instance=facture)
if facture_form.is_valid():
ventes_objects = Vente.objects.filter(facture=facture)
vente_form_set = modelformset_factory(Vente, fields=('name','prix','number'), can_delete=True)
vente_form = vente_form_set(request.POST or None, queryset=ventes_objects)
if facture_form.is_valid() and vente_form.is_valid():
facture_form.save()
vente_form.save()
messages.success(request, "La facture a bien été modifiée")
return redirect("/cotisations/")
return form({'factureform': facture_form}, 'cotisations/facture.html', request)
return form({'factureform': facture_form, 'venteform': vente_form}, 'cotisations/facture.html', request)
@login_required
@permission_required('trésorier')
......
......@@ -12,7 +12,7 @@ https://docs.djangoproject.com/en/1.8/ref/settings/
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
from .settings_local import SECRET_KEY, DATABASES, DEBUG, ALLOWED_HOSTS, ASSO_NAME, ASSO_ADDRESS_LINE1, ASSO_ADDRESS_LINE2, ASSO_SIRET, ASSO_EMAIL, ASSO_PHONE
from .settings_local import SECRET_KEY, DATABASES, DEBUG, ALLOWED_HOSTS, ASSO_NAME, ASSO_ADDRESS_LINE1, ASSO_ADDRESS_LINE2, ASSO_SIRET, ASSO_EMAIL, ASSO_PHONE, LOGO_PATH
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment