const db = require("../models"); const logger = require("../services/logger"); const IPICalculationService = require("../services/ipi_calculation_service"); const SubmissionAutoFillService = require("../services/auto_fill_missing_quarterly_submissions_service"); const CalculationLog = db.CalculationLog; // Database configuration const dbConfig = { host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_NAME, dialect: process.env.DB_DIALECT || 'mysql', pool: { max: 5, min: 0, acquire: 30000, idle: 10000 } }; // SELECT // p.id AS product_id, // p.hs_code AS product_hs_code, // s.year, // u.uom_short_name AS unit, // -- Q1 // SUM(CASE WHEN s.quarter = 'Q1' THEN sp.current_quantity_period_one END) AS Jan, // SUM(CASE WHEN s.quarter = 'Q1' THEN sp.current_quantity_period_two END) AS Feb, // SUM(CASE WHEN s.quarter = 'Q1' THEN sp.current_quantity_period_three END)AS Mar, // -- Q2 // SUM(CASE WHEN s.quarter = 'Q2' THEN sp.current_quantity_period_one END) AS Apr, // SUM(CASE WHEN s.quarter = 'Q2' THEN sp.current_quantity_period_two END) AS May, // SUM(CASE WHEN s.quarter = 'Q2' THEN sp.current_quantity_period_three END)AS Jun, // -- Q3 // SUM(CASE WHEN s.quarter = 'Q3' THEN sp.current_quantity_period_one END) AS Jul, // SUM(CASE WHEN s.quarter = 'Q3' THEN sp.current_quantity_period_two END) AS Aug, // SUM(CASE WHEN s.quarter = 'Q3' THEN sp.current_quantity_period_three END)AS Sep, // -- Q4 // SUM(CASE WHEN s.quarter = 'Q4' THEN sp.current_quantity_period_one END) AS Oct, // SUM(CASE WHEN s.quarter = 'Q4' THEN sp.current_quantity_period_two END) AS Nov, // SUM(CASE WHEN s.quarter = 'Q4' THEN sp.current_quantity_period_three END)AS `Dec`, // -- Average (A.M.) Base Year Production // ROUND( // ( // COALESCE(SUM(CASE WHEN s.quarter='Q1' THEN sp.current_quantity_period_one END),0) + // COALESCE(SUM(CASE WHEN s.quarter='Q1' THEN sp.current_quantity_period_two END),0) + // COALESCE(SUM(CASE WHEN s.quarter='Q1' THEN sp.current_quantity_period_three END),0) + // COALESCE(SUM(CASE WHEN s.quarter='Q2' THEN sp.current_quantity_period_one END),0) + // COALESCE(SUM(CASE WHEN s.quarter='Q2' THEN sp.current_quantity_period_two END),0) + // COALESCE(SUM(CASE WHEN s.quarter='Q2' THEN sp.current_quantity_period_three END),0) + // COALESCE(SUM(CASE WHEN s.quarter='Q3' THEN sp.current_quantity_period_one END),0) + // COALESCE(SUM(CASE WHEN s.quarter='Q3' THEN sp.current_quantity_period_two END),0) + // COALESCE(SUM(CASE WHEN s.quarter='Q3' THEN sp.current_quantity_period_three END),0) + // COALESCE(SUM(CASE WHEN s.quarter='Q4' THEN sp.current_quantity_period_one END),0) + // COALESCE(SUM(CASE WHEN s.quarter='Q4' THEN sp.current_quantity_period_two END),0) + // COALESCE(SUM(CASE WHEN s.quarter='Q4' THEN sp.current_quantity_period_three END),0) // ) / 12, // 2) AS avg_by_production // FROM submission_products sp // JOIN submission s ON s.id = sp.submission_id // JOIN products p ON p.id = sp.product_id // LEFT JOIN unit_master u ON u.id = p.unit_id -- if you have units table // WHERE // s.year = 2022 -- base year // AND sp.is_active = 1 // AND s.status = 'Approved' -- optional, recommended // GROUP BY // p.id; // 1. Calculate Base Year Production (Run once for base year 2022) exports.calculate_base_year = async (req, res) => { try { const { baseYear = 2022, forceRecalculate = false } = req.body; const service = new IPICalculationService(dbConfig); const result = await service.calculateBaseYearProduction(baseYear , forceRecalculate); await service.close(); res.json({ success: true, message: `Base year ${baseYear} production calculated successfully`, data: result }); } catch (error) { console.error('Error:', error); res.status(500).json({ success: false, message: 'Error calculating base year production', error: error.message }); } }; // 2. Calculate IPI for Specific Month exports.calculate_month = async (req, res) => { try { // const { year, month } = req.body; const year = 2026; const month = 3; if (!year || !month) { return res.status(400).json({ success: false, message: 'Year and month are required' }); } if (month < 1 || month > 12) { return res.status(400).json({ success: false, message: 'Month must be between 1 and 12' }); } const service = new IPICalculationService(dbConfig); const result = await service.runCompleteCalculation(year, month); await service.close(); res.json({ success: true, message: `IPI calculated for ${year}-${String(month).padStart(2, '0')}`, data: result }); } catch (error) { console.error('Error:', error); res.status(500).json({ success: false, message: 'Error calculating IPI', error: error.message }); } }; // 3. Calculate IPI for Multiple Months exports.calculate_quarter = async (req, res) => { try { const { year, quarter } = req.body; if (!year || !quarter) { return res.status(400).json({ success: false, message: 'Year and quarter are required' }); } // Quarter to month mapping const quarterMap = { Q1: { startMonth: 1, endMonth: 3 }, Q2: { startMonth: 4, endMonth: 6 }, Q3: { startMonth: 7, endMonth: 9 }, Q4: { startMonth: 10, endMonth: 12 }, }; const selectedQuarter = quarterMap[quarter]; if (!selectedQuarter) { return res.status(400).json({ success: false, message: 'Invalid quarter. Accepted values: Q1, Q2, Q3, Q4' }); } const { startMonth, endMonth } = selectedQuarter; const service = new IPICalculationService(dbConfig); const results = []; for (let month = startMonth; month <= endMonth; month++) { const result = await service.runCompleteCalculation(year, month); results.push({ month, ...result }); } await service.close(); res.json({ success: true, message: `IPI calculated for ${year} months ${startMonth}-${endMonth}`, data: results }); } catch (error) { console.error('Error:', error); res.status(500).json({ success: false, message: 'Error calculating IPI range', error: error.message }); } }; // 4. Get Calculation Status/Log exports.calculation_log = async (req, res) => { try { const { year, month, type } = req.query; const service = new IPICalculationService(dbConfig); const connection = await service.pool.getConnection(); let query = ` SELECT * FROM calculation_log WHERE 1=1 `; const params = []; if (year) { query += ` AND reference_year = ?`; params.push(year); } if (month) { query += ` AND reference_month = ?`; params.push(month); } if (type) { query += ` AND calculation_type = ?`; params.push(type); } query += ` ORDER BY started_at DESC LIMIT 100`; const [results] = await connection.query(query, params); connection.release(); await service.close(); res.json({ success: true, data: results}); } catch (error) { console.error('Error:', error); res.status(500).json({ success: false, message: 'Error fetching calculation log', error: error.message }); } }; // 5. Survey Auto Submit exports.survey_auto_submit = async (req, res) => { try { const { year, quarter } = req.body; const autoSubmissionService = new SubmissionAutoFillService(dbConfig); // Auto-fill missing submissions for specific year and quarter const result = await autoSubmissionService.autoFillMissingSubmissions(year, quarter); // Get report for specific quarter // const result2 = await autoSubmissionService.getAutoFillReport(year, quarter); // Verify completeness for specific quarter const result3 = await autoSubmissionService.verifyCompleteness(year, quarter); res.json({ success: true, autoFillMissingSubmissions: result , verifyCompleteness: result3 }); } catch (error) { console.error('Error:', error); res.status(500).json({ success: false, message: '', error: error.message }); } }; exports.getCalculationLogsByYearMonth = async (req, res) => { try { const { year, month } = req.query; if (!year) { return res.status(400).json({ message: "Year is required", }); } if (!month) { return res.status(400).json({ message: "Month is required", }); } const logs = await CalculationLog.findAll({ where: { reference_year: year, reference_month: month, }, order: [["started_at", "DESC"]], }); if (!logs.length) { return res.status(404).json({ message: "No calculation logs found", }); } return res.status(200).json({ message: "Calculation logs fetched successfully", data: logs, }); } catch (err) { logger.error(`Error getting calculation logs: ${err.message }`); logger.error(`Stack trace: ${err.stack}`); return res.status(500).json({ message: "Server error", }); } };