mirror of
https://github.com/nanoy42/coope
synced 2024-11-22 03:13:12 +00:00
Generate invoice
This commit is contained in:
parent
9ba037ec12
commit
8c44b4edc9
9 changed files with 162 additions and 3 deletions
|
@ -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)
|
||||
|
|
|
@ -123,3 +123,17 @@ 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}))
|
||||
|
||||
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
Normal file
100
gestion/templates/gestion/invoice.tex
Normal 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 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}
|
|
@ -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"),
|
||||
]
|
|
@ -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
|
||||
|
|
Before Width: | Height: | Size: 5 KiB After Width: | Height: | Size: 5 KiB |
|
@ -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>
|
||||
|
|
|
@ -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")
|
||||
"""
|
||||
|
|
|
@ -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…
Reference in a new issue