push rasad front on new repo

This commit is contained in:
2026-01-18 14:32:49 +03:30
commit 4fe6e70525
2139 changed files with 303150 additions and 0 deletions

View File

@@ -0,0 +1,602 @@
import {
Autocomplete,
Button,
CircularProgress,
FormControl,
InputAdornment,
InputLabel,
MenuItem,
Select,
TextField,
Typography,
} from "@mui/material";
import { DatePicker } from "@mui/x-date-pickers";
import { useFormik } from "formik";
import moment from "moment/moment";
import { useContext, useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { Grid } from "../../../../components/grid/Grid";
import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom";
import { AppContext } from "../../../../contexts/AppContext";
import { SPACING } from "../../../../data/spacing";
import { DRAWER } from "../../../../lib/redux/slices/appSlice";
import { Yup } from "../../../../lib/yup/yup";
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
import { slaughterGetKillerKillhousesService } from "../../../slaughter-house/services/slaughter-get-killers-killhouses";
import { slaughterGetPoultriesService } from "../../services/salughter-get-poultries";
import { slaughterEditFreeBuyService } from "../../services/slaughter-edit-free-buy";
import { slaughterGetProfile } from "../../services/slaughter-get-profile";
import { slaughterSubmitFreeBuyPostService } from "../../services/slaughter-submit-free-buy-post";
import { slaughterGetKillhousesService } from "../../services/slaughter-get-killhouses";
import { slaughterGetCountries } from "../../services/slaughter-get-countries";
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
export const SlaughterSubmitExport = ({ edit, updateTable, item }) => {
const [selectedAge1, setSelectedAge1] = useState(1);
const [selectedAge2, setSelectedAge2] = useState(1);
const dispatch = useDispatch();
const [openNotif] = useContext(AppContext);
const [maxAllowed, setMaxAllowed] = useState(0);
const [isKiller, setIsKiller] = useState(false);
const [countries, setCountries] = useState([]);
const [selectedCountry, setSelectedCountry] = useState(
item?.exportCountry ? item?.exportCountry : ""
);
const selectedSubUser = useSelector(
(state) => state.userSlice.selectedSubUser
);
const {
slaughterGetPoultries,
slaughterGetKillerKillhouses,
slaughterGetKillhouses,
} = useSelector((state) => state.slaughterSlice);
useEffect(() => {
dispatch(
slaughterGetPoultriesService({
role_key: checkPathStartsWith("slaughter")
? selectedSubUser?.key || ""
: "",
})
);
dispatch(
slaughterGetKillerKillhousesService({
role_key: checkPathStartsWith("slaughter")
? selectedSubUser?.key || ""
: "",
})
);
dispatch(
slaughterGetProfile({
role_key: checkPathStartsWith("slaughter")
? selectedSubUser?.key || ""
: "",
})
);
dispatch(
slaughterGetKillhousesService({
role_key: checkPathStartsWith("slaughter")
? selectedSubUser?.key || ""
: "",
})
);
dispatch(
slaughterGetCountries({
role_key: checkPathStartsWith("slaughter")
? selectedSubUser?.key || ""
: "",
})
).then((r) => {
setCountries(r.payload.data);
});
}, [selectedSubUser?.key]);
const initialValues = {
killhouse: null,
killerPlace: null,
poultry: null,
killDate: item ? new Date(item.createDate) : new Date(),
numberForBuy: item ? item.killCapacity : null,
indexWeight: item ? item.IndexWeight : "",
};
const onSubmit = (values) => {
dispatch(
slaughterSubmitFreeBuyPostService({
kill_capacity: values.numberForBuy,
recive_time: "12 - 14",
recive_date: values.killDate,
low_weight: false,
high_weight: false,
Index_weight: values.indexWeight,
chicken_breed: formik?.values?.poultry?.item?.hatchingAge?.breed,
cash: true,
credit: false,
sms_payment: false,
kill_house_key: values.killhouse,
killer_kill_house_key: values.killerPlace ? values.killerPlace : null,
role: getRoleFromUrl(),
poultry_key: formik?.values?.poultry?.value,
export_status: true,
export_country: selectedCountry,
})
).then((r) => {
if (r.payload.error) {
openNotif({
vertical: "top",
horizontal: "center",
msg: r.payload.error,
severity: "error",
});
} else {
updateTable();
openNotif({
vertical: "top",
horizontal: "center",
msg: "عملیات با موفقیت انجام شد.",
severity: "success",
});
dispatch(
DRAWER({
right: false,
bottom: false,
left: false,
content: null,
})
);
}
});
};
useEffect(() => {
if (item) {
setMaxAllowed(
item?.poultry?.lastHatchingDiffrentRequestQuantity
?.leftExportQuantity === null
? item.poultry?.lastHatchingDiffrentRequestQuantity
?.lastHatchingRemainQuantity
: item?.poultry?.lastHatchingDiffrentRequestQuantity
?.leftExportQuantity
);
}
}, []);
const validationSchema = Yup.object().shape({
killhouse: Yup.string("")
.typeError("این فیلد الزامی است")
.required("این فیلد الزامی است"),
poultry: Yup.object("")
.typeError("این فیلد الزامی است")
.required("این فیلد الزامی است"),
numberForBuy: Yup.number()
.typeError("لطفا عدد وارد کنید")
.max(maxAllowed, "تعداد بیش از حد مجاز است")
.required("لطفا عدد وارد کنید")
.positive("لطفا عدد وارد کنید")
.integer("لطفا عدد وارد کنید"),
indexWeight: Yup.number()
.typeError("لطفا عدد وارد کنید")
.required("لطفا عدد وارد کنید")
.positive("لطفا عدد وارد کنید"),
});
const formik = useFormik({
initialValues,
validationSchema,
onSubmit,
});
useEffect(() => {
let newVal = formik.values.indexWeight;
const mystring = formik.values?.indexWeight
?.toString()
?.split(".")
?.join("");
if (formik.values.indexWeight) {
if (mystring.length <= 3) {
if (mystring.length === 2) {
newVal = mystring[0] + "." + mystring[1];
}
if (mystring.length === 3) {
newVal = mystring[0] + "." + mystring[1] + mystring[2];
}
}
}
if (isNaN(Number.parseFloat(newVal))) {
formik.setFieldValue("indexWeight", "");
} else {
formik.setFieldValue("indexWeight", Number.parseFloat(newVal));
}
}, [formik.values.indexWeight]);
const handleSubmitSearchByAge = async (event) => {
event.preventDefault();
dispatch(
slaughterGetPoultriesService({
min_age: selectedAge1 ? selectedAge1 : 1,
max_age: selectedAge2 ? selectedAge2 : 1,
role_key: checkPathStartsWith("slaughter")
? selectedSubUser?.key || ""
: "",
})
);
};
const handleSubmitSearchNoAge = async (event) => {
event.preventDefault();
setSelectedAge1(1);
setSelectedAge2(1);
dispatch(
slaughterGetPoultriesService({
role_key: checkPathStartsWith("slaughter"),
})
);
};
return (
<form onSubmit={formik.handleSubmit}>
<Grid container direction="column" gap={SPACING.SMALL}>
{!edit && (
<>
{slaughterGetKillhouses?.length ? (
<Autocomplete
id="killhouse"
disableClearable={true}
options={slaughterGetKillhouses?.map((item) => {
const buyerNamePrefix = item?.killer ? "کشتارکن" : "کشتارگاه";
return {
label: buyerNamePrefix + " " + item.name,
value: item.key,
killer: item.killer,
item: item,
disabled: item.allowDirectBuying,
};
})}
getOptionDisabled={(option) => !option.disabled}
getOptionLabel={(option) => option.label}
onChange={(_, value) => {
setIsKiller(value.killer);
formik.setFieldValue("killhouse", value.value);
}}
onBlur={formik.handleBlur}
renderInput={(params) => (
<TextField
{...params}
label="انتخاب کشتارگاه/کشتارکن"
variant="outlined"
error={
formik.touched.killhouse &&
Boolean(formik.errors.killhouse)
}
helperText={
formik.touched.killhouse && formik.errors.killhouse
}
/>
)}
/>
) : (
<CircularProgress />
)}
{isKiller && (
<Autocomplete
id="killerPlace"
disableClearable={true}
options={slaughterGetKillerKillhouses?.map((item) => {
return {
label: "کشتارگاه " + item.name,
value: item.key,
};
})}
getOptionLabel={(option) => option.label}
onChange={(_, value) =>
formik.setFieldValue("killerPlace", value.value)
}
onBlur={formik.handleBlur}
renderInput={(params) => (
<TextField
{...params}
label="انتخاب محل کشتار"
variant="outlined"
error={
formik.touched.killerPlace &&
Boolean(formik.errors.killerPlace)
}
helperText={
formik.touched.killerPlace && formik.errors.killerPlace
}
/>
)}
/>
)}
<Grid
container
alignItems="center"
gap={SPACING.SMALL}
style={{
padding: "10px",
border: "1px solid #bbb",
borderRadius: "10px",
}}
>
<Grid style={{ width: "70px" }}>
<TextField
fullWidth
size="small"
label="از سن"
id="outlined-controlled"
value={selectedAge1}
onChange={(event) => {
setSelectedAge1(event.target.value);
}}
/>
</Grid>
<Grid style={{ width: "70px" }}>
<TextField
fullWidth
size="small"
label="تا سن"
id="outlined-controlled"
value={selectedAge2}
onChange={(event) => {
setSelectedAge2(event.target.value);
}}
/>
</Grid>
<Grid display="grid" alignItems="center">
<Button
disabled={
selectedAge1 > selectedAge2 ||
selectedAge1 < 1 ||
selectedAge2 < 1
}
onClick={handleSubmitSearchByAge}
>
جستجو
</Button>
<Button color="error" onClick={handleSubmitSearchNoAge}>
حذف فیلتر
</Button>
</Grid>
</Grid>
{slaughterGetPoultries?.length ? (
<Autocomplete
id="poultry"
disableClearable={true}
options={slaughterGetPoultries?.map((item) => {
return {
label: `${item.unitName} (${item.user.fullname}) سن: ${item.lastHatchingDiffrentRequestQuantity?.age} روز / نژاد: ${item.lastHatchingDiffrentRequestQuantity?.breed}`,
value: item.key,
item,
};
})}
getOptionLabel={(option) => option.label}
onChange={(_, value) => {
formik.setFieldValue("poultry", value);
setMaxAllowed(
value?.item?.lastHatchingDiffrentRequestQuantity
?.leftExportQuantity === null
? value.item?.lastHatchingRemainQuantity
: value?.item?.lastHatchingDiffrentRequestQuantity
?.leftExportQuantity
);
}}
onBlur={formik.handleBlur}
renderInput={(params) => (
<TextField
{...params}
label="انتخاب مرغداری"
variant="outlined"
error={
formik.touched.poultry && Boolean(formik.errors.poultry)
}
helperText={formik.touched.poultry && formik.errors.poultry}
/>
)}
/>
) : (
<Typography color="error" variant="body2">
موردی یافت نشد!
</Typography>
)}
{formik.values.poultry && (
<Grid container direction="column" justifyContent="space-between">
<Grid container gap={SPACING.TINY}>
<Typography>نام و نام خانوادگی:</Typography>
<Typography>
{formik?.values?.poultry?.item.user.fullname}
</Typography>
</Grid>
<Grid container gap={SPACING.TINY}>
<Typography>تلفن:</Typography>
<Typography>
{formik?.values?.poultry?.item.user.mobile}
</Typography>
</Grid>
<Grid container gap={SPACING.TINY}>
<Typography>آدرس:</Typography>
<Typography>
{`${formik?.values?.poultry?.item.address.province.name} - ${formik?.values?.poultry?.item.address.city.name} - ${formik?.values?.poultry?.item.address.address}`}
</Typography>
</Grid>
<Grid container gap={SPACING.TINY}>
<Typography>سن جوجه:</Typography>
<Typography>
{
formik?.values?.poultry?.item
?.lastHatchingDiffrentRequestQuantity?.age
}{" "}
روز
</Typography>
</Grid>
<Grid container gap={SPACING.TINY}>
<Typography>مانده در سالن:</Typography>
<Typography>
{formik?.values?.poultry?.item?.lastHatchingRemainQuantity?.toLocaleString()}{" "}
قطعه
</Typography>
</Grid>
<Grid container gap={SPACING.TINY}>
<Typography color="error"> مانده قابل صادرات:</Typography>
<Typography color="error">
{maxAllowed?.toLocaleString()} قطعه
</Typography>
</Grid>
{/* <Grid container gap={SPACING.TINY}>
<Typography>نژاد:</Typography>
<Typography>
{formik?.values?.poultry?.item?.hatchingAge?.breed}
</Typography>
</Grid> */}
</Grid>
)}
</>
)}
<DatePicker
fullWidth
label="تاریخ کشتار"
id="killDate"
renderInput={(params) => <TextField {...params} />}
value={formik.values.killDate}
error={
formik.touched.killDate ? Boolean(formik.errors.killDate) : null
}
onChange={(e) => {
formik.setFieldValue(
"killDate",
moment(e).format("YYYY-MM-DD hh:mm:ss")
);
}}
onBlur={formik.handleBlur}
helperText={
formik.touched.killDate && Boolean(formik.errors.killDate)
? formik.errors.killDate
: null
}
/>
<NumberInput
allowLeadingZeros
thousandSeparator=","
id="numberForBuy"
name="numberForBuy"
label="قطعه"
variant="outlined"
value={formik.values.numberForBuy}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
error={
formik.touched.numberForBuy && Boolean(formik.errors.numberForBuy)
}
helperText={formik.touched.numberForBuy && formik.errors.numberForBuy}
/>
<TextField
id="indexWeight"
name="indexWeight"
label="میانگین وزنی"
variant="outlined"
value={formik.values.indexWeight}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
InputProps={{
endAdornment: (
<InputAdornment position="end">کیلوگرم</InputAdornment>
),
}}
error={
formik.touched.indexWeight && Boolean(formik.errors.indexWeight)
}
helperText={formik.touched.indexWeight && formik.errors.indexWeight}
/>
<FormControl>
<InputLabel id="hour-label">کشور مقصد</InputLabel>
<Select
labelId="hour-label"
label="کشور مقصد"
id="hour-select"
value={selectedCountry}
onChange={(event) => setSelectedCountry(event.target.value)}
>
{countries?.map((country) => (
<MenuItem key={country.fa} value={country.fa}>
{country.fa}
</MenuItem>
))}
</Select>
</FormControl>
{!edit && (
<Button
type="submit"
variant="contained"
color="primary"
fullWidth
disabled={!selectedCountry}
>
ثبت
</Button>
)}
{edit && (
<Button
disabled={
!formik.values.numberForBuy ||
!formik.values.killDate ||
!formik.values.indexWeight ||
formik.values.numberForBuy > maxAllowed ||
!selectedCountry
}
variant="contained"
color="primary"
fullWidth
onClick={() => {
dispatch(
slaughterEditFreeBuyService({
role: getRoleFromUrl(),
kill_capacity: formik.values.numberForBuy,
recive_date: formik.values.killDate,
Index_weight: formik.values.indexWeight,
kill_request_key: item.key,
remain_quantity: formik.values.numberForBuy,
export_status: true,
})
).then((r) => {
if (r?.payload?.error) {
openNotif({
vertical: "top",
horizontal: "center",
msg: r?.payload?.error,
severity: "error",
});
} else {
updateTable();
openNotif({
vertical: "top",
horizontal: "center",
msg: "عملیات با موفقیت انجام شد.",
severity: "success",
});
dispatch(
DRAWER({
right: false,
bottom: false,
left: false,
content: null,
})
);
}
});
}}
>
ثبت ویرایش
</Button>
)}
</Grid>
</form>
);
};