diff --git a/README.md b/README.md
index 735c9083..0f873031 100644
--- a/README.md
+++ b/README.md
@@ -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 :
diff --git a/cotisations/forms.py b/cotisations/forms.py
index 86cc95d5..bf323602 100644
--- a/cotisations/forms.py
+++ b/cotisations/forms.py
@@ -1,13 +1,13 @@
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):
diff --git a/cotisations/templates/cotisations/aff_cotisations.html b/cotisations/templates/cotisations/aff_cotisations.html
index 54080588..5638c6ab 100644
--- a/cotisations/templates/cotisations/aff_cotisations.html
+++ b/cotisations/templates/cotisations/aff_cotisations.html
@@ -3,8 +3,7 @@
Utilisateur |
Designation |
- Nombre |
- Prix unitaire |
+ Prix total |
Moyen de paiement |
Date |
|
@@ -15,8 +14,7 @@
{{ facture.user }} |
{{ facture.name }} |
- {{ facture.number }} |
- {{ facture.prix }} |
+ {{ facture.prix_total }} |
{{ facture.paiement }} |
{{ facture.date }} |
{% if is_cableur %} Editer{% endif %} |
diff --git a/cotisations/templates/cotisations/facture.html b/cotisations/templates/cotisations/facture.html
index 48147b96..50721ef7 100644
--- a/cotisations/templates/cotisations/facture.html
+++ b/cotisations/templates/cotisations/facture.html
@@ -9,6 +9,10 @@
{% endblock %}
diff --git a/cotisations/templates/cotisations/factures.tex b/cotisations/templates/cotisations/factures.tex
index acead159..d2d68e6a 100644
--- a/cotisations/templates/cotisations/factures.tex
+++ b/cotisations/templates/cotisations/factures.tex
@@ -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
diff --git a/cotisations/templates/cotisations/sidebar.html b/cotisations/templates/cotisations/sidebar.html
index e34d045b..42a627ec 100644
--- a/cotisations/templates/cotisations/sidebar.html
+++ b/cotisations/templates/cotisations/sidebar.html
@@ -5,4 +5,5 @@
Liste des articles en vente
Liste des banques
Liste des moyens de paiement
+ {% if is_trez %}Créer une nouvelle facture
{% endif %}
{% endblock %}
diff --git a/cotisations/views.py b/cotisations/views.py
index 772319aa..19d9dca0 100644
--- a/cotisations/views.py
+++ b/cotisations/views.py
@@ -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')
diff --git a/re2o/settings.py b/re2o/settings.py
index e110269d..5cb9903a 100644
--- a/re2o/settings.py
+++ b/re2o/settings.py
@@ -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__)))