2020-08-01 16:06:50 +00:00
|
|
|
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
|
|
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
2020-08-05 21:15:05 +00:00
|
|
|
from django.core.mail import send_mail
|
2020-08-01 16:06:50 +00:00
|
|
|
from django.core.management import BaseCommand
|
|
|
|
from django.db.models import Sum, F
|
|
|
|
|
|
|
|
from note.models import Note, Transaction
|
|
|
|
from note.templatetags.pretty_money import pretty_money
|
|
|
|
|
|
|
|
|
|
|
|
class Command(BaseCommand):
|
|
|
|
def add_arguments(self, parser):
|
|
|
|
parser.add_argument('--sum-all', '-s', action='store_true', help='Check if the global sum is equal to zero')
|
2020-08-05 21:15:05 +00:00
|
|
|
parser.add_argument('--check-all', '-a', action='store_true', help='Check all notes')
|
|
|
|
parser.add_argument('--check', '-c', type=int, nargs='+', help='Select note ids')
|
2020-08-03 09:15:50 +00:00
|
|
|
parser.add_argument('--fix', '-f', action='store_true', help='Fix note balances')
|
2020-08-05 21:15:05 +00:00
|
|
|
parser.add_argument('--mail', '-m', action='store_true', help='Send mail to admins if there is an error')
|
2020-08-01 16:06:50 +00:00
|
|
|
|
|
|
|
def handle(self, *args, **options):
|
2020-08-05 21:15:05 +00:00
|
|
|
error = False
|
|
|
|
err_log = ""
|
|
|
|
|
2020-08-01 16:06:50 +00:00
|
|
|
if options["sum_all"]:
|
|
|
|
s = Note.objects.aggregate(Sum("balance"))["balance__sum"]
|
|
|
|
if s:
|
2020-08-05 21:15:05 +00:00
|
|
|
err_log += self.style.NOTICE("LA SOMME DES NOTES NE VAUT PAS ZÉRO : " + pretty_money(s)) + "\n"
|
|
|
|
error = True
|
2020-08-01 16:06:50 +00:00
|
|
|
else:
|
|
|
|
self.stdout.write(self.style.SUCCESS("La somme des notes vaut bien zéro."))
|
|
|
|
|
2020-08-05 21:53:44 +00:00
|
|
|
notes = Note.objects.none()
|
2020-08-05 21:51:55 +00:00
|
|
|
if options["check_all"]:
|
2020-08-05 21:15:05 +00:00
|
|
|
notes = Note.objects.all()
|
|
|
|
elif options["check"]:
|
|
|
|
notes = Note.objects.filter(pk__in=options["check"])
|
|
|
|
|
|
|
|
for note in notes:
|
2020-08-01 16:06:50 +00:00
|
|
|
balance = note.balance
|
|
|
|
incoming = Transaction.objects.filter(valid=True, destination=note)\
|
|
|
|
.annotate(total=F("quantity") * F("amount")).aggregate(Sum("total"))["total__sum"] or 0
|
|
|
|
outcoming = Transaction.objects.filter(valid=True, source=note)\
|
|
|
|
.annotate(total=F("quantity") * F("amount")).aggregate(Sum("total"))["total__sum"] or 0
|
2020-08-03 09:15:50 +00:00
|
|
|
calculated_balance = incoming - outcoming
|
|
|
|
if calculated_balance != balance:
|
2020-08-05 21:15:05 +00:00
|
|
|
err_log += self.style.NOTICE("LA SOMME DES TRANSACTIONS DE LA NOTE {} NE CORRESPOND PAS "
|
|
|
|
"AVEC LE MONTANT RÉEL".format(str(note))) + "\n"
|
|
|
|
err_log += self.style.NOTICE("Attendu : {}, calculé : {}"
|
|
|
|
.format(pretty_money(balance), pretty_money(calculated_balance))) + "\n"
|
2020-08-03 09:15:50 +00:00
|
|
|
if options["fix"]:
|
|
|
|
note.balance = calculated_balance
|
|
|
|
note.save()
|
2020-08-01 16:06:50 +00:00
|
|
|
error = True
|
2020-08-05 21:15:05 +00:00
|
|
|
|
|
|
|
if error:
|
|
|
|
self.stderr.write(err_log)
|
|
|
|
if options["mail"]:
|
|
|
|
send_mail("[Note Kfet] La base de données n'est pas consistante", err_log,
|
|
|
|
"NoteKfet2020 <notekfet2020@crans.org>", ["respoinfo.bde@lists.crans.org"])
|
|
|
|
|
2020-08-01 16:06:50 +00:00
|
|
|
exit(1 if error else 0)
|