diff --git a/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetTable.ts b/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetTable.ts
index 2854154e2..e1f4ec8fe 100644
--- a/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetTable.ts
+++ b/packages/server/src/services/FinancialStatements/JournalSheet/JournalSheetTable.ts
@@ -1,7 +1,8 @@
import * as R from 'ramda';
+import { first } from 'lodash';
import {
+ IColumnMapperMeta,
IJournalEntry,
- IJournalReport,
IJournalReportEntriesGroup,
IJournalReportQuery,
IJournalTableData,
@@ -13,7 +14,7 @@ import { tableRowMapper } from '@/utils';
import { FinancialTable } from '../FinancialTable';
import { FinancialSheetStructure } from '../FinancialSheetStructure';
import FinancialSheet from '../FinancialSheet';
-import { first } from 'lodash';
+import { ROW_TYPE } from './types';
export class JournalSheetTable extends R.compose(
FinancialTable,
@@ -70,6 +71,10 @@ export class JournalSheetTable extends R.compose(
];
};
+ /**
+ * Retrieves the total entry column accessors.
+ * @returns {ITableColumnAccessor[]}
+ */
private totalEntryColumnAccessors = (): ITableColumnAccessor[] => {
return [
{ key: 'date', accessor: '_empty_' },
@@ -83,6 +88,23 @@ export class JournalSheetTable extends R.compose(
];
};
+ /**
+ * Retrieves the total entry column accessors.
+ * @returns {IColumnMapperMeta[]}
+ */
+ private blankEnrtyColumnAccessors = (): IColumnMapperMeta[] => {
+ return [
+ { key: 'date', value: '' },
+ { key: 'transaction_type', value: '' },
+ { key: 'transaction_number', value: '' },
+ { key: 'description', value: '' },
+ { key: 'account_code', value: '' },
+ { key: 'account_name', value: '' },
+ { key: 'credit', value: '' },
+ { key: 'debit', value: '' },
+ ];
+ };
+
/**
* Retrieves the common columns.
* @returns {ITableColumn[]}
@@ -113,6 +135,7 @@ export class JournalSheetTable extends R.compose(
};
const computedGroup = { ...group, entry: first(group.entries) };
const columns = this.groupColumnsAccessors();
+
return tableRowMapper(computedGroup, columns, meta);
};
@@ -153,6 +176,16 @@ export class JournalSheetTable extends R.compose(
return tableRowMapper(group, total, meta);
};
+ /**
+ * Retrieves the blank entry row.
+ * @returns {ITableRow}
+ */
+ private blankEntryMapper = (): ITableRow => {
+ const columns = this.blankEnrtyColumnAccessors();
+ const meta = {};
+ return tableRowMapper({} as IJournalEntry, columns, meta);
+ };
+
/**
* Maps the entry group to table rows.
* @param {IJournalReportEntriesGroup} group -
@@ -162,8 +195,9 @@ export class JournalSheetTable extends R.compose(
const firstRow = this.firstEntryGroupMapper(group);
const lastRows = this.entriesMapper(group);
const totalRow = this.totalEntryMapper(group);
+ const blankRow = this.blankEntryMapper();
- return [firstRow, ...lastRows, totalRow];
+ return [firstRow, ...lastRows, totalRow, blankRow];
};
/**
diff --git a/packages/server/src/services/FinancialStatements/JournalSheet/types.ts b/packages/server/src/services/FinancialStatements/JournalSheet/types.ts
index f71970251..6eff84957 100644
--- a/packages/server/src/services/FinancialStatements/JournalSheet/types.ts
+++ b/packages/server/src/services/FinancialStatements/JournalSheet/types.ts
@@ -1,6 +1,5 @@
-
-enum ROW_TYPE {
+export enum ROW_TYPE {
ENTRY = 'ENTRY',
TOTAL = 'TOTAL'
};
\ No newline at end of file
diff --git a/packages/webapp/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerActionsBar.tsx b/packages/webapp/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerActionsBar.tsx
index 971da31d9..e450c78bb 100644
--- a/packages/webapp/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerActionsBar.tsx
+++ b/packages/webapp/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerActionsBar.tsx
@@ -12,6 +12,7 @@ import {
import classNames from 'classnames';
import { DashboardActionsBar, FormattedMessage as T, Icon } from '@/components';
+import { GeneralLedgerSheetExportMenu } from './components';
import { useGeneralLedgerContext } from './GeneralLedgerProvider';
import { compose } from '@/utils';
@@ -84,11 +85,18 @@ function GeneralLedgerActionsBar({
icon={}
text={}
/>
- }
- text={}
- />
+ }
+ interactionKind={PopoverInteractionKind.CLICK}
+ placement="bottom-start"
+ minimal
+ >
+ }
+ text={}
+ />
+
);
diff --git a/packages/webapp/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerHeaderDimensionsPanelProvider.tsx b/packages/webapp/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerHeaderDimensionsPanelProvider.tsx
index c1afde8bd..2b2683df2 100644
--- a/packages/webapp/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerHeaderDimensionsPanelProvider.tsx
+++ b/packages/webapp/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerHeaderDimensionsPanelProvider.tsx
@@ -10,7 +10,7 @@ const GeneralLedgerHeaderDimensionsPanelContext = React.createContext();
/**
* General Ledger Header Dimensions Panel provider.
- * @returns
+ * @returns {JSX.Element}
*/
function GeneralLedgerHeaderDimensionsPanelProvider({ query, ...props }) {
// Features guard.
diff --git a/packages/webapp/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerProvider.tsx b/packages/webapp/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerProvider.tsx
index b30bf42da..d38464d77 100644
--- a/packages/webapp/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerProvider.tsx
+++ b/packages/webapp/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerProvider.tsx
@@ -29,6 +29,7 @@ function GeneralLedgerProvider({ query, ...props }) {
sheetRefresh: refetch,
isFetching,
isLoading,
+ httpRequest: requestQuery
};
return (
diff --git a/packages/webapp/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerTable.tsx b/packages/webapp/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerTable.tsx
index b46038fcc..c0f1ce0b7 100644
--- a/packages/webapp/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerTable.tsx
+++ b/packages/webapp/src/containers/FinancialStatements/GeneralLedger/GeneralLedgerTable.tsx
@@ -13,7 +13,7 @@ import {
} from '@/components';
import { useGeneralLedgerContext } from './GeneralLedgerProvider';
-import { useGeneralLedgerTableColumns } from './components';
+import { useGeneralLedgerTableColumns } from './dynamicColumns';
/**
* General ledger table.
@@ -21,7 +21,7 @@ import { useGeneralLedgerTableColumns } from './components';
export default function GeneralLedgerTable({ companyName }) {
// General ledger context.
const {
- generalLedger: { tableRows, query },
+ generalLedger: { query, table },
isLoading,
} = useGeneralLedgerContext();
@@ -30,8 +30,8 @@ export default function GeneralLedgerTable({ companyName }) {
// Default expanded rows of general ledger table.
const expandedRows = useMemo(
- () => defaultExpanderReducer(tableRows, 1),
- [tableRows],
+ () => defaultExpanderReducer(table.rows, 1),
+ [table.rows],
);
return (
@@ -48,7 +48,7 @@ export default function GeneralLedgerTable({ companyName }) {
'this_report_does_not_contain_any_data_between_date_period',
)}
columns={columns}
- data={tableRows}
+ data={table.rows}
rowClassNames={tableRowTypesToClassnames}
expanded={expandedRows}
virtualizedRows={true}
diff --git a/packages/webapp/src/containers/FinancialStatements/GeneralLedger/components.tsx b/packages/webapp/src/containers/FinancialStatements/GeneralLedger/components.tsx
index 441892178..fbb9a0b10 100644
--- a/packages/webapp/src/containers/FinancialStatements/GeneralLedger/components.tsx
+++ b/packages/webapp/src/containers/FinancialStatements/GeneralLedger/components.tsx
@@ -1,107 +1,31 @@
// @ts-nocheck
-import React from 'react';
-import intl from 'react-intl-universal';
-import { Button } from '@blueprintjs/core';
-import { FormattedMessage as T, Icon, If } from '@/components';
+import React, { useRef } from 'react';
+import classNames from 'classnames';
+import {
+ Button,
+ Classes,
+ Intent,
+ Menu,
+ MenuItem,
+ ProgressBar,
+ Text,
+} from '@blueprintjs/core';
+import {
+ FormattedMessage as T,
+ Icon,
+ If,
+ Stack,
+ AppToaster,
+} from '@/components';
-import { getColumnWidth } from '@/utils';
import { useGeneralLedgerContext } from './GeneralLedgerProvider';
import FinancialLoadingBar from '../FinancialLoadingBar';
import { FinancialComputeAlert } from '../FinancialReportPage';
-import { Align } from '@/constants';
-
-/**
- * Retrieve the general ledger table columns.
- */
-export function useGeneralLedgerTableColumns() {
- // General ledger context.
- const {
- generalLedger: { tableRows },
- } = useGeneralLedgerContext();
-
- return React.useMemo(
- () => [
- {
- Header: intl.get('date'),
- accessor: 'date',
- className: 'date',
- width: 120,
- },
- {
- Header: intl.get('account_name'),
- accessor: 'name',
- className: 'name',
- textOverview: true,
- },
- {
- Header: intl.get('transaction_type'),
- accessor: 'reference_type_formatted',
- className: 'transaction_type',
- width: 125,
- textOverview: true,
- },
- {
- Header: intl.get('transaction_number'),
- accessor: 'reference_id',
- className: 'transaction_number',
- width: 100,
- textOverview: true,
- },
- {
- Header: intl.get('description'),
- accessor: 'note',
- className: 'description',
- textOverview: true,
- },
- {
- Header: intl.get('credit'),
- accessor: 'formatted_credit',
- className: 'credit',
- width: getColumnWidth(tableRows, 'formatted_credit', {
- minWidth: 100,
- magicSpacing: 10,
- }),
- textOverview: true,
- align: Align.Right,
- },
- {
- Header: intl.get('debit'),
- accessor: 'formatted_debit',
- className: 'debit',
- width: getColumnWidth(tableRows, 'formatted_debit', {
- minWidth: 100,
- magicSpacing: 10,
- }),
- textOverview: true,
- align: Align.Right,
- },
- {
- Header: intl.get('amount'),
- accessor: 'formatted_amount',
- className: 'amount',
- width: getColumnWidth(tableRows, 'formatted_amount', {
- minWidth: 100,
- magicSpacing: 10,
- }),
- textOverview: true,
- align: Align.Right,
- },
- {
- Header: intl.get('running_balance'),
- accessor: 'formatted_running_balance',
- className: 'running_balance',
- width: getColumnWidth(tableRows, 'formatted_running_balance', {
- minWidth: 100,
- magicSpacing: 10,
- }),
- textOverview: true,
- align: Align.Right,
- },
- ],
- [tableRows],
- );
-}
+import {
+ useGeneralLedgerSheetCsvExport,
+ useGeneralLedgerSheetXlsxExport,
+} from '@/hooks/query';
/**
* General ledger sheet alerts.
@@ -144,3 +68,93 @@ export function GeneralLedgerSheetLoadingBar() {
);
}
+
+/**
+ * Renders the G/L sheet export menu.
+ * @returns {JSX.Element}
+ */
+export const GeneralLedgerSheetExportMenu = () => {
+ const toastKey = useRef(null);
+ const commonToastConfig = {
+ isCloseButtonShown: true,
+ timeout: 2000,
+ };
+ const { httpRequest } = useGeneralLedgerContext();
+
+ const openProgressToast = (amount: number) => {
+ return (
+
+ The report has been exported successfully.
+ = 100,
+ })}
+ intent={amount < 100 ? Intent.PRIMARY : Intent.SUCCESS}
+ value={amount / 100}
+ />
+
+ );
+ };
+ // Export the report to xlsx.
+ const { mutateAsync: xlsxExport } = useGeneralLedgerSheetXlsxExport(
+ httpRequest,
+ {
+ onDownloadProgress: (xlsxExportProgress: number) => {
+ if (!toastKey.current) {
+ toastKey.current = AppToaster.show({
+ message: openProgressToast(xlsxExportProgress),
+ ...commonToastConfig,
+ });
+ } else {
+ AppToaster.show(
+ {
+ message: openProgressToast(xlsxExportProgress),
+ ...commonToastConfig,
+ },
+ toastKey.current,
+ );
+ }
+ },
+ },
+ );
+ // Export the report to csv.
+ const { mutateAsync: csvExport } = useGeneralLedgerSheetCsvExport(
+ httpRequest,
+ {
+ onDownloadProgress: (xlsxExportProgress: number) => {
+ if (!toastKey.current) {
+ toastKey.current = AppToaster.show({
+ message: openProgressToast(xlsxExportProgress),
+ ...commonToastConfig,
+ });
+ } else {
+ AppToaster.show(
+ {
+ message: openProgressToast(xlsxExportProgress),
+ ...commonToastConfig,
+ },
+ toastKey.current,
+ );
+ }
+ },
+ },
+ );
+ // Handle csv export button click.
+ const handleCsvExportBtnClick = () => {
+ csvExport().then(() => {});
+ };
+ // Handle xlsx export button click.
+ const handleXlsxExportBtnClick = () => {
+ xlsxExport().then(() => {});
+ };
+
+ return (
+
+ );
+};
diff --git a/packages/webapp/src/containers/FinancialStatements/GeneralLedger/dynamicColumns.ts b/packages/webapp/src/containers/FinancialStatements/GeneralLedger/dynamicColumns.ts
new file mode 100644
index 000000000..70204030f
--- /dev/null
+++ b/packages/webapp/src/containers/FinancialStatements/GeneralLedger/dynamicColumns.ts
@@ -0,0 +1,117 @@
+// @ts-nocheck
+import { getColumnWidth } from '@/utils';
+import * as R from 'ramda';
+import { useGeneralLedgerContext } from './GeneralLedgerProvider';
+import { Align } from '@/constants';
+
+const getTableCellValueAccessor = (index) => `cells[${index}].value`;
+
+const getReportColWidth = (data, accessor, headerText) => {
+ return getColumnWidth(
+ data,
+ accessor,
+ { magicSpacing: 10, minWidth: 100 },
+ headerText,
+ );
+};
+
+/**
+ * Account name column mapper.
+ */
+const commonColumnMapper = R.curry((data, column) => {
+ const accessor = getTableCellValueAccessor(column.cell_index);
+
+ return {
+ key: column.key,
+ Header: column.label,
+ accessor,
+ className: column.key,
+ textOverview: true,
+ };
+});
+
+/**
+ * Numeric columns accessor.
+ */
+const numericColumnAccessor = R.curry((data, column) => {
+ const accessor = getTableCellValueAccessor(column.cell_index);
+ const width = getReportColWidth(data, accessor, column.label);
+
+ return {
+ ...column,
+ align: Align.Right,
+ width,
+ };
+});
+
+/**
+ * Date column accessor.
+ */
+const dateColumnAccessor = R.curry((column) => {
+ return {
+ ...column,
+ width: 120,
+ };
+});
+
+/**
+ * Transaction type column accessor.
+ */
+const transactionTypeColumnAccessor = (column) => {
+ return {
+ ...column,
+ width: 125,
+ };
+};
+
+/**
+ * Transaction number column accessor.
+ */
+const transactionIdColumnAccessor = (column) => {
+ return {
+ ...column,
+ width: 100,
+ };
+};
+
+const dynamiColumnMapper = R.curry((data, column) => {
+ const _numericColumnAccessor = numericColumnAccessor(data);
+
+ return R.compose(
+ R.when(R.pathEq(['key'], 'date'), dateColumnAccessor),
+ R.when(
+ R.pathEq(['key'], 'reference_type'),
+ transactionTypeColumnAccessor,
+ ),
+ R.when(
+ R.pathEq(['key'], 'reference_number'),
+ transactionIdColumnAccessor,
+ ),
+ R.when(R.pathEq(['key'], 'credit'), _numericColumnAccessor),
+ R.when(R.pathEq(['key'], 'debit'), _numericColumnAccessor),
+ R.when(R.pathEq(['key'], 'amount'), _numericColumnAccessor),
+ R.when(R.pathEq(['key'], 'running_balance'), _numericColumnAccessor),
+ commonColumnMapper(data),
+ )(column);
+});
+
+/**
+ * Composes the dynamic columns that fetched from request to columns to table component.
+ */
+export const dynamicColumns = R.curry((data, columns) => {
+ return R.map(dynamiColumnMapper(data), columns);
+});
+
+/**
+ * Retrieves the G/L sheet table columns for table component.
+ */
+export const useGeneralLedgerTableColumns = () => {
+ const { generalLedger } = useGeneralLedgerContext();
+
+ if (!generalLedger) {
+ throw new Error('asdfadsf');
+ }
+ const { table } = generalLedger;
+
+ return dynamicColumns(table.rows, table.columns);
+};
diff --git a/packages/webapp/src/containers/FinancialStatements/Journal/JournalActionsBar.tsx b/packages/webapp/src/containers/FinancialStatements/Journal/JournalActionsBar.tsx
index b5ee2b467..5e49ee11a 100644
--- a/packages/webapp/src/containers/FinancialStatements/Journal/JournalActionsBar.tsx
+++ b/packages/webapp/src/containers/FinancialStatements/Journal/JournalActionsBar.tsx
@@ -18,6 +18,7 @@ import withJournal from './withJournal';
import { compose } from '@/utils';
import { useJournalSheetContext } from './JournalProvider';
+import { JournalSheetExportMenu } from './components';
/**
* Journal sheeet - Actions bar.
@@ -85,11 +86,18 @@ function JournalActionsBar({
icon={}
text={}
/>
- }
- text={}
- />
+ }
+ interactionKind={PopoverInteractionKind.CLICK}
+ placement="bottom-start"
+ minimal
+ >
+ }
+ text={}
+ />
+
);
diff --git a/packages/webapp/src/containers/FinancialStatements/Journal/JournalProvider.tsx b/packages/webapp/src/containers/FinancialStatements/Journal/JournalProvider.tsx
index 372dc2b70..b13efe9a6 100644
--- a/packages/webapp/src/containers/FinancialStatements/Journal/JournalProvider.tsx
+++ b/packages/webapp/src/containers/FinancialStatements/Journal/JournalProvider.tsx
@@ -28,6 +28,7 @@ function JournalSheetProvider({ query, ...props }) {
isLoading,
isFetching,
refetchSheet: refetch,
+ httpQuery: requestQuery
};
return (
diff --git a/packages/webapp/src/containers/FinancialStatements/Journal/JournalTable.tsx b/packages/webapp/src/containers/FinancialStatements/Journal/JournalTable.tsx
index f1004dadc..5b706ea1c 100644
--- a/packages/webapp/src/containers/FinancialStatements/Journal/JournalTable.tsx
+++ b/packages/webapp/src/containers/FinancialStatements/Journal/JournalTable.tsx
@@ -11,10 +11,10 @@ import {
TableVirtualizedListRows,
} from '@/components';
-import { useJournalTableColumns } from './components';
import { useJournalSheetContext } from './JournalProvider';
import { defaultExpanderReducer, tableRowTypesToClassnames } from '@/utils';
+import { useJournalSheetColumns } from './dynamicColumns';
/**
* Journal sheet table.
@@ -23,12 +23,12 @@ import { defaultExpanderReducer, tableRowTypesToClassnames } from '@/utils';
export function JournalTable({ companyName }) {
// Journal sheet context.
const {
- journalSheet: { tableRows, query },
+ journalSheet: { table, query },
isLoading,
} = useJournalSheetContext();
- // Retreive the journal table columns.
- const columns = useJournalTableColumns();
+ // Retrieves the journal table columns.
+ const columns = useJournalSheetColumns();
// Default expanded rows of general journal table.
const expandedRows = useMemo(() => defaultExpanderReducer([], 1), []);
@@ -39,13 +39,13 @@ export function JournalTable({ companyName }) {
sheetType={intl.get('journal_sheet')}
fromDate={query.from_date}
toDate={query.to_date}
- name="journal"
loading={isLoading}
fullWidth={true}
+ name="journal"
>
{
- return React.useMemo(
- () => [
- {
- Header: intl.get('date'),
- accessor: (row) =>
- row.date ? moment(row.date).format('YYYY MMM DD') : '',
- className: 'date',
- width: 100,
- textOverview: true,
- },
- {
- Header: intl.get('transaction_type'),
- accessor: 'reference_type_formatted',
- className: 'reference_type_formatted',
- width: 120,
- textOverview: true,
- },
- {
- Header: intl.get('num'),
- accessor: 'transaction_number',
- className: 'reference_id',
- width: 70,
- textOverview: true,
- },
- {
- Header: intl.get('description'),
- accessor: 'note',
- className: 'note',
- textOverview: true,
- },
- {
- Header: intl.get('acc_code'),
- accessor: 'account_code',
- width: 95,
- className: 'account_code',
- textOverview: true,
- },
- {
- Header: intl.get('account'),
- accessor: 'account_name',
- className: 'account_name',
- textOverview: true,
- },
- {
- Header: intl.get('credit'),
- accessor: 'formatted_credit',
- align: Align.Right,
- },
- {
- Header: intl.get('debit'),
- accessor: 'formatted_debit',
- align: Align.Right,
- },
- ],
- [],
- );
-};
+import {
+ useJournalSheetCsvExport,
+ useJournalSheetXlsxExport,
+} from '@/hooks/query';
/**
* Journal sheet loading bar.
@@ -115,3 +69,87 @@ export function JournalSheetAlerts() {
);
}
+
+/**
+ * Retrieves the journal sheet export menu.
+ * @returns {JSX.Element}
+ */
+export const JournalSheetExportMenu = () => {
+ const toastKey = useRef(null);
+ const commonToastConfig = {
+ isCloseButtonShown: true,
+ timeout: 2000,
+ };
+ const { httpQuery } = useJournalSheetContext();
+
+ const openProgressToast = (amount: number) => {
+ return (
+
+ The report has been exported successfully.
+ = 100,
+ })}
+ intent={amount < 100 ? Intent.PRIMARY : Intent.SUCCESS}
+ value={amount / 100}
+ />
+
+ );
+ };
+ // Exports the report to xlsx.
+ const { mutateAsync: xlsxExport } = useJournalSheetXlsxExport(httpQuery, {
+ onDownloadProgress: (xlsxExportProgress: number) => {
+ if (!toastKey.current) {
+ toastKey.current = AppToaster.show({
+ message: openProgressToast(xlsxExportProgress),
+ ...commonToastConfig,
+ });
+ } else {
+ AppToaster.show(
+ {
+ message: openProgressToast(xlsxExportProgress),
+ ...commonToastConfig,
+ },
+ toastKey.current,
+ );
+ }
+ },
+ });
+ // Exports the report to csv.
+ const { mutateAsync: csvExport } = useJournalSheetCsvExport(httpQuery, {
+ onDownloadProgress: (xlsxExportProgress: number) => {
+ if (!toastKey.current) {
+ toastKey.current = AppToaster.show({
+ message: openProgressToast(xlsxExportProgress),
+ ...commonToastConfig,
+ });
+ } else {
+ AppToaster.show(
+ {
+ message: openProgressToast(xlsxExportProgress),
+ ...commonToastConfig,
+ },
+ toastKey.current,
+ );
+ }
+ },
+ });
+ // Handle csv export button click.
+ const handleCsvExportBtnClick = () => {
+ csvExport();
+ };
+ // Handle xlsx export button click.
+ const handleXlsxExportBtnClick = () => {
+ xlsxExport();
+ };
+
+ return (
+
+ );
+};
diff --git a/packages/webapp/src/containers/FinancialStatements/Journal/dynamicColumns.ts b/packages/webapp/src/containers/FinancialStatements/Journal/dynamicColumns.ts
new file mode 100644
index 000000000..a7acd7743
--- /dev/null
+++ b/packages/webapp/src/containers/FinancialStatements/Journal/dynamicColumns.ts
@@ -0,0 +1,134 @@
+// @ts-nocheck
+import { Align } from '@/constants';
+import { getColumnWidth } from '@/utils';
+import * as R from 'ramda';
+import { useJournalSheetContext } from './JournalProvider';
+
+const getTableCellValueAccessor = (index) => `cells[${index}].value`;
+
+const getReportColWidth = (data, accessor, headerText) => {
+ return getColumnWidth(
+ data,
+ accessor,
+ { magicSpacing: 10, minWidth: 100 },
+ headerText,
+ );
+};
+
+/**
+ * Common column mapper.
+ */
+const commonAccessor = R.curry((data, column) => {
+ const accessor = getTableCellValueAccessor(column.cell_index);
+
+ return {
+ key: column.key,
+ Header: column.label,
+ accessor,
+ className: column.key,
+ textOverview: true,
+ align: Align.Left,
+ };
+});
+
+/**
+ * Numeric columns accessor.
+ */
+const numericColumnAccessor = R.curry((data, column) => {
+ const accessor = getTableCellValueAccessor(column.cell_index);
+ const width = getReportColWidth(data, accessor, column.label);
+
+ return {
+ ...column,
+ align: Align.Right,
+ width,
+ };
+});
+
+/**
+ * Date column accessor.
+ */
+const dateColumnAccessor = (column) => {
+ return {
+ ...column,
+ width: 100,
+ };
+};
+
+/**
+ * Transaction type column accessor.
+ */
+const transactionTypeColumnAccessor = (column) => {
+ return {
+ ...column,
+ width: 120,
+ };
+};
+
+/**
+ * Transaction number column accessor.
+ */
+const transactionNumberColumnAccessor = (column) => {
+ return {
+ ...column,
+ width: 70,
+ };
+};
+
+/**
+ * Account code column accessor.
+ */
+const accountCodeColumnAccessor = (column) => {
+ return {
+ ...column,
+ width: 70,
+ };
+};
+
+/**
+ * Dynamic column mapper.
+ * @param {} data -
+ * @param {} column -
+ */
+const dynamicColumnMapper = R.curry((data, column) => {
+ const _commonAccessor = commonAccessor(data);
+ const _numericColumnAccessor = numericColumnAccessor(data);
+
+ return R.compose(
+ R.when(R.pathEq(['key'], 'date'), dateColumnAccessor),
+ R.when(
+ R.pathEq(['key'], 'transaction_type'),
+ transactionTypeColumnAccessor,
+ ),
+ R.when(
+ R.pathEq(['key'], 'transaction_number'),
+ transactionNumberColumnAccessor,
+ ),
+ R.when(R.pathEq(['key'], 'account_code'), accountCodeColumnAccessor),
+ R.when(R.pathEq(['key'], 'credit'), _numericColumnAccessor),
+ R.when(R.pathEq(['key'], 'debit'), _numericColumnAccessor),
+ _commonAccessor,
+ )(column);
+});
+
+/**
+ * Composes the fetched dynamic columns from the server to the columns to pass it
+ * to the table component.
+ */
+export const dynamicColumns = (columns, data) => {
+ return R.map(dynamicColumnMapper(data), columns);
+};
+
+/**
+ * Retrieves the table columns of journal sheet.
+ */
+export const useJournalSheetColumns = () => {
+ const { journalSheet } = useJournalSheetContext();
+
+ if (!journalSheet) {
+ throw new Error('The journal sheet is not loaded');
+ }
+ const { table } = journalSheet;
+
+ return dynamicColumns(table.columns, table.rows);
+};
diff --git a/packages/webapp/src/containers/FinancialStatements/Journal/utils.tsx b/packages/webapp/src/containers/FinancialStatements/Journal/utils.tsx
index f65f027ed..22cf34638 100644
--- a/packages/webapp/src/containers/FinancialStatements/Journal/utils.tsx
+++ b/packages/webapp/src/containers/FinancialStatements/Journal/utils.tsx
@@ -1,6 +1,5 @@
// @ts-nocheck
import React from 'react';
-import { castArray } from 'lodash';
import moment from 'moment';
import { useAppQueryString } from '@/hooks';
diff --git a/packages/webapp/src/hooks/query/financialReports.tsx b/packages/webapp/src/hooks/query/financialReports.tsx
index e9531ddec..e10951472 100644
--- a/packages/webapp/src/hooks/query/financialReports.tsx
+++ b/packages/webapp/src/hooks/query/financialReports.tsx
@@ -1,8 +1,6 @@
// @ts-nocheck
import { useRequestQuery } from '../useQueryRequest';
import {
- generalLedgerTableRowsReducer,
- journalTableRowsReducer,
inventoryValuationReducer,
purchasesByItemsReducer,
salesByItemsReducer,
@@ -167,21 +165,44 @@ export function useGeneralLedgerSheet(query, props) {
method: 'get',
url: '/financial_statements/general_ledger',
params: query,
+ headers: {
+ Accept: 'application/json+table',
+ },
},
{
- select: (res) => ({
- tableRows: generalLedgerTableRowsReducer(res.data.data),
- ...res.data,
- }),
- defaultData: {
- tableRows: [],
- data: {},
- query: {},
- },
+ select: (res) => res.data,
...props,
},
);
}
+export const useGeneralLedgerSheetXlsxExport = (query, args) => {
+return useDownloadFile({
+ url: '/financial_statements/general_ledger',
+ config: {
+ headers: {
+ accept: 'application/xlsx',
+ },
+ params: query,
+ },
+ filename: 'general_ledger.xlsx',
+ ...args,
+});
+};
+
+export const useGeneralLedgerSheetCsvExport = (query, args) => {
+return useDownloadFile({
+ url: '/financial_statements/general_ledger',
+ config: {
+ headers: {
+ accept: 'application/csv',
+ },
+ params: query,
+ },
+ filename: 'general_ledger.csv',
+ ...args,
+});
+};
+
/**
* Retrieve journal sheet.
@@ -189,22 +210,49 @@ export function useGeneralLedgerSheet(query, props) {
export function useJournalSheet(query, props) {
return useRequestQuery(
[t.FINANCIAL_REPORT, t.JOURNAL, query],
- { method: 'get', url: '/financial_statements/journal', params: query },
{
- select: (res) => ({
- tableRows: journalTableRowsReducer(res.data.data),
- ...res.data,
- }),
- defaultData: {
- data: {},
- tableRows: [],
- query: {},
+ method: 'get',
+ url: '/financial_statements/journal',
+ params: query,
+ headers: {
+ Accept: 'application/json+table',
},
+ },
+ {
+ select: (res) => res.data,
...props,
},
);
}
+export const useJournalSheetXlsxExport = (query, args) => {
+ return useDownloadFile({
+ url: '/financial_statements/journal',
+ config: {
+ headers: {
+ accept: 'application/xlsx',
+ },
+ params: query,
+ },
+ filename: 'journal.xlsx',
+ ...args,
+ });
+};
+
+export const useJournalSheetCsvExport = (query, args) => {
+ return useDownloadFile({
+ url: '/financial_statements/journal',
+ config: {
+ headers: {
+ accept: 'application/csv',
+ },
+ params: query,
+ },
+ filename: 'journal.csv',
+ ...args,
+ });
+};
+
/**
* Retrieve A/R aging summary report.
*/