Feature/wms 50 (#57)
* create warehouse * edit warehouse changes * Update: linted and formatted * add warehouse button * user access changes * basic table component changes * Updated: eslint errors * basic table component changes * update: linted * add New Product form api integrate * add new product changes * textarea changes * Linted code * Fix: image preview placeholder Co-authored-by: [Diksha] <[diksha39511@gmail.com]> Co-authored-by: Llewellyn Dsouza <lledsouza2209@gmail.com>
This commit is contained in:
@@ -3,5 +3,6 @@ export default {
|
|||||||
GET_WAREHOUSE_DATA: '/warehouse/all?page=0&perPage=50',
|
GET_WAREHOUSE_DATA: '/warehouse/all?page=0&perPage=50',
|
||||||
CREATE_WAREHOUSE: '/warehouse/',
|
CREATE_WAREHOUSE: '/warehouse/',
|
||||||
GET_USERS_DATA: '/user/all?page=0&perPage=10',
|
GET_USERS_DATA: '/user/all?page=0&perPage=10',
|
||||||
|
ADD_PRODUCT: '/item/',
|
||||||
GET_ROLES_DATA: '/user-role/all?page=0&perPage=10'
|
GET_ROLES_DATA: '/user-role/all?page=0&perPage=10'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
/* eslint-disable complexity */
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Grid, TextareaAutosize, TextField, Box } from '@mui/material';
|
import { Grid, TextField, Box, FormHelperText, TextareaAutosize } from '@mui/material';
|
||||||
import { makeStyles } from '@mui/styles';
|
import { makeStyles } from '@mui/styles';
|
||||||
import DashboardNavbar from 'components/DashboardNavbar';
|
import DashboardNavbar from 'components/DashboardNavbar';
|
||||||
import DashboardLayout from 'layouts/DashboardLayout';
|
import DashboardLayout from 'layouts/DashboardLayout';
|
||||||
@@ -11,6 +12,13 @@ import MDButton from 'components/Button';
|
|||||||
import Dialog from '@mui/material/Dialog';
|
import Dialog from '@mui/material/Dialog';
|
||||||
import DialogContent from '@mui/material/DialogContent';
|
import DialogContent from '@mui/material/DialogContent';
|
||||||
import CrossIcon from 'assets/images/CrossIcon';
|
import CrossIcon from 'assets/images/CrossIcon';
|
||||||
|
import { useFormik } from 'formik';
|
||||||
|
import schema from 'services/ValidationServices';
|
||||||
|
import MDInput from 'components/MDInput';
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
|
import ProductActions from 'redux/ProductsRedux';
|
||||||
|
import { API } from 'constant';
|
||||||
|
import LOGGER from 'services/Logger';
|
||||||
|
|
||||||
const useStyles = makeStyles({
|
const useStyles = makeStyles({
|
||||||
labelSize: {
|
labelSize: {
|
||||||
@@ -23,7 +31,7 @@ const useStyles = makeStyles({
|
|||||||
textAreaSize: {
|
textAreaSize: {
|
||||||
width: '100% !important',
|
width: '100% !important',
|
||||||
resize: 'none',
|
resize: 'none',
|
||||||
height: '208px !important',
|
height: '203px !important',
|
||||||
boxSizing: 'border-box',
|
boxSizing: 'border-box',
|
||||||
border: '1px solid #C4C4C4',
|
border: '1px solid #C4C4C4',
|
||||||
borderRadius: '4px',
|
borderRadius: '4px',
|
||||||
@@ -33,11 +41,15 @@ const useStyles = makeStyles({
|
|||||||
cursor: 'pointer'
|
cursor: 'pointer'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const previewImg = [1, 2, 3];
|
|
||||||
|
const inventoryTypes = ['Perishable', 'Material', 'Product', 'Inventory', 'Fleet'];
|
||||||
|
|
||||||
function AddNewProduct() {
|
function AddNewProduct() {
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
|
const dispatch = useDispatch();
|
||||||
const [Manufacturer, setManufacturer] = React.useState('');
|
const [Manufacturer, setManufacturer] = React.useState('');
|
||||||
const [open, setOpen] = React.useState(false);
|
const [open, setOpen] = React.useState(false);
|
||||||
|
|
||||||
const handleClickOpen = () => {
|
const handleClickOpen = () => {
|
||||||
setOpen(true);
|
setOpen(true);
|
||||||
};
|
};
|
||||||
@@ -49,262 +61,501 @@ function AddNewProduct() {
|
|||||||
const handleChange = (event) => {
|
const handleChange = (event) => {
|
||||||
setManufacturer(event.target.value);
|
setManufacturer(event.target.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const formik = useFormik({
|
||||||
|
initialValues: {
|
||||||
|
warehousename: '',
|
||||||
|
description: '',
|
||||||
|
manufacturer: '',
|
||||||
|
type: '',
|
||||||
|
unitofmaterial: '',
|
||||||
|
packagecount: '',
|
||||||
|
formalname: '',
|
||||||
|
size: '',
|
||||||
|
color: '',
|
||||||
|
unitcost: '',
|
||||||
|
countperpallet: '',
|
||||||
|
countperpalletpackage: '',
|
||||||
|
productfamilyassociation: '',
|
||||||
|
under: '',
|
||||||
|
over: '',
|
||||||
|
alert: '',
|
||||||
|
images: []
|
||||||
|
},
|
||||||
|
validationSchema: schema.addNewProduct,
|
||||||
|
onSubmit: (values, onSubmitProps) => {
|
||||||
|
LOGGER.log('values', values);
|
||||||
|
dispatch(
|
||||||
|
ProductActions.addProductAction({
|
||||||
|
loader: 'loading-request',
|
||||||
|
slug: API.ADD_PRODUCT,
|
||||||
|
method: 'post',
|
||||||
|
data: {
|
||||||
|
commonName: values.warehousename,
|
||||||
|
formalName: values.formalname,
|
||||||
|
description: values.description,
|
||||||
|
manufacturer: values.manufacturer,
|
||||||
|
size: values.size,
|
||||||
|
color: values.color,
|
||||||
|
type: values.type,
|
||||||
|
unitOfMaterial: values.unitofmaterial,
|
||||||
|
unitCost: values.unitcost,
|
||||||
|
packageCount: values.packagecount,
|
||||||
|
countPerPallet: values.countperpallet,
|
||||||
|
countPerPalletPackage: values.countperpalletpackage,
|
||||||
|
customAttributes: [
|
||||||
|
{ fieldName: 'someName', fieldType: 'String', fieldValue: 'someValue' }
|
||||||
|
],
|
||||||
|
widgetFamilyId: '61dcdd10699e8f55b44c606d'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
onSubmitProps.resetForm();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DashboardLayout>
|
<DashboardLayout>
|
||||||
<DashboardNavbar />
|
<DashboardNavbar />
|
||||||
<Box mx={3} my={3}>
|
<Box mx={3} my={3}>
|
||||||
<Box sx={{ backgroundColor: '#fff', padding: '30px' }}>
|
<form onSubmit={formik.handleSubmit}>
|
||||||
<Grid container spacing={5}>
|
<Box sx={{ backgroundColor: '#fff', padding: '30px' }}>
|
||||||
<Grid item xs={12} sm={6} md={6}>
|
<Grid container spacing={5}>
|
||||||
<Box component="div" sx={{ marginBottom: '24px' }}>
|
<Grid item xs={12} sm={6} md={6}>
|
||||||
<Box component="div" className={classes.labelSize}>
|
<Box component="div" sx={{ marginBottom: '24px' }}>
|
||||||
Warehouse name
|
<Box component="div" className={classes.labelSize}>
|
||||||
|
Warehouse name
|
||||||
|
</Box>
|
||||||
|
<MDInput
|
||||||
|
fullWidth
|
||||||
|
name="warehousename"
|
||||||
|
type="text"
|
||||||
|
variant="outlined"
|
||||||
|
value={formik.values.warehousename}
|
||||||
|
error={formik.touched.warehousename && Boolean(formik.errors.warehousename)}
|
||||||
|
helperText={formik.touched.warehousename && formik.errors.warehousename}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<TextField fullWidth variant="outlined" />
|
<Box component="div" sx={{ marginBottom: '24px' }}>
|
||||||
</Box>
|
<Box component="div" className={classes.labelSize}>
|
||||||
<Box component="div" sx={{ marginBottom: '24px' }}>
|
Description
|
||||||
<Box component="div" className={classes.labelSize}>
|
</Box>
|
||||||
Description
|
<TextareaAutosize
|
||||||
|
variant="outlined"
|
||||||
|
name="description"
|
||||||
|
className={classes.textAreaSize}
|
||||||
|
value={formik.values.description}
|
||||||
|
error={formik.touched.description && Boolean(formik.errors.description)}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
/>
|
||||||
|
<FormHelperText>
|
||||||
|
{formik.errors.description &&
|
||||||
|
formik.touched.description &&
|
||||||
|
formik.errors.description}
|
||||||
|
</FormHelperText>
|
||||||
</Box>
|
</Box>
|
||||||
<TextareaAutosize className={classes.textAreaSize} />
|
<Box component="div" sx={{ marginBottom: '24px' }}>
|
||||||
</Box>
|
<Box component="div" className={classes.labelSize}>
|
||||||
<Box component="div" sx={{ marginBottom: '24px' }}>
|
Manufacturer
|
||||||
<Box component="div" className={classes.labelSize}>
|
</Box>
|
||||||
Manufacturer
|
<FormControl fullWidth>
|
||||||
|
<Select
|
||||||
|
select
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
name="manufacturer"
|
||||||
|
value={formik.values.manufacturer}
|
||||||
|
error={formik.touched.manufacturer && Boolean(formik.errors.manufacturer)}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
>
|
||||||
|
<MenuItem key={''} value={''}>
|
||||||
|
None Selected
|
||||||
|
</MenuItem>
|
||||||
|
{inventoryTypes.map((name) => (
|
||||||
|
<MenuItem key={name} value={name}>
|
||||||
|
{name}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
<FormHelperText>
|
||||||
|
{formik.errors.manufacturer &&
|
||||||
|
formik.touched.manufacturer &&
|
||||||
|
formik.errors.manufacturer}
|
||||||
|
</FormHelperText>
|
||||||
|
</FormControl>
|
||||||
</Box>
|
</Box>
|
||||||
<FormControl fullWidth>
|
<Box component="div" sx={{ marginBottom: '24px' }}>
|
||||||
<Select
|
<Box component="div" className={classes.labelSize}>
|
||||||
value={Manufacturer}
|
Type
|
||||||
renderValue={(selected) => {
|
</Box>
|
||||||
if (selected.length === 0) {
|
<FormControl fullWidth>
|
||||||
return <em>Placeholder</em>;
|
<Select
|
||||||
|
select
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
name="type"
|
||||||
|
value={formik.values.type}
|
||||||
|
error={formik.touched.type && Boolean(formik.errors.type)}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
>
|
||||||
|
<MenuItem key={''} value={''}>
|
||||||
|
None Selected
|
||||||
|
</MenuItem>
|
||||||
|
{inventoryTypes.map((name) => (
|
||||||
|
<MenuItem key={name} value={name}>
|
||||||
|
{name}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
<FormHelperText>
|
||||||
|
{formik.errors.type && formik.touched.type && formik.errors.type}
|
||||||
|
</FormHelperText>
|
||||||
|
</FormControl>
|
||||||
|
</Box>
|
||||||
|
<Box component="div" sx={{ marginBottom: '24px' }}>
|
||||||
|
<Box component="div" className={classes.labelSize}>
|
||||||
|
Unit of Material
|
||||||
|
</Box>
|
||||||
|
<FormControl fullWidth>
|
||||||
|
<Select
|
||||||
|
select
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
name="unitofmaterial"
|
||||||
|
value={formik.values.unitofmaterial}
|
||||||
|
error={
|
||||||
|
formik.touched.unitofmaterial && Boolean(formik.errors.unitofmaterial)
|
||||||
}
|
}
|
||||||
}}
|
onChange={formik.handleChange}
|
||||||
onChange={handleChange}
|
>
|
||||||
>
|
<MenuItem key={''} value={''}>
|
||||||
<MenuItem value={10}>Ten</MenuItem>
|
None Selected
|
||||||
<MenuItem value={20}>Twenty</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem value={30}>Thirty</MenuItem>
|
{inventoryTypes.map((name) => (
|
||||||
</Select>
|
<MenuItem key={name} value={name}>
|
||||||
</FormControl>
|
{name}
|
||||||
</Box>
|
</MenuItem>
|
||||||
<Box component="div" sx={{ marginBottom: '24px' }}>
|
))}
|
||||||
<Box component="div" className={classes.labelSize}>
|
</Select>
|
||||||
Type
|
<FormHelperText>
|
||||||
|
{formik.errors.unitofmaterial &&
|
||||||
|
formik.touched.unitofmaterial &&
|
||||||
|
formik.errors.unitofmaterial}
|
||||||
|
</FormHelperText>
|
||||||
|
</FormControl>
|
||||||
</Box>
|
</Box>
|
||||||
<FormControl fullWidth>
|
<Box component="div" sx={{ marginBottom: '24px' }}>
|
||||||
<Select
|
<Box component="div" className={classes.labelSize}>
|
||||||
value={Manufacturer}
|
Package Count
|
||||||
renderValue={(selected) => {
|
</Box>
|
||||||
if (selected.length === 0) {
|
<MDInput
|
||||||
return <em>Placeholder</em>;
|
fullWidth
|
||||||
|
name="packagecount"
|
||||||
|
type="text"
|
||||||
|
variant="outlined"
|
||||||
|
value={formik.values.packagecount}
|
||||||
|
error={formik.touched.packagecount && Boolean(formik.errors.packagecount)}
|
||||||
|
helperText={formik.touched.packagecount && formik.errors.packagecount}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} sm={6} md={6}>
|
||||||
|
<Box component="div" sx={{ marginBottom: '24px' }}>
|
||||||
|
<Box component="div" className={classes.labelSize}>
|
||||||
|
Formal Name
|
||||||
|
</Box>
|
||||||
|
<MDInput
|
||||||
|
fullWidth
|
||||||
|
name="formalname"
|
||||||
|
type="text"
|
||||||
|
variant="outlined"
|
||||||
|
value={formik.values.formalname}
|
||||||
|
error={formik.touched.formalname && Boolean(formik.errors.formalname)}
|
||||||
|
helperText={formik.touched.formalname && formik.errors.formalname}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box component="div" sx={{ marginBottom: '24px' }}>
|
||||||
|
<Box component="div" className={classes.labelSize}>
|
||||||
|
Size
|
||||||
|
</Box>
|
||||||
|
<FormControl fullWidth>
|
||||||
|
<Select
|
||||||
|
select
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
name="size"
|
||||||
|
value={formik.values.size}
|
||||||
|
error={formik.touched.size && Boolean(formik.errors.size)}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
>
|
||||||
|
<MenuItem key={''} value={''}>
|
||||||
|
None Selected
|
||||||
|
</MenuItem>
|
||||||
|
{inventoryTypes.map((name) => (
|
||||||
|
<MenuItem key={name} value={name}>
|
||||||
|
{name}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
<FormHelperText>
|
||||||
|
{formik.errors.size && formik.touched.size && formik.errors.size}
|
||||||
|
</FormHelperText>
|
||||||
|
</FormControl>
|
||||||
|
</Box>
|
||||||
|
<Box component="div" sx={{ marginBottom: '24px' }}>
|
||||||
|
<Box component="div" className={classes.labelSize}>
|
||||||
|
Color
|
||||||
|
</Box>
|
||||||
|
<FormControl fullWidth>
|
||||||
|
<Select
|
||||||
|
select
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
name="color"
|
||||||
|
value={formik.values.color}
|
||||||
|
error={formik.touched.color && Boolean(formik.errors.color)}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
>
|
||||||
|
<MenuItem key={''} value={''}>
|
||||||
|
None Selected
|
||||||
|
</MenuItem>
|
||||||
|
{inventoryTypes.map((name) => (
|
||||||
|
<MenuItem key={name} value={name}>
|
||||||
|
{name}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
<FormHelperText>
|
||||||
|
{formik.errors.color && formik.touched.color && formik.errors.color}
|
||||||
|
</FormHelperText>
|
||||||
|
</FormControl>
|
||||||
|
</Box>
|
||||||
|
<Box component="div" sx={{ marginBottom: '24px' }}>
|
||||||
|
<Box component="div" className={classes.labelSize}>
|
||||||
|
Unit Cost
|
||||||
|
</Box>
|
||||||
|
<MDInput
|
||||||
|
fullWidth
|
||||||
|
name="unitcost"
|
||||||
|
type="text"
|
||||||
|
variant="outlined"
|
||||||
|
value={formik.values.unitcost}
|
||||||
|
error={formik.touched.unitcost && Boolean(formik.errors.unitcost)}
|
||||||
|
helperText={formik.touched.unitcost && formik.errors.unitcost}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box component="div" sx={{ marginBottom: '24px' }}>
|
||||||
|
<Box component="div" className={classes.labelSize}>
|
||||||
|
Count per Pallet
|
||||||
|
</Box>
|
||||||
|
<MDInput
|
||||||
|
fullWidth
|
||||||
|
name="countperpallet"
|
||||||
|
type="text"
|
||||||
|
variant="outlined"
|
||||||
|
value={formik.values.countperpallet}
|
||||||
|
error={formik.touched.countperpallet && Boolean(formik.errors.countperpallet)}
|
||||||
|
helperText={formik.touched.countperpallet && formik.errors.countperpallet}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box component="div" sx={{ marginBottom: '24px' }}>
|
||||||
|
<Box component="div" className={classes.labelSize}>
|
||||||
|
Count per Pallet Package
|
||||||
|
</Box>
|
||||||
|
<MDInput
|
||||||
|
fullWidth
|
||||||
|
name="countperpalletpackage"
|
||||||
|
type="text"
|
||||||
|
variant="outlined"
|
||||||
|
value={formik.values.countperpalletpackage}
|
||||||
|
error={
|
||||||
|
formik.touched.countperpalletpackage &&
|
||||||
|
Boolean(formik.errors.countperpalletpackage)
|
||||||
|
}
|
||||||
|
helperText={
|
||||||
|
formik.touched.countperpalletpackage && formik.errors.countperpalletpackage
|
||||||
|
}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box component="div" sx={{ marginBottom: '24px' }}>
|
||||||
|
<Box component="div" className={classes.labelSize}>
|
||||||
|
Product Family Association
|
||||||
|
</Box>
|
||||||
|
<FormControl fullWidth sx={{ marginBottom: '32px' }}>
|
||||||
|
<Select
|
||||||
|
select
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
name="productfamilyassociation"
|
||||||
|
value={formik.values.productfamilyassociation}
|
||||||
|
error={
|
||||||
|
formik.touched.productfamilyassociation &&
|
||||||
|
Boolean(formik.errors.productfamilyassociation)
|
||||||
}
|
}
|
||||||
}}
|
onChange={formik.handleChange}
|
||||||
onChange={handleChange}
|
>
|
||||||
>
|
<MenuItem key={''} value={''}>
|
||||||
<MenuItem value={10}>Ten</MenuItem>
|
None Selected
|
||||||
<MenuItem value={20}>Twenty</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem value={30}>Thirty</MenuItem>
|
{inventoryTypes.map((name) => (
|
||||||
</Select>
|
<MenuItem key={name} value={name}>
|
||||||
</FormControl>
|
{name}
|
||||||
</Box>
|
</MenuItem>
|
||||||
<Box component="div" sx={{ marginBottom: '24px' }}>
|
))}
|
||||||
<Box component="div" className={classes.labelSize}>
|
</Select>
|
||||||
Unit of Material
|
<FormHelperText>
|
||||||
</Box>
|
{formik.errors.productfamilyassociation &&
|
||||||
<FormControl fullWidth>
|
formik.touched.productfamilyassociation &&
|
||||||
<Select
|
formik.errors.productfamilyassociation}
|
||||||
value={Manufacturer}
|
</FormHelperText>
|
||||||
renderValue={(selected) => {
|
</FormControl>
|
||||||
if (selected.length === 0) {
|
<FormControl fullWidth>
|
||||||
return <em>Placeholder</em>;
|
<Select
|
||||||
|
select
|
||||||
|
fullWidth
|
||||||
|
variant="outlined"
|
||||||
|
name="productfamilyassociation"
|
||||||
|
value={formik.values.productfamilyassociation}
|
||||||
|
error={
|
||||||
|
formik.touched.productfamilyassociation &&
|
||||||
|
Boolean(formik.errors.productfamilyassociation)
|
||||||
}
|
}
|
||||||
}}
|
onChange={formik.handleChange}
|
||||||
onChange={handleChange}
|
>
|
||||||
>
|
<MenuItem key={''} value={''}>
|
||||||
<MenuItem value={10}>Ten</MenuItem>
|
None Selected
|
||||||
<MenuItem value={20}>Twenty</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem value={30}>Thirty</MenuItem>
|
{inventoryTypes.map((name) => (
|
||||||
</Select>
|
<MenuItem key={name} value={name}>
|
||||||
</FormControl>
|
{name}
|
||||||
</Box>
|
</MenuItem>
|
||||||
<Box component="div" sx={{ marginBottom: '24px' }}>
|
))}
|
||||||
<Box component="div" className={classes.labelSize}>
|
</Select>
|
||||||
Package Count
|
<FormHelperText>
|
||||||
|
{formik.errors.productfamilyassociation &&
|
||||||
|
formik.touched.productfamilyassociation &&
|
||||||
|
formik.errors.productfamilyassociation}
|
||||||
|
</FormHelperText>
|
||||||
|
</FormControl>
|
||||||
</Box>
|
</Box>
|
||||||
<TextField fullWidth variant="outlined" />
|
</Grid>
|
||||||
</Box>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} sm={6} md={6}>
|
|
||||||
<Box component="div" sx={{ marginBottom: '24px' }}>
|
|
||||||
<Box component="div" className={classes.labelSize}>
|
|
||||||
Formal Name
|
|
||||||
</Box>
|
|
||||||
<TextField fullWidth variant="outlined" />
|
|
||||||
</Box>
|
|
||||||
<Box component="div" sx={{ marginBottom: '24px' }}>
|
|
||||||
<Box component="div" className={classes.labelSize}>
|
|
||||||
Size
|
|
||||||
</Box>
|
|
||||||
<FormControl fullWidth>
|
|
||||||
<Select
|
|
||||||
value={Manufacturer}
|
|
||||||
renderValue={(selected) => {
|
|
||||||
if (selected.length === 0) {
|
|
||||||
return <em>Placeholder</em>;
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onChange={handleChange}
|
|
||||||
>
|
|
||||||
<MenuItem value={10}>Ten</MenuItem>
|
|
||||||
<MenuItem value={20}>Twenty</MenuItem>
|
|
||||||
<MenuItem value={30}>Thirty</MenuItem>
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
</Box>
|
|
||||||
<Box component="div" sx={{ marginBottom: '24px' }}>
|
|
||||||
<Box component="div" className={classes.labelSize}>
|
|
||||||
Color
|
|
||||||
</Box>
|
|
||||||
<FormControl fullWidth>
|
|
||||||
<Select
|
|
||||||
value={Manufacturer}
|
|
||||||
renderValue={(selected) => {
|
|
||||||
if (selected.length === 0) {
|
|
||||||
return <em>Placeholder</em>;
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onChange={handleChange}
|
|
||||||
>
|
|
||||||
<MenuItem value={10}>Ten</MenuItem>
|
|
||||||
<MenuItem value={20}>Twenty</MenuItem>
|
|
||||||
<MenuItem value={30}>Thirty</MenuItem>
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
</Box>
|
|
||||||
<Box component="div" sx={{ marginBottom: '24px' }}>
|
|
||||||
<Box component="div" className={classes.labelSize}>
|
|
||||||
Unit Cost
|
|
||||||
</Box>
|
|
||||||
<TextField fullWidth variant="outlined" />
|
|
||||||
</Box>
|
|
||||||
<Box component="div" sx={{ marginBottom: '24px' }}>
|
|
||||||
<Box component="div" className={classes.labelSize}>
|
|
||||||
Count per Pallet
|
|
||||||
</Box>
|
|
||||||
<TextField fullWidth variant="outlined" />
|
|
||||||
</Box>
|
|
||||||
<Box component="div" sx={{ marginBottom: '24px' }}>
|
|
||||||
<Box component="div" className={classes.labelSize}>
|
|
||||||
Count per Pallet Package
|
|
||||||
</Box>
|
|
||||||
<TextField fullWidth variant="outlined" />
|
|
||||||
</Box>
|
|
||||||
<Box component="div" sx={{ marginBottom: '24px' }}>
|
|
||||||
<Box component="div" className={classes.labelSize}>
|
|
||||||
Product Family Association
|
|
||||||
</Box>
|
|
||||||
<FormControl fullWidth sx={{ marginBottom: '32px' }}>
|
|
||||||
<Select
|
|
||||||
value={Manufacturer}
|
|
||||||
renderValue={(selected) => {
|
|
||||||
if (selected.length === 0) {
|
|
||||||
return <em>Placeholder</em>;
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onChange={handleChange}
|
|
||||||
>
|
|
||||||
<MenuItem value={10}>Ten</MenuItem>
|
|
||||||
<MenuItem value={20}>Twenty</MenuItem>
|
|
||||||
<MenuItem value={30}>Thirty</MenuItem>
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
<FormControl fullWidth>
|
|
||||||
<Select
|
|
||||||
value={Manufacturer}
|
|
||||||
renderValue={(selected) => {
|
|
||||||
if (selected.length === 0) {
|
|
||||||
return <em>Placeholder</em>;
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onChange={handleChange}
|
|
||||||
>
|
|
||||||
<MenuItem value={10}>Ten</MenuItem>
|
|
||||||
<MenuItem value={20}>Twenty</MenuItem>
|
|
||||||
<MenuItem value={30}>Thirty</MenuItem>
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
</Box>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
<Box>
|
|
||||||
<ImageUpload heading="Upload Warehouse Image" previewImg={previewImg} />
|
|
||||||
</Box>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: 'flex',
|
|
||||||
justifyContent: 'center',
|
|
||||||
columnGap: '20px',
|
|
||||||
marginTop: '30px',
|
|
||||||
marginBottom: '30px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<MDButton size="large" color="primary" variant="outlined" onClick={handleClickOpen}>
|
|
||||||
add custom fields
|
|
||||||
</MDButton>
|
|
||||||
<MDButton size="large" color="primary" variant="outlined">
|
|
||||||
import
|
|
||||||
</MDButton>
|
|
||||||
</Box>
|
|
||||||
<Box
|
|
||||||
component="div"
|
|
||||||
sx={{
|
|
||||||
marginBottom: '30px',
|
|
||||||
paddingBottom: '24px',
|
|
||||||
borderBottom: '1px solid #C2C2C2',
|
|
||||||
color: '#000'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Stock Level Triggers
|
|
||||||
</Box>
|
|
||||||
<Box sx={{ display: 'flex', width: '50%', columnGap: '24px', marginBottom: '30px' }}>
|
|
||||||
<Box>
|
<Box>
|
||||||
<Box component="div" className={classes.labelSize}>
|
<ImageUpload
|
||||||
Under
|
multiple
|
||||||
</Box>
|
heading="Upload Product Image"
|
||||||
<TextField fullWidth variant="outlined" type="number" />
|
accept="image/*"
|
||||||
|
images={formik.values.images}
|
||||||
|
setImages={(images) => {
|
||||||
|
formik.setFieldValue('images', images);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box
|
||||||
<Box component="div" className={classes.labelSize}>
|
sx={{
|
||||||
Over
|
display: 'flex',
|
||||||
</Box>
|
justifyContent: 'center',
|
||||||
<TextField fullWidth variant="outlined" type="number" />
|
columnGap: '20px',
|
||||||
|
marginTop: '30px',
|
||||||
|
marginBottom: '30px'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MDButton
|
||||||
|
disabled
|
||||||
|
size="large"
|
||||||
|
color="primary"
|
||||||
|
variant="outlined"
|
||||||
|
onClick={handleClickOpen}
|
||||||
|
>
|
||||||
|
add custom fields
|
||||||
|
</MDButton>
|
||||||
|
<MDButton disabled size="large" color="primary" variant="outlined">
|
||||||
|
import
|
||||||
|
</MDButton>
|
||||||
</Box>
|
</Box>
|
||||||
<Box>
|
<Box
|
||||||
<Box component="div" className={classes.labelSize}>
|
component="div"
|
||||||
Alert
|
sx={{
|
||||||
|
marginBottom: '30px',
|
||||||
|
paddingBottom: '24px',
|
||||||
|
borderBottom: '1px solid #C2C2C2',
|
||||||
|
color: '#000'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Stock Level Triggers
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ display: 'flex', width: '50%', columnGap: '24px', marginBottom: '30px' }}>
|
||||||
|
<Box>
|
||||||
|
<Box component="div" className={classes.labelSize}>
|
||||||
|
Under
|
||||||
|
</Box>
|
||||||
|
<MDInput
|
||||||
|
fullWidth
|
||||||
|
name="under"
|
||||||
|
type="number"
|
||||||
|
variant="outlined"
|
||||||
|
value={formik.values.under}
|
||||||
|
error={formik.touched.under && Boolean(formik.errors.under)}
|
||||||
|
helperText={formik.touched.under && formik.errors.under}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<TextField fullWidth variant="outlined" type="number" />
|
<Box>
|
||||||
|
<Box component="div" className={classes.labelSize}>
|
||||||
|
Over
|
||||||
|
</Box>
|
||||||
|
<MDInput
|
||||||
|
fullWidth
|
||||||
|
name="over"
|
||||||
|
type="number"
|
||||||
|
variant="outlined"
|
||||||
|
value={formik.values.over}
|
||||||
|
error={formik.touched.over && Boolean(formik.errors.over)}
|
||||||
|
helperText={formik.touched.over && formik.errors.over}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<Box component="div" className={classes.labelSize}>
|
||||||
|
Alert
|
||||||
|
</Box>
|
||||||
|
<MDInput
|
||||||
|
fullWidth
|
||||||
|
name="alert"
|
||||||
|
type="number"
|
||||||
|
variant="outlined"
|
||||||
|
value={formik.values.alert}
|
||||||
|
error={formik.touched.alert && Boolean(formik.errors.alert)}
|
||||||
|
helperText={formik.touched.alert && formik.errors.alert}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'center',
|
||||||
|
columnGap: '20px',
|
||||||
|
marginTop: '72px',
|
||||||
|
marginBottom: '30px'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MDButton size="medium" color="error" variant="outlined">
|
||||||
|
cancel
|
||||||
|
</MDButton>
|
||||||
|
<MDButton size="medium" color="primary" variant="contained" type="submit">
|
||||||
|
add ITem
|
||||||
|
</MDButton>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
<Box
|
</form>
|
||||||
sx={{
|
|
||||||
display: 'flex',
|
|
||||||
justifyContent: 'center',
|
|
||||||
columnGap: '20px',
|
|
||||||
marginTop: '72px',
|
|
||||||
marginBottom: '30px'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<MDButton size="medium" color="error" variant="outlined">
|
|
||||||
cancel
|
|
||||||
</MDButton>
|
|
||||||
<MDButton size="medium" color="primary" variant="contained">
|
|
||||||
add ITem
|
|
||||||
</MDButton>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
</Box>
|
||||||
</DashboardLayout>
|
</DashboardLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ function SetupInventory() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Products',
|
name: 'Products',
|
||||||
path: { update: '/', addNew: '/setup/inventory/inventory-new', cycleCount: '/', list: '/' },
|
path: { update: '/', addNew: '/setup/inventory/product/add-new-product', cycleCount: '/', list: '/' },
|
||||||
icon: <ProductsIcon />
|
icon: <ProductsIcon />
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
54
src/redux/ProductsRedux.js
Normal file
54
src/redux/ProductsRedux.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import { createActions, createReducer } from 'reduxsauce';
|
||||||
|
import Immutable from 'seamless-immutable';
|
||||||
|
import _ from 'underscore';
|
||||||
|
import { getFetchingValue, getErrorValue } from '../services/Utils';
|
||||||
|
|
||||||
|
/* ------------- Types and Action Creators ------------- */
|
||||||
|
const { Types, Creators } = createActions({
|
||||||
|
addProductAction: ['payload'],
|
||||||
|
addProductSuccess: ['data'],
|
||||||
|
addProductFailure: ['error']
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ProductTypes = Types;
|
||||||
|
const ProductActions = Creators;
|
||||||
|
export default ProductActions;
|
||||||
|
|
||||||
|
/* ------------- Initial State ------------- */
|
||||||
|
export const INITIAL_STATE = Immutable({
|
||||||
|
addProductDetail: [],
|
||||||
|
addProductLoading: false,
|
||||||
|
addProducterror: {}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* ------------- Selectors ------------- */
|
||||||
|
export const ProductSelectors = {
|
||||||
|
addProductDetail: (state) => state.product.productDetail
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ------------- Reducers ------------- */
|
||||||
|
export const onAddProductAction = (state, { payload }) =>
|
||||||
|
state.merge({
|
||||||
|
fetching: _.uniq([state.fetching, payload?.loader]),
|
||||||
|
error: getErrorValue(state?.error, payload?.loader)
|
||||||
|
});
|
||||||
|
|
||||||
|
export const onAddProductSuccess = (state, { data }) =>
|
||||||
|
state.merge({
|
||||||
|
fetching: getFetchingValue(state.fetching, data?.loader),
|
||||||
|
error: getErrorValue(state?.error, data?.loader),
|
||||||
|
addProductDetail: data.addProductDetail
|
||||||
|
});
|
||||||
|
|
||||||
|
export const onAddProductFailure = (state, { error }) =>
|
||||||
|
state.merge({
|
||||||
|
fetching: _.without(state.fetching, error?.loader),
|
||||||
|
error: { ...state.error, [error?.loader]: error?.error }
|
||||||
|
});
|
||||||
|
|
||||||
|
/* ------------- Hookup Reducers To Types ------------- */
|
||||||
|
export const productReducer = createReducer(INITIAL_STATE, {
|
||||||
|
[Types.ADD_PRODUCT_ACTION]: onAddProductAction,
|
||||||
|
[Types.ADD_PRODUCT_SUCCESS]: onAddProductSuccess,
|
||||||
|
[Types.ADD_PRODUCT_FAILURE]: onAddProductFailure
|
||||||
|
});
|
||||||
@@ -2,6 +2,7 @@ import { combineReducers } from 'redux';
|
|||||||
import { authReducer } from './AuthRedux';
|
import { authReducer } from './AuthRedux';
|
||||||
import { warehouseReducer } from './WarehouseRedux';
|
import { warehouseReducer } from './WarehouseRedux';
|
||||||
import { usersReducer } from './UsersRedux';
|
import { usersReducer } from './UsersRedux';
|
||||||
|
import { productReducer } from './ProductsRedux';
|
||||||
import { rolesReducer } from './RolesRedux';
|
import { rolesReducer } from './RolesRedux';
|
||||||
|
|
||||||
// Combine all reducers.
|
// Combine all reducers.
|
||||||
@@ -9,6 +10,7 @@ const appReducer = combineReducers({
|
|||||||
auth: authReducer,
|
auth: authReducer,
|
||||||
warehouse: warehouseReducer,
|
warehouse: warehouseReducer,
|
||||||
users: usersReducer,
|
users: usersReducer,
|
||||||
|
product: productReducer,
|
||||||
roles: rolesReducer
|
roles: rolesReducer
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
31
src/sagas/Product.js
Normal file
31
src/sagas/Product.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { AuthorizedAPI } from 'config';
|
||||||
|
import { takeLatest, call, put } from 'redux-saga/effects';
|
||||||
|
import ProductActions from 'redux/ProductsRedux';
|
||||||
|
import { ProductTypes } from 'redux/ProductsRedux';
|
||||||
|
import ApiServices from 'services/API/ApiServices';
|
||||||
|
|
||||||
|
export function* onRequestAddProductData({ payload }) {
|
||||||
|
const response = yield call(
|
||||||
|
ApiServices[payload?.method],
|
||||||
|
AuthorizedAPI,
|
||||||
|
payload?.slug,
|
||||||
|
payload?.data
|
||||||
|
);
|
||||||
|
if (response?.status === 200) {
|
||||||
|
yield put(
|
||||||
|
ProductActions.addProductSuccess({
|
||||||
|
loader: payload?.loader,
|
||||||
|
addProductDetail: response?.data?.data
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
payload.onFailedAddProductData(response.data.error);
|
||||||
|
yield put(
|
||||||
|
ProductActions.addProductFailure({
|
||||||
|
loader: payload?.loader,
|
||||||
|
error: response?.data
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default [takeLatest(ProductTypes.ADD_PRODUCT_ACTION, onRequestAddProductData)];
|
||||||
@@ -2,11 +2,13 @@ import { all } from 'redux-saga/effects';
|
|||||||
import AuthSaga from './Auth';
|
import AuthSaga from './Auth';
|
||||||
import WarehouseSaga from './Warehouse';
|
import WarehouseSaga from './Warehouse';
|
||||||
import UsersSaga from './Users';
|
import UsersSaga from './Users';
|
||||||
|
import ProductSaga from './Product';
|
||||||
import RolesSaga from './Roles';
|
import RolesSaga from './Roles';
|
||||||
|
|
||||||
export default function* rootSaga() {
|
export default function* rootSaga() {
|
||||||
yield all([...AuthSaga]);
|
yield all([...AuthSaga]);
|
||||||
yield all([...WarehouseSaga]);
|
yield all([...WarehouseSaga]);
|
||||||
yield all([...UsersSaga]);
|
yield all([...UsersSaga]);
|
||||||
|
yield all([...ProductSaga]);
|
||||||
yield all([...RolesSaga]);
|
yield all([...RolesSaga]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,33 @@ const schema = {
|
|||||||
warehouseForm: Yup.object({
|
warehouseForm: Yup.object({
|
||||||
warehousename: Yup.string('Enter warehouse name').required('warehouse name is required'),
|
warehousename: Yup.string('Enter warehouse name').required('warehouse name is required'),
|
||||||
address: Yup.string('Enter address').required('address is required'),
|
address: Yup.string('Enter address').required('address is required'),
|
||||||
inventorytype: Yup.string('Enter inventory Type').required('inventory Type is required'),
|
inventorytype: Yup.array('Enter inventory Type')
|
||||||
|
.of(Yup.string())
|
||||||
|
.required('inventory Type is required'),
|
||||||
attributes: Yup.string('Enter other attributes').required('attributes is required')
|
attributes: Yup.string('Enter other attributes').required('attributes is required')
|
||||||
|
}),
|
||||||
|
|
||||||
|
addNewProduct: Yup.object({
|
||||||
|
warehousename: Yup.string('Enter warehouse name').required('warehouse name is required'),
|
||||||
|
description: Yup.string('Enter Description').required('description is required'),
|
||||||
|
manufacturer: Yup.string('Enter manufacturer').required('manufacturer is required'),
|
||||||
|
type: Yup.string('Enter type').required('type is required'),
|
||||||
|
unitofmaterial: Yup.string('Enter unitofmaterial').required('Unit of material is required'),
|
||||||
|
packagecount: Yup.number('Enter packagecount').required('Package Count is required'),
|
||||||
|
formalname: Yup.string('Enter formal name').required('Formal Name is required'),
|
||||||
|
size: Yup.string('Enter Size').required('Size is required'),
|
||||||
|
color: Yup.string('Enter Color').required('Color is required'),
|
||||||
|
unitcost: Yup.number('Enter UnitCost').required('Unit Cost is required'),
|
||||||
|
countperpallet: Yup.number('Enter countperpallet').required('Count per pallet is required'),
|
||||||
|
countperpalletpackage: Yup.number('Enter countperpalletpackage').required(
|
||||||
|
'count per pallet package is required'
|
||||||
|
),
|
||||||
|
productfamilyassociation: Yup.string('Enter productfamilyassociation').required(
|
||||||
|
'product Family Association is required'
|
||||||
|
),
|
||||||
|
under: Yup.number().required('required'),
|
||||||
|
over: Yup.number().required('required'),
|
||||||
|
alert: Yup.number().required('required')
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user