@etsoo/appscript 1.3.37 → 1.3.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -249,7 +249,18 @@ test('Tests for publicApi', async () => {
249
249
  const currencies1 = app.publicApi.currencies(true);
250
250
  expect(currencies1.length >= 10).toBeTruthy();
251
251
 
252
+ expect(app.publicApi.getCurrencyLabel('USD')).toBe('美元$');
253
+
254
+ const defaultExchangeRate = await app.publicApi.exchangeRate('CNY', {
255
+ showLoading: false
256
+ });
257
+ expect(defaultExchangeRate?.exchangeRate).toBe(100);
258
+
252
259
  /*
260
+ const amount1 = await app.publicApi.exchangeAmount(1000, 'NZD', 'CNY');
261
+ const amount2 = await app.publicApi.exchangeAmount(100, 'NZD', 'USD');
262
+ console.log(amount1, amount2);
263
+
253
264
  const orgs = await app.orgApi.list();
254
265
  console.log(orgs);
255
266
 
@@ -34,6 +34,10 @@ export declare abstract class CoreApp<U extends IUser, S extends IAppSettings, N
34
34
  * Settings
35
35
  */
36
36
  readonly settings: S;
37
+ /**
38
+ * Default region
39
+ */
40
+ readonly defaultRegion: AddressRegion;
37
41
  /**
38
42
  * Fields
39
43
  */
@@ -92,6 +92,7 @@ class CoreApp {
92
92
  * @param name Application name
93
93
  */
94
94
  constructor(settings, api, notifier, storage, name) {
95
+ var _a;
95
96
  this._authorized = false;
96
97
  this._isTryingLogin = false;
97
98
  /**
@@ -110,7 +111,15 @@ class CoreApp {
110
111
  * Passphrase for encryption
111
112
  */
112
113
  this.passphrase = '';
114
+ if (((_a = settings === null || settings === void 0 ? void 0 : settings.regions) === null || _a === void 0 ? void 0 : _a.length) === 0) {
115
+ throw new Error('No regions defined');
116
+ }
113
117
  this.settings = settings;
118
+ const region = AddressRegion_1.AddressRegion.getById(settings.regions[0]);
119
+ if (region == null) {
120
+ throw new Error('No default region defined');
121
+ }
122
+ this.defaultRegion = region;
114
123
  this.api = api;
115
124
  this.notifier = notifier;
116
125
  this.storage = storage;
@@ -64,6 +64,10 @@ export interface IApp {
64
64
  * Settings
65
65
  */
66
66
  readonly settings: IAppSettings;
67
+ /**
68
+ * Default region
69
+ */
70
+ readonly defaultRegion: AddressRegion;
67
71
  /**
68
72
  * Fields
69
73
  */
@@ -27,6 +27,12 @@ export declare class AddressApi extends BaseApi {
27
27
  * @param rq Rquest data
28
28
  */
29
29
  getRegions(rq?: RegionsRQ): Promise<AddressRegionDb[] | undefined>;
30
+ /**
31
+ * Get region's currency, current region's currency as default
32
+ * @param regionId Region id
33
+ * @returns Result
34
+ */
35
+ regionCurrency(regionId?: string): "AUD" | "CAD" | "CNY" | "EUR" | "GBP" | "HKD" | "JPY" | "NZD" | "SGD" | "USD";
30
36
  /**
31
37
  * Get all local regions
32
38
  */
@@ -78,6 +78,18 @@ class AddressApi extends BaseApi_1.BaseApi {
78
78
  // Return the top items
79
79
  return regions.slice(0, items);
80
80
  }
81
+ /**
82
+ * Get region's currency, current region's currency as default
83
+ * @param regionId Region id
84
+ * @returns Result
85
+ */
86
+ regionCurrency(regionId) {
87
+ var _a;
88
+ const region = (_a = (regionId
89
+ ? this.regions().find((region) => region.id === regionId)
90
+ : null)) !== null && _a !== void 0 ? _a : this.app.settings.currentRegion;
91
+ return region.currency;
92
+ }
81
93
  regions(p) {
82
94
  const items = p == null || p.length === 0
83
95
  ? AddressRegion_1.AddressRegion.all
@@ -11,20 +11,33 @@ import { PublicOrgProductDto, PublicProductDto } from './dto/PublicProductDto';
11
11
  * Public API
12
12
  */
13
13
  export declare class PublicApi extends BaseApi {
14
+ /**
15
+ * Default currency
16
+ */
17
+ defaultCurrency: string | Currency;
14
18
  /**
15
19
  * Get currencies
16
- * @param currencyNames Limited currency names for local data, undefined will try to retrive remoately
20
+ * @param names Limited currency names for local data, undefined will try to retrive remoately
17
21
  * @returns Result
18
22
  */
19
23
  currencies(): Promise<CurrencyDto[] | undefined>;
20
24
  currencies(names: string[] | Currency[] | boolean): ListType1[];
25
+ /**
26
+ * Get exchange amount
27
+ * @param amount Amount
28
+ * @param sourceCurrency Source currency
29
+ * @param targetCurrency Target currency
30
+ * @returns Result
31
+ */
32
+ exchangeAmount(amount: number, sourceCurrency: Currency | string, targetCurrency?: Currency | string): Promise<number | undefined>;
21
33
  /**
22
34
  * Get exchange rate
23
35
  * @param currency Currency
24
36
  * @param payload Payload
37
+ * @param reload Reload data
25
38
  * @returns Result
26
39
  */
27
- exchangeRate(currency: Currency | string, payload?: IApiPayload<ExchangeRateDto>): Promise<ExchangeRateDto | undefined>;
40
+ exchangeRate(currency: Currency | string, payload?: IApiPayload<ExchangeRateDto>, reload?: boolean): Promise<ExchangeRateDto | undefined>;
28
41
  /**
29
42
  * Get exchange rate history
30
43
  * @param currencies Currencies
@@ -33,6 +46,12 @@ export declare class PublicApi extends BaseApi {
33
46
  * @returns Result
34
47
  */
35
48
  exchangeRateHistory(currencies: (Currency | string)[], months?: number, payload?: IApiPayload<ExchangeRateHistoryDto[]>): Promise<ExchangeRateHistoryDto[] | undefined>;
49
+ /**
50
+ * Get currency label
51
+ * @param currency Currency
52
+ * @returns Label
53
+ */
54
+ getCurrencyLabel(currency: Currency | string): string;
36
55
  /**
37
56
  * Get product unit's label
38
57
  * Please define the label in culture with key 'unitPC' for ProductUnit.PC like that
@@ -6,10 +6,18 @@ const Currency_1 = require("../business/Currency");
6
6
  const ProductUnit_1 = require("../business/ProductUnit");
7
7
  const RepeatOption_1 = require("../business/RepeatOption");
8
8
  const BaseApi_1 = require("./BaseApi");
9
+ const cachedCurrencyRates = {};
9
10
  /**
10
11
  * Public API
11
12
  */
12
13
  class PublicApi extends BaseApi_1.BaseApi {
14
+ constructor() {
15
+ super(...arguments);
16
+ /**
17
+ * Default currency
18
+ */
19
+ this.defaultCurrency = this.app.defaultRegion.currency;
20
+ }
13
21
  currencies(names) {
14
22
  if (typeof names === 'boolean' && names) {
15
23
  return Currency_1.Currencies.map((name) => {
@@ -34,14 +42,48 @@ class PublicApi extends BaseApi_1.BaseApi {
34
42
  showLoading: false
35
43
  });
36
44
  }
45
+ /**
46
+ * Get exchange amount
47
+ * @param amount Amount
48
+ * @param sourceCurrency Source currency
49
+ * @param targetCurrency Target currency
50
+ * @returns Result
51
+ */
52
+ async exchangeAmount(amount, sourceCurrency, targetCurrency) {
53
+ targetCurrency !== null && targetCurrency !== void 0 ? targetCurrency : (targetCurrency = this.app.defaultRegion.currency);
54
+ const [sourceRate, targetRate] = await Promise.all([
55
+ this.exchangeRate(sourceCurrency, {
56
+ showLoading: false
57
+ }),
58
+ this.exchangeRate(targetCurrency, {
59
+ showLoading: false
60
+ })
61
+ ]);
62
+ if (sourceRate == null || targetRate == null)
63
+ return undefined;
64
+ const result = Math.round((1000 * amount * sourceRate.exchangeRate) /
65
+ targetRate.exchangeRate) / 1000;
66
+ return result;
67
+ }
37
68
  /**
38
69
  * Get exchange rate
39
70
  * @param currency Currency
40
71
  * @param payload Payload
72
+ * @param reload Reload data
41
73
  * @returns Result
42
74
  */
43
- exchangeRate(currency, payload) {
44
- return this.api.get(`Public/ExchangeRate/${currency}`, undefined, payload);
75
+ async exchangeRate(currency, payload, reload = false) {
76
+ let rate = cachedCurrencyRates[currency];
77
+ if (rate == null || reload) {
78
+ rate =
79
+ currency === this.defaultCurrency
80
+ ? { exchangeRate: 100, updateTime: new Date() }
81
+ : await this.api.get(`Public/ExchangeRate/${currency}`, undefined, payload);
82
+ if (rate == null)
83
+ return undefined;
84
+ cachedCurrencyRates[currency] = rate;
85
+ }
86
+ return rate;
45
87
  }
46
88
  /**
47
89
  * Get exchange rate history
@@ -54,6 +96,16 @@ class PublicApi extends BaseApi_1.BaseApi {
54
96
  payload !== null && payload !== void 0 ? payload : (payload = { defaultValue: [] });
55
97
  return this.api.post('Public/ExchangeRateHistory', { currencies, months }, payload);
56
98
  }
99
+ /**
100
+ * Get currency label
101
+ * @param currency Currency
102
+ * @returns Label
103
+ */
104
+ getCurrencyLabel(currency) {
105
+ var _a;
106
+ const c = `currency${currency}`;
107
+ return (_a = this.app.get(c)) !== null && _a !== void 0 ? _a : c;
108
+ }
57
109
  /**
58
110
  * Get product unit's label
59
111
  * Please define the label in culture with key 'unitPC' for ProductUnit.PC like that
@@ -34,6 +34,10 @@ export declare abstract class CoreApp<U extends IUser, S extends IAppSettings, N
34
34
  * Settings
35
35
  */
36
36
  readonly settings: S;
37
+ /**
38
+ * Default region
39
+ */
40
+ readonly defaultRegion: AddressRegion;
37
41
  /**
38
42
  * Fields
39
43
  */
@@ -89,6 +89,7 @@ export class CoreApp {
89
89
  * @param name Application name
90
90
  */
91
91
  constructor(settings, api, notifier, storage, name) {
92
+ var _a;
92
93
  this._authorized = false;
93
94
  this._isTryingLogin = false;
94
95
  /**
@@ -107,7 +108,15 @@ export class CoreApp {
107
108
  * Passphrase for encryption
108
109
  */
109
110
  this.passphrase = '';
111
+ if (((_a = settings === null || settings === void 0 ? void 0 : settings.regions) === null || _a === void 0 ? void 0 : _a.length) === 0) {
112
+ throw new Error('No regions defined');
113
+ }
110
114
  this.settings = settings;
115
+ const region = AddressRegion.getById(settings.regions[0]);
116
+ if (region == null) {
117
+ throw new Error('No default region defined');
118
+ }
119
+ this.defaultRegion = region;
111
120
  this.api = api;
112
121
  this.notifier = notifier;
113
122
  this.storage = storage;
@@ -64,6 +64,10 @@ export interface IApp {
64
64
  * Settings
65
65
  */
66
66
  readonly settings: IAppSettings;
67
+ /**
68
+ * Default region
69
+ */
70
+ readonly defaultRegion: AddressRegion;
67
71
  /**
68
72
  * Fields
69
73
  */
@@ -27,6 +27,12 @@ export declare class AddressApi extends BaseApi {
27
27
  * @param rq Rquest data
28
28
  */
29
29
  getRegions(rq?: RegionsRQ): Promise<AddressRegionDb[] | undefined>;
30
+ /**
31
+ * Get region's currency, current region's currency as default
32
+ * @param regionId Region id
33
+ * @returns Result
34
+ */
35
+ regionCurrency(regionId?: string): "AUD" | "CAD" | "CNY" | "EUR" | "GBP" | "HKD" | "JPY" | "NZD" | "SGD" | "USD";
30
36
  /**
31
37
  * Get all local regions
32
38
  */
@@ -75,6 +75,18 @@ export class AddressApi extends BaseApi {
75
75
  // Return the top items
76
76
  return regions.slice(0, items);
77
77
  }
78
+ /**
79
+ * Get region's currency, current region's currency as default
80
+ * @param regionId Region id
81
+ * @returns Result
82
+ */
83
+ regionCurrency(regionId) {
84
+ var _a;
85
+ const region = (_a = (regionId
86
+ ? this.regions().find((region) => region.id === regionId)
87
+ : null)) !== null && _a !== void 0 ? _a : this.app.settings.currentRegion;
88
+ return region.currency;
89
+ }
78
90
  regions(p) {
79
91
  const items = p == null || p.length === 0
80
92
  ? AddressRegion.all
@@ -11,20 +11,33 @@ import { PublicOrgProductDto, PublicProductDto } from './dto/PublicProductDto';
11
11
  * Public API
12
12
  */
13
13
  export declare class PublicApi extends BaseApi {
14
+ /**
15
+ * Default currency
16
+ */
17
+ defaultCurrency: string | Currency;
14
18
  /**
15
19
  * Get currencies
16
- * @param currencyNames Limited currency names for local data, undefined will try to retrive remoately
20
+ * @param names Limited currency names for local data, undefined will try to retrive remoately
17
21
  * @returns Result
18
22
  */
19
23
  currencies(): Promise<CurrencyDto[] | undefined>;
20
24
  currencies(names: string[] | Currency[] | boolean): ListType1[];
25
+ /**
26
+ * Get exchange amount
27
+ * @param amount Amount
28
+ * @param sourceCurrency Source currency
29
+ * @param targetCurrency Target currency
30
+ * @returns Result
31
+ */
32
+ exchangeAmount(amount: number, sourceCurrency: Currency | string, targetCurrency?: Currency | string): Promise<number | undefined>;
21
33
  /**
22
34
  * Get exchange rate
23
35
  * @param currency Currency
24
36
  * @param payload Payload
37
+ * @param reload Reload data
25
38
  * @returns Result
26
39
  */
27
- exchangeRate(currency: Currency | string, payload?: IApiPayload<ExchangeRateDto>): Promise<ExchangeRateDto | undefined>;
40
+ exchangeRate(currency: Currency | string, payload?: IApiPayload<ExchangeRateDto>, reload?: boolean): Promise<ExchangeRateDto | undefined>;
28
41
  /**
29
42
  * Get exchange rate history
30
43
  * @param currencies Currencies
@@ -33,6 +46,12 @@ export declare class PublicApi extends BaseApi {
33
46
  * @returns Result
34
47
  */
35
48
  exchangeRateHistory(currencies: (Currency | string)[], months?: number, payload?: IApiPayload<ExchangeRateHistoryDto[]>): Promise<ExchangeRateHistoryDto[] | undefined>;
49
+ /**
50
+ * Get currency label
51
+ * @param currency Currency
52
+ * @returns Label
53
+ */
54
+ getCurrencyLabel(currency: Currency | string): string;
36
55
  /**
37
56
  * Get product unit's label
38
57
  * Please define the label in culture with key 'unitPC' for ProductUnit.PC like that
@@ -3,10 +3,18 @@ import { Currencies } from '../business/Currency';
3
3
  import { ProductUnit } from '../business/ProductUnit';
4
4
  import { RepeatOption } from '../business/RepeatOption';
5
5
  import { BaseApi } from './BaseApi';
6
+ const cachedCurrencyRates = {};
6
7
  /**
7
8
  * Public API
8
9
  */
9
10
  export class PublicApi extends BaseApi {
11
+ constructor() {
12
+ super(...arguments);
13
+ /**
14
+ * Default currency
15
+ */
16
+ this.defaultCurrency = this.app.defaultRegion.currency;
17
+ }
10
18
  currencies(names) {
11
19
  if (typeof names === 'boolean' && names) {
12
20
  return Currencies.map((name) => {
@@ -31,14 +39,48 @@ export class PublicApi extends BaseApi {
31
39
  showLoading: false
32
40
  });
33
41
  }
42
+ /**
43
+ * Get exchange amount
44
+ * @param amount Amount
45
+ * @param sourceCurrency Source currency
46
+ * @param targetCurrency Target currency
47
+ * @returns Result
48
+ */
49
+ async exchangeAmount(amount, sourceCurrency, targetCurrency) {
50
+ targetCurrency !== null && targetCurrency !== void 0 ? targetCurrency : (targetCurrency = this.app.defaultRegion.currency);
51
+ const [sourceRate, targetRate] = await Promise.all([
52
+ this.exchangeRate(sourceCurrency, {
53
+ showLoading: false
54
+ }),
55
+ this.exchangeRate(targetCurrency, {
56
+ showLoading: false
57
+ })
58
+ ]);
59
+ if (sourceRate == null || targetRate == null)
60
+ return undefined;
61
+ const result = Math.round((1000 * amount * sourceRate.exchangeRate) /
62
+ targetRate.exchangeRate) / 1000;
63
+ return result;
64
+ }
34
65
  /**
35
66
  * Get exchange rate
36
67
  * @param currency Currency
37
68
  * @param payload Payload
69
+ * @param reload Reload data
38
70
  * @returns Result
39
71
  */
40
- exchangeRate(currency, payload) {
41
- return this.api.get(`Public/ExchangeRate/${currency}`, undefined, payload);
72
+ async exchangeRate(currency, payload, reload = false) {
73
+ let rate = cachedCurrencyRates[currency];
74
+ if (rate == null || reload) {
75
+ rate =
76
+ currency === this.defaultCurrency
77
+ ? { exchangeRate: 100, updateTime: new Date() }
78
+ : await this.api.get(`Public/ExchangeRate/${currency}`, undefined, payload);
79
+ if (rate == null)
80
+ return undefined;
81
+ cachedCurrencyRates[currency] = rate;
82
+ }
83
+ return rate;
42
84
  }
43
85
  /**
44
86
  * Get exchange rate history
@@ -51,6 +93,16 @@ export class PublicApi extends BaseApi {
51
93
  payload !== null && payload !== void 0 ? payload : (payload = { defaultValue: [] });
52
94
  return this.api.post('Public/ExchangeRateHistory', { currencies, months }, payload);
53
95
  }
96
+ /**
97
+ * Get currency label
98
+ * @param currency Currency
99
+ * @returns Label
100
+ */
101
+ getCurrencyLabel(currency) {
102
+ var _a;
103
+ const c = `currency${currency}`;
104
+ return (_a = this.app.get(c)) !== null && _a !== void 0 ? _a : c;
105
+ }
54
106
  /**
55
107
  * Get product unit's label
56
108
  * Please define the label in culture with key 'unitPC' for ProductUnit.PC like that
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/appscript",
3
- "version": "1.3.37",
3
+ "version": "1.3.38",
4
4
  "description": "Applications shared TypeScript framework",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/mjs/index.js",
@@ -65,8 +65,8 @@
65
65
  "@babel/preset-env": "^7.20.2",
66
66
  "@babel/runtime-corejs3": "^7.20.1",
67
67
  "@types/jest": "^29.2.3",
68
- "@typescript-eslint/eslint-plugin": "^5.43.0",
69
- "@typescript-eslint/parser": "^5.43.0",
68
+ "@typescript-eslint/eslint-plugin": "^5.44.0",
69
+ "@typescript-eslint/parser": "^5.44.0",
70
70
  "eslint": "^8.28.0",
71
71
  "eslint-config-airbnb-base": "^15.0.0",
72
72
  "eslint-plugin-import": "^2.26.0",
@@ -89,6 +89,11 @@ export abstract class CoreApp<
89
89
  */
90
90
  readonly settings: S;
91
91
 
92
+ /**
93
+ * Default region
94
+ */
95
+ readonly defaultRegion: AddressRegion;
96
+
92
97
  /**
93
98
  * Fields
94
99
  */
@@ -246,7 +251,17 @@ export abstract class CoreApp<
246
251
  storage: IStorage,
247
252
  name: string
248
253
  ) {
254
+ if (settings?.regions?.length === 0) {
255
+ throw new Error('No regions defined');
256
+ }
249
257
  this.settings = settings;
258
+
259
+ const region = AddressRegion.getById(settings.regions[0]);
260
+ if (region == null) {
261
+ throw new Error('No default region defined');
262
+ }
263
+ this.defaultRegion = region;
264
+
250
265
  this.api = api;
251
266
  this.notifier = notifier;
252
267
  this.storage = storage;
package/src/app/IApp.ts CHANGED
@@ -89,6 +89,11 @@ export interface IApp {
89
89
  */
90
90
  readonly settings: IAppSettings;
91
91
 
92
+ /**
93
+ * Default region
94
+ */
95
+ readonly defaultRegion: AddressRegion;
96
+
92
97
  /**
93
98
  * Fields
94
99
  */
@@ -92,6 +92,19 @@ export class AddressApi extends BaseApi {
92
92
  return regions.slice(0, items);
93
93
  }
94
94
 
95
+ /**
96
+ * Get region's currency, current region's currency as default
97
+ * @param regionId Region id
98
+ * @returns Result
99
+ */
100
+ regionCurrency(regionId?: string) {
101
+ const region =
102
+ (regionId
103
+ ? this.regions().find((region) => region.id === regionId)
104
+ : null) ?? this.app.settings.currentRegion;
105
+ return region.currency;
106
+ }
107
+
95
108
  /**
96
109
  * Get all local regions
97
110
  */
@@ -9,13 +9,22 @@ import { ExchangeRateDto } from './dto/ExchangeRateDto';
9
9
  import { ExchangeRateHistoryDto } from './dto/ExchangeRateHistoryDto';
10
10
  import { PublicOrgProductDto, PublicProductDto } from './dto/PublicProductDto';
11
11
 
12
+ const cachedCurrencyRates: {
13
+ [P: Currency | string]: ExchangeRateDto | undefined | null;
14
+ } = {};
15
+
12
16
  /**
13
17
  * Public API
14
18
  */
15
19
  export class PublicApi extends BaseApi {
20
+ /**
21
+ * Default currency
22
+ */
23
+ defaultCurrency: string | Currency = this.app.defaultRegion.currency;
24
+
16
25
  /**
17
26
  * Get currencies
18
- * @param currencyNames Limited currency names for local data, undefined will try to retrive remoately
27
+ * @param names Limited currency names for local data, undefined will try to retrive remoately
19
28
  * @returns Result
20
29
  */
21
30
  currencies(): Promise<CurrencyDto[] | undefined>;
@@ -41,21 +50,64 @@ export class PublicApi extends BaseApi {
41
50
  });
42
51
  }
43
52
 
53
+ /**
54
+ * Get exchange amount
55
+ * @param amount Amount
56
+ * @param sourceCurrency Source currency
57
+ * @param targetCurrency Target currency
58
+ * @returns Result
59
+ */
60
+ async exchangeAmount(
61
+ amount: number,
62
+ sourceCurrency: Currency | string,
63
+ targetCurrency?: Currency | string
64
+ ) {
65
+ targetCurrency ??= this.app.defaultRegion.currency;
66
+
67
+ const [sourceRate, targetRate] = await Promise.all([
68
+ this.exchangeRate(sourceCurrency, {
69
+ showLoading: false
70
+ }),
71
+ this.exchangeRate(targetCurrency, {
72
+ showLoading: false
73
+ })
74
+ ]);
75
+ if (sourceRate == null || targetRate == null) return undefined;
76
+
77
+ const result =
78
+ Math.round(
79
+ (1000 * amount * sourceRate.exchangeRate) /
80
+ targetRate.exchangeRate
81
+ ) / 1000;
82
+ return result;
83
+ }
84
+
44
85
  /**
45
86
  * Get exchange rate
46
87
  * @param currency Currency
47
88
  * @param payload Payload
89
+ * @param reload Reload data
48
90
  * @returns Result
49
91
  */
50
- exchangeRate(
92
+ async exchangeRate(
51
93
  currency: Currency | string,
52
- payload?: IApiPayload<ExchangeRateDto>
94
+ payload?: IApiPayload<ExchangeRateDto>,
95
+ reload = false
53
96
  ) {
54
- return this.api.get(
55
- `Public/ExchangeRate/${currency}`,
56
- undefined,
57
- payload
58
- );
97
+ let rate = cachedCurrencyRates[currency];
98
+ if (rate == null || reload) {
99
+ rate =
100
+ currency === this.defaultCurrency
101
+ ? { exchangeRate: 100, updateTime: new Date() }
102
+ : await this.api.get(
103
+ `Public/ExchangeRate/${currency}`,
104
+ undefined,
105
+ payload
106
+ );
107
+ if (rate == null) return undefined;
108
+ cachedCurrencyRates[currency] = rate;
109
+ }
110
+ return rate;
59
111
  }
60
112
 
61
113
  /**
@@ -78,6 +130,16 @@ export class PublicApi extends BaseApi {
78
130
  );
79
131
  }
80
132
 
133
+ /**
134
+ * Get currency label
135
+ * @param currency Currency
136
+ * @returns Label
137
+ */
138
+ getCurrencyLabel(currency: Currency | string) {
139
+ const c = `currency${currency}`;
140
+ return this.app.get(c) ?? c;
141
+ }
142
+
81
143
  /**
82
144
  * Get product unit's label
83
145
  * Please define the label in culture with key 'unitPC' for ProductUnit.PC like that