forked from uncloud/uncloud
Cleanup code so that *most* test work again
Still need to solve the downgrade test
This commit is contained in:
parent
ecc9e6f734
commit
0b1c2cc168
8 changed files with 40 additions and 2254 deletions
|
@ -236,16 +236,16 @@ VPNNetworks can be managed by all authenticated users.
|
||||||
|
|
||||||
** Milestones :uncloud:
|
** Milestones :uncloud:
|
||||||
*** 1.1 (cleanup 1)
|
*** 1.1 (cleanup 1)
|
||||||
**** TODO Unify ValidationError, FieldError - define proper Exception
|
**** TODO [#C] Unify ValidationError, FieldError - define proper Exception
|
||||||
- What do we use for model errors
|
- What do we use for model errors
|
||||||
*** 1.0 (initial release)
|
*** 1.0 (initial release)
|
||||||
**** TODO Initial Generic product support
|
**** TODO [#C] Initial Generic product support
|
||||||
- Product
|
- Product
|
||||||
***** TODO Recurring product support
|
***** TODO [#C] Recurring product support
|
||||||
****** TODO Support replacing orders for updates
|
****** TODO [#C] Support replacing orders for updates
|
||||||
****** DONE [#A] Finish split of bill creation
|
****** DONE [#A] Finish split of bill creation
|
||||||
CLOSED: [2020-09-11 Fri 23:19]
|
CLOSED: [2020-09-11 Fri 23:19]
|
||||||
****** TODO Test the new functions in the Order class
|
****** TODO [#C] Test the new functions in the Order class
|
||||||
****** Define the correct order replacement logic
|
****** Define the correct order replacement logic
|
||||||
Assumption:
|
Assumption:
|
||||||
- recurringperiods are 30days
|
- recurringperiods are 30days
|
||||||
|
@ -302,13 +302,14 @@ VPNNetworks can be managed by all authenticated users.
|
||||||
- Total on bill: 30 CHF
|
- Total on bill: 30 CHF
|
||||||
|
|
||||||
|
|
||||||
****** TODO Note: ending date not set if replaced by default (implicit!)
|
****** TODO [#C] Note: ending date not set if replaced by default (implicit!)
|
||||||
- Should the new order modify the old order on save()?
|
- Should the new order modify the old order on save()?
|
||||||
****** DONE Fix totally wrong bill dates in our test case
|
****** DONE Fix totally wrong bill dates in our test case
|
||||||
CLOSED: [2020-09-09 Wed 01:00]
|
CLOSED: [2020-09-09 Wed 01:00]
|
||||||
- 2020 used instead of 2019
|
- 2020 used instead of 2019
|
||||||
- Was due to existing test data ...
|
- Was due to existing test data ...
|
||||||
***** TODO Bill logic is still wrong
|
***** DONE Bill logic is still wrong
|
||||||
|
CLOSED: [2020-11-05 Thu 18:58]
|
||||||
- Bill starting_date is the date of the first order
|
- Bill starting_date is the date of the first order
|
||||||
- However first encountered order does not have to be the
|
- However first encountered order does not have to be the
|
||||||
earliest in the bill!
|
earliest in the bill!
|
||||||
|
|
|
@ -3,6 +3,7 @@ from django.db.models import JSONField, Q
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django.core.validators import MinValueValidator, MaxValueValidator
|
from django.core.validators import MinValueValidator, MaxValueValidator
|
||||||
|
from django.core.exceptions import FieldError
|
||||||
|
|
||||||
from uncloud import COUNTRIES
|
from uncloud import COUNTRIES
|
||||||
|
|
||||||
|
|
|
@ -196,11 +196,27 @@ class ReverseDNSEntry(models.Model):
|
||||||
|
|
||||||
name = models.CharField(max_length=253, null=False)
|
name = models.CharField(max_length=253, null=False)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def reverse_pointer(self):
|
||||||
|
return ipaddress.ip_address(self.ip_address).reverse_pointer
|
||||||
|
|
||||||
|
def implement(self):
|
||||||
|
"""
|
||||||
|
The implement function implements the change
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Get all DNS entries (?) / update this DNS entry
|
||||||
|
# convert to DNS name
|
||||||
|
#
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
# Product.objects.filter(config__parameters__contains='reverse_dns_network')
|
# Product.objects.filter(config__parameters__contains='reverse_dns_network')
|
||||||
# FIXME: check if order is still active / not replaced
|
# FIXME: check if order is still active / not replaced
|
||||||
|
|
||||||
allowed = False
|
allowed = False
|
||||||
|
product = None
|
||||||
|
|
||||||
for order in Order.objects.filter(config__parameters__reverse_dns_network__isnull=False,
|
for order in Order.objects.filter(config__parameters__reverse_dns_network__isnull=False,
|
||||||
owner=self.owner):
|
owner=self.owner):
|
||||||
|
@ -211,6 +227,7 @@ class ReverseDNSEntry(models.Model):
|
||||||
|
|
||||||
if addr in net:
|
if addr in net:
|
||||||
allowed = True
|
allowed = True
|
||||||
|
product = order.product
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ from .views import *
|
||||||
from .models import *
|
from .models import *
|
||||||
|
|
||||||
from uncloud_pay.models import BillingAddress, Order
|
from uncloud_pay.models import BillingAddress, Order
|
||||||
|
from uncloud.models import UncloudNetwork
|
||||||
|
|
||||||
class UncloudNetworkTests(TestCase):
|
class UncloudNetworkTests(TestCase):
|
||||||
def test_invalid_IPv4_network(self):
|
def test_invalid_IPv4_network(self):
|
||||||
|
|
|
@ -209,7 +209,7 @@ class PaymentMethod(models.Model):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# See https://docs.djangoproject.com/en/dev/ref/models/fields/#field-choices-enum-types
|
# See https://docs.djangoproject.com/en/dev/ref/models/fields/#field-choices-enum-types
|
||||||
class RecurringPeriodChoices(models.IntegerChoices):
|
class RecurringPeriodDefaultChoices(models.IntegerChoices):
|
||||||
"""
|
"""
|
||||||
This is an old class and being superseeded by the database model below
|
This is an old class and being superseeded by the database model below
|
||||||
"""
|
"""
|
||||||
|
@ -234,7 +234,7 @@ class RecurringPeriod(models.Model):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def populate_db_defaults(cls):
|
def populate_db_defaults(cls):
|
||||||
for (seconds, name) in RecurringPeriodChoices.choices:
|
for (seconds, name) in RecurringPeriodDefaultChoices.choices:
|
||||||
obj, created = cls.objects.get_or_create(name=name,
|
obj, created = cls.objects.get_or_create(name=name,
|
||||||
defaults={ 'duration_seconds': seconds })
|
defaults={ 'duration_seconds': seconds })
|
||||||
|
|
||||||
|
@ -470,7 +470,7 @@ class Product(models.Model):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def recurring_orders(self):
|
def recurring_orders(self):
|
||||||
return self.orders.order_by('id').exclude(recurring_period=RecurringPeriod.ONE_TIME)
|
return self.orders.order_by('id').exclude(recurring_period=RecurringPeriod.objects.get(name="ONE_TIME"))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def last_recurring_order(self):
|
def last_recurring_order(self):
|
||||||
|
@ -478,7 +478,7 @@ class Product(models.Model):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def one_time_orders(self):
|
def one_time_orders(self):
|
||||||
return self.orders.order_by('id').filter(recurring_period=RecurringPeriod.ONE_TIME)
|
return self.orders.order_by('id').filter(recurring_period=RecurringPeriod.objects.get(name="ONE_TIME"))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def last_one_time_order(self):
|
def last_one_time_order(self):
|
||||||
|
@ -503,13 +503,13 @@ class Product(models.Model):
|
||||||
billing_address=billing_address,
|
billing_address=billing_address,
|
||||||
starting_date=when_to_start,
|
starting_date=when_to_start,
|
||||||
price=self.one_time_price,
|
price=self.one_time_price,
|
||||||
recurring_period=RecurringPeriod.ONE_TIME,
|
recurring_period=RecurringPeriod.objects.get(name="ONE_TIME"),
|
||||||
description=str(self))
|
description=str(self))
|
||||||
self.orders.add(one_time_order)
|
self.orders.add(one_time_order)
|
||||||
else:
|
else:
|
||||||
one_time_order = None
|
one_time_order = None
|
||||||
|
|
||||||
if recurring_period != RecurringPeriod.ONE_TIME:
|
if recurring_period != RecurringPeriod.objects.get(name="ONE_TIME"):
|
||||||
if one_time_order:
|
if one_time_order:
|
||||||
recurring_order = Order.objects.create(owner=self.owner,
|
recurring_order = Order.objects.create(owner=self.owner,
|
||||||
billing_address=billing_address,
|
billing_address=billing_address,
|
||||||
|
@ -827,7 +827,7 @@ class Order(models.Model):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_recurring(self):
|
def is_recurring(self):
|
||||||
return not self.recurring_period == RecurringPeriod.ONE_TIME
|
return not self.recurring_period == RecurringPeriod.objects.get(name="ONE_TIME")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_one_time(self):
|
def is_one_time(self):
|
||||||
|
@ -857,6 +857,8 @@ class Order(models.Model):
|
||||||
|
|
||||||
(new_order.one_time_price, new_order.recurring_price, new_order.config) = new_order.calculate_prices_and_config()
|
(new_order.one_time_price, new_order.recurring_price, new_order.config) = new_order.calculate_prices_and_config()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
new_order.replaces = self
|
new_order.replaces = self
|
||||||
new_order.save()
|
new_order.save()
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,721 +0,0 @@
|
||||||
from django.test import TestCase
|
|
||||||
from django.contrib.auth import get_user_model
|
|
||||||
from datetime import datetime, date, timedelta
|
|
||||||
from django.utils import timezone
|
|
||||||
|
|
||||||
from .models import *
|
|
||||||
from uncloud_service.models import GenericServiceProduct
|
|
||||||
|
|
||||||
class OrderTestCase(TestCase):
|
|
||||||
"""
|
|
||||||
The heart of ordering products
|
|
||||||
"""
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.user = get_user_model().objects.create(
|
|
||||||
username='random_user',
|
|
||||||
email='jane.random@domain.tld')
|
|
||||||
|
|
||||||
self.ba = BillingAddress.objects.create(
|
|
||||||
owner=self.user,
|
|
||||||
organization = 'Test org',
|
|
||||||
street="unknown",
|
|
||||||
city="unknown",
|
|
||||||
postal_code="somewhere else",
|
|
||||||
active=True)
|
|
||||||
|
|
||||||
def test_create_one_time_product(self):
|
|
||||||
"""
|
|
||||||
One time payment products cannot be updated - can they?
|
|
||||||
"""
|
|
||||||
|
|
||||||
p = SampleOneTimeProduct.objects.create(owner=self.user)
|
|
||||||
|
|
||||||
self.assertEqual(p.one_time_price, 5)
|
|
||||||
self.assertEqual(p.recurring_price, 0)
|
|
||||||
|
|
||||||
|
|
||||||
# class ProductTestCase(TestCase):
|
|
||||||
# """
|
|
||||||
# Test products and products <-> order interaction
|
|
||||||
# """
|
|
||||||
|
|
||||||
# def setUp(self):
|
|
||||||
# self.user = get_user_model().objects.create(
|
|
||||||
# username='random_user',
|
|
||||||
# email='jane.random@domain.tld')
|
|
||||||
|
|
||||||
# self.ba = BillingAddress.objects.create(
|
|
||||||
# owner=self.user,
|
|
||||||
# organization = 'Test org',
|
|
||||||
# street="unknown",
|
|
||||||
# city="unknown",
|
|
||||||
# postal_code="somewhere else",
|
|
||||||
# active=True)
|
|
||||||
|
|
||||||
# def test_create_one_time_product(self):
|
|
||||||
# """
|
|
||||||
# One time payment products cannot be updated - can they?
|
|
||||||
# """
|
|
||||||
|
|
||||||
# p = SampleOneTimeProduct.objects.create(owner=self.user)
|
|
||||||
|
|
||||||
# self.assertEqual(p.one_time_price, 5)
|
|
||||||
# self.assertEqual(p.recurring_price, 0)
|
|
||||||
|
|
||||||
# def test_create_product_without_active_billing_address(self):
|
|
||||||
# """
|
|
||||||
# Fail to create a product without an active billing address
|
|
||||||
# """
|
|
||||||
|
|
||||||
# self.ba.active = False
|
|
||||||
# self.ba.save()
|
|
||||||
|
|
||||||
# with self.assertRaises(ValidationError):
|
|
||||||
# p = SampleOneTimeProduct.objects.create(owner=self.user)
|
|
||||||
|
|
||||||
# def test_create_product_without_billing_address(self):
|
|
||||||
# """
|
|
||||||
# Fail to create a product without a billing address
|
|
||||||
# """
|
|
||||||
|
|
||||||
# user2 = get_user_model().objects.create(
|
|
||||||
# username='random_user2',
|
|
||||||
# email='jane.randomly@domain.tld')
|
|
||||||
|
|
||||||
# with self.assertRaises(ValidationError):
|
|
||||||
# p = SampleOneTimeProduct.objects.create(owner=user2)
|
|
||||||
|
|
||||||
|
|
||||||
# def test_create_order_creates_correct_order_count(self):
|
|
||||||
# """
|
|
||||||
# Ensure creating orders from product only creates 1 order
|
|
||||||
# """
|
|
||||||
|
|
||||||
# # One order
|
|
||||||
# p = SampleOneTimeProduct.objects.create(owner=self.user)
|
|
||||||
# p.create_order(timezone.make_aware(datetime.datetime(2020,3,3)))
|
|
||||||
|
|
||||||
# order_count = Order.objects.filter(owner=self.user).count()
|
|
||||||
# self.assertEqual(order_count, 1)
|
|
||||||
|
|
||||||
# # One more order
|
|
||||||
# p = SampleRecurringProduct.objects.create(owner=self.user)
|
|
||||||
# p.create_order(timezone.make_aware(datetime.datetime(2020,3,3)))
|
|
||||||
|
|
||||||
# order_count = Order.objects.filter(owner=self.user).count()
|
|
||||||
# self.assertEqual(order_count, 2)
|
|
||||||
|
|
||||||
# # Should create 2 orders
|
|
||||||
# p = SampleRecurringProductOneTimeFee.objects.create(owner=self.user)
|
|
||||||
# p.create_order(timezone.make_aware(datetime.datetime(2020,3,3)))
|
|
||||||
|
|
||||||
# order_count = Order.objects.filter(owner=self.user).count()
|
|
||||||
# self.assertEqual(order_count, 4)
|
|
||||||
|
|
||||||
|
|
||||||
# def test_update_recurring_order(self):
|
|
||||||
# """
|
|
||||||
# Ensure creating orders from product only creates 1 order
|
|
||||||
# """
|
|
||||||
|
|
||||||
# p = SampleRecurringProduct.objects.create(owner=self.user)
|
|
||||||
# p.create_order(timezone.make_aware(datetime.datetime(2020,3,3)))
|
|
||||||
|
|
||||||
# p.create_or_update_recurring_order(timezone.make_aware(datetime.datetime(2020,3,4)))
|
|
||||||
|
|
||||||
# # FIXME: where is the assert?
|
|
||||||
|
|
||||||
|
|
||||||
class BillingAddressTestCase(TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
self.user = get_user_model().objects.create(
|
|
||||||
username='random_user',
|
|
||||||
email='jane.random@domain.tld')
|
|
||||||
|
|
||||||
|
|
||||||
def test_user_no_address(self):
|
|
||||||
"""
|
|
||||||
Raise an error, when there is no address
|
|
||||||
"""
|
|
||||||
|
|
||||||
self.assertRaises(uncloud_pay.models.BillingAddress.DoesNotExist,
|
|
||||||
BillingAddress.get_address_for,
|
|
||||||
self.user)
|
|
||||||
|
|
||||||
def test_user_only_inactive_address(self):
|
|
||||||
"""
|
|
||||||
Raise an error, when there is no active address
|
|
||||||
"""
|
|
||||||
|
|
||||||
ba = BillingAddress.objects.create(
|
|
||||||
owner=self.user,
|
|
||||||
organization = 'Test org',
|
|
||||||
street="unknown",
|
|
||||||
city="unknown",
|
|
||||||
postal_code="somewhere else",
|
|
||||||
active=False)
|
|
||||||
|
|
||||||
self.assertRaises(uncloud_pay.models.BillingAddress.DoesNotExist,
|
|
||||||
BillingAddress.get_address_for,
|
|
||||||
self.user)
|
|
||||||
|
|
||||||
def test_find_active_address(self):
|
|
||||||
"""
|
|
||||||
Find the active address
|
|
||||||
"""
|
|
||||||
|
|
||||||
ba = BillingAddress.objects.create(
|
|
||||||
owner=self.user,
|
|
||||||
organization = 'Test org',
|
|
||||||
street="unknown",
|
|
||||||
city="unknown",
|
|
||||||
postal_code="unknown",
|
|
||||||
active=True)
|
|
||||||
|
|
||||||
|
|
||||||
self.assertEqual(BillingAddress.get_address_for(self.user), ba)
|
|
||||||
|
|
||||||
def test_find_right_address_with_multiple_addresses(self):
|
|
||||||
"""
|
|
||||||
Find the active address only, skip inactive
|
|
||||||
"""
|
|
||||||
|
|
||||||
ba = BillingAddress.objects.create(
|
|
||||||
owner=self.user,
|
|
||||||
organization = 'Test org',
|
|
||||||
street="unknown",
|
|
||||||
city="unknown",
|
|
||||||
postal_code="unknown",
|
|
||||||
active=True)
|
|
||||||
|
|
||||||
ba2 = BillingAddress.objects.create(
|
|
||||||
owner=self.user,
|
|
||||||
organization = 'Test org',
|
|
||||||
street="unknown",
|
|
||||||
city="unknown",
|
|
||||||
postal_code="somewhere else",
|
|
||||||
active=False)
|
|
||||||
|
|
||||||
|
|
||||||
self.assertEqual(BillingAddress.get_address_for(self.user), ba)
|
|
||||||
|
|
||||||
def test_change_addresses(self):
|
|
||||||
"""
|
|
||||||
Switch the active address
|
|
||||||
"""
|
|
||||||
|
|
||||||
ba = BillingAddress.objects.create(
|
|
||||||
owner=self.user,
|
|
||||||
organization = 'Test org',
|
|
||||||
street="unknown",
|
|
||||||
city="unknown",
|
|
||||||
postal_code="unknown",
|
|
||||||
active=True)
|
|
||||||
|
|
||||||
self.assertEqual(BillingAddress.get_address_for(self.user), ba)
|
|
||||||
|
|
||||||
ba.active=False
|
|
||||||
ba.save()
|
|
||||||
|
|
||||||
ba2 = BillingAddress.objects.create(
|
|
||||||
owner=self.user,
|
|
||||||
organization = 'Test org',
|
|
||||||
street="unknown",
|
|
||||||
city="unknown",
|
|
||||||
postal_code="somewhere else",
|
|
||||||
active=True)
|
|
||||||
|
|
||||||
self.assertEqual(BillingAddress.get_address_for(self.user), ba2)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class BillTestCase(TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
self.user_without_address = get_user_model().objects.create(
|
|
||||||
username='no_home_person',
|
|
||||||
email='far.away@domain.tld')
|
|
||||||
|
|
||||||
self.user = get_user_model().objects.create(
|
|
||||||
username='jdoe',
|
|
||||||
email='john.doe@domain.tld')
|
|
||||||
|
|
||||||
self.recurring_user = get_user_model().objects.create(
|
|
||||||
username='recurrent_product_user',
|
|
||||||
email='jane.doe@domain.tld')
|
|
||||||
|
|
||||||
self.user_addr = BillingAddress.objects.create(
|
|
||||||
owner=self.user,
|
|
||||||
organization = 'Test org',
|
|
||||||
street="unknown",
|
|
||||||
city="unknown",
|
|
||||||
postal_code="unknown",
|
|
||||||
active=True)
|
|
||||||
|
|
||||||
self.recurring_user_addr = BillingAddress.objects.create(
|
|
||||||
owner=self.recurring_user,
|
|
||||||
organization = 'Test org',
|
|
||||||
street="Somewhere",
|
|
||||||
city="Else",
|
|
||||||
postal_code="unknown",
|
|
||||||
active=True)
|
|
||||||
|
|
||||||
self.order_meta = {}
|
|
||||||
self.order_meta[1] = {
|
|
||||||
'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'
|
|
||||||
}
|
|
||||||
|
|
||||||
self.one_time_order = Order.objects.create(
|
|
||||||
owner=self.user,
|
|
||||||
starting_date=self.order_meta[1]['starting_date'],
|
|
||||||
ending_date=self.order_meta[1]['ending_date'],
|
|
||||||
recurring_period=RecurringPeriod.ONE_TIME,
|
|
||||||
price=self.order_meta[1]['price'],
|
|
||||||
description=self.order_meta[1]['description'],
|
|
||||||
billing_address=BillingAddress.get_address_for(self.user))
|
|
||||||
|
|
||||||
self.recurring_order = Order.objects.create(
|
|
||||||
owner=self.recurring_user,
|
|
||||||
starting_date=timezone.make_aware(datetime.datetime(2020,3,3)),
|
|
||||||
recurring_period=RecurringPeriod.PER_30D,
|
|
||||||
price=15,
|
|
||||||
description="A pretty VM",
|
|
||||||
billing_address=BillingAddress.get_address_for(self.recurring_user)
|
|
||||||
)
|
|
||||||
|
|
||||||
# used for generating multiple bills
|
|
||||||
self.bill_dates = [
|
|
||||||
timezone.make_aware(datetime.datetime(2020,3,31)),
|
|
||||||
timezone.make_aware(datetime.datetime(2020,4,30)),
|
|
||||||
timezone.make_aware(datetime.datetime(2020,5,31)),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_bill_one_time_one_bill_record(self):
|
|
||||||
"""
|
|
||||||
Ensure there is only 1 bill record per order
|
|
||||||
"""
|
|
||||||
|
|
||||||
bill = Bill.create_next_bill_for_user_address(self.user_addr)
|
|
||||||
|
|
||||||
self.assertEqual(self.one_time_order.billrecord_set.count(), 1)
|
|
||||||
|
|
||||||
def test_bill_sum_onetime(self):
|
|
||||||
"""
|
|
||||||
Check the bill sum for a single one time order
|
|
||||||
"""
|
|
||||||
|
|
||||||
bill = Bill.create_next_bill_for_user_address(self.user_addr)
|
|
||||||
self.assertEqual(bill.sum, self.order_meta[1]['price'])
|
|
||||||
|
|
||||||
|
|
||||||
def test_bill_creates_record_for_recurring_order(self):
|
|
||||||
"""
|
|
||||||
Ensure there is only 1 bill record per order
|
|
||||||
"""
|
|
||||||
|
|
||||||
bill = Bill.create_next_bill_for_user_address(self.recurring_user_addr)
|
|
||||||
|
|
||||||
self.assertEqual(self.recurring_order.billrecord_set.count(), 1)
|
|
||||||
self.assertEqual(bill.billrecord_set.count(), 1)
|
|
||||||
|
|
||||||
|
|
||||||
def test_new_bill_after_closing(self):
|
|
||||||
"""
|
|
||||||
After closing a bill and the user has a recurring product,
|
|
||||||
the next bill run should create e new bill
|
|
||||||
"""
|
|
||||||
|
|
||||||
for ending_date in self.bill_dates:
|
|
||||||
b = Bill.create_next_bill_for_user_address(self.recurring_user_addr, ending_date)
|
|
||||||
b.close()
|
|
||||||
|
|
||||||
bill_count = Bill.objects.filter(owner=self.recurring_user).count()
|
|
||||||
|
|
||||||
self.assertEqual(len(self.bill_dates), bill_count)
|
|
||||||
|
|
||||||
def test_multi_addr_multi_bill(self):
|
|
||||||
"""
|
|
||||||
Ensure multiple bills are created if orders exist with different billing addresses
|
|
||||||
"""
|
|
||||||
|
|
||||||
username="lotsofplaces"
|
|
||||||
multi_addr_user = get_user_model().objects.create(
|
|
||||||
username=username,
|
|
||||||
email=f"{username}@example.org")
|
|
||||||
|
|
||||||
user_addr1 = BillingAddress.objects.create(
|
|
||||||
owner=multi_addr_user,
|
|
||||||
organization = 'Test org',
|
|
||||||
street="unknown",
|
|
||||||
city="unknown",
|
|
||||||
postal_code="unknown",
|
|
||||||
active=True)
|
|
||||||
|
|
||||||
order1 = Order.objects.create(
|
|
||||||
owner=multi_addr_user,
|
|
||||||
starting_date=self.order_meta[1]['starting_date'],
|
|
||||||
ending_date=self.order_meta[1]['ending_date'],
|
|
||||||
recurring_period=RecurringPeriod.ONE_TIME,
|
|
||||||
price=self.order_meta[1]['price'],
|
|
||||||
description=self.order_meta[1]['description'],
|
|
||||||
billing_address=BillingAddress.get_address_for(self.user))
|
|
||||||
|
|
||||||
# Make this address inactive
|
|
||||||
user_addr1.active = False
|
|
||||||
user_addr1.save()
|
|
||||||
|
|
||||||
user_addr2 = BillingAddress.objects.create(
|
|
||||||
owner=multi_addr_user,
|
|
||||||
organization = 'Test2 org',
|
|
||||||
street="unknown2",
|
|
||||||
city="unknown2",
|
|
||||||
postal_code="unknown2",
|
|
||||||
active=True)
|
|
||||||
|
|
||||||
order2 = Order.objects.create(
|
|
||||||
owner=multi_addr_user,
|
|
||||||
starting_date=self.order_meta[1]['starting_date'],
|
|
||||||
ending_date=self.order_meta[1]['ending_date'],
|
|
||||||
recurring_period=RecurringPeriod.ONE_TIME,
|
|
||||||
price=self.order_meta[1]['price'],
|
|
||||||
description=self.order_meta[1]['description'],
|
|
||||||
billing_address=BillingAddress.get_address_for(self.user))
|
|
||||||
|
|
||||||
|
|
||||||
bills = Bill.create_next_bills_for_user(multi_addr_user)
|
|
||||||
|
|
||||||
self.assertEqual(len(bills), 2)
|
|
||||||
|
|
||||||
|
|
||||||
# TO BE IMPLEMENTED -- once orders can be marked as "done" / "inactive" / "not for billing"
|
|
||||||
# def test_skip_disabled_orders(self):
|
|
||||||
# """
|
|
||||||
# Ensure that a bill only considers "active" orders
|
|
||||||
# """
|
|
||||||
|
|
||||||
# self.assertEqual(1, 2)
|
|
||||||
|
|
||||||
|
|
||||||
class ModifyProductTestCase(TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
self.user = get_user_model().objects.create(
|
|
||||||
username='random_user',
|
|
||||||
email='jane.random@domain.tld')
|
|
||||||
|
|
||||||
self.ba = BillingAddress.objects.create(
|
|
||||||
owner=self.user,
|
|
||||||
organization = 'Test org',
|
|
||||||
street="unknown",
|
|
||||||
city="unknown",
|
|
||||||
postal_code="somewhere else",
|
|
||||||
active=True)
|
|
||||||
|
|
||||||
def test_no_pro_rata_first_bill(self):
|
|
||||||
"""
|
|
||||||
The bill should NOT contain a partial amount -- this is a BILL TEST :-)
|
|
||||||
"""
|
|
||||||
|
|
||||||
price = 5
|
|
||||||
|
|
||||||
# Standard 30d recurring product
|
|
||||||
product = SampleRecurringProduct.objects.create(owner=self.user,
|
|
||||||
rc_price=price)
|
|
||||||
|
|
||||||
starting_date = timezone.make_aware(datetime.datetime(2020,3,3))
|
|
||||||
ending_date = timezone.make_aware(datetime.datetime(2020,3,31))
|
|
||||||
time_diff = (ending_date - starting_date).total_seconds()
|
|
||||||
|
|
||||||
product.create_order(starting_date)
|
|
||||||
|
|
||||||
bills = Bill.create_next_bills_for_user(self.user,
|
|
||||||
ending_date=ending_date)
|
|
||||||
|
|
||||||
|
|
||||||
# We expect 1 bill for 1 billing address and 1 time frame
|
|
||||||
self.assertEqual(len(bills), 1)
|
|
||||||
|
|
||||||
pro_rata_amount = time_diff / product.default_recurring_period.value
|
|
||||||
|
|
||||||
self.assertNotEqual(bills[0].sum, pro_rata_amount * price)
|
|
||||||
self.assertEqual(bills[0].sum, price)
|
|
||||||
|
|
||||||
|
|
||||||
def test_downgrade_product(self):
|
|
||||||
"""
|
|
||||||
Test downgrading behaviour:
|
|
||||||
|
|
||||||
We create a recurring product (recurring time: 30 days) and downgrade after 15 days.
|
|
||||||
|
|
||||||
We create the bill right AFTER the end of the first order.
|
|
||||||
|
|
||||||
Expected result:
|
|
||||||
|
|
||||||
- First bill record for 30 days
|
|
||||||
- Second bill record starting after 30 days
|
|
||||||
- Bill contains two bill records
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
user = self.user
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
starting_price = 10
|
|
||||||
downgrade_price = 5
|
|
||||||
|
|
||||||
|
|
||||||
starting_date = timezone.make_aware(datetime.datetime(2019,3,3))
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
product = SampleRecurringProduct.objects.create(owner=user, rc_price=starting_price)
|
|
||||||
product.create_order(starting_date)
|
|
||||||
|
|
||||||
product.rc_price = downgrade_price
|
|
||||||
product.save()
|
|
||||||
product.create_or_update_recurring_order(when_to_start=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(bill_records[0].starting_date, starting_date)
|
|
||||||
|
|
||||||
self.assertEqual(bill_records[0].order.ending_date, first_order_should_end_at)
|
|
||||||
|
|
||||||
# self.assertEqual(bill_records[0].ending_date, first_order_should_end_at)
|
|
||||||
|
|
||||||
# self.assertEqual(bill_records[0].quantity, 1)
|
|
||||||
|
|
||||||
# self.assertEqual(bill_records[1].quantity, 1)
|
|
||||||
# self.assertEqual(int(bill.sum), 15)
|
|
||||||
|
|
||||||
def test_upgrade_product(self):
|
|
||||||
"""
|
|
||||||
Test upgrading behaviour
|
|
||||||
"""
|
|
||||||
|
|
||||||
user = self.user
|
|
||||||
|
|
||||||
# Create product
|
|
||||||
starting_date = timezone.make_aware(datetime.datetime(2019,3,3))
|
|
||||||
starting_price = 10
|
|
||||||
product = SampleRecurringProduct.objects.create(owner=user, rc_price=starting_price)
|
|
||||||
product.create_order(starting_date)
|
|
||||||
|
|
||||||
change1_date = start_after(starting_date + datetime.timedelta(days=15))
|
|
||||||
product.rc_price = 20
|
|
||||||
product.save()
|
|
||||||
product.create_or_update_recurring_order(when_to_start=change1_date)
|
|
||||||
|
|
||||||
bill_ending_date = change1_date + datetime.timedelta(days=1)
|
|
||||||
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(bill_records[0].quantity, .5)
|
|
||||||
|
|
||||||
self.assertEqual(bill_records[0].ending_date, end_before(change1_date))
|
|
||||||
|
|
||||||
self.assertEqual(bill_records[1].quantity, 1)
|
|
||||||
self.assertEqual(bill_records[1].starting_date, change1_date)
|
|
||||||
|
|
||||||
self.assertEqual(int(bill.sum), 25)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# def test_bill_for_increasing_product(self):
|
|
||||||
# """
|
|
||||||
# Modify a product, see one pro rata entry
|
|
||||||
# """
|
|
||||||
|
|
||||||
# # Create product
|
|
||||||
# starting_date = timezone.make_aware(datetime.datetime(2019,3,3))
|
|
||||||
# starting_price = 30.5
|
|
||||||
# product = SampleRecurringProduct.objects.create(owner=self.user,
|
|
||||||
# rc_price=starting_price)
|
|
||||||
# product.create_order(starting_date)
|
|
||||||
|
|
||||||
# recurring_period = product.default_recurring_period.value
|
|
||||||
|
|
||||||
# # First change
|
|
||||||
# change1_date = timezone.make_aware(datetime.datetime(2019,4,17))
|
|
||||||
# product.rc_price = 49.5
|
|
||||||
# product.save()
|
|
||||||
# product.create_or_update_recurring_order(when_to_start=change1_date)
|
|
||||||
|
|
||||||
# # Second change
|
|
||||||
# change2_date = timezone.make_aware(datetime.datetime(2019,5,8))
|
|
||||||
# product.rc_price = 56.5
|
|
||||||
# product.save()
|
|
||||||
# product.create_or_update_recurring_order(when_to_start=change2_date)
|
|
||||||
|
|
||||||
# # Create bill one month after 2nd change
|
|
||||||
# bill_ending_date = timezone.make_aware(datetime.datetime(2019,6,30))
|
|
||||||
# bills = Bill.create_next_bills_for_user(self.user,
|
|
||||||
# ending_date=bill_ending_date)
|
|
||||||
|
|
||||||
# # only one bill in this test case
|
|
||||||
# bill = bills[0]
|
|
||||||
|
|
||||||
# expected_amount = starting_price
|
|
||||||
|
|
||||||
# d2 = starting_date + recurring_period
|
|
||||||
# duration2 = change1_date - d2
|
|
||||||
|
|
||||||
# expected_amount = 0
|
|
||||||
|
|
||||||
# # Expected bill sum & records:
|
|
||||||
# # 2019-03-03 - 2019-04-02 +30d: 30.5
|
|
||||||
# # 2019-04-02 - 2019-04-17: +15d: 15.25
|
|
||||||
# # 2019-04-17 - 2019-05-08: +21d: (21/30) * 49.5
|
|
||||||
# # 2019-05-08 - 2019-06-07: +30d: 56.5
|
|
||||||
# # 2019-06-07 - 2019-07-07: +30d: 56.5
|
|
||||||
|
|
||||||
|
|
||||||
# self.assertEqual(bills[0].sum, price)
|
|
||||||
|
|
||||||
# # expeted result:
|
|
||||||
# # 1x 5 chf bill record
|
|
||||||
# # 1x 5 chf bill record
|
|
||||||
# # 1x 10 partial bill record
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# class NotABillingTC(TestCase):
|
|
||||||
# #class BillingTestCase(TestCase):
|
|
||||||
# def setUp(self):
|
|
||||||
# self.user = get_user_model().objects.create(
|
|
||||||
# username='jdoe',
|
|
||||||
# email='john.doe@domain.tld')
|
|
||||||
# self.billing_address = BillingAddress.objects.create(
|
|
||||||
# owner=self.user,
|
|
||||||
# street="unknown",
|
|
||||||
# city="unknown",
|
|
||||||
# postal_code="unknown")
|
|
||||||
|
|
||||||
# def test_basic_monthly_billing(self):
|
|
||||||
# one_time_price = 10
|
|
||||||
# recurring_price = 20
|
|
||||||
# description = "Test Product 1"
|
|
||||||
|
|
||||||
# # Three months: full, full, partial.
|
|
||||||
# # starting_date = datetime.fromisoformat('2020-03-01')
|
|
||||||
# starting_date = datetime(2020,3,1)
|
|
||||||
# ending_date = datetime(2020,5,8)
|
|
||||||
|
|
||||||
# # Create order to be billed.
|
|
||||||
# order = Order.objects.create(
|
|
||||||
# owner=self.user,
|
|
||||||
# starting_date=starting_date,
|
|
||||||
# ending_date=ending_date,
|
|
||||||
# recurring_period=RecurringPeriod.PER_30D,
|
|
||||||
# recurring_price=recurring_price,
|
|
||||||
# one_time_price=one_time_price,
|
|
||||||
# description=description,
|
|
||||||
# billing_address=self.billing_address)
|
|
||||||
|
|
||||||
# # Generate & check bill for first month: full recurring_price + setup.
|
|
||||||
# first_month_bills = order.generate_initial_bill()
|
|
||||||
# self.assertEqual(len(first_month_bills), 1)
|
|
||||||
# self.assertEqual(first_month_bills[0].amount, one_time_price + recurring_price)
|
|
||||||
|
|
||||||
# # Generate & check bill for second month: full recurring_price.
|
|
||||||
# second_month_bills = Bill.generate_for(2020, 4, self.user)
|
|
||||||
# self.assertEqual(len(second_month_bills), 1)
|
|
||||||
# self.assertEqual(second_month_bills[0].amount, recurring_price)
|
|
||||||
|
|
||||||
# # Generate & check bill for third and last month: partial recurring_price.
|
|
||||||
# third_month_bills = Bill.generate_for(2020, 5, self.user)
|
|
||||||
# self.assertEqual(len(third_month_bills), 1)
|
|
||||||
# # 31 days in May.
|
|
||||||
# self.assertEqual(float(third_month_bills[0].amount),
|
|
||||||
# round(round((7/31), AMOUNT_DECIMALS) * recurring_price, AMOUNT_DECIMALS))
|
|
||||||
|
|
||||||
# # Check that running Bill.generate_for() twice does not create duplicates.
|
|
||||||
# self.assertEqual(len(Bill.generate_for(2020, 3, self.user)), 0)
|
|
||||||
|
|
||||||
# def test_basic_yearly_billing(self):
|
|
||||||
# one_time_price = 10
|
|
||||||
# recurring_price = 150
|
|
||||||
# description = "Test Product 1"
|
|
||||||
|
|
||||||
# starting_date = datetime.fromisoformat('2020-03-31T08:05:23')
|
|
||||||
|
|
||||||
# # Create order to be billed.
|
|
||||||
# order = Order.objects.create(
|
|
||||||
# owner=self.user,
|
|
||||||
# starting_date=starting_date,
|
|
||||||
# recurring_period=RecurringPeriod.PER_365D,
|
|
||||||
# recurring_price=recurring_price,
|
|
||||||
# one_time_price=one_time_price,
|
|
||||||
# description=description,
|
|
||||||
# billing_address=self.billing_address)
|
|
||||||
|
|
||||||
# # Generate & check bill for first year: recurring_price + setup.
|
|
||||||
# first_year_bills = order.generate_initial_bill()
|
|
||||||
# self.assertEqual(len(first_year_bills), 1)
|
|
||||||
# self.assertEqual(first_year_bills[0].starting_date.date(),
|
|
||||||
# date.fromisoformat('2020-03-31'))
|
|
||||||
# self.assertEqual(first_year_bills[0].ending_date.date(),
|
|
||||||
# date.fromisoformat('2021-03-30'))
|
|
||||||
# self.assertEqual(first_year_bills[0].amount,
|
|
||||||
# recurring_price + one_time_price)
|
|
||||||
|
|
||||||
# # Generate & check bill for second year: recurring_price.
|
|
||||||
# second_year_bills = Bill.generate_for(2021, 3, self.user)
|
|
||||||
# self.assertEqual(len(second_year_bills), 1)
|
|
||||||
# self.assertEqual(second_year_bills[0].starting_date.date(),
|
|
||||||
# date.fromisoformat('2021-03-31'))
|
|
||||||
# self.assertEqual(second_year_bills[0].ending_date.date(),
|
|
||||||
# date.fromisoformat('2022-03-30'))
|
|
||||||
# self.assertEqual(second_year_bills[0].amount, recurring_price)
|
|
||||||
|
|
||||||
# # Check that running Bill.generate_for() twice does not create duplicates.
|
|
||||||
# self.assertEqual(len(Bill.generate_for(2020, 3, self.user)), 0)
|
|
||||||
# self.assertEqual(len(Bill.generate_for(2020, 4, self.user)), 0)
|
|
||||||
# self.assertEqual(len(Bill.generate_for(2020, 2, self.user)), 0)
|
|
||||||
# self.assertEqual(len(Bill.generate_for(2021, 3, self.user)), 0)
|
|
||||||
|
|
||||||
# def test_basic_hourly_billing(self):
|
|
||||||
# one_time_price = 10
|
|
||||||
# recurring_price = 1.4
|
|
||||||
# description = "Test Product 1"
|
|
||||||
|
|
||||||
# starting_date = datetime.fromisoformat('2020-03-31T08:05:23')
|
|
||||||
# ending_date = datetime.fromisoformat('2020-04-01T11:13:32')
|
|
||||||
|
|
||||||
# # Create order to be billed.
|
|
||||||
# order = Order.objects.create(
|
|
||||||
# owner=self.user,
|
|
||||||
# starting_date=starting_date,
|
|
||||||
# ending_date=ending_date,
|
|
||||||
# recurring_period=RecurringPeriod.PER_HOUR,
|
|
||||||
# recurring_price=recurring_price,
|
|
||||||
# one_time_price=one_time_price,
|
|
||||||
# description=description,
|
|
||||||
# billing_address=self.billing_address)
|
|
||||||
|
|
||||||
# # Generate & check bill for first month: recurring_price + setup.
|
|
||||||
# first_month_bills = order.generate_initial_bill()
|
|
||||||
# self.assertEqual(len(first_month_bills), 1)
|
|
||||||
# self.assertEqual(float(first_month_bills[0].amount),
|
|
||||||
# round(16 * recurring_price, AMOUNT_DECIMALS) + one_time_price)
|
|
||||||
|
|
||||||
# # Generate & check bill for first month: recurring_price.
|
|
||||||
# second_month_bills = Bill.generate_for(2020, 4, self.user)
|
|
||||||
# self.assertEqual(len(second_month_bills), 1)
|
|
||||||
# self.assertEqual(float(second_month_bills[0].amount),
|
|
||||||
# round(12 * recurring_price, AMOUNT_DECIMALS))
|
|
|
@ -244,36 +244,6 @@ class ModifyOrderTestCase(TestCase):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# def test_no_pro_rata_first_bill(self):
|
|
||||||
# """
|
|
||||||
# The bill should NOT contain a partial amount -- this is a BILL TEST :-)
|
|
||||||
# """
|
|
||||||
|
|
||||||
# price = 5
|
|
||||||
|
|
||||||
# # Standard 30d recurring product
|
|
||||||
# product = SampleRecurringProduct.objects.create(owner=self.user,
|
|
||||||
# rc_price=price)
|
|
||||||
|
|
||||||
# starting_date = timezone.make_aware(datetime.datetime(2020,3,3))
|
|
||||||
# ending_date = timezone.make_aware(datetime.datetime(2020,3,31))
|
|
||||||
# time_diff = (ending_date - starting_date).total_seconds()
|
|
||||||
|
|
||||||
# product.create_order(starting_date)
|
|
||||||
|
|
||||||
# bills = Bill.create_next_bills_for_user(self.user,
|
|
||||||
# ending_date=ending_date)
|
|
||||||
|
|
||||||
|
|
||||||
# # We expect 1 bill for 1 billing address and 1 time frame
|
|
||||||
# self.assertEqual(len(bills), 1)
|
|
||||||
|
|
||||||
# pro_rata_amount = time_diff / product.default_recurring_period.value
|
|
||||||
|
|
||||||
# self.assertNotEqual(bills[0].sum, pro_rata_amount * price)
|
|
||||||
# self.assertEqual(bills[0].sum, price)
|
|
||||||
|
|
||||||
|
|
||||||
def test_downgrade_product(self):
|
def test_downgrade_product(self):
|
||||||
"""
|
"""
|
||||||
Test downgrading behaviour:
|
Test downgrading behaviour:
|
||||||
|
@ -300,7 +270,6 @@ class ModifyOrderTestCase(TestCase):
|
||||||
change1_date = start_after(starting_date + datetime.timedelta(days=15))
|
change1_date = start_after(starting_date + datetime.timedelta(days=15))
|
||||||
bill_ending_date = change1_date + datetime.timedelta(days=1)
|
bill_ending_date = change1_date + datetime.timedelta(days=1)
|
||||||
|
|
||||||
|
|
||||||
order1 = Order.objects.create(owner=self.user,
|
order1 = Order.objects.create(owner=self.user,
|
||||||
billing_address=BillingAddress.get_address_for(self.user),
|
billing_address=BillingAddress.get_address_for(self.user),
|
||||||
product=self.product,
|
product=self.product,
|
||||||
|
@ -309,12 +278,6 @@ class ModifyOrderTestCase(TestCase):
|
||||||
|
|
||||||
order1.update_order(vm_order_downgrade_config, starting_date=change1_date)
|
order1.update_order(vm_order_downgrade_config, starting_date=change1_date)
|
||||||
|
|
||||||
# product = Product.objects.create(owner=user, rc_price=starting_price)
|
|
||||||
# product.create_order(starting_date)
|
|
||||||
# product.rc_price = downgrade_price
|
|
||||||
# product.save()
|
|
||||||
# product.create_or_update_recurring_order(when_to_start=change1_date)
|
|
||||||
|
|
||||||
bills = Bill.create_next_bills_for_user(user, ending_date=bill_ending_date)
|
bills = Bill.create_next_bills_for_user(user, ending_date=bill_ending_date)
|
||||||
|
|
||||||
bill = bills[0]
|
bill = bills[0]
|
||||||
|
@ -325,105 +288,6 @@ class ModifyOrderTestCase(TestCase):
|
||||||
self.assertEqual(bill_records[0].starting_date, starting_date)
|
self.assertEqual(bill_records[0].starting_date, starting_date)
|
||||||
self.assertEqual(bill_records[0].order.ending_date, first_order_should_end_at)
|
self.assertEqual(bill_records[0].order.ending_date, first_order_should_end_at)
|
||||||
|
|
||||||
# self.assertEqual(bill_records[0].ending_date, first_order_should_end_at)
|
|
||||||
|
|
||||||
# self.assertEqual(bill_records[0].quantity, 1)
|
|
||||||
|
|
||||||
# self.assertEqual(bill_records[1].quantity, 1)
|
|
||||||
# self.assertEqual(int(bill.sum), 15)
|
|
||||||
|
|
||||||
# def test_upgrade_product(self):
|
|
||||||
# """
|
|
||||||
# Test upgrading behaviour
|
|
||||||
# """
|
|
||||||
|
|
||||||
# user = self.user
|
|
||||||
|
|
||||||
# # Create product
|
|
||||||
# starting_date = timezone.make_aware(datetime.datetime(2019,3,3))
|
|
||||||
# starting_price = 10
|
|
||||||
# product = SampleRecurringProduct.objects.create(owner=user, rc_price=starting_price)
|
|
||||||
# product.create_order(starting_date)
|
|
||||||
|
|
||||||
# change1_date = start_after(starting_date + datetime.timedelta(days=15))
|
|
||||||
# product.rc_price = 20
|
|
||||||
# product.save()
|
|
||||||
# product.create_or_update_recurring_order(when_to_start=change1_date)
|
|
||||||
|
|
||||||
# bill_ending_date = change1_date + datetime.timedelta(days=1)
|
|
||||||
# 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(bill_records[0].quantity, .5)
|
|
||||||
|
|
||||||
# self.assertEqual(bill_records[0].ending_date, end_before(change1_date))
|
|
||||||
|
|
||||||
# self.assertEqual(bill_records[1].quantity, 1)
|
|
||||||
# self.assertEqual(bill_records[1].starting_date, change1_date)
|
|
||||||
|
|
||||||
# self.assertEqual(int(bill.sum), 25)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# def test_bill_for_increasing_product(self):
|
|
||||||
# """
|
|
||||||
# Modify a product, see one pro rata entry
|
|
||||||
# """
|
|
||||||
|
|
||||||
# # Create product
|
|
||||||
# starting_date = timezone.make_aware(datetime.datetime(2019,3,3))
|
|
||||||
# starting_price = 30.5
|
|
||||||
# product = SampleRecurringProduct.objects.create(owner=self.user,
|
|
||||||
# rc_price=starting_price)
|
|
||||||
# product.create_order(starting_date)
|
|
||||||
|
|
||||||
# recurring_period = product.default_recurring_period.value
|
|
||||||
|
|
||||||
# # First change
|
|
||||||
# change1_date = timezone.make_aware(datetime.datetime(2019,4,17))
|
|
||||||
# product.rc_price = 49.5
|
|
||||||
# product.save()
|
|
||||||
# product.create_or_update_recurring_order(when_to_start=change1_date)
|
|
||||||
|
|
||||||
# # Second change
|
|
||||||
# change2_date = timezone.make_aware(datetime.datetime(2019,5,8))
|
|
||||||
# product.rc_price = 56.5
|
|
||||||
# product.save()
|
|
||||||
# product.create_or_update_recurring_order(when_to_start=change2_date)
|
|
||||||
|
|
||||||
# # Create bill one month after 2nd change
|
|
||||||
# bill_ending_date = timezone.make_aware(datetime.datetime(2019,6,30))
|
|
||||||
# bills = Bill.create_next_bills_for_user(self.user,
|
|
||||||
# ending_date=bill_ending_date)
|
|
||||||
|
|
||||||
# # only one bill in this test case
|
|
||||||
# bill = bills[0]
|
|
||||||
|
|
||||||
# expected_amount = starting_price
|
|
||||||
|
|
||||||
# d2 = starting_date + recurring_period
|
|
||||||
# duration2 = change1_date - d2
|
|
||||||
|
|
||||||
# expected_amount = 0
|
|
||||||
|
|
||||||
# # Expected bill sum & records:
|
|
||||||
# # 2019-03-03 - 2019-04-02 +30d: 30.5
|
|
||||||
# # 2019-04-02 - 2019-04-17: +15d: 15.25
|
|
||||||
# # 2019-04-17 - 2019-05-08: +21d: (21/30) * 49.5
|
|
||||||
# # 2019-05-08 - 2019-06-07: +30d: 56.5
|
|
||||||
# # 2019-06-07 - 2019-07-07: +30d: 56.5
|
|
||||||
|
|
||||||
|
|
||||||
# self.assertEqual(bills[0].sum, price)
|
|
||||||
|
|
||||||
# # expeted result:
|
|
||||||
# # 1x 5 chf bill record
|
|
||||||
# # 1x 5 chf bill record
|
|
||||||
# # 1x 10 partial bill record
|
|
||||||
|
|
||||||
|
|
||||||
class BillTestCase(TestCase):
|
class BillTestCase(TestCase):
|
||||||
"""
|
"""
|
||||||
|
@ -431,6 +295,8 @@ class BillTestCase(TestCase):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
RecurringPeriod.populate_db_defaults()
|
||||||
|
|
||||||
self.user_without_address = get_user_model().objects.create(
|
self.user_without_address = get_user_model().objects.create(
|
||||||
username='no_home_person',
|
username='no_home_person',
|
||||||
email='far.away@domain.tld')
|
email='far.away@domain.tld')
|
||||||
|
@ -500,7 +366,7 @@ class BillTestCase(TestCase):
|
||||||
def order_chocolate(self):
|
def order_chocolate(self):
|
||||||
return Order.objects.create(
|
return Order.objects.create(
|
||||||
owner=self.user,
|
owner=self.user,
|
||||||
recurring_period=RecurringPeriod.ONE_TIME,
|
recurring_period=RecurringPeriod.objects.get(name="Onetime"),
|
||||||
product=self.chocolate,
|
product=self.chocolate,
|
||||||
billing_address=BillingAddress.get_address_for(self.user),
|
billing_address=BillingAddress.get_address_for(self.user),
|
||||||
starting_date=self.order_meta[1]['starting_date'],
|
starting_date=self.order_meta[1]['starting_date'],
|
||||||
|
@ -522,7 +388,7 @@ class BillTestCase(TestCase):
|
||||||
|
|
||||||
return Order.objects.create(
|
return Order.objects.create(
|
||||||
owner=self.user,
|
owner=self.user,
|
||||||
recurring_period=RecurringPeriod.ONE_TIME,
|
recurring_period=RecurringPeriod.objects.get(name="Onetime"),
|
||||||
product=self.chocolate,
|
product=self.chocolate,
|
||||||
billing_address=BillingAddress.get_address_for(self.user),
|
billing_address=BillingAddress.get_address_for(self.user),
|
||||||
starting_date=self.order_meta[1]['starting_date'],
|
starting_date=self.order_meta[1]['starting_date'],
|
||||||
|
@ -580,167 +446,6 @@ class BillTestCase(TestCase):
|
||||||
|
|
||||||
self.assertEqual(len(self.bill_dates), bill_count)
|
self.assertEqual(len(self.bill_dates), bill_count)
|
||||||
|
|
||||||
# def test_multi_addr_multi_bill(self):
|
|
||||||
# """
|
|
||||||
# Ensure multiple bills are created if orders exist with different billing addresses
|
|
||||||
# """
|
|
||||||
|
|
||||||
# username="lotsofplaces"
|
|
||||||
# multi_addr_user = get_user_model().objects.create(
|
|
||||||
# username=username,
|
|
||||||
# email=f"{username}@example.org")
|
|
||||||
|
|
||||||
# user_addr1 = BillingAddress.objects.create(
|
|
||||||
# owner=multi_addr_user,
|
|
||||||
# organization = 'Test org',
|
|
||||||
# street="unknown",
|
|
||||||
# city="unknown",
|
|
||||||
# postal_code="unknown",
|
|
||||||
# active=True)
|
|
||||||
|
|
||||||
# order1 = Order.objects.create(
|
|
||||||
# owner=multi_addr_user,
|
|
||||||
# recurring_period=RecurringPeriod.ONE_TIME,
|
|
||||||
# product=self.chocolate,
|
|
||||||
# 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)
|
|
||||||
|
|
||||||
# order1 = Order.objects.create(
|
|
||||||
# owner=multi_addr_user,
|
|
||||||
# starting_date=self.order_meta[1]['starting_date'],
|
|
||||||
# ending_date=self.order_meta[1]['ending_date'],
|
|
||||||
# recurring_period=RecurringPeriod.ONE_TIME,
|
|
||||||
# price=self.order_meta[1]['price'],
|
|
||||||
# description=self.order_meta[1]['description'],
|
|
||||||
# billing_address=BillingAddress.get_address_for(self.user))
|
|
||||||
|
|
||||||
# # Make this address inactive
|
|
||||||
# user_addr1.active = False
|
|
||||||
# user_addr1.save()
|
|
||||||
|
|
||||||
# user_addr2 = BillingAddress.objects.create(
|
|
||||||
# owner=multi_addr_user,
|
|
||||||
# organization = 'Test2 org',
|
|
||||||
# street="unknown2",
|
|
||||||
# city="unknown2",
|
|
||||||
# postal_code="unknown2",
|
|
||||||
# active=True)
|
|
||||||
|
|
||||||
# order2 = Order.objects.create(
|
|
||||||
# owner=multi_addr_user,
|
|
||||||
# starting_date=self.order_meta[1]['starting_date'],
|
|
||||||
# ending_date=self.order_meta[1]['ending_date'],
|
|
||||||
# recurring_period=RecurringPeriod.ONE_TIME,
|
|
||||||
# price=self.order_meta[1]['price'],
|
|
||||||
# description=self.order_meta[1]['description'],
|
|
||||||
# billing_address=BillingAddress.get_address_for(self.user))
|
|
||||||
|
|
||||||
|
|
||||||
# bills = Bill.create_next_bills_for_user(multi_addr_user)
|
|
||||||
|
|
||||||
# self.assertEqual(len(bills), 2)
|
|
||||||
|
|
||||||
|
|
||||||
# # TO BE IMPLEMENTED -- once orders can be marked as "done" / "inactive" / "not for billing"
|
|
||||||
# # def test_skip_disabled_orders(self):
|
|
||||||
# # """
|
|
||||||
# # Ensure that a bill only considers "active" orders
|
|
||||||
# # """
|
|
||||||
|
|
||||||
# # self.assertEqual(1, 2)
|
|
||||||
|
|
||||||
# class ProductTestCase(TestCase):
|
|
||||||
# """
|
|
||||||
# Test products and products <-> order interaction
|
|
||||||
# """
|
|
||||||
|
|
||||||
# def setUp(self):
|
|
||||||
# self.user = get_user_model().objects.create(
|
|
||||||
# username='random_user',
|
|
||||||
# email='jane.random@domain.tld')
|
|
||||||
|
|
||||||
# self.ba = BillingAddress.objects.create(
|
|
||||||
# owner=self.user,
|
|
||||||
# organization = 'Test org',
|
|
||||||
# street="unknown",
|
|
||||||
# city="unknown",
|
|
||||||
# postal_code="somewhere else",
|
|
||||||
# active=True)
|
|
||||||
|
|
||||||
# def test_create_one_time_product(self):
|
|
||||||
# """
|
|
||||||
# One time payment products cannot be updated - can they?
|
|
||||||
# """
|
|
||||||
|
|
||||||
# p = SampleOneTimeProduct.objects.create(owner=self.user)
|
|
||||||
|
|
||||||
# self.assertEqual(p.one_time_price, 5)
|
|
||||||
# self.assertEqual(p.recurring_price, 0)
|
|
||||||
|
|
||||||
# def test_create_product_without_active_billing_address(self):
|
|
||||||
# """
|
|
||||||
# Fail to create a product without an active billing address
|
|
||||||
# """
|
|
||||||
|
|
||||||
# self.ba.active = False
|
|
||||||
# self.ba.save()
|
|
||||||
|
|
||||||
# with self.assertRaises(ValidationError):
|
|
||||||
# p = SampleOneTimeProduct.objects.create(owner=self.user)
|
|
||||||
|
|
||||||
# def test_create_product_without_billing_address(self):
|
|
||||||
# """
|
|
||||||
# Fail to create a product without a billing address
|
|
||||||
# """
|
|
||||||
|
|
||||||
# user2 = get_user_model().objects.create(
|
|
||||||
# username='random_user2',
|
|
||||||
# email='jane.randomly@domain.tld')
|
|
||||||
|
|
||||||
# with self.assertRaises(ValidationError):
|
|
||||||
# p = SampleOneTimeProduct.objects.create(owner=user2)
|
|
||||||
|
|
||||||
|
|
||||||
# def test_create_order_creates_correct_order_count(self):
|
|
||||||
# """
|
|
||||||
# Ensure creating orders from product only creates 1 order
|
|
||||||
# """
|
|
||||||
|
|
||||||
# # One order
|
|
||||||
# p = SampleOneTimeProduct.objects.create(owner=self.user)
|
|
||||||
# p.create_order(timezone.make_aware(datetime.datetime(2020,3,3)))
|
|
||||||
|
|
||||||
# order_count = Order.objects.filter(owner=self.user).count()
|
|
||||||
# self.assertEqual(order_count, 1)
|
|
||||||
|
|
||||||
# # One more order
|
|
||||||
# p = SampleRecurringProduct.objects.create(owner=self.user)
|
|
||||||
# p.create_order(timezone.make_aware(datetime.datetime(2020,3,3)))
|
|
||||||
|
|
||||||
# order_count = Order.objects.filter(owner=self.user).count()
|
|
||||||
# self.assertEqual(order_count, 2)
|
|
||||||
|
|
||||||
# # Should create 2 orders
|
|
||||||
# p = SampleRecurringProductOneTimeFee.objects.create(owner=self.user)
|
|
||||||
# p.create_order(timezone.make_aware(datetime.datetime(2020,3,3)))
|
|
||||||
|
|
||||||
# order_count = Order.objects.filter(owner=self.user).count()
|
|
||||||
# self.assertEqual(order_count, 4)
|
|
||||||
|
|
||||||
|
|
||||||
# def test_update_recurring_order(self):
|
|
||||||
# """
|
|
||||||
# Ensure creating orders from product only creates 1 order
|
|
||||||
# """
|
|
||||||
|
|
||||||
# p = SampleRecurringProduct.objects.create(owner=self.user)
|
|
||||||
# p.create_order(timezone.make_aware(datetime.datetime(2020,3,3)))
|
|
||||||
|
|
||||||
# p.create_or_update_recurring_order(timezone.make_aware(datetime.datetime(2020,3,4)))
|
|
||||||
|
|
||||||
# # FIXME: where is the assert?
|
|
||||||
|
|
||||||
|
|
||||||
class BillingAddressTestCase(TestCase):
|
class BillingAddressTestCase(TestCase):
|
||||||
|
@ -758,219 +463,3 @@ class BillingAddressTestCase(TestCase):
|
||||||
self.assertRaises(uncloud_pay.models.BillingAddress.DoesNotExist,
|
self.assertRaises(uncloud_pay.models.BillingAddress.DoesNotExist,
|
||||||
BillingAddress.get_address_for,
|
BillingAddress.get_address_for,
|
||||||
self.user)
|
self.user)
|
||||||
|
|
||||||
# def test_user_only_inactive_address(self):
|
|
||||||
# """
|
|
||||||
# Raise an error, when there is no active address
|
|
||||||
# """
|
|
||||||
|
|
||||||
# ba = BillingAddress.objects.create(
|
|
||||||
# owner=self.user,
|
|
||||||
# organization = 'Test org',
|
|
||||||
# street="unknown",
|
|
||||||
# city="unknown",
|
|
||||||
# postal_code="somewhere else",
|
|
||||||
# active=False)
|
|
||||||
|
|
||||||
# self.assertRaises(uncloud_pay.models.BillingAddress.DoesNotExist,
|
|
||||||
# BillingAddress.get_address_for,
|
|
||||||
# self.user)
|
|
||||||
|
|
||||||
# def test_find_active_address(self):
|
|
||||||
# """
|
|
||||||
# Find the active address
|
|
||||||
# """
|
|
||||||
|
|
||||||
# ba = BillingAddress.objects.create(
|
|
||||||
# owner=self.user,
|
|
||||||
# organization = 'Test org',
|
|
||||||
# street="unknown",
|
|
||||||
# city="unknown",
|
|
||||||
# postal_code="unknown",
|
|
||||||
# active=True)
|
|
||||||
|
|
||||||
|
|
||||||
# self.assertEqual(BillingAddress.get_address_for(self.user), ba)
|
|
||||||
|
|
||||||
# def test_find_right_address_with_multiple_addresses(self):
|
|
||||||
# """
|
|
||||||
# Find the active address only, skip inactive
|
|
||||||
# """
|
|
||||||
|
|
||||||
# ba = BillingAddress.objects.create(
|
|
||||||
# owner=self.user,
|
|
||||||
# organization = 'Test org',
|
|
||||||
# street="unknown",
|
|
||||||
# city="unknown",
|
|
||||||
# postal_code="unknown",
|
|
||||||
# active=True)
|
|
||||||
|
|
||||||
# ba2 = BillingAddress.objects.create(
|
|
||||||
# owner=self.user,
|
|
||||||
# organization = 'Test org',
|
|
||||||
# street="unknown",
|
|
||||||
# city="unknown",
|
|
||||||
# postal_code="somewhere else",
|
|
||||||
# active=False)
|
|
||||||
|
|
||||||
|
|
||||||
# self.assertEqual(BillingAddress.get_address_for(self.user), ba)
|
|
||||||
|
|
||||||
# def test_change_addresses(self):
|
|
||||||
# """
|
|
||||||
# Switch the active address
|
|
||||||
# """
|
|
||||||
|
|
||||||
# ba = BillingAddress.objects.create(
|
|
||||||
# owner=self.user,
|
|
||||||
# organization = 'Test org',
|
|
||||||
# street="unknown",
|
|
||||||
# city="unknown",
|
|
||||||
# postal_code="unknown",
|
|
||||||
# active=True)
|
|
||||||
|
|
||||||
# self.assertEqual(BillingAddress.get_address_for(self.user), ba)
|
|
||||||
|
|
||||||
# ba.active=False
|
|
||||||
# ba.save()
|
|
||||||
|
|
||||||
# ba2 = BillingAddress.objects.create(
|
|
||||||
# owner=self.user,
|
|
||||||
# organization = 'Test org',
|
|
||||||
# street="unknown",
|
|
||||||
# city="unknown",
|
|
||||||
# postal_code="somewhere else",
|
|
||||||
# active=True)
|
|
||||||
|
|
||||||
# self.assertEqual(BillingAddress.get_address_for(self.user), ba2)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# class NotABillingTC(TestCase):
|
|
||||||
# #class BillingTestCase(TestCase):
|
|
||||||
# def setUp(self):
|
|
||||||
# self.user = get_user_model().objects.create(
|
|
||||||
# username='jdoe',
|
|
||||||
# email='john.doe@domain.tld')
|
|
||||||
# self.billing_address = BillingAddress.objects.create(
|
|
||||||
# owner=self.user,
|
|
||||||
# street="unknown",
|
|
||||||
# city="unknown",
|
|
||||||
# postal_code="unknown")
|
|
||||||
|
|
||||||
# def test_basic_monthly_billing(self):
|
|
||||||
# one_time_price = 10
|
|
||||||
# recurring_price = 20
|
|
||||||
# description = "Test Product 1"
|
|
||||||
|
|
||||||
# # Three months: full, full, partial.
|
|
||||||
# # starting_date = datetime.fromisoformat('2020-03-01')
|
|
||||||
# starting_date = datetime(2020,3,1)
|
|
||||||
# ending_date = datetime(2020,5,8)
|
|
||||||
|
|
||||||
# # Create order to be billed.
|
|
||||||
# order = Order.objects.create(
|
|
||||||
# owner=self.user,
|
|
||||||
# starting_date=starting_date,
|
|
||||||
# ending_date=ending_date,
|
|
||||||
# recurring_period=RecurringPeriod.PER_30D,
|
|
||||||
# recurring_price=recurring_price,
|
|
||||||
# one_time_price=one_time_price,
|
|
||||||
# description=description,
|
|
||||||
# billing_address=self.billing_address)
|
|
||||||
|
|
||||||
# # Generate & check bill for first month: full recurring_price + setup.
|
|
||||||
# first_month_bills = order.generate_initial_bill()
|
|
||||||
# self.assertEqual(len(first_month_bills), 1)
|
|
||||||
# self.assertEqual(first_month_bills[0].amount, one_time_price + recurring_price)
|
|
||||||
|
|
||||||
# # Generate & check bill for second month: full recurring_price.
|
|
||||||
# second_month_bills = Bill.generate_for(2020, 4, self.user)
|
|
||||||
# self.assertEqual(len(second_month_bills), 1)
|
|
||||||
# self.assertEqual(second_month_bills[0].amount, recurring_price)
|
|
||||||
|
|
||||||
# # Generate & check bill for third and last month: partial recurring_price.
|
|
||||||
# third_month_bills = Bill.generate_for(2020, 5, self.user)
|
|
||||||
# self.assertEqual(len(third_month_bills), 1)
|
|
||||||
# # 31 days in May.
|
|
||||||
# self.assertEqual(float(third_month_bills[0].amount),
|
|
||||||
# round(round((7/31), AMOUNT_DECIMALS) * recurring_price, AMOUNT_DECIMALS))
|
|
||||||
|
|
||||||
# # Check that running Bill.generate_for() twice does not create duplicates.
|
|
||||||
# self.assertEqual(len(Bill.generate_for(2020, 3, self.user)), 0)
|
|
||||||
|
|
||||||
# def test_basic_yearly_billing(self):
|
|
||||||
# one_time_price = 10
|
|
||||||
# recurring_price = 150
|
|
||||||
# description = "Test Product 1"
|
|
||||||
|
|
||||||
# starting_date = datetime.fromisoformat('2020-03-31T08:05:23')
|
|
||||||
|
|
||||||
# # Create order to be billed.
|
|
||||||
# order = Order.objects.create(
|
|
||||||
# owner=self.user,
|
|
||||||
# starting_date=starting_date,
|
|
||||||
# recurring_period=RecurringPeriod.PER_365D,
|
|
||||||
# recurring_price=recurring_price,
|
|
||||||
# one_time_price=one_time_price,
|
|
||||||
# description=description,
|
|
||||||
# billing_address=self.billing_address)
|
|
||||||
|
|
||||||
# # Generate & check bill for first year: recurring_price + setup.
|
|
||||||
# first_year_bills = order.generate_initial_bill()
|
|
||||||
# self.assertEqual(len(first_year_bills), 1)
|
|
||||||
# self.assertEqual(first_year_bills[0].starting_date.date(),
|
|
||||||
# date.fromisoformat('2020-03-31'))
|
|
||||||
# self.assertEqual(first_year_bills[0].ending_date.date(),
|
|
||||||
# date.fromisoformat('2021-03-30'))
|
|
||||||
# self.assertEqual(first_year_bills[0].amount,
|
|
||||||
# recurring_price + one_time_price)
|
|
||||||
|
|
||||||
# # Generate & check bill for second year: recurring_price.
|
|
||||||
# second_year_bills = Bill.generate_for(2021, 3, self.user)
|
|
||||||
# self.assertEqual(len(second_year_bills), 1)
|
|
||||||
# self.assertEqual(second_year_bills[0].starting_date.date(),
|
|
||||||
# date.fromisoformat('2021-03-31'))
|
|
||||||
# self.assertEqual(second_year_bills[0].ending_date.date(),
|
|
||||||
# date.fromisoformat('2022-03-30'))
|
|
||||||
# self.assertEqual(second_year_bills[0].amount, recurring_price)
|
|
||||||
|
|
||||||
# # Check that running Bill.generate_for() twice does not create duplicates.
|
|
||||||
# self.assertEqual(len(Bill.generate_for(2020, 3, self.user)), 0)
|
|
||||||
# self.assertEqual(len(Bill.generate_for(2020, 4, self.user)), 0)
|
|
||||||
# self.assertEqual(len(Bill.generate_for(2020, 2, self.user)), 0)
|
|
||||||
# self.assertEqual(len(Bill.generate_for(2021, 3, self.user)), 0)
|
|
||||||
|
|
||||||
# def test_basic_hourly_billing(self):
|
|
||||||
# one_time_price = 10
|
|
||||||
# recurring_price = 1.4
|
|
||||||
# description = "Test Product 1"
|
|
||||||
|
|
||||||
# starting_date = datetime.fromisoformat('2020-03-31T08:05:23')
|
|
||||||
# ending_date = datetime.fromisoformat('2020-04-01T11:13:32')
|
|
||||||
|
|
||||||
# # Create order to be billed.
|
|
||||||
# order = Order.objects.create(
|
|
||||||
# owner=self.user,
|
|
||||||
# starting_date=starting_date,
|
|
||||||
# ending_date=ending_date,
|
|
||||||
# recurring_period=RecurringPeriod.PER_HOUR,
|
|
||||||
# recurring_price=recurring_price,
|
|
||||||
# one_time_price=one_time_price,
|
|
||||||
# description=description,
|
|
||||||
# billing_address=self.billing_address)
|
|
||||||
|
|
||||||
# # Generate & check bill for first month: recurring_price + setup.
|
|
||||||
# first_month_bills = order.generate_initial_bill()
|
|
||||||
# self.assertEqual(len(first_month_bills), 1)
|
|
||||||
# self.assertEqual(float(first_month_bills[0].amount),
|
|
||||||
# round(16 * recurring_price, AMOUNT_DECIMALS) + one_time_price)
|
|
||||||
|
|
||||||
# # Generate & check bill for first month: recurring_price.
|
|
||||||
# second_month_bills = Bill.generate_for(2020, 4, self.user)
|
|
||||||
# self.assertEqual(len(second_month_bills), 1)
|
|
||||||
# self.assertEqual(float(second_month_bills[0].amount),
|
|
||||||
# round(12 * recurring_price, AMOUNT_DECIMALS))
|
|
||||||
|
|
Loading…
Reference in a new issue