This commit is contained in:
elforjani3
2021-01-18 01:03:35 +02:00
16 changed files with 401 additions and 198 deletions

View File

@@ -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>
); );
} };

View File

@@ -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>
); );

View File

@@ -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>
); );

View File

@@ -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(),
}); });

View File

@@ -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);

View File

@@ -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>

View File

@@ -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>
);
}

View File

@@ -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>

View File

@@ -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);
}; };

View File

@@ -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 }) => ({

View File

@@ -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],

View 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);
};

View File

@@ -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);

View File

@@ -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'
}; };

View 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;
}
}

View File

@@ -388,3 +388,8 @@ export const getColumnWidth = (
return result; return result;
}; };
export const toSafeNumber = (number) => {
return _.toNumber(_.defaultTo(number, 0));
}