CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/client/purchases.ts
Views: 687
1
/*
2
Functions for interfacing with the purchases functionality.
3
4
TODO/DEPRECATE: this module is mostly pointess since I moved essentially
5
all of this code to @cocalc/frontend/purchases/api, which is much better
6
since it can also be used directly by our nextjs app, and also is
7
scoped better. That said quotaModal is here.
8
*/
9
10
import type { Service } from "@cocalc/util/db-schema/purchases";
11
import { redux } from "@cocalc/frontend/app-framework";
12
import { once } from "@cocalc/util/async-utils";
13
import type { ProjectQuota } from "@cocalc/util/db-schema/purchase-quotas";
14
import * as purchasesApi from "@cocalc/frontend/purchases/api";
15
import type { Changes as EditLicenseChanges } from "@cocalc/util/purchases/cost-to-edit-license";
16
import { round2up } from "@cocalc/util/misc";
17
18
export class PurchasesClient {
19
api: typeof purchasesApi;
20
21
constructor() {
22
this.api = purchasesApi;
23
}
24
async getQuotas(): Promise<{
25
minBalance: number;
26
services: { [service: string]: number };
27
}> {
28
return await purchasesApi.getQuotas();
29
}
30
31
async getBalance(): Promise<number> {
32
return await purchasesApi.getBalance();
33
}
34
35
async getSpendRate(): Promise<number> {
36
return await purchasesApi.getSpendRate();
37
}
38
39
async getClosingDates(): Promise<{ last: Date; next: Date }> {
40
return await purchasesApi.getClosingDates();
41
}
42
43
async setQuota(
44
service: Service,
45
value: number,
46
): Promise<{ global: number; services: { [service: string]: number } }> {
47
return await purchasesApi.setQuota(service, value);
48
}
49
50
async isPurchaseAllowed(
51
service: Service,
52
cost?: number,
53
): Promise<{ allowed: boolean; reason?: string; chargeAmount?: number }> {
54
return await purchasesApi.isPurchaseAllowed(service, cost);
55
}
56
57
async getPurchases(opts: {
58
thisMonth?: boolean; // if true, limit and offset are ignored
59
limit?: number;
60
offset?: number;
61
service?: Service;
62
project_id?: string;
63
group?: boolean;
64
}) {
65
return await purchasesApi.getPurchases(opts);
66
}
67
68
async editLicense(opts: { license_id: string; changes: EditLicenseChanges }) {
69
return await purchasesApi.editLicense(opts);
70
}
71
72
async getInvoice(invoice_id: string) {
73
return await purchasesApi.getInvoice(invoice_id);
74
}
75
76
async getCostPerDay(opts: { limit?: number; offset?: number }) {
77
return await purchasesApi.getCostPerDay(opts);
78
}
79
80
async quotaModal({
81
service,
82
cost,
83
allowed,
84
reason,
85
cost_per_hour,
86
}: {
87
service?: Service;
88
// cost = how much you have to have available in your account
89
cost?: number;
90
allowed?: boolean;
91
reason?: string;
92
// the rate if this is a pay-as-you-go metered purchase.
93
cost_per_hour?: number;
94
} = {}): Promise<void> {
95
const actions = redux.getActions("billing");
96
actions.setState({
97
pay_as_you_go: {
98
showModal: true,
99
service,
100
cost: cost != null ? round2up(cost) : cost,
101
reason,
102
allowed,
103
cost_per_hour,
104
} as any,
105
});
106
await waitUntilPayAsYouGoModalCloses();
107
}
108
109
async getPaymentMethods() {
110
return await purchasesApi.getPaymentMethods();
111
}
112
113
async getCustomer() {
114
return await purchasesApi.getCustomer();
115
}
116
117
async getChargesByService() {
118
return await purchasesApi.getChargesByService();
119
}
120
121
async createCredit(opts): Promise<any> {
122
return await purchasesApi.createCredit(opts);
123
}
124
125
async getCurrentCheckoutSession() {
126
return await purchasesApi.getCurrentCheckoutSession();
127
}
128
129
async getUnpaidInvoices(): Promise<any[]> {
130
return await purchasesApi.getUnpaidInvoices();
131
}
132
133
async getServiceCost(service: Service): Promise<any> {
134
return await purchasesApi.getServiceCost(service);
135
}
136
137
async getMinimumPayment(): Promise<number> {
138
return await purchasesApi.getMinimumPayment();
139
}
140
141
async setPayAsYouGoProjectQuotas(project_id: string, quota: ProjectQuota) {
142
await purchasesApi.setPayAsYouGoProjectQuotas(project_id, quota);
143
}
144
145
async getPayAsYouGoMaxProjectQuotas(): Promise<ProjectQuota> {
146
return await purchasesApi.getPayAsYouGoMaxProjectQuotas();
147
}
148
149
async getPayAsYouGoPricesProjectQuotas(): Promise<{
150
cores: number;
151
disk_quota: number;
152
memory: number;
153
member_host: number;
154
}> {
155
return await purchasesApi.getPayAsYouGoPricesProjectQuotas();
156
}
157
158
async syncPaidInvoices() {
159
await purchasesApi.syncPaidInvoices();
160
}
161
162
// this is only used in the nextjs store app right now...
163
async getShoppingCartCheckoutParams() {
164
return await purchasesApi.getShoppingCartCheckoutParams();
165
}
166
167
async getVoucherCartCheckoutParams(count: number) {
168
return await purchasesApi.getVoucherCartCheckoutParams(count);
169
}
170
171
async adminGetMinBalance(account_id: string): Promise<number> {
172
return await purchasesApi.adminGetMinBalance(account_id);
173
}
174
175
async adminSetMinBalance(account_id: string, minBalance: number) {
176
await purchasesApi.adminSetMinBalance(account_id, minBalance);
177
}
178
179
async getLicense(license_id: string) {
180
return await purchasesApi.getLicense(license_id);
181
}
182
183
async renewSubscription(
184
subscription_id: number,
185
): Promise<{ purchase_id: number | null }> {
186
return await purchasesApi.renewSubscription(subscription_id);
187
}
188
189
async getLiveSubscriptions() {
190
return await purchasesApi.getLiveSubscriptions();
191
}
192
}
193
194
async function waitUntilPayAsYouGoModalCloses() {
195
const store = redux.getStore("billing");
196
while (true) {
197
await once(store, "change");
198
if (!store.getIn(["pay_as_you_go", "showModal"])) {
199
return;
200
}
201
}
202
}
203
204