gm-mcp 1.0.9 → 1.1.0
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/helpers/search-like.d.ts +1 -0
- package/dist/helpers/search-like.js +40 -0
- package/dist/index.js +10 -2
- package/dist/services/constants/report-columns.d.ts +150 -0
- package/dist/services/constants/report-columns.js +963 -0
- package/dist/services/lark-base.service.d.ts +5 -0
- package/dist/services/lark-base.service.js +33 -0
- package/dist/services/lark.service.d.ts +1 -0
- package/dist/services/lark.service.js +4 -3
- package/dist/services/lending.service.d.ts +9 -4
- package/dist/services/lending.service.js +4 -3
- package/dist/services/types/index.d.ts +1 -0
- package/dist/services/types/index.js +1 -0
- package/dist/services/types/lark.type.d.ts +4 -0
- package/dist/services/types/lark.type.js +2 -0
- package/dist/services/types/lending.type.d.ts +3 -0
- package/dist/services/types/response.d.ts +10 -0
- package/dist/services/types/response.js +2 -0
- package/dist/test.js +30 -1
- package/dist/tools/lark-tool.d.ts +6 -0
- package/dist/tools/lark-tool.js +50 -0
- package/dist/tools/statistic-x3.js +5 -5
- package/package.json +2 -2
- package/src/helpers/search-like.ts +39 -0
- package/src/index.ts +17 -3
- package/src/services/constants/report-columns.ts +962 -0
- package/src/services/lark-base.service.ts +18 -0
- package/src/services/lark.service.ts +3 -3
- package/src/services/lending.service.ts +6 -6
- package/src/services/types/index.ts +1 -0
- package/src/services/types/lark.type.ts +4 -0
- package/src/services/types/lending.type.ts +4 -0
- package/src/services/types/response.ts +10 -0
- package/src/test.ts +39 -1
- package/src/tools/lark-tool.ts +46 -0
- package/src/tools/statistic-x3.ts +4 -4
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { LarkRecord } from "./types/lark.type";
|
|
3
|
+
import { getLarkTenantAccessToken } from "./lark.service";
|
|
4
|
+
|
|
5
|
+
export async function fetchReportRecords(p: { view_id: string; field_names: string[] }) {
|
|
6
|
+
const access_token = await getLarkTenantAccessToken();
|
|
7
|
+
const appToken = "V5akbIXqfaBvXqs8twfl6rALgLd";
|
|
8
|
+
const tableId = "tblQGKjGd8MnK5qs";
|
|
9
|
+
const url = `https://open.larksuite.com/open-apis/bitable/v1/apps/${appToken}/tables/${tableId}/records/search`;
|
|
10
|
+
return axios
|
|
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);
|
|
18
|
+
}
|
|
@@ -13,7 +13,7 @@ const larkClient = new lark.Client({
|
|
|
13
13
|
disableTokenCache: true,
|
|
14
14
|
});
|
|
15
15
|
|
|
16
|
-
async function
|
|
16
|
+
export async function getLarkTenantAccessToken() {
|
|
17
17
|
const url = "https://open.larksuite.com/open-apis/auth/v3/tenant_access_token/internal";
|
|
18
18
|
return axios
|
|
19
19
|
.post<{
|
|
@@ -68,7 +68,7 @@ async function getAccessToken() {
|
|
|
68
68
|
|
|
69
69
|
// Split later
|
|
70
70
|
export async function sendStatisticX3Message(data: { date: string; content: string }) {
|
|
71
|
-
const access_token = await
|
|
71
|
+
const access_token = await getLarkTenantAccessToken();
|
|
72
72
|
const { date, content } = data;
|
|
73
73
|
const messageContent = {
|
|
74
74
|
type: "template",
|
|
@@ -98,7 +98,7 @@ export async function sendStatisticX3Message(data: { date: string; content: stri
|
|
|
98
98
|
|
|
99
99
|
export async function sendLarkTextMessage(p: { message_content: { text: string }; receive_id: string }) {
|
|
100
100
|
const { message_content, receive_id } = p;
|
|
101
|
-
const access_token = await
|
|
101
|
+
const access_token = await getLarkTenantAccessToken();
|
|
102
102
|
return larkClient.im.message.create(
|
|
103
103
|
{
|
|
104
104
|
params: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import axios from "axios";
|
|
2
2
|
import { getEnv } from "../env";
|
|
3
|
-
import { Gimo, GimoLending } from "./types";
|
|
3
|
+
import { ApiResponseBase, Gimo, GimoLending } from "./types";
|
|
4
4
|
|
|
5
5
|
async function getAccessToken() {
|
|
6
6
|
const url = `${getEnv().DASH_URL}/api/v1/auth/admin/login`;
|
|
@@ -42,6 +42,7 @@ export async function statisticLoan(p: GimoLending.FilterLoan) {
|
|
|
42
42
|
.get<{
|
|
43
43
|
result: {
|
|
44
44
|
loan_instance_list_statistics: GimoLending.LoanStatistic;
|
|
45
|
+
loan_instance_list_data: ApiResponseBase<GimoLending.Loan>;
|
|
45
46
|
};
|
|
46
47
|
}>(url, {
|
|
47
48
|
headers: {
|
|
@@ -52,7 +53,7 @@ export async function statisticLoan(p: GimoLending.FilterLoan) {
|
|
|
52
53
|
sort: "created_at,DESC",
|
|
53
54
|
},
|
|
54
55
|
})
|
|
55
|
-
.then((res) => res.data.result
|
|
56
|
+
.then((res) => res.data.result);
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
export async function statisticX3(p: GimoLending.FilterApplication) {
|
|
@@ -86,9 +87,9 @@ export async function statisticX3(p: GimoLending.FilterApplication) {
|
|
|
86
87
|
(item) => item.status === GimoLending.LendingApplicationStatus.CLOSED
|
|
87
88
|
).length;
|
|
88
89
|
|
|
89
|
-
const total_dibursed = applications.filter(
|
|
90
|
-
|
|
91
|
-
).length;
|
|
90
|
+
// const total_dibursed = applications.filter(
|
|
91
|
+
// (item) => item.disbursement_status === GimoLending.LoanDisbursementStatus.DISBURSED
|
|
92
|
+
// ).length;
|
|
92
93
|
|
|
93
94
|
return {
|
|
94
95
|
total: total_elements,
|
|
@@ -98,7 +99,6 @@ export async function statisticX3(p: GimoLending.FilterApplication) {
|
|
|
98
99
|
total_rejected,
|
|
99
100
|
total_signed,
|
|
100
101
|
total_closed,
|
|
101
|
-
total_dibursed,
|
|
102
102
|
loan_statistic,
|
|
103
103
|
};
|
|
104
104
|
} catch (error) {
|
package/src/test.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { ensureEnvVariables, getEnv } from "./env";
|
|
2
|
+
import { searchLike } from "./helpers/search-like";
|
|
3
|
+
import { REPORT_COLUMS } from "./services/constants/report-columns";
|
|
4
|
+
import { fetchReportRecords } from "./services/lark-base.service";
|
|
2
5
|
import { sendLarkTextMessage, sendMessageToX3Group } from "./services/lark.service";
|
|
3
6
|
import {
|
|
4
7
|
statisticX3RangeTool,
|
|
@@ -7,10 +10,45 @@ import {
|
|
|
7
10
|
statisticX3WeekTool,
|
|
8
11
|
statisticX3YesterdayTool,
|
|
9
12
|
} from "./tools";
|
|
13
|
+
import { debtCollectionRateTool } from "./tools/lark-tool";
|
|
10
14
|
|
|
11
15
|
async function setupTest() {
|
|
12
16
|
ensureEnvVariables();
|
|
13
|
-
const
|
|
17
|
+
const compnay = "BGG";
|
|
18
|
+
const month = "12/2025";
|
|
19
|
+
const res = await debtCollectionRateTool({ sendMessageToLark: false, companyName: compnay, monthDate: month });
|
|
20
|
+
console.log(res);
|
|
21
|
+
|
|
22
|
+
// const fieldNames = REPORT_COLUMS.map((item) => item.field_name);
|
|
23
|
+
// try {
|
|
24
|
+
// const records = await fetchReportRecords({ view_id: "vewI23hNnx", field_names: fieldNames });
|
|
25
|
+
// // console.log(records);
|
|
26
|
+
|
|
27
|
+
// // Find by name first
|
|
28
|
+
// const companyNames = records.map((item) => (item.fields["CÔNG TY"] || "") as string);
|
|
29
|
+
// // console.log(companyNames);
|
|
30
|
+
// const searchTems = "DENKO";
|
|
31
|
+
// const monthTerm = "12";
|
|
32
|
+
// const foundName = searchLike(searchTems, companyNames)[0];
|
|
33
|
+
// const companiesMatchName = records.filter((item) => item.fields["CÔNG TY"] === foundName);
|
|
34
|
+
// // console.log(companiesMatchName);
|
|
35
|
+
|
|
36
|
+
// // Find by pay period
|
|
37
|
+
// const foundMonth = searchLike(
|
|
38
|
+
// monthTerm,
|
|
39
|
+
// companiesMatchName.map((item) => item.fields["KỲ LƯƠNG"])
|
|
40
|
+
// )[0];
|
|
41
|
+
// console.log(foundMonth);
|
|
42
|
+
|
|
43
|
+
// const finalCompnay = companiesMatchName.find((item) => item.fields["KỲ LƯƠNG"] === foundMonth);
|
|
44
|
+
// console.log(finalCompnay);
|
|
45
|
+
|
|
46
|
+
// // console.log(companyCandidates);
|
|
47
|
+
// } catch (e) {
|
|
48
|
+
// console.log(e);
|
|
49
|
+
// }
|
|
50
|
+
|
|
51
|
+
// const sendMessageToLark = getEnv().SEND_MESSAGE_TO_LARK;
|
|
14
52
|
|
|
15
53
|
// const reuslt = await statisticX3TodayTool({ sendMessageToLark: false });
|
|
16
54
|
// console.log(reuslt);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { CallToolResult } from "@modelcontextprotocol/sdk/types";
|
|
2
|
+
import { extractMonth } from "../helpers";
|
|
3
|
+
import { searchLike } from "../helpers/search-like";
|
|
4
|
+
import { REPORT_COLUMS } from "../services/constants/report-columns";
|
|
5
|
+
import { fetchReportRecords } from "../services/lark-base.service";
|
|
6
|
+
|
|
7
|
+
export async function debtCollectionRateTool(options: {
|
|
8
|
+
sendMessageToLark: boolean;
|
|
9
|
+
companyName: string;
|
|
10
|
+
monthDate: string;
|
|
11
|
+
}): Promise<CallToolResult> {
|
|
12
|
+
const { sendMessageToLark, companyName, monthDate } = options;
|
|
13
|
+
const monthParts = extractMonth(monthDate);
|
|
14
|
+
if (monthParts === null) {
|
|
15
|
+
return { content: [{ type: "text", text: `${monthDate} is invalid` }] };
|
|
16
|
+
}
|
|
17
|
+
const { month, year } = monthParts;
|
|
18
|
+
const fieldNames = REPORT_COLUMS.map((item) => item.field_name);
|
|
19
|
+
try {
|
|
20
|
+
const records = await fetchReportRecords({ view_id: "vewI23hNnx", field_names: fieldNames });
|
|
21
|
+
// console.log(records);
|
|
22
|
+
|
|
23
|
+
// Find by name first
|
|
24
|
+
const companyNames = records.map((item) => (item.fields["CÔNG TY"] || "") as string);
|
|
25
|
+
// console.log(companyNames);
|
|
26
|
+
// const searchTems = "DENKO";
|
|
27
|
+
// const monthTerm = "12";
|
|
28
|
+
const foundName = searchLike(companyName, companyNames)[0];
|
|
29
|
+
const companiesMatchName = records.filter((item) => item.fields["CÔNG TY"] === foundName);
|
|
30
|
+
// console.log(companiesMatchName);
|
|
31
|
+
|
|
32
|
+
// Find by pay period
|
|
33
|
+
const foundMonth = searchLike(
|
|
34
|
+
month.toString(),
|
|
35
|
+
companiesMatchName.map((item) => item.fields["KỲ LƯƠNG"])
|
|
36
|
+
)[0];
|
|
37
|
+
console.log(foundMonth);
|
|
38
|
+
const finalCompnay = companiesMatchName.find((item) => item.fields["KỲ LƯƠNG"] === foundMonth);
|
|
39
|
+
return { content: [{ type: "text", text: JSON.stringify(finalCompnay) }] };
|
|
40
|
+
console.log(finalCompnay);
|
|
41
|
+
if (sendMessageToLark) {
|
|
42
|
+
}
|
|
43
|
+
} catch (e) {
|
|
44
|
+
return { content: [{ type: "text", text: JSON.stringify(e) }] };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -360,7 +360,7 @@ async function _statisticX3(p: {
|
|
|
360
360
|
`<br>`,
|
|
361
361
|
`Số đơn chờ duyệt: ${res.total_appraisal || "0"}`,
|
|
362
362
|
`<br>`,
|
|
363
|
-
`Số đơn được giải ngân: ${res.
|
|
363
|
+
`Số đơn được giải ngân: ${res.loan_statistic.loan_instance_list_data.total_elements || "0"}`,
|
|
364
364
|
`<hr>`,
|
|
365
365
|
`Số đơn bị từ chối: ${res.total_rejected || "0"}`,
|
|
366
366
|
`<br>`,
|
|
@@ -368,11 +368,11 @@ async function _statisticX3(p: {
|
|
|
368
368
|
`<hr>`,
|
|
369
369
|
// `Tỷ lê đơn đơn được giải ngân/được duyệt: ${distributedOverApproval}%`,
|
|
370
370
|
// `<hr>`,
|
|
371
|
-
`Tổng đã giải ngân: ${formatCurrency(res.loan_statistic?.total_disbursement_amount) || "0"}`,
|
|
371
|
+
`Tổng đã giải ngân: ${formatCurrency(res.loan_statistic?.loan_instance_list_statistics?.total_disbursement_amount) || "0"}`,
|
|
372
372
|
`<br>`,
|
|
373
|
-
`Tổng phải trả: ${formatCurrency(res.loan_statistic?.total_payment_amount) || "0"}`,
|
|
373
|
+
`Tổng phải trả: ${formatCurrency(res.loan_statistic?.loan_instance_list_statistics?.total_payment_amount) || "0"}`,
|
|
374
374
|
`<br>`,
|
|
375
|
-
`Tổng lãi phải trả: ${formatCurrency(res.loan_statistic?.total_interest_amount) || "0"}`,
|
|
375
|
+
`Tổng lãi phải trả: ${formatCurrency(res.loan_statistic?.loan_instance_list_statistics?.total_interest_amount) || "0"}`,
|
|
376
376
|
];
|
|
377
377
|
return { message: messageContent.join(""), statisticData: res };
|
|
378
378
|
}
|