PDF generation refactoring.

This commit is contained in:
Trullemans Gregory 2020-03-03 20:53:01 +01:00
parent 4083c58207
commit d293464ff4
6 changed files with 419 additions and 372 deletions

3
.gitignore vendored
View File

@ -1,3 +1,6 @@
# IDE
.vscode/
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]

View File

@ -13,7 +13,7 @@ from .models import (
Prestation,
)
from tools.pdf_generator import PDFDocument
from tools.pdf_generator import BillPaper
def contract_listing(request):
@ -75,16 +75,8 @@ def contract_export(request, contract_id):
response["Content-Disposition"] = (
'attachment; filename="facture_' + str(contract.reference) + '.pdf"'
)
document = PDFDocument(response)
document.generate_bill_paper(contract)
# document.header(club_infos, contract)
# document.title(contract)
# document.payementInformation(club_infos, contract)
# document.prestations(contract)
# document.conclusion(club_infos, contract)
# document.addSignature(club_infos)
# document.footer()
document = BillPaper(response)
document.generate(contract)
document.download()
return response

View File

@ -38,7 +38,7 @@ class Annuality(models.Model):
verbose_name = "0. Annualité"
verbose_name_plural = "0. Annualités"
year = models.DateField(default=timezone.now(), verbose_name="Année comptabile")
year = models.DateField(default=timezone.now, verbose_name="Année comptabile")
opening_balance = models.DecimalField(
max_digits=9,
decimal_places=2,
@ -80,7 +80,7 @@ class Comptability(models.Model):
verbose_name_plural = "Comptabilités"
registrationDate = models.DateTimeField(
default=timezone.now(), verbose_name="Date d'enregistrement"
default=timezone.now, verbose_name="Date d'enregistrement"
)
totalAmount = models.DecimalField(
max_digits=9,

View File

@ -23,7 +23,10 @@ from .tools import (
get_asset_liability_and_sump_spf,
)
from tools.pdf_generator import PDFDocument
from tools.pdf_generator import (
SpfDocument,
BillPaper,
)
import locale
@ -190,8 +193,8 @@ def generate_pdf_for_spf(request, accounting_year):
response["Content-Disposition"] = (
'attachment; filename="comptes_simplifies_annuels_' + accounting_year + '.pdf"'
)
document = PDFDocument(response)
document.generate_spf_export(accounting_year)
document = SpfDocument(response)
document.generate(accounting_year)
document.download()
return response

View File

@ -88,6 +88,7 @@
</div>
</div>
{% if transaction_list %}
<script type="text/javascript">
$(document).ready(function() {
$('#comptaTable').tablesorter({
@ -187,5 +188,6 @@
});
});
</script>
{% endif %}
{% endblock %}

View File

@ -30,8 +30,9 @@ from comptabilite.tools import (
import os
import yaml
import re
EXTENSES = 0
EXPENSES = 0
RECETTES = 1
X = 35
@ -79,37 +80,17 @@ class PDFDocument(object):
except yaml.YAMLError as exc:
print(exc)
def generate_spf_export(self, accounting_year):
""" Genère un document aux normes du SPF Finance. """
self.add_header()
self.add_title_spf(accounting_year)
self.add_recette_expenses(accounting_year)
self.add_annexes(accounting_year)
def generate_bill_paper(self, contract):
""" Génère une facture pour un contrat """
self.amount = 0
self.add_header(contract)
self.add_title_billing(contract)
self.add_prestations(contract)
self.add_conclusion(contract)
self.add_signature()
self.add_footer()
def add_vspace(self, height=None):
def add_vspace(self, height=COMMON_LINE_HEIGHT):
""" Passe à la ligne, la hauteur de la ligne étant passée en paramètre.
Args:
height (int): hauteur de la ligne
height (int): hauteur de la ligne.
Returns:
ne retourne rien.
"""
if height == DOUBLE_LINE_HEIGHT:
self.y += DOUBLE_LINE_HEIGHT
elif height == BIG_LINE_HEIGHT:
self.y += BIG_LINE_HEIGHT
elif height == HUGE_LINE_HEIGHT:
self.y += HUGE_LINE_HEIGHT
else:
self.y += COMMON_LINE_HEIGHT
self.y += height
# if y < 120;
# document.PageBreak()
@ -118,7 +99,7 @@ class PDFDocument(object):
def add_string(
self, x, string, font_family="Helvetica", font_decoration=None, font_size=10
):
if font_decoration is not None:
if font_decoration:
font_family += "-" + font_decoration
self.document.setFont(font_family, font_size)
self.document.drawString(x, self.y, string)
@ -127,7 +108,7 @@ class PDFDocument(object):
self,
x,
string,
height=None,
height=COMMON_LINE_HEIGHT,
font_family="Helvetica",
font_decoration=None,
font_size=10,
@ -140,6 +121,9 @@ class PDFDocument(object):
Args:
contract (contract): instance de la class Contract.
Returns:
ne retourne rien.
"""
rect_height = 40
self.document.rect(X, self.y, RIGHT_X - X, -rect_height, fill=0)
@ -162,18 +146,380 @@ class PDFDocument(object):
)
self.add_vspace(BIG_LINE_HEIGHT)
def add_title_billing(self, contract):
def download(self):
# Close the PDF object cleanly, and we're done.
self.document.showPage()
self.document.save()
class SpfDocument(PDFDocument):
def generate(self, accounting_year):
""" Genère un document aux normes du SPF Finance.
Args:
accounting_year (int): année comptable.
Returns:
ne retourne rien.
"""
self.add_header()
self.add_title(accounting_year)
self.add_recette_expenses(accounting_year)
self.add_annexes(accounting_year)
def add_title(self, accounting_year):
""" Ajoute un titre au document.
Args:
accounting_year (int): année comptable.
Returns:
ne retourne rien.
"""
self.add_string(
130,
"Comptes simplifiés de l'exercice " + accounting_year,
font_decoration="Bold",
font_size=20,
)
self.add_vspace(DOUBLE_LINE_HEIGHT)
def add_recette_expenses(self, accounting_year):
""" Ajoute l'état des recettes et dépense pour une année comptable passée en paramètre.
Args:
accounting_year (int): année comptable.
Returns:
ne retourne rien.
"""
self.add_string(
X, "Etat recettes/dépenses (en €)", font_decoration="Oblique", font_size=14
)
self.__display_transactiontypes_table(accounting_year)
self.add_vspace()
def add_annexes(self, accounting_year):
""" Ajoute les annexes au document PDF
Args:
accounting_year (int): année comptable.
Returns:
ne retourne rien.
"""
self.add_new_line(X, "Annexes", font_decoration="Oblique", font_size=14)
self.add_evaluation_rules(accounting_year)
self.add_modification_evaluation_rules(accounting_year)
self.add_additional_information(accounting_year)
self.add_patrimony(accounting_year)
self.add_right_engagement(accounting_year)
def add_evaluation_rules(self, accounting_year):
""" Ajoute les règles d'évaluation au PDF
Args:
accounting_year (int): année comptable.
Returns:
ne retourne rien.
"""
self.add_new_line(X, "1. Résumé des règles d'évaluation")
rules_list = EvaluationRules.objects.filter(
Q(stop_date__year__lte=accounting_year) | Q(stop_date__isnull=True)
).exclude(start_date__year__gt=accounting_year)
if rules_list:
for rule in rules_list:
self.add_new_line(
INDENTED_X + INDENT * 2,
rule.label + " : " + rule.explanation,
font_size=9,
)
else:
self.add_new_line(
INDENTED_X + INDENT * 2, "Pas de règle d'évaluation.", font_size=9
)
self.add_vspace()
def add_modification_evaluation_rules(self, accounting_year):
""" Ajoute les modifications d'évaluation au PDF
Args:
accounting_year (int): année comptable.
Returns:
ne retourne rien.
"""
self.add_new_line(X, "2. Adaptation des règles d'évaluation")
rules_adaptation_list = EvaluationRulesAdaptation.objects.filter(
start_date__year=accounting_year
)
if rules_adaptation_list:
for line in rules_adaptation_list:
self.add_new_line(
INDENTED_X + INDENT * 2,
line.label + " : " + line.information,
font_size=9,
)
else:
self.add_new_line(
INDENTED_X + INDENT * 2,
"Pas d'adaptation des règles d'évaluation.",
font_size=9,
)
self.add_vspace()
def add_additional_information(self, accounting_year):
""" Ajoute les informations complémentaires au PDF
Args:
accounting_year (int): année comptable.
Returns:
ne retourne rien.
"""
self.add_new_line(X, "3. Informations complémentaires")
annuality = Annuality.objects.filter(year__year=accounting_year)
complementary_informations = ComplementaryInformations.objects.filter(
annuality=annuality[0]
)
if complementary_informations:
for line in complementary_informations:
self.add_new_line(
INDENTED_X + INDENT * 2,
line.label + " : " + line.information,
font_size=9,
)
else:
self.add_new_line(
INDENTED_X + INDENT * 2,
"Pas d'informations complémentaires.",
font_size=9,
)
self.add_vspace()
def add_patrimony(self, accounting_year):
""" Ajoute les informations du patrimoine au PDF
Args:
accounting_year (int): année comptable.
Returns:
ne retourne rien.
"""
self.add_new_line(X, "4. Etat du patrimoine")
annuality = Annuality.objects.filter(year__year=accounting_year)
tmp_compta_expenses = get_transactiontype_and_sum_for_spf_export(
accounting_year, EXPENSES
)
tmp_compta_recettes = get_transactiontype_and_sum_for_spf_export(
accounting_year, RECETTES
)
assets_list = get_asset_liability_and_sump_spf(accounting_year, category=0)
for item in assets_list:
if item[0] == "Liquidité":
item[1] += (
annuality[0].opening_balance
+ tmp_compta_recettes["sum_total_transaction"]
- tmp_compta_expenses["sum_total_transaction"]
)
liability_list = get_asset_liability_and_sump_spf(accounting_year, category=1)
self.__display_table_header("AVOIRS", "DETTES")
save = self.y
self.__display_table_two_column(1, assets_list)
longest_y = self.y
self.y = save
self.__display_table_two_column(2, liability_list)
if self.y > longest_y:
self.y = longest_y
self.add_vspace()
def add_right_engagement(self, accounting_year):
""" Ajoute les droits & engagements au PDF
Args:
accounting_year (int): année comptable.
Returns:
ne retourne rien
"""
self.add_new_line(
X,
"5. Droits et engagements importants qui ne sont pas susceptibles d'être quantifiés",
)
# self.__display_table_header("DROITS", "ENGAGEMENT")
self.add_new_line(
INDENTED_X + INDENT * 2, "Pas de droits ou d'engagements.", font_size=9
)
self.add_vspace()
def __display_transactiontypes_table(self, accounting_year):
""" Ajoute le table pour les recettes & dépenses d'une année comptable.
Args:
accounting_year (int): année comptable
Returns:
ne retourne rien.
"""
expenses = get_transactiontype_and_sum_for_spf_export(accounting_year, EXPENSES)
recettes = get_transactiontype_and_sum_for_spf_export(accounting_year, RECETTES)
self.__display_table_header("DEPENSES", "RECETTES")
self.__display_transactiontype_table_body(
expenses,
recettes,
int(expenses["sum_total_transaction"]),
int(recettes["sum_total_transaction"]),
)
def __display_table_header(self, title_left, title_right):
self.add_vspace()
self.document.rect(X, self.y - 5, RIGHT_X - X, -COMMON_LINE_HEIGHT, fill=0)
self.add_string(INDENTED_X, title_left, font_decoration="Bold", font_size=9)
self.add_string(
MIDDLE + INDENTED_X, title_right, font_decoration="Bold", font_size=9
)
def __display_transactiontype_table_body(
self, expenses, recettes, totalexpenses, totalrecettes
):
for i in range(4):
self.__display_table_line(
expenses["transaction_type_info"][i]["label"],
int(expenses["transaction_type_info"][i]["sum_total_amount"]),
recettes["transaction_type_info"][i]["label"],
int(recettes["transaction_type_info"][i]["sum_total_amount"]),
)
self.add_vspace()
self.document.rect(
X, self.y - 5, MIDDLE, 5 * -COMMON_LINE_HEIGHT
) # Séparation en deux
self.document.rect(
MIDDLE, self.y - 5, MIDDLE, 5 * -COMMON_LINE_HEIGHT
) # Séparation descriptif et montant recettes
self.y -= COMMON_LINE_HEIGHT
self.__display_table_line(
"Total des dépenses",
totalexpenses,
"Total des recettes",
totalrecettes,
font_decoration="Bold",
)
def __display_key_part(self, column_number, key, font_decoration=None):
""" Ajoute dans la colonne d'un tableau (à deux colonnes) la clef d'un couple clef/valeur.
Args:
column_number (int): numéro de la colonne du tableau
key (str): la clef à afficher
font_decoration (str): décoration de la police de carectères
Returns:
ne retourne rien.
"""
if column_number == 1:
space = INDENTED_X
else:
space = MIDDLE + INDENTED_X
self.add_string(space, key, font_decoration=font_decoration, font_size=9)
def __display_value_part(self, column_number, value):
""" Ajoute dans la colonne d'un tableau (à deux colonnes) la valeur d'un couple clef/valeur
Args:
column_number (int): numéro de la colonne du tableau
value (str): la valeur à afficher
Returns:
ne retourne rien.
"""
if column_number == 1:
space = MIDDLE + X - INDENT
else:
space = INDENTED_RIGHT_X
self.document.drawRightString(
space, self.y, str(locale.format("%d", int(value), grouping=True)),
)
def __display_column(self, column_number, key, value, font_decoration):
self.__display_key_part(column_number, key, font_decoration)
self.__display_value_part(column_number, value)
def __display_table_line(self, key1, value1, key2, value2, font_decoration=None):
self.document.rect(X, self.y - 5, RIGHT_X - X, COMMON_LINE_HEIGHT, fill=0)
self.add_vspace()
self.__display_column(1, key1, value1, font_decoration)
self.__display_column(2, key2, value2, font_decoration)
def __display_table_two_column(self, column_number, list):
if column_number == 1:
begin_rect_line = X
begin_rect_res = MIDDLE
begin_text = INDENTED_X
begin_res = MIDDLE + X - INDENT
else:
begin_rect_line = MIDDLE + X
begin_rect_res = MIDDLE * 2
begin_text = MIDDLE + INDENTED_X
begin_res = INDENTED_RIGHT_X
total = 0
locale.setlocale(locale.LC_ALL, "pt_br.utf-8")
for line in list:
self.document.rect(
begin_rect_line, self.y - 5, MIDDLE, COMMON_LINE_HEIGHT, fill=0
)
self.document.rect(
begin_rect_res, self.y - 5, X, COMMON_LINE_HEIGHT, fill=0
)
self.add_new_line(begin_text, line[0], font_size=9)
self.document.drawRightString(
begin_res, self.y, str(locale.format("%d", int(line[1]), grouping=True))
)
total += int(line[1])
return total
class BillPaper(PDFDocument):
def generate(self, contract):
""" Génère une facture pour un contrat
Args:
contract (contract): instance de la class Contract.
Returns:
ne retourne rien
"""
self.amount = 0
self.add_header(contract)
self.add_title(contract)
self.add_prestations(contract)
self.add_conclusion(contract)
self.add_signature()
self.add_footer()
def add_title(self, contract):
""" Génère le "titre" de la facture.
Args:
contract (contract): instance de la class Contract.
Returns:
ne retourne rien
"""
res = contract.client.contact.count("i")
res += contract.client.contact.count("t")
res += contract.client.contact.count("l")
res += contract.client.contact.count("j")
res += contract.client.contact.count("f")
# res += contract.client.contact.count('r')
res = len(re.findall(r'[fijlt]', contract.client.contact))
print(res)
self.add_string(TITLED_X, "A l'attention de")
self.add_string(194.25, contract.client.contact, font_decoration="Bold")
@ -193,25 +539,14 @@ class PDFDocument(object):
self.add_string(200, contract.name, font_decoration="Bold")
self.add_vspace()
def add_title_spf(self, accounting_year):
""" Ajoute un titre au document.
Args:
accounting_year (int): année comptable.
"""
self.add_string(
130,
"Comptes simplifiés de l'exercice " + accounting_year,
font_decoration="Bold",
font_size=20,
)
self.add_vspace(DOUBLE_LINE_HEIGHT)
def add_payement_informations(self, contract):
""" Génère les informations de payement.
Args:
contract (contract): instance de la class Contract.
Returns:
ne retourne rien
"""
self.add_vspace()
height = 40
@ -243,6 +578,9 @@ class PDFDocument(object):
Args:
contract (contract): instance de la class Contract.
Returns:
ne retourne rien.
"""
self.add_new_line(X, "Prestations", font_decoration="Bold")
total = self.draw_prestations_table(contract.get_prestation.all())
@ -256,7 +594,7 @@ class PDFDocument(object):
self.amount = total - contract.advance
self.document.drawRightString(INDENTED_RIGHT_X, self.y, str(self.amount))
def draw_colored_row(self, c=0.43, m=0.2, y=0, k=0):
def draw_colored_row(self, c=1, m=0, y=0, k=0.1):
""" Génère une ligne colorée. """
self.document.setFillColorCMYK(c, y, m, k)
self.document.rect(
@ -282,6 +620,9 @@ class PDFDocument(object):
Args:
total (int): somme totale des prestations.
Returns:
ne retourne rien.
"""
self.draw_colored_row()
self.add_vspace()
@ -315,7 +656,10 @@ class PDFDocument(object):
""" Génère le tableau des prestations.
Args:
prestations_list (list): liste des prestations d'un contrat
prestations_list (list): liste des prestations d'un contrat.
Returns:
ne retourne rien.
"""
self.draw_prestations_table_header()
total = 0
@ -329,6 +673,9 @@ class PDFDocument(object):
Args:
contract (contract): instance de la class Contract.
Returns:
ne retourne rien.
"""
self.add_vspace(DOUBLE_LINE_HEIGHT)
self.document.rect(X, self.y, RIGHT_X - X, BIG_LINE_HEIGHT, fill=0)
@ -387,314 +734,14 @@ class PDFDocument(object):
self.add_new_line(INDENTED_X, "Facture payable au comptant.")
self.add_new_line(
INDENTED_X,
"""En cas de défaut de paiement à l'échéance, il est dû de plein droit et sans mise en demeure, un interêt fixé au taux de""",
"""En cas de défaut de paiement à l'échéance, il est dû de plein droit et sans mise en demeure, un interêt fixé au taux de""", # NOQA
)
self.add_new_line(INDENTED_X, "15% l'an.")
self.add_new_line(
INDENTED_X,
"""Tout réclamation, pour être admise, doit être faite dans les huit jours de la réception de la facture.""",
"""Tout réclamation, pour être admise, doit être faite dans les huit jours de la réception de la facture.""", # NOQA
)
self.add_new_line(
INDENTED_X,
"""En cas de litige concernant la présente facture, seuls les tribunaux de MONS seront compétents.""",
"""En cas de litige concernant la présente facture, seuls les tribunaux de MONS seront compétents.""", # NOQA
)
def add_recette_expenses(self, accounting_year):
""" Ajoute l'état des recettes et dépense pour une année comptable passée en paramètre.
Args:
accounting_year (int): année comptable
"""
self.add_string(
X, "Etat recettes/dépenses (en €)", font_decoration="Oblique", font_size=14
)
self.__display_transactiontypes_table(accounting_year)
self.add_vspace()
def __display_transactiontypes_table(self, accounting_year):
""" Ajoute le table pour les recettes & dépenses d'une année comptable.
Args:
accounting_year (int): année comptable
"""
extenses = get_transactiontype_and_sum_for_spf_export(accounting_year, EXTENSES)
recettes = get_transactiontype_and_sum_for_spf_export(accounting_year, RECETTES)
self.__display_table_header("DEPENSES", "RECETTES")
self.__display_transactiontype_table_body(
extenses,
recettes,
int(extenses["sum_total_transaction"]),
int(recettes["sum_total_transaction"]),
)
def __display_table_header(self, title_left, title_right):
self.add_vspace()
self.document.rect(X, self.y - 5, RIGHT_X - X, -COMMON_LINE_HEIGHT, fill=0)
self.add_string(INDENTED_X, title_left, font_decoration="Bold", font_size=9)
self.add_string(
MIDDLE + INDENTED_X, title_right, font_decoration="Bold", font_size=9
)
def __display_transactiontype_table_body(
self, extenses, recettes, totalexpenses, totalrecettes
):
for i in range(4):
self.__display_table_line(
extenses["transaction_type_info"][i]["label"],
int(extenses["transaction_type_info"][i]["sum_total_amount"]),
recettes["transaction_type_info"][i]["label"],
int(recettes["transaction_type_info"][i]["sum_total_amount"]),
)
self.add_vspace()
self.document.rect(
X, self.y - 5, MIDDLE, 5 * -COMMON_LINE_HEIGHT
) # Séparation en deux
self.document.rect(
MIDDLE, self.y - 5, MIDDLE, 5 * -COMMON_LINE_HEIGHT
) # Séparation descriptif et montant recettes
self.y -= COMMON_LINE_HEIGHT
self.__display_table_line(
"Total des dépenses",
totalexpenses,
"Total des recettes",
totalrecettes,
font_decoration="Bold",
)
def __display_key_part(self, column_number, key, font_decoration=None):
""" Ajoute dans la colonne d'un tableau (à deux colonnes) la clef d'un couple clef/valeur.
Args:
column_number (int): numéro de la colonne du tableau
key (str): la clef à afficher
font_decoration (str): décoration de la police de carectères
"""
if column_number == 1:
space = INDENTED_X
else:
space = MIDDLE + INDENTED_X
self.add_string(space, key, font_decoration=font_decoration, font_size=9)
def __display_value_part(self, column_number, value):
""" Ajoute dans la colonne d'un tableau (à deux colonnes) la valeur d'un couple clef/valeur
Args:
column_number (int): numéro de la colonne du tableau
value (str): la valeur à afficher
"""
if column_number == 1:
space = MIDDLE + X - INDENT
else:
space = INDENTED_RIGHT_X
self.document.drawRightString(
space, self.y, str(locale.format("%d", int(value), grouping=True)),
)
def __display_column(self, column_number, key, value, font_decoration):
self.__display_key_part(column_number, key, font_decoration)
self.__display_value_part(column_number, value)
def __display_table_line(self, key1, value1, key2, value2, font_decoration=None):
locale.setlocale(locale.LC_ALL, "pt_br.utf-8")
self.document.rect(X, self.y - 5, RIGHT_X - X, COMMON_LINE_HEIGHT, fill=0)
self.add_vspace()
self.__display_column(1, key1, value1, font_decoration)
self.__display_column(2, key2, value2, font_decoration)
def add_annexes(self, accounting_year):
""" Ajoute les annexes au document PDF
Args:
accounting_year (int): année comptable
Returns:
Ne retourne rien
"""
self.add_new_line(X, "Annexes", font_decoration="Oblique", font_size=14)
self.add_evaluation_rules(accounting_year)
self.add_modification_evaluation_rules(accounting_year)
self.add_additional_information(accounting_year)
self.add_patrimony(accounting_year)
self.add_right_engagement(accounting_year)
def add_evaluation_rules(self, accounting_year):
""" Ajoute les règles d'évaluation au PDF
Args:
accounting_year (int): année comptable
Returns:
Ne retourne rien
"""
self.add_new_line(X, "1. Résumé des règles d'évaluation")
rules_list = EvaluationRules.objects.filter(
Q(stop_date__year__lte=accounting_year) | Q(stop_date__isnull=True)
).exclude(start_date__year__gt=accounting_year)
if rules_list:
for rule in rules_list:
self.add_new_line(
INDENTED_X + INDENT * 2,
rule.label + " : " + rule.explanation,
font_size=9,
)
else:
self.add_new_line(
INDENTED_X + INDENT * 2, "Pas de règle d'évaluation.", font_size=9
)
self.add_vspace()
def add_modification_evaluation_rules(self, accounting_year):
""" Ajoute les modifications d'évaluation au PDF
Args:
accounting_year (int): année comptable
Returns:
Ne retourne rien
"""
self.add_new_line(X, "2. Adaptation des règles d'évaluation")
rules_adaptation_list = EvaluationRulesAdaptation.objects.filter(
start_date__year=accounting_year
)
if rules_adaptation_list:
for line in rules_adaptation_list:
self.add_new_line(
INDENTED_X + INDENT * 2,
line.label + " : " + line.information,
font_size=9,
)
else:
self.add_new_line(
INDENTED_X + INDENT * 2,
"Pas d'adaptation des règles d'évaluation.",
font_size=9,
)
self.add_vspace()
def add_additional_information(self, accounting_year):
""" Ajoute les informations complémentaires au PDF
Args:
accounting_year (int): année comptable
Returns:
Ne retourne rien
"""
self.add_new_line(X, "3. Informations complémentaires")
annuality = Annuality.objects.filter(year__year=accounting_year)
complementary_informations = ComplementaryInformations.objects.filter(
annuality=annuality[0]
)
if complementary_informations:
for line in complementary_informations:
self.add_new_line(
INDENTED_X + INDENT * 2,
line.label + " : " + line.information,
font_size=9,
)
else:
self.add_new_line(
INDENTED_X + INDENT * 2,
"Pas d'informations complémentaires.",
font_size=9,
)
self.add_vspace()
def add_patrimony(self, accounting_year):
""" Ajoute les informations du patrimoine au PDF
Args:
accounting_year (int): année comptable
Returns:
Ne retourne rien
"""
self.add_new_line(X, "4. Etat du patrimoine")
annuality = Annuality.objects.filter(year__year=accounting_year)
tmp_compta_extenses = get_transactiontype_and_sum_for_spf_export(
accounting_year, EXTENSES
)
tmp_compta_recettes = get_transactiontype_and_sum_for_spf_export(
accounting_year, RECETTES
)
assets_list = get_asset_liability_and_sump_spf(accounting_year, category=0)
for item in assets_list:
if item[0] == "Liquidité":
item[1] += (
annuality[0].opening_balance
+ tmp_compta_recettes["sum_total_transaction"]
- tmp_compta_extenses["sum_total_transaction"]
)
liability_list = get_asset_liability_and_sump_spf(accounting_year, category=1)
self.__display_table_header("AVOIRS", "DETTES")
save = self.y
self.__display_table_two_column(1, assets_list)
longest_y = self.y
self.y = save
self.__display_table_two_column(2, liability_list)
if self.y > longest_y:
self.y = longest_y
self.add_vspace()
def __display_table_two_column(self, column_number, list):
if column_number == 1:
begin_rect_line = X
begin_rect_res = MIDDLE
begin_text = INDENTED_X
begin_res = MIDDLE + X - INDENT
else:
begin_rect_line = MIDDLE + X
begin_rect_res = MIDDLE * 2
begin_text = MIDDLE + INDENTED_X
begin_res = INDENTED_RIGHT_X
total = 0
locale.setlocale(locale.LC_ALL, "pt_br.utf-8")
for line in list:
self.document.rect(
begin_rect_line, self.y - 5, MIDDLE, COMMON_LINE_HEIGHT, fill=0
)
self.document.rect(
begin_rect_res, self.y - 5, X, COMMON_LINE_HEIGHT, fill=0
)
self.add_new_line(begin_text, line[0], font_size=9)
self.document.drawRightString(
begin_res, self.y, str(locale.format("%d", int(line[1]), grouping=True))
)
total += int(line[1])
return total
def add_right_engagement(self, accounting_year):
""" Ajoute les droits & engagements au PDF
Args:
accounting_year (int): année comptable
Returns:
Ne retourne rien
"""
self.add_new_line(
X,
"5. Droits et engagements importants qui ne sont pas susceptibles d'être quantifiés",
)
# self.__display_table_header("DROITS", "ENGAGEMENT")
self.add_new_line(
INDENTED_X + INDENT * 2, "Pas de droits ou d'engagements.", font_size=9
)
self.add_vspace()
def download(self):
# Close the PDF object cleanly, and we're done.
self.document.showPage()
self.document.save()