diff --git a/accounting/models.py b/accounting/models.py index af71089..3f9ecad 100644 --- a/accounting/models.py +++ b/accounting/models.py @@ -21,7 +21,7 @@ from dirtyfields import DirtyFieldsMixin from django.conf import settings from django.db import models, transaction -from django.db.models import Q +from django.db.models import Q, Max from django.urls import reverse from mia_core.utils import get_multi_lingual_attr, set_multi_lingual_attr, \ @@ -191,6 +191,55 @@ class Transaction(DirtyFieldsMixin, models.Model): return True return False + def save(self, current_user=None, old_date=None, force_insert=False, + force_update=False, using=None, update_fields=None): + # When the date is changed, the orders of the transactions in the same + # day need to be reordered + txn_to_sort = [] + if self.date != old_date: + if old_date is not None: + txn_same_day = list( + Transaction.objects + .filter(Q(date=old_date), ~Q(pk=self.pk)) + .order_by("ord")) + for i in range(len(txn_same_day)): + if txn_same_day[i].ord != i + 1: + txn_to_sort.append([txn_same_day[i], i + 1]) + max_ord = Transaction.objects\ + .filter(date=self.date)\ + .aggregate(max=Max("ord"))["max"] + self.ord = 1 if max_ord is None else max_ord + 1 + # Collects the records to be deleted + to_keep = [x.pk for x in self.records if x.pk is not None] + to_delete = [x for x in self.record_set.all() if x.pk not in to_keep] + # Applies the created by and updated by + if self.pk is None: + self.pk = new_pk(Transaction) + if current_user is not None: + self.created_by = current_user + if current_user is not None: + self.updated_by = current_user + to_save = [x for x in self.records if x.is_dirty()] + for record in to_save: + if record.pk is None: + record.pk = new_pk(Record) + if current_user is not None: + record.created_by = current_user + if current_user is not None: + record.updated_by = current_user + # Runs the update + with transaction.atomic(): + super().save(force_insert=force_insert, force_update=force_update, + using=using, update_fields=update_fields) + for record in to_delete: + record.delete() + for record in to_save: + record.save(force_insert=force_insert, + force_update=force_update, + using=using, update_fields=update_fields) + for x in txn_to_sort: + Transaction.objects.filter(pk=x[0].pk).update(ord=x[1]) + def delete(self, using=None, keep_parents=False): txn_same_day = list( Transaction.objects diff --git a/accounting/views.py b/accounting/views.py index 6266786..e04dcb7 100644 --- a/accounting/views.py +++ b/accounting/views.py @@ -872,60 +872,16 @@ def txn_store(request, txn_type, txn=None): url = reverse("accounting:transactions.edit", args=(txn_type, txn)) url = str(UrlBuilder(url).query(r=request.GET.get("r"))) return stored_post.error_redirect(request, url, post) - if txn is None: txn = Transaction() old_date = txn.date utils.fill_txn_from_post(txn_type, txn, post) if not txn.is_dirty(check_relationship=True): - messages.success(request, gettext_noop( - "This transaction was not modified.")) - url = reverse("accounting:transactions.detail", args=(txn_type, txn)) - return redirect(str(UrlBuilder(url).query(r=request.GET.get("r")))) - - # Prepares the data - user = request.user - if txn.pk is None: - txn.pk = new_pk(Transaction) - txn.created_at = Now() - txn.created_by = user - txn.updated_at = Now() - txn.updated_by = user - txn_to_sort = [] - if txn.date != old_date: - if old_date is not None: - txn_same_day = list( - Transaction.objects - .filter(Q(date=old_date), ~Q(pk=txn.pk)) - .order_by("ord")) - for i in range(len(txn_same_day)): - txn_same_day[i].ord = i + 1 - if txn_same_day[i].is_dirty(): - txn_to_sort.append(txn_same_day[i]) - max_ord = Transaction.objects\ - .filter(date=txn.date)\ - .aggregate(max=Max("ord"))["max"] - txn.ord = 1 if max_ord is None else max_ord + 1 - for record in txn.records: - if record.pk is None: - record.pk = new_pk(Record) - record.created_at = Now() - record.created_by = user - record.updated_at = Now() - record.updated_by = user - to_keep = [x.pk for x in txn.records if x.pk is not None] - to_delete = [x for x in txn.record_set.all() if x.pk not in to_keep] - # Runs the update - with transaction.atomic(): - txn.save() - for record in to_delete: - record.delete() - for record in txn.records: - record.save() - for x in txn_to_sort: - x.save() - messages.success(request, gettext_noop( - "This transaction was saved successfully.")) + message = gettext_noop("This transaction was not modified.") + else: + txn.save(current_user=request.user, old_date=old_date) + message = gettext_noop("This transaction was saved successfully.") + messages.success(request, message) url = reverse("accounting:transactions.detail", args=(txn_type, txn)) return redirect(str(UrlBuilder(url).query(r=request.GET.get("r"))))