mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-21 15:20:34 +00:00
Merge branch 'master' of https://github.com/abouolia/Bigcapital
This commit is contained in:
@@ -4,10 +4,10 @@ import { If } from 'components';
|
|||||||
export const accountNameAccessor = (account) => {
|
export const accountNameAccessor = (account) => {
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
<If condition={account.name}>
|
|
||||||
<span class={'account-name'}>{account.name}</span>
|
<span class={'account-name'}>{account.name}</span>
|
||||||
</If>
|
<If condition={account.description}>
|
||||||
<span class={'account-desc'}>{account.description}</span>
|
<span class={'account-desc'}>{account.description}</span>
|
||||||
|
</If>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
import React, { useRef } from 'react';
|
import React from 'react';
|
||||||
import { FastField, ErrorMessage, useFormikContext } from 'formik';
|
import { Field, ErrorMessage, FastField } from 'formik';
|
||||||
import { FormGroup, InputGroup, Intent } from '@blueprintjs/core';
|
import { FormGroup, InputGroup } from '@blueprintjs/core';
|
||||||
import { inputIntent } from 'utils';
|
import { inputIntent } from 'utils';
|
||||||
import { Row, Col, If, FieldRequiredHint } from 'components';
|
import { Row, Col, MoneyInputGroup } from 'components';
|
||||||
import { FormattedMessage as T } from 'react-intl';
|
import { FormattedMessage as T } from 'react-intl';
|
||||||
import { decrementCalc, dec } from './utils';
|
import { decrementQuantity } from './utils';
|
||||||
|
import { toSafeNumber } from 'utils';
|
||||||
|
|
||||||
function DecrementAdjustmentFields() {
|
function DecrementAdjustmentFields() {
|
||||||
return (
|
return (
|
||||||
<Row>
|
<Row className={'row--decrement-fields'}>
|
||||||
{/*------------ Quantity on hand -----------*/}
|
{/*------------ Quantity on hand -----------*/}
|
||||||
<Col sm={3}>
|
<Col className={'col--quantity-on-hand'}>
|
||||||
<FastField name={'quantity_on_hand'}>
|
<FastField name={'quantity_on_hand'}>
|
||||||
{({ field, meta: { error, touched } }) => (
|
{({ field, meta: { error, touched } }) => (
|
||||||
<FormGroup
|
<FormGroup
|
||||||
@@ -23,9 +24,14 @@ function DecrementAdjustmentFields() {
|
|||||||
)}
|
)}
|
||||||
</FastField>
|
</FastField>
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
|
<Col className={'col--sign'}>
|
||||||
|
<span>–</span>
|
||||||
|
</Col>
|
||||||
|
|
||||||
{/*------------ Decrement -----------*/}
|
{/*------------ Decrement -----------*/}
|
||||||
<Col sm={2}>
|
<Col className={'col--decrement'}>
|
||||||
<FastField name={'quantity'}>
|
<Field name={'quantity'}>
|
||||||
{({
|
{({
|
||||||
form: { values, setFieldValue },
|
form: { values, setFieldValue },
|
||||||
field,
|
field,
|
||||||
@@ -37,19 +43,34 @@ function DecrementAdjustmentFields() {
|
|||||||
helperText={<ErrorMessage name="quantity" />}
|
helperText={<ErrorMessage name="quantity" />}
|
||||||
fill={true}
|
fill={true}
|
||||||
>
|
>
|
||||||
<InputGroup
|
<MoneyInputGroup
|
||||||
{...field}
|
value={field.value}
|
||||||
onBlur={(event) => {
|
allowDecimals={false}
|
||||||
setFieldValue('new_quantity', decrementCalc(values, event));
|
allowNegativeValue={true}
|
||||||
|
onChange={(value) => {
|
||||||
|
setFieldValue('quantity', value);
|
||||||
|
}}
|
||||||
|
onBlurValue={(value) => {
|
||||||
|
setFieldValue(
|
||||||
|
'new_quantity',
|
||||||
|
decrementQuantity(
|
||||||
|
toSafeNumber(value),
|
||||||
|
toSafeNumber(values.quantity_on_hand),
|
||||||
|
),
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
)}
|
)}
|
||||||
</FastField>
|
</Field>
|
||||||
|
</Col>
|
||||||
|
|
||||||
|
<Col className={'col--sign'}>
|
||||||
|
<span>=</span>
|
||||||
</Col>
|
</Col>
|
||||||
{/*------------ New quantity -----------*/}
|
{/*------------ New quantity -----------*/}
|
||||||
<Col sm={4}>
|
<Col className={'col--quantity'}>
|
||||||
<FastField name={'new_quantity'}>
|
<Field name={'new_quantity'}>
|
||||||
{({
|
{({
|
||||||
form: { values, setFieldValue },
|
form: { values, setFieldValue },
|
||||||
field,
|
field,
|
||||||
@@ -60,15 +81,26 @@ function DecrementAdjustmentFields() {
|
|||||||
intent={inputIntent({ error, touched })}
|
intent={inputIntent({ error, touched })}
|
||||||
helperText={<ErrorMessage name="new_quantity" />}
|
helperText={<ErrorMessage name="new_quantity" />}
|
||||||
>
|
>
|
||||||
<InputGroup
|
<MoneyInputGroup
|
||||||
{...field}
|
value={field.value}
|
||||||
onBlur={(event) => {
|
allowDecimals={false}
|
||||||
setFieldValue('quantity', decrementCalc(values, event));
|
allowNegativeValue={true}
|
||||||
|
onChange={(value) => {
|
||||||
|
setFieldValue('new_quantity', value);
|
||||||
|
}}
|
||||||
|
onBlurValue={(value) => {
|
||||||
|
setFieldValue(
|
||||||
|
'quantity',
|
||||||
|
decrementQuantity(
|
||||||
|
toSafeNumber(value),
|
||||||
|
toSafeNumber(values.quantity_on_hand),
|
||||||
|
),
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
)}
|
)}
|
||||||
</FastField>
|
</Field>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FastField, ErrorMessage, useFormikContext } from 'formik';
|
import { Field, FastField, ErrorMessage } from 'formik';
|
||||||
import { FormGroup, InputGroup, Intent } from '@blueprintjs/core';
|
import { FormGroup, InputGroup } from '@blueprintjs/core';
|
||||||
import { Row, Col, FieldRequiredHint } from 'components';
|
import { Row, Col, MoneyInputGroup } from 'components';
|
||||||
import { inputIntent } from 'utils';
|
import { inputIntent, toSafeNumber } from 'utils';
|
||||||
import { FormattedMessage as T } from 'react-intl';
|
import { FormattedMessage as T } from 'react-intl';
|
||||||
import { decrementCalc, incrementCalc } from './utils';
|
import { decrementQuantity, incrementQuantity } from './utils';
|
||||||
|
|
||||||
function IncrementAdjustmentFields() {
|
function IncrementAdjustmentFields() {
|
||||||
return (
|
return (
|
||||||
<Row>
|
<Row>
|
||||||
{/*------------ Quantity on hand -----------*/}
|
{/*------------ Quantity on hand -----------*/}
|
||||||
<Col sm={3}>
|
<Col className={'col--quantity-on-hand'}>
|
||||||
<FastField name={'quantity_on_hand'}>
|
<FastField name={'quantity_on_hand'}>
|
||||||
{({ field, meta: { error, touched } }) => (
|
{({ field, meta: { error, touched } }) => (
|
||||||
<FormGroup
|
<FormGroup
|
||||||
@@ -23,9 +23,15 @@ function IncrementAdjustmentFields() {
|
|||||||
)}
|
)}
|
||||||
</FastField>
|
</FastField>
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
|
{/*------------ Sign -----------*/}
|
||||||
|
<Col className={'col--sign'}>
|
||||||
|
<span>+</span>
|
||||||
|
</Col>
|
||||||
|
|
||||||
{/*------------ Increment -----------*/}
|
{/*------------ Increment -----------*/}
|
||||||
<Col sm={2}>
|
<Col className={'col--quantity'}>
|
||||||
<FastField name={'quantity'}>
|
<Field name={'quantity'}>
|
||||||
{({
|
{({
|
||||||
form: { values, setFieldValue },
|
form: { values, setFieldValue },
|
||||||
field,
|
field,
|
||||||
@@ -37,33 +43,60 @@ function IncrementAdjustmentFields() {
|
|||||||
helperText={<ErrorMessage name="quantity" />}
|
helperText={<ErrorMessage name="quantity" />}
|
||||||
fill={true}
|
fill={true}
|
||||||
>
|
>
|
||||||
<InputGroup
|
<MoneyInputGroup
|
||||||
{...field}
|
value={field.value}
|
||||||
onBlur={(event) => {
|
allowDecimals={false}
|
||||||
setFieldValue('new_quantity', incrementCalc(values, event));
|
allowNegativeValue={true}
|
||||||
|
onChange={(value) => {
|
||||||
|
setFieldValue('quantity', value);
|
||||||
|
}}
|
||||||
|
onBlurValue={(value) => {
|
||||||
|
setFieldValue(
|
||||||
|
'new_quantity',
|
||||||
|
incrementQuantity(
|
||||||
|
toSafeNumber(value),
|
||||||
|
toSafeNumber(values.quantity_on_hand),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
)}
|
||||||
|
</Field>
|
||||||
|
</Col>
|
||||||
|
|
||||||
|
{/*------------ Cost -----------*/}
|
||||||
|
<Col className={'col--cost'}>
|
||||||
|
<FastField name={'cost'}>
|
||||||
|
{({
|
||||||
|
form: { setFieldValue },
|
||||||
|
field: { value },
|
||||||
|
meta: { error, touched },
|
||||||
|
}) => (
|
||||||
|
<FormGroup
|
||||||
|
label={<T id={'cost'} />}
|
||||||
|
intent={inputIntent({ error, touched })}
|
||||||
|
helperText={<ErrorMessage name="cost" />}
|
||||||
|
>
|
||||||
|
<MoneyInputGroup
|
||||||
|
value={value}
|
||||||
|
onChange={(value) => {
|
||||||
|
setFieldValue('cost', value);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
)}
|
)}
|
||||||
</FastField>
|
</FastField>
|
||||||
</Col>
|
</Col>
|
||||||
{/*------------ Cost -----------*/}
|
|
||||||
<Col sm={2}>
|
{/*------------ Sign -----------*/}
|
||||||
<FastField name={'cost'}>
|
<Col className={'col--sign'}>
|
||||||
{({ field, meta: { error, touched } }) => (
|
<span>=</span>
|
||||||
<FormGroup
|
|
||||||
label={<T id={'cost'} />}
|
|
||||||
intent={inputIntent({ error, touched })}
|
|
||||||
helperText={<ErrorMessage name="cost" />}
|
|
||||||
>
|
|
||||||
<InputGroup medium={'true'} {...field} />
|
|
||||||
</FormGroup>
|
|
||||||
)}
|
|
||||||
</FastField>
|
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
{/*------------ New quantity -----------*/}
|
{/*------------ New quantity -----------*/}
|
||||||
<Col sm={4}>
|
<Col className={'col--quantity-on-hand'}>
|
||||||
<FastField name={'new_quantity'}>
|
<Field name={'new_quantity'}>
|
||||||
{({
|
{({
|
||||||
form: { values, setFieldValue },
|
form: { values, setFieldValue },
|
||||||
field,
|
field,
|
||||||
@@ -74,15 +107,26 @@ function IncrementAdjustmentFields() {
|
|||||||
intent={inputIntent({ error, touched })}
|
intent={inputIntent({ error, touched })}
|
||||||
helperText={<ErrorMessage name="new_quantity" />}
|
helperText={<ErrorMessage name="new_quantity" />}
|
||||||
>
|
>
|
||||||
<InputGroup
|
<MoneyInputGroup
|
||||||
{...field}
|
value={field.value}
|
||||||
onBlur={(event) => {
|
allowDecimals={false}
|
||||||
setFieldValue('quantity', decrementCalc(values, event));
|
allowNegativeValue={true}
|
||||||
|
onChange={(value) => {
|
||||||
|
setFieldValue('new_quantity', value);
|
||||||
|
}}
|
||||||
|
onBlurValue={(value) => {
|
||||||
|
setFieldValue(
|
||||||
|
'quantity',
|
||||||
|
decrementQuantity(
|
||||||
|
toSafeNumber(value),
|
||||||
|
toSafeNumber(values.quantity_on_hand),
|
||||||
|
),
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
)}
|
)}
|
||||||
</FastField>
|
</Field>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -11,19 +11,19 @@ const Schema = Yup.object().shape({
|
|||||||
item_id: Yup.number().required(),
|
item_id: Yup.number().required(),
|
||||||
reason: Yup.string()
|
reason: Yup.string()
|
||||||
.required()
|
.required()
|
||||||
|
.min(3)
|
||||||
|
.max(DATATYPES_LENGTH.TEXT)
|
||||||
.label(formatMessage({ id: 'reason' })),
|
.label(formatMessage({ id: 'reason' })),
|
||||||
quantity_on_hand: Yup.number()
|
quantity_on_hand: Yup.number()
|
||||||
.min(0)
|
|
||||||
.required()
|
.required()
|
||||||
.label(formatMessage({ id: 'qty' })),
|
.label(formatMessage({ id: 'qty' })),
|
||||||
quantity: Yup.number().integer().max(Yup.ref('quantity_on_hand')).required(),
|
quantity: Yup.number().integer().min(1).required(),
|
||||||
cost: Yup.number().when(['type'], {
|
cost: Yup.number().when(['type'], {
|
||||||
is: (type) => type,
|
is: (type) => type === 'increment',
|
||||||
then: Yup.number(),
|
then: Yup.number().required(),
|
||||||
}),
|
}),
|
||||||
reference_no: Yup.string(),
|
reference_no: Yup.string(),
|
||||||
new_quantity: Yup.number().min(Yup.ref('quantity')).required(),
|
new_quantity: Yup.number().required(),
|
||||||
description: Yup.string().min(3).max(DATATYPES_LENGTH.TEXT).nullable().trim(),
|
|
||||||
publish: Yup.boolean(),
|
publish: Yup.boolean(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,26 @@
|
|||||||
import React, { useState, useCallback, useMemo } from 'react';
|
import React, { useState, useCallback } from 'react';
|
||||||
import { Intent } from '@blueprintjs/core';
|
import { Intent } from '@blueprintjs/core';
|
||||||
import { Formik, Form } from 'formik';
|
import { Formik, Form } from 'formik';
|
||||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
import { useIntl } from 'react-intl';
|
||||||
import { useQuery, queryCache } from 'react-query';
|
import { useQuery, queryCache } from 'react-query';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { omit } from 'lodash';
|
import { omit, get } from 'lodash';
|
||||||
|
|
||||||
|
import 'style/pages/Items/ItemAdjustmentDialog.scss';
|
||||||
|
|
||||||
import { AppToaster, DialogContent } from 'components';
|
import { AppToaster, DialogContent } from 'components';
|
||||||
|
|
||||||
import { CreateInventoryAdjustmentFormSchema } from './InventoryAdjustmentForm.schema';
|
import { CreateInventoryAdjustmentFormSchema } from './InventoryAdjustmentForm.schema';
|
||||||
|
|
||||||
import InventoryAdjustmentFormDialogFields from './InventoryAdjustmentFormDialogFields';
|
import InventoryAdjustmentFormDialogFields from './InventoryAdjustmentFormDialogFields';
|
||||||
import InventoryAdjustmentFloatingActions from './InventoryAdjustmentFloatingActions';
|
import InventoryAdjustmentFloatingActions from './InventoryAdjustmentFloatingActions';
|
||||||
|
|
||||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||||
import withInventoryAdjustmentActions from 'containers/Items/withInventoryAdjustmentActions';
|
import withInventoryAdjustmentActions from 'containers/Items/withInventoryAdjustmentActions';
|
||||||
|
import withAccountsActions from 'containers/Accounts/withAccountsActions';
|
||||||
|
import withItem from 'containers/Items/withItem';
|
||||||
|
import withItemsActions from 'containers/Items/withItemsActions';
|
||||||
|
|
||||||
import { compose } from 'utils';
|
import { compose } from 'utils';
|
||||||
|
|
||||||
const defaultInitialValues = {
|
const defaultInitialValues = {
|
||||||
@@ -24,7 +33,6 @@ const defaultInitialValues = {
|
|||||||
quantity: '',
|
quantity: '',
|
||||||
reference_no: '',
|
reference_no: '',
|
||||||
quantity_on_hand: '',
|
quantity_on_hand: '',
|
||||||
description: '',
|
|
||||||
publish: '',
|
publish: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -41,8 +49,14 @@ function InventoryAdjustmentFormDialogContent({
|
|||||||
// #withInventoryAdjustmentActions
|
// #withInventoryAdjustmentActions
|
||||||
requestSubmitInventoryAdjustment,
|
requestSubmitInventoryAdjustment,
|
||||||
|
|
||||||
|
// #withItemsActions
|
||||||
|
requestFetchItem,
|
||||||
|
|
||||||
|
// #withItem
|
||||||
|
item,
|
||||||
|
|
||||||
// #ownProp
|
// #ownProp
|
||||||
itemDetail,
|
itemId,
|
||||||
dialogName,
|
dialogName,
|
||||||
}) {
|
}) {
|
||||||
const { formatMessage } = useIntl();
|
const { formatMessage } = useIntl();
|
||||||
@@ -51,13 +65,16 @@ function InventoryAdjustmentFormDialogContent({
|
|||||||
// Fetches accounts list.
|
// Fetches accounts list.
|
||||||
const fetchAccount = useQuery('accounts-list', () => requestFetchAccounts());
|
const fetchAccount = useQuery('accounts-list', () => requestFetchAccounts());
|
||||||
|
|
||||||
const initialValues = useMemo(
|
// Fetches the item details.
|
||||||
() => ({
|
const fetchItem = useQuery(['item', itemId],
|
||||||
|
(key, id) => requestFetchItem(id));
|
||||||
|
|
||||||
|
// Initial form values.
|
||||||
|
const initialValues = {
|
||||||
...defaultInitialValues,
|
...defaultInitialValues,
|
||||||
...itemDetail,
|
item_id: itemId,
|
||||||
}),
|
quantity_on_hand: get(item, 'quantity_on_hand', 0),
|
||||||
[],
|
};
|
||||||
);
|
|
||||||
|
|
||||||
// Handles the form submit.
|
// Handles the form submit.
|
||||||
const handleFormSubmit = (values, { setSubmitting, setErrors }) => {
|
const handleFormSubmit = (values, { setSubmitting, setErrors }) => {
|
||||||
@@ -65,7 +82,6 @@ function InventoryAdjustmentFormDialogContent({
|
|||||||
...omit(values, ['quantity_on_hand', 'new_quantity', 'action']),
|
...omit(values, ['quantity_on_hand', 'new_quantity', 'action']),
|
||||||
publish: submitPayload.publish,
|
publish: submitPayload.publish,
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSuccess = ({ response }) => {
|
const onSuccess = ({ response }) => {
|
||||||
closeDialog(dialogName);
|
closeDialog(dialogName);
|
||||||
queryCache.invalidateQueries('accounts-list');
|
queryCache.invalidateQueries('accounts-list');
|
||||||
@@ -97,7 +113,7 @@ function InventoryAdjustmentFormDialogContent({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DialogContent>
|
<DialogContent isLoading={fetchAccount.isFetching || fetchItem.isFetching}>
|
||||||
<Formik
|
<Formik
|
||||||
validationSchema={CreateInventoryAdjustmentFormSchema}
|
validationSchema={CreateInventoryAdjustmentFormSchema}
|
||||||
initialValues={initialValues}
|
initialValues={initialValues}
|
||||||
@@ -118,4 +134,9 @@ function InventoryAdjustmentFormDialogContent({
|
|||||||
export default compose(
|
export default compose(
|
||||||
withInventoryAdjustmentActions,
|
withInventoryAdjustmentActions,
|
||||||
withDialogActions,
|
withDialogActions,
|
||||||
|
withAccountsActions,
|
||||||
|
withItem(({ item }) => ({
|
||||||
|
item: item
|
||||||
|
})),
|
||||||
|
withItemsActions,
|
||||||
)(InventoryAdjustmentFormDialogContent);
|
)(InventoryAdjustmentFormDialogContent);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FastField, ErrorMessage, useFormikContext } from 'formik';
|
import { FastField, ErrorMessage, Field, useFormikContext } from 'formik';
|
||||||
import {
|
import {
|
||||||
Classes,
|
Classes,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
@@ -10,21 +10,22 @@ import {
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||||
import { DateInput } from '@blueprintjs/datetime';
|
import { DateInput } from '@blueprintjs/datetime';
|
||||||
import { ListSelect, Choose, If, FieldRequiredHint } from 'components';
|
import { compose } from 'redux';
|
||||||
|
import { ListSelect, FieldRequiredHint, Col, Row } from 'components';
|
||||||
import {
|
import {
|
||||||
inputIntent,
|
inputIntent,
|
||||||
momentFormatter,
|
momentFormatter,
|
||||||
tansformDateValue,
|
tansformDateValue,
|
||||||
handleDateChange,
|
handleDateChange,
|
||||||
|
toSafeNumber
|
||||||
} from 'utils';
|
} from 'utils';
|
||||||
import { CLASSES } from 'common/classes';
|
import { CLASSES } from 'common/classes';
|
||||||
import adjustmentType from 'common/adjustmentType';
|
import adjustmentType from 'common/adjustmentType';
|
||||||
import IncrementAdjustmentFields from './IncrementAdjustmentFields';
|
|
||||||
import DecrementAdjustmentFields from './DecrementAdjustmentFields';
|
|
||||||
import AccountsSuggestField from 'components/AccountsSuggestField';
|
import AccountsSuggestField from 'components/AccountsSuggestField';
|
||||||
import withAccounts from 'containers/Accounts/withAccounts';
|
import withAccounts from 'containers/Accounts/withAccounts';
|
||||||
import { compose } from 'redux';
|
import { diffQuantity } from './utils';
|
||||||
import { decrementCalc, incrementCalc, dec } from './utils';
|
import InventoryAdjustmentQuantityFields from './InventoryAdjustmentQuantityFields';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inventory adjustment form dialogs fields.
|
* Inventory adjustment form dialogs fields.
|
||||||
@@ -38,6 +39,8 @@ function InventoryAdjustmentFormDialogFields({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={Classes.DIALOG_BODY}>
|
<div className={Classes.DIALOG_BODY}>
|
||||||
|
<Row>
|
||||||
|
<Col xs={5}>
|
||||||
{/*------------ Date -----------*/}
|
{/*------------ Date -----------*/}
|
||||||
<FastField name={'date'}>
|
<FastField name={'date'}>
|
||||||
{({ form, field: { value }, meta: { error, touched } }) => (
|
{({ form, field: { value }, meta: { error, touched } }) => (
|
||||||
@@ -47,7 +50,7 @@ function InventoryAdjustmentFormDialogFields({
|
|||||||
intent={inputIntent({ error, touched })}
|
intent={inputIntent({ error, touched })}
|
||||||
helperText={<ErrorMessage name="date" />}
|
helperText={<ErrorMessage name="date" />}
|
||||||
minimal={true}
|
minimal={true}
|
||||||
className={classNames(CLASSES.FILL)}
|
className={classNames(CLASSES.FILL, 'form-group--date')}
|
||||||
>
|
>
|
||||||
<DateInput
|
<DateInput
|
||||||
{...momentFormatter('YYYY/MM/DD')}
|
{...momentFormatter('YYYY/MM/DD')}
|
||||||
@@ -63,27 +66,29 @@ function InventoryAdjustmentFormDialogFields({
|
|||||||
</FormGroup>
|
</FormGroup>
|
||||||
)}
|
)}
|
||||||
</FastField>
|
</FastField>
|
||||||
|
</Col>
|
||||||
|
|
||||||
|
<Col xs={5}>
|
||||||
{/*------------ Adjustment type -----------*/}
|
{/*------------ Adjustment type -----------*/}
|
||||||
<FastField name={'type'}>
|
<Field name={'type'}>
|
||||||
{({ form, field: { value }, meta: { error, touched } }) => (
|
{({ form: { values, setFieldValue }, field: { value }, meta: { error, touched } }) => (
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={<T id={'adjustment_type'} />}
|
label={<T id={'adjustment_type'} />}
|
||||||
labelInfo={<FieldRequiredHint />}
|
labelInfo={<FieldRequiredHint />}
|
||||||
helperText={<ErrorMessage name="type" />}
|
helperText={<ErrorMessage name="type" />}
|
||||||
intent={inputIntent({ error, touched })}
|
intent={inputIntent({ error, touched })}
|
||||||
className={classNames(CLASSES.FILL)}
|
className={classNames(CLASSES.FILL, 'form-group--type')}
|
||||||
>
|
>
|
||||||
<ListSelect
|
<ListSelect
|
||||||
items={adjustmentType}
|
items={adjustmentType}
|
||||||
onItemSelect={(type) => {
|
onItemSelect={(type) => {
|
||||||
form.setFieldValue('type', type.value);
|
const result = diffQuantity(
|
||||||
type?.value == 'increment'
|
toSafeNumber(values.quantity),
|
||||||
? form.setFieldValue('new_quantity', incrementCalc(values))
|
toSafeNumber(values.quantity_on_hand),
|
||||||
: form.setFieldValue(
|
type.value
|
||||||
'new_quantity',
|
|
||||||
values.quantity_on_hand - values.quantity,
|
|
||||||
);
|
);
|
||||||
|
setFieldValue('type', type.value);
|
||||||
|
setFieldValue('new_quantity', result);
|
||||||
}}
|
}}
|
||||||
filterable={false}
|
filterable={false}
|
||||||
selectedItem={value}
|
selectedItem={value}
|
||||||
@@ -93,28 +98,12 @@ function InventoryAdjustmentFormDialogFields({
|
|||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
)}
|
)}
|
||||||
</FastField>
|
</Field>
|
||||||
<Choose>
|
</Col>
|
||||||
<Choose.When condition={values.type === 'decrement'}>
|
</Row>
|
||||||
<DecrementAdjustmentFields />
|
|
||||||
</Choose.When>
|
<InventoryAdjustmentQuantityFields />
|
||||||
<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 -----------*/}
|
{/*------------ Adjustment account -----------*/}
|
||||||
<FastField name={'adjustment_account_id'}>
|
<FastField name={'adjustment_account_id'}>
|
||||||
{({ form, field, meta: { error, touched } }) => (
|
{({ form, field, meta: { error, touched } }) => (
|
||||||
@@ -123,6 +112,7 @@ function InventoryAdjustmentFormDialogFields({
|
|||||||
labelInfo={<FieldRequiredHint />}
|
labelInfo={<FieldRequiredHint />}
|
||||||
intent={inputIntent({ error, touched })}
|
intent={inputIntent({ error, touched })}
|
||||||
helperText={<ErrorMessage name="reason" />}
|
helperText={<ErrorMessage name="reason" />}
|
||||||
|
className={'form-group--adjustment-account'}
|
||||||
>
|
>
|
||||||
<AccountsSuggestField
|
<AccountsSuggestField
|
||||||
accounts={accountsList}
|
accounts={accountsList}
|
||||||
@@ -138,27 +128,29 @@ function InventoryAdjustmentFormDialogFields({
|
|||||||
</FormGroup>
|
</FormGroup>
|
||||||
)}
|
)}
|
||||||
</FastField>
|
</FastField>
|
||||||
|
|
||||||
{/*------------ Reference -----------*/}
|
{/*------------ Reference -----------*/}
|
||||||
<FastField name={'reference_no'}>
|
<FastField name={'reference_no'}>
|
||||||
{({ form, field, meta: { error, touched } }) => (
|
{({ form, field, meta: { error, touched } }) => (
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={<T id={'reference_no'} />}
|
label={<T id={'reference_no'} />}
|
||||||
className={classNames(CLASSES.FILL)}
|
|
||||||
intent={inputIntent({ error, touched })}
|
intent={inputIntent({ error, touched })}
|
||||||
helperText={<ErrorMessage name="reference_no" />}
|
helperText={<ErrorMessage name="reference_no" />}
|
||||||
|
className={'form-group--reference-no'}
|
||||||
>
|
>
|
||||||
<InputGroup {...field} />
|
<InputGroup {...field} />
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
)}
|
)}
|
||||||
</FastField>
|
</FastField>
|
||||||
|
|
||||||
{/*------------ description -----------*/}
|
{/*------------ description -----------*/}
|
||||||
<FastField name={'description'}>
|
<FastField name={'reason'}>
|
||||||
{({ field, meta: { error, touched } }) => (
|
{({ field, meta: { error, touched } }) => (
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={<T id={'description'} />}
|
label={<T id={'adjustment_reasons'} />}
|
||||||
className={'form-group--description'}
|
className={'form-group--adjustment-reasons'}
|
||||||
intent={inputIntent({ error, touched })}
|
intent={inputIntent({ error, touched })}
|
||||||
helperText={<ErrorMessage name={'description'} />}
|
helperText={<ErrorMessage name={'adjustment_reasons'} />}
|
||||||
>
|
>
|
||||||
<TextArea growVertically={true} large={true} {...field} />
|
<TextArea growVertically={true} large={true} {...field} />
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { useFormikContext } from 'formik';
|
||||||
|
import { Choose, If } from 'components';
|
||||||
|
import IncrementAdjustmentFields from './IncrementAdjustmentFields';
|
||||||
|
import DecrementAdjustmentFields from './DecrementAdjustmentFields';
|
||||||
|
|
||||||
|
export default function InventoryAdjustmentQuantityFields() {
|
||||||
|
const { values } = useFormikContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class="adjustment-fields">
|
||||||
|
<Choose>
|
||||||
|
<Choose.When condition={values.type === 'decrement'}>
|
||||||
|
<DecrementAdjustmentFields />
|
||||||
|
</Choose.When>
|
||||||
|
<Choose.When condition={values.type === 'increment'}>
|
||||||
|
<IncrementAdjustmentFields />
|
||||||
|
</Choose.When>
|
||||||
|
</Choose>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -13,7 +13,7 @@ const InventoryAdjustmentFormDialogContent = lazy(() =>
|
|||||||
*/
|
*/
|
||||||
function InventoryAdjustmentFormDialog({
|
function InventoryAdjustmentFormDialog({
|
||||||
dialogName,
|
dialogName,
|
||||||
payload = { action: '', id: null },
|
payload = { action: '', itemId: null },
|
||||||
isOpen,
|
isOpen,
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
@@ -23,11 +23,12 @@ function InventoryAdjustmentFormDialog({
|
|||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
canEscapeJeyClose={true}
|
canEscapeJeyClose={true}
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
|
className={'dialog--adjustment-item'}
|
||||||
>
|
>
|
||||||
<DialogSuspense>
|
<DialogSuspense>
|
||||||
<InventoryAdjustmentFormDialogContent
|
<InventoryAdjustmentFormDialogContent
|
||||||
dialogName={dialogName}
|
dialogName={dialogName}
|
||||||
itemDetail={payload}
|
itemId={payload.itemId}
|
||||||
/>
|
/>
|
||||||
</DialogSuspense>
|
</DialogSuspense>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
export const decrementCalc = ({ quantity_on_hand, type }, e) => {
|
|
||||||
if (type == 'decrement') {
|
export const decrementQuantity = (newQuantity, quantityOnHand) => {
|
||||||
return parseInt(quantity_on_hand, 10) - parseInt(e.currentTarget.value, 10);
|
return quantityOnHand - newQuantity;
|
||||||
} else {
|
|
||||||
return e.currentTarget.value - quantity_on_hand;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const incrementCalc = ({ quantity_on_hand, quantity }, e) => {
|
export const incrementQuantity = (newQuantity, quantityOnHand) => {
|
||||||
return parseInt(quantity_on_hand, 10) + parseInt(quantity, 10);
|
return quantityOnHand + newQuantity;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const diffQuantity = (newQuantity, quantityOnHand, type) => {
|
||||||
|
return type === 'decrement'
|
||||||
|
? decrementQuantity(newQuantity, quantityOnHand)
|
||||||
|
: incrementQuantity(newQuantity, quantityOnHand);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { useHistory } from 'react-router-dom';
|
|||||||
import { useIntl } from 'react-intl';
|
import { useIntl } from 'react-intl';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { defaultTo } from 'lodash';
|
import { defaultTo } from 'lodash';
|
||||||
import moment from 'moment';
|
|
||||||
|
|
||||||
import { CLASSES } from 'common/classes';
|
import { CLASSES } from 'common/classes';
|
||||||
import AppToaster from 'components/AppToaster';
|
import AppToaster from 'components/AppToaster';
|
||||||
@@ -18,7 +17,7 @@ import ItemFormInventorySection from './ItemFormInventorySection';
|
|||||||
import withItemsActions from 'containers/Items/withItemsActions';
|
import withItemsActions from 'containers/Items/withItemsActions';
|
||||||
import withMediaActions from 'containers/Media/withMediaActions';
|
import withMediaActions from 'containers/Media/withMediaActions';
|
||||||
import useMedia from 'hooks/useMedia';
|
import useMedia from 'hooks/useMedia';
|
||||||
import withItemDetail from 'containers/Items/withItemDetail';
|
import withItem from 'containers/Items/withItem';
|
||||||
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
||||||
import withSettings from 'containers/Settings/withSettings';
|
import withSettings from 'containers/Settings/withSettings';
|
||||||
|
|
||||||
@@ -56,7 +55,7 @@ function ItemForm({
|
|||||||
requestEditItem,
|
requestEditItem,
|
||||||
|
|
||||||
itemId,
|
itemId,
|
||||||
itemDetail,
|
item,
|
||||||
onFormSubmit,
|
onFormSubmit,
|
||||||
|
|
||||||
// #withDashboardActions
|
// #withDashboardActions
|
||||||
@@ -106,12 +105,12 @@ function ItemForm({
|
|||||||
* as well.
|
* as well.
|
||||||
*/
|
*/
|
||||||
...transformToForm(
|
...transformToForm(
|
||||||
transformItemFormData(itemDetail, defaultInitialValues),
|
transformItemFormData(item, defaultInitialValues),
|
||||||
defaultInitialValues,
|
defaultInitialValues,
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
[
|
[
|
||||||
itemDetail,
|
item,
|
||||||
preferredCostAccount,
|
preferredCostAccount,
|
||||||
preferredSellAccount,
|
preferredSellAccount,
|
||||||
preferredInventoryAccount,
|
preferredInventoryAccount,
|
||||||
@@ -177,20 +176,20 @@ function ItemForm({
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (itemDetail && itemDetail.type) {
|
if (item && item.type) {
|
||||||
changePageSubtitle(transitionItemTypeKeyToLabel(itemDetail.type));
|
changePageSubtitle(transitionItemTypeKeyToLabel(item.type));
|
||||||
}
|
}
|
||||||
}, [itemDetail, changePageSubtitle, formatMessage]);
|
}, [item, changePageSubtitle, formatMessage]);
|
||||||
|
|
||||||
const initialAttachmentFiles = useMemo(() => {
|
const initialAttachmentFiles = useMemo(() => {
|
||||||
return itemDetail && itemDetail.media
|
return item && item.media
|
||||||
? itemDetail.media.map((attach) => ({
|
? item.media.map((attach) => ({
|
||||||
preview: attach.attachment_file,
|
preview: attach.attachment_file,
|
||||||
upload: true,
|
upload: true,
|
||||||
metadata: { ...attach },
|
metadata: { ...attach },
|
||||||
}))
|
}))
|
||||||
: [];
|
: [];
|
||||||
}, [itemDetail]);
|
}, [item]);
|
||||||
|
|
||||||
const handleDropFiles = useCallback(
|
const handleDropFiles = useCallback(
|
||||||
(_files) => {
|
(_files) => {
|
||||||
@@ -233,7 +232,7 @@ function ItemForm({
|
|||||||
{({ isSubmitting, handleSubmit }) => (
|
{({ isSubmitting, handleSubmit }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<div class={classNames(CLASSES.PAGE_FORM_BODY)}>
|
<div class={classNames(CLASSES.PAGE_FORM_BODY)}>
|
||||||
<ItemFormPrimarySection itemType={itemDetail?.type} />
|
<ItemFormPrimarySection itemType={item?.type} />
|
||||||
<ItemFormBody />
|
<ItemFormBody />
|
||||||
<ItemFormInventorySection />
|
<ItemFormInventorySection />
|
||||||
</div>
|
</div>
|
||||||
@@ -254,7 +253,7 @@ function ItemForm({
|
|||||||
|
|
||||||
export default compose(
|
export default compose(
|
||||||
withItemsActions,
|
withItemsActions,
|
||||||
withItemDetail,
|
withItem(({ item }) => ({ item })),
|
||||||
withDashboardActions,
|
withDashboardActions,
|
||||||
withMediaActions,
|
withMediaActions,
|
||||||
withSettings(({ itemsSettings }) => ({
|
withSettings(({ itemsSettings }) => ({
|
||||||
|
|||||||
@@ -79,8 +79,7 @@ function ItemsDataTable({
|
|||||||
(item) => () => {
|
(item) => () => {
|
||||||
openDialog('inventory-adjustment-form', {
|
openDialog('inventory-adjustment-form', {
|
||||||
action: 'make_adjustment',
|
action: 'make_adjustment',
|
||||||
item_id: item.id,
|
itemId: item.id,
|
||||||
quantity_on_hand: item.quantity_on_hand,
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[openDialog],
|
[openDialog],
|
||||||
|
|||||||
13
client/src/containers/Items/withItem.js
Normal file
13
client/src/containers/Items/withItem.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { getItemById } from 'store/items/items.reducer';
|
||||||
|
|
||||||
|
export default (mapState) => {
|
||||||
|
const mapStateToProps = (state, props) => {
|
||||||
|
const mapped = {
|
||||||
|
item: getItemById(state, props.itemId),
|
||||||
|
};
|
||||||
|
return mapState ? mapState(mapped, state, props) : mapped;
|
||||||
|
};
|
||||||
|
|
||||||
|
return connect(mapStateToProps);
|
||||||
|
};
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
import { connect } from 'react-redux';
|
|
||||||
import { getItemById } from 'store/items/items.reducer';
|
|
||||||
|
|
||||||
const mapStateToProps = (state, props) => ({
|
|
||||||
itemDetail: getItemById(state, props.itemId),
|
|
||||||
});
|
|
||||||
|
|
||||||
export default connect(mapStateToProps);
|
|
||||||
@@ -957,7 +957,7 @@ export default {
|
|||||||
the_adjustment_has_been_successfully_deleted:
|
the_adjustment_has_been_successfully_deleted:
|
||||||
'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?`,
|
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',
|
select_adjustment_account: 'Select adjustment account',
|
||||||
qty: 'Quantity on hand',
|
qty: 'Quantity on hand',
|
||||||
money_format: 'Money format',
|
money_format: 'Money format',
|
||||||
show_zero: 'Show zero',
|
show_zero: 'Show zero',
|
||||||
@@ -970,4 +970,5 @@ export default {
|
|||||||
'You could not delete item that has associated inventory adjustments transactions',
|
'You could not delete item that has associated inventory adjustments transactions',
|
||||||
format: 'Format',
|
format: 'Format',
|
||||||
current: 'Current',
|
current: 'Current',
|
||||||
|
adjustment_reasons: 'Adjustment reasons'
|
||||||
};
|
};
|
||||||
|
|||||||
79
client/src/style/pages/Items/ItemAdjustmentDialog.scss
Normal file
79
client/src/style/pages/Items/ItemAdjustmentDialog.scss
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
.dialog--adjustment-item {
|
||||||
|
.bp3-form-group {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
|
||||||
|
label.bp3-label {
|
||||||
|
font-size: 13px;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.form-group {
|
||||||
|
&--adjustment-reasons {
|
||||||
|
.bp3-form-content {
|
||||||
|
textarea {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 100%;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&--reference-no,
|
||||||
|
&--adjustment-account {
|
||||||
|
max-width: 270px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.adjustment-fields {
|
||||||
|
padding-top: 16px;
|
||||||
|
border-top: 2px solid #e9e9e9;
|
||||||
|
margin-bottom: 18px;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
border-bottom: 2px solid #e9e9e9;
|
||||||
|
|
||||||
|
.bp3-input-group{
|
||||||
|
|
||||||
|
.bp3-input{
|
||||||
|
padding-left: 8px;
|
||||||
|
padding-right: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
margin-left: -0.3rem;
|
||||||
|
margin-right: -0.3rem;
|
||||||
|
|
||||||
|
.col {
|
||||||
|
padding-left: 0.3rem;
|
||||||
|
padding-right: 0.3rem;
|
||||||
|
|
||||||
|
.bp3-form-group {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
&--quantity-on-hand,
|
||||||
|
&--quantity {
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
&--sign {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
span {
|
||||||
|
margin-top: auto;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&--decrement,
|
||||||
|
&--increment {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
&--cost {
|
||||||
|
width: 95px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-dialog-footer {
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -388,3 +388,8 @@ export const getColumnWidth = (
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export const toSafeNumber = (number) => {
|
||||||
|
return _.toNumber(_.defaultTo(number, 0));
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user