const express = require('express'); const router = express.Router(); const { budgetRepository, budgetItemRepository } = require('../repositories'); /** * Check if site has access to budgeting feature (premium) * Budgeting is available in Professional and Enterprise plans */ async function hasBudgetingAccess(site_id) { // TODO: Implement subscription check // For now, assume all sites have access for testing return true; } /** * GET /api/plugins/financials/budgets * Get all budgets for a site */ router.get('/', async (req, res) => { try { const { site_id } = req.query; if (!site_id) { return res.status(400).json({ success: false, error: 'site_id query parameter is required' }); } // Check feature access if (!(await hasBudgetingAccess(site_id))) { return res.status(403).json({ success: false, error: 'Budgeting feature not available', message: 'Please upgrade to Professional or Enterprise plan to access budgeting features' }); } const budgets = await budgetRepository.findBySiteId(site_id); res.json({ success: true, data: budgets, message: 'Budgets retrieved successfully' }); } catch (error) { console.error('Failed to get budgets:', error); res.status(500).json({ success: false, error: 'Failed to retrieve budgets', message: error.message }); } }); /** * GET /api/plugins/financials/budgets/:id * Get budget by ID */ router.get('/:id', async (req, res) => { try { const { id } = req.params; const { site_id } = req.query; if (!site_id) { return res.status(400).json({ success: false, error: 'site_id is required' }); } // Check feature access if (!(await hasBudgetingAccess(site_id))) { return res.status(403).json({ success: false, error: 'Budgeting feature not available', message: 'Please upgrade to Professional or Enterprise plan to access budgeting features' }); } const budget = await budgetRepository.findById(id); if (!budget) { return res.status(404).json({ success: false, error: 'Budget not found' }); } // Verify budget belongs to site if (budget.site_id !== site_id) { return res.status(403).json({ success: false, error: 'Access denied' }); } // Get budget items const items = await budgetItemRepository.findByBudgetId(id); res.json({ success: true, data: { ...budget, items }, message: 'Budget details retrieved successfully' }); } catch (error) { console.error('Failed to get budget:', error); res.status(500).json({ success: false, error: 'Failed to retrieve budget', message: error.message }); } }); /** * POST /api/plugins/financials/budgets * Create a new budget */ router.post('/', async (req, res) => { try { const { site_id, name, description, fiscal_year, start_date, end_date, total_amount, status, items, created_by } = req.body; if (!site_id || !name || !fiscal_year || !start_date || !end_date || !total_amount) { return res.status(400).json({ success: false, error: 'Missing required fields', message: 'Site ID, name, fiscal year, start date, end date, and total amount are required' }); } // Check feature access if (!(await hasBudgetingAccess(site_id))) { return res.status(403).json({ success: false, error: 'Budgeting feature not available', message: 'Please upgrade to Professional or Enterprise plan to access budgeting features' }); } const budget = await budgetRepository.createBudget({ site_id, name, description, fiscal_year, start_date, end_date, total_amount, status, created_by: created_by || req.user?.id || 'system' }); // Create budget items if provided if (items && Array.isArray(items)) { for (const item of items) { await budgetItemRepository.createItem({ budget_id: budget.id, account_id: item.account_id, planned_amount: item.planned_amount, notes: item.notes }); } } res.status(201).json({ success: true, data: budget, message: 'Budget created successfully' }); } catch (error) { console.error('Failed to create budget:', error); res.status(500).json({ success: false, error: 'Failed to create budget', message: error.message }); } }); /** * POST /api/plugins/financials/budgets/:id/items * Add budget item */ router.post('/:id/items', async (req, res) => { try { const { id } = req.params; const { account_id, planned_amount, notes } = req.body; const { site_id } = req.query; if (!site_id) { return res.status(400).json({ success: false, error: 'site_id is required' }); } // Validate required fields if (!account_id || !planned_amount) { return res.status(400).json({ success: false, error: 'Missing required fields', message: 'Account ID and planned amount are required' }); } // Check feature access if (!(await hasBudgetingAccess(site_id))) { return res.status(403).json({ success: false, error: 'Budgeting feature not available', message: 'Please upgrade to Professional or Enterprise plan to access budgeting features' }); } const item = await budgetItemRepository.createItem({ budget_id: id, account_id, planned_amount, notes }); res.status(201).json({ success: true, data: item, message: 'Budget item added successfully' }); } catch (error) { console.error('Failed to add budget item:', error); res.status(500).json({ success: false, error: 'Failed to add budget item', message: error.message }); } }); module.exports = router;