model changes

Signed-off-by: Nico Schottelius <nico@nico-notebook.schottelius.org>
This commit is contained in:
Nico Schottelius 2020-08-04 11:26:42 +02:00
parent e563780142
commit 2ce667e8c7

View file

@ -254,8 +254,8 @@ class BillingAddress(models.Model):
# VAT # VAT
class VATRate(models.Model): class VATRate(models.Model):
start_date = models.DateField(blank=True, null=True) starting_date = models.DateField(blank=True, null=True)
stop_date = models.DateField(blank=True, null=True) ending_date = models.DateField(blank=True, null=True)
territory_codes = models.TextField(blank=True, default='') territory_codes = models.TextField(blank=True, default='')
currency_code = models.CharField(max_length=10) currency_code = models.CharField(max_length=10)
rate = models.FloatField() rate = models.FloatField()
@ -324,7 +324,6 @@ class Order(models.Model):
null=True) null=True)
@property @property
def count_billed(self): def count_billed(self):
""" """
@ -345,6 +344,7 @@ class Order(models.Model):
@property @property
def is_recurring(self): def is_recurring(self):
return not self.recurring_period == RecurringPeriod.ONE_TIME return not self.recurring_period == RecurringPeriod.ONE_TIME
@property @property
def is_terminated(self): def is_terminated(self):
return self.ending_date != None and self.ending_date < timezone.now() return self.ending_date != None and self.ending_date < timezone.now()
@ -367,73 +367,24 @@ class Order(models.Model):
def generate_initial_bill(self): def generate_initial_bill(self):
return Bill.generate_for(self.starting_date.year, self.starting_date.month, self.owner) return Bill.generate_for(self.starting_date.year, self.starting_date.month, self.owner)
# Used by uncloud_pay tests.
@property
def bills(self):
return Bill.objects.filter(order=self)
@staticmethod
def from_product(product, **kwargs):
# FIXME: this is only a workaround.
billing_address = BillingAddress.get_preferred_address_for(product.owner)
if billing_address == None:
raise Exception("Owner does not have a billing address!")
return Order(description=product.description,
one_time_price=product.one_time_price,
recurring_price=product.recurring_price,
billing_address=billing_address,
owner=product.owner,
**kwargs)
@property @property
def records(self): def records(self):
return OrderRecord.objects.filter(order=self) return OrderRecord.objects.filter(order=self)
# these are real fields!!!
# @property
# def one_time_price(self):
# return reduce(lambda acc, record: acc + record.one_time_price, self.records, 0)
# @property
# def recurring_price(self):
# return reduce(lambda acc, record: acc + record.recurring_price, self.records, 0)
# Used by uncloud_pay tests.
@property
def bills(self):
return Bill.objects.filter(order=self)
def add_record(self, one_time_price, recurring_price, description):
OrderRecord.objects.create(order=self,
one_time_price=one_time_price,
recurring_price=recurring_price,
description=description)
def __str__(self): def __str__(self):
return f"Order {self.owner}-{self.id}" return f"Order {self.owner}-{self.id}"
# return "{} created at {}, {}->{}, recurring period {}. One time price {}, recurring price {}".format(
# self.id, self.creation_date,
# self.starting_date, self.ending_date,
# self.recurring_period,
# self.one_time_price,
# self.recurring_price)
class Bill(models.Model): class Bill(models.Model):
owner = models.ForeignKey(get_user_model(), owner = models.ForeignKey(get_user_model(),
on_delete=models.CASCADE) on_delete=models.CASCADE)
creation_date = models.DateTimeField(auto_now_add=True) creation_date = models.DateTimeField(auto_now_add=True)
# FIXME: this is a race condition, if ending_date is evaluated
# in the next month the bill spawns two months!
starting_date = models.DateTimeField(default=start_of_this_month) starting_date = models.DateTimeField(default=start_of_this_month)
ending_date = models.DateTimeField(default=end_of_this_month) ending_date = models.DateTimeField()
due_date = models.DateField(default=default_payment_delay) due_date = models.DateField(default=default_payment_delay)
# what is valid for? should this be "final"?
valid = models.BooleanField(default=True) valid = models.BooleanField(default=True)
# Mapping to BillRecords # Mapping to BillRecords
@ -448,15 +399,34 @@ class Bill(models.Model):
name='one_bill_per_month_per_user') name='one_bill_per_month_per_user')
] ]
# billing address and vat rate is the same for the whole bill
# @property
# def vat_rate(self):
# return Decimal(VATRate.get_for_country(self.bill.billing_address.country))
def __str__(self): def __str__(self):
return f"Bill {self.owner}-{self.id}" return f"Bill {self.owner}-{self.id}"
@classmethod
def create_next_bill_for_user(cls, user):
last_bill = cls.objects.filter(owner=user).order_by('id').last()
all_orders = Order.objects.filter(owner=user).order_by('id')
first_order = all_orders.first()
# Calculate the start date
if last_bill:
starting_date = last_bill.end_date + datetime.timedelta(seconds=1)
else:
if first_order:
starting_date = first_order.starting_date
else:
starting_date = timezone.now()
ending_date = end_of_month(starting_date)
for order in all_orders:
# check if order needs to be billed
# check if order has previous billing record
pass
@classmethod @classmethod
def create_all_bills(cls): def create_all_bills(cls):
for owner in get_user_model().objects.all(): for owner in get_user_model().objects.all():
@ -539,10 +509,11 @@ class BillRecord(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE) order = models.ForeignKey(Order, on_delete=models.CASCADE)
# How many times the order has been used in this record # How many times the order has been used in this record
quantity = models.IntegerField(default=1) quantity = models.DecimalField(max_digits=19, decimal_places=10)
# The timeframe the bill record is for can (and probably often will) differ # The timeframe the bill record is for can (and probably often will) differ
# from the bill time # from the bill time
creation_date = models.DateTimeField(auto_now_add=True) creation_date = models.DateTimeField(auto_now_add=True)
starting_date = models.DateTimeField() starting_date = models.DateTimeField()
ending_date = models.DateTimeField() ending_date = models.DateTimeField()