const express = require('express'); const multer = require('multer'); const { audit, now, one, run } = require('../db'); const { annualSchedule } = require('../depreciation'); const { requireRole } = require('../middleware/auth'); const { createAsset, deleteAsset, hydrateAsset, listAssets, massUpdateAssets, updateAsset } = require('../services/assets'); const { activeRuleSet } = require('../services/reports'); const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 16 * 1024 * 1024 } }); const router = express.Router(); router.get('/assets', (req, res) => { res.json({ assets: listAssets(req.query) }); }); router.post('/assets', requireRole('admin', 'finance', 'operations'), (req, res) => { res.status(201).json({ asset: createAsset(req.body, req.user.id) }); }); router.get('/assets/:id', (req, res) => { const asset = hydrateAsset(req.params.id); if (!asset) return res.status(404).json({ error: 'Asset not found' }); return res.json({ asset }); }); router.put('/assets/:id', requireRole('admin', 'finance', 'operations'), (req, res) => { const asset = updateAsset(req.params.id, req.body, req.user.id); if (!asset) return res.status(404).json({ error: 'Asset not found' }); return res.json({ asset }); }); router.delete('/assets/:id', requireRole('admin', 'finance'), (req, res) => { if (!deleteAsset(req.params.id, req.user.id)) return res.status(404).json({ error: 'Asset not found' }); return res.status(204).end(); }); router.post('/assets/mass-update', requireRole('admin', 'finance'), (req, res) => { const ids = Array.isArray(req.body.ids) ? req.body.ids : []; const updated = massUpdateAssets(ids, req.body.changes || {}, req.user.id); if (!updated) return res.status(400).json({ error: 'Choose assets and editable fields' }); return res.json({ updated }); }); router.get('/assets/:id/depreciation', (req, res) => { const asset = hydrateAsset(req.params.id); if (!asset) return res.status(404).json({ error: 'Asset not found' }); const rules = activeRuleSet(); const startYear = Number(req.query.startYear || new Date().getFullYear()); const endYear = Number(req.query.endYear || startYear + 5); const schedules = asset.books .filter((book) => book.active) .flatMap((book) => annualSchedule(asset, book, rules, { startYear, endYear })); res.json({ assetId: asset.asset_id, schedules }); }); router.post('/assets/:id/files', upload.single('file'), requireRole('admin', 'finance', 'operations'), (req, res) => { if (!req.file) return res.status(400).json({ error: 'File is required' }); const result = run( 'INSERT INTO asset_files (asset_id, file_name, mime_type, size, content_base64, uploaded_by, uploaded_at) VALUES (?, ?, ?, ?, ?, ?, ?)', [req.params.id, req.file.originalname, req.file.mimetype, req.file.size, req.file.buffer.toString('base64'), req.user.id, now()] ); audit(req.user.id, 'upload_file', 'asset', req.params.id, null, { file: req.file.originalname }); res.status(201).json({ file: one('SELECT id, file_name, mime_type, size, uploaded_at FROM asset_files WHERE id = ?', [result.lastInsertRowid]) }); }); router.post('/assets/:id/tasks', requireRole('admin', 'finance', 'operations'), (req, res) => { const created = now(); const result = run( 'INSERT INTO tasks (asset_id, title, type, status, due_date, assigned_to, notes, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', [req.params.id, req.body.title, req.body.type || 'maintenance', req.body.status || 'open', req.body.due_date || null, req.body.assigned_to || null, req.body.notes || null, created, created] ); audit(req.user.id, 'create', 'task', result.lastInsertRowid, null, req.body); res.status(201).json({ task: one('SELECT * FROM tasks WHERE id = ?', [result.lastInsertRowid]) }); }); module.exports = router;