import { createReducer } from '@reduxjs/toolkit'; import t from 'store/types'; import { // getBalanceSheetIndexByQuery, getFinancialSheetIndexByQuery, // getFinancialSheetIndexByQuery, } from './financialStatements.selectors'; import {omit} from 'lodash'; const initialState = { balanceSheet: { sheets: [], loading: false, filter: true, }, trialBalance: { sheets: [], loading: false, filter: true, }, generalLedger: { sheets: [], loading: false, filter: true, }, journal: { sheets: [], loading: false, tableRows: [], filter: true, }, profitLoss: { sheets: [], loading: false, tableRows: [], filter: true, } }; const mapGeneralLedgerAccountsToRows = (accounts) => { return accounts.reduce((tableRows, account) => { const children = []; children.push({ ...account.opening, rowType: 'opening_balance', }); account.transactions.map((transaction) => { children.push({ ...transaction, ...omit(account, ['transactions']), rowType: 'transaction' }); }); children.push({ ...account.closing, rowType: 'closing_balance', }); tableRows.push({ ...omit(account, ['transactions']), children, rowType: 'account_name', }); return tableRows; }, []); } const mapJournalTableRows = (journal) => { return journal.reduce((rows, journal) => { journal.entries.forEach((entry, index) => { rows.push({ ...entry, rowType: (index === 0) ? 'first_entry' : 'entry' }); }); rows.push({ credit: journal.credit, debit: journal.debit, rowType: 'entries_total', }); rows.push({ rowType: 'space_entry', }); return rows; }, []); } const mapProfitLossToTableRows = (profitLoss) => { return [ { name: 'Income', total: profitLoss.income.total, children: [ ...profitLoss.income.accounts, { name: 'Total Income', total: profitLoss.income.total, rowType: 'income_total', } ], }, { name: 'Expenses', total: profitLoss.expenses.total, children: [ ...profitLoss.expenses.accounts, { name: 'Total Expenses', total: profitLoss.expenses.total, rowType: 'expense_total', } ], }, { name: 'Net Income', total: profitLoss.net_income.total, rowType: 'net_income', } ] }; const financialStatementFilterToggle = (financialName, statePath) => { return { [`${financialName}_FILTER_TOGGLE`]: (state, action) => { state[statePath].filter = !state[statePath].filter; }, } }; export default createReducer(initialState, { [t.BALANCE_SHEET_STATEMENT_SET]: (state, action) => { const index = getFinancialSheetIndexByQuery(state.balanceSheet.sheets, action.query); const balanceSheet = { accounts: action.data.accounts, columns: Object.values(action.data.columns), query: action.data.query, }; if (index !== -1) { state.balanceSheet.sheets[index] = balanceSheet; } else { state.balanceSheet.sheets.push(balanceSheet); } }, [t.BALANCE_SHEET_LOADING]: (state, action) => { state.balanceSheet.loading = !!action.loading; }, ...financialStatementFilterToggle('BALANCE_SHEET', 'balanceSheet'), [t.TRAIL_BALANCE_STATEMENT_SET]: (state, action) => { const index = getFinancialSheetIndexByQuery(state.trialBalance.sheets, action.query); const trailBalanceSheet = { accounts: action.data.accounts, query: action.data.query, }; if (index !== -1) { state.trialBalance.sheets[index] = trailBalanceSheet; } else { state.trialBalance.sheets.push(trailBalanceSheet); } }, [t.TRIAL_BALANCE_SHEET_LOADING]: (state, action) => { state.trialBalance.loading = !!action.loading; }, ...financialStatementFilterToggle('TRIAL_BALANCE', 'trialBalance'), [t.JOURNAL_SHEET_SET]: (state, action) => { const index = getFinancialSheetIndexByQuery(state.journal.sheets, action.query); const journal = { query: action.data.query, journal: action.data.journal, tableRows: mapJournalTableRows(action.data.journal), }; if (index !== -1) { state.journal.sheets[index] = journal; } else { state.journal.sheets.push(journal); } }, [t.JOURNAL_SHEET_LOADING]: (state, action) => { state.journal.loading = !!action.loading; }, ...financialStatementFilterToggle('JOURNAL', 'journal'), [t.GENERAL_LEDGER_STATEMENT_SET]: (state, action) => { const index = getFinancialSheetIndexByQuery(state.generalLedger.sheets, action.query); const generalLedger = { query: action.data.query, accounts: action.data.accounts, tableRows: mapGeneralLedgerAccountsToRows(action.data.accounts), }; if (index !== -1) { state.generalLedger.sheets[index] = generalLedger; } else { state.generalLedger.sheets.push(generalLedger); } }, [t.GENERAL_LEDGER_SHEET_LOADING]: (state, action) => { state.generalLedger.loading = !!action.loading; }, ...financialStatementFilterToggle('GENERAL_LEDGER', 'generalLedger'), [t.PROFIT_LOSS_SHEET_SET]: (state, action) => { const index = getFinancialSheetIndexByQuery(state.profitLoss.sheets, action.query); const profitLossSheet = { query: action.query, profitLoss: action.profitLoss, columns: action.columns, tableRows: mapProfitLossToTableRows(action.profitLoss), }; if (index !== -1) { state.profitLoss.sheets[index] = profitLossSheet; } else { state.profitLoss.sheets.push(profitLossSheet); } }, [t.PROFIT_LOSS_SHEET_LOADING]: (state, action) => { state.profitLoss.loading = !!action.loading; }, ...financialStatementFilterToggle('PROFIT_LOSS', 'profitLoss'), });