Merge branch 'develop' into feature/multi-dimensions

This commit is contained in:
Ahmed Bouhuolia
2022-03-23 12:12:20 +02:00
committed by GitHub
60 changed files with 449 additions and 172 deletions

View File

@@ -2,6 +2,26 @@
All notable changes to Bigcapital server-side will be in this file. All notable changes to Bigcapital server-side will be in this file.
## [1.6.3] - 21-02-2022
### Fixed
- `BIG-337` Display billing page once the organization subscription is inactive.
## [1.6.2] - 19-02-2022
### Fixed
- fix syled components dependency with imported as default components.
## [1.6.0] - 18-02-2022
### Added
- Balance sheet comparison of previous period (PP).
- Balance sheet comparison of previous year (PY).
- Balance sheet percentage analysis columns and rows basis.
- Profit & loss sheet comparison of preivous period (PP).
- Profit & loss sheet comparison of previous year (PY).
- Profit & loss sheet percentage analysis columns, rows, income and expenses basis.
## [1.5.8] - 13-01-2022 ## [1.5.8] - 13-01-2022
### Added ### Added

View File

@@ -1,6 +1,6 @@
{ {
"name": "bigcapital-client", "name": "bigcapital-client",
"version": "1.5.8", "version": "1.6.3",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@babel/core": "7.8.4", "@babel/core": "7.8.4",

View File

@@ -1,3 +1 @@
export * from './ButtonLink'; export * from './ButtonLink';

View File

@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import * as R from 'ramda'; import * as R from 'ramda';
import { ButtonLink } from 'components'; import { ButtonLink } from '../Button';
import withDrawerActions from 'containers/Drawer/withDrawerActions'; import withDrawerActions from 'containers/Drawer/withDrawerActions';
function CustomerDrawerLinkComponent({ function CustomerDrawerLinkComponent({

View File

@@ -1,7 +1,8 @@
import React from 'react'; import React from 'react';
import { Ability } from '@casl/ability'; import { Ability } from '@casl/ability';
import { createContextualCan } from '@casl/react'; import { createContextualCan } from '@casl/react';
import { useDashboardMeta } from '../../hooks/query';
import { useDashboardMetaBoot } from './DashboardBoot';
export const AbilityContext = React.createContext(); export const AbilityContext = React.createContext();
export const Can = createContextualCan(AbilityContext.Consumer); export const Can = createContextualCan(AbilityContext.Consumer);
@@ -11,8 +12,8 @@ export const Can = createContextualCan(AbilityContext.Consumer);
*/ */
export function DashboardAbilityProvider({ children }) { export function DashboardAbilityProvider({ children }) {
const { const {
data: { abilities }, meta: { abilities },
} = useDashboardMeta(); } = useDashboardMetaBoot();
// Ability instance. // Ability instance.
const ability = new Ability(abilities); const ability = new Ability(abilities);

View File

@@ -6,18 +6,26 @@ import {
} from '../../hooks/query'; } from '../../hooks/query';
import { useSplashLoading } from '../../hooks/state'; import { useSplashLoading } from '../../hooks/state';
import { useWatch, useWatchImmediate, useWhen } from '../../hooks'; import { useWatch, useWatchImmediate, useWhen } from '../../hooks';
import { useSubscription } from '../../hooks/state';
import { setCookie, getCookie } from '../../utils'; import { setCookie, getCookie } from '../../utils';
/** /**
* Dashboard meta async booting. * Dashboard meta async booting.
* - Fetches the dashboard meta only if the organization subscribe is active.
* - Once the dashboard meta query is loading display dashboard splash screen.
*/ */
export function useDashboardMetaBoot() { export function useDashboardMetaBoot() {
const { isSubscriptionActive } = useSubscription();
const { const {
data: dashboardMeta, data: dashboardMeta,
isLoading: isDashboardMetaLoading, isLoading: isDashboardMetaLoading,
isSuccess: isDashboardMetaSuccess, isSuccess: isDashboardMetaSuccess,
} = useDashboardMeta({ } = useDashboardMeta({
keepPreviousData: true, keepPreviousData: true,
// Avoid run the query if the organization subscription is not active.
enabled: isSubscriptionActive,
}); });
const [startLoading, stopLoading] = useSplashLoading(); const [startLoading, stopLoading] = useSplashLoading();
@@ -30,20 +38,12 @@ export function useDashboardMetaBoot() {
}, isDashboardMetaSuccess); }, isDashboardMetaSuccess);
return { return {
meta: dashboardMeta,
isLoading: isDashboardMetaLoading, isLoading: isDashboardMetaLoading,
isSuccess: isDashboardMetaSuccess
}; };
} }
/**
* Dashboard async booting.
* @returns {{ isLoading: boolean }}
*/
export function useDashboardBoot() {
const { isLoading } = useDashboardMetaBoot();
return { isLoading };
}
/** /**
* Application async booting. * Application async booting.
*/ */

View File

@@ -1,12 +1,12 @@
import React from 'react'; import React from 'react';
import { DashboardAbilityProvider } from '../../components'; import { DashboardAbilityProvider } from '../../components';
import { useDashboardBoot } from './DashboardBoot'; import { useDashboardMetaBoot } from './DashboardBoot';
/** /**
* Dashboard provider. * Dashboard provider.
*/ */
export default function DashboardProvider({ children }) { export default function DashboardProvider({ children }) {
const { isLoading } = useDashboardBoot(); const { isLoading } = useDashboardMetaBoot();
// Avoid display any dashboard component before complete booting. // Avoid display any dashboard component before complete booting.
if (isLoading) { if (isLoading) {

View File

@@ -2,7 +2,8 @@ import React, { useMemo, useCallback } from 'react';
import moment from 'moment'; import moment from 'moment';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { If, FormattedMessage as T } from 'components'; import If from '../Utils/If';
import { FormattedMessage as T } from '../FormattedMessage';
import { import {
FinancialSheetRoot, FinancialSheetRoot,
FinancialSheetFooterCurrentTime, FinancialSheetFooterCurrentTime,

View File

@@ -2,7 +2,8 @@ import React from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import { Align } from 'common'; import { Align } from 'common';
import { SkeletonText, DataTable } from 'components'; import { SkeletonText } from 'components';
import DataTable from '../../components/DataTable'
import TableSkeletonRows from 'components/Datatable/TableSkeletonRows'; import TableSkeletonRows from 'components/Datatable/TableSkeletonRows';
import TableSkeletonHeader from 'components/Datatable/TableHeaderSkeleton'; import TableSkeletonHeader from 'components/Datatable/TableHeaderSkeleton';

View File

@@ -0,0 +1,9 @@
import styled from 'styled-components';
import DataTable from '../DataTable';
export const ReportDataTable = styled(DataTable)`
.table .tbody .tr.no-results:last-of-type .td {
border-bottom: 1px solid #ddd;
}
`;

View File

@@ -1,2 +1,3 @@
export * from './FinancialSheet'; export * from './FinancialSheet';
export * from './FinancialSheetSkeleton'; export * from './FinancialSheetSkeleton';
export * from './ReportDataTable';

View File

@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import * as R from 'ramda'; import * as R from 'ramda';
import { ButtonLink } from 'components'; import { ButtonLink } from '../Button';
import withDrawerActions from 'containers/Drawer/withDrawerActions'; import withDrawerActions from 'containers/Drawer/withDrawerActions';
function VendorDrawerLinkComponent({ function VendorDrawerLinkComponent({

View File

@@ -70,6 +70,20 @@ export const financialReportMenus = [
subject: AbilitySubject.Report, subject: AbilitySubject.Report,
ability: ReportsAction.READ_AP_AGING_SUMMARY, ability: ReportsAction.READ_AP_AGING_SUMMARY,
}, },
{
title: <T id={'report.balance_sheet_comparison.title'} />,
desc: <T id={'report.balance_sheet_comparison.desc'} />,
link: 'financial-reports/balance-sheet?previousYear=true&previousYearAmountChange=true&previousYearPercentageChange=true',
subject: AbilitySubject.Report,
ability: ReportsAction.READ_BALANCE_SHEET,
},
{
title: <T id={'report.profit_loss_sheet_comparison.title'} />,
desc: <T id={'report.profit_loss_sheet_comparison.desc'} />,
link: '/financial-reports/profit-loss-sheet?previousYear=true&previousYearAmountChange=true&previousYearPercentageChange=true',
subject: AbilitySubject.Report,
ability: ReportsAction.READ_PROFIT_LOSS,
},
], ],
}, },
]; ];

View File

@@ -64,6 +64,7 @@ function BillPaymentTransactions({
}} }}
styleName={TableStyle.Constrant} styleName={TableStyle.Constrant}
TableLoadingRenderer={TableSkeletonRows} TableLoadingRenderer={TableSkeletonRows}
sticky={true}
/> />
); );
} }

View File

@@ -66,6 +66,7 @@ function EstimatePaymentTransactions({
}} }}
styleName={TableStyle.Constrant} styleName={TableStyle.Constrant}
TableLoadingRenderer={TableSkeletonRows} TableLoadingRenderer={TableSkeletonRows}
sticky={true}
/> />
); );
} }

View File

@@ -68,6 +68,7 @@ function InvoicePaymentTransactions({
}} }}
styleName={TableStyle.Constrant} styleName={TableStyle.Constrant}
TableLoadingRenderer={TableSkeletonRows} TableLoadingRenderer={TableSkeletonRows}
sticky={true}
/> />
); );
} }

View File

@@ -66,6 +66,7 @@ function ReceiptPaymentTransactions({
}} }}
styleName={TableStyle.Constrant} styleName={TableStyle.Constrant}
TableLoadingRenderer={TableSkeletonRows} TableLoadingRenderer={TableSkeletonRows}
sticky={true}
/> />
); );
} }

View File

@@ -4,6 +4,7 @@ import { Formik, Form } from 'formik';
import * as Yup from 'yup'; import * as Yup from 'yup';
import moment from 'moment'; import moment from 'moment';
import { Tabs, Tab, Button, Intent } from '@blueprintjs/core'; import { Tabs, Tab, Button, Intent } from '@blueprintjs/core';
import styled from 'styled-components';
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader'; import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
import APAgingSummaryHeaderGeneral from './APAgingSummaryHeaderGeneral'; import APAgingSummaryHeaderGeneral from './APAgingSummaryHeaderGeneral';
@@ -12,8 +13,8 @@ import APAgingSummaryHeaderDimensions from './APAgingSummaryHeaderDimensions';
import withAPAgingSummary from './withAPAgingSummary'; import withAPAgingSummary from './withAPAgingSummary';
import withAPAgingSummaryActions from './withAPAgingSummaryActions'; import withAPAgingSummaryActions from './withAPAgingSummaryActions';
import { compose } from 'utils';
import { transformToForm } from '../../../utils'; import { transformToForm } from '../../../utils';
import { compose } from 'utils';
/** /**
* AP Aging Summary Report - Drawer Header. * AP Aging Summary Report - Drawer Header.
@@ -74,7 +75,7 @@ function APAgingSummaryHeader({
}; };
return ( return (
<FinancialStatementHeader <APAgingDrawerHeader
isOpen={isFilterDrawerOpen} isOpen={isFilterDrawerOpen}
drawerProps={{ onClose: handleDrawerClose }} drawerProps={{ onClose: handleDrawerClose }}
> >
@@ -106,7 +107,7 @@ function APAgingSummaryHeader({
</div> </div>
</Form> </Form>
</Formik> </Formik>
</FinancialStatementHeader> </APAgingDrawerHeader>
); );
} }
@@ -116,3 +117,9 @@ export default compose(
isFilterDrawerOpen: APAgingSummaryFilterDrawer, isFilterDrawerOpen: APAgingSummaryFilterDrawer,
})), })),
)(APAgingSummaryHeader); )(APAgingSummaryHeader);
const APAgingDrawerHeader = styled(FinancialStatementHeader)`
.bp3-drawer {
max-height: 520px;
}
`;

View File

@@ -2,7 +2,7 @@ import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import styled from 'styled-components'; import styled from 'styled-components';
import { DataTable, FinancialSheet } from 'components'; import { ReportDataTable, FinancialSheet } from 'components';
import { TableStyle } from 'common'; import { TableStyle } from 'common';
import { useAPAgingSummaryContext } from './APAgingSummaryProvider'; import { useAPAgingSummaryContext } from './APAgingSummaryProvider';
@@ -29,7 +29,6 @@ export default function APAgingSummaryTable({
return ( return (
<FinancialSheet <FinancialSheet
companyName={organizationName} companyName={organizationName}
name={'payable-aging-summary'}
sheetType={intl.get('payable_aging_summary')} sheetType={intl.get('payable_aging_summary')}
asDate={new Date()} asDate={new Date()}
loading={isAPAgingLoading} loading={isAPAgingLoading}
@@ -46,7 +45,7 @@ export default function APAgingSummaryTable({
); );
} }
const APAgingSummaryDataTable = styled(DataTable)` const APAgingSummaryDataTable = styled(ReportDataTable)`
.table { .table {
.tbody .tr { .tbody .tr {
.td { .td {

View File

@@ -4,6 +4,7 @@ import { Formik, Form } from 'formik';
import * as Yup from 'yup'; import * as Yup from 'yup';
import moment from 'moment'; import moment from 'moment';
import { Tabs, Tab, Button, Intent } from '@blueprintjs/core'; import { Tabs, Tab, Button, Intent } from '@blueprintjs/core';
import styled from 'styled-components';
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader'; import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
import ARAgingSummaryHeaderGeneral from './ARAgingSummaryHeaderGeneral'; import ARAgingSummaryHeaderGeneral from './ARAgingSummaryHeaderGeneral';
@@ -60,14 +61,12 @@ function ARAgingSummaryHeader({
}, },
defaultValues, defaultValues,
); );
// Handle form submit. // Handle form submit.
const handleSubmit = (values, { setSubmitting }) => { const handleSubmit = (values, { setSubmitting }) => {
onSubmitFilter(values); onSubmitFilter(values);
toggleFilterDrawerDisplay(false); toggleFilterDrawerDisplay(false);
setSubmitting(false); setSubmitting(false);
}; };
// Handle cancel button click. // Handle cancel button click.
const handleCancelClick = () => { const handleCancelClick = () => {
toggleFilterDrawerDisplay(false); toggleFilterDrawerDisplay(false);
@@ -78,7 +77,7 @@ function ARAgingSummaryHeader({
}; };
return ( return (
<FinancialStatementHeader <ARAgingDrawerHeader
isOpen={isFilterDrawerOpen} isOpen={isFilterDrawerOpen}
drawerProps={{ onClose: handleDrawerClose }} drawerProps={{ onClose: handleDrawerClose }}
> >
@@ -111,7 +110,7 @@ function ARAgingSummaryHeader({
</div> </div>
</Form> </Form>
</Formik> </Formik>
</FinancialStatementHeader> </ARAgingDrawerHeader>
); );
} }
@@ -121,3 +120,9 @@ export default compose(
isFilterDrawerOpen: ARAgingSummaryFilterDrawer, isFilterDrawerOpen: ARAgingSummaryFilterDrawer,
})), })),
)(ARAgingSummaryHeader); )(ARAgingSummaryHeader);
const ARAgingDrawerHeader = styled(FinancialStatementHeader)`
.bp3-drawer {
max-height: 520px;
}
`;

View File

@@ -2,7 +2,7 @@ import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import styled from 'styled-components'; import styled from 'styled-components';
import { DataTable, FinancialSheet } from 'components'; import { ReportDataTable, FinancialSheet } from 'components';
import { TableStyle } from 'common'; import { TableStyle } from 'common';
import { useARAgingSummaryContext } from './ARAgingSummaryProvider'; import { useARAgingSummaryContext } from './ARAgingSummaryProvider';
@@ -26,7 +26,6 @@ export default function ReceivableAgingSummaryTable({
return ( return (
<FinancialSheet <FinancialSheet
companyName={organizationName} companyName={organizationName}
name={'receivable-aging-summary'}
sheetType={intl.get('receivable_aging_summary')} sheetType={intl.get('receivable_aging_summary')}
asDate={new Date()} asDate={new Date()}
loading={isARAgingLoading} loading={isARAgingLoading}
@@ -43,7 +42,7 @@ export default function ReceivableAgingSummaryTable({
); );
} }
const ARAgingSummaryDataTable = styled(DataTable)` const ARAgingSummaryDataTable = styled(ReportDataTable)`
.table { .table {
.tbody .tr { .tbody .tr {
.td { .td {

View File

@@ -1,8 +1,10 @@
import React from 'react'; import React from 'react';
import { Tabs, Tab, Button, Intent } from '@blueprintjs/core'; import { Tabs, Tab, Button, Intent } from '@blueprintjs/core';
import { FormattedMessage as T } from 'components';
import moment from 'moment'; import moment from 'moment';
import { Formik, Form } from 'formik'; import { Formik, Form } from 'formik';
import styled from 'styled-components';
import { FormattedMessage as T } from 'components';
import withBalanceSheet from './withBalanceSheet'; import withBalanceSheet from './withBalanceSheet';
import withBalanceSheetActions from './withBalanceSheetActions'; import withBalanceSheetActions from './withBalanceSheetActions';
@@ -65,9 +67,11 @@ function BalanceSheetHeader({
}; };
return ( return (
<FinancialStatementHeader <BalanceSheetFinancialHeader
isOpen={balanceSheetDrawerFilter} isOpen={balanceSheetDrawerFilter}
drawerProps={{ onClose: handleDrawerClose }} drawerProps={{
onClose: handleDrawerClose,
}}
> >
<Formik <Formik
initialValues={initialValues} initialValues={initialValues}
@@ -103,7 +107,7 @@ function BalanceSheetHeader({
</div> </div>
</Form> </Form>
</Formik> </Formik>
</FinancialStatementHeader> </BalanceSheetFinancialHeader>
); );
} }
@@ -113,3 +117,9 @@ export default compose(
})), })),
withBalanceSheetActions, withBalanceSheetActions,
)(BalanceSheetHeader); )(BalanceSheetHeader);
const BalanceSheetFinancialHeader = styled(FinancialStatementHeader)`
.bp3-drawer {
max-height: 520px;
}
`;

View File

@@ -2,7 +2,7 @@ import React from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { DataTable, FinancialSheet } from 'components'; import { ReportDataTable, FinancialSheet } from 'components';
import { useBalanceSheetContext } from './BalanceSheetProvider'; import { useBalanceSheetContext } from './BalanceSheetProvider';
@@ -56,7 +56,7 @@ export default function BalanceSheetTable({
); );
} }
const BalanceSheetDataTable = styled(DataTable)` const BalanceSheetDataTable = styled(ReportDataTable)`
.table { .table {
.tbody .tr { .tbody .tr {
.td { .td {
@@ -81,7 +81,7 @@ const BalanceSheetDataTable = styled(DataTable)`
} }
&.row_type--TOTAL.row-id--ASSETS, &.row_type--TOTAL.row-id--ASSETS,
&.row_type--TOTAL.row-id--LIABILITY_EQUITY { &.row_type--TOTAL.row-id--LIABILITY_EQUITY {
.td{ .td {
border-bottom: 3px double #000; border-bottom: 3px double #000;
} }
} }

View File

@@ -17,6 +17,7 @@ const accountNameMapper = (column) => ({
textOverview: true, textOverview: true,
width: 400, width: 400,
disableSortBy: true, disableSortBy: true,
sticky: Align.Left,
}); });
/** /**

View File

@@ -3,6 +3,8 @@ import * as Yup from 'yup';
import { Formik, Form } from 'formik'; import { Formik, Form } from 'formik';
import moment from 'moment'; import moment from 'moment';
import { Tabs, Tab, Button, Intent } from '@blueprintjs/core'; import { Tabs, Tab, Button, Intent } from '@blueprintjs/core';
import styled from 'styled-components';
import { FormattedMessage as T } from 'components'; import { FormattedMessage as T } from 'components';
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader'; import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
@@ -30,7 +32,6 @@ function CustomersBalanceSummaryHeader({
const validationSchema = Yup.object().shape({ const validationSchema = Yup.object().shape({
asDate: Yup.date().required().label('asDate'), asDate: Yup.date().required().label('asDate'),
}); });
// Default form values. // Default form values.
const defaultValues = { const defaultValues = {
...pageFilter, ...pageFilter,
@@ -47,21 +48,19 @@ function CustomersBalanceSummaryHeader({
}, },
defaultValues, defaultValues,
); );
// handle form submit. // handle form submit.
const handleSubmit = (values, { setSubmitting }) => { const handleSubmit = (values, { setSubmitting }) => {
onSubmitFilter(values); onSubmitFilter(values);
toggleCustomerBalanceFilterDrawer(false); toggleCustomerBalanceFilterDrawer(false);
setSubmitting(false); setSubmitting(false);
}; };
// handle close drawer. // handle close drawer.
const handleDrawerClose = () => { const handleDrawerClose = () => {
toggleCustomerBalanceFilterDrawer(false); toggleCustomerBalanceFilterDrawer(false);
}; };
return ( return (
<FinancialStatementHeader <CustomerBalanceDrawerHeader
isOpen={customersBalanceDrawerFilter} isOpen={customersBalanceDrawerFilter}
drawerProps={{ onClose: handleDrawerClose }} drawerProps={{ onClose: handleDrawerClose }}
> >
@@ -89,7 +88,7 @@ function CustomersBalanceSummaryHeader({
</div> </div>
</Form> </Form>
</Formik> </Formik>
</FinancialStatementHeader> </CustomerBalanceDrawerHeader>
); );
} }
@@ -99,3 +98,9 @@ export default compose(
})), })),
withCustomersBalanceSummaryActions, withCustomersBalanceSummaryActions,
)(CustomersBalanceSummaryHeader); )(CustomersBalanceSummaryHeader);
const CustomerBalanceDrawerHeader = styled(FinancialStatementHeader)`
.bp3-drawer {
max-height: 450px;
}
`;

View File

@@ -1,15 +1,17 @@
import React from 'react'; import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import styled from 'styled-components';
import { DataTable, FinancialSheet } from 'components'; import { ReportDataTable, FinancialSheet } from 'components';
import { useCustomersBalanceSummaryContext } from './CustomersBalanceSummaryProvider'; import { useCustomersBalanceSummaryContext } from './CustomersBalanceSummaryProvider';
import { useCustomersSummaryColumns } from './components'; import { useCustomersSummaryColumns } from './components';
import { TableStyle } from 'common';
import { tableRowTypesToClassnames } from 'utils'; import { tableRowTypesToClassnames } from 'utils';
/** /**
* customers balance summary table. * Customers balance summary table.
*/ */
export default function CustomersBalanceSummaryTable({ export default function CustomersBalanceSummaryTable({
// #ownProps // #ownProps
@@ -19,6 +21,7 @@ export default function CustomersBalanceSummaryTable({
CustomerBalanceSummary: { table }, CustomerBalanceSummary: { table },
} = useCustomersBalanceSummaryContext(); } = useCustomersBalanceSummaryContext();
// Retrieves the customers summary columns.
const columns = useCustomersSummaryColumns(); const columns = useCustomersSummaryColumns();
return ( return (
@@ -27,12 +30,36 @@ export default function CustomersBalanceSummaryTable({
sheetType={intl.get('customers_balance_summary')} sheetType={intl.get('customers_balance_summary')}
asDate={new Date()} asDate={new Date()}
> >
<DataTable <CustomerBalanceDataTable
columns={columns} columns={columns}
data={table.data} data={table.data}
rowClassNames={tableRowTypesToClassnames} rowClassNames={tableRowTypesToClassnames}
noInitialFetch={true} noInitialFetch={true}
styleName={TableStyle.Constrant}
/> />
</FinancialSheet> </FinancialSheet>
); );
} }
const CustomerBalanceDataTable = styled(ReportDataTable)`
.table {
.tbody {
.tr:not(.no-results) {
.td {
border-bottom: 0;
padding-top: 0.4rem;
padding-bottom: 0.4rem;
}
&.row_type--TOTAL {
font-weight: 500;
.td {
border-top: 1px solid #bbb;
border-bottom: 3px double #333;
}
}
}
}
}
`;

View File

@@ -6,6 +6,8 @@ import { If } from 'components';
import FinancialLoadingBar from '../FinancialLoadingBar'; import FinancialLoadingBar from '../FinancialLoadingBar';
import { useCustomersBalanceSummaryContext } from './CustomersBalanceSummaryProvider'; import { useCustomersBalanceSummaryContext } from './CustomersBalanceSummaryProvider';
import { Align } from 'common';
/** /**
* Retrieve customers balance summary columns. * Retrieve customers balance summary columns.
*/ */
@@ -37,6 +39,7 @@ const totalColumnAccessor = () => ({
accessor: 'cells[1].value', accessor: 'cells[1].value',
className: 'total', className: 'total',
width: 140, width: 140,
align: Align.Right,
}); });
/** /**
@@ -47,6 +50,7 @@ const percentageColumnAccessor = () => ({
accessor: 'cells[2].value', accessor: 'cells[2].value',
className: 'total', className: 'total',
width: 140, width: 140,
align: Align.Right,
}); });
const dynamicColumns = (columns) => { const dynamicColumns = (columns) => {
@@ -54,7 +58,10 @@ const dynamicColumns = (columns) => {
R.compose( R.compose(
R.when(R.pathEq(['key'], 'name'), accountNameColumnAccessor), R.when(R.pathEq(['key'], 'name'), accountNameColumnAccessor),
R.when(R.pathEq(['key'], 'total'), totalColumnAccessor), R.when(R.pathEq(['key'], 'total'), totalColumnAccessor),
R.when(R.pathEq(['key'], 'percentage_of_column'), percentageColumnAccessor), R.when(
R.pathEq(['key'], 'percentage_of_column'),
percentageColumnAccessor,
),
), ),
)(columns); )(columns);
}; };

View File

@@ -5,6 +5,7 @@ import intl from 'react-intl-universal';
import moment from 'moment'; import moment from 'moment';
import * as Yup from 'yup'; import * as Yup from 'yup';
import { Formik, Form } from 'formik'; import { Formik, Form } from 'formik';
import styled from 'styled-components';
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader'; import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
import CustomersTransactionsHeaderGeneralPanel from './CustomersTransactionsHeaderGeneralPanel'; import CustomersTransactionsHeaderGeneralPanel from './CustomersTransactionsHeaderGeneralPanel';
@@ -67,7 +68,7 @@ function CustomersTransactionsHeader({
}; };
return ( return (
<FinancialStatementHeader <CustomerTransactionsDrawerHeader
isOpen={isFilterDrawerOpen} isOpen={isFilterDrawerOpen}
drawerProps={{ onClose: handleDrawerClose }} drawerProps={{ onClose: handleDrawerClose }}
> >
@@ -95,7 +96,7 @@ function CustomersTransactionsHeader({
</div> </div>
</Form> </Form>
</Formik> </Formik>
</FinancialStatementHeader> </CustomerTransactionsDrawerHeader>
); );
} }
@@ -105,3 +106,9 @@ export default compose(
})), })),
withCustomersTransactionsActions, withCustomersTransactionsActions,
)(CustomersTransactionsHeader); )(CustomersTransactionsHeader);
const CustomerTransactionsDrawerHeader = styled(FinancialStatementHeader)`
.bp3-drawer {
max-height: 450px;
}
`;

View File

@@ -58,10 +58,10 @@ const CustomersTransactionsDataTable = styled(DataTable)`
.table { .table {
.tbody { .tbody {
.tr .td { .tr .td {
padding-top: 0.2rem; padding-top: 0.36rem;
padding-bottom: 0.2rem; padding-bottom: 0.36rem;
} }
.tr:not(.no-results) .td { .tr:not(.no-results) .td:not(:first-of-type) {
border-left: 1px solid #ececec; border-left: 1px solid #ececec;
} }
.tr:last-child .td { .tr:last-child .td {
@@ -73,6 +73,11 @@ const CustomersTransactionsDataTable = styled(DataTable)`
.td { .td {
&.customer_name { &.customer_name {
font-weight: 500; font-weight: 500;
.cell-inner {
white-space: nowrap;
position: relative;
}
} }
} }
&:not(:first-child).is-expanded .td { &:not(:first-child).is-expanded .td {

View File

@@ -3,14 +3,13 @@ import intl from 'react-intl-universal';
import { If } from 'components'; import { If } from 'components';
import { useCustomersTransactionsContext } from './CustomersTransactionsProvider'; import { useCustomersTransactionsContext } from './CustomersTransactionsProvider';
import FinancialLoadingBar from '../FinancialLoadingBar'; import FinancialLoadingBar from '../FinancialLoadingBar';
import { getForceWidth, getColumnWidth } from 'utils'; import { getColumnWidth } from 'utils';
import { Align } from 'common'; import { Align } from 'common';
/** /**
* Retrieve customers transactions columns. * Retrieve customers transactions columns.
*/ */
export const useCustomersTransactionsColumns = () => { export const useCustomersTransactionsColumns = () => {
const { const {
customersTransactions: { tableRows }, customersTransactions: { tableRows },
@@ -20,16 +19,7 @@ export const useCustomersTransactionsColumns = () => {
() => [ () => [
{ {
Header: intl.get('customer_name'), Header: intl.get('customer_name'),
accessor: ({ cells }) => { accessor: 'cells[0].value',
return (
<span
className={'force-width'}
style={{ minWidth: getForceWidth(cells[0].value) }}
>
{cells[0].value}
</span>
);
},
className: 'customer_name', className: 'customer_name',
}, },
{ {

View File

@@ -3,10 +3,15 @@ import classNames from 'classnames';
import { Position, Drawer } from '@blueprintjs/core'; import { Position, Drawer } from '@blueprintjs/core';
import 'style/containers/FinancialStatements/DrawerHeader.scss'; import 'style/containers/FinancialStatements/DrawerHeader.scss';
/**
* Financial statement header.
* @returns {JSX.Element}
*/
export default function FinancialStatementHeader({ export default function FinancialStatementHeader({
children, children,
isOpen, isOpen,
drawerProps, drawerProps,
className,
}) { }) {
const timeoutRef = React.useRef(); const timeoutRef = React.useRef();
const [isDrawerOpen, setIsDrawerOpen] = useState(false); const [isDrawerOpen, setIsDrawerOpen] = useState(false);
@@ -42,6 +47,7 @@ export default function FinancialStatementHeader({
{ {
'is-hidden': !isDrawerOpen, 'is-hidden': !isDrawerOpen,
}, },
className,
)} )}
> >
<Drawer <Drawer

View File

@@ -3,6 +3,8 @@ import moment from 'moment';
import * as Yup from 'yup'; import * as Yup from 'yup';
import { Formik, Form } from 'formik'; import { Formik, Form } from 'formik';
import { Tabs, Tab, Button, Intent } from '@blueprintjs/core'; import { Tabs, Tab, Button, Intent } from '@blueprintjs/core';
import styled from 'styled-components';
import { FormattedMessage as T } from 'components'; import { FormattedMessage as T } from 'components';
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader'; import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
@@ -71,7 +73,7 @@ function GeneralLedgerHeader({
}; };
return ( return (
<FinancialStatementHeader <GeneralLedgerDrawerHeader
isOpen={isFilterDrawerOpen} isOpen={isFilterDrawerOpen}
drawerProps={{ onClose: handleDrawerClose }} drawerProps={{ onClose: handleDrawerClose }}
> >
@@ -105,7 +107,7 @@ function GeneralLedgerHeader({
</div> </div>
</Form> </Form>
</Formik> </Formik>
</FinancialStatementHeader> </GeneralLedgerDrawerHeader>
); );
} }
@@ -115,3 +117,9 @@ export default compose(
})), })),
withGeneralLedgerActions, withGeneralLedgerActions,
)(GeneralLedgerHeader); )(GeneralLedgerHeader);
const GeneralLedgerDrawerHeader = styled(FinancialStatementHeader)`
.bp3-drawer {
max-height: 520px;
}
`;

View File

@@ -4,7 +4,7 @@ import styled from 'styled-components';
import { defaultExpanderReducer, tableRowTypesToClassnames } from 'utils'; import { defaultExpanderReducer, tableRowTypesToClassnames } from 'utils';
import { FinancialSheet, DataTable } from 'components'; import { FinancialSheet, ReportDataTable } from 'components';
import TableVirtualizedListRows from 'components/Datatable/TableVirtualizedRows'; import TableVirtualizedListRows from 'components/Datatable/TableVirtualizedRows';
import TableFastCell from 'components/Datatable/TableFastCell'; import TableFastCell from 'components/Datatable/TableFastCell';
@@ -66,7 +66,7 @@ export default function GeneralLedgerTable({ companyName }) {
); );
} }
const GeneralLedgerDataTable = styled(DataTable)` const GeneralLedgerDataTable = styled(ReportDataTable)`
.tbody { .tbody {
.tr .td { .tr .td {
padding-top: 0.2rem; padding-top: 0.2rem;
@@ -78,7 +78,7 @@ const GeneralLedgerDataTable = styled(DataTable)`
} }
} }
.tr:not(.no-results) .td { .tr:not(.no-results) .td:not(:first-of-type) {
border-left: 1px solid #ececec; border-left: 1px solid #ececec;
} }
.tr:last-child .td { .tr:last-child .td {
@@ -90,13 +90,13 @@ const GeneralLedgerDataTable = styled(DataTable)`
.td { .td {
&.date { &.date {
font-weight: 500; font-weight: 500;
}
&.name { .cell-inner {
border-left-color: transparent; white-space: nowrap;
position: relative;
}
} }
} }
&:not(:first-child).is-expanded .td { &:not(:first-child).is-expanded .td {
border-top: 1px solid #ddd; border-top: 1px solid #ddd;
} }
@@ -108,7 +108,6 @@ const GeneralLedgerDataTable = styled(DataTable)`
font-weight: 500; font-weight: 500;
} }
} }
&--CLOSING_BALANCE { &--CLOSING_BALANCE {
.name { .name {
font-weight: 500; font-weight: 500;

View File

@@ -2,7 +2,7 @@ import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { Button } from '@blueprintjs/core'; import { Button } from '@blueprintjs/core';
import { Icon, If } from 'components'; import { Icon, If } from 'components';
import { ForceWidth, FormattedMessage as T } from 'components'; import { FormattedMessage as T } from 'components';
import { getColumnWidth } from 'utils'; import { getColumnWidth } from 'utils';
import { useGeneralLedgerContext } from './GeneralLedgerProvider'; import { useGeneralLedgerContext } from './GeneralLedgerProvider';
@@ -23,12 +23,7 @@ export function useGeneralLedgerTableColumns() {
() => [ () => [
{ {
Header: intl.get('date'), Header: intl.get('date'),
accessor: (row) => { accessor: 'date',
if (row.rowType === 'ACCOUNT_ROW') {
return <ForceWidth children={row.date} />;
}
return row.date;
},
className: 'date', className: 'date',
width: 120, width: 120,
}, },

View File

@@ -3,8 +3,10 @@ import * as Yup from 'yup';
import moment from 'moment'; import moment from 'moment';
import { Formik, Form } from 'formik'; import { Formik, Form } from 'formik';
import { Tabs, Tab, Button, Intent } from '@blueprintjs/core'; import { Tabs, Tab, Button, Intent } from '@blueprintjs/core';
import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import styled from 'styled-components';
import { FormattedMessage as T } from 'components';
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader'; import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
import InventoryItemDetailsHeaderGeneralPanel from './InventoryItemDetailsHeaderGeneralPanel'; import InventoryItemDetailsHeaderGeneralPanel from './InventoryItemDetailsHeaderGeneralPanel';
@@ -68,7 +70,7 @@ function InventoryItemDetailsHeader({
}; };
return ( return (
<FinancialStatementHeader <InventoryItemDetailsDrawerHeader
isOpen={isFilterDrawerOpen} isOpen={isFilterDrawerOpen}
drawerProps={{ onClose: handleDrawerClose }} drawerProps={{ onClose: handleDrawerClose }}
> >
@@ -100,7 +102,7 @@ function InventoryItemDetailsHeader({
</div> </div>
</Form> </Form>
</Formik> </Formik>
</FinancialStatementHeader> </InventoryItemDetailsDrawerHeader>
); );
} }
@@ -110,3 +112,9 @@ export default compose(
})), })),
withInventoryItemDetailsActions, withInventoryItemDetailsActions,
)(InventoryItemDetailsHeader); )(InventoryItemDetailsHeader);
const InventoryItemDetailsDrawerHeader = styled(FinancialStatementHeader)`
.bp3-drawer {
max-height: 400px;
}
`;

View File

@@ -2,12 +2,11 @@ import React, { useMemo } from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import styled from 'styled-components'; import styled from 'styled-components';
import { DataTable, FinancialSheet } from 'components'; import { ReportDataTable, FinancialSheet } from 'components';
import { useInventoryItemDetailsColumns } from './components'; import { useInventoryItemDetailsColumns } from './components';
import { useInventoryItemDetailsContext } from './InventoryItemDetailsProvider'; import { useInventoryItemDetailsContext } from './InventoryItemDetailsProvider';
import { defaultExpanderReducer, tableRowTypesToClassnames } from 'utils'; import { defaultExpanderReducer, tableRowTypesToClassnames } from 'utils';
import { TableStyle } from 'common'; import { TableStyle } from 'common';
/** /**
@@ -37,6 +36,7 @@ export function InventoryItemDetailsTable({
loading={isInventoryItemDetailsLoading} loading={isInventoryItemDetailsLoading}
fromDate={query.from_date} fromDate={query.from_date}
toDate={query.to_date} toDate={query.to_date}
fullWidth={true}
> >
<InventoryItemDetailsDataTable <InventoryItemDetailsDataTable
columns={columns} columns={columns}
@@ -53,27 +53,15 @@ export function InventoryItemDetailsTable({
); );
} }
const InventoryItemDetailsDataTable = styled(DataTable)` const InventoryItemDetailsDataTable = styled(ReportDataTable)`
.table { .table {
.tbody { .tbody {
.tr .td { .tr .td {
padding-top: 0.2rem; padding-top: 0.3rem;
padding-bottom: 0.2rem; padding-bottom: 0.3rem;
border-top-color: transparent;
border-bottom-color: transparent;
&.date {
> div {
display: flex;
}
span.force-width {
position: relative;
}
}
} }
.tr:not(.no-results) .td { .tr:not(.no-results) .td:not(:first-of-type) {
border-left: 1px solid #ececec; border-left: 1px solid #ececec;
} }
@@ -87,8 +75,14 @@ const InventoryItemDetailsDataTable = styled(DataTable)`
&.transaction_type { &.transaction_type {
border-left-color: transparent; border-left-color: transparent;
} }
}
&.date {
.cell-inner {
white-space: nowrap;
position: relative;
}
}
}
&:not(:first-child).is-expanded .td { &:not(:first-child).is-expanded .td {
border-top: 1px solid #ddd; border-top: 1px solid #ddd;
} }

View File

@@ -1,17 +1,43 @@
import * as R from 'ramda'; import * as R from 'ramda';
import { getColumnWidth } from 'utils'; import { getColumnWidth } from 'utils';
import { CellForceWidth } from '../../../components'; import { Align } from 'common';
const itemNameOrDateColumn = R.curry((data, index, column) => ({
id: column.key,
key: column.key,
Header: column.label,
accessor: `cells[${index}].value`,
className: column.key,
width: getColumnWidth(data, `cells.${index}.key`, {
minWidth: 130,
magicSpacing: 10,
}),
disableSortBy: true,
}));
const numericColumn = R.curry((data, index, column) => ({
id: column.key,
key: column.key,
Header: column.label,
accessor: `cells[${index}].value`,
className: column.key,
width: getColumnWidth(data, `cells.${index}.key`, {
minWidth: 130,
magicSpacing: 10,
}),
disableSortBy: true,
align: Align.Right,
}));
/** /**
* columns mapper. * columns mapper.
*/ */
const columnsMapper = (data, index, column) => ({ const columnsMapper = R.curry((data, index, column) => ({
id: column.key, id: column.key,
key: column.key, key: column.key,
Header: column.label, Header: column.label,
Cell: CellForceWidth,
accessor: `cells[${index}].value`, accessor: `cells[${index}].value`,
forceWidthAccess: `cells[0].value`,
className: column.key, className: column.key,
width: getColumnWidth(data, `cells.${index}.key`, { width: getColumnWidth(data, `cells.${index}.key`, {
minWidth: 130, minWidth: 130,
@@ -19,7 +45,7 @@ const columnsMapper = (data, index, column) => ({
}), }),
disableSortBy: true, disableSortBy: true,
textOverview: true, textOverview: true,
}); }));
/** /**
* Inventory item details columns. * Inventory item details columns.
@@ -27,7 +53,17 @@ const columnsMapper = (data, index, column) => ({
export const dynamicColumns = (columns, data) => { export const dynamicColumns = (columns, data) => {
const mapper = (column, index) => { const mapper = (column, index) => {
return R.compose( return R.compose(
R.when(R.pathEq(['key']), R.curry(columnsMapper)(data, index)), R.cond([
[R.pathEq(['key'], 'date'), itemNameOrDateColumn(data, index)],
[R.pathEq(['key'], 'running_quantity'), numericColumn(data, index)],
[R.pathEq(['key'], 'profit_margin'), numericColumn(data, index)],
[R.pathEq(['key'], 'running_value'), numericColumn(data, index)],
[R.pathEq(['key'], 'quantity'), numericColumn(data, index)],
[R.pathEq(['key'], 'rate'), numericColumn(data, index)],
[R.pathEq(['key'], 'total'), numericColumn(data, index)],
[R.pathEq(['key'], 'value'), numericColumn(data, index)],
[R.T, columnsMapper(data, index)],
]),
)(column); )(column);
}; };
return columns.map(mapper); return columns.map(mapper);

View File

@@ -1,9 +1,11 @@
import React from 'react'; import React from 'react';
import * as Yup from 'yup'; import * as Yup from 'yup';
import moment from 'moment'; import moment from 'moment';
import { FormattedMessage as T } from 'components';
import { Formik, Form } from 'formik'; import { Formik, Form } from 'formik';
import { Tabs, Tab, Button, Intent } from '@blueprintjs/core'; import { Tabs, Tab, Button, Intent } from '@blueprintjs/core';
import styled from 'styled-components';
import { FormattedMessage as T } from 'components';
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader'; import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
import InventoryValuationHeaderGeneralPanel from './InventoryValuationHeaderGeneralPanel'; import InventoryValuationHeaderGeneralPanel from './InventoryValuationHeaderGeneralPanel';
@@ -68,7 +70,7 @@ function InventoryValuationHeader({
}; };
return ( return (
<FinancialStatementHeader <InventoryValuationDrawerHeader
isOpen={isFilterDrawerOpen} isOpen={isFilterDrawerOpen}
drawerProps={{ onClose: handleDrawerClose }} drawerProps={{ onClose: handleDrawerClose }}
> >
@@ -100,7 +102,7 @@ function InventoryValuationHeader({
</div> </div>
</Form> </Form>
</Formik> </Formik>
</FinancialStatementHeader> </InventoryValuationDrawerHeader>
); );
} }
@@ -110,3 +112,9 @@ export default compose(
})), })),
withInventoryValuationActions, withInventoryValuationActions,
)(InventoryValuationHeader); )(InventoryValuationHeader);
const InventoryValuationDrawerHeader = styled(FinancialStatementHeader)`
.bp3-drawer {
max-height: 450px;
}
`;

View File

@@ -2,7 +2,7 @@ import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import styled from 'styled-components'; import styled from 'styled-components';
import { DataTable, FinancialSheet } from 'components'; import { ReportDataTable, FinancialSheet } from 'components';
import { useInventoryValuationContext } from './InventoryValuationProvider'; import { useInventoryValuationContext } from './InventoryValuationProvider';
import { useInventoryValuationTableColumns } from './components'; import { useInventoryValuationTableColumns } from './components';
@@ -54,7 +54,7 @@ const InventoryValuationSheet = styled(FinancialSheet)`
min-width: 850px; min-width: 850px;
`; `;
const InventoryValuationDataTable = styled(DataTable)` const InventoryValuationDataTable = styled(ReportDataTable)`
.table { .table {
.tbody { .tbody {
.tr .td { .tr .td {

View File

@@ -3,6 +3,8 @@ import moment from 'moment';
import { Formik, Form } from 'formik'; import { Formik, Form } from 'formik';
import { Tab, Tabs, Button, Intent } from '@blueprintjs/core'; import { Tab, Tabs, Button, Intent } from '@blueprintjs/core';
import * as Yup from 'yup'; import * as Yup from 'yup';
import styled from 'styled-components';
import { FormattedMessage as T } from 'components'; import { FormattedMessage as T } from 'components';
import JournalSheetHeaderGeneral from './JournalSheetHeaderGeneral'; import JournalSheetHeaderGeneral from './JournalSheetHeaderGeneral';
@@ -56,7 +58,7 @@ function JournalHeader({
}; };
return ( return (
<FinancialStatementHeader <JournalDrawerHeader
isOpen={journalSheetDrawerFilter} isOpen={journalSheetDrawerFilter}
drawerProps={{ onClose: handleDrawerClose }} drawerProps={{ onClose: handleDrawerClose }}
> >
@@ -89,7 +91,7 @@ function JournalHeader({
</div> </div>
</Form> </Form>
</Formik> </Formik>
</FinancialStatementHeader> </JournalDrawerHeader>
); );
} }
@@ -99,3 +101,9 @@ export default compose(
})), })),
withJournalActions, withJournalActions,
)(JournalHeader); )(JournalHeader);
const JournalDrawerHeader = styled(FinancialStatementHeader)`
.bp3-drawer {
max-height: 350px;
}
`;

View File

@@ -2,7 +2,7 @@ import React, { useMemo } from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import styled from 'styled-components'; import styled from 'styled-components';
import { DataTable, FinancialSheet } from 'components'; import { ReportDataTable, FinancialSheet } from 'components';
import TableVirtualizedListRows from 'components/Datatable/TableVirtualizedRows'; import TableVirtualizedListRows from 'components/Datatable/TableVirtualizedRows';
import TableFastCell from 'components/Datatable/TableFastCell'; import TableFastCell from 'components/Datatable/TableFastCell';
@@ -60,7 +60,7 @@ export function JournalTable({ companyName }) {
); );
} }
const JournalDataTable = styled(DataTable)` const JournalDataTable = styled(ReportDataTable)`
.table { .table {
.tbody { .tbody {
.tr:not(.no-results) .td { .tr:not(.no-results) .td {

View File

@@ -3,6 +3,7 @@ import moment from 'moment';
import { Formik, Form } from 'formik'; import { Formik, Form } from 'formik';
import * as R from 'ramda'; import * as R from 'ramda';
import { Tabs, Tab, Button, Intent } from '@blueprintjs/core'; import { Tabs, Tab, Button, Intent } from '@blueprintjs/core';
import styled from 'styled-components';
import { FormattedMessage as T } from 'components'; import { FormattedMessage as T } from 'components';
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader'; import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
@@ -54,7 +55,7 @@ function ProfitLossHeader({
}; };
return ( return (
<FinancialStatementHeader <ProfitLossSheetHeader
isOpen={profitLossDrawerFilter} isOpen={profitLossDrawerFilter}
drawerProps={{ onClose: handleDrawerClose }} drawerProps={{ onClose: handleDrawerClose }}
> >
@@ -92,7 +93,7 @@ function ProfitLossHeader({
</div> </div>
</Form> </Form>
</Formik> </Formik>
</FinancialStatementHeader> </ProfitLossSheetHeader>
); );
} }
@@ -102,3 +103,9 @@ export default R.compose(
})), })),
withProfitLossActions, withProfitLossActions,
)(ProfitLossHeader); )(ProfitLossHeader);
const ProfitLossSheetHeader = styled(FinancialStatementHeader)`
.bp3-drawer {
max-height: 520px;
}
`;

View File

@@ -2,7 +2,11 @@ import React from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import { TableStyle } from 'common'; import { TableStyle } from 'common';
import { DataTable, FinancialSheet, FormattedMessage as T } from 'components'; import {
ReportDataTable,
FinancialSheet,
FormattedMessage as T,
} from 'components';
import { tableRowTypesToClassnames, defaultExpanderReducer } from 'utils'; import { tableRowTypesToClassnames, defaultExpanderReducer } from 'utils';
import { useProfitLossSheetColumns } from './hooks'; import { useProfitLossSheetColumns } from './hooks';
@@ -49,7 +53,7 @@ export default function ProfitLossSheetTable({
); );
} }
const ProfitLossDataTable = styled(DataTable)` const ProfitLossDataTable = styled(ReportDataTable)`
.table { .table {
.tbody .tr { .tbody .tr {
.td { .td {

View File

@@ -1,10 +1,12 @@
import React from 'react'; import React from 'react';
import * as Yup from 'yup'; import * as Yup from 'yup';
import moment from 'moment'; import moment from 'moment';
import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { Formik, Form } from 'formik'; import { Formik, Form } from 'formik';
import { Tabs, Tab, Button, Intent } from '@blueprintjs/core'; import { Tabs, Tab, Button, Intent } from '@blueprintjs/core';
import styled from 'styled-components';
import { FormattedMessage as T } from 'components';
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader'; import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
import PurchasesByItemsGeneralPanel from './PurchasesByItemsGeneralPanel'; import PurchasesByItemsGeneralPanel from './PurchasesByItemsGeneralPanel';
@@ -36,7 +38,6 @@ function PurchasesByItemsHeader({
.required() .required()
.label(intl.get('to_date')), .label(intl.get('to_date')),
}); });
// Default form values. // Default form values.
const defaultValues = { const defaultValues = {
...pageFilter, ...pageFilter,
@@ -68,7 +69,7 @@ function PurchasesByItemsHeader({
}; };
return ( return (
<FinancialStatementHeader <PurchasesByItemsDrawerHeader
isOpen={purchasesByItemsDrawerFilter} isOpen={purchasesByItemsDrawerFilter}
drawerProps={{ onClose: handleDrawerClose }} drawerProps={{ onClose: handleDrawerClose }}
> >
@@ -95,7 +96,7 @@ function PurchasesByItemsHeader({
</div> </div>
</Form> </Form>
</Formik> </Formik>
</FinancialStatementHeader> </PurchasesByItemsDrawerHeader>
); );
} }
@@ -105,3 +106,9 @@ export default compose(
})), })),
withPurchasesByItemsActions, withPurchasesByItemsActions,
)(PurchasesByItemsHeader); )(PurchasesByItemsHeader);
const PurchasesByItemsDrawerHeader = styled(FinancialStatementHeader)`
.bp3-drawer {
max-height: 450px;
}
`;

View File

@@ -2,7 +2,7 @@ import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import styled from 'styled-components'; import styled from 'styled-components';
import { DataTable, FinancialSheet } from 'components'; import { ReportDataTable, FinancialSheet } from 'components';
import { usePurchaseByItemsContext } from './PurchasesByItemsProvider'; import { usePurchaseByItemsContext } from './PurchasesByItemsProvider';
import { usePurchasesByItemsTableColumns } from './components'; import { usePurchasesByItemsTableColumns } from './components';
@@ -50,7 +50,7 @@ const PurchasesByItemsSheet = styled(FinancialSheet)`
min-width: 850px; min-width: 850px;
`; `;
const PurchasesByItemsDataTable = styled(DataTable)` const PurchasesByItemsDataTable = styled(ReportDataTable)`
.table { .table {
.tbody { .tbody {
.tr .td { .tr .td {

View File

@@ -1,10 +1,12 @@
import React from 'react'; import React from 'react';
import * as Yup from 'yup'; import * as Yup from 'yup';
import moment from 'moment'; import moment from 'moment';
import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { Formik, Form } from 'formik'; import { Formik, Form } from 'formik';
import { Tabs, Tab, Button, Intent } from '@blueprintjs/core'; import { Tabs, Tab, Button, Intent } from '@blueprintjs/core';
import styled from 'styled-components';
import { FormattedMessage as T } from 'components';
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader'; import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
import SalesByItemsHeaderGeneralPanel from './SalesByItemsHeaderGeneralPanel'; import SalesByItemsHeaderGeneralPanel from './SalesByItemsHeaderGeneralPanel';
@@ -61,7 +63,7 @@ function SalesByItemsHeader({
}; };
return ( return (
<FinancialStatementHeader <SalesByItemsDrawerHeader
isOpen={salesByItemsDrawerFilter} isOpen={salesByItemsDrawerFilter}
drawerProps={{ onClose: handleDrawerClose }} drawerProps={{ onClose: handleDrawerClose }}
> >
@@ -88,7 +90,7 @@ function SalesByItemsHeader({
</div> </div>
</Form> </Form>
</Formik> </Formik>
</FinancialStatementHeader> </SalesByItemsDrawerHeader>
); );
} }
@@ -98,3 +100,9 @@ export default compose(
})), })),
withSalesByItemsActions, withSalesByItemsActions,
)(SalesByItemsHeader); )(SalesByItemsHeader);
const SalesByItemsDrawerHeader = styled(FinancialStatementHeader)`
.bp3-drawer {
max-height: 450px;
}
`;

View File

@@ -2,7 +2,7 @@ import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import styled from 'styled-components'; import styled from 'styled-components';
import { DataTable, FinancialSheet } from 'components'; import { ReportDataTable, FinancialSheet } from 'components';
import { useSalesByItemsContext } from './SalesByItemProvider'; import { useSalesByItemsContext } from './SalesByItemProvider';
import { useSalesByItemsTableColumns } from './components'; import { useSalesByItemsTableColumns } from './components';
@@ -52,7 +52,7 @@ const SalesByItemsSheet = styled(FinancialSheet)`
min-width: 850px; min-width: 850px;
`; `;
const SalesByItemsDataTable = styled(DataTable)` const SalesByItemsDataTable = styled(ReportDataTable)`
.table { .table {
.tbody { .tbody {
.tr .td { .tr .td {

View File

@@ -22,9 +22,6 @@ import { compose } from 'utils';
* Trial balance sheet. * Trial balance sheet.
*/ */
function TrialBalanceSheet({ function TrialBalanceSheet({
// #withPreferences
organizationName,
// #withTrialBalanceSheetActions // #withTrialBalanceSheetActions
toggleTrialBalanceFilterDrawer: toggleFilterDrawer, toggleTrialBalanceFilterDrawer: toggleFilterDrawer,
}) { }) {
@@ -44,7 +41,6 @@ function TrialBalanceSheet({
}, },
[setFilter], [setFilter],
); );
// Handle numebr format form submit. // Handle numebr format form submit.
const handleNumberFormatSubmit = (numberFormat) => { const handleNumberFormatSubmit = (numberFormat) => {
setFilter({ setFilter({

View File

@@ -1,10 +1,12 @@
import React from 'react'; import React from 'react';
import * as Yup from 'yup'; import * as Yup from 'yup';
import moment from 'moment'; import moment from 'moment';
import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import { Formik, Form } from 'formik'; import { Formik, Form } from 'formik';
import intl from 'react-intl-universal';
import { Tabs, Tab, Button, Intent } from '@blueprintjs/core'; import { Tabs, Tab, Button, Intent } from '@blueprintjs/core';
import styled from 'styled-components';
import { FormattedMessage as T } from 'components';
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader'; import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
import TrialBalanceSheetHeaderGeneralPanel from './TrialBalanceSheetHeaderGeneralPanel'; import TrialBalanceSheetHeaderGeneralPanel from './TrialBalanceSheetHeaderGeneralPanel';
@@ -72,7 +74,7 @@ function TrialBalanceSheetHeader({
}; };
return ( return (
<FinancialStatementHeader <TrialBalanceSheetDrawerHeader
isOpen={trialBalanceDrawerFilter} isOpen={trialBalanceDrawerFilter}
drawerProps={{ onClose: handleDrawerClose }} drawerProps={{ onClose: handleDrawerClose }}
> >
@@ -105,7 +107,7 @@ function TrialBalanceSheetHeader({
</div> </div>
</Form> </Form>
</Formik> </Formik>
</FinancialStatementHeader> </TrialBalanceSheetDrawerHeader>
); );
} }
@@ -115,3 +117,9 @@ export default compose(
})), })),
withTrialBalanceActions, withTrialBalanceActions,
)(TrialBalanceSheetHeader); )(TrialBalanceSheetHeader);
const TrialBalanceSheetDrawerHeader = styled(FinancialStatementHeader)`
.bp3-drawer {
max-height: 450px;
}
`;

View File

@@ -2,7 +2,7 @@ import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import styled from 'styled-components'; import styled from 'styled-components';
import { DataTable, FinancialSheet } from 'components'; import { ReportDataTable, FinancialSheet } from 'components';
import { useTrialBalanceSheetContext } from './TrialBalanceProvider'; import { useTrialBalanceSheetContext } from './TrialBalanceProvider';
import { useTrialBalanceTableColumns } from './components'; import { useTrialBalanceTableColumns } from './components';
@@ -47,7 +47,7 @@ export default function TrialBalanceSheetTable({ companyName }) {
); );
} }
const TrialBalanceDataTable = styled(DataTable)` const TrialBalanceDataTable = styled(ReportDataTable)`
.table { .table {
.tbody { .tbody {
.tr .td { .tr .td {

View File

@@ -13,6 +13,7 @@ import { VendorBalanceSummaryBody } from './VendorsBalanceSummaryBody';
import withVendorsBalanceSummaryActions from './withVendorsBalanceSummaryActions'; import withVendorsBalanceSummaryActions from './withVendorsBalanceSummaryActions';
import { TableStyle } from 'common';
import { getDefaultVendorsBalanceQuery } from './utils'; import { getDefaultVendorsBalanceQuery } from './utils';
import { compose } from 'utils'; import { compose } from 'utils';

View File

@@ -3,6 +3,8 @@ import * as Yup from 'yup';
import { Formik, Form } from 'formik'; import { Formik, Form } from 'formik';
import moment from 'moment'; import moment from 'moment';
import { Tabs, Tab, Button, Intent } from '@blueprintjs/core'; import { Tabs, Tab, Button, Intent } from '@blueprintjs/core';
import styled from 'styled-components';
import { FormattedMessage as T } from 'components'; import { FormattedMessage as T } from 'components';
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader'; import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
@@ -61,7 +63,7 @@ function VendorsBalanceSummaryHeader({
}; };
return ( return (
<FinancialStatementHeader <VendorBalanceDrawerHeader
isOpen={VendorsSummaryFilterDrawer} isOpen={VendorsSummaryFilterDrawer}
drawerProps={{ onClose: handleCancelClick }} drawerProps={{ onClose: handleCancelClick }}
> >
@@ -88,7 +90,7 @@ function VendorsBalanceSummaryHeader({
</div> </div>
</Form> </Form>
</Formik> </Formik>
</FinancialStatementHeader> </VendorBalanceDrawerHeader>
); );
} }
@@ -98,3 +100,9 @@ export default compose(
})), })),
withVendorsBalanceSummaryActions, withVendorsBalanceSummaryActions,
)(VendorsBalanceSummaryHeader); )(VendorsBalanceSummaryHeader);
const VendorBalanceDrawerHeader = styled(FinancialStatementHeader)`
.bp3-drawer {
max-height: 450px;
}
`;

View File

@@ -2,11 +2,12 @@ import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import styled from 'styled-components'; import styled from 'styled-components';
import { DataTable, FinancialSheet } from 'components'; import { ReportDataTable, FinancialSheet } from 'components';
import { useVendorsBalanceColumns } from './components'; import { useVendorsBalanceColumns } from './components';
import { useVendorsBalanceSummaryContext } from './VendorsBalanceSummaryProvider'; import { useVendorsBalanceSummaryContext } from './VendorsBalanceSummaryProvider';
import { TableStyle } from 'common';
import { tableRowTypesToClassnames } from 'utils'; import { tableRowTypesToClassnames } from 'utils';
/** /**
@@ -34,6 +35,7 @@ export default function VendorsBalanceSummaryTable({
data={table.data} data={table.data}
rowClassNames={tableRowTypesToClassnames} rowClassNames={tableRowTypesToClassnames}
noInitialFetch={true} noInitialFetch={true}
styleName={TableStyle.Constrant}
/> />
</VendorBalanceFinancialSheet> </VendorBalanceFinancialSheet>
); );
@@ -41,7 +43,7 @@ export default function VendorsBalanceSummaryTable({
const VendorBalanceFinancialSheet = styled(FinancialSheet)``; const VendorBalanceFinancialSheet = styled(FinancialSheet)``;
const VendorBalanceDataTable = styled(DataTable)` const VendorBalanceDataTable = styled(ReportDataTable)`
.table { .table {
.tbody { .tbody {
.tr:not(.no-results) { .tr:not(.no-results) {
@@ -51,7 +53,7 @@ const VendorBalanceDataTable = styled(DataTable)`
padding-bottom: 0.4rem; padding-bottom: 0.4rem;
} }
&.row-type--TOTAL { &.row_type--TOTAL {
font-weight: 500; font-weight: 500;
.td { .td {

View File

@@ -6,6 +6,8 @@ import { If } from 'components';
import FinancialLoadingBar from '../FinancialLoadingBar'; import FinancialLoadingBar from '../FinancialLoadingBar';
import { useVendorsBalanceSummaryContext } from './VendorsBalanceSummaryProvider'; import { useVendorsBalanceSummaryContext } from './VendorsBalanceSummaryProvider';
import { Align } from 'common';
/** /**
* Retrieve vendors balance summary columns. * Retrieve vendors balance summary columns.
*/ */
@@ -39,8 +41,8 @@ const percentageColumnAccessor = () => ({
accessor: 'cells[2].value', accessor: 'cells[2].value',
className: 'total', className: 'total',
width: 140, width: 140,
align: 'right',
textOverview: true, textOverview: true,
align: Align.Right,
}); });
/** /**
@@ -51,8 +53,8 @@ const totalColumnAccessor = () => ({
accessor: 'cells[1].value', accessor: 'cells[1].value',
className: 'total', className: 'total',
width: 140, width: 140,
align: 'right',
textOverview: true, textOverview: true,
align: Align.Right,
}); });
/** /**

View File

@@ -1,9 +1,10 @@
import React from 'react'; import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { If } from 'components'; import { If } from 'components';
import { useVendorsTransactionsContext } from './VendorsTransactionsProvider'; import { useVendorsTransactionsContext } from './VendorsTransactionsProvider';
import FinancialLoadingBar from '../FinancialLoadingBar'; import FinancialLoadingBar from '../FinancialLoadingBar';
import { getColumnWidth, getForceWidth } from 'utils'; import { getColumnWidth } from 'utils';
/** /**
* Retrieve vendors transactions columns. * Retrieve vendors transactions columns.
@@ -17,19 +18,8 @@ export const useVendorsTransactionsColumns = () => {
() => [ () => [
{ {
Header: intl.get('vendor_name'), Header: intl.get('vendor_name'),
accessor: ({ cells }) => { accessor: 'cells[0].value',
return (
<span
className={'force-width'}
style={{ minWidth: getForceWidth(cells[0].value) }}
>
{cells[0].value}
</span>
);
},
className: 'vendor_name', className: 'vendor_name',
// textOverview: true,
// width: 240,
}, },
{ {
Header: intl.get('account_name'), Header: intl.get('account_name'),

View File

@@ -0,0 +1,15 @@
import React from 'react';
import { T } from 'components';
import { PaymentMethodTabs } from './SubscriptionTabs';
export default ({ formik, title, description }) => {
return (
<section class="billing-plans__section">
<h1 className="title"><T id={'setup.plans.payment_methods.title'} /></h1>
<p className="paragraph"><T id={'setup.plans.payment_methods.description' } /></p>
<PaymentMethodTabs formik={formik} />
</section>
);
};

View File

@@ -1,10 +1,13 @@
import React from 'react'; import React from 'react';
import * as R from 'ramda';
import 'style/pages/Subscription/BillingPlans.scss'; import 'style/pages/Subscription/BillingPlans.scss';
import BillingPlansInput from './BillingPlansInput'; import BillingPlansInput from './BillingPlansInput';
import BillingPeriodsInput from './BillingPeriodsInput'; import BillingPeriodsInput from './BillingPeriodsInput';
// import BillingPaymentMethod from './BillingPaymentMethod'; import BillingPaymentMethod from './BillingPaymentMethod';
import withSubscriptions from './withSubscriptions';
/** /**
* Billing plans form. * Billing plans form.
@@ -14,7 +17,24 @@ export default function BillingPlansForm() {
<div class="billing-plans"> <div class="billing-plans">
<BillingPlansInput /> <BillingPlansInput />
<BillingPeriodsInput /> <BillingPeriodsInput />
{/* <BillingPaymentMethod /> */} <BillingPaymentMethodWhenSubscriptionInactive />
</div> </div>
); );
} }
/**
* Billing payment methods when subscription is inactive.
* @returns {JSX.Element}
*/
function BillingPaymentMethodWhenSubscriptionInactiveJSX({
// # withSubscriptions
isSubscriptionActive,
...props
}) {
return !isSubscriptionActive ? <BillingPaymentMethod {...props} /> : null;
}
const BillingPaymentMethodWhenSubscriptionInactive = R.compose(
withSubscriptions(({ isSubscriptionActive }) => ({ isSubscriptionActive })),
)(BillingPaymentMethodWhenSubscriptionInactiveJSX);

View File

@@ -1,6 +1,11 @@
import { useCallback } from "react" import { useCallback } from "react"
import { useDispatch } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { setSubscriptions } from 'store/subscription/subscription.actions'; import { setSubscriptions } from 'store/subscription/subscription.actions';
import {
isSubscriptionOnTrialFactory,
isSubscriptionInactiveFactory,
isSubscriptionActiveFactory,
} from 'store/subscription/subscription.selectors';
/** /**
* Sets subscriptions. * Sets subscriptions.
@@ -12,3 +17,20 @@ export const useSetSubscriptions = () => {
dispatch(setSubscriptions(subscriptions)); dispatch(setSubscriptions(subscriptions));
}, [dispatch]); }, [dispatch]);
} }
/**
* The organization subscription selector.
* @param {string} slug
* @returns {}
*/
export const useSubscription = (slug = 'main') => {
const isSubscriptionOnTrial = useSelector(isSubscriptionOnTrialFactory(slug));
const isSubscriptionInactive = useSelector(isSubscriptionInactiveFactory(slug));
const isSubscriptionActive = useSelector(isSubscriptionActiveFactory(slug));
return {
isSubscriptionActive,
isSubscriptionInactive,
isSubscriptionOnTrial
}
}

View File

@@ -1795,6 +1795,13 @@
"profit_loss_sheet.percentage_of_row": "% التغير الأفقي", "profit_loss_sheet.percentage_of_row": "% التغير الأفقي",
"profit_loss_sheet.percentage_of_expense": "% التغير في المصاريف", "profit_loss_sheet.percentage_of_expense": "% التغير في المصاريف",
"profit_loss_sheet.percentage_of_income": "% التغير الإيرادات", "profit_loss_sheet.percentage_of_income": "% التغير الإيرادات",
"report.balance_sheet_comparison.title": "مقارنة الميزانية العمومية",
"report.balance_sheet_comparison.desc": "يعرض أصول الشركة والتزاماتها وحقوق المساهمين في نقطة زمنية محددة مقارنة بالسنة الماضية.",
"report.profit_loss_sheet_comparison.title": "مقارنة قائمة الدخل",
"report.profit_loss_sheet_comparison.desc": "يعرض الإيرادات والتكاليف والمصاريف المتكبدة في نقطة محددة ومقارنة بالعام السابق.",
"warehouse_locations.label": "المخازن", "warehouse_locations.label": "المخازن",
"warehouse_locations.column.warehouse_name": "اسم المخزن", "warehouse_locations.column.warehouse_name": "اسم المخزن",
"warehouse_locations.column.quantity": "الكمية", "warehouse_locations.column.quantity": "الكمية",
@@ -2001,5 +2008,4 @@
"receipt.warehouse_button.label": "المخزن: {label}", "receipt.warehouse_button.label": "المخزن: {label}",
"warehouse_transfer.empty_status.title": "", "warehouse_transfer.empty_status.title": "",
"warehouse_transfer.empty_status.description": "" "warehouse_transfer.empty_status.description": ""
} }

View File

@@ -1775,6 +1775,13 @@
"profit_loss_sheet.percentage_of_row": "% of Row", "profit_loss_sheet.percentage_of_row": "% of Row",
"profit_loss_sheet.percentage_of_expense": "% of Expense", "profit_loss_sheet.percentage_of_expense": "% of Expense",
"profit_loss_sheet.percentage_of_income": "% of Income", "profit_loss_sheet.percentage_of_income": "% of Income",
"report.balance_sheet_comparison.title": "Balance Sheet Comparison",
"report.balance_sheet_comparison.desc": "Reports a company's assets, liabilities and shareholders' equity compared to previous year.",
"report.profit_loss_sheet_comparison.title": "Profit/Loss Comparison",
"report.profit_loss_sheet_comparison.desc": "Reports the revenues, costs and expenses incurred at a specific point and compared to previous year.",
"the_vendor_has_been_inactivated_successfully": "The contact has been inactivated successfully.", "the_vendor_has_been_inactivated_successfully": "The contact has been inactivated successfully.",
"vendor.alert.activated_message": "The vendor has been activated successfully.", "vendor.alert.activated_message": "The vendor has been activated successfully.",
"vendor.alert.are_you_sure_want_to_inactivate_this_vendor": "Are you sure want to inactivate this vendor? You will to able to activate it later.", "vendor.alert.are_you_sure_want_to_inactivate_this_vendor": "Are you sure want to inactivate this vendor? You will to able to activate it later.",
@@ -1786,6 +1793,7 @@
"customer.alert.are_you_sure_want_to_inactivate_this_customer": "Are you sure want to inactivate this customer? You will to able to activate it later.", "customer.alert.are_you_sure_want_to_inactivate_this_customer": "Are you sure want to inactivate this customer? You will to able to activate it later.",
"credit_note_preview.dialog.title": "Credit Note PDF Preview", "credit_note_preview.dialog.title": "Credit Note PDF Preview",
"payment_receive_preview.dialog.title": "Payment Receive PDF Preview", "payment_receive_preview.dialog.title": "Payment Receive PDF Preview",
"warehouses.label": "Warehouses", "warehouses.label": "Warehouses",
"warehouses.label.new_warehouse": "New Warehouse", "warehouses.label.new_warehouse": "New Warehouse",
"warehouse.dialog.label.new_warehouse": "New Warehouse", "warehouse.dialog.label.new_warehouse": "New Warehouse",