bililng: Fix incorrect price per license on billing page.

There is a discrepancy between price per license shown on billing
and upgrade page for annual billing frequency due to difference
in methods used to calculate the amount.

To fix it, we use the same method on both the pages.

I didn't use the helpers.format_money directly here since that would
create a visual delay in showing the price per license which will
not be nice considering that will be the only thing on this page
being updated that way.

The stripe fixture used is same as
free_trial_upgrade_by_card--Customer.retrieve.3.json
This commit is contained in:
Aman Agrawal 2023-11-14 02:20:29 +00:00
parent 091e2f177b
commit 27ffcc6576
5 changed files with 32 additions and 8 deletions

View File

@ -68,6 +68,20 @@ STRIPE_API_VERSION = "2020-08-27"
stripe.api_version = STRIPE_API_VERSION
# This function imitates the behavior of the format_money in billing/helpers.ts
def format_money(cents: float) -> str:
# allow for small floating point errors
cents = math.ceil(cents - 0.001)
if cents % 100 == 0:
precision = 0
else:
precision = 2
dollars = cents / 100
# Format the number as a string with the correct number of decimal places
return f"{dollars:.{precision}f}"
def get_latest_seat_count(realm: Realm) -> int:
return get_seat_count(realm, extra_non_guests_count=0, extra_guests_count=0)

View File

@ -1208,6 +1208,16 @@ class StripeTest(StripeTestCase):
invoice_plans_as_needed(add_months(free_trial_end_date, 12))
[invoice0, invoice1, invoice2] = stripe.Invoice.list(customer=stripe_customer.id)
# Check /billing/ has correct information for fixed price customers.
plan.fixed_price = 127
plan.price_per_license = None
plan.save(update_fields=["fixed_price", "price_per_license"])
with patch("corporate.views.billing_page.timezone_now", return_value=self.now):
response = self.client_get("/billing/")
self.assert_in_success_response(["$1.27"], response)
# Don't show price breakdown
self.assert_not_in_success_response(["{self.seat_count} x"], response)
@mock_stripe(tested_timestamp_fields=["created"])
def test_free_trial_upgrade_by_card_from_onboarding_page(self, *mocks: Mock) -> None:
user = self.example_user("hamlet")

View File

@ -14,6 +14,7 @@ from corporate.lib.stripe import (
do_change_plan_status,
downgrade_at_the_end_of_billing_cycle,
downgrade_now_without_creating_additional_invoices,
format_money,
get_latest_seat_count,
make_end_of_cycle_updates_if_needed,
renewal_amount,
@ -194,15 +195,13 @@ def billing_home(
)
billing_frequency = CustomerPlan.BILLING_SCHEDULES[plan.billing_schedule]
price_per_license_int = plan.price_per_license
if price_per_license_int is not None and billing_frequency == "Annual":
price_per_license_int = int(price_per_license_int / 12)
price_per_license = (
cents_to_dollar_string(price_per_license_int)
if price_per_license_int is not None
else None
)
if plan.price_per_license is None:
price_per_license = ""
elif billing_frequency == "Annual":
price_per_license = format_money(plan.price_per_license / 12)
else:
price_per_license = format_money(plan.price_per_license)
context.update(
plan_name=plan.name,

View File

@ -89,6 +89,7 @@ export function create_ajax_request(
});
}
// This function imitates the behavior of the format_money in views/billing_page.py
export function format_money(cents: number): string {
// allow for small floating point errors
cents = Math.ceil(cents - 0.001);