({
- payableAgingFilter: payableAgingSummaryFilter,
+ withAPAgingSummary(({ APAgingSummaryFilterDrawer }) => ({
+ isFilterDrawerOpen: APAgingSummaryFilterDrawer,
})),
)(APAgingSummaryHeader);
diff --git a/client/src/containers/FinancialStatements/APAgingSummary/APAgingSummaryHeaderGeneral.js b/client/src/containers/FinancialStatements/APAgingSummary/APAgingSummaryHeaderGeneral.js
index 4d72cfeb7..a6b8589fb 100644
--- a/client/src/containers/FinancialStatements/APAgingSummary/APAgingSummaryHeaderGeneral.js
+++ b/client/src/containers/FinancialStatements/APAgingSummary/APAgingSummaryHeaderGeneral.js
@@ -1,9 +1,17 @@
import React from 'react';
import { FastField } from 'formik';
import { DateInput } from '@blueprintjs/datetime';
-import { Intent, FormGroup, InputGroup, Position } from '@blueprintjs/core';
+import {
+ Intent,
+ FormGroup,
+ InputGroup,
+ Position,
+ Classes,
+} from '@blueprintjs/core';
import { FormattedMessage as T } from 'react-intl';
-import { Row, Col, FieldHint } from 'components';
+import classNames from 'classnames';
+import { ContactsMultiSelect, Row, Col, FieldHint } from 'components';
+import { useAPAgingSummaryContext } from './APAgingSummaryProvider';
import {
momentFormatter,
tansformDateValue,
@@ -15,6 +23,7 @@ import {
* AP Aging Summary - Drawer Header - General Fields.
*/
export default function APAgingSummaryHeaderGeneral() {
+ const { vendors } = useAPAgingSummaryContext();
return (
@@ -72,6 +81,19 @@ export default function APAgingSummaryHeaderGeneral() {
+
+
+ }
+ className={classNames('form-group--select-list', Classes.FILL)}
+ >
+ }
+ contacts={vendors}
+ />
+
+
+
);
}
diff --git a/client/src/containers/FinancialStatements/APAgingSummary/APAgingSummaryProvider.js b/client/src/containers/FinancialStatements/APAgingSummary/APAgingSummaryProvider.js
new file mode 100644
index 000000000..0a5629729
--- /dev/null
+++ b/client/src/containers/FinancialStatements/APAgingSummary/APAgingSummaryProvider.js
@@ -0,0 +1,49 @@
+import React, { useMemo, createContext, useContext } from 'react';
+import DashboardInsider from 'components/Dashboard/DashboardInsider';
+import { useAPAgingSummaryReport,useARAgingSummaryReport , useVendors } from 'hooks/query';
+import { transformFilterFormToQuery } from '../common';
+
+const APAgingSummaryContext = createContext();
+
+/**
+ * A/P aging summary provider.
+ */
+function APAgingSummaryProvider({ filter, ...props }) {
+ // Transformers the filter from to the Url query.
+ const query = useMemo(() => transformFilterFormToQuery(filter), [filter]);
+
+ const {
+ data: APAgingSummary,
+ isLoading: isAPAgingLoading,
+ isFetching: isAPAgingFetching,
+ refetch,
+ } = useAPAgingSummaryReport(query);
+
+ // Retrieve the vendors list.
+ const {
+ data: { vendors },
+ isFetching: isVendorsLoading,
+ } = useVendors();
+
+ const provider = {
+ APAgingSummary,
+ vendors,
+
+ isAPAgingLoading,
+ isAPAgingFetching,
+ isVendorsLoading,
+ refetch,
+ };
+
+ return (
+
+
+
+ );
+}
+
+
+const useAPAgingSummaryContext = () => useContext(APAgingSummaryContext);
+
+
+export { APAgingSummaryProvider, useAPAgingSummaryContext };
diff --git a/client/src/containers/FinancialStatements/APAgingSummary/APAgingSummaryTable.js b/client/src/containers/FinancialStatements/APAgingSummary/APAgingSummaryTable.js
index 303d7c28b..bd433e254 100644
--- a/client/src/containers/FinancialStatements/APAgingSummary/APAgingSummaryTable.js
+++ b/client/src/containers/FinancialStatements/APAgingSummary/APAgingSummaryTable.js
@@ -1,71 +1,29 @@
-import React, { useMemo, useCallback } from 'react';
+import React, { useCallback } from 'react';
import { FormattedMessage as T, useIntl } from 'react-intl';
import { DataTable } from 'components';
import FinancialSheet from 'components/FinancialSheet';
-import withAPAgingSummary from './withAPAgingSummary';
-
-import { compose, getColumnWidth } from 'utils';
+import { useAPAgingSummaryContext } from './APAgingSummaryProvider';
+import { useAPAgingSummaryColumns } from './components';
/**
* AP aging summary table sheet.
*/
-function APAgingSummaryTable({
- //#withPayableAgingSummary
- payableAgingColumns,
- payableAgingRows,
- payableAgingLoading,
-
+export default function APAgingSummaryTable({
//#ownProps
organizationName,
}) {
const { formatMessage } = useIntl();
- const agingColumns = useMemo(
- () =>
- payableAgingColumns.map((agingColumn) => {
- return `${agingColumn.before_days} - ${
- agingColumn.to_days || 'And Over'
- }`;
- }),
- [payableAgingColumns],
- );
- const columns = useMemo(
- () => [
- {
- Header: ,
- accessor: 'name',
- className: 'name',
- width: 240,
- sticky: 'left',
- textOverview: true,
- },
- {
- Header: ,
- accessor: 'current',
- className: 'current',
- width: getColumnWidth(payableAgingRows, `current`, {
- minWidth: 120,
- }),
- },
+ // AP aging summary report content.
+ const {
+ APAgingSummary: { tableRows },
+ isAPAgingFetching,
+ } = useAPAgingSummaryContext();
+
+ // AP aging summary columns.
+ const columns = useAPAgingSummaryColumns();
- ...agingColumns.map((agingColumn, index) => ({
- Header: agingColumn,
- accessor: `aging-${index}`,
- width: getColumnWidth(payableAgingRows, `aging-${index}`, {
- minWidth: 120,
- }),
- })),
- {
- Header: ,
- accessor: 'total',
- width: getColumnWidth(payableAgingRows, 'total', {
- minWidth: 120,
- }),
- },
- ],
- [payableAgingRows],
- );
const rowClassNames = (row) => [`row-type--${row.original.rowType}`];
return (
@@ -74,12 +32,12 @@ function APAgingSummaryTable({
name={'payable-aging-summary'}
sheetType={formatMessage({ id: 'payable_aging_summary' })}
asDate={new Date()}
- loading={payableAgingLoading}
+ loading={isAPAgingFetching}
>
);
}
-
-export default compose(
- withAPAgingSummary(
- ({
- payableAgingSummaryLoading,
- payableAgingSummaryColumns,
- payableAgingSummaryRows,
- }) => ({
- payableAgingLoading: payableAgingSummaryLoading,
- payableAgingColumns: payableAgingSummaryColumns,
- payableAgingRows: payableAgingSummaryRows,
- }),
- ),
-)(APAgingSummaryTable);
diff --git a/client/src/containers/FinancialStatements/APAgingSummary/components.js b/client/src/containers/FinancialStatements/APAgingSummary/components.js
new file mode 100644
index 000000000..0e1c1afec
--- /dev/null
+++ b/client/src/containers/FinancialStatements/APAgingSummary/components.js
@@ -0,0 +1,56 @@
+import React, { useMemo } from 'react';
+import { useAPAgingSummaryContext } from './APAgingSummaryProvider';
+import { getColumnWidth } from 'utils';
+import { FormattedMessage as T } from 'react-intl';
+
+/**
+ * Retrieve AP aging summary columns.
+ */
+export const useAPAgingSummaryColumns = () => {
+ const {
+ APAgingSummary: { tableRows, columns },
+ } = useAPAgingSummaryContext();
+
+ const agingColumns = React.useMemo(() => {
+ return columns.map(
+ (agingColumn) =>
+ `${agingColumn.before_days} - ${agingColumn.to_days || 'And Over'}`,
+ );
+ }, [columns]);
+
+ return useMemo(
+ () => [
+ {
+ Header: ,
+ accessor: 'name',
+ className: 'name',
+ width: 240,
+ sticky: 'left',
+ textOverview: true,
+ },
+ {
+ Header: ,
+ accessor: 'current',
+ className: 'current',
+ width: getColumnWidth(tableRows, `current`, {
+ minWidth: 120,
+ }),
+ },
+ ...agingColumns.map((agingColumn, index) => ({
+ Header: agingColumn,
+ accessor: `aging-${index}`,
+ width: getColumnWidth(tableRows, `aging-${index}`, {
+ minWidth: 120,
+ }),
+ })),
+ {
+ Header: ,
+ accessor: 'total',
+ width: getColumnWidth(tableRows, 'total', {
+ minWidth: 120,
+ }),
+ },
+ ],
+ [tableRows, agingColumns],
+ );
+};
diff --git a/client/src/containers/FinancialStatements/APAgingSummary/withAPAgingSummary.js b/client/src/containers/FinancialStatements/APAgingSummary/withAPAgingSummary.js
index 9a0bed6b4..912904c8e 100644
--- a/client/src/containers/FinancialStatements/APAgingSummary/withAPAgingSummary.js
+++ b/client/src/containers/FinancialStatements/APAgingSummary/withAPAgingSummary.js
@@ -1,33 +1,15 @@
import { connect } from 'react-redux';
import {
- getFinancialSheetFactory,
- getFinancialSheetColumnsFactory,
- getFinancialSheetTableRowsFactory,
+ APAgingSummaryFilterDrawerSelector,
} from 'store/financialStatement/financialStatements.selectors';
export default (mapState) => {
const mapStateToProps = (state, props) => {
- const getAPAgingSheet = getFinancialSheetFactory('payableAgingSummary');
- const getAPAgingSheetColumns = getFinancialSheetColumnsFactory(
- 'payableAgingSummary',
- );
- const getAPAgingSheetRows = getFinancialSheetTableRowsFactory(
- 'payableAgingSummary',
- );
-
- const {
- loading,
- filter,
- refresh,
- } = state.financialStatements.payableAgingSummary;
-
const mapped = {
- payableAgingSummarySheet: getAPAgingSheet(state, props),
- payableAgingSummaryColumns: getAPAgingSheetColumns(state, props),
- payableAgingSummaryRows: getAPAgingSheetRows(state, props),
- payableAgingSummaryLoading: loading,
- payableAgingSummaryFilter: filter,
- APAgingSummaryRefresh: refresh,
+ APAgingSummaryFilterDrawer: APAgingSummaryFilterDrawerSelector(
+ state,
+ props,
+ ),
};
return mapState ? mapState(mapped, state, props) : mapped;
};
diff --git a/client/src/containers/FinancialStatements/APAgingSummary/withAPAgingSummaryActions.js b/client/src/containers/FinancialStatements/APAgingSummary/withAPAgingSummaryActions.js
index 87cefd3d8..b1572b493 100644
--- a/client/src/containers/FinancialStatements/APAgingSummary/withAPAgingSummaryActions.js
+++ b/client/src/containers/FinancialStatements/APAgingSummary/withAPAgingSummaryActions.js
@@ -1,18 +1,9 @@
import { connect } from 'react-redux';
-import {
- fetchPayableAginSummary,
- payableAgingSummaryRefresh,
-} from 'store/financialStatement/financialStatements.actions';
+import { toggleAPAgingSummaryFilterDrawer } from 'store/financialStatement/financialStatements.actions';
const mapActionsToProps = (dispatch) => ({
- requestPayableAgingSummary: (query) =>
- dispatch(fetchPayableAginSummary({ query })),
- refreshAPAgingSummary: (refresh) =>
- dispatch(payableAgingSummaryRefresh(refresh)),
- toggleFilterAPAgingSummary: () =>
- dispatch({
- type: 'PAYABLE_AGING_SUMMARY_FILTER_TOGGLE',
- }),
+ toggleAPAgingSummaryFilterDrawer: (toggle) =>
+ dispatch(toggleAPAgingSummaryFilterDrawer(toggle)),
});
export default connect(null, mapActionsToProps);
diff --git a/client/src/containers/FinancialStatements/ARAgingSummary/ARAgingSummaryActionsBar.js b/client/src/containers/FinancialStatements/ARAgingSummary/ARAgingSummaryActionsBar.js
index af52486c5..3618b14bb 100644
--- a/client/src/containers/FinancialStatements/ARAgingSummary/ARAgingSummaryActionsBar.js
+++ b/client/src/containers/FinancialStatements/ARAgingSummary/ARAgingSummaryActionsBar.js
@@ -39,7 +39,7 @@ function ARAgingSummaryActionsBar({
const { isARAgingFetching, refetch } = useARAgingSummaryContext();
const handleFilterToggleClick = () => {
- toggleDisplayFilterDrawer(false);
+ toggleDisplayFilterDrawer();
};
// Handles re-calculate report button.
diff --git a/client/src/containers/FinancialStatements/ARAgingSummary/ARAgingSummaryHeader.js b/client/src/containers/FinancialStatements/ARAgingSummary/ARAgingSummaryHeader.js
index e25aaef97..8b2e0ec18 100644
--- a/client/src/containers/FinancialStatements/ARAgingSummary/ARAgingSummaryHeader.js
+++ b/client/src/containers/FinancialStatements/ARAgingSummary/ARAgingSummaryHeader.js
@@ -25,7 +25,7 @@ function ARAgingSummaryHeader({
toggleARAgingSummaryFilterDrawer: toggleFilterDrawerDisplay,
// #withARAgingSummary
- isFilterDrawerOpen
+ isFilterDrawerOpen,
}) {
const validationSchema = Yup.object().shape({
asDate: Yup.date().required().label('asDate'),
@@ -53,13 +53,22 @@ function ARAgingSummaryHeader({
toggleFilterDrawerDisplay(false);
setSubmitting(false);
};
+
// Handle cancel button click.
const handleCancelClick = () => {
toggleFilterDrawerDisplay(false);
};
+
+ // Handle the drawer close.
+ const handleDrawerClose = () => {
+ toggleFilterDrawerDisplay(false);
+ };
return (
-
+
}
className={classNames('form-group--select-list', Classes.FILL)}
>
-
+
diff --git a/client/src/containers/FinancialStatements/reducers.js b/client/src/containers/FinancialStatements/reducers.js
index 775a2c074..6af950eea 100644
--- a/client/src/containers/FinancialStatements/reducers.js
+++ b/client/src/containers/FinancialStatements/reducers.js
@@ -261,3 +261,38 @@ export const ARAgingSummaryTableRowsMapper = (sheet, total) => {
},
];
};
+
+export const APAgingSummaryTableRowsMapper = (sheet, total) => {
+ const rows = [];
+
+ const mapAging = (agingPeriods) => {
+ return agingPeriods.reduce((acc, aging, index) => {
+ acc[`aging-${index}`] = aging.total.formatted_amount;
+ return acc;
+ }, {});
+ };
+ sheet.vendors.forEach((vendor) => {
+ const agingRow = mapAging(vendor.aging);
+
+ rows.push({
+ rowType: 'vendor',
+ name: vendor.vendor_name,
+ ...agingRow,
+ current: vendor.current.formatted_amount,
+ total: vendor.total.formatted_amount,
+ });
+ });
+ if (rows.length <= 0) {
+ return [];
+ }
+ return [
+ ...rows,
+ {
+ name: '',
+ rowType: 'total',
+ current: sheet.total.current.formatted_amount,
+ ...mapAging(sheet.total.aging),
+ total: sheet.total.total.formatted_amount,
+ },
+ ];
+};
diff --git a/client/src/hooks/query/financialReports.js b/client/src/hooks/query/financialReports.js
index b7bdf7d51..b7b03fdaa 100644
--- a/client/src/hooks/query/financialReports.js
+++ b/client/src/hooks/query/financialReports.js
@@ -6,10 +6,11 @@ import {
profitLossSheetReducer,
generalLedgerTableRowsReducer,
journalTableRowsReducer,
- ARAgingSummaryTableRowsMapper
+ ARAgingSummaryTableRowsMapper,
+ APAgingSummaryTableRowsMapper
} from 'containers/FinancialStatements/reducers';
import useApiRequest from '../useRequest';
-
+
/**
* Retrieve balance sheet.
*/
@@ -27,7 +28,7 @@ export function useBalanceSheet(query, props) {
tableRows: balanceSheetRowsReducer(res.data.data),
...res.data,
}),
- ...props
+ ...props,
},
);
@@ -69,8 +70,8 @@ export function useTrialBalanceSheet(query, props) {
tableRows: [],
data: [],
query: {},
- })
- }
+ }),
+ };
}
/**
@@ -101,7 +102,7 @@ export function useProfitLossSheet(query, props) {
columns: [],
query: {},
}),
- }
+ };
}
/**
@@ -132,7 +133,7 @@ export function useGeneralLedgerSheet(query, props) {
data: {},
query: {},
}),
- }
+ };
}
/**
@@ -143,12 +144,11 @@ export function useJournalSheet(query, props) {
const states = useQuery(
['FINANCIAL-REPORT', 'JOURNAL', query],
- () =>
- apiRequest.get('/financial_statements/journal', { params: query }),
+ () => apiRequest.get('/financial_statements/journal', { params: query }),
{
select: (res) => ({
tableRows: journalTableRowsReducer(res.data.data),
- ...res.data,
+ ...res.data,
}),
...props,
},
@@ -160,8 +160,8 @@ export function useJournalSheet(query, props) {
data: {},
tableRows: [],
query: {},
- })
- }
+ }),
+ };
}
/**
@@ -185,7 +185,7 @@ export function useARAgingSummaryReport(query, props) {
customers: res.data.data.customers,
total: res.data.data.total,
columns: res.data.columns,
- }),
+ }),
}),
initialData: {
data: {
@@ -194,11 +194,50 @@ export function useARAgingSummaryReport(query, props) {
total: {},
},
columns: [],
- tableRows: []
- }
+ tableRows: [],
+ },
},
initialDataUpdatedAt: 0,
- ...props
+ ...props,
+ },
+ );
+}
+
+/**
+ * Retrieve AP aging summary report.
+ */
+export function useAPAgingSummaryReport(query, props) {
+ const apiRequest = useApiRequest();
+
+ return useQuery(
+ ['FINANCIAL-REPORT', 'AP-AGING-SUMMARY', query],
+ () =>
+ apiRequest.get('/financial_statements/payable_aging_summary', {
+ params: query,
+ }),
+ {
+ select: (res) => ({
+ columns: res.data.columns,
+ data: res.data.data,
+ query: res.data.query,
+ tableRows: APAgingSummaryTableRowsMapper({
+ vendors: res.data.data.vendors,
+ total: res.data.data.total,
+ columns: res.data.columns,
+ }),
+ }),
+ initialData: {
+ data: {
+ data: {
+ vendors: [],
+ total: {},
+ },
+ columns: [],
+ tableRows: [],
+ },
+ },
+ initialDataUpdatedAt: 0,
+ ...props,
},
);
}
diff --git a/client/src/lang/en/index.js b/client/src/lang/en/index.js
index 5b9e390d8..4e436e30d 100644
--- a/client/src/lang/en/index.js
+++ b/client/src/lang/en/index.js
@@ -961,6 +961,7 @@ export default {
adjustment_reasons: 'Adjustment reasons',
specific_customers: 'Specific Customers',
all_customers: 'All Customers',
+ all_vendors: 'All Vendors',
selected_customers: '{count} Selected Customers',
transaction_number: 'Transaction #',
running_balance: 'Running balance',
@@ -976,4 +977,6 @@ export default {
receipt_paper: 'Receipt Paper',
payable_aging_summary: 'Payable Aging Summary',
payment_receive_paper: 'Payment Receive Paper',
+ specific_vendors: 'Specific Vendors',
+
};
diff --git a/client/src/routes/dashboard.js b/client/src/routes/dashboard.js
index c5a423dae..db593d92f 100644
--- a/client/src/routes/dashboard.js
+++ b/client/src/routes/dashboard.js
@@ -159,13 +159,16 @@ export default [
backLink: true,
sidebarShrink: true,
},
- // {
- // path: '/financial-reports/payable-aging-summary',
- // component: lazy(() =>
- // import('containers/FinancialStatements/APAgingSummary/APAgingSummary'),
- // ),
- // breadcrumb: 'Payable Aging Summary',
- // },
+ {
+ path: '/financial-reports/payable-aging-summary',
+ component: lazy(() =>
+ import('containers/FinancialStatements/APAgingSummary/APAgingSummary'),
+ ),
+ breadcrumb: 'Payable Aging Summary',
+ pageTitle: formatMessage({ id: 'payable_aging_summary' }),
+ backLink: true,
+ sidebarShrink: true,
+ },
{
path: `/financial-reports/journal-sheet`,
component: lazy(() =>
diff --git a/client/src/store/financialStatement/financialStatements.actions.js b/client/src/store/financialStatement/financialStatements.actions.js
index 2060aefbb..f961a7eda 100644
--- a/client/src/store/financialStatement/financialStatements.actions.js
+++ b/client/src/store/financialStatement/financialStatements.actions.js
@@ -76,4 +76,17 @@ export function toggleARAgingSummaryFilterDrawer(toggle) {
toggle,
}
};
+}
+
+/**
+ * Toggles display of the AP aging summary filter drawer.
+ * @param {boolean} toggle -
+ */
+export function toggleAPAgingSummaryFilterDrawer(toggle) {
+ return {
+ type: `${t.AP_AGING_SUMMARY}/${t.DISPLAY_FILTER_DRAWER_TOGGLE}`,
+ payload: {
+ toggle,
+ }
+ };
}
\ No newline at end of file
diff --git a/client/src/store/financialStatement/financialStatements.mappers.js b/client/src/store/financialStatement/financialStatements.mappers.js
index e771198cf..7377bbb23 100644
--- a/client/src/store/financialStatement/financialStatements.mappers.js
+++ b/client/src/store/financialStatement/financialStatements.mappers.js
@@ -137,6 +137,41 @@ export const ARAgingSummaryTableRowsMapper = (sheet, total) => {
];
};
+export const APAgingSummaryTableRowsMapper = (sheet, total) => {
+ const rows = [];
+
+ const mapAging = (agingPeriods) => {
+ return agingPeriods.reduce((acc, aging, index) => {
+ acc[`aging-${index}`] = aging.total.formatted_amount;
+ return acc;
+ }, {});
+ };
+ sheet.vendors.forEach((vendor) => {
+ const agingRow = mapAging(vendor.aging);
+
+ rows.push({
+ rowType: 'vendor',
+ name: vendor.vendor_name,
+ ...agingRow,
+ current: vendor.current.formatted_amount,
+ total: vendor.total.formatted_amount,
+ });
+ });
+ if (rows.length <= 0) {
+ return [];
+ }
+ return [
+ ...rows,
+ {
+ name: '',
+ rowType: 'total',
+ current: sheet.total.current.formatted_amount,
+ ...mapAging(sheet.total.aging),
+ total: sheet.total.total.formatted_amount,
+ },
+ ];
+};
+
export const mapTrialBalanceSheetToRows = (sheet) => {
const results = [];
diff --git a/client/src/store/financialStatement/financialStatements.selectors.js b/client/src/store/financialStatement/financialStatements.selectors.js
index eee24b610..5954c8209 100644
--- a/client/src/store/financialStatement/financialStatements.selectors.js
+++ b/client/src/store/financialStatement/financialStatements.selectors.js
@@ -34,6 +34,11 @@ export const ARAgingSummaryFilterDrawerSelector = (state) => {
return filterDrawerByTypeSelector('ARAgingSummary')(state);
};
+export const APAgingSummaryFilterDrawerSelector = (state) => {
+ return filterDrawerByTypeSelector('APAgingSummary')(state);
+}
+
+
/**
* Retrieve balance sheet filter drawer.
*/
@@ -94,6 +99,17 @@ export const getARAgingSummaryFilterDrawer = createSelector(
},
);
+
+/**
+ * Retrieve whether display AR aging summary drawer filter.
+ */
+export const getAPAgingSummaryFilterDrawer = createSelector(
+ APAgingSummaryFilterDrawerSelector,
+ (isOpen) => {
+ return isOpen;
+ },
+);
+
/**
* Retrieve financial statement query by the given sheet index.
*/