import React, { useContext, useEffect, useState, useCallback } from "react"; import { Autocomplete, Button, Checkbox, FormControl, FormControlLabel, InputAdornment, Radio, RadioGroup, TextField, Typography, } from "@mui/material"; import { useDispatch } from "react-redux"; 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; }, []); const updateCalendarData = useCallback( (dataArray) => { const transformed = transformCalendarData(dataArray); setCalendarDayData(transformed); }, [transformCalendarData] ); 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); } }, [selectedInventory, updateCalendarData, selectedDate1] ); const [buyerData, setBuyerData] = useState({ key, item, buyerType, allocationType, }); useEffect(() => { if (getRoleFromUrl() === "Steward") { setValue("free"); } }, []); useEffect(() => { fetchCalendarData(selectedDate1); }, [fetchCalendarData, selectedDate1]); 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(() => { dispatch(provincePolicyGetUploadImageService()).then((r) => { if (r.payload?.data) { setImageUploadLimit(r.payload.data.killHouseAllocation); } }); if (!editData) { dispatch(slaughterGetProductsService()).then((r) => { setProductData(r.payload.data); }); if (!item) { dispatch( slaughterGetGuildsForAllocateService({ free: value === "free" ? true : false, }) ).then((r) => { setGuildsData(r.payload.data); }); } } }, [dispatch, value]); 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 = () => { dispatch(CLOSE_MODAL()); openNotif({ vertical: "top", horizontal: "center", msg: "عملیات با موفقیت انجام شد.", severity: "success", }); dispatch(fetchSlaughterBroadcastAndProducts()); dispatch( DRAWER({ right: false, bottom: false, left: false, content: null, }) ); fetchApiData && fetchApiData(1); updateTable && updateTable(); fetchData && fetchData(1); }; const [dateRangeError, setDateRangeError] = useState(null); return ( {!editData && ( ( )} 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 && ( { return { data: i, label: `${i.name}`, }; }) : [] } onChange={(event, value) => { setProductKey(value.data); }} renderInput={(params) => ( )} /> )} {!editData && ( } label="صنوف اختصاصی" /> } label="صنوف آزاد" /> )} {!item && !editData && ( { return { data: i, label: `${i?.steward ? "مباشر" : "صنف"} ${ i?.guildsName } ${i?.user?.fullname} (${i?.user?.mobile})`, }; }) : [] } onChange={(event, value) => { setBuyerData({ item: value?.data, key: value?.data?.key, allocationType: value?.data?.steward ? "steward_steward" : "steward_guild", buyerType: value?.data?.steward ? "Steward" : "Guild", }); 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) => ( )} /> )} {!item && !editData && ( setChangeMobile(!changeMobile)} /> از این قسمت میتوانید تلفن مباشر/صنف را ویرایش کنید. {buyerData?.key && changeMobile && ( )} )} {!item && !editData && priceInfo?.active !== false && ( } label="قیمت دولتی" /> } label="قیمت آزاد" /> )} {!item && !editData && ( } label="دولتی" /> } label="آزاد" /> )} {productionDate && selectedDate1 && moment(productionDate).isAfter(moment(selectedDate1), "day") && ( تاریخ تولید نمی‌تواند بعد از تاریخ انتخابی باشد )} 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, }, }} /> ریال, }} 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 } /> ریال, }} 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)) && ( {formik.touched.image && Boolean(formik.errors.image) && ( ثبت تصویر الزامی است )} )} ); };