@casys/mcp-erpnext 2.2.0 → 2.2.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/mcp-erpnext.mjs +1109 -256
- package/package.json +1 -1
- package/ui-dist/chart-viewer/index.html +10 -10
- package/ui-dist/doclist-viewer/index.html +10 -10
- package/ui-dist/funnel-viewer/index.html +10 -10
- package/ui-dist/invoice-viewer/index.html +11 -11
- package/ui-dist/kanban-viewer/index.html +10 -10
- package/ui-dist/kpi-viewer/index.html +10 -10
- package/ui-dist/stock-viewer/index.html +11 -11
package/mcp-erpnext.mjs
CHANGED
|
@@ -32411,7 +32411,10 @@ var salesTools = [
|
|
|
32411
32411
|
type: "object",
|
|
32412
32412
|
properties: {
|
|
32413
32413
|
limit: { type: "number", description: "Max results (default 20)" },
|
|
32414
|
-
customer_group: {
|
|
32414
|
+
customer_group: {
|
|
32415
|
+
type: "string",
|
|
32416
|
+
description: "Filter by customer group"
|
|
32417
|
+
},
|
|
32415
32418
|
territory: { type: "string", description: "Filter by territory" },
|
|
32416
32419
|
include_disabled: {
|
|
32417
32420
|
type: "boolean",
|
|
@@ -32432,7 +32435,14 @@ var salesTools = [
|
|
|
32432
32435
|
filters.push(["territory", "=", input.territory]);
|
|
32433
32436
|
}
|
|
32434
32437
|
const docs = await ctx.client.list("Customer", {
|
|
32435
|
-
fields: [
|
|
32438
|
+
fields: [
|
|
32439
|
+
"name",
|
|
32440
|
+
"customer_name",
|
|
32441
|
+
"customer_group",
|
|
32442
|
+
"territory",
|
|
32443
|
+
"email_id",
|
|
32444
|
+
"disabled"
|
|
32445
|
+
],
|
|
32436
32446
|
filters,
|
|
32437
32447
|
limit,
|
|
32438
32448
|
order_by: "modified desc"
|
|
@@ -32477,7 +32487,10 @@ var salesTools = [
|
|
|
32477
32487
|
type: "string",
|
|
32478
32488
|
description: "Customer group (default: 'Commercial')"
|
|
32479
32489
|
},
|
|
32480
|
-
territory: {
|
|
32490
|
+
territory: {
|
|
32491
|
+
type: "string",
|
|
32492
|
+
description: "Territory (default: 'All Territories')"
|
|
32493
|
+
},
|
|
32481
32494
|
email_id: { type: "string", description: "Primary email address" },
|
|
32482
32495
|
customer_type: {
|
|
32483
32496
|
type: "string",
|
|
@@ -32489,15 +32502,21 @@ var salesTools = [
|
|
|
32489
32502
|
},
|
|
32490
32503
|
handler: async (input, ctx) => {
|
|
32491
32504
|
if (!input.customer_name) {
|
|
32492
|
-
throw new Error(
|
|
32505
|
+
throw new Error(
|
|
32506
|
+
"[erpnext_customer_create] 'customer_name' is required"
|
|
32507
|
+
);
|
|
32493
32508
|
}
|
|
32494
32509
|
const data = {
|
|
32495
32510
|
customer_name: input.customer_name
|
|
32496
32511
|
};
|
|
32497
|
-
if (input.customer_group)
|
|
32512
|
+
if (input.customer_group) {
|
|
32513
|
+
data.customer_group = input.customer_group;
|
|
32514
|
+
}
|
|
32498
32515
|
if (input.territory) data.territory = input.territory;
|
|
32499
32516
|
if (input.email_id) data.email_id = input.email_id;
|
|
32500
|
-
if (input.customer_type)
|
|
32517
|
+
if (input.customer_type) {
|
|
32518
|
+
data.customer_type = input.customer_type;
|
|
32519
|
+
}
|
|
32501
32520
|
const doc = await ctx.client.create("Customer", data);
|
|
32502
32521
|
return {
|
|
32503
32522
|
data: doc,
|
|
@@ -32534,7 +32553,9 @@ var salesTools = [
|
|
|
32534
32553
|
if (v !== void 0) data[k] = v;
|
|
32535
32554
|
}
|
|
32536
32555
|
if (Object.keys(data).length === 0) {
|
|
32537
|
-
throw new Error(
|
|
32556
|
+
throw new Error(
|
|
32557
|
+
"[erpnext_customer_update] At least one field to update is required"
|
|
32558
|
+
);
|
|
32538
32559
|
}
|
|
32539
32560
|
const doc = await ctx.client.update("Customer", name, data);
|
|
32540
32561
|
return {
|
|
@@ -32559,7 +32580,10 @@ var salesTools = [
|
|
|
32559
32580
|
type: "string",
|
|
32560
32581
|
description: "Filter by status (Draft, To Deliver and Bill, Completed, Cancelled, etc.)"
|
|
32561
32582
|
},
|
|
32562
|
-
date_from: {
|
|
32583
|
+
date_from: {
|
|
32584
|
+
type: "string",
|
|
32585
|
+
description: "Start date filter YYYY-MM-DD"
|
|
32586
|
+
},
|
|
32563
32587
|
date_to: { type: "string", description: "End date filter YYYY-MM-DD" }
|
|
32564
32588
|
}
|
|
32565
32589
|
},
|
|
@@ -32579,7 +32603,14 @@ var salesTools = [
|
|
|
32579
32603
|
filters.push(["transaction_date", "<=", input.date_to]);
|
|
32580
32604
|
}
|
|
32581
32605
|
const docs = await ctx.client.list("Sales Order", {
|
|
32582
|
-
fields: [
|
|
32606
|
+
fields: [
|
|
32607
|
+
"name",
|
|
32608
|
+
"customer",
|
|
32609
|
+
"transaction_date",
|
|
32610
|
+
"status",
|
|
32611
|
+
"grand_total",
|
|
32612
|
+
"currency"
|
|
32613
|
+
],
|
|
32583
32614
|
filters,
|
|
32584
32615
|
limit,
|
|
32585
32616
|
order_by: "modified desc"
|
|
@@ -32601,7 +32632,10 @@ var salesTools = [
|
|
|
32601
32632
|
inputSchema: {
|
|
32602
32633
|
type: "object",
|
|
32603
32634
|
properties: {
|
|
32604
|
-
name: {
|
|
32635
|
+
name: {
|
|
32636
|
+
type: "string",
|
|
32637
|
+
description: "Sales Order name (e.g. SO-00001)"
|
|
32638
|
+
}
|
|
32605
32639
|
},
|
|
32606
32640
|
required: ["name"]
|
|
32607
32641
|
},
|
|
@@ -32631,7 +32665,10 @@ var salesTools = [
|
|
|
32631
32665
|
item_code: { type: "string" },
|
|
32632
32666
|
qty: { type: "number" },
|
|
32633
32667
|
rate: { type: "number" },
|
|
32634
|
-
warehouse: {
|
|
32668
|
+
warehouse: {
|
|
32669
|
+
type: "string",
|
|
32670
|
+
description: "Item warehouse (e.g. 'Stores - CI')"
|
|
32671
|
+
}
|
|
32635
32672
|
},
|
|
32636
32673
|
required: ["item_code", "qty", "rate"]
|
|
32637
32674
|
}
|
|
@@ -32664,7 +32701,9 @@ var salesTools = [
|
|
|
32664
32701
|
throw new Error("[erpnext_sales_order_create] 'customer' is required");
|
|
32665
32702
|
}
|
|
32666
32703
|
if (!input.items || !Array.isArray(input.items) || input.items.length === 0) {
|
|
32667
|
-
throw new Error(
|
|
32704
|
+
throw new Error(
|
|
32705
|
+
"[erpnext_sales_order_create] 'items' must be a non-empty array"
|
|
32706
|
+
);
|
|
32668
32707
|
}
|
|
32669
32708
|
const items = input.items.map((item) => {
|
|
32670
32709
|
if (!item.item_code || item.qty == null || item.rate == null) {
|
|
@@ -32685,15 +32724,21 @@ var salesTools = [
|
|
|
32685
32724
|
customer: input.customer,
|
|
32686
32725
|
items
|
|
32687
32726
|
};
|
|
32688
|
-
if (input.delivery_date)
|
|
32727
|
+
if (input.delivery_date) {
|
|
32728
|
+
data.delivery_date = input.delivery_date;
|
|
32729
|
+
}
|
|
32689
32730
|
if (input.company) data.company = input.company;
|
|
32690
|
-
if (input.selling_price_list)
|
|
32731
|
+
if (input.selling_price_list) {
|
|
32732
|
+
data.selling_price_list = input.selling_price_list;
|
|
32733
|
+
}
|
|
32691
32734
|
if (input.currency) {
|
|
32692
32735
|
data.currency = input.currency;
|
|
32693
32736
|
data.price_list_currency = input.currency;
|
|
32694
32737
|
data.plc_conversion_rate = 1;
|
|
32695
32738
|
}
|
|
32696
|
-
if (input.set_warehouse)
|
|
32739
|
+
if (input.set_warehouse) {
|
|
32740
|
+
data.set_warehouse = input.set_warehouse;
|
|
32741
|
+
}
|
|
32697
32742
|
const doc = await ctx.client.create("Sales Order", data);
|
|
32698
32743
|
return {
|
|
32699
32744
|
data: doc,
|
|
@@ -32708,8 +32753,14 @@ var salesTools = [
|
|
|
32708
32753
|
inputSchema: {
|
|
32709
32754
|
type: "object",
|
|
32710
32755
|
properties: {
|
|
32711
|
-
name: {
|
|
32712
|
-
|
|
32756
|
+
name: {
|
|
32757
|
+
type: "string",
|
|
32758
|
+
description: "Sales Order name (e.g. SO-00001)"
|
|
32759
|
+
},
|
|
32760
|
+
delivery_date: {
|
|
32761
|
+
type: "string",
|
|
32762
|
+
description: "New delivery date YYYY-MM-DD"
|
|
32763
|
+
},
|
|
32713
32764
|
items: {
|
|
32714
32765
|
type: "array",
|
|
32715
32766
|
description: "Replacement item list: [{item_code, qty, rate}]",
|
|
@@ -32730,12 +32781,20 @@ var salesTools = [
|
|
|
32730
32781
|
throw new Error("[erpnext_sales_order_update] 'name' is required");
|
|
32731
32782
|
}
|
|
32732
32783
|
const data = {};
|
|
32733
|
-
if (input.delivery_date)
|
|
32784
|
+
if (input.delivery_date) {
|
|
32785
|
+
data.delivery_date = input.delivery_date;
|
|
32786
|
+
}
|
|
32734
32787
|
if (input.items) data.items = input.items;
|
|
32735
32788
|
if (Object.keys(data).length === 0) {
|
|
32736
|
-
throw new Error(
|
|
32789
|
+
throw new Error(
|
|
32790
|
+
"[erpnext_sales_order_update] At least one field to update is required"
|
|
32791
|
+
);
|
|
32737
32792
|
}
|
|
32738
|
-
const doc = await ctx.client.update(
|
|
32793
|
+
const doc = await ctx.client.update(
|
|
32794
|
+
"Sales Order",
|
|
32795
|
+
input.name,
|
|
32796
|
+
data
|
|
32797
|
+
);
|
|
32739
32798
|
return {
|
|
32740
32799
|
data: doc,
|
|
32741
32800
|
message: `Sales Order ${input.name} updated successfully`
|
|
@@ -32751,7 +32810,10 @@ var salesTools = [
|
|
|
32751
32810
|
inputSchema: {
|
|
32752
32811
|
type: "object",
|
|
32753
32812
|
properties: {
|
|
32754
|
-
name: {
|
|
32813
|
+
name: {
|
|
32814
|
+
type: "string",
|
|
32815
|
+
description: "Sales Order name (e.g. SO-00001)"
|
|
32816
|
+
}
|
|
32755
32817
|
},
|
|
32756
32818
|
required: ["name"]
|
|
32757
32819
|
},
|
|
@@ -32777,7 +32839,10 @@ var salesTools = [
|
|
|
32777
32839
|
inputSchema: {
|
|
32778
32840
|
type: "object",
|
|
32779
32841
|
properties: {
|
|
32780
|
-
name: {
|
|
32842
|
+
name: {
|
|
32843
|
+
type: "string",
|
|
32844
|
+
description: "Sales Order name (e.g. SO-00001)"
|
|
32845
|
+
}
|
|
32781
32846
|
},
|
|
32782
32847
|
required: ["name"]
|
|
32783
32848
|
},
|
|
@@ -32811,7 +32876,10 @@ var salesTools = [
|
|
|
32811
32876
|
type: "string",
|
|
32812
32877
|
description: "Filter by status (Draft, Unpaid, Paid, Overdue, Cancelled, etc.)"
|
|
32813
32878
|
},
|
|
32814
|
-
date_from: {
|
|
32879
|
+
date_from: {
|
|
32880
|
+
type: "string",
|
|
32881
|
+
description: "Start date filter YYYY-MM-DD"
|
|
32882
|
+
},
|
|
32815
32883
|
date_to: { type: "string", description: "End date filter YYYY-MM-DD" }
|
|
32816
32884
|
}
|
|
32817
32885
|
},
|
|
@@ -32861,7 +32929,10 @@ var salesTools = [
|
|
|
32861
32929
|
inputSchema: {
|
|
32862
32930
|
type: "object",
|
|
32863
32931
|
properties: {
|
|
32864
|
-
name: {
|
|
32932
|
+
name: {
|
|
32933
|
+
type: "string",
|
|
32934
|
+
description: "Sales Invoice name (e.g. SINV-00001)"
|
|
32935
|
+
}
|
|
32865
32936
|
},
|
|
32866
32937
|
required: ["name"]
|
|
32867
32938
|
},
|
|
@@ -32893,7 +32964,10 @@ var salesTools = [
|
|
|
32893
32964
|
item_code: { type: "string" },
|
|
32894
32965
|
qty: { type: "number" },
|
|
32895
32966
|
rate: { type: "number" },
|
|
32896
|
-
warehouse: {
|
|
32967
|
+
warehouse: {
|
|
32968
|
+
type: "string",
|
|
32969
|
+
description: "Item warehouse (e.g. 'Stores - CI')"
|
|
32970
|
+
}
|
|
32897
32971
|
},
|
|
32898
32972
|
required: ["item_code", "qty", "rate"]
|
|
32899
32973
|
}
|
|
@@ -32927,10 +33001,14 @@ var salesTools = [
|
|
|
32927
33001
|
},
|
|
32928
33002
|
handler: async (input, ctx) => {
|
|
32929
33003
|
if (!input.customer) {
|
|
32930
|
-
throw new Error(
|
|
33004
|
+
throw new Error(
|
|
33005
|
+
"[erpnext_sales_invoice_create] 'customer' is required"
|
|
33006
|
+
);
|
|
32931
33007
|
}
|
|
32932
33008
|
if (!input.items || !Array.isArray(input.items) || input.items.length === 0) {
|
|
32933
|
-
throw new Error(
|
|
33009
|
+
throw new Error(
|
|
33010
|
+
"[erpnext_sales_invoice_create] 'items' must be a non-empty array"
|
|
33011
|
+
);
|
|
32934
33012
|
}
|
|
32935
33013
|
const items = input.items.map((item) => {
|
|
32936
33014
|
if (!item.item_code || item.qty == null || item.rate == null) {
|
|
@@ -32953,13 +33031,17 @@ var salesTools = [
|
|
|
32953
33031
|
if (input.posting_date) data.posting_date = input.posting_date;
|
|
32954
33032
|
if (input.due_date) data.due_date = input.due_date;
|
|
32955
33033
|
if (input.company) data.company = input.company;
|
|
32956
|
-
if (input.selling_price_list)
|
|
33034
|
+
if (input.selling_price_list) {
|
|
33035
|
+
data.selling_price_list = input.selling_price_list;
|
|
33036
|
+
}
|
|
32957
33037
|
if (input.currency) {
|
|
32958
33038
|
data.currency = input.currency;
|
|
32959
33039
|
data.price_list_currency = input.currency;
|
|
32960
33040
|
data.plc_conversion_rate = 1;
|
|
32961
33041
|
}
|
|
32962
|
-
if (input.set_warehouse)
|
|
33042
|
+
if (input.set_warehouse) {
|
|
33043
|
+
data.set_warehouse = input.set_warehouse;
|
|
33044
|
+
}
|
|
32963
33045
|
const doc = await ctx.client.create("Sales Invoice", data);
|
|
32964
33046
|
return {
|
|
32965
33047
|
data: doc,
|
|
@@ -33026,7 +33108,13 @@ var salesTools = [
|
|
|
33026
33108
|
filters.push(["status", "=", input.status]);
|
|
33027
33109
|
}
|
|
33028
33110
|
const docs = await ctx.client.list("Quotation", {
|
|
33029
|
-
fields: [
|
|
33111
|
+
fields: [
|
|
33112
|
+
"name",
|
|
33113
|
+
"party_name",
|
|
33114
|
+
"transaction_date",
|
|
33115
|
+
"status",
|
|
33116
|
+
"grand_total"
|
|
33117
|
+
],
|
|
33030
33118
|
filters,
|
|
33031
33119
|
limit,
|
|
33032
33120
|
order_by: "modified desc"
|
|
@@ -33048,7 +33136,10 @@ var salesTools = [
|
|
|
33048
33136
|
inputSchema: {
|
|
33049
33137
|
type: "object",
|
|
33050
33138
|
properties: {
|
|
33051
|
-
name: {
|
|
33139
|
+
name: {
|
|
33140
|
+
type: "string",
|
|
33141
|
+
description: "Quotation name (e.g. QTN-00001)"
|
|
33142
|
+
}
|
|
33052
33143
|
},
|
|
33053
33144
|
required: ["name"]
|
|
33054
33145
|
},
|
|
@@ -33115,13 +33206,17 @@ var salesTools = [
|
|
|
33115
33206
|
},
|
|
33116
33207
|
handler: async (input, ctx) => {
|
|
33117
33208
|
if (!input.quotation_to) {
|
|
33118
|
-
throw new Error(
|
|
33209
|
+
throw new Error(
|
|
33210
|
+
"[erpnext_quotation_create] 'quotation_to' is required"
|
|
33211
|
+
);
|
|
33119
33212
|
}
|
|
33120
33213
|
if (!input.party_name) {
|
|
33121
33214
|
throw new Error("[erpnext_quotation_create] 'party_name' is required");
|
|
33122
33215
|
}
|
|
33123
33216
|
if (!input.items || !Array.isArray(input.items) || input.items.length === 0) {
|
|
33124
|
-
throw new Error(
|
|
33217
|
+
throw new Error(
|
|
33218
|
+
"[erpnext_quotation_create] 'items' must be a non-empty array"
|
|
33219
|
+
);
|
|
33125
33220
|
}
|
|
33126
33221
|
const items = input.items.map(
|
|
33127
33222
|
(item) => {
|
|
@@ -33130,7 +33225,11 @@ var salesTools = [
|
|
|
33130
33225
|
"[erpnext_quotation_create] Each item must have item_code, qty, and rate"
|
|
33131
33226
|
);
|
|
33132
33227
|
}
|
|
33133
|
-
return {
|
|
33228
|
+
return {
|
|
33229
|
+
item_code: item.item_code,
|
|
33230
|
+
qty: item.qty,
|
|
33231
|
+
rate: item.rate
|
|
33232
|
+
};
|
|
33134
33233
|
}
|
|
33135
33234
|
);
|
|
33136
33235
|
const data = {
|
|
@@ -33138,10 +33237,14 @@ var salesTools = [
|
|
|
33138
33237
|
party_name: input.party_name,
|
|
33139
33238
|
items
|
|
33140
33239
|
};
|
|
33141
|
-
if (input.transaction_date)
|
|
33240
|
+
if (input.transaction_date) {
|
|
33241
|
+
data.transaction_date = input.transaction_date;
|
|
33242
|
+
}
|
|
33142
33243
|
if (input.valid_till) data.valid_till = input.valid_till;
|
|
33143
33244
|
if (input.company) data.company = input.company;
|
|
33144
|
-
if (input.selling_price_list)
|
|
33245
|
+
if (input.selling_price_list) {
|
|
33246
|
+
data.selling_price_list = input.selling_price_list;
|
|
33247
|
+
}
|
|
33145
33248
|
if (input.currency) {
|
|
33146
33249
|
data.currency = input.currency;
|
|
33147
33250
|
data.price_list_currency = input.currency;
|
|
@@ -33190,7 +33293,11 @@ var inventoryTools = [
|
|
|
33190
33293
|
filters.push(["item_group", "=", input.item_group]);
|
|
33191
33294
|
}
|
|
33192
33295
|
if (input.is_stock_item !== void 0) {
|
|
33193
|
-
filters.push([
|
|
33296
|
+
filters.push([
|
|
33297
|
+
"is_stock_item",
|
|
33298
|
+
"=",
|
|
33299
|
+
input.is_stock_item ? 1 : 0
|
|
33300
|
+
]);
|
|
33194
33301
|
}
|
|
33195
33302
|
const docs = await ctx.client.list("Item", {
|
|
33196
33303
|
fields: [
|
|
@@ -33247,7 +33354,10 @@ var inventoryTools = [
|
|
|
33247
33354
|
type: "string",
|
|
33248
33355
|
description: "Item group (default: 'All Item Groups')"
|
|
33249
33356
|
},
|
|
33250
|
-
uom: {
|
|
33357
|
+
uom: {
|
|
33358
|
+
type: "string",
|
|
33359
|
+
description: "Unit of measure (default: 'Nos')"
|
|
33360
|
+
},
|
|
33251
33361
|
is_stock_item: {
|
|
33252
33362
|
type: "boolean",
|
|
33253
33363
|
description: "True for physical stock items (default: true)"
|
|
@@ -33270,8 +33380,12 @@ var inventoryTools = [
|
|
|
33270
33380
|
};
|
|
33271
33381
|
if (input.item_group) data.item_group = input.item_group;
|
|
33272
33382
|
if (input.uom) data.uom = input.uom;
|
|
33273
|
-
if (input.is_stock_item !== void 0)
|
|
33274
|
-
|
|
33383
|
+
if (input.is_stock_item !== void 0) {
|
|
33384
|
+
data.is_stock_item = input.is_stock_item;
|
|
33385
|
+
}
|
|
33386
|
+
if (input.standard_rate !== void 0) {
|
|
33387
|
+
data.standard_rate = input.standard_rate;
|
|
33388
|
+
}
|
|
33275
33389
|
if (input.description) data.description = input.description;
|
|
33276
33390
|
const doc = await ctx.client.create("Item", data);
|
|
33277
33391
|
return {
|
|
@@ -33290,9 +33404,15 @@ var inventoryTools = [
|
|
|
33290
33404
|
name: { type: "string", description: "Item name/item_code" },
|
|
33291
33405
|
item_name: { type: "string", description: "New item name" },
|
|
33292
33406
|
item_group: { type: "string", description: "New item group" },
|
|
33293
|
-
standard_rate: {
|
|
33407
|
+
standard_rate: {
|
|
33408
|
+
type: "number",
|
|
33409
|
+
description: "New default selling rate"
|
|
33410
|
+
},
|
|
33294
33411
|
description: { type: "string", description: "New description" },
|
|
33295
|
-
disabled: {
|
|
33412
|
+
disabled: {
|
|
33413
|
+
type: "boolean",
|
|
33414
|
+
description: "Set to true to disable the item"
|
|
33415
|
+
}
|
|
33296
33416
|
},
|
|
33297
33417
|
required: ["name"]
|
|
33298
33418
|
},
|
|
@@ -33306,7 +33426,9 @@ var inventoryTools = [
|
|
|
33306
33426
|
if (v !== void 0) data[k] = v;
|
|
33307
33427
|
}
|
|
33308
33428
|
if (Object.keys(data).length === 0) {
|
|
33309
|
-
throw new Error(
|
|
33429
|
+
throw new Error(
|
|
33430
|
+
"[erpnext_item_update] At least one field to update is required"
|
|
33431
|
+
);
|
|
33310
33432
|
}
|
|
33311
33433
|
const doc = await ctx.client.update("Item", name, data);
|
|
33312
33434
|
return {
|
|
@@ -33374,7 +33496,10 @@ var inventoryTools = [
|
|
|
33374
33496
|
properties: {
|
|
33375
33497
|
limit: { type: "number", description: "Max results (default 20)" },
|
|
33376
33498
|
company: { type: "string", description: "Filter by company" },
|
|
33377
|
-
warehouse_type: {
|
|
33499
|
+
warehouse_type: {
|
|
33500
|
+
type: "string",
|
|
33501
|
+
description: "Filter by warehouse type"
|
|
33502
|
+
}
|
|
33378
33503
|
}
|
|
33379
33504
|
},
|
|
33380
33505
|
handler: async (input, ctx) => {
|
|
@@ -33415,7 +33540,10 @@ var inventoryTools = [
|
|
|
33415
33540
|
type: "string",
|
|
33416
33541
|
description: "Filter by type (Material Issue, Material Receipt, Material Transfer, etc.)"
|
|
33417
33542
|
},
|
|
33418
|
-
date_from: {
|
|
33543
|
+
date_from: {
|
|
33544
|
+
type: "string",
|
|
33545
|
+
description: "Start date filter YYYY-MM-DD"
|
|
33546
|
+
},
|
|
33419
33547
|
date_to: { type: "string", description: "End date filter YYYY-MM-DD" }
|
|
33420
33548
|
}
|
|
33421
33549
|
},
|
|
@@ -33423,7 +33551,11 @@ var inventoryTools = [
|
|
|
33423
33551
|
const limit = input.limit ?? 20;
|
|
33424
33552
|
const filters = [];
|
|
33425
33553
|
if (input.stock_entry_type) {
|
|
33426
|
-
filters.push([
|
|
33554
|
+
filters.push([
|
|
33555
|
+
"stock_entry_type",
|
|
33556
|
+
"=",
|
|
33557
|
+
input.stock_entry_type
|
|
33558
|
+
]);
|
|
33427
33559
|
}
|
|
33428
33560
|
if (input.date_from) {
|
|
33429
33561
|
filters.push(["posting_date", ">=", input.date_from]);
|
|
@@ -33460,7 +33592,10 @@ var inventoryTools = [
|
|
|
33460
33592
|
inputSchema: {
|
|
33461
33593
|
type: "object",
|
|
33462
33594
|
properties: {
|
|
33463
|
-
name: {
|
|
33595
|
+
name: {
|
|
33596
|
+
type: "string",
|
|
33597
|
+
description: "Stock Entry name (e.g. STE-00001)"
|
|
33598
|
+
}
|
|
33464
33599
|
},
|
|
33465
33600
|
required: ["name"]
|
|
33466
33601
|
},
|
|
@@ -33494,7 +33629,10 @@ var inventoryTools = [
|
|
|
33494
33629
|
qty: { type: "number" },
|
|
33495
33630
|
s_warehouse: { type: "string", description: "Source warehouse" },
|
|
33496
33631
|
t_warehouse: { type: "string", description: "Target warehouse" },
|
|
33497
|
-
basic_rate: {
|
|
33632
|
+
basic_rate: {
|
|
33633
|
+
type: "number",
|
|
33634
|
+
description: "Valuation rate (for receipts)"
|
|
33635
|
+
}
|
|
33498
33636
|
},
|
|
33499
33637
|
required: ["item_code", "qty"]
|
|
33500
33638
|
}
|
|
@@ -33507,23 +33645,32 @@ var inventoryTools = [
|
|
|
33507
33645
|
type: "string",
|
|
33508
33646
|
description: "Default target warehouse (applies to all items if not per-item)"
|
|
33509
33647
|
},
|
|
33510
|
-
posting_date: {
|
|
33648
|
+
posting_date: {
|
|
33649
|
+
type: "string",
|
|
33650
|
+
description: "Posting date YYYY-MM-DD"
|
|
33651
|
+
},
|
|
33511
33652
|
remarks: { type: "string", description: "Optional remarks" }
|
|
33512
33653
|
},
|
|
33513
33654
|
required: ["stock_entry_type", "items"]
|
|
33514
33655
|
},
|
|
33515
33656
|
handler: async (input, ctx) => {
|
|
33516
33657
|
if (!input.stock_entry_type) {
|
|
33517
|
-
throw new Error(
|
|
33658
|
+
throw new Error(
|
|
33659
|
+
"[erpnext_stock_entry_create] 'stock_entry_type' is required"
|
|
33660
|
+
);
|
|
33518
33661
|
}
|
|
33519
33662
|
if (!input.items || !Array.isArray(input.items) || input.items.length === 0) {
|
|
33520
|
-
throw new Error(
|
|
33663
|
+
throw new Error(
|
|
33664
|
+
"[erpnext_stock_entry_create] 'items' must be a non-empty array"
|
|
33665
|
+
);
|
|
33521
33666
|
}
|
|
33522
33667
|
const data = {
|
|
33523
33668
|
stock_entry_type: input.stock_entry_type,
|
|
33524
33669
|
items: input.items
|
|
33525
33670
|
};
|
|
33526
|
-
if (input.from_warehouse)
|
|
33671
|
+
if (input.from_warehouse) {
|
|
33672
|
+
data.from_warehouse = input.from_warehouse;
|
|
33673
|
+
}
|
|
33527
33674
|
if (input.to_warehouse) data.to_warehouse = input.to_warehouse;
|
|
33528
33675
|
if (input.posting_date) data.posting_date = input.posting_date;
|
|
33529
33676
|
if (input.remarks) data.remarks = input.remarks;
|
|
@@ -33554,7 +33701,10 @@ var accountingTools = [
|
|
|
33554
33701
|
description: "Filter by root type: Asset, Liability, Income, Expense, Equity",
|
|
33555
33702
|
enum: ["Asset", "Liability", "Income", "Expense", "Equity"]
|
|
33556
33703
|
},
|
|
33557
|
-
is_group: {
|
|
33704
|
+
is_group: {
|
|
33705
|
+
type: "boolean",
|
|
33706
|
+
description: "Filter by group accounts only"
|
|
33707
|
+
},
|
|
33558
33708
|
company: { type: "string", description: "Filter by company" }
|
|
33559
33709
|
}
|
|
33560
33710
|
},
|
|
@@ -33571,7 +33721,14 @@ var accountingTools = [
|
|
|
33571
33721
|
filters.push(["company", "=", input.company]);
|
|
33572
33722
|
}
|
|
33573
33723
|
const docs = await ctx.client.list("Account", {
|
|
33574
|
-
fields: [
|
|
33724
|
+
fields: [
|
|
33725
|
+
"name",
|
|
33726
|
+
"account_name",
|
|
33727
|
+
"account_type",
|
|
33728
|
+
"root_type",
|
|
33729
|
+
"parent_account",
|
|
33730
|
+
"is_group"
|
|
33731
|
+
],
|
|
33575
33732
|
filters,
|
|
33576
33733
|
limit,
|
|
33577
33734
|
order_by: "name asc"
|
|
@@ -33599,7 +33756,10 @@ var accountingTools = [
|
|
|
33599
33756
|
type: "string",
|
|
33600
33757
|
description: "Filter by voucher type (Journal Entry, Bank Entry, Cash Entry, etc.)"
|
|
33601
33758
|
},
|
|
33602
|
-
date_from: {
|
|
33759
|
+
date_from: {
|
|
33760
|
+
type: "string",
|
|
33761
|
+
description: "Start date filter YYYY-MM-DD"
|
|
33762
|
+
},
|
|
33603
33763
|
date_to: { type: "string", description: "End date filter YYYY-MM-DD" }
|
|
33604
33764
|
}
|
|
33605
33765
|
},
|
|
@@ -33616,7 +33776,14 @@ var accountingTools = [
|
|
|
33616
33776
|
filters.push(["posting_date", "<=", input.date_to]);
|
|
33617
33777
|
}
|
|
33618
33778
|
const docs = await ctx.client.list("Journal Entry", {
|
|
33619
|
-
fields: [
|
|
33779
|
+
fields: [
|
|
33780
|
+
"name",
|
|
33781
|
+
"voucher_type",
|
|
33782
|
+
"posting_date",
|
|
33783
|
+
"total_debit",
|
|
33784
|
+
"total_credit",
|
|
33785
|
+
"remark"
|
|
33786
|
+
],
|
|
33620
33787
|
filters,
|
|
33621
33788
|
limit,
|
|
33622
33789
|
order_by: "modified desc"
|
|
@@ -33637,7 +33804,10 @@ var accountingTools = [
|
|
|
33637
33804
|
inputSchema: {
|
|
33638
33805
|
type: "object",
|
|
33639
33806
|
properties: {
|
|
33640
|
-
name: {
|
|
33807
|
+
name: {
|
|
33808
|
+
type: "string",
|
|
33809
|
+
description: "Journal Entry name (e.g. JV-00001)"
|
|
33810
|
+
}
|
|
33641
33811
|
},
|
|
33642
33812
|
required: ["name"]
|
|
33643
33813
|
},
|
|
@@ -33670,7 +33840,10 @@ var accountingTools = [
|
|
|
33670
33840
|
description: "Filter by party type (Customer, Supplier, Employee)"
|
|
33671
33841
|
},
|
|
33672
33842
|
party: { type: "string", description: "Filter by party name" },
|
|
33673
|
-
date_from: {
|
|
33843
|
+
date_from: {
|
|
33844
|
+
type: "string",
|
|
33845
|
+
description: "Start date filter YYYY-MM-DD"
|
|
33846
|
+
}
|
|
33674
33847
|
}
|
|
33675
33848
|
},
|
|
33676
33849
|
handler: async (input, ctx) => {
|
|
@@ -33718,7 +33891,10 @@ var accountingTools = [
|
|
|
33718
33891
|
inputSchema: {
|
|
33719
33892
|
type: "object",
|
|
33720
33893
|
properties: {
|
|
33721
|
-
name: {
|
|
33894
|
+
name: {
|
|
33895
|
+
type: "string",
|
|
33896
|
+
description: "Payment Entry name (e.g. PE-00001)"
|
|
33897
|
+
}
|
|
33722
33898
|
},
|
|
33723
33899
|
required: ["name"]
|
|
33724
33900
|
},
|
|
@@ -33770,10 +33946,14 @@ var accountingTools = [
|
|
|
33770
33946
|
},
|
|
33771
33947
|
handler: async (input, ctx) => {
|
|
33772
33948
|
if (!input.voucher_type) {
|
|
33773
|
-
throw new Error(
|
|
33949
|
+
throw new Error(
|
|
33950
|
+
"[erpnext_journal_entry_create] 'voucher_type' is required"
|
|
33951
|
+
);
|
|
33774
33952
|
}
|
|
33775
33953
|
if (!input.accounts || !Array.isArray(input.accounts) || input.accounts.length === 0) {
|
|
33776
|
-
throw new Error(
|
|
33954
|
+
throw new Error(
|
|
33955
|
+
"[erpnext_journal_entry_create] 'accounts' must be a non-empty array"
|
|
33956
|
+
);
|
|
33777
33957
|
}
|
|
33778
33958
|
const data = {
|
|
33779
33959
|
voucher_type: input.voucher_type,
|
|
@@ -33854,7 +34034,10 @@ var hrTools = [
|
|
|
33854
34034
|
inputSchema: {
|
|
33855
34035
|
type: "object",
|
|
33856
34036
|
properties: {
|
|
33857
|
-
name: {
|
|
34037
|
+
name: {
|
|
34038
|
+
type: "string",
|
|
34039
|
+
description: "Employee ID (e.g. HR-EMP-00001)"
|
|
34040
|
+
}
|
|
33858
34041
|
},
|
|
33859
34042
|
required: ["name"]
|
|
33860
34043
|
},
|
|
@@ -33883,7 +34066,10 @@ var hrTools = [
|
|
|
33883
34066
|
description: "Filter by status (Present, Absent, Half Day, On Leave)",
|
|
33884
34067
|
enum: ["Present", "Absent", "Half Day", "On Leave"]
|
|
33885
34068
|
},
|
|
33886
|
-
date_from: {
|
|
34069
|
+
date_from: {
|
|
34070
|
+
type: "string",
|
|
34071
|
+
description: "Start date filter YYYY-MM-DD"
|
|
34072
|
+
},
|
|
33887
34073
|
date_to: { type: "string", description: "End date filter YYYY-MM-DD" }
|
|
33888
34074
|
}
|
|
33889
34075
|
},
|
|
@@ -33903,7 +34089,13 @@ var hrTools = [
|
|
|
33903
34089
|
filters.push(["attendance_date", "<=", input.date_to]);
|
|
33904
34090
|
}
|
|
33905
34091
|
const docs = await ctx.client.list("Attendance", {
|
|
33906
|
-
fields: [
|
|
34092
|
+
fields: [
|
|
34093
|
+
"name",
|
|
34094
|
+
"employee",
|
|
34095
|
+
"employee_name",
|
|
34096
|
+
"attendance_date",
|
|
34097
|
+
"status"
|
|
34098
|
+
],
|
|
33907
34099
|
filters,
|
|
33908
34100
|
limit,
|
|
33909
34101
|
order_by: "attendance_date desc"
|
|
@@ -33933,7 +34125,10 @@ var hrTools = [
|
|
|
33933
34125
|
description: "Filter by status (Open, Approved, Rejected, Cancelled)",
|
|
33934
34126
|
enum: ["Open", "Approved", "Rejected", "Cancelled"]
|
|
33935
34127
|
},
|
|
33936
|
-
leave_type: {
|
|
34128
|
+
leave_type: {
|
|
34129
|
+
type: "string",
|
|
34130
|
+
description: "Filter by leave type (e.g. Sick Leave)"
|
|
34131
|
+
}
|
|
33937
34132
|
}
|
|
33938
34133
|
},
|
|
33939
34134
|
handler: async (input, ctx) => {
|
|
@@ -33986,7 +34181,10 @@ var hrTools = [
|
|
|
33986
34181
|
if (!input.name) {
|
|
33987
34182
|
throw new Error("[erpnext_leave_application_get] 'name' is required");
|
|
33988
34183
|
}
|
|
33989
|
-
const doc = await ctx.client.get(
|
|
34184
|
+
const doc = await ctx.client.get(
|
|
34185
|
+
"Leave Application",
|
|
34186
|
+
input.name
|
|
34187
|
+
);
|
|
33990
34188
|
return { data: doc };
|
|
33991
34189
|
}
|
|
33992
34190
|
},
|
|
@@ -33997,8 +34195,14 @@ var hrTools = [
|
|
|
33997
34195
|
inputSchema: {
|
|
33998
34196
|
type: "object",
|
|
33999
34197
|
properties: {
|
|
34000
|
-
employee: {
|
|
34001
|
-
|
|
34198
|
+
employee: {
|
|
34199
|
+
type: "string",
|
|
34200
|
+
description: "Employee ID (e.g. HR-EMP-00001)"
|
|
34201
|
+
},
|
|
34202
|
+
leave_type: {
|
|
34203
|
+
type: "string",
|
|
34204
|
+
description: "Leave type (e.g. Sick Leave, Casual Leave)"
|
|
34205
|
+
},
|
|
34002
34206
|
from_date: { type: "string", description: "Start date YYYY-MM-DD" },
|
|
34003
34207
|
to_date: { type: "string", description: "End date YYYY-MM-DD" },
|
|
34004
34208
|
reason: { type: "string", description: "Reason for leave (optional)" }
|
|
@@ -34007,16 +34211,24 @@ var hrTools = [
|
|
|
34007
34211
|
},
|
|
34008
34212
|
handler: async (input, ctx) => {
|
|
34009
34213
|
if (!input.employee) {
|
|
34010
|
-
throw new Error(
|
|
34214
|
+
throw new Error(
|
|
34215
|
+
"[erpnext_leave_application_create] 'employee' is required"
|
|
34216
|
+
);
|
|
34011
34217
|
}
|
|
34012
34218
|
if (!input.leave_type) {
|
|
34013
|
-
throw new Error(
|
|
34219
|
+
throw new Error(
|
|
34220
|
+
"[erpnext_leave_application_create] 'leave_type' is required"
|
|
34221
|
+
);
|
|
34014
34222
|
}
|
|
34015
34223
|
if (!input.from_date) {
|
|
34016
|
-
throw new Error(
|
|
34224
|
+
throw new Error(
|
|
34225
|
+
"[erpnext_leave_application_create] 'from_date' is required"
|
|
34226
|
+
);
|
|
34017
34227
|
}
|
|
34018
34228
|
if (!input.to_date) {
|
|
34019
|
-
throw new Error(
|
|
34229
|
+
throw new Error(
|
|
34230
|
+
"[erpnext_leave_application_create] 'to_date' is required"
|
|
34231
|
+
);
|
|
34020
34232
|
}
|
|
34021
34233
|
const data = {
|
|
34022
34234
|
employee: input.employee,
|
|
@@ -34051,8 +34263,14 @@ var hrTools = [
|
|
|
34051
34263
|
description: "Filter by status (Draft, Submitted, Cancelled)",
|
|
34052
34264
|
enum: ["Draft", "Submitted", "Cancelled"]
|
|
34053
34265
|
},
|
|
34054
|
-
date_from: {
|
|
34055
|
-
|
|
34266
|
+
date_from: {
|
|
34267
|
+
type: "string",
|
|
34268
|
+
description: "Start date filter YYYY-MM-DD (posting_date >=)"
|
|
34269
|
+
},
|
|
34270
|
+
date_to: {
|
|
34271
|
+
type: "string",
|
|
34272
|
+
description: "End date filter YYYY-MM-DD (posting_date <=)"
|
|
34273
|
+
}
|
|
34056
34274
|
}
|
|
34057
34275
|
},
|
|
34058
34276
|
handler: async (input, ctx) => {
|
|
@@ -34102,7 +34320,10 @@ var hrTools = [
|
|
|
34102
34320
|
inputSchema: {
|
|
34103
34321
|
type: "object",
|
|
34104
34322
|
properties: {
|
|
34105
|
-
name: {
|
|
34323
|
+
name: {
|
|
34324
|
+
type: "string",
|
|
34325
|
+
description: "Salary Slip ID (e.g. Salary Slip/HR-EMP-00001/00001)"
|
|
34326
|
+
}
|
|
34106
34327
|
},
|
|
34107
34328
|
required: ["name"]
|
|
34108
34329
|
},
|
|
@@ -34143,7 +34364,13 @@ var hrTools = [
|
|
|
34143
34364
|
filters.push(["status", "=", input.status]);
|
|
34144
34365
|
}
|
|
34145
34366
|
const docs = await ctx.client.list("Payroll Entry", {
|
|
34146
|
-
fields: [
|
|
34367
|
+
fields: [
|
|
34368
|
+
"name",
|
|
34369
|
+
"company",
|
|
34370
|
+
"posting_date",
|
|
34371
|
+
"payroll_frequency",
|
|
34372
|
+
"status"
|
|
34373
|
+
],
|
|
34147
34374
|
filters,
|
|
34148
34375
|
limit,
|
|
34149
34376
|
order_by: "posting_date desc"
|
|
@@ -34221,30 +34448,46 @@ var hrTools = [
|
|
|
34221
34448
|
inputSchema: {
|
|
34222
34449
|
type: "object",
|
|
34223
34450
|
properties: {
|
|
34224
|
-
employee: {
|
|
34451
|
+
employee: {
|
|
34452
|
+
type: "string",
|
|
34453
|
+
description: "Employee ID (e.g. HR-EMP-00001)"
|
|
34454
|
+
},
|
|
34225
34455
|
expenses: {
|
|
34226
34456
|
type: "array",
|
|
34227
34457
|
description: "List of expense line items",
|
|
34228
34458
|
items: {
|
|
34229
34459
|
type: "object",
|
|
34230
34460
|
properties: {
|
|
34231
|
-
expense_type: {
|
|
34461
|
+
expense_type: {
|
|
34462
|
+
type: "string",
|
|
34463
|
+
description: "Expense type (e.g. Travel, Food)"
|
|
34464
|
+
},
|
|
34232
34465
|
amount: { type: "number", description: "Claimed amount" },
|
|
34233
|
-
description: {
|
|
34466
|
+
description: {
|
|
34467
|
+
type: "string",
|
|
34468
|
+
description: "Description of the expense (optional)"
|
|
34469
|
+
}
|
|
34234
34470
|
},
|
|
34235
34471
|
required: ["expense_type", "amount"]
|
|
34236
34472
|
}
|
|
34237
34473
|
},
|
|
34238
|
-
posting_date: {
|
|
34474
|
+
posting_date: {
|
|
34475
|
+
type: "string",
|
|
34476
|
+
description: "Posting date YYYY-MM-DD (optional, defaults to today)"
|
|
34477
|
+
}
|
|
34239
34478
|
},
|
|
34240
34479
|
required: ["employee", "expenses"]
|
|
34241
34480
|
},
|
|
34242
34481
|
handler: async (input, ctx) => {
|
|
34243
34482
|
if (!input.employee) {
|
|
34244
|
-
throw new Error(
|
|
34483
|
+
throw new Error(
|
|
34484
|
+
"[erpnext_expense_claim_create] 'employee' is required"
|
|
34485
|
+
);
|
|
34245
34486
|
}
|
|
34246
34487
|
if (!input.expenses || !Array.isArray(input.expenses) || input.expenses.length === 0) {
|
|
34247
|
-
throw new Error(
|
|
34488
|
+
throw new Error(
|
|
34489
|
+
"[erpnext_expense_claim_create] 'expenses' is required and must be a non-empty array"
|
|
34490
|
+
);
|
|
34248
34491
|
}
|
|
34249
34492
|
const expenses = input.expenses;
|
|
34250
34493
|
const data = {
|
|
@@ -34275,7 +34518,10 @@ var hrTools = [
|
|
|
34275
34518
|
inputSchema: {
|
|
34276
34519
|
type: "object",
|
|
34277
34520
|
properties: {
|
|
34278
|
-
employee: {
|
|
34521
|
+
employee: {
|
|
34522
|
+
type: "string",
|
|
34523
|
+
description: "Employee ID (e.g. HR-EMP-00001)"
|
|
34524
|
+
}
|
|
34279
34525
|
},
|
|
34280
34526
|
required: ["employee"]
|
|
34281
34527
|
},
|
|
@@ -34288,7 +34534,14 @@ var hrTools = [
|
|
|
34288
34534
|
["docstatus", "=", 1]
|
|
34289
34535
|
];
|
|
34290
34536
|
const docs = await ctx.client.list("Leave Allocation", {
|
|
34291
|
-
fields: [
|
|
34537
|
+
fields: [
|
|
34538
|
+
"name",
|
|
34539
|
+
"leave_type",
|
|
34540
|
+
"total_leaves_allocated",
|
|
34541
|
+
"new_leaves_allocated",
|
|
34542
|
+
"from_date",
|
|
34543
|
+
"to_date"
|
|
34544
|
+
],
|
|
34292
34545
|
filters,
|
|
34293
34546
|
limit: 50,
|
|
34294
34547
|
order_by: "leave_type asc"
|
|
@@ -34446,15 +34699,28 @@ var projectTools = [
|
|
|
34446
34699
|
status: {
|
|
34447
34700
|
type: "string",
|
|
34448
34701
|
description: "Task status (default: Open)",
|
|
34449
|
-
enum: [
|
|
34702
|
+
enum: [
|
|
34703
|
+
"Open",
|
|
34704
|
+
"Working",
|
|
34705
|
+
"Pending Review",
|
|
34706
|
+
"Overdue",
|
|
34707
|
+
"Completed",
|
|
34708
|
+
"Cancelled"
|
|
34709
|
+
]
|
|
34450
34710
|
},
|
|
34451
34711
|
priority: {
|
|
34452
34712
|
type: "string",
|
|
34453
34713
|
description: "Task priority (default: Medium)",
|
|
34454
34714
|
enum: ["Low", "Medium", "High", "Urgent"]
|
|
34455
34715
|
},
|
|
34456
|
-
exp_start_date: {
|
|
34457
|
-
|
|
34716
|
+
exp_start_date: {
|
|
34717
|
+
type: "string",
|
|
34718
|
+
description: "Expected start date YYYY-MM-DD"
|
|
34719
|
+
},
|
|
34720
|
+
exp_end_date: {
|
|
34721
|
+
type: "string",
|
|
34722
|
+
description: "Expected end date YYYY-MM-DD"
|
|
34723
|
+
}
|
|
34458
34724
|
},
|
|
34459
34725
|
required: ["project", "subject"]
|
|
34460
34726
|
},
|
|
@@ -34471,7 +34737,9 @@ var projectTools = [
|
|
|
34471
34737
|
};
|
|
34472
34738
|
if (input.status) data.status = input.status;
|
|
34473
34739
|
if (input.priority) data.priority = input.priority;
|
|
34474
|
-
if (input.exp_start_date)
|
|
34740
|
+
if (input.exp_start_date) {
|
|
34741
|
+
data.exp_start_date = input.exp_start_date;
|
|
34742
|
+
}
|
|
34475
34743
|
if (input.exp_end_date) data.exp_end_date = input.exp_end_date;
|
|
34476
34744
|
const doc = await ctx.client.create("Task", data);
|
|
34477
34745
|
return {
|
|
@@ -34511,7 +34779,14 @@ var projectTools = [
|
|
|
34511
34779
|
status: {
|
|
34512
34780
|
type: "string",
|
|
34513
34781
|
description: "New status",
|
|
34514
|
-
enum: [
|
|
34782
|
+
enum: [
|
|
34783
|
+
"Open",
|
|
34784
|
+
"Working",
|
|
34785
|
+
"Pending Review",
|
|
34786
|
+
"Overdue",
|
|
34787
|
+
"Completed",
|
|
34788
|
+
"Cancelled"
|
|
34789
|
+
]
|
|
34515
34790
|
},
|
|
34516
34791
|
priority: {
|
|
34517
34792
|
type: "string",
|
|
@@ -34522,7 +34797,10 @@ var projectTools = [
|
|
|
34522
34797
|
type: "number",
|
|
34523
34798
|
description: "Completion percentage (0-100)"
|
|
34524
34799
|
},
|
|
34525
|
-
exp_end_date: {
|
|
34800
|
+
exp_end_date: {
|
|
34801
|
+
type: "string",
|
|
34802
|
+
description: "New expected end date YYYY-MM-DD"
|
|
34803
|
+
},
|
|
34526
34804
|
description: { type: "string", description: "New task description" }
|
|
34527
34805
|
},
|
|
34528
34806
|
required: ["name"]
|
|
@@ -34537,7 +34815,9 @@ var projectTools = [
|
|
|
34537
34815
|
if (v !== void 0) data[k] = v;
|
|
34538
34816
|
}
|
|
34539
34817
|
if (Object.keys(data).length === 0) {
|
|
34540
|
-
throw new Error(
|
|
34818
|
+
throw new Error(
|
|
34819
|
+
"[erpnext_task_update] At least one field to update is required"
|
|
34820
|
+
);
|
|
34541
34821
|
}
|
|
34542
34822
|
const doc = await ctx.client.update("Task", name, data);
|
|
34543
34823
|
return {
|
|
@@ -34578,7 +34858,14 @@ var projectTools = [
|
|
|
34578
34858
|
filters.push(["status", "=", input.status]);
|
|
34579
34859
|
}
|
|
34580
34860
|
const docs = await ctx.client.list("Timesheet", {
|
|
34581
|
-
fields: [
|
|
34861
|
+
fields: [
|
|
34862
|
+
"name",
|
|
34863
|
+
"employee",
|
|
34864
|
+
"start_date",
|
|
34865
|
+
"end_date",
|
|
34866
|
+
"status",
|
|
34867
|
+
"total_hours"
|
|
34868
|
+
],
|
|
34582
34869
|
filters,
|
|
34583
34870
|
limit,
|
|
34584
34871
|
order_by: "modified desc"
|
|
@@ -34651,7 +34938,9 @@ var projectTools = [
|
|
|
34651
34938
|
if (input.expected_start_date) {
|
|
34652
34939
|
data.expected_start_date = input.expected_start_date;
|
|
34653
34940
|
}
|
|
34654
|
-
if (input.expected_end_date)
|
|
34941
|
+
if (input.expected_end_date) {
|
|
34942
|
+
data.expected_end_date = input.expected_end_date;
|
|
34943
|
+
}
|
|
34655
34944
|
if (input.estimated_costing !== void 0) {
|
|
34656
34945
|
data.estimated_costing = input.estimated_costing;
|
|
34657
34946
|
}
|
|
@@ -34678,7 +34967,10 @@ var purchasingTools = [
|
|
|
34678
34967
|
type: "object",
|
|
34679
34968
|
properties: {
|
|
34680
34969
|
limit: { type: "number", description: "Max results (default 20)" },
|
|
34681
|
-
supplier_group: {
|
|
34970
|
+
supplier_group: {
|
|
34971
|
+
type: "string",
|
|
34972
|
+
description: "Filter by supplier group"
|
|
34973
|
+
},
|
|
34682
34974
|
supplier_type: {
|
|
34683
34975
|
type: "string",
|
|
34684
34976
|
description: "Filter by supplier type (Company, Individual)"
|
|
@@ -34749,23 +35041,36 @@ var purchasingTools = [
|
|
|
34749
35041
|
inputSchema: {
|
|
34750
35042
|
type: "object",
|
|
34751
35043
|
properties: {
|
|
34752
|
-
supplier_name: {
|
|
34753
|
-
|
|
35044
|
+
supplier_name: {
|
|
35045
|
+
type: "string",
|
|
35046
|
+
description: "Supplier company or person name"
|
|
35047
|
+
},
|
|
35048
|
+
supplier_group: {
|
|
35049
|
+
type: "string",
|
|
35050
|
+
description: "Supplier Group (e.g. 'Hardware', 'Services')"
|
|
35051
|
+
},
|
|
34754
35052
|
supplier_type: {
|
|
34755
35053
|
type: "string",
|
|
34756
35054
|
description: "Company or Individual (default Company)"
|
|
34757
35055
|
},
|
|
34758
35056
|
country: { type: "string", description: "Country name" },
|
|
34759
|
-
default_currency: {
|
|
35057
|
+
default_currency: {
|
|
35058
|
+
type: "string",
|
|
35059
|
+
description: "Currency code (e.g. EUR, USD)"
|
|
35060
|
+
}
|
|
34760
35061
|
},
|
|
34761
35062
|
required: ["supplier_name", "supplier_group"]
|
|
34762
35063
|
},
|
|
34763
35064
|
handler: async (input, ctx) => {
|
|
34764
35065
|
if (!input.supplier_name) {
|
|
34765
|
-
throw new Error(
|
|
35066
|
+
throw new Error(
|
|
35067
|
+
"[erpnext_supplier_create] 'supplier_name' is required"
|
|
35068
|
+
);
|
|
34766
35069
|
}
|
|
34767
35070
|
if (!input.supplier_group) {
|
|
34768
|
-
throw new Error(
|
|
35071
|
+
throw new Error(
|
|
35072
|
+
"[erpnext_supplier_create] 'supplier_group' is required"
|
|
35073
|
+
);
|
|
34769
35074
|
}
|
|
34770
35075
|
const data = {
|
|
34771
35076
|
supplier_name: input.supplier_name,
|
|
@@ -34773,7 +35078,9 @@ var purchasingTools = [
|
|
|
34773
35078
|
supplier_type: input.supplier_type ?? "Company"
|
|
34774
35079
|
};
|
|
34775
35080
|
if (input.country) data.country = input.country;
|
|
34776
|
-
if (input.default_currency)
|
|
35081
|
+
if (input.default_currency) {
|
|
35082
|
+
data.default_currency = input.default_currency;
|
|
35083
|
+
}
|
|
34777
35084
|
const doc = await ctx.client.create("Supplier", data);
|
|
34778
35085
|
return {
|
|
34779
35086
|
data: doc,
|
|
@@ -34797,7 +35104,10 @@ var purchasingTools = [
|
|
|
34797
35104
|
type: "string",
|
|
34798
35105
|
description: "Filter by status (Draft, To Receive and Bill, To Bill, Completed, Cancelled, etc.)"
|
|
34799
35106
|
},
|
|
34800
|
-
date_from: {
|
|
35107
|
+
date_from: {
|
|
35108
|
+
type: "string",
|
|
35109
|
+
description: "Start date filter YYYY-MM-DD"
|
|
35110
|
+
},
|
|
34801
35111
|
date_to: { type: "string", description: "End date filter YYYY-MM-DD" }
|
|
34802
35112
|
}
|
|
34803
35113
|
},
|
|
@@ -34846,7 +35156,10 @@ var purchasingTools = [
|
|
|
34846
35156
|
inputSchema: {
|
|
34847
35157
|
type: "object",
|
|
34848
35158
|
properties: {
|
|
34849
|
-
name: {
|
|
35159
|
+
name: {
|
|
35160
|
+
type: "string",
|
|
35161
|
+
description: "Purchase Order name (e.g. PO-00001)"
|
|
35162
|
+
}
|
|
34850
35163
|
},
|
|
34851
35164
|
required: ["name"]
|
|
34852
35165
|
},
|
|
@@ -34888,10 +35201,14 @@ var purchasingTools = [
|
|
|
34888
35201
|
},
|
|
34889
35202
|
handler: async (input, ctx) => {
|
|
34890
35203
|
if (!input.supplier) {
|
|
34891
|
-
throw new Error(
|
|
35204
|
+
throw new Error(
|
|
35205
|
+
"[erpnext_purchase_order_create] 'supplier' is required"
|
|
35206
|
+
);
|
|
34892
35207
|
}
|
|
34893
35208
|
if (!input.items || !Array.isArray(input.items) || input.items.length === 0) {
|
|
34894
|
-
throw new Error(
|
|
35209
|
+
throw new Error(
|
|
35210
|
+
"[erpnext_purchase_order_create] 'items' must be a non-empty array"
|
|
35211
|
+
);
|
|
34895
35212
|
}
|
|
34896
35213
|
const items = input.items.map(
|
|
34897
35214
|
(item) => {
|
|
@@ -34935,7 +35252,10 @@ var purchasingTools = [
|
|
|
34935
35252
|
type: "string",
|
|
34936
35253
|
description: "Filter by status (Draft, Unpaid, Paid, Overdue, Cancelled, etc.)"
|
|
34937
35254
|
},
|
|
34938
|
-
date_from: {
|
|
35255
|
+
date_from: {
|
|
35256
|
+
type: "string",
|
|
35257
|
+
description: "Start date filter YYYY-MM-DD"
|
|
35258
|
+
},
|
|
34939
35259
|
date_to: { type: "string", description: "End date filter YYYY-MM-DD" }
|
|
34940
35260
|
}
|
|
34941
35261
|
},
|
|
@@ -34984,7 +35304,10 @@ var purchasingTools = [
|
|
|
34984
35304
|
inputSchema: {
|
|
34985
35305
|
type: "object",
|
|
34986
35306
|
properties: {
|
|
34987
|
-
name: {
|
|
35307
|
+
name: {
|
|
35308
|
+
type: "string",
|
|
35309
|
+
description: "Purchase Invoice name (e.g. PINV-00001)"
|
|
35310
|
+
}
|
|
34988
35311
|
},
|
|
34989
35312
|
required: ["name"]
|
|
34990
35313
|
},
|
|
@@ -34992,7 +35315,10 @@ var purchasingTools = [
|
|
|
34992
35315
|
if (!input.name) {
|
|
34993
35316
|
throw new Error("[erpnext_purchase_invoice_get] 'name' is required");
|
|
34994
35317
|
}
|
|
34995
|
-
const doc = await ctx.client.get(
|
|
35318
|
+
const doc = await ctx.client.get(
|
|
35319
|
+
"Purchase Invoice",
|
|
35320
|
+
input.name
|
|
35321
|
+
);
|
|
34996
35322
|
return { data: doc };
|
|
34997
35323
|
}
|
|
34998
35324
|
},
|
|
@@ -35012,7 +35338,10 @@ var purchasingTools = [
|
|
|
35012
35338
|
type: "string",
|
|
35013
35339
|
description: "Filter by status (Draft, To Bill, Completed, Cancelled, etc.)"
|
|
35014
35340
|
},
|
|
35015
|
-
date_from: {
|
|
35341
|
+
date_from: {
|
|
35342
|
+
type: "string",
|
|
35343
|
+
description: "Start date filter YYYY-MM-DD"
|
|
35344
|
+
},
|
|
35016
35345
|
date_to: { type: "string", description: "End date filter YYYY-MM-DD" }
|
|
35017
35346
|
}
|
|
35018
35347
|
},
|
|
@@ -35032,7 +35361,14 @@ var purchasingTools = [
|
|
|
35032
35361
|
filters.push(["posting_date", "<=", input.date_to]);
|
|
35033
35362
|
}
|
|
35034
35363
|
const docs = await ctx.client.list("Purchase Receipt", {
|
|
35035
|
-
fields: [
|
|
35364
|
+
fields: [
|
|
35365
|
+
"name",
|
|
35366
|
+
"supplier",
|
|
35367
|
+
"posting_date",
|
|
35368
|
+
"status",
|
|
35369
|
+
"total_qty",
|
|
35370
|
+
"grand_total"
|
|
35371
|
+
],
|
|
35036
35372
|
filters,
|
|
35037
35373
|
limit,
|
|
35038
35374
|
order_by: "modified desc"
|
|
@@ -35053,7 +35389,10 @@ var purchasingTools = [
|
|
|
35053
35389
|
inputSchema: {
|
|
35054
35390
|
type: "object",
|
|
35055
35391
|
properties: {
|
|
35056
|
-
name: {
|
|
35392
|
+
name: {
|
|
35393
|
+
type: "string",
|
|
35394
|
+
description: "Purchase Receipt name (e.g. MAT-PRE-00001)"
|
|
35395
|
+
}
|
|
35057
35396
|
},
|
|
35058
35397
|
required: ["name"]
|
|
35059
35398
|
},
|
|
@@ -35061,7 +35400,10 @@ var purchasingTools = [
|
|
|
35061
35400
|
if (!input.name) {
|
|
35062
35401
|
throw new Error("[erpnext_purchase_receipt_get] 'name' is required");
|
|
35063
35402
|
}
|
|
35064
|
-
const doc = await ctx.client.get(
|
|
35403
|
+
const doc = await ctx.client.get(
|
|
35404
|
+
"Purchase Receipt",
|
|
35405
|
+
input.name
|
|
35406
|
+
);
|
|
35065
35407
|
return { data: doc };
|
|
35066
35408
|
}
|
|
35067
35409
|
},
|
|
@@ -35093,7 +35435,13 @@ var purchasingTools = [
|
|
|
35093
35435
|
filters.push(["status", "=", input.status]);
|
|
35094
35436
|
}
|
|
35095
35437
|
const docs = await ctx.client.list("Supplier Quotation", {
|
|
35096
|
-
fields: [
|
|
35438
|
+
fields: [
|
|
35439
|
+
"name",
|
|
35440
|
+
"supplier",
|
|
35441
|
+
"transaction_date",
|
|
35442
|
+
"status",
|
|
35443
|
+
"grand_total"
|
|
35444
|
+
],
|
|
35097
35445
|
filters,
|
|
35098
35446
|
limit,
|
|
35099
35447
|
order_by: "modified desc"
|
|
@@ -35126,7 +35474,10 @@ var deliveryTools = [
|
|
|
35126
35474
|
type: "string",
|
|
35127
35475
|
description: "Filter by status (Draft, To Bill, Completed, Cancelled, etc.)"
|
|
35128
35476
|
},
|
|
35129
|
-
date_from: {
|
|
35477
|
+
date_from: {
|
|
35478
|
+
type: "string",
|
|
35479
|
+
description: "Start date filter YYYY-MM-DD"
|
|
35480
|
+
},
|
|
35130
35481
|
date_to: { type: "string", description: "End date filter YYYY-MM-DD" }
|
|
35131
35482
|
}
|
|
35132
35483
|
},
|
|
@@ -35146,7 +35497,14 @@ var deliveryTools = [
|
|
|
35146
35497
|
filters.push(["posting_date", "<=", input.date_to]);
|
|
35147
35498
|
}
|
|
35148
35499
|
const docs = await ctx.client.list("Delivery Note", {
|
|
35149
|
-
fields: [
|
|
35500
|
+
fields: [
|
|
35501
|
+
"name",
|
|
35502
|
+
"customer",
|
|
35503
|
+
"posting_date",
|
|
35504
|
+
"status",
|
|
35505
|
+
"total_qty",
|
|
35506
|
+
"grand_total"
|
|
35507
|
+
],
|
|
35150
35508
|
filters,
|
|
35151
35509
|
limit,
|
|
35152
35510
|
order_by: "modified desc"
|
|
@@ -35167,7 +35525,10 @@ var deliveryTools = [
|
|
|
35167
35525
|
inputSchema: {
|
|
35168
35526
|
type: "object",
|
|
35169
35527
|
properties: {
|
|
35170
|
-
name: {
|
|
35528
|
+
name: {
|
|
35529
|
+
type: "string",
|
|
35530
|
+
description: "Delivery Note name (e.g. MAT-DN-00001)"
|
|
35531
|
+
}
|
|
35171
35532
|
},
|
|
35172
35533
|
required: ["name"]
|
|
35173
35534
|
},
|
|
@@ -35212,10 +35573,14 @@ var deliveryTools = [
|
|
|
35212
35573
|
},
|
|
35213
35574
|
handler: async (input, ctx) => {
|
|
35214
35575
|
if (!input.customer) {
|
|
35215
|
-
throw new Error(
|
|
35576
|
+
throw new Error(
|
|
35577
|
+
"[erpnext_delivery_note_create] 'customer' is required"
|
|
35578
|
+
);
|
|
35216
35579
|
}
|
|
35217
35580
|
if (!input.items || !Array.isArray(input.items) || input.items.length === 0) {
|
|
35218
|
-
throw new Error(
|
|
35581
|
+
throw new Error(
|
|
35582
|
+
"[erpnext_delivery_note_create] 'items' must be a non-empty array"
|
|
35583
|
+
);
|
|
35219
35584
|
}
|
|
35220
35585
|
const items = input.items.map((item) => {
|
|
35221
35586
|
if (!item.item_code || item.qty == null) {
|
|
@@ -35256,8 +35621,14 @@ var deliveryTools = [
|
|
|
35256
35621
|
description: "Filter by status (Draft, Submitted, Booked, Delivered, Cancelled, etc.)"
|
|
35257
35622
|
},
|
|
35258
35623
|
carrier: { type: "string", description: "Filter by carrier name" },
|
|
35259
|
-
date_from: {
|
|
35260
|
-
|
|
35624
|
+
date_from: {
|
|
35625
|
+
type: "string",
|
|
35626
|
+
description: "Pickup date start filter YYYY-MM-DD"
|
|
35627
|
+
},
|
|
35628
|
+
date_to: {
|
|
35629
|
+
type: "string",
|
|
35630
|
+
description: "Pickup date end filter YYYY-MM-DD"
|
|
35631
|
+
}
|
|
35261
35632
|
}
|
|
35262
35633
|
},
|
|
35263
35634
|
handler: async (input, ctx) => {
|
|
@@ -35331,7 +35702,10 @@ var manufacturingTools = [
|
|
|
35331
35702
|
type: "object",
|
|
35332
35703
|
properties: {
|
|
35333
35704
|
limit: { type: "number", description: "Max results (default 20)" },
|
|
35334
|
-
item: {
|
|
35705
|
+
item: {
|
|
35706
|
+
type: "string",
|
|
35707
|
+
description: "Filter by finished goods item code"
|
|
35708
|
+
},
|
|
35335
35709
|
is_active: {
|
|
35336
35710
|
type: "boolean",
|
|
35337
35711
|
description: "Filter by active status (default: all)"
|
|
@@ -35352,7 +35726,11 @@ var manufacturingTools = [
|
|
|
35352
35726
|
filters.push(["is_active", "=", input.is_active ? 1 : 0]);
|
|
35353
35727
|
}
|
|
35354
35728
|
if (input.is_default !== void 0) {
|
|
35355
|
-
filters.push([
|
|
35729
|
+
filters.push([
|
|
35730
|
+
"is_default",
|
|
35731
|
+
"=",
|
|
35732
|
+
input.is_default ? 1 : 0
|
|
35733
|
+
]);
|
|
35356
35734
|
}
|
|
35357
35735
|
const docs = await ctx.client.list("BOM", {
|
|
35358
35736
|
fields: [
|
|
@@ -35408,13 +35786,22 @@ var manufacturingTools = [
|
|
|
35408
35786
|
type: "object",
|
|
35409
35787
|
properties: {
|
|
35410
35788
|
limit: { type: "number", description: "Max results (default 20)" },
|
|
35411
|
-
production_item: {
|
|
35789
|
+
production_item: {
|
|
35790
|
+
type: "string",
|
|
35791
|
+
description: "Filter by item being produced"
|
|
35792
|
+
},
|
|
35412
35793
|
status: {
|
|
35413
35794
|
type: "string",
|
|
35414
35795
|
description: "Filter by status (Draft, Submitted, Not Started, In Process, Completed, Stopped, etc.)"
|
|
35415
35796
|
},
|
|
35416
|
-
date_from: {
|
|
35417
|
-
|
|
35797
|
+
date_from: {
|
|
35798
|
+
type: "string",
|
|
35799
|
+
description: "Planned start date from YYYY-MM-DD"
|
|
35800
|
+
},
|
|
35801
|
+
date_to: {
|
|
35802
|
+
type: "string",
|
|
35803
|
+
description: "Planned start date to YYYY-MM-DD"
|
|
35804
|
+
}
|
|
35418
35805
|
}
|
|
35419
35806
|
},
|
|
35420
35807
|
handler: async (input, ctx) => {
|
|
@@ -35462,7 +35849,10 @@ var manufacturingTools = [
|
|
|
35462
35849
|
inputSchema: {
|
|
35463
35850
|
type: "object",
|
|
35464
35851
|
properties: {
|
|
35465
|
-
name: {
|
|
35852
|
+
name: {
|
|
35853
|
+
type: "string",
|
|
35854
|
+
description: "Work Order name (e.g. MFG-WO-00001)"
|
|
35855
|
+
}
|
|
35466
35856
|
},
|
|
35467
35857
|
required: ["name"]
|
|
35468
35858
|
},
|
|
@@ -35481,8 +35871,14 @@ var manufacturingTools = [
|
|
|
35481
35871
|
inputSchema: {
|
|
35482
35872
|
type: "object",
|
|
35483
35873
|
properties: {
|
|
35484
|
-
production_item: {
|
|
35485
|
-
|
|
35874
|
+
production_item: {
|
|
35875
|
+
type: "string",
|
|
35876
|
+
description: "Item code of the item to produce"
|
|
35877
|
+
},
|
|
35878
|
+
bom_no: {
|
|
35879
|
+
type: "string",
|
|
35880
|
+
description: "BOM to use (e.g. BOM-ITEM-00001)"
|
|
35881
|
+
},
|
|
35486
35882
|
qty: { type: "number", description: "Quantity to produce" },
|
|
35487
35883
|
planned_start_date: {
|
|
35488
35884
|
type: "string",
|
|
@@ -35501,7 +35897,9 @@ var manufacturingTools = [
|
|
|
35501
35897
|
},
|
|
35502
35898
|
handler: async (input, ctx) => {
|
|
35503
35899
|
if (!input.production_item) {
|
|
35504
|
-
throw new Error(
|
|
35900
|
+
throw new Error(
|
|
35901
|
+
"[erpnext_work_order_create] 'production_item' is required"
|
|
35902
|
+
);
|
|
35505
35903
|
}
|
|
35506
35904
|
if (!input.bom_no) {
|
|
35507
35905
|
throw new Error("[erpnext_work_order_create] 'bom_no' is required");
|
|
@@ -35615,7 +36013,10 @@ var crmTools = [
|
|
|
35615
36013
|
type: "string",
|
|
35616
36014
|
description: "Filter by status (Open, Replied, Opportunity, Interested, Converted, Do Not Contact)"
|
|
35617
36015
|
},
|
|
35618
|
-
lead_owner: {
|
|
36016
|
+
lead_owner: {
|
|
36017
|
+
type: "string",
|
|
36018
|
+
description: "Filter by assigned sales rep (user)"
|
|
36019
|
+
}
|
|
35619
36020
|
}
|
|
35620
36021
|
},
|
|
35621
36022
|
handler: async (input, ctx) => {
|
|
@@ -35676,7 +36077,10 @@ var crmTools = [
|
|
|
35676
36077
|
inputSchema: {
|
|
35677
36078
|
type: "object",
|
|
35678
36079
|
properties: {
|
|
35679
|
-
lead_name: {
|
|
36080
|
+
lead_name: {
|
|
36081
|
+
type: "string",
|
|
36082
|
+
description: "Full name of the lead contact"
|
|
36083
|
+
},
|
|
35680
36084
|
company_name: { type: "string", description: "Company name" },
|
|
35681
36085
|
email_id: { type: "string", description: "Email address" },
|
|
35682
36086
|
mobile_no: { type: "string", description: "Mobile number" },
|
|
@@ -35684,7 +36088,10 @@ var crmTools = [
|
|
|
35684
36088
|
type: "string",
|
|
35685
36089
|
description: "Lead source (Cold Calling, Website, Advertisement, etc.)"
|
|
35686
36090
|
},
|
|
35687
|
-
lead_owner: {
|
|
36091
|
+
lead_owner: {
|
|
36092
|
+
type: "string",
|
|
36093
|
+
description: "Assigned sales rep (ERPNext user)"
|
|
36094
|
+
}
|
|
35688
36095
|
},
|
|
35689
36096
|
required: ["lead_name"]
|
|
35690
36097
|
},
|
|
@@ -35725,7 +36132,10 @@ var crmTools = [
|
|
|
35725
36132
|
type: "string",
|
|
35726
36133
|
description: "Filter by assigned sales rep (user)"
|
|
35727
36134
|
},
|
|
35728
|
-
party_name: {
|
|
36135
|
+
party_name: {
|
|
36136
|
+
type: "string",
|
|
36137
|
+
description: "Filter by customer or lead name"
|
|
36138
|
+
}
|
|
35729
36139
|
}
|
|
35730
36140
|
},
|
|
35731
36141
|
handler: async (input, ctx) => {
|
|
@@ -35735,7 +36145,11 @@ var crmTools = [
|
|
|
35735
36145
|
filters.push(["status", "=", input.status]);
|
|
35736
36146
|
}
|
|
35737
36147
|
if (input.opportunity_owner) {
|
|
35738
|
-
filters.push([
|
|
36148
|
+
filters.push([
|
|
36149
|
+
"opportunity_owner",
|
|
36150
|
+
"=",
|
|
36151
|
+
input.opportunity_owner
|
|
36152
|
+
]);
|
|
35739
36153
|
}
|
|
35740
36154
|
if (input.party_name) {
|
|
35741
36155
|
filters.push(["party_name", "=", input.party_name]);
|
|
@@ -35863,7 +36277,10 @@ var crmTools = [
|
|
|
35863
36277
|
type: "object",
|
|
35864
36278
|
properties: {
|
|
35865
36279
|
limit: { type: "number", description: "Max results (default 20)" },
|
|
35866
|
-
campaign_type: {
|
|
36280
|
+
campaign_type: {
|
|
36281
|
+
type: "string",
|
|
36282
|
+
description: "Filter by campaign type"
|
|
36283
|
+
}
|
|
35867
36284
|
}
|
|
35868
36285
|
},
|
|
35869
36286
|
handler: async (input, ctx) => {
|
|
@@ -35912,9 +36329,15 @@ var assetsTools = [
|
|
|
35912
36329
|
type: "string",
|
|
35913
36330
|
description: "Filter by status (Draft, Submitted, Partially Depreciated, Fully Depreciated, Scrapped, Sold)"
|
|
35914
36331
|
},
|
|
35915
|
-
asset_category: {
|
|
36332
|
+
asset_category: {
|
|
36333
|
+
type: "string",
|
|
36334
|
+
description: "Filter by asset category"
|
|
36335
|
+
},
|
|
35916
36336
|
location: { type: "string", description: "Filter by location" },
|
|
35917
|
-
custodian: {
|
|
36337
|
+
custodian: {
|
|
36338
|
+
type: "string",
|
|
36339
|
+
description: "Filter by custodian (employee)"
|
|
36340
|
+
}
|
|
35918
36341
|
}
|
|
35919
36342
|
},
|
|
35920
36343
|
handler: async (input, ctx) => {
|
|
@@ -35983,16 +36406,43 @@ var assetsTools = [
|
|
|
35983
36406
|
inputSchema: {
|
|
35984
36407
|
type: "object",
|
|
35985
36408
|
properties: {
|
|
35986
|
-
asset_name: {
|
|
35987
|
-
|
|
36409
|
+
asset_name: {
|
|
36410
|
+
type: "string",
|
|
36411
|
+
description: "Name/description of the asset"
|
|
36412
|
+
},
|
|
36413
|
+
asset_category: {
|
|
36414
|
+
type: "string",
|
|
36415
|
+
description: "Asset category (e.g. Computers, Vehicles)"
|
|
36416
|
+
},
|
|
35988
36417
|
company: { type: "string", description: "Company owning the asset" },
|
|
35989
|
-
purchase_date: {
|
|
35990
|
-
|
|
35991
|
-
|
|
35992
|
-
|
|
35993
|
-
|
|
36418
|
+
purchase_date: {
|
|
36419
|
+
type: "string",
|
|
36420
|
+
description: "Purchase date YYYY-MM-DD"
|
|
36421
|
+
},
|
|
36422
|
+
gross_purchase_amount: {
|
|
36423
|
+
type: "number",
|
|
36424
|
+
description: "Purchase cost (before depreciation)"
|
|
36425
|
+
},
|
|
36426
|
+
item_code: {
|
|
36427
|
+
type: "string",
|
|
36428
|
+
description: "Linked item code (optional)"
|
|
36429
|
+
},
|
|
36430
|
+
location: {
|
|
36431
|
+
type: "string",
|
|
36432
|
+
description: "Physical location of the asset"
|
|
36433
|
+
},
|
|
36434
|
+
custodian: {
|
|
36435
|
+
type: "string",
|
|
36436
|
+
description: "Employee responsible for the asset"
|
|
36437
|
+
}
|
|
35994
36438
|
},
|
|
35995
|
-
required: [
|
|
36439
|
+
required: [
|
|
36440
|
+
"asset_name",
|
|
36441
|
+
"asset_category",
|
|
36442
|
+
"company",
|
|
36443
|
+
"purchase_date",
|
|
36444
|
+
"gross_purchase_amount"
|
|
36445
|
+
]
|
|
35996
36446
|
},
|
|
35997
36447
|
handler: async (input, ctx) => {
|
|
35998
36448
|
if (!input.asset_name) {
|
|
@@ -36008,7 +36458,9 @@ var assetsTools = [
|
|
|
36008
36458
|
throw new Error("[erpnext_asset_create] 'purchase_date' is required");
|
|
36009
36459
|
}
|
|
36010
36460
|
if (input.gross_purchase_amount == null) {
|
|
36011
|
-
throw new Error(
|
|
36461
|
+
throw new Error(
|
|
36462
|
+
"[erpnext_asset_create] 'gross_purchase_amount' is required"
|
|
36463
|
+
);
|
|
36012
36464
|
}
|
|
36013
36465
|
const doc = await ctx.client.create("Asset", {
|
|
36014
36466
|
asset_name: input.asset_name,
|
|
@@ -36041,8 +36493,14 @@ var assetsTools = [
|
|
|
36041
36493
|
type: "string",
|
|
36042
36494
|
description: "Filter by purpose (Issue, Transfer, Receipt)"
|
|
36043
36495
|
},
|
|
36044
|
-
date_from: {
|
|
36045
|
-
|
|
36496
|
+
date_from: {
|
|
36497
|
+
type: "string",
|
|
36498
|
+
description: "Transaction date from YYYY-MM-DD"
|
|
36499
|
+
},
|
|
36500
|
+
date_to: {
|
|
36501
|
+
type: "string",
|
|
36502
|
+
description: "Transaction date to YYYY-MM-DD"
|
|
36503
|
+
}
|
|
36046
36504
|
}
|
|
36047
36505
|
},
|
|
36048
36506
|
handler: async (input, ctx) => {
|
|
@@ -36116,7 +36574,11 @@ var assetsTools = [
|
|
|
36116
36574
|
filters.push(["asset_name", "=", input.asset_name]);
|
|
36117
36575
|
}
|
|
36118
36576
|
if (input.maintenance_status) {
|
|
36119
|
-
filters.push([
|
|
36577
|
+
filters.push([
|
|
36578
|
+
"maintenance_status",
|
|
36579
|
+
"=",
|
|
36580
|
+
input.maintenance_status
|
|
36581
|
+
]);
|
|
36120
36582
|
}
|
|
36121
36583
|
const docs = await ctx.client.list("Asset Maintenance", {
|
|
36122
36584
|
fields: [
|
|
@@ -36154,7 +36616,10 @@ var assetsTools = [
|
|
|
36154
36616
|
if (!input.name) {
|
|
36155
36617
|
throw new Error("[erpnext_asset_maintenance_get] 'name' is required");
|
|
36156
36618
|
}
|
|
36157
|
-
const doc = await ctx.client.get(
|
|
36619
|
+
const doc = await ctx.client.get(
|
|
36620
|
+
"Asset Maintenance",
|
|
36621
|
+
input.name
|
|
36622
|
+
);
|
|
36158
36623
|
return { data: doc };
|
|
36159
36624
|
}
|
|
36160
36625
|
},
|
|
@@ -36216,7 +36681,9 @@ var operationsTools = [
|
|
|
36216
36681
|
throw new Error("[erpnext_doc_create] 'doctype' is required");
|
|
36217
36682
|
}
|
|
36218
36683
|
if (!input.data || typeof input.data !== "object") {
|
|
36219
|
-
throw new Error(
|
|
36684
|
+
throw new Error(
|
|
36685
|
+
"[erpnext_doc_create] 'data' must be an object with document fields"
|
|
36686
|
+
);
|
|
36220
36687
|
}
|
|
36221
36688
|
const doc = await ctx.client.create(
|
|
36222
36689
|
input.doctype,
|
|
@@ -36260,7 +36727,9 @@ var operationsTools = [
|
|
|
36260
36727
|
throw new Error("[erpnext_doc_update] 'name' is required");
|
|
36261
36728
|
}
|
|
36262
36729
|
if (!input.data || typeof input.data !== "object") {
|
|
36263
|
-
throw new Error(
|
|
36730
|
+
throw new Error(
|
|
36731
|
+
"[erpnext_doc_update] 'data' must be an object with fields to update"
|
|
36732
|
+
);
|
|
36264
36733
|
}
|
|
36265
36734
|
const doc = await ctx.client.update(
|
|
36266
36735
|
input.doctype,
|
|
@@ -36336,7 +36805,10 @@ var operationsTools = [
|
|
|
36336
36805
|
if (!input.name) {
|
|
36337
36806
|
throw new Error("[erpnext_doc_submit] 'name' is required");
|
|
36338
36807
|
}
|
|
36339
|
-
const doc = await ctx.client.get(
|
|
36808
|
+
const doc = await ctx.client.get(
|
|
36809
|
+
input.doctype,
|
|
36810
|
+
input.name
|
|
36811
|
+
);
|
|
36340
36812
|
const result = await ctx.client.callMethod("frappe.client.submit", {
|
|
36341
36813
|
doc: { ...doc, doctype: input.doctype }
|
|
36342
36814
|
});
|
|
@@ -36414,7 +36886,10 @@ var operationsTools = [
|
|
|
36414
36886
|
if (!input.name) {
|
|
36415
36887
|
throw new Error("[erpnext_doc_get] 'name' is required");
|
|
36416
36888
|
}
|
|
36417
|
-
const doc = await ctx.client.get(
|
|
36889
|
+
const doc = await ctx.client.get(
|
|
36890
|
+
input.doctype,
|
|
36891
|
+
input.name
|
|
36892
|
+
);
|
|
36418
36893
|
return { data: doc };
|
|
36419
36894
|
}
|
|
36420
36895
|
},
|
|
@@ -36515,9 +36990,18 @@ var setupTools = [
|
|
|
36515
36990
|
type: "object",
|
|
36516
36991
|
properties: {
|
|
36517
36992
|
company_name: { type: "string", description: "Company name" },
|
|
36518
|
-
abbr: {
|
|
36519
|
-
|
|
36520
|
-
|
|
36993
|
+
abbr: {
|
|
36994
|
+
type: "string",
|
|
36995
|
+
description: "Abbreviation (e.g. CI for Casys Industries)"
|
|
36996
|
+
},
|
|
36997
|
+
default_currency: {
|
|
36998
|
+
type: "string",
|
|
36999
|
+
description: "Currency code (e.g. EUR, USD)"
|
|
37000
|
+
},
|
|
37001
|
+
country: {
|
|
37002
|
+
type: "string",
|
|
37003
|
+
description: "Country name (e.g. France, United States)"
|
|
37004
|
+
},
|
|
36521
37005
|
domain: {
|
|
36522
37006
|
type: "string",
|
|
36523
37007
|
description: "Business domain (Manufacturing, Services, Retail, Distribution, Education, etc.)"
|
|
@@ -36533,7 +37017,9 @@ var setupTools = [
|
|
|
36533
37017
|
throw new Error("[erpnext_company_create] 'abbr' is required");
|
|
36534
37018
|
}
|
|
36535
37019
|
if (!input.default_currency) {
|
|
36536
|
-
throw new Error(
|
|
37020
|
+
throw new Error(
|
|
37021
|
+
"[erpnext_company_create] 'default_currency' is required"
|
|
37022
|
+
);
|
|
36537
37023
|
}
|
|
36538
37024
|
if (!input.country) {
|
|
36539
37025
|
throw new Error("[erpnext_company_create] 'country' is required");
|
|
@@ -36568,20 +37054,34 @@ var analyticsTools = [
|
|
|
36568
37054
|
properties: {
|
|
36569
37055
|
warehouse: { type: "string", description: "Filter by warehouse name" },
|
|
36570
37056
|
item_group: { type: "string", description: "Filter by item group" },
|
|
36571
|
-
limit: {
|
|
37057
|
+
limit: {
|
|
37058
|
+
type: "number",
|
|
37059
|
+
description: "Max items to show (default 20)"
|
|
37060
|
+
},
|
|
36572
37061
|
type: {
|
|
36573
37062
|
type: "string",
|
|
36574
37063
|
enum: ["bar", "horizontal-bar"],
|
|
36575
37064
|
description: "Chart type (default: horizontal-bar for many items, bar for few)"
|
|
36576
37065
|
},
|
|
36577
|
-
min_qty: {
|
|
37066
|
+
min_qty: {
|
|
37067
|
+
type: "number",
|
|
37068
|
+
description: "Only show items with qty >= this value (filters out zeros)"
|
|
37069
|
+
}
|
|
36578
37070
|
}
|
|
36579
37071
|
},
|
|
36580
37072
|
handler: async (input, ctx) => {
|
|
36581
37073
|
const limit = input.limit ?? 20;
|
|
36582
|
-
const filters = [[
|
|
36583
|
-
|
|
36584
|
-
|
|
37074
|
+
const filters = [[
|
|
37075
|
+
"actual_qty",
|
|
37076
|
+
">",
|
|
37077
|
+
input.min_qty ?? 0
|
|
37078
|
+
]];
|
|
37079
|
+
if (input.warehouse) {
|
|
37080
|
+
filters.push(["warehouse", "=", input.warehouse]);
|
|
37081
|
+
}
|
|
37082
|
+
if (input.item_group) {
|
|
37083
|
+
filters.push(["item_group", "=", input.item_group]);
|
|
37084
|
+
}
|
|
36585
37085
|
const bins = await ctx.client.list("Bin", {
|
|
36586
37086
|
fields: ["item_code", "warehouse", "actual_qty", "stock_value"],
|
|
36587
37087
|
filters,
|
|
@@ -36632,7 +37132,10 @@ var analyticsTools = [
|
|
|
36632
37132
|
description: "Dimension to group by (default: customer)"
|
|
36633
37133
|
},
|
|
36634
37134
|
limit: { type: "number", description: "Top N results (default 10)" },
|
|
36635
|
-
include_drafts: {
|
|
37135
|
+
include_drafts: {
|
|
37136
|
+
type: "boolean",
|
|
37137
|
+
description: "Include Draft invoices (default false)"
|
|
37138
|
+
}
|
|
36636
37139
|
}
|
|
36637
37140
|
},
|
|
36638
37141
|
handler: async (input, ctx) => {
|
|
@@ -36676,7 +37179,12 @@ var analyticsTools = [
|
|
|
36676
37179
|
const byItem = {};
|
|
36677
37180
|
for (const row of items) {
|
|
36678
37181
|
const code = row.item_code ?? "Unknown";
|
|
36679
|
-
if (!byItem[code])
|
|
37182
|
+
if (!byItem[code]) {
|
|
37183
|
+
byItem[code] = {
|
|
37184
|
+
name: row.item_name ?? code,
|
|
37185
|
+
total: 0
|
|
37186
|
+
};
|
|
37187
|
+
}
|
|
36680
37188
|
byItem[code].total += Number(row.amount) || 0;
|
|
36681
37189
|
}
|
|
36682
37190
|
const sorted2 = Object.entries(byItem).sort(([, a], [, b]) => b.total - a.total).slice(0, limit);
|
|
@@ -36685,7 +37193,11 @@ var analyticsTools = [
|
|
|
36685
37193
|
subtitle: `Top ${sorted2.length} items`,
|
|
36686
37194
|
type: "horizontal-bar",
|
|
36687
37195
|
labels: sorted2.map(([, { name }]) => name),
|
|
36688
|
-
datasets: [{
|
|
37196
|
+
datasets: [{
|
|
37197
|
+
label: "Revenue",
|
|
37198
|
+
values: sorted2.map(([, { total }]) => total),
|
|
37199
|
+
color: "#c084fc"
|
|
37200
|
+
}],
|
|
36689
37201
|
currency: "EUR",
|
|
36690
37202
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
36691
37203
|
_meta: CHART_META
|
|
@@ -36700,7 +37212,12 @@ var analyticsTools = [
|
|
|
36700
37212
|
const byCustomer = {};
|
|
36701
37213
|
for (const inv of invoices) {
|
|
36702
37214
|
const code = inv.customer ?? "Unknown";
|
|
36703
|
-
if (!byCustomer[code])
|
|
37215
|
+
if (!byCustomer[code]) {
|
|
37216
|
+
byCustomer[code] = {
|
|
37217
|
+
name: inv.customer_name ?? code,
|
|
37218
|
+
total: 0
|
|
37219
|
+
};
|
|
37220
|
+
}
|
|
36704
37221
|
byCustomer[code].total += Number(inv.grand_total) || 0;
|
|
36705
37222
|
}
|
|
36706
37223
|
const sorted = Object.entries(byCustomer).sort(([, a], [, b]) => b.total - a.total).slice(0, limit);
|
|
@@ -36709,7 +37226,11 @@ var analyticsTools = [
|
|
|
36709
37226
|
subtitle: `Top ${sorted.length} customers`,
|
|
36710
37227
|
type: "horizontal-bar",
|
|
36711
37228
|
labels: sorted.map(([, { name }]) => name),
|
|
36712
|
-
datasets: [{
|
|
37229
|
+
datasets: [{
|
|
37230
|
+
label: "Revenue",
|
|
37231
|
+
values: sorted.map(([, { total }]) => total),
|
|
37232
|
+
color: "#4ade80"
|
|
37233
|
+
}],
|
|
36713
37234
|
currency: "EUR",
|
|
36714
37235
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
36715
37236
|
_meta: CHART_META
|
|
@@ -36726,7 +37247,10 @@ var analyticsTools = [
|
|
|
36726
37247
|
inputSchema: {
|
|
36727
37248
|
type: "object",
|
|
36728
37249
|
properties: {
|
|
36729
|
-
months: {
|
|
37250
|
+
months: {
|
|
37251
|
+
type: "number",
|
|
37252
|
+
description: "How many months back to include (default 6)"
|
|
37253
|
+
},
|
|
36730
37254
|
type: {
|
|
36731
37255
|
type: "string",
|
|
36732
37256
|
enum: ["line", "area", "stacked-area"],
|
|
@@ -36744,7 +37268,11 @@ var analyticsTools = [
|
|
|
36744
37268
|
const chartType = input.type ?? "line";
|
|
36745
37269
|
const groupBy = input.group_by ?? "total";
|
|
36746
37270
|
const now = /* @__PURE__ */ new Date();
|
|
36747
|
-
const startDate = new Date(
|
|
37271
|
+
const startDate = new Date(
|
|
37272
|
+
now.getFullYear(),
|
|
37273
|
+
now.getMonth() - monthsBack + 1,
|
|
37274
|
+
1
|
|
37275
|
+
);
|
|
36748
37276
|
const startStr = startDate.toISOString().split("T")[0];
|
|
36749
37277
|
const orders = await ctx.client.list("Sales Order", {
|
|
36750
37278
|
fields: ["customer_name", "grand_total", "transaction_date"],
|
|
@@ -36754,8 +37282,14 @@ var analyticsTools = [
|
|
|
36754
37282
|
});
|
|
36755
37283
|
const months = [];
|
|
36756
37284
|
for (let m = 0; m < monthsBack; m++) {
|
|
36757
|
-
const d = new Date(
|
|
36758
|
-
|
|
37285
|
+
const d = new Date(
|
|
37286
|
+
now.getFullYear(),
|
|
37287
|
+
now.getMonth() - monthsBack + 1 + m,
|
|
37288
|
+
1
|
|
37289
|
+
);
|
|
37290
|
+
months.push(
|
|
37291
|
+
`${d.toLocaleString("en", { month: "short" })} ${d.getFullYear().toString().slice(2)}`
|
|
37292
|
+
);
|
|
36759
37293
|
}
|
|
36760
37294
|
if (groupBy === "customer") {
|
|
36761
37295
|
const byCustomerMonth = {};
|
|
@@ -36764,10 +37298,14 @@ var analyticsTools = [
|
|
|
36764
37298
|
const mIdx = (d.getFullYear() - startDate.getFullYear()) * 12 + d.getMonth() - startDate.getMonth();
|
|
36765
37299
|
if (mIdx < 0 || mIdx >= monthsBack) continue;
|
|
36766
37300
|
const cust = order.customer_name ?? "Unknown";
|
|
36767
|
-
if (!byCustomerMonth[cust])
|
|
37301
|
+
if (!byCustomerMonth[cust]) {
|
|
37302
|
+
byCustomerMonth[cust] = new Array(monthsBack).fill(0);
|
|
37303
|
+
}
|
|
36768
37304
|
byCustomerMonth[cust][mIdx] += Number(order.grand_total) || 0;
|
|
36769
37305
|
}
|
|
36770
|
-
const sorted = Object.entries(byCustomerMonth).sort(
|
|
37306
|
+
const sorted = Object.entries(byCustomerMonth).sort(
|
|
37307
|
+
([, a], [, b]) => b.reduce((s, v) => s + v, 0) - a.reduce((s, v) => s + v, 0)
|
|
37308
|
+
).slice(0, 5);
|
|
36771
37309
|
const COLORS = ["#60a5fa", "#4ade80", "#fbbf24", "#c084fc", "#f472b6"];
|
|
36772
37310
|
return {
|
|
36773
37311
|
title: "Revenue by Customer",
|
|
@@ -36854,7 +37392,13 @@ var analyticsTools = [
|
|
|
36854
37392
|
_meta: CHART_META
|
|
36855
37393
|
};
|
|
36856
37394
|
}
|
|
36857
|
-
const STATUS_ORDER = [
|
|
37395
|
+
const STATUS_ORDER = [
|
|
37396
|
+
"Draft",
|
|
37397
|
+
"To Deliver and Bill",
|
|
37398
|
+
"To Bill",
|
|
37399
|
+
"Completed",
|
|
37400
|
+
"Cancelled"
|
|
37401
|
+
];
|
|
36858
37402
|
const STATUS_COLORS = {
|
|
36859
37403
|
Draft: "#78716c",
|
|
36860
37404
|
"To Deliver and Bill": "#60a5fa",
|
|
@@ -36869,7 +37413,10 @@ var analyticsTools = [
|
|
|
36869
37413
|
if (!byCustomerStatus[c]) byCustomerStatus[c] = {};
|
|
36870
37414
|
byCustomerStatus[c][s] = (byCustomerStatus[c][s] ?? 0) + (Number(o.grand_total) || 0);
|
|
36871
37415
|
}
|
|
36872
|
-
const customerTotals = Object.entries(byCustomerStatus).map(([c, statuses]) => ({
|
|
37416
|
+
const customerTotals = Object.entries(byCustomerStatus).map(([c, statuses]) => ({
|
|
37417
|
+
name: c,
|
|
37418
|
+
total: Object.values(statuses).reduce((s, v) => s + v, 0)
|
|
37419
|
+
})).sort((a, b) => b.total - a.total).slice(0, limit);
|
|
36873
37420
|
const customers = customerTotals.map((c) => c.name);
|
|
36874
37421
|
const activeStatuses = STATUS_ORDER.filter(
|
|
36875
37422
|
(s) => customers.some((c) => (byCustomerStatus[c]?.[s] ?? 0) > 0)
|
|
@@ -36982,7 +37529,20 @@ var analyticsTools = [
|
|
|
36982
37529
|
grouped[key] = (grouped[key] ?? 0) + (Number(bin.stock_value) || 0);
|
|
36983
37530
|
}
|
|
36984
37531
|
const sorted = Object.entries(grouped).sort(([, a], [, b]) => b - a).slice(0, limit);
|
|
36985
|
-
const COLORS = [
|
|
37532
|
+
const COLORS = [
|
|
37533
|
+
"#60a5fa",
|
|
37534
|
+
"#4ade80",
|
|
37535
|
+
"#fbbf24",
|
|
37536
|
+
"#818cf8",
|
|
37537
|
+
"#c084fc",
|
|
37538
|
+
"#fb923c",
|
|
37539
|
+
"#34d399",
|
|
37540
|
+
"#f472b6",
|
|
37541
|
+
"#a78bfa",
|
|
37542
|
+
"#f97316",
|
|
37543
|
+
"#22d3ee",
|
|
37544
|
+
"#e879f9"
|
|
37545
|
+
];
|
|
36986
37546
|
return {
|
|
36987
37547
|
title: `Stock Value by ${groupBy === "warehouse" ? "Warehouse" : "Item"}`,
|
|
36988
37548
|
type: "treemap",
|
|
@@ -37043,8 +37603,14 @@ var analyticsTools = [
|
|
|
37043
37603
|
filters: [["item_code", "=", code]],
|
|
37044
37604
|
limit: 100
|
|
37045
37605
|
});
|
|
37046
|
-
const totalQty = bins.reduce(
|
|
37047
|
-
|
|
37606
|
+
const totalQty = bins.reduce(
|
|
37607
|
+
(s, b) => s + (Number(b.actual_qty) || 0),
|
|
37608
|
+
0
|
|
37609
|
+
);
|
|
37610
|
+
const totalVal = bins.reduce(
|
|
37611
|
+
(s, b) => s + (Number(b.stock_value) || 0),
|
|
37612
|
+
0
|
|
37613
|
+
);
|
|
37048
37614
|
raw2[code] = [totalQty, totalVal, 0, 0];
|
|
37049
37615
|
}
|
|
37050
37616
|
const soItems = await ctx.client.list("Sales Order Item", {
|
|
@@ -37071,7 +37637,9 @@ var analyticsTools = [
|
|
|
37071
37637
|
labels: dimensions,
|
|
37072
37638
|
datasets: itemCodes.map((code, i) => ({
|
|
37073
37639
|
label: code,
|
|
37074
|
-
values: dimensions.map(
|
|
37640
|
+
values: dimensions.map(
|
|
37641
|
+
(_, di) => Math.round((raw2[code]?.[di] ?? 0) / maxPerDim[di] * 100)
|
|
37642
|
+
),
|
|
37075
37643
|
color: COLORS[i % COLORS.length]
|
|
37076
37644
|
})),
|
|
37077
37645
|
_meta: CHART_META
|
|
@@ -37088,7 +37656,10 @@ var analyticsTools = [
|
|
|
37088
37656
|
inputSchema: {
|
|
37089
37657
|
type: "object",
|
|
37090
37658
|
properties: {
|
|
37091
|
-
limit: {
|
|
37659
|
+
limit: {
|
|
37660
|
+
type: "number",
|
|
37661
|
+
description: "Max items to show (default 30)"
|
|
37662
|
+
}
|
|
37092
37663
|
}
|
|
37093
37664
|
},
|
|
37094
37665
|
handler: async (input, ctx) => {
|
|
@@ -37445,7 +38016,10 @@ var analyticsTools = [
|
|
|
37445
38016
|
{
|
|
37446
38017
|
label: "Opportunities",
|
|
37447
38018
|
count: opps.length,
|
|
37448
|
-
value: opps.reduce(
|
|
38019
|
+
value: opps.reduce(
|
|
38020
|
+
(s, o) => s + (Number(o.opportunity_amount) || 0),
|
|
38021
|
+
0
|
|
38022
|
+
),
|
|
37449
38023
|
color: "#60a5fa",
|
|
37450
38024
|
conversionRate: leads.length > 0 ? Math.round(opps.length / leads.length * 100) : 0
|
|
37451
38025
|
},
|
|
@@ -37501,7 +38075,12 @@ var analyticsTools = [
|
|
|
37501
38075
|
const limit = input.limit ?? 10;
|
|
37502
38076
|
const chartType = input.type ?? "stacked-bar";
|
|
37503
38077
|
const invoices = await ctx.client.list("Sales Invoice", {
|
|
37504
|
-
fields: [
|
|
38078
|
+
fields: [
|
|
38079
|
+
"customer_name",
|
|
38080
|
+
"outstanding_amount",
|
|
38081
|
+
"due_date",
|
|
38082
|
+
"posting_date"
|
|
38083
|
+
],
|
|
37505
38084
|
filters: [["outstanding_amount", ">", 0], ["docstatus", "=", 1]],
|
|
37506
38085
|
limit: 500,
|
|
37507
38086
|
order_by: "outstanding_amount desc"
|
|
@@ -37518,16 +38097,38 @@ var analyticsTools = [
|
|
|
37518
38097
|
const customer = inv.customer_name ?? "Unknown";
|
|
37519
38098
|
const dateStr = inv.due_date ?? inv.posting_date;
|
|
37520
38099
|
const dueDate = dateStr ? new Date(dateStr) : today;
|
|
37521
|
-
const agingDays = Math.max(
|
|
37522
|
-
|
|
37523
|
-
|
|
38100
|
+
const agingDays = Math.max(
|
|
38101
|
+
0,
|
|
38102
|
+
Math.floor((today.getTime() - dueDate.getTime()) / 864e5)
|
|
38103
|
+
);
|
|
38104
|
+
if (!byCustomer[customer]) {
|
|
38105
|
+
byCustomer[customer] = new Array(BUCKETS.length).fill(0);
|
|
38106
|
+
}
|
|
38107
|
+
const bucketIdx = BUCKETS.findIndex(
|
|
38108
|
+
(b) => agingDays >= b.min && agingDays <= b.max
|
|
38109
|
+
);
|
|
37524
38110
|
if (bucketIdx >= 0) {
|
|
37525
38111
|
byCustomer[customer][bucketIdx] += Number(inv.outstanding_amount) || 0;
|
|
37526
38112
|
}
|
|
37527
38113
|
}
|
|
37528
|
-
const sorted = Object.entries(byCustomer).map(([name, buckets]) => ({
|
|
38114
|
+
const sorted = Object.entries(byCustomer).map(([name, buckets]) => ({
|
|
38115
|
+
name,
|
|
38116
|
+
buckets,
|
|
38117
|
+
total: buckets.reduce((s, v) => s + v, 0)
|
|
38118
|
+
})).sort((a, b) => b.total - a.total).slice(0, limit);
|
|
37529
38119
|
if (chartType === "treemap") {
|
|
37530
|
-
const COLORS = [
|
|
38120
|
+
const COLORS = [
|
|
38121
|
+
"#60a5fa",
|
|
38122
|
+
"#4ade80",
|
|
38123
|
+
"#fbbf24",
|
|
38124
|
+
"#818cf8",
|
|
38125
|
+
"#c084fc",
|
|
38126
|
+
"#fb923c",
|
|
38127
|
+
"#34d399",
|
|
38128
|
+
"#f472b6",
|
|
38129
|
+
"#a78bfa",
|
|
38130
|
+
"#f97316"
|
|
38131
|
+
];
|
|
37531
38132
|
return {
|
|
37532
38133
|
title: "Accounts Receivable by Customer",
|
|
37533
38134
|
type: "treemap",
|
|
@@ -37596,7 +38197,10 @@ var analyticsTools = [
|
|
|
37596
38197
|
const costMap = {};
|
|
37597
38198
|
for (const bin of bins) {
|
|
37598
38199
|
const code = bin.item_code;
|
|
37599
|
-
costMap[code] = Math.max(
|
|
38200
|
+
costMap[code] = Math.max(
|
|
38201
|
+
costMap[code] ?? 0,
|
|
38202
|
+
Number(bin.valuation_rate) || 0
|
|
38203
|
+
);
|
|
37600
38204
|
}
|
|
37601
38205
|
if (groupBy === "customer") {
|
|
37602
38206
|
const invoices = await ctx.client.list("Sales Invoice", {
|
|
@@ -37611,7 +38215,9 @@ var analyticsTools = [
|
|
|
37611
38215
|
const byCustomer = {};
|
|
37612
38216
|
for (const row of siItems) {
|
|
37613
38217
|
const customer = custMap[row.parent] ?? "Unknown";
|
|
37614
|
-
if (!byCustomer[customer])
|
|
38218
|
+
if (!byCustomer[customer]) {
|
|
38219
|
+
byCustomer[customer] = { revenue: 0, cost: 0 };
|
|
38220
|
+
}
|
|
37615
38221
|
const qty = Number(row.qty) || 0;
|
|
37616
38222
|
const unitCost = costMap[row.item_code] ?? 0;
|
|
37617
38223
|
byCustomer[customer].revenue += Number(row.amount) || 0;
|
|
@@ -37629,8 +38235,20 @@ var analyticsTools = [
|
|
|
37629
38235
|
type: "composed",
|
|
37630
38236
|
labels: labels2,
|
|
37631
38237
|
datasets: [
|
|
37632
|
-
{
|
|
37633
|
-
|
|
38238
|
+
{
|
|
38239
|
+
label: "Revenue",
|
|
38240
|
+
values: revenues2,
|
|
38241
|
+
color: "#60a5fa",
|
|
38242
|
+
type: "bar"
|
|
38243
|
+
},
|
|
38244
|
+
{
|
|
38245
|
+
label: "Margin %",
|
|
38246
|
+
values: margins2,
|
|
38247
|
+
color: "#4ade80",
|
|
38248
|
+
type: "line",
|
|
38249
|
+
yAxisId: "right",
|
|
38250
|
+
showDots: true
|
|
38251
|
+
}
|
|
37634
38252
|
],
|
|
37635
38253
|
showRightAxis: true,
|
|
37636
38254
|
currency: "EUR",
|
|
@@ -37642,7 +38260,13 @@ var analyticsTools = [
|
|
|
37642
38260
|
const byItem = {};
|
|
37643
38261
|
for (const row of siItems) {
|
|
37644
38262
|
const code = row.item_code ?? "Unknown";
|
|
37645
|
-
if (!byItem[code])
|
|
38263
|
+
if (!byItem[code]) {
|
|
38264
|
+
byItem[code] = {
|
|
38265
|
+
name: row.item_name ?? code,
|
|
38266
|
+
revenue: 0,
|
|
38267
|
+
cost: 0
|
|
38268
|
+
};
|
|
38269
|
+
}
|
|
37646
38270
|
const qty = Number(row.qty) || 0;
|
|
37647
38271
|
const unitCost = costMap[code] ?? 0;
|
|
37648
38272
|
byItem[code].revenue += Number(row.amount) || 0;
|
|
@@ -37660,8 +38284,20 @@ var analyticsTools = [
|
|
|
37660
38284
|
type: "composed",
|
|
37661
38285
|
labels,
|
|
37662
38286
|
datasets: [
|
|
37663
|
-
{
|
|
37664
|
-
|
|
38287
|
+
{
|
|
38288
|
+
label: "Revenue",
|
|
38289
|
+
values: revenues,
|
|
38290
|
+
color: "#60a5fa",
|
|
38291
|
+
type: "bar"
|
|
38292
|
+
},
|
|
38293
|
+
{
|
|
38294
|
+
label: "Margin %",
|
|
38295
|
+
values: margins,
|
|
38296
|
+
color: "#4ade80",
|
|
38297
|
+
type: "line",
|
|
38298
|
+
yAxisId: "right",
|
|
38299
|
+
showDots: true
|
|
38300
|
+
}
|
|
37665
38301
|
],
|
|
37666
38302
|
showRightAxis: true,
|
|
37667
38303
|
currency: "EUR",
|
|
@@ -37681,7 +38317,10 @@ var analyticsTools = [
|
|
|
37681
38317
|
inputSchema: {
|
|
37682
38318
|
type: "object",
|
|
37683
38319
|
properties: {
|
|
37684
|
-
months: {
|
|
38320
|
+
months: {
|
|
38321
|
+
type: "number",
|
|
38322
|
+
description: "How many months back (default 6)"
|
|
38323
|
+
},
|
|
37685
38324
|
type: {
|
|
37686
38325
|
type: "string",
|
|
37687
38326
|
enum: ["bar", "stacked-bar", "composed"],
|
|
@@ -37693,7 +38332,11 @@ var analyticsTools = [
|
|
|
37693
38332
|
const monthsBack = input.months ?? 6;
|
|
37694
38333
|
const chartType = input.type ?? "composed";
|
|
37695
38334
|
const now = /* @__PURE__ */ new Date();
|
|
37696
|
-
const startDate = new Date(
|
|
38335
|
+
const startDate = new Date(
|
|
38336
|
+
now.getFullYear(),
|
|
38337
|
+
now.getMonth() - monthsBack + 1,
|
|
38338
|
+
1
|
|
38339
|
+
);
|
|
37697
38340
|
const startStr = startDate.toISOString().split("T")[0];
|
|
37698
38341
|
const salesOrders = await ctx.client.list("Sales Order", {
|
|
37699
38342
|
fields: ["grand_total", "transaction_date"],
|
|
@@ -37709,8 +38352,14 @@ var analyticsTools = [
|
|
|
37709
38352
|
});
|
|
37710
38353
|
const months = [];
|
|
37711
38354
|
for (let m = 0; m < monthsBack; m++) {
|
|
37712
|
-
const d = new Date(
|
|
37713
|
-
|
|
38355
|
+
const d = new Date(
|
|
38356
|
+
now.getFullYear(),
|
|
38357
|
+
now.getMonth() - monthsBack + 1 + m,
|
|
38358
|
+
1
|
|
38359
|
+
);
|
|
38360
|
+
months.push(
|
|
38361
|
+
`${d.toLocaleString("en", { month: "short" })} ${d.getFullYear().toString().slice(2)}`
|
|
38362
|
+
);
|
|
37714
38363
|
}
|
|
37715
38364
|
const income = new Array(monthsBack).fill(0);
|
|
37716
38365
|
const expenses = new Array(monthsBack).fill(0);
|
|
@@ -37730,8 +38379,18 @@ var analyticsTools = [
|
|
|
37730
38379
|
}
|
|
37731
38380
|
const netProfit = income.map((inc, i) => Math.round(inc - expenses[i]));
|
|
37732
38381
|
const datasets = [
|
|
37733
|
-
{
|
|
37734
|
-
|
|
38382
|
+
{
|
|
38383
|
+
label: "Income",
|
|
38384
|
+
values: income.map((v) => Math.round(v)),
|
|
38385
|
+
color: "#4ade80",
|
|
38386
|
+
type: "bar"
|
|
38387
|
+
},
|
|
38388
|
+
{
|
|
38389
|
+
label: "Expenses",
|
|
38390
|
+
values: expenses.map((v) => Math.round(v)),
|
|
38391
|
+
color: "#f87171",
|
|
38392
|
+
type: "bar"
|
|
38393
|
+
}
|
|
37735
38394
|
];
|
|
37736
38395
|
if (chartType === "composed") {
|
|
37737
38396
|
datasets.push({
|
|
@@ -37780,7 +38439,9 @@ var KANBAN_BOARD_DEFINITIONS = [
|
|
|
37780
38439
|
}
|
|
37781
38440
|
];
|
|
37782
38441
|
function getKanbanBoardDefinition(doctype) {
|
|
37783
|
-
return KANBAN_BOARD_DEFINITIONS.find(
|
|
38442
|
+
return KANBAN_BOARD_DEFINITIONS.find(
|
|
38443
|
+
(definition) => definition.doctype === doctype
|
|
38444
|
+
);
|
|
37784
38445
|
}
|
|
37785
38446
|
|
|
37786
38447
|
// src/kanban/field-utils.ts
|
|
@@ -37803,7 +38464,9 @@ function truncateDescription(desc, maxLen = 80) {
|
|
|
37803
38464
|
return plain.slice(0, maxLen).trimEnd() + "\u2026";
|
|
37804
38465
|
}
|
|
37805
38466
|
function isDateOverdue(dateStr) {
|
|
37806
|
-
if (typeof dateStr !== "string" || !/^\d{4}-\d{2}-\d{2}/.test(dateStr))
|
|
38467
|
+
if (typeof dateStr !== "string" || !/^\d{4}-\d{2}-\d{2}/.test(dateStr)) {
|
|
38468
|
+
return false;
|
|
38469
|
+
}
|
|
37807
38470
|
const todayStr = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
37808
38471
|
return dateStr.slice(0, 10) < todayStr;
|
|
37809
38472
|
}
|
|
@@ -37823,13 +38486,32 @@ function priorityTone(priority) {
|
|
|
37823
38486
|
var TASK_COLUMNS = [
|
|
37824
38487
|
{ id: "open", label: "Open", color: "#60a5fa", status: "Open" },
|
|
37825
38488
|
{ id: "working", label: "Working", color: "#f59e0b", status: "Working" },
|
|
37826
|
-
{
|
|
38489
|
+
{
|
|
38490
|
+
id: "pending-review",
|
|
38491
|
+
label: "Pending Review",
|
|
38492
|
+
color: "#a78bfa",
|
|
38493
|
+
status: "Pending Review"
|
|
38494
|
+
},
|
|
37827
38495
|
{ id: "overdue", label: "Overdue", color: "#ef4444", status: "Overdue" },
|
|
37828
|
-
{
|
|
37829
|
-
|
|
38496
|
+
{
|
|
38497
|
+
id: "completed",
|
|
38498
|
+
label: "Completed",
|
|
38499
|
+
color: "#22c55e",
|
|
38500
|
+
status: "Completed"
|
|
38501
|
+
},
|
|
38502
|
+
{
|
|
38503
|
+
id: "cancelled",
|
|
38504
|
+
label: "Cancelled",
|
|
38505
|
+
color: "#78716c",
|
|
38506
|
+
status: "Cancelled"
|
|
38507
|
+
}
|
|
37830
38508
|
];
|
|
37831
|
-
var STATUS_BY_COLUMN = new Map(
|
|
37832
|
-
|
|
38509
|
+
var STATUS_BY_COLUMN = new Map(
|
|
38510
|
+
TASK_COLUMNS.map((column) => [column.id, column.status])
|
|
38511
|
+
);
|
|
38512
|
+
var COLUMN_BY_STATUS = new Map(
|
|
38513
|
+
TASK_COLUMNS.map((column) => [column.status, column.id])
|
|
38514
|
+
);
|
|
37833
38515
|
var TASK_LIST_FIELDS = [
|
|
37834
38516
|
"name",
|
|
37835
38517
|
"subject",
|
|
@@ -37846,19 +38528,44 @@ var TASK_LIST_FIELDS = [
|
|
|
37846
38528
|
"is_milestone"
|
|
37847
38529
|
];
|
|
37848
38530
|
var TASK_ALLOWED_TRANSITIONS = [
|
|
37849
|
-
{
|
|
38531
|
+
{
|
|
38532
|
+
fromColumn: "open",
|
|
38533
|
+
toColumn: "working",
|
|
38534
|
+
allowed: true,
|
|
38535
|
+
label: "Start work"
|
|
38536
|
+
},
|
|
37850
38537
|
{ fromColumn: "open", toColumn: "pending-review", allowed: true },
|
|
37851
38538
|
{ fromColumn: "open", toColumn: "completed", allowed: true },
|
|
37852
38539
|
{ fromColumn: "open", toColumn: "cancelled", allowed: true },
|
|
37853
38540
|
{ fromColumn: "working", toColumn: "open", allowed: true },
|
|
37854
|
-
{
|
|
38541
|
+
{
|
|
38542
|
+
fromColumn: "working",
|
|
38543
|
+
toColumn: "pending-review",
|
|
38544
|
+
allowed: true,
|
|
38545
|
+
label: "Request review"
|
|
38546
|
+
},
|
|
37855
38547
|
{ fromColumn: "working", toColumn: "completed", allowed: true },
|
|
37856
38548
|
{ fromColumn: "working", toColumn: "cancelled", allowed: true },
|
|
37857
|
-
{
|
|
37858
|
-
|
|
38549
|
+
{
|
|
38550
|
+
fromColumn: "pending-review",
|
|
38551
|
+
toColumn: "working",
|
|
38552
|
+
allowed: true,
|
|
38553
|
+
label: "Resume work"
|
|
38554
|
+
},
|
|
38555
|
+
{
|
|
38556
|
+
fromColumn: "pending-review",
|
|
38557
|
+
toColumn: "completed",
|
|
38558
|
+
allowed: true,
|
|
38559
|
+
label: "Approve"
|
|
38560
|
+
},
|
|
37859
38561
|
{ fromColumn: "pending-review", toColumn: "open", allowed: true },
|
|
37860
38562
|
{ fromColumn: "pending-review", toColumn: "cancelled", allowed: true },
|
|
37861
|
-
{
|
|
38563
|
+
{
|
|
38564
|
+
fromColumn: "completed",
|
|
38565
|
+
toColumn: "working",
|
|
38566
|
+
allowed: true,
|
|
38567
|
+
label: "Reopen"
|
|
38568
|
+
},
|
|
37862
38569
|
{ fromColumn: "completed", toColumn: "open", allowed: true },
|
|
37863
38570
|
{ fromColumn: "cancelled", toColumn: "open", allowed: true, label: "Reopen" }
|
|
37864
38571
|
];
|
|
@@ -37880,15 +38587,21 @@ function buildTaskCard(row) {
|
|
|
37880
38587
|
badges.push({ label: "Overdue", tone: "error" });
|
|
37881
38588
|
}
|
|
37882
38589
|
const metrics = [];
|
|
37883
|
-
if (progress !== void 0)
|
|
38590
|
+
if (progress !== void 0) {
|
|
38591
|
+
metrics.push({ label: "Progress", value: `${progress}%` });
|
|
38592
|
+
}
|
|
37884
38593
|
const dueDateDisplay = formatShortDate(dueDateStr);
|
|
37885
38594
|
if (dueDateDisplay) metrics.push({ label: "Due", value: dueDateDisplay });
|
|
37886
38595
|
const startDisplay = formatShortDate(row.exp_start_date);
|
|
37887
38596
|
if (startDisplay) metrics.push({ label: "Start", value: startDisplay });
|
|
37888
38597
|
const expectedTime = Number(row.expected_time);
|
|
37889
|
-
if (Number.isFinite(expectedTime) && expectedTime > 0)
|
|
38598
|
+
if (Number.isFinite(expectedTime) && expectedTime > 0) {
|
|
38599
|
+
metrics.push({ label: "Est.", value: `${expectedTime}h` });
|
|
38600
|
+
}
|
|
37890
38601
|
const actualTime = Number(row.actual_time);
|
|
37891
|
-
if (Number.isFinite(actualTime) && actualTime > 0)
|
|
38602
|
+
if (Number.isFinite(actualTime) && actualTime > 0) {
|
|
38603
|
+
metrics.push({ label: "Actual", value: `${actualTime}h` });
|
|
38604
|
+
}
|
|
37892
38605
|
const assignee = parseFirstAssignee(row._assign);
|
|
37893
38606
|
return {
|
|
37894
38607
|
id: String(row.name ?? ""),
|
|
@@ -37979,7 +38692,9 @@ var taskKanbanAdapter = {
|
|
|
37979
38692
|
errorMessage: "Unknown Task column"
|
|
37980
38693
|
};
|
|
37981
38694
|
}
|
|
37982
|
-
const serverTask = await ctx.client.update("Task", move.cardId, {
|
|
38695
|
+
const serverTask = await ctx.client.update("Task", move.cardId, {
|
|
38696
|
+
status
|
|
38697
|
+
});
|
|
37983
38698
|
return {
|
|
37984
38699
|
ok: true,
|
|
37985
38700
|
cardId: move.cardId,
|
|
@@ -37994,13 +38709,27 @@ var taskKanbanAdapter = {
|
|
|
37994
38709
|
var OPPORTUNITY_COLUMNS = [
|
|
37995
38710
|
{ id: "open", label: "Open", color: "#60a5fa", status: "Open" },
|
|
37996
38711
|
{ id: "replied", label: "Replied", color: "#f59e0b", status: "Replied" },
|
|
37997
|
-
{
|
|
37998
|
-
|
|
38712
|
+
{
|
|
38713
|
+
id: "quotation",
|
|
38714
|
+
label: "Quotation",
|
|
38715
|
+
color: "#a78bfa",
|
|
38716
|
+
status: "Quotation"
|
|
38717
|
+
},
|
|
38718
|
+
{
|
|
38719
|
+
id: "converted",
|
|
38720
|
+
label: "Converted",
|
|
38721
|
+
color: "#22c55e",
|
|
38722
|
+
status: "Converted"
|
|
38723
|
+
},
|
|
37999
38724
|
{ id: "closed", label: "Closed", color: "#64748b", status: "Closed" },
|
|
38000
38725
|
{ id: "lost", label: "Lost", color: "#ef4444", status: "Lost" }
|
|
38001
38726
|
];
|
|
38002
|
-
var STATUS_BY_COLUMN2 = new Map(
|
|
38003
|
-
|
|
38727
|
+
var STATUS_BY_COLUMN2 = new Map(
|
|
38728
|
+
OPPORTUNITY_COLUMNS.map((column) => [column.id, column.status])
|
|
38729
|
+
);
|
|
38730
|
+
var COLUMN_BY_STATUS2 = new Map(
|
|
38731
|
+
OPPORTUNITY_COLUMNS.map((column) => [column.status, column.id])
|
|
38732
|
+
);
|
|
38004
38733
|
var OPPORTUNITY_LIST_FIELDS = [
|
|
38005
38734
|
"name",
|
|
38006
38735
|
"title",
|
|
@@ -38018,22 +38747,72 @@ var OPPORTUNITY_LIST_FIELDS = [
|
|
|
38018
38747
|
];
|
|
38019
38748
|
var OPPORTUNITY_ALLOWED_TRANSITIONS = [
|
|
38020
38749
|
{ fromColumn: "open", toColumn: "replied", allowed: true, label: "Reply" },
|
|
38021
|
-
{
|
|
38022
|
-
|
|
38750
|
+
{
|
|
38751
|
+
fromColumn: "open",
|
|
38752
|
+
toColumn: "quotation",
|
|
38753
|
+
allowed: true,
|
|
38754
|
+
label: "Send quotation"
|
|
38755
|
+
},
|
|
38756
|
+
{
|
|
38757
|
+
fromColumn: "open",
|
|
38758
|
+
toColumn: "converted",
|
|
38759
|
+
allowed: true,
|
|
38760
|
+
label: "Convert"
|
|
38761
|
+
},
|
|
38023
38762
|
{ fromColumn: "open", toColumn: "closed", allowed: true, label: "Close" },
|
|
38024
38763
|
{ fromColumn: "open", toColumn: "lost", allowed: true, label: "Mark lost" },
|
|
38025
38764
|
{ fromColumn: "replied", toColumn: "open", allowed: true, label: "Reopen" },
|
|
38026
|
-
{
|
|
38027
|
-
|
|
38765
|
+
{
|
|
38766
|
+
fromColumn: "replied",
|
|
38767
|
+
toColumn: "quotation",
|
|
38768
|
+
allowed: true,
|
|
38769
|
+
label: "Send quotation"
|
|
38770
|
+
},
|
|
38771
|
+
{
|
|
38772
|
+
fromColumn: "replied",
|
|
38773
|
+
toColumn: "converted",
|
|
38774
|
+
allowed: true,
|
|
38775
|
+
label: "Convert"
|
|
38776
|
+
},
|
|
38028
38777
|
{ fromColumn: "replied", toColumn: "closed", allowed: true, label: "Close" },
|
|
38029
|
-
{
|
|
38778
|
+
{
|
|
38779
|
+
fromColumn: "replied",
|
|
38780
|
+
toColumn: "lost",
|
|
38781
|
+
allowed: true,
|
|
38782
|
+
label: "Mark lost"
|
|
38783
|
+
},
|
|
38030
38784
|
{ fromColumn: "quotation", toColumn: "open", allowed: true, label: "Reopen" },
|
|
38031
|
-
{
|
|
38032
|
-
|
|
38033
|
-
|
|
38034
|
-
|
|
38785
|
+
{
|
|
38786
|
+
fromColumn: "quotation",
|
|
38787
|
+
toColumn: "replied",
|
|
38788
|
+
allowed: true,
|
|
38789
|
+
label: "Resume conversation"
|
|
38790
|
+
},
|
|
38791
|
+
{
|
|
38792
|
+
fromColumn: "quotation",
|
|
38793
|
+
toColumn: "converted",
|
|
38794
|
+
allowed: true,
|
|
38795
|
+
label: "Convert"
|
|
38796
|
+
},
|
|
38797
|
+
{
|
|
38798
|
+
fromColumn: "quotation",
|
|
38799
|
+
toColumn: "closed",
|
|
38800
|
+
allowed: true,
|
|
38801
|
+
label: "Close"
|
|
38802
|
+
},
|
|
38803
|
+
{
|
|
38804
|
+
fromColumn: "quotation",
|
|
38805
|
+
toColumn: "lost",
|
|
38806
|
+
allowed: true,
|
|
38807
|
+
label: "Mark lost"
|
|
38808
|
+
},
|
|
38035
38809
|
{ fromColumn: "converted", toColumn: "open", allowed: true, label: "Reopen" },
|
|
38036
|
-
{
|
|
38810
|
+
{
|
|
38811
|
+
fromColumn: "converted",
|
|
38812
|
+
toColumn: "closed",
|
|
38813
|
+
allowed: true,
|
|
38814
|
+
label: "Close"
|
|
38815
|
+
},
|
|
38037
38816
|
{ fromColumn: "closed", toColumn: "open", allowed: true, label: "Reopen" },
|
|
38038
38817
|
{ fromColumn: "closed", toColumn: "replied", allowed: true, label: "Resume" },
|
|
38039
38818
|
{ fromColumn: "lost", toColumn: "open", allowed: true, label: "Reopen" },
|
|
@@ -38051,7 +38830,10 @@ function formatOpportunityAmount(amount, currency) {
|
|
|
38051
38830
|
function buildOpportunityCard(row) {
|
|
38052
38831
|
const status = String(row.status ?? "Open");
|
|
38053
38832
|
const columnId = columnIdForOpportunityStatus(status);
|
|
38054
|
-
const amountValue = formatOpportunityAmount(
|
|
38833
|
+
const amountValue = formatOpportunityAmount(
|
|
38834
|
+
row.opportunity_amount,
|
|
38835
|
+
row.currency
|
|
38836
|
+
);
|
|
38055
38837
|
const probability = Number(row.probability);
|
|
38056
38838
|
const probabilityValue = Number.isFinite(probability) ? `${probability}%` : null;
|
|
38057
38839
|
let title;
|
|
@@ -38075,7 +38857,9 @@ function buildOpportunityCard(row) {
|
|
|
38075
38857
|
}
|
|
38076
38858
|
const metrics = [];
|
|
38077
38859
|
if (amountValue) metrics.push({ label: "Amount", value: amountValue });
|
|
38078
|
-
if (probabilityValue)
|
|
38860
|
+
if (probabilityValue) {
|
|
38861
|
+
metrics.push({ label: "Probability", value: probabilityValue });
|
|
38862
|
+
}
|
|
38079
38863
|
const closingDisplay = formatShortDate(closingDate);
|
|
38080
38864
|
if (closingDisplay) metrics.push({ label: "Closing", value: closingDisplay });
|
|
38081
38865
|
const createdDisplay = formatShortDate(row.transaction_date);
|
|
@@ -38130,13 +38914,21 @@ var opportunityKanbanAdapter = {
|
|
|
38130
38914
|
(transition) => transition.fromColumn === move.fromColumn && transition.toColumn === move.toColumn && transition.allowed
|
|
38131
38915
|
);
|
|
38132
38916
|
if (!match2) {
|
|
38133
|
-
return {
|
|
38917
|
+
return {
|
|
38918
|
+
allowed: false,
|
|
38919
|
+
reason: "Opportunity transition is not allowed"
|
|
38920
|
+
};
|
|
38134
38921
|
}
|
|
38135
38922
|
return { allowed: true };
|
|
38136
38923
|
},
|
|
38137
38924
|
async executeMove(move, ctx) {
|
|
38138
|
-
const currentOpportunity = await ctx.client.get(
|
|
38139
|
-
|
|
38925
|
+
const currentOpportunity = await ctx.client.get(
|
|
38926
|
+
"Opportunity",
|
|
38927
|
+
move.cardId
|
|
38928
|
+
);
|
|
38929
|
+
const serverColumn = columnIdForOpportunityStatus(
|
|
38930
|
+
currentOpportunity.status
|
|
38931
|
+
);
|
|
38140
38932
|
if (serverColumn !== move.fromColumn) {
|
|
38141
38933
|
return {
|
|
38142
38934
|
ok: false,
|
|
@@ -38166,9 +38958,13 @@ var opportunityKanbanAdapter = {
|
|
|
38166
38958
|
errorMessage: "Unknown Opportunity column"
|
|
38167
38959
|
};
|
|
38168
38960
|
}
|
|
38169
|
-
const serverOpportunity = await ctx.client.update(
|
|
38170
|
-
|
|
38171
|
-
|
|
38961
|
+
const serverOpportunity = await ctx.client.update(
|
|
38962
|
+
"Opportunity",
|
|
38963
|
+
move.cardId,
|
|
38964
|
+
{
|
|
38965
|
+
status
|
|
38966
|
+
}
|
|
38967
|
+
);
|
|
38172
38968
|
return {
|
|
38173
38969
|
ok: true,
|
|
38174
38970
|
cardId: move.cardId,
|
|
@@ -38187,8 +38983,12 @@ var ISSUE_COLUMNS = [
|
|
|
38187
38983
|
{ id: "resolved", label: "Resolved", color: "#22c55e", status: "Resolved" },
|
|
38188
38984
|
{ id: "closed", label: "Closed", color: "#64748b", status: "Closed" }
|
|
38189
38985
|
];
|
|
38190
|
-
var STATUS_BY_COLUMN3 = new Map(
|
|
38191
|
-
|
|
38986
|
+
var STATUS_BY_COLUMN3 = new Map(
|
|
38987
|
+
ISSUE_COLUMNS.map((column) => [column.id, column.status])
|
|
38988
|
+
);
|
|
38989
|
+
var COLUMN_BY_STATUS3 = new Map(
|
|
38990
|
+
ISSUE_COLUMNS.map((column) => [column.status, column.id])
|
|
38991
|
+
);
|
|
38192
38992
|
var ISSUE_LIST_FIELDS = [
|
|
38193
38993
|
"name",
|
|
38194
38994
|
"subject",
|
|
@@ -38204,19 +39004,44 @@ var ISSUE_LIST_FIELDS = [
|
|
|
38204
39004
|
];
|
|
38205
39005
|
var ISSUE_ALLOWED_TRANSITIONS = [
|
|
38206
39006
|
{ fromColumn: "open", toColumn: "replied", allowed: true, label: "Reply" },
|
|
38207
|
-
{
|
|
39007
|
+
{
|
|
39008
|
+
fromColumn: "open",
|
|
39009
|
+
toColumn: "on-hold",
|
|
39010
|
+
allowed: true,
|
|
39011
|
+
label: "Put on hold"
|
|
39012
|
+
},
|
|
38208
39013
|
{ fromColumn: "open", toColumn: "resolved", allowed: true, label: "Resolve" },
|
|
38209
39014
|
{ fromColumn: "open", toColumn: "closed", allowed: true, label: "Close" },
|
|
38210
39015
|
{ fromColumn: "replied", toColumn: "open", allowed: true, label: "Reopen" },
|
|
38211
|
-
{
|
|
38212
|
-
|
|
39016
|
+
{
|
|
39017
|
+
fromColumn: "replied",
|
|
39018
|
+
toColumn: "on-hold",
|
|
39019
|
+
allowed: true,
|
|
39020
|
+
label: "Put on hold"
|
|
39021
|
+
},
|
|
39022
|
+
{
|
|
39023
|
+
fromColumn: "replied",
|
|
39024
|
+
toColumn: "resolved",
|
|
39025
|
+
allowed: true,
|
|
39026
|
+
label: "Resolve"
|
|
39027
|
+
},
|
|
38213
39028
|
{ fromColumn: "replied", toColumn: "closed", allowed: true, label: "Close" },
|
|
38214
39029
|
{ fromColumn: "on-hold", toColumn: "open", allowed: true, label: "Resume" },
|
|
38215
39030
|
{ fromColumn: "on-hold", toColumn: "replied", allowed: true, label: "Reply" },
|
|
38216
|
-
{
|
|
39031
|
+
{
|
|
39032
|
+
fromColumn: "on-hold",
|
|
39033
|
+
toColumn: "resolved",
|
|
39034
|
+
allowed: true,
|
|
39035
|
+
label: "Resolve"
|
|
39036
|
+
},
|
|
38217
39037
|
{ fromColumn: "on-hold", toColumn: "closed", allowed: true, label: "Close" },
|
|
38218
39038
|
{ fromColumn: "resolved", toColumn: "open", allowed: true, label: "Reopen" },
|
|
38219
|
-
{
|
|
39039
|
+
{
|
|
39040
|
+
fromColumn: "resolved",
|
|
39041
|
+
toColumn: "replied",
|
|
39042
|
+
allowed: true,
|
|
39043
|
+
label: "Reply"
|
|
39044
|
+
},
|
|
38220
39045
|
{ fromColumn: "resolved", toColumn: "closed", allowed: true, label: "Close" },
|
|
38221
39046
|
{ fromColumn: "closed", toColumn: "open", allowed: true, label: "Reopen" },
|
|
38222
39047
|
{ fromColumn: "closed", toColumn: "replied", allowed: true, label: "Reply" }
|
|
@@ -38249,7 +39074,9 @@ function buildIssueCard(row) {
|
|
|
38249
39074
|
const openedDisplay = formatShortDate(row.opening_date);
|
|
38250
39075
|
if (openedDisplay) metrics.push({ label: "Opened", value: openedDisplay });
|
|
38251
39076
|
const resolvedDisplay = formatShortDate(row.resolution_date);
|
|
38252
|
-
if (resolvedDisplay)
|
|
39077
|
+
if (resolvedDisplay) {
|
|
39078
|
+
metrics.push({ label: "Resolved", value: resolvedDisplay });
|
|
39079
|
+
}
|
|
38253
39080
|
const assignee = parseFirstAssignee(row._assign);
|
|
38254
39081
|
return {
|
|
38255
39082
|
id: String(row.name ?? ""),
|
|
@@ -38339,7 +39166,9 @@ var issueKanbanAdapter = {
|
|
|
38339
39166
|
errorMessage: "Unknown Issue column"
|
|
38340
39167
|
};
|
|
38341
39168
|
}
|
|
38342
|
-
const serverIssue = await ctx.client.update("Issue", move.cardId, {
|
|
39169
|
+
const serverIssue = await ctx.client.update("Issue", move.cardId, {
|
|
39170
|
+
status
|
|
39171
|
+
});
|
|
38343
39172
|
return {
|
|
38344
39173
|
ok: true,
|
|
38345
39174
|
cardId: move.cardId,
|
|
@@ -38393,8 +39222,14 @@ var kanbanTools = [
|
|
|
38393
39222
|
enum: ["Task", "Opportunity", "Issue"]
|
|
38394
39223
|
},
|
|
38395
39224
|
limit: { type: "number", description: "Page size (default 50)" },
|
|
38396
|
-
offset: {
|
|
38397
|
-
|
|
39225
|
+
offset: {
|
|
39226
|
+
type: "number",
|
|
39227
|
+
description: "Pagination offset (default 0)"
|
|
39228
|
+
},
|
|
39229
|
+
project: {
|
|
39230
|
+
type: "string",
|
|
39231
|
+
description: "Optional Task project filter"
|
|
39232
|
+
},
|
|
38398
39233
|
priority: {
|
|
38399
39234
|
type: "string",
|
|
38400
39235
|
description: "Optional Task priority filter",
|
|
@@ -38476,8 +39311,14 @@ var kanbanTools = [
|
|
|
38476
39311
|
enum: ["Task", "Opportunity", "Issue"]
|
|
38477
39312
|
},
|
|
38478
39313
|
card_id: { type: "string", description: "Card/document identifier" },
|
|
38479
|
-
from_column: {
|
|
38480
|
-
|
|
39314
|
+
from_column: {
|
|
39315
|
+
type: "string",
|
|
39316
|
+
description: "Source column identifier"
|
|
39317
|
+
},
|
|
39318
|
+
to_column: {
|
|
39319
|
+
type: "string",
|
|
39320
|
+
description: "Destination column identifier"
|
|
39321
|
+
}
|
|
38481
39322
|
},
|
|
38482
39323
|
required: ["doctype", "card_id", "from_column", "to_column"]
|
|
38483
39324
|
},
|
|
@@ -38941,8 +39782,12 @@ function withUiRefreshRequest(result, toolName, args) {
|
|
|
38941
39782
|
if (isKpiViewer(enriched)) {
|
|
38942
39783
|
const kpiHints = KPI_DRILL_DOWN[toolName];
|
|
38943
39784
|
if (kpiHints) {
|
|
38944
|
-
if (kpiHints._drillDown && !enriched._drillDown)
|
|
38945
|
-
|
|
39785
|
+
if (kpiHints._drillDown && !enriched._drillDown) {
|
|
39786
|
+
enriched._drillDown = kpiHints._drillDown;
|
|
39787
|
+
}
|
|
39788
|
+
if (kpiHints._trendDrillDown && !enriched._trendDrillDown) {
|
|
39789
|
+
enriched._trendDrillDown = kpiHints._trendDrillDown;
|
|
39790
|
+
}
|
|
38946
39791
|
}
|
|
38947
39792
|
}
|
|
38948
39793
|
return enriched;
|
|
@@ -39067,7 +39912,11 @@ var DEFAULT_HTTP_PORT = 3012;
|
|
|
39067
39912
|
async function main() {
|
|
39068
39913
|
const args = getArgs();
|
|
39069
39914
|
if (args.includes("--inspect")) {
|
|
39070
|
-
await launchInspector("deno", [
|
|
39915
|
+
await launchInspector("deno", [
|
|
39916
|
+
"run",
|
|
39917
|
+
"--allow-all",
|
|
39918
|
+
import.meta.filename
|
|
39919
|
+
]);
|
|
39071
39920
|
return;
|
|
39072
39921
|
}
|
|
39073
39922
|
const categoriesArg = args.find((arg) => arg.startsWith("--categories="));
|
|
@@ -39082,7 +39931,7 @@ async function main() {
|
|
|
39082
39931
|
);
|
|
39083
39932
|
const server = new ConcurrentMCPServer({
|
|
39084
39933
|
name: "mcp-erpnext",
|
|
39085
|
-
version: "2.2.
|
|
39934
|
+
version: "2.2.2",
|
|
39086
39935
|
maxConcurrent: 10,
|
|
39087
39936
|
backpressureStrategy: "queue",
|
|
39088
39937
|
validateSchema: true,
|
|
@@ -39097,7 +39946,11 @@ async function main() {
|
|
|
39097
39946
|
const handlers = toolsClient.buildHandlersMap();
|
|
39098
39947
|
server.registerTools(mcpTools, handlers);
|
|
39099
39948
|
for (const viewerName of UI_VIEWERS) {
|
|
39100
|
-
const distPath = resolveViewerDistPath2(
|
|
39949
|
+
const distPath = resolveViewerDistPath2(
|
|
39950
|
+
import.meta.url,
|
|
39951
|
+
viewerName,
|
|
39952
|
+
statSync
|
|
39953
|
+
);
|
|
39101
39954
|
const resourceUri = `ui://mcp-erpnext/${viewerName}`;
|
|
39102
39955
|
const humanName = viewerName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
39103
39956
|
if (distPath) {
|