Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/frontend/client/purchases.ts
Views: 687
/*1Functions for interfacing with the purchases functionality.23TODO/DEPRECATE: this module is mostly pointess since I moved essentially4all of this code to @cocalc/frontend/purchases/api, which is much better5since it can also be used directly by our nextjs app, and also is6scoped better. That said quotaModal is here.7*/89import type { Service } from "@cocalc/util/db-schema/purchases";10import { redux } from "@cocalc/frontend/app-framework";11import { once } from "@cocalc/util/async-utils";12import type { ProjectQuota } from "@cocalc/util/db-schema/purchase-quotas";13import * as purchasesApi from "@cocalc/frontend/purchases/api";14import type { Changes as EditLicenseChanges } from "@cocalc/util/purchases/cost-to-edit-license";15import { round2up } from "@cocalc/util/misc";1617export class PurchasesClient {18api: typeof purchasesApi;1920constructor() {21this.api = purchasesApi;22}23async getQuotas(): Promise<{24minBalance: number;25services: { [service: string]: number };26}> {27return await purchasesApi.getQuotas();28}2930async getBalance(): Promise<number> {31return await purchasesApi.getBalance();32}3334async getSpendRate(): Promise<number> {35return await purchasesApi.getSpendRate();36}3738async getClosingDates(): Promise<{ last: Date; next: Date }> {39return await purchasesApi.getClosingDates();40}4142async setQuota(43service: Service,44value: number,45): Promise<{ global: number; services: { [service: string]: number } }> {46return await purchasesApi.setQuota(service, value);47}4849async isPurchaseAllowed(50service: Service,51cost?: number,52): Promise<{ allowed: boolean; reason?: string; chargeAmount?: number }> {53return await purchasesApi.isPurchaseAllowed(service, cost);54}5556async getPurchases(opts: {57thisMonth?: boolean; // if true, limit and offset are ignored58limit?: number;59offset?: number;60service?: Service;61project_id?: string;62group?: boolean;63}) {64return await purchasesApi.getPurchases(opts);65}6667async editLicense(opts: { license_id: string; changes: EditLicenseChanges }) {68return await purchasesApi.editLicense(opts);69}7071async getInvoice(invoice_id: string) {72return await purchasesApi.getInvoice(invoice_id);73}7475async getCostPerDay(opts: { limit?: number; offset?: number }) {76return await purchasesApi.getCostPerDay(opts);77}7879async quotaModal({80service,81cost,82allowed,83reason,84cost_per_hour,85}: {86service?: Service;87// cost = how much you have to have available in your account88cost?: number;89allowed?: boolean;90reason?: string;91// the rate if this is a pay-as-you-go metered purchase.92cost_per_hour?: number;93} = {}): Promise<void> {94const actions = redux.getActions("billing");95actions.setState({96pay_as_you_go: {97showModal: true,98service,99cost: cost != null ? round2up(cost) : cost,100reason,101allowed,102cost_per_hour,103} as any,104});105await waitUntilPayAsYouGoModalCloses();106}107108async getPaymentMethods() {109return await purchasesApi.getPaymentMethods();110}111112async getCustomer() {113return await purchasesApi.getCustomer();114}115116async getChargesByService() {117return await purchasesApi.getChargesByService();118}119120async createCredit(opts): Promise<any> {121return await purchasesApi.createCredit(opts);122}123124async getCurrentCheckoutSession() {125return await purchasesApi.getCurrentCheckoutSession();126}127128async getUnpaidInvoices(): Promise<any[]> {129return await purchasesApi.getUnpaidInvoices();130}131132async getServiceCost(service: Service): Promise<any> {133return await purchasesApi.getServiceCost(service);134}135136async getMinimumPayment(): Promise<number> {137return await purchasesApi.getMinimumPayment();138}139140async setPayAsYouGoProjectQuotas(project_id: string, quota: ProjectQuota) {141await purchasesApi.setPayAsYouGoProjectQuotas(project_id, quota);142}143144async getPayAsYouGoMaxProjectQuotas(): Promise<ProjectQuota> {145return await purchasesApi.getPayAsYouGoMaxProjectQuotas();146}147148async getPayAsYouGoPricesProjectQuotas(): Promise<{149cores: number;150disk_quota: number;151memory: number;152member_host: number;153}> {154return await purchasesApi.getPayAsYouGoPricesProjectQuotas();155}156157async syncPaidInvoices() {158await purchasesApi.syncPaidInvoices();159}160161// this is only used in the nextjs store app right now...162async getShoppingCartCheckoutParams() {163return await purchasesApi.getShoppingCartCheckoutParams();164}165166async getVoucherCartCheckoutParams(count: number) {167return await purchasesApi.getVoucherCartCheckoutParams(count);168}169170async adminGetMinBalance(account_id: string): Promise<number> {171return await purchasesApi.adminGetMinBalance(account_id);172}173174async adminSetMinBalance(account_id: string, minBalance: number) {175await purchasesApi.adminSetMinBalance(account_id, minBalance);176}177178async getLicense(license_id: string) {179return await purchasesApi.getLicense(license_id);180}181182async renewSubscription(183subscription_id: number,184): Promise<{ purchase_id: number | null }> {185return await purchasesApi.renewSubscription(subscription_id);186}187188async getLiveSubscriptions() {189return await purchasesApi.getLiveSubscriptions();190}191}192193async function waitUntilPayAsYouGoModalCloses() {194const store = redux.getStore("billing");195while (true) {196await once(store, "change");197if (!store.getIn(["pay_as_you_go", "showModal"])) {198return;199}200}201}202203204