Changes to payment models #32
|
@ -67,9 +67,8 @@ class Transaction(CreatedModifiedAbstract):
|
|||
class Order(CreatedModifiedAbstract):
|
||||
"""An order.
|
||||
|
||||
Scoped out: Contents of invoices will have to be tracked either here or in
|
||||
a separate Invoice model. This is undecided because we are not generating
|
||||
invoices at the moment.
|
||||
We assemble the order from a number of products. Once an order is paid, the contents should be
|
||||
considered locked.
|
||||
"""
|
||||
|
||||
user = models.ForeignKey("auth.User", on_delete=models.PROTECT)
|
||||
|
@ -114,6 +113,32 @@ class Order(CreatedModifiedAbstract):
|
|||
return x.hexdigest()
|
||||
|
||||
|
||||
class Product(CreatedModifiedAbstract):
|
||||
"""A generic product, for instance a membership or a service fee."""
|
||||
|
||||
name = models.CharField(max_length=512)
|
||||
price = MoneyField(max_digits=16, decimal_places=2)
|
||||
vat = MoneyField(max_digits=16, decimal_places=2)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.name
|
||||
|
||||
|
||||
class OrderProduct(CreatedModifiedAbstract):
|
||||
"""When a product is ordered, we store the product on the order.
|
||||
|
||||
This includes pricing information.
|
||||
"""
|
||||
|
||||
order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name="ordered_products")
|
||||
product = models.ForeignKey(Product, related_name="ordered_products", on_delete=models.PROTECT)
|
||||
price = MoneyField(max_digits=16, decimal_places=2)
|
||||
vat = MoneyField(max_digits=16, decimal_places=2)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"{self.product.name}"
|
||||
|
||||
|
||||
class Payment(CreatedModifiedAbstract):
|
||||
"""A payment is a transaction that is made to pay for an order."""
|
||||
|
||||
|
|
|
@ -133,9 +133,23 @@ class MembershipType(CreatedModifiedAbstract):
|
|||
|
||||
name = models.CharField(verbose_name=_("name"), max_length=64)
|
||||
|
||||
product = models.ForeignKey("accounting.Product", on_delete=models.PROTECT)
|
||||
|
||||
current = models.BooleanField(default=False)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("membership type")
|
||||
verbose_name_plural = _("membership types")
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.name
|
||||
|
||||
def create_membership(self, user: User) -> Membership:
|
||||
"""Create a current membership for this type."""
|
||||
from .selectors import get_current_subscription_period
|
||||
|
||||
return Membership.objects.create(
|
||||
membership_type=self,
|
||||
user=user,
|
||||
period=get_current_subscription_period(),
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue