Update frontend to match part 1

This commit is contained in:
2025-01-28 01:30:48 -05:00
parent 8323ae7703
commit 64d9ab2f83
25 changed files with 936 additions and 686 deletions

View File

@@ -29,8 +29,8 @@ router.get('/', async (req, res) => {
const [costMetrics] = await pool.query(`
SELECT
vendor,
ROUND(SUM(ordered * cost_price) / NULLIF(SUM(ordered), 0), 2) as avg_unit_cost,
SUM(ordered * cost_price) as total_spend
CAST(ROUND(SUM(ordered * cost_price) / NULLIF(SUM(ordered), 0), 2) AS DECIMAL(15,3)) as avg_unit_cost,
CAST(SUM(ordered * cost_price) AS DECIMAL(15,3)) as total_spend
FROM purchase_orders
WHERE status = 'closed'
AND cost_price IS NOT NULL
@@ -56,9 +56,9 @@ router.get('/', async (req, res) => {
WHEN COALESCE(vm.total_orders, 0) > 0 AND COALESCE(vm.order_fill_rate, 0) >= 75
THEN p.vendor
END) as activeVendors,
ROUND(AVG(NULLIF(vm.avg_lead_time_days, 0)), 1) as avgLeadTime,
ROUND(AVG(NULLIF(vm.order_fill_rate, 0)), 1) as avgFillRate,
ROUND(AVG(NULLIF(vm.on_time_delivery_rate, 0)), 1) as avgOnTimeDelivery
COALESCE(ROUND(AVG(NULLIF(vm.avg_lead_time_days, 0)), 1), 0) as avgLeadTime,
COALESCE(ROUND(AVG(NULLIF(vm.order_fill_rate, 0)), 1), 0) as avgFillRate,
COALESCE(ROUND(AVG(NULLIF(vm.on_time_delivery_rate, 0)), 1), 0) as avgOnTimeDelivery
FROM products p
LEFT JOIN vendor_metrics vm ON p.vendor = vm.vendor
WHERE p.vendor IS NOT NULL AND p.vendor != ''
@@ -67,8 +67,8 @@ router.get('/', async (req, res) => {
// Get overall cost metrics
const [overallCostMetrics] = await pool.query(`
SELECT
ROUND(SUM(ordered * cost_price) / NULLIF(SUM(ordered), 0), 2) as avg_unit_cost,
SUM(ordered * cost_price) as total_spend
CAST(ROUND(SUM(ordered * cost_price) / NULLIF(SUM(ordered), 0), 2) AS DECIMAL(15,3)) as avg_unit_cost,
CAST(SUM(ordered * cost_price) AS DECIMAL(15,3)) as total_spend
FROM purchase_orders
WHERE status = 'closed'
AND cost_price IS NOT NULL
@@ -78,25 +78,25 @@ router.get('/', async (req, res) => {
res.json({
vendors: vendors.map(vendor => ({
vendor_id: vendor.vendor_id || vendor.name,
vendor_id: vendor.name,
name: vendor.name,
status: vendor.status,
avg_lead_time_days: parseFloat(vendor.avg_lead_time_days || 0),
on_time_delivery_rate: parseFloat(vendor.on_time_delivery_rate || 0),
order_fill_rate: parseFloat(vendor.order_fill_rate || 0),
total_orders: parseInt(vendor.total_orders || 0),
active_products: parseInt(vendor.active_products || 0),
avg_lead_time_days: parseFloat(vendor.avg_lead_time_days),
on_time_delivery_rate: parseFloat(vendor.on_time_delivery_rate),
order_fill_rate: parseFloat(vendor.order_fill_rate),
total_orders: parseInt(vendor.total_orders),
active_products: parseInt(vendor.active_products),
avg_unit_cost: parseFloat(costMetricsMap[vendor.name]?.avg_unit_cost || 0),
total_spend: parseFloat(costMetricsMap[vendor.name]?.total_spend || 0)
})),
stats: {
totalVendors: parseInt(stats[0].totalVendors || 0),
activeVendors: parseInt(stats[0].activeVendors || 0),
avgLeadTime: parseFloat(stats[0].avgLeadTime || 0),
avgFillRate: parseFloat(stats[0].avgFillRate || 0),
avgOnTimeDelivery: parseFloat(stats[0].avgOnTimeDelivery || 0),
avgUnitCost: parseFloat(overallCostMetrics[0].avg_unit_cost || 0),
totalSpend: parseFloat(overallCostMetrics[0].total_spend || 0)
totalVendors: parseInt(stats[0].totalVendors),
activeVendors: parseInt(stats[0].activeVendors),
avgLeadTime: parseFloat(stats[0].avgLeadTime),
avgFillRate: parseFloat(stats[0].avgFillRate),
avgOnTimeDelivery: parseFloat(stats[0].avgOnTimeDelivery),
avgUnitCost: parseFloat(overallCostMetrics[0].avg_unit_cost),
totalSpend: parseFloat(overallCostMetrics[0].total_spend)
}
});
} catch (error) {