mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-19 06:10:31 +00:00
feat: Receivable aging summary front-end.
This commit is contained in:
@@ -2,7 +2,6 @@ import { createReducer } from '@reduxjs/toolkit';
|
||||
import { createTableQueryReducers } from 'store/queryReducers';
|
||||
|
||||
import t from 'store/types';
|
||||
import { omit } from 'lodash';
|
||||
|
||||
const initialState = {
|
||||
items: {},
|
||||
@@ -90,7 +89,5 @@ const reducer = createReducer(initialState, {
|
||||
export default createTableQueryReducers('expenses', reducer);
|
||||
|
||||
export const getExpenseById = (state, id) => {
|
||||
// debugger;
|
||||
// state.items = omit(state.items, [id]);
|
||||
return state.expenses.items[id];
|
||||
return state.expenses.items[id] || {};
|
||||
};
|
||||
|
||||
@@ -23,9 +23,6 @@ export const fetchGeneralLedger = ({ query }) => {
|
||||
|
||||
export const fetchBalanceSheet = ({ query }) => {
|
||||
return (dispatch) => new Promise((resolve, reject) => {
|
||||
dispatch({
|
||||
type: t.SET_DASHBOARD_REQUEST_LOADING,
|
||||
});
|
||||
dispatch({
|
||||
type: t.BALANCE_SHEET_LOADING,
|
||||
loading: true,
|
||||
@@ -109,4 +106,37 @@ export const fetchJournalSheet = ({ query }) => {
|
||||
resolve(response.data);
|
||||
}).catch(error => { reject(error); });
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
export const fetchReceivableAgingSummary = ({ query }) => {
|
||||
return (dispatch) => new Promise((resolve, reject) => {
|
||||
dispatch({
|
||||
type: t.RECEIVABLE_AGING_SUMMARY_LOADING,
|
||||
payload: {
|
||||
loading: true,
|
||||
},
|
||||
});
|
||||
ApiService
|
||||
.get('/financial_statements/receivable_aging_summary', { params: query })
|
||||
.then((response) => {
|
||||
dispatch({
|
||||
type: t.RECEIVABLE_AGING_SUMMARY_SET,
|
||||
payload: {
|
||||
aging: response.data.aging,
|
||||
columns: response.data.columns,
|
||||
query,
|
||||
},
|
||||
});
|
||||
dispatch({
|
||||
type: t.RECEIVABLE_AGING_SUMMARY_LOADING,
|
||||
payload: {
|
||||
loading: false,
|
||||
},
|
||||
});
|
||||
resolve(response);
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
})
|
||||
});
|
||||
}
|
||||
@@ -1,11 +1,9 @@
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import t from 'store/types';
|
||||
import {
|
||||
// getBalanceSheetIndexByQuery,
|
||||
getFinancialSheetIndexByQuery,
|
||||
// getFinancialSheetIndexByQuery,
|
||||
} from './financialStatements.selectors';
|
||||
import {omit} from 'lodash';
|
||||
import { omit } from 'lodash';
|
||||
|
||||
const initialState = {
|
||||
balanceSheet: {
|
||||
@@ -34,38 +32,48 @@ const initialState = {
|
||||
loading: false,
|
||||
tableRows: [],
|
||||
filter: true,
|
||||
}
|
||||
},
|
||||
receivableAgingSummary: {
|
||||
sheets: [],
|
||||
loading: false,
|
||||
tableRows: [],
|
||||
filter: true,
|
||||
},
|
||||
};
|
||||
|
||||
const mapGeneralLedgerAccountsToRows = (accounts) => {
|
||||
return accounts.reduce((tableRows, account) => {
|
||||
const children = [];
|
||||
children.push({
|
||||
...account.opening, rowType: 'opening_balance',
|
||||
...account.opening,
|
||||
rowType: 'opening_balance',
|
||||
});
|
||||
account.transactions.map((transaction) => {
|
||||
children.push({
|
||||
...transaction, ...omit(account, ['transactions']),
|
||||
rowType: 'transaction'
|
||||
...transaction,
|
||||
...omit(account, ['transactions']),
|
||||
rowType: 'transaction',
|
||||
});
|
||||
});
|
||||
children.push({
|
||||
...account.closing, rowType: 'closing_balance',
|
||||
...account.closing,
|
||||
rowType: 'closing_balance',
|
||||
});
|
||||
tableRows.push({
|
||||
...omit(account, ['transactions']), children,
|
||||
...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'
|
||||
rowType: index === 0 ? 'first_entry' : 'entry',
|
||||
});
|
||||
});
|
||||
rows.push({
|
||||
@@ -78,8 +86,7 @@ const mapJournalTableRows = (journal) => {
|
||||
});
|
||||
return rows;
|
||||
}, []);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const mapProfitLossToTableRows = (profitLoss) => {
|
||||
return [
|
||||
@@ -92,7 +99,7 @@ const mapProfitLossToTableRows = (profitLoss) => {
|
||||
name: 'Total Income',
|
||||
total: profitLoss.income.total,
|
||||
rowType: 'income_total',
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -104,15 +111,15 @@ const mapProfitLossToTableRows = (profitLoss) => {
|
||||
name: 'Total Expenses',
|
||||
total: profitLoss.expenses.total,
|
||||
rowType: 'expense_total',
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Net Income',
|
||||
total: profitLoss.net_income.total,
|
||||
total: profitLoss.net_income.total,
|
||||
rowType: 'net_income',
|
||||
}
|
||||
]
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
const financialStatementFilterToggle = (financialName, statePath) => {
|
||||
@@ -120,13 +127,16 @@ const financialStatementFilterToggle = (financialName, statePath) => {
|
||||
[`${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 index = getFinancialSheetIndexByQuery(
|
||||
state.balanceSheet.sheets,
|
||||
action.query,
|
||||
);
|
||||
|
||||
const balanceSheet = {
|
||||
accounts: action.data.accounts,
|
||||
columns: Object.values(action.data.columns),
|
||||
@@ -145,7 +155,10 @@ export default createReducer(initialState, {
|
||||
...financialStatementFilterToggle('BALANCE_SHEET', 'balanceSheet'),
|
||||
|
||||
[t.TRAIL_BALANCE_STATEMENT_SET]: (state, action) => {
|
||||
const index = getFinancialSheetIndexByQuery(state.trialBalance.sheets, action.query);
|
||||
const index = getFinancialSheetIndexByQuery(
|
||||
state.trialBalance.sheets,
|
||||
action.query,
|
||||
);
|
||||
const trailBalanceSheet = {
|
||||
accounts: action.data.accounts,
|
||||
query: action.data.query,
|
||||
@@ -163,7 +176,10 @@ export default createReducer(initialState, {
|
||||
...financialStatementFilterToggle('TRIAL_BALANCE', 'trialBalance'),
|
||||
|
||||
[t.JOURNAL_SHEET_SET]: (state, action) => {
|
||||
const index = getFinancialSheetIndexByQuery(state.journal.sheets, action.query);
|
||||
const index = getFinancialSheetIndexByQuery(
|
||||
state.journal.sheets,
|
||||
action.query,
|
||||
);
|
||||
|
||||
const journal = {
|
||||
query: action.data.query,
|
||||
@@ -183,8 +199,11 @@ export default createReducer(initialState, {
|
||||
...financialStatementFilterToggle('JOURNAL', 'journal'),
|
||||
|
||||
[t.GENERAL_LEDGER_STATEMENT_SET]: (state, action) => {
|
||||
const index = getFinancialSheetIndexByQuery(state.generalLedger.sheets, action.query);
|
||||
|
||||
const index = getFinancialSheetIndexByQuery(
|
||||
state.generalLedger.sheets,
|
||||
action.query,
|
||||
);
|
||||
|
||||
const generalLedger = {
|
||||
query: action.data.query,
|
||||
accounts: action.data.accounts,
|
||||
@@ -203,7 +222,10 @@ export default createReducer(initialState, {
|
||||
...financialStatementFilterToggle('GENERAL_LEDGER', 'generalLedger'),
|
||||
|
||||
[t.PROFIT_LOSS_SHEET_SET]: (state, action) => {
|
||||
const index = getFinancialSheetIndexByQuery(state.profitLoss.sheets, action.query);
|
||||
const index = getFinancialSheetIndexByQuery(
|
||||
state.profitLoss.sheets,
|
||||
action.query,
|
||||
);
|
||||
|
||||
const profitLossSheet = {
|
||||
query: action.query,
|
||||
@@ -212,7 +234,7 @@ export default createReducer(initialState, {
|
||||
tableRows: mapProfitLossToTableRows(action.profitLoss),
|
||||
};
|
||||
if (index !== -1) {
|
||||
state.profitLoss.sheets[index] = profitLossSheet;
|
||||
state.profitLoss.sheets[index] = profitLossSheet;
|
||||
} else {
|
||||
state.profitLoss.sheets.push(profitLossSheet);
|
||||
}
|
||||
@@ -222,4 +244,27 @@ export default createReducer(initialState, {
|
||||
state.profitLoss.loading = !!action.loading;
|
||||
},
|
||||
...financialStatementFilterToggle('PROFIT_LOSS', 'profitLoss'),
|
||||
});
|
||||
|
||||
[t.RECEIVABLE_AGING_SUMMARY_LOADING]: (state, action) => {
|
||||
const { loading } = action.payload;
|
||||
state.receivableAgingSummary.loading = loading;
|
||||
},
|
||||
|
||||
[t.RECEIVABLE_AGING_SUMMARY_SET]: (state, action) => {
|
||||
const { aging, columns, query } = action.payload;
|
||||
const index = getFinancialSheetIndexByQuery(state.receivableAgingSummary.sheets, query);
|
||||
|
||||
const receivableSheet = {
|
||||
query,
|
||||
columns,
|
||||
aging,
|
||||
tableRows: aging
|
||||
};
|
||||
if (index !== -1) {
|
||||
state.receivableAgingSummary[index] = receivableSheet;
|
||||
} else {
|
||||
state.receivableAgingSummary.sheets.push(receivableSheet);
|
||||
}
|
||||
},
|
||||
...financialStatementFilterToggle('RECEIVABLE_AGING_SUMMARY', 'receivableAgingSummary'),
|
||||
});
|
||||
|
||||
@@ -15,4 +15,7 @@ export default {
|
||||
|
||||
PROFIT_LOSS_SHEET_SET: 'PROFIT_LOSS_SHEET_SET',
|
||||
PROFIT_LOSS_SHEET_LOADING: 'PROFIT_LOSS_SHEET_LOADING',
|
||||
|
||||
RECEIVABLE_AGING_SUMMARY_LOADING: 'RECEIVABLE_AGING_SUMMARY_LOADING',
|
||||
RECEIVABLE_AGING_SUMMARY_SET: 'RECEIVABLE_AGING_SUMMARY_SET',
|
||||
}
|
||||
@@ -3,4 +3,5 @@
|
||||
export default {
|
||||
RESOURCE_COLUMNS_SET: 'RESOURCE_COLUMNS_SET',
|
||||
RESOURCE_FIELDS_SET: 'RESOURCE_FIELDS_SET',
|
||||
RESOURCE_DATA_SET: 'RESOURCE_DATA_SET',
|
||||
};
|
||||
@@ -3,9 +3,6 @@ import t from 'store/types';
|
||||
|
||||
export const fetchResourceColumns = ({ resourceSlug }) => {
|
||||
return (dispatch) => new Promise((resolve, reject) => {
|
||||
dispatch({
|
||||
type: t.SET_DASHBOARD_REQUEST_LOADING,
|
||||
});
|
||||
ApiService.get(`resources/${resourceSlug}/columns`).then((response) => {
|
||||
dispatch({
|
||||
type: t.RESOURCE_COLUMNS_SET,
|
||||
@@ -22,9 +19,6 @@ export const fetchResourceColumns = ({ resourceSlug }) => {
|
||||
|
||||
export const fetchResourceFields = ({ resourceSlug }) => {
|
||||
return (dispatch) => new Promise((resolve, reject) => {
|
||||
dispatch({
|
||||
type: t.SET_DASHBOARD_REQUEST_LOADING,
|
||||
});
|
||||
ApiService.get(`resources/${resourceSlug}/fields`).then((response) => {
|
||||
dispatch({
|
||||
type: t.RESOURCE_FIELDS_SET,
|
||||
@@ -37,4 +31,19 @@ export const fetchResourceFields = ({ resourceSlug }) => {
|
||||
resolve(response);
|
||||
}).catch((error) => { reject(error); });
|
||||
});
|
||||
};
|
||||
|
||||
export const fetchResourceData = ({ resourceSlug }) => {
|
||||
return (dispatch) => new Promise((resolve, reject) => {
|
||||
ApiService.get(`/resources/${resourceSlug}/data`).then((response) => {
|
||||
dispatch({
|
||||
type: t.RESOURCE_DATA_SET,
|
||||
payload: {
|
||||
data: response.data.data,
|
||||
resource_key: resourceSlug,
|
||||
},
|
||||
});
|
||||
resolve(response);
|
||||
}).catch(error => { reject(error); });
|
||||
});
|
||||
};
|
||||
@@ -3,6 +3,7 @@ import t from 'store/types';
|
||||
import { pickItemsFromIds } from 'store/selectors'
|
||||
|
||||
const initialState = {
|
||||
data: {},
|
||||
fields: {},
|
||||
columns: {},
|
||||
resourceFields: {},
|
||||
@@ -50,6 +51,14 @@ export default createReducer(initialState, {
|
||||
};
|
||||
state.resourceFields[action.resource_slug] = action.fields.map(f => f.id);
|
||||
},
|
||||
|
||||
[t.RESOURCE_DATA_SET]: (state, action) => {
|
||||
const { data, resource_key: resourceKey } = action.payload;
|
||||
const dataMapped = {};
|
||||
|
||||
data.forEach((item) => { dataMapped[item.id] = item; })
|
||||
state.data[resourceKey] = dataMapped;
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -96,4 +105,9 @@ export const getResourceColumn = (state, columnId) => {
|
||||
|
||||
export const getResourceMetadata = (state, resourceSlug) => {
|
||||
return state.resources.metadata[resourceSlug];
|
||||
};
|
||||
|
||||
|
||||
export const getResourceData = (state, resourceSlug) => {
|
||||
return state.resources.data[resourceSlug] || {};
|
||||
};
|
||||
Reference in New Issue
Block a user