3
0
Fork 0
mirror of https://github.com/nanoy42/coope synced 2024-12-23 15:33:45 +00:00

Merge branch 'compta' into dev

Close #18
This commit is contained in:
Yoann Pétri 2019-01-06 00:02:04 +01:00
commit d94676d5ec
9 changed files with 186 additions and 30 deletions

View file

@ -38,6 +38,7 @@ INSTALLED_APPS = [
'dal',
'dal_select2',
'simple_history',
'django_tex',
]
MIDDLEWARE = [
@ -68,6 +69,14 @@ TEMPLATES = [
],
},
},
{
'NAME': 'tex',
'BACKEND': 'django_tex.engine.TeXEngine',
'APP_DIRS': True,
'OPTIONS': {
'environment': 'gestion.environment.my_environment',
}
},
]
WSGI_APPLICATION = 'coopeV3.wsgi.application'

12
gestion/environment.py Normal file
View file

@ -0,0 +1,12 @@
from django_tex.environment import environment
def latex_safe(value):
return str(value).replace('_', '\_').replace('$', '\$').replace('&', '\&').replace('#', '\#').replace('{', '\{').replace('}','\}')
def my_environment(**options):
env = environment(**options)
env.filters.update({
'latex_safe': latex_safe
})
return env

View file

@ -66,4 +66,8 @@ class SelectActiveKegForm(forms.Form):
class PinteForm(forms.Form):
ids = forms.CharField(widget=forms.Textarea, label="Numéros", help_text="Numéros séparés par un espace. Laissez vide pour utiliser le range.", required=False)
begin = forms.IntegerField(label="Début", help_text="Début du range", required=False)
end = forms.IntegerField(label="Fin", help_text="Fin du range", required=False)
end = forms.IntegerField(label="Fin", help_text="Fin du range", required=False)
class GenerateReleveForm(forms.Form):
begin = forms.DateTimeField(label="Date de début")
end = forms.DateTimeField(label="Date de fin")

View file

@ -0,0 +1,71 @@
\documentclass[11pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[french]{babel}
\usepackage[T1]{fontenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{graphicx}
\usepackage{eurosym}
\usepackage[left=2cm,right=2cm,top=2cm,bottom=2cm]{geometry}
\usepackage{tabularx}
\usepackage{longtable}
\usepackage{tabu}
\author{Généré par CoopeV3}
\title{Relevé Coopé Technopôle Metz}
\begin{document}
\maketitle
\section{Informations générales}
\begin{longtabu}{|X|X|X|}
\hline
\multicolumn{2}{|c|}{Généré le } & \textbf{ {{- now | date('d/m/Y H:i:s') -}} }\\
\hline
Infos & De & \textbf{ {{- begin | date('d/m/Y H:i:s')-}} } \\
\cline{2-3} & À & \textbf{ {{- end | date('d/m/Y H:i:s') -}} }\\
\hline
Estimations & Espèces & \textbf{ {{- value_especes | latex_safe -}} \euro{}} \\
\cline{2-3} & Lydia & \textbf{ {{- value_lydia | latex_safe -}} \euro{}} \\
\cline{2-3} & Chèques & \textbf{ {{- value_cheque | latex_safe -}} \euro{}} \\
\hline
\end{longtabu}
\section{Transactions}
\begin{longtabu}{|c|X|X|X|X|X|}
\hline
\# & Date & Client & Montant & Moyen de paiement & Produit (Qté) \\
\hline
{% for consumption in consumptions %}
{{consumption.pk}} & {{consumption.date | date('d/m/Y H:i:s')}} & {{consumption.customer.first_name|latex_safe}} {{consumption.customer.last_name|latex_safe}} & {{consumption.amount}} \euro{} & {{consumption.paymentMethod}} & {{consumption.product}} (x{{consumption.quantity}})\\
\hline
{% endfor %}
\end{longtabu}
\section{Rechargements}
\begin{longtabu}{|c|X|X|X|X|}
\hline
\# & Date & Client & Montant & Moyen de paiement \\
\hline
{% for reload in reloads %}
{{reload.pk}} & {{ reload.date | date('d/m/Y H:i:s')}} & {{reload.customer.first_name | latex_safe}} {{reload.customer.last_name | latex_safe}} & {{ reload.amount }} \euro{} & {{reload.PaymentMethod}} \\
\hline
{% endfor %}
\end{longtabu}
\section{Remboursement}
\begin{longtabu}{|c|X|X|X|}
\hline
\# & Date & Client & Montant\\
\hline
{% for refund in refunds %}
{{refund.pk}} & {{ refund.date | date('d/m/Y H:i:s')}} & {{refund.customer.first_name|latex_safe}} {{refund.customer.last_name|latex_safe}} & {{ refund.amount }} \euro{}\\
\hline
{% endfor %}
\end{longtabu}
\section{Cotisations}
\begin{longtabu}{|c|X|X|X|X|X|}
\hline
\# & Date & Client & Montant & Durée & Moyen de paiement \\
\hline
{% for cot in cotisations %}
{{cot.pk}} & {{ cot.paymentDate | date('d/m/Y H:i:s')}} & {{cot.user.first_name|latex_safe}} {{cot.user.last_name|latex_safe}} & {{cot.amount}} \euro{} & {{cot.duration}} jours & {{cot.paymentMethod}} \\
\hline
{% endfor %}
\end{longtabu}
\end{document}

View file

@ -44,4 +44,5 @@ urlpatterns = [
path('kegs-active-autocomplete', views.KegActiveAutocomplete.as_view(), name="kegs-active-autocomplete"),
path('menus-autcomplete', views.MenusAutocomplete.as_view(), name="menus-autocomplete"),
path('cancelReload/<int:pk>', views.cancel_reload, name="cancelReload"),
path('gen_releve', views.gen_releve, name="gen_releve"),
]

View file

@ -8,15 +8,19 @@ from django.contrib.auth.decorators import login_required, permission_required
from django.utils import timezone
from django.http import HttpResponseRedirect
from coopeV3.acl import active_required, acl_or
from django_tex.views import render_to_pdf
from coopeV3.acl import active_required, acl_or, admin_required
import simplejson as json
from dal import autocomplete
from decimal import *
import datetime
from .forms import ReloadForm, RefundForm, ProductForm, KegForm, MenuForm, GestionForm, SearchMenuForm, SearchProductForm, SelectPositiveKegForm, SelectActiveKegForm, PinteForm
from .models import Product, Menu, Keg, ConsumptionHistory, KegHistory, Consumption, MenuHistory, Pinte, Reload
from .forms import ReloadForm, RefundForm, ProductForm, KegForm, MenuForm, GestionForm, SearchMenuForm, SearchProductForm, SelectPositiveKegForm, SelectActiveKegForm, PinteForm, GenerateReleveForm
from .models import Product, Menu, Keg, ConsumptionHistory, KegHistory, Consumption, MenuHistory, Pinte, Reload, Refund
from preferences.models import PaymentMethod, GeneralPreferences
from users.models import CotisationHistory
@active_required
@login_required
@ -26,10 +30,10 @@ def manage(request):
Display the manage page
**Context**
``gestion_form``
The manage form
``reload_form``
The :model:`gestion.Reload` form
@ -44,13 +48,13 @@ def manage(request):
``panini``
A list of active :model:`gestion.Product` corresponding to panini items
``food``
A list of active :model:`gestion.Product` corresponding to non-panini items
``soft``
A list of active :model:`gestion.Product` correspond to non alcoholic beverage
``menus``
The list of active :model:`gestion.Menu`
@ -288,7 +292,7 @@ def cancel_menu(request, pk):
for product in manu_history.menu.articles:
consumptionT = Consumption.objects.get(customer=user, product=product)
consumptionT -= menu_history.quantity
consumptionT.save()
consumptionT.save()
menu_history.delete()
messages.success(request, "La consommation du menu a bien été annulée")
return redirect(reverse('users:profile', kwargs={'pk': user.pk}))
@ -318,7 +322,7 @@ def addProduct(request):
``form``
The ProductForm instance
``form_title``
The title for the form template
@ -350,7 +354,7 @@ def editProduct(request, pk):
``form``
The ProductForm instance
``form_title``
The title for the form template
@ -399,7 +403,7 @@ def searchProduct(request):
``form``
The SearchProductForm instance
``form_title``
The title for the form template
@ -426,7 +430,7 @@ def productProfile(request, pk):
The primary key of the requested :model:`gestion.Product`
**Context**
``product``
The :model:`gestion.Product` instance
@ -500,10 +504,10 @@ def addKeg(request):
Display a form to add a :model:`gestion.Keg`
**Context**
``form``
The KegForm instance
``form_title``
The title for the :template:`form.html` template
@ -532,10 +536,10 @@ def editKeg(request, pk):
The primary key of the requested :model:`gestion.Keg`
**Context**
``form``
The KegForm instance
``form_title``
The title for the :template:`form.html` template
@ -562,10 +566,10 @@ def openKeg(request):
Display a form to open a :model:`gestion.Keg`
**Context**
``form``
The SelectPositiveKegForm instance
``form_title``
The title for the :template:`form.html` template
@ -628,10 +632,10 @@ def closeKeg(request):
Display a form to close a :model:`gestion.Keg`
**Context**
``form``
The SelectActiveKegForm instance
``form_title``
The title for the :template:`form.html` template
@ -716,7 +720,7 @@ def kegH(request, pk):
``keg``
The :model:`gestion.Keg` instance
``kegHistory``
List of :model:`gestion.KegHistory` attached to keg
@ -758,10 +762,10 @@ def addMenu(request):
Display a form to add a :model:`gestion.Menu`
**Context**
``form``
The MenuForm instance
``form_title``
The title for the :template:`form.html` template
@ -791,10 +795,10 @@ def edit_menu(request, pk):
The primary key of requested :model:`gestion.Menu`
**Context**
``form``
The MenuForm instance
``form_title``
The title for the :template:`form.html` template
@ -962,7 +966,7 @@ def release(request, pinte_pk):
else:
messages.error(request, "Impossible de libérer la pinte")
return redirect(reverse('gestion:pintesList'))
@active_required
@login_required
@permission_required('gestion.add_pinte')
@ -1017,4 +1021,52 @@ def pintes_list(request):
def pintes_user_list(request):
pks = [x.pk for x in User.objects.all() if x.profile.nb_pintes > 0]
users = User.objects.filter(pk__in=pks)
return render(request, "gestion/pintes_user_list.html", {"users": users})
return render(request, "gestion/pintes_user_list.html", {"users": users})
@active_required
@login_required
@admin_required
def gen_releve(request):
form = GenerateReleveForm(request.POST or None)
if form.is_valid():
begin, end = form.cleaned_data['begin'], form.cleaned_data['end']
consumptions = ConsumptionHistory.objects.filter(date__gte=begin).filter(date__lte=end).order_by('-date')
reloads = Reload.objects.filter(date__gt=begin).filter(date__lt=end).order_by('-date')
refunds = Refund.objects.filter(date__gt=begin).filter(date__lt=end).order_by('-date')
cotisations = CotisationHistory.objects.filter(paymentDate__gt=begin).filter(paymentDate__lt=end).order_by('-paymentDate')
especes = PaymentMethod.objects.get(name="Espèces")
lydia = PaymentMethod.objects.get(name="Lydia")
cheque = PaymentMethod.objects.get(name="Chèque")
value_especes = 0
value_lydia = 0
value_cheque = 0
for consumption in consumptions:
pm = consumption.paymentMethod
if pm == especes:
value_especes += consumption.amount
elif pm == lydia:
value_lydia += consumption.amount
elif pm == cheque:
value_cheque += consumption.amount
for reload in reloads:
pm = reload.PaymentMethod
if pm == especes:
value_especes += reload.amount
elif pm == lydia:
value_lydia += reload.amount
elif pm == cheque:
value_cheque += reload.amount
for refund in refunds:
value_especes -= refund.amount
for cot in cotisations:
pm = cot.paymentMethod
if pm == especes:
value_especes += cot.amount
elif pm == lydia:
value_lydia += cot.amount
elif pm == cheque:
value_cheque += cot.amount
now = datetime.datetime.now()
return render_to_pdf(request, 'gestion/releve.tex', {"consumptions": consumptions, "reloads": reloads, "refunds": refunds, "cotisations": cotisations, "begin": begin, "end": end, "now": now, "value_especes": value_especes, "value_lydia": value_lydia, "value_cheque": value_cheque}, filename="releve.pdf")
else:
return render(request, "form.html", {"form": form, "form_title": "Génération d'un relevé", "form_button": "Générer"})

View file

@ -3,4 +3,5 @@ django-autocomplete-light==3.3.2
pytz==2018.5
simplejson==3.16.0
docutils==0.14
django-simple-history==2.5.1
django-simple-history==2.5.1
jinja2==2.10

View file

@ -25,6 +25,11 @@
<a href="{% url 'preferences:generalPreferences' %}">Admin</a>
</span>
{% endif %}
{% if request.user.is_staff %}
<span class="tabulation2">
<a href="{% url 'gestion:gen_releve' %}">Comptabilité</a>
</span>
{% endif %}
{% if perms.preferences.view_cotisation %}
<span class="tabulation2">
<a href="{% url 'preferences:cotisationsIndex' %}">Cotisations</a>

View file

@ -169,4 +169,5 @@ def str_user(self):
fin = "Non adhérent"
return self.username + " (" + self.first_name + " " + self.last_name + ", " + str(self.profile.balance) + "€, " + fin + ")"
User.add_to_class("__str__", str_user)
User.add_to_class("__str__", str_user)