ComptaClub/comptabilite/views.py

434 lines
14 KiB
Python
Raw Normal View History

2020-02-17 21:38:47 +01:00
from itertools import zip_longest
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, get_object_or_404
2020-02-17 21:38:47 +01:00
from django.db.models import Q
from django.urls import reverse
2020-02-17 21:38:47 +01:00
from collections import OrderedDict
from django.views.decorators.http import require_http_methods
2022-05-06 14:49:54 +02:00
from django.contrib.auth.decorators import login_required
2020-02-17 21:38:47 +01:00
from .models import (
Transaction,
TransactionType,
EvaluationRules,
EvaluationRulesAdaptation,
Annuality,
ComplementaryInformations,
)
from .forms import TransactionForm
2020-02-21 21:47:09 +01:00
from .tools import (
2020-02-21 08:50:12 +01:00
get_transactions_and_sums_for_year_and_type,
get_transactiontypes_and_total_amount_transactions,
get_transactiontype_and_sum_for_spf_export,
2020-02-17 21:38:47 +01:00
get_right_engagement_and_sump_spf,
get_asset_liability_and_sump_spf,
)
2020-03-03 20:53:01 +01:00
from tools.pdf_generator import (
SpfDocument,
BillPaper,
)
2020-02-26 15:18:19 +01:00
2020-02-17 21:38:47 +01:00
import locale
2020-02-21 21:47:09 +01:00
EXTENSES = 0
RECETTES = 1
2020-02-17 21:38:47 +01:00
2020-02-22 11:08:26 +01:00
2022-05-06 14:49:54 +02:00
@login_required
@require_http_methods(["GET"])
2020-02-21 08:50:12 +01:00
def comptability_export(request, accounting_year, export_type):
2020-02-18 22:38:02 +01:00
"""
Définit une fonction d'export.
2020-02-17 21:38:47 +01:00
Args:
request: La requête HTTP
2020-02-21 21:47:09 +01:00
accounting_year (int): L'année à exporter.
2020-02-25 21:50:56 +01:00
export_type (string): à choisir parmi `sxs` (side by side) ou `ooo` (one over other).
2020-02-17 21:38:47 +01:00
Returns:
render_to_response sur la page HTML correspondante.
"""
if export_type == "sxs":
2020-02-21 21:47:09 +01:00
return get_transaction_list_for_accountingyear_sxs(request, accounting_year)
2020-02-17 21:38:47 +01:00
else:
2020-02-21 21:47:09 +01:00
return get_transaction_list_for_accountingyear_ooo(request, accounting_year)
2020-02-17 21:38:47 +01:00
2022-05-06 14:49:54 +02:00
@login_required
@require_http_methods(["GET"])
2020-02-21 21:47:09 +01:00
def get_transaction_list_for_accountingyear_ooo(request, accounting_year):
2020-02-17 21:38:47 +01:00
"""
2020-02-22 11:08:26 +01:00
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).
2020-02-25 21:50:56 +01:00
Args:
accounting_year (int): année comptable
2020-02-17 21:38:47 +01:00
"""
2020-02-22 11:08:26 +01:00
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
)
2020-02-17 21:38:47 +01:00
context = {
2020-02-21 21:47:09 +01:00
"transactions_list_expenses": transactions_list_expenses,
2020-02-21 08:50:12 +01:00
"accounting_year": accounting_year,
2020-02-21 21:47:09 +01:00
"transactions_list_recettes": transactions_list_recettes,
2020-02-17 21:38:47 +01:00
}
return render(request, "comptability/year_transaction_export_ooo.html", context)
2020-02-17 21:38:47 +01:00
2022-05-06 14:49:54 +02:00
@login_required
@require_http_methods(["GET"])
2020-02-21 21:47:09 +01:00
def get_transaction_list_for_accountingyear_sxs(request, accounting_year):
2020-02-17 21:38:47 +01:00
"""
Calcule et affiche la comptabilité d'une année passée en parametre dans un unique tableau (side
by side).
2020-02-25 21:50:56 +01:00
Args:
accounting_year (int): année comptable
2020-02-17 21:38:47 +01:00
"""
2020-02-22 11:08:26 +01:00
expenses_transactiontypes_list = get_transactiontypes_and_total_amount_transactions(
accounting_year, EXTENSES
)
recettes_transactiontypes_list = get_transactiontypes_and_total_amount_transactions(
accounting_year, RECETTES
)
2020-02-17 21:38:47 +01:00
2020-02-21 08:50:12 +01:00
transactiontypes_list = zip_longest(
recettes_transactiontypes_list["transactiontypes_info_list"],
2020-02-22 11:08:26 +01:00
expenses_transactiontypes_list["transactiontypes_info_list"],
2020-02-21 08:50:12 +01:00
)
2020-02-17 21:38:47 +01:00
context = {
2020-02-21 08:50:12 +01:00
"transactiontypes_list": transactiontypes_list,
"accounting_year": accounting_year,
"total_expenses": expenses_transactiontypes_list["total"],
"total_recettes": recettes_transactiontypes_list["total"],
2020-02-17 21:38:47 +01:00
}
return render(request, "comptability/year_transaction_export_sxs.html", context)
2020-02-17 21:38:47 +01:00
2022-05-06 14:49:54 +02:00
@login_required
@require_http_methods(["GET"])
2020-02-21 08:50:12 +01:00
def export_year_spf_finance(request, accounting_year):
2020-02-17 21:38:47 +01:00
"""
Calcule et affiche la comptabilité d'une année passée en parametre dans un unique tableau (side
by side).
2020-02-25 21:50:56 +01:00
Args:
accounting_year (int): année comptable
2020-02-17 21:38:47 +01:00
"""
2020-02-21 08:50:12 +01:00
annuality = Annuality.objects.filter(year__year=accounting_year)
2020-02-17 21:38:47 +01:00
2020-02-22 11:08:26 +01:00
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
)
transactiontypes_list = [
2020-02-21 08:50:12 +01:00
x
for x in zip_longest(
2020-02-25 21:50:56 +01:00
transactiontypes_list_recettes["transaction_type_info"],
transactiontypes_list_expenses["transaction_type_info"],
2020-02-21 08:50:12 +01:00
)
2020-02-17 21:38:47 +01:00
]
# règle d'évaluation
rules_list = EvaluationRules.objects.filter(
2020-02-21 08:50:12 +01:00
Q(stop_date__year__lte=accounting_year) | Q(stop_date__isnull=True)
).exclude(start_date__year__gt=accounting_year)
2020-02-17 21:38:47 +01:00
rules_adaptation_list = EvaluationRulesAdaptation.objects.filter(
2020-02-21 08:50:12 +01:00
start_date__year=accounting_year
2020-02-17 21:38:47 +01:00
)
complementary_informations = ComplementaryInformations.objects.filter(
annuality=annuality[0]
)
liquidity = 0
2020-02-21 08:50:12 +01:00
assets_list = get_asset_liability_and_sump_spf(accounting_year, category=0)
2020-02-17 21:38:47 +01:00
for item in assets_list:
if item[0] == "Liquidité":
item[1] += (
annuality[0].opening_balance
2020-02-21 08:50:12 +01:00
+ transactiontypes_list_recettes["sum_total_transaction"]
- transactiontypes_list_expenses["sum_total_transaction"]
2020-02-17 21:38:47 +01:00
)
liquidity = item[1]
2020-02-22 11:08:26 +01:00
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)]
2020-02-17 21:38:47 +01:00
2020-02-21 08:50:12 +01:00
right_list = get_right_engagement_and_sump_spf(accounting_year, category=0)
engagement_list = get_right_engagement_and_sump_spf(accounting_year, category=1)
2020-02-17 21:38:47 +01:00
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 = {
"transactiontypes_list": transactiontypes_list,
2020-02-21 08:50:12 +01:00
"accounting_year": accounting_year,
"total_expenses": transactiontypes_list_expenses["sum_total_transaction"],
"total_recette": transactiontypes_list_recettes["sum_total_transaction"],
2020-02-17 21:38:47 +01:00
"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, "comptability/year_transaction_export_spf.html", context)
2020-02-17 21:38:47 +01:00
2022-05-06 14:49:54 +02:00
@login_required
@require_http_methods(["GET"])
2020-02-21 08:50:12 +01:00
def generate_pdf_for_spf(request, accounting_year):
2020-02-21 21:47:09 +01:00
""" Génère un fichier PDF suivant les contraintes du SPF Finances
Args:
accounting_year (int): année
2020-02-22 11:08:26 +01:00
2020-02-21 21:47:09 +01:00
Returns:
???
2020-02-17 21:38:47 +01:00
"""
response = HttpResponse(content_type="application/pdf")
response["Content-Disposition"] = (
2022-05-26 07:20:57 +02:00
'attachment; filename="comptes_simplifies_annuels_' + str(accounting_year) + '.pdf"'
2020-02-17 21:38:47 +01:00
)
2020-03-03 20:53:01 +01:00
document = SpfDocument(response)
2022-05-26 07:20:57 +02:00
document.generate(str(accounting_year))
2020-02-17 21:38:47 +01:00
document.download()
return response
2020-02-22 11:08:26 +01:00
def __get_transactions_for_accounting_year_and_kind(
accounting_year, transaction_kind=None
):
2020-02-17 21:38:47 +01:00
"""
"""
2020-02-22 11:08:26 +01:00
transactions_list = Transaction.objects.by_year(accounting_year)
2020-02-21 21:47:09 +01:00
if transaction_kind == "bank":
transaction_kind = "Banque"
2020-02-22 11:08:26 +01:00
transactions_list = transactions_list.filter(bkAmount__isnull=False).exclude(
bkAmount=0
)
2020-02-21 21:47:09 +01:00
elif transaction_kind == "box":
transaction_kind = "Caisse"
2020-02-22 11:08:26 +01:00
transactions_list = transactions_list.filter(bxAmount__isnull=False).exclude(
bxAmount=0
)
2020-02-17 21:38:47 +01:00
else:
2020-02-21 21:47:09 +01:00
transaction_kind = "Tous"
transactions_list = transactions_list.order_by("registrationDate")
return transactions_list, transaction_kind
2022-05-06 14:49:54 +02:00
@login_required
@require_http_methods(["GET"])
2020-02-21 21:47:09 +01:00
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
2020-02-22 11:08:26 +01:00
transaction_kind (string):
2020-02-21 21:47:09 +01:00
"""
2020-02-22 11:08:26 +01:00
(
transactions_list,
transaction_kind,
) = __get_transactions_for_accounting_year_and_kind(
accounting_year, transaction_kind
)
2020-02-17 21:38:47 +01:00
# pour mon dictionnaire date/total
previous_date = None
date_sum = OrderedDict()
tmp_Total = 0
tmp_Amount = 0
2020-02-21 08:50:12 +01:00
sum_extense = 0
sum_extense_simulated = 0
2020-02-17 21:38:47 +01:00
sumrecette = 0
sumrecette_simulated = 0
transaction_list_and_sum = []
2020-02-21 21:47:09 +01:00
for transaction in transactions_list:
2020-02-17 21:38:47 +01:00
# 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
2020-02-21 21:47:09 +01:00
if transaction.transaction_type.transaction_type == EXTENSES:
2020-02-21 08:50:12 +01:00
sum_extense_simulated += tmp_Amount
2020-02-17 21:38:47 +01:00
if transaction.is_simulated is not None and transaction.is_simulated == 0:
2020-02-21 08:50:12 +01:00
sum_extense += tmp_Amount
2020-02-17 21:38:47 +01:00
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()
2020-02-21 08:50:12 +01:00
total = sumrecette - sum_extense
total_simulated = sumrecette_simulated - sum_extense_simulated
2020-02-17 21:38:47 +01:00
2020-02-21 21:47:09 +01:00
nb_transaction = transactions_list.count()
2020-02-17 21:38:47 +01:00
context = {
"transaction_list": transaction_list_and_sum,
2020-02-21 08:50:12 +01:00
"accounting_year": accounting_year,
"totaldepense": sum_extense,
2020-02-17 21:38:47 +01:00
"totalrecette": sumrecette,
2020-02-21 08:50:12 +01:00
"totaldepense_simulated": sum_extense_simulated,
2020-02-17 21:38:47 +01:00
"totalrecette_simulated": sumrecette_simulated,
"total": total,
"total_simulated": total_simulated,
"date_sum": date_sum,
"nb_transaction": nb_transaction,
2020-02-21 21:47:09 +01:00
"t_type": transaction_kind,
2020-02-17 21:38:47 +01:00
}
return render(request, "comptability/transactions/listing.html", context)
2020-02-17 21:38:47 +01:00
2022-05-06 14:49:54 +02:00
@login_required
@require_http_methods(["GET"])
2020-02-17 21:38:47 +01:00
def year_listing(request):
"""
Liste toutes les années pour lesquelles il y a des transactions.
2020-02-17 21:38:47 +01:00
"""
years = Transaction.objects.dates("registrationDate", "year")
year_list = []
for year in years:
2020-02-22 11:08:26 +01:00
year_list.append((year.year, Transaction.objects.by_year(year.year).count(),))
2020-02-17 21:38:47 +01:00
context = {"year_list": year_list}
return render(request, "comptability/year_listing.html", context)
2020-02-17 21:38:47 +01:00
2022-05-06 14:49:54 +02:00
@login_required
@require_http_methods(["GET"])
2020-02-22 11:08:26 +01:00
def transaction_listing_for_year_and_type(
request, accounting_year, transaction_type_id
):
2020-02-17 21:38:47 +01:00
"""
2020-02-22 11:08:26 +01:00
Liste toutes les transactions d'un `type de transaction` et pour une année passés en paramètre.
2020-02-17 21:38:47 +01:00
Args:
request (???):
2020-02-21 08:50:12 +01:00
accounting_year (int): année
transaction_type_id (int): id d'un type de transaction
Returns:
(???)
2020-02-17 21:38:47 +01:00
"""
transaction_type = TransactionType.objects.get(pk=transaction_type_id)
2020-02-21 21:47:09 +01:00
# 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)
2020-02-21 08:50:12 +01:00
2020-02-22 11:08:26 +01:00
transaction_list = (
Transaction.objects.by_year(accounting_year)
.filter((by_type_condition | by_parent_type_condition))
.order_by("registrationDate")
)
2020-02-17 21:38:47 +01:00
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),
2020-02-21 08:50:12 +01:00
"accounting_year": accounting_year,
2020-02-17 21:38:47 +01:00
"total_simulated": total_simulated,
"total": total,
}
return render(request, "comptability/transactions/listing.html", context)
2020-02-17 21:38:47 +01:00
2022-05-06 14:49:54 +02:00
@login_required
@require_http_methods(["GET"])
2022-01-07 12:29:22 +01:00
def transaction_details(request, transaction_id):
2020-02-17 21:38:47 +01:00
"""
Renvoie les détails d'une ligne de comptabilité.
"""
transaction = Transaction.objects.get(pk=transaction_id)
context = {"event": transaction.event, "transaction": transaction}
# changed template
return render(request, "comptability/transactions/details.html", context)
2022-05-06 14:49:54 +02:00
@login_required
@require_http_methods(["GET", "POST"])
def transaction_create_or_update(request, transaction_id=None):
""" Création ou modificatin d'une transaction.
2020-02-25 21:50:56 +01:00
Args:
transaction_id (int): identifiant d'une transaction.
2020-02-17 21:38:47 +01:00
"""
if transaction_id:
transaction = get_object_or_404(Transaction, pk=transaction_id)
else:
transaction = None
if request.method == "POST":
form = TransactionForm(request.POST, instance=transaction)
if form.is_valid():
transaction = form.save()
return HttpResponseRedirect(reverse("transaction_details", args=(transaction.pk, )))
else:
form = TransactionForm(instance=transaction)
context = {"form": form, "transaction_id": transaction_id}
return render(request, "comptability/transactions/create.html", context)