775 lines
25 KiB
Python
775 lines
25 KiB
Python
# coding=utf-8
|
|
|
|
from itertools import zip_longest
|
|
|
|
from reportlab.pdfgen import canvas
|
|
from reportlab.lib.pagesizes import A4
|
|
|
|
from django.http import HttpResponse
|
|
from django.shortcuts import render
|
|
from django.db.models import Q
|
|
|
|
from collections import OrderedDict
|
|
|
|
from .models import (
|
|
Transaction,
|
|
TransactionType,
|
|
EvaluationRules,
|
|
EvaluationRulesAdaptation,
|
|
Annuality,
|
|
ComplementaryInformations,
|
|
)
|
|
|
|
from .tools import (
|
|
get_transactions_and_sums_for_year_and_type,
|
|
get_transactiontypes_and_total_amount_transactions,
|
|
get_transactiontype_and_sum_for_spf_export,
|
|
get_right_engagement_and_sump_spf,
|
|
get_asset_liability_and_sump_spf,
|
|
)
|
|
|
|
from comptaClub.site_config import load
|
|
|
|
import locale
|
|
|
|
EXTENSES = 0
|
|
RECETTES = 1
|
|
|
|
|
|
def comptability_export(request, accounting_year, export_type):
|
|
"""
|
|
Définit une fonction d'export.
|
|
|
|
Args:
|
|
request: La requête HTTP
|
|
accounting_year (int): L'année à exporter.
|
|
export_type: à choisir parmi `sxs` (side by side) ou `ooo` (one over other).
|
|
|
|
Returns:
|
|
render_to_response sur la page HTML correspondante.
|
|
"""
|
|
if export_type == "sxs":
|
|
return get_transaction_list_for_accountingyear_sxs(request, accounting_year)
|
|
else:
|
|
return get_transaction_list_for_accountingyear_ooo(request, accounting_year)
|
|
|
|
|
|
def get_transaction_list_for_accountingyear_ooo(request, accounting_year):
|
|
"""
|
|
Affichage et calcul des `Recettes` et `Dépenses` pour une année donnée dans deux tableaux l'un
|
|
au dessus de l'autre (one over other - ooo).
|
|
"""
|
|
transactions_list_expenses = get_transactions_and_sums_for_year_and_type(
|
|
accounting_year, EXTENSES
|
|
)
|
|
transactions_list_recettes = get_transactions_and_sums_for_year_and_type(
|
|
accounting_year, RECETTES
|
|
)
|
|
context = {
|
|
"transactions_list_expenses": transactions_list_expenses,
|
|
"accounting_year": accounting_year,
|
|
"transactions_list_recettes": transactions_list_recettes,
|
|
}
|
|
|
|
return render(request, "year_transaction_export_ooo.html", context)
|
|
|
|
|
|
# def two_table_side_by_side_export(request, accounting_year):
|
|
def get_transaction_list_for_accountingyear_sxs(request, accounting_year):
|
|
"""
|
|
Calcule et affiche la comptabilité d'une année passée en parametre dans un unique tableau (side
|
|
by side).
|
|
"""
|
|
expenses_transactiontypes_list = get_transactiontypes_and_total_amount_transactions(
|
|
accounting_year, EXTENSES
|
|
)
|
|
recettes_transactiontypes_list = get_transactiontypes_and_total_amount_transactions(
|
|
accounting_year, RECETTES
|
|
)
|
|
|
|
transactiontypes_list = zip_longest(
|
|
recettes_transactiontypes_list["transactiontypes_info_list"],
|
|
expenses_transactiontypes_list["transactiontypes_info_list"],
|
|
)
|
|
|
|
context = {
|
|
"transactiontypes_list": transactiontypes_list,
|
|
"accounting_year": accounting_year,
|
|
"total_expenses": expenses_transactiontypes_list["total"],
|
|
"total_recettes": recettes_transactiontypes_list["total"],
|
|
}
|
|
return render(request, "year_transaction_export_sxs.html", context)
|
|
|
|
|
|
def export_year_spf_finance(request, accounting_year):
|
|
"""
|
|
Calcule et affiche la comptabilité d'une année passée en parametre dans un unique tableau (side
|
|
by side).
|
|
|
|
La fonction va chercher chaque type de dépenses/recettes père (n'ayant pas de parent).
|
|
Pour chacun de ces types, … <<< on fait quoi >>> ?
|
|
"""
|
|
annuality = Annuality.objects.filter(year__year=accounting_year)
|
|
|
|
transactiontypes_list_expenses = get_transactiontype_and_sum_for_spf_export(
|
|
accounting_year, EXTENSES
|
|
)
|
|
transactiontypes_list_recettes = get_transactiontype_and_sum_for_spf_export(
|
|
accounting_year, RECETTES
|
|
)
|
|
list_sum = [
|
|
x
|
|
for x in zip_longest(
|
|
transactiontypes_list_recettes["sum"], transactiontypes_list_expenses["sum"]
|
|
)
|
|
]
|
|
|
|
# règle 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)
|
|
|
|
rules_adaptation_list = EvaluationRulesAdaptation.objects.filter(
|
|
start_date__year=accounting_year
|
|
)
|
|
complementary_informations = ComplementaryInformations.objects.filter(
|
|
annuality=annuality[0]
|
|
)
|
|
|
|
liquidity = 0
|
|
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
|
|
+ transactiontypes_list_recettes["sum_total_transaction"]
|
|
- transactiontypes_list_expenses["sum_total_transaction"]
|
|
)
|
|
liquidity = item[1]
|
|
|
|
asset_liability_list = get_asset_liability_and_sump_spf(accounting_year, category=1)
|
|
asset_liability_sum = [x for x in zip_longest(assets_list, asset_liability_list)]
|
|
|
|
right_list = get_right_engagement_and_sump_spf(accounting_year, category=0)
|
|
engagement_list = get_right_engagement_and_sump_spf(accounting_year, category=1)
|
|
right_engagement_sum = [x for x in zip_longest(right_list, engagement_list)]
|
|
|
|
if len(right_engagement_sum) == 0:
|
|
right_engagement_sum = None
|
|
|
|
annuality[0].closing_balance = liquidity
|
|
annuality[0].save()
|
|
|
|
context = {
|
|
"list_sum": list_sum,
|
|
"accounting_year": accounting_year,
|
|
"total_expenses": transactiontypes_list_expenses["sum_total_transaction"],
|
|
"total_recette": transactiontypes_list_recettes["sum_total_transaction"],
|
|
"rules_list": rules_list,
|
|
"rules_adaptation_list": rules_adaptation_list,
|
|
"complementary_informations": complementary_informations,
|
|
"asset_liability_sum": asset_liability_sum,
|
|
"right_engagement_sum": right_engagement_sum,
|
|
}
|
|
|
|
return render(request, "year_transaction_export_spf.html", context)
|
|
|
|
|
|
X = 35
|
|
Y = 841.89
|
|
INDENT = 5
|
|
RIGHT_X = 595.27 - X
|
|
TITLED_X = 125
|
|
INDENTED_X = X + INDENT
|
|
INDENTED_RIGHT_X = RIGHT_X - INDENT
|
|
MIDDLE = (RIGHT_X - X) / 2
|
|
|
|
PRESTATION_COLUMN_2 = INDENTED_X + 65
|
|
PRESTATION_COLUMN_3 = INDENTED_X + 400
|
|
PRESTATION_COLUMN_4 = INDENTED_X + 455
|
|
|
|
COMMON_LINE_HEIGHT = -15
|
|
SMALL_LINE_HEIGHT = COMMON_LINE_HEIGHT + 5
|
|
LARGE_LINE_HEIGHT = COMMON_LINE_HEIGHT - 5
|
|
DOUBLE_LINE_HEIGHT = COMMON_LINE_HEIGHT * 2
|
|
BIG_LINE_HEIGHT = COMMON_LINE_HEIGHT * 3
|
|
HUGE_LINE_HEIGHT = COMMON_LINE_HEIGHT * 4
|
|
|
|
|
|
class MyDocument(object):
|
|
# http://www.reportlab.com/docs/reportlab-userguide.pdf
|
|
|
|
def __init__(self, response):
|
|
# Create the PDF object, using the response object as its "file."
|
|
self.document = canvas.Canvas(response, pagesize=A4)
|
|
self.y = Y - X
|
|
|
|
def newline(self, height=None):
|
|
"""
|
|
Passe à la ligne, la hauteur de la ligne est passée en paramètre.
|
|
"""
|
|
if height == SMALL_LINE_HEIGHT:
|
|
self.y += SMALL_LINE_HEIGHT
|
|
|
|
elif 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
|
|
|
|
# if y < 120;
|
|
# document.PageBreak()
|
|
# y = 790
|
|
|
|
def drawString(
|
|
self, x, string, font_family="Helvetica", font_decoration=None, font_size=10
|
|
):
|
|
font = font_family
|
|
if font_decoration is not None:
|
|
font += "-" + font_decoration
|
|
self.document.setFont(font, font_size)
|
|
self.document.drawString(x, self.y, string)
|
|
|
|
def drawNewLine(
|
|
self,
|
|
x,
|
|
string,
|
|
height=None,
|
|
font_family="Helvetica",
|
|
font_decoration=None,
|
|
font_size=10,
|
|
):
|
|
self.newline(height)
|
|
self.drawString(x, string, font_family, font_decoration, font_size)
|
|
|
|
def download(self):
|
|
# Close the PDF object cleanly, and we're done.
|
|
self.document.showPage()
|
|
self.document.save()
|
|
|
|
def header(self, info):
|
|
rect_height = 40
|
|
self.document.rect(X, self.y, RIGHT_X - X, -rect_height, fill=0)
|
|
self.drawNewLine(INDENTED_X, "A.S.B.L. : " + info["CLUB_NAME"])
|
|
self.document.drawRightString(
|
|
INDENTED_RIGHT_X, self.y, "N° Entreprise : " + info["BCE"]
|
|
)
|
|
self.drawNewLine(INDENTED_X, "Siège social : " + info["SIEGE_SOCIAL"])
|
|
self.newline(BIG_LINE_HEIGHT)
|
|
|
|
def title(self, accounting_year):
|
|
self.drawString(
|
|
130,
|
|
"Comptes simplifiés de l'exercice " + accounting_year,
|
|
font_decoration="Bold",
|
|
font_size=20,
|
|
)
|
|
self.newline(DOUBLE_LINE_HEIGHT)
|
|
|
|
def recette_depense(self, accounting_year):
|
|
self.drawString(
|
|
X, "Etat recettes/dépenses (en €)", font_decoration="Oblique", font_size=14
|
|
)
|
|
self.__display_table_transaction(accounting_year)
|
|
self.newline()
|
|
|
|
def __display_table_transaction(self, accounting_year):
|
|
self.__display_table_header("DEPENSES", "RECETTES")
|
|
|
|
transactions_extenses = get_transactiontype_and_sum_for_spf_export(
|
|
accounting_year, EXTENSES
|
|
)
|
|
transactions_recettes = get_transactiontype_and_sum_for_spf_export(
|
|
accounting_year, RECETTES
|
|
)
|
|
|
|
self.__display_table_transaction_body(
|
|
transactions_extenses, transactions_recettes
|
|
)
|
|
|
|
self.__display_table_footer(
|
|
int(transactions_extenses["sum_total_transaction"]),
|
|
int(transactions_recettes["sum_total_transaction"]),
|
|
)
|
|
|
|
def __display_table_header(self, title_left, title_right):
|
|
self.newline()
|
|
self.document.rect(X, self.y - 5, RIGHT_X - X, -COMMON_LINE_HEIGHT, fill=0)
|
|
self.drawString(INDENTED_X, title_left, font_decoration="Bold", font_size=9)
|
|
self.drawString(
|
|
MIDDLE + INDENTED_X, title_right, font_decoration="Bold", font_size=9
|
|
)
|
|
|
|
# TODO : à revoir !!!!!!
|
|
def __display_table_transaction_body(
|
|
self, transactions_extenses, transactions_recettes
|
|
):
|
|
|
|
for i in range(4):
|
|
self.__display_table_line(
|
|
transactions_extenses["sum"][i][0],
|
|
int(transactions_extenses["sum"][i][1]),
|
|
transactions_recettes["sum"][i][0],
|
|
int(transactions_recettes["sum"][i][1]),
|
|
)
|
|
self.newline()
|
|
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
|
|
|
|
def __display_table_footer(self, totaldepense, totalrecette):
|
|
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.newline()
|
|
|
|
# first column
|
|
self.drawString(
|
|
INDENTED_X, "Total des dépenses ", font_decoration="Bold", font_size=9
|
|
)
|
|
self.document.drawRightString(
|
|
MIDDLE + X - INDENT,
|
|
self.y,
|
|
str(locale.format("%d", int(totaldepense), grouping=True)),
|
|
)
|
|
|
|
# second column
|
|
self.drawString(
|
|
(MIDDLE + INDENTED_X),
|
|
"Total des recettes ",
|
|
font_decoration="Bold",
|
|
font_size=9,
|
|
)
|
|
self.document.drawRightString(
|
|
INDENTED_RIGHT_X,
|
|
self.y,
|
|
str(locale.format("%d", int(totalrecette), grouping=True)),
|
|
)
|
|
|
|
def __display_table_line(self, key1, value1, key2, value2):
|
|
locale.setlocale(locale.LC_ALL, "pt_br.utf-8")
|
|
self.newline()
|
|
self.document.rect(X, self.y - 5, RIGHT_X - X, 15, fill=0) # ligne entière
|
|
|
|
# first column
|
|
self.drawString(INDENTED_X, key1, font_size=9)
|
|
self.document.drawRightString(
|
|
MIDDLE + X - INDENT,
|
|
self.y,
|
|
str(locale.format("%d", int(value1), grouping=True)),
|
|
)
|
|
|
|
# second column
|
|
self.drawString((MIDDLE + INDENTED_X), key2, font_size=9)
|
|
self.document.drawRightString(
|
|
INDENTED_RIGHT_X,
|
|
self.y,
|
|
str(locale.format("%d", int(value2), grouping=True)),
|
|
)
|
|
|
|
def annexes(self, accounting_year):
|
|
""" Ajoute les annexes du document au PDF
|
|
|
|
Args:
|
|
accounting_year (int): année comptable
|
|
|
|
Returns:
|
|
Ne retourne rien
|
|
"""
|
|
self.drawNewLine(X, "Annexes", font_decoration="Oblique", font_size=14)
|
|
self.display_evaluation_rules(accounting_year)
|
|
self.display_modification_evaluation_rules(accounting_year)
|
|
self.display_additional_information(accounting_year)
|
|
self.display_patrimony(accounting_year)
|
|
self.display_right_engagement(accounting_year)
|
|
|
|
def display_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.drawNewLine(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.drawNewLine(
|
|
INDENTED_X + INDENT * 2,
|
|
rule.label + " : " + rule.explanation,
|
|
font_size=9,
|
|
)
|
|
else:
|
|
self.drawNewLine(
|
|
INDENTED_X + INDENT * 2, "Pas de règle d'évaluation.", font_size=9
|
|
)
|
|
self.newline()
|
|
|
|
def display_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.drawNewLine(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.drawNewLine(
|
|
INDENTED_X + INDENT * 2,
|
|
line.label + " : " + line.information,
|
|
font_size=9,
|
|
)
|
|
else:
|
|
self.drawNewLine(
|
|
INDENTED_X + INDENT * 2,
|
|
"Pas d'adaptation des règles d'évaluation.",
|
|
font_size=9,
|
|
)
|
|
self.newline()
|
|
|
|
def display_additional_information(self, accounting_year):
|
|
""" Ajoute les informations complémentaires au PDF
|
|
|
|
Args:
|
|
accounting_year (int): année comptable
|
|
|
|
Returns:
|
|
Ne retourne rien
|
|
"""
|
|
self.drawNewLine(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.drawNewLine(
|
|
INDENTED_X + INDENT * 2,
|
|
line.label + " : " + line.information,
|
|
font_size=9,
|
|
)
|
|
else:
|
|
self.drawNewLine(
|
|
INDENTED_X + INDENT * 2,
|
|
"Pas d'informations complémentaires.",
|
|
font_size=9,
|
|
)
|
|
self.newline()
|
|
|
|
def display_patrimony(self, accounting_year):
|
|
""" Ajoute les informations du patrimoine au PDF
|
|
|
|
Args:
|
|
accounting_year (int): année comptable
|
|
|
|
Returns:
|
|
Ne retourne rien
|
|
"""
|
|
self.drawNewLine(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(assets_list, 1)
|
|
longest_y = self.y
|
|
self.y = save
|
|
self.__display_table_two_column(liability_list, 2)
|
|
|
|
if self.y > longest_y:
|
|
self.y = longest_y
|
|
|
|
self.newline()
|
|
|
|
def __display_table_two_column(self, list, column=1):
|
|
if column == 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.drawNewLine(begin_text, line[0])
|
|
self.document.drawRightString(
|
|
begin_res, self.y, str(locale.format("%d", int(line[1]), grouping=True))
|
|
)
|
|
|
|
total += int(line[1])
|
|
|
|
return total
|
|
|
|
def display_right_engagement(self, accounting_year):
|
|
""" Ajoute les droits & engagements au PDF
|
|
|
|
Args:
|
|
accounting_year (int): année comptable
|
|
|
|
Returns:
|
|
Ne retourne rien
|
|
"""
|
|
self.drawNewLine(
|
|
X,
|
|
"5. Droits et engagements importants qui ne sont pas susceptibles d'être quantifiés",
|
|
)
|
|
# self.__display_table_header("DROITS", "ENGAGEMENT")
|
|
self.drawNewLine(
|
|
INDENTED_X + INDENT * 2, "Pas de droits ou d'engagements.", font_size=9
|
|
)
|
|
self.newline()
|
|
|
|
|
|
def generate_pdf_for_spf(request, accounting_year):
|
|
""" Génère un fichier PDF suivant les contraintes du SPF Finances
|
|
|
|
Args:
|
|
accounting_year (int): année
|
|
|
|
Returns:
|
|
???
|
|
"""
|
|
response = HttpResponse(content_type="application/pdf")
|
|
response["Content-Disposition"] = (
|
|
'attachment; filename="comptes_simplifies_annuels_' + accounting_year + '.pdf"'
|
|
)
|
|
document = MyDocument(response)
|
|
info = load(request)
|
|
|
|
document.header(info)
|
|
document.title(accounting_year)
|
|
document.recette_depense(accounting_year)
|
|
document.annexes(accounting_year)
|
|
document.download()
|
|
|
|
return response
|
|
|
|
|
|
def __get_transactions_for_accounting_year_and_kind(
|
|
accounting_year, transaction_kind=None
|
|
):
|
|
"""
|
|
"""
|
|
|
|
transactions_list = Transaction.objects.by_year(accounting_year)
|
|
|
|
if transaction_kind == "bank":
|
|
transaction_kind = "Banque"
|
|
transactions_list = transactions_list.filter(bkAmount__isnull=False).exclude(
|
|
bkAmount=0
|
|
)
|
|
|
|
elif transaction_kind == "box":
|
|
transaction_kind = "Caisse"
|
|
transactions_list = transactions_list.filter(bxAmount__isnull=False).exclude(
|
|
bxAmount=0
|
|
)
|
|
|
|
else:
|
|
transaction_kind = "Tous"
|
|
|
|
transactions_list = transactions_list.order_by("registrationDate")
|
|
|
|
return transactions_list, transaction_kind
|
|
|
|
|
|
def transaction_by_year_listing(request, accounting_year, transaction_kind=None):
|
|
""" Liste toutes les lignes de comptabilité pour une année recue en paramètre
|
|
|
|
Args:
|
|
accounting_year (int): année comptable
|
|
transaction_kind (string):
|
|
"""
|
|
|
|
(
|
|
transactions_list,
|
|
transaction_kind,
|
|
) = __get_transactions_for_accounting_year_and_kind(
|
|
accounting_year, transaction_kind
|
|
)
|
|
|
|
# pour mon dictionnaire date/total
|
|
previous_date = None
|
|
date_sum = OrderedDict()
|
|
|
|
tmp_Total = 0
|
|
tmp_Amount = 0
|
|
sum_extense = 0
|
|
sum_extense_simulated = 0
|
|
sumrecette = 0
|
|
sumrecette_simulated = 0
|
|
transaction_list_and_sum = []
|
|
|
|
for transaction in transactions_list:
|
|
|
|
# transaction type :
|
|
# 0 : dépense
|
|
# 1 : recette
|
|
# Suivant le type de la transaction, on ajoute son montant aux recettes ou au dépenses et
|
|
# on ajoute le signe ("+" ou "-") afin de pouvoir l'utiliser dans des calculs après.
|
|
tmp_Amount = transaction.totalAmount
|
|
if transaction.transaction_type.transaction_type == EXTENSES:
|
|
sum_extense_simulated += tmp_Amount
|
|
if transaction.is_simulated is not None and transaction.is_simulated == 0:
|
|
sum_extense += tmp_Amount
|
|
tmp_Amount = -tmp_Amount
|
|
else:
|
|
sumrecette_simulated += tmp_Amount
|
|
if transaction.is_simulated is not None and transaction.is_simulated == 0:
|
|
sumrecette += tmp_Amount
|
|
|
|
# Si la transaction n'est pas simulée on ajoute la transaction au total temporaire.
|
|
if (
|
|
transaction.is_simulated is not None and transaction.is_simulated == 0
|
|
) and (transaction.is_done is not None and transaction.is_done == 1):
|
|
tmp_Total += tmp_Amount
|
|
|
|
transaction_list_and_sum.append((transaction, tmp_Total))
|
|
|
|
if transaction.registrationDate.date() in date_sum:
|
|
date_sum[transaction.registrationDate.date()] += tmp_Amount
|
|
else:
|
|
if previous_date is not None:
|
|
date_sum[transaction.registrationDate.date()] = (
|
|
date_sum[previous_date] + tmp_Amount
|
|
)
|
|
else:
|
|
date_sum[transaction.registrationDate.date()] = tmp_Amount
|
|
|
|
previous_date = transaction.registrationDate.date()
|
|
|
|
total = sumrecette - sum_extense
|
|
total_simulated = sumrecette_simulated - sum_extense_simulated
|
|
|
|
nb_transaction = transactions_list.count()
|
|
context = {
|
|
"transaction_list": transaction_list_and_sum,
|
|
"accounting_year": accounting_year,
|
|
"totaldepense": sum_extense,
|
|
"totalrecette": sumrecette,
|
|
"totaldepense_simulated": sum_extense_simulated,
|
|
"totalrecette_simulated": sumrecette_simulated,
|
|
"total": total,
|
|
"total_simulated": total_simulated,
|
|
"date_sum": date_sum,
|
|
"nb_transaction": nb_transaction,
|
|
"t_type": transaction_kind,
|
|
}
|
|
return render(request, "year_transaction_listing.html", context)
|
|
|
|
|
|
def year_listing(request):
|
|
"""
|
|
Liste toutes les années pour lesquelles il y a des transactions.
|
|
"""
|
|
years = Transaction.objects.dates("registrationDate", "year")
|
|
|
|
year_list = []
|
|
for year in years:
|
|
year_list.append((year.year, Transaction.objects.by_year(year.year).count(),))
|
|
|
|
context = {"year_list": year_list}
|
|
return render(request, "year_listing.html", context)
|
|
|
|
|
|
def transaction_listing_for_year_and_type(
|
|
request, accounting_year, transaction_type_id
|
|
):
|
|
"""
|
|
Liste toutes les transactions d'un `type de transaction` et pour une année passés en paramètre.
|
|
|
|
Args:
|
|
request (???):
|
|
accounting_year (int): année
|
|
transaction_type_id (int): id d'un type de transaction
|
|
|
|
Returns:
|
|
(???)
|
|
"""
|
|
transaction_type = TransactionType.objects.get(pk=transaction_type_id)
|
|
# by_year_condition = Q(registrationDate__year=accounting_year)
|
|
by_type_condition = Q(transaction_type=transaction_type_id)
|
|
by_parent_type_condition = Q(transaction_type__parent=transaction_type_id)
|
|
|
|
transaction_list = (
|
|
Transaction.objects.by_year(accounting_year)
|
|
.filter((by_type_condition | by_parent_type_condition))
|
|
.order_by("registrationDate")
|
|
)
|
|
|
|
total = 0
|
|
total_simulated = 0
|
|
transaction_list_and_sum = []
|
|
for transaction in transaction_list:
|
|
total_simulated += transaction.totalAmount
|
|
if transaction.is_simulated is not None and transaction.is_simulated == 0:
|
|
total += transaction.totalAmount
|
|
|
|
transaction_list_and_sum.append((transaction, total))
|
|
|
|
context = {
|
|
"transaction_list": transaction_list_and_sum,
|
|
"transaction_type": str(transaction_type),
|
|
"accounting_year": accounting_year,
|
|
"total_simulated": total_simulated,
|
|
"total": total,
|
|
}
|
|
return render(request, "transaction_listing.html", context)
|
|
|
|
|
|
def transaction_details(request, transactionid):
|
|
"""
|
|
Récupère les détails d'une transaction
|
|
"""
|
|
transaction = Transaction.objects.get(pk=transactionid)
|
|
context = {"transaction": transaction}
|
|
return render(request, "year_transaction_details.html", context)
|