Implement ending/replacing date logic
This commit is contained in:
parent
9211894b23
commit
18f9a3848a
2 changed files with 49 additions and 5 deletions
|
@ -57,6 +57,10 @@ def end_before(a_date):
|
||||||
""" Return suitable datetimefield for ending just before a_date """
|
""" Return suitable datetimefield for ending just before a_date """
|
||||||
return a_date - datetime.timedelta(seconds=1)
|
return a_date - datetime.timedelta(seconds=1)
|
||||||
|
|
||||||
|
def start_after(a_date):
|
||||||
|
""" Return suitable datetimefield for starting just after a_date """
|
||||||
|
return a_date + datetime.timedelta(seconds=1)
|
||||||
|
|
||||||
def default_payment_delay():
|
def default_payment_delay():
|
||||||
return timezone.now() + BILL_PAYMENT_DELAY
|
return timezone.now() + BILL_PAYMENT_DELAY
|
||||||
|
|
||||||
|
@ -333,6 +337,24 @@ class Order(models.Model):
|
||||||
|
|
||||||
return self.starting_date + datetime.timedelta(seconds=self.recurring_period)
|
return self.starting_date + datetime.timedelta(seconds=self.recurring_period)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def next_ending_date(self):
|
||||||
|
"""
|
||||||
|
Return the next proper ending date after n times the
|
||||||
|
recurring_period, where n is an integer.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if self.recurring_period > 0:
|
||||||
|
now = timezone.now()
|
||||||
|
delta = now - self.starting_date
|
||||||
|
|
||||||
|
num_times = math.ceil(delta.total_seconds() / self.recurring_period)
|
||||||
|
|
||||||
|
next_date = self.starting_date + datetime.timedelta(seconds= num_times * self.recurring_period)
|
||||||
|
else:
|
||||||
|
next_date = self.starting_date
|
||||||
|
|
||||||
|
return next_date
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def count_billed(self):
|
def count_billed(self):
|
||||||
|
@ -698,7 +720,6 @@ class Product(UncloudModel):
|
||||||
|
|
||||||
|
|
||||||
def create_or_update_recurring_order(self, when_to_start=None, recurring_period=None):
|
def create_or_update_recurring_order(self, when_to_start=None, recurring_period=None):
|
||||||
|
|
||||||
if not self.recurring_price:
|
if not self.recurring_price:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -709,6 +730,13 @@ class Product(UncloudModel):
|
||||||
when_to_start = timezone.now()
|
when_to_start = timezone.now()
|
||||||
|
|
||||||
if self.last_recurring_order:
|
if self.last_recurring_order:
|
||||||
|
# If the new order is less in value than the previous
|
||||||
|
# order, the previous order needs to be finished first
|
||||||
|
if self.recurring_price < self.last_recurring_order.price:
|
||||||
|
|
||||||
|
if when_to_start < self.last_recurring_order.next_ending_date:
|
||||||
|
when_to_start = start_after(self.last_recurring_order.next_ending_date)
|
||||||
|
|
||||||
when_to_end = end_before(when_to_start)
|
when_to_end = end_before(when_to_start)
|
||||||
|
|
||||||
new_order = Order.objects.create(owner=self.owner,
|
new_order = Order.objects.create(owner=self.owner,
|
||||||
|
|
|
@ -416,7 +416,7 @@ class ModifyProductTestCase(TestCase):
|
||||||
|
|
||||||
def test_bill_for_modified_product(self):
|
def test_bill_for_modified_product(self):
|
||||||
"""
|
"""
|
||||||
The bill should NOT contain a partial amount -- this is a BILL TEST :-)
|
Modify a product, see one pro rata entry
|
||||||
"""
|
"""
|
||||||
|
|
||||||
price = 5
|
price = 5
|
||||||
|
@ -429,16 +429,32 @@ class ModifyProductTestCase(TestCase):
|
||||||
ending_date = timezone.make_aware(datetime.datetime(2019,3,31))
|
ending_date = timezone.make_aware(datetime.datetime(2019,3,31))
|
||||||
change_date = timezone.make_aware(datetime.datetime(2019,4,17))
|
change_date = timezone.make_aware(datetime.datetime(2019,4,17))
|
||||||
|
|
||||||
product.create_order(starting_date)
|
bill_ending_date = timezone.make_aware(datetime.datetime(2019,4,30))
|
||||||
|
|
||||||
bills = Bill.create_next_bills_for_user(self.user,
|
product.create_order(starting_date)
|
||||||
ending_date=ending_date)
|
|
||||||
|
|
||||||
product.rc_price = 10
|
product.rc_price = 10
|
||||||
product.save()
|
product.save()
|
||||||
|
|
||||||
product.create_or_update_recurring_order(when_to_start=change_date)
|
product.create_or_update_recurring_order(when_to_start=change_date)
|
||||||
|
|
||||||
|
bills = Bill.create_next_bills_for_user(self.user,
|
||||||
|
ending_date=bill_ending_date)
|
||||||
|
|
||||||
|
# Sum:
|
||||||
|
# recurring1 = 5 CHF -> for 30days
|
||||||
|
# recurring2 = 5 CHF -> from 3rd of April to 3rd of May
|
||||||
|
# recurring3 = 10 CHF -> from 17th of April to ... 17th of May?
|
||||||
|
|
||||||
|
# If replacing lower order with higher:
|
||||||
|
# - close the lower order NOW
|
||||||
|
# - start higher order NOW+1s
|
||||||
|
# If replacing higher order with lower order:
|
||||||
|
# higher order continues until its end
|
||||||
|
# lower order starts after higher order+1s
|
||||||
|
|
||||||
|
self.assertEqual(bills[0].sum, price)
|
||||||
|
|
||||||
# expeted result:
|
# expeted result:
|
||||||
# 1x 5 chf bill record
|
# 1x 5 chf bill record
|
||||||
# 1x 5 chf bill record
|
# 1x 5 chf bill record
|
||||||
|
|
Loading…
Reference in a new issue