Completely re-structured the project from scratch, wrote a better bootstrap script, changed configuration format to yaml, improved Caddyfile, and more. #15 #16 #20
This commit is contained in:
parent
0012214f9b
commit
5572fec9c1
91 changed files with 739 additions and 1345 deletions
152
app/models.py
Normal file
152
app/models.py
Normal file
|
@ -0,0 +1,152 @@
|
|||
|
||||
from django.db import models
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
from django.forms import ValidationError
|
||||
from django.utils import timezone
|
||||
|
||||
|
||||
|
||||
# Custom user model
|
||||
class User(AbstractUser):
|
||||
|
||||
balance = models.DecimalField(max_digits=8, decimal_places=2, default=0.00)
|
||||
allow_order_with_negative_balance = models.BooleanField(default=False)
|
||||
profile_picture_filename = models.CharField(default="default.svg", max_length=25)
|
||||
allowed_to_supply = models.BooleanField(default=False)
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
self.balance = 0
|
||||
self.is_active = False
|
||||
self.username = f"<deleted user #{self.pk}>"
|
||||
self.last_name = ""
|
||||
self.first_name = ""
|
||||
self.email = ""
|
||||
super().save()
|
||||
|
||||
#
|
||||
|
||||
|
||||
class Drink(models.Model):
|
||||
|
||||
product_name = models.CharField(max_length=64)
|
||||
content_litres = models.DecimalField(max_digits=6, decimal_places=3, default=0.5)
|
||||
price = models.DecimalField(max_digits=6, decimal_places=2, default=0.00)
|
||||
available = models.PositiveIntegerField(default=0)
|
||||
deleted = models.BooleanField(default=False)
|
||||
|
||||
# when the following field is true, the amount of drinks will
|
||||
# not change and will not be displayed.
|
||||
# available > 0 -> there is a indefinetly amount of drinks left
|
||||
# available < 1 -> there are no drinks left
|
||||
do_not_count = models.BooleanField(default=False)
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
self.deleted = True
|
||||
super().save()
|
||||
|
||||
def __str__(self): return f"{self.product_name} ({float(self.content_litres):.2f}l) - {self.price}{settings.CURRENCY_SUFFIX}"
|
||||
|
||||
|
||||
class RegisterTransaction(models.Model):
|
||||
|
||||
class Meta:
|
||||
verbose_name = "transaction"
|
||||
verbose_name_plural = "transactions"
|
||||
|
||||
transaction_sum = models.DecimalField(max_digits=6, decimal_places=2, default=0.00)
|
||||
# the following original_transaction_sum is needed when need to be
|
||||
# updated, but the old value needs to be known (field is hidden)
|
||||
old_transaction_sum = models.DecimalField(max_digits=6, decimal_places=2, default=0.00)
|
||||
datetime = models.DateTimeField(default=timezone.now)
|
||||
is_user_deposit = models.BooleanField(default=False)
|
||||
comment = models.TextField(default=" ")
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self._state.adding:
|
||||
if self.is_user_deposit == True: # update user balance
|
||||
self.user.balance += self.transaction_sum
|
||||
self.user.save()
|
||||
self.old_transaction_sum = self.transaction_sum
|
||||
super().save(*args, **kwargs)
|
||||
else:
|
||||
# update register transaction
|
||||
sum_diff = self.transaction_sum - self.old_transaction_sum
|
||||
# update user balance
|
||||
if self.is_user_deposit == True:
|
||||
ub_sum_diff = self.transaction_sum - self.old_transaction_sum
|
||||
self.user.balance += ub_sum_diff
|
||||
self.user.save()
|
||||
self.old_transaction_sum = self.transaction_sum
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
# update user deposit
|
||||
if self.is_user_deposit:
|
||||
self.user.balance -= self.transaction_sum
|
||||
self.user.save()
|
||||
super().delete(*args, kwargs)
|
||||
|
||||
def __str__(self): return f"{self.transaction_sum}{settings.CURRENCY_SUFFIX} by {self.user}"
|
||||
|
||||
|
||||
class Order(models.Model):
|
||||
|
||||
drink = models.ForeignKey(
|
||||
"Drink",
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
limit_choices_to=models.Q(available__gt=0) # Query only those drinks with a availability greater than (gt) 0
|
||||
)
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
datetime = models.DateTimeField(default=timezone.now)
|
||||
amount = models.PositiveIntegerField(default=1, editable=False)
|
||||
|
||||
# the following fields will be set automatically
|
||||
# won't use foreign key, because the values of the foreign objects may change over time.
|
||||
product_name = models.CharField(max_length=64, editable=False)
|
||||
price_sum = models.DecimalField(max_digits=6, decimal_places=2, default=0, editable=False)
|
||||
content_litres = models.DecimalField(max_digits=6, decimal_places=3, default=0, editable=False)
|
||||
|
||||
# TODO: Add more comments on how and why the save & delete functions are implemented
|
||||
# address this in a refactoring issue.
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
drink = Drink.objects.get(pk=self.drink.pk)
|
||||
if self._state.adding and drink.available > 0:
|
||||
if not drink.do_not_count:
|
||||
drink.available -= self.amount
|
||||
drink.save()
|
||||
self.product_name = drink.product_name
|
||||
self.price_sum = drink.price * self.amount
|
||||
self.content_litres = drink.content_litres
|
||||
self.user.balance -= self.price_sum
|
||||
self.user.save()
|
||||
super().save(*args, **kwargs)
|
||||
else:
|
||||
raise ValidationError("This entry can't be changed.")
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
self.user.balance += self.price_sum
|
||||
self.user.save()
|
||||
drink = Drink.objects.get(pk=self.drink.pk)
|
||||
if not drink.do_not_count:
|
||||
drink.available += self.amount
|
||||
drink.save()
|
||||
super().delete(*args, **kwargs)
|
||||
|
||||
def __str__(self): return f"{self.drink.product_name} ({float(self.drink.content_litres):.2f}l) x {self.amount} - {self.price_sum}{settings.CURRENCY_SUFFIX}"
|
||||
|
||||
|
||||
class Global(models.Model):
|
||||
|
||||
# this contains global values that are generated/calculated by code
|
||||
# e.g. the current balance of the register, ...
|
||||
|
||||
name = models.CharField(max_length=42, unique=True, primary_key=True)
|
||||
comment = models.TextField()
|
||||
value_float = models.FloatField(default=0.00)
|
||||
value_string = models.TextField()
|
||||
|
||||
def __str__(self): return self.name
|
Loading…
Add table
Add a link
Reference in a new issue