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/src/test.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import z from "zod";
|
|
2
1
|
import { ensureEnvVariables, getEnv } from "./env";
|
|
3
2
|
import { searchLike } from "./helpers/search-like";
|
|
4
3
|
import { REPORT_COLUMS } from "./services/constants/report-columns";
|
|
5
|
-
import {
|
|
4
|
+
import { fetchReportRecords } from "./services/lark-base.service";
|
|
6
5
|
import { sendLarkTextMessage, sendMessageToX3Group } from "./services/lark.service";
|
|
7
6
|
import {
|
|
8
7
|
statisticX3RangeTool,
|
|
@@ -12,41 +11,13 @@ import {
|
|
|
12
11
|
statisticX3YesterdayTool,
|
|
13
12
|
} from "./tools";
|
|
14
13
|
import { debtCollectionRateTool } from "./tools/lark-tool";
|
|
15
|
-
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
16
|
-
import { PRODUCT_TYPE } from "./services/constants/product-type";
|
|
17
14
|
|
|
18
15
|
async function setupTest() {
|
|
19
16
|
ensureEnvVariables();
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
year: z.string().describe("Year to get company debt collection").default("2025").optional(),
|
|
25
|
-
product_type: z
|
|
26
|
-
.string()
|
|
27
|
-
.nullable()
|
|
28
|
-
.describe("Product type to get data one of follow values EWA 02 - 03 | EWA 04 | Lương X3 | Lương X3 - EVF "),
|
|
29
|
-
month: z.string().nullable().describe("Month to get company debt collection").default("").optional(),
|
|
30
|
-
})
|
|
31
|
-
.toJSONSchema())
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
// const res = zodToJsonSchema();
|
|
35
|
-
|
|
36
|
-
// console.log(res);
|
|
37
|
-
|
|
38
|
-
// const r = await fetchDebtCollectionRecords();
|
|
39
|
-
// console.log(r.length);
|
|
40
|
-
|
|
41
|
-
// const compnay = "BGG";
|
|
42
|
-
// const month = "12/2025";
|
|
43
|
-
// const res = await debtCollectionRateTool({
|
|
44
|
-
// sendMessageToLark: true,
|
|
45
|
-
// companyName: "Tkg",
|
|
46
|
-
// // monthDate: "8/2025",
|
|
47
|
-
// productType: PRODUCT_TYPE.X3_EVF,
|
|
48
|
-
// });
|
|
49
|
-
// console.log(res);
|
|
17
|
+
const compnay = "BGG";
|
|
18
|
+
const month = "12/2025";
|
|
19
|
+
const res = await debtCollectionRateTool({ sendMessageToLark: false, companyName: compnay, monthDate: month });
|
|
20
|
+
console.log(res);
|
|
50
21
|
|
|
51
22
|
// const fieldNames = REPORT_COLUMS.map((item) => item.field_name);
|
|
52
23
|
// try {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { CallToolResult } from "@modelcontextprotocol/sdk/types";
|
|
2
|
+
import { findCustomerEWAByPhonenumber } from "../services/gimo.service";
|
|
3
|
+
|
|
4
|
+
export async function accessibleTool(phoneNumber: string): Promise<CallToolResult> {
|
|
5
|
+
try {
|
|
6
|
+
const customer = await findCustomerEWAByPhonenumber(phoneNumber);
|
|
7
|
+
if (!customer) {
|
|
8
|
+
throw "Customer not found";
|
|
9
|
+
}
|
|
10
|
+
const currentInformation = {
|
|
11
|
+
ewa_status: customer?.ewa_status,
|
|
12
|
+
dda: customer?.dda_status,
|
|
13
|
+
seniority: 1,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const validInformation: Record<string, string> = {
|
|
17
|
+
ewa_status: "active",
|
|
18
|
+
dda: "REGISTERED",
|
|
19
|
+
seniority: ">= 0.3 năm",
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const returnData = {
|
|
23
|
+
current_information: currentInformation,
|
|
24
|
+
valid_information: validInformation,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
return { content: [{ type: "text", text: JSON.stringify(returnData) }] };
|
|
28
|
+
} catch (error) {
|
|
29
|
+
return {
|
|
30
|
+
content: [
|
|
31
|
+
{
|
|
32
|
+
type: "text",
|
|
33
|
+
text: "Oh no,có rồi, thử lại nhé " + error,
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
package/src/tools/lark-tool.ts
CHANGED
|
@@ -2,133 +2,59 @@ import { CallToolResult } from "@modelcontextprotocol/sdk/types";
|
|
|
2
2
|
import { extractMonth } from "../helpers";
|
|
3
3
|
import { searchLike } from "../helpers/search-like";
|
|
4
4
|
import { REPORT_COLUMS } from "../services/constants/report-columns";
|
|
5
|
-
import {
|
|
5
|
+
import { fetchReportRecords } from "../services/lark-base.service";
|
|
6
6
|
import { sendReportOpsGroup } from "../services/lark.service";
|
|
7
7
|
|
|
8
8
|
const companyKey = "CÔNG TY";
|
|
9
9
|
const preiodKey = "KỲ LƯƠNG";
|
|
10
10
|
const debtCollectionRateKey = "TỈ LỆ THU NỢ";
|
|
11
|
-
const debReductionMonthKey = "THÁNG CẮT NỢ";
|
|
12
|
-
const productKey = "Loại Sản phẩm";
|
|
13
|
-
const monthReductionDebtKey = "THÁNG CẮT NỢ";
|
|
14
|
-
const statusKey = "TRẠNG THÁI";
|
|
15
|
-
|
|
16
|
-
const VALID_YEARS = ["2025", "2026"];
|
|
17
11
|
|
|
18
12
|
export async function debtCollectionRateTool(options: {
|
|
19
13
|
sendMessageToLark: boolean;
|
|
20
14
|
companyName: string;
|
|
21
|
-
monthDate
|
|
22
|
-
productType?: string;
|
|
23
|
-
month?: string;
|
|
24
|
-
year?: string;
|
|
15
|
+
monthDate: string;
|
|
25
16
|
}): Promise<CallToolResult> {
|
|
26
|
-
const { sendMessageToLark, companyName, monthDate
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
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(",")}`,
|
|
31
|
-
});
|
|
32
|
-
throw new Error("Year is invalid");
|
|
17
|
+
const { sendMessageToLark, companyName, monthDate } = options;
|
|
18
|
+
const monthParts = extractMonth(monthDate);
|
|
19
|
+
if (monthParts === null) {
|
|
20
|
+
return { content: [{ type: "text", text: `${monthDate} is invalid` }] };
|
|
33
21
|
}
|
|
34
|
-
|
|
35
|
-
// if (monthParts === null) {
|
|
36
|
-
// return { content: [{ type: "text", text: `${monthDate} is invalid` }] };
|
|
37
|
-
// }
|
|
22
|
+
const { month, year } = monthParts;
|
|
38
23
|
const fieldNames = REPORT_COLUMS.map((item) => item.field_name);
|
|
39
24
|
try {
|
|
40
|
-
|
|
41
|
-
//
|
|
42
|
-
const records = await fetchDebtCollectionRecords();
|
|
25
|
+
const records = await fetchReportRecords({ view_id: "vewI23hNnx", field_names: fieldNames });
|
|
43
26
|
// console.log(records);
|
|
44
27
|
|
|
45
28
|
// Find by name first
|
|
46
|
-
const companyNames = records.map((item) => (item.fields[
|
|
29
|
+
const companyNames = records.map((item) => (item.fields["CÔNG TY"] || "") as string);
|
|
47
30
|
// console.log(companyNames);
|
|
48
31
|
// const searchTems = "DENKO";
|
|
49
32
|
// const monthTerm = "12";
|
|
50
33
|
const foundName = searchLike(companyName, companyNames)[0];
|
|
51
|
-
const companiesMatchName = records.filter((item) => item.fields[
|
|
34
|
+
const companiesMatchName = records.filter((item) => item.fields["CÔNG TY"] === foundName);
|
|
52
35
|
// console.log(companiesMatchName);
|
|
53
36
|
|
|
54
|
-
// Find by
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
return compareReductionDebtMonth(item.fields[debReductionMonthKey], month.toString());
|
|
62
|
-
})
|
|
63
|
-
.filter((item) => {
|
|
64
|
-
if (!productType) {
|
|
65
|
-
return true;
|
|
66
|
-
}
|
|
67
|
-
return (item.fields[productKey] as string)?.toLowerCase() === productType.toLowerCase();
|
|
68
|
-
})
|
|
69
|
-
.sort((a, b) => (b.fields[debReductionMonthKey] as string).localeCompare(a.fields[debReductionMonthKey]));
|
|
70
|
-
// const foundMonth = searchLike(
|
|
71
|
-
// month.toString(),
|
|
72
|
-
// companiesMatchName.map((item) => item.fields["KỲ LƯƠNG"])
|
|
73
|
-
// )[0];
|
|
74
|
-
// console.log(foundRecords);
|
|
75
|
-
// const finalCompnay = companiesMatchName.find((item) => item.fields["KỲ LƯƠNG"] === foundMonth);
|
|
76
|
-
// console.log(finalCompnay);
|
|
77
|
-
if (foundRecords.length === 0 && sendMessageToLark) {
|
|
78
|
-
await sendReportOpsGroup({
|
|
79
|
-
title: ["Tỉ lệ thu nợ", foundName, productType].filter(Boolean).join(" - "),
|
|
80
|
-
message_content: `Rất tiếc, Tôi chưa có thông tin`,
|
|
81
|
-
});
|
|
82
|
-
throw new Error("Data is not found");
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const messages: string[] = [];
|
|
86
|
-
for (const item of foundRecords) {
|
|
87
|
-
messages.push(
|
|
88
|
-
[
|
|
89
|
-
item.fields[debReductionMonthKey] || "N/A",
|
|
90
|
-
typeof item.fields[debtCollectionRateKey] === "undefined"
|
|
91
|
-
? "N/A"
|
|
92
|
-
: round(Number(item.fields[debtCollectionRateKey])) + "%",
|
|
93
|
-
item?.fields[statusKey]?.[0]?.text || "N/A",
|
|
94
|
-
].join(" | ")
|
|
95
|
-
);
|
|
96
|
-
// messages.push(
|
|
97
|
-
// [
|
|
98
|
-
// `Sản phẩm: ${item.fields[productKey] || "N/A"}`,
|
|
99
|
-
// `Kỳ lương: ${item?.fields[preiodKey] || "N/A"}`,
|
|
100
|
-
// `Tr.thái cắt nợ: ${item?.fields[statusKey]?.[0]?.text || "N/A"}`,
|
|
101
|
-
// `Tháng cắt nợ: ${item.fields[monthReductionDebtKey] || "N/A"}`,
|
|
102
|
-
// `Tỷ lệ thu nợ: ${
|
|
103
|
-
// typeof item.fields[debtCollectionRateKey] === "undefined"
|
|
104
|
-
// ? "N/A"
|
|
105
|
-
// : round(Number(item.fields[debtCollectionRateKey])) + "%"
|
|
106
|
-
// }`,
|
|
107
|
-
// ].join("<br>")
|
|
108
|
-
// );
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// return {} as any;
|
|
37
|
+
// Find by pay period
|
|
38
|
+
const foundMonth = searchLike(
|
|
39
|
+
month.toString(),
|
|
40
|
+
companiesMatchName.map((item) => item.fields["KỲ LƯƠNG"])
|
|
41
|
+
)[0];
|
|
42
|
+
console.log(foundMonth);
|
|
43
|
+
const finalCompnay = companiesMatchName.find((item) => item.fields["KỲ LƯƠNG"] === foundMonth);
|
|
112
44
|
|
|
113
45
|
if (sendMessageToLark) {
|
|
114
46
|
await sendReportOpsGroup({
|
|
115
|
-
title:
|
|
116
|
-
message_content:
|
|
47
|
+
title: "Tỉ lệ thu nợ",
|
|
48
|
+
message_content: [
|
|
49
|
+
`Công ty: ${finalCompnay?.fields[companyKey] || "N/A"}`,
|
|
50
|
+
`Kỳ lương: ${finalCompnay?.fields[preiodKey] || "N/A"}`,
|
|
51
|
+
`Tỷ lệ thu nợ: ${Number(finalCompnay?.fields[debtCollectionRateKey]) * 100}%`,
|
|
52
|
+
].join("<hr>"),
|
|
117
53
|
});
|
|
118
54
|
}
|
|
119
|
-
return { content: [{ type: "text", text: JSON.stringify(
|
|
55
|
+
return { content: [{ type: "text", text: JSON.stringify(finalCompnay) }] };
|
|
120
56
|
// console.log(finalCompnay);
|
|
121
57
|
} catch (e) {
|
|
122
58
|
return { content: [{ type: "text", text: JSON.stringify(e) }] };
|
|
123
59
|
}
|
|
124
60
|
}
|
|
125
|
-
|
|
126
|
-
function compareReductionDebtMonth(a: string, b: string) {
|
|
127
|
-
const _a = a.toLowerCase().trim().replace("tháng", "");
|
|
128
|
-
const _b = b.toLowerCase().trim().replace("tháng", "");
|
|
129
|
-
return parseInt(_a, 10) === parseInt(_b, 10);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function round(x: number) {
|
|
133
|
-
return Math.round(x * 10000) / 100;
|
|
134
|
-
}
|