3
0
Fork 0
mirror of https://github.com/nanoy42/coope synced 2024-11-22 03:13:12 +00:00

Generate invoice

This commit is contained in:
Yoann Pétri 2019-06-23 13:46:12 +02:00
parent 9ba037ec12
commit 8c44b4edc9
9 changed files with 162 additions and 3 deletions

View file

@ -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)

View file

@ -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")

View file

@ -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 dinstance 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}

View file

@ -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"),
]

View file

@ -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

View file

Before

Width:  |  Height:  |  Size: 5 KiB

After

Width:  |  Height:  |  Size: 5 KiB

View file

@ -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>

View file

@ -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")
"""

View file

@ -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 ##########