- Added PricingPlan Model

- Implement a complete cycle for buying a Matrix Chat Host
- Refactor the Payement cycle and stripe related methods
This commit is contained in:
amalelshihaby 2021-07-19 16:36:10 +02:00 committed by Nico Schottelius
commit b7aa1c6971
81 changed files with 5079 additions and 810 deletions

View file

@ -5,52 +5,28 @@ from django.utils import timezone
from .models import *
from uncloud_service.models import GenericServiceProduct
from uncloud.models import UncloudProvider
from uncloud.models import UncloudProvider, UncloudNetwork
import json
chocolate_product_config = {
'features': {
'gramm':
{ 'min': 100,
'max': 5000,
'one_time_price_per_unit': 0.2,
'recurring_price_per_unit': 0
},
},
}
chocolate_order_config = {
'features': {
'gramm': 500,
}
}
chocolate_one_time_price = chocolate_order_config['features']['gramm'] * chocolate_product_config['features']['gramm']['one_time_price_per_unit']
vm_product_config = {
'features': {
'cores':
{ 'min': 1,
'max': 48,
'one_time_price_per_unit': 0,
'recurring_price_per_unit': 4
'max': 48
},
'ram_gb':
{ 'min': 1,
'max': 256,
'one_time_price_per_unit': 0,
'recurring_price_per_unit': 4
'max': 256
},
},
}
vm_order_config = {
'features': {
'cores': 2,
'ram_gb': 2
}
}
vm_order_config = json.dumps({
'cores': 1,
'memory': 2,
'storage': 100
})
vm_order_downgrade_config = {
'features': {
@ -87,12 +63,11 @@ class ProductTestCase(TestCase):
RecurringPeriod.populate_db_defaults()
self.default_recurring_period = RecurringPeriod.objects.get(name="Per 30 days")
def test_create_product(self):
"""
Create a sample product
"""
p = Product.objects.create(name="Testproduct",
description="Only for testing",
config=vm_product_config)
@ -107,6 +82,8 @@ class OrderTestCase(TestCase):
"""
def setUp(self):
self.pricing_plan = PricingPlan.objects.create(name="PricingSample", set_up_fees=35, cores_unit_price=3,
ram_unit_price=4, storage_unit_price=0.02)
self.user = get_user_model().objects.create(
username='random_user',
email='jane.random@domain.tld')
@ -135,23 +112,35 @@ class OrderTestCase(TestCase):
Order a products with a recurringperiod that is not added to the product
"""
order_config = json.dumps({
'cores': 1,
'memory':2,
'storage': 100
})
o = Order.objects.create(owner=self.user,
billing_address=self.ba,
pricing_plan = self.pricing_plan,
product=self.product,
config=vm_order_config)
config=order_config)
def test_order_product(self):
"""
Order a product, ensure the order has correct price setup
"""
order_config = json.dumps({
'cores': 1,
'memory':2,
'storage': 100
})
o = Order.objects.create(owner=self.user,
billing_address=self.ba,
product=self.product)
pricing_plan = self.pricing_plan,
product=self.product,
config=order_config)
self.assertEqual(o.one_time_price, 0)
self.assertEqual(o.recurring_price, 16)
self.assertEqual(o.recurring_price, 13.0)
def test_change_order(self):
"""
@ -159,14 +148,19 @@ class OrderTestCase(TestCase):
- a new order is created
- the price is correct in the new order
"""
order_config = json.dumps({
'cores': 2,
'memory':4,
'storage': 200
})
order1 = Order.objects.create(owner=self.user,
billing_address=self.ba,
pricing_plan = self.pricing_plan,
product=self.product,
config=vm_order_config)
config=order_config)
self.assertEqual(order1.one_time_price, 0)
self.assertEqual(order1.recurring_price, 16)
self.assertEqual(order1.recurring_price, 26.0)
class ModifyOrderTestCase(TestCase):
@ -181,7 +175,18 @@ class ModifyOrderTestCase(TestCase):
self.user = get_user_model().objects.create(
username='random_user',
email='jane.random@domain.tld')
self.pricing_plan = PricingPlan.objects.create(name="PricingSample", set_up_fees=35, cores_unit_price=3,
ram_unit_price=4, storage_unit_price=0.02)
self.order1_config = json.dumps({
'cores': 2,
'memory':4,
'storage': 200
})
self.order2_config = json.dumps({
'cores': 1,
'memory':2,
'storage': 100
})
self.ba = BillingAddress.objects.create(
owner=self.user,
organization = 'Test org',
@ -226,10 +231,11 @@ class ModifyOrderTestCase(TestCase):
order1 = Order.objects.create(owner=self.user,
billing_address=BillingAddress.get_address_for(self.user),
product=self.product,
config=vm_order_config,
config=self.order1_config,
pricing_plan=self.pricing_plan,
starting_date=starting_date)
order1.update_order(vm_order_downgrade_config, starting_date=change1_date)
order1.update_order(self.order2_config, starting_date=change1_date)
bills = Bill.create_next_bills_for_user(user, ending_date=bill_ending_date)
@ -270,24 +276,26 @@ class ModifyOrderTestCase(TestCase):
first_order_should_end_at = starting_date + datetime.timedelta(days=30)
change1_date = start_after(starting_date + datetime.timedelta(days=15))
bill_ending_date = change1_date + datetime.timedelta(days=1)
order1 = Order.objects.create(owner=self.user,
billing_address=BillingAddress.get_address_for(self.user),
product=self.product,
config=vm_order_config,
pricing_plan=self.pricing_plan,
config=self.order1_config,
starting_date=starting_date)
order1.update_order(vm_order_downgrade_config, starting_date=change1_date)
bills = Bill.create_next_bills_for_user(user, ending_date=bill_ending_date)
bill = bills[0]
bill_records = BillRecord.objects.filter(bill=bill)
self.assertEqual(len(bill_records), 2)
self.assertEqual(len(bill_records), 1)
self.assertEqual(bill_records[0].starting_date, starting_date)
self.assertEqual(bill_records[0].order.ending_date, first_order_should_end_at)
order1.update_order(self.order2_config, starting_date=change1_date)
bills = Bill.create_next_bills_for_user(user, ending_date=bill_ending_date)
bill_records = BillRecord.objects.filter(bill=bill)
self.assertEqual(len(bill_records), 2)
self.assertEqual(bill_records[0].order.ending_date.date(), change1_date.date())
class BillTestCase(TestCase):
@ -298,6 +306,9 @@ class BillTestCase(TestCase):
def setUp(self):
RecurringPeriod.populate_db_defaults()
self.pricing_plan = PricingPlan.objects.create(name="PricingSample", set_up_fees=35, cores_unit_price=3,
ram_unit_price=4, storage_unit_price=0.02)
self.user_without_address = get_user_model().objects.create(
username='no_home_person',
email='far.away@domain.tld')
@ -331,12 +342,12 @@ class BillTestCase(TestCase):
'starting_date': timezone.make_aware(datetime.datetime(2020,3,3)),
'ending_date': timezone.make_aware(datetime.datetime(2020,4,17)),
'price': 15,
'description': 'One chocolate bar'
'description': ''
}
self.chocolate = Product.objects.create(name="Swiss Chocolate",
self.product = Product.objects.create(name="Product Sample",
description="Not only for testing, but for joy",
config=chocolate_product_config)
config=vm_product_config)
self.vm = Product.objects.create(name="Super Fast VM",
@ -349,7 +360,7 @@ class BillTestCase(TestCase):
self.onetime_recurring_period = RecurringPeriod.objects.get(name="Onetime")
self.chocolate.recurring_periods.add(self.onetime_recurring_period,
self.product.recurring_periods.add(self.onetime_recurring_period,
through_defaults= { 'is_default': True })
self.vm.recurring_periods.add(self.default_recurring_period,
@ -364,15 +375,16 @@ class BillTestCase(TestCase):
]
def order_chocolate(self):
def order_product(self):
return Order.objects.create(
owner=self.user,
recurring_period=RecurringPeriod.objects.get(name="Onetime"),
product=self.chocolate,
product=self.product,
billing_address=BillingAddress.get_address_for(self.user),
starting_date=self.order_meta[1]['starting_date'],
ending_date=self.order_meta[1]['ending_date'],
config=chocolate_order_config)
pricing_plan=self.pricing_plan,
config=vm_order_config)
def order_vm(self, owner=None):
@ -383,27 +395,52 @@ class BillTestCase(TestCase):
owner=owner,
product=self.vm,
config=vm_order_config,
pricing_plan=self.pricing_plan,
billing_address=BillingAddress.get_address_for(self.recurring_user),
starting_date=timezone.make_aware(datetime.datetime(2020,3,3)),
)
return Order.objects.create(
def test_bill_one_time_with_recurring(self):
"""
Validate that if the order contains one_time_price and recurring_pricing
One Bill records should be created
"""
order = Order.objects.create(
owner=self.user,
recurring_period=RecurringPeriod.objects.get(name="Onetime"),
product=self.chocolate,
product=self.vm,
config=vm_order_config,
pricing_plan=self.pricing_plan,
one_time_price = 35,
billing_address=BillingAddress.get_address_for(self.user),
starting_date=self.order_meta[1]['starting_date'],
ending_date=self.order_meta[1]['ending_date'],
config=chocolate_order_config)
starting_date=timezone.make_aware(datetime.datetime(2020,3,3)),
)
bill = Bill.create_next_bill_for_user_address(self.user_addr)
self.assertEqual(order.billrecord_set.count(), 1)
record = order.billrecord_set.first()
self.assertEqual(record.is_recurring_record, False)
self.assertEqual(record.price, 35)
self.assertEqual(record.quantity, 1)
self.assertEqual(record.sum, 35)
#close the bill as it has been paid
bill.close()
bill2 = Bill.create_next_bill_for_user_address(self.user_addr)
self.assertNotEqual(bill.id, bill2.id)
self.assertEqual(order.billrecord_set.count(), 2)
record = BillRecord.objects.filter(bill=bill2, order=order).first()
self.assertEqual(record.is_recurring_record, True)
self.assertEqual(record.price, 13)
self.assertEqual(record.quantity, 1)
self.assertEqual(record.sum, 13)
def test_bill_one_time_one_bill_record(self):
"""
Ensure there is only 1 bill record per order
"""
order = self.order_chocolate()
order = self.order_product()
bill = Bill.create_next_bill_for_user_address(self.user_addr)
@ -414,9 +451,14 @@ class BillTestCase(TestCase):
Check the bill sum for a single one time order
"""
order = self.order_chocolate()
order = self.order_product()
self.assertEqual(order.recurring_price, 13.0)
bill = Bill.create_next_bill_for_user_address(self.user_addr)
self.assertEqual(bill.sum, chocolate_one_time_price)
self.assertEqual(order.billrecord_set.count(), 1)
record = order.billrecord_set.first()
self.assertEqual(record.price, 13)
self.assertEqual(record.quantity, 1)
self.assertEqual(bill.sum, 13)
def test_bill_creates_record_for_recurring_order(self):
@ -461,7 +503,7 @@ class BillingAddressTestCase(TestCase):
Raise an error, when there is no address
"""
self.assertRaises(uncloud_pay.models.BillingAddress.DoesNotExist,
self.assertRaises(BillingAddress.DoesNotExist,
BillingAddress.get_address_for,
self.user)
@ -478,7 +520,8 @@ class VATRatesTestCase(TestCase):
city="unknown",
postal_code="unknown",
active=True)
UncloudNetwork.populate_db_defaults()
UncloudProvider.populate_db_defaults()