From 085545c039cacb68164170f5344a7f26b32cc273 Mon Sep 17 00:00:00 2001 From: elforjani3 Date: Sat, 26 Dec 2020 23:09:48 +0200 Subject: [PATCH] fix: opening quantity & cost & date --- client/src/containers/Items/ItemForm.js | 4 ++ .../src/containers/Items/ItemForm.schema.js | 55 ++++++++++----- client/src/containers/Items/ItemFormBody.js | 2 - .../Items/ItemFormInventorySection.js | 70 ++++++++++++++----- client/src/containers/Items/ItemsDataTable.js | 16 +++-- client/src/lang/en/index.js | 7 +- client/src/style/pages/items.scss | 3 + 7 files changed, 112 insertions(+), 45 deletions(-) diff --git a/client/src/containers/Items/ItemForm.js b/client/src/containers/Items/ItemForm.js index 67ed8446c..2acc022f0 100644 --- a/client/src/containers/Items/ItemForm.js +++ b/client/src/containers/Items/ItemForm.js @@ -6,6 +6,7 @@ import { useHistory } from 'react-router-dom'; import { useIntl } from 'react-intl'; import classNames from 'classnames'; import { defaultTo } from 'lodash'; +import moment from 'moment'; import { CLASSES } from 'common/classes'; import AppToaster from 'components/AppToaster'; @@ -42,6 +43,9 @@ const defaultInitialValues = { category_id: '', sellable: 1, purchasable: true, + opening_quantity: '', + opening_cost: '', + opening_date: moment(new Date()).format('YYYY-MM-DD'), }; /** diff --git a/client/src/containers/Items/ItemForm.schema.js b/client/src/containers/Items/ItemForm.schema.js index 76c0d09ad..0ebc8ab17 100644 --- a/client/src/containers/Items/ItemForm.schema.js +++ b/client/src/containers/Items/ItemForm.schema.js @@ -2,6 +2,7 @@ import * as Yup from 'yup'; import { defaultTo } from 'lodash'; import { formatMessage } from 'services/intl'; import { DATATYPES_LENGTH } from 'common/dataTypes'; +import { isBlank } from 'utils'; const Schema = Yup.object().shape({ active: Yup.boolean(), @@ -17,20 +18,24 @@ const Schema = Yup.object().shape({ .max(DATATYPES_LENGTH.STRING) .label(formatMessage({ id: 'item_type_' })), code: Yup.string().trim().min(0).max(DATATYPES_LENGTH.STRING), - cost_price: Yup.number().min(0).when(['purchasable'], { - is: true, - then: Yup.number() - .required() - .label(formatMessage({ id: 'cost_price_' })), - otherwise: Yup.number().nullable(true), - }), - sell_price: Yup.number().min(0).when(['sellable'], { - is: true, - then: Yup.number() - .required() - .label(formatMessage({ id: 'sell_price_' })), - otherwise: Yup.number().nullable(true), - }), + cost_price: Yup.number() + .min(0) + .when(['purchasable'], { + is: true, + then: Yup.number() + .required() + .label(formatMessage({ id: 'cost_price_' })), + otherwise: Yup.number().nullable(true), + }), + sell_price: Yup.number() + .min(0) + .when(['sellable'], { + is: true, + then: Yup.number() + .required() + .label(formatMessage({ id: 'sell_price_' })), + otherwise: Yup.number().nullable(true), + }), cost_account_id: Yup.number() .when(['purchasable'], { is: true, @@ -56,9 +61,27 @@ const Schema = Yup.object().shape({ stock: Yup.string() || Yup.boolean(), sellable: Yup.boolean().required(), purchasable: Yup.boolean().required(), + opening_cost: Yup.number().when(['opening_quantity'], { + is: (value) => value, + then: Yup.number() + .min(0) + .required() + .label(formatMessage({ id: 'opening_cost_' })), + otherwise: Yup.number().nullable(), + }), + opening_quantity: Yup.number() + .min(1) + .nullable() + .label(formatMessage({ id: 'opening_quantity_' })), + opening_date: Yup.date().when(['opening_quantity', 'opening_cost'], { + is: (quantity, cost) => !isBlank(quantity) && !isBlank(cost), + then: Yup.date() + .required() + .label(formatMessage({ id: 'opening_date_' })), + otherwise: Yup.date().nullable(), + }), }); - export const transformItemFormData = (item, defaultValue) => { return { ...item, @@ -66,7 +89,7 @@ export const transformItemFormData = (item, defaultValue) => { purchasable: !!defaultTo(item?.purchasable, defaultValue.purchasable), active: !!defaultTo(item?.active, defaultValue.active), }; -} +}; export const CreateItemFormSchema = Schema; export const EditItemFormSchema = Schema; diff --git a/client/src/containers/Items/ItemFormBody.js b/client/src/containers/Items/ItemFormBody.js index 9750123e5..c33019628 100644 --- a/client/src/containers/Items/ItemFormBody.js +++ b/client/src/containers/Items/ItemFormBody.js @@ -57,7 +57,6 @@ function ItemFormBody({ accountsList, baseCurrency }) { { @@ -132,7 +131,6 @@ function ItemFormBody({ accountsList, baseCurrency }) { { diff --git a/client/src/containers/Items/ItemFormInventorySection.js b/client/src/containers/Items/ItemFormInventorySection.js index 42fa52166..f595635cc 100644 --- a/client/src/containers/Items/ItemFormInventorySection.js +++ b/client/src/containers/Items/ItemFormInventorySection.js @@ -1,18 +1,37 @@ import React from 'react'; import { FastField, ErrorMessage } from 'formik'; -import { FormGroup, InputGroup, Position } from '@blueprintjs/core'; +import { + FormGroup, + InputGroup, + ControlGroup, + Position, +} from '@blueprintjs/core'; import { DateInput } from '@blueprintjs/datetime'; -import { AccountsSelectList, Col, Row, Hint } from 'components'; +import { + AccountsSelectList, + MoneyInputGroup, + InputPrependText, + Col, + Row, + Hint, +} from 'components'; import { CLASSES } from 'common/classes'; import { FormattedMessage as T } from 'react-intl'; import classNames from 'classnames'; import withAccounts from 'containers/Accounts/withAccounts'; -import { compose, tansformDateValue, momentFormatter, inputIntent } from 'utils'; +import withSettings from 'containers/Settings/withSettings'; +import { + compose, + tansformDateValue, + momentFormatter, + inputIntent, + handleDateChange, +} from 'utils'; /** * Item form inventory sections. */ -function ItemFormInventorySection({ accountsList }) { +function ItemFormInventorySection({ accountsList, baseCurrency }) { return (

@@ -47,23 +66,23 @@ function ItemFormInventorySection({ accountsList }) { )} + {/*------------- Opening quantity ------------- */} - {({ field, field: { value }, meta: { touched, error } }) => ( + {({ field, meta: { touched, error } }) => ( } labelInfo={} className={'form-group--opening_quantity'} intent={inputIntent({ error, touched })} + helperText={} inline={true} > - + )} + {/*------------- Opening date ------------- */} {({ form, field: { value }, meta: { touched, error } }) => ( } inline={true} > { + onChange={handleDateChange((value) => { form.setFieldValue('opening_date', value); - }} + })} + helperText={} popoverProps={{ position: Position.BOTTOM, minimal: true }} /> @@ -90,20 +111,28 @@ function ItemFormInventorySection({ accountsList }) { + {/*------------- Opening cost ------------- */} - - {({ field, field: { value }, meta: { touched, error } }) => ( + + {({ form, field: { value }, meta: { touched, error } }) => ( } labelInfo={} - className={'form-group--opening_average_rate'} + className={'form-group--opening_cost'} intent={inputIntent({ error, touched })} + helperText={} inline={true} > - + + + { + form.setFieldValue('opening_cost', unformattedValue); + }} + /> + )} @@ -117,4 +146,7 @@ export default compose( withAccounts(({ accountsList }) => ({ accountsList, })), + withSettings(({ organizationSettings }) => ({ + baseCurrency: organizationSettings?.baseCurrency, + })), )(ItemFormInventorySection); diff --git a/client/src/containers/Items/ItemsDataTable.js b/client/src/containers/Items/ItemsDataTable.js index 09a9736f1..7b1d8f925 100644 --- a/client/src/containers/Items/ItemsDataTable.js +++ b/client/src/containers/Items/ItemsDataTable.js @@ -124,6 +124,14 @@ function ItemsDataTable({ ], ); + const quantityonHandCell = ({ value: quantity }) => { + return quantity <= 0 ? ( + {quantity} + ) : ( + {quantity} + ); + }; + const handleRowContextMenu = useCallback( (cell) => { return actionMenuList(cell.row.original); @@ -189,13 +197,7 @@ function ItemsDataTable({ { Header: formatMessage({ id: 'quantity_on_hand' }), accessor: 'quantity_on_hand', - className: 'quantity_on_hand', - width: 140, - }, - { - Header: formatMessage({ id: 'average_rate' }), - accessor: 'average_cost_rate', - className: 'average_cost_rate', + Cell: quantityonHandCell, width: 140, }, { diff --git a/client/src/lang/en/index.js b/client/src/lang/en/index.js index 8a825ad04..757673bac 100644 --- a/client/src/lang/en/index.js +++ b/client/src/lang/en/index.js @@ -100,6 +100,7 @@ export default { inventory_information: 'Inventory Information', inventory_account: 'Inventory Account', opening_quantity: 'Opening quantity', + opening_cost: 'Opening cost', save: 'Save', save_as_draft: 'Save as Draft', active: 'Active', @@ -928,5 +929,9 @@ export default { 'Are you sure you want to activate this item? You will be able to inactivate it later', inactivate_item: 'Inactivate Item', activate_item: 'Activate Item', - all_payments:'All Payments' + all_payments: 'All Payments', + opening_quantity_: 'Opening quantity', + opening_average_cost: 'Opening average cost', + opening_cost_: 'Opening cost ', + opening_date_: 'Opening date ', }; diff --git a/client/src/style/pages/items.scss b/client/src/style/pages/items.scss index 383b524a0..0e4287f67 100644 --- a/client/src/style/pages/items.scss +++ b/client/src/style/pages/items.scss @@ -95,6 +95,9 @@ color: #9eaab6; } } + .quantity_on_hand { + color: #ff0000; + } } } }