version mise à jour par claude , à tester
This commit is contained in:
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* WMS Query Service
|
||||
* Helper functions for building and executing LINQ queries via WMS API
|
||||
*/
|
||||
|
||||
const apiService = require('./api-service').getInstance();
|
||||
const constants = require('../config/constants');
|
||||
|
||||
/**
|
||||
* Build a LINQ select expression
|
||||
* @param {string} entityType - Entity type (Products, Containers, etc.)
|
||||
* @param {string} selectFields - Fields to select (e.g., "z => new { z.Id, z.Name }")
|
||||
* @param {string|null} filter - Optional filter (e.g., "z.Status == 'Active'")
|
||||
* @param {number|null} limit - Optional limit
|
||||
*/
|
||||
/**
|
||||
* Query WMS entities with LINQ expression
|
||||
* @param {string} entityType - Entity type
|
||||
* @param {string} selectExpression - LINQ select expression
|
||||
* @param {string|null} filter - Optional filter
|
||||
* @param {number} limit - Result limit
|
||||
*/
|
||||
async function queryEntities(entityType, selectExpression = 'z => z', filter = null, limit = 100) {
|
||||
try {
|
||||
// Enforce max limit
|
||||
const maxLimit = parseInt(process.env.MAX_QUERY_ROWS) || 1000;
|
||||
const actualLimit = Math.min(limit, maxLimit);
|
||||
|
||||
// Build expression: Context + optional Where + OrderBy (required by EF when Take is used)
|
||||
let expression = `Context.${entityType}`;
|
||||
if (filter) {
|
||||
const whereExpr = /^\s*\w+\s*=>/.test(filter) ? filter : `z => ${filter}`;
|
||||
expression += `.Where(${whereExpr})`;
|
||||
}
|
||||
// OrderBy must be embedded in the expression (not as a separate API param)
|
||||
expression += `.OrderBy(z => z.Id)`;
|
||||
|
||||
console.error(`[WMSQuery] Querying ${entityType}: ${expression} | take=${actualLimit} select=${selectExpression}`);
|
||||
|
||||
const result = await apiService.executeQuery(expression, {
|
||||
take: actualLimit,
|
||||
select: selectExpression !== 'z => z' ? selectExpression : undefined,
|
||||
});
|
||||
|
||||
return {
|
||||
entityType,
|
||||
expression,
|
||||
limit: actualLimit,
|
||||
count: Array.isArray(result) ? result.length : 0,
|
||||
data: result
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(`[WMSQuery] Query failed:`, error.message);
|
||||
throw new Error(`Query failed for ${entityType}: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Query entity by ID
|
||||
* @param {string} entityType - Entity type
|
||||
* @param {string|number} id - Entity ID
|
||||
*/
|
||||
async function queryById(entityType, id) {
|
||||
const filter = `z => z.Id == ${id}`;
|
||||
const result = await queryEntities(entityType, 'z => z', filter, 1);
|
||||
|
||||
if (!result.data || result.data.length === 0) {
|
||||
throw new Error(`${entityType} with ID ${id} not found`);
|
||||
}
|
||||
|
||||
return result.data[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Search entities by keyword in common fields
|
||||
* @param {string} entityType - Entity type
|
||||
* @param {string} keyword - Search keyword
|
||||
* @param {number} limit - Result limit
|
||||
*/
|
||||
async function searchEntities(entityType, keyword, limit = 50) {
|
||||
// Common searchable fields by entity type
|
||||
const searchFields = {
|
||||
'Products': ['Code', 'Description', 'Reference'],
|
||||
'Containers': ['Code', 'Reference'],
|
||||
'Tasks': ['Code', 'Reference'],
|
||||
'InboundOrders': ['Code', 'Reference'],
|
||||
'OutboundOrders': ['Code', 'Reference'],
|
||||
'Accounts': ['Code', 'Name'],
|
||||
'Suppliers': ['Code', 'Name']
|
||||
};
|
||||
|
||||
const fields = searchFields[entityType] || ['Code'];
|
||||
|
||||
// Build filter for multiple fields (OR condition)
|
||||
const conditions = fields.map(field => `z.${field}.Contains("${keyword}")`).join(' || ');
|
||||
const filter = `z => ${conditions}`;
|
||||
|
||||
try {
|
||||
return await queryEntities(entityType, 'z => z', filter, limit);
|
||||
} catch (error) {
|
||||
// If Contains doesn't work, try simpler approach
|
||||
console.error(`[WMSQuery] Search failed, trying alternative method:`, error.message);
|
||||
return await queryEntities(entityType, 'z => z', null, limit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get entity schema information (example entity to show available fields)
|
||||
* @param {string} entityType - Entity type
|
||||
*/
|
||||
async function getEntitySchema(entityType) {
|
||||
try {
|
||||
// Query one entity to see its structure
|
||||
const result = await queryEntities(entityType, 'z => z', null, 1);
|
||||
|
||||
if (!result.data || result.data.length === 0) {
|
||||
return {
|
||||
entityType,
|
||||
fields: [],
|
||||
message: `No ${entityType} found to inspect schema`
|
||||
};
|
||||
}
|
||||
|
||||
const sample = result.data[0];
|
||||
const fields = Object.keys(sample).map(key => ({
|
||||
name: key,
|
||||
type: typeof sample[key],
|
||||
sample: sample[key]
|
||||
}));
|
||||
|
||||
return {
|
||||
entityType,
|
||||
fields,
|
||||
totalFields: fields.length
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(`[WMSQuery] Failed to get schema for ${entityType}:`, error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Count entities with optional filter
|
||||
* @param {string} entityType - Entity type
|
||||
* @param {string|null} filter - Optional filter
|
||||
*/
|
||||
async function countEntities(entityType, filter = null) {
|
||||
try {
|
||||
// Build: Context.Entity.Where(...).Count()
|
||||
const parts = [`Context.${entityType}`];
|
||||
if (filter) {
|
||||
const whereExpr = /^\s*\w+\s*=>/.test(filter) ? filter : `z => ${filter}`;
|
||||
parts.push(`Where(${whereExpr})`);
|
||||
}
|
||||
parts.push('Count()');
|
||||
const fullExpression = parts.join('.');
|
||||
|
||||
console.error(`[WMSQuery] Counting ${entityType}: ${fullExpression}`);
|
||||
|
||||
const count = await apiService.executeScalarQuery(fullExpression);
|
||||
|
||||
return {
|
||||
entityType,
|
||||
filter,
|
||||
count
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(`[WMSQuery] Count failed:`, error.message);
|
||||
throw new Error(`Count failed for ${entityType}: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
queryEntities,
|
||||
queryById,
|
||||
searchEntities,
|
||||
getEntitySchema,
|
||||
countEntities,
|
||||
};
|
||||
Reference in New Issue
Block a user