implement basic logic for updating a recurring order

Signed-off-by: Nico Schottelius <nico@nico-notebook.schottelius.org>
This commit is contained in:
Nico Schottelius 2020-08-27 14:45:37 +02:00
commit 9211894b23
2 changed files with 103 additions and 21 deletions

View file

@ -608,6 +608,20 @@ class BillRecord(models.Model):
# Products
class Product(UncloudModel):
"""
A product is something a user orders. To record the pricing, we
create order that define a state in time.
A product can *depend* on other products.
A product can have *one* one_time_order and/or *one*
recurring_order.
If either of them needs to be updated, a new order of the same
type will be created and links to the previous order.
"""
owner = models.ForeignKey(get_user_model(),
on_delete=models.CASCADE,
editable=False)
@ -623,7 +637,23 @@ class Product(UncloudModel):
# Default period for all products
default_recurring_period = RecurringPeriod.PER_30D
def create_order_at(self, when_to_start=None, recurring_period=None):
@property
def recurring_orders(self):
return self.orders.order_by('id').exclude(recurring_period=RecurringPeriod.ONE_TIME)
@property
def last_recurring_order(self):
return self.recurring_orders.last()
@property
def one_time_orders(self):
return self.orders.order_by('id').filter(recurring_period=RecurringPeriod.ONE_TIME)
@property
def last_one_time_order(self):
return self.one_time_orders.last()
def create_order(self, when_to_start=None, recurring_period=None):
billing_address = BillingAddress.get_address_for(self.owner)
if not billing_address:
@ -636,7 +666,8 @@ class Product(UncloudModel):
recurring_period = self.default_recurring_period
if self.one_time_price > 0:
# Create one time order if we did not create one already
if self.one_time_price > 0 and not self.last_one_time_order:
one_time_order = Order.objects.create(owner=self.owner,
billing_address=billing_address,
starting_date=when_to_start,
@ -667,32 +698,32 @@ class Product(UncloudModel):
def create_or_update_recurring_order(self, when_to_start=None, recurring_period=None):
if not self.recurring_price:
return
if not recurring_period:
recurring_period = self.default_recurring_period
if not when_to_start:
when_to_start = timezone.now()
# current_recurring_order = Order.objects.filter(
# NEXT: find the latest order, use that one...
# Update order = create new order
if self.order:
previous_order = self.order
if self.last_recurring_order:
when_to_end = end_before(when_to_start)
new_order = Order.objects.create(owner=self.owner,
billing_address=self.order.billing_address,
billing_address=self.last_recurring_order.billing_address,
starting_date=when_to_start,
price=self.recurring_price,
recurring_period=recurring_period,
description=str(self),
replaces=self.order)
print(new_order)
self.order.end_date = when_to_end
self.order.save()
self.order = new_order
replaces=self.last_recurring_order)
self.last_recurring_order.end_date = when_to_end
self.orders.add(new_order)
else:
return self.create_order_at(when_to_start, recurring_period)
# This might be a bug as it might (re-)create the one time order
self.create_order(when_to_start, recurring_period)
@property
def recurring_price(self):