Skip to content

Commit 2e3d18d

Browse files
committed
add price fetching in FE & fix linting etc in backend changes
1 parent a47170e commit 2e3d18d

File tree

2 files changed

+34
-8
lines changed

2 files changed

+34
-8
lines changed

backend/btrixcloud/subs.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ async def get_billing_portal_url(
382382
return SubscriptionPortalUrlResponse()
383383

384384
async def get_execution_minutes_price(self, org: Organization):
385+
"""Fetch price for addon execution minutes from external subscription app"""
385386
if not org.subscription:
386387
raise HTTPException(
387388
status_code=404, detail="Organization has no subscription"
@@ -399,10 +400,12 @@ async def get_execution_minutes_price(self, org: Organization):
399400
) as resp:
400401
text = await resp.text()
401402
return AddonMinutesPricing.model_validate_json(text)
403+
# pylint: disable=broad-exception-caught
402404
except Exception as exc:
403405
print("Error fetching checkout url", exc)
404406

405407
async def get_checkout_url(self, org: Organization, minutes: int | None):
408+
"""Create checkout url for additional minutes"""
406409
if not org.subscription:
407410
raise HTTPException(
408411
status_code=404, detail="Organization has no subscription"
@@ -426,11 +429,12 @@ async def get_checkout_url(self, org: Organization, minutes: int | None):
426429
) as resp:
427430
text = await resp.text()
428431
return CheckoutAddonMinutesResponse.model_validate_json(text)
432+
# pylint: disable=broad-exception-caught
429433
except Exception as exc:
430434
print("Error fetching checkout url", exc)
431435

432436

433-
# pylint: disable=invalid-name,too-many-arguments
437+
# pylint: disable=invalid-name,too-many-arguments,too-many-locals
434438
def init_subs_api(
435439
app,
436440
mdb,
@@ -555,7 +559,7 @@ async def get_billing_portal_url(
555559
@org_ops.router.get(
556560
"/price/execution-minutes",
557561
tags=["organizations"],
558-
response_model=PriceResponse,
562+
response_model=AddonMinutesPricing,
559563
)
560564
async def get_execution_minutes_price(
561565
org: Organization = Depends(org_ops.org_owner_dep),
@@ -567,7 +571,7 @@ async def get_execution_minutes_price(
567571
tags=["organizations"],
568572
response_model=CheckoutAddonMinutesResponse,
569573
)
570-
async def get_billing_portal_url(
574+
async def get_execution_minutes_checkout_url(
571575
minutes: int | None = None,
572576
org: Organization = Depends(org_ops.org_owner_dep),
573577
):

frontend/src/pages/org/settings/components/billing-addon-link.ts

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,37 @@ import { type BillingAddonCheckout } from "@/types/billing";
99
import appState from "@/utils/state";
1010

1111
const PRESET_MINUTES = [600, 1500, 3000];
12-
const PRICE_PER_MINUTE: { value: number; currency: string } | undefined =
13-
undefined;
12+
13+
type Price = {
14+
value: number;
15+
currency: string;
16+
};
1417

1518
@customElement("btrix-org-settings-billing-addon-link")
1619
@localized()
1720
export class OrgSettingsBillingAddonLink extends BtrixElement {
21+
static _price: Price | undefined;
22+
1823
@state()
1924
private lastClickedMinutesPreset: number | undefined = undefined;
2025

26+
private readonly price = new Task(this, {
27+
task: async () => {
28+
if (OrgSettingsBillingAddonLink._price)
29+
return OrgSettingsBillingAddonLink._price;
30+
try {
31+
const price = await this.api.fetch<Price>(
32+
`/orgs/${this.orgId}/prices/execution-minutes`,
33+
);
34+
OrgSettingsBillingAddonLink._price = price;
35+
return price;
36+
} catch (error) {
37+
console.log("Failed to fetch price", error);
38+
return;
39+
}
40+
},
41+
});
42+
2143
private readonly checkoutUrl = new Task(this, {
2244
task: async ([minutes]) => {
2345
if (!appState.settings?.billingEnabled || !appState.org?.subscription)
@@ -73,10 +95,10 @@ export class OrgSettingsBillingAddonLink extends BtrixElement {
7395

7496
render() {
7597
const priceForMinutes = (minutes: number) => {
76-
if (!PRICE_PER_MINUTE) return;
77-
return this.localize.number(minutes * PRICE_PER_MINUTE.value, {
98+
if (!this.price.value) return;
99+
return this.localize.number(minutes * this.price.value.value, {
78100
style: "currency",
79-
currency: PRICE_PER_MINUTE.currency,
101+
currency: this.price.value.currency,
80102
});
81103
};
82104
const price = priceForMinutes(1);

0 commit comments

Comments
 (0)