Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Support for Tiered Pricing Plans #629

Open
wants to merge 14 commits into
base: original
Choose a base branch
from
Prev Previous commit
Increase Code Coverage
  • Loading branch information
jksimoniii committed Feb 3, 2019
commit 4104c7dbc06d47861f77c69357b29ec7ff3a9413
8 changes: 3 additions & 5 deletions pinax/stripe/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,14 @@ def calculate_final_cost(self, plan, quantity, mode):
raise Exception("Received wrong type of mode ({})".format(mode))

all_tiers = self.all_tiers(plan)

cost = 0
if mode == self.TIERS_MODE_VOLUME:
applicable_tiers = list(filter(lambda t: not t.up_to or quantity <= t.up_to, all_tiers))
tier = applicable_tiers[0] if applicable_tiers else all_tiers[-1]
cost = tier.calculate_cost(quantity)
elif mode == self.TIERS_MODE_GRADUATED:

if mode == self.TIERS_MODE_GRADUATED:
quantity_billed = 0
cost = 0
idx = 0
while quantity > 0:
tier = all_tiers[idx]
Expand All @@ -109,7 +109,5 @@ def calculate_final_cost(self, plan, quantity, mode):
quantity -= quantity_to_bill
quantity_billed += quantity_to_bill
idx += 1
else:
cost = 0

return cost
23 changes: 23 additions & 0 deletions pinax/stripe/tests/test_managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,26 @@ def test_calculate_final_cost_with_graduated_tiers_mode(self):
for quantity, expected in test_cases:
cost = Tier.pricing.calculate_final_cost(self.plan, quantity, Tier.pricing.TIERS_MODE_GRADUATED)
self.assertEqual(cost, expected)

def test_calculate_final_cost_with_volume_tiers_and_flat_fees(self):
test_cases = [
(12, 66)
]
for quantity, expected in test_cases:
cost = Tier.pricing.calculate_final_cost(self.plan, quantity, Tier.pricing.TIERS_MODE_VOLUME)
self.assertEqual(cost, expected)

def test_calculate_final_cost_with_graduated_tiers_and_flat_fees(self):
test_cases = [
(12, 111)
]
for quantity, expected in test_cases:
cost = Tier.pricing.calculate_final_cost(self.plan, quantity, Tier.pricing.TIERS_MODE_GRADUATED)
self.assertEqual(cost, expected)

def test_calculate_final_cost_with_invalid_tier(self):
try:
Tier.pricing.calculate_final_cost(self.plan, 1, "invalid")
self.fail("Excepted an exception from calculate_total_amount")
except:
pass
10 changes: 10 additions & 0 deletions pinax/stripe/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,16 @@ def test_plan_calculate_total_amount_tiered_billing_scheme(self, TierPricingMock
p.calculate_total_amount(quantity)
TierPricingMock.calculate_final_cost.assert_called_with(p, quantity, p.tiers_mode)

@patch("pinax.stripe.models.Tier.pricing")
def test_plan_calculate_total_amount_raises_exception_for_invalid_billing_scheme(self, TierPricingMock):
quantity = 10
p = Plan(amount=0, stripe_id="plan", billing_scheme="unknown")
try:
p.calculate_total_amount(quantity)
self.fail("Excepted an exception from calculate_total_amount")
except:
pass

def test_plan_per_account(self):
Plan.objects.create(stripe_id="plan", amount=decimal.Decimal("100"), interval="monthly", interval_count=1)
account = Account.objects.create(stripe_id="acct_A")
Expand Down