mirror of
https://github.com/zulip/zulip.git
synced 2025-10-24 08:33:43 +00:00
stripe: Check for min_licenses when switching plan tier.
When we are upgrading a customer to a different plan tier, we should check if switching plans would lead to different licenses due to different minimum license requirement between plans.
This commit is contained in:
@@ -3164,7 +3164,17 @@ class BillingSession(ABC):
|
||||
LicenseLedger.objects.filter(plan=current_plan).order_by("id").last()
|
||||
)
|
||||
assert current_plan_last_ledger is not None
|
||||
licenses_for_new_plan = current_plan_last_ledger.licenses_at_next_renewal
|
||||
|
||||
old_plan_licenses_at_next_renewal = current_plan_last_ledger.licenses_at_next_renewal
|
||||
assert old_plan_licenses_at_next_renewal is not None
|
||||
licenses_for_new_plan = self.get_billable_licenses_for_customer(
|
||||
current_plan.customer,
|
||||
new_plan_tier,
|
||||
old_plan_licenses_at_next_renewal,
|
||||
)
|
||||
if not new_plan.automanage_licenses: # nocoverage
|
||||
licenses_for_new_plan = max(old_plan_licenses_at_next_renewal, licenses_for_new_plan)
|
||||
|
||||
assert licenses_for_new_plan is not None
|
||||
LicenseLedger.objects.create(
|
||||
plan=new_plan,
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
"account_country": "US",
|
||||
"account_name": "Kandra Labs, Inc.",
|
||||
"account_tax_ids": null,
|
||||
"amount_due": 3600,
|
||||
"amount_due": 4800,
|
||||
"amount_paid": 0,
|
||||
"amount_remaining": 3600,
|
||||
"amount_remaining": 4800,
|
||||
"amount_shipping": 0,
|
||||
"application": null,
|
||||
"application_fee_amount": null,
|
||||
@@ -12,6 +12,7 @@
|
||||
"attempted": false,
|
||||
"auto_advance": true,
|
||||
"automatic_tax": {
|
||||
"disabled_reason": null,
|
||||
"enabled": false,
|
||||
"liability": null,
|
||||
"status": null
|
||||
@@ -53,8 +54,8 @@
|
||||
"lines": {
|
||||
"data": [
|
||||
{
|
||||
"amount": 10800,
|
||||
"amount_excluding_tax": 10800,
|
||||
"amount": 12000,
|
||||
"amount_excluding_tax": 12000,
|
||||
"currency": "usd",
|
||||
"description": "Zulip Cloud Plus - renewal",
|
||||
"discount_amounts": [],
|
||||
@@ -71,6 +72,7 @@
|
||||
"start": 1000000000
|
||||
},
|
||||
"plan": null,
|
||||
"pretax_credit_amounts": [],
|
||||
"price": {
|
||||
"active": false,
|
||||
"billing_scheme": "per_unit",
|
||||
@@ -96,7 +98,7 @@
|
||||
"proration_details": {
|
||||
"credited_items": null
|
||||
},
|
||||
"quantity": 9,
|
||||
"quantity": 10,
|
||||
"subscription": null,
|
||||
"tax_amounts": [],
|
||||
"tax_rates": [],
|
||||
@@ -153,13 +155,14 @@
|
||||
"subscription_details": {
|
||||
"metadata": null
|
||||
},
|
||||
"subtotal": 10800,
|
||||
"subtotal_excluding_tax": 10800,
|
||||
"subtotal": 12000,
|
||||
"subtotal_excluding_tax": 12000,
|
||||
"tax": null,
|
||||
"test_clock": null,
|
||||
"total": 10800,
|
||||
"total": 12000,
|
||||
"total_discount_amounts": [],
|
||||
"total_excluding_tax": 10800,
|
||||
"total_excluding_tax": 12000,
|
||||
"total_pretax_credit_amounts": [],
|
||||
"total_tax_amounts": [],
|
||||
"transfer_data": null,
|
||||
"webhooks_delivered_at": null
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
"account_country": "US",
|
||||
"account_name": "Kandra Labs, Inc.",
|
||||
"account_tax_ids": null,
|
||||
"amount_due": 3600,
|
||||
"amount_due": 4800,
|
||||
"amount_paid": 0,
|
||||
"amount_remaining": 3600,
|
||||
"amount_remaining": 4800,
|
||||
"amount_shipping": 0,
|
||||
"application": null,
|
||||
"application_fee_amount": null,
|
||||
@@ -12,6 +12,7 @@
|
||||
"attempted": false,
|
||||
"auto_advance": true,
|
||||
"automatic_tax": {
|
||||
"disabled_reason": null,
|
||||
"enabled": false,
|
||||
"liability": null,
|
||||
"status": null
|
||||
@@ -53,8 +54,8 @@
|
||||
"lines": {
|
||||
"data": [
|
||||
{
|
||||
"amount": 10800,
|
||||
"amount_excluding_tax": 10800,
|
||||
"amount": 12000,
|
||||
"amount_excluding_tax": 12000,
|
||||
"currency": "usd",
|
||||
"description": "Zulip Cloud Plus - renewal",
|
||||
"discount_amounts": [],
|
||||
@@ -71,6 +72,7 @@
|
||||
"start": 1000000000
|
||||
},
|
||||
"plan": null,
|
||||
"pretax_credit_amounts": [],
|
||||
"price": {
|
||||
"active": false,
|
||||
"billing_scheme": "per_unit",
|
||||
@@ -96,7 +98,7 @@
|
||||
"proration_details": {
|
||||
"credited_items": null
|
||||
},
|
||||
"quantity": 9,
|
||||
"quantity": 10,
|
||||
"subscription": null,
|
||||
"tax_amounts": [],
|
||||
"tax_rates": [],
|
||||
@@ -153,13 +155,14 @@
|
||||
"subscription_details": {
|
||||
"metadata": null
|
||||
},
|
||||
"subtotal": 10800,
|
||||
"subtotal_excluding_tax": 10800,
|
||||
"subtotal": 12000,
|
||||
"subtotal_excluding_tax": 12000,
|
||||
"tax": null,
|
||||
"test_clock": null,
|
||||
"total": 10800,
|
||||
"total": 12000,
|
||||
"total_discount_amounts": [],
|
||||
"total_excluding_tax": 10800,
|
||||
"total_excluding_tax": 12000,
|
||||
"total_pretax_credit_amounts": [],
|
||||
"total_tax_amounts": [],
|
||||
"transfer_data": null,
|
||||
"webhooks_delivered_at": null
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"account_country": "US",
|
||||
"account_name": "Kandra Labs, Inc.",
|
||||
"account_tax_ids": null,
|
||||
"amount_due": 3600,
|
||||
"amount_due": 4800,
|
||||
"amount_paid": 0,
|
||||
"amount_remaining": 3600,
|
||||
"amount_remaining": 4800,
|
||||
"amount_shipping": 0,
|
||||
"application": null,
|
||||
"application_fee_amount": null,
|
||||
@@ -14,6 +14,7 @@
|
||||
"attempted": false,
|
||||
"auto_advance": true,
|
||||
"automatic_tax": {
|
||||
"disabled_reason": null,
|
||||
"enabled": false,
|
||||
"liability": null,
|
||||
"status": null
|
||||
@@ -55,8 +56,8 @@
|
||||
"lines": {
|
||||
"data": [
|
||||
{
|
||||
"amount": 10800,
|
||||
"amount_excluding_tax": 10800,
|
||||
"amount": 12000,
|
||||
"amount_excluding_tax": 12000,
|
||||
"currency": "usd",
|
||||
"description": "Zulip Cloud Plus - renewal",
|
||||
"discount_amounts": [],
|
||||
@@ -73,6 +74,7 @@
|
||||
"start": 1000000000
|
||||
},
|
||||
"plan": null,
|
||||
"pretax_credit_amounts": [],
|
||||
"price": {
|
||||
"active": false,
|
||||
"billing_scheme": "per_unit",
|
||||
@@ -98,7 +100,7 @@
|
||||
"proration_details": {
|
||||
"credited_items": null
|
||||
},
|
||||
"quantity": 9,
|
||||
"quantity": 10,
|
||||
"subscription": null,
|
||||
"tax_amounts": [],
|
||||
"tax_rates": [],
|
||||
@@ -155,16 +157,17 @@
|
||||
"subscription_details": {
|
||||
"metadata": null
|
||||
},
|
||||
"subtotal": 10800,
|
||||
"subtotal_excluding_tax": 10800,
|
||||
"subtotal": 12000,
|
||||
"subtotal_excluding_tax": 12000,
|
||||
"tax": null,
|
||||
"test_clock": null,
|
||||
"total": 10800,
|
||||
"total": 12000,
|
||||
"total_discount_amounts": [],
|
||||
"total_excluding_tax": 10800,
|
||||
"total_excluding_tax": 12000,
|
||||
"total_pretax_credit_amounts": [],
|
||||
"total_tax_amounts": [],
|
||||
"transfer_data": null,
|
||||
"webhooks_delivered_at": 1000000000
|
||||
"webhooks_delivered_at": null
|
||||
}
|
||||
],
|
||||
"has_more": false,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"amount": 10800,
|
||||
"amount": 12000,
|
||||
"currency": "usd",
|
||||
"customer": "cus_NORMALIZED",
|
||||
"date": 1000000000,
|
||||
@@ -38,7 +38,7 @@
|
||||
"unit_amount_decimal": "1200"
|
||||
},
|
||||
"proration": false,
|
||||
"quantity": 9,
|
||||
"quantity": 10,
|
||||
"subscription": null,
|
||||
"tax_rates": [],
|
||||
"test_clock": null,
|
||||
|
||||
@@ -4912,10 +4912,11 @@ class StripeTest(StripeTestCase):
|
||||
|
||||
# There are 9 licenses and the realm is on the Standard monthly plan.
|
||||
# Therefore, the customer has already paid 800 * 9 = 7200 = $72 for
|
||||
# the month. Once they upgrade to Plus, the new price for their 9
|
||||
# licenses will be 1200 * 9 = 10800 = $108. Since the customer has
|
||||
# already paid $72 for a month, -7200 = -$72 will be credited to the
|
||||
# customer's balance.
|
||||
# the month. Once they upgrade to Plus, they will have to pay for 10
|
||||
# licenses as that is the minimum licenses for that plan.
|
||||
# The new price for their 10 licenses will be 1200 * 10 = 12000 = $120.
|
||||
# Since the customer has already paid $72 for a month, -7200 = -$72 will
|
||||
# be credited to the customer's balance.
|
||||
stripe_customer_id = customer.stripe_customer_id
|
||||
assert stripe_customer_id is not None
|
||||
_, cb_txn = iter(stripe.Customer.list_balance_transactions(stripe_customer_id))
|
||||
@@ -4926,10 +4927,10 @@ class StripeTest(StripeTestCase):
|
||||
)
|
||||
self.assertEqual(cb_txn.type, "adjustment")
|
||||
|
||||
# The customer now only pays the difference 10800 - 7200 = 3600 = $36,
|
||||
# The customer now only pays the difference 12000 - 7200 = 4800 = $48,
|
||||
# since the unused proration is for the whole month.
|
||||
(invoice,) = iter(stripe.Invoice.list(customer=stripe_customer_id))
|
||||
self.assertEqual(invoice.amount_due, 3600)
|
||||
self.assertEqual(invoice.amount_due, 4800)
|
||||
|
||||
@mock_stripe()
|
||||
def test_customer_has_credit_card_as_default_payment_method(self, *mocks: Mock) -> None:
|
||||
|
||||
Reference in New Issue
Block a user