Files
WYGIWYH/app/apps/rules/utils/transactions.py

102 lines
3.3 KiB
Python

import logging
from decimal import Decimal
from django.db.models import Sum, Value, DecimalField, Case, When, F
from django.db.models.functions import Coalesce
from apps.transactions.models import (
Transaction,
)
logger = logging.getLogger(__name__)
class TransactionsGetter:
def __init__(self, **filters):
self.__queryset = Transaction.objects.filter(**filters)
def exclude(self, **exclude_filters):
self.__queryset = self.__queryset.exclude(**exclude_filters)
return self
@property
def sum(self):
return self.__queryset.aggregate(
total=Coalesce(
Sum("amount"), Value(Decimal("0")), output_field=DecimalField()
)
)["total"]
@property
def balance(self):
return abs(
self.__queryset.aggregate(
balance=Coalesce(
Sum(
Case(
When(type=Transaction.Type.EXPENSE, then=-F("amount")),
default=F("amount"),
output_field=DecimalField(),
)
),
Value(Decimal("0")),
output_field=DecimalField(),
)
)["balance"]
)
@property
def raw_balance(self):
return self.__queryset.aggregate(
balance=Coalesce(
Sum(
Case(
When(type=Transaction.Type.EXPENSE, then=-F("amount")),
default=F("amount"),
output_field=DecimalField(),
)
),
Value(Decimal("0")),
output_field=DecimalField(),
)
)["balance"]
def serialize_transaction(sender: Transaction, deleted: bool):
return {
"id": sender.id,
"account": (sender.account.id, sender.account.name),
"account_group": (
sender.account.group.id if sender.account.group else None,
sender.account.group.name if sender.account.group else None,
),
"type": str(sender.type),
"is_paid": sender.is_paid,
"is_asset": sender.account.is_asset,
"is_archived": sender.account.is_archived,
"category": (
sender.category.id if sender.category else None,
sender.category.name if sender.category else None,
),
"date": sender.date.isoformat(),
"reference_date": sender.reference_date.isoformat(),
"amount": str(sender.amount),
"description": sender.description,
"notes": sender.notes,
"tags": list(sender.tags.values_list("id", "name")),
"entities": list(sender.entities.values_list("id", "name")),
"deleted": deleted,
"internal_note": sender.internal_note,
"internal_id": sender.internal_id,
"mute": sender.mute,
"installment_id": sender.installment_id if sender.installment_plan else None,
"installment_total": (
sender.installment_plan.number_of_installments
if sender.installment_plan is not None
else None
),
"installment": sender.installment_plan is not None,
"recurring_transaction": sender.recurring_transaction is not None,
}