diff --git a/uncloud_pay/migrations/0011_bill_billing_address.py b/uncloud_pay/migrations/0011_bill_billing_address.py new file mode 100644 index 0000000..e13e7b3 --- /dev/null +++ b/uncloud_pay/migrations/0011_bill_billing_address.py @@ -0,0 +1,19 @@ +# Generated by Django 3.1 on 2020-08-09 10:24 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('uncloud_pay', '0010_auto_20200809_0856'), + ] + + operations = [ + migrations.AddField( + model_name='bill', + name='billing_address', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='uncloud_pay.billingaddress'), + ), + ] diff --git a/uncloud_pay/migrations/0012_auto_20200809_1026.py b/uncloud_pay/migrations/0012_auto_20200809_1026.py new file mode 100644 index 0000000..dff0e78 --- /dev/null +++ b/uncloud_pay/migrations/0012_auto_20200809_1026.py @@ -0,0 +1,19 @@ +# Generated by Django 3.1 on 2020-08-09 10:26 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('uncloud_pay', '0011_bill_billing_address'), + ] + + operations = [ + migrations.AlterField( + model_name='bill', + name='billing_address', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='uncloud_pay.billingaddress'), + ), + ] diff --git a/uncloud_pay/models.py b/uncloud_pay/models.py index 4005908..5d69523 100644 --- a/uncloud_pay/models.py +++ b/uncloud_pay/models.py @@ -347,6 +347,11 @@ class Order(models.Model): def is_one_time(self): return not self.is_recurring + def replace_with(self, new_order): + new_order.replaces = self + self.ending_date = new_order.starting_date - datetime.timedelta(seconds=1) + self.save() + def save(self, *args, **kwargs): if self.ending_date and self.ending_date < self.starting_date: @@ -395,6 +400,13 @@ class Bill(models.Model): ending_date = models.DateTimeField() due_date = models.DateField(default=default_payment_delay) + + billing_address = models.ForeignKey(BillingAddress, + on_delete=models.CASCADE, + editable=True, + null=False) + # FIXME: editable=True -> is in the admin, but also editable in DRF + is_final = models.BooleanField(default=False) class Meta: @@ -408,10 +420,13 @@ class Bill(models.Model): def __str__(self): return f"Bill {self.owner}-{self.id}" - @property - def billing_address(self): - pass -# if self.order_set.all + def close(self): + """ + Close/finish a bill + """ + + self.is_final = True + self.save() @property def sum(self): @@ -420,12 +435,26 @@ class Bill(models.Model): @classmethod - def create_next_bill_for_user(cls, owner, ending_date=None): - last_bill = cls.objects.filter(owner=owner).order_by('id').last() + def create_next_bills_for_user(cls, owner, ending_date=None): + """ + Create one bill per billing address, as the VAT rates might be different + for each address + """ + + bills = [] + + for billing_address in BillingAddress.objects.filter(owner=owner): + bills.append(cls.create_next_bill_for_user_address(owner, billing_address, ending_date)) + + return bills + + @classmethod + def create_next_bill_for_user_address(cls, owner, billing_address, ending_date=None): + 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).order_by('id') + all_orders = Order.objects.filter(owner=owner, billing_address=billing_address).order_by('id') first_order = all_orders.first() bill = None @@ -452,7 +481,8 @@ class Bill(models.Model): bill = cls.objects.create( owner=owner, starting_date=starting_date, - ending_date=ending_date) + ending_date=ending_date, + billing_address=billing_address) for order in all_orders: if order.is_one_time: @@ -557,23 +587,6 @@ class Bill(models.Model): cls.create_next_bill_for_user(owner) - # for order in Order.objects.filter(Q(starting_date__gte=self.starting_date), - # Q(starting_date__lte=self.ending_date), - - #for order in Order.objects.filter(owner=owner, - # bill_records=None): - - # For each recurring order get the usage and bill it - - - def close(self): - """ - Close/finish a bill - """ - - self.is_final = True - self.save() - class BillRecord(models.Model): """ Entry of a bill, dynamically generated from an order. @@ -657,8 +670,6 @@ class Product(UncloudModel): one_time_order = None if recurring_period != RecurringPeriod.ONE_TIME: - print("not one time") - if one_time_order: recurring_order = Order.objects.create(owner=self.owner, billing_address=billing_address, @@ -700,15 +711,6 @@ class Product(UncloudModel): self.order = new_order - -# def save(self, *args, **kwargs): - # if not self.order: - # raise ValidationError("Cannot create product without order") - -# self.create_or_update_order() - -# super().save(*args, **kwargs) - @property def recurring_price(self): """ implement correct values in the child class """ @@ -724,9 +726,6 @@ class Product(UncloudModel): def is_recurring(self): return self.recurring_price > 0 - # on is_one_time as this should be has_one_time which is the same as > 0 again... - - @property def billing_address(self): return self.order.billing_address diff --git a/uncloud_pay/templates/bill.html.j2 b/uncloud_pay/templates/bill.html.j2 index 456e4a6..d5993ae 100644 --- a/uncloud_pay/templates/bill.html.j2 +++ b/uncloud_pay/templates/bill.html.j2 @@ -674,7 +674,7 @@ oAsAAAAAAACGQNAFAAAAAAAAQyDoAgAAAAAAgCEQdAEAAAAAAMAQCLoAAAAAAABgCP83AL6WQ1Y7