Updates for new analytics page + add pipeline chart to PO page
This commit is contained in:
@@ -1185,4 +1185,67 @@ router.get('/delivery-metrics', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
// PO Pipeline — expected arrivals timeline + overdue summary
|
||||
router.get('/pipeline', async (req, res) => {
|
||||
try {
|
||||
const pool = req.app.locals.pool;
|
||||
|
||||
// Expected arrivals by week (ordered + electronically_sent with expected_date)
|
||||
const { rows: arrivals } = await pool.query(`
|
||||
SELECT
|
||||
DATE_TRUNC('week', expected_date)::date AS week,
|
||||
COUNT(DISTINCT po_id) AS po_count,
|
||||
ROUND(SUM(po_cost_price * ordered)::numeric, 0) AS expected_value,
|
||||
COUNT(DISTINCT vendor) AS vendor_count
|
||||
FROM purchase_orders
|
||||
WHERE status IN ('ordered', 'electronically_sent')
|
||||
AND expected_date IS NOT NULL
|
||||
GROUP BY 1
|
||||
ORDER BY 1
|
||||
`);
|
||||
|
||||
// Overdue POs (expected_date in the past)
|
||||
const { rows: [overdue] } = await pool.query(`
|
||||
SELECT
|
||||
COUNT(DISTINCT po_id) AS po_count,
|
||||
ROUND(COALESCE(SUM(po_cost_price * ordered), 0)::numeric, 0) AS total_value
|
||||
FROM purchase_orders
|
||||
WHERE status IN ('ordered', 'electronically_sent')
|
||||
AND expected_date IS NOT NULL
|
||||
AND expected_date < CURRENT_DATE
|
||||
`);
|
||||
|
||||
// Summary: all open POs
|
||||
const { rows: [summary] } = await pool.query(`
|
||||
SELECT
|
||||
COUNT(DISTINCT po_id) AS total_open_pos,
|
||||
ROUND(COALESCE(SUM(po_cost_price * ordered), 0)::numeric, 0) AS total_on_order_value,
|
||||
COUNT(DISTINCT vendor) AS vendor_count
|
||||
FROM purchase_orders
|
||||
WHERE status IN ('ordered', 'electronically_sent')
|
||||
`);
|
||||
|
||||
res.json({
|
||||
arrivals: arrivals.map(r => ({
|
||||
week: r.week,
|
||||
poCount: Number(r.po_count) || 0,
|
||||
expectedValue: Number(r.expected_value) || 0,
|
||||
vendorCount: Number(r.vendor_count) || 0,
|
||||
})),
|
||||
overdue: {
|
||||
count: Number(overdue.po_count) || 0,
|
||||
value: Number(overdue.total_value) || 0,
|
||||
},
|
||||
summary: {
|
||||
totalOpenPOs: Number(summary.total_open_pos) || 0,
|
||||
totalOnOrderValue: Number(summary.total_on_order_value) || 0,
|
||||
vendorCount: Number(summary.vendor_count) || 0,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error fetching PO pipeline:', error);
|
||||
res.status(500).json({ error: 'Failed to fetch PO pipeline' });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
Reference in New Issue
Block a user