LDAP Integration
This commit is contained in:
parent
8ca5b2d104
commit
02ad7a9441
26 changed files with 425 additions and 191 deletions
22
uncloud_pay/migrations/0031_auto_20210819_1304.py
Normal file
22
uncloud_pay/migrations/0031_auto_20210819_1304.py
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# Generated by Django 3.2.4 on 2021-08-19 13:04
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('uncloud_pay', '0030_pricingplan_monthly_maintenance_fees'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='bill',
|
||||
name='is_closed',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='bill',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('new', 'New'), ('cancelled', 'Cancelled'), ('paid', 'Paid')], default='new', max_length=32),
|
||||
),
|
||||
]
|
||||
|
|
@ -27,6 +27,12 @@ from .services import *
|
|||
# Used to generate bill due dates.
|
||||
BILL_PAYMENT_DELAY=datetime.timedelta(days=settings.BILL_PAYMENT_DELAY)
|
||||
|
||||
EU_COUNTRIES = ['at', 'be', 'bg', 'ch', 'cy', 'cz', 'hr', 'dk',
|
||||
'ee', 'fi', 'fr', 'mc', 'de', 'gr', 'hu', 'ie', 'it',
|
||||
'lv', 'lu', 'mt', 'nl', 'po', 'pt', 'ro','sk', 'si', 'es',
|
||||
'se', 'gb']
|
||||
|
||||
|
||||
# Initialize logger.
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -254,41 +260,26 @@ class VATRate(models.Model):
|
|||
description = models.TextField(blank=True, default='')
|
||||
|
||||
@staticmethod
|
||||
def get_for_country(country_code):
|
||||
vat_rate = None
|
||||
try:
|
||||
vat_rate = VATRate.objects.get(
|
||||
territory_codes=country_code, start_date__isnull=False, stop_date=None
|
||||
)
|
||||
return vat_rate.rate
|
||||
except VATRate.DoesNotExist as dne:
|
||||
logger.debug(str(dne))
|
||||
logger.debug("Did not find VAT rate for %s, returning 0" % country_code)
|
||||
return 0
|
||||
|
||||
@staticmethod
|
||||
def get_vat_rate(billing_address, when=None):
|
||||
def get_vat_rate_for_country(country, when=None):
|
||||
"""
|
||||
Returns the VAT rate for business to customer.
|
||||
|
||||
B2B is always 0% with the exception of trading within the own country
|
||||
"""
|
||||
|
||||
country = billing_address.country
|
||||
|
||||
# Need to have a provider country
|
||||
providers = UncloudProvider.objects.all()
|
||||
vatrate = filter_for_when(VATRate.objects.filter(territory_codes=country), when).first()
|
||||
|
||||
if not providers and not vatrate:
|
||||
return 0
|
||||
|
||||
uncloud_provider = filter_for_when(providers).get()
|
||||
|
||||
# By default we charge VAT. This affects:
|
||||
# - Same country sales (VAT applied)
|
||||
# - B2C to EU (VAT applied)
|
||||
rate = vatrate.rate if vatrate else 0
|
||||
if not country.lower().strip() in EU_COUNTRIES:
|
||||
rate = 0
|
||||
|
||||
return rate
|
||||
|
||||
@staticmethod
|
||||
def get_vat_rate(billing_address, when=None):
|
||||
rate = VATRate.get_vat_rate_for_country(billing_address.country, when)
|
||||
|
||||
# Exception: if...
|
||||
# - the billing_address is in EU,
|
||||
|
|
@ -296,7 +287,7 @@ class VATRate(models.Model):
|
|||
# - the vat_number has been verified
|
||||
# Then we do not charge VAT
|
||||
|
||||
if uncloud_provider.country != country and billing_address.vat_number and billing_address.vat_number_verified:
|
||||
if rate != 0 and billing_address.vat_number and billing_address.vat_number_verified:
|
||||
rate = 0
|
||||
return rate
|
||||
|
||||
|
|
@ -408,7 +399,7 @@ class Product(models.Model):
|
|||
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.name} - {self.description}"
|
||||
return f"{self.name}"
|
||||
|
||||
@property
|
||||
def recurring_orders(self):
|
||||
|
|
@ -1010,7 +1001,11 @@ class Bill(models.Model):
|
|||
# FIXME: editable=True -> is in the admin, but also editable in DRF
|
||||
# Maybe filter fields in the serializer?
|
||||
|
||||
is_closed = models.BooleanField(default=False)
|
||||
status = models.CharField(max_length=32, choices= (
|
||||
('new', 'New'),
|
||||
('cancelled', 'Cancelled'),
|
||||
('paid', 'Paid')
|
||||
), null=False, blank=False, default="new")
|
||||
|
||||
class Meta:
|
||||
constraints = [
|
||||
|
|
@ -1020,11 +1015,11 @@ class Bill(models.Model):
|
|||
name='one_bill_per_month_per_user')
|
||||
]
|
||||
|
||||
def close(self):
|
||||
def close(self, status):
|
||||
"""
|
||||
Close/finish a bill
|
||||
"""
|
||||
self.is_closed = True
|
||||
self.status = status
|
||||
if not self.ending_date:
|
||||
self.ending_date = timezone.now()
|
||||
self.save()
|
||||
|
|
@ -1120,7 +1115,7 @@ class Bill(models.Model):
|
|||
|
||||
# Get date & bill from previous bill, if it exists
|
||||
if last_bill:
|
||||
if not last_bill.is_closed:
|
||||
if last_bill.status == 'new':
|
||||
bill = last_bill
|
||||
starting_date = last_bill.starting_date
|
||||
ending_date = bill.ending_date
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ class BillSerializer(serializers.ModelSerializer):
|
|||
model = Bill
|
||||
fields = ['owner', 'sum', 'vat_rate',
|
||||
'due_date', 'creation_date', 'starting_date', 'ending_date',
|
||||
'records', 'is_closed', 'billing_address']
|
||||
'records', 'status', 'billing_address']
|
||||
|
||||
# We do not want users to mutate the country / VAT number of an address, as it
|
||||
# will change VAT on existing bills.
|
||||
|
|
|
|||
|
|
@ -425,7 +425,7 @@ class BillTestCase(TestCase):
|
|||
self.assertEqual(record.quantity, 1)
|
||||
self.assertEqual(record.sum, 35)
|
||||
#close the bill as it has been paid
|
||||
bill.close()
|
||||
bill.close(status="paid")
|
||||
bill2 = Bill.create_next_bill_for_user_address(self.user_addr)
|
||||
self.assertNotEqual(bill.id, bill2.id)
|
||||
self.assertEqual(order.billrecord_set.count(), 2)
|
||||
|
|
@ -483,7 +483,7 @@ class BillTestCase(TestCase):
|
|||
|
||||
for ending_date in self.bill_dates:
|
||||
b = Bill.create_next_bill_for_user_address(self.recurring_user_addr, ending_date)
|
||||
b.close()
|
||||
b.close(status="paid")
|
||||
|
||||
bill_count = Bill.objects.filter(owner=self.recurring_user).count()
|
||||
|
||||
|
|
@ -519,14 +519,28 @@ class VATRatesTestCase(TestCase):
|
|||
street="unknown",
|
||||
city="unknown",
|
||||
postal_code="unknown",
|
||||
country="CH",
|
||||
active=True)
|
||||
|
||||
UncloudNetwork.populate_db_defaults()
|
||||
UncloudProvider.populate_db_defaults()
|
||||
|
||||
VATRate.objects.create(territory_codes="CH", currency_code="CHF", rate=7.7,
|
||||
starting_date=timezone.make_aware(datetime.datetime(2000,1,1)))
|
||||
|
||||
|
||||
|
||||
def test_get_rate_for_user(self):
|
||||
"""
|
||||
Raise an error, when there is no address
|
||||
"""
|
||||
rate = VATRate.get_vat_rate(self.user_addr)
|
||||
self.assertEqual(rate, 7.7)
|
||||
self.user_addr.vat_number_verified = True
|
||||
self.user_addr.vat_number = "11111"
|
||||
rate1 = VATRate.get_vat_rate(self.user_addr)
|
||||
self.assertEqual(rate1, 0)
|
||||
rate2 = VATRate.get_vat_rate_for_country('CH')
|
||||
self.assertEqual(rate, 7.7)
|
||||
rate2 = VATRate.get_vat_rate_for_country('EG')
|
||||
self.assertEqual(rate2, 0)
|
||||
|
|
|
|||
|
|
@ -41,11 +41,16 @@ class PricingView(View):
|
|||
vat_rate = False
|
||||
vat_validation_status = False
|
||||
address = False
|
||||
selected_country = request.GET.get('country', False)
|
||||
if self.request.user and self.request.user.is_authenticated:
|
||||
address = get_billing_address_for_user(self.request.user)
|
||||
if address:
|
||||
address = get_billing_address_for_user(self.request.user)
|
||||
if address and (address.country == selected_country or not selected_country):
|
||||
vat_rate = VATRate.get_vat_rate(address)
|
||||
vat_validation_status = "verified" if address.vat_number_validated_on and address.vat_number_verified else False
|
||||
elif selected_country:
|
||||
vat_rate = VATRate.get_vat_rate_for_country(selected_country)
|
||||
vat_validation_status = False
|
||||
|
||||
pricing = get_order_total_with_vat(
|
||||
request.GET.get('cores'),
|
||||
request.GET.get('memory'),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue