Browse Source

Generate invoice

pull/1/head
Yoann Piétri 7 years ago
parent
commit
8c44b4edc9
  1. 1
      django_tex/core.py
  2. 16
      gestion/forms.py
  3. 100
      gestion/templates/gestion/invoice.tex
  4. 1
      gestion/urls.py
  5. 39
      gestion/views.py
  6. 0
      templates/coope.png
  7. 5
      templates/nav.html
  8. 1
      users/models.py
  9. 2
      users/views.py

1
django_tex/core.py

@ -18,6 +18,7 @@ def run_tex(source):
filename = os.path.join(tempdir, 'texput.tex')
with open(filename, 'x', encoding='utf-8') as f:
f.write(source)
print(source)
latex_interpreter = getattr(settings, 'LATEX_INTERPRETER', DEFAULT_INTERPRETER)
latex_command = 'cd "{tempdir}" && {latex_interpreter} -interaction=batchmode {path}'.format(tempdir=tempdir, latex_interpreter=latex_interpreter, path=os.path.basename(filename))
process = run(latex_command, shell=True, stdout=PIPE, stderr=PIPE)

16
gestion/forms.py

@ -122,4 +122,18 @@ class SearchCategoryForm(forms.Form):
"""
A form to search a :class:`~gestion.models.Category`.
"""
category = forms.ModelChoiceField(queryset=Category.objects.all(), required=True, label="Catégorie", widget=autocomplete.ModelSelect2(url='gestion:categories-autocomplete', attrs={'data-minimum-input-length':2}))
category = forms.ModelChoiceField(queryset=Category.objects.all(), required=True, label="Catégorie", widget=autocomplete.ModelSelect2(url='gestion:categories-autocomplete', attrs={'data-minimum-input-length':2}))
class GenerateInvoiceForm(forms.Form):
"""
A form to generate an invoice
"""
invoice_date = forms.CharField(label="Date")
invoice_number = forms.CharField(label="Numéro", help_text="Au format 19018, sans le FE")
invoice_place = forms.CharField(label="Lieu")
invoice_object = forms.CharField(label="Objet")
invoice_description = forms.CharField(label="Description", required=False)
client_name = forms.CharField(label="Nom du client")
client_address_fisrt_line = forms.CharField(label="Première ligne d'adresse")
client_address_second_line = forms.CharField(label="Deuxième ligne d'adresse")
products = forms.CharField(widget=forms.Textarea, label="Produits", help_text="Au format nom;prix;quantité avec saut de ligne")

100
gestion/templates/gestion/invoice.tex

@ -0,0 +1,100 @@
\documentclass[french,11pt]{article}
\usepackage{babel}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[a4paper]{geometry}
\usepackage{units}
\usepackage{graphicx}
\usepackage{fancyhdr}
\usepackage{fp}
\usepackage{float}
\usepackage{eurosym}
\def\FactureDate { {{- invoice_date -}} }
\def\FactureNum { {{- invoice_number -}} }
\def\FactureAcquittee {non}
\def\FactureLieu { {{- invoice_place -}} }
\def\FactureObjet { {{- invoice_object -}} }
\def\FactureDescr {
{{- invoice_description -}}
}
\def\ClientNom{ {{- client_name -}} }
\def\ClientAdresse{
{{- client_address_first_line -}}\newline
{{ client_address_second_line }}
}
\geometry{verbose,tmargin=4em,bmargin=8em,lmargin=6em,rmargin=6em}
\setlength{\parindent}{0pt}
\setlength{\parskip}{1ex plus 0.5ex minus 0.2ex}
\thispagestyle{fancy}
\pagestyle{fancy}
\setlength{\parindent}{0pt}
\renewcommand{\headrulewidth}{0pt}
\cfoot{
\small{
Coopé Technopôle Metz (CTM)\\
Adresse mail : coopemetz@gmail.com\\}
\tiny{
Inscrite au registre des associations du tribunal d’instance de Metz
}
}
\begin{document}
\begin{figure}[H]
\includegraphics[scale=0.3]{ {{- path -}} }
\end{figure}
Coopé Technopôle Metz\\
4 place Édouard Branly\\
57070 Metz
Facture FE\FactureNum
{\addtolength{\leftskip}{10.5cm}
\textbf{\ClientNom} \\
\ClientAdresse \\
}
\hspace*{10.5cm}
\FactureLieu, le \FactureDate
~\\~\\
\textbf{Objet : \FactureObjet \\}
\textnormal{\FactureDescr}
\vspace{10mm}
\begin{center}
\begin{tabular}{lrrr}
\textbf{Désignation ~~~~~~} & \textbf{Prix unitaire} & \textbf{Quantité} & \textbf{Montant (EUR)} \\
\hline
{% for product in products %}
{{- product.0 -}} & {{- product.1 -}} \euro{} & {{- product.2 -}} & {{- product.3 -}} \euro{}\\
{% endfor %}
\hline
\textbf{Total HT} & & & {{- total -}} \euro{}
\end{tabular}
\end{center}
\vfill
À régler par chèque, espèces ou par virement bancaire :
\begin{center}
\begin{tabular}{|c c c c|}
\hline \textbf{Code banque} & \textbf{Code guichet}& \textbf{Nº de Compte} & \textbf{Clé RIB} \\
20041 & 01010 & 1074350Z031 & 48 \\
\hline \textbf{IBAN Nº} & \multicolumn{3}{|l|}{ FR82 2004 1010 1010 7435 0Z03 148 } \\
\hline \textbf{BIC} & \multicolumn{3}{|l|}{ PSSTFRPPNCY }\\
\hline \textbf{Domiciliation} & \multicolumn{3}{|l|}{La Banque Postale - Centre Financier - 54900 Nancy CEDEX 9}\\
\hline \textbf{Titulaire} & \multicolumn{3}{|l|}{ASSO COOPE TECHNOPOLE METZ}\\
\hline
\end{tabular}
\end{center}
\end{document}

1
gestion/urls.py

@ -54,4 +54,5 @@ urlpatterns = [
path('categories-autocomplete', views.CategoriesAutocomplete.as_view(), name="categories-autocomplete"),
path('stats', views.stats, name="stats"),
path('divide', views.divide, name="divide"),
path('gen_invoice', views.gen_invoice, name="gen_invoice"),
]

39
gestion/views.py

@ -8,6 +8,7 @@ from django.contrib.auth.decorators import login_required, permission_required
from django.utils import timezone
from django.http import HttpResponseRedirect
from django.db import transaction
from django.conf import settings
from datetime import datetime, timedelta
@ -17,8 +18,9 @@ from coopeV3.acl import active_required, acl_or, admin_required
import simplejson as json
from dal import autocomplete
from decimal import *
import os
from .forms import ReloadForm, RefundForm, ProductForm, KegForm, MenuForm, GestionForm, SearchMenuForm, SearchProductForm, SelectPositiveKegForm, SelectActiveKegForm, PinteForm, GenerateReleveForm, CategoryForm, SearchCategoryForm
from .forms import ReloadForm, RefundForm, ProductForm, KegForm, MenuForm, GestionForm, SearchMenuForm, SearchProductForm, SelectPositiveKegForm, SelectActiveKegForm, PinteForm, GenerateReleveForm, CategoryForm, SearchCategoryForm, GenerateInvoiceForm
from .models import Product, Menu, Keg, ConsumptionHistory, KegHistory, Consumption, MenuHistory, Pinte, Reload, Refund, Category
from users.models import School
from preferences.models import PaymentMethod, GeneralPreferences, Cotisation, DivideHistory
@ -826,6 +828,41 @@ def pintes_user_list(request):
users = User.objects.filter(pk__in=pks)
return render(request, "gestion/pintes_user_list.html", {"users": users})
@active_required
@login_required
@permission_required('users.can_generate_invoices')
def gen_invoice(request):
"""
Displays a form to generate an invoice.
"""
form = GenerateInvoiceForm(request.POST or None)
if form.is_valid():
products = [x.split(";") for x in form.cleaned_data["products"].split("\n")]
total = 0
for product in products:
sub_total = Decimal(product[1]) * Decimal(product[2])
product.append(sub_total)
total += sub_total
return render_to_pdf(
request,
'gestion/invoice.tex',
{
"invoice_date": form.cleaned_data["invoice_date"],
"invoice_number": form.cleaned_data["invoice_number"],
"invoice_place": form.cleaned_data["invoice_place"],
"invoice_object": form.cleaned_data["invoice_object"],
"invoice_description": form.cleaned_data["invoice_description"],
"client_name": form.cleaned_data["client_name"],
"client_address_first_line": form.cleaned_data["client_address_fisrt_line"],
"client_address_second_line": form.cleaned_data["client_address_second_line"],
"products" : products,
"total": total,
"path" : os.path.join(settings.BASE_DIR, "templates/coope.png"),
},
filename="FE" + form.cleaned_data["invoice_number"] + ".pdf")
else:
return render(request, "form.html", {"form": form, "form_title": "Génération d'une facture", "form_button": "Générer", "form_button_icon": "file-pdf"})
@active_required
@login_required
@admin_required

0
users/templates/users/coope.png → templates/coope.png

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

5
templates/nav.html

@ -42,6 +42,11 @@
<i class="fa fa-hand-holding-usd"></i> <a href="{% url 'gestion:divide' %}">Répartition</a>
</span>
{% endif %}
{% if perms.users.can_generate_invoices %}
<span class="tabulation2">
<i class="fa fa-file-invoice-dollar"></i> <a href="{% url 'gestion:gen_invoice' %}">Facture</a>
</span>
{% endif %}
{% if perms.preferences.view_cotisation %}
<span class="tabulation2">
<i class="fa fa-calendar-check"></i> <a href="{% url 'preferences:cotisationsIndex' %}">Cotisations</a>

1
users/models.py

@ -111,6 +111,7 @@ class Profile(models.Model):
"""
class Meta:
verbose_name = "Profil"
permissions = (('can_generate_invoices', 'Can generate invocies'),)
user = models.OneToOneField(User, on_delete=models.CASCADE, verbose_name="Utilisateur")
"""

2
users/views.py

@ -346,7 +346,7 @@ def gen_user_infos(request, pk):
user= get_object_or_404(User, pk=pk)
cotisations = CotisationHistory.objects.filter(user=user).order_by('-paymentDate')
now = datetime.now()
path = os.path.join(settings.BASE_DIR, "users/templates/users/coope.png")
path = os.path.join(settings.BASE_DIR, "templates/coope.png")
return render_to_pdf(request, 'users/bulletin.tex', {"user": user, "now": now, "cotisations": cotisations, "path":path}, filename="bulletin_" + user.first_name + "_" + user.last_name + ".pdf")
########## Groups ##########

Loading…
Cancel
Save