Start wiring BillingAddresses to bills & orders

This commit is contained in:
fnux 2020-04-18 08:30:45 +02:00
parent 3fa1d5753e
commit 0522927c50
3 changed files with 66 additions and 19 deletions

View file

@ -440,6 +440,36 @@ class PaymentMethod(models.Model):
### ###
# Bills. # Bills.
class BillingAddress(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
owner = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
name = models.CharField(max_length=100)
street = models.CharField(max_length=100)
city = models.CharField(max_length=50)
postal_code = models.CharField(max_length=50)
country = CountryField(blank=True)
vat_number = models.CharField(max_length=100, default="", blank=True)
@staticmethod
def get_addresses_for(user):
return BillingAddress.objects.filter(owner=user)
@staticmethod
def get_preferred_address_for(user):
addresses = get_addresses_for(user)
if len(addresses) == 0:
return None
else:
# TODO: allow user to set primary/preferred address
return addresses[0]
def __str__(self):
return "{}, {}, {} {}, {}".format(
self.name, self.street, self.postal_code, self.city,
self.country)
class Bill(models.Model): class Bill(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
owner = models.ForeignKey(get_user_model(), owner = models.ForeignKey(get_user_model(),
@ -484,6 +514,7 @@ class Bill(models.Model):
# A bill is final when its ending date is passed. # A bill is final when its ending date is passed.
return self.ending_date < timezone.now() return self.ending_date < timezone.now()
<<<<<<< HEAD
def activate_products(self): def activate_products(self):
for order in self.order_set.all(): for order in self.order_set.all():
# FIXME: using __something might not be a good idea. # FIXME: using __something might not be a good idea.
@ -492,8 +523,12 @@ class Bill(models.Model):
if product.status == UncloudStatus.AWAITING_PAYMENT: if product.status == UncloudStatus.AWAITING_PAYMENT:
product.status = UncloudStatus.PENDING product.status = UncloudStatus.PENDING
product.save() product.save()
@property
def billing_address(self):
return self.order.billing_address
@staticmethod @staticmethod
def generate_for(year, month, user): def generate_for(year, month, user):
# /!\ We exclusively work on the specified year and month. # /!\ We exclusively work on the specified year and month.
generated_bills = [] generated_bills = []
@ -704,17 +739,6 @@ class BillRecord():
def amount(self): def amount(self):
return Decimal(float(self.recurring_price) * self.recurring_count) + self.one_time_price return Decimal(float(self.recurring_price) * self.recurring_count) + self.one_time_price
class BillingAddress(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
owner = models.ForeignKey(get_user_model(),
on_delete=models.CASCADE)
street = models.CharField(max_length=100)
city = models.CharField(max_length=50)
postal_code = models.CharField(max_length=50)
country = CountryField(blank=True)
vat_number = models.CharField(max_length=100, default="", blank=True)
# Populated with the import-vat-numbers django command. # Populated with the import-vat-numbers django command.
class VATRate(models.Model): class VATRate(models.Model):
start_date = models.DateField(blank=True, null=True) start_date = models.DateField(blank=True, null=True)
@ -725,6 +749,21 @@ class VATRate(models.Model):
rate_type = models.TextField(blank=True, default='') rate_type = models.TextField(blank=True, default='')
description = models.TextField(blank=True, default='') description = models.TextField(blank=True, default='')
@staticmethod
def get_for_country(country_code):
vat_rate = None
try:
vat_rate = VATRates.objects.get(
territory_codes=country, start_date__isnull=False, stop_date=None
)
logger.debug("VAT rate for %s is %s" % (country, vat_rate.rate))
return vat_rate.rate
except VATRates.DoesNotExist as dne:
logger.debug(str(dne))
logger.debug("Did not find VAT rate for %s, returning 0" % country)
return 0
### ###
# Orders. # Orders.
@ -735,6 +774,7 @@ class Order(models.Model):
owner = models.ForeignKey(get_user_model(), owner = models.ForeignKey(get_user_model(),
on_delete=models.CASCADE, on_delete=models.CASCADE,
editable=False) editable=False)
billing_address = models.ForeignKey(BillingAddress, on_delete=models.CASCADE)
# TODO: enforce ending_date - starting_date to be larger than recurring_period. # TODO: enforce ending_date - starting_date to be larger than recurring_period.
creation_date = models.DateTimeField(auto_now_add=True) creation_date = models.DateTimeField(auto_now_add=True)

View file

@ -57,18 +57,19 @@ class BillRecordSerializer(serializers.Serializer):
view_name='order-detail', view_name='order-detail',
read_only=True) read_only=True)
class BillingAddressSerializer(serializers.ModelSerializer):
class Meta:
model = BillingAddress
fields = ['uuid', 'name', 'street', 'city', 'postal_code', 'country', 'vat_number']
class BillSerializer(serializers.ModelSerializer): class BillSerializer(serializers.ModelSerializer):
billing_address = BillingAddressSerializer(read_only=True)
records = BillRecordSerializer(many=True, read_only=True) records = BillRecordSerializer(many=True, read_only=True)
class Meta: class Meta:
model = Bill model = Bill
fields = ['reference', 'owner', 'total', 'due_date', 'creation_date', fields = ['reference', 'owner', 'total', 'due_date', 'creation_date',
'starting_date', 'ending_date', 'records', 'final'] 'starting_date', 'ending_date', 'records', 'final', 'billing_address']
class BillingAddressSerializer(serializers.ModelSerializer):
class Meta:
model = BillingAddress
fields = ['uuid', 'street', 'city', 'postal_code', 'country', 'vat_number']
# We do not want users to mutate the country / VAT number of an address, as it # We do not want users to mutate the country / VAT number of an address, as it
# will change VAT on existing bills. # will change VAT on existing bills.

View file

@ -2,7 +2,7 @@ from rest_framework import serializers
from .models import * from .models import *
from uncloud_vm.serializers import ManagedVMProductSerializer from uncloud_vm.serializers import ManagedVMProductSerializer
from uncloud_vm.models import VMProduct from uncloud_vm.models import VMProduct
from uncloud_pay.models import RecurringPeriod from uncloud_pay.models import RecurringPeriod, BillingAddress
class MatrixServiceProductSerializer(serializers.ModelSerializer): class MatrixServiceProductSerializer(serializers.ModelSerializer):
vm = ManagedVMProductSerializer() vm = ManagedVMProductSerializer()
@ -11,9 +11,15 @@ class MatrixServiceProductSerializer(serializers.ModelSerializer):
recurring_period = serializers.ChoiceField( recurring_period = serializers.ChoiceField(
choices=MatrixServiceProduct.allowed_recurring_periods()) choices=MatrixServiceProduct.allowed_recurring_periods())
def __init__(self, *args, **kwargs):
super(MatrixServiceProductSerializer, self).__init__(*args, **kwargs)
self.fields['billing_address'] = serializers.ChoiceField(
choices=BillingAddress.get_addresses_for(self.context['request'].user))
class Meta: class Meta:
model = MatrixServiceProduct model = MatrixServiceProduct
fields = ['uuid', 'order', 'owner', 'status', 'vm', 'domain', 'recurring_period'] fields = ['uuid', 'order', 'owner', 'status', 'vm', 'domain',
'recurring_period']
read_only_fields = ['uuid', 'order', 'owner', 'status'] read_only_fields = ['uuid', 'order', 'owner', 'status']
class GenericServiceProductSerializer(serializers.ModelSerializer): class GenericServiceProductSerializer(serializers.ModelSerializer):