BIG-52: fix customize Report in purchases by items report not working.

BIG-55: fix customize report in inventory valuation report not working.
BIG-56: fix customize report in Inventory item details report not working.
This commit is contained in:
a.bouhuolia
2021-09-13 13:47:13 +02:00
parent 1eca5e0308
commit 143e15e7ce
47 changed files with 1130 additions and 613 deletions

View File

@@ -0,0 +1,35 @@
import React, { createContext, useContext } from 'react';
import { useVendors } from '../../../hooks/query';
import { FinancialHeaderLoadingSkeleton } from '../FinancialHeaderLoadingSkeleton';
const APAgingSummaryGeneralContext = createContext();
/**
* A/P aging summary provider.
*/
function APAgingSummaryGeneralProvider({ filter, ...props }) {
// Retrieve the vendors list.
const {
data: { vendors },
isFetching: isVendorsLoading,
} = useVendors();
const provider = {
vendors,
isVendorsLoading,
};
// Loading state.
const loading = isVendorsLoading;
return loading ? (
<FinancialHeaderLoadingSkeleton />
) : (
<APAgingSummaryGeneralContext.Provider value={provider} {...props} />
);
}
const useAPAgingSummaryGeneralContext = () =>
useContext(APAgingSummaryGeneralContext);
export { APAgingSummaryGeneralProvider, useAPAgingSummaryGeneralContext };

View File

@@ -1,113 +1,14 @@
import React from 'react'; import React from 'react';
import { FastField, Field } from 'formik'; import { APAgingSummaryGeneralProvider } from './APAgingSummaryGeneralProvider';
import { DateInput } from '@blueprintjs/datetime'; import APAgingSummaryHeaderGeneralContent from './APAgingSummaryHeaderGeneralContent';
import {
Intent,
FormGroup,
InputGroup,
Position,
Classes,
} from '@blueprintjs/core';
import { FormattedMessage as T } from 'components';
import classNames from 'classnames';
import { ContactsMultiSelect, Row, Col, FieldHint } from 'components';
import { useAPAgingSummaryContext } from './APAgingSummaryProvider';
import {
momentFormatter,
tansformDateValue,
inputIntent,
handleDateChange,
} from 'utils';
/** /**
* AP Aging Summary - Drawer Header - General Fields. * AP Aging Summary - Drawer Header - General panel.
*/ */
export default function APAgingSummaryHeaderGeneral() { export default function APAgingSummaryHeaderGeneral() {
const { vendors } = useAPAgingSummaryContext();
return ( return (
<div> <APAgingSummaryGeneralProvider>
<Row> <APAgingSummaryHeaderGeneralContent />
<Col xs={5}> </APAgingSummaryGeneralProvider>
<FastField name={'asDate'}>
{({ form, field: { value }, meta: { error } }) => (
<FormGroup
label={<T id={'as_date'} />}
labelInfo={<FieldHint />}
fill={true}
intent={inputIntent({ error })}
>
<DateInput
{...momentFormatter('YYYY/MM/DD')}
value={tansformDateValue(value)}
onChange={handleDateChange((selectedDate) => {
form.setFieldValue('asDate', selectedDate);
})}
popoverProps={{ position: Position.BOTTOM, minimal: true }}
minimal={true}
fill={true}
/>
</FormGroup>
)}
</FastField>
</Col>
</Row>
<Row>
<Col xs={5}>
<FastField name={'agingDaysBefore'}>
{({ field, meta: { error } }) => (
<FormGroup
label={<T id={'aging_before_days'} />}
labelInfo={<FieldHint />}
intent={inputIntent({ error })}
>
<InputGroup intent={error && Intent.DANGER} {...field} />
</FormGroup>
)}
</FastField>
</Col>
</Row>
<Row>
<Col xs={5}>
<FastField name={'agingPeriods'}>
{({ field, meta: { error } }) => (
<FormGroup
label={<T id={'aging_periods'} />}
labelInfo={<FieldHint />}
intent={inputIntent({ error })}
>
<InputGroup intent={error && Intent.DANGER} {...field} />
</FormGroup>
)}
</FastField>
</Col>
</Row>
<Row>
<Col xs={5}>
<Field name={'vendorsIds'}>
{({
form: { setFieldValue },
field: { value },
}) => (
<FormGroup
label={<T id={'specific_vendors'} />}
className={classNames('form-group--select-list', Classes.FILL)}
>
<ContactsMultiSelect
defaultText={<T id={'all_vendors'} />}
contacts={vendors}
contactsSelected={value}
onContactSelect={(contactsIds) => {
setFieldValue('vendorsIds', contactsIds);
}}
/>
</FormGroup>
)}
</Field>
</Col>
</Row>
</div>
); );
} }

View File

@@ -0,0 +1,116 @@
import React from 'react';
import { FastField, Field } from 'formik';
import { DateInput } from '@blueprintjs/datetime';
import {
Intent,
FormGroup,
InputGroup,
Position,
Classes,
} from '@blueprintjs/core';
import classNames from 'classnames';
import {
FormattedMessage as T,
ContactsMultiSelect,
Row,
Col,
FieldHint,
} from 'components';
import { useAPAgingSummaryGeneralContext } from './APAgingSummaryGeneralProvider';
import {
momentFormatter,
tansformDateValue,
inputIntent,
handleDateChange,
} from 'utils';
/**
* AP Aging Summary - Drawer Header - General panel - Content.
*/
export default function APAgingSummaryHeaderGeneralContent() {
const { vendors } = useAPAgingSummaryGeneralContext();
return (
<div>
<Row>
<Col xs={5}>
<FastField name={'asDate'}>
{({ form, field: { value }, meta: { error } }) => (
<FormGroup
label={<T id={'as_date'} />}
labelInfo={<FieldHint />}
fill={true}
intent={inputIntent({ error })}
>
<DateInput
{...momentFormatter('YYYY/MM/DD')}
value={tansformDateValue(value)}
onChange={handleDateChange((selectedDate) => {
form.setFieldValue('asDate', selectedDate);
})}
popoverProps={{ position: Position.BOTTOM, minimal: true }}
minimal={true}
fill={true}
/>
</FormGroup>
)}
</FastField>
</Col>
</Row>
<Row>
<Col xs={5}>
<FastField name={'agingDaysBefore'}>
{({ field, meta: { error } }) => (
<FormGroup
label={<T id={'aging_before_days'} />}
labelInfo={<FieldHint />}
intent={inputIntent({ error })}
>
<InputGroup intent={error && Intent.DANGER} {...field} />
</FormGroup>
)}
</FastField>
</Col>
</Row>
<Row>
<Col xs={5}>
<FastField name={'agingPeriods'}>
{({ field, meta: { error } }) => (
<FormGroup
label={<T id={'aging_periods'} />}
labelInfo={<FieldHint />}
intent={inputIntent({ error })}
>
<InputGroup intent={error && Intent.DANGER} {...field} />
</FormGroup>
)}
</FastField>
</Col>
</Row>
<Row>
<Col xs={5}>
<Field name={'vendorsIds'}>
{({ form: { setFieldValue }, field: { value } }) => (
<FormGroup
label={<T id={'specific_vendors'} />}
className={classNames('form-group--select-list', Classes.FILL)}
>
<ContactsMultiSelect
defaultText={<T id={'all_vendors'} />}
contacts={vendors}
contactsSelected={value}
onContactSelect={(contactsIds) => {
setFieldValue('vendorsIds', contactsIds);
}}
/>
</FormGroup>
)}
</Field>
</Col>
</Row>
</div>
);
}

View File

@@ -19,19 +19,11 @@ function APAgingSummaryProvider({ filter, ...props }) {
refetch, refetch,
} = useAPAgingSummaryReport(query, { keepPreviousData: true }); } = useAPAgingSummaryReport(query, { keepPreviousData: true });
// Retrieve the vendors list.
const {
data: { vendors },
isFetching: isVendorsLoading,
} = useVendors();
const provider = { const provider = {
APAgingSummary, APAgingSummary,
vendors,
isAPAgingLoading, isAPAgingLoading,
isAPAgingFetching, isAPAgingFetching,
isVendorsLoading,
refetch, refetch,
}; };

View File

@@ -0,0 +1,34 @@
import React, { createContext, useContext } from 'react';
import { useCustomers } from 'hooks/query';
import { FinancialHeaderLoadingSkeleton } from '../FinancialHeaderLoadingSkeleton';
const ARAgingSummaryGeneralContext = createContext();
/**
* A/R aging summary general tab provider.
*/
function ARAgingSummaryGeneralProvider({ ...props }) {
// Retrieve the customers list.
const {
data: { customers },
isLoading: isCustomersLoading,
} = useCustomers();
const provider = {
customers,
isCustomersLoading,
};
// Loading state.
const loading = isCustomersLoading;
return loading ? (
<FinancialHeaderLoadingSkeleton />
) : (
<ARAgingSummaryGeneralContext.Provider value={provider} {...props} />
);
}
const useARAgingSummaryGeneralContext = () =>
useContext(ARAgingSummaryGeneralContext);
export { ARAgingSummaryGeneralProvider, useARAgingSummaryGeneralContext };

View File

@@ -1,116 +1,14 @@
import React from 'react'; import React from 'react';
import { FastField, Field } from 'formik'; import { ARAgingSummaryGeneralProvider } from './ARAgingSummaryGeneralProvider';
import { DateInput } from '@blueprintjs/datetime'; import ARAgingSummaryHeaderGeneralContent from './ARAgingSummaryHeaderGeneralContent';
import {
Intent,
FormGroup,
InputGroup,
Position,
Classes,
} from '@blueprintjs/core';
import { FormattedMessage as T } from 'components';
import classNames from 'classnames';
import { ContactsMultiSelect, Row, Col, FieldHint } from 'components';
import { momentFormatter } from 'utils';
import { useARAgingSummaryContext } from './ARAgingSummaryProvider';
/** /**
* AR Aging Summary - Drawer Header - General Fields. * AR Aging Summary - Drawer Header - General Fields - Content.
*/ */
export default function ARAgingSummaryHeaderGeneral() { export default function ARAgingSummaryHeaderGeneral() {
// AR Aging summary context.
const { customers } = useARAgingSummaryContext();
return ( return (
<div> <ARAgingSummaryGeneralProvider>
<Row> <ARAgingSummaryHeaderGeneralContent />
<Col xs={5}> </ARAgingSummaryGeneralProvider>
<FastField name={'asDate'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'as_date'} />}
labelInfo={<FieldHint />}
fill={true}
intent={error && Intent.DANGER}
>
<DateInput
{...momentFormatter('YYYY/MM/DD')}
value={value}
onChange={(selectedDate) => {
form.setFieldValue('asDate', selectedDate);
}}
popoverProps={{ position: Position.BOTTOM, minimal: true }}
minimal={true}
fill={true}
/>
</FormGroup>
)}
</FastField>
</Col>
</Row>
<Row>
<Col xs={5}>
<FastField name={'agingDaysBefore'}>
{({ field, meta: { error, touched } }) => (
<FormGroup
label={<T id={'aging_before_days'} />}
labelInfo={<FieldHint />}
className={'form-group--aging-before-days'}
intent={error && Intent.DANGER}
>
<InputGroup
medium={true}
intent={error && Intent.DANGER}
{...field}
/>
</FormGroup>
)}
</FastField>
</Col>
</Row>
<Row>
<Col xs={5}>
<FastField name={'agingPeriods'}>
{({ field, meta: { error, touched } }) => (
<FormGroup
label={<T id={'aging_periods'} />}
labelInfo={<FieldHint />}
className={'form-group--aging-periods'}
intent={error && Intent.DANGER}
>
<InputGroup
medium={true}
intent={error && Intent.DANGER}
{...field}
/>
</FormGroup>
)}
</FastField>
</Col>
</Row>
<Row>
<Col xs={5}>
<Field name="customersIds">
{({ form: { setFieldValue }, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'specific_customers'} />}
className={classNames('form-group--select-list', Classes.FILL)}
>
<ContactsMultiSelect
contacts={customers}
contactsSelected={value}
onContactSelect={(contactsIds) => {
setFieldValue('customersIds', contactsIds);
}}
/>
</FormGroup>
)}
</Field>
</Col>
</Row>
</div>
); );
} }

View File

@@ -0,0 +1,121 @@
import React from 'react';
import { FastField, Field } from 'formik';
import { DateInput } from '@blueprintjs/datetime';
import {
Intent,
FormGroup,
InputGroup,
Position,
Classes,
} from '@blueprintjs/core';
import classNames from 'classnames';
import {
FormattedMessage as T,
ContactsMultiSelect,
Row,
Col,
FieldHint,
} from 'components';
import { momentFormatter } from 'utils';
import { useARAgingSummaryGeneralContext } from './ARAgingSummaryGeneralProvider';
/**
* AR Aging Summary - Drawer Header - General Fields.
*/
export default function ARAgingSummaryHeaderGeneralContent() {
// AR Aging summary context.
const { customers } = useARAgingSummaryGeneralContext();
return (
<div>
<Row>
<Col xs={5}>
<FastField name={'asDate'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'as_date'} />}
labelInfo={<FieldHint />}
fill={true}
intent={error && Intent.DANGER}
>
<DateInput
{...momentFormatter('YYYY/MM/DD')}
value={value}
onChange={(selectedDate) => {
form.setFieldValue('asDate', selectedDate);
}}
popoverProps={{ position: Position.BOTTOM, minimal: true }}
minimal={true}
fill={true}
/>
</FormGroup>
)}
</FastField>
</Col>
</Row>
<Row>
<Col xs={5}>
<FastField name={'agingDaysBefore'}>
{({ field, meta: { error, touched } }) => (
<FormGroup
label={<T id={'aging_before_days'} />}
labelInfo={<FieldHint />}
className={'form-group--aging-before-days'}
intent={error && Intent.DANGER}
>
<InputGroup
medium={true}
intent={error && Intent.DANGER}
{...field}
/>
</FormGroup>
)}
</FastField>
</Col>
</Row>
<Row>
<Col xs={5}>
<FastField name={'agingPeriods'}>
{({ field, meta: { error, touched } }) => (
<FormGroup
label={<T id={'aging_periods'} />}
labelInfo={<FieldHint />}
className={'form-group--aging-periods'}
intent={error && Intent.DANGER}
>
<InputGroup
medium={true}
intent={error && Intent.DANGER}
{...field}
/>
</FormGroup>
)}
</FastField>
</Col>
</Row>
<Row>
<Col xs={5}>
<Field name="customersIds">
{({ form: { setFieldValue }, field: { value } }) => (
<FormGroup
label={<T id={'specific_customers'} />}
className={classNames('form-group--select-list', Classes.FILL)}
>
<ContactsMultiSelect
contacts={customers}
contactsSelected={value}
onContactSelect={(contactsIds) => {
setFieldValue('customersIds', contactsIds);
}}
/>
</FormGroup>
)}
</Field>
</Col>
</Row>
</div>
);
}

View File

@@ -20,19 +20,11 @@ function ARAgingSummaryProvider({ filter, ...props }) {
refetch, refetch,
} = useARAgingSummaryReport(query, { keepPreviousData: true }); } = useARAgingSummaryReport(query, { keepPreviousData: true });
// Retrieve the customers list.
const {
data: { customers },
isFetching: isCustomersFetching,
} = useCustomers();
const provider = { const provider = {
ARAgingSummary, ARAgingSummary,
customers,
isARAgingLoading, isARAgingLoading,
isARAgingFetching, isARAgingFetching,
isCustomersFetching,
refetch, refetch,
}; };

View File

@@ -2,16 +2,17 @@ import React, { useEffect, useState } from 'react';
import moment from 'moment'; import moment from 'moment';
import 'style/pages/FinancialStatements/BalanceSheet.scss'; import 'style/pages/FinancialStatements/BalanceSheet.scss';
import { BalanceSheetAlerts, BalanceSheetLoadingBar } from './components';
import { FinancialStatement } from 'components';
import BalanceSheetHeader from './BalanceSheetHeader'; import BalanceSheetHeader from './BalanceSheetHeader';
import BalanceSheetTable from './BalanceSheetTable'; import BalanceSheetTable from './BalanceSheetTable';
import DashboardPageContent from 'components/Dashboard/DashboardPageContent'; import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
import BalanceSheetActionsBar from './BalanceSheetActionsBar'; import BalanceSheetActionsBar from './BalanceSheetActionsBar';
import { BalanceSheetAlerts, BalanceSheetLoadingBar } from './components'; import { BalanceSheetProvider } from './BalanceSheetProvider';
import { FinancialStatement } from 'components';
import withBalanceSheetActions from './withBalanceSheetActions'; import withBalanceSheetActions from './withBalanceSheetActions';
import withCurrentOrganization from '../../../containers/Organization/withCurrentOrganization'; import withCurrentOrganization from '../../../containers/Organization/withCurrentOrganization';
import { BalanceSheetProvider } from './BalanceSheetProvider';
import { compose } from 'utils'; import { compose } from 'utils';
@@ -19,7 +20,7 @@ import { compose } from 'utils';
* Balance sheet. * Balance sheet.
*/ */
function BalanceSheet({ function BalanceSheet({
// #withPreferences // #withCurrentOrganization
organizationName, organizationName,
// #withBalanceSheetActions // #withBalanceSheetActions
@@ -30,7 +31,7 @@ function BalanceSheet({
toDate: moment().endOf('year').format('YYYY-MM-DD'), toDate: moment().endOf('year').format('YYYY-MM-DD'),
basis: 'cash', basis: 'cash',
displayColumnsType: 'total', displayColumnsType: 'total',
accountsFilter: 'all-accounts', accountsFilter: 'without-zero-balance',
}); });
// Handle re-fetch balance sheet after filter change. // Handle re-fetch balance sheet after filter change.
@@ -66,7 +67,6 @@ function BalanceSheet({
onNumberFormatSubmit={handleNumberFormatSubmit} onNumberFormatSubmit={handleNumberFormatSubmit}
/> />
<BalanceSheetLoadingBar /> <BalanceSheetLoadingBar />
<BalanceSheetAlerts />
<DashboardPageContent> <DashboardPageContent>
<FinancialStatement> <FinancialStatement>
@@ -79,6 +79,8 @@ function BalanceSheet({
</div> </div>
</FinancialStatement> </FinancialStatement>
</DashboardPageContent> </DashboardPageContent>
<BalanceSheetAlerts />
</BalanceSheetProvider> </BalanceSheetProvider>
); );
} }

View File

@@ -1,18 +1,20 @@
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 { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal';
import moment from 'moment'; import moment from 'moment';
import * as Yup from 'yup';
import { Formik, Form } from 'formik'; import { Formik, Form } from 'formik';
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
import withBalanceSheet from './withBalanceSheet'; import withBalanceSheet from './withBalanceSheet';
import withBalanceSheetActions from './withBalanceSheetActions'; import withBalanceSheetActions from './withBalanceSheetActions';
import { compose, transformToForm } from 'utils';
import BalanceSheetHeaderGeneralPanal from './BalanceSheetHeaderGeneralPanal'; import BalanceSheetHeaderGeneralPanal from './BalanceSheetHeaderGeneralPanal';
import FinancialStatementHeader from '../../FinancialStatements/FinancialStatementHeader';
import { compose, transformToForm } from 'utils';
import {
getBalanceSheetHeaderDefaultValues,
getBalanceSheetHeaderValidationSchema,
} from './utils';
/** /**
* Balance sheet header. * Balance sheet header.
@@ -28,14 +30,12 @@ function BalanceSheetHeader({
// #withBalanceSheetActions // #withBalanceSheetActions
toggleBalanceSheetFilterDrawer: toggleFilterDrawer, toggleBalanceSheetFilterDrawer: toggleFilterDrawer,
}) { }) {
const defaultValues = { const defaultValues = getBalanceSheetHeaderDefaultValues();
basic: 'cash',
fromDate: moment().toDate(),
toDate: moment().toDate(),
};
// Filter form initial values. // Filter form initial values.
const initialValues = transformToForm( const initialValues = transformToForm(
{ {
...defaultValues,
...pageFilter, ...pageFilter,
fromDate: moment(pageFilter.fromDate).toDate(), fromDate: moment(pageFilter.fromDate).toDate(),
toDate: moment(pageFilter.toDate).toDate(), toDate: moment(pageFilter.toDate).toDate(),
@@ -44,16 +44,7 @@ function BalanceSheetHeader({
); );
// Validation schema. // Validation schema.
const validationSchema = Yup.object().shape({ const validationSchema = getBalanceSheetHeaderValidationSchema();
dateRange: Yup.string().optional(),
fromDate: Yup.date().required().label(intl.get('fromDate')),
toDate: Yup.date()
.min(Yup.ref('fromDate'))
.required()
.label(intl.get('toDate')),
accountsFilter: Yup.string(),
displayColumnsType: Yup.string(),
});
// Handle form submit. // Handle form submit.
const handleSubmit = (values, actions) => { const handleSubmit = (values, actions) => {
@@ -63,10 +54,14 @@ function BalanceSheetHeader({
}; };
// Handle cancel button click. // Handle cancel button click.
const handleCancelClick = () => { toggleFilterDrawer(false); }; const handleCancelClick = () => {
toggleFilterDrawer(false);
};
// Handle drawer close action. // Handle drawer close action.
const handleDrawerClose = () => { toggleFilterDrawer(false); }; const handleDrawerClose = () => {
toggleFilterDrawer(false);
};
return ( return (
<FinancialStatementHeader <FinancialStatementHeader

View File

@@ -0,0 +1,25 @@
import * as Yup from 'yup';
import intl from 'react-intl-universal';
import moment from 'moment';
export const getBalanceSheetHeaderDefaultValues = () => {
return {
basic: 'cash',
accountsFilter: 'without-zero-balance',
displayColumnsType: 'total',
fromDate: moment().toDate(),
toDate: moment().toDate(),
};
};
export const getBalanceSheetHeaderValidationSchema = () =>
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')),
accountsFilter: Yup.string(),
displayColumnsType: Yup.string(),
});

View File

@@ -1,94 +1,14 @@
import React from 'react'; import React from 'react';
import { FastField, Field } from 'formik'; import CustomersBalanceSummaryGeneralPanelContent from './CustomersBalanceSummaryGeneralPanelContent';
import { DateInput } from '@blueprintjs/datetime'; import { CustomersBalanceSummaryGeneralProvider } from './CustomersBalanceSummaryGeneralProvider';
import { Classes, FormGroup, Position, Checkbox } from '@blueprintjs/core';
import { ContactsMultiSelect, FormattedMessage as T } from 'components';
import classNames from 'classnames';
import { Row, Col, FieldHint } from 'components';
import {
momentFormatter,
tansformDateValue,
inputIntent,
handleDateChange,
} from 'utils';
import { useCustomersBalanceSummaryContext } from './CustomersBalanceSummaryProvider';
/** /**
* Customers balance header - general panel. * Customers balance header - General panel.
*/ */
export default function CustomersBalanceSummaryGeneralPanel() { export default function CustomersBalanceSummaryGeneralPanel() {
const { customers } = useCustomersBalanceSummaryContext();
return ( return (
<div> <CustomersBalanceSummaryGeneralProvider>
<Row> <CustomersBalanceSummaryGeneralPanelContent />
<Col xs={5}> </CustomersBalanceSummaryGeneralProvider>
<FastField name={'asDate'}>
{({ form, field: { value }, meta: { error } }) => (
<FormGroup
label={<T id={'as_date'} />}
labelInfo={<FieldHint />}
fill={true}
intent={inputIntent({ error })}
>
<DateInput
{...momentFormatter('YYYY/MM/DD')}
value={tansformDateValue(value)}
onChange={handleDateChange((selectedDate) => {
form.setFieldValue('asDate', selectedDate);
})}
popoverProps={{ position: Position.BOTTOM, minimal: true }}
minimal={true}
fill={true}
/>
</FormGroup>
)}
</FastField>
</Col>
</Row>
<Row>
<Col xs={5}>
<FastField name={'percentage'} type={'checkbox'}>
{({ field }) => (
<FormGroup labelInfo={<FieldHint />}>
<Checkbox
inline={true}
name={'percentage'}
small={true}
label={<T id={'percentage_of_column'} />}
{...field}
/>
</FormGroup>
)}
</FastField>
</Col>
</Row>
<Row>
<Col xs={5}>
<Field name={'customersIds'}>
{({
form: { setFieldValue },
field: { value },
meta: { error, touched },
}) => (
<FormGroup
label={<T id={'Specific customers'} />}
className={classNames('form-group--select-list', Classes.FILL)}
>
<ContactsMultiSelect
onContactSelect={(contactsIds) => {
setFieldValue('customersIds', contactsIds);
}}
contacts={customers}
contactsSelected={value}
/>
</FormGroup>
)}
</Field>
</Col>
</Row>
</div>
); );
} }

View File

@@ -0,0 +1,94 @@
import React from 'react';
import { FastField, Field } from 'formik';
import { DateInput } from '@blueprintjs/datetime';
import { Classes, FormGroup, Position, Checkbox } from '@blueprintjs/core';
import { ContactsMultiSelect, FormattedMessage as T } from 'components';
import classNames from 'classnames';
import { Row, Col, FieldHint } from 'components';
import {
momentFormatter,
tansformDateValue,
inputIntent,
handleDateChange,
} from 'utils';
import { useCustomersBalanceSummaryGeneralContext } from './CustomersBalanceSummaryGeneralProvider';
/**
* Customers balance header - General panel - Content
*/
export default function CustomersBalanceSummaryGeneralPanelContent() {
const { customers } = useCustomersBalanceSummaryGeneralContext();
return (
<div>
<Row>
<Col xs={5}>
<FastField name={'asDate'}>
{({ form, field: { value }, meta: { error } }) => (
<FormGroup
label={<T id={'as_date'} />}
labelInfo={<FieldHint />}
fill={true}
intent={inputIntent({ error })}
>
<DateInput
{...momentFormatter('YYYY/MM/DD')}
value={tansformDateValue(value)}
onChange={handleDateChange((selectedDate) => {
form.setFieldValue('asDate', selectedDate);
})}
popoverProps={{ position: Position.BOTTOM, minimal: true }}
minimal={true}
fill={true}
/>
</FormGroup>
)}
</FastField>
</Col>
</Row>
<Row>
<Col xs={5}>
<FastField name={'percentage'} type={'checkbox'}>
{({ field }) => (
<FormGroup labelInfo={<FieldHint />}>
<Checkbox
inline={true}
name={'percentage'}
small={true}
label={<T id={'percentage_of_column'} />}
{...field}
/>
</FormGroup>
)}
</FastField>
</Col>
</Row>
<Row>
<Col xs={5}>
<Field name={'customersIds'}>
{({
form: { setFieldValue },
field: { value },
meta: { error, touched },
}) => (
<FormGroup
label={<T id={'Specific customers'} />}
className={classNames('form-group--select-list', Classes.FILL)}
>
<ContactsMultiSelect
onContactSelect={(contactsIds) => {
setFieldValue('customersIds', contactsIds);
}}
contacts={customers}
contactsSelected={value}
/>
</FormGroup>
)}
</Field>
</Col>
</Row>
</div>
);
}

View File

@@ -0,0 +1,42 @@
import React, { createContext, useContext } from 'react';
import { FinancialHeaderLoadingSkeleton } from '../FinancialHeaderLoadingSkeleton';
import { useCustomers } from 'hooks/query';
const CustomersBalanceSummaryGeneralContext = createContext();
/**
* Customers balance summary provider.
*/
function CustomersBalanceSummaryGeneralProvider({ ...props }) {
// Fetches the customers list.
const {
data: { customers },
isFetching: isCustomersFetching,
isLoading: isCustomersLoading,
} = useCustomers();
const provider = {
isCustomersLoading,
isCustomersFetching,
customers,
};
const loading = isCustomersLoading;
return loading ? (
<FinancialHeaderLoadingSkeleton />
) : (
<CustomersBalanceSummaryGeneralContext.Provider
value={provider}
{...props}
/>
);
}
const useCustomersBalanceSummaryGeneralContext = () =>
useContext(CustomersBalanceSummaryGeneralContext);
export {
CustomersBalanceSummaryGeneralProvider,
useCustomersBalanceSummaryGeneralContext,
};

View File

@@ -20,10 +20,10 @@ function CustomersBalanceSummaryHeader({
onSubmitFilter, onSubmitFilter,
pageFilter, pageFilter,
//#withCustomersBalanceSummary // #withCustomersBalanceSummary
customersBalanceDrawerFilter, customersBalanceDrawerFilter,
//#withCustomersBalanceSummaryActions // #withCustomersBalanceSummaryActions
toggleCustomerBalanceFilterDrawer, toggleCustomerBalanceFilterDrawer,
}) { }) {

View File

@@ -1,6 +1,6 @@
import React, { createContext, useContext } from 'react'; import React, { createContext, useContext } from 'react';
import FinancialReportPage from '../FinancialReportPage'; import FinancialReportPage from '../FinancialReportPage';
import { useCustomerBalanceSummaryReport, useCustomers } from 'hooks/query'; import { useCustomerBalanceSummaryReport } from '../../../hooks/query';
import { transformFilterFormToQuery } from '../common'; import { transformFilterFormToQuery } from '../common';
const CustomersBalanceSummaryContext = createContext(); const CustomersBalanceSummaryContext = createContext();
@@ -9,37 +9,26 @@ const CustomersBalanceSummaryContext = createContext();
* Customers balance summary provider. * Customers balance summary provider.
*/ */
function CustomersBalanceSummaryProvider({ filter, ...props }) { function CustomersBalanceSummaryProvider({ filter, ...props }) {
const query = React.useMemo(
const query = React.useMemo(() => transformFilterFormToQuery(filter), [ () => transformFilterFormToQuery(filter),
filter, [filter],
]); );
// Fetches customers balance summary report based on the given report. // Fetches customers balance summary report based on the given report.
const { const {
data: CustomerBalanceSummary, data: CustomerBalanceSummary,
isLoading: isCustomersBalanceLoading, isLoading: isCustomersBalanceLoading,
isFetching: isCustomersBalanceFetching, isFetching: isCustomersBalanceFetching,
refetch refetch,
} = useCustomerBalanceSummaryReport(query, { } = useCustomerBalanceSummaryReport(query, {
keepPreviousData: true, keepPreviousData: true,
}); });
// Fetches the customers list.
const {
data: { customers },
isFetching: isCustomersFetching,
isLoading: isCustomersLoading,
} = useCustomers();
const provider = { const provider = {
CustomerBalanceSummary, CustomerBalanceSummary,
isCustomersBalanceFetching, isCustomersBalanceFetching,
isCustomersBalanceLoading, isCustomersBalanceLoading,
isCustomersLoading,
isCustomersFetching,
customers,
refetch, refetch,
}; };
return ( return (

View File

@@ -5,13 +5,27 @@ import { Classes, FormGroup } from '@blueprintjs/core';
import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange'; import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
import { Row, Col } from 'components'; import { Row, Col } from 'components';
import { ContactsMultiSelect, FormattedMessage as T } from 'components'; import { ContactsMultiSelect, FormattedMessage as T } from 'components';
import { useCustomersTransactionsContext } from './CustomersTransactionsProvider'; import {
CustomersTransactionsGeneralPanelProvider,
useCustomersTransactionsGeneralPanelContext,
} from './CustomersTransactionsHeaderGeneralPanelProvider';
/** /**
* Customers transactions header - General panel. * Customers transactions header - General panel.
*/ */
export default function CustomersTransactionsHeaderGeneralPanel() { export default function CustomersTransactionsHeaderGeneralPanel() {
const { customers } = useCustomersTransactionsContext(); return (
<CustomersTransactionsGeneralPanelProvider>
<CustomersTransactionsHeaderGeneralPanelContent />
</CustomersTransactionsGeneralPanelProvider>
);
}
/**
* Customers transactions header - General panel - Content.
*/
function CustomersTransactionsHeaderGeneralPanelContent() {
const { customers } = useCustomersTransactionsGeneralPanelContext();
return ( return (
<div> <div>
@@ -20,10 +34,7 @@ export default function CustomersTransactionsHeaderGeneralPanel() {
<Row> <Row>
<Col xs={5}> <Col xs={5}>
<Field name={'customersIds'}> <Field name={'customersIds'}>
{({ {({ form: { setFieldValue }, field: { value } }) => (
form: { setFieldValue },
field: { value },
}) => (
<FormGroup <FormGroup
label={<T id={'specific_customers'} />} label={<T id={'specific_customers'} />}
className={classNames('form-group--select-list', Classes.FILL)} className={classNames('form-group--select-list', Classes.FILL)}

View File

@@ -0,0 +1,41 @@
import React, { createContext, useContext } from 'react';
import { FinancialHeaderLoadingSkeleton } from '../FinancialHeaderLoadingSkeleton';
import { useCustomers } from '../../../hooks/query';
const CustomersTransactionsGeneralPanelContext = createContext();
/**
* Customers transactions provider.
*/
function CustomersTransactionsGeneralPanelProvider({ ...props }) {
// Fetches the customers list.
const {
data: { customers },
isFetching: isCustomersFetching,
isLoading: isCustomersLoading,
} = useCustomers();
const provider = {
customers,
isCustomersLoading,
isCustomersFetching,
};
const loading = isCustomersLoading;
return loading ? (
<FinancialHeaderLoadingSkeleton />
) : (
<CustomersTransactionsGeneralPanelContext.Provider
value={provider}
{...props}
/>
);
}
const useCustomersTransactionsGeneralPanelContext = () =>
useContext(CustomersTransactionsGeneralPanelContext);
export {
CustomersTransactionsGeneralPanelProvider,
useCustomersTransactionsGeneralPanelContext,
};

View File

@@ -1,6 +1,6 @@
import React, { createContext, useContext, useMemo } from 'react'; import React, { createContext, useContext, useMemo } from 'react';
import FinancialReportPage from '../FinancialReportPage'; import FinancialReportPage from '../FinancialReportPage';
import { useCustomersTransactionsReport, useCustomers } from 'hooks/query'; import { useCustomersTransactionsReport } from '../../../hooks/query';
import { transformFilterFormToQuery } from '../common'; import { transformFilterFormToQuery } from '../common';
const CustomersTransactionsContext = createContext(); const CustomersTransactionsContext = createContext();
@@ -21,23 +21,12 @@ function CustomersTransactionsProvider({ filter, ...props }) {
refetch: CustomersTransactionsRefetch, refetch: CustomersTransactionsRefetch,
} = useCustomersTransactionsReport(query, { keepPreviousData: true }); } = useCustomersTransactionsReport(query, { keepPreviousData: true });
// Fetches the customers list.
const {
data: { customers },
isFetching: isCustomersFetching,
isLoading: isCustomersLoading,
} = useCustomers();
const provider = { const provider = {
customersTransactions, customersTransactions,
isCustomersTransactionsFetching, isCustomersTransactionsFetching,
isCustomersTransactionsLoading, isCustomersTransactionsLoading,
CustomersTransactionsRefetch, CustomersTransactionsRefetch,
customers,
isCustomersLoading,
isCustomersFetching,
filter, filter,
query query
}; };

View File

@@ -0,0 +1,26 @@
import React from 'react';
import { Classes } from '@blueprintjs/core';
import clsx from 'classnames';
import Style from './FinancialHeaderLoadingSkeleton.module.scss';
function FinancialHeaderLoadingSkeletonLine() {
return (
<div className={clsx(Style.line)}>
<h4 className={clsx(Classes.SKELETON, Style.line_label)}>XXXXXXXX</h4>
<h4 className={clsx(Classes.SKELETON, Style.line_field)}>XXXXXXXX</h4>
</div>
);
}
/**
* Financial drawer header loading skeleton.
*/
export function FinancialHeaderLoadingSkeleton() {
return (
<div className={clsx(Style.lines)}>
<FinancialHeaderLoadingSkeletonLine />
<FinancialHeaderLoadingSkeletonLine />
<FinancialHeaderLoadingSkeletonLine />
</div>
);
}

View File

@@ -0,0 +1,22 @@
.lines {
padding-top: 20px;
.line+.line {
margin-top: 30px;
}
}
.line {
display: flex;
width: 600px;
flex-direction: row;
&_label {
width: 30%;
margin-right: 20px;
}
&_field {
width: 70%;
}
}

View File

@@ -0,0 +1,32 @@
import React, { createContext, useContext } from 'react';
import { useAccounts } from 'hooks/query';
import { FinancialHeaderLoadingSkeleton } from '../FinancialHeaderLoadingSkeleton';
const GLHeaderGeneralPanelContext = createContext();
/**
* General ledger provider.
*/
function GLHeaderGeneralPanelProvider({ ...props }) {
// Accounts list.
const { data: accounts, isLoading: isAccountsLoading } = useAccounts();
// Provider
const provider = {
accounts,
isAccountsLoading,
};
const loading = isAccountsLoading;
return loading ? (
<FinancialHeaderLoadingSkeleton />
) : (
<GLHeaderGeneralPanelContext.Provider value={provider} {...props} />
);
}
const useGLGeneralPanelContext = () => useContext(GLHeaderGeneralPanelContext);
export { GLHeaderGeneralPanelProvider, useGLGeneralPanelContext };

View File

@@ -1,8 +1,5 @@
import React from 'react'; import React from 'react';
import { import { FormGroup, Classes } from '@blueprintjs/core';
FormGroup,
Classes,
} from '@blueprintjs/core';
import { FormattedMessage as T } from 'components'; import { FormattedMessage as T } from 'components';
import classNames from 'classnames'; import classNames from 'classnames';
@@ -11,18 +8,30 @@ import { AccountsMultiSelect, Row, Col } from 'components';
import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange'; import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
import RadiosAccountingBasis from '../RadiosAccountingBasis'; import RadiosAccountingBasis from '../RadiosAccountingBasis';
import FinancialAccountsFilter from '../FinancialAccountsFilter'; import FinancialAccountsFilter from '../FinancialAccountsFilter';
import { GLHeaderGeneralPanelProvider } from './GLHeaderGeneralPaneProvider';
import { filterAccountsOptions } from './common'; import { filterAccountsOptions } from './common';
import { useGeneralLedgerContext } from './GeneralLedgerProvider' import { useGLGeneralPanelContext } from './GLHeaderGeneralPaneProvider';
/** /**
* General ledger (GL) - Header - General panel. * General ledger (GL) - Header - General panel.
*/ */
export default function GeneralLedgerHeaderGeneralPane() { export default function GLHeaderGeneralPane() {
const { accounts } = useGeneralLedgerContext(); return (
<GLHeaderGeneralPanelProvider>
<GLHeaderGeneralPaneContent />
</GLHeaderGeneralPanelProvider>
);
}
/**
* General ledger (GL) - Header - General panel - content.
*/
function GLHeaderGeneralPaneContent() {
const { accounts } = useGLGeneralPanelContext();
return ( return (
<div> <React.Fragment>
<FinancialStatementDateRange /> <FinancialStatementDateRange />
<FinancialAccountsFilter <FinancialAccountsFilter
items={filterAccountsOptions} items={filterAccountsOptions}
@@ -40,6 +49,6 @@ export default function GeneralLedgerHeaderGeneralPane() {
</Row> </Row>
<RadiosAccountingBasis key={'basis'} /> <RadiosAccountingBasis key={'basis'} />
</div> </React.Fragment>
); );
} }

View File

@@ -13,20 +13,13 @@ function GeneralLedgerProvider({ query, ...props }) {
isFetching, isFetching,
isLoading, isLoading,
refetch, refetch,
} = useGeneralLedgerSheet(query, { } = useGeneralLedgerSheet(query, { keepPreviousData: true });
keepPreviousData: true,
});
// Accounts list.
const { data: accounts, isFetching: isAccountsLoading } = useAccounts();
const provider = { const provider = {
generalLedger, generalLedger,
accounts,
sheetRefresh: refetch, sheetRefresh: refetch,
isFetching, isFetching,
isLoading, isLoading,
isAccountsLoading,
}; };
return ( return (
<FinancialReportPage name={'general-ledger-sheet'}> <FinancialReportPage name={'general-ledger-sheet'}>

View File

@@ -3,14 +3,25 @@ import classNames from 'classnames';
import { FormGroup, Classes } from '@blueprintjs/core'; import { FormGroup, Classes } from '@blueprintjs/core';
import { Field } from 'formik'; import { Field } from 'formik';
import { Row, Col, FormattedMessage as T } from 'components'; import { Row, Col, FormattedMessage as T } from 'components';
import { ItemsMultiSelect } from 'components';
import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange'; import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
import { useInventoryItemDetailsContext } from './InventoryItemDetailsProvider'; import { useInventoryItemDetailsContext } from './InventoryItemDetailsProvider';
import { InventoryItemDetailsHeaderGeneralProvider } from './InventoryItemDetailsHeaderGeneralProvider';
/** /**
* Inventory item details header - General panel. * Inventory item details header - General panel.
*/ */
export default function InventoryItemDetailsHeaderGeneralPanel() { export default function InventoryItemDetailsHeaderGeneralPanel() {
return (
<InventoryItemDetailsHeaderGeneralProvider>
<InventoryItemDetailsHeaderGeneralPanelContent />
</InventoryItemDetailsHeaderGeneralProvider>
);
}
/**
* Inventory item details header - General panel - Content.
*/
function InventoryItemDetailsHeaderGeneralPanelContent() {
const { items } = useInventoryItemDetailsContext(); const { items } = useInventoryItemDetailsContext();
return ( return (
@@ -28,15 +39,7 @@ export default function InventoryItemDetailsHeaderGeneralPanel() {
<FormGroup <FormGroup
label={<T id={'Specific items'} />} label={<T id={'Specific items'} />}
className={classNames('form-group--select-list', Classes.FILL)} className={classNames('form-group--select-list', Classes.FILL)}
> ></FormGroup>
<ItemsMultiSelect
items={items}
selectedItems={value}
onItemSelect={(itemsIds) => {
setFieldValue('itemsIds', itemsIds);
}}
/>
</FormGroup>
)} )}
</Field> </Field>
</Col> </Col>

View File

@@ -0,0 +1,46 @@
import React from 'react';
import { useItems } from 'hooks/query';
import { FinancialHeaderLoadingSkeleton } from '../FinancialHeaderLoadingSkeleton';
const InventoryItemDetailsHeaderGeneralContext = React.createContext();
/**
* Inventory item details provider.
*/
function InventoryItemDetailsHeaderGeneralProvider({ ...props }) {
// Handle fetching the items based on the given query.
const {
data: { items },
isLoading: isItemsLoading,
isFetching: isItemsFetching,
} = useItems({
stringified_filter_roles: JSON.stringify([
{ fieldKey: 'type', comparator: 'is', value: 'inventory', index: 1 },
]),
page_size: 10000,
});
const provider = {
isItemsFetching,
isItemsLoading,
items,
};
// Loading state.
const loading = isItemsLoading;
return loading ? (
<FinancialHeaderLoadingSkeleton />
) : (
<InventoryItemDetailsHeaderGeneralContext.Provider
value={provider}
{...props}
/>
);
}
const useInventoryItemDetailsHeaderGeneralContext = () =>
React.useContext(InventoryItemDetailsHeaderGeneralContext);
export {
InventoryItemDetailsHeaderGeneralProvider,
useInventoryItemDetailsHeaderGeneralContext,
};

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import FinancialReportPage from '../FinancialReportPage'; import FinancialReportPage from '../FinancialReportPage';
import { useItems, useInventoryItemDetailsReport } from 'hooks/query'; import { useInventoryItemDetailsReport } from 'hooks/query';
import { transformFilterFormToQuery } from '../common'; import { transformFilterFormToQuery } from '../common';
const InventoryItemDetailsContext = React.createContext(); const InventoryItemDetailsContext = React.createContext();
@@ -22,28 +22,12 @@ function InventoryItemDetailsProvider({ filter, ...props }) {
refetch: inventoryItemDetailsRefetch, refetch: inventoryItemDetailsRefetch,
} = useInventoryItemDetailsReport(query, { keepPreviousData: true }); } = useInventoryItemDetailsReport(query, { keepPreviousData: true });
// Handle fetching the items based on the given query.
const {
data: { items },
isLoading: isItemsLoading,
isFetching: isItemsFetching,
} = useItems({
stringified_filter_roles: JSON.stringify([
{ fieldKey: 'type', comparator: 'is', value: 'inventory', index: 1 },
]),
page_size: 10000,
});
const provider = { const provider = {
inventoryItemDetails, inventoryItemDetails,
isInventoryItemDetailsFetching, isInventoryItemDetailsFetching,
isInventoryItemDetailsLoading, isInventoryItemDetailsLoading,
inventoryItemDetailsRefetch, inventoryItemDetailsRefetch,
isItemsFetching,
isItemsLoading,
items,
query, query,
filter, filter,
}; };

View File

@@ -11,13 +11,27 @@ import {
inputIntent, inputIntent,
handleDateChange, handleDateChange,
} from 'utils'; } from 'utils';
import { useInventoryValuationContext } from './InventoryValuationProvider'; import {
InventoryValuationGeneralPanelProvider,
useInventoryValuationGeneralPanelContext,
} from './InventoryValuationHeaderGeneralPanelProvider';
/** /**
* Inventory valuation - Drawer Header - General panel. * Inventory valuation - Drawer Header - General panel.
*/ */
export default function InventoryValuationHeaderGeneralPanel() { export default function InventoryValuationHeaderGeneralPanel() {
const { items } = useInventoryValuationContext(); return (
<InventoryValuationGeneralPanelProvider>
<InventoryValuationHeaderGeneralPanelContent />
</InventoryValuationGeneralPanelProvider>
);
}
/**
* Inventory valuation - Drawer Header - General panel - Content.
*/
function InventoryValuationHeaderGeneralPanelContent() {
const { items } = useInventoryValuationGeneralPanelContext();
return ( return (
<div> <div>
@@ -59,13 +73,7 @@ export default function InventoryValuationHeaderGeneralPanel() {
label={<T id={'Specific items'} />} label={<T id={'Specific items'} />}
className={classNames('form-group--select-list', Classes.FILL)} className={classNames('form-group--select-list', Classes.FILL)}
> >
<ItemsMultiSelect
items={items}
selectedItems={value}
onItemSelect={(itemsIds) => {
setFieldValue('itemsIds', itemsIds);
}}
/>
</FormGroup> </FormGroup>
)} )}
</Field> </Field>

View File

@@ -0,0 +1,45 @@
import React from 'react';
import { FinancialHeaderLoadingSkeleton } from '../FinancialHeaderLoadingSkeleton';
import { useItems } from 'hooks/query';
const InventoryValuationGeneralPanelContext = React.createContext();
function InventoryValuationGeneralPanelProvider({ query, ...props }) {
// Handle fetching the items based on the given query.
const {
data: { items },
isLoading: isItemsLoading,
isFetching: isItemsFetching,
} = useItems({
stringified_filter_roles: JSON.stringify([
{ fieldKey: 'type', comparator: 'is', value: 'inventory', index: 1 },
]),
page_size: 10000,
});
// Provider data.
const provider = {
items,
isItemsFetching,
isItemsLoading,
};
const loading = isItemsLoading;
return loading ? (
<FinancialHeaderLoadingSkeleton />
) : (
<InventoryValuationGeneralPanelContext.Provider
value={provider}
{...props}
/>
);
}
const useInventoryValuationGeneralPanelContext = () =>
React.useContext(InventoryValuationGeneralPanelContext);
export {
InventoryValuationGeneralPanelProvider,
useInventoryValuationGeneralPanelContext,
};

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import FinancialReportPage from '../FinancialReportPage'; import FinancialReportPage from '../FinancialReportPage';
import { useInventoryValuation, useItems } from 'hooks/query'; import { useInventoryValuation } from 'hooks/query';
import { transformFilterFormToQuery } from '../common'; import { transformFilterFormToQuery } from '../common';
const InventoryValuationContext = React.createContext(); const InventoryValuationContext = React.createContext();
@@ -20,17 +20,6 @@ function InventoryValuationProvider({ query, ...props }) {
}, },
); );
// Handle fetching the items based on the given query.
const {
data: { items },
isLoading: isItemsLoading,
isFetching: isItemsFetching,
} = useItems({
stringified_filter_roles: JSON.stringify([
{ fieldKey: 'type', comparator: 'is', value: 'inventory', index: 1 },
]),
page_size: 10000,
});
// Provider data. // Provider data.
const provider = { const provider = {
@@ -38,10 +27,6 @@ function InventoryValuationProvider({ query, ...props }) {
isLoading, isLoading,
isFetching, isFetching,
refetchSheet: refetch, refetchSheet: refetch,
items,
isItemsFetching,
isItemsLoading,
}; };
return ( return (

View File

@@ -19,29 +19,34 @@ export const useJournalTableColumns = () => {
row.date ? moment(row.date).format('YYYY MMM DD') : '', row.date ? moment(row.date).format('YYYY MMM DD') : '',
className: 'date', className: 'date',
width: 100, width: 100,
textOverview: true,
}, },
{ {
Header: intl.get('transaction_type'), Header: intl.get('transaction_type'),
accessor: 'reference_type_formatted', accessor: 'reference_type_formatted',
className: 'reference_type_formatted', className: 'reference_type_formatted',
width: 120, width: 120,
textOverview: true,
}, },
{ {
Header: intl.get('num'), Header: intl.get('num'),
accessor: 'transaction_number', accessor: 'transaction_number',
className: 'reference_id', className: 'reference_id',
width: 70, width: 70,
textOverview: true,
}, },
{ {
Header: intl.get('description'), Header: intl.get('description'),
accessor: 'note', accessor: 'note',
className: 'note', className: 'note',
textOverview: true,
}, },
{ {
Header: intl.get('acc_code'), Header: intl.get('acc_code'),
accessor: 'account_code', accessor: 'account_code',
width: 95, width: 95,
className: 'account_code', className: 'account_code',
textOverview: true,
}, },
{ {
Header: intl.get('account'), Header: intl.get('account'),

View File

@@ -65,6 +65,7 @@ function PurchasesByItems({
onNumberFormatSubmit={handleNumberFormatSubmit} onNumberFormatSubmit={handleNumberFormatSubmit}
/> />
<PurchasesByItemsLoadingBar /> <PurchasesByItemsLoadingBar />
<DashboardPageContent> <DashboardPageContent>
<div className="financial-statement financial-statement--purchases-by-items"> <div className="financial-statement financial-statement--purchases-by-items">
<PurchasesByItemsHeader <PurchasesByItemsHeader

View File

@@ -6,13 +6,27 @@ import classNames from 'classnames';
import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange'; import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
import { ItemsMultiSelect } from 'components'; import { ItemsMultiSelect } from 'components';
import { usePurchaseByItemsContext } from './PurchasesByItemsProvider'; import {
PurchasesByItemsGeneralPanelProvider,
usePurchaseByItemsGeneralPanelContext,
} from './PurchasesByItemsGeneralPanelProvider';
/**
*
*/
export default function PurchasesByItemsGeneralPanel() {
return (
<PurchasesByItemsGeneralPanelProvider>
<PurchasesByItemsGeneralPanelContent />
</PurchasesByItemsGeneralPanelProvider>
);
}
/** /**
* Purchases by items - Drawer header - General panel. * Purchases by items - Drawer header - General panel.
*/ */
export default function PurchasesByItemsGeneralPanel() { function PurchasesByItemsGeneralPanelContent() {
const { items } = usePurchaseByItemsContext(); const { items } = usePurchaseByItemsGeneralPanelContext();
return ( return (
<div> <div>
@@ -30,13 +44,7 @@ export default function PurchasesByItemsGeneralPanel() {
label={<T id={'Specific items'} />} label={<T id={'Specific items'} />}
className={classNames('form-group--select-list', Classes.FILL)} className={classNames('form-group--select-list', Classes.FILL)}
> >
<ItemsMultiSelect
items={items}
selectedItems={value}
onItemSelect={(itemsIds) => {
setFieldValue('itemsIds', itemsIds);
}}
/>
</FormGroup> </FormGroup>
)} )}
</Field> </Field>

View File

@@ -0,0 +1,40 @@
import React, { createContext, useContext } from 'react';
import { useItems } from '../../../hooks/query';
import { FinancialHeaderLoadingSkeleton } from '../FinancialHeaderLoadingSkeleton';
const PurchasesByItemsGeneralPanelContext = createContext();
function PurchasesByItemsGeneralPanelProvider({ ...props }) {
// Handle fetching the items based on the given query.
const {
data: { items },
isLoading: isItemsLoading,
isFetching: isItemsFetching,
} = useItems({
page_size: 10000,
stringified_filter_roles: JSON.stringify([
{ fieldKey: 'type', comparator: 'is', value: 'inventory', index: 1 },
]),
});
const provider = {
items,
isItemsLoading,
isItemsFetching,
};
const loading = isItemsLoading;
return loading ? (
<FinancialHeaderLoadingSkeleton />
) : (
<PurchasesByItemsGeneralPanelContext.Provider value={provider} {...props} />
);
}
const usePurchaseByItemsGeneralPanelContext = () =>
useContext(PurchasesByItemsGeneralPanelContext);
export {
PurchasesByItemsGeneralPanelProvider,
usePurchaseByItemsGeneralPanelContext,
};

View File

@@ -1,6 +1,6 @@
import React, { createContext, useContext } from 'react'; import React, { createContext, useContext } from 'react';
import FinancialReportPage from '../FinancialReportPage'; import FinancialReportPage from '../FinancialReportPage';
import { usePurchasesByItems, useItems } from 'hooks/query'; import { usePurchasesByItems } from 'hooks/query';
import { transformFilterFormToQuery } from '../common'; import { transformFilterFormToQuery } from '../common';
const PurchasesByItemsContext = createContext(); const PurchasesByItemsContext = createContext();
@@ -21,27 +21,11 @@ function PurchasesByItemsProvider({ query, ...props }) {
}, },
); );
// Handle fetching the items based on the given query.
const {
data: { items },
isLoading: isItemsLoading,
isFetching: isItemsFetching,
} = useItems({
page_size: 10000,
stringified_filter_roles: JSON.stringify([
{ fieldKey: 'type', comparator: 'is', value: 'inventory', index: 1 },
]),
});
const provider = { const provider = {
purchaseByItems, purchaseByItems,
isFetching, isFetching,
isLoading, isLoading,
items,
isItemsLoading,
isItemsFetching,
refetchSheet: refetch, refetchSheet: refetch,
}; };
return ( return (

View File

@@ -20,27 +20,10 @@ function SalesByItemProvider({ query, ...props }) {
}, },
); );
// Handle fetching the items based on the given query.
const {
data: { items },
isLoading: isItemsLoading,
isFetching: isItemsFetching,
} = useItems({
page_size: 10000,
stringified_filter_roles: JSON.stringify([
{ fieldKey: 'type', comparator: 'is', value: 'inventory', index: 1 },
]),
});
const provider = { const provider = {
salesByItems, salesByItems,
isFetching, isFetching,
isLoading, isLoading,
items,
isItemsLoading,
isItemsFetching,
refetchSheet: refetch, refetchSheet: refetch,
}; };
return ( return (

View File

@@ -67,6 +67,7 @@ function SalesByItems({
onNumberFormatSubmit={handleNumberFormatSubmit} onNumberFormatSubmit={handleNumberFormatSubmit}
/> />
<SalesByItemsLoadingBar /> <SalesByItemsLoadingBar />
<DashboardPageContent> <DashboardPageContent>
<div class="financial-statement financial-statement--sales-by-items"> <div class="financial-statement financial-statement--sales-by-items">
<SalesByItemsHeader <SalesByItemsHeader

View File

@@ -2,15 +2,30 @@ import React from 'react';
import { FormGroup, Classes } from '@blueprintjs/core'; import { FormGroup, Classes } from '@blueprintjs/core';
import { Field } from 'formik'; import { Field } from 'formik';
import classNames from 'classnames'; import classNames from 'classnames';
import { Row, Col, ItemsMultiSelect, FormattedMessage as T } from 'components'; import { Row, Col, ItemsMultiSelect, FormattedMessage as T } from 'components';
import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange'; import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
import { useSalesByItemsContext } from './SalesByItemProvider'; import {
SalesByItemGeneralPanelProvider,
useSalesByItemsGeneralPanelContext,
} from './SalesByItemsHeaderGeneralPanelProvider';
/** /**
* sells by items - Drawer header - General panel. * Sales by items - Drawer header - General panel.
*/ */
export default function SalesByItemsHeaderGeneralPanel() { export default function SalesByItemsHeaderGeneralPanel() {
const { items } = useSalesByItemsContext(); return (
<SalesByItemGeneralPanelProvider>
<SalesByItemsHeaderGeneralPanelContent />
</SalesByItemGeneralPanelProvider>
);
}
/**
* Sales by items - Drawer header - General panel - Content.
*/
function SalesByItemsHeaderGeneralPanelContent() {
const { items } = useSalesByItemsGeneralPanelContext();
return ( return (
<div> <div>

View File

@@ -0,0 +1,40 @@
import React, { createContext, useContext } from 'react';
import { useItems } from 'hooks/query';
import { FinancialHeaderLoadingSkeleton } from '../FinancialHeaderLoadingSkeleton';
const SalesByItemGeneralPanelContext = createContext();
/**
* Sales by items - General panel - Booting.
*/
function SalesByItemGeneralPanelProvider({ query, ...props }) {
// Handle fetching the items based on the given query.
const {
data: { items },
isLoading: isItemsLoading,
isFetching: isItemsFetching,
} = useItems({
page_size: 10000,
stringified_filter_roles: JSON.stringify([
{ fieldKey: 'type', comparator: 'is', value: 'inventory', index: 1 },
]),
});
const provider = {
items,
isItemsLoading,
isItemsFetching,
};
const loading = isItemsLoading;
return loading ? (
<FinancialHeaderLoadingSkeleton />
) : (
<SalesByItemGeneralPanelContext.Provider value={provider} {...props} />
);
}
const useSalesByItemsGeneralPanelContext = () =>
useContext(SalesByItemGeneralPanelContext);
export { SalesByItemGeneralPanelProvider, useSalesByItemsGeneralPanelContext };

View File

@@ -1,94 +1,14 @@
import React from 'react'; import React from 'react';
import { Field, FastField } from 'formik'; import VendorsBalanceSummaryHeaderGeneralContent from './VendorsBalanceSummaryHeaderGeneralContent';
import { DateInput } from '@blueprintjs/datetime'; import { VendorsBalanceSummaryGeneralPanelProvider } from './VendorsBalanceSummaryHeaderGeneralProvider';
import classNames from 'classnames';
import { FormGroup, Position, Classes, Checkbox } from '@blueprintjs/core';
import { ContactsMultiSelect, FormattedMessage as T } from 'components';
import { Row, Col, FieldHint } from 'components';
import {
momentFormatter,
tansformDateValue,
inputIntent,
handleDateChange,
} from 'utils';
import { useVendorsBalanceSummaryContext } from './VendorsBalanceSummaryProvider';
/** /**
* Vendors balance header -general panel. * Vendors balance header - General panel.
*/ */
export default function VendorsBalanceSummaryHeaderGeneral() { export default function VendorsBalanceSummaryHeaderGeneral() {
const { vendors } = useVendorsBalanceSummaryContext();
return ( return (
<div> <VendorsBalanceSummaryGeneralPanelProvider>
<Row> <VendorsBalanceSummaryHeaderGeneralContent />
<Col xs={5}> </VendorsBalanceSummaryGeneralPanelProvider>
<FastField name={'asDate'}>
{({ form, field: { value }, meta: { error } }) => (
<FormGroup
label={<T id={'as_date'} />}
labelInfo={<FieldHint />}
fill={true}
intent={inputIntent({ error })}
>
<DateInput
{...momentFormatter('YYYY/MM/DD')}
value={tansformDateValue(value)}
onChange={handleDateChange((selectedDate) => {
form.setFieldValue('asDate', selectedDate);
})}
popoverProps={{ position: Position.BOTTOM, minimal: true }}
minimal={true}
fill={true}
/>
</FormGroup>
)}
</FastField>
</Col>
</Row>
<Row>
<Col xs={5}>
<FastField name={'percentage'} type={'checkbox'}>
{({ field }) => (
<FormGroup labelInfo={<FieldHint />}>
<Checkbox
inline={true}
small={true}
label={<T id={'percentage_of_column'} />}
name={'percentage'}
{...field}
/>
</FormGroup>
)}
</FastField>
</Col>
</Row>
<Row>
<Col xs={4}>
<Field name={'vendorsIds'}>
{({
form: { setFieldValue },
field: { value },
meta: { error, touched },
}) => (
<FormGroup
label={<T id={'specific_vendors'} />}
className={classNames('form-group--select-list', Classes.FILL)}
>
<ContactsMultiSelect
onContactSelect={(contactsIds) => {
setFieldValue('vendorsIds', contactsIds);
}}
contacts={vendors}
contactsSelected={value}
/>
</FormGroup>
)}
</Field>
</Col>
</Row>
</div>
); );
} }

View File

@@ -0,0 +1,86 @@
import React from 'react';
import { Field, FastField } from 'formik';
import { DateInput } from '@blueprintjs/datetime';
import classNames from 'classnames';
import { FormGroup, Position, Classes, Checkbox } from '@blueprintjs/core';
import { Row, Col, FieldHint, FormattedMessage as T } from 'components';
import {
momentFormatter,
tansformDateValue,
inputIntent,
handleDateChange,
} from 'utils';
import { useVendorsBalanceSummaryGeneralPanelContext } from './VendorsBalanceSummaryHeaderGeneralProvider';
/**
* Vendors balance header - General panel - Content.
*/
export default function VendorsBalanceSummaryHeaderGeneralContent() {
const { vendors } = useVendorsBalanceSummaryGeneralPanelContext();
return (
<div>
<Row>
<Col xs={5}>
<FastField name={'asDate'}>
{({ form, field: { value }, meta: { error } }) => (
<FormGroup
label={<T id={'as_date'} />}
labelInfo={<FieldHint />}
fill={true}
intent={inputIntent({ error })}
>
<DateInput
{...momentFormatter('YYYY/MM/DD')}
value={tansformDateValue(value)}
onChange={handleDateChange((selectedDate) => {
form.setFieldValue('asDate', selectedDate);
})}
popoverProps={{ position: Position.BOTTOM, minimal: true }}
minimal={true}
fill={true}
/>
</FormGroup>
)}
</FastField>
</Col>
</Row>
<Row>
<Col xs={5}>
<FastField name={'percentage'} type={'checkbox'}>
{({ field }) => (
<FormGroup labelInfo={<FieldHint />}>
<Checkbox
inline={true}
small={true}
label={<T id={'percentage_of_column'} />}
name={'percentage'}
{...field}
/>
</FormGroup>
)}
</FastField>
</Col>
</Row>
<Row>
<Col xs={4}>
<Field name={'vendorsIds'}>
{({
form: { setFieldValue },
field: { value },
meta: { error, touched },
}) => (
<FormGroup
label={<T id={'specific_vendors'} />}
className={classNames('form-group--select-list', Classes.FILL)}
></FormGroup>
)}
</Field>
</Col>
</Row>
</div>
);
}

View File

@@ -0,0 +1,44 @@
import React from 'react';
import { FinancialHeaderLoadingSkeleton } from '../FinancialHeaderLoadingSkeleton';
import { useVendors } from '../../../hooks/query';
const VendorsBalanceSummaryGeneralPanelContext = React.createContext();
/**
* Vendors balance summary provider.
*/
function VendorsBalanceSummaryGeneralPanelProvider({ filter, ...props }) {
// Fetch vendors list with pagination meta.
const {
data: { vendors },
isLoading: isVendorsLoading,
isFetching: isVendorsFetching,
} = useVendors({ page_size: 1000000 });
// Provider.
const provider = {
vendors,
isVendorsFetching,
isVendorsLoading,
};
const loading = isVendorsLoading;
return loading ? (
<FinancialHeaderLoadingSkeleton />
) : (
<VendorsBalanceSummaryGeneralPanelContext.Provider
value={provider}
{...props}
/>
);
}
const useVendorsBalanceSummaryGeneralPanelContext = () =>
React.useContext(VendorsBalanceSummaryGeneralPanelContext);
export {
VendorsBalanceSummaryGeneralPanelProvider,
useVendorsBalanceSummaryGeneralPanelContext,
};

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import FinancialReportPage from '../FinancialReportPage'; import FinancialReportPage from '../FinancialReportPage';
import { useVendorsBalanceSummaryReport, useVendors } from 'hooks/query'; import { useVendorsBalanceSummaryReport } from 'hooks/query';
import { transformFilterFormToQuery } from '../common'; import { transformFilterFormToQuery } from '../common';
const VendorsBalanceSummaryContext = React.createContext(); const VendorsBalanceSummaryContext = React.createContext();
@@ -23,23 +23,12 @@ function VendorsBalanceSummaryProvider({ filter, ...props }) {
keepPreviousData: true, keepPreviousData: true,
}); });
// Fetch vendors list with pagination meta.
const {
data: { vendors },
isLoading: isVendorsLoading,
isFetching: isVendorsFetching,
} = useVendors({ page_size: 1000000 });
// Provider. // Provider.
const provider = { const provider = {
VendorBalanceSummary, VendorBalanceSummary,
isVendorsBalanceLoading, isVendorsBalanceLoading,
isVendorsBalanceFetching, isVendorsBalanceFetching,
vendors,
isVendorsFetching,
isVendorsLoading,
refetch, refetch,
}; };

View File

@@ -2,16 +2,35 @@ import React from 'react';
import { Field } from 'formik'; import { Field } from 'formik';
import classNames from 'classnames'; import classNames from 'classnames';
import { Classes, FormGroup } from '@blueprintjs/core'; import { Classes, FormGroup } from '@blueprintjs/core';
import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
import { Row, Col } from 'components'; import FinancialStatementDateRange from '../FinancialStatementDateRange';
import { ContactsMultiSelect, FormattedMessage as T } from 'components'; import {
import { useVendorsTransactionsContext } from './VendorsTransactionsProvider'; Row,
Col,
ContactsMultiSelect,
FormattedMessage as T,
} from 'components';
import {
VendorsTransactionsGeneralPanelProvider,
useVendorsTransactionsGeneralPanelContext,
} from './VendorsTransactionsHeaderGeneralPanelProvider';
/** /**
* Vendors transactions header - General panel. * Vendors transactions header - General panel
*/ */
export default function VendorsTransactionsHeaderGeneralPanel() { export default function VendorsTransactionsHeaderGeneralPanel() {
const { vendors } = useVendorsTransactionsContext(); return (
<VendorsTransactionsGeneralPanelProvider>
<VendorsTransactionsHeaderGeneralPanelContent />
</VendorsTransactionsGeneralPanelProvider>
);
}
/**
* Vendors transactions header - General panel - Content.
*/
function VendorsTransactionsHeaderGeneralPanelContent() {
const { vendors } = useVendorsTransactionsGeneralPanelContext();
return ( return (
<div> <div>

View File

@@ -0,0 +1,42 @@
import React, { createContext, useContext } from 'react';
import { useVendors } from 'hooks/query';
import { FinancialHeaderLoadingSkeleton } from '../FinancialHeaderLoadingSkeleton';
const VendorsTransactionsGeneralPanelContext = createContext();
/**
* Vendors transactions provider.
*/
function VendorsTransactionsGeneralPanelProvider({ ...props }) {
// Fetch vendors list based on the given query.
const {
data: { vendors },
isLoading: isVendorsLoading,
isFetching: isVendorsFetching,
} = useVendors({ page_size: 100000 });
const provider = {
vendors,
isVendorsLoading,
isVendorsFetching,
};
const loading = isVendorsLoading;
return loading ? (
<FinancialHeaderLoadingSkeleton />
) : (
<VendorsTransactionsGeneralPanelContext.Provider
value={provider}
{...props}
/>
);
}
const useVendorsTransactionsGeneralPanelContext = () =>
useContext(VendorsTransactionsGeneralPanelContext);
export {
VendorsTransactionsGeneralPanelProvider,
useVendorsTransactionsGeneralPanelContext,
};

View File

@@ -1,6 +1,6 @@
import React, { createContext, useContext, useMemo } from 'react'; import React, { createContext, useContext, useMemo } from 'react';
import FinancialReportPage from '../FinancialReportPage'; import FinancialReportPage from '../FinancialReportPage';
import { useVendorsTransactionsReport, useVendors } from 'hooks/query'; import { useVendorsTransactionsReport } from 'hooks/query';
import { transformFilterFormToQuery } from '../common'; import { transformFilterFormToQuery } from '../common';
const VendorsTransactionsContext = createContext(); const VendorsTransactionsContext = createContext();
@@ -19,22 +19,11 @@ function VendorsTransactionsProvider({ filter, ...props }) {
refetch, refetch,
} = useVendorsTransactionsReport(query, { keepPreviousData: true }); } = useVendorsTransactionsReport(query, { keepPreviousData: true });
// Fetch vendors list based on the given query.
const {
data: { vendors },
isLoading: isVendorsLoading,
isFetching: isVendorsFetching,
} = useVendors({ page_size: 100000 });
const provider = { const provider = {
vendorsTransactions, vendorsTransactions,
isVendorsTransactionsLoading, isVendorsTransactionsLoading,
isVendorsTransactionFetching, isVendorsTransactionFetching,
vendors,
isVendorsLoading,
isVendorsFetching,
refetch, refetch,
filter, filter,
query, query,

View File

@@ -25,6 +25,7 @@
max-height: 550px; max-height: 550px;
height: 100%; height: 100%;
padding-bottom: 49px; padding-bottom: 49px;
background-color: #fff;
> form { > form {
display: flex; display: flex;