Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
AE UTBM
Sith
Commits
00feca44
Commit
00feca44
authored
Nov 29, 2016
by
Skia
🤘
Browse files
Merge branch 'krophil' into 'master'
pdf generation for operations See merge request
!21
parents
a60063f0
0b4f8265
Pipeline
#443
passed with stage
in 2 minutes and 19 seconds
Changes
5
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
accounting/templates/accounting/journal_details.jinja
View file @
00feca44
...
...
@@ -37,6 +37,7 @@
<td>
{%
trans
%}
Comment
{%
endtrans
%}
</td>
<td>
{%
trans
%}
File
{%
endtrans
%}
</td>
<td>
{%
trans
%}
Actions
{%
endtrans
%}
</td>
<td>
{%
trans
%}
PDF
{%
endtrans
%}
</td>
</tr>
</thead>
<tbody>
...
...
@@ -70,6 +71,7 @@
<a
href=
"
{{
url
(
'accounting:op_edit'
,
op_id
=
o.id
)
}}
"
>
{%
trans
%}
Edit
{%
endtrans
%}
</a>
{%
endif
%}
</td>
<td><a
href=
"
{{
url
(
'accounting:op_pdf'
,
op_id
=
o.id
)
}}
"
>
{%
trans
%}
Generate
{%
endtrans
%}
</a></td>
</tr>
{%
endfor
%}
</tbody>
...
...
accounting/urls.py
View file @
00feca44
...
...
@@ -29,6 +29,7 @@ urlpatterns = [
# Operations
url
(
r
'^operation/create/(?P<j_id>[0-9]+)$'
,
OperationCreateView
.
as_view
(),
name
=
'op_new'
),
url
(
r
'^operation/(?P<op_id>[0-9]+)$'
,
OperationEditView
.
as_view
(),
name
=
'op_edit'
),
url
(
r
'^operation/(?P<op_id>[0-9]+)/pdf$'
,
OperationPDFView
.
as_view
(),
name
=
'op_pdf'
),
# Companies
url
(
r
'^company/create$'
,
CompanyCreateView
.
as_view
(),
name
=
'co_new'
),
url
(
r
'^company/(?P<co_id>[0-9]+)$'
,
CompanyEditView
.
as_view
(),
name
=
'co_edit'
),
...
...
accounting/views.py
View file @
00feca44
...
...
@@ -5,6 +5,10 @@ from django.core.urlresolvers import reverse_lazy
from
django.forms.models
import
modelform_factory
from
django.forms
import
HiddenInput
from
django
import
forms
from
django.http
import
HttpResponseRedirect
,
HttpResponse
from
django.utils.translation
import
ugettext
as
_
from
django.conf
import
settings
from
ajax_select.fields
import
AutoCompleteSelectField
,
AutoCompleteSelectMultipleField
...
...
@@ -190,6 +194,7 @@ class JournalEditView(CanEditMixin, UpdateView):
fields
=
[
'name'
,
'start_date'
,
'end_date'
,
'club_account'
,
'closed'
]
template_name
=
'core/edit.jinja'
# Operation views
class
OperationForm
(
forms
.
ModelForm
):
...
...
@@ -303,6 +308,125 @@ class OperationEditView(CanEditMixin, UpdateView):
kwargs
[
'object'
]
=
self
.
object
.
journal
return
kwargs
class
OperationPDFView
(
CanViewMixin
,
DetailView
):
"""
Display the PDF of a given operation
"""
model
=
Operation
pk_url_kwarg
=
"op_id"
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
from
reportlab.pdfgen
import
canvas
from
reportlab.lib.units
import
cm
from
reportlab.platypus
import
SimpleDocTemplate
,
Table
,
TableStyle
from
reportlab.lib
import
colors
from
reportlab.lib.pagesizes
import
letter
from
reportlab.lib.utils
import
ImageReader
from
reportlab.graphics.shapes
import
Drawing
from
reportlab.pdfbase.ttfonts
import
TTFont
from
reportlab.pdfbase
import
pdfmetrics
pdfmetrics
.
registerFont
(
TTFont
(
'DejaVu'
,
'DejaVuSerif.ttf'
))
self
.
object
=
self
.
get_object
()
amount
=
self
.
object
.
amount
remark
=
self
.
object
.
remark
nature
=
self
.
object
.
accounting_type
.
movement_type
num
=
self
.
object
.
number
date
=
self
.
object
.
date
mode
=
self
.
object
.
mode
cheque_number
=
self
.
object
.
cheque_number
club_name
=
self
.
object
.
journal
.
club_account
.
name
ti
=
self
.
object
.
journal
.
name
op_label
=
self
.
object
.
label
club_address
=
self
.
object
.
journal
.
club_account
.
club
.
address
id_op
=
self
.
object
.
id
if
self
.
object
.
target_type
==
"OTHER"
:
target
=
self
.
object
.
target_label
else
:
target
=
self
.
object
.
target
.
get_display_name
()
response
=
HttpResponse
(
content_type
=
'application/pdf'
)
response
[
'Content-Disposition'
]
=
'attachment; filename="op-%d(%s_on_%s).pdf"'
%
(
num
,
ti
,
club_name
)
p
=
canvas
.
Canvas
(
response
)
p
.
setFont
(
'DejaVu'
,
12
)
p
.
setTitle
(
"%s %d"
%
(
_
(
"Operation"
),
num
))
width
,
height
=
letter
im
=
ImageReader
(
"core/static/core/img/logo.jpg"
)
iw
,
ih
=
im
.
getSize
()
p
.
drawImage
(
im
,
40
,
height
-
50
,
width
=
iw
/
2
,
height
=
ih
/
2
)
labelStr
=
[[
"%s %s - %s %s"
%
(
_
(
"Journal"
),
ti
,
_
(
"Operation"
),
num
)]]
label
=
Table
(
labelStr
,
colWidths
=
[
150
],
rowHeights
=
[
20
])
label
.
setStyle
(
TableStyle
([
(
'ALIGN'
,(
0
,
0
),(
-
1
,
-
1
),
'CENTER'
),
(
'BOX'
,
(
0
,
0
),
(
-
1
,
-
1
),
0.25
,
colors
.
black
),
]))
w
,
h
=
label
.
wrapOn
(
label
,
0
,
0
)
label
.
drawOn
(
p
,
width
-
180
,
height
)
p
.
drawString
(
90
,
height
-
100
,
_
(
"Financial proof: "
)
+
"OP%010d"
%
(
id_op
))
#Justificatif du libellé
p
.
drawString
(
90
,
height
-
130
,
_
(
"Club: %(club_name)s"
)
%
({
"club_name"
:
club_name
}))
p
.
drawString
(
90
,
height
-
160
,
_
(
"Label: %(op_label)s"
)
%
{
"op_label"
:
op_label
if
op_label
!=
None
else
""
})
data
=
[]
data
+=
[[
"%s"
%
(
_
(
"Credit"
).
upper
()
if
nature
==
'CREDIT'
else
_
(
"Debit"
).
upper
())]]
data
+=
[[
_
(
"Amount: %(amount).2f €"
)
%
{
"amount"
:
amount
}]]
payment_mode
=
""
for
m
in
settings
.
SITH_ACCOUNTING_PAYMENT_METHOD
:
if
m
[
0
]
==
mode
:
payment_mode
+=
"[
\u00D7
]"
else
:
payment_mode
+=
"[ ]"
payment_mode
+=
" %s
\n
"
%
(
m
[
1
])
data
+=
[[
payment_mode
]]
data
+=
[[
"%s : %s"
%
(
_
(
"Debtor"
)
if
nature
==
'CREDIT'
else
_
(
"Creditor"
),
target
),
""
]]
data
+=
[[
"%s
\n
%s"
%
(
_
(
"Comment:"
),
remark
)]]
t
=
Table
(
data
,
colWidths
=
[(
width
-
90
*
2
)
/
2
]
*
2
,
rowHeights
=
[
20
,
20
,
70
,
20
,
80
])
t
.
setStyle
(
TableStyle
([
(
'ALIGN'
,(
0
,
0
),(
-
1
,
-
1
),
'CENTER'
),
(
'VALIGN'
,(
-
2
,
-
1
),(
-
1
,
-
1
),
'TOP'
),
(
'VALIGN'
,(
0
,
0
),(
-
1
,
-
2
),
'MIDDLE'
),
(
'INNERGRID'
,
(
0
,
0
),
(
-
1
,
-
1
),
0.25
,
colors
.
black
),
(
'SPAN'
,
(
0
,
0
),
(
1
,
0
)),
# line DEBIT/CREDIT
(
'SPAN'
,
(
0
,
1
),
(
1
,
1
)),
# line amount
(
'SPAN'
,(
-
2
,
-
1
),
(
-
1
,
-
1
)),
# line comment
(
'SPAN'
,
(
0
,
-
2
),
(
-
1
,
-
2
)),
# line creditor/debtor
(
'SPAN'
,
(
0
,
2
),
(
1
,
2
)),
# line payment_mode
(
'ALIGN'
,(
0
,
2
),
(
1
,
2
),
'LEFT'
),
# line payment_mode
(
'ALIGN'
,
(
-
2
,
-
1
),
(
-
1
,
-
1
),
'LEFT'
),
(
'BOX'
,
(
0
,
0
),
(
-
1
,
-
1
),
0.25
,
colors
.
black
),
]))
w
,
h
=
t
.
wrapOn
(
p
,
0
,
0
)
t
.
drawOn
(
p
,
90
,
350
)
p
.
drawCentredString
(
10.5
*
cm
,
2
*
cm
,
club_name
)
p
.
drawCentredString
(
10.5
*
cm
,
1
*
cm
,
club_address
)
p
.
showPage
()
p
.
save
()
return
response
# Company views
class
CompanyCreateView
(
CanCreateMixin
,
CreateView
):
...
...
@@ -357,4 +481,3 @@ class LabelDeleteView(CanEditMixin, DeleteView):
def
get_success_url
(
self
):
return
self
.
object
.
get_absolute_url
()
core/static/core/img/logo.jpg
0 → 100644
View file @
00feca44
29.8 KB
locale/fr/LC_MESSAGES/django.po
View file @
00feca44
...
...
@@ -6,7 +6,7 @@
msgid
""
msgstr
""
"Report-Msgid-Bugs-To:
\n
"
"POT-Creation-Date: 2016-11-29 1
1:25
+0100
\n
"
"POT-Creation-Date: 2016-11-29 1
2:34
+0100
\n
"
"PO-Revision-Date: 2016-07-18
\n
"
"Last-Translator: Skia <skia@libskia.so>
\n
"
"Language-Team: AE info <ae.info@utbm.fr>
\n
"
...
...
@@ -244,11 +244,11 @@ msgstr "Un code comptable ne contient que des numéros"
msgid
"movement type"
msgstr
"type de mouvement"
#: accounting/models.py:300
#: accounting/models.py:300
accounting/views.py:383
msgid
"Credit"
msgstr
"Crédit"
#: accounting/models.py:300
#: accounting/models.py:300
accounting/views.py:383
msgid
"Debit"
msgstr
"Débit"
...
...
@@ -337,7 +337,7 @@ msgstr "Nouveau compte club"
#: accounting/templates/accounting/bank_account_details.jinja:26
#: accounting/templates/accounting/bank_account_list.jinja:21
#: accounting/templates/accounting/club_account_details.jinja:55
#: accounting/templates/accounting/journal_details.jinja:7
0
club/views.py:54
#: accounting/templates/accounting/journal_details.jinja:7
1
club/views.py:54
#: core/templates/core/file.jinja:38 core/templates/core/page.jinja:31
#: core/templates/core/user_tools.jinja:36 core/views/user.py:152
#: counter/templates/counter/cash_summary_list.jinja:53
...
...
@@ -403,9 +403,11 @@ msgstr "Nom"
#: accounting/templates/accounting/club_account_details.jinja:29
msgid
"Start"
msgstr
"
Début
"
msgstr
""
#: accounting/templates/accounting/club_account_details.jinja:30
#, fuzzy
#| msgid "End"
msgid
"End"
msgstr
"Fin"
...
...
@@ -431,12 +433,12 @@ msgid "Actions"
msgstr
"Actions"
#: accounting/templates/accounting/club_account_details.jinja:50
#: accounting/templates/accounting/journal_details.jinja:5
8
#: accounting/templates/accounting/journal_details.jinja:5
9
msgid
"Yes"
msgstr
"Oui"
#: accounting/templates/accounting/club_account_details.jinja:52
#: accounting/templates/accounting/journal_details.jinja:6
0
#: accounting/templates/accounting/journal_details.jinja:6
1
msgid
"No"
msgstr
"Non"
...
...
@@ -455,7 +457,7 @@ msgstr "Classeur : "
#: core/templates/core/user_account_detail.jinja:10
#: counter/templates/counter/counter_click.jinja:32
msgid
"Amount: "
msgstr
"Montant: "
msgstr
"Montant
: "
#: accounting/templates/accounting/journal_details.jinja:19
msgid
"Effective amount: "
...
...
@@ -521,6 +523,14 @@ msgstr "Commentaire"
msgid
"File"
msgstr
"Fichier"
#: accounting/templates/accounting/journal_details.jinja:40
msgid
"PDF"
msgstr
""
#: accounting/templates/accounting/journal_details.jinja:74
msgid
"Generate"
msgstr
"Générer"
#: accounting/templates/accounting/label_list.jinja:14
msgid
"Back to club account"
msgstr
"Retour au compte club"
...
...
@@ -559,6 +569,45 @@ msgstr "Types simplifiés"
msgid
"New simplified type"
msgstr
"Nouveau type simplifié"
#: accounting/views.py:360 accounting/views.py:366
msgid
"Operation"
msgstr
"Opération"
#: accounting/views.py:366
msgid
"Journal"
msgstr
"Classeur"
#: accounting/views.py:377
msgid
"Financial proof: "
msgstr
"Justificatif de libellé : "
#: accounting/views.py:378
#, python-format
msgid
"Club: %(club_name)s"
msgstr
"Club : %(club_name)s"
#: accounting/views.py:379
#, python-format
msgid
"Label: %(op_label)s"
msgstr
"Libellé : %(op_label)s"
#: accounting/views.py:385
#, python-format
msgid
"Amount: %(amount).2f €"
msgstr
"Montant : %(amount).2f €"
#: accounting/views.py:397
msgid
"Debtor"
msgstr
"Débiteur"
#: accounting/views.py:397
msgid
"Creditor"
msgstr
"Créditeur"
#: accounting/views.py:399
msgid
"Comment:"
msgstr
"Commentaire :"
#: club/models.py:21
msgid
"unix name"
msgstr
"nom unix"
...
...
@@ -593,7 +642,7 @@ msgstr "Un club avec ce nom UNIX existe déjà."
#: club/models.py:145 counter/models.py:386 counter/models.py:403
#: eboutic/models.py:14 eboutic/models.py:47 launderette/models.py:89
#: launderette/models.py:126 sas/models.py:9
6
#: launderette/models.py:126 sas/models.py:9
8
msgid
"user"
msgstr
"nom d'utilisateur"
...
...
@@ -646,8 +695,10 @@ msgstr "Rôle"
#: club/templates/club/club_old_members.jinja:10
#: core/templates/core/user_clubs.jinja:17
#: core/templates/core/user_clubs.jinja:43
#, fuzzy
#| msgid "description"
msgid
"Description"
msgstr
"
D
escription"
msgstr
"
d
escription"
#: club/templates/club/club_members.jinja:11
#: core/templates/core/user_clubs.jinja:18
...
...
@@ -1234,6 +1285,8 @@ msgid "page content"
msgstr
"contenu de la page"
#: core/templates/core/403.jinja:5
#, fuzzy
#| msgid "403, Forbidden"
msgid
"403, Forbidden"
msgstr
"403. Non autorisé"
...
...
@@ -1366,8 +1419,10 @@ msgid "Edit %(obj)s"
msgstr
"Éditer %(obj)s"
#: core/templates/core/file.jinja:7 core/templates/core/file_list.jinja:6
#, fuzzy
#| msgid "Files"
msgid
"File list"
msgstr
"
Liste des f
ichiers"
msgstr
"
F
ichiers"
#: core/templates/core/file.jinja:9
msgid
"New file"
...
...
@@ -1575,8 +1630,10 @@ msgid "History"
msgstr
"Historique"
#: core/templates/core/page.jinja:45
#, fuzzy
#| msgid "Target does not exists"
msgid
"Page does not exist"
msgstr
"La
pag
e n'existe pas."
msgstr
"La
cibl
e n'existe pas."
#: core/templates/core/page.jinja:47
msgid
"Create it?"
...
...
@@ -1725,6 +1782,8 @@ msgid "Year"
msgstr
"Année"
#: core/templates/core/user_account.jinja:9
#, fuzzy
#| msgid "Month"
msgid
"Month"
msgstr
"Mois"
...
...
@@ -1784,8 +1843,10 @@ msgid "Club(s)"
msgstr
"Clubs"
#: core/templates/core/user_clubs.jinja:10
#, fuzzy
#| msgid "Current scrub: "
msgid
"Current club(s) :"
msgstr
"
Clubs
actuel
s
: "
msgstr
"
Blouse
actuel
le
: "
#: core/templates/core/user_clubs.jinja:36
msgid
"Old club(s) :"
...
...
@@ -2428,6 +2489,8 @@ msgid "Choose another month: "
msgstr
"Choisir un autre mois : "
#: counter/templates/counter/invoices_call.jinja:21
#, fuzzy
#| msgid "Sum"
msgid
"Sum"
msgstr
"Somme"
...
...
@@ -2804,7 +2867,7 @@ msgstr "Utilisateur qui sera conservé"
msgid
"User that will be deleted"
msgstr
"Utilisateur qui sera supprimé"
#: sas/models.py:9
7
#: sas/models.py:9
9
msgid
"picture"
msgstr
"photo"
...
...
@@ -3018,3 +3081,321 @@ msgstr "Un utilisateur avec cette adresse email existe déjà"
msgid
"You must either choose an existing user or create a new one properly"
msgstr
""
"Vous devez soit choisir un utilisateur existant, ou en créer un proprement."
#, fuzzy
#~| msgid "Nature"
#~ msgid "Nature bilan: "
#~ msgstr "Nature"
#, fuzzy
#~| msgid "linked operation"
#~ msgid "Nature of operation"
#~ msgstr "opération liée"
#, fuzzy
#~| msgid "location"
#~ msgid "Syndication"
#~ msgstr "lieu"
#, fuzzy
#~| msgid "second email address"
#~ msgid "Enter a valid value."
#~ msgstr "adresse email secondaire"
#, fuzzy
#~| msgid "second email address"
#~ msgid "Enter a valid URL."
#~ msgstr "adresse email secondaire"
#, fuzzy
#~| msgid "second email address"
#~ msgid "Enter a valid integer."
#~ msgstr "adresse email secondaire"
#, fuzzy
#~| msgid "second email address"
#~ msgid "Enter a valid email address."
#~ msgstr "adresse email secondaire"
#, fuzzy
#~| msgid ""
#~| "Enter a valid username. This value may contain only letters, numbers "
#~| "and ./+/-/_ characters."
#~ msgid ""
#~ "Enter a valid 'slug' consisting of letters, numbers, underscores or "
#~ "hyphens."
#~ msgstr ""
#~ "Entrez un nom d'utilisateur correct. Uniquement des lettres, numéros, "
#~ "et ./+/-/_"
#, fuzzy
#~| msgid "second email address"
#~ msgid "Enter a valid IPv4 address."
#~ msgstr "adresse email secondaire"
#, fuzzy
#~| msgid "second email address"
#~ msgid "Enter a valid IPv6 address."
#~ msgstr "adresse email secondaire"
#, fuzzy
#~| msgid "second email address"
#~ msgid "Enter a valid IPv4 or IPv6 address."
#~ msgstr "adresse email secondaire"
#, fuzzy
#~| msgid "A user with that email address already exists"
#~ msgid "%(model_name)s with this %(field_labels)s already exists."
#~ msgstr "Un utilisateur avec cette adresse email existe déjà"
#, fuzzy
#~| msgid "Token name can not be blank"
#~ msgid "This field cannot be null."
#~ msgstr "Le nom du jeton ne peut pas être vide"
#, fuzzy
#~| msgid "Token name can not be blank"
#~ msgid "This field cannot be blank."
#~ msgstr "Le nom du jeton ne peut pas être vide"
#, fuzzy
#~| msgid "A user with that email address already exists"
#~ msgid "%(model_name)s with this %(field_label)s already exists."
#~ msgstr "Un utilisateur avec cette adresse email existe déjà"
#, fuzzy
#~| msgid "number"
#~ msgid "Decimal number"
#~ msgstr "numéro"
#, fuzzy
#~| msgid "Description"
#~ msgid "Duration"
#~ msgstr "Description"
#, fuzzy
#~| msgid "email address"
#~ msgid "Email address"
#~ msgstr "adresse email"
#, fuzzy
#~| msgid "File list"
#~ msgid "File path"
#~ msgstr "Liste des fichiers"
#, fuzzy
#~| msgid "account number"
#~ msgid "Floating point number"
#~ msgstr "numero de compte"
#, fuzzy
#~| msgid "address"
#~ msgid "IPv4 address"
#~ msgstr "Adresse"
#, fuzzy
#~| msgid "address"
#~ msgid "IP address"
#~ msgstr "Adresse"
#, fuzzy
#~| msgid "A user with that email address already exists"
#~ msgid "%(model)s instance with %(field)s %(value)r does not exist."
#~ msgstr "Un utilisateur avec cette adresse email existe déjà"
#, fuzzy
#~| msgid "account number"
#~ msgid "Enter a whole number."
#~ msgstr "numero de compte"
#, fuzzy
#~| msgid "account number"
#~ msgid "Enter a number."
#~ msgstr "numero de compte"
#, fuzzy
#~| msgid "second email address"
#~ msgid "Enter a valid date."
#~ msgstr "adresse email secondaire"
#, fuzzy
#~| msgid "second email address"
#~ msgid "Enter a valid time."
#~ msgstr "adresse email secondaire"
#, fuzzy
#~| msgid "second email address"
#~ msgid "Enter a valid date/time."
#~ msgstr "adresse email secondaire"
#, fuzzy
#~| msgid "second email address"
#~ msgid "Enter a valid duration."
#~ msgstr "adresse email secondaire"
#, fuzzy
#~| msgid "second email address"
#~ msgid "Enter a list of values."
#~ msgstr "adresse email secondaire"
#, fuzzy
#~| msgid "second email address"
#~ msgid "Enter a valid UUID."
#~ msgstr "adresse email secondaire"
#, fuzzy
#~| msgid "Current club(s) :"
#~ msgid "Currently"
#~ msgstr "Clubs actuels : "
#, fuzzy
#~| msgid "Unknown event"
#~ msgid "Unknown"
#~ msgstr "Événement inconnu"
#, fuzzy
#~| msgid "M"
#~ msgid "PM"
#~ msgstr "M"
#, fuzzy
#~| msgid "M"
#~ msgid "AM"
#~ msgstr "M"
#, fuzzy
#~| msgid "Month"
#~ msgid "Mon"
#~ msgstr "Mois"
#, fuzzy
#~| msgid "Start"
#~ msgid "Sat"
#~ msgstr "Début"
#, fuzzy
#~| msgid "Search"
#~ msgid "March"
#~ msgstr "Recherche"
#, fuzzy
#~| msgid "Man"
#~ msgid "May"
#~ msgstr "Homme"
#, fuzzy
#~| msgid "past member"
#~ msgid "September"
#~ msgstr "Anciens membres"
#, fuzzy
#~| msgid "Members"
#~ msgid "November"
#~ msgstr "Membres"
#, fuzzy
#~| msgid "Members"
#~ msgid "December"
#~ msgstr "Membres"
#, fuzzy
#~| msgid "Man"
#~ msgid "jan"
#~ msgstr "Homme"
#, fuzzy
#~| msgid "Bar"
#~ msgid "mar"
#~ msgstr "Bar"
#, fuzzy
#~| msgid "Bar"
#~ msgid "apr"
#~ msgstr "Bar"
#, fuzzy
#~| msgid "company"