const express = require('express'); const router = express.Router(); const { invoiceRepository, paymentRepository } = require('../repositories'); /** * GET /api/plugins/financials/invoices * Get all invoices for a site or unit */ router.get('/', async (req, res) => { try { const { site_id, unit_id, status, invoice_type } = req.query; if (!site_id) { return res.status(400).json({ success: false, error: 'site_id query parameter is required' }); } let invoices; // Filter by unit_id if provided if (unit_id) { invoices = await invoiceRepository.findByUnitId(unit_id); } else { invoices = await invoiceRepository.findBySiteId(site_id); } // Filter by status if provided if (status) { invoices = invoices.filter(inv => inv.status === status); } // Filter by invoice_type if provided if (invoice_type) { invoices = invoices.filter(inv => inv.invoice_type === invoice_type); } res.json({ success: true, data: invoices, message: 'Invoices retrieved successfully' }); } catch (error) { console.error('Failed to get invoices:', error); res.status(500).json({ success: false, error: 'Failed to retrieve invoices', message: error.message }); } }); /** * GET /api/plugins/financials/invoices/:id * Get invoice 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' }); } const invoice = await invoiceRepository.findById(id); if (!invoice) { return res.status(404).json({ success: false, error: 'Invoice not found' }); } // Verify invoice belongs to site if (invoice.site_id !== site_id) { return res.status(403).json({ success: false, error: 'Access denied' }); } res.json({ success: true, data: invoice, message: 'Invoice details retrieved successfully' }); } catch (error) { console.error('Failed to get invoice:', error); res.status(500).json({ success: false, error: 'Failed to retrieve invoice', message: error.message }); } }); /** * POST /api/plugins/financials/invoices * Create a new invoice */ router.post('/', async (req, res) => { try { const { site_id, unit_id, invoice_number, invoice_type, description, amount, due_date, work_order_id, notes, created_by } = req.body; if (!site_id || !unit_id || !invoice_type || !description || !amount || !due_date) { return res.status(400).json({ success: false, error: 'Missing required fields', message: 'Site ID, unit ID, invoice type, description, amount, and due date are required' }); } const invoice = await invoiceRepository.createInvoice({ site_id, unit_id, invoice_number, invoice_type, description, amount, due_date, work_order_id, notes, created_by: created_by || req.user?.id || 'system' }); res.status(201).json({ success: true, data: invoice, message: 'Invoice created successfully' }); } catch (error) { console.error('Failed to create invoice:', error); if (error.message.includes('already exists')) { return res.status(409).json({ success: false, error: 'Invoice number already exists', message: error.message }); } res.status(500).json({ success: false, error: 'Failed to create invoice', message: error.message }); } }); /** * PUT /api/plugins/financials/invoices/:id/pay * Mark invoice as paid */ router.put('/:id/pay', async (req, res) => { try { const { id } = req.params; const { payment_date, payment_method, payment_reference } = req.body; const { site_id } = req.query; if (!site_id) { return res.status(400).json({ success: false, error: 'site_id is required' }); } // Get invoice first to verify it exists const invoice = await invoiceRepository.findById(id); if (!invoice) { return res.status(404).json({ success: false, error: 'Invoice not found' }); } if (invoice.site_id !== site_id) { return res.status(403).json({ success: false, error: 'Access denied' }); } const updatedInvoice = await invoiceRepository.markAsPaid(id, { payment_date, payment_method, payment_reference }); res.json({ success: true, data: updatedInvoice, message: 'Invoice marked as paid successfully' }); } catch (error) { console.error('Failed to mark invoice as paid:', error); res.status(500).json({ success: false, error: 'Failed to mark invoice as paid', message: error.message }); } }); /** * PUT /api/plugins/financials/invoices/:id * Update invoice */ router.put('/:id', async (req, res) => { try { const { id } = req.params; const { site_id, description, amount, due_date, status, notes } = req.body; if (!site_id) { return res.status(400).json({ success: false, error: 'site_id is required' }); } // Get invoice first const invoice = await invoiceRepository.findById(id); if (!invoice) { return res.status(404).json({ success: false, error: 'Invoice not found' }); } if (invoice.site_id !== site_id) { return res.status(403).json({ success: false, error: 'Access denied' }); } const updatedInvoice = await invoiceRepository.updateById(id, { description, amount, due_date, status, notes, updated_at: new Date().toISOString() }); res.json({ success: true, data: updatedInvoice, message: 'Invoice updated successfully' }); } catch (error) { console.error('Failed to update invoice:', error); res.status(500).json({ success: false, error: 'Failed to update invoice', message: error.message }); } }); /** * GET /api/plugins/financials/invoices/overdue * Get overdue invoices */ router.get('/overdue', async (req, res) => { try { const { site_id } = req.query; if (!site_id) { return res.status(400).json({ success: false, error: 'site_id is required' }); } const overdueInvoices = await invoiceRepository.findOverdue(site_id); res.json({ success: true, data: overdueInvoices, message: 'Overdue invoices retrieved successfully' }); } catch (error) { console.error('Failed to get overdue invoices:', error); res.status(500).json({ success: false, error: 'Failed to retrieve overdue invoices', message: error.message }); } }); module.exports = router;