@etsoo/smarterp-core 1.1.59 → 1.1.60

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.
@@ -3,11 +3,56 @@ import { isLocalTest, TestApp } from "./app/TestApp";
3
3
  import { EntityStatus } from "@etsoo/appscript";
4
4
  import { OrgApi } from "../src/OrgApi";
5
5
  import { OrgCreateRQ } from "../src/rq/org/OrgCreateRQ";
6
+ import { CoreApp } from "../src";
7
+
8
+ const app = new TestApp();
9
+ await app.changeCulture(app.settings.cultures[0]);
10
+
11
+ test("Test SysResourceKeyPrefix", () => {
12
+ const source = [
13
+ {
14
+ period: 202601,
15
+ qty: 236
16
+ },
17
+ {
18
+ period: 202602,
19
+ qty: 99
20
+ },
21
+ {
22
+ period: 202603,
23
+ qty: 120
24
+ },
25
+ {
26
+ period: 202604,
27
+ qty: 199
28
+ },
29
+ {
30
+ period: 202605,
31
+ qty: 230
32
+ },
33
+ {
34
+ period: 202606,
35
+ qty: 3
36
+ },
37
+ {
38
+ period: 202505,
39
+ qty: 215
40
+ }
41
+ ];
42
+
43
+ const core = new CoreApp(app, app.api);
44
+ const result = core.transformReportData(source, true, 2026);
45
+
46
+ expect(result.labels.length).toBe(12);
47
+ expect(result.currentYearData[5]).toBe(3);
48
+ expect(result.lastYearData[4]).toBe(215);
49
+ });
50
+
51
+ test("Test SysResourceKeyPrefix", () => {
52
+ expect(OrgApi.SysResourceKeyPrefix).toBe("etsoo");
53
+ });
6
54
 
7
55
  if (isLocalTest) {
8
- const app = new TestApp();
9
- await app.changeCulture(app.settings.cultures[0]);
10
-
11
56
  // Simulate logined
12
57
  app.authorize(
13
58
  "eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGVuYyNrdy1hZXMyNTYiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwidHlwIjoiSldUIiwiY3R5IjoiSldUIn0.dtsirpxAaX-pHgFrSRp9bTEvkFkphcihoOC9Mj-hgNEY9fvgSrb4-NkaQxiw1KIIXdct_2wXeHe4-vcWOrkpABANtf6LHdJo.vk9wrjb6DIw0f9xLAj-3AQ.CwEV20n7LhwalIx3a3WDQkJjMAHW1Bn6VJGMjfckNVBZv0G_xcWZbo5Gg2CF4vdUjH6pqAH5IhuMmRqlkeCYwuF5d_rQVI_kLtmvgpAJoqYhU3-J_XqPrLpdWXPQ-V84lzngTAJlIX4On6JP_ZRTWLZDGxiiC1Tg_6GlWU3EUX2kcMBb03NWGczHaPS5-ivp4L9CntqaEOOK35cWQx6oZyp0KmwM6KjoY3ard5SLUofF10DqBwto6KqNAeZnLjBnJV_j9dX-si5FalrGrTV09KtjSMeXd7Rp3VfC5BRge5zSx5CecEzk_yt50GdYjvDRYj31whyVx0bVLKH9Pyz1OsHLDfolVpSRRIk-1UuaZz-5WfKcUrE6EWB-Mykn5Mxiyo7CxlhHOnEkUAJ5wdYGiRdVkk04HA8YdOxBRHUZzB44nrUVIWEYtWu8KddQTkWhYOCNc4OdCBweuiO_TEt2haxEsUmyuRZ0PgoVg-B8ZUXz0ot79GNQcd8ZYoaaap8WYhvMod8lw-e-HH7fABlCoAsIx8xt4aMGOD1iVgXFTnJ4qD9x5suZczHqj4BoeoKkgg1Lil_jG_3cADxIRPmReWqeOrrA6f54PjBd5kdSNNv72axxW3AfbZaOYQ-n7zzQjWUgKZnMnu4N2NXCkis8JvHCfVi3jgUO3jeGp6vVlPoaCbFXXMiKKL1bkhRXZT47uglPi4zD2tRqKOEzGMPpB4d0X_tZVt_lPRvbLFjUNUVikQGA3nD_9c5B5QfI4olFjA6H4eUN7b74R4HcVIr6hNBvDKGXeTJBmoopu4fGMAysCJ_ybUcJxWXldoy6nFTZjJ2QllbLLqdYuCvxYlTo3Z4nODna6NW18QcSXIIHj3U6H6VIDkXBnjArkvsgj_0uvqW_zyZNj_JIONAuwZYfDC6gsjbzV7llp53d3o3-xFhOBvxUibFTPvY39E-X_-crww6flp_tDyndlzBoVYMhybhnRLQy-PpO4dZQhzr2sdHpsF57Fj7SecXwbAtcQdKp.C6VZunr9ohscx6vVMVmRQnG37pWumGCHMLO0jJmLQXo"
@@ -58,10 +103,6 @@ if (isLocalTest) {
58
103
  });
59
104
  */
60
105
 
61
- test("Test SysResourceKeyPrefix", () => {
62
- expect(OrgApi.SysResourceKeyPrefix).toBe("etsoo");
63
- });
64
-
65
106
  test("Test for query zero return", async () => {
66
107
  const result = await api.query({
67
108
  keyword: "亿速",
@@ -6,7 +6,7 @@
6
6
  "moduleResolution": "bundler",
7
7
  "allowJs": false,
8
8
  "isolatedModules": true,
9
- "outDir": "./lib",
9
+ "rootDir": "..",
10
10
  "noEmit": false,
11
11
  "declaration": true,
12
12
  "strict": true,
@@ -10,6 +10,7 @@ import { ListType, ListType1 } from "@etsoo/shared";
10
10
  import { CoreApiService } from "./dto/org/CoreApiService";
11
11
  import { DocumentApi } from "./DocumentApi";
12
12
  import { DocumentKind } from "./dto/document/DocumentKind";
13
+ import { OrgReportData } from "./dto/org/OrgReportData";
13
14
  type AppData = {
14
15
  id: number;
15
16
  appId?: number;
@@ -123,6 +124,27 @@ export interface ICoreApp {
123
124
  * @returns List
124
125
  */
125
126
  getIdentityFlags(identity?: number | true): ListType[];
127
+ /**
128
+ * Get report data
129
+ * 获取报告数据
130
+ * @param data Input data
131
+ * @param year Year to calculate
132
+ * @returns Result
133
+ */
134
+ getReportData(data: OrgReportData[], year: number): number[];
135
+ /**
136
+ * Transform report data for chart
137
+ * 转换报告数据用于图表
138
+ * @param data Input data
139
+ * @param hasLastYear Has last year data
140
+ * @param year Year to calculate, default is current year
141
+ * @returns Transformed report data
142
+ */
143
+ transformReportData(data: OrgReportData[], hasLastYear?: boolean, year?: number): {
144
+ labels: string[];
145
+ currentYearData: number[];
146
+ lastYearData: number[];
147
+ };
126
148
  }
127
149
  /**
128
150
  * Core application
@@ -256,5 +278,26 @@ export declare class CoreApp implements ICoreApp {
256
278
  * @returns List
257
279
  */
258
280
  getIdentityFlags(identity?: number | true): ListType[];
281
+ /**
282
+ * Get report data
283
+ * 获取报告数据
284
+ * @param data Input data
285
+ * @param year Year to calculate
286
+ * @returns Result
287
+ */
288
+ getReportData(data: OrgReportData[], year: number): number[];
289
+ /**
290
+ * Transform report data for chart
291
+ * 转换报告数据用于图表
292
+ * @param data Input data
293
+ * @param hasLastYear Has last year data
294
+ * @param year Year to calculate, default is current year
295
+ * @returns Transformed report data
296
+ */
297
+ transformReportData(data: OrgReportData[], hasLastYear?: boolean, year?: number): {
298
+ labels: string[];
299
+ currentYearData: number[];
300
+ lastYearData: number[];
301
+ };
259
302
  }
260
303
  export {};
@@ -220,5 +220,39 @@ class CoreApp {
220
220
  return id;
221
221
  });
222
222
  }
223
+ /**
224
+ * Get report data
225
+ * 获取报告数据
226
+ * @param data Input data
227
+ * @param year Year to calculate
228
+ * @returns Result
229
+ */
230
+ getReportData(data, year) {
231
+ const [start, end] = shared_1.NumberUtils.getMonthPeriodRange(year);
232
+ const items = [];
233
+ for (let i = start; i <= end; i++) {
234
+ const item = data.find((d) => d.period === i);
235
+ items.push(item ? ("qty" in item ? item.qty : item.amount) : 0);
236
+ }
237
+ return items;
238
+ }
239
+ /**
240
+ * Transform report data for chart
241
+ * 转换报告数据用于图表
242
+ * @param data Input data
243
+ * @param hasLastYear Has last year data
244
+ * @param year Year to calculate, default is current year
245
+ * @returns Transformed report data
246
+ */
247
+ transformReportData(data, hasLastYear, year) {
248
+ year ??= new Date().getFullYear();
249
+ const months = appscript_1.BusinessUtils.getMonths(this.app.get("months") ?? []);
250
+ const labels = months.map((m) => m.label);
251
+ const currentYearData = this.getReportData(data, year);
252
+ const lastYearData = hasLastYear == null || hasLastYear
253
+ ? this.getReportData(data, year - 1)
254
+ : [];
255
+ return { labels, currentYearData, lastYearData };
256
+ }
223
257
  }
224
258
  exports.CoreApp = CoreApp;
@@ -26,6 +26,8 @@ import { OrgQueryApiData } from "./dto/org/OrgQueryApiData";
26
26
  import { CoreApiService } from "./dto/org/CoreApiService";
27
27
  import { UploadFilesResult } from "./dto/org/UploadFilesResult";
28
28
  import { OrgOwnsRQ } from "./rq/org/OrgOwnsRQ";
29
+ import { OrgUsageReportRQ } from "./rq/org/OrgUsageReportRQ";
30
+ import { OrgReportData } from "./dto/org/OrgReportData";
29
31
  /**
30
32
  * Organization API
31
33
  * 机构接口
@@ -247,4 +249,11 @@ export declare class OrgApi extends EntityApi {
247
249
  * @returns Result
248
250
  */
249
251
  updateResourceRead(id: number, payload?: IApiPayload<OrgUpdateResourceReadData>): Promise<OrgUpdateResourceReadData | undefined>;
252
+ /**
253
+ * Get usage report
254
+ * @param rq Request data
255
+ * @param payload Payload
256
+ * @returns Result
257
+ */
258
+ usageReport(rq: OrgUsageReportRQ, payload?: IApiPayload<OrgReportData[]>): Promise<OrgReportData[] | undefined>;
250
259
  }
package/lib/cjs/OrgApi.js CHANGED
@@ -305,5 +305,14 @@ class OrgApi extends appscript_1.EntityApi {
305
305
  updateResourceRead(id, payload) {
306
306
  return this.api.get(`${this.flag}/UpdateResourceRead/${id}`, undefined, payload);
307
307
  }
308
+ /**
309
+ * Get usage report
310
+ * @param rq Request data
311
+ * @param payload Payload
312
+ * @returns Result
313
+ */
314
+ usageReport(rq, payload) {
315
+ return this.api.post(`${this.flag}/UsageReport`, rq, payload);
316
+ }
308
317
  }
309
318
  exports.OrgApi = OrgApi;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Organization usage report data
3
+ * 机构使用报告数据
4
+ */
5
+ type OrgUsageReportData = {
6
+ /**
7
+ * Period
8
+ * 周期
9
+ */
10
+ period: number;
11
+ /**
12
+ * Qty.
13
+ * 数量
14
+ */
15
+ qty: number;
16
+ };
17
+ /**
18
+ * Organization amount report data
19
+ * 机构金额报告数据
20
+ */
21
+ type OrgAmountReportData = {
22
+ /**
23
+ * Period
24
+ * 周期
25
+ */
26
+ period: number;
27
+ /**
28
+ * Amount
29
+ * 金额
30
+ */
31
+ amount: number;
32
+ };
33
+ /**
34
+ * Organization report data
35
+ * 机构报告数据
36
+ */
37
+ export type OrgReportData = OrgUsageReportData | OrgAmountReportData;
38
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -106,6 +106,7 @@
106
106
  "roleOperator": "Operator",
107
107
  "rolePartner": "Channel Partner",
108
108
  "roleUser": "User",
109
+ "samePeriodLastYear": "Same period last year",
109
110
  "slogan": "Slogan",
110
111
  "smarterp": "SmartERP Cloud",
111
112
  "signin": "Sign in",
@@ -139,5 +140,7 @@
139
140
  "uiTypeAlipay": "Alipay",
140
141
  "uiTypeGoogle": "Google",
141
142
  "uiTypeMicrosoft": "Microsoft",
142
- "updatedAt": "Updated at"
143
+ "updatedAt": "Updated at",
144
+ "usage": "Usage",
145
+ "usageReport": "Usage report"
143
146
  }
@@ -106,6 +106,7 @@
106
106
  "roleOperator": "操作员",
107
107
  "rolePartner": "渠道伙伴",
108
108
  "roleUser": "用户",
109
+ "samePeriodLastYear": "去年同期",
109
110
  "slogan": "标语",
110
111
  "smarterp": "司友®云ERP",
111
112
  "signin": "登录",
@@ -139,5 +140,7 @@
139
140
  "uiTypeAlipay": "支付宝",
140
141
  "uiTypeGoogle": "谷歌",
141
142
  "uiTypeMicrosoft": "微软",
142
- "updatedAt": "更新时间"
143
+ "updatedAt": "更新时间",
144
+ "usage": "使用量",
145
+ "usageReport": "使用情况报告"
143
146
  }
@@ -106,6 +106,7 @@
106
106
  "roleOperator": "操作員",
107
107
  "rolePartner": "渠道夥伴",
108
108
  "roleUser": "用戶",
109
+ "samePeriodLastYear": "去年同期",
109
110
  "signin": "登入",
110
111
  "signout": "登出",
111
112
  "slogan": "標語",
@@ -139,5 +140,7 @@
139
140
  "uiTypeAlipay": "支付寶",
140
141
  "uiTypeGoogle": "谷歌",
141
142
  "uiTypeMicrosoft": "微軟",
142
- "updatedAt": "更新時間"
143
+ "updatedAt": "更新時間",
144
+ "usage": "使用量",
145
+ "usageReport": "使用情況報告"
143
146
  }
@@ -22,6 +22,7 @@ export * from "./dto/org/OrgQueryApiData";
22
22
  export * from "./dto/org/OrgQueryDto";
23
23
  export * from "./dto/org/OrgQueryResourceData";
24
24
  export * from "./dto/org/OrgReadDto";
25
+ export * from "./dto/org/OrgReportData";
25
26
  export * from "./dto/org/OrgResourceItem";
26
27
  export * from "./dto/org/OrgUpdateApiReadDto";
27
28
  export * from "./dto/org/OrgUpdateReadDto";
@@ -68,6 +69,7 @@ export * from "./rq/org/OrgQueryApiRQ";
68
69
  export * from "./rq/org/OrgQueryResourceRQ";
69
70
  export * from "./rq/org/OrgQueryRQ";
70
71
  export * from "./rq/org/OrgUpdateApiRQ";
72
+ export * from "./rq/org/OrgUsageReportRQ";
71
73
  export * from "./rq/org/OrgUpdateRQ";
72
74
  export * from "./rq/org/SendEmailMessage";
73
75
  export * from "./rq/org/SendProfileEmailRQ";
package/lib/cjs/index.js CHANGED
@@ -39,6 +39,7 @@ __exportStar(require("./dto/org/OrgQueryApiData"), exports);
39
39
  __exportStar(require("./dto/org/OrgQueryDto"), exports);
40
40
  __exportStar(require("./dto/org/OrgQueryResourceData"), exports);
41
41
  __exportStar(require("./dto/org/OrgReadDto"), exports);
42
+ __exportStar(require("./dto/org/OrgReportData"), exports);
42
43
  __exportStar(require("./dto/org/OrgResourceItem"), exports);
43
44
  __exportStar(require("./dto/org/OrgUpdateApiReadDto"), exports);
44
45
  __exportStar(require("./dto/org/OrgUpdateReadDto"), exports);
@@ -87,6 +88,7 @@ __exportStar(require("./rq/org/OrgQueryApiRQ"), exports);
87
88
  __exportStar(require("./rq/org/OrgQueryResourceRQ"), exports);
88
89
  __exportStar(require("./rq/org/OrgQueryRQ"), exports);
89
90
  __exportStar(require("./rq/org/OrgUpdateApiRQ"), exports);
91
+ __exportStar(require("./rq/org/OrgUsageReportRQ"), exports);
90
92
  __exportStar(require("./rq/org/OrgUpdateRQ"), exports);
91
93
  __exportStar(require("./rq/org/SendEmailMessage"), exports);
92
94
  __exportStar(require("./rq/org/SendProfileEmailRQ"), exports);
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Organization usage report request data
3
+ * 机构使用报告请求数据
4
+ */
5
+ export type OrgUsageReportRQ = {
6
+ /**
7
+ * Organization id
8
+ * 机构编号
9
+ */
10
+ orgId?: number;
11
+ /**
12
+ * Year
13
+ * 年
14
+ */
15
+ year?: number;
16
+ /**
17
+ * Whether to include last year data
18
+ * 是否包含去年数据
19
+ */
20
+ hasLastYear?: boolean;
21
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -10,6 +10,7 @@ import { ListType, ListType1 } from "@etsoo/shared";
10
10
  import { CoreApiService } from "./dto/org/CoreApiService";
11
11
  import { DocumentApi } from "./DocumentApi";
12
12
  import { DocumentKind } from "./dto/document/DocumentKind";
13
+ import { OrgReportData } from "./dto/org/OrgReportData";
13
14
  type AppData = {
14
15
  id: number;
15
16
  appId?: number;
@@ -123,6 +124,27 @@ export interface ICoreApp {
123
124
  * @returns List
124
125
  */
125
126
  getIdentityFlags(identity?: number | true): ListType[];
127
+ /**
128
+ * Get report data
129
+ * 获取报告数据
130
+ * @param data Input data
131
+ * @param year Year to calculate
132
+ * @returns Result
133
+ */
134
+ getReportData(data: OrgReportData[], year: number): number[];
135
+ /**
136
+ * Transform report data for chart
137
+ * 转换报告数据用于图表
138
+ * @param data Input data
139
+ * @param hasLastYear Has last year data
140
+ * @param year Year to calculate, default is current year
141
+ * @returns Transformed report data
142
+ */
143
+ transformReportData(data: OrgReportData[], hasLastYear?: boolean, year?: number): {
144
+ labels: string[];
145
+ currentYearData: number[];
146
+ lastYearData: number[];
147
+ };
126
148
  }
127
149
  /**
128
150
  * Core application
@@ -256,5 +278,26 @@ export declare class CoreApp implements ICoreApp {
256
278
  * @returns List
257
279
  */
258
280
  getIdentityFlags(identity?: number | true): ListType[];
281
+ /**
282
+ * Get report data
283
+ * 获取报告数据
284
+ * @param data Input data
285
+ * @param year Year to calculate
286
+ * @returns Result
287
+ */
288
+ getReportData(data: OrgReportData[], year: number): number[];
289
+ /**
290
+ * Transform report data for chart
291
+ * 转换报告数据用于图表
292
+ * @param data Input data
293
+ * @param hasLastYear Has last year data
294
+ * @param year Year to calculate, default is current year
295
+ * @returns Transformed report data
296
+ */
297
+ transformReportData(data: OrgReportData[], hasLastYear?: boolean, year?: number): {
298
+ labels: string[];
299
+ currentYearData: number[];
300
+ lastYearData: number[];
301
+ };
259
302
  }
260
303
  export {};
@@ -3,9 +3,9 @@ import { OrgApi } from "./OrgApi";
3
3
  import { AppApi } from "./AppApi";
4
4
  import { PublicApi } from "./PublicApi";
5
5
  import { UserApi } from "./UserApi";
6
- import { AuthApi, IdentityType, IdentityTypeFlags, UserIdentifierType } from "@etsoo/appscript";
6
+ import { AuthApi, BusinessUtils, IdentityType, IdentityTypeFlags, UserIdentifierType } from "@etsoo/appscript";
7
7
  import { AuthCodeApi } from "./AuthCodeApi";
8
- import { DataTypes } from "@etsoo/shared";
8
+ import { DataTypes, NumberUtils } from "@etsoo/shared";
9
9
  import { CoreApiService } from "./dto/org/CoreApiService";
10
10
  import { DocumentApi } from "./DocumentApi";
11
11
  import { DocumentKind } from "./dto/document/DocumentKind";
@@ -217,4 +217,38 @@ export class CoreApp {
217
217
  return id;
218
218
  });
219
219
  }
220
+ /**
221
+ * Get report data
222
+ * 获取报告数据
223
+ * @param data Input data
224
+ * @param year Year to calculate
225
+ * @returns Result
226
+ */
227
+ getReportData(data, year) {
228
+ const [start, end] = NumberUtils.getMonthPeriodRange(year);
229
+ const items = [];
230
+ for (let i = start; i <= end; i++) {
231
+ const item = data.find((d) => d.period === i);
232
+ items.push(item ? ("qty" in item ? item.qty : item.amount) : 0);
233
+ }
234
+ return items;
235
+ }
236
+ /**
237
+ * Transform report data for chart
238
+ * 转换报告数据用于图表
239
+ * @param data Input data
240
+ * @param hasLastYear Has last year data
241
+ * @param year Year to calculate, default is current year
242
+ * @returns Transformed report data
243
+ */
244
+ transformReportData(data, hasLastYear, year) {
245
+ year ??= new Date().getFullYear();
246
+ const months = BusinessUtils.getMonths(this.app.get("months") ?? []);
247
+ const labels = months.map((m) => m.label);
248
+ const currentYearData = this.getReportData(data, year);
249
+ const lastYearData = hasLastYear == null || hasLastYear
250
+ ? this.getReportData(data, year - 1)
251
+ : [];
252
+ return { labels, currentYearData, lastYearData };
253
+ }
220
254
  }
@@ -26,6 +26,8 @@ import { OrgQueryApiData } from "./dto/org/OrgQueryApiData";
26
26
  import { CoreApiService } from "./dto/org/CoreApiService";
27
27
  import { UploadFilesResult } from "./dto/org/UploadFilesResult";
28
28
  import { OrgOwnsRQ } from "./rq/org/OrgOwnsRQ";
29
+ import { OrgUsageReportRQ } from "./rq/org/OrgUsageReportRQ";
30
+ import { OrgReportData } from "./dto/org/OrgReportData";
29
31
  /**
30
32
  * Organization API
31
33
  * 机构接口
@@ -247,4 +249,11 @@ export declare class OrgApi extends EntityApi {
247
249
  * @returns Result
248
250
  */
249
251
  updateResourceRead(id: number, payload?: IApiPayload<OrgUpdateResourceReadData>): Promise<OrgUpdateResourceReadData | undefined>;
252
+ /**
253
+ * Get usage report
254
+ * @param rq Request data
255
+ * @param payload Payload
256
+ * @returns Result
257
+ */
258
+ usageReport(rq: OrgUsageReportRQ, payload?: IApiPayload<OrgReportData[]>): Promise<OrgReportData[] | undefined>;
250
259
  }
package/lib/mjs/OrgApi.js CHANGED
@@ -302,4 +302,13 @@ export class OrgApi extends EntityApi {
302
302
  updateResourceRead(id, payload) {
303
303
  return this.api.get(`${this.flag}/UpdateResourceRead/${id}`, undefined, payload);
304
304
  }
305
+ /**
306
+ * Get usage report
307
+ * @param rq Request data
308
+ * @param payload Payload
309
+ * @returns Result
310
+ */
311
+ usageReport(rq, payload) {
312
+ return this.api.post(`${this.flag}/UsageReport`, rq, payload);
313
+ }
305
314
  }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Organization usage report data
3
+ * 机构使用报告数据
4
+ */
5
+ type OrgUsageReportData = {
6
+ /**
7
+ * Period
8
+ * 周期
9
+ */
10
+ period: number;
11
+ /**
12
+ * Qty.
13
+ * 数量
14
+ */
15
+ qty: number;
16
+ };
17
+ /**
18
+ * Organization amount report data
19
+ * 机构金额报告数据
20
+ */
21
+ type OrgAmountReportData = {
22
+ /**
23
+ * Period
24
+ * 周期
25
+ */
26
+ period: number;
27
+ /**
28
+ * Amount
29
+ * 金额
30
+ */
31
+ amount: number;
32
+ };
33
+ /**
34
+ * Organization report data
35
+ * 机构报告数据
36
+ */
37
+ export type OrgReportData = OrgUsageReportData | OrgAmountReportData;
38
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -106,6 +106,7 @@
106
106
  "roleOperator": "Operator",
107
107
  "rolePartner": "Channel Partner",
108
108
  "roleUser": "User",
109
+ "samePeriodLastYear": "Same period last year",
109
110
  "slogan": "Slogan",
110
111
  "smarterp": "SmartERP Cloud",
111
112
  "signin": "Sign in",
@@ -139,5 +140,7 @@
139
140
  "uiTypeAlipay": "Alipay",
140
141
  "uiTypeGoogle": "Google",
141
142
  "uiTypeMicrosoft": "Microsoft",
142
- "updatedAt": "Updated at"
143
+ "updatedAt": "Updated at",
144
+ "usage": "Usage",
145
+ "usageReport": "Usage report"
143
146
  }
@@ -106,6 +106,7 @@
106
106
  "roleOperator": "操作员",
107
107
  "rolePartner": "渠道伙伴",
108
108
  "roleUser": "用户",
109
+ "samePeriodLastYear": "去年同期",
109
110
  "slogan": "标语",
110
111
  "smarterp": "司友®云ERP",
111
112
  "signin": "登录",
@@ -139,5 +140,7 @@
139
140
  "uiTypeAlipay": "支付宝",
140
141
  "uiTypeGoogle": "谷歌",
141
142
  "uiTypeMicrosoft": "微软",
142
- "updatedAt": "更新时间"
143
+ "updatedAt": "更新时间",
144
+ "usage": "使用量",
145
+ "usageReport": "使用情况报告"
143
146
  }
@@ -106,6 +106,7 @@
106
106
  "roleOperator": "操作員",
107
107
  "rolePartner": "渠道夥伴",
108
108
  "roleUser": "用戶",
109
+ "samePeriodLastYear": "去年同期",
109
110
  "signin": "登入",
110
111
  "signout": "登出",
111
112
  "slogan": "標語",
@@ -139,5 +140,7 @@
139
140
  "uiTypeAlipay": "支付寶",
140
141
  "uiTypeGoogle": "谷歌",
141
142
  "uiTypeMicrosoft": "微軟",
142
- "updatedAt": "更新時間"
143
+ "updatedAt": "更新時間",
144
+ "usage": "使用量",
145
+ "usageReport": "使用情況報告"
143
146
  }
@@ -22,6 +22,7 @@ export * from "./dto/org/OrgQueryApiData";
22
22
  export * from "./dto/org/OrgQueryDto";
23
23
  export * from "./dto/org/OrgQueryResourceData";
24
24
  export * from "./dto/org/OrgReadDto";
25
+ export * from "./dto/org/OrgReportData";
25
26
  export * from "./dto/org/OrgResourceItem";
26
27
  export * from "./dto/org/OrgUpdateApiReadDto";
27
28
  export * from "./dto/org/OrgUpdateReadDto";
@@ -68,6 +69,7 @@ export * from "./rq/org/OrgQueryApiRQ";
68
69
  export * from "./rq/org/OrgQueryResourceRQ";
69
70
  export * from "./rq/org/OrgQueryRQ";
70
71
  export * from "./rq/org/OrgUpdateApiRQ";
72
+ export * from "./rq/org/OrgUsageReportRQ";
71
73
  export * from "./rq/org/OrgUpdateRQ";
72
74
  export * from "./rq/org/SendEmailMessage";
73
75
  export * from "./rq/org/SendProfileEmailRQ";
package/lib/mjs/index.js CHANGED
@@ -23,6 +23,7 @@ export * from "./dto/org/OrgQueryApiData";
23
23
  export * from "./dto/org/OrgQueryDto";
24
24
  export * from "./dto/org/OrgQueryResourceData";
25
25
  export * from "./dto/org/OrgReadDto";
26
+ export * from "./dto/org/OrgReportData";
26
27
  export * from "./dto/org/OrgResourceItem";
27
28
  export * from "./dto/org/OrgUpdateApiReadDto";
28
29
  export * from "./dto/org/OrgUpdateReadDto";
@@ -71,6 +72,7 @@ export * from "./rq/org/OrgQueryApiRQ";
71
72
  export * from "./rq/org/OrgQueryResourceRQ";
72
73
  export * from "./rq/org/OrgQueryRQ";
73
74
  export * from "./rq/org/OrgUpdateApiRQ";
75
+ export * from "./rq/org/OrgUsageReportRQ";
74
76
  export * from "./rq/org/OrgUpdateRQ";
75
77
  export * from "./rq/org/SendEmailMessage";
76
78
  export * from "./rq/org/SendProfileEmailRQ";
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Organization usage report request data
3
+ * 机构使用报告请求数据
4
+ */
5
+ export type OrgUsageReportRQ = {
6
+ /**
7
+ * Organization id
8
+ * 机构编号
9
+ */
10
+ orgId?: number;
11
+ /**
12
+ * Year
13
+ * 年
14
+ */
15
+ year?: number;
16
+ /**
17
+ * Whether to include last year data
18
+ * 是否包含去年数据
19
+ */
20
+ hasLastYear?: boolean;
21
+ };
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/smarterp-core",
3
- "version": "1.1.59",
3
+ "version": "1.1.60",
4
4
  "description": "TypeScript APIs for SmartERP Core",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/mjs/index.js",
@@ -49,7 +49,7 @@
49
49
  "@vitejs/plugin-react": "^6.0.2",
50
50
  "jsdom": "^29.1.1",
51
51
  "typescript": "^6.0.3",
52
- "vitest": "^4.1.8"
52
+ "vitest": "^4.1.9"
53
53
  },
54
54
  "overrides": {
55
55
  "react": "$react",
@@ -57,9 +57,9 @@
57
57
  },
58
58
  "dependencies": {
59
59
  "@etsoo/appscript": "^1.6.66",
60
- "@etsoo/materialui": "^1.6.70",
60
+ "@etsoo/materialui": "^1.6.71",
61
61
  "@etsoo/react": "^1.8.91",
62
- "@etsoo/shared": "^1.2.84",
62
+ "@etsoo/shared": "^1.2.86",
63
63
  "@etsoo/toolpad": "^1.0.50",
64
64
  "@mui/material": "^9.1.1",
65
65
  "ajv": "^8.20.0",
package/src/CoreApp.ts CHANGED
@@ -6,16 +6,18 @@ import { PublicApi } from "./PublicApi";
6
6
  import { UserApi } from "./UserApi";
7
7
  import {
8
8
  AuthApi,
9
+ BusinessUtils,
9
10
  IApp,
10
11
  IdentityType,
11
12
  IdentityTypeFlags,
12
13
  UserIdentifierType
13
14
  } from "@etsoo/appscript";
14
15
  import { AuthCodeApi } from "./AuthCodeApi";
15
- import { DataTypes, ListType, ListType1 } from "@etsoo/shared";
16
+ import { DataTypes, ListType, ListType1, NumberUtils } from "@etsoo/shared";
16
17
  import { CoreApiService } from "./dto/org/CoreApiService";
17
18
  import { DocumentApi } from "./DocumentApi";
18
19
  import { DocumentKind } from "./dto/document/DocumentKind";
20
+ import { OrgReportData } from "./dto/org/OrgReportData";
19
21
 
20
22
  type AppData = { id: number; appId?: number; name: string; localName?: string };
21
23
 
@@ -149,6 +151,33 @@ export interface ICoreApp {
149
151
  * @returns List
150
152
  */
151
153
  getIdentityFlags(identity?: number | true): ListType[];
154
+
155
+ /**
156
+ * Get report data
157
+ * 获取报告数据
158
+ * @param data Input data
159
+ * @param year Year to calculate
160
+ * @returns Result
161
+ */
162
+ getReportData(data: OrgReportData[], year: number): number[];
163
+
164
+ /**
165
+ * Transform report data for chart
166
+ * 转换报告数据用于图表
167
+ * @param data Input data
168
+ * @param hasLastYear Has last year data
169
+ * @param year Year to calculate, default is current year
170
+ * @returns Transformed report data
171
+ */
172
+ transformReportData(
173
+ data: OrgReportData[],
174
+ hasLastYear?: boolean,
175
+ year?: number
176
+ ): {
177
+ labels: string[];
178
+ currentYearData: number[];
179
+ lastYearData: number[];
180
+ };
152
181
  }
153
182
 
154
183
  /**
@@ -383,4 +412,52 @@ export class CoreApp implements ICoreApp {
383
412
  if (id === 0 || (id & identity) > 0) return id;
384
413
  });
385
414
  }
415
+
416
+ /**
417
+ * Get report data
418
+ * 获取报告数据
419
+ * @param data Input data
420
+ * @param year Year to calculate
421
+ * @returns Result
422
+ */
423
+ getReportData(data: OrgReportData[], year: number) {
424
+ const [start, end] = NumberUtils.getMonthPeriodRange(year);
425
+ const items: number[] = [];
426
+
427
+ for (let i = start; i <= end; i++) {
428
+ const item = data.find((d) => d.period === i);
429
+ items.push(item ? ("qty" in item ? item.qty : item.amount) : 0);
430
+ }
431
+
432
+ return items;
433
+ }
434
+
435
+ /**
436
+ * Transform report data for chart
437
+ * 转换报告数据用于图表
438
+ * @param data Input data
439
+ * @param hasLastYear Has last year data
440
+ * @param year Year to calculate, default is current year
441
+ * @returns Transformed report data
442
+ */
443
+ transformReportData(
444
+ data: OrgReportData[],
445
+ hasLastYear?: boolean,
446
+ year?: number
447
+ ) {
448
+ year ??= new Date().getFullYear();
449
+
450
+ const months = BusinessUtils.getMonths(
451
+ this.app.get<string[]>("months") ?? []
452
+ );
453
+ const labels = months.map((m) => m.label);
454
+
455
+ const currentYearData = this.getReportData(data, year);
456
+ const lastYearData =
457
+ hasLastYear == null || hasLastYear
458
+ ? this.getReportData(data, year - 1)
459
+ : [];
460
+
461
+ return { labels, currentYearData, lastYearData };
462
+ }
386
463
  }
package/src/OrgApi.ts CHANGED
@@ -36,6 +36,8 @@ import { OrgQueryApiData } from "./dto/org/OrgQueryApiData";
36
36
  import { CoreApiService } from "./dto/org/CoreApiService";
37
37
  import { UploadFilesResult } from "./dto/org/UploadFilesResult";
38
38
  import { OrgOwnsRQ } from "./rq/org/OrgOwnsRQ";
39
+ import { OrgUsageReportRQ } from "./rq/org/OrgUsageReportRQ";
40
+ import { OrgReportData } from "./dto/org/OrgReportData";
39
41
 
40
42
  /**
41
43
  * Organization API
@@ -412,4 +414,14 @@ export class OrgApi extends EntityApi {
412
414
  payload
413
415
  );
414
416
  }
417
+
418
+ /**
419
+ * Get usage report
420
+ * @param rq Request data
421
+ * @param payload Payload
422
+ * @returns Result
423
+ */
424
+ usageReport(rq: OrgUsageReportRQ, payload?: IApiPayload<OrgReportData[]>) {
425
+ return this.api.post(`${this.flag}/UsageReport`, rq, payload);
426
+ }
415
427
  }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Organization usage report data
3
+ * 机构使用报告数据
4
+ */
5
+ type OrgUsageReportData = {
6
+ /**
7
+ * Period
8
+ * 周期
9
+ */
10
+ period: number;
11
+
12
+ /**
13
+ * Qty.
14
+ * 数量
15
+ */
16
+ qty: number;
17
+ };
18
+
19
+ /**
20
+ * Organization amount report data
21
+ * 机构金额报告数据
22
+ */
23
+ type OrgAmountReportData = {
24
+ /**
25
+ * Period
26
+ * 周期
27
+ */
28
+ period: number;
29
+
30
+ /**
31
+ * Amount
32
+ * 金额
33
+ */
34
+ amount: number;
35
+ };
36
+
37
+ /**
38
+ * Organization report data
39
+ * 机构报告数据
40
+ */
41
+ export type OrgReportData = OrgUsageReportData | OrgAmountReportData;
package/src/i18n/en.json CHANGED
@@ -106,6 +106,7 @@
106
106
  "roleOperator": "Operator",
107
107
  "rolePartner": "Channel Partner",
108
108
  "roleUser": "User",
109
+ "samePeriodLastYear": "Same period last year",
109
110
  "slogan": "Slogan",
110
111
  "smarterp": "SmartERP Cloud",
111
112
  "signin": "Sign in",
@@ -139,5 +140,7 @@
139
140
  "uiTypeAlipay": "Alipay",
140
141
  "uiTypeGoogle": "Google",
141
142
  "uiTypeMicrosoft": "Microsoft",
142
- "updatedAt": "Updated at"
143
+ "updatedAt": "Updated at",
144
+ "usage": "Usage",
145
+ "usageReport": "Usage report"
143
146
  }
@@ -106,6 +106,7 @@
106
106
  "roleOperator": "操作员",
107
107
  "rolePartner": "渠道伙伴",
108
108
  "roleUser": "用户",
109
+ "samePeriodLastYear": "去年同期",
109
110
  "slogan": "标语",
110
111
  "smarterp": "司友®云ERP",
111
112
  "signin": "登录",
@@ -139,5 +140,7 @@
139
140
  "uiTypeAlipay": "支付宝",
140
141
  "uiTypeGoogle": "谷歌",
141
142
  "uiTypeMicrosoft": "微软",
142
- "updatedAt": "更新时间"
143
+ "updatedAt": "更新时间",
144
+ "usage": "使用量",
145
+ "usageReport": "使用情况报告"
143
146
  }
@@ -106,6 +106,7 @@
106
106
  "roleOperator": "操作員",
107
107
  "rolePartner": "渠道夥伴",
108
108
  "roleUser": "用戶",
109
+ "samePeriodLastYear": "去年同期",
109
110
  "signin": "登入",
110
111
  "signout": "登出",
111
112
  "slogan": "標語",
@@ -139,5 +140,7 @@
139
140
  "uiTypeAlipay": "支付寶",
140
141
  "uiTypeGoogle": "谷歌",
141
142
  "uiTypeMicrosoft": "微軟",
142
- "updatedAt": "更新時間"
143
+ "updatedAt": "更新時間",
144
+ "usage": "使用量",
145
+ "usageReport": "使用情況報告"
143
146
  }
package/src/index.ts CHANGED
@@ -27,6 +27,7 @@ export * from "./dto/org/OrgQueryApiData";
27
27
  export * from "./dto/org/OrgQueryDto";
28
28
  export * from "./dto/org/OrgQueryResourceData";
29
29
  export * from "./dto/org/OrgReadDto";
30
+ export * from "./dto/org/OrgReportData";
30
31
  export * from "./dto/org/OrgResourceItem";
31
32
  export * from "./dto/org/OrgUpdateApiReadDto";
32
33
  export * from "./dto/org/OrgUpdateReadDto";
@@ -83,6 +84,7 @@ export * from "./rq/org/OrgQueryApiRQ";
83
84
  export * from "./rq/org/OrgQueryResourceRQ";
84
85
  export * from "./rq/org/OrgQueryRQ";
85
86
  export * from "./rq/org/OrgUpdateApiRQ";
87
+ export * from "./rq/org/OrgUsageReportRQ";
86
88
  export * from "./rq/org/OrgUpdateRQ";
87
89
  export * from "./rq/org/SendEmailMessage";
88
90
  export * from "./rq/org/SendProfileEmailRQ";
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Organization usage report request data
3
+ * 机构使用报告请求数据
4
+ */
5
+ export type OrgUsageReportRQ = {
6
+ /**
7
+ * Organization id
8
+ * 机构编号
9
+ */
10
+ orgId?: number;
11
+
12
+ /**
13
+ * Year
14
+ * 年
15
+ */
16
+ year?: number;
17
+
18
+ /**
19
+ * Whether to include last year data
20
+ * 是否包含去年数据
21
+ */
22
+ hasLastYear?: boolean;
23
+ };