Start wiring BillingAddresses to bills & orders
This commit is contained in:
parent
3fa1d5753e
commit
0522927c50
3 changed files with 66 additions and 19 deletions
|
@ -440,6 +440,36 @@ class PaymentMethod(models.Model):
|
|||
###
|
||||
# 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):
|
||||
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
owner = models.ForeignKey(get_user_model(),
|
||||
|
@ -484,6 +514,7 @@ class Bill(models.Model):
|
|||
# A bill is final when its ending date is passed.
|
||||
return self.ending_date < timezone.now()
|
||||
|
||||
<<<<<<< HEAD
|
||||
def activate_products(self):
|
||||
for order in self.order_set.all():
|
||||
# FIXME: using __something might not be a good idea.
|
||||
|
@ -492,8 +523,12 @@ class Bill(models.Model):
|
|||
if product.status == UncloudStatus.AWAITING_PAYMENT:
|
||||
product.status = UncloudStatus.PENDING
|
||||
product.save()
|
||||
@property
|
||||
def billing_address(self):
|
||||
return self.order.billing_address
|
||||
|
||||
@staticmethod
|
||||
|
||||
def generate_for(year, month, user):
|
||||
# /!\ We exclusively work on the specified year and month.
|
||||
generated_bills = []
|
||||
|
@ -704,17 +739,6 @@ class BillRecord():
|
|||
def amount(self):
|
||||
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.
|
||||
class VATRate(models.Model):
|
||||
start_date = models.DateField(blank=True, null=True)
|
||||
|
@ -725,6 +749,21 @@ class VATRate(models.Model):
|
|||
rate_type = 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.
|
||||
|
||||
|
@ -735,6 +774,7 @@ class Order(models.Model):
|
|||
owner = models.ForeignKey(get_user_model(),
|
||||
on_delete=models.CASCADE,
|
||||
editable=False)
|
||||
billing_address = models.ForeignKey(BillingAddress, on_delete=models.CASCADE)
|
||||
|
||||
# TODO: enforce ending_date - starting_date to be larger than recurring_period.
|
||||
creation_date = models.DateTimeField(auto_now_add=True)
|
||||
|
|
|
@ -57,18 +57,19 @@ class BillRecordSerializer(serializers.Serializer):
|
|||
view_name='order-detail',
|
||||
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):
|
||||
billing_address = BillingAddressSerializer(read_only=True)
|
||||
records = BillRecordSerializer(many=True, read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = Bill
|
||||
fields = ['reference', 'owner', 'total', 'due_date', 'creation_date',
|
||||
'starting_date', 'ending_date', 'records', 'final']
|
||||
|
||||
class BillingAddressSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = BillingAddress
|
||||
fields = ['uuid', 'street', 'city', 'postal_code', 'country', 'vat_number']
|
||||
'starting_date', 'ending_date', 'records', 'final', 'billing_address']
|
||||
|
||||
# We do not want users to mutate the country / VAT number of an address, as it
|
||||
# will change VAT on existing bills.
|
||||
|
|
|
@ -2,7 +2,7 @@ from rest_framework import serializers
|
|||
from .models import *
|
||||
from uncloud_vm.serializers import ManagedVMProductSerializer
|
||||
from uncloud_vm.models import VMProduct
|
||||
from uncloud_pay.models import RecurringPeriod
|
||||
from uncloud_pay.models import RecurringPeriod, BillingAddress
|
||||
|
||||
class MatrixServiceProductSerializer(serializers.ModelSerializer):
|
||||
vm = ManagedVMProductSerializer()
|
||||
|
@ -11,9 +11,15 @@ class MatrixServiceProductSerializer(serializers.ModelSerializer):
|
|||
recurring_period = serializers.ChoiceField(
|
||||
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:
|
||||
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']
|
||||
|
||||
class GenericServiceProductSerializer(serializers.ModelSerializer):
|
||||
|
|
Loading…
Reference in a new issue