feat(webapp): wip sales tax liability summary report
This commit is contained in:
@@ -169,6 +169,7 @@ export const ReportsAction = {
|
||||
READ_INVENTORY_VALUATION_SUMMARY: 'read-inventory-valuation-summary',
|
||||
READ_INVENTORY_ITEM_DETAILS: 'read-inventory-item-details',
|
||||
READ_CASHFLOW_ACCOUNT_TRANSACTION: 'read-cashflow-account-transactions',
|
||||
READ_SALES_TAX_LIABILITY_SUMMARY: 'read-sales-tax-liability-summary',
|
||||
};
|
||||
|
||||
export const PreferencesAbility = {
|
||||
|
||||
@@ -85,6 +85,13 @@ export const financialReportMenus = [
|
||||
subject: AbilitySubject.Report,
|
||||
ability: ReportsAction.READ_PROFIT_LOSS,
|
||||
},
|
||||
{
|
||||
title: 'Sales Tax Liability Summary',
|
||||
desc: 'Reports the total amount of sales tax collected from customers',
|
||||
link: '/financial-reports/sales-tax-liability-summary',
|
||||
subject: AbilitySubject.Report,
|
||||
ability: ReportsAction.READ_SALES_TAX_LIABILITY_SUMMARY,
|
||||
}
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
// @ts-nocheck
|
||||
import React, { useEffect } from 'react';
|
||||
import moment from 'moment';
|
||||
|
||||
import { SalesTaxLiabilitySummaryLoadingBar } from './components';
|
||||
import { FinancialStatement, DashboardPageContent } from '@/components';
|
||||
|
||||
import SalesTaxLiabilitySummaryHeader from './SalesTaxLiabilitySummaryHeader';
|
||||
import SalesTaxLiabilitySummaryActionsBar from './SalesTaxLiabilitySummaryActionsBar';
|
||||
import { SalesTaxLiabilitySummaryBoot } from './SalesTaxLiabilitySummaryBoot';
|
||||
import { SalesTaxLiabilitySummaryBody } from './SalesTaxLiabilitySummaryBody';
|
||||
import { useSalesTaxLiabilitySummaryQuery } from './utils';
|
||||
import withSalesTaxLiabilitySummaryActions from './withSalesTaxLiabilitySummaryActions';
|
||||
import { compose } from '@/utils';
|
||||
|
||||
/**
|
||||
* Sales tax liability summary.
|
||||
* @returns {React.JSX}
|
||||
*/
|
||||
function SalesTaxLiabilitySummary({
|
||||
// #withSalesTaxLiabilitySummaryActions
|
||||
toggleSalesTaxLiabilitySummaryFilterDrawer,
|
||||
}) {
|
||||
const [query, setQuery] = useSalesTaxLiabilitySummaryQuery();
|
||||
|
||||
const handleFilterSubmit = (filter) => {
|
||||
const newFilter = {
|
||||
...filter,
|
||||
fromDate: moment(filter.fromDate).format('YYYY-MM-DD'),
|
||||
toDate: moment(filter.toDate).format('YYYY-MM-DD'),
|
||||
};
|
||||
setQuery({ ...newFilter });
|
||||
};
|
||||
// Handle number format submit.
|
||||
const handleNumberFormatSubmit = (values) => {
|
||||
setQuery({
|
||||
...query,
|
||||
numberFormat: values,
|
||||
});
|
||||
};
|
||||
// Hides the filter drawer once the page unmount.
|
||||
useEffect(
|
||||
() => () => {
|
||||
toggleSalesTaxLiabilitySummaryFilterDrawer(false);
|
||||
},
|
||||
[toggleSalesTaxLiabilitySummaryFilterDrawer],
|
||||
);
|
||||
|
||||
return (
|
||||
<SalesTaxLiabilitySummaryBoot filter={query}>
|
||||
<SalesTaxLiabilitySummaryActionsBar
|
||||
numberFormat={query.numberFormat}
|
||||
onNumberFormatSubmit={handleNumberFormatSubmit}
|
||||
/>
|
||||
<SalesTaxLiabilitySummaryLoadingBar />
|
||||
|
||||
<DashboardPageContent>
|
||||
<FinancialStatement>
|
||||
<SalesTaxLiabilitySummaryHeader
|
||||
pageFilter={query}
|
||||
onSubmitFilter={handleFilterSubmit}
|
||||
/>
|
||||
<SalesTaxLiabilitySummaryBody />
|
||||
</FinancialStatement>
|
||||
</DashboardPageContent>
|
||||
</SalesTaxLiabilitySummaryBoot>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(withSalesTaxLiabilitySummaryActions)(
|
||||
SalesTaxLiabilitySummary,
|
||||
);
|
||||
@@ -0,0 +1,133 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import {
|
||||
NavbarGroup,
|
||||
Button,
|
||||
Classes,
|
||||
NavbarDivider,
|
||||
Popover,
|
||||
PopoverInteractionKind,
|
||||
Position,
|
||||
} from '@blueprintjs/core';
|
||||
import classNames from 'classnames';
|
||||
import { DashboardActionsBar, FormattedMessage as T, Icon } from '@/components';
|
||||
|
||||
import NumberFormatDropdown from '@/components/NumberFormatDropdown';
|
||||
|
||||
import { compose, saveInvoke } from '@/utils';
|
||||
import { useSalesTaxLiabilitySummaryContext } from './SalesTaxLiabilitySummaryBoot';
|
||||
import withSalesTaxLiabilitySummary from './withSalesTaxLiabilitySummary';
|
||||
import withSalesTaxLiabilitySummaryActions from './withSalesTaxLiabilitySummaryActions';
|
||||
|
||||
/**
|
||||
* Sales tax liability summary - actions bar.
|
||||
*/
|
||||
function SalesTaxLiabilitySummaryActionsBar({
|
||||
// #withSalesTaxLiabilitySummary
|
||||
salesTaxLiabilitySummaryFilter,
|
||||
|
||||
// #withSalesTaxLiabilitySummaryActions
|
||||
toggleBalanceSheetFilterDrawer: toggleFilterDrawer,
|
||||
|
||||
// #ownProps
|
||||
numberFormat,
|
||||
onNumberFormatSubmit,
|
||||
}) {
|
||||
const { isLoading, refetchBalanceSheet } =
|
||||
useSalesTaxLiabilitySummaryContext();
|
||||
|
||||
// Handle filter toggle click.
|
||||
const handleFilterToggleClick = () => {
|
||||
toggleFilterDrawer();
|
||||
};
|
||||
|
||||
// Handle recalculate the report button.
|
||||
const handleRecalcReport = () => {
|
||||
refetchBalanceSheet();
|
||||
};
|
||||
|
||||
// Handle number format form submit.
|
||||
const handleNumberFormatSubmit = (values) => {
|
||||
saveInvoke(onNumberFormatSubmit, values);
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardActionsBar>
|
||||
<NavbarGroup>
|
||||
<Button
|
||||
className={classNames(Classes.MINIMAL, 'button--gray-highlight')}
|
||||
text={<T id={'recalc_report'} />}
|
||||
onClick={handleRecalcReport}
|
||||
icon={<Icon icon="refresh-16" iconSize={16} />}
|
||||
/>
|
||||
<NavbarDivider />
|
||||
|
||||
<Button
|
||||
className={classNames(Classes.MINIMAL, 'button--table-views')}
|
||||
icon={<Icon icon="cog-16" iconSize={16} />}
|
||||
text={
|
||||
!salesTaxLiabilitySummaryFilter ? (
|
||||
<T id={'customize_report'} />
|
||||
) : (
|
||||
<T id={'hide_customizer'} />
|
||||
)
|
||||
}
|
||||
onClick={handleFilterToggleClick}
|
||||
active={salesTaxLiabilitySummaryFilter}
|
||||
/>
|
||||
<NavbarDivider />
|
||||
|
||||
<Popover
|
||||
content={
|
||||
<NumberFormatDropdown
|
||||
numberFormat={numberFormat}
|
||||
onSubmit={handleNumberFormatSubmit}
|
||||
submitDisabled={isLoading}
|
||||
/>
|
||||
}
|
||||
minimal={true}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
position={Position.BOTTOM_LEFT}
|
||||
>
|
||||
<Button
|
||||
className={classNames(Classes.MINIMAL, 'button--filter')}
|
||||
text={<T id={'format'} />}
|
||||
icon={<Icon icon="numbers" width={23} height={16} />}
|
||||
/>
|
||||
</Popover>
|
||||
|
||||
<Popover
|
||||
// content={}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
position={Position.BOTTOM_LEFT}
|
||||
>
|
||||
<Button
|
||||
className={classNames(Classes.MINIMAL, 'button--filter')}
|
||||
text={<T id={'filter'} />}
|
||||
icon={<Icon icon="filter-16" iconSize={16} />}
|
||||
/>
|
||||
</Popover>
|
||||
|
||||
<NavbarDivider />
|
||||
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="print-16" iconSize={16} />}
|
||||
text={<T id={'print'} />}
|
||||
/>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
</NavbarGroup>
|
||||
</DashboardActionsBar>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withSalesTaxLiabilitySummary(({ salesTaxLiabilitySummaryFilter }) => ({
|
||||
salesTaxLiabilitySummaryFilter,
|
||||
})),
|
||||
withSalesTaxLiabilitySummaryActions,
|
||||
)(SalesTaxLiabilitySummaryActionsBar);
|
||||
@@ -0,0 +1,37 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
|
||||
import { FinancialReportBody } from '../FinancialReportPage';
|
||||
import { FinancialSheetSkeleton } from '@/components';
|
||||
import { SalesTaxLiabilitySummaryTable } from './SalesTaxLiabilitySummaryTable';
|
||||
|
||||
import withCurrentOrganization from '@/containers/Organization/withCurrentOrganization';
|
||||
import { useSalesTaxLiabilitySummaryContext } from './SalesTaxLiabilitySummaryBoot';
|
||||
import { compose } from '@/utils';
|
||||
|
||||
/**
|
||||
* Sales tax liability summary body.
|
||||
* @returns {React.JSX}
|
||||
*/
|
||||
function SalesTaxLiabilitySummaryBodyRoot({
|
||||
// #withCurrentOrganization
|
||||
organizationName,
|
||||
}) {
|
||||
const { isLoading } = useSalesTaxLiabilitySummaryContext();
|
||||
|
||||
return (
|
||||
<FinancialReportBody>
|
||||
{isLoading ? (
|
||||
<FinancialSheetSkeleton />
|
||||
) : (
|
||||
<SalesTaxLiabilitySummaryTable />
|
||||
)}
|
||||
</FinancialReportBody>
|
||||
);
|
||||
}
|
||||
|
||||
export const SalesTaxLiabilitySummaryBody = compose(
|
||||
withCurrentOrganization(({ organization }) => ({
|
||||
organizationName: organization.name,
|
||||
})),
|
||||
)(SalesTaxLiabilitySummaryBodyRoot);
|
||||
@@ -0,0 +1,45 @@
|
||||
// @ts-nocheck
|
||||
import React, { createContext, useContext } from 'react';
|
||||
import FinancialReportPage from '../FinancialReportPage';
|
||||
import { transformFilterFormToQuery } from '../common';
|
||||
import { useSalesTaxLiabilitySummary } from '@/hooks/query';
|
||||
|
||||
const SalesTaxLiabilitySummaryContext = createContext();
|
||||
|
||||
/**
|
||||
* Sales tax liability summary boot.
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
function SalesTaxLiabilitySummaryBoot({ filter, ...props }) {
|
||||
// Transformes the given filter to query.
|
||||
const query = React.useMemo(
|
||||
() => transformFilterFormToQuery(filter),
|
||||
[filter],
|
||||
);
|
||||
// Fetches the sales tax liability summary report.
|
||||
const {
|
||||
data: salesTaxLiabilitySummary,
|
||||
isFetching,
|
||||
isLoading,
|
||||
refetch,
|
||||
} = useSalesTaxLiabilitySummary(query, { keepPreviousData: true });
|
||||
|
||||
const provider = {
|
||||
salesTaxLiabilitySummary,
|
||||
isFetching,
|
||||
isLoading,
|
||||
query,
|
||||
filter,
|
||||
};
|
||||
|
||||
return (
|
||||
<FinancialReportPage name={'sales-tax-liability-summary'}>
|
||||
<SalesTaxLiabilitySummaryContext.Provider value={provider} {...props} />
|
||||
</FinancialReportPage>
|
||||
);
|
||||
}
|
||||
|
||||
const useSalesTaxLiabilitySummaryContext = () =>
|
||||
useContext(SalesTaxLiabilitySummaryContext);
|
||||
|
||||
export { SalesTaxLiabilitySummaryBoot, useSalesTaxLiabilitySummaryContext };
|
||||
@@ -0,0 +1,116 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import moment from 'moment';
|
||||
import { Tabs, Tab, Button, Intent } from '@blueprintjs/core';
|
||||
import { Formik, Form } from 'formik';
|
||||
|
||||
import { FormattedMessage as T } from '@/components';
|
||||
import { useFeatureCan } from '@/hooks/state';
|
||||
import { Features } from '@/constants';
|
||||
|
||||
import BalanceSheetHeaderGeneralPanal from './BalanceSheetHeaderGeneralPanal';
|
||||
import FinancialStatementHeader from '../../FinancialStatements/FinancialStatementHeader';
|
||||
|
||||
import { compose, transformToForm } from '@/utils';
|
||||
import {
|
||||
getDefaultSalesTaxLiablitySummaryQuery,
|
||||
getSalesTaxLiabilitySummaryQueryValidation,
|
||||
} from './utils';
|
||||
import withSalesTaxLiabilitySummary from './withSalesTaxLiabilitySummary';
|
||||
import withSalesTaxLiabilitySummaryActions from './withSalesTaxLiabilitySummaryActions';
|
||||
|
||||
/**
|
||||
* Sales tax liability summary header.
|
||||
*/
|
||||
function SalesTaxLiabilitySummaryHeader({
|
||||
// #ownProps
|
||||
onSubmitFilter,
|
||||
pageFilter,
|
||||
|
||||
// #withSalesTaxLiabilitySummary
|
||||
salesTaxLiabilitySummaryFilter,
|
||||
|
||||
// #withSalesTaxLiabilitySummaryActions
|
||||
toggleSalesTaxLiabilitySummaryFilterDrawer: toggleFilterDrawer,
|
||||
}) {
|
||||
const defaultValues = getDefaultSalesTaxLiablitySummaryQuery();
|
||||
|
||||
// Filter form initial values.
|
||||
const initialValues = transformToForm(
|
||||
{
|
||||
...defaultValues,
|
||||
...pageFilter,
|
||||
fromDate: moment(pageFilter.fromDate).toDate(),
|
||||
toDate: moment(pageFilter.toDate).toDate(),
|
||||
},
|
||||
defaultValues,
|
||||
);
|
||||
// Validation schema.
|
||||
const validationSchema = getSalesTaxLiabilitySummaryQueryValidation();
|
||||
|
||||
// Handle form submit.
|
||||
const handleSubmit = (values, actions) => {
|
||||
onSubmitFilter(values);
|
||||
toggleFilterDrawer(false);
|
||||
actions.setSubmitting(false);
|
||||
};
|
||||
// Handle cancel button click.
|
||||
const handleCancelClick = () => {
|
||||
toggleFilterDrawer(false);
|
||||
};
|
||||
// Handle drawer close action.
|
||||
const handleDrawerClose = () => {
|
||||
toggleFilterDrawer(false);
|
||||
};
|
||||
// Detarmines the given feature whether is enabled.
|
||||
const { featureCan } = useFeatureCan();
|
||||
const isBranchesFeatureCan = featureCan(Features.Branches);
|
||||
|
||||
return (
|
||||
<BalanceSheetFinancialHeader
|
||||
isOpen={salesTaxLiabilitySummaryFilter}
|
||||
drawerProps={{
|
||||
onClose: handleDrawerClose,
|
||||
}}
|
||||
>
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
validationSchema={validationSchema}
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
<Form>
|
||||
{/* <Tabs animate={true} vertical={true} renderActiveTabPanelOnly={true}>
|
||||
<Tab
|
||||
id="general"
|
||||
title={<T id={'general'} />}
|
||||
panel={<BalanceSheetHeaderGeneralPanal />}
|
||||
/>
|
||||
</Tabs> */}
|
||||
|
||||
<div class="financial-header-drawer__footer">
|
||||
<Button className={'mr1'} intent={Intent.PRIMARY} type={'submit'}>
|
||||
<T id={'calculate_report'} />
|
||||
</Button>
|
||||
<Button onClick={handleCancelClick} minimal={true}>
|
||||
<T id={'cancel'} />
|
||||
</Button>
|
||||
</div>
|
||||
</Form>
|
||||
</Formik>
|
||||
</BalanceSheetFinancialHeader>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withSalesTaxLiabilitySummary(({ salesTaxLiabilitySummaryFilter }) => ({
|
||||
salesTaxLiabilitySummaryFilter,
|
||||
})),
|
||||
withSalesTaxLiabilitySummaryActions,
|
||||
)(SalesTaxLiabilitySummaryHeader);
|
||||
|
||||
const BalanceSheetFinancialHeader = styled(FinancialStatementHeader)`
|
||||
.bp3-drawer {
|
||||
max-height: 520px;
|
||||
}
|
||||
`;
|
||||
@@ -0,0 +1,93 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import intl from 'react-intl-universal';
|
||||
|
||||
import { TableStyle } from '@/constants';
|
||||
import { ReportDataTable, FinancialSheet } from '@/components';
|
||||
import { defaultExpanderReducer, tableRowTypesToClassnames } from '@/utils';
|
||||
import { useSalesTaxLiabilitySummaryContext } from './SalesTaxLiabilitySummaryBoot';
|
||||
import withCurrentOrganization from '@/containers/Organization/withCurrentOrganization';
|
||||
import { useSalesTaxLiabilitySummaryColumns } from './utils';
|
||||
import { compose } from 'ramda';
|
||||
|
||||
/**
|
||||
* Balance sheet table.
|
||||
*/
|
||||
function SalesTaxLiabilitySummaryTableRoot({
|
||||
// #ownProps
|
||||
organizationName,
|
||||
}) {
|
||||
// Balance sheet context.
|
||||
const {
|
||||
salesTaxLiabilitySummary: { table },
|
||||
} = useSalesTaxLiabilitySummaryContext();
|
||||
|
||||
// Retrieve the database columns.
|
||||
const columns = useSalesTaxLiabilitySummaryColumns();
|
||||
|
||||
// Retrieve default expanded rows of balance sheet.
|
||||
const expandedRows = React.useMemo(
|
||||
() => defaultExpanderReducer(table.rows, 3),
|
||||
[table],
|
||||
);
|
||||
|
||||
return (
|
||||
<FinancialSheet
|
||||
companyName={organizationName}
|
||||
sheetType={'Sales Tax Liability Summary'}
|
||||
asDate={new Date()}
|
||||
basis={''}
|
||||
>
|
||||
<SalesTaxLiabilitySummaryDataTable
|
||||
columns={columns}
|
||||
data={table.rows}
|
||||
rowClassNames={tableRowTypesToClassnames}
|
||||
noInitialFetch={true}
|
||||
expandable={true}
|
||||
expanded={expandedRows}
|
||||
expandToggleColumn={1}
|
||||
expandColumnSpace={0.8}
|
||||
headerLoading={true}
|
||||
sticky={true}
|
||||
styleName={TableStyle.Constrant}
|
||||
/>
|
||||
</FinancialSheet>
|
||||
);
|
||||
}
|
||||
|
||||
const SalesTaxLiabilitySummaryDataTable = styled(ReportDataTable)`
|
||||
.table {
|
||||
.tbody .tr {
|
||||
.td {
|
||||
border-bottom: 0;
|
||||
padding-top: 0.32rem;
|
||||
padding-bottom: 0.32rem;
|
||||
}
|
||||
&:not(.no-results) {
|
||||
.td {
|
||||
border-bottom: 0;
|
||||
padding-top: 0.4rem;
|
||||
padding-bottom: 0.4rem;
|
||||
}
|
||||
&:not(:first-child) .td {
|
||||
border-top: 1px solid transparent;
|
||||
}
|
||||
&.row_type--Total {
|
||||
font-weight: 500;
|
||||
|
||||
.td {
|
||||
border-top: 1px solid #bbb;
|
||||
border-bottom: 3px double #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const SalesTaxLiabilitySummaryTable = compose(
|
||||
withCurrentOrganization(({ organization }) => ({
|
||||
organizationName: organization.name,
|
||||
})),
|
||||
)(SalesTaxLiabilitySummaryTableRoot);
|
||||
@@ -0,0 +1,17 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
|
||||
import { useSalesTaxLiabilitySummaryContext } from './SalesTaxLiabilitySummaryBoot';
|
||||
import FinancialLoadingBar from '../FinancialLoadingBar';
|
||||
|
||||
/**
|
||||
* Balance sheet loading bar.
|
||||
*/
|
||||
export function SalesTaxLiabilitySummaryLoadingBar() {
|
||||
const { isFetching } = useSalesTaxLiabilitySummaryContext();
|
||||
|
||||
if (!isFetching) {
|
||||
return null;
|
||||
}
|
||||
return <FinancialLoadingBar />;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
// @ts-nocheck
|
||||
import React, { useMemo } from 'react';
|
||||
import * as R from 'ramda';
|
||||
import { getColumnWidth } from '@/utils';
|
||||
import { Align } from '@/constants';
|
||||
|
||||
const getTableCellValueAccessor = (index) => `cells[${index}].value`;
|
||||
|
||||
const taxNameAccessor = R.curry((data, column) => ({
|
||||
key: column.key,
|
||||
Header: column.label,
|
||||
accessor: getTableCellValueAccessor(column.cell_index),
|
||||
sticky: 'left',
|
||||
width: 240,
|
||||
textOverview: true,
|
||||
}));
|
||||
|
||||
const taxCodeAccessor = R.curry((data, column) => ({
|
||||
key: column.key,
|
||||
Header: column.label,
|
||||
accessor: getTableCellValueAccessor(column.cell_index),
|
||||
sticky: 'left',
|
||||
width: 240,
|
||||
textOverview: true,
|
||||
}));
|
||||
|
||||
const taxableAmountAccessor = R.curry((data, column) => {
|
||||
const accessor = getTableCellValueAccessor(column.cell_index);
|
||||
|
||||
return {
|
||||
Header: column.label,
|
||||
id: column.key,
|
||||
accessor: getTableCellValueAccessor(column.cell_index),
|
||||
className: column.key,
|
||||
width: getColumnWidth(data, accessor, { minWidth: 120 }),
|
||||
align: Align.Right,
|
||||
};
|
||||
});
|
||||
|
||||
const dynamicColumnMapper = R.curry((data, column) => {
|
||||
const taxNameAccessorColumn = taxNameAccessor(data);
|
||||
const taxCodeAccessorColumn = taxCodeAccessor(data);
|
||||
const taxableAmountColumn = taxableAmountAccessor(data);
|
||||
|
||||
return R.compose(
|
||||
R.when(R.pathEq(['key'], 'taxName'), taxNameAccessorColumn),
|
||||
R.when(R.pathEq(['key'], 'taxCode'), taxCodeAccessorColumn),
|
||||
R.when(R.pathEq(['key'], 'taxableAmount'), taxableAmountColumn),
|
||||
R.when(R.pathEq(['key'], 'taxRate'), taxableAmountColumn),
|
||||
)(column);
|
||||
});
|
||||
|
||||
export const salesTaxLiabilitySummaryDynamicColumns = (columns, data) => {
|
||||
return R.map(dynamicColumnMapper(data), columns);
|
||||
};
|
||||
@@ -0,0 +1,89 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import * as Yup from 'yup';
|
||||
import { castArray } from 'lodash';
|
||||
import intl from 'react-intl-universal';
|
||||
import { transformToForm } from '@/utils';
|
||||
import { useAppQueryString } from '@/hooks';
|
||||
import { salesTaxLiabilitySummaryDynamicColumns } from './dynamicColumns';
|
||||
import { useSalesTaxLiabilitySummaryContext } from './SalesTaxLiabilitySummaryBoot';
|
||||
|
||||
/**
|
||||
* Retrieves the default sales tax liability summary query.
|
||||
* @returns {}
|
||||
*/
|
||||
export const getDefaultSalesTaxLiablitySummaryQuery = () => ({
|
||||
fromDate: moment().startOf('month').format('YYYY-MM-DD'),
|
||||
toDate: moment().format('YYYY-MM-DD'),
|
||||
basis: 'cash',
|
||||
});
|
||||
|
||||
/**
|
||||
* Parses the sales tax liability summary query.
|
||||
*/
|
||||
const parseSalesTaxLiabilitySummaryQuery = (locationQuery) => {
|
||||
const defaultQuery = getDefaultSalesTaxLiablitySummaryQuery();
|
||||
|
||||
const transformed = {
|
||||
...defaultQuery,
|
||||
...transformToForm(locationQuery, defaultQuery),
|
||||
};
|
||||
return {
|
||||
...transformed,
|
||||
|
||||
// Ensures the branches ids is always array.
|
||||
branchesIds: castArray(transformed.branchesIds),
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the sales tax liability summary query.
|
||||
*/
|
||||
export const useSalesTaxLiabilitySummaryQuery = () => {
|
||||
// Retrieves location query.
|
||||
const [locationQuery, setLocationQuery] = useAppQueryString();
|
||||
|
||||
// Merges the default filter query with location URL query.
|
||||
const parsedQuery = React.useMemo(
|
||||
() => parseSalesTaxLiabilitySummaryQuery(locationQuery),
|
||||
[locationQuery],
|
||||
);
|
||||
return [parsedQuery, setLocationQuery];
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the sales tax liability summary default query.
|
||||
*/
|
||||
export const getSalesTaxLiabilitySummaryDefaultQuery = () => {
|
||||
return {
|
||||
basic: 'cash',
|
||||
fromDate: moment().toDate(),
|
||||
toDate: moment().toDate(),
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the sales tax liability summary query validation.
|
||||
*/
|
||||
export const getSalesTaxLiabilitySummaryQueryValidation = () =>
|
||||
Yup.object().shape({
|
||||
dateRange: Yup.string().optional(),
|
||||
fromDate: Yup.date().required().label(intl.get('fromDate')),
|
||||
toDate: Yup.date()
|
||||
.min(Yup.ref('fromDate'))
|
||||
.required()
|
||||
.label(intl.get('toDate')),
|
||||
});
|
||||
|
||||
/**
|
||||
* Retrieves the sales tax liability summary columns.
|
||||
* @returns {ITableColumn[]}
|
||||
*/
|
||||
export const useSalesTaxLiabilitySummaryColumns = () => {
|
||||
const {
|
||||
salesTaxLiabilitySummary: { table },
|
||||
} = useSalesTaxLiabilitySummaryContext();
|
||||
|
||||
return salesTaxLiabilitySummaryDynamicColumns(table.columns, table.rows);
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
// @ts-nocheck
|
||||
import { connect } from 'react-redux';
|
||||
import { getSalesTaxLiabilitySummaryFilterDrawer } from '@/store/financialStatement/financialStatements.selectors';
|
||||
|
||||
export default (mapState) => {
|
||||
const mapStateToProps = (state, props) => {
|
||||
const mapped = {
|
||||
salesTaxLiabilitySummaryFilter:
|
||||
getSalesTaxLiabilitySummaryFilterDrawer(state),
|
||||
};
|
||||
return mapState ? mapState(mapped, state, props) : mapped;
|
||||
};
|
||||
|
||||
return connect(mapStateToProps);
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
// @ts-nocheck
|
||||
import { connect } from 'react-redux';
|
||||
import { toggleBalanceSheetFilterDrawer } from '@/store/financialStatement/financialStatements.actions';
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
toggleSalesTaxLiabilitySummaryFilterDrawer: (toggle) =>
|
||||
dispatch(toggleBalanceSheetFilterDrawer(toggle)),
|
||||
});
|
||||
|
||||
export default connect(null, mapDispatchToProps);
|
||||
@@ -444,3 +444,25 @@ export function useTransactionsByReference(query, props) {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export function useSalesTaxLiabilitySummary(query, props) {
|
||||
return useRequestQuery(
|
||||
[t.FINANCIAL_REPORT, t.BALANCE_SHEET, query],
|
||||
{
|
||||
method: 'get',
|
||||
url: '/financial_statements/sales-tax-liability-summary',
|
||||
params: query,
|
||||
headers: {
|
||||
Accept: 'application/json+table',
|
||||
},
|
||||
},
|
||||
{
|
||||
select: (res) => res.data,
|
||||
...props,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -440,7 +440,9 @@ export const getDashboardRoutes = () => [
|
||||
path: `/financial-reports/project-profitability-summary`,
|
||||
component: lazy(
|
||||
() =>
|
||||
import('@/containers/FinancialStatements/ProjectProfitabilitySummary/ProjectProfitabilitySummary'),
|
||||
import(
|
||||
'@/containers/FinancialStatements/ProjectProfitabilitySummary/ProjectProfitabilitySummary'
|
||||
),
|
||||
),
|
||||
breadcrumb: intl.get('project_profitability_summary'),
|
||||
pageTitle: intl.get('project_profitability_summary'),
|
||||
@@ -448,6 +450,20 @@ export const getDashboardRoutes = () => [
|
||||
sidebarExpand: false,
|
||||
subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
|
||||
},
|
||||
{
|
||||
path: '/financial-reports/sales-tax-liability-summary',
|
||||
component: lazy(
|
||||
() =>
|
||||
import(
|
||||
'@/containers/FinancialStatements/SalesTaxLiabilitySummary/SalesTaxLiabilitySummary'
|
||||
),
|
||||
),
|
||||
breadcrumb: 'Sales Tax Liability Summary',
|
||||
pageTitle: 'Sales Tax Liability Summary',
|
||||
backLink: true,
|
||||
sidebarExpand: false,
|
||||
subscriptionActive: [SUBSCRIPTION_TYPE.MAIN],
|
||||
},
|
||||
{
|
||||
path: '/financial-reports',
|
||||
component: lazy(
|
||||
|
||||
@@ -86,6 +86,10 @@ export const projectProfitabilitySummaryFilterDrawerSelector = (state) => {
|
||||
return filterDrawerByTypeSelector('projectProfitabilitySummary')(state);
|
||||
};
|
||||
|
||||
export const salesTaxLiabilitySummaryFilterDrawerSelector = (state) => {
|
||||
return filterDrawerByTypeSelector('projectProfitabilitySummary')(state);
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve balance sheet filter drawer.
|
||||
*/
|
||||
@@ -278,3 +282,11 @@ export const getProjectProfitabilitySummaryFilterDrawer = createSelector(
|
||||
return isOpen;
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Retrieve sales tax liability summary filter drawer.
|
||||
*/
|
||||
export const getSalesTaxLiabilitySummaryFilterDrawer = createSelector(
|
||||
salesTaxLiabilitySummaryFilterDrawerSelector,
|
||||
(isOpen) => isOpen,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user