// server/budget-helpers.js — Budget availability calculations // Single source of truth: BudgetEntries table const nocodb = require('./nocodb'); function computeFromEntries(entries) { const income = entries.filter(e => (e.type || 'income') === 'income'); const expenses = entries.filter(e => e.type === 'expense'); const totalReceived = income.reduce((s, e) => s + (e.amount || 0), 0); const totalExpenses = expenses.reduce((s, e) => s + (e.amount || 0), 0); const totalCampaignBudget = income.filter(e => e.campaign_id).reduce((s, e) => s + (e.amount || 0), 0); const totalProjectBudget = income.filter(e => e.project_id).reduce((s, e) => s + (e.amount || 0), 0); return { totalReceived, totalExpenses, totalCampaignBudget, totalProjectBudget, available: totalReceived - totalExpenses - totalCampaignBudget - totalProjectBudget }; } async function getMainAvailable(prefetchedEntries) { const entries = prefetchedEntries || await nocodb.list('BudgetEntries', { limit: 10000 }); return computeFromEntries(entries); } async function getCampaignAvailable(campaignId, prefetchedEntries) { const entries = prefetchedEntries || await nocodb.list('BudgetEntries', { limit: 10000 }); const campaignIncome = entries.filter(e => e.campaign_id && Number(e.campaign_id) === Number(campaignId) && (e.type || 'income') === 'income' ); const allocated = campaignIncome.reduce((s, e) => s + (e.amount || 0), 0); const tracks = await nocodb.list('CampaignTracks', { where: `(campaign_id,eq,${campaignId})`, limit: 10000, }); const trackAllocated = tracks.reduce((s, t) => s + (t.budget_allocated || 0), 0); return { allocated, trackAllocated, available: allocated - trackAllocated }; } async function getCampaignAllocatedFromEntries(campaignId, prefetchedEntries) { const entries = prefetchedEntries || await nocodb.list('BudgetEntries', { limit: 10000 }); return entries .filter(e => e.campaign_id && Number(e.campaign_id) === Number(campaignId) && (e.type || 'income') === 'income') .reduce((s, e) => s + (e.amount || 0), 0); } async function getAllBudgetData() { const entries = await nocodb.list('BudgetEntries', { limit: 10000 }); const main = computeFromEntries(entries); return { entries, ...main }; } module.exports = { getMainAvailable, getCampaignAvailable, getCampaignAllocatedFromEntries, getAllBudgetData, computeFromEntries };