diff --git a/app/apps/rules/signals.py b/app/apps/rules/signals.py index c96fbd2..88d0980 100644 --- a/app/apps/rules/signals.py +++ b/app/apps/rules/signals.py @@ -1,11 +1,12 @@ -from django.dispatch import Signal, receiver +from django.dispatch import receiver -from apps.transactions.models import Transaction +from apps.transactions.models import ( + Transaction, + transaction_created, + transaction_updated, +) from apps.rules.tasks import check_for_transaction_rules -transaction_created = Signal() -transaction_updated = Signal() - @receiver(transaction_created) @receiver(transaction_updated) diff --git a/app/apps/transactions/models.py b/app/apps/transactions/models.py index 4bdc808..2d0bb41 100644 --- a/app/apps/transactions/models.py +++ b/app/apps/transactions/models.py @@ -1,22 +1,66 @@ import logging from dateutil.relativedelta import relativedelta +from django.conf import settings from django.core.validators import MinValueValidator from django.db import models, transaction from django.db.models import Q +from django.dispatch import Signal +from django.template.defaultfilters import date from django.utils import timezone from django.utils.translation import gettext_lazy as _ -from django.conf import settings from apps.common.fields.month_year import MonthYearModelField from apps.common.functions.decimals import truncate_decimal +from apps.common.templatetags.decimal import localize_number, drop_trailing_zeros from apps.currencies.utils.convert import convert from apps.transactions.validators import validate_decimal_places, validate_non_negative logger = logging.getLogger() +transaction_created = Signal() +transaction_updated = Signal() + + class SoftDeleteQuerySet(models.QuerySet): + @staticmethod + def _emit_signals(instances, created=False): + """Helper to emit signals for multiple instances""" + for instance in instances: + if created: + transaction_created.send(sender=instance) + else: + transaction_updated.send(sender=instance) + + def bulk_create(self, objs, emit_signal=True, **kwargs): + instances = super().bulk_create(objs, **kwargs) + + if emit_signal: + self._emit_signals(instances, created=True) + + return instances + + def bulk_update(self, objs, fields, emit_signal=True, **kwargs): + result = super().bulk_update(objs, fields, **kwargs) + + if emit_signal: + self._emit_signals(objs, created=False) + + return result + + def update(self, emit_signal=True, **kwargs): + # Get instances before update + instances = list(self) + result = super().update(**kwargs) + + if emit_signal: + # Refresh instances to get new values + refreshed = self.model.objects.filter(pk__in=[obj.pk for obj in instances]) + self._emit_signals(refreshed, created=False) + + return result + def delete(self): if not settings.ENABLE_SOFT_DELETE: # If soft deletion is disabled, perform a normal delete @@ -274,7 +318,13 @@ class Transaction(models.Model): def __str__(self): type_display = self.get_type_display() - return f"{self.description} - {type_display} - {self.account} - {self.date}" + frmt_date = date(self.date, "SHORT_DATE_FORMAT") + account = self.account + tags = ", ".join([x.name for x in self.tags.all()]) or _("No Tags") + category = self.category or _("No Category") + amount = localize_number(drop_trailing_zeros(self.amount)) + description = self.description or _("No Description") + return f"[{frmt_date}][{type_display}][{account}] {description} • {category} • {tags} • {amount}" class InstallmentPlan(models.Model): diff --git a/app/apps/transactions/views/actions.py b/app/apps/transactions/views/actions.py index 96d4031..bdb68fd 100644 --- a/app/apps/transactions/views/actions.py +++ b/app/apps/transactions/views/actions.py @@ -18,9 +18,6 @@ def bulk_pay_transactions(request): count = transactions.count() transactions.update(is_paid=True) - for transaction in transactions: - transaction_updated.send(sender=transaction) - messages.success( request, ngettext_lazy( @@ -45,9 +42,6 @@ def bulk_unpay_transactions(request): count = transactions.count() transactions.update(is_paid=False) - for transaction in transactions: - transaction_updated.send(sender=transaction) - messages.success( request, ngettext_lazy( @@ -94,7 +88,7 @@ def bulk_undelete_transactions(request): selected_transactions = request.GET.getlist("transactions", []) transactions = Transaction.deleted_objects.filter(id__in=selected_transactions) count = transactions.count() - transactions.update(deleted=False, deleted_at=None) + transactions.update(deleted=False, deleted_at=None, emit_signal=False) messages.success( request,