Added Wizard for Month/Year End Close
This commit is contained in:
79
server/routes/close.js
Normal file
79
server/routes/close.js
Normal file
@@ -0,0 +1,79 @@
|
||||
const express = require('express');
|
||||
const { requireCapability } = require('../middleware/auth');
|
||||
const close = require('../services/closePeriods');
|
||||
|
||||
const router = express.Router();
|
||||
const reader = requireCapability('finance.view');
|
||||
const closer = requireCapability('finance.close');
|
||||
|
||||
// Period close (month-end / year-end). All scoped to the active company (req.companyId).
|
||||
|
||||
router.get('/close-periods', reader, (req, res) => {
|
||||
res.json({ periods: close.listPeriods(req.companyId, req.query.book || null) });
|
||||
});
|
||||
|
||||
// Step definitions for the wizard (month vs year).
|
||||
router.get('/close-periods/step-defs', reader, (req, res) => {
|
||||
res.json({ month: close.stepDefs('month'), year: close.stepDefs('year') });
|
||||
});
|
||||
|
||||
router.post('/close-periods/start', closer, (req, res, next) => {
|
||||
try {
|
||||
const period = close.getOrStart(req.companyId, req.body.book, req.body.period_type || 'month', req.body.fiscal_year, req.body.period_month, req.user.id);
|
||||
res.status(201).json({ period, steps: close.stepDefs(period.period_type) });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/close-periods/:id', reader, (req, res) => {
|
||||
const period = close.getPeriod(req.params.id, req.companyId);
|
||||
if (!period) return res.status(404).json({ error: 'Close period not found' });
|
||||
return res.json({ period, steps: close.stepDefs(period.period_type), data: close.stepData(period, req.companyId) });
|
||||
});
|
||||
|
||||
function withPeriod(handler) {
|
||||
return (req, res, next) => {
|
||||
const period = close.getPeriod(req.params.id, req.companyId);
|
||||
if (!period) return res.status(404).json({ error: 'Close period not found' });
|
||||
try {
|
||||
return handler(period, req, res);
|
||||
} catch (error) {
|
||||
return next(error);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
router.post('/close-periods/:id/steps/:key', closer, withPeriod((period, req, res) => {
|
||||
res.json({ period: close.recordStep(period.id, req.params.key, req.body || {}, req.user.id, req.companyId) });
|
||||
}));
|
||||
|
||||
router.post('/close-periods/:id/post-depreciation', closer, withPeriod((period, req, res) => {
|
||||
const summary = close.postDepreciation(period, req.user.id, req.companyId);
|
||||
res.json({ summary, period: close.getPeriod(period.id, req.companyId) });
|
||||
}));
|
||||
|
||||
router.post('/close-periods/:id/post-disposals', closer, withPeriod((period, req, res) => {
|
||||
res.json({ result: close.postDisposalEntries(period, req.user.id, req.companyId) });
|
||||
}));
|
||||
|
||||
router.post('/close-periods/:id/reconcile', closer, withPeriod((period, req, res) => {
|
||||
const reconciliation = close.reconcile(period, req.companyId);
|
||||
res.json({ reconciliation, period: close.getPeriod(period.id, req.companyId) });
|
||||
}));
|
||||
|
||||
router.post('/close-periods/:id/wip/:assetId/capitalize', closer, withPeriod((period, req, res) => {
|
||||
const asset = close.capitalizeWip(Number(req.params.assetId), req.body || {}, req.user.id, req.companyId);
|
||||
if (!asset) return res.status(404).json({ error: 'Asset not found' });
|
||||
return res.json({ asset });
|
||||
}));
|
||||
|
||||
router.post('/close-periods/:id/finalize', closer, withPeriod((period, req, res) => {
|
||||
res.json({ period: close.finalize(period, req.user.id, req.companyId, req.body || {}) });
|
||||
}));
|
||||
|
||||
router.post('/close-periods/:id/reopen', closer, withPeriod((period, req, res) => {
|
||||
res.json({ period: close.reopen(period.id, req.user.id, req.companyId) });
|
||||
}));
|
||||
|
||||
module.exports = router;
|
||||
Reference in New Issue
Block a user