Files
John 69b4e68baf
SAP-ERP Portal CI/CD / build (push) Failing after 5m20s
first commit
2026-09-23 17:31:02 +05:30

134 lines
5.2 KiB
JavaScript

'use strict';
const express = require('express');
const router = express.Router();
const { verifyToken } = require('../middleware/auth');
const { getPool } = require('../services/sqlPool');
const store = () => require('../services/balanceSheetStore');
// ── Bootstrap on first require ────────────────────────────────────────────────
store().bootstrap().catch(e => console.error('[BalanceSheet] bootstrap error:', e));
// GET /api/balance-sheet/config
router.get('/config', verifyToken, async (req, res) => {
try {
const cfg = await store().getConfig();
res.json({ success: true, data: cfg, items: store().BS_ITEMS });
} catch (err) { res.status(500).json({ success: false, message: err.message }); }
});
// POST /api/balance-sheet/config body: { group_key, acct_codes[], fixed_value, notes }
router.post('/config', verifyToken, async (req, res) => {
try {
const { group_key, acct_codes, opening_acct_codes, fixed_value, notes } = req.body;
if (!group_key) return res.status(400).json({ success: false, message: 'group_key required' });
await store().saveConfig(group_key, acct_codes, opening_acct_codes, fixed_value, notes);
res.json({ success: true });
} catch (err) { res.status(500).json({ success: false, message: err.message }); }
});
// GET /api/balance-sheet/data?asOf=YYYY-MM-DD&from=YYYY-MM-DD&to=YYYY-MM-DD
router.get('/data', verifyToken, async (req, res) => {
try {
const { asOf, from, to, snapshotId, netProfitOverride } = req.query;
if (!asOf) return res.status(400).json({ success: false, message: 'asOf date required' });
if (!from || !to) return res.status(400).json({ success: false, message: 'from and to required for P&L data' });
const s = store();
const pool = await getPool();
const cfg = await s.getConfig();
const [netProfit, closingStock, totalProvisions] = await Promise.all([
netProfitOverride != null && netProfitOverride !== ''
? Promise.resolve(parseFloat(netProfitOverride))
: snapshotId
? s.fetchNetProfitFromSnapshot(pool, snapshotId)
: s.fetchNetProfit(pool, from, to),
s.fetchClosingStock(pool, from, to),
s.fetchTotalProvisions(pool, from, to),
]);
const values = {};
let reservesDebug = null;
await Promise.all(
s.BS_ITEMS.map(async item => {
const c = cfg[item.key] || {};
let val = 0;
if (item.src === 'fixed') {
val = c.fixed_value != null ? c.fixed_value * 100000 : 0;
} else if (item.src === 'pl_net') {
val = netProfit;
} else if (item.src === 'closing_stock') {
val = closingStock;
} else if (item.src === 'provisions') {
const ledger = await s.fetchGroupBalance(pool, c.acct_codes || [], null, asOf);
val = -ledger + totalProvisions;
} else if (item.src === 'reserves_formula') {
const rd = await s.fetchReservesSurplusDebug(
pool, c.acct_codes || [], c.opening_acct_codes || [], from, to, asOf
);
val = rd.result;
reservesDebug = rd;
} else {
val = await s.fetchGroupBalance(pool, c.acct_codes || [], null, asOf);
}
values[item.key] = val;
})
);
res.json({
success: true,
asOf, from, to,
values,
meta: { net_profit: netProfit, closing_stock: closingStock, total_provisions: totalProvisions },
reserves_debug: reservesDebug,
});
} catch (err) { res.status(500).json({ success: false, message: err.message }); }
});
// GET /api/balance-sheet/snapshot-profit?id= — compute net profit from snapshot period
router.get('/snapshot-profit', verifyToken, async (req, res) => {
try {
const { id } = req.query;
if (!id) return res.status(400).json({ success: false, message: 'id required' });
const pool = await getPool();
const s = store();
const net = await s.fetchNetProfitFromSnapshot(pool, id);
res.json({ success: true, net_profit: net });
} catch (err) { res.status(500).json({ success: false, message: err.message }); }
});
// GET /api/balance-sheet/snapshots — list available P&L snapshots
router.get('/snapshots', verifyToken, async (req, res) => {
try {
const snaps = await require('../services/costingStore').getSnapshots();
res.json({ success: true, data: snaps });
} catch (err) { res.status(500).json({ success: false, message: err.message }); }
});
// GET /api/balance-sheet/accounts?q= — search chart of accounts for configure panel
router.get('/accounts', verifyToken, async (req, res) => {
try {
const { q } = req.query;
const pool = await getPool();
const req2 = pool.request();
let where = `WHERE T0.GroupMask IN (1,2,3)`;
if (q) {
req2.input('q', `%${q}%`);
where += ` AND (T0.AcctCode LIKE @q OR T0.AcctName LIKE @q)`;
}
const r = await req2.query(`
SELECT TOP 100 T0.AcctCode, T0.AcctName, T0.GroupMask
FROM OACT T0
${where}
ORDER BY T0.AcctCode
`);
res.json({ success: true, data: r.recordset });
} catch (err) { res.status(500).json({ success: false, message: err.message }); }
});
module.exports = router;