Add operators for numerical filters
This commit is contained in:
@@ -16,7 +16,6 @@ router.get('/', async (req, res) => {
|
||||
const sortColumn = req.query.sort || 'title';
|
||||
const sortDirection = req.query.order === 'desc' ? 'DESC' : 'ASC';
|
||||
|
||||
// Build the WHERE clause
|
||||
const conditions = ['p.visible = true'];
|
||||
const params = [];
|
||||
|
||||
@@ -25,185 +24,89 @@ router.get('/', async (req, res) => {
|
||||
conditions.push('p.replenishable = true');
|
||||
}
|
||||
|
||||
// Handle text search filters
|
||||
// Handle search filter
|
||||
if (req.query.search) {
|
||||
conditions.push('(p.title LIKE ? OR p.SKU LIKE ?)');
|
||||
params.push(`%${req.query.search}%`, `%${req.query.search}%`);
|
||||
conditions.push('(p.title LIKE ? OR p.SKU LIKE ? OR p.barcode LIKE ?)');
|
||||
const searchTerm = `%${req.query.search}%`;
|
||||
params.push(searchTerm, searchTerm, searchTerm);
|
||||
}
|
||||
|
||||
if (req.query.sku) {
|
||||
conditions.push('p.SKU LIKE ?');
|
||||
params.push(`%${req.query.sku}%`);
|
||||
}
|
||||
// Handle numeric filters with operators
|
||||
const numericFields = {
|
||||
stock: 'p.stock_quantity',
|
||||
price: 'p.price',
|
||||
costPrice: 'p.cost_price',
|
||||
landingCost: 'p.landing_cost_price',
|
||||
dailySalesAvg: 'pm.daily_sales_avg',
|
||||
weeklySalesAvg: 'pm.weekly_sales_avg',
|
||||
monthlySalesAvg: 'pm.monthly_sales_avg',
|
||||
margin: 'pm.avg_margin_percent',
|
||||
gmroi: 'pm.gmroi',
|
||||
leadTime: 'pm.current_lead_time',
|
||||
stockCoverage: 'pm.days_of_inventory',
|
||||
daysOfStock: 'pm.days_of_inventory'
|
||||
};
|
||||
|
||||
Object.entries(req.query).forEach(([key, value]) => {
|
||||
const field = numericFields[key];
|
||||
if (field) {
|
||||
const operator = req.query[`${key}_operator`] || '=';
|
||||
if (operator === 'between') {
|
||||
// Handle between operator
|
||||
try {
|
||||
const [min, max] = JSON.parse(value);
|
||||
conditions.push(`${field} BETWEEN ? AND ?`);
|
||||
params.push(min, max);
|
||||
} catch (e) {
|
||||
console.error(`Invalid between value for ${key}:`, value);
|
||||
}
|
||||
} else {
|
||||
// Handle other operators
|
||||
conditions.push(`${field} ${operator} ?`);
|
||||
params.push(parseFloat(value));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Handle select filters
|
||||
if (req.query.category && req.query.category !== 'all') {
|
||||
conditions.push(`
|
||||
p.product_id IN (
|
||||
SELECT pc.product_id
|
||||
FROM product_categories pc
|
||||
JOIN categories c ON pc.category_id = c.id
|
||||
WHERE c.name = ?
|
||||
)
|
||||
`);
|
||||
params.push(req.query.category);
|
||||
}
|
||||
|
||||
if (req.query.vendor && req.query.vendor !== 'all') {
|
||||
if (req.query.vendor) {
|
||||
conditions.push('p.vendor = ?');
|
||||
params.push(req.query.vendor);
|
||||
}
|
||||
|
||||
if (req.query.brand && req.query.brand !== 'all') {
|
||||
if (req.query.brand) {
|
||||
conditions.push('p.brand = ?');
|
||||
params.push(req.query.brand);
|
||||
}
|
||||
|
||||
if (req.query.category) {
|
||||
conditions.push('p.categories LIKE ?');
|
||||
params.push(`%${req.query.category}%`);
|
||||
}
|
||||
|
||||
if (req.query.stockStatus && req.query.stockStatus !== 'all') {
|
||||
conditions.push('pm.stock_status = ?');
|
||||
params.push(req.query.stockStatus);
|
||||
}
|
||||
|
||||
if (req.query.abcClass) {
|
||||
conditions.push('pm.abc_class = ?');
|
||||
params.push(req.query.abcClass);
|
||||
}
|
||||
|
||||
// Handle numeric range filters
|
||||
if (req.query.minStock) {
|
||||
conditions.push('p.stock_quantity >= ?');
|
||||
params.push(parseFloat(req.query.minStock));
|
||||
}
|
||||
|
||||
if (req.query.maxStock) {
|
||||
conditions.push('p.stock_quantity <= ?');
|
||||
params.push(parseFloat(req.query.maxStock));
|
||||
}
|
||||
|
||||
if (req.query.daysOfStock) {
|
||||
conditions.push('pm.days_of_inventory >= ?');
|
||||
params.push(parseFloat(req.query.daysOfStock));
|
||||
}
|
||||
|
||||
// Handle boolean filters
|
||||
if (req.query.replenishable === 'true' || req.query.replenishable === 'false') {
|
||||
conditions.push('p.replenishable = ?');
|
||||
params.push(req.query.replenishable === 'true');
|
||||
}
|
||||
|
||||
if (req.query.managingStock === 'true' || req.query.managingStock === 'false') {
|
||||
conditions.push('p.managing_stock = ?');
|
||||
params.push(req.query.managingStock === 'true');
|
||||
}
|
||||
|
||||
// Handle price filters
|
||||
if (req.query.minPrice) {
|
||||
conditions.push('p.price >= ?');
|
||||
params.push(parseFloat(req.query.minPrice));
|
||||
}
|
||||
|
||||
if (req.query.maxPrice) {
|
||||
conditions.push('p.price <= ?');
|
||||
params.push(parseFloat(req.query.maxPrice));
|
||||
}
|
||||
|
||||
if (req.query.minCostPrice) {
|
||||
conditions.push('p.cost_price >= ?');
|
||||
params.push(parseFloat(req.query.minCostPrice));
|
||||
}
|
||||
|
||||
if (req.query.maxCostPrice) {
|
||||
conditions.push('p.cost_price <= ?');
|
||||
params.push(parseFloat(req.query.maxCostPrice));
|
||||
}
|
||||
|
||||
if (req.query.minLandingCost) {
|
||||
conditions.push('p.landing_cost_price >= ?');
|
||||
params.push(parseFloat(req.query.minLandingCost));
|
||||
}
|
||||
|
||||
if (req.query.maxLandingCost) {
|
||||
conditions.push('p.landing_cost_price <= ?');
|
||||
params.push(parseFloat(req.query.maxLandingCost));
|
||||
}
|
||||
|
||||
// Handle sales metrics filters
|
||||
if (req.query.minSalesAvg) {
|
||||
conditions.push('pm.daily_sales_avg >= ?');
|
||||
params.push(parseFloat(req.query.minSalesAvg));
|
||||
}
|
||||
|
||||
if (req.query.maxSalesAvg) {
|
||||
conditions.push('pm.daily_sales_avg <= ?');
|
||||
params.push(parseFloat(req.query.maxSalesAvg));
|
||||
}
|
||||
|
||||
if (req.query.minWeeklySales) {
|
||||
conditions.push('pm.weekly_sales_avg >= ?');
|
||||
params.push(parseFloat(req.query.minWeeklySales));
|
||||
}
|
||||
|
||||
if (req.query.maxWeeklySales) {
|
||||
conditions.push('pm.weekly_sales_avg <= ?');
|
||||
params.push(parseFloat(req.query.maxWeeklySales));
|
||||
}
|
||||
|
||||
if (req.query.minMonthlySales) {
|
||||
conditions.push('pm.monthly_sales_avg >= ?');
|
||||
params.push(parseFloat(req.query.minMonthlySales));
|
||||
}
|
||||
|
||||
if (req.query.maxMonthlySales) {
|
||||
conditions.push('pm.monthly_sales_avg <= ?');
|
||||
params.push(parseFloat(req.query.maxMonthlySales));
|
||||
}
|
||||
|
||||
// Handle financial metrics filters
|
||||
if (req.query.minMargin) {
|
||||
conditions.push('pm.avg_margin_percent >= ?');
|
||||
params.push(parseFloat(req.query.minMargin));
|
||||
}
|
||||
|
||||
if (req.query.maxMargin) {
|
||||
conditions.push('pm.avg_margin_percent <= ?');
|
||||
params.push(parseFloat(req.query.maxMargin));
|
||||
}
|
||||
|
||||
if (req.query.minGMROI) {
|
||||
conditions.push('pm.gmroi >= ?');
|
||||
params.push(parseFloat(req.query.minGMROI));
|
||||
}
|
||||
|
||||
if (req.query.maxGMROI) {
|
||||
conditions.push('pm.gmroi <= ?');
|
||||
params.push(parseFloat(req.query.maxGMROI));
|
||||
}
|
||||
|
||||
// Handle lead time and coverage filters
|
||||
if (req.query.minLeadTime) {
|
||||
conditions.push('pm.avg_lead_time_days >= ?');
|
||||
params.push(parseFloat(req.query.minLeadTime));
|
||||
}
|
||||
|
||||
if (req.query.maxLeadTime) {
|
||||
conditions.push('pm.avg_lead_time_days <= ?');
|
||||
params.push(parseFloat(req.query.maxLeadTime));
|
||||
}
|
||||
|
||||
if (req.query.leadTimeStatus) {
|
||||
conditions.push('pm.lead_time_status = ?');
|
||||
params.push(req.query.leadTimeStatus);
|
||||
}
|
||||
|
||||
if (req.query.minStockCoverage) {
|
||||
conditions.push('(pm.days_of_inventory / pt.target_days) >= ?');
|
||||
params.push(parseFloat(req.query.minStockCoverage));
|
||||
if (req.query.replenishable !== undefined) {
|
||||
conditions.push('p.replenishable = ?');
|
||||
params.push(req.query.replenishable === 'true' ? 1 : 0);
|
||||
}
|
||||
|
||||
if (req.query.maxStockCoverage) {
|
||||
conditions.push('(pm.days_of_inventory / pt.target_days) <= ?');
|
||||
params.push(parseFloat(req.query.maxStockCoverage));
|
||||
}
|
||||
|
||||
// Handle stock status filter
|
||||
if (req.query.stockStatus && req.query.stockStatus !== 'all') {
|
||||
conditions.push('pm.stock_status = ?');
|
||||
params.push(req.query.stockStatus);
|
||||
if (req.query.managingStock !== undefined) {
|
||||
conditions.push('p.managing_stock = ?');
|
||||
params.push(req.query.managingStock === 'true' ? 1 : 0);
|
||||
}
|
||||
|
||||
// Combine all conditions with AND
|
||||
@@ -359,7 +262,7 @@ router.get('/', async (req, res) => {
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error fetching products:', error);
|
||||
res.status(500).json({ error: 'Internal server error' });
|
||||
res.status(500).json({ error: 'Failed to fetch products' });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user