push rasad front on new repo
This commit is contained in:
@@ -0,0 +1,595 @@
|
||||
import React, { useContext, useEffect, useState, useCallback } from "react";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import {
|
||||
Autocomplete,
|
||||
Button,
|
||||
FormControl,
|
||||
FormControlLabel,
|
||||
Radio,
|
||||
RadioGroup,
|
||||
TextField,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { slaughterGetProductsService } from "../../services/slaughter-inventory-gets";
|
||||
import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom";
|
||||
import { useFormik } from "formik";
|
||||
import { Yup } from "../../../../lib/yup/yup";
|
||||
import {
|
||||
slaughterAllocateStewardService,
|
||||
slaughterEditAllocateStewardService,
|
||||
} from "../../services/slaughter-allocate-steward";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice";
|
||||
import { liveStockGetInventoryData } from "../../../live-stock-support/services/live-stock-get-inventory-data";
|
||||
import { DatePicker } from "@mui/x-date-pickers";
|
||||
import moment from "moment";
|
||||
import { fetchSlaughterBroadcastAndProducts } from "../../services/handle-fetch-slaughter-products";
|
||||
import MonthlyDataCalendar from "../../../../components/date-picker/MonthlyDataCalendar";
|
||||
import PersianDate from "persian-date";
|
||||
import axios from "axios";
|
||||
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
import { LabelField } from "../../../../components/label-field/LabelField";
|
||||
|
||||
export const SlaughterAllocateForFreezing = ({
|
||||
sellerType,
|
||||
sellType,
|
||||
updateTable,
|
||||
fetchApiData,
|
||||
editData,
|
||||
remainWeight,
|
||||
priceInfo,
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
const [productData, setProductData] = useState([]);
|
||||
const [productKey, setProductKey] = useState(null);
|
||||
const [coldHouseData, setColdHouseData] = useState([]);
|
||||
const [coldHouseKey, setColdHouseKey] = useState(null);
|
||||
const [selectedInventory, setSelectedInventory] = useState("governmental");
|
||||
const [approvedStatus, setApprovedStatus] = useState(
|
||||
priceInfo?.active === false ? false : true
|
||||
);
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
const [openNotif] = useContext(AppContext);
|
||||
|
||||
// Calendar states
|
||||
const [selectedCalendarDate, setSelectedCalendarDate] = useState(null);
|
||||
const [calendarDayData, setCalendarDayData] = useState({});
|
||||
const [productionDate, setProductionDate] = useState(null);
|
||||
const [selectedDateAmount, setSelectedDateAmount] = useState(null);
|
||||
const [calendarRawData, setCalendarRawData] = useState({
|
||||
governmental: [],
|
||||
free: [],
|
||||
});
|
||||
|
||||
const transformCalendarData = useCallback((dataArray) => {
|
||||
if (!Array.isArray(dataArray)) return {};
|
||||
|
||||
const transformedData = {};
|
||||
dataArray.forEach((item) => {
|
||||
if (item.day && item.amount !== undefined) {
|
||||
const persianDate = new PersianDate(new Date(item.day));
|
||||
const persianDateStr = persianDate.format("YYYY/MM/DD");
|
||||
transformedData[persianDateStr] = {
|
||||
value1: item.amount,
|
||||
originalDay: item.day,
|
||||
active: item.active === true,
|
||||
};
|
||||
}
|
||||
});
|
||||
return transformedData;
|
||||
}, []);
|
||||
|
||||
const updateCalendarData = useCallback(
|
||||
(dataArray) => {
|
||||
const transformed = transformCalendarData(dataArray);
|
||||
setCalendarDayData(transformed);
|
||||
},
|
||||
[transformCalendarData]
|
||||
);
|
||||
|
||||
// Fetch calendar data from API
|
||||
const fetchCalendarData = useCallback(
|
||||
async (dateParam) => {
|
||||
try {
|
||||
const response = await axios.get("/kill-house-remain-weight/", {
|
||||
params: {
|
||||
date: dateParam,
|
||||
role_key: checkPathStartsWith("slaughter")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
},
|
||||
});
|
||||
if (response.data) {
|
||||
setCalendarRawData({
|
||||
governmental: response.data.governmental || [],
|
||||
free: response.data.free || [],
|
||||
});
|
||||
const dataToShow =
|
||||
selectedInventory === "governmental"
|
||||
? response.data.governmental
|
||||
: response.data.free;
|
||||
updateCalendarData(dataToShow);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching calendar data:", error);
|
||||
}
|
||||
},
|
||||
[selectedInventory, updateCalendarData, selectedSubUser]
|
||||
);
|
||||
|
||||
const handleDateSelect = (dateInfo) => {
|
||||
if (dateInfo && dateInfo.formattedDate) {
|
||||
setSelectedCalendarDate(dateInfo.formattedDate);
|
||||
|
||||
const data = calendarDayData[dateInfo.formattedDate];
|
||||
|
||||
if (data && data.originalDay) {
|
||||
const selectedOriginalDay = data.originalDay;
|
||||
if (
|
||||
selectedDate1 &&
|
||||
moment(selectedOriginalDay).isAfter(moment(selectedDate1), "day")
|
||||
) {
|
||||
setCalendarDateError(
|
||||
"تاریخ تولید نمیتواند بعد از تاریخ انتخابی باشد"
|
||||
);
|
||||
return;
|
||||
}
|
||||
setCalendarDateError(null);
|
||||
setProductionDate(selectedOriginalDay);
|
||||
}
|
||||
|
||||
if (data && data.value1 !== undefined) {
|
||||
setSelectedDateAmount(data.value1);
|
||||
} else {
|
||||
setSelectedDateAmount(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const getValidationSchema = useCallback(
|
||||
() =>
|
||||
Yup.object({
|
||||
weight: Yup.number()
|
||||
.required("این فیلد اجباری است!")
|
||||
.integer("عدد باید صحیح باشد!")
|
||||
.min(1, "یک مقدار مثبت وارد کنید!")
|
||||
.max(
|
||||
remainWeight + (editData?.realWeightOfCarcasses || 0),
|
||||
"وزن وارد شده بیش از موجودی انبار است!"
|
||||
)
|
||||
.test(
|
||||
"max-production-date-amount",
|
||||
`وزن نمیتواند بیشتر از موجودی تاریخ تولید (${
|
||||
selectedDateAmount?.toLocaleString() || 0
|
||||
} کیلوگرم) باشد!`,
|
||||
function (value) {
|
||||
if (!selectedDateAmount || selectedDateAmount === null)
|
||||
return true;
|
||||
return value <= selectedDateAmount;
|
||||
}
|
||||
),
|
||||
}),
|
||||
[remainWeight, editData, selectedDateAmount]
|
||||
);
|
||||
|
||||
const validationSchema = getValidationSchema();
|
||||
const [selectedDate1, setSelectedDate1] = useState(
|
||||
moment(new Date()).format("YYYY-MM-DD")
|
||||
);
|
||||
const [dateRangeError, setDateRangeError] = useState(null);
|
||||
const [calendarDateError, setCalendarDateError] = useState(null);
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues: {
|
||||
weight: editData?.realWeightOfCarcasses || "",
|
||||
},
|
||||
validationSchema,
|
||||
});
|
||||
|
||||
const successSubmit = () => {
|
||||
dispatch(CLOSE_MODAL());
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
dispatch(
|
||||
fetchSlaughterBroadcastAndProducts({
|
||||
role_key: checkPathStartsWith("slaughter")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
);
|
||||
fetchApiData();
|
||||
updateTable();
|
||||
};
|
||||
|
||||
const handleSellType = (event) => {
|
||||
const newType = event.target.value;
|
||||
setSelectedInventory(newType);
|
||||
};
|
||||
|
||||
const handleApprovedPrice = (event) => {
|
||||
const newType = event.target.value;
|
||||
setApprovedStatus(newType);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!editData) {
|
||||
dispatch(
|
||||
slaughterGetProductsService({
|
||||
role_key: checkPathStartsWith("slaughter")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
).then((r) => {
|
||||
setProductData(r.payload.data);
|
||||
});
|
||||
|
||||
dispatch(
|
||||
liveStockGetInventoryData({
|
||||
role_key: checkPathStartsWith("slaughter")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
).then((r) => {
|
||||
setColdHouseData(r.payload.data);
|
||||
});
|
||||
}
|
||||
fetchCalendarData(selectedDate1);
|
||||
}, [
|
||||
dispatch,
|
||||
editData,
|
||||
fetchCalendarData,
|
||||
selectedDate1,
|
||||
selectedSubUser?.key,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchCalendarData(selectedDate1);
|
||||
}, [selectedDate1, fetchCalendarData, selectedSubUser?.key]);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
calendarRawData.governmental.length > 0 ||
|
||||
calendarRawData.free.length > 0
|
||||
) {
|
||||
const dataToShow =
|
||||
selectedInventory === "governmental"
|
||||
? calendarRawData.governmental
|
||||
: calendarRawData.free;
|
||||
updateCalendarData(dataToShow);
|
||||
setSelectedCalendarDate(null);
|
||||
setProductionDate(null);
|
||||
setSelectedDateAmount(null);
|
||||
}
|
||||
}, [selectedInventory, calendarRawData, updateCalendarData]);
|
||||
|
||||
useEffect(() => {
|
||||
formik.validateForm();
|
||||
}, [selectedDateAmount]);
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
xs={12}
|
||||
direction="column"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
gap={1}
|
||||
>
|
||||
{!editData && (
|
||||
<DatePicker
|
||||
label="تاریخ"
|
||||
id="date"
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
fullWidth
|
||||
{...params}
|
||||
error={Boolean(dateRangeError) || params.error}
|
||||
helperText={dateRangeError || params.helperText}
|
||||
/>
|
||||
)}
|
||||
shouldDisableDate={(date) => {
|
||||
const d = moment(date);
|
||||
const today = moment();
|
||||
const yesterday = moment().subtract(1, "day");
|
||||
return !(d.isSame(today, "day") || d.isSame(yesterday, "day"));
|
||||
}}
|
||||
value={selectedDate1}
|
||||
onChange={(e) => {
|
||||
if (!e) {
|
||||
setDateRangeError(null);
|
||||
return;
|
||||
}
|
||||
const d = moment(e);
|
||||
const today = moment();
|
||||
const yesterday = moment().subtract(1, "day");
|
||||
const isAllowed =
|
||||
d.isSame(today, "day") || d.isSame(yesterday, "day");
|
||||
if (!isAllowed) {
|
||||
setDateRangeError(
|
||||
"تنها امکان انتخاب «امروز» یا «دیروز» وجود دارد."
|
||||
);
|
||||
return;
|
||||
}
|
||||
setDateRangeError(null);
|
||||
const formatted = moment(e).format("YYYY-MM-DD");
|
||||
setSelectedDate1(formatted);
|
||||
fetchCalendarData(formatted);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{!editData && (
|
||||
<Grid xs={12} container>
|
||||
<Autocomplete
|
||||
fullWidth
|
||||
style={{ minWidth: 210 }}
|
||||
disablePortal
|
||||
id="hatching"
|
||||
options={
|
||||
productData
|
||||
? productData.map((i) => {
|
||||
return {
|
||||
data: i,
|
||||
label: `${i.name}`,
|
||||
};
|
||||
})
|
||||
: []
|
||||
}
|
||||
onChange={(event, value) => {
|
||||
setProductKey(value.data);
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField fullWidth {...params} label="انتخاب محصول" />
|
||||
)}
|
||||
/>
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
{!editData && (
|
||||
<Grid xs={12} container>
|
||||
<Autocomplete
|
||||
fullWidth
|
||||
style={{ minWidth: 210 }}
|
||||
disablePortal
|
||||
id="hatching"
|
||||
options={
|
||||
coldHouseData
|
||||
? coldHouseData.map((i) => {
|
||||
return {
|
||||
data: i,
|
||||
label: `${i.name}`,
|
||||
};
|
||||
})
|
||||
: []
|
||||
}
|
||||
onChange={(event, value) => {
|
||||
setColdHouseKey(value.data?.key);
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField fullWidth {...params} label="انتخاب سردخانه" />
|
||||
)}
|
||||
/>
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
{!editData && priceInfo?.active && (
|
||||
<FormControl>
|
||||
<RadioGroup
|
||||
row
|
||||
aria-labelledby="segment-type-radio-group"
|
||||
name="segmentType"
|
||||
value={approvedStatus}
|
||||
onChange={handleApprovedPrice}
|
||||
>
|
||||
<FormControlLabel
|
||||
value={true}
|
||||
control={<Radio />}
|
||||
label="قیمت دولتی"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value={false}
|
||||
control={<Radio />}
|
||||
label="قیمت آزاد"
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
)}
|
||||
|
||||
{!editData && (
|
||||
<Grid my={1} xs={12}>
|
||||
<LabelField label="نوع انبار">
|
||||
<FormControl>
|
||||
<RadioGroup
|
||||
row
|
||||
aria-labelledby="segment-type-radio-group"
|
||||
name="segmentType"
|
||||
value={selectedInventory}
|
||||
onChange={handleSellType}
|
||||
>
|
||||
<FormControlLabel
|
||||
value="governmental"
|
||||
control={<Radio />}
|
||||
label="دولتی"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value="free"
|
||||
control={<Radio />}
|
||||
label="آزاد"
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
</LabelField>
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
{!editData && (
|
||||
<Grid
|
||||
style={{ width: "100%" }}
|
||||
container
|
||||
xs={12}
|
||||
lg={3}
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
mb={3}
|
||||
mt={2}
|
||||
gap={1}
|
||||
>
|
||||
<MonthlyDataCalendar
|
||||
onDateSelect={handleDateSelect}
|
||||
dayData={calendarDayData}
|
||||
selectedDate={selectedCalendarDate}
|
||||
maxGregorianDate={selectedDate1}
|
||||
label={`تاریخ تولید گوشت ${
|
||||
selectedDateAmount !== null
|
||||
? `(موجودی: ${selectedDateAmount?.toLocaleString()} کیلوگرم)`
|
||||
: ""
|
||||
}`}
|
||||
/>
|
||||
{calendarDateError && (
|
||||
<Typography
|
||||
sx={{
|
||||
color: "#d32f2f",
|
||||
fontSize: "0.75rem",
|
||||
marginTop: "4px",
|
||||
marginRight: "14px",
|
||||
textAlign: "right",
|
||||
}}
|
||||
>
|
||||
{calendarDateError}
|
||||
</Typography>
|
||||
)}
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
<NumberInput
|
||||
allowLeadingZeros
|
||||
thousandSeparator=","
|
||||
decimalScale={0}
|
||||
allowNegative={false}
|
||||
fullWidth
|
||||
id="weight"
|
||||
disabled={remainWeight < 1}
|
||||
label="وزن لاشه"
|
||||
variant="outlined"
|
||||
value={formik.values.weight}
|
||||
error={
|
||||
remainWeight < 1
|
||||
? true
|
||||
: formik.touched.weight
|
||||
? Boolean(formik.errors.weight)
|
||||
: selectedDateAmount && formik.values.weight > selectedDateAmount
|
||||
}
|
||||
onChange={(e) => {
|
||||
const value = e.target.value;
|
||||
if (value === "" || value === null || value === undefined) {
|
||||
formik.setFieldValue("weight", "");
|
||||
return;
|
||||
}
|
||||
const intValue = Math.floor(Number(value));
|
||||
if (intValue > 0) {
|
||||
formik.setFieldValue("weight", intValue);
|
||||
} else if (intValue === 0) {
|
||||
formik.setFieldValue("weight", "");
|
||||
}
|
||||
}}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
remainWeight < 1
|
||||
? "موجودی انبار خالی است!"
|
||||
: selectedDateAmount && formik.values.weight > selectedDateAmount
|
||||
? `وزن نمیتواند بیشتر از موجودی تاریخ تولید (${selectedDateAmount?.toLocaleString()} کیلوگرم) باشد!`
|
||||
: formik.touched.weight && Boolean(formik.errors.weight)
|
||||
? formik.errors.weight
|
||||
: null
|
||||
}
|
||||
/>
|
||||
|
||||
<Button
|
||||
variant="contained"
|
||||
fullWidth
|
||||
disabled={
|
||||
editData
|
||||
? !formik.isValid
|
||||
: !formik.isValid ||
|
||||
!productKey ||
|
||||
!coldHouseKey ||
|
||||
!productionDate ||
|
||||
(selectedDateAmount &&
|
||||
formik.values.weight > selectedDateAmount) ||
|
||||
(productionDate &&
|
||||
selectedDate1 &&
|
||||
moment(productionDate).isAfter(moment(selectedDate1), "day"))
|
||||
}
|
||||
onClick={() => {
|
||||
let req = {};
|
||||
if (!editData) {
|
||||
req = {
|
||||
seller_type: sellerType,
|
||||
product_key: productKey.key,
|
||||
type: "manual",
|
||||
number_of_carcasses: 0,
|
||||
weight_of_carcasses: formik.values.weight,
|
||||
approved_price_status: approvedStatus === "true" ? true : false,
|
||||
quota: selectedInventory,
|
||||
sell_type: sellType,
|
||||
buyer_type: "ColdHouse",
|
||||
cold_house_key: coldHouseKey,
|
||||
role_key: checkPathStartsWith("slaughter")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
allocation_type: "ColdHouse",
|
||||
date: selectedDate1,
|
||||
production_date: productionDate,
|
||||
distribution_type: "web",
|
||||
};
|
||||
} else {
|
||||
req = {
|
||||
weight_of_carcasses: formik.values.weight,
|
||||
allocation_key: editData?.key,
|
||||
distribution_type: "web",
|
||||
role_key: checkPathStartsWith("slaughter")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
};
|
||||
}
|
||||
|
||||
if (!editData) {
|
||||
dispatch(slaughterAllocateStewardService(req)).then((r) => {
|
||||
if (r.payload.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.error,
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
successSubmit();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
dispatch(slaughterEditAllocateStewardService(req)).then((r) => {
|
||||
if (r.payload.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.error,
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
successSubmit();
|
||||
}
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
ثبت
|
||||
</Button>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user