2026-01-18 14:32:49 +03:30
|
|
|
|
import React, { useContext, useEffect, useState, useCallback } from "react";
|
|
|
|
|
|
import {
|
|
|
|
|
|
Autocomplete,
|
|
|
|
|
|
Button,
|
|
|
|
|
|
Checkbox,
|
|
|
|
|
|
FormControl,
|
|
|
|
|
|
FormControlLabel,
|
|
|
|
|
|
InputAdornment,
|
|
|
|
|
|
Radio,
|
|
|
|
|
|
RadioGroup,
|
|
|
|
|
|
TextField,
|
|
|
|
|
|
Typography,
|
|
|
|
|
|
} from "@mui/material";
|
2026-01-18 16:03:27 +03:30
|
|
|
|
import { useDispatch } from "react-redux";
|
2026-01-18 14:32:49 +03:30
|
|
|
|
import { useFormik } from "formik";
|
|
|
|
|
|
import { DatePicker } from "@mui/x-date-pickers";
|
|
|
|
|
|
import moment from "moment";
|
|
|
|
|
|
import { AppContext } from "../../../contexts/AppContext";
|
|
|
|
|
|
import { provincePolicyGetUploadImageService } from "../../province/services/province-policy-upload-image";
|
|
|
|
|
|
import { getRoleFromUrl } from "../../../utils/getRoleFromUrl";
|
|
|
|
|
|
import { slaughterGetProductsService } from "../../slaughter-house/services/slaughter-inventory-gets";
|
|
|
|
|
|
import { slaughterGetGuildsForAllocateService } from "../../slaughter-house/services/slaughter-get-guilds-for-allocate";
|
|
|
|
|
|
import { Yup } from "../../../lib/yup/yup";
|
|
|
|
|
|
import { fixBase64 } from "../../../utils/toBase64";
|
|
|
|
|
|
import { CLOSE_MODAL, DRAWER } from "../../../lib/redux/slices/appSlice";
|
|
|
|
|
|
import { NumberInput } from "../../../components/number-format-custom/NumberFormatCustom";
|
|
|
|
|
|
import { ImageUpload } from "../../../components/image-upload/ImageUpload";
|
|
|
|
|
|
import { Grid } from "../../../components/grid/Grid";
|
|
|
|
|
|
import {
|
|
|
|
|
|
slaughterAllocateStewardService,
|
|
|
|
|
|
slaughterEditAllocateStewardService,
|
|
|
|
|
|
} from "../../slaughter-house/services/slaughter-allocate-steward";
|
|
|
|
|
|
import { fetchSlaughterBroadcastAndProducts } from "../../slaughter-house/services/handle-fetch-slaughter-products";
|
|
|
|
|
|
import MonthlyDataCalendar from "../../../components/date-picker/MonthlyDataCalendar";
|
|
|
|
|
|
import PersianDate from "persian-date";
|
|
|
|
|
|
import axios from "axios";
|
|
|
|
|
|
import { LabelField } from "../../../components/label-field/LabelField";
|
|
|
|
|
|
import { SPACING } from "../../../data/spacing";
|
|
|
|
|
|
|
|
|
|
|
|
export const StewardAllocationToGuild = ({
|
|
|
|
|
|
item,
|
|
|
|
|
|
key,
|
|
|
|
|
|
sellerType,
|
|
|
|
|
|
fetchData,
|
|
|
|
|
|
buyerType,
|
|
|
|
|
|
allocationType,
|
|
|
|
|
|
sellType,
|
|
|
|
|
|
updateTable,
|
|
|
|
|
|
fetchApiData,
|
|
|
|
|
|
editData,
|
|
|
|
|
|
coldHouseKey,
|
|
|
|
|
|
coldHouseItemKey,
|
|
|
|
|
|
killHouseAllocation,
|
|
|
|
|
|
priceInfo,
|
|
|
|
|
|
}) => {
|
|
|
|
|
|
const dispatch = useDispatch();
|
|
|
|
|
|
const [productData, setProductData] = useState([]);
|
|
|
|
|
|
const [guildsData, setGuildsData] = useState([]);
|
|
|
|
|
|
const [selectedInventory, setSelectedInventory] = useState("governmental");
|
|
|
|
|
|
const [approvedStatus, setApprovedStatus] = useState("true");
|
|
|
|
|
|
const [productKey, setProductKey] = useState(null);
|
|
|
|
|
|
const [openNotif] = useContext(AppContext);
|
|
|
|
|
|
const [profileImages, setProfileImages] = useState(
|
|
|
|
|
|
editData?.image ? [{ data_url: editData.image }] : []
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
const [value, setValue] = useState("own");
|
|
|
|
|
|
const [imageUploadLimit, setImageUploadLimit] = useState(1);
|
|
|
|
|
|
const [imageChanged, setImageChanged] = useState(false);
|
|
|
|
|
|
const [changeMobile, setChangeMobile] = useState(false);
|
|
|
|
|
|
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 [selectedDate1, setSelectedDate1] = useState(
|
|
|
|
|
|
moment(new Date()).format("YYYY-MM-DD")
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
const handleChange = (event) => {
|
|
|
|
|
|
setValue(event.target.value);
|
|
|
|
|
|
setBuyerData({
|
|
|
|
|
|
key: "",
|
|
|
|
|
|
item: "",
|
|
|
|
|
|
buyerType: "",
|
|
|
|
|
|
allocationType: "",
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
if (priceInfo?.active === false) {
|
|
|
|
|
|
setApprovedStatus("false");
|
|
|
|
|
|
}
|
|
|
|
|
|
}, [priceInfo?.active]);
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
if (approvedStatus === "true" && priceInfo?.active) {
|
|
|
|
|
|
formik.setFieldValue("price", priceInfo?.killHousePrice);
|
|
|
|
|
|
}
|
|
|
|
|
|
}, [approvedStatus]);
|
|
|
|
|
|
|
|
|
|
|
|
const handleSellType = (event) => {
|
|
|
|
|
|
const newType = event.target.value;
|
|
|
|
|
|
setSelectedInventory(newType);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handleApprovedPrice = (event) => {
|
|
|
|
|
|
const newType = event.target.value;
|
|
|
|
|
|
setApprovedStatus(newType);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handleDateSelect = (dateInfo) => {
|
|
|
|
|
|
if (dateInfo && dateInfo.formattedDate) {
|
|
|
|
|
|
setSelectedCalendarDate(dateInfo.formattedDate);
|
|
|
|
|
|
|
|
|
|
|
|
const data = calendarDayData[dateInfo.formattedDate];
|
|
|
|
|
|
|
|
|
|
|
|
if (data && data.originalDay) {
|
|
|
|
|
|
setProductionDate(data.originalDay);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (data && (data.amount !== undefined || data.value1 !== undefined)) {
|
|
|
|
|
|
const rawAmount = data.amount !== undefined ? data.amount : data.value1;
|
|
|
|
|
|
const normalizedAmount =
|
|
|
|
|
|
typeof rawAmount === "string"
|
|
|
|
|
|
? Number(rawAmount.replace(/,/g, ""))
|
|
|
|
|
|
: Number(rawAmount);
|
|
|
|
|
|
setSelectedDateAmount(
|
|
|
|
|
|
Number.isFinite(normalizedAmount) ? normalizedAmount : null
|
|
|
|
|
|
);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
setSelectedDateAmount(null);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
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");
|
|
|
|
|
|
const rawAmount = item.amount;
|
|
|
|
|
|
const normalizedAmount =
|
|
|
|
|
|
typeof rawAmount === "string"
|
|
|
|
|
|
? Number(rawAmount.replace(/,/g, ""))
|
|
|
|
|
|
: Number(rawAmount);
|
|
|
|
|
|
transformedData[persianDateStr] = {
|
|
|
|
|
|
value1: normalizedAmount,
|
|
|
|
|
|
originalDay: item.day,
|
|
|
|
|
|
active: item.active === true, // Store active status
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
return transformedData;
|
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
2026-01-18 16:03:27 +03:30
|
|
|
|
const updateCalendarData = useCallback(
|
|
|
|
|
|
(dataArray) => {
|
|
|
|
|
|
const transformed = transformCalendarData(dataArray);
|
|
|
|
|
|
setCalendarDayData(transformed);
|
|
|
|
|
|
},
|
|
|
|
|
|
[transformCalendarData]
|
|
|
|
|
|
);
|
2026-01-18 14:32:49 +03:30
|
|
|
|
|
|
|
|
|
|
const fetchCalendarData = useCallback(
|
|
|
|
|
|
async (dateParam = selectedDate1) => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const response = await axios.get("/steward-remain-weight/", {
|
|
|
|
|
|
params: {
|
|
|
|
|
|
date: dateParam,
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
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);
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
2026-01-18 16:03:27 +03:30
|
|
|
|
[selectedInventory, updateCalendarData, selectedDate1]
|
2026-01-18 14:32:49 +03:30
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
const [buyerData, setBuyerData] = useState({
|
|
|
|
|
|
key,
|
|
|
|
|
|
item,
|
|
|
|
|
|
buyerType,
|
|
|
|
|
|
allocationType,
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
if (getRoleFromUrl() === "Steward") {
|
|
|
|
|
|
setValue("free");
|
|
|
|
|
|
}
|
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
fetchCalendarData(selectedDate1);
|
2026-01-18 16:03:27 +03:30
|
|
|
|
}, [fetchCalendarData, selectedDate1]);
|
2026-01-18 14:32:49 +03:30
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
}
|
2026-01-18 16:03:27 +03:30
|
|
|
|
}, [selectedInventory, calendarRawData, updateCalendarData]);
|
2026-01-18 14:32:49 +03:30
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
2026-01-18 16:03:27 +03:30
|
|
|
|
dispatch(provincePolicyGetUploadImageService()).then((r) => {
|
2026-01-18 14:32:49 +03:30
|
|
|
|
if (r.payload?.data) {
|
|
|
|
|
|
setImageUploadLimit(r.payload.data.killHouseAllocation);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (!editData) {
|
2026-01-18 16:03:27 +03:30
|
|
|
|
dispatch(slaughterGetProductsService()).then((r) => {
|
2026-01-18 14:32:49 +03:30
|
|
|
|
setProductData(r.payload.data);
|
|
|
|
|
|
});
|
|
|
|
|
|
if (!item) {
|
|
|
|
|
|
dispatch(
|
|
|
|
|
|
slaughterGetGuildsForAllocateService({
|
|
|
|
|
|
free: value === "free" ? true : false,
|
|
|
|
|
|
})
|
|
|
|
|
|
).then((r) => {
|
|
|
|
|
|
setGuildsData(r.payload.data);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-01-18 16:03:27 +03:30
|
|
|
|
}, [dispatch, value]);
|
2026-01-18 14:32:49 +03:30
|
|
|
|
|
|
|
|
|
|
const validationSchema = Yup.object({
|
|
|
|
|
|
mobile: Yup.string().when([], {
|
|
|
|
|
|
is: () => !editData,
|
|
|
|
|
|
then: (schema) =>
|
|
|
|
|
|
schema
|
|
|
|
|
|
.required("شماره موبایل الزامی است")
|
|
|
|
|
|
.min(11, "شماره موبایل باید 11 رقم باشد")
|
|
|
|
|
|
.max(11, "شماره موبایل باید 11 رقم باشد")
|
|
|
|
|
|
.matches(
|
|
|
|
|
|
/^09\d{9}$/,
|
|
|
|
|
|
"شماره موبایل باید با 09 شروع شود و 11 رقم باشد"
|
|
|
|
|
|
),
|
|
|
|
|
|
otherwise: (schema) => schema.notRequired(),
|
|
|
|
|
|
}),
|
|
|
|
|
|
weight: Yup.number()
|
|
|
|
|
|
.required("این فیلد اجباری است!")
|
|
|
|
|
|
.integer("عدد باید صحیح باشد!")
|
|
|
|
|
|
.min(1, "یک مقدار مثبت وارد کنید!")
|
|
|
|
|
|
.test(
|
|
|
|
|
|
"max-production-date-amount",
|
|
|
|
|
|
`وزن نمیتواند بیشتر از موجودی تاریخ تولید (${
|
|
|
|
|
|
selectedDateAmount?.toLocaleString() || 0
|
|
|
|
|
|
} کیلوگرم) باشد!`,
|
|
|
|
|
|
function (value) {
|
|
|
|
|
|
if (!selectedDateAmount || selectedDateAmount === null) return true;
|
|
|
|
|
|
return (
|
|
|
|
|
|
value <= selectedDateAmount + (editData?.realWeightOfCarcasses || 0)
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
),
|
|
|
|
|
|
price: Yup.number()
|
|
|
|
|
|
.required("این فیلد اجباری است!")
|
|
|
|
|
|
.min(1, "یک مقدار مثبت وارد کنید!"),
|
|
|
|
|
|
wholePrice: Yup.number()
|
|
|
|
|
|
.required("این فیلد اجباری است!")
|
|
|
|
|
|
.min(1, "یک مقدار مثبت وارد کنید!"),
|
|
|
|
|
|
...(killHouseAllocation && {
|
|
|
|
|
|
image: Yup.string().when([], {
|
|
|
|
|
|
is: () => (!editData || imageChanged) && imageUploadLimit > 0,
|
|
|
|
|
|
then: Yup.string().required("عکس الزامی است"),
|
|
|
|
|
|
otherwise: Yup.string().notRequired(),
|
|
|
|
|
|
}),
|
|
|
|
|
|
}),
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const factorPaymentHandler = (imageList) => {
|
|
|
|
|
|
if (imageList[0]) {
|
|
|
|
|
|
formik.setFieldValue("image", fixBase64(imageList[0]?.data_url));
|
|
|
|
|
|
setImageChanged(true);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
formik.setFieldValue("image", "");
|
|
|
|
|
|
setImageChanged(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
setProfileImages(imageList);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const formik = useFormik({
|
|
|
|
|
|
initialValues: {
|
|
|
|
|
|
mobile: "",
|
|
|
|
|
|
weight: editData?.realWeightOfCarcasses || "",
|
|
|
|
|
|
wholePrice: editData?.totalAmount || "",
|
|
|
|
|
|
price: editData?.amount || "",
|
|
|
|
|
|
image: editData?.image || "",
|
|
|
|
|
|
},
|
|
|
|
|
|
validationSchema,
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
formik.validateForm();
|
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
formik.validateForm();
|
|
|
|
|
|
}, [selectedDateAmount]);
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
if (formik.values.weight && formik.values.price) {
|
|
|
|
|
|
formik.setFieldValue(
|
|
|
|
|
|
"wholePrice",
|
|
|
|
|
|
formik.values.price * formik.values.weight
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
}, [formik.values.price, formik.values.weight]);
|
|
|
|
|
|
|
|
|
|
|
|
const successSubmit = () => {
|
2026-01-18 16:03:27 +03:30
|
|
|
|
dispatch(CLOSE_MODAL());
|
|
|
|
|
|
openNotif({
|
|
|
|
|
|
vertical: "top",
|
|
|
|
|
|
horizontal: "center",
|
|
|
|
|
|
msg: "عملیات با موفقیت انجام شد.",
|
|
|
|
|
|
severity: "success",
|
|
|
|
|
|
});
|
|
|
|
|
|
dispatch(fetchSlaughterBroadcastAndProducts());
|
2026-01-18 14:32:49 +03:30
|
|
|
|
dispatch(
|
|
|
|
|
|
DRAWER({
|
|
|
|
|
|
right: false,
|
|
|
|
|
|
bottom: false,
|
|
|
|
|
|
left: false,
|
|
|
|
|
|
content: null,
|
|
|
|
|
|
})
|
|
|
|
|
|
);
|
|
|
|
|
|
fetchApiData && fetchApiData(1);
|
|
|
|
|
|
updateTable && updateTable();
|
|
|
|
|
|
fetchData && fetchData(1);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const [dateRangeError, setDateRangeError] = useState(null);
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Grid
|
|
|
|
|
|
container
|
|
|
|
|
|
xs={12}
|
|
|
|
|
|
direction="column"
|
|
|
|
|
|
justifyContent="center"
|
|
|
|
|
|
alignItems="flex-start"
|
|
|
|
|
|
gap={1.8}
|
|
|
|
|
|
>
|
|
|
|
|
|
{!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 && !coldHouseKey && (
|
|
|
|
|
|
<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 && (
|
|
|
|
|
|
<LabelField label="خریداران">
|
|
|
|
|
|
<FormControl fullWidth>
|
|
|
|
|
|
<RadioGroup
|
|
|
|
|
|
row
|
|
|
|
|
|
aria-labelledby="demo-controlled-radio-buttons-group"
|
|
|
|
|
|
name="controlled-radio-buttons-group"
|
|
|
|
|
|
value={value}
|
|
|
|
|
|
onChange={handleChange}
|
|
|
|
|
|
sx={{
|
|
|
|
|
|
justifyContent: "space-between",
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
<FormControlLabel
|
|
|
|
|
|
value="own"
|
|
|
|
|
|
control={<Radio />}
|
2026-01-18 16:03:27 +03:30
|
|
|
|
label="صنوف اختصاصی"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<FormControlLabel
|
|
|
|
|
|
value="free"
|
|
|
|
|
|
control={<Radio />}
|
|
|
|
|
|
label="صنوف آزاد"
|
2026-01-18 14:32:49 +03:30
|
|
|
|
/>
|
|
|
|
|
|
</RadioGroup>
|
|
|
|
|
|
</FormControl>
|
|
|
|
|
|
</LabelField>
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
|
|
{!item && !editData && (
|
|
|
|
|
|
<Grid xs={12} container>
|
|
|
|
|
|
<Autocomplete
|
|
|
|
|
|
fullWidth
|
|
|
|
|
|
style={{ minWidth: 210 }}
|
|
|
|
|
|
disablePortal
|
|
|
|
|
|
id="hatching"
|
|
|
|
|
|
options={
|
|
|
|
|
|
guildsData
|
|
|
|
|
|
? guildsData.map((i) => {
|
|
|
|
|
|
return {
|
|
|
|
|
|
data: i,
|
2026-01-18 16:03:27 +03:30
|
|
|
|
label: `${i?.steward ? "مباشر" : "صنف"} ${
|
|
|
|
|
|
i?.guildsName
|
|
|
|
|
|
} ${i?.user?.fullname} (${i?.user?.mobile})`,
|
2026-01-18 14:32:49 +03:30
|
|
|
|
};
|
|
|
|
|
|
})
|
|
|
|
|
|
: []
|
|
|
|
|
|
}
|
|
|
|
|
|
onChange={(event, value) => {
|
|
|
|
|
|
setBuyerData({
|
|
|
|
|
|
item: value?.data,
|
|
|
|
|
|
key: value?.data?.key,
|
2026-01-18 16:03:27 +03:30
|
|
|
|
allocationType: value?.data?.steward
|
|
|
|
|
|
? "steward_steward"
|
|
|
|
|
|
: "steward_guild",
|
|
|
|
|
|
buyerType: value?.data?.steward ? "Steward" : "Guild",
|
2026-01-18 14:32:49 +03:30
|
|
|
|
});
|
|
|
|
|
|
formik.setFieldValue("mobile", value?.data?.user?.mobile);
|
|
|
|
|
|
formik.setFieldTouched("mobile", true, false);
|
|
|
|
|
|
formik.validateField("mobile");
|
|
|
|
|
|
const reg = new RegExp(/^09\d{9}$/);
|
|
|
|
|
|
if (!reg.test(value?.data?.user?.mobile)) {
|
|
|
|
|
|
setChangeMobile(true);
|
|
|
|
|
|
}
|
|
|
|
|
|
}}
|
|
|
|
|
|
renderInput={(params) => (
|
2026-01-18 16:03:27 +03:30
|
|
|
|
<TextField fullWidth {...params} label="انتخاب مباشر / صنف" />
|
2026-01-18 14:32:49 +03:30
|
|
|
|
)}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
)}
|
|
|
|
|
|
{!item && !editData && (
|
|
|
|
|
|
<Grid
|
|
|
|
|
|
container
|
|
|
|
|
|
xs={12}
|
|
|
|
|
|
alignItems="center"
|
|
|
|
|
|
justifyContent="center"
|
|
|
|
|
|
p={1}
|
|
|
|
|
|
gap={SPACING.TINY}
|
|
|
|
|
|
sx={{
|
|
|
|
|
|
border: 2,
|
|
|
|
|
|
borderColor: "#e6e6e6",
|
|
|
|
|
|
borderRadius: 2,
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Typography variant="caption" color="error">
|
|
|
|
|
|
<Checkbox
|
|
|
|
|
|
sx={{ ml: -1.25 }}
|
|
|
|
|
|
checked={changeMobile}
|
|
|
|
|
|
onChange={() => setChangeMobile(!changeMobile)}
|
|
|
|
|
|
/>
|
2026-01-18 16:03:27 +03:30
|
|
|
|
از این قسمت میتوانید تلفن مباشر/صنف را ویرایش کنید.
|
2026-01-18 14:32:49 +03:30
|
|
|
|
</Typography>
|
|
|
|
|
|
|
|
|
|
|
|
{buyerData?.key && changeMobile && (
|
|
|
|
|
|
<TextField
|
|
|
|
|
|
fullWidth
|
|
|
|
|
|
id="mobile"
|
|
|
|
|
|
value={formik.values.mobile}
|
|
|
|
|
|
error={
|
|
|
|
|
|
formik.touched.mobile ? Boolean(formik.errors.mobile) : null
|
|
|
|
|
|
}
|
|
|
|
|
|
onChange={formik.handleChange}
|
|
|
|
|
|
onBlur={formik.handleBlur}
|
|
|
|
|
|
helperText={
|
|
|
|
|
|
formik.touched.mobile && Boolean(formik.errors.mobile)
|
|
|
|
|
|
? formik.errors.mobile
|
|
|
|
|
|
: null
|
|
|
|
|
|
}
|
|
|
|
|
|
label="موبایل"
|
|
|
|
|
|
autoComplete="current-password"
|
|
|
|
|
|
variant="outlined"
|
|
|
|
|
|
/>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
|
|
{!item && !editData && priceInfo?.active !== false && (
|
|
|
|
|
|
<LabelField label="نوع فروش">
|
|
|
|
|
|
<FormControl fullWidth>
|
|
|
|
|
|
<RadioGroup
|
|
|
|
|
|
row
|
|
|
|
|
|
aria-labelledby="segment-type-radio-group"
|
|
|
|
|
|
name="segmentType"
|
|
|
|
|
|
value={approvedStatus}
|
|
|
|
|
|
onChange={handleApprovedPrice}
|
|
|
|
|
|
sx={{
|
|
|
|
|
|
justifyContent: "space-between",
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
<FormControlLabel
|
|
|
|
|
|
value={true}
|
|
|
|
|
|
control={<Radio />}
|
|
|
|
|
|
label="قیمت دولتی"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<FormControlLabel
|
|
|
|
|
|
value={false}
|
|
|
|
|
|
control={<Radio />}
|
|
|
|
|
|
label="قیمت آزاد"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</RadioGroup>
|
|
|
|
|
|
</FormControl>
|
|
|
|
|
|
</LabelField>
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
|
|
{!item && !editData && (
|
|
|
|
|
|
<LabelField label="نوع انبار">
|
|
|
|
|
|
<FormControl fullWidth>
|
|
|
|
|
|
<RadioGroup
|
|
|
|
|
|
row
|
|
|
|
|
|
aria-labelledby="segment-type-radio-group"
|
|
|
|
|
|
name="segmentType"
|
|
|
|
|
|
value={selectedInventory}
|
|
|
|
|
|
onChange={handleSellType}
|
|
|
|
|
|
sx={{
|
|
|
|
|
|
justifyContent: "space-between",
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
<FormControlLabel
|
|
|
|
|
|
value="governmental"
|
|
|
|
|
|
control={<Radio />}
|
|
|
|
|
|
label="دولتی"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<FormControlLabel value="free" control={<Radio />} label="آزاد" />
|
|
|
|
|
|
</RadioGroup>
|
|
|
|
|
|
</FormControl>
|
|
|
|
|
|
</LabelField>
|
|
|
|
|
|
)}
|
|
|
|
|
|
<Grid
|
|
|
|
|
|
container
|
|
|
|
|
|
xs={12}
|
|
|
|
|
|
justifyContent="center"
|
|
|
|
|
|
alignItems="center"
|
|
|
|
|
|
gap={SPACING.TINY}
|
|
|
|
|
|
sx={{ width: "100%" }}
|
|
|
|
|
|
direction="column"
|
|
|
|
|
|
>
|
|
|
|
|
|
<MonthlyDataCalendar
|
|
|
|
|
|
onDateSelect={handleDateSelect}
|
|
|
|
|
|
dayData={calendarDayData}
|
|
|
|
|
|
selectedDate={selectedCalendarDate}
|
|
|
|
|
|
maxGregorianDate={selectedDate1}
|
|
|
|
|
|
label={`تاریخ تولید گوشت ${
|
|
|
|
|
|
selectedDateAmount !== null
|
|
|
|
|
|
? `(موجودی: ${selectedDateAmount?.toLocaleString()} کیلوگرم)`
|
|
|
|
|
|
: ""
|
|
|
|
|
|
}`}
|
|
|
|
|
|
/>
|
|
|
|
|
|
{productionDate &&
|
|
|
|
|
|
selectedDate1 &&
|
|
|
|
|
|
moment(productionDate).isAfter(moment(selectedDate1), "day") && (
|
|
|
|
|
|
<Typography
|
|
|
|
|
|
sx={{
|
|
|
|
|
|
color: "#d32f2f",
|
|
|
|
|
|
fontSize: "0.75rem",
|
|
|
|
|
|
marginTop: "4px",
|
|
|
|
|
|
marginRight: "14px",
|
|
|
|
|
|
textAlign: "right",
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
تاریخ تولید نمیتواند بعد از تاریخ انتخابی باشد
|
|
|
|
|
|
</Typography>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
<NumberInput
|
|
|
|
|
|
allowLeadingZeros
|
|
|
|
|
|
thousandSeparator=","
|
|
|
|
|
|
decimalScale={0}
|
|
|
|
|
|
allowNegative={false}
|
|
|
|
|
|
fullWidth
|
|
|
|
|
|
id="weight"
|
|
|
|
|
|
label="وزن لاشه"
|
|
|
|
|
|
variant="outlined"
|
|
|
|
|
|
value={formik.values.weight}
|
|
|
|
|
|
error={
|
|
|
|
|
|
!selectedDateAmount && !productionDate
|
|
|
|
|
|
? 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={
|
|
|
|
|
|
!selectedDateAmount && !productionDate
|
|
|
|
|
|
? "لطفاً ابتدا تاریخ تولید را انتخاب کنید!"
|
|
|
|
|
|
: formik.touched.weight && Boolean(formik.errors.weight)
|
|
|
|
|
|
? formik.errors.weight
|
|
|
|
|
|
: null
|
|
|
|
|
|
}
|
|
|
|
|
|
disabled={!selectedDateAmount && !productionDate}
|
|
|
|
|
|
sx={{
|
|
|
|
|
|
"& .MuiFormHelperText-root": {
|
|
|
|
|
|
color:
|
|
|
|
|
|
selectedDateAmount && formik.values.weight > selectedDateAmount
|
|
|
|
|
|
? "error.main"
|
|
|
|
|
|
: undefined,
|
|
|
|
|
|
},
|
|
|
|
|
|
}}
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<NumberInput
|
|
|
|
|
|
allowLeadingZeros
|
|
|
|
|
|
thousandSeparator=","
|
|
|
|
|
|
fullWidth
|
|
|
|
|
|
id="price"
|
|
|
|
|
|
label="قیمت هر کیلوگرم"
|
|
|
|
|
|
variant="outlined"
|
|
|
|
|
|
InputProps={{
|
|
|
|
|
|
endAdornment: <InputAdornment position="start">ریال</InputAdornment>,
|
|
|
|
|
|
}}
|
|
|
|
|
|
value={formik.values.price}
|
|
|
|
|
|
error={formik.touched.price ? Boolean(formik.errors.price) : null}
|
|
|
|
|
|
onChange={formik.handleChange}
|
|
|
|
|
|
onBlur={formik.handleBlur}
|
|
|
|
|
|
helperText={
|
|
|
|
|
|
formik.touched.price && Boolean(formik.errors.price)
|
|
|
|
|
|
? formik.errors.price
|
|
|
|
|
|
: null
|
|
|
|
|
|
}
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<NumberInput
|
|
|
|
|
|
disabled
|
|
|
|
|
|
allowLeadingZeros
|
|
|
|
|
|
thousandSeparator=","
|
|
|
|
|
|
fullWidth
|
|
|
|
|
|
id="wholePrice"
|
|
|
|
|
|
label="هزینه کل"
|
|
|
|
|
|
variant="outlined"
|
|
|
|
|
|
InputProps={{
|
|
|
|
|
|
endAdornment: <InputAdornment position="start">ریال</InputAdornment>,
|
|
|
|
|
|
}}
|
|
|
|
|
|
value={formik.values.wholePrice}
|
|
|
|
|
|
error={
|
|
|
|
|
|
formik.touched.wholePrice ? Boolean(formik.errors.wholePrice) : null
|
|
|
|
|
|
}
|
|
|
|
|
|
onChange={formik.handleChange}
|
|
|
|
|
|
onBlur={formik.handleBlur}
|
|
|
|
|
|
helperText={
|
|
|
|
|
|
formik.touched.wholePrice && Boolean(formik.errors.wholePrice)
|
|
|
|
|
|
? formik.errors.wholePrice
|
|
|
|
|
|
: null
|
|
|
|
|
|
}
|
|
|
|
|
|
/>
|
|
|
|
|
|
{(killHouseAllocation || (editData && editData.image)) && (
|
|
|
|
|
|
<Grid container xs={12} justifyContent="center" alignItems="center">
|
|
|
|
|
|
<ImageUpload
|
|
|
|
|
|
onChange={factorPaymentHandler}
|
|
|
|
|
|
images={profileImages}
|
|
|
|
|
|
maxNumber={1}
|
|
|
|
|
|
title={"بارگزاری سند"}
|
|
|
|
|
|
/>
|
|
|
|
|
|
{formik.touched.image && Boolean(formik.errors.image) && (
|
|
|
|
|
|
<Typography color="error">ثبت تصویر الزامی است</Typography>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
|
|
<Grid container xs={12} spacing={SPACING.SMALL}>
|
|
|
|
|
|
<Grid xs={6}>
|
|
|
|
|
|
<Button
|
|
|
|
|
|
variant="contained"
|
|
|
|
|
|
fullWidth
|
|
|
|
|
|
disabled={
|
|
|
|
|
|
editData
|
|
|
|
|
|
? !formik.isValid
|
|
|
|
|
|
: !formik.isValid ||
|
|
|
|
|
|
(coldHouseKey ? false : !productKey) ||
|
|
|
|
|
|
!buyerData?.item?.key ||
|
|
|
|
|
|
!productionDate ||
|
|
|
|
|
|
(productionDate &&
|
|
|
|
|
|
selectedDate1 &&
|
|
|
|
|
|
moment(selectedDate1).isBefore(
|
|
|
|
|
|
moment(productionDate),
|
|
|
|
|
|
"day"
|
|
|
|
|
|
))
|
|
|
|
|
|
}
|
|
|
|
|
|
onClick={() => {
|
|
|
|
|
|
let req = {};
|
|
|
|
|
|
if (coldHouseItemKey) {
|
|
|
|
|
|
req = {
|
|
|
|
|
|
allocation_key: coldHouseItemKey,
|
|
|
|
|
|
number_of_carcasses: 0,
|
|
|
|
|
|
weight_of_carcasses: formik.values.weight,
|
|
|
|
|
|
amount: formik.values.price,
|
|
|
|
|
|
total_amount: formik.values.wholePrice,
|
|
|
|
|
|
distribution_type: "web",
|
|
|
|
|
|
...(imageChanged && { image: formik.values.image }),
|
|
|
|
|
|
};
|
|
|
|
|
|
} else if (!editData) {
|
|
|
|
|
|
req = {
|
|
|
|
|
|
seller_type: sellerType,
|
2026-01-18 16:03:27 +03:30
|
|
|
|
buyer_type: buyerData?.buyerType,
|
|
|
|
|
|
guild_key:
|
|
|
|
|
|
buyerData?.buyerType === "Guild"
|
|
|
|
|
|
? buyerData?.item?.key
|
|
|
|
|
|
: null,
|
|
|
|
|
|
steward_key:
|
|
|
|
|
|
buyerData?.buyerType === "Steward"
|
|
|
|
|
|
? buyerData?.item?.key
|
|
|
|
|
|
: null,
|
|
|
|
|
|
kill_house_key:
|
|
|
|
|
|
buyerData?.buyerType === "KillHouse"
|
|
|
|
|
|
? buyerData?.item?.key
|
|
|
|
|
|
: null,
|
2026-01-18 14:32:49 +03:30
|
|
|
|
cold_house_key: coldHouseKey || null,
|
|
|
|
|
|
product_key: coldHouseKey ? null : productKey.key,
|
|
|
|
|
|
type: "manual",
|
2026-01-18 16:03:27 +03:30
|
|
|
|
allocation_type: coldHouseKey
|
|
|
|
|
|
? "ColdHouse"
|
|
|
|
|
|
: buyerData?.allocationType,
|
2026-01-18 14:32:49 +03:30
|
|
|
|
number_of_carcasses: 0,
|
|
|
|
|
|
weight_of_carcasses: formik.values.weight,
|
|
|
|
|
|
sell_type: sellType,
|
|
|
|
|
|
amount: formik.values.price,
|
|
|
|
|
|
total_amount: formik.values.wholePrice,
|
|
|
|
|
|
approved_price_status:
|
|
|
|
|
|
approvedStatus === "true" ? true : false,
|
|
|
|
|
|
quota: selectedInventory,
|
|
|
|
|
|
date: selectedDate1,
|
|
|
|
|
|
production_date: productionDate,
|
|
|
|
|
|
distribution_type: "web",
|
|
|
|
|
|
...(buyerData?.item?.user?.mobile !== formik.values.mobile
|
|
|
|
|
|
? { interface_number: formik.values.mobile }
|
|
|
|
|
|
: {}),
|
|
|
|
|
|
...(profileImages.length > 0 && {
|
|
|
|
|
|
image: formik.values.image,
|
|
|
|
|
|
}),
|
|
|
|
|
|
};
|
|
|
|
|
|
req = Object.fromEntries(
|
|
|
|
|
|
Object.entries(req).filter(([, value]) => value !== null)
|
|
|
|
|
|
);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
req = {
|
|
|
|
|
|
allocation_key: editData?.key,
|
|
|
|
|
|
number_of_carcasses: 0,
|
|
|
|
|
|
weight_of_carcasses: formik.values.weight,
|
|
|
|
|
|
amount: formik.values.price,
|
|
|
|
|
|
total_amount: formik.values.wholePrice,
|
|
|
|
|
|
distribution_type: "web",
|
|
|
|
|
|
...(imageChanged && { image: formik.values.image }),
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
{editData ? "ویرایش" : "ثبت"}
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
<Grid xs={6}>
|
|
|
|
|
|
<Button
|
|
|
|
|
|
fullWidth
|
|
|
|
|
|
variant="outlined"
|
|
|
|
|
|
color="primary"
|
|
|
|
|
|
onClick={() => {
|
|
|
|
|
|
dispatch(DRAWER({ right: false, bottom: false, content: null }));
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
انصراف
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
</Grid>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|