gm-mcp 1.3.21 → 2.0.2
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.
- package/dist/env.d.ts +4 -4
- package/dist/env.js +12 -12
- package/dist/index.js +44 -146
- package/dist/services/gimo.service.d.ts +3 -2
- package/dist/services/gimo.service.js +22 -2
- package/dist/services/lark-base.service.d.ts +2 -12
- package/dist/services/lark-base.service.js +6 -32
- package/dist/services/types/gimo.type.d.ts +32 -19
- package/dist/test.js +5 -28
- package/dist/tools/accessible-tools.d.ts +2 -0
- package/dist/tools/accessible-tools.js +48 -0
- package/dist/tools/lark-tool.d.ts +1 -4
- package/dist/tools/lark-tool.js +20 -88
- package/package.json +4 -4
- package/src/env.ts +3 -3
- package/src/index.ts +61 -151
- package/src/services/gimo.service.ts +23 -5
- package/src/services/lark-base.service.ts +9 -51
- package/src/services/types/gimo.type.ts +32 -19
- package/src/test.ts +5 -34
- package/src/tools/accessible-tools.ts +38 -0
- package/src/tools/lark-tool.ts +24 -98
- package/src/services/constants/product-type.ts +0 -6
package/dist/tools/lark-tool.js
CHANGED
|
@@ -10,6 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.debtCollectionRateTool = debtCollectionRateTool;
|
|
13
|
+
const helpers_1 = require("../helpers");
|
|
13
14
|
const search_like_1 = require("../helpers/search-like");
|
|
14
15
|
const report_columns_1 = require("../services/constants/report-columns");
|
|
15
16
|
const lark_base_service_1 = require("../services/lark-base.service");
|
|
@@ -17,102 +18,41 @@ const lark_service_1 = require("../services/lark.service");
|
|
|
17
18
|
const companyKey = "CÔNG TY";
|
|
18
19
|
const preiodKey = "KỲ LƯƠNG";
|
|
19
20
|
const debtCollectionRateKey = "TỈ LỆ THU NỢ";
|
|
20
|
-
const debReductionMonthKey = "THÁNG CẮT NỢ";
|
|
21
|
-
const productKey = "Loại Sản phẩm";
|
|
22
|
-
const monthReductionDebtKey = "THÁNG CẮT NỢ";
|
|
23
|
-
const statusKey = "TRẠNG THÁI";
|
|
24
|
-
const VALID_YEARS = ["2025", "2026"];
|
|
25
21
|
function debtCollectionRateTool(options) {
|
|
26
22
|
return __awaiter(this, void 0, void 0, function* () {
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
if (
|
|
30
|
-
|
|
31
|
-
title: ["Tỉ lệ thu nợ", companyName].filter(Boolean).join(" - "),
|
|
32
|
-
message_content: `Rất tiếc tôi chưa có dữ liệu của năm ${year}, bạn hãy thử lại với năm ${VALID_YEARS.join(",")}`,
|
|
33
|
-
});
|
|
34
|
-
throw new Error("Year is invalid");
|
|
23
|
+
const { sendMessageToLark, companyName, monthDate } = options;
|
|
24
|
+
const monthParts = (0, helpers_1.extractMonth)(monthDate);
|
|
25
|
+
if (monthParts === null) {
|
|
26
|
+
return { content: [{ type: "text", text: `${monthDate} is invalid` }] };
|
|
35
27
|
}
|
|
36
|
-
|
|
37
|
-
// if (monthParts === null) {
|
|
38
|
-
// return { content: [{ type: "text", text: `${monthDate} is invalid` }] };
|
|
39
|
-
// }
|
|
28
|
+
const { month, year } = monthParts;
|
|
40
29
|
const fieldNames = report_columns_1.REPORT_COLUMS.map((item) => item.field_name);
|
|
41
30
|
try {
|
|
42
|
-
|
|
43
|
-
//
|
|
44
|
-
const records = yield (0, lark_base_service_1.fetchDebtCollectionRecords)();
|
|
31
|
+
const records = yield (0, lark_base_service_1.fetchReportRecords)({ view_id: "vewI23hNnx", field_names: fieldNames });
|
|
45
32
|
// console.log(records);
|
|
46
33
|
// Find by name first
|
|
47
|
-
const companyNames = records.map((item) => (item.fields[
|
|
34
|
+
const companyNames = records.map((item) => (item.fields["CÔNG TY"] || ""));
|
|
48
35
|
// console.log(companyNames);
|
|
49
36
|
// const searchTems = "DENKO";
|
|
50
37
|
// const monthTerm = "12";
|
|
51
38
|
const foundName = (0, search_like_1.searchLike)(companyName, companyNames)[0];
|
|
52
|
-
const companiesMatchName = records.filter((item) => item.fields[
|
|
39
|
+
const companiesMatchName = records.filter((item) => item.fields["CÔNG TY"] === foundName);
|
|
53
40
|
// console.log(companiesMatchName);
|
|
54
|
-
// Find by
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (!month) {
|
|
59
|
-
return true;
|
|
60
|
-
}
|
|
61
|
-
return compareReductionDebtMonth(item.fields[debReductionMonthKey], month.toString());
|
|
62
|
-
})
|
|
63
|
-
.filter((item) => {
|
|
64
|
-
var _c;
|
|
65
|
-
if (!productType) {
|
|
66
|
-
return true;
|
|
67
|
-
}
|
|
68
|
-
return ((_c = item.fields[productKey]) === null || _c === void 0 ? void 0 : _c.toLowerCase()) === productType.toLowerCase();
|
|
69
|
-
})
|
|
70
|
-
.sort((a, b) => b.fields[debReductionMonthKey].localeCompare(a.fields[debReductionMonthKey]));
|
|
71
|
-
// const foundMonth = searchLike(
|
|
72
|
-
// month.toString(),
|
|
73
|
-
// companiesMatchName.map((item) => item.fields["KỲ LƯƠNG"])
|
|
74
|
-
// )[0];
|
|
75
|
-
// console.log(foundRecords);
|
|
76
|
-
// const finalCompnay = companiesMatchName.find((item) => item.fields["KỲ LƯƠNG"] === foundMonth);
|
|
77
|
-
// console.log(finalCompnay);
|
|
78
|
-
if (foundRecords.length === 0 && sendMessageToLark) {
|
|
79
|
-
yield (0, lark_service_1.sendReportOpsGroup)({
|
|
80
|
-
title: ["Tỉ lệ thu nợ", foundName, productType].filter(Boolean).join(" - "),
|
|
81
|
-
message_content: `Rất tiếc, Tôi chưa có thông tin`,
|
|
82
|
-
});
|
|
83
|
-
throw new Error("Data is not found");
|
|
84
|
-
}
|
|
85
|
-
const messages = [];
|
|
86
|
-
for (const item of foundRecords) {
|
|
87
|
-
messages.push([
|
|
88
|
-
item.fields[debReductionMonthKey] || "N/A",
|
|
89
|
-
typeof item.fields[debtCollectionRateKey] === "undefined"
|
|
90
|
-
? "N/A"
|
|
91
|
-
: round(Number(item.fields[debtCollectionRateKey])) + "%",
|
|
92
|
-
((_d = (_c = item === null || item === void 0 ? void 0 : item.fields[statusKey]) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.text) || "N/A",
|
|
93
|
-
].join(" | "));
|
|
94
|
-
// messages.push(
|
|
95
|
-
// [
|
|
96
|
-
// `Sản phẩm: ${item.fields[productKey] || "N/A"}`,
|
|
97
|
-
// `Kỳ lương: ${item?.fields[preiodKey] || "N/A"}`,
|
|
98
|
-
// `Tr.thái cắt nợ: ${item?.fields[statusKey]?.[0]?.text || "N/A"}`,
|
|
99
|
-
// `Tháng cắt nợ: ${item.fields[monthReductionDebtKey] || "N/A"}`,
|
|
100
|
-
// `Tỷ lệ thu nợ: ${
|
|
101
|
-
// typeof item.fields[debtCollectionRateKey] === "undefined"
|
|
102
|
-
// ? "N/A"
|
|
103
|
-
// : round(Number(item.fields[debtCollectionRateKey])) + "%"
|
|
104
|
-
// }`,
|
|
105
|
-
// ].join("<br>")
|
|
106
|
-
// );
|
|
107
|
-
}
|
|
108
|
-
// return {} as any;
|
|
41
|
+
// Find by pay period
|
|
42
|
+
const foundMonth = (0, search_like_1.searchLike)(month.toString(), companiesMatchName.map((item) => item.fields["KỲ LƯƠNG"]))[0];
|
|
43
|
+
console.log(foundMonth);
|
|
44
|
+
const finalCompnay = companiesMatchName.find((item) => item.fields["KỲ LƯƠNG"] === foundMonth);
|
|
109
45
|
if (sendMessageToLark) {
|
|
110
46
|
yield (0, lark_service_1.sendReportOpsGroup)({
|
|
111
|
-
title:
|
|
112
|
-
message_content:
|
|
47
|
+
title: "Tỉ lệ thu nợ",
|
|
48
|
+
message_content: [
|
|
49
|
+
`Công ty: ${(finalCompnay === null || finalCompnay === void 0 ? void 0 : finalCompnay.fields[companyKey]) || "N/A"}`,
|
|
50
|
+
`Kỳ lương: ${(finalCompnay === null || finalCompnay === void 0 ? void 0 : finalCompnay.fields[preiodKey]) || "N/A"}`,
|
|
51
|
+
`Tỷ lệ thu nợ: ${Number(finalCompnay === null || finalCompnay === void 0 ? void 0 : finalCompnay.fields[debtCollectionRateKey]) * 100}%`,
|
|
52
|
+
].join("<hr>"),
|
|
113
53
|
});
|
|
114
54
|
}
|
|
115
|
-
return { content: [{ type: "text", text: JSON.stringify(
|
|
55
|
+
return { content: [{ type: "text", text: JSON.stringify(finalCompnay) }] };
|
|
116
56
|
// console.log(finalCompnay);
|
|
117
57
|
}
|
|
118
58
|
catch (e) {
|
|
@@ -120,11 +60,3 @@ function debtCollectionRateTool(options) {
|
|
|
120
60
|
}
|
|
121
61
|
});
|
|
122
62
|
}
|
|
123
|
-
function compareReductionDebtMonth(a, b) {
|
|
124
|
-
const _a = a.toLowerCase().trim().replace("tháng", "");
|
|
125
|
-
const _b = b.toLowerCase().trim().replace("tháng", "");
|
|
126
|
-
return parseInt(_a, 10) === parseInt(_b, 10);
|
|
127
|
-
}
|
|
128
|
-
function round(x) {
|
|
129
|
-
return Math.round(x * 10000) / 100;
|
|
130
|
-
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gm-mcp",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Mcp server for Gm",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -25,11 +25,11 @@
|
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@dotenvx/dotenvx": "^1.44.2",
|
|
27
27
|
"@larksuiteoapi/node-sdk": "^1.29.0",
|
|
28
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
28
|
+
"@modelcontextprotocol/sdk": "^1.8.0",
|
|
29
29
|
"currency-formatter": "^1.5.9",
|
|
30
30
|
"date-fns": "^2.30.0",
|
|
31
31
|
"date-fns-tz": "^2.0.1",
|
|
32
|
-
"
|
|
33
|
-
"zod
|
|
32
|
+
"gimo-mcp": "^1.0.3",
|
|
33
|
+
"zod": "^3.25.67"
|
|
34
34
|
}
|
|
35
35
|
}
|
package/src/env.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import z from "zod
|
|
1
|
+
import z from "zod";
|
|
2
2
|
|
|
3
3
|
const envSchema = z.object({
|
|
4
4
|
DASH_URL: z.string({ description: "Dash url for login" }),
|
|
@@ -9,7 +9,7 @@ const envSchema = z.object({
|
|
|
9
9
|
LARK_APP_SECRET: z.string({ description: `Lark's Bot app secret` }),
|
|
10
10
|
LARK_X3_GROUP_ID: z.string({ description: `Id of lark's group x3` }),
|
|
11
11
|
LARK_X3_TEMPLATE_ID: z.string({ description: `Id of lark's card template x3` }),
|
|
12
|
-
SEND_MESSAGE_TO_LARK: z.
|
|
12
|
+
SEND_MESSAGE_TO_LARK: z.boolean({ description: "Send message to lark or not", coerce: true }),
|
|
13
13
|
});
|
|
14
14
|
export type GimoMcpEnv = z.infer<typeof envSchema>;
|
|
15
15
|
export function ensureEnvVariables() {
|
|
@@ -30,7 +30,7 @@ export function getEnv(): GimoMcpEnv {
|
|
|
30
30
|
const LARK_APP_SECRET = process.env["LARK_APP_SECRET"] as string;
|
|
31
31
|
const LARK_X3_GROUP_ID = process.env["LARK_X3_GROUP_ID"] as string;
|
|
32
32
|
const LARK_X3_TEMPLATE_ID = process.env["LARK_X3_TEMPLATE_ID"] as string;
|
|
33
|
-
const SEND_MESSAGE_TO_LARK = process.env["SEND_MESSAGE_TO_LARK"]
|
|
33
|
+
const SEND_MESSAGE_TO_LARK = Boolean(process.env["SEND_MESSAGE_TO_LARK"]);
|
|
34
34
|
return {
|
|
35
35
|
DASH_URL,
|
|
36
36
|
PASSWORD,
|
package/src/index.ts
CHANGED
|
@@ -10,10 +10,10 @@ import {
|
|
|
10
10
|
statisticX3WeekTool,
|
|
11
11
|
statisticX3YesterdayTool,
|
|
12
12
|
} from "./tools";
|
|
13
|
-
import z from "zod
|
|
13
|
+
import z from "zod";
|
|
14
14
|
import { ensureEnvVariables, getEnv } from "./env";
|
|
15
15
|
import { debtCollectionRateTool } from "./tools/lark-tool";
|
|
16
|
-
import {
|
|
16
|
+
import { accessibleTool } from "./tools/accessible-tools";
|
|
17
17
|
|
|
18
18
|
export const server = new McpServer(
|
|
19
19
|
{
|
|
@@ -28,15 +28,15 @@ export const server = new McpServer(
|
|
|
28
28
|
);
|
|
29
29
|
|
|
30
30
|
server.tool("statistic_salary_x3_today", "Get statistic salary x3 today", {}, async (args) => {
|
|
31
|
-
return statisticX3TodayTool({ sendMessageToLark: getEnv().SEND_MESSAGE_TO_LARK
|
|
31
|
+
return statisticX3TodayTool({ sendMessageToLark: getEnv().SEND_MESSAGE_TO_LARK });
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
server.tool("statistic_salary_x3_yesterday", "Get statistic salary x3 yesterday", {}, async (args) => {
|
|
35
|
-
return statisticX3YesterdayTool({ sendMessageToLark: getEnv().SEND_MESSAGE_TO_LARK
|
|
35
|
+
return statisticX3YesterdayTool({ sendMessageToLark: getEnv().SEND_MESSAGE_TO_LARK });
|
|
36
36
|
});
|
|
37
37
|
|
|
38
38
|
server.tool("statistic_salary_x3_this_week", "Get statistic salary x3 this week", {}, async (args) => {
|
|
39
|
-
return statisticX3WeekTool({ sendMessageToLark: getEnv().SEND_MESSAGE_TO_LARK
|
|
39
|
+
return statisticX3WeekTool({ sendMessageToLark: getEnv().SEND_MESSAGE_TO_LARK });
|
|
40
40
|
});
|
|
41
41
|
|
|
42
42
|
server.tool(
|
|
@@ -46,168 +46,78 @@ server.tool(
|
|
|
46
46
|
month: z.string().describe("Month to statistic, month must be represented with format MM/yyyy"),
|
|
47
47
|
},
|
|
48
48
|
async (args) => {
|
|
49
|
-
return statisticX3MonthTool({ sendMessageToLark: getEnv().SEND_MESSAGE_TO_LARK
|
|
49
|
+
return statisticX3MonthTool({ sendMessageToLark: getEnv().SEND_MESSAGE_TO_LARK, month: args.month });
|
|
50
50
|
}
|
|
51
51
|
);
|
|
52
52
|
|
|
53
53
|
server.tool("statistic_salary_x3_this_month", `Get statistic salary x3 this month`, {}, async (args) => {
|
|
54
|
-
return statisticX3ThisMonthTool({ sendMessageToLark: getEnv().SEND_MESSAGE_TO_LARK
|
|
54
|
+
return statisticX3ThisMonthTool({ sendMessageToLark: getEnv().SEND_MESSAGE_TO_LARK });
|
|
55
55
|
});
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
// {
|
|
61
|
-
// date: z.string({
|
|
62
|
-
// description: "Date to statistic with format dd/mm/yyy or dd-mm-yyyy",
|
|
63
|
-
// }),
|
|
64
|
-
// },
|
|
65
|
-
// async (args) => {
|
|
66
|
-
// return statisticX3Tool({
|
|
67
|
-
// date: args.date,
|
|
68
|
-
// sendMessageToLark: getEnv().SEND_MESSAGE_TO_LARK === "true",
|
|
69
|
-
// });
|
|
70
|
-
// }
|
|
71
|
-
// );
|
|
72
|
-
|
|
73
|
-
// server.tool(
|
|
74
|
-
// "statistic_salary_x3_in_range",
|
|
75
|
-
// "Get statistic salary x3 with range of date,date must be formated in dd/mm/yyy or dd-mm-yyyy",
|
|
76
|
-
// {
|
|
77
|
-
// start_date: z.string({
|
|
78
|
-
// description: "Start date to statistic with format dd/mm/yyy or dd-mm-yyyy",
|
|
79
|
-
// }),
|
|
80
|
-
// end_date: z.string({
|
|
81
|
-
// description: "End date to statistic with format dd/mm/yyy or dd-mm-yyyy",
|
|
82
|
-
// }),
|
|
83
|
-
// },
|
|
84
|
-
// async (args) => {
|
|
85
|
-
// return statisticX3RangeTool({
|
|
86
|
-
// startDateStr: args.start_date,
|
|
87
|
-
// endDateStr: args.end_date,
|
|
88
|
-
// sendMessageToLark: getEnv().SEND_MESSAGE_TO_LARK === "true",
|
|
89
|
-
// });
|
|
90
|
-
// }
|
|
91
|
-
// );
|
|
92
|
-
|
|
93
|
-
server.registerTool(
|
|
94
|
-
"debt_collection",
|
|
57
|
+
server.tool(
|
|
58
|
+
"statistic_salary_x3",
|
|
59
|
+
"Get statistic salary x3 with specific date,date must be formated in dd/mm/yyy or dd-mm-yyyy",
|
|
95
60
|
{
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
- compnany name
|
|
99
|
-
- year (optional) - default 2025
|
|
100
|
-
- product type (optional) one of values EWA 02 - 03 | EWA 04 | Lương X3 | Lương X3 - EVF , default EWA 02 - 03
|
|
101
|
-
- month (optional) - default ""
|
|
102
|
-
|
|
103
|
-
`,
|
|
104
|
-
inputSchema: z.object({
|
|
105
|
-
company_name: z.string().describe("Company name to get data"),
|
|
106
|
-
year: z.string().nullable().describe("Year to get company debt collection"),
|
|
107
|
-
product_type: z
|
|
108
|
-
.string()
|
|
109
|
-
.nullable()
|
|
110
|
-
.describe("Product type to get data one of follow values EWA 02 - 03 | EWA 04 | Lương X3 | Lương X3 - EVF "),
|
|
111
|
-
month: z.string().nullable().describe("Month to get company debt collection"),
|
|
61
|
+
date: z.string({
|
|
62
|
+
description: "Date to statistic with format dd/mm/yyy or dd-mm-yyyy",
|
|
112
63
|
}),
|
|
113
64
|
},
|
|
114
65
|
async (args) => {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
sendMessageToLark: getEnv().SEND_MESSAGE_TO_LARK
|
|
118
|
-
companyName: company_name || "",
|
|
119
|
-
productType: product_type || PRODUCT_TYPE.EWA_02_03,
|
|
120
|
-
month: month || "",
|
|
121
|
-
year: year || "",
|
|
66
|
+
return statisticX3Tool({
|
|
67
|
+
date: args.date,
|
|
68
|
+
sendMessageToLark: getEnv().SEND_MESSAGE_TO_LARK,
|
|
122
69
|
});
|
|
123
70
|
}
|
|
124
71
|
);
|
|
125
72
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
// }
|
|
146
|
-
// );
|
|
147
|
-
|
|
148
|
-
// server.tool(
|
|
149
|
-
// "debt_collection_ewa_02",
|
|
150
|
-
// "The company's debt collection information with EWA 02 - 03 product type",
|
|
151
|
-
// {
|
|
152
|
-
// company_name: z.string({ description: "Company name to get data" }),
|
|
153
|
-
// },
|
|
154
|
-
// async (args) => {
|
|
155
|
-
// const { company_name } = args;
|
|
156
|
-
// return debtCollectionRateTool({
|
|
157
|
-
// sendMessageToLark: getEnv().SEND_MESSAGE_TO_LARK === "true",
|
|
158
|
-
// companyName: company_name,
|
|
159
|
-
// productType: PRODUCT_TYPE.EWA_02_03,
|
|
160
|
-
// });
|
|
161
|
-
// }
|
|
162
|
-
// );
|
|
163
|
-
|
|
164
|
-
// server.tool(
|
|
165
|
-
// "debt_collection_ewa_04",
|
|
166
|
-
// "The company's debt collection information with EWA 04 product type",
|
|
167
|
-
// {
|
|
168
|
-
// company_name: z.string({ description: "Company name to get data" }),
|
|
169
|
-
// },
|
|
170
|
-
// async (args) => {
|
|
171
|
-
// const { company_name } = args;
|
|
172
|
-
// return debtCollectionRateTool({
|
|
173
|
-
// sendMessageToLark: getEnv().SEND_MESSAGE_TO_LARK === "true",
|
|
174
|
-
// companyName: company_name,
|
|
175
|
-
// productType: PRODUCT_TYPE.EWA_04,
|
|
176
|
-
// });
|
|
177
|
-
// }
|
|
178
|
-
// );
|
|
73
|
+
server.tool(
|
|
74
|
+
"statistic_salary_x3_in_range",
|
|
75
|
+
"Get statistic salary x3 with range of date,date must be formated in dd/mm/yyy or dd-mm-yyyy",
|
|
76
|
+
{
|
|
77
|
+
start_date: z.string({
|
|
78
|
+
description: "Start date to statistic with format dd/mm/yyy or dd-mm-yyyy",
|
|
79
|
+
}),
|
|
80
|
+
end_date: z.string({
|
|
81
|
+
description: "End date to statistic with format dd/mm/yyy or dd-mm-yyyy",
|
|
82
|
+
}),
|
|
83
|
+
},
|
|
84
|
+
async (args) => {
|
|
85
|
+
return statisticX3RangeTool({
|
|
86
|
+
startDateStr: args.start_date,
|
|
87
|
+
endDateStr: args.end_date,
|
|
88
|
+
sendMessageToLark: getEnv().SEND_MESSAGE_TO_LARK,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
);
|
|
179
92
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
93
|
+
server.tool(
|
|
94
|
+
"debt_collection_by_month",
|
|
95
|
+
"The company's debt collection rate by month",
|
|
96
|
+
{
|
|
97
|
+
month: z.string({ description: "Month to get data, month must be represented with format MM/yyyy" }),
|
|
98
|
+
company_name: z.string({ description: "Company name to get data" }),
|
|
99
|
+
},
|
|
100
|
+
async (args) => {
|
|
101
|
+
const { month, company_name } = args;
|
|
102
|
+
return debtCollectionRateTool({
|
|
103
|
+
sendMessageToLark: getEnv().SEND_MESSAGE_TO_LARK,
|
|
104
|
+
monthDate: month,
|
|
105
|
+
companyName: company_name,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
);
|
|
195
109
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
// productType: PRODUCT_TYPE.X3_EVF,
|
|
208
|
-
// });
|
|
209
|
-
// }
|
|
210
|
-
// );
|
|
110
|
+
server.tool(
|
|
111
|
+
"check_eligibility",
|
|
112
|
+
"Check customer's eligibility for salary advance",
|
|
113
|
+
{
|
|
114
|
+
phone_number: z.string({ description: "Customer's phone number" }),
|
|
115
|
+
},
|
|
116
|
+
async (args) => {
|
|
117
|
+
const { phone_number } = args;
|
|
118
|
+
return accessibleTool(phone_number);
|
|
119
|
+
}
|
|
120
|
+
);
|
|
211
121
|
|
|
212
122
|
function bootstap() {
|
|
213
123
|
ensureEnvVariables();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import axios from
|
|
2
|
-
import { Gimo } from
|
|
3
|
-
import { getEnv } from
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { Gimo } from "./types";
|
|
3
|
+
import { getEnv } from "../env";
|
|
4
4
|
|
|
5
5
|
export async function getAccessToken() {
|
|
6
6
|
const url = `${getEnv().DASH_URL}/api/v1/auth/admin/login`;
|
|
@@ -20,12 +20,30 @@ export async function findCustomerEWAByPhonenumber(phoneNumber: string) {
|
|
|
20
20
|
.get<{ content: Gimo.CustomerEWA[] }>(customerApiUrl, {
|
|
21
21
|
params: { phone_number: phoneNumber },
|
|
22
22
|
headers: {
|
|
23
|
-
Authorization:
|
|
23
|
+
Authorization: "Bearer " + access_token,
|
|
24
24
|
},
|
|
25
25
|
})
|
|
26
26
|
.then((res) => res.data)
|
|
27
27
|
.then((res) => res.content);
|
|
28
28
|
// Select first customer
|
|
29
|
-
const
|
|
29
|
+
const foundedCustomer = customers?.[0];
|
|
30
|
+
if (!foundedCustomer) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
return findCustomerEWAById(foundedCustomer.customer_id);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export async function findCustomerEWAById(id: number) {
|
|
37
|
+
const customerApiUrl = `${getEnv().DASH_URL}/api/v1/admin/customers/ewa/${id}`;
|
|
38
|
+
const access_token = await getAccessToken();
|
|
39
|
+
// Find inlist
|
|
40
|
+
const customer = await axios
|
|
41
|
+
.get<Gimo.CustomerEWA>(customerApiUrl, {
|
|
42
|
+
headers: {
|
|
43
|
+
Authorization: "Bearer " + access_token,
|
|
44
|
+
},
|
|
45
|
+
})
|
|
46
|
+
.then((res) => res.data);
|
|
47
|
+
// Select first customer
|
|
30
48
|
return customer || null;
|
|
31
49
|
}
|
|
@@ -1,60 +1,18 @@
|
|
|
1
1
|
import axios from "axios";
|
|
2
2
|
import { LarkRecord } from "./types/lark.type";
|
|
3
3
|
import { getLarkTenantAccessToken } from "./lark.service";
|
|
4
|
-
import { REPORT_COLUMS } from "./constants/report-columns";
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
const DEBT_COLLECTION_VIEW_ID = "vewI23hNnx";
|
|
8
|
-
const DEBT_COLLECTION_TABLE_ID = "tblQGKjGd8MnK5qs";
|
|
9
|
-
const DEBT_COLLECTION_APP_TOKEN = "V5akbIXqfaBvXqs8twfl6rALgLd";
|
|
10
|
-
|
|
11
|
-
export async function fetchLarkBaseRecords(p: {
|
|
12
|
-
view_id: string;
|
|
13
|
-
field_names: string[];
|
|
14
|
-
app_token: string;
|
|
15
|
-
table_id: string;
|
|
16
|
-
page_size: number;
|
|
17
|
-
page_token?: string;
|
|
18
|
-
}) {
|
|
5
|
+
export async function fetchReportRecords(p: { view_id: string; field_names: string[] }) {
|
|
19
6
|
const access_token = await getLarkTenantAccessToken();
|
|
20
|
-
const { view_id, table_id, app_token, field_names, page_size, page_token } = p;
|
|
21
7
|
const appToken = "V5akbIXqfaBvXqs8twfl6rALgLd";
|
|
22
8
|
const tableId = "tblQGKjGd8MnK5qs";
|
|
23
|
-
const url = `https://open.larksuite.com/open-apis/bitable/v1/apps/${
|
|
9
|
+
const url = `https://open.larksuite.com/open-apis/bitable/v1/apps/${appToken}/tables/${tableId}/records/search`;
|
|
24
10
|
return axios
|
|
25
|
-
.post<{ data: { items: LarkRecord[]
|
|
26
|
-
|
|
27
|
-
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
},
|
|
33
|
-
}
|
|
34
|
-
)
|
|
35
|
-
.then((res) => res.data.data);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export async function fetchDebtCollectionRecords(page_token?: string): Promise<LarkRecord[]> {
|
|
39
|
-
const fieldNames = REPORT_COLUMS.map((item) => item.field_name);
|
|
40
|
-
const {
|
|
41
|
-
has_more,
|
|
42
|
-
items,
|
|
43
|
-
page_token: nextPageToken,
|
|
44
|
-
total,
|
|
45
|
-
} = await fetchLarkBaseRecords({
|
|
46
|
-
view_id: DEBT_COLLECTION_VIEW_ID,
|
|
47
|
-
field_names: fieldNames,
|
|
48
|
-
app_token: DEBT_COLLECTION_APP_TOKEN,
|
|
49
|
-
table_id: DEBT_COLLECTION_TABLE_ID,
|
|
50
|
-
page_size: 500,
|
|
51
|
-
page_token: page_token,
|
|
52
|
-
});
|
|
53
|
-
console.log(total);
|
|
54
|
-
|
|
55
|
-
if (!has_more) {
|
|
56
|
-
return items;
|
|
57
|
-
}
|
|
58
|
-
const result: LarkRecord[] = [...items];
|
|
59
|
-
return result.concat(await fetchDebtCollectionRecords(nextPageToken));
|
|
11
|
+
.post<{ data: { items: LarkRecord[] } }>(url, p, {
|
|
12
|
+
params: { page_size: 500 },
|
|
13
|
+
headers: {
|
|
14
|
+
Authorization: "Bearer " + access_token,
|
|
15
|
+
},
|
|
16
|
+
})
|
|
17
|
+
.then((res) => res.data.data.items);
|
|
60
18
|
}
|
|
@@ -11,29 +11,42 @@ export namespace Gimo {
|
|
|
11
11
|
|
|
12
12
|
export interface CustomerEWA {
|
|
13
13
|
customer_id: number;
|
|
14
|
+
customer_service_id: number;
|
|
14
15
|
customer_full_name: string;
|
|
15
|
-
customer_code
|
|
16
|
-
identify_number
|
|
17
|
-
employee_id?: number;
|
|
18
|
-
employee_code?: string;
|
|
19
|
-
partner_id?: number;
|
|
20
|
-
partner_name?: string;
|
|
21
|
-
debt_collection_type?: string;
|
|
22
|
-
onboard_method?: string;
|
|
23
|
-
verification_status?: string;
|
|
24
|
-
working_status: string;
|
|
25
|
-
dda_status?: string;
|
|
26
|
-
ewa_longest_over_due_day: string;
|
|
27
|
-
ewa_debt_amount?: number;
|
|
28
|
-
ewa_status?: string;
|
|
16
|
+
customer_code: string;
|
|
17
|
+
identify_number: string;
|
|
29
18
|
customer_phone_number: string;
|
|
19
|
+
employee_id: number;
|
|
20
|
+
employee_code: string;
|
|
21
|
+
partner_id: number;
|
|
22
|
+
partner_name: string;
|
|
23
|
+
debt_collection_type: string;
|
|
24
|
+
onboard_method: string;
|
|
25
|
+
verification_status: boolean;
|
|
26
|
+
working_status: string;
|
|
27
|
+
dda_status: string;
|
|
28
|
+
ewa_longest_over_due_day: any;
|
|
29
|
+
ewa_due_debt_amount: any;
|
|
30
|
+
ewa_over_due_debt_amount: any;
|
|
31
|
+
ewa_status: string;
|
|
32
|
+
ekyc_status: string;
|
|
30
33
|
created_at: string;
|
|
31
34
|
updated_at: string;
|
|
32
|
-
bank_full_name
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
bank_full_name: string;
|
|
36
|
+
bank_acc_number: string;
|
|
37
|
+
bank_id: number;
|
|
38
|
+
bank_name: string;
|
|
39
|
+
log_id: any;
|
|
40
|
+
log_ewa_status: any;
|
|
41
|
+
log_type: any;
|
|
42
|
+
log_user_id: any;
|
|
43
|
+
log_username: any;
|
|
44
|
+
log_description: any;
|
|
45
|
+
log_created_at: any;
|
|
46
|
+
source: any;
|
|
47
|
+
sale_code: any;
|
|
48
|
+
created_by: any;
|
|
49
|
+
b_score: any;
|
|
37
50
|
}
|
|
38
51
|
|
|
39
52
|
export interface Customer {
|