607 lines
20 KiB
Plaintext
607 lines
20 KiB
Plaintext
import { Stack,TextField,useMediaQuery,Button } from "@mui/material";
|
|
import { useTheme } from "@mui/material/styles";
|
|
import Box from '@mui/material/Box';
|
|
|
|
import { ToastContainer, toast } from 'react-toastify';
|
|
import 'react-toastify/dist/ReactToastify.css';
|
|
import useAxiosPrivate from '../../utils/useAxiosPrivate';
|
|
import { useFormik } from "formik";
|
|
import DeleteIcon from '@mui/icons-material/Delete';
|
|
import { useEffect, useState } from "react";// import Input from "../common/Input";
|
|
// import TextArea from "../common/TextArea";
|
|
import SingleSelectNew from "../common/SingleSelectNew";
|
|
import * as Yup from 'yup';
|
|
import { useNavigate } from "react-router-dom";
|
|
|
|
import { useLocation } from 'react-router-dom';
|
|
|
|
|
|
|
|
const ProcurementValidationForm = Yup.object({
|
|
invoiceNo: Yup.string().required("Please Enter Invoice No!"),
|
|
|
|
});
|
|
|
|
|
|
// const handleRemoveAbnormality = (index) => {
|
|
// const updatedAilment = values.ailment.filter((_, i) => i !== index);
|
|
// setFieldValue('ailment', updatedAilment);
|
|
// };
|
|
|
|
|
|
|
|
const ProcurementForm = () => {
|
|
|
|
// const isSmaller = useMediaQuery('minWidth : 700px')
|
|
|
|
const [procurementEditId,setProcurementEditId] = useState();
|
|
|
|
const location = useLocation();
|
|
const { procurementId } = location.state || {};
|
|
|
|
// setProcurementEditId(procurementId);
|
|
|
|
useEffect(() => {
|
|
if (procurementId) {
|
|
setProcurementEditId(procurementId);
|
|
setShowupdate(true);
|
|
}
|
|
|
|
}, [procurementId]);
|
|
|
|
console.log("procurement edit id",procurementId);
|
|
|
|
const theme = useTheme();
|
|
// const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
|
|
const isMobile = useMediaQuery(theme.breakpoints.down("md"));
|
|
|
|
|
|
const axiosClientPrivate = useAxiosPrivate();
|
|
|
|
// const [fetchTrigger, setFetchTrigger] = useState(0);
|
|
|
|
// const [id,setId] = useState(1);
|
|
|
|
const [showupdate,setShowupdate] = useState(false);
|
|
|
|
const [medicalItem,setMedicalItem] = useState([]);
|
|
|
|
const Navigate = useNavigate();
|
|
|
|
const[index,setIndex] = useState();
|
|
|
|
|
|
|
|
const todayDate = new Date().toISOString().split('T')[0];
|
|
|
|
const {
|
|
values,
|
|
touched,
|
|
errors,
|
|
handleBlur,
|
|
// handleChange,
|
|
setFieldValue,
|
|
handleSubmit,
|
|
resetForm,
|
|
getFieldProps,
|
|
} = useFormik({
|
|
initialValues: {
|
|
invoiceNo: '',
|
|
procurementDate: todayDate,
|
|
remarks: '',
|
|
items: [
|
|
{
|
|
|
|
itemId: "",
|
|
qty: "",
|
|
batch: '',
|
|
// mrp: "",
|
|
ratePerUnit : "",
|
|
// discount: "",
|
|
netValue: "",
|
|
expiry: '',
|
|
remarks: '',
|
|
tax : ''
|
|
// isExpired: '', // Or some default value like 'No'
|
|
}
|
|
],
|
|
ohcTypeId: 1,
|
|
|
|
},
|
|
validationSchema: ProcurementValidationForm,
|
|
// onSubmit: (values, action) => {
|
|
// console.log(values);
|
|
// action.resetForm();
|
|
// },
|
|
onSubmit: async (values, {resetForm}) => {
|
|
try {
|
|
if(values.items.length > 0 && values.items[0].itemId){
|
|
console.log("save",values);
|
|
const response = await axiosClientPrivate.post('/procurements', values);
|
|
toast.success("Saved Successfully!",{
|
|
position:"top-center",
|
|
autoClose : 500
|
|
});
|
|
|
|
setTimeout(()=>{
|
|
Navigate('/inventory/procurement-list')
|
|
},1000)
|
|
// getting id(key,value) of last index
|
|
// const id = rowData[rowData.length-1].buId;
|
|
// const obj = {
|
|
// buId : id+1,
|
|
// ...values
|
|
// }
|
|
// console.log(obj);
|
|
// setRowData(rowData => [...rowData, obj]);
|
|
// setFetchTrigger(prev => prev+1);
|
|
|
|
console.log('Response:', response.data);
|
|
resetForm();
|
|
}
|
|
else{
|
|
toast.error("Please Select Indent!", {
|
|
position: "top-center",
|
|
autoClose : 1000
|
|
});
|
|
}
|
|
|
|
} catch (error) {
|
|
console.log(values);
|
|
console.error('Error:', error);
|
|
}
|
|
},
|
|
});
|
|
|
|
|
|
// edit
|
|
useEffect(() => {
|
|
|
|
if (!procurementEditId) return;
|
|
|
|
const controller = new AbortController();
|
|
|
|
const getAllOhc = async () => {
|
|
try {
|
|
const response = await axiosClientPrivate.get(`/procurements/${procurementEditId}`, { signal: controller.signal });
|
|
const items = response.data;
|
|
|
|
setFieldValue("procurementDate",response.data.procurementDate);
|
|
setFieldValue("invoiceNo",response.data.invoiceNo);
|
|
setFieldValue("remarks",response.data.remarks);
|
|
|
|
|
|
const changeitems = items.items.map((item)=>{
|
|
return{
|
|
...item,
|
|
itemId : item.itemDetails.id
|
|
}
|
|
})
|
|
setFieldValue("items",changeitems);
|
|
|
|
console.log("procurement edit",items);
|
|
console.log("showupdate",showupdate);
|
|
}
|
|
catch (err) {
|
|
console.error("Failed to fetch procurement edit items : ", err);
|
|
}
|
|
};
|
|
|
|
getAllOhc();
|
|
|
|
return () => {
|
|
controller.abort();
|
|
};
|
|
|
|
}, [procurementEditId]);
|
|
|
|
|
|
// handle update
|
|
const handleUpdate = async ()=> {
|
|
// alert(id);
|
|
// const update = values;
|
|
try{
|
|
console.log("pro update",values);
|
|
await axiosClientPrivate.put(`/procurements/procurement-indent/${procurementEditId}`,values);
|
|
toast.success("Updated Successfully!",{
|
|
position:"top-center",
|
|
autoClose: 500,
|
|
});
|
|
resetForm();
|
|
|
|
setTimeout(()=>{
|
|
Navigate('/inventory/procurement-list')
|
|
},500)
|
|
// setRowData(rowData => [...rowData,values]);
|
|
// setFetchTrigger(prev => prev+1);
|
|
|
|
}
|
|
catch(err){
|
|
console.log(values);
|
|
console.log(err);
|
|
}
|
|
}
|
|
|
|
// tbl_items // medical item
|
|
useEffect(() => {
|
|
const controller = new AbortController();
|
|
|
|
const getAllOhc = async () => {
|
|
try {
|
|
const response = await axiosClientPrivate.get('/items', { signal: controller.signal });
|
|
const items = response.data.content;
|
|
console.log("medial item",items);
|
|
|
|
|
|
const tableItem = items.map((item)=>{
|
|
return {label : item.itemName,id : item.id};
|
|
});
|
|
|
|
|
|
setMedicalItem(tableItem);
|
|
|
|
|
|
}
|
|
catch (err) {
|
|
console.error("Failed to fetch medical item data: ", err);
|
|
}
|
|
};
|
|
|
|
getAllOhc();
|
|
|
|
return () => {
|
|
controller.abort();
|
|
};
|
|
|
|
}, []);
|
|
|
|
const handleAddProcurement = () => {
|
|
const newProcurement = { itemId: '', qty: '', batch: '', ratePerUnit : '',tax : '', netValue: '', expiry: '', remarks: '', isExpired: '' };
|
|
setFieldValue('items', [...values.items, newProcurement]);
|
|
};
|
|
|
|
const handleRemoveProcurement = (index) => {
|
|
const updatedProcurement = values.items.filter((_, i) => i !== index);
|
|
setFieldValue('items', updatedProcurement);
|
|
};
|
|
|
|
|
|
|
|
// useEffect(() => {
|
|
// const qty = values.items[index].qty;
|
|
// const netValue = values.items[index].netValue;
|
|
|
|
// if (qty && netValue) {
|
|
// const perUnitRate = (netValue / qty).toFixed(2);
|
|
// setFieldValue(`items[${index}].mrp`, perUnitRate); // Set per unit rate (mrp)
|
|
// }
|
|
// }, [index]);
|
|
useEffect(() => {
|
|
if (values.items && values.items.length > index && values.items[index]) {
|
|
const qty = values.items[index].qty;
|
|
const netValue = values.items[index].netValue;
|
|
|
|
// Only calculate per unit rate if both qty and netValue are defined
|
|
if (qty && netValue) {
|
|
const perUnitRate = (netValue / qty).toFixed(2);
|
|
setFieldValue(`items[${index}].ratePerUnit`, Number(perUnitRate)); // Set per unit rate (mrp)
|
|
}
|
|
}
|
|
}, [index, values.items, setFieldValue]);
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Box sx={{ padding: '4px' ,width: '100%',maxHeight : '100vh',overflow : 'auto'}} >
|
|
<ToastContainer />
|
|
<Stack
|
|
direction={isMobile ? "column" : 'row'}
|
|
|
|
spacing={isMobile ? 2 : 4}
|
|
sx={{ mt: 2, justifyContent: "center", alignItems: errors.procurementRefno && touched.procurementRefno ? 'flex-start' :"center" ,width : '100%' }}
|
|
>
|
|
<TextField
|
|
label="Invoice Date"
|
|
name="procurementDate"
|
|
{...getFieldProps("procurementDate")}
|
|
fullWidth={true}
|
|
type="date"
|
|
size="small"
|
|
// sx={{ width: "250px" }}
|
|
InputLabelProps={{
|
|
shrink: true, // If you meant 'shrink' instead of 'stretch'
|
|
}}
|
|
// value={values.vaccineDesc}
|
|
// onChange={handleChange}
|
|
// onBlur={handleBlur}
|
|
// helperText={
|
|
// errors.vaccineDesc && touched.vaccineDesc ? (
|
|
// <span style={{ color: "red" }}>{errors.vaccineDesc}</span>
|
|
// ) : null
|
|
// }
|
|
/>
|
|
<TextField
|
|
label="Invoice No"
|
|
name="invoiceNo"
|
|
{...getFieldProps("invoiceNo")}
|
|
fullWidth={true}
|
|
type="text"
|
|
size="small"
|
|
// sx={{ width: "250px" }}
|
|
// sx={{ width: "600px" }}
|
|
// value={values.vaccineDesc}
|
|
// onChange={handleChange}
|
|
// onBlur={handleBlur}
|
|
helperText={
|
|
errors.invoiceNo && touched.invoiceNo ? (
|
|
<span style={{ color: "red" }}>{errors.invoiceNo}</span>
|
|
) : null
|
|
}
|
|
/>
|
|
{/*<TextField
|
|
label="Supplier Name"
|
|
// name="vaccineDesc"
|
|
fullWidth={true}
|
|
type="text"
|
|
size="small"
|
|
// sx={{ width: "250px" }}
|
|
// sx={{ width: "600px" }}
|
|
// value={values.vaccineDesc}
|
|
// onChange={handleChange}
|
|
// onBlur={handleBlur}
|
|
// helperText={
|
|
// errors.vaccineDesc && touched.vaccineDesc ? (
|
|
// <span style={{ color: "red" }}>{errors.vaccineDesc}</span>
|
|
// ) : null
|
|
// }
|
|
/>*/}
|
|
|
|
<TextField
|
|
label= "Remarks"
|
|
type={'text'}
|
|
fullWidth={true}
|
|
size= "small"
|
|
name="remarks"
|
|
{...getFieldProps("remarks")}
|
|
multiline
|
|
minRows={1}
|
|
maxRows={Infinity}
|
|
/>
|
|
|
|
</Stack>
|
|
|
|
<Stack
|
|
sx={{ mt: 4,width : '100%' }}
|
|
>
|
|
{
|
|
values.items.map((item,index)=>(
|
|
<Stack
|
|
direction={'row'}
|
|
spacing={1}
|
|
key={index}
|
|
sx={{ mt: 4, justifyContent: "center", alignItems: "center",width : '100%',mr : '100px' }}
|
|
>
|
|
|
|
|
|
<SingleSelectNew
|
|
label="Item Name"
|
|
name={`items.[${index}].itemId`}
|
|
type="text"
|
|
size="small"
|
|
// sx={{ width: "70%" }}
|
|
sx={{ width: "20%" }}
|
|
// helpertext="Some important text"
|
|
|
|
options={medicalItem}
|
|
getOptionLabel={(option) => option.label}
|
|
value={
|
|
medicalItem.find(
|
|
(option) => option.id === values.items[index].itemId
|
|
) || null
|
|
}
|
|
onChange={(event, newValue) => {
|
|
setFieldValue(
|
|
`items[${index}].itemId`,
|
|
newValue ? newValue.id : ""
|
|
); // Store only the id in Formik
|
|
}}
|
|
onBlur={handleBlur}
|
|
/>
|
|
|
|
<TextField
|
|
label="Accepted Qty"
|
|
|
|
name={`items[${index}].qty`}
|
|
{...getFieldProps(`items[${index}].qty`)}
|
|
// onChange={setIndex(index)}
|
|
onChange={(e) => {
|
|
setIndex(index); // Correctly set the index when onChange happens
|
|
getFieldProps(`items[${index}].qty`).onChange(e); // Call Formik's internal handler to update form state
|
|
}}
|
|
fullWidth={true}
|
|
type="number"
|
|
size="small"
|
|
sx={{ width: "10%" }}
|
|
|
|
// value={values.vaccineDesc}
|
|
// onChange={handleChange}
|
|
// onBlur={handleBlur}
|
|
// helperText={
|
|
// errors.vaccineDesc && touched.vaccineDesc ? (
|
|
// <span style={{ color: "red" }}>{errors.vaccineDesc}</span>
|
|
// ) : null
|
|
// }
|
|
/>
|
|
|
|
<TextField
|
|
label="Per Unit Rate"
|
|
name={`items[${index}].ratePerUnit`}
|
|
{...getFieldProps(`items[${index}].ratePerUnit`)}
|
|
// name="vaccineDesc"
|
|
onChange={(e) => {
|
|
setIndex(index); // Correctly set the index when onChange happens
|
|
getFieldProps(`items[${index}].ratePerUnit`).onChange(e); // Call Formik's internal handler to update form state
|
|
}}
|
|
fullWidth={true}
|
|
type="number"
|
|
size="small"
|
|
sx={{ width: "11%" }}
|
|
|
|
// value={values.vaccineDesc}
|
|
// onChange={handleChange}
|
|
// onBlur={handleBlur}
|
|
// helperText={
|
|
// errors.vaccineDesc && touched.vaccineDesc ? (
|
|
// <span style={{ color: "red" }}>{errors.vaccineDesc}</span>
|
|
// ) : null
|
|
// }
|
|
/>
|
|
<TextField
|
|
label="GST(%)"
|
|
name={`items[${index}].tax`}
|
|
{...getFieldProps(`items[${index}].tax`)}
|
|
// name="vaccineDesc"
|
|
fullWidth={true}
|
|
type="number"
|
|
size="small"
|
|
sx={{ width: "10%" }}
|
|
|
|
// value={values.vaccineDesc}
|
|
// onChange={handleChange}
|
|
// onBlur={handleBlur}
|
|
// helperText={
|
|
// errors.vaccineDesc && touched.vaccineDesc ? (
|
|
// <span style={{ color: "red" }}>{errors.vaccineDesc}</span>
|
|
// ) : null
|
|
// }
|
|
/>
|
|
<TextField
|
|
label="Net Value"
|
|
name={`items[${index}].netValue`}
|
|
{...getFieldProps(`items[${index}].netValue`)}
|
|
// name="vaccineDesc"
|
|
onChange={(e) => {
|
|
setIndex(index); // Correctly set the index when onChange happens
|
|
getFieldProps(`items[${index}].netValue`).onChange(e); // Call Formik's internal handler to update form state
|
|
}}
|
|
fullWidth={true}
|
|
type="number"
|
|
size="small"
|
|
sx={{ width: "10%" }}
|
|
|
|
// value={values.vaccineDesc}
|
|
// onChange={handleChange}
|
|
// onBlur={handleBlur}
|
|
// helperText={
|
|
// errors.vaccineDesc && touched.vaccineDesc ? (
|
|
// <span style={{ color: "red" }}>{errors.vaccineDesc}</span>
|
|
// ) : null
|
|
// }
|
|
/>
|
|
<TextField
|
|
label="Batch"
|
|
name={`items[${index}].batch`}
|
|
{...getFieldProps(`items[${index}].batch`)}
|
|
// name="vaccineDesc"
|
|
fullWidth={true}
|
|
type="text"
|
|
size="small"
|
|
sx={{ width: "15%" }}
|
|
|
|
// value={values.vaccineDesc}
|
|
// onChange={handleChange}
|
|
// onBlur={handleBlur}
|
|
// helperText={
|
|
// errors.vaccineDesc && touched.vaccineDesc ? (
|
|
// <span style={{ color: "red" }}>{errors.vaccineDesc}</span>
|
|
// ) : null
|
|
// }
|
|
/>
|
|
<TextField
|
|
label="Expiry Month"
|
|
name={`items[${index}].expiry`}
|
|
{...getFieldProps(`items[${index}].expiry`)}
|
|
// name="vaccineDesc"
|
|
fullWidth={true}
|
|
// type="date"
|
|
type="month"
|
|
size="small"
|
|
inputProps={{
|
|
placeholder: "Select month", // Custom placeholder
|
|
}}
|
|
InputLabelProps={{
|
|
shrink: true, // If you meant 'shrink' instead of 'stretch'
|
|
}}
|
|
sx={{ width: "13%" }}
|
|
|
|
// value={values.vaccineDesc}
|
|
// onChange={handleChange}
|
|
// onBlur={handleBlur}
|
|
// helperText={
|
|
// errors.vaccineDesc && touched.vaccineDesc ? (
|
|
// <span style={{ color: "red" }}>{errors.vaccineDesc}</span>
|
|
// ) : null
|
|
// }
|
|
/>
|
|
<TextField
|
|
label="Item Remarks"
|
|
name={`items[${index}].remarks`}
|
|
{...getFieldProps(`items[${index}].remarks`)}
|
|
// name="vaccineDesc"
|
|
fullWidth={true}
|
|
type="text"
|
|
size="small"
|
|
sx={{ width: "30%" }}
|
|
|
|
// value={values.vaccineDesc}
|
|
// onChange={handleChange}
|
|
// onBlur={handleBlur}
|
|
// helperText={
|
|
// errors.vaccineDesc && touched.vaccineDesc ? (
|
|
// <span style={{ color: "red" }}>{errors.vaccineDesc}</span>
|
|
// ) : null
|
|
// }
|
|
/>
|
|
{index > 0 && (
|
|
<DeleteIcon
|
|
color="error"
|
|
style={{ cursor: 'pointer', marginLeft: '1rem' }}
|
|
onClick={() => handleRemoveProcurement(index)}
|
|
/>
|
|
)}
|
|
|
|
</Stack>
|
|
))
|
|
}
|
|
</Stack>
|
|
|
|
|
|
|
|
|
|
<Button
|
|
sx={{mt : 1,mb : 4,backgroundColor : '#46b06e', ':hover': {
|
|
backgroundColor: '#46b06e', // Same color to prevent hover effect
|
|
},}}
|
|
// style={{display : showupdate ? "none" : "null" }}
|
|
fullWidth
|
|
variant="contained"
|
|
type="button"
|
|
onClick={() => handleAddProcurement()}
|
|
>Add Row</Button>
|
|
|
|
<Stack direction={'row'} spacing ={2} sx={{ justifyContent : 'center',alignItems : 'center', mt : 4 }} marginY={1} paddingX={1}>
|
|
|
|
<Button type="submit" onClick={()=> handleUpdate()} variant="outlined" style={{display : showupdate ? "block" : "none",color : '#46b06e',border : '1px solid #46b06e' }}>Update</Button>
|
|
<Button type="submit" onClick={() => handleSubmit()} variant="outlined" style={{display : showupdate ? "none" : "null",color : '#46b06e',border : '1px solid #46b06e' }}>Save</Button>
|
|
<Button onClick={() => resetForm()} type="reset" color='warning' variant="outlined">Reset</Button>
|
|
|
|
|
|
</Stack>
|
|
</Box>
|
|
|
|
);
|
|
};
|
|
|
|
export default ProcurementForm;
|