import React, { useState, useMemo, useCallback,useEffect } from 'react'; import * as Yup from 'yup'; import { useFormik } from 'formik'; import { FormGroup, MenuItem, Intent, InputGroup, HTMLSelect, Button, Classes, Checkbox, } from '@blueprintjs/core'; import { Row, Col } from 'react-grid-system'; import { FormattedMessage as T, useIntl } from 'react-intl'; import { Select } from '@blueprintjs/select'; import { queryCache } from 'react-query'; import {useParams ,useHistory} from 'react-router-dom'; import AppToaster from 'components/AppToaster'; import { compose } from 'utils'; import ErrorMessage from 'components/ErrorMessage'; import classNames from 'classnames'; import Icon from 'components/Icon'; import withItemsActions from 'containers/Items/withItemsActions'; import withItemCategories from 'containers/Items/withItemCategories' import withAccounts from 'containers/Accounts/withAccounts'; import withMediaActions from 'containers/Media/withMediaActions'; import MoneyInputGroup from 'components/MoneyInputGroup'; import Dragzone from 'components/Dragzone'; import useMedia from 'hooks/useMedia'; import withItems from './withItems'; import withItemDetail from 'containers/Items/withItemDetail' import { pick } from 'lodash'; import withDashboardActions from 'containers/Dashboard/withDashboard'; import withAccountDetail from 'containers/Accounts/withAccountDetail'; const ItemForm = ({ // #withItemActions requestSubmitItem, requestEditItem, accounts, itemDetail, onFormSubmit, onCancelForm, // #withDashboard changePageTitle, // #withItemCategories categoriesList, // #withMediaActions requestSubmitMedia, requestDeleteMedia, }) => { const [selectedAccounts, setSelectedAccounts] = useState({}); const [payload, setPayload] = useState({}); const history = useHistory(); const { formatMessage } = useIntl(); const {id} =useParams(); const { files, setFiles, saveMedia, deletedFiles, setDeletedFiles, deleteMedia, } = useMedia({ saveCallback: requestSubmitMedia, deleteCallback: requestDeleteMedia, }); const ItemTypeDisplay = useMemo(() => [ { value: null, label: formatMessage({id:'select_item_type'}) }, { value: 'service', label: formatMessage({id:'service'}) }, { value: 'inventory', label: formatMessage({id:'inventory'}) }, { value: 'non-inventory', label: formatMessage({id:'non_inventory'}) }, ], []); const validationSchema = Yup.object().shape({ active: Yup.boolean(), name: Yup.string().required().label(formatMessage({id:'item_name_'})), type: Yup.string().trim().required().label(formatMessage({id:'item_type_'})), sku: Yup.string().trim(), cost_price: Yup.number(), sell_price: Yup.number(), cost_account_id: Yup.number().required().label(formatMessage({id:'cost_account_id'})), sell_account_id: Yup.number().required().label(formatMessage({id:'sell_account_id'})), inventory_account_id: Yup.number().when('type', { is: (value) => value === 'inventory', then: Yup.number().required(), otherwise: Yup.number().nullable(), }), category_id: Yup.number().nullable(), stock: Yup.string() || Yup.boolean(), }); const defaultInitialValues = useMemo( () => ({ active: true, name: '', type: '', sku: '', cost_price: 0, sell_price: 0, cost_account_id: null, sell_account_id: null, inventory_account_id: null, category_id: null, note: '', }), [] ); const initialValues = useMemo(() => ({ ...(itemDetail) ? { ...pick(itemDetail, Object.keys(defaultInitialValues)), } : { ...defaultInitialValues, } }), [itemDetail, defaultInitialValues]); const saveInvokeSubmit = useCallback((payload) => { onFormSubmit && onFormSubmit(payload) }, [onFormSubmit]); useEffect(() => { itemDetail && itemDetail.id ? changePageTitle(formatMessage({id:'edit_item_details'})) : changePageTitle(formatMessage({id:'new_item'})); }, [changePageTitle,itemDetail]); const { getFieldProps, setFieldValue, values, touched, errors, handleSubmit, isSubmitting, } = useFormik({ enableReinitialize: true, validationSchema: validationSchema, initialValues: { ...initialValues, }, onSubmit: (values, { setSubmitting,resetForm,setErrors }) => { const saveItem = (mediaIds) => { const formValues = { ...values, media_ids: mediaIds }; if(itemDetail && itemDetail.id ){ requestEditItem(itemDetail.id,formValues) .then((response)=>{ AppToaster.show({ message:formatMessage({ id:'the_item_has_been_successfully_edited', },{ number:itemDetail.id }), intent:Intent.SUCCESS }); setSubmitting(false); saveInvokeSubmit({action:'update',...payload}) history.push('/items'); resetForm(); }).catch((errors)=>{ setSubmitting(false) }); }else{ requestSubmitItem(formValues).then((response) => { AppToaster.show({ message: formatMessage({ id: 'service_has_been_successful_created', }, { name: values.name, service: formatMessage({ id: 'item' }), }), intent: Intent.SUCCESS, }); queryCache.removeQueries(['items-table']); history.push('/items'); }); }; } Promise.all([saveMedia(), deleteMedia()]).then( ([savedMediaResponses]) => { const mediaIds = savedMediaResponses.map((res) => res.data.media.id); return saveItem(mediaIds); } ); }, }); const accountItem = useCallback( (item, { handleClick }) => ( ), [] ); // Filter Account Items const filterAccounts = (query, account, _index, exactMatch) => { const normalizedTitle = account.name.toLowerCase(); const normalizedQuery = query.toLowerCase(); if (exactMatch) { return normalizedTitle === normalizedQuery; } else { return `${account.code} ${normalizedTitle}`.indexOf(normalizedQuery) >= 0; } }; const onItemAccountSelect = useCallback( (filedName) => { return (account) => { setSelectedAccounts({ ...selectedAccounts, [filedName]: account, }); setFieldValue(filedName, account.id); }; }, [setFieldValue, selectedAccounts] ); const categoryItem = useCallback( (item, { handleClick }) => ( ), [] ); const getSelectedAccountLabel = useCallback( (fieldName, defaultLabel) => { return typeof selectedAccounts[fieldName] !== 'undefined' ? selectedAccounts[fieldName].name : defaultLabel; }, [selectedAccounts] ); const requiredSpan = useMemo(() => *, []); const infoIcon = useMemo(() => , []); const handleMoneyInputChange = (fieldKey) => (e, value) => { setFieldValue(fieldKey, value); }; const initialAttachmentFiles =useMemo(()=>{ return itemDetail && itemDetail.media ? itemDetail.media.map((attach)=>({ preview:attach.attachment_file, upload:true, metadata:{...attach} })):[]; },[itemDetail]) const handleDropFiles = useCallback((_files) => { setFiles(_files.filter((file) => file.uploaded === false)); }, []); const handleDeleteFile = useCallback( (_deletedFiles) => { _deletedFiles.forEach((deletedFile) => { if (deletedFile.uploaded && deletedFile.metadata.id) { setDeletedFiles([...deletedFiles, deletedFile.metadata.id]); } }); }, [setDeletedFiles, deletedFiles] ); const handleCancelClickBtn = () => { history.goBack(); }; return (
} labelInfo={requiredSpan} className={'form-group--item-type'} intent={errors.type && touched.type && Intent.DANGER} helperText={ } inline={true} > } labelInfo={requiredSpan} className={'form-group--item-name'} intent={errors.name && touched.name && Intent.DANGER} helperText={ } inline={true} > } labelInfo={infoIcon} className={'form-group--item-sku'} intent={errors.sku && touched.sku && Intent.DANGER} helperText={ } inline={true} > } labelInfo={infoIcon} inline={true} intent={ errors.category_id && touched.category_id && Intent.DANGER } helperText={ } className={classNames( 'form-group--select-list', 'form-group--category', Classes.FILL )} > } defaultChecked={values.active} {...getFieldProps('active')} />

} className={'form-group--item-selling-price'} intent={ errors.selling_price && touched.selling_price && Intent.DANGER } helperText={ } inline={true} > } labelInfo={infoIcon} inline={true} intent={ errors.sell_account_id && touched.sell_account_id && Intent.DANGER } helperText={ } className={classNames( 'form-group--sell-account', 'form-group--select-list', Classes.FILL )} >

} className={'form-group--item-cost-price'} intent={errors.cost_price && touched.cost_price && Intent.DANGER} helperText={ } inline={true} > } labelInfo={infoIcon} inline={true} intent={ errors.cost_account_id && touched.cost_account_id && Intent.DANGER } helperText={ } className={classNames( 'form-group--cost-account', 'form-group--select-list', Classes.FILL )} >

} inline={true} intent={ errors.inventory_account_id && touched.inventory_account_id && Intent.DANGER } helperText={ } className={classNames( 'form-group--item-inventory_account', 'form-group--select-list', Classes.FILL )} > } className={'form-group--item-stock'} inline={true} >
); }; export default compose( withAccounts(({accounts})=>({ accounts, })), withAccountDetail, withItemsActions, withItemDetail, withItemCategories(({ categoriesList }) => ({ categoriesList, })), withDashboardActions, withMediaActions, )(ItemForm);