from decimal import Decimal, ROUND_HALF_UP from django.core.management.base import BaseCommand from django.db.models import F, Sum from gaehsnitz.models import Consumption, Payment, UserPayment YEAR = 2026 CASH_PREFILL = Decimal("500.00") def eur(amount): return str(Decimal(amount).quantize(Decimal("1"), rounding=ROUND_HALF_UP)) class Command(BaseCommand): help = "Print full 2026 festival finance summary" def handle(self, *args, **options): w = self.stdout.write sep = "-" * 40 # --- Ausgaben --- w("\nAUSGABEN") w(sep) payments = Payment.objects.filter(date__year=YEAR).order_by("date") total_out = Decimal("0") for p in payments: method_label = dict(Payment.Method.choices).get(p.method, p.method) w(f" {p.date} {eur(p.amount):>6}€ {method_label:<15} {p.purpose}") total_out += p.amount w(sep) w(f" {'TOTAL':<11} {eur(total_out):>6}€") # by method w("") for method, label in Payment.Method.choices: subtotal = payments.filter(method=method).aggregate(s=Sum("amount"))["s"] or Decimal("0") if subtotal: w(f" {label:<15} {eur(subtotal):>6}€") # --- Einnahmen --- w("\nEINNAHMEN") w(sep) up = UserPayment.objects.filter(created_at__year=YEAR) cash_prefill = CASH_PREFILL cash_payments = up.filter(method="cash").aggregate(s=Sum("amount"))["s"] or Decimal("0") cash_from_sales = cash_payments - cash_prefill non_cash = up.exclude(method="cash").aggregate(s=Sum("amount"))["s"] or Decimal("0") total_in = cash_from_sales + non_cash drink_revenue = Consumption.objects.filter(for_free=False, drink__year=YEAR).annotate( cost=F("amount") * F("drink__sale_price_per_bottle") ).aggregate(s=Sum("cost"))["s"] or Decimal("0") entry_donations = total_in - drink_revenue w(f" Cash: {eur(cash_from_sales):>6}€") w(f" Cashless: {eur(non_cash):>6}€") w(f" Einnahmen Gesamt: {eur(total_in):>6}€") w(f" - Getränke-Umsatz: {eur(drink_revenue):>6}€") w(f" - Eintrittsspenden: {eur(entry_donations):>6}€") # --- Kassensaldo --- w("\nKASSE") w(sep) cash_out = payments.filter(method="cash").aggregate(s=Sum("amount"))["s"] or Decimal("0") expected_cash = cash_prefill + cash_from_sales - cash_out w(f" Kassen-Vorschuss: {eur(cash_prefill):>6}€") w(f" Cash-Einnahmen: {eur(cash_from_sales):>6}€") w(f" Cash-Ausgaben: {eur(cash_out):>6}€") w(f" -> in Kasse: {eur(expected_cash):>6}€") # --- Gesamtbilanz --- w("\nGESAMTBILANZ") w(sep) net = total_in - total_out out_of_pocket = total_out - total_in w(f" Gesamtausgaben: {eur(total_out):>6}€") w(f" Gesamteinnahmen: {eur(total_in):>6}€") w(sep) label = "Verlust" if out_of_pocket > 0 else "Gewinn" w(f" {label}: {eur(abs(net)):>6}€\n")