version mise à jour par claude , à tester

This commit is contained in:
Arthur Ria
2026-05-20 09:38:07 +02:00
commit b59cbb3546
58 changed files with 24548 additions and 0 deletions
+275
View File
@@ -0,0 +1,275 @@
/**
* WMS Query Tools
* MCP tools for querying WMS entities via LINQ expressions
*/
const wmsQueryService = require('../services/wms-query-service');
/**
* List available WMS query tools
*/
function listTools() {
return [
{
name: 'query_wms_entities',
description: `Query WMS entities using LINQ expressions. Returns rows (up to 1000).
Uses QueryExecute with QueryType=Reading — status fields are STRINGS (enum names, not integers).
Common entities: Products, Containers, Tasks, Stocks, ProductLocations, Location, InboundOrders, OutboundOrders, Receptions, Accounts, Suppliers, Kits, Aliases.
IMPORTANT — before building a filter with a status/enum field:
1. Check docs first: read resource docs://entities/ (e.g. easywms_reading_entites_outboundorder_OutboundOrderStatus for OutboundOrders)
2. If no doc found: call get_ad_elements(element_type="Entity", search=entity_name)
3. Last resort: call get_entity_metadata(entity_name=...) to get field names
Never guess enum string values — they differ between Reading and Writing models.`,
inputSchema: {
type: 'object',
properties: {
entity_type: {
type: 'string',
description: 'Entity type (Products, Containers, Tasks, Stocks, ProductLocations, InboundOrders, OutboundOrders, Accounts, Suppliers, Kits, Aliases, Receptions)',
},
select_expression: {
type: 'string',
description: 'LINQ select expression (default: "z => z" for all fields, or "z => new { z.Id, z.Name }" for specific fields)',
default: 'z => z',
},
filter: {
type: 'string',
description: 'Optional LINQ filter (e.g., "z => z.Id > 100" or "z => z.Status == \'Active\'")',
},
limit: {
type: 'number',
description: 'Maximum results to return (default: 100, max: 1000)',
default: 100,
},
},
required: ['entity_type'],
},
},
{
name: 'get_entity_schema',
description: 'Get the schema/structure of a WMS entity by querying one sample record',
inputSchema: {
type: 'object',
properties: {
entity_type: {
type: 'string',
description: 'Entity type to inspect',
},
},
required: ['entity_type'],
},
},
{
name: 'count_wms_entities',
description: `PREFERRED TOOL for counting ("combien", "nombre de", "how many"). Uses QueryScalarExecute → Reading model. Never adds Take(), safe on all entity types.
IMPORTANT: Always use this tool first for any counting question — do not use query_wms_entities for counts.
IMPORTANT — enum/status values MUST be verified before use. Reading model uses string enum names, NOT integers.
Lookup order for enum values:
1. Read the relevant doc: docs://entities/ (e.g. easywms_reading_entites_outboundorder_OutboundOrderStatus for OutboundOrders)
2. If no doc: call get_ad_elements(element_type="Entity", search=entity_name)
3. Last resort: call get_entity_metadata(entity_name=...) — gives field names but not all enum values
Never hardcode enum values without checking — Reading vs Writing model distinction has caused bugs before.
Verified values (curl-tested):
- Tasks actives: filter='z.TaskStatus == "InProcess" || z.TaskStatus == "Pending"'
- Tasks en cours: filter='z.TaskStatus == "InProcess"'
- Tasks en attente: filter='z.TaskStatus == "Pending"'
- ODS lancés: filter='z.OutboundOrderStatus == "Release"'
- OS incomplètes actives: filter='z.IncompleteOrder == true && z.IsActive == true'
(par classe: ajouter && z.OutboundClassCode == "X")
- Containers bloquants: filter='z.NumContainerPendingTasks > 0'
(sur un emplacement: ajouter && z.LocationCode == "X")`,
inputSchema: {
type: 'object',
properties: {
entity_type: {
type: 'string',
description: 'Entity type (Products, Containers, Tasks, Stocks, OutboundOrders, InboundOrders, etc.)',
},
filter: {
type: 'string',
description: 'Optional LINQ filter condition. Status fields are strings (enum names from Reading model). Always verify enum values via docs://entities/ before use.',
},
},
required: ['entity_type'],
},
},
{
name: 'search_wms_data',
description: 'Search for a keyword across multiple WMS entities',
inputSchema: {
type: 'object',
properties: {
keyword: {
type: 'string',
description: 'Keyword to search for',
},
entity_types: {
type: 'array',
items: { type: 'string' },
description: 'List of entity types to search in (default: Products, Containers, Tasks)',
},
limit: {
type: 'number',
description: 'Maximum results per entity (default: 50)',
default: 50,
},
},
required: ['keyword'],
},
},
];
}
/**
* Execute WMS query tool
*/
async function executeTool(name, args) {
try {
switch (name) {
case 'query_wms_entities':
return await queryWmsEntities(args);
case 'count_wms_entities':
return await countWmsEntities(args);
case 'get_entity_schema':
return await getEntitySchema(args);
case 'search_wms_data':
return await searchWmsData(args);
default:
throw new Error(`Unknown WMS query tool: ${name}`);
}
} catch (error) {
console.error(`[WMSQueryTools] Error executing ${name}:`, error.message);
return {
content: [{
type: 'text',
text: JSON.stringify({
success: false,
error: error.message,
tool: name
}, null, 2)
}],
isError: true
};
}
}
/**
* Tool: query_wms_entities
*/
async function queryWmsEntities(args) {
const { entity_type, select_expression = 'z => z', filter, limit = 100 } = args;
console.error(`[WMSQueryTools] Querying ${entity_type}: limit=${limit}`);
const result = await wmsQueryService.queryEntities(
entity_type,
select_expression,
filter,
limit
);
return {
content: [{
type: 'text',
text: JSON.stringify({
success: true,
...result
}, null, 2)
}]
};
}
/**
* Tool: count_wms_entities
*/
async function countWmsEntities(args) {
const { entity_type, filter } = args;
console.error(`[WMSQueryTools] Counting ${entity_type}${filter ? ` where ${filter}` : ''}`);
const result = await wmsQueryService.countEntities(entity_type, filter || null);
return {
content: [{
type: 'text',
text: JSON.stringify({
success: true,
...result
}, null, 2)
}]
};
}
/**
* Tool: get_entity_schema
*/
async function getEntitySchema(args) {
const { entity_type } = args;
console.error(`[WMSQueryTools] Getting schema for ${entity_type}`);
const result = await wmsQueryService.getEntitySchema(entity_type);
return {
content: [{
type: 'text',
text: JSON.stringify({
success: true,
...result
}, null, 2)
}]
};
}
/**
* Tool: search_wms_data
*/
async function searchWmsData(args) {
const { keyword, entity_types = ['Products', 'Containers', 'Tasks'], limit = 50 } = args;
console.error(`[WMSQueryTools] Searching for "${keyword}" in ${entity_types.join(', ')}`);
const results = {};
let totalFound = 0;
for (const entityType of entity_types) {
try {
const result = await wmsQueryService.searchEntities(entityType, keyword, limit);
results[entityType] = {
count: result.count,
data: result.data
};
totalFound += result.count;
} catch (error) {
console.error(`[WMSQueryTools] Search failed for ${entityType}:`, error.message);
results[entityType] = {
error: error.message,
count: 0
};
}
}
return {
content: [{
type: 'text',
text: JSON.stringify({
success: true,
keyword,
totalFound,
results
}, null, 2)
}]
};
}
module.exports = {
listTools,
executeTool,
};