Ajout export pdf des heures supplémetnaires
This commit is contained in:
@@ -133,6 +133,8 @@ USE_I18N = True
|
|||||||
|
|
||||||
USE_TZ = False
|
USE_TZ = False
|
||||||
|
|
||||||
|
DATE_FORMAT = "d.m.Y"
|
||||||
|
USE_L10N = False
|
||||||
|
|
||||||
# Static files (CSS, JavaScript, Images)
|
# Static files (CSS, JavaScript, Images)
|
||||||
# https://docs.djangoproject.com/en/4.0/howto/static-files/
|
# https://docs.djangoproject.com/en/4.0/howto/static-files/
|
||||||
|
@@ -2,6 +2,7 @@ from django.contrib import admin
|
|||||||
from rangefilter.filters import DateRangeFilter
|
from rangefilter.filters import DateRangeFilter
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
from collabs.models import *
|
from collabs.models import *
|
||||||
|
|
||||||
@@ -37,7 +38,6 @@ class Collabs_hour_Admin(admin.ModelAdmin):
|
|||||||
list_editable = ['bNoticed']
|
list_editable = ['bNoticed']
|
||||||
list_filter = [('dtDate', DateRangeFilter), ('user', admin.RelatedOnlyFieldListFilter),'sBases','type']
|
list_filter = [('dtDate', DateRangeFilter), ('user', admin.RelatedOnlyFieldListFilter),'sBases','type']
|
||||||
|
|
||||||
|
|
||||||
search_fields = ['userName']
|
search_fields = ['userName']
|
||||||
|
|
||||||
readonly_fields = ["userName"]
|
readonly_fields = ["userName"]
|
||||||
|
15
collabs/list_pdf_export.py
Normal file
15
collabs/list_pdf_export.py
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
from django.http import HttpResponse
|
||||||
|
from django.template.loader import get_template
|
||||||
|
from xhtml2pdf import pisa
|
||||||
|
|
||||||
|
|
||||||
|
def render_to_pdf(template_src, context_dict={}):
|
||||||
|
template = get_template(template_src)
|
||||||
|
html = template.render(context_dict)
|
||||||
|
response = HttpResponse(content_type='application/pdf')
|
||||||
|
pdf_status = pisa.CreatePDF(html, dest=response)
|
||||||
|
|
||||||
|
if pdf_status.err:
|
||||||
|
return HttpResponse('Some errors were encountered <pre>' + html + '</pre>')
|
||||||
|
|
||||||
|
return response
|
@@ -10,6 +10,11 @@ from django.contrib import admin
|
|||||||
|
|
||||||
#test
|
#test
|
||||||
|
|
||||||
|
BASES_CHOICES = [
|
||||||
|
('1', 'Monthey'),
|
||||||
|
('2', 'Uvrier'),
|
||||||
|
]
|
||||||
|
|
||||||
class Collabs_hour_types(models.Model):
|
class Collabs_hour_types(models.Model):
|
||||||
|
|
||||||
|
|
||||||
@@ -27,10 +32,7 @@ class Collabs_hour_types(models.Model):
|
|||||||
|
|
||||||
class Collabs_hour(models.Model):
|
class Collabs_hour(models.Model):
|
||||||
|
|
||||||
BASES_CHOICES = [
|
|
||||||
('1', 'Monthey'),
|
|
||||||
('2', 'Uvrier'),
|
|
||||||
]
|
|
||||||
|
|
||||||
userName = models.CharField("Auteur", max_length=100)
|
userName = models.CharField("Auteur", max_length=100)
|
||||||
user = models.ForeignKey(settings.AUTH_USER_MODEL, limit_choices_to={'groups__name': "Intervenants"}, verbose_name="Collaborateur", on_delete=models.DO_NOTHING)
|
user = models.ForeignKey(settings.AUTH_USER_MODEL, limit_choices_to={'groups__name': "Intervenants"}, verbose_name="Collaborateur", on_delete=models.DO_NOTHING)
|
||||||
@@ -50,18 +52,17 @@ class Collabs_hour(models.Model):
|
|||||||
def get_total_hour_by_user(self):
|
def get_total_hour_by_user(self):
|
||||||
#objs = Collabs_hour.objects.filter(user_id=self.user_id,dtCreated__year=self.dtCreated.year, dtCreated__month=self.dtCreated.month)
|
#objs = Collabs_hour.objects.filter(user_id=self.user_id,dtCreated__year=self.dtCreated.year, dtCreated__month=self.dtCreated.month)
|
||||||
objs = Collabs_hour.objects.filter(user_id=self.user_id, dtDate__year=self.dtDate.year , dtDate__month=self.dtDate.month)
|
objs = Collabs_hour.objects.filter(user_id=self.user_id, dtDate__year=self.dtDate.year , dtDate__month=self.dtDate.month)
|
||||||
print(f"user {self.user} dtCreated__year {self.dtDate.year} dtCreated__month {self.dtDate.month}")
|
# print(f"user {self.user} dtCreated__year {self.dtDate.year} dtCreated__month {self.dtDate.month}")
|
||||||
#print( Collabs_hour.objects.all())
|
#print( Collabs_hour.objects.all())
|
||||||
|
|
||||||
total = 0.0
|
total = 0.0
|
||||||
|
|
||||||
for object in objs:
|
for object in objs:
|
||||||
total += object.nHour + object.nMinutes/60
|
total += object.nHour + object.nMinutes/60
|
||||||
print(f"hour = {object.nHour} minutes = {object.nMinutes} = {object.nMinutes/60}")
|
# print(f"hour = {object.nHour} minutes = {object.nMinutes} = {object.nMinutes/60}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
print(total)
|
|
||||||
print(objs)
|
|
||||||
if total > 0.0:
|
if total > 0.0:
|
||||||
hours = int(total)
|
hours = int(total)
|
||||||
minutes = (total*60) % 60
|
minutes = (total*60) % 60
|
||||||
@@ -74,6 +75,9 @@ class Collabs_hour(models.Model):
|
|||||||
|
|
||||||
return ret_string
|
return ret_string
|
||||||
|
|
||||||
|
def get_bases_name(self):
|
||||||
|
return BASES_CHOICES[int(self.sBases)-1][1]
|
||||||
|
|
||||||
@admin.display(description='Présence de remarques', boolean=True)
|
@admin.display(description='Présence de remarques', boolean=True)
|
||||||
def has_remarques(self):
|
def has_remarques(self):
|
||||||
ret = False
|
ret = False
|
||||||
|
58
collabs/templates/pdf_template.html
Normal file
58
collabs/templates/pdf_template.html
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
@page{
|
||||||
|
size: A4 landscape;
|
||||||
|
margin: 2cm;
|
||||||
|
}
|
||||||
|
* {
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
table-layout: fixed;
|
||||||
|
width: 100%;
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
|
|
||||||
|
table th {
|
||||||
|
text-align: left;
|
||||||
|
padding: 3px;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
table td {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
padding: 3px;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>N°</th>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>Heures</th>
|
||||||
|
<th>Minutes</th>
|
||||||
|
<th>Collaborateur</th>
|
||||||
|
<th>Types</th>
|
||||||
|
<th>Total du mois</th>
|
||||||
|
</tr>
|
||||||
|
{%for data in record%}
|
||||||
|
<tr>
|
||||||
|
<td style="width: 10%;"> {{forloop.counter}} </td>
|
||||||
|
<td sttyle=""> {{data.dtDate}} </td>
|
||||||
|
<td style=""> {{data.nHour}} </td>
|
||||||
|
<td style=""> {{data.nMinutes}} </td>
|
||||||
|
<td style=""> {{data.user}} ({{data.get_bases_name}}) </td>
|
||||||
|
<td style=""> {{data.type}} </td>
|
||||||
|
<td style=""> {{data.get_total_hour_by_user}} </td>
|
||||||
|
</tr>
|
||||||
|
{%endfor%}
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
7
collabs/templatetags/replace_collabs.py
Normal file
7
collabs/templatetags/replace_collabs.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
from django import template
|
||||||
|
|
||||||
|
register = template.Library()
|
||||||
|
|
||||||
|
@register.filter
|
||||||
|
def replace_collabs(value):
|
||||||
|
return value.replace("/admin/collabs/collabs_hour/","")
|
@@ -1,11 +1,13 @@
|
|||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
app_name = "collabs"
|
app_name = "collabs"
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('export/<year>/<month>', views.ExportView.as_view(), name='detail'),
|
#path('export/<year>/<month>', views.ExportView.as_view(), name='detail'),
|
||||||
|
path('print_pdf', views.ExportPdfView, name='print_pdf'),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@@ -7,10 +7,19 @@ from django.urls import reverse
|
|||||||
from django.views import generic
|
from django.views import generic
|
||||||
|
|
||||||
from collabs.models import *
|
from collabs.models import *
|
||||||
|
from collabs.list_pdf_export import render_to_pdf
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
|
||||||
|
|
||||||
|
def ExportPdfView(request):
|
||||||
|
start = request.GET['dtDate__range__gte']
|
||||||
|
template_name = "pdf_template.html"
|
||||||
|
records = Collabs_hour.objects.filter(dtDate__range=[start,request.GET['dtDate__range__lte']])
|
||||||
|
return render_to_pdf(template_name,{"record": records})
|
||||||
|
|
||||||
|
|
||||||
class ExportView(generic.ListView):
|
class ExportView(generic.ListView):
|
||||||
model = Collabs_hour
|
model = Collabs_hour
|
||||||
template_name = 'collabs_hour/detail.html'
|
template_name = 'collabs_hour/detail.html'
|
||||||
|
@@ -1,22 +1,49 @@
|
|||||||
|
arabic-reshaper==2.1.3
|
||||||
asgiref==3.4.1
|
asgiref==3.4.1
|
||||||
|
asn1crypto==1.5.1
|
||||||
Brotli==1.0.9
|
Brotli==1.0.9
|
||||||
|
certifi==2021.10.8
|
||||||
cffi==1.15.0
|
cffi==1.15.0
|
||||||
|
charset-normalizer==2.0.12
|
||||||
|
click==8.1.3
|
||||||
|
colorama==0.4.4
|
||||||
|
cryptography==37.0.1
|
||||||
cssselect2==0.4.1
|
cssselect2==0.4.1
|
||||||
Django==4.0
|
Django==4.0
|
||||||
django-admin-rangefilter==0.8.3
|
django-admin-rangefilter==0.8.3
|
||||||
django-baton==2.2.3
|
django-baton==2.2.3
|
||||||
django-jazzmin==2.4.8
|
django-jazzmin==2.4.8
|
||||||
fonttools==4.29.1
|
fonttools==4.29.1
|
||||||
|
future==0.18.2
|
||||||
html5lib==1.1
|
html5lib==1.1
|
||||||
|
idna==3.3
|
||||||
|
lxml==4.8.0
|
||||||
mysqlclient==2.1.0
|
mysqlclient==2.1.0
|
||||||
|
oscrypto==1.3.0
|
||||||
Pillow==9.0.1
|
Pillow==9.0.1
|
||||||
pycparser==2.21
|
pycparser==2.21
|
||||||
pydyf==0.1.2
|
pydyf==0.1.2
|
||||||
|
pyHanko==0.13.1
|
||||||
|
pyhanko-certvalidator==0.19.5
|
||||||
|
PyPDF3==1.0.6
|
||||||
pyphen==0.12.0
|
pyphen==0.12.0
|
||||||
|
python-bidi==0.4.2
|
||||||
|
pytz==2022.1
|
||||||
|
pytz-deprecation-shim==0.1.0.post0
|
||||||
|
PyYAML==6.0
|
||||||
|
qrcode==7.3.1
|
||||||
|
reportlab==3.6.9
|
||||||
|
requests==2.27.1
|
||||||
six==1.16.0
|
six==1.16.0
|
||||||
sqlparse==0.4.2
|
sqlparse==0.4.2
|
||||||
|
svglib==1.2.1
|
||||||
tinycss2==1.1.1
|
tinycss2==1.1.1
|
||||||
|
tqdm==4.64.0
|
||||||
tzdata==2021.5
|
tzdata==2021.5
|
||||||
|
tzlocal==4.2
|
||||||
|
uritools==4.0.0
|
||||||
|
urllib3==1.26.9
|
||||||
weasyprint==54.1
|
weasyprint==54.1
|
||||||
webencodings==0.5.1
|
webencodings==0.5.1
|
||||||
|
xhtml2pdf==0.2.7
|
||||||
zopfli==0.1.9
|
zopfli==0.1.9
|
||||||
|
@@ -44,10 +44,14 @@
|
|||||||
{% block object-tools-items %}
|
{% block object-tools-items %}
|
||||||
{% change_list_object_tools %}
|
{% change_list_object_tools %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% load replace_collabs %}
|
||||||
<li>
|
<li>
|
||||||
<a href="export/" class="historylink">Export</a>
|
<a href="/collabs/print_pdf{{ request.get_full_path | replace_collabs }}" class="historylink">Export</a>
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% if cl.formset and cl.formset.errors %}
|
{% if cl.formset and cl.formset.errors %}
|
||||||
<p class="errornote">
|
<p class="errornote">
|
||||||
|
54
templates/admin/collabs/pdf_template.html
Normal file
54
templates/admin/collabs/pdf_template.html
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
table-layout: fixed;
|
||||||
|
width: 100%;
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
|
|
||||||
|
table th {
|
||||||
|
text-align: left;
|
||||||
|
padding: 3px;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
table td {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
padding: 3px;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>N°</th>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>Heures</th>
|
||||||
|
<th>Minutes</th>
|
||||||
|
<th>Collaborateur</th>
|
||||||
|
<th>Types</th>
|
||||||
|
<th>Total du mois</th>
|
||||||
|
</tr>
|
||||||
|
{%for data in record%}
|
||||||
|
<tr>
|
||||||
|
<td style="width: 10%;"> {{forloop.counter}} </td>
|
||||||
|
<td sttyle="width: 40%; text-align: left;"> {{data.date}} </td>
|
||||||
|
<td style="width: 30%;"> {{data.hours}} </td>
|
||||||
|
<td style="width: 20%;"> {{data.minutes}} </td>
|
||||||
|
<td style="width: 20%;"> {{data.user}} ({{data.bases}}) </td>
|
||||||
|
<td style="width: 20%;"> {{data.types}} </td>
|
||||||
|
<td style="width: 20%;"> {{data.total}} </td>
|
||||||
|
</tr>
|
||||||
|
{%endfor%}
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
Reference in New Issue
Block a user