rewrite models
This commit is contained in:
@@ -1,26 +1,170 @@
|
|||||||
|
from django.contrib.auth.models import AbstractUser
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.db.models import Sum, F
|
||||||
|
|
||||||
|
|
||||||
|
class PriceField(models.DecimalField):
|
||||||
|
|
||||||
|
def __init__(self, verbose_name=None, name=None, **kwargs):
|
||||||
|
kwargs.update({"max_digits": 6, "decimal_places": 2})
|
||||||
|
super().__init__(verbose_name, name, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class User(AbstractUser):
|
||||||
|
|
||||||
|
@property
|
||||||
|
def paid_drinks(self):
|
||||||
|
return self.consumption_list.filter(for_free=False)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def free_drinks(self):
|
||||||
|
return self.consumption_list.filter(for_free=True)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def donations_made(self):
|
||||||
|
query = self.donations.aggregate(sum=Sum("amount"))
|
||||||
|
return query["sum"] or 0
|
||||||
|
|
||||||
|
@property
|
||||||
|
def consumed_drinks_price(self):
|
||||||
|
query = self.paid_drinks \
|
||||||
|
.annotate(cost=F("amount") * F("drink__sale_price_per_bottle")) \
|
||||||
|
.aggregate(sum=Sum("cost"))
|
||||||
|
return query["sum"] or 0
|
||||||
|
|
||||||
|
@property
|
||||||
|
def other_payments_made(self):
|
||||||
|
query = self.payments.aggregate(sum=Sum("amount"))
|
||||||
|
return query["sum"] or 0
|
||||||
|
|
||||||
|
@property
|
||||||
|
def paybacks_received(self):
|
||||||
|
query = self.paybacks.aggregate(sum=Sum("amount"))
|
||||||
|
return query["sum"] or 0
|
||||||
|
|
||||||
|
@property
|
||||||
|
def balance(self):
|
||||||
|
return self.donations_made - self.consumed_drinks_price + self.other_payments_made - self.paybacks_received
|
||||||
|
|
||||||
|
|
||||||
|
class Donation(models.Model):
|
||||||
|
from_user = models.ForeignKey(
|
||||||
|
to=User, on_delete=models.PROTECT,
|
||||||
|
related_name="donations", related_query_name="donation")
|
||||||
|
date = models.DateField()
|
||||||
|
amount = PriceField()
|
||||||
|
note = models.CharField(max_length=64, blank=True, default="")
|
||||||
|
|
||||||
|
|
||||||
class Payment(models.Model):
|
class Payment(models.Model):
|
||||||
class Topic(models.IntegerChoices):
|
class Topic(models.IntegerChoices):
|
||||||
# positive
|
|
||||||
donation = 0, "Spenden/Vorauszahlungen"
|
|
||||||
admission_fee = 1, "Eintrittsgeld"
|
|
||||||
supply_sale = 2, "Getränke-/Essensverkauf"
|
|
||||||
# negative
|
|
||||||
site = 10, "Gelände"
|
site = 10, "Gelände"
|
||||||
bands = 11, "Bands"
|
bands = 11, "Bands"
|
||||||
supply_purchase = 12, "Getränke-/Essenseinkauf"
|
supply_purchase = 12, "Getränke-/Essenseinkauf"
|
||||||
|
|
||||||
other_party = models.TextField()
|
purpose = models.CharField(max_length=64)
|
||||||
topic = models.PositiveSmallIntegerField(choices=Topic.choices)
|
|
||||||
amount = models.PositiveIntegerField()
|
|
||||||
date = models.DateField()
|
date = models.DateField()
|
||||||
note = models.TextField(blank=True)
|
amount = PriceField()
|
||||||
is_estimated = models.BooleanField(default=False)
|
from_user = models.ForeignKey(
|
||||||
|
to=User, on_delete=models.PROTECT,
|
||||||
|
related_name="payments", related_query_name="payment")
|
||||||
|
|
||||||
def is_incoming(self):
|
|
||||||
return self.topic < 10
|
|
||||||
|
|
||||||
def is_outgoing(self):
|
class Payback(models.Model):
|
||||||
return not self.is_incoming()
|
to_user = models.ForeignKey(
|
||||||
|
to=User, on_delete=models.PROTECT,
|
||||||
|
related_name="paybacks", related_query_name="payback")
|
||||||
|
date = models.DateField()
|
||||||
|
amount = PriceField()
|
||||||
|
note = models.CharField(max_length=64, blank=True, default="")
|
||||||
|
|
||||||
|
|
||||||
|
class Drink(models.Model):
|
||||||
|
name = models.CharField(max_length=32, unique=True)
|
||||||
|
crates_ordered = models.PositiveSmallIntegerField(
|
||||||
|
help_text="just informational to see how good we planned, not the actual consumed/paid drinks"
|
||||||
|
)
|
||||||
|
crates_purchased = models.PositiveSmallIntegerField()
|
||||||
|
crates_returned = models.PositiveSmallIntegerField()
|
||||||
|
purchase_price_per_crate = PriceField()
|
||||||
|
deposit_per_crate = PriceField()
|
||||||
|
bottles_per_crate = models.PositiveSmallIntegerField()
|
||||||
|
bottle_size = models.FloatField()
|
||||||
|
sale_price_per_bottle = PriceField()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def bottles_total(self):
|
||||||
|
return self.bottles_per_crate * self.crates_purchased
|
||||||
|
|
||||||
|
@property
|
||||||
|
def bottles_returned(self):
|
||||||
|
return self.bottles_per_crate * self.crates_returned
|
||||||
|
|
||||||
|
@property
|
||||||
|
def amount_per_crate(self):
|
||||||
|
return self.bottle_size * self.bottles_per_crate
|
||||||
|
|
||||||
|
@property
|
||||||
|
def amount_total(self):
|
||||||
|
return self.amount_per_crate * self.crates_purchased
|
||||||
|
|
||||||
|
@property
|
||||||
|
def purchase_price_per_bottle(self):
|
||||||
|
return self.purchase_price_per_crate / self.bottles_per_crate
|
||||||
|
|
||||||
|
@property
|
||||||
|
def purchase_price_total(self):
|
||||||
|
return self.purchase_price_per_crate * self.crates_purchased
|
||||||
|
|
||||||
|
@property
|
||||||
|
def deposit_total(self):
|
||||||
|
return self.deposit_per_crate * self.crates_purchased
|
||||||
|
|
||||||
|
@property
|
||||||
|
def deposit_refund(self):
|
||||||
|
return self.deposit_per_crate * self.crates_returned
|
||||||
|
|
||||||
|
@property
|
||||||
|
def deposit_kept(self):
|
||||||
|
return self.deposit_total - self.deposit_refund
|
||||||
|
|
||||||
|
@property
|
||||||
|
def bottles_sold(self):
|
||||||
|
query = self.consumption_list.filter(for_free=False).aggregate(sum=Sum("amount"))
|
||||||
|
return query["sum"] or 0
|
||||||
|
|
||||||
|
@property
|
||||||
|
def sales_purchase_value(self):
|
||||||
|
return self.bottles_sold * self.purchase_price_per_bottle
|
||||||
|
|
||||||
|
@property
|
||||||
|
def sale_price_total(self):
|
||||||
|
return self.bottles_sold * self.sale_price_per_bottle
|
||||||
|
|
||||||
|
@property
|
||||||
|
def bottles_given_away(self):
|
||||||
|
query = self.consumption_list.filter(for_free=True).aggregate(sum=Sum("amount"))
|
||||||
|
return query["sum"] or 0
|
||||||
|
|
||||||
|
@property
|
||||||
|
def giveaway_purchase_value(self):
|
||||||
|
return self.bottles_given_away * self.purchase_price_per_bottle
|
||||||
|
|
||||||
|
@property
|
||||||
|
def balance(self):
|
||||||
|
return self.sale_price_total - self.sales_purchase_value - self.giveaway_purchase_value
|
||||||
|
|
||||||
|
|
||||||
|
class Consumption(models.Model):
|
||||||
|
user = models.ForeignKey(
|
||||||
|
to=User, on_delete=models.CASCADE,
|
||||||
|
related_name="consumption_list", related_query_name="consumption")
|
||||||
|
drink = models.ForeignKey(
|
||||||
|
to=Drink, on_delete=models.CASCADE,
|
||||||
|
related_name="consumption_list", related_query_name="consumption")
|
||||||
|
amount = models.PositiveSmallIntegerField()
|
||||||
|
day = models.PositiveSmallIntegerField(choices=[(1, "Do"), (2, "Fr"), (3, "Sa")])
|
||||||
|
for_free = models.BooleanField(default=False)
|
||||||
|
|||||||
@@ -99,3 +99,5 @@ USE_L10N = False
|
|||||||
USE_TZ = True
|
USE_TZ = True
|
||||||
|
|
||||||
STATIC_URL = "/static/"
|
STATIC_URL = "/static/"
|
||||||
|
|
||||||
|
AUTH_USER_MODEL = "gaehsnitz.User"
|
||||||
|
|||||||
Reference in New Issue
Block a user