Add a bunch of untested calculations enhancements based on import script changes

This commit is contained in:
2025-02-01 14:46:17 -05:00
parent b2d7744cc5
commit 0a51328da2
8 changed files with 659 additions and 76 deletions

View File

@@ -13,7 +13,12 @@ async function calculateTimeAggregates(startTime, totalProducts, processedCount,
elapsed: formatElapsedTime(startTime),
remaining: null,
rate: calculateRate(startTime, processedCount),
percentage: ((processedCount / totalProducts) * 100).toFixed(1)
percentage: ((processedCount / totalProducts) * 100).toFixed(1),
timing: {
start_time: new Date(startTime).toISOString(),
end_time: new Date().toISOString(),
elapsed_seconds: Math.round((Date.now() - startTime) / 1000)
}
});
return processedCount;
}
@@ -26,7 +31,12 @@ async function calculateTimeAggregates(startTime, totalProducts, processedCount,
elapsed: formatElapsedTime(startTime),
remaining: estimateRemaining(startTime, processedCount, totalProducts),
rate: calculateRate(startTime, processedCount),
percentage: ((processedCount / totalProducts) * 100).toFixed(1)
percentage: ((processedCount / totalProducts) * 100).toFixed(1),
timing: {
start_time: new Date(startTime).toISOString(),
end_time: new Date().toISOString(),
elapsed_seconds: Math.round((Date.now() - startTime) / 1000)
}
});
// Initial insert of time-based aggregates
@@ -71,10 +81,40 @@ async function calculateTimeAggregates(startTime, totalProducts, processedCount,
YEAR(date) as year,
MONTH(date) as month,
SUM(received) as stock_received,
SUM(ordered) as stock_ordered
SUM(ordered) as stock_ordered,
COUNT(DISTINCT CASE WHEN receiving_status = 40 THEN id END) as fulfilled_orders,
COUNT(DISTINCT id) as total_orders,
AVG(CASE
WHEN receiving_status = 40
THEN DATEDIFF(received_date, date)
END) as avg_lead_time,
SUM(CASE
WHEN receiving_status = 40 AND received_date > expected_date
THEN 1 ELSE 0
END) as late_deliveries
FROM purchase_orders
WHERE status = 50
GROUP BY pid, YEAR(date), MONTH(date)
),
stock_trends AS (
SELECT
p.pid,
YEAR(po.date) as year,
MONTH(po.date) as month,
AVG(p.stock_quantity) as avg_stock_level,
STDDEV(p.stock_quantity) as stock_volatility,
SUM(CASE
WHEN p.stock_quantity <= COALESCE(pm.reorder_point, 5)
THEN 1 ELSE 0
END) as days_below_reorder,
COUNT(*) as total_days
FROM products p
CROSS JOIN (
SELECT DISTINCT DATE(date) as date
FROM purchase_orders
WHERE date >= DATE_SUB(CURRENT_DATE, INTERVAL 12 MONTH)
) po
LEFT JOIN product_metrics pm ON p.pid = pm.pid
GROUP BY p.pid, YEAR(po.date), MONTH(po.date)
)
SELECT
s.pid,
@@ -87,12 +127,24 @@ async function calculateTimeAggregates(startTime, totalProducts, processedCount,
COALESCE(p.stock_received, 0) as stock_received,
COALESCE(p.stock_ordered, 0) as stock_ordered,
s.avg_price,
s.profit_margin
s.profit_margin,
COALESCE(p.fulfilled_orders, 0) as fulfilled_orders,
COALESCE(p.total_orders, 0) as total_orders,
COALESCE(p.avg_lead_time, 0) as avg_lead_time,
COALESCE(p.late_deliveries, 0) as late_deliveries,
COALESCE(st.avg_stock_level, 0) as avg_stock_level,
COALESCE(st.stock_volatility, 0) as stock_volatility,
COALESCE(st.days_below_reorder, 0) as days_below_reorder,
COALESCE(st.total_days, 0) as total_days
FROM sales_data s
LEFT JOIN purchase_data p
ON s.pid = p.pid
AND s.year = p.year
AND s.month = p.month
LEFT JOIN stock_trends st
ON s.pid = st.pid
AND s.year = st.year
AND s.month = st.month
UNION
SELECT
p.pid,
@@ -105,12 +157,24 @@ async function calculateTimeAggregates(startTime, totalProducts, processedCount,
p.stock_received,
p.stock_ordered,
0 as avg_price,
0 as profit_margin
0 as profit_margin,
p.fulfilled_orders,
p.total_orders,
p.avg_lead_time,
p.late_deliveries,
st.avg_stock_level,
st.stock_volatility,
st.days_below_reorder,
st.total_days
FROM purchase_data p
LEFT JOIN sales_data s
ON p.pid = s.pid
AND p.year = s.year
AND p.month = s.month
LEFT JOIN stock_trends st
ON p.pid = st.pid
AND p.year = st.year
AND p.month = st.month
WHERE s.pid IS NULL
ON DUPLICATE KEY UPDATE
total_quantity_sold = VALUES(total_quantity_sold),
@@ -120,7 +184,8 @@ async function calculateTimeAggregates(startTime, totalProducts, processedCount,
stock_received = VALUES(stock_received),
stock_ordered = VALUES(stock_ordered),
avg_price = VALUES(avg_price),
profit_margin = VALUES(profit_margin)
profit_margin = VALUES(profit_margin),
last_calculated_at = CURRENT_TIMESTAMP
`);
processedCount = Math.floor(totalProducts * 0.60);
@@ -132,7 +197,12 @@ async function calculateTimeAggregates(startTime, totalProducts, processedCount,
elapsed: formatElapsedTime(startTime),
remaining: estimateRemaining(startTime, processedCount, totalProducts),
rate: calculateRate(startTime, processedCount),
percentage: ((processedCount / totalProducts) * 100).toFixed(1)
percentage: ((processedCount / totalProducts) * 100).toFixed(1),
timing: {
start_time: new Date(startTime).toISOString(),
end_time: new Date().toISOString(),
elapsed_seconds: Math.round((Date.now() - startTime) / 1000)
}
});
if (isCancelled) return processedCount;
@@ -161,7 +231,8 @@ async function calculateTimeAggregates(startTime, totalProducts, processedCount,
WHEN COALESCE(fin.inventory_value, 0) > 0 AND fin.days_in_period > 0 THEN
(COALESCE(fin.gross_profit, 0) * (365.0 / fin.days_in_period)) / COALESCE(fin.inventory_value, 0)
ELSE 0
END
END,
pta.last_calculated_at = CURRENT_TIMESTAMP
`);
processedCount = Math.floor(totalProducts * 0.65);
@@ -173,7 +244,12 @@ async function calculateTimeAggregates(startTime, totalProducts, processedCount,
elapsed: formatElapsedTime(startTime),
remaining: estimateRemaining(startTime, processedCount, totalProducts),
rate: calculateRate(startTime, processedCount),
percentage: ((processedCount / totalProducts) * 100).toFixed(1)
percentage: ((processedCount / totalProducts) * 100).toFixed(1),
timing: {
start_time: new Date(startTime).toISOString(),
end_time: new Date().toISOString(),
elapsed_seconds: Math.round((Date.now() - startTime) / 1000)
}
});
return processedCount;