fcsc_ipi_backend/app/controllers/calculation.controller.js

293 lines
8.5 KiB
JavaScript

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");
// 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
});
}
};