Fix and restyle stock and purchases components
This commit is contained in:
@@ -16,30 +16,60 @@ async function executeQuery(sql, params = []) {
|
||||
router.get('/stock/metrics', async (req, res) => {
|
||||
try {
|
||||
// Get stock metrics
|
||||
const [stockMetrics] = await executeQuery(`
|
||||
const [rows] = await executeQuery(`
|
||||
SELECT
|
||||
COALESCE(COUNT(*), 0) as total_products,
|
||||
COALESCE(COUNT(CASE WHEN stock_quantity > 0 THEN 1 END), 0) as products_in_stock,
|
||||
COALESCE(SUM(stock_quantity), 0) as total_units,
|
||||
COALESCE(SUM(stock_quantity * cost_price), 0) as total_cost,
|
||||
COALESCE(SUM(stock_quantity * price), 0) as total_retail
|
||||
COALESCE(SUM(CASE WHEN stock_quantity > 0 THEN stock_quantity END), 0) as total_units,
|
||||
COALESCE(SUM(CASE WHEN stock_quantity > 0 THEN stock_quantity * cost_price END), 0) as total_cost,
|
||||
COALESCE(SUM(CASE WHEN stock_quantity > 0 THEN stock_quantity * price END), 0) as total_retail
|
||||
FROM products
|
||||
`);
|
||||
const stockMetrics = rows[0];
|
||||
|
||||
// Get vendor stock values
|
||||
const [vendorValues] = await executeQuery(`
|
||||
SELECT
|
||||
vendor,
|
||||
COUNT(DISTINCT product_id) as variant_count,
|
||||
COALESCE(SUM(stock_quantity), 0) as stock_units,
|
||||
COALESCE(SUM(stock_quantity * cost_price), 0) as stock_cost,
|
||||
COALESCE(SUM(stock_quantity * price), 0) as stock_retail
|
||||
FROM products
|
||||
WHERE vendor IS NOT NULL
|
||||
AND stock_quantity > 0
|
||||
GROUP BY vendor
|
||||
HAVING stock_cost > 0
|
||||
ORDER BY stock_cost DESC
|
||||
console.log('Raw stockMetrics from database:', stockMetrics);
|
||||
console.log('stockMetrics.total_products:', stockMetrics.total_products);
|
||||
console.log('stockMetrics.products_in_stock:', stockMetrics.products_in_stock);
|
||||
console.log('stockMetrics.total_units:', stockMetrics.total_units);
|
||||
console.log('stockMetrics.total_cost:', stockMetrics.total_cost);
|
||||
console.log('stockMetrics.total_retail:', stockMetrics.total_retail);
|
||||
|
||||
// Get brand stock values with Other category
|
||||
const [brandValues] = await executeQuery(`
|
||||
WITH brand_totals AS (
|
||||
SELECT
|
||||
brand,
|
||||
COUNT(DISTINCT product_id) as variant_count,
|
||||
COALESCE(SUM(stock_quantity), 0) as stock_units,
|
||||
COALESCE(SUM(stock_quantity * cost_price), 0) as stock_cost,
|
||||
COALESCE(SUM(stock_quantity * price), 0) as stock_retail
|
||||
FROM products
|
||||
WHERE brand IS NOT NULL
|
||||
AND stock_quantity > 0
|
||||
GROUP BY brand
|
||||
HAVING stock_cost > 0
|
||||
),
|
||||
other_brands AS (
|
||||
SELECT
|
||||
'Other' as brand,
|
||||
SUM(variant_count) as variant_count,
|
||||
SUM(stock_units) as stock_units,
|
||||
SUM(stock_cost) as stock_cost,
|
||||
SUM(stock_retail) as stock_retail
|
||||
FROM brand_totals
|
||||
WHERE stock_cost <= 5000
|
||||
),
|
||||
main_brands AS (
|
||||
SELECT *
|
||||
FROM brand_totals
|
||||
WHERE stock_cost > 5000
|
||||
ORDER BY stock_cost DESC
|
||||
)
|
||||
SELECT * FROM main_brands
|
||||
UNION ALL
|
||||
SELECT * FROM other_brands
|
||||
WHERE stock_cost > 0
|
||||
ORDER BY CASE WHEN brand = 'Other' THEN 1 ELSE 0 END, stock_cost DESC
|
||||
`);
|
||||
|
||||
// Format the response with explicit type conversion
|
||||
@@ -49,8 +79,8 @@ router.get('/stock/metrics', async (req, res) => {
|
||||
totalStockUnits: parseInt(stockMetrics.total_units) || 0,
|
||||
totalStockCost: parseFloat(stockMetrics.total_cost) || 0,
|
||||
totalStockRetail: parseFloat(stockMetrics.total_retail) || 0,
|
||||
vendorStock: vendorValues.map(v => ({
|
||||
vendor: v.vendor,
|
||||
brandStock: brandValues.map(v => ({
|
||||
brand: v.brand,
|
||||
variants: parseInt(v.variant_count) || 0,
|
||||
units: parseInt(v.stock_units) || 0,
|
||||
cost: parseFloat(v.stock_cost) || 0,
|
||||
@@ -69,7 +99,7 @@ router.get('/stock/metrics', async (req, res) => {
|
||||
// Returns purchase order metrics by vendor
|
||||
router.get('/purchase/metrics', async (req, res) => {
|
||||
try {
|
||||
const [poMetrics] = await executeQuery(`
|
||||
const [rows] = await executeQuery(`
|
||||
SELECT
|
||||
COALESCE(COUNT(DISTINCT CASE WHEN po.status = 'open' THEN po.po_id END), 0) as active_pos,
|
||||
COALESCE(COUNT(DISTINCT CASE
|
||||
@@ -90,6 +120,14 @@ router.get('/purchase/metrics', async (req, res) => {
|
||||
FROM purchase_orders po
|
||||
JOIN products p ON po.product_id = p.product_id
|
||||
`);
|
||||
const poMetrics = rows[0];
|
||||
|
||||
console.log('Raw poMetrics from database:', poMetrics);
|
||||
console.log('poMetrics.active_pos:', poMetrics.active_pos);
|
||||
console.log('poMetrics.overdue_pos:', poMetrics.overdue_pos);
|
||||
console.log('poMetrics.total_units:', poMetrics.total_units);
|
||||
console.log('poMetrics.total_cost:', poMetrics.total_cost);
|
||||
console.log('poMetrics.total_retail:', poMetrics.total_retail);
|
||||
|
||||
const [vendorOrders] = await executeQuery(`
|
||||
SELECT
|
||||
@@ -106,7 +144,7 @@ router.get('/purchase/metrics', async (req, res) => {
|
||||
ORDER BY order_cost DESC
|
||||
`);
|
||||
|
||||
res.json({
|
||||
const response = {
|
||||
activePurchaseOrders: parseInt(poMetrics.active_pos) || 0,
|
||||
overduePurchaseOrders: parseInt(poMetrics.overdue_pos) || 0,
|
||||
onOrderUnits: parseInt(poMetrics.total_units) || 0,
|
||||
@@ -119,7 +157,9 @@ router.get('/purchase/metrics', async (req, res) => {
|
||||
cost: parseFloat(v.order_cost) || 0,
|
||||
retail: parseFloat(v.order_retail) || 0
|
||||
}))
|
||||
});
|
||||
};
|
||||
|
||||
res.json(response);
|
||||
} catch (err) {
|
||||
console.error('Error fetching purchase metrics:', err);
|
||||
res.status(500).json({ error: 'Failed to fetch purchase metrics' });
|
||||
|
||||
Reference in New Issue
Block a user