mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 21:00:31 +00:00
feat: adjustments.
This commit is contained in:
@@ -1,21 +1,23 @@
|
||||
import React from 'react';
|
||||
import { FastField, ErrorMessage } from 'formik';
|
||||
import { FormGroup, InputGroup } from '@blueprintjs/core';
|
||||
import { Row, Col, FieldRequiredHint } from 'components';
|
||||
import { sumBy, subtract, add } from 'lodash';
|
||||
import { FastField, ErrorMessage, useFormikContext } from 'formik';
|
||||
import { FormGroup, InputGroup, Intent } from '@blueprintjs/core';
|
||||
import { inputIntent } from 'utils';
|
||||
import { Row, Col, If, FieldRequiredHint } from 'components';
|
||||
import { FormattedMessage as T } from 'react-intl';
|
||||
import { calculate } from './utils';
|
||||
|
||||
function DecrementAdjustmentFields() {
|
||||
return (
|
||||
<Row>
|
||||
{/*------------ Quantity on hand -----------*/}
|
||||
<Col sm={3}>
|
||||
<FastField name={'quantity'}>
|
||||
<FastField name={'quantity_on_hand'}>
|
||||
{({ field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'qty_on_hand'} />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="quantity" />}
|
||||
helperText={<ErrorMessage name="quantity_on_hand" />}
|
||||
>
|
||||
<InputGroup disabled={true} medium={'true'} {...field} />
|
||||
</FormGroup>
|
||||
@@ -24,15 +26,24 @@ function DecrementAdjustmentFields() {
|
||||
</Col>
|
||||
{/*------------ Decrement -----------*/}
|
||||
<Col sm={2}>
|
||||
<FastField name={'decrement'}>
|
||||
{({ field, meta: { error, touched } }) => (
|
||||
<FastField name={'quantity'}>
|
||||
{({
|
||||
form: { values, setFieldValue },
|
||||
field,
|
||||
meta: { error, touched },
|
||||
}) => (
|
||||
<FormGroup
|
||||
label={<T id={'decrement'} />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="decrement" />}
|
||||
helperText={<ErrorMessage name="quantity" />}
|
||||
fill={true}
|
||||
>
|
||||
<InputGroup medium={'true'} {...field} />
|
||||
<InputGroup
|
||||
{...field}
|
||||
onBlur={(event) => {
|
||||
setFieldValue('new_quantity', calculate(values, field.value));
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
@@ -40,13 +51,26 @@ function DecrementAdjustmentFields() {
|
||||
{/*------------ New quantity -----------*/}
|
||||
<Col sm={4}>
|
||||
<FastField name={'new_quantity'}>
|
||||
{({ field, meta: { error, touched } }) => (
|
||||
{({
|
||||
form: { values, setFieldValue },
|
||||
field,
|
||||
meta: { error, touched },
|
||||
}) => (
|
||||
<FormGroup
|
||||
label={<T id={'new_quantity'} />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="new_quantity" />}
|
||||
>
|
||||
<InputGroup medium={'true'} {...field} />
|
||||
<InputGroup
|
||||
medium={'true'}
|
||||
{...field}
|
||||
onBlur={(event) => {
|
||||
setFieldValue(
|
||||
'quantity',
|
||||
subtract(field.value, values.quantity_on_hand),
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
|
||||
@@ -1,21 +1,23 @@
|
||||
import React from 'react';
|
||||
import { FastField, ErrorMessage } from 'formik';
|
||||
import { FastField, ErrorMessage, useFormikContext } from 'formik';
|
||||
import { add, sumBy, subtract } from 'lodash';
|
||||
import { FormGroup, InputGroup, Intent } from '@blueprintjs/core';
|
||||
import { Row, Col, FieldRequiredHint } from 'components';
|
||||
import { inputIntent } from 'utils';
|
||||
import { FormattedMessage as T } from 'react-intl';
|
||||
import { calculate } from './utils';
|
||||
|
||||
function IncrementAdjustmentFields() {
|
||||
return (
|
||||
<Row>
|
||||
{/*------------ Quantity on hand -----------*/}
|
||||
<Col sm={3}>
|
||||
<FastField name={'quantity'}>
|
||||
<FastField name={'quantity_on_hand'}>
|
||||
{({ field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'qty_on_hand'} />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="quantity" />}
|
||||
helperText={<ErrorMessage name="quantity_on_hand" />}
|
||||
>
|
||||
<InputGroup disabled={true} medium={'true'} {...field} />
|
||||
</FormGroup>
|
||||
@@ -24,15 +26,28 @@ function IncrementAdjustmentFields() {
|
||||
</Col>
|
||||
{/*------------ Increment -----------*/}
|
||||
<Col sm={2}>
|
||||
<FastField name={'increment'}>
|
||||
{({ field, meta: { error, touched } }) => (
|
||||
<FastField name={'quantity'}>
|
||||
{({
|
||||
form: { values, setFieldValue },
|
||||
field,
|
||||
meta: { error, touched },
|
||||
}) => (
|
||||
<FormGroup
|
||||
label={<T id={'increment'} />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="increment" />}
|
||||
helperText={<ErrorMessage name="quantity" />}
|
||||
fill={true}
|
||||
>
|
||||
<InputGroup medium={'true'} {...field} />
|
||||
<InputGroup
|
||||
medium={'true'}
|
||||
{...field}
|
||||
onBlur={(event) => {
|
||||
setFieldValue(
|
||||
'new_quantity',
|
||||
calculate(values, event.currentTarget.value),
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
@@ -54,13 +69,26 @@ function IncrementAdjustmentFields() {
|
||||
{/*------------ New quantity -----------*/}
|
||||
<Col sm={4}>
|
||||
<FastField name={'new_quantity'}>
|
||||
{({ field, meta: { error, touched } }) => (
|
||||
{({
|
||||
form: { values, setFieldValue },
|
||||
field,
|
||||
meta: { error, touched },
|
||||
}) => (
|
||||
<FormGroup
|
||||
label={<T id={'new_quantity'} />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="new_quantity" />}
|
||||
>
|
||||
<InputGroup medium={'true'} {...field} />
|
||||
<InputGroup
|
||||
medium={'true'}
|
||||
{...field}
|
||||
onBlur={(event) => {
|
||||
setFieldValue(
|
||||
'quantity',
|
||||
subtract(field.value, values.quantity_on_hand),
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import React from 'react';
|
||||
import { Intent, Button, Classes } from '@blueprintjs/core';
|
||||
import { useFormikContext } from 'formik';
|
||||
import { FormattedMessage as T } from 'react-intl';
|
||||
import { saveInvoke } from 'utils';
|
||||
|
||||
export default function InventoryAdjustmentFloatingActions({
|
||||
onCloseClick,
|
||||
onSubmitClick,
|
||||
}) {
|
||||
const { isSubmitting } = useFormikContext();
|
||||
|
||||
const handleSubmitDraftBtnClick = (event) => {
|
||||
saveInvoke(onSubmitClick, event, {
|
||||
publish: false,
|
||||
});
|
||||
};
|
||||
const handleSubmitMakeAdjustmentBtnClick = (event) => {
|
||||
saveInvoke(onSubmitClick, event, {
|
||||
publish: true,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={Classes.DIALOG_FOOTER}>
|
||||
<div className={Classes.DIALOG_FOOTER_ACTIONS}>
|
||||
<Button onClick={onCloseClick} style={{ minWidth: '75px' }}>
|
||||
<T id={'close'} />
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
disabled={isSubmitting}
|
||||
style={{ minWidth: '75px' }}
|
||||
type="submit"
|
||||
onClick={handleSubmitDraftBtnClick}
|
||||
>
|
||||
{<T id={'save_as_draft'} />}
|
||||
</Button>
|
||||
<Button
|
||||
intent={Intent.PRIMARY}
|
||||
disabled={isSubmitting}
|
||||
style={{ minWidth: '75px' }}
|
||||
type="submit"
|
||||
onClick={handleSubmitMakeAdjustmentBtnClick}
|
||||
>
|
||||
{<T id={'make_adjustment'} />}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -6,22 +6,25 @@ const Schema = Yup.object().shape({
|
||||
date: Yup.date()
|
||||
.required()
|
||||
.label(formatMessage({ id: 'date' })),
|
||||
type: Yup.number().required(),
|
||||
adjustment_account_id: Yup.number().required(),
|
||||
type: Yup.string().required(),
|
||||
adjustment_account_id: Yup.string().required(),
|
||||
item_id: Yup.number().required(),
|
||||
reason: Yup.string()
|
||||
.required()
|
||||
.label(formatMessage({ id: 'reason' })),
|
||||
quantity: Yup.number().when(['type'], {
|
||||
is: (type) => type,
|
||||
then: Yup.number().required(),
|
||||
}),
|
||||
quantity_on_hand: Yup.number()
|
||||
.min(0)
|
||||
.required()
|
||||
.label(formatMessage({ id: 'qty' })),
|
||||
quantity: Yup.number().integer().max(Yup.ref('quantity_on_hand')).required(),
|
||||
cost: Yup.number().when(['type'], {
|
||||
is: (type) => type,
|
||||
then: Yup.number().required(),
|
||||
then: Yup.number(),
|
||||
}),
|
||||
reference_no: Yup.string(),
|
||||
new_quantity: Yup.number(),
|
||||
new_quantity: Yup.number().min(Yup.ref('quantity')).required(),
|
||||
description: Yup.string().min(3).max(DATATYPES_LENGTH.TEXT).nullable().trim(),
|
||||
publish: Yup.boolean(),
|
||||
});
|
||||
|
||||
export const CreateInventoryAdjustmentFormSchema = Schema;
|
||||
|
||||
@@ -1,33 +1,31 @@
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import React, { useState, useCallback, useMemo } from 'react';
|
||||
import { Intent } from '@blueprintjs/core';
|
||||
import { Formik } from 'formik';
|
||||
import { Formik, Form } from 'formik';
|
||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||
import { useQuery, queryCache } from 'react-query';
|
||||
import moment from 'moment';
|
||||
import { omit } from 'lodash';
|
||||
|
||||
import {
|
||||
AppToaster,
|
||||
DialogContent,
|
||||
Row,
|
||||
Col,
|
||||
ListSelect,
|
||||
IF,
|
||||
} from 'components';
|
||||
import { AppToaster, DialogContent } from 'components';
|
||||
import { CreateInventoryAdjustmentFormSchema } from './InventoryAdjustmentForm.schema';
|
||||
import InventoryAdjustmentFormDialogFields from './InventoryAdjustmentFormDialogFields';
|
||||
|
||||
import InventoryAdjustmentFloatingActions from './InventoryAdjustmentFloatingActions';
|
||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||
|
||||
import withInventoryAdjustmentActions from 'containers/Items/withInventoryAdjustmentActions';
|
||||
import { compose } from 'utils';
|
||||
|
||||
const defaultInitialValues = {
|
||||
date: moment(new Date()).format('YYYY-MM-DD'),
|
||||
type: 'decrement',
|
||||
adjustment_account_id: '',
|
||||
item_id: '',
|
||||
reason: '',
|
||||
cost: '',
|
||||
quantity: '',
|
||||
reference_no: '',
|
||||
quantity_on_hand: '',
|
||||
description: '',
|
||||
publish: '',
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -40,31 +38,38 @@ function InventoryAdjustmentFormDialogContent({
|
||||
// #withAccountsActions
|
||||
requestFetchAccounts,
|
||||
|
||||
// #withInventoryAdjustmentActions
|
||||
requestSubmitInventoryAdjustment,
|
||||
|
||||
// #ownProp
|
||||
itemDetail,
|
||||
dialogName,
|
||||
action,
|
||||
}) {
|
||||
const { formatMessage } = useIntl();
|
||||
const [submitPayload, setSubmitPayload] = useState({});
|
||||
|
||||
// Fetches accounts list.
|
||||
const fetchAccountsList = useQuery('accounts-list', () =>
|
||||
requestFetchAccounts(),
|
||||
);
|
||||
const fetchAccount = useQuery('accounts-list', () => requestFetchAccounts());
|
||||
|
||||
const initialValues = useMemo(
|
||||
() => ({
|
||||
...defaultInitialValues,
|
||||
...itemDetail,
|
||||
}),
|
||||
[],
|
||||
);
|
||||
|
||||
// Handles the form submit.
|
||||
const handleFormSubmit = (values, { setSubmitting, setErrors }) => {
|
||||
const form = { ...values };
|
||||
const form = {
|
||||
...omit(values, ['quantity_on_hand', 'new_quantity', 'action']),
|
||||
publish: submitPayload.publish,
|
||||
};
|
||||
|
||||
const onSuccess = ({ response }) => {
|
||||
closeDialog(dialogName);
|
||||
queryCache.invalidateQueries('accounts-list');
|
||||
queryCache.invalidateQueries('items-table');
|
||||
|
||||
AppToaster.show({
|
||||
message: formatMessage({
|
||||
@@ -76,14 +81,21 @@ function InventoryAdjustmentFormDialogContent({
|
||||
const onError = (error) => {
|
||||
setSubmitting(false);
|
||||
};
|
||||
//requestInventoryAdjustment
|
||||
requestSubmitInventoryAdjustment({ form }).then(onSuccess).catch(onError);
|
||||
};
|
||||
|
||||
// Handles dialog close.
|
||||
const handleClose = useCallback(() => {
|
||||
const handleCloseClick = useCallback(() => {
|
||||
closeDialog(dialogName);
|
||||
}, [closeDialog, dialogName]);
|
||||
|
||||
const handleSubmitClick = useCallback(
|
||||
(event, payload) => {
|
||||
setSubmitPayload({ ...payload });
|
||||
},
|
||||
[setSubmitPayload],
|
||||
);
|
||||
|
||||
return (
|
||||
<DialogContent>
|
||||
<Formik
|
||||
@@ -91,13 +103,19 @@ function InventoryAdjustmentFormDialogContent({
|
||||
initialValues={initialValues}
|
||||
onSubmit={handleFormSubmit}
|
||||
>
|
||||
<InventoryAdjustmentFormDialogFields
|
||||
dialogName={dialogName}
|
||||
onClose={handleClose}
|
||||
/>
|
||||
<Form>
|
||||
<InventoryAdjustmentFormDialogFields dialogName={dialogName} />
|
||||
<InventoryAdjustmentFloatingActions
|
||||
onSubmitClick={handleSubmitClick}
|
||||
onCloseClick={handleCloseClick}
|
||||
/>
|
||||
</Form>
|
||||
</Formik>
|
||||
</DialogContent>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(withDialogActions)(InventoryAdjustmentFormDialogContent);
|
||||
export default compose(
|
||||
withInventoryAdjustmentActions,
|
||||
withDialogActions,
|
||||
)(InventoryAdjustmentFormDialogContent);
|
||||
|
||||
@@ -1,24 +1,16 @@
|
||||
import React from 'react';
|
||||
import { FastField, ErrorMessage, useFormikContext } from 'formik';
|
||||
import {
|
||||
Form,
|
||||
FastField,
|
||||
ErrorMessage,
|
||||
useFormikContext,
|
||||
useField,
|
||||
} from 'formik';
|
||||
import {
|
||||
Button,
|
||||
Classes,
|
||||
FormGroup,
|
||||
InputGroup,
|
||||
Intent,
|
||||
TextArea,
|
||||
Position,
|
||||
} from '@blueprintjs/core';
|
||||
import classNames from 'classnames';
|
||||
import { FormattedMessage as T } from 'react-intl';
|
||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import { ListSelect, Choose, If, FieldRequiredHint } from 'components';
|
||||
import { ListSelect, Choose, FieldRequiredHint } from 'components';
|
||||
import {
|
||||
inputIntent,
|
||||
momentFormatter,
|
||||
@@ -30,7 +22,6 @@ import adjustmentType from 'common/adjustmentType';
|
||||
import IncrementAdjustmentFields from './IncrementAdjustmentFields';
|
||||
import DecrementAdjustmentFields from './DecrementAdjustmentFields';
|
||||
import AccountsSuggestField from 'components/AccountsSuggestField';
|
||||
|
||||
import withAccounts from 'containers/Accounts/withAccounts';
|
||||
import { compose } from 'redux';
|
||||
|
||||
@@ -38,158 +29,135 @@ import { compose } from 'redux';
|
||||
* Inventory adjustment form dialogs fields.
|
||||
*/
|
||||
function InventoryAdjustmentFormDialogFields({
|
||||
// #ownProps
|
||||
onClose,
|
||||
|
||||
//# withAccount
|
||||
accountsList,
|
||||
}) {
|
||||
const { values, isSubmitting } = useFormikContext();
|
||||
|
||||
const { values } = useFormikContext();
|
||||
const { formatMessage } = useIntl();
|
||||
// console.log(values, 'EE');
|
||||
return (
|
||||
<Form>
|
||||
<div className={Classes.DIALOG_BODY}>
|
||||
{/*------------ Date -----------*/}
|
||||
<FastField name={'date'}>
|
||||
{({ form, field: { value }, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'date'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="date" />}
|
||||
minimal={true}
|
||||
className={classNames(CLASSES.FILL)}
|
||||
>
|
||||
<DateInput
|
||||
{...momentFormatter('YYYY/MM/DD')}
|
||||
onChange={handleDateChange((formattedDate) => {
|
||||
form.setFieldValue('date', formattedDate);
|
||||
})}
|
||||
value={tansformDateValue(value)}
|
||||
popoverProps={{
|
||||
position: Position.BOTTOM,
|
||||
minimal: true,
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
|
||||
{/*------------ Adjustment type -----------*/}
|
||||
<FastField name={'type'}>
|
||||
{({ form, field: { value }, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'adjustment_type'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
helperText={<ErrorMessage name="type" />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
className={classNames(CLASSES.FILL)}
|
||||
>
|
||||
<ListSelect
|
||||
items={adjustmentType}
|
||||
onItemSelect={(type) => {
|
||||
console.log(type.value, 'EE');
|
||||
form.setFieldValue('type', type.value);
|
||||
}}
|
||||
selectedItem={value}
|
||||
selectedItemProp={'value'}
|
||||
labelProp={'name'}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
<Choose>
|
||||
<Choose.When condition={values.type === 'decrement'}>
|
||||
<DecrementAdjustmentFields />
|
||||
</Choose.When>
|
||||
<Choose.When condition={values.type === 'increment'}>
|
||||
<IncrementAdjustmentFields />
|
||||
</Choose.When>
|
||||
</Choose>
|
||||
|
||||
{/*------------ Reason -----------*/}
|
||||
<FastField name={'reason'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'reason'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="reason" />}
|
||||
>
|
||||
<InputGroup fill={true} {...field} />
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
{/*------------ Adjustment account -----------*/}
|
||||
<FastField name={'adjustment_account_id'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'adjustment_account'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="reason" />}
|
||||
>
|
||||
<AccountsSuggestField
|
||||
accounts={accountsList}
|
||||
onAccountSelected={(item) =>
|
||||
form.setFieldValue('adjustment_account_id', item)
|
||||
}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
{/*------------ Reference -----------*/}
|
||||
<FastField name={'reference_no'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'reference_no'} />}
|
||||
className={classNames(CLASSES.FILL)}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="reference_no" />}
|
||||
>
|
||||
<InputGroup {...field} />
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
{/*------------ description -----------*/}
|
||||
<FastField name={'description'}>
|
||||
{({ field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'description'} />}
|
||||
className={'form-group--description'}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name={'description'} />}
|
||||
>
|
||||
<TextArea growVertically={true} large={true} {...field} />
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
</div>
|
||||
<div className={Classes.DIALOG_FOOTER}>
|
||||
<div className={Classes.DIALOG_FOOTER_ACTIONS}>
|
||||
<Button onClick={onClose} style={{ minWidth: '75px' }}>
|
||||
<T id={'close'} />
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
disabled={isSubmitting}
|
||||
style={{ minWidth: '75px' }}
|
||||
type="submit"
|
||||
<div className={Classes.DIALOG_BODY}>
|
||||
{/*------------ Date -----------*/}
|
||||
<FastField name={'date'}>
|
||||
{({ form, field: { value }, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'date'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="date" />}
|
||||
minimal={true}
|
||||
className={classNames(CLASSES.FILL)}
|
||||
>
|
||||
{<T id={'save_as_draft'} />}
|
||||
</Button>
|
||||
<Button
|
||||
intent={Intent.PRIMARY}
|
||||
disabled={isSubmitting}
|
||||
style={{ minWidth: '75px' }}
|
||||
type="submit"
|
||||
<DateInput
|
||||
{...momentFormatter('YYYY/MM/DD')}
|
||||
onChange={handleDateChange((formattedDate) => {
|
||||
form.setFieldValue('date', formattedDate);
|
||||
})}
|
||||
value={tansformDateValue(value)}
|
||||
popoverProps={{
|
||||
position: Position.BOTTOM,
|
||||
minimal: true,
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
|
||||
{/*------------ Adjustment type -----------*/}
|
||||
<FastField name={'type'}>
|
||||
{({ form, field: { value }, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'adjustment_type'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
helperText={<ErrorMessage name="type" />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
className={classNames(CLASSES.FILL)}
|
||||
>
|
||||
{<T id={'make_adjustment'} />}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
<ListSelect
|
||||
items={adjustmentType}
|
||||
onItemSelect={(type) => {
|
||||
form.setFieldValue('type', type.value);
|
||||
}}
|
||||
filterable={false}
|
||||
selectedItem={value}
|
||||
selectedItemProp={'value'}
|
||||
labelProp={'name'}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
<Choose>
|
||||
<Choose.When condition={values.type === 'decrement'}>
|
||||
<DecrementAdjustmentFields />
|
||||
</Choose.When>
|
||||
<Choose.When condition={values.type === 'increment'}>
|
||||
<IncrementAdjustmentFields />
|
||||
</Choose.When>
|
||||
</Choose>
|
||||
{/*------------ Reason -----------*/}
|
||||
<FastField name={'reason'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'reason'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="reason" />}
|
||||
>
|
||||
<InputGroup fill={true} {...field} />
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
{/*------------ Adjustment account -----------*/}
|
||||
<FastField name={'adjustment_account_id'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'adjustment_account'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="reason" />}
|
||||
>
|
||||
<AccountsSuggestField
|
||||
accounts={accountsList}
|
||||
onAccountSelected={(item) =>
|
||||
form.setFieldValue('adjustment_account_id', item.id)
|
||||
}
|
||||
inputProps={{
|
||||
placeholder: formatMessage({
|
||||
id: 'select_adjustment_account',
|
||||
}),
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
{/*------------ Reference -----------*/}
|
||||
<FastField name={'reference_no'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'reference_no'} />}
|
||||
className={classNames(CLASSES.FILL)}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="reference_no" />}
|
||||
>
|
||||
<InputGroup {...field} />
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
{/*------------ description -----------*/}
|
||||
<FastField name={'description'}>
|
||||
{({ field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'description'} />}
|
||||
className={'form-group--description'}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name={'description'} />}
|
||||
>
|
||||
<TextArea growVertically={true} large={true} {...field} />
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ function InventoryAdjustmentFormDialog({
|
||||
<DialogSuspense>
|
||||
<InventoryAdjustmentFormDialogContent
|
||||
dialogName={dialogName}
|
||||
action={payload.action}
|
||||
itemDetail={payload}
|
||||
/>
|
||||
</DialogSuspense>
|
||||
</Dialog>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { add, sumBy, subtract } from 'lodash';
|
||||
|
||||
export const calculate = ({ type, quantity_on_hand }, operator) => {
|
||||
const qty = parseInt(quantity_on_hand);
|
||||
const quantity = parseInt(operator);
|
||||
|
||||
if (type == 'decrement') {
|
||||
return subtract(qty, quantity);
|
||||
} else {
|
||||
return add(qty, quantity);
|
||||
}
|
||||
};
|
||||
|
||||
// function calculate(qty, operator) {
|
||||
// return operator > 0
|
||||
// ? calculate(qty + 1, operator - 1)
|
||||
// : operator < 0
|
||||
// ? calculate(qty - 1, operator + 1)
|
||||
// : qty;
|
||||
// }
|
||||
@@ -7,38 +7,42 @@ import {
|
||||
MenuItem,
|
||||
MenuDivider,
|
||||
Position,
|
||||
Tag,
|
||||
} from '@blueprintjs/core';
|
||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||
import moment from 'moment';
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
DataTable,
|
||||
If,
|
||||
Money,
|
||||
Choose,
|
||||
Icon,
|
||||
LoadingIndicator,
|
||||
} from 'components';
|
||||
import { DataTable, Icon, LoadingIndicator } from 'components';
|
||||
import { CLASSES } from 'common/classes';
|
||||
import { useIsValuePassed } from 'hooks';
|
||||
|
||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||
// withInventoryAdjustments
|
||||
// withInventoryAdjustmentsActions
|
||||
import withInventoryAdjustments from './withInventoryAdjustments';
|
||||
import withInventoryAdjustmentActions from './withInventoryAdjustmentActions';
|
||||
|
||||
import { compose, saveInvoke } from 'utils';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
|
||||
function InventoryAdjustmentDataTable({
|
||||
// withInventoryAdjustments
|
||||
inventoryAdjustmentItems,
|
||||
inventoryAdjustmentCurrentPage,
|
||||
inventoryAdjustmentLoading,
|
||||
inventoryAdjustmentsPagination,
|
||||
|
||||
// withInventoryAdjustmentsActions
|
||||
addInventoryAdjustmentTableQueries,
|
||||
|
||||
// #ownProps
|
||||
onDeleteInventoryAdjustment,
|
||||
onSelectedRowsChange,
|
||||
}) {
|
||||
const { formatMessage } = useIntl();
|
||||
const isLoadedBefore = useIsValuePassed(inventoryAdjustmentLoading, false);
|
||||
|
||||
const handleDeleteInventoryAdjustment = useCallback(
|
||||
(_inventory) => {
|
||||
saveInvoke(onDeleteInventoryAdjustment, _inventory);
|
||||
(_adjustment) => () => {
|
||||
saveInvoke(onDeleteInventoryAdjustment, _adjustment);
|
||||
},
|
||||
[onDeleteInventoryAdjustment],
|
||||
);
|
||||
@@ -53,9 +57,9 @@ function InventoryAdjustmentDataTable({
|
||||
<MenuDivider />
|
||||
<MenuItem
|
||||
text={formatMessage({ id: 'delete_adjustment' })}
|
||||
icon={<Icon icon="trash-16" iconSize={16} />}
|
||||
intent={Intent.DANGER}
|
||||
onClick={handleDeleteInventoryAdjustment(adjustment)}
|
||||
icon={<Icon icon="trash-16" iconSize={16} />}
|
||||
/>
|
||||
</Menu>
|
||||
),
|
||||
@@ -79,41 +83,53 @@ function InventoryAdjustmentDataTable({
|
||||
{
|
||||
id: 'type',
|
||||
Header: formatMessage({ id: 'type' }),
|
||||
accessor: 'type',
|
||||
accessor: (row) =>
|
||||
row.type ? (
|
||||
<Tag minimal={true} round={true} intent={Intent.NONE}>
|
||||
{formatMessage({ id: row.type })}
|
||||
</Tag>
|
||||
) : (
|
||||
''
|
||||
),
|
||||
className: 'type',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
id: 'reason',
|
||||
Header: formatMessage({ id: 'reason' }),
|
||||
// accessor: (r) => (
|
||||
// <Tooltip
|
||||
// content={}
|
||||
// position={Position.RIGHT_BOTTOM}
|
||||
// >
|
||||
// </Tooltip>
|
||||
// ),
|
||||
accessor: 'reason',
|
||||
className: 'reason',
|
||||
width: 115,
|
||||
},
|
||||
{
|
||||
id: 'reference',
|
||||
Header: formatMessage({ id: 'reference' }),
|
||||
accessor: (row) => `#${row.reference}`,
|
||||
className: 'reference',
|
||||
id: 'reference_no',
|
||||
Header: formatMessage({ id: 'reference_no' }),
|
||||
accessor: 'reference_no',
|
||||
className: 'reference_no',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
id: 'status',
|
||||
id: 'publish',
|
||||
Header: formatMessage({ id: 'status' }),
|
||||
accessor: 'status',
|
||||
accessor: (r) => {
|
||||
return r.is_published ? (
|
||||
<Tag minimal={true}>
|
||||
<T id={'published'} />
|
||||
</Tag>
|
||||
) : (
|
||||
<Tag minimal={true} intent={Intent.WARNING}>
|
||||
<T id={'draft'} />
|
||||
</Tag>
|
||||
);
|
||||
},
|
||||
width: 95,
|
||||
className: 'status',
|
||||
className: 'publish',
|
||||
},
|
||||
|
||||
{
|
||||
id: 'description',
|
||||
Header: formatMessage({ id: 'description' }),
|
||||
accessor: 'description',
|
||||
disableSorting: true,
|
||||
width: 85,
|
||||
className: 'description',
|
||||
@@ -144,6 +160,23 @@ function InventoryAdjustmentDataTable({
|
||||
[actionMenuList, formatMessage],
|
||||
);
|
||||
|
||||
const handleDataTableFetchData = useCallback(
|
||||
({ pageSize, pageIndex, sortBy }) => {
|
||||
addInventoryAdjustmentTableQueries({
|
||||
...(sortBy.length > 0
|
||||
? {
|
||||
column_sort_by: sortBy[0].id,
|
||||
sort_order: sortBy[0].desc ? 'desc' : 'asc',
|
||||
}
|
||||
: {}),
|
||||
page_size: pageSize,
|
||||
page: pageIndex + 1,
|
||||
});
|
||||
},
|
||||
[addInventoryAdjustmentTableQueries],
|
||||
);
|
||||
|
||||
|
||||
const handleSelectedRowsChange = useCallback(
|
||||
(selectedRows) => {
|
||||
saveInvoke(
|
||||
@@ -160,11 +193,23 @@ function InventoryAdjustmentDataTable({
|
||||
|
||||
return (
|
||||
<div className={classNames(CLASSES.DASHBOARD_DATATABLE)}>
|
||||
<LoadingIndicator
|
||||
|
||||
// loading={}
|
||||
>
|
||||
<DataTable noInitialFetch={true} columns={columns} data={[]} />
|
||||
<LoadingIndicator loading={inventoryAdjustmentLoading && !isLoadedBefore}>
|
||||
<DataTable
|
||||
columns={columns}
|
||||
data={inventoryAdjustmentItems}
|
||||
onFetchData={handleDataTableFetchData}
|
||||
manualSortBy={true}
|
||||
selectionColumn={true}
|
||||
noInitialFetch={true}
|
||||
onSelectedRowsChange={handleSelectedRowsChange}
|
||||
rowContextMenu={onRowContextMenu}
|
||||
pagination={true}
|
||||
autoResetSortBy={false}
|
||||
autoResetPage={false}
|
||||
pagesCount={inventoryAdjustmentsPagination.pagesCount}
|
||||
initialPageSize={inventoryAdjustmentsPagination.pageSize}
|
||||
initialPageIndex={inventoryAdjustmentsPagination.page - 1}
|
||||
/>
|
||||
</LoadingIndicator>
|
||||
</div>
|
||||
);
|
||||
@@ -173,4 +218,18 @@ function InventoryAdjustmentDataTable({
|
||||
export default compose(
|
||||
withRouter,
|
||||
withDialogActions,
|
||||
withInventoryAdjustmentActions,
|
||||
withInventoryAdjustments(
|
||||
({
|
||||
inventoryAdjustmentLoading,
|
||||
inventoryAdjustmentItems,
|
||||
inventoryAdjustmentCurrentPage,
|
||||
inventoryAdjustmentsPagination,
|
||||
}) => ({
|
||||
inventoryAdjustmentLoading,
|
||||
inventoryAdjustmentItems,
|
||||
inventoryAdjustmentCurrentPage,
|
||||
inventoryAdjustmentsPagination,
|
||||
}),
|
||||
),
|
||||
)(InventoryAdjustmentDataTable);
|
||||
|
||||
@@ -3,13 +3,15 @@ import { useQuery } from 'react-query';
|
||||
import { Alert, Intent } from '@blueprintjs/core';
|
||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||
|
||||
import AppToaster from 'components/AppToaster';
|
||||
import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
|
||||
import DashboardInsider from 'components/Dashboard/DashboardInsider';
|
||||
|
||||
import InventoryAdjustmentDataTable from './InventoryAdjustmentDataTable';
|
||||
|
||||
import withInventoryAdjustmentActions from './withInventoryAdjustmentActions';
|
||||
import withInventoryAdjustments from './withInventoryAdjustments';
|
||||
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
||||
//withInventoryAdjustmentsActions
|
||||
|
||||
import { compose } from 'utils';
|
||||
import { Route, Switch } from 'react-router-dom';
|
||||
|
||||
@@ -19,7 +21,13 @@ import { Route, Switch } from 'react-router-dom';
|
||||
function InventoryAdjustmentList({
|
||||
// #withDashboardActions
|
||||
changePageTitle,
|
||||
|
||||
// #withInventoryAdjustments
|
||||
inventoryAdjustmentTableQuery,
|
||||
|
||||
// #withInventoryAdjustmentsActions
|
||||
requestFetchInventoryAdjustmentTable,
|
||||
requestDeleteInventoryAdjustment,
|
||||
}) {
|
||||
const { formatMessage } = useIntl();
|
||||
const [selectedRows, setSelectedRows] = useState([]);
|
||||
@@ -32,8 +40,8 @@ function InventoryAdjustmentList({
|
||||
}, [changePageTitle, formatMessage]);
|
||||
|
||||
const fetchInventoryAdjustments = useQuery(
|
||||
['inventory-adjustment-list'],
|
||||
() => {},
|
||||
['inventory-adjustment-list' ,inventoryAdjustmentTableQuery],
|
||||
(key, query) => requestFetchInventoryAdjustmentTable({ ...query }),
|
||||
);
|
||||
|
||||
// Handle selected rows change.
|
||||
@@ -55,7 +63,25 @@ function InventoryAdjustmentList({
|
||||
setDeleteInventoryAdjustment(false);
|
||||
}, [setDeleteInventoryAdjustment]);
|
||||
|
||||
const handleConfirmInventoryAdjustmentDelete = useCallback(() => {}, []);
|
||||
const handleConfirmInventoryAdjustmentDelete = useCallback(() => {
|
||||
requestDeleteInventoryAdjustment(deleteInventoryAdjustment.id)
|
||||
.then(() => {
|
||||
setDeleteInventoryAdjustment(false);
|
||||
AppToaster.show({
|
||||
message: formatMessage({
|
||||
id: 'the_adjustment_has_been_successfully_deleted',
|
||||
}),
|
||||
intent: Intent.SUCCESS,
|
||||
});
|
||||
})
|
||||
.catch((errors) => {
|
||||
setDeleteInventoryAdjustment(false);
|
||||
});
|
||||
}, [
|
||||
deleteInventoryAdjustment,
|
||||
requestDeleteInventoryAdjustment,
|
||||
formatMessage,
|
||||
]);
|
||||
|
||||
// Calculates the data table selected rows count.
|
||||
const selectedRowsCount = useMemo(() => Object.values(selectedRows).length, [
|
||||
@@ -63,7 +89,7 @@ function InventoryAdjustmentList({
|
||||
]);
|
||||
|
||||
return (
|
||||
<DashboardInsider>
|
||||
<DashboardInsider name={'inventory_adjustments'}>
|
||||
<DashboardPageContent>
|
||||
<Switch>
|
||||
<Route exact={true}>
|
||||
@@ -73,9 +99,32 @@ function InventoryAdjustmentList({
|
||||
/>
|
||||
</Route>
|
||||
</Switch>
|
||||
<Alert
|
||||
cancelButtonText={<T id={'cancel'} />}
|
||||
confirmButtonText={<T id={'delete'} />}
|
||||
icon={'trash'}
|
||||
intent={Intent.DANGER}
|
||||
isOpen={deleteInventoryAdjustment}
|
||||
onCancel={handleCancelInventoryAdjustmentDelete}
|
||||
onConfirm={handleConfirmInventoryAdjustmentDelete}
|
||||
>
|
||||
<p>
|
||||
<T
|
||||
id={
|
||||
'once_delete_this_inventory_a_adjustment_you_will_able_to_restore_it'
|
||||
}
|
||||
/>
|
||||
</p>
|
||||
</Alert>
|
||||
</DashboardPageContent>
|
||||
</DashboardInsider>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(withDashboardActions)(InventoryAdjustmentList);
|
||||
export default compose(
|
||||
withDashboardActions,
|
||||
withInventoryAdjustmentActions,
|
||||
withInventoryAdjustments(({ inventoryAdjustmentTableQuery }) => ({
|
||||
inventoryAdjustmentTableQuery,
|
||||
})),
|
||||
)(InventoryAdjustmentList);
|
||||
|
||||
@@ -75,6 +75,17 @@ function ItemsDataTable({
|
||||
[addItemsTableQueries],
|
||||
);
|
||||
|
||||
const handleMakeAdjustment = useCallback(
|
||||
(item) => () => {
|
||||
openDialog('inventory-adjustment-form', {
|
||||
action: 'make_adjustment',
|
||||
item_id: item.id,
|
||||
quantity_on_hand: item.quantity_on_hand,
|
||||
});
|
||||
},
|
||||
[openDialog],
|
||||
);
|
||||
|
||||
const handleEditItem = useCallback(
|
||||
(item) => () => {
|
||||
onEditItem && onEditItem(item);
|
||||
@@ -89,10 +100,6 @@ function ItemsDataTable({
|
||||
[onDeleteItem],
|
||||
);
|
||||
|
||||
const handleMakeAdjustment = useCallback(() => {
|
||||
openDialog('inventory-adjustment-form', {});
|
||||
}, [openDialog]);
|
||||
|
||||
const actionMenuList = useCallback(
|
||||
(item) => (
|
||||
<Menu>
|
||||
@@ -120,11 +127,11 @@ function ItemsDataTable({
|
||||
onClick={() => onActivateItem(item)}
|
||||
/>
|
||||
</If>
|
||||
|
||||
|
||||
<If condition={item.type === 'inventory'}>
|
||||
<MenuItem
|
||||
text={formatMessage({ id: 'make_adjustment' })}
|
||||
onClick={handleMakeAdjustment}
|
||||
onClick={handleMakeAdjustment(item)}
|
||||
/>
|
||||
</If>
|
||||
<MenuItem
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
import t from 'store/types';
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
requestSubmitInventoryAdjustment: (form) =>
|
||||
requestSubmitInventoryAdjustment: ({ form }) =>
|
||||
dispatch(submitInventoryAdjustment({ form })),
|
||||
requestFetchInventoryAdjustmentTable: (query = {}) =>
|
||||
dispatch(fetchInventoryAdjustmentsTable({ query: { ...query } })),
|
||||
|
||||
@@ -1,4 +1,34 @@
|
||||
import { connect } from 'react-redux';
|
||||
import {
|
||||
getInvoiceTableQueryFactory,
|
||||
getInventoryAdjustmentCurrentPageFactory,
|
||||
getInventoryAdjustmentPaginationMetaFactory,
|
||||
} from 'store/inventoryAdjustments/inventoryAdjustment.selector';
|
||||
|
||||
export default (mapState) => {
|
||||
const getInventoryAdjustmentItems = getInventoryAdjustmentCurrentPageFactory();
|
||||
const getInventoryAdjustmentTableQuery = getInvoiceTableQueryFactory();
|
||||
const getInventoryAdjustmentsPaginationMeta = getInventoryAdjustmentPaginationMetaFactory();
|
||||
|
||||
const mapStateToProps = (state, props) => {
|
||||
const query = getInventoryAdjustmentTableQuery(state, props);
|
||||
|
||||
const mapped = {
|
||||
inventoryAdjustmentCurrentPage: getInventoryAdjustmentItems(
|
||||
state,
|
||||
props,
|
||||
query,
|
||||
),
|
||||
inventoryAdjustmentItems: Object.values(state.inventoryAdjustments.items),
|
||||
inventoryAdjustmentTableQuery: query,
|
||||
inventoryAdjustmentsPagination: getInventoryAdjustmentsPaginationMeta(
|
||||
state,
|
||||
props,
|
||||
query,
|
||||
),
|
||||
inventoryAdjustmentLoading: state.inventoryAdjustments.loading,
|
||||
};
|
||||
return mapState ? mapState(mapped, state, props) : mapped;
|
||||
};
|
||||
return connect(mapStateToProps);
|
||||
};
|
||||
|
||||
@@ -950,8 +950,13 @@ export default {
|
||||
cost: 'Cost',
|
||||
qty_on_hand: 'Qty on hand',
|
||||
adjustment_account: 'Adjustment account',
|
||||
inventory_adjustment_list:'Inventory Adjustment List',
|
||||
delete_adjustment:'Delete Adjustment',
|
||||
inventory_adjustment_list: 'Inventory Adjustment List',
|
||||
delete_adjustment: 'Delete Adjustment',
|
||||
the_make_adjustment_has_been_successfully_created:
|
||||
'The make adjustment has been successfully created.',
|
||||
the_adjustment_has_been_successfully_deleted:
|
||||
'The adjustment has been successfully deleted.',
|
||||
once_delete_this_inventory_a_adjustment_you_will_able_to_restore_it: `Once you delete this inventory a adjustment, you won\'t be able to restore it later. Are you sure you want to delete this invoice?`,
|
||||
select_adjustment_account: 'Select Adjustment account',
|
||||
qty: 'Quantity on hand',
|
||||
};
|
||||
|
||||
@@ -4,10 +4,11 @@ import t from 'store/types';
|
||||
export const submitInventoryAdjustment = ({ form }) => {
|
||||
return (dispatch) =>
|
||||
new Promise((resolve, reject) => {
|
||||
ApiService.post('inventory_adjustments', form).then((response) => {
|
||||
resolve(response);
|
||||
}),
|
||||
caches((error) => {
|
||||
ApiService.post('inventory_adjustments/quick', form)
|
||||
.then((response) => {
|
||||
resolve(response);
|
||||
})
|
||||
.catch((error) => {
|
||||
const { response } = error;
|
||||
const { data } = response;
|
||||
|
||||
@@ -51,7 +52,7 @@ export const fetchInventoryAdjustmentsTable = ({ query } = {}) => {
|
||||
dispatch({
|
||||
type: t.INVENTORY_ADJUSTMENTS_PAGE_SET,
|
||||
payload: {
|
||||
inventory_adjustments: response.data,
|
||||
inventory_adjustments: response.data.inventoy_adjustments,
|
||||
pagination: response.data.pagination,
|
||||
customViewId:
|
||||
response.data?.filter_meta?.view?.custom_view_id || -1,
|
||||
@@ -60,7 +61,7 @@ export const fetchInventoryAdjustmentsTable = ({ query } = {}) => {
|
||||
dispatch({
|
||||
type: t.INVENTORY_ADJUSTMENT_ITEMS_SET,
|
||||
payload: {
|
||||
inventory_adjustment: response.data,
|
||||
inventory_adjustment: response.data.inventoy_adjustments,
|
||||
},
|
||||
});
|
||||
dispatch({
|
||||
|
||||
@@ -14,9 +14,6 @@ const initialState = {
|
||||
page_size: 12,
|
||||
page: 1,
|
||||
},
|
||||
paginationMeta: {
|
||||
total: 0,
|
||||
},
|
||||
};
|
||||
|
||||
export default createReducer(initialState, {
|
||||
@@ -37,7 +34,6 @@ export default createReducer(initialState, {
|
||||
|
||||
const viewId = customViewId || -1;
|
||||
const view = state.views[viewId] || {};
|
||||
|
||||
state.views[viewId] = {
|
||||
...view,
|
||||
pages: {
|
||||
@@ -49,7 +45,6 @@ export default createReducer(initialState, {
|
||||
};
|
||||
},
|
||||
|
||||
//useless
|
||||
[t.INVENTORY_ADJUSTMENT_ITEMS_SET]: (state, action) => {
|
||||
const { inventory_adjustment } = action.payload;
|
||||
const _inventory_adjustment = {};
|
||||
|
||||
@@ -5,3 +5,55 @@ import {
|
||||
defaultPaginationMeta,
|
||||
} from 'store/selectors';
|
||||
|
||||
const inventoryAdjustmentTableQuery = (state) =>
|
||||
state.inventoryAdjustments.tableQuery;
|
||||
|
||||
const inventoryAdjustmentsPaginationSelector = (state, props) => {
|
||||
const viewId = state.inventoryAdjustments.currentViewId;
|
||||
return state.inventoryAdjustments.views?.[viewId];
|
||||
};
|
||||
|
||||
const inventoryAdjustmentItemsSelector = (state) =>
|
||||
state.inventoryAdjustments.items;
|
||||
|
||||
const inventoryAdjustmentCurrentPageSelector = (state, props) => {
|
||||
const currentViewId = state.inventoryAdjustments.currentViewId;
|
||||
const currentView = state.inventoryAdjustments.views?.[currentViewId];
|
||||
const currentPageId = currentView?.paginationMeta?.page;
|
||||
|
||||
return currentView?.pages?.[currentPageId];
|
||||
};
|
||||
|
||||
const getinventoryAdjustmentCurrentViewIdSelector = (state) =>
|
||||
state.inventoryAdjustments.currentViewId;
|
||||
|
||||
export const getInvoiceTableQueryFactory = () =>
|
||||
createSelector(
|
||||
paginationLocationQuery,
|
||||
inventoryAdjustmentTableQuery,
|
||||
(locationQuery, tableQuery) => {
|
||||
return {
|
||||
...locationQuery,
|
||||
...tableQuery,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
export const getInventoryAdjustmentCurrentPageFactory = () =>
|
||||
createSelector(
|
||||
inventoryAdjustmentCurrentPageSelector,
|
||||
inventoryAdjustmentItemsSelector,
|
||||
(currentPage, items) => {
|
||||
return typeof currentPage === 'object'
|
||||
? pickItemsFromIds(items, currentPage.ids) || []
|
||||
: [];
|
||||
},
|
||||
);
|
||||
|
||||
export const getInventoryAdjustmentPaginationMetaFactory = () =>
|
||||
createSelector(inventoryAdjustmentsPaginationSelector, (Page) => {
|
||||
return {
|
||||
...defaultPaginationMeta(),
|
||||
...(Page?.paginationMeta || {}),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@ export default {
|
||||
|
||||
|
||||
INVENTORY_ADJUSTMENTS_TABLE_QUERIES_ADD:
|
||||
'INVENTORY_ADJUSTMENTS_TABLE_QUERIES_ADD',
|
||||
'INVENTORY_ADJUSTMENTS/TABLE_QUERIES_ADD',
|
||||
INVENTORY_ADJUSTMENTS_SET_CURRENT_VIEW:
|
||||
'INVENTORY_ADJUSTMENTS_SET_CURRENT_VIEW',
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user