const { outputProgress } = require('./utils/progress'); const { getConnection } = require('./utils/db'); async function calculateBrandMetrics(startTime, totalProducts, processedCount) { const connection = await getConnection(); try { outputProgress({ status: 'running', operation: 'Calculating brand metrics', current: Math.floor(totalProducts * 0.95), total: totalProducts, elapsed: formatElapsedTime(startTime), remaining: estimateRemaining(startTime, Math.floor(totalProducts * 0.95), totalProducts), rate: calculateRate(startTime, Math.floor(totalProducts * 0.95)), percentage: '95' }); // Calculate brand metrics with optimized queries await connection.query(` INSERT INTO brand_metrics ( brand, product_count, active_products, total_stock_units, total_stock_cost, total_stock_retail, total_revenue, avg_margin, growth_rate ) WITH filtered_products AS ( SELECT p.*, CASE WHEN p.stock_quantity <= 5000 THEN p.pid END as valid_pid, CASE WHEN p.visible = true AND p.stock_quantity <= 5000 THEN p.pid END as active_pid, CASE WHEN p.stock_quantity IS NULL OR p.stock_quantity < 0 OR p.stock_quantity > 5000 THEN 0 ELSE p.stock_quantity END as valid_stock FROM products p WHERE p.brand IS NOT NULL ), sales_periods AS ( SELECT p.brand, SUM(o.quantity * o.price) as period_revenue, CASE WHEN o.date >= DATE_SUB(CURRENT_DATE, INTERVAL 3 MONTH) THEN 'current' WHEN o.date BETWEEN DATE_SUB(CURRENT_DATE, INTERVAL 15 MONTH) AND DATE_SUB(CURRENT_DATE, INTERVAL 12 MONTH) THEN 'previous' END as period_type FROM filtered_products p JOIN orders o ON p.pid = o.pid WHERE o.canceled = false AND o.date >= DATE_SUB(CURRENT_DATE, INTERVAL 15 MONTH) GROUP BY p.brand, period_type ), brand_data AS ( SELECT p.brand, COUNT(DISTINCT p.valid_pid) as product_count, COUNT(DISTINCT p.active_pid) as active_products, SUM(p.valid_stock) as total_stock_units, SUM(p.valid_stock * p.cost_price) as total_stock_cost, SUM(p.valid_stock * p.price) as total_stock_retail, COALESCE(SUM(o.quantity * o.price), 0) as total_revenue, CASE WHEN SUM(o.quantity * o.price) > 0 THEN (SUM((o.price - p.cost_price) * o.quantity) * 100.0) / SUM(o.price * o.quantity) ELSE 0 END as avg_margin FROM filtered_products p LEFT JOIN orders o ON p.pid = o.pid AND o.canceled = false GROUP BY p.brand ) SELECT bd.brand, bd.product_count, bd.active_products, bd.total_stock_units, bd.total_stock_cost, bd.total_stock_retail, bd.total_revenue, bd.avg_margin, CASE WHEN MAX(CASE WHEN sp.period_type = 'previous' THEN sp.period_revenue END) = 0 AND MAX(CASE WHEN sp.period_type = 'current' THEN sp.period_revenue END) > 0 THEN 100.0 WHEN MAX(CASE WHEN sp.period_type = 'previous' THEN sp.period_revenue END) = 0 THEN 0.0 ELSE LEAST( GREATEST( ((MAX(CASE WHEN sp.period_type = 'current' THEN sp.period_revenue END) - MAX(CASE WHEN sp.period_type = 'previous' THEN sp.period_revenue END)) / NULLIF(MAX(CASE WHEN sp.period_type = 'previous' THEN sp.period_revenue END), 0)) * 100.0, -100.0 ), 999.99 ) END as growth_rate FROM brand_data bd LEFT JOIN sales_periods sp ON bd.brand = sp.brand GROUP BY bd.brand, bd.product_count, bd.active_products, bd.total_stock_units, bd.total_stock_cost, bd.total_stock_retail, bd.total_revenue, bd.avg_margin ON DUPLICATE KEY UPDATE product_count = VALUES(product_count), active_products = VALUES(active_products), total_stock_units = VALUES(total_stock_units), total_stock_cost = VALUES(total_stock_cost), total_stock_retail = VALUES(total_stock_retail), total_revenue = VALUES(total_revenue), avg_margin = VALUES(avg_margin), growth_rate = VALUES(growth_rate), last_calculated_at = CURRENT_TIMESTAMP `); // Calculate brand time-based metrics with optimized query await connection.query(` INSERT INTO brand_time_metrics ( brand, year, month, product_count, active_products, total_stock_units, total_stock_cost, total_stock_retail, total_revenue, avg_margin ) WITH filtered_products AS ( SELECT p.*, CASE WHEN p.stock_quantity <= 5000 THEN p.pid END as valid_pid, CASE WHEN p.visible = true AND p.stock_quantity <= 5000 THEN p.pid END as active_pid, CASE WHEN p.stock_quantity IS NULL OR p.stock_quantity < 0 OR p.stock_quantity > 5000 THEN 0 ELSE p.stock_quantity END as valid_stock FROM products p WHERE p.brand IS NOT NULL ), monthly_metrics AS ( SELECT p.brand, YEAR(o.date) as year, MONTH(o.date) as month, COUNT(DISTINCT p.valid_pid) as product_count, COUNT(DISTINCT p.active_pid) as active_products, SUM(p.valid_stock) as total_stock_units, SUM(p.valid_stock * p.cost_price) as total_stock_cost, SUM(p.valid_stock * p.price) as total_stock_retail, SUM(o.quantity * o.price) as total_revenue, CASE WHEN SUM(o.quantity * o.price) > 0 THEN (SUM((o.price - p.cost_price) * o.quantity) * 100.0) / SUM(o.price * o.quantity) ELSE 0 END as avg_margin FROM filtered_products p LEFT JOIN orders o ON p.pid = o.pid AND o.canceled = false WHERE o.date >= DATE_SUB(CURRENT_DATE, INTERVAL 12 MONTH) GROUP BY p.brand, YEAR(o.date), MONTH(o.date) ) SELECT * FROM monthly_metrics ON DUPLICATE KEY UPDATE product_count = VALUES(product_count), active_products = VALUES(active_products), total_stock_units = VALUES(total_stock_units), total_stock_cost = VALUES(total_stock_cost), total_stock_retail = VALUES(total_stock_retail), total_revenue = VALUES(total_revenue), avg_margin = VALUES(avg_margin) `); return Math.floor(totalProducts * 0.98); } finally { connection.release(); } } module.exports = calculateBrandMetrics;