diff --git a/app/base/models/account.py b/app/base/models/account.py index e1998bb..ad399b7 100755 --- a/app/base/models/account.py +++ b/app/base/models/account.py @@ -21,10 +21,10 @@ class Account(models.Model): def __str__(self): return f"{self.user}'s Konto" - # def change_balance(self, amount): - # self.balance = self.balance - amount - # self.save() - # return True + def update_balance(self, amount: 'Decimal') -> None: + if amount: + self.balance += amount + self.save() # def lock(self): # self.locked = True diff --git a/app/base/models/booking.py b/app/base/models/booking.py index 93ad5f9..1447a55 100755 --- a/app/base/models/booking.py +++ b/app/base/models/booking.py @@ -5,6 +5,7 @@ from django.urls import reverse from app.base.forms.fields import DateTimeField, TextField from app.base.forms.utils import datetime_now +from app.base.models.transaction import Transaction from typing import TYPE_CHECKING if TYPE_CHECKING: @@ -42,11 +43,14 @@ class Booking(models.Model): if self.end_time else '') def save(self, *args, **kwargs): - # update last_visit time of all involved persons prev = Booking.objects.get(pk=self.pk) if self.pk else None rv = super().save(*args, **kwargs) + # update Transaction + Transaction.upsertFromBooking(self) + + # update last_visit time of all involved persons if prev and prev.user != self.user: prev.user.update_last_visit(None) if not prev or prev.user != self.user or \ diff --git a/app/base/models/person.py b/app/base/models/person.py index a492ea8..3ff5fca 100755 --- a/app/base/models/person.py +++ b/app/base/models/person.py @@ -59,6 +59,7 @@ class Person(models.Model): if self._state.adding: self.created = date.today() self.last_visit = date.today() + Account.objects.create(user=self) return super().save(*args, **kwargs) @property diff --git a/app/base/models/transaction.py b/app/base/models/transaction.py index 5303540..ac167fd 100755 --- a/app/base/models/transaction.py +++ b/app/base/models/transaction.py @@ -38,4 +38,37 @@ class Transaction(models.Model): def save(self, *args, **kwargs): if self._state.adding: self.time_stamp = datetime_now() + self.account.update_balance(self.amount) + elif self.pk: # basically an "else", but just to be sure + prev = Transaction.objects.get(pk=self.pk) + self.account.update_balance(self.amount - prev.amount) + return super().save(*args, **kwargs) + + def delete(self, *args, **kwargs): + self.account.update_balance(-self.amount) + return super().delete(*args, **kwargs) + + @staticmethod + def upsertFromBooking(booking: 'Booking'): + amount = booking.calculated_price + should_exist = booking.end_time and amount + description = f'{booking.type.label} ({booking.duration or 0} Min)' + + # Create or update existing Transaction + transaction = Transaction.objects.filter(booking=booking).first() + if transaction: + if should_exist: + transaction.amount = -amount + transaction.description = description + transaction.save() + else: + transaction.delete() + + elif should_exist: + Transaction.objects.create( + account=booking.user.account, + amount=-amount, + description=description, + booking=booking, + ) diff --git a/app/base/signals/__init__.py b/app/base/signals/__init__.py index 665b25e..e69de29 100755 --- a/app/base/signals/__init__.py +++ b/app/base/signals/__init__.py @@ -1,7 +0,0 @@ -from app.base.signals.booking import booking_post_save -from app.base.signals.person import person_post_save -from app.base.signals.transaction import ( - transaction_pre_save, - transaction_post_save, - transaction_pre_delete -) diff --git a/app/base/signals/booking.py b/app/base/signals/booking.py deleted file mode 100755 index d35a693..0000000 --- a/app/base/signals/booking.py +++ /dev/null @@ -1,29 +0,0 @@ -from django.db.models.signals import post_save -from django.dispatch import receiver - -from app.base.models import Transaction, Booking - - -@receiver(post_save, sender=Booking) -def booking_post_save(sender, instance: Booking, created: bool, **kwargs): - amount = instance.calculated_price - with_transaction = instance.end_time and amount - description = f'{instance.type.label} ({instance.duration or 0} Min)' - - # Create or update existing Transaction - transaction = Transaction.objects.filter(booking=instance).first() - if transaction: - if with_transaction: - transaction.amount = -amount - transaction.description = description - transaction.save() - else: - transaction.delete() - - elif with_transaction: - Transaction.objects.create( - account=instance.user.account, - amount=-amount, - description=description, - booking=instance, - ) diff --git a/app/base/signals/person.py b/app/base/signals/person.py deleted file mode 100755 index 0e209ad..0000000 --- a/app/base/signals/person.py +++ /dev/null @@ -1,9 +0,0 @@ -from django.dispatch import receiver -from django.db.models.signals import post_save -from app.base.models import Person, Account - - -@receiver(post_save, sender=Person) -def person_post_save(sender, instance: Person, created: bool, **kwargs): - if created: - Account.objects.create(user=instance) diff --git a/app/base/signals/transaction.py b/app/base/signals/transaction.py deleted file mode 100755 index 4b14996..0000000 --- a/app/base/signals/transaction.py +++ /dev/null @@ -1,28 +0,0 @@ -from django.dispatch import receiver -from django.db.models.signals import pre_save, post_save, pre_delete -from app.base.models import Transaction - - -@receiver(pre_save, sender=Transaction) -def transaction_pre_save(sender, instance: Transaction, **kwargs): - if instance.pk: - pre_edit = Transaction.objects.get(pk=instance.pk) - - if pre_edit.amount != instance.amount: - delta = pre_edit.amount - instance.amount - account = instance.account - account.balance = account.balance - delta - account.save() - - -@receiver(post_save, sender=Transaction) -def transaction_post_save(sender, instance: Transaction, created, **kwargs): - if created: - instance.account.balance += instance.amount - instance.account.save() - - -@receiver(pre_delete, sender=Transaction) -def transaction_pre_delete(sender, instance: Transaction, **kwargs): - instance.account.balance -= instance.amount - instance.account.save()