diff --git a/uncloud_pay/models.py b/uncloud_pay/models.py index ebc1c09..781cd95 100644 --- a/uncloud_pay/models.py +++ b/uncloud_pay/models.py @@ -254,8 +254,8 @@ class BillingAddress(models.Model): # VAT class VATRate(models.Model): - start_date = models.DateField(blank=True, null=True) - stop_date = models.DateField(blank=True, null=True) + starting_date = models.DateField(blank=True, null=True) + ending_date = models.DateField(blank=True, null=True) territory_codes = models.TextField(blank=True, default='') currency_code = models.CharField(max_length=10) rate = models.FloatField() @@ -324,7 +324,6 @@ class Order(models.Model): null=True) - @property def count_billed(self): """ @@ -345,6 +344,7 @@ class Order(models.Model): @property def is_recurring(self): return not self.recurring_period == RecurringPeriod.ONE_TIME + @property def is_terminated(self): return self.ending_date != None and self.ending_date < timezone.now() @@ -367,73 +367,24 @@ class Order(models.Model): def generate_initial_bill(self): 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 def records(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): 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): owner = models.ForeignKey(get_user_model(), on_delete=models.CASCADE) 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) - ending_date = models.DateTimeField(default=end_of_this_month) + ending_date = models.DateTimeField() due_date = models.DateField(default=default_payment_delay) + # what is valid for? should this be "final"? valid = models.BooleanField(default=True) # Mapping to BillRecords @@ -448,15 +399,34 @@ class Bill(models.Model): 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): 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 def create_all_bills(cls): for owner in get_user_model().objects.all(): @@ -539,10 +509,11 @@ class BillRecord(models.Model): order = models.ForeignKey(Order, on_delete=models.CASCADE) # 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 # from the bill time + creation_date = models.DateTimeField(auto_now_add=True) starting_date = models.DateTimeField() ending_date = models.DateTimeField()