begin splitting bill record creation function

This commit is contained in:
Nico Schottelius 2020-09-02 16:02:28 +02:00
commit 1c7d81762d
3 changed files with 185 additions and 52 deletions

View file

@ -459,19 +459,121 @@ class Bill(models.Model):
return bills
@classmethod
def create_next_bill_for_user_address(cls, owner, billing_address, ending_date=None):
def create_bill_records_for_recurring_orders(cls, bill):
"""
Create or update bill records for recurring orders for the
given bill
"""
owner = bill.owner
billing_address = bill.billing_address
all_orders = Order.objects.filter(owner=owner,
billing_address=billing_address).order_by('id').exclude(recurring_period=RecurringPeriod.ONE_TIME)
for order in all_orders:
bill_record_for_this_bill = BillRecord.objects.filter(bill=bill,
order=order).first()
if bill_record_for_this_bill:
cls.update_bill_record_for_this_bill(bill_record_for_this_bill,
order,
bill)
else:
cls.create_new_bill_record_for_this_bill(order, bill)
@staticmethod
def create_new_bill_record_for_this_bill(order, bill):
last_bill_record = BillRecord.objects.filter(order=order).order_by('id').last()
this_starting_date=order.starting_date
if last_bill_record:
if last_bill_record.ending_date >= bill.ending_date:
return
if order.ending_date:
if last_bill_record.ending_date == order.ending_date:
return
this_starting_date = start_after(last_bill_record.ending_date)
ending_date = cls.get_bill_record_ending_date(order, bill)
return BillRecord.objects.create(bill=bill,
order=order,
starting_date=this_starting_date,
ending_date=this_ending_date)
@staticmethod
def update_bill_record_for_this_bill(bill_record,
order,
bill):
# we may need to adjust it, but let's do this logic another time
# If the order has an ending date set, we might need to adjust the bill_record
if order.ending_date:
if bill_record_for_this_bill.ending_date != order.ending_date:
bill_record_for_this_bill.ending_date = order.ending_date
else:
# recurring, not terminated, should go until at least end of bill
if bill_record_for_this_bill.ending_date < bill.ending_date:
bill_record_for_this_bill.ending_date = bill.ending_date
bill_record_for_this_bill.save()
@staticmethod
def get_bill_record_ending_date(order, bill):
"""
Determine the ending date of the billing record
"""
# If the order is quit, charge the final amount (?)
if order.ending_date:
this_ending_date = order.ending_date
else:
if order.earliest_ending_date > bill.ending_date:
this_ending_date = order.earliest_ending_date
else:
this_ending_date = bill.ending_date
return this_ending_date
@classmethod
def create_next_bill_for_user_address(cls,
owner,
billing_address,
ending_date=None):
"""
Filtering ideas (TBD):
If order is replaced, it should not be added anymore if it has been billed "last time"
If order has ended and finally charged, do not charge anymore
Find out the last billrecord for the order, if there is none, bill from the starting date
"""
last_bill = cls.objects.filter(owner=owner, billing_address=billing_address).order_by('id').last()
# it is important to sort orders here, as bill records will be
# created (and listed) in this order
all_orders = Order.objects.filter(owner=owner, billing_address=billing_address).order_by('id')
all_orders = Order.objects.filter(owner=owner,
billing_address=billing_address).order_by('id')
first_order = all_orders.first()
bill = None
ending_date = None
# Get date & bill from previous bill
# Get date & bill from previous bill, if it exists
if last_bill:
if not last_bill.is_final:
bill = last_bill
@ -504,12 +606,10 @@ class Bill(models.Model):
starting_date=order.starting_date,
ending_date=order.ending_date)
else:
# Bill all recurring orders
else: # recurring orders
bill_record_for_this_bill = BillRecord.objects.filter(bill=bill,
order=order).first()
# This bill already has a bill record for the order
# We potentially need to update the ending_date if the ending_date
# of the bill changed.
@ -529,11 +629,8 @@ class Bill(models.Model):
bill_record_for_this_bill.save()
else:
# No bill record in this bill for the order yet
# Find out whether it was already billed for the billing period of
# this bill
else: # No bill record in this bill for this order yet
# Find out when billed last time
last_bill_record = BillRecord.objects.filter(order=order).order_by('id').last()
# Default starting date
@ -580,12 +677,6 @@ class Bill(models.Model):
# Filtering ideas:
# If order is replaced, it should not be added anymore if it has been billed "last time"
# If order has ended and finally charged, do not charge anymore
# Find out the last billrecord for the order, if there is none, bill from the starting date
return bill
@ -730,8 +821,6 @@ class Product(UncloudModel):
when_to_start = timezone.now()
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: