push rasad front on new repo
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
import { Button, IconButton, Popover } from "@mui/material";
|
||||
import { useState } from "react";
|
||||
import { useDispatch } from "react-redux";
|
||||
import TuneIcon from "@mui/icons-material/Tune";
|
||||
import { stewardDeleteFreeBarService } from "../../../guild/services/steward-submit-free-bar-service";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { DRAWER } from "../../../../lib/redux/slices/appSlice";
|
||||
import { StewardSubmitFreeBar } from "../steward-submit-free-bar/StewardSubmitFreeBar";
|
||||
|
||||
export const StewardSellOutOperations = ({ item, updateTable }) => {
|
||||
const dispatch = useDispatch();
|
||||
const [anchorEl, setAnchorEl] = useState(null);
|
||||
|
||||
const handleClick = (event) => {
|
||||
setAnchorEl(event.currentTarget);
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setAnchorEl(null);
|
||||
};
|
||||
|
||||
const open = Boolean(anchorEl);
|
||||
const id = open ? "popover" : undefined;
|
||||
|
||||
const handleDelete = () => {
|
||||
handleClose();
|
||||
dispatch(stewardDeleteFreeBarService(item.key)).then(() => {
|
||||
updateTable();
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<IconButton
|
||||
aria-describedby={id}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={handleClick}
|
||||
>
|
||||
<TuneIcon />
|
||||
</IconButton>
|
||||
<Popover
|
||||
anchorOrigin={{
|
||||
vertical: "bottom",
|
||||
horizontal: "right",
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: "top",
|
||||
horizontal: "left",
|
||||
}}
|
||||
id={id}
|
||||
open={open}
|
||||
anchorEl={anchorEl}
|
||||
onClose={handleClose}
|
||||
>
|
||||
<div style={{ padding: "20px" }}>
|
||||
<Grid container direction="column" gap={1}>
|
||||
<Button
|
||||
onClick={() => {
|
||||
handleClose();
|
||||
dispatch(
|
||||
DRAWER({
|
||||
right: !(window.innerWidth <= 600),
|
||||
bottom: window.innerWidth <= 600,
|
||||
title: "ویرایش خرید خارج استان",
|
||||
content: (
|
||||
<StewardSubmitFreeBar
|
||||
item={item}
|
||||
updateTable={updateTable}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
ویرایش
|
||||
</Button>
|
||||
<Button color="error" onClick={handleDelete}>
|
||||
حذف
|
||||
</Button>
|
||||
</Grid>
|
||||
</div>
|
||||
</Popover>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,99 @@
|
||||
import React, { useContext, useState } from "react";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { Button, TextField } from "@mui/material";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { guildEditOutOfProvinceService } from "../../../slaughter-house/services/slaughterEditOutOfProvinceService";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import { Done } from "@mui/icons-material";
|
||||
|
||||
export const StewardOutProvinceRegistrationCodeInput = ({
|
||||
item,
|
||||
fetchApiData,
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
const [openNotif] = useContext(AppContext);
|
||||
const [registrationCode, setRegistrationCode] = useState(
|
||||
item?.loggedRegistrationCode || ""
|
||||
);
|
||||
|
||||
const handleSubmit = () => {
|
||||
dispatch(
|
||||
guildEditOutOfProvinceService({
|
||||
key: item?.key,
|
||||
register_code: parseInt(registrationCode),
|
||||
role: getRoleFromUrl(),
|
||||
// Include all required fields from item
|
||||
date: item?.date,
|
||||
buyer_name: item?.buyerName,
|
||||
buyer_mobile: item?.buyerMobile,
|
||||
province: item?.province,
|
||||
city: item?.city,
|
||||
clearance_code: item?.clearanceCode,
|
||||
number_of_carcasses: item?.numberOfCarcasses,
|
||||
quarantine_weight_of_carcasses: item?.quarantineWeightOfCarcasses,
|
||||
weight_of_carcasses: item?.weightOfCarcasses,
|
||||
...(item?.buyer?.key && { buyer_key: item?.buyer?.key }),
|
||||
})
|
||||
).then((r) => {
|
||||
if (r.payload.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.error,
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "کد احراز با موفقیت ثبت شد.",
|
||||
severity: "success",
|
||||
});
|
||||
fetchApiData();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
direction="row"
|
||||
alignItems="center"
|
||||
justifyContent="flex-start"
|
||||
gap={1}
|
||||
sx={{ position: "relative" }}
|
||||
>
|
||||
<TextField
|
||||
value={registrationCode}
|
||||
size="small"
|
||||
onChange={(e) => setRegistrationCode(e.target.value)}
|
||||
style={{ minWidth: "150px" }}
|
||||
disabled={item?.loggedRegistrationCode}
|
||||
placeholder="کد احراز"
|
||||
inputProps={{
|
||||
inputMode: "numeric",
|
||||
pattern: "[0-9]*",
|
||||
}}
|
||||
type="number"
|
||||
/>
|
||||
{!item?.loggedRegistrationCode && registrationCode && (
|
||||
<Button
|
||||
size="small"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={handleSubmit}
|
||||
sx={{
|
||||
position: "absolute",
|
||||
right: "0",
|
||||
minWidth: "40px",
|
||||
width: "40px",
|
||||
height: "38px",
|
||||
}}
|
||||
>
|
||||
<Done />
|
||||
</Button>
|
||||
)}
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,177 @@
|
||||
import React, { useContext, useState } from "react";
|
||||
import { Button, IconButton, Popover, Tooltip } from "@mui/material";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { DRAWER } from "../../../../lib/redux/slices/appSlice";
|
||||
import { stewardDeleteOutSellService } from "../../../guild/services/steward-sell-out-delete-service";
|
||||
import { StewardSellOutOfProvinceEditSell } from "../steward-purchase-out-province-edit-sell/StewardSellOutOfProvinceEditSell";
|
||||
import { fetchStewardBroadcastAndProducts } from "../../services/handle-fetch-steward-products";
|
||||
import { stewardResendOutProvinceRegistrationCodeService } from "../../services/steward-resend-out-province-registration-code";
|
||||
import TuneIcon from "@mui/icons-material/Tune";
|
||||
import EditIcon from "@mui/icons-material/Edit";
|
||||
import DeleteIcon from "@mui/icons-material/Delete";
|
||||
import SendIcon from "@mui/icons-material/Send";
|
||||
|
||||
export const StewardOutProvinceSalesOperations = ({
|
||||
item,
|
||||
updateTable,
|
||||
fetchApiData,
|
||||
page,
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
const [openNotif] = useContext(AppContext);
|
||||
const [popoverOpen, setPopoverOpen] = useState(false);
|
||||
const [anchorEl, setAnchorEl] = useState(null);
|
||||
|
||||
const openPopover = (event) => {
|
||||
setPopoverOpen(true);
|
||||
setAnchorEl(event.currentTarget);
|
||||
};
|
||||
|
||||
const closePopover = () => {
|
||||
setPopoverOpen(false);
|
||||
setAnchorEl(null);
|
||||
};
|
||||
|
||||
const handleEdit = () => {
|
||||
closePopover();
|
||||
dispatch(
|
||||
DRAWER({
|
||||
right: !(window.innerWidth <= 600),
|
||||
bottom: window.innerWidth <= 600,
|
||||
title: "ویرایش فروش خارج از استان",
|
||||
content: (
|
||||
<StewardSellOutOfProvinceEditSell
|
||||
fetchItems={updateTable}
|
||||
isEdit={true}
|
||||
item={item}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const handleDelete = () => {
|
||||
closePopover();
|
||||
dispatch(stewardDeleteOutSellService(item?.key)).then((r) => {
|
||||
if (r.payload.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.data.result,
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
updateTable();
|
||||
dispatch(fetchStewardBroadcastAndProducts());
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.data.result,
|
||||
severity: "success",
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleResend = () => {
|
||||
closePopover();
|
||||
dispatch(
|
||||
stewardResendOutProvinceRegistrationCodeService({
|
||||
key: item?.key,
|
||||
})
|
||||
).then((r) => {
|
||||
if (r.payload.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.error,
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "کد با موفقیت ارسال شد.",
|
||||
severity: "success",
|
||||
});
|
||||
fetchApiData(page);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const open = Boolean(anchorEl);
|
||||
const id = open ? "popover" : undefined;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<IconButton
|
||||
aria-describedby={id}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={openPopover}
|
||||
>
|
||||
<TuneIcon />
|
||||
</IconButton>
|
||||
<Popover
|
||||
anchorOrigin={{
|
||||
vertical: "bottom",
|
||||
horizontal: "right",
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: "top",
|
||||
horizontal: "left",
|
||||
}}
|
||||
id={id}
|
||||
open={open}
|
||||
anchorEl={anchorEl}
|
||||
onClose={closePopover}
|
||||
>
|
||||
<div style={{ padding: "20px" }}>
|
||||
<Grid container direction="column">
|
||||
<Tooltip title="ویرایش" placement="left-start">
|
||||
<Button
|
||||
aria-label="edit"
|
||||
color="primary"
|
||||
variant="text"
|
||||
onClick={handleEdit}
|
||||
startIcon={<EditIcon />}
|
||||
>
|
||||
ویرایش
|
||||
</Button>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip title="حذف" placement="left-start">
|
||||
<Button
|
||||
aria-label="delete"
|
||||
color="error"
|
||||
variant="text"
|
||||
onClick={handleDelete}
|
||||
startIcon={<DeleteIcon />}
|
||||
>
|
||||
حذف
|
||||
</Button>
|
||||
</Tooltip>
|
||||
|
||||
{item?.systemRegistrationCode &&
|
||||
item?.registrationCode &&
|
||||
!item?.loggedRegistrationCode && (
|
||||
<Tooltip title="ارسال مجدد کد" placement="left-start">
|
||||
<Button
|
||||
aria-label="resend"
|
||||
color="success"
|
||||
variant="text"
|
||||
onClick={handleResend}
|
||||
startIcon={<SendIcon />}
|
||||
>
|
||||
ارسال مجدد کد
|
||||
</Button>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Grid>
|
||||
</div>
|
||||
</Popover>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,420 @@
|
||||
import { useFormik } from "formik";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import {
|
||||
Autocomplete,
|
||||
Button,
|
||||
IconButton,
|
||||
TextField,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import SearchIcon from "@mui/icons-material/Search";
|
||||
import { Yup } from "../../../../lib/yup/yup";
|
||||
import {
|
||||
slaughterGetCitiesService,
|
||||
slaughterGetProvinceService,
|
||||
} from "../../../slaughter-house/services/slaughter-get-provinces";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import {
|
||||
stewardSellOutGetBuyers,
|
||||
stewatdSubmitBuyerDataService,
|
||||
} from "../../../guild/services/steward-sell-out-get-buyers";
|
||||
import { DRAWER, LOADING_END } from "../../../../lib/redux/slices/appSlice";
|
||||
import { slaughterEditBuyerDataService } from "../../../slaughter-house/services/slaughter-house-submit-buyer";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
|
||||
export const StewardSellOutOfProvinceAddBuyer = ({
|
||||
updateTable,
|
||||
isEdit,
|
||||
data,
|
||||
}) => {
|
||||
const [openNotif] = useContext(AppContext);
|
||||
const [userData, setUserData] = useState(null);
|
||||
const [notFound, setNotFound] = useState(false);
|
||||
const dispatch = useDispatch();
|
||||
const [provinceData, setProvinceData] = useState([]);
|
||||
const [cityData, setCityData] = useState([]);
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues: {
|
||||
mobile: "",
|
||||
firstName: "",
|
||||
lastName: "",
|
||||
unitName: "",
|
||||
province: "",
|
||||
city: "",
|
||||
},
|
||||
validationSchema: Yup.object({
|
||||
mobile: Yup.string()
|
||||
.required("این فیلد اجباری است!")
|
||||
.min(11, "شماره موبایل باید 11 رقم باشد")
|
||||
.max(11, "شماره موبایل باید 11 رقم باشد")
|
||||
.matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"),
|
||||
firstName: Yup.string()
|
||||
.required("این فیلد اجباری است!")
|
||||
.typeError("لطفا فیلد را به درستی وارد کنید!"),
|
||||
lastName: Yup.string()
|
||||
.required("این فیلد اجباری است!")
|
||||
.typeError("لطفا فیلد را به درستی وارد کنید!"),
|
||||
unitName: Yup.string()
|
||||
.required("این فیلد اجباری است!")
|
||||
.typeError("لطفا فیلد را به درستی وارد کنید!"),
|
||||
province: Yup.string()
|
||||
.required("این فیلد اجباری است!")
|
||||
.typeError("لطفا فیلد را به درستی وارد کنید!"),
|
||||
city: Yup.string()
|
||||
.required("این فیلد اجباری است!")
|
||||
.typeError("لطفا فیلد را به درستی وارد کنید!"),
|
||||
}),
|
||||
});
|
||||
|
||||
const formik2 = useFormik({
|
||||
initialValues: {
|
||||
userInfoCheck: "",
|
||||
},
|
||||
validationSchema: Yup.object({
|
||||
userInfoCheck: Yup.string()
|
||||
.required("این فیلد اجباری است!")
|
||||
.min(11, "شماره موبایل باید 11 رقم باشد")
|
||||
.max(11, "شماره موبایل باید 11 رقم باشد")
|
||||
.matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"),
|
||||
}),
|
||||
validateOnMount: true,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
formik.validateForm();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (userData) {
|
||||
formik.setValues({
|
||||
mobile: userData.mobile || "",
|
||||
firstName: userData.firstName || "",
|
||||
lastName: userData.lastName || "",
|
||||
unitName: userData.unitName || "",
|
||||
province: userData.province || "",
|
||||
city: userData.city || "",
|
||||
});
|
||||
setTimeout(() => {
|
||||
formik.validateForm();
|
||||
}, 1);
|
||||
}
|
||||
}, [userData]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isEdit) {
|
||||
formik.setValues({
|
||||
mobile: data.mobile || "",
|
||||
firstName: data.firstName || "",
|
||||
lastName: data.lastName || "",
|
||||
unitName: data.unitName || "",
|
||||
province: data.province || "",
|
||||
city: data.city || "",
|
||||
});
|
||||
setTimeout(() => {
|
||||
formik.validateForm();
|
||||
}, 1);
|
||||
}
|
||||
}, [isEdit]);
|
||||
|
||||
useEffect(() => {
|
||||
if (notFound) {
|
||||
formik.setFieldValue("mobile", formik2.values.userInfoCheck);
|
||||
}
|
||||
}, [notFound]);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(slaughterGetProvinceService()).then((r) => {
|
||||
setProvinceData(r.payload.data);
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (formik.values.province) {
|
||||
setCityData(
|
||||
[],
|
||||
dispatch(slaughterGetCitiesService(formik.values.province)).then(
|
||||
(r) => {
|
||||
setCityData(r.payload.data);
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}, [formik.values.province]);
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
xs={12}
|
||||
direction="column"
|
||||
gap={2}
|
||||
>
|
||||
{!userData && !isEdit ? (
|
||||
<Grid container xs={12}>
|
||||
<Typography>جستجو کاربر</Typography>
|
||||
<Grid mt={SPACING.SMALL} display="flex" width={1}>
|
||||
<TextField
|
||||
fullWidth
|
||||
id="userInfoCheck"
|
||||
label="شماره موبایل"
|
||||
variant="outlined"
|
||||
value={formik2.values.userInfoCheck}
|
||||
error={
|
||||
formik2.touched.userInfoCheck &&
|
||||
Boolean(formik2.errors.userInfoCheck)
|
||||
}
|
||||
onChange={(e) => {
|
||||
formik2.handleChange(e);
|
||||
// Reset notFound when user starts typing
|
||||
if (notFound) {
|
||||
setNotFound(false);
|
||||
}
|
||||
}}
|
||||
onBlur={formik2.handleBlur}
|
||||
helperText={
|
||||
formik2.touched.userInfoCheck && formik2.errors.userInfoCheck
|
||||
}
|
||||
/>
|
||||
<IconButton
|
||||
disabled={!formik2.isValid}
|
||||
aria-label="search"
|
||||
color="primary"
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
stewardSellOutGetBuyers({
|
||||
mobile: formik2.values.userInfoCheck,
|
||||
role_key: checkPathStartsWith("steward")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
).then((r) => {
|
||||
dispatch(LOADING_END());
|
||||
if (r.error) {
|
||||
setNotFound(true);
|
||||
setUserData(null);
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "خریدار یافت نشد، یک خریدار جدید ثبت کنید!",
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
const responseData = r.payload?.data;
|
||||
// Check if response is an empty array
|
||||
if (
|
||||
Array.isArray(responseData) &&
|
||||
responseData.length === 0
|
||||
) {
|
||||
setNotFound(true);
|
||||
setUserData(null);
|
||||
} else {
|
||||
setNotFound(false);
|
||||
setUserData(responseData);
|
||||
}
|
||||
}
|
||||
});
|
||||
}}
|
||||
>
|
||||
<SearchIcon />
|
||||
</IconButton>
|
||||
</Grid>
|
||||
{notFound && (
|
||||
<Grid container xs={12} mt={SPACING.SMALL}>
|
||||
<Typography variant="body2" color="error" sx={{ width: "100%" }}>
|
||||
خریداری یافت نشد
|
||||
</Typography>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
) : (
|
||||
<Grid
|
||||
container
|
||||
justifyContent="space-between"
|
||||
alignItems="start"
|
||||
xs={12}
|
||||
direction="column"
|
||||
gap={2}
|
||||
>
|
||||
<TextField
|
||||
fullWidth
|
||||
id="mobile"
|
||||
label="شماره موبایل"
|
||||
variant="outlined"
|
||||
value={formik.values.mobile}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={formik.touched.mobile && formik.errors.mobile}
|
||||
/>
|
||||
<TextField
|
||||
fullWidth
|
||||
id="firstName"
|
||||
label="نام"
|
||||
variant="outlined"
|
||||
value={formik.values.firstName}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={formik.touched.firstName && formik.errors.firstName}
|
||||
/>
|
||||
<TextField
|
||||
fullWidth
|
||||
id="lastName"
|
||||
label="نام خانوادگی"
|
||||
variant="outlined"
|
||||
value={formik.values.lastName}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={formik.touched.lastName && formik.errors.lastName}
|
||||
/>
|
||||
<TextField
|
||||
fullWidth
|
||||
id="unitName"
|
||||
label="نام واحد"
|
||||
variant="outlined"
|
||||
value={formik.values.unitName}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={formik.touched.unitName && formik.errors.unitName}
|
||||
/>
|
||||
|
||||
<Autocomplete
|
||||
style={{ width: "100%" }}
|
||||
disablePortal
|
||||
id="province"
|
||||
options={
|
||||
provinceData
|
||||
? provinceData.map((i) => ({ id: i.name, label: i.name }))
|
||||
: []
|
||||
}
|
||||
onChange={(e, value) => {
|
||||
formik.setFieldValue("province", value ? value.id : "");
|
||||
formik.setFieldValue("city", "");
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField {...params} label="استان را انتخاب کنید" />
|
||||
)}
|
||||
/>
|
||||
{!notFound && (
|
||||
<Typography variant="caption" color="error">
|
||||
استان: {formik.values.province}
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
<Autocomplete
|
||||
minWidth={210}
|
||||
style={{ width: "100%" }}
|
||||
disabled={!formik.values.province}
|
||||
disablePortal
|
||||
id="city"
|
||||
options={
|
||||
cityData
|
||||
? cityData.map((i) => ({ id: i.name, label: i.name }))
|
||||
: []
|
||||
}
|
||||
onChange={(e, value) => {
|
||||
formik.setFieldValue("city", value ? value.id : "");
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField {...params} label="شهر را انتخاب کنید" />
|
||||
)}
|
||||
/>
|
||||
|
||||
{!notFound && (
|
||||
<Typography variant="caption" color="error">
|
||||
شهر: {formik.values.city}
|
||||
</Typography>
|
||||
)}
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
{(userData || isEdit) && (
|
||||
<Grid container xs={12}>
|
||||
<Button
|
||||
fullWidth
|
||||
variant="contained"
|
||||
disabled={!formik.isValid}
|
||||
onClick={() => {
|
||||
if (isEdit) {
|
||||
dispatch(
|
||||
slaughterEditBuyerDataService({
|
||||
buyer_key: data?.key,
|
||||
mobile: formik.values.mobile,
|
||||
first_name: formik.values.firstName,
|
||||
last_name: formik.values.lastName,
|
||||
unit_name: formik.values.unitName,
|
||||
city: formik.values.city,
|
||||
province: formik.values.province,
|
||||
})
|
||||
).then((r) => {
|
||||
updateTable();
|
||||
if (r.payload.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.error,
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
dispatch(
|
||||
DRAWER({ right: false, bottom: false, content: null })
|
||||
);
|
||||
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
dispatch(
|
||||
stewatdSubmitBuyerDataService({
|
||||
role: getRoleFromUrl(),
|
||||
mobile: formik.values.mobile,
|
||||
first_name: formik.values.firstName,
|
||||
last_name: formik.values.lastName,
|
||||
unit_name: formik.values.unitName,
|
||||
city: formik.values.city,
|
||||
province: formik.values.province,
|
||||
})
|
||||
).then((r) => {
|
||||
updateTable();
|
||||
if (r.payload.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.error,
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
dispatch(
|
||||
DRAWER({ right: false, bottom: false, content: null })
|
||||
);
|
||||
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
{isEdit ? "ویرایش" : "ثبت"}
|
||||
</Button>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,184 @@
|
||||
import { useDispatch } from "react-redux";
|
||||
import { useContext } from "react";
|
||||
import moment from "moment";
|
||||
import { Field, Form, Formik } from "formik";
|
||||
import { DatePicker } from "@mui/x-date-pickers";
|
||||
import { Button, TextField } from "@mui/material";
|
||||
import { Yup } from "../../../../lib/yup/yup";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { guildEditOutOfProvinceService } from "../../../slaughter-house/services/slaughterEditOutOfProvinceService";
|
||||
import {
|
||||
guildSubmitOutOfProvinceService,
|
||||
slaughterSubmitOutOfProvinceService,
|
||||
} from "../../../slaughter-house/services/slaughter-submit-out-province-service";
|
||||
import { stewardEditBuyerDataService } from "../../../guild/services/steward-edit-sell-out-buyer";
|
||||
import { guildGetInventoryStockService } from "../../../guild/services/guild-get-inventory-stock";
|
||||
import { guildGetFreeSaleBarService } from "../../../guild/services/guild-get-free-sale-bar";
|
||||
import { DRAWER } from "../../../../lib/redux/slices/appSlice";
|
||||
import { fetchStewardBroadcastAndProducts } from "../../services/handle-fetch-steward-products";
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
quarantineCode: Yup.string().required("کد قرنطینه الزامی است"),
|
||||
carcassCount: Yup.number().required("حجم لاشه الزامی است"),
|
||||
carcassWeight: Yup.number().required("وزن لاشه الزامی است"),
|
||||
date: Yup.string().required("تاریخ الزامی است"),
|
||||
});
|
||||
|
||||
export const StewardSellOutOfProvinceEditSell = ({
|
||||
fetchItems,
|
||||
isEdit,
|
||||
item,
|
||||
selectedDate,
|
||||
stewardKey,
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
const [openNotif] = useContext(AppContext);
|
||||
|
||||
const initialValues = {
|
||||
quarantineCode: item?.clearanceCode || "",
|
||||
carcassCount: item?.numberOfCarcasses || "0",
|
||||
carcassWeight: item?.weightOfCarcasses || "",
|
||||
date: item?.date || moment().format("YYYY-MM-DD HH:mm:ss"),
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid>
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
validationSchema={validationSchema}
|
||||
onSubmit={(values) => {
|
||||
const payload = {
|
||||
...values,
|
||||
date: values.date,
|
||||
number_of_carcasses: values.carcassCount,
|
||||
weight_of_carcasses: values.carcassWeight,
|
||||
};
|
||||
|
||||
if (values.quarantineCode !== item?.quarantineCode) {
|
||||
payload.quarantineCode = values.quarantineCode;
|
||||
}
|
||||
|
||||
const service = stewardKey
|
||||
? isEdit
|
||||
? guildEditOutOfProvinceService({ key: item?.key, ...payload })
|
||||
: guildSubmitOutOfProvinceService({
|
||||
steward_key: stewardKey,
|
||||
...payload,
|
||||
})
|
||||
: isEdit
|
||||
? stewardEditBuyerDataService({
|
||||
key: item?.key,
|
||||
driver_mobile: values.driverPhone,
|
||||
...payload,
|
||||
})
|
||||
: slaughterSubmitOutOfProvinceService({
|
||||
driver_mobile: values.driverPhone,
|
||||
...payload,
|
||||
});
|
||||
|
||||
dispatch(service).then((r) => {
|
||||
if (r.payload.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.error,
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
stewardKey
|
||||
? dispatch(guildGetInventoryStockService({ date: values.date }))
|
||||
: fetchItems();
|
||||
|
||||
stewardKey &&
|
||||
dispatch(
|
||||
guildGetFreeSaleBarService({
|
||||
date: values.date,
|
||||
steward_key: stewardKey,
|
||||
})
|
||||
);
|
||||
|
||||
dispatch(fetchStewardBroadcastAndProducts());
|
||||
dispatch(DRAWER({ right: false, bottom: false, content: null }));
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
}
|
||||
});
|
||||
}}
|
||||
>
|
||||
{({ errors, touched, setFieldValue, values }) => (
|
||||
<Form>
|
||||
<Grid
|
||||
container
|
||||
spacing={1}
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
>
|
||||
<Grid item xs={12}>
|
||||
<Field
|
||||
as={TextField}
|
||||
name="quarantineCode"
|
||||
label="کد قرنطینه"
|
||||
fullWidth
|
||||
error={
|
||||
touched.quarantineCode && Boolean(errors.quarantineCode)
|
||||
}
|
||||
helperText={touched.quarantineCode && errors.quarantineCode}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Field
|
||||
as={TextField}
|
||||
name="carcassCount"
|
||||
label="حجم لاشه"
|
||||
type="number"
|
||||
fullWidth
|
||||
error={touched.carcassCount && Boolean(errors.carcassCount)}
|
||||
helperText={touched.carcassCount && errors.carcassCount}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<DatePicker
|
||||
label="تاریخ"
|
||||
value={moment(values.date)}
|
||||
onChange={(val) => {
|
||||
const formatted = moment(val).format("YYYY-MM-DD HH:mm:ss");
|
||||
setFieldValue("date", formatted);
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
{...params}
|
||||
fullWidth
|
||||
error={touched.date && Boolean(errors.date)}
|
||||
helperText={touched.date && errors.date}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Field
|
||||
as={TextField}
|
||||
name="carcassWeight"
|
||||
label="وزن لاشه"
|
||||
type="number"
|
||||
fullWidth
|
||||
error={touched.carcassWeight && Boolean(errors.carcassWeight)}
|
||||
helperText={touched.carcassWeight && errors.carcassWeight}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Button variant="contained" fullWidth type="submit">
|
||||
{isEdit ? "ویرایش" : "ثبت"}
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Form>
|
||||
)}
|
||||
</Formik>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,546 @@
|
||||
import { useContext, useEffect, useState, useCallback, useRef } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import {
|
||||
Autocomplete,
|
||||
Button,
|
||||
FormControl,
|
||||
FormControlLabel,
|
||||
Radio,
|
||||
RadioGroup,
|
||||
TextField,
|
||||
} from "@mui/material";
|
||||
import { Field, Form, Formik } from "formik";
|
||||
import moment from "moment";
|
||||
import { DatePicker } from "@mui/x-date-pickers";
|
||||
import { Yup } from "../../../../lib/yup/yup";
|
||||
import { stewardSellOutGetBuyers } from "../../../guild/services/steward-sell-out-get-buyers";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { stewardGetOutSellService } from "../../../guild/services/steward-get-sell-out-service";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { stewardSellOuutSubmitSell } from "../../../guild/services/steward-sell-out-submit-sell";
|
||||
import { DRAWER } from "../../../../lib/redux/slices/appSlice";
|
||||
import { fetchStewardBroadcastAndProducts } from "../../services/handle-fetch-steward-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 { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
|
||||
const validationSchema = (selectedDateAmount) =>
|
||||
Yup.object({
|
||||
weight_of_carcasses: Yup.number()
|
||||
.required("وزن لاشهها الزامی است")
|
||||
.positive("وزن باید عددی مثبت باشد")
|
||||
.test(
|
||||
"max-production-date-amount",
|
||||
`وزن نمیتواند بیشتر از موجودی تاریخ تولید (${
|
||||
selectedDateAmount?.toLocaleString() || 0
|
||||
} کیلوگرم) باشد!`,
|
||||
function (value) {
|
||||
if (!selectedDateAmount || selectedDateAmount === null) return true;
|
||||
return value <= selectedDateAmount;
|
||||
}
|
||||
),
|
||||
|
||||
clearance_code: Yup.string()
|
||||
.required("کد قرنطینه الزامی است")
|
||||
.matches(
|
||||
/^(?=.*[A-Z])(?=.*\d)[A-Z0-9]+$/,
|
||||
"کد قرنطینه باید ترکیبی از حروف بزرگ انگلیسی و عدد باشد"
|
||||
),
|
||||
date: Yup.date().required("تاریخ الزامی است"),
|
||||
production_date: Yup.string().required("تاریخ تولید الزامی است"),
|
||||
});
|
||||
|
||||
export const StewardSellOutOfProvinceSubmitSell = ({
|
||||
updateTable,
|
||||
fetchItems,
|
||||
isInventory,
|
||||
}) => {
|
||||
const [productData, setProductData] = useState([]);
|
||||
const [productKey, setProductKey] = useState(null);
|
||||
const [buterData, setBuyerData] = useState([]);
|
||||
const [buyerSelected, setBuyerSelected] = useState(null);
|
||||
const [selectedInventory] = useState("free");
|
||||
const [approvedStatus, setApprovedStatus] = useState("governmental");
|
||||
const [selectedCalendarDate, setSelectedCalendarDate] = useState(null);
|
||||
const [calendarDayData, setCalendarDayData] = useState({});
|
||||
const [productionDate, setProductionDate] = useState(null);
|
||||
const [selectedDateAmount, setSelectedDateAmount] = useState(null);
|
||||
const [calendarDateError, setCalendarDateError] = useState(null);
|
||||
const formikRef = useRef(null);
|
||||
const dispatch = useDispatch();
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
|
||||
const [openNotif] = useContext(AppContext);
|
||||
|
||||
const handleDateSelect = (dateInfo) => {
|
||||
if (dateInfo && dateInfo.formattedDate) {
|
||||
setSelectedCalendarDate(dateInfo.formattedDate);
|
||||
|
||||
// Get the data for the selected date
|
||||
const data = calendarDayData[dateInfo.formattedDate];
|
||||
|
||||
// Use the original Gregorian date from the API data for production_date
|
||||
if (data && data.originalDay) {
|
||||
// Prevent choosing a production date after the main form date
|
||||
if (
|
||||
formikRef.current?.values?.date &&
|
||||
moment(data.originalDay).isAfter(
|
||||
moment(formikRef.current.values.date),
|
||||
"day"
|
||||
)
|
||||
) {
|
||||
setCalendarDateError(
|
||||
"تاریخ تولید نمیتواند بعد از تاریخ انتخابی باشد"
|
||||
);
|
||||
return;
|
||||
}
|
||||
setCalendarDateError(null);
|
||||
setProductionDate(data.originalDay);
|
||||
if (formikRef.current) {
|
||||
formikRef.current.setFieldValue("production_date", data.originalDay);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the amount for the selected date
|
||||
if (data && data.value1 !== undefined) {
|
||||
setSelectedDateAmount(data.value1);
|
||||
} else {
|
||||
setSelectedDateAmount(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const transformCalendarData = useCallback((dataArray) => {
|
||||
if (!Array.isArray(dataArray)) return {};
|
||||
|
||||
const transformedData = {};
|
||||
dataArray.forEach((item) => {
|
||||
// Include all items to show amounts, but store active status
|
||||
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, // Store active status
|
||||
};
|
||||
}
|
||||
});
|
||||
return transformedData;
|
||||
}, []);
|
||||
|
||||
const updateCalendarData = useCallback(
|
||||
(dataArray) => {
|
||||
const transformed = transformCalendarData(dataArray);
|
||||
setCalendarDayData(transformed);
|
||||
},
|
||||
[transformCalendarData]
|
||||
);
|
||||
|
||||
const [selectedFormDate, setSelectedFormDate] = useState(
|
||||
moment(new Date()).format("YYYY-MM-DD")
|
||||
);
|
||||
|
||||
const fetchCalendarData = useCallback(
|
||||
async (dateParam = selectedFormDate) => {
|
||||
try {
|
||||
const response = await axios.get("/steward-remain-weight/", {
|
||||
params: {
|
||||
date: dateParam,
|
||||
role_key: checkPathStartsWith("steward")
|
||||
? selectedSubUser?.key
|
||||
: "",
|
||||
},
|
||||
});
|
||||
if (response.data) {
|
||||
const dataToShow =
|
||||
approvedStatus === "governmental"
|
||||
? response.data.governmental
|
||||
: response.data.free;
|
||||
updateCalendarData(dataToShow || []);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching calendar data:", error);
|
||||
}
|
||||
},
|
||||
[approvedStatus, updateCalendarData, selectedFormDate, selectedSubUser]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
stewardSellOutGetBuyers({
|
||||
role_key: checkPathStartsWith("steward") ? selectedSubUser?.key : "",
|
||||
})
|
||||
).then((r) => {
|
||||
setBuyerData(r.payload.data);
|
||||
});
|
||||
}, [selectedSubUser?.key]);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
stewardGetOutSellService({
|
||||
role_key: checkPathStartsWith("steward") ? selectedSubUser?.key : "",
|
||||
})
|
||||
).then((r) => {
|
||||
const data = r.payload?.data;
|
||||
if (Array.isArray(data)) {
|
||||
setProductData(data);
|
||||
} else if (data?.data && Array.isArray(data.data)) {
|
||||
setProductData(data.data);
|
||||
} else {
|
||||
setProductData([]);
|
||||
}
|
||||
});
|
||||
}, [dispatch, selectedSubUser?.key]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchCalendarData(selectedFormDate);
|
||||
}, [selectedFormDate, fetchCalendarData]);
|
||||
|
||||
useEffect(() => {
|
||||
let dateToUse = selectedFormDate;
|
||||
if (approvedStatus === "governmental" && formikRef.current) {
|
||||
const today = moment(new Date()).format("YYYY-MM-DD");
|
||||
formikRef.current.setFieldValue("date", today);
|
||||
setSelectedFormDate(today);
|
||||
dateToUse = today;
|
||||
}
|
||||
|
||||
fetchCalendarData(dateToUse);
|
||||
setSelectedCalendarDate(null);
|
||||
setProductionDate(null);
|
||||
setSelectedDateAmount(null);
|
||||
if (formikRef.current) {
|
||||
formikRef.current.setFieldValue("production_date", "");
|
||||
}
|
||||
}, [
|
||||
approvedStatus,
|
||||
selectedFormDate,
|
||||
fetchCalendarData,
|
||||
selectedSubUser?.key,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (formikRef.current) {
|
||||
formikRef.current.validateForm();
|
||||
}
|
||||
}, [selectedDateAmount]);
|
||||
|
||||
// const handleSellType = (event) => {
|
||||
// const newType = event.target.value;
|
||||
// setSelectedInventory(newType);
|
||||
// };
|
||||
|
||||
const handleApprovedPrice = (event) => {
|
||||
const newType = event.target.value;
|
||||
setApprovedStatus(newType);
|
||||
|
||||
if (newType === "governmental" && formikRef.current) {
|
||||
const today = moment(new Date()).format("YYYY-MM-DD");
|
||||
formikRef.current.setFieldValue("date", today);
|
||||
setSelectedFormDate(today);
|
||||
fetchCalendarData(today);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid container gap={SPACING.SMALL} direction="column" display={"flex"}>
|
||||
<Grid container gap={SPACING.SMALL} direction={"column"}>
|
||||
<Grid minWidth={210}>
|
||||
<Autocomplete
|
||||
disablePortal
|
||||
id="combo-box-demo"
|
||||
getOptionDisabled={(option) => option.disabled}
|
||||
options={
|
||||
buterData
|
||||
? buterData.map((i) => ({
|
||||
id: i?.key,
|
||||
label: `${i?.fullname} (${i.mobile}) / استان ${i.province} / شهر ${i.city}`,
|
||||
item: i,
|
||||
}))
|
||||
: []
|
||||
}
|
||||
onChange={(event, value) => {
|
||||
setBuyerSelected(value?.id);
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField {...params} label="انتخاب خریدار" />
|
||||
)}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
{buyerSelected && (
|
||||
<>
|
||||
<Grid xs={12} container>
|
||||
<Autocomplete
|
||||
fullWidth
|
||||
style={{ minWidth: 210 }}
|
||||
disablePortal
|
||||
id="hatching"
|
||||
options={
|
||||
Array.isArray(productData) && productData.length > 0
|
||||
? productData.map((i) => {
|
||||
return {
|
||||
data: i,
|
||||
label: `${i.name || ""}`,
|
||||
};
|
||||
})
|
||||
: []
|
||||
}
|
||||
onChange={(event, value) => {
|
||||
setProductKey(value?.data || null);
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField fullWidth {...params} label="انتخاب محصول" />
|
||||
)}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<Formik
|
||||
innerRef={formikRef}
|
||||
initialValues={{
|
||||
weight_of_carcasses: "",
|
||||
clearance_code: "",
|
||||
date: moment(new Date()).format("YYYY-MM-DD"),
|
||||
production_date: "",
|
||||
}}
|
||||
validationSchema={validationSchema(selectedDateAmount)}
|
||||
onSubmit={(values) => {
|
||||
dispatch(
|
||||
stewardSellOuutSubmitSell({
|
||||
buyer_key: buyerSelected,
|
||||
number_of_carcasses:
|
||||
Math.round(
|
||||
values?.weight_of_carcasses / productKey?.weightAverage
|
||||
) || 0,
|
||||
weight_of_carcasses: parseInt(values.weight_of_carcasses),
|
||||
date: values.date,
|
||||
clearance_code: values.clearance_code,
|
||||
product_key: productKey?.key,
|
||||
sale_type: selectedInventory,
|
||||
quota: approvedStatus,
|
||||
production_date: values.production_date,
|
||||
distribution_type: "web",
|
||||
})
|
||||
).then((r) => {
|
||||
if (r.payload.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.error,
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
if (isInventory) {
|
||||
fetchItems();
|
||||
} else {
|
||||
updateTable();
|
||||
}
|
||||
dispatch(fetchStewardBroadcastAndProducts());
|
||||
dispatch(
|
||||
DRAWER({ right: false, bottom: false, content: null })
|
||||
);
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
}
|
||||
});
|
||||
}}
|
||||
>
|
||||
{({ values, errors, touched, setFieldValue }) => (
|
||||
<Form>
|
||||
<Grid container gap={SPACING.SMALL} direction={"column"}>
|
||||
<Grid item>
|
||||
<TextField
|
||||
disabled
|
||||
label="حجم تقریبی"
|
||||
value={
|
||||
Math.round(
|
||||
values?.weight_of_carcasses /
|
||||
productKey?.weightAverage
|
||||
) || 0
|
||||
}
|
||||
InputProps={{
|
||||
readOnly: true,
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<LabelField label="نوع انبار">
|
||||
<FormControl fullWidth>
|
||||
<RadioGroup
|
||||
row
|
||||
aria-labelledby="segment-type-radio-group"
|
||||
name="segmentType"
|
||||
value={approvedStatus}
|
||||
onChange={handleApprovedPrice}
|
||||
sx={{
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<FormControlLabel
|
||||
value="governmental"
|
||||
control={<Radio />}
|
||||
label="انبار دولتی"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value="free"
|
||||
control={<Radio />}
|
||||
label="انبار آزاد"
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
</LabelField>
|
||||
<Grid xs={12}>
|
||||
<DatePicker
|
||||
label="تاریخ"
|
||||
disabled={approvedStatus === "governmental"}
|
||||
value={moment(values.date)}
|
||||
onChange={(newValue) => {
|
||||
const formatted =
|
||||
moment(newValue).format("YYYY-MM-DD");
|
||||
setFieldValue("date", formatted);
|
||||
setSelectedFormDate(formatted);
|
||||
fetchCalendarData(formatted);
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
fullWidth
|
||||
{...params}
|
||||
size="small"
|
||||
error={touched.date && Boolean(errors.date)}
|
||||
helperText={touched.date && errors.date}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Field
|
||||
name="clearance_code"
|
||||
as={TextField}
|
||||
label="کد قرنطینه"
|
||||
fullWidth
|
||||
onChange={(e) =>
|
||||
setFieldValue(
|
||||
"clearance_code",
|
||||
e.target.value.toUpperCase()
|
||||
)
|
||||
}
|
||||
error={
|
||||
touched.clearance_code &&
|
||||
Boolean(errors.clearance_code)
|
||||
}
|
||||
helperText={
|
||||
touched.clearance_code && errors.clearance_code
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
{/* <LabelField label="نوع قیمت">
|
||||
<FormControl fullWidth>
|
||||
<RadioGroup
|
||||
row
|
||||
aria-labelledby="segment-type-radio-group"
|
||||
name="segmentType"
|
||||
value={selectedInventory}
|
||||
onChange={handleSellType}
|
||||
sx={{
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<FormControlLabel
|
||||
disabled
|
||||
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%" }}
|
||||
>
|
||||
<MonthlyDataCalendar
|
||||
onDateSelect={handleDateSelect}
|
||||
dayData={calendarDayData}
|
||||
selectedDate={selectedCalendarDate}
|
||||
maxGregorianDate={values.date}
|
||||
label={`تاریخ تولید گوشت ${
|
||||
selectedDateAmount !== null
|
||||
? `(موجودی: ${selectedDateAmount?.toLocaleString()} کیلوگرم)`
|
||||
: ""
|
||||
}`}
|
||||
/>
|
||||
{calendarDateError && (
|
||||
<TextField
|
||||
error
|
||||
helperText={calendarDateError}
|
||||
sx={{
|
||||
visibility: "hidden",
|
||||
height: 0,
|
||||
mt: 0,
|
||||
mb: 0,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
|
||||
<Grid item>
|
||||
<Field
|
||||
name="weight_of_carcasses"
|
||||
as={TextField}
|
||||
label="وزن لاشهها"
|
||||
fullWidth
|
||||
disabled={!selectedDateAmount && !productionDate}
|
||||
error={
|
||||
!selectedDateAmount && !productionDate
|
||||
? true
|
||||
: touched.weight_of_carcasses &&
|
||||
Boolean(errors.weight_of_carcasses)
|
||||
}
|
||||
helperText={
|
||||
!selectedDateAmount && !productionDate
|
||||
? "لطفاً ابتدا تاریخ تولید را انتخاب کنید!"
|
||||
: touched.weight_of_carcasses &&
|
||||
errors.weight_of_carcasses
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Button
|
||||
fullWidth
|
||||
type="submit"
|
||||
variant="contained"
|
||||
disabled={!productKey || !productionDate}
|
||||
>
|
||||
ارسال
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Form>
|
||||
)}
|
||||
</Formik>
|
||||
</>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,293 @@
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import axios from "axios";
|
||||
import { Button, TextField, Tooltip } from "@mui/material";
|
||||
import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri";
|
||||
import { DatePicker } from "@mui/x-date-pickers";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { stawardGetOutDashboardService } from "../../../guild/services/steward-get-out-dashboard";
|
||||
import moment from "moment";
|
||||
import {
|
||||
DRAWER,
|
||||
LOADING_END,
|
||||
LOADING_START,
|
||||
} from "../../../../lib/redux/slices/appSlice";
|
||||
import { formatJustDate } from "../../../../utils/formatTime";
|
||||
import ShowImage from "../../../../components/show-image/ShowImage";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
|
||||
import { StewardSellOutOperations } from "../steward-buy-out-operations/StewardSellOutOperations";
|
||||
import { StewardSubmitFreeBar } from "../steward-submit-free-bar/StewardSubmitFreeBar";
|
||||
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
|
||||
export const StewardPurchaseOutProvince = ({ isBarManagemen }) => {
|
||||
const [data, setData] = useState([]);
|
||||
|
||||
const [tableData, setTableData] = useState([]);
|
||||
|
||||
const [totalRows, setTotalRows] = useState(0);
|
||||
const [perPage, setPerPage] = useState(10);
|
||||
const [textValue, setTextValue] = useState("");
|
||||
const [page, setPage] = useState(1);
|
||||
const [dashboardData, setDashboardData] = useState([]);
|
||||
const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] =
|
||||
useContext(AppContext);
|
||||
// const [openNotif] = useContext(AppContext);
|
||||
const dispatch = useDispatch();
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
|
||||
const userKey = useSelector((state) => state.userSlice.userProfile.key);
|
||||
|
||||
const getDashboardData = () => {
|
||||
dispatch(
|
||||
stawardGetOutDashboardService({
|
||||
date1: selectedDate1,
|
||||
date2: selectedDate2,
|
||||
search: "filter",
|
||||
role_key: checkPathStartsWith("steward")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
).then((r) => {
|
||||
setDashboardData(r.payload.data);
|
||||
});
|
||||
};
|
||||
|
||||
const fetchApiData = async (page) => {
|
||||
dispatch(LOADING_START());
|
||||
const response = await axios.get(
|
||||
`steward_free_bar/?search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}&role=${getRoleFromUrl()}${
|
||||
checkPathStartsWith("steward")
|
||||
? `&role_key=${selectedSubUser?.key}`
|
||||
: ""
|
||||
}`
|
||||
);
|
||||
|
||||
getDashboardData();
|
||||
dispatch(LOADING_END());
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
};
|
||||
|
||||
// Initialize dates on mount
|
||||
useEffect(() => {
|
||||
const currentDate = moment(new Date()).format("YYYY-MM-DD");
|
||||
setSelectedDate1(currentDate);
|
||||
setSelectedDate2(currentDate);
|
||||
}, []);
|
||||
|
||||
// Fetch data when dates or perPage change (only if dates are set)
|
||||
useEffect(() => {
|
||||
if (selectedDate1 && selectedDate2) {
|
||||
fetchApiData(1);
|
||||
setPage(1);
|
||||
}
|
||||
}, [selectedDate1, selectedDate2, perPage]);
|
||||
|
||||
const handlePageChange = (page) => {
|
||||
fetchApiData(page);
|
||||
setPage(page);
|
||||
};
|
||||
const updateTable = () => {
|
||||
setPage(1);
|
||||
getDashboardData();
|
||||
fetchApiData(1);
|
||||
};
|
||||
|
||||
const handlePerRowsChange = (perRows) => {
|
||||
setPerPage(perRows);
|
||||
setPage(1);
|
||||
};
|
||||
|
||||
const handleTextChange = (event) => {
|
||||
setTextValue(event.target.value);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const d = data?.map((item, i) => {
|
||||
return [
|
||||
page === 1 ? i + 1 : i + perPage * (page - 1) + 1,
|
||||
formatJustDate(item.createDate),
|
||||
`${item?.killHouseName} (${item?.killHouseMobile})`,
|
||||
item?.product?.name?.toLocaleString() || "-",
|
||||
item?.killHouseName?.toLocaleString(),
|
||||
`${item?.city} (${item?.province})`,
|
||||
item?.numberOfCarcasses?.toLocaleString() || "-",
|
||||
item?.weightOfCarcasses?.toLocaleString() || "-",
|
||||
<ShowImage key={i} src={item?.barImage} />,
|
||||
|
||||
<StewardSellOutOperations
|
||||
key={i}
|
||||
item={item}
|
||||
updateTable={updateTable}
|
||||
/>,
|
||||
];
|
||||
});
|
||||
|
||||
setTableData(d);
|
||||
}, [data, page, perPage]);
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
dispatch(LOADING_START());
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`steward_free_bar/?search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&role=${getRoleFromUrl()}${
|
||||
checkPathStartsWith("steward")
|
||||
? `&role_key=${selectedSubUser?.key}`
|
||||
: ""
|
||||
}`
|
||||
);
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
getDashboardData();
|
||||
dispatch(LOADING_END());
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid container direction="column" flexWrap="nowrap" mt={SPACING.SMALL}>
|
||||
<Grid
|
||||
container
|
||||
mt={SPACING.MEDIUM}
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
gap={2}
|
||||
>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Grid container alignItems="center" gap={SPACING.SMALL}>
|
||||
{getRoleFromUrl() === "Steward" && !isBarManagemen && (
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
DRAWER({
|
||||
right: !(window.innerWidth <= 600),
|
||||
bottom: window.innerWidth <= 600,
|
||||
title: "ثبت اطلاعات خرید",
|
||||
content: (
|
||||
<StewardSubmitFreeBar
|
||||
selectedDate={selectedDate1}
|
||||
updateTable={updateTable}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
ثبت اطلاعات خرید
|
||||
</Button>
|
||||
)}
|
||||
|
||||
<TextField
|
||||
size="small"
|
||||
autoComplete="off"
|
||||
label="جستجو"
|
||||
variant="outlined"
|
||||
style={{ width: 250 }}
|
||||
onChange={handleTextChange}
|
||||
/>
|
||||
<Button
|
||||
type="submit"
|
||||
onClick={handleSubmit}
|
||||
endIcon={<RiSearchLine />}
|
||||
>
|
||||
جستجو
|
||||
</Button>
|
||||
<Grid>
|
||||
<DatePicker
|
||||
label="از تاریخ"
|
||||
id="date"
|
||||
renderInput={(params) => (
|
||||
<TextField style={{ width: "160px" }} {...params} />
|
||||
)}
|
||||
value={selectedDate1}
|
||||
onChange={(e) =>
|
||||
setSelectedDate1(moment(e).format("YYYY-MM-DD"))
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<DatePicker
|
||||
label="تا تاریخ"
|
||||
id="date"
|
||||
renderInput={(params) => (
|
||||
<TextField style={{ width: "160px" }} {...params} />
|
||||
)}
|
||||
value={selectedDate2}
|
||||
onChange={(e) =>
|
||||
setSelectedDate2(moment(e).format("YYYY-MM-DD"))
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Tooltip title="خروجی اکسل">
|
||||
<Button
|
||||
color="success"
|
||||
onClick={() => {
|
||||
const link = `${
|
||||
axios.defaults.baseURL
|
||||
}kill_house_free_bar_excel/?role=${getRoleFromUrl()}${
|
||||
checkPathStartsWith("steward")
|
||||
? `&role_key=${selectedSubUser?.key}`
|
||||
: ""
|
||||
}&key=${userKey}&date1=${selectedDate1}&date2=${selectedDate2}&type=carcass&search=filter&value=${textValue}&date_type=buy`;
|
||||
window.location.href = link;
|
||||
}}
|
||||
>
|
||||
<RiFileExcel2Fill size={32} />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
</form>
|
||||
|
||||
<Grid container mt={2} mb={4} isDashboard xs={12}>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
columns={["تعداد کل بارها", "تعداد کل", "وزن کل (کیلوگرم)"]}
|
||||
data={[
|
||||
[
|
||||
dashboardData?.totalBars?.toLocaleString() || "0",
|
||||
dashboardData?.totalQuantity?.toLocaleString() || "0",
|
||||
dashboardData?.totalWeight?.toLocaleString() || "0",
|
||||
],
|
||||
]}
|
||||
title={"خلاصه اطلاعات"}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<ResponsiveTable
|
||||
data={tableData}
|
||||
columns={[
|
||||
"ردیف",
|
||||
"تاریخ خرید",
|
||||
"خریدار",
|
||||
"محصول",
|
||||
"فروشنده",
|
||||
"استان/شهر",
|
||||
// "پلاک ماشین",
|
||||
// "نام راننده",
|
||||
// "تلفن راننده",
|
||||
// "تاریخ ورود به انبار",
|
||||
"حجم لاشه",
|
||||
"وزن لاشه (کیلوگرم)",
|
||||
"بارنامه",
|
||||
"عملیات",
|
||||
]}
|
||||
handlePageChange={handlePageChange}
|
||||
totalRows={totalRows}
|
||||
page={page}
|
||||
perPage={perPage}
|
||||
handlePerRowsChange={handlePerRowsChange}
|
||||
title="خرید های خارج استان"
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,109 @@
|
||||
import React, { useEffect, useRef, useCallback } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { Button } from "@mui/material";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { getKillhouseApprovedPriceState } from "../../../province/services/get-approved-price-state";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { StewardShowProducts } from "../steward-show-products/StewardShowProducts";
|
||||
import { DRAWER } from "../../../../lib/redux/slices/appSlice";
|
||||
import { StewardAllocationToGuild } from "../../../guild/components/StewardAllocationToGuild";
|
||||
import { ROUTE_STEWARD_DAILY_LIST } from "../../../../routes/routes";
|
||||
import { StewardShowAllocations } from "../steward-show-allocations/StewardShowAllocations";
|
||||
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
|
||||
export const StewardSellInProvince = () => {
|
||||
const dispatch = useDispatch();
|
||||
const allocationsRef = useRef(null);
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
const { stewardProducts } = useSelector((state) => state.stewardSlice);
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { priceInfo } = useSelector((state) => state.slaughterSlice);
|
||||
|
||||
const fetchData = useCallback(async () => {
|
||||
dispatch(
|
||||
getKillhouseApprovedPriceState({
|
||||
role_key: checkPathStartsWith("steward")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
);
|
||||
|
||||
if (allocationsRef.current?.updateTable) {
|
||||
allocationsRef.current.updateTable();
|
||||
}
|
||||
}, [dispatch, selectedSubUser?.key]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
}, [selectedSubUser?.key]);
|
||||
|
||||
return (
|
||||
<Grid container xs={12} justifyContent="center" alignItems="center">
|
||||
<Grid container width="100%" isDashboard>
|
||||
<StewardShowProducts />
|
||||
</Grid>
|
||||
|
||||
<Grid container xs={12} my={2} gap={2}>
|
||||
<Button
|
||||
disabled={
|
||||
!stewardProducts ||
|
||||
!Array.isArray(stewardProducts) ||
|
||||
stewardProducts.length === 0
|
||||
}
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
DRAWER({
|
||||
right: !(window.innerWidth <= 600),
|
||||
bottom: window.innerWidth <= 600,
|
||||
title: "ثبت توزیع/ فروش درون استان",
|
||||
size: {
|
||||
xs: "100%",
|
||||
md: "360px",
|
||||
},
|
||||
content: (
|
||||
<StewardAllocationToGuild
|
||||
fetchData={fetchData}
|
||||
sellerType={"Steward"}
|
||||
sellType="exclusive"
|
||||
priceInfo={priceInfo}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
ثبت توزیع/ فروش
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
disabled
|
||||
variant="contained"
|
||||
color="success"
|
||||
onClick={() => {
|
||||
navigate(ROUTE_STEWARD_DAILY_LIST);
|
||||
}}
|
||||
>
|
||||
لیست روزانه
|
||||
</Button>
|
||||
</Grid>
|
||||
|
||||
<Grid container xs={12} mt={4}>
|
||||
<StewardShowAllocations
|
||||
ref={allocationsRef}
|
||||
handleUpdate={fetchData}
|
||||
priceInfo={priceInfo}
|
||||
remainWeight={
|
||||
stewardProducts?.[0]?.totalRemainWeight !== undefined
|
||||
? stewardProducts[0].totalRemainWeight
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,387 @@
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { useFormik } from "formik";
|
||||
import {
|
||||
Autocomplete,
|
||||
Button,
|
||||
IconButton,
|
||||
TextField,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import SearchIcon from "@mui/icons-material/Search";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { Yup } from "../../../../lib/yup/yup";
|
||||
import {
|
||||
slaughterGetCitiesService,
|
||||
slaughterGetProvinceService,
|
||||
} from "../../../slaughter-house/services/slaughter-get-provinces";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import {
|
||||
slaughterEditBuyerDataService,
|
||||
slaughterGetBuyerDataService,
|
||||
slaughterSubmitBuyerDataService,
|
||||
} from "../../../slaughter-house/services/slaughter-house-submit-buyer";
|
||||
import { DRAWER, LOADING_END } from "../../../../lib/redux/slices/appSlice";
|
||||
import { fetchStewardBroadcastAndProducts } from "../../services/handle-fetch-steward-products";
|
||||
|
||||
export const StewardSellOutOfProvinceBuyersEditBuyer = ({
|
||||
updateTable,
|
||||
isEdit,
|
||||
data,
|
||||
}) => {
|
||||
const [openNotif] = useContext(AppContext);
|
||||
const [userData, setUserData] = useState(null);
|
||||
const [notFound, setNotFound] = useState(false);
|
||||
const dispatch = useDispatch();
|
||||
const [provinceData, setProvinceData] = useState([]);
|
||||
const [cityData, setCityData] = useState([]);
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues: {
|
||||
mobile: "",
|
||||
firstName: "",
|
||||
lastName: "",
|
||||
unitName: "",
|
||||
province: "",
|
||||
city: "",
|
||||
},
|
||||
validationSchema: Yup.object({
|
||||
mobile: Yup.string()
|
||||
.required("این فیلد اجباری است!")
|
||||
.min(11, "شماره موبایل باید 11 رقم باشد")
|
||||
.max(11, "شماره موبایل باید 11 رقم باشد")
|
||||
.matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"),
|
||||
firstName: Yup.string()
|
||||
.required("این فیلد اجباری است!")
|
||||
.typeError("لطفا فیلد را به درستی وارد کنید!"),
|
||||
lastName: Yup.string()
|
||||
.required("این فیلد اجباری است!")
|
||||
.typeError("لطفا فیلد را به درستی وارد کنید!"),
|
||||
unitName: Yup.string()
|
||||
.required("این فیلد اجباری است!")
|
||||
.typeError("لطفا فیلد را به درستی وارد کنید!"),
|
||||
province: Yup.string()
|
||||
.required("این فیلد اجباری است!")
|
||||
.typeError("لطفا فیلد را به درستی وارد کنید!"),
|
||||
city: Yup.string()
|
||||
.required("این فیلد اجباری است!")
|
||||
.typeError("لطفا فیلد را به درستی وارد کنید!"),
|
||||
}),
|
||||
});
|
||||
|
||||
const formik2 = useFormik({
|
||||
initialValues: {
|
||||
userInfoCheck: "",
|
||||
},
|
||||
validationSchema: Yup.object({
|
||||
userInfoCheck: Yup.string()
|
||||
.required("این فیلد اجباری است!")
|
||||
.min(11, "شماره موبایل باید 11 رقم باشد")
|
||||
.max(11, "شماره موبایل باید 11 رقم باشد")
|
||||
.matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شود و 11 رقم باشد"),
|
||||
}),
|
||||
validateOnMount: true,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
formik.validateForm();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (userData) {
|
||||
formik.setValues({
|
||||
mobile: userData.mobile || "",
|
||||
firstName: userData.firstName || "",
|
||||
lastName: userData.lastName || "",
|
||||
unitName: userData.unitName || "",
|
||||
province: userData.province || "",
|
||||
city: userData.city || "",
|
||||
});
|
||||
setTimeout(() => {
|
||||
formik.validateForm();
|
||||
}, 1);
|
||||
}
|
||||
}, [userData]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isEdit) {
|
||||
formik.setValues({
|
||||
mobile: data.mobile || "",
|
||||
firstName: data.firstName || "",
|
||||
lastName: data.lastName || "",
|
||||
unitName: data.unitName || "",
|
||||
province: data.province || "",
|
||||
city: data.city || "",
|
||||
});
|
||||
setTimeout(() => {
|
||||
formik.validateForm();
|
||||
}, 1);
|
||||
}
|
||||
}, [isEdit]);
|
||||
|
||||
useEffect(() => {
|
||||
if (notFound) {
|
||||
formik.setFieldValue("mobile", formik2.values.userInfoCheck);
|
||||
}
|
||||
}, [notFound]);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(slaughterGetProvinceService()).then((r) => {
|
||||
setProvinceData(r.payload.data);
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (formik.values.province) {
|
||||
setCityData(
|
||||
[],
|
||||
dispatch(slaughterGetCitiesService(formik.values.province)).then(
|
||||
(r) => {
|
||||
setCityData(r.payload.data);
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}, [formik.values.province]);
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
xs={12}
|
||||
direction="column"
|
||||
gap={2}
|
||||
>
|
||||
{!userData && !notFound && !isEdit ? (
|
||||
<Grid container xs={12}>
|
||||
<Typography>جستجو کاربر</Typography>
|
||||
<Grid mt={SPACING.SMALL} display="flex" width={1}>
|
||||
<TextField
|
||||
fullWidth
|
||||
id="userInfoCheck"
|
||||
label="شماره موبایل"
|
||||
variant="outlined"
|
||||
value={formik2.values.userInfoCheck}
|
||||
error={
|
||||
formik2.touched.userInfoCheck &&
|
||||
Boolean(formik2.errors.userInfoCheck)
|
||||
}
|
||||
onChange={formik2.handleChange}
|
||||
onBlur={formik2.handleBlur}
|
||||
helperText={
|
||||
formik2.touched.userInfoCheck && formik2.errors.userInfoCheck
|
||||
}
|
||||
/>
|
||||
<IconButton
|
||||
disabled={!formik2.isValid}
|
||||
aria-label="search"
|
||||
color="primary"
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
slaughterGetBuyerDataService(formik2.values.userInfoCheck)
|
||||
).then((r) => {
|
||||
dispatch(LOADING_END());
|
||||
if (r.error) {
|
||||
setNotFound(true);
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "خریدار یافت نشد، یک خریدار جدید ثبت کنید!",
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
setUserData(r.payload.data);
|
||||
}
|
||||
});
|
||||
}}
|
||||
>
|
||||
<SearchIcon />
|
||||
</IconButton>
|
||||
</Grid>
|
||||
</Grid>
|
||||
) : (
|
||||
<Grid
|
||||
container
|
||||
justifyContent="space-between"
|
||||
alignItems="start"
|
||||
xs={12}
|
||||
direction="column"
|
||||
gap={2}
|
||||
>
|
||||
<TextField
|
||||
fullWidth
|
||||
id="mobile"
|
||||
label="شماره موبایل"
|
||||
variant="outlined"
|
||||
value={formik.values.mobile}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={formik.touched.mobile && formik.errors.mobile}
|
||||
/>
|
||||
<TextField
|
||||
fullWidth
|
||||
id="firstName"
|
||||
label="نام"
|
||||
variant="outlined"
|
||||
value={formik.values.firstName}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={formik.touched.firstName && formik.errors.firstName}
|
||||
/>
|
||||
<TextField
|
||||
fullWidth
|
||||
id="lastName"
|
||||
label="نام خانوادگی"
|
||||
variant="outlined"
|
||||
value={formik.values.lastName}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={formik.touched.lastName && formik.errors.lastName}
|
||||
/>
|
||||
<TextField
|
||||
fullWidth
|
||||
id="unitName"
|
||||
label="نام واحد"
|
||||
variant="outlined"
|
||||
value={formik.values.unitName}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={formik.touched.unitName && formik.errors.unitName}
|
||||
/>
|
||||
|
||||
<Autocomplete
|
||||
style={{ width: "100%" }}
|
||||
disablePortal
|
||||
id="province"
|
||||
options={
|
||||
provinceData
|
||||
? provinceData.map((i) => ({ id: i.name, label: i.name }))
|
||||
: []
|
||||
}
|
||||
onChange={(e, value) => {
|
||||
formik.setFieldValue("province", value ? value.id : "");
|
||||
formik.setFieldValue("city", "");
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField {...params} label="استان را انتخاب کنید" />
|
||||
)}
|
||||
/>
|
||||
{!notFound && (
|
||||
<Typography variant="caption" color="error">
|
||||
استان: {formik.values.province}
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
<Autocomplete
|
||||
minWidth={210}
|
||||
style={{ width: "100%" }}
|
||||
disabled={!formik.values.province}
|
||||
disablePortal
|
||||
id="city"
|
||||
options={
|
||||
cityData
|
||||
? cityData.map((i) => ({ id: i.name, label: i.name }))
|
||||
: []
|
||||
}
|
||||
onChange={(e, value) => {
|
||||
formik.setFieldValue("city", value ? value.id : "");
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField {...params} label="شهر را انتخاب کنید" />
|
||||
)}
|
||||
/>
|
||||
|
||||
{!notFound && (
|
||||
<Typography variant="caption" color="error">
|
||||
شهر: {formik.values.city}
|
||||
</Typography>
|
||||
)}
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
{(userData || notFound || isEdit) && (
|
||||
<Grid container xs={12}>
|
||||
<Button
|
||||
fullWidth
|
||||
variant="contained"
|
||||
disabled={!formik.isValid}
|
||||
onClick={() => {
|
||||
if (isEdit) {
|
||||
dispatch(
|
||||
slaughterEditBuyerDataService({
|
||||
buyer_key: data?.key,
|
||||
mobile: formik.values.mobile,
|
||||
first_name: formik.values.firstName,
|
||||
last_name: formik.values.lastName,
|
||||
unit_name: formik.values.unitName,
|
||||
city: formik.values.city,
|
||||
province: formik.values.province,
|
||||
})
|
||||
).then((r) => {
|
||||
updateTable();
|
||||
dispatch(fetchStewardBroadcastAndProducts());
|
||||
if (r.payload.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.error,
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
dispatch(
|
||||
DRAWER({ right: false, bottom: false, content: null })
|
||||
);
|
||||
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
dispatch(
|
||||
slaughterSubmitBuyerDataService({
|
||||
mobile: formik.values.mobile,
|
||||
first_name: formik.values.firstName,
|
||||
last_name: formik.values.lastName,
|
||||
unit_name: formik.values.unitName,
|
||||
city: formik.values.city,
|
||||
province: formik.values.province,
|
||||
})
|
||||
).then((r) => {
|
||||
updateTable();
|
||||
dispatch(fetchStewardBroadcastAndProducts());
|
||||
if (r.payload.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.error,
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
dispatch(
|
||||
DRAWER({ right: false, bottom: false, content: null })
|
||||
);
|
||||
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
{isEdit ? "ویرایش" : "ثبت"}
|
||||
</Button>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,197 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import axios from "axios";
|
||||
import { Button, IconButton, TextField } from "@mui/material";
|
||||
import { RiSearchLine } from "react-icons/ri";
|
||||
// import DeleteIcon from "@mui/icons-material/Delete";
|
||||
import EditIcon from "@mui/icons-material/Edit";
|
||||
import {
|
||||
DRAWER,
|
||||
LOADING_END,
|
||||
LOADING_START,
|
||||
} from "../../../../lib/redux/slices/appSlice";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
|
||||
import { StewardSellOutOfProvinceAddBuyer } from "../steward-purchase-out-province-add-buyer/StewardSellOutOfProvinceAddBuyer";
|
||||
import { StewardSellOutOfProvinceBuyersEditBuyer } from "../steward-sell-out-of-province-buyers-edit-buyer/StewardSellOutOfProvinceBuyersEditBuyer";
|
||||
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
|
||||
export const StewardSellOutOfProvinceBuyers = () => {
|
||||
const handleTextChange = (event) => {
|
||||
setTextValue(event.target.value);
|
||||
};
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [data, setData] = useState([]);
|
||||
const [totalRows, setTotalRows] = useState(0);
|
||||
const [perPage, setPerPage] = useState(10);
|
||||
const [textValue, setTextValue] = useState("");
|
||||
const [page, setPage] = useState(1);
|
||||
const [tableData, setTableData] = useState([]);
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
|
||||
const fetchApiData = async (page) => {
|
||||
dispatch(LOADING_START());
|
||||
const response = await axios.get(
|
||||
`out-province-carcasses-buyer/?search=filter&value=${textValue}&role=${getRoleFromUrl()}${
|
||||
checkPathStartsWith("steward")
|
||||
? `&role_key=${selectedSubUser?.key}`
|
||||
: ""
|
||||
}&page=${page}&page_size=${perPage}&state=buyer-list`
|
||||
);
|
||||
dispatch(LOADING_END());
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
};
|
||||
|
||||
const handlePageChange = (page) => {
|
||||
fetchApiData(page);
|
||||
setPage(page);
|
||||
};
|
||||
|
||||
const handlePerRowsChange = (perRows) => {
|
||||
setPerPage(perRows);
|
||||
setPage(1);
|
||||
};
|
||||
|
||||
const updateTable = () => {
|
||||
fetchApiData(page !== 0 ? page : 1);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const d = data?.map((item, i) => {
|
||||
return [
|
||||
page === 1 ? i + 1 : i + perPage * (page - 1) + 1,
|
||||
`${item?.fullname} (${item?.mobile})`,
|
||||
item?.unitName,
|
||||
item?.province,
|
||||
item?.city,
|
||||
item?.requestsInfo?.numberOfRequests?.toLocaleString(),
|
||||
item?.requestsInfo?.totalQuantity?.toLocaleString(),
|
||||
item?.requestsInfo?.totalWeight?.toLocaleString(),
|
||||
<IconButton
|
||||
color="primary"
|
||||
key={i}
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
DRAWER({
|
||||
right: !(window.innerWidth <= 600),
|
||||
bottom: window.innerWidth <= 600,
|
||||
content: (
|
||||
<StewardSellOutOfProvinceBuyersEditBuyer
|
||||
updateTable={updateTable}
|
||||
isEdit
|
||||
data={item}
|
||||
/>
|
||||
),
|
||||
title: "ویرایش خریدار",
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
<EditIcon />
|
||||
</IconButton>,
|
||||
];
|
||||
});
|
||||
|
||||
setTableData(d);
|
||||
}, [data]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchApiData(1);
|
||||
setPage(1);
|
||||
}, [perPage]);
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
dispatch(LOADING_START());
|
||||
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`out-province-carcasses-buyer/?role=${getRoleFromUrl()}${
|
||||
checkPathStartsWith("steward") ? selectedSubUser?.key || "" : ""
|
||||
}&search=filter&value=${textValue}&page=${1}&page_size=${perPage}&state=buyer-list`
|
||||
);
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
dispatch(LOADING_END());
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid container xs={12} justifyContent="center" alignItems="center" gap={2}>
|
||||
<Grid
|
||||
container
|
||||
xs={12}
|
||||
justifyContent="start"
|
||||
alignItems="center"
|
||||
gap={2}
|
||||
>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
DRAWER({
|
||||
right: !(window.innerWidth <= 600),
|
||||
bottom: window.innerWidth <= 600,
|
||||
content: (
|
||||
<StewardSellOutOfProvinceAddBuyer updateTable={updateTable} />
|
||||
),
|
||||
title: "افزودن خریدار",
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
افزودن خریدار
|
||||
</Button>
|
||||
<Grid>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<TextField
|
||||
id="outlined-basic"
|
||||
size="small"
|
||||
label="جستجو"
|
||||
variant="outlined"
|
||||
style={{ width: 250 }}
|
||||
onChange={handleTextChange}
|
||||
/>
|
||||
<Button
|
||||
// disabled={!textValue}
|
||||
type="submit"
|
||||
onClick={handleSubmit}
|
||||
endIcon={<RiSearchLine />}
|
||||
>
|
||||
جستجو
|
||||
</Button>
|
||||
</form>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<ResponsiveTable
|
||||
data={tableData}
|
||||
columns={[
|
||||
"ردیف",
|
||||
"مشخصات خریدار",
|
||||
"نام واحد",
|
||||
"استان",
|
||||
"شهر",
|
||||
"تعداد درخواست ها",
|
||||
"حجم تقریبی (قطعه)",
|
||||
"وزن (کیلوگرم)",
|
||||
"ویرایش",
|
||||
]}
|
||||
handlePageChange={handlePageChange}
|
||||
totalRows={totalRows}
|
||||
page={page}
|
||||
perPage={perPage}
|
||||
handlePerRowsChange={handlePerRowsChange}
|
||||
title="خریداران لاشه خارج استان"
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,315 @@
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import moment from "moment";
|
||||
import axios from "axios";
|
||||
import { Button, TextField } from "@mui/material";
|
||||
import { DatePicker } from "@mui/x-date-pickers";
|
||||
import { RiSearchLine } from "react-icons/ri";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import {
|
||||
DRAWER,
|
||||
LOADING_END,
|
||||
LOADING_START,
|
||||
} from "../../../../lib/redux/slices/appSlice";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import { formatJustDate, formatTime } from "../../../../utils/formatTime";
|
||||
import { CheckCleanceCode } from "../../../../components/check-clearance-code/ChechClearanceCode";
|
||||
import { stewardSellOutGetDashboard } from "../../../guild/services/steward-sell-out-get-dashboard";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
|
||||
import { StewardSellOutOfProvinceSubmitSell } from "../steward-purchase-out-province-submit-sell/StewardSellOutOfProvinceSubmitSell";
|
||||
import { StewardOutProvinceRegistrationCodeInput } from "../steward-out-province-registration-code-input/StewardOutProvinceRegistrationCodeInput";
|
||||
import { StewardOutProvinceSalesOperations } from "../steward-out-province-sales-operations/StewardOutProvinceSalesOperations";
|
||||
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
|
||||
export const StewardSellOutOfProvinceSells = () => {
|
||||
const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] =
|
||||
useContext(AppContext);
|
||||
const dispatch = useDispatch();
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
|
||||
const [data, setData] = useState([]);
|
||||
const [totalRows, setTotalRows] = useState(0);
|
||||
const [perPage, setPerPage] = useState(10);
|
||||
const [textValue, setTextValue] = useState("");
|
||||
const [page, setPage] = useState(1);
|
||||
const [tableData, setTableData] = useState([]);
|
||||
const [dashboardData, setDashboardData] = useState([]);
|
||||
|
||||
const fetchApiData = async (page) => {
|
||||
dispatch(LOADING_START());
|
||||
const response = await axios.get(
|
||||
`steward_free_sale_bar/?search=filter&value=${textValue}&role=${getRoleFromUrl()}${
|
||||
checkPathStartsWith("steward")
|
||||
? `&role_key=${selectedSubUser?.key}`
|
||||
: ""
|
||||
}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}`
|
||||
);
|
||||
dispatch(LOADING_END());
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
};
|
||||
|
||||
const getDashboardData = () => {
|
||||
dispatch(
|
||||
stewardSellOutGetDashboard({
|
||||
selectedDate1,
|
||||
selectedDate2,
|
||||
role_key: checkPathStartsWith("steward") ? selectedSubUser?.key : "",
|
||||
})
|
||||
).then((r) => {
|
||||
setDashboardData(r.payload.data);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const currentDate = moment(new Date()).format("YYYY-MM-DD");
|
||||
setSelectedDate1(currentDate);
|
||||
setSelectedDate2(currentDate);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedDate1 && selectedDate2) {
|
||||
fetchApiData(1);
|
||||
setPage(1);
|
||||
getDashboardData();
|
||||
}
|
||||
}, [selectedDate1, selectedDate2, perPage]);
|
||||
|
||||
const handleTextChange = (event) => {
|
||||
setTextValue(event.target.value);
|
||||
};
|
||||
|
||||
const handlePageChange = (page) => {
|
||||
fetchApiData(page);
|
||||
setPage(page);
|
||||
};
|
||||
|
||||
const handlePerRowsChange = (perRows) => {
|
||||
setPerPage(perRows);
|
||||
setPage(1);
|
||||
};
|
||||
|
||||
const updateTable = () => {
|
||||
setPage(1);
|
||||
fetchApiData(1);
|
||||
getDashboardData();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const d = data?.map((item, i) => {
|
||||
return [
|
||||
page === 1 ? i + 1 : i + perPage * (page - 1) + 1,
|
||||
item?.date ? formatTime(item?.date) : "-",
|
||||
item?.productionDate ? formatJustDate(item?.productionDate) : "-",
|
||||
item?.distributionType === "web"
|
||||
? "سایت"
|
||||
: item?.distributionType === "app"
|
||||
? "موبایل"
|
||||
: item?.distributionType === "pos"
|
||||
? "پوز"
|
||||
: item?.distributionType || "-",
|
||||
`${item?.buyerName} (${item?.buyerMobile})`,
|
||||
item?.buyer ? `${item?.buyer?.unitName}` : `${item?.buyerName}`,
|
||||
item?.province,
|
||||
item?.city,
|
||||
// item?.numberOfCarcasses?.toLocaleString(),
|
||||
item?.clearanceCode && (
|
||||
<CheckCleanceCode clearanceCode={item?.clearanceCode} />
|
||||
),
|
||||
item?.quarantineWeightOfCarcasses?.toLocaleString(),
|
||||
item?.weightOfCarcasses?.toLocaleString(),
|
||||
item?.systemRegistrationCode ? (
|
||||
item?.loggedRegistrationCode ? (
|
||||
"تایید شده"
|
||||
) : item?.registrationCode ? (
|
||||
<StewardOutProvinceRegistrationCodeInput
|
||||
key={i}
|
||||
item={item}
|
||||
fetchApiData={() => fetchApiData(page)}
|
||||
/>
|
||||
) : (
|
||||
"-"
|
||||
)
|
||||
) : (
|
||||
"-"
|
||||
),
|
||||
<StewardOutProvinceSalesOperations
|
||||
key={i}
|
||||
item={item}
|
||||
updateTable={updateTable}
|
||||
fetchApiData={fetchApiData}
|
||||
page={page}
|
||||
/>,
|
||||
];
|
||||
});
|
||||
|
||||
setTableData(d);
|
||||
}, [data, page, perPage]);
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
dispatch(LOADING_START());
|
||||
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`steward_free_sale_bar/?role=${getRoleFromUrl()}${
|
||||
checkPathStartsWith("steward")
|
||||
? `&role_key=${selectedSubUser?.key}`
|
||||
: ""
|
||||
}&search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${1}&page_size=${perPage}`
|
||||
);
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
getDashboardData();
|
||||
dispatch(LOADING_END());
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
dispatch(LOADING_END());
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid container xs={12} justifyContent="center" alignItems="center" gap={2}>
|
||||
<Grid
|
||||
container
|
||||
xs={12}
|
||||
justifyContent="start"
|
||||
alignItems="center"
|
||||
gap={2}
|
||||
mt={2}
|
||||
>
|
||||
<Grid>
|
||||
<DatePicker
|
||||
label="از تاریخ"
|
||||
id="date"
|
||||
renderInput={(params) => (
|
||||
<TextField style={{ width: "160px" }} {...params} size="small" />
|
||||
)}
|
||||
value={selectedDate1}
|
||||
onChange={(e) => {
|
||||
setSelectedDate1(moment(e).format("YYYY-MM-DD"));
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<DatePicker
|
||||
label="تا تاریخ"
|
||||
id="date"
|
||||
renderInput={(params) => (
|
||||
<TextField style={{ width: "160px" }} {...params} size="small" />
|
||||
)}
|
||||
value={selectedDate2}
|
||||
onChange={(e) => {
|
||||
setSelectedDate2(moment(e).format("YYYY-MM-DD"));
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<TextField
|
||||
id="outlined-basic"
|
||||
size="small"
|
||||
label="جستجو"
|
||||
variant="outlined"
|
||||
style={{ width: 250 }}
|
||||
onChange={handleTextChange}
|
||||
/>
|
||||
<Button
|
||||
// disabled={!textValue}
|
||||
type="submit"
|
||||
onClick={handleSubmit}
|
||||
endIcon={<RiSearchLine />}
|
||||
>
|
||||
جستجو
|
||||
</Button>
|
||||
</form>
|
||||
</Grid>
|
||||
{/* <Tooltip title="خروجی اکسل">
|
||||
<a
|
||||
href={`${
|
||||
axios.defaults.baseURL
|
||||
}kill_house_free_sale_bar_information_for_excel_excel/?key=${userKey}&role=${getRoleFromUrl()}&date1=${selectedDate1}&date2=${selectedDate2}`}
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Button color="success">
|
||||
<RiFileExcel2Fill size={32} />
|
||||
</Button>
|
||||
</a>
|
||||
</Tooltip> */}
|
||||
</Grid>
|
||||
|
||||
<Grid container xs={12} mt={2} mb={4} isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
columns={[
|
||||
"تعداد فروش",
|
||||
"خریدار",
|
||||
"حجم لاشه ها (تقریبی)",
|
||||
"وزن کل لاشه ها",
|
||||
]}
|
||||
data={[
|
||||
[
|
||||
dashboardData?.numberOfBars?.toLocaleString(),
|
||||
dashboardData?.numberOfBuyers?.toLocaleString(),
|
||||
dashboardData?.barsQuantity?.toLocaleString(),
|
||||
dashboardData?.barsWeight?.toLocaleString(),
|
||||
],
|
||||
]}
|
||||
title={"خلاصه اطلاعات"}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<Grid container xs={12}>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
DRAWER({
|
||||
right: !(window.innerWidth <= 600),
|
||||
bottom: window.innerWidth <= 600,
|
||||
content: (
|
||||
<StewardSellOutOfProvinceSubmitSell
|
||||
updateTable={updateTable}
|
||||
/>
|
||||
),
|
||||
title: "ثبت اطلاعات فروش",
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
ثبت اطلاعات فروش
|
||||
</Button>
|
||||
</Grid>
|
||||
|
||||
<ResponsiveTable
|
||||
data={tableData}
|
||||
columns={[
|
||||
"ردیف",
|
||||
"تاریخ",
|
||||
"تاریخ تولید گوشت",
|
||||
"ثبت شده",
|
||||
"مشخصات خریدار",
|
||||
"نام واحد",
|
||||
"استان",
|
||||
"شهر",
|
||||
// "حجم لاشه (تقریبی)",
|
||||
"کد قرنطینه",
|
||||
"وزن استعلامی",
|
||||
"وزن لاشه",
|
||||
"کد احراز",
|
||||
"عملیات",
|
||||
]}
|
||||
handlePageChange={handlePageChange}
|
||||
totalRows={totalRows}
|
||||
page={page}
|
||||
perPage={perPage}
|
||||
handlePerRowsChange={handlePerRowsChange}
|
||||
title="فروش لاشه به خارج استان"
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,78 @@
|
||||
import { Box, Tab, Tabs } from "@mui/material";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { fetchStewardBroadcastAndProducts } from "../../services/handle-fetch-steward-products";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { StewardShowProducts } from "../steward-show-products/StewardShowProducts";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { StewardSellOutOfProvinceSells } from "../steward-sell-out-of-province-sells/StewardSellOutOfProvinceSells";
|
||||
import { StewardSellOutOfProvinceBuyers } from "../steward-sell-out-of-province-buyers/StewardSellOutOfProvinceBuyers";
|
||||
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
|
||||
export const StewardSellOutOfProvince = () => {
|
||||
const dispatch = useDispatch();
|
||||
const [valueOutProvince, setValueOutProvince] = useState(0);
|
||||
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
const handleChangeTabsetOutProvince = (event, newValue) => {
|
||||
setValueOutProvince(newValue);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
fetchStewardBroadcastAndProducts({
|
||||
role_key: checkPathStartsWith("steward") ? selectedSubUser?.key : "",
|
||||
})
|
||||
);
|
||||
}, [selectedSubUser?.key]);
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
direction="column"
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
gap={SPACING.SMALL}
|
||||
mt={SPACING.MEDIUM}
|
||||
width="100%"
|
||||
>
|
||||
<Grid container width="100%" isDashboard>
|
||||
<StewardShowProducts />
|
||||
</Grid>
|
||||
|
||||
<Grid
|
||||
container
|
||||
direction="column"
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
gap={SPACING.SMALL}
|
||||
mb={SPACING.SMALL}
|
||||
width="100%"
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
borderBottom: 1,
|
||||
borderColor: "divider",
|
||||
}}
|
||||
>
|
||||
<Tabs
|
||||
className="insidetabs"
|
||||
size="small"
|
||||
value={valueOutProvince}
|
||||
onChange={handleChangeTabsetOutProvince}
|
||||
aria-label="basic tabs example"
|
||||
>
|
||||
<Tab label="فروش" />
|
||||
<Tab label="خریداران" />
|
||||
</Tabs>
|
||||
</Box>
|
||||
|
||||
{valueOutProvince === 0 && <StewardSellOutOfProvinceSells />}
|
||||
|
||||
{valueOutProvince === 1 && <StewardSellOutOfProvinceBuyers />}
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,165 @@
|
||||
import { Button, IconButton, Popover } from "@mui/material";
|
||||
import { useState } from "react";
|
||||
import TuneIcon from "@mui/icons-material/Tune";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { SlaughterAllocateToGuild } from "../../../slaughter-house/components/slaughter-allocate-to-guild/SlaughterAllocateToGuild";
|
||||
import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { StewardNorEnterdBarChangeState } from "../../../guild/components/StewardNorEnterdBarChangeState";
|
||||
import { slaughterDeleteAllocatedService } from "../../../slaughter-house/services/salughter-delete-allocated";
|
||||
import { fetchSlaughterBroadcastAndProducts } from "../../../slaughter-house/services/handle-fetch-slaughter-products";
|
||||
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
|
||||
export const StewardShowAllocationsOperations = ({
|
||||
item,
|
||||
type,
|
||||
handleUpdate,
|
||||
priceInfo,
|
||||
remainWeight,
|
||||
updateTable,
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
const [popoverOpen, setPopoverOpen] = useState(false);
|
||||
const [anchorEl, setAnchorEl] = useState(null);
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
const openPopover = (event) => {
|
||||
setPopoverOpen(true);
|
||||
setAnchorEl(event.currentTarget);
|
||||
};
|
||||
|
||||
const closePopover = () => {
|
||||
setPopoverOpen(false);
|
||||
setAnchorEl(null);
|
||||
};
|
||||
|
||||
const handleDistributeToGuild = () => {
|
||||
closePopover();
|
||||
const handleEditSuccess = () => {
|
||||
if (updateTable) updateTable(1);
|
||||
if (handleUpdate) handleUpdate();
|
||||
};
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "ویرایش توزیع و فروش محصول",
|
||||
content: (
|
||||
<SlaughterAllocateToGuild
|
||||
updateTable={handleEditSuccess}
|
||||
fetchApiData={handleEditSuccess}
|
||||
sellerType="KillHouse"
|
||||
sellType="exclusive"
|
||||
priceInfo={priceInfo}
|
||||
remainWeight={remainWeight}
|
||||
editData={item}
|
||||
item={item}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid>
|
||||
<IconButton
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={openPopover}
|
||||
disabled={!type && item?.registrationCode}
|
||||
>
|
||||
<TuneIcon />
|
||||
</IconButton>
|
||||
<Popover
|
||||
open={popoverOpen}
|
||||
anchorEl={anchorEl}
|
||||
onClose={closePopover}
|
||||
anchorOrigin={{
|
||||
vertical: "bottom",
|
||||
horizontal: "right",
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: "top",
|
||||
horizontal: "left",
|
||||
}}
|
||||
>
|
||||
<div style={{ padding: 10 }}>
|
||||
<Grid
|
||||
container
|
||||
direction="column"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
gap={1}
|
||||
>
|
||||
{type && (
|
||||
<Button
|
||||
size="small"
|
||||
color="primary"
|
||||
variant="outlined"
|
||||
onClick={() => {
|
||||
closePopover();
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "ویرایش اطلاعات بار",
|
||||
content: (
|
||||
<StewardNorEnterdBarChangeState
|
||||
updateTable={updateTable}
|
||||
handleUpdate={handleUpdate}
|
||||
item={item}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
تایید / رد
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{!type && (
|
||||
<Button
|
||||
size="small"
|
||||
color="primary"
|
||||
variant="outlined"
|
||||
onClick={handleDistributeToGuild}
|
||||
>
|
||||
ویرایش
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{!type && (
|
||||
<Button
|
||||
size="small"
|
||||
disabled={item?.registrationCode}
|
||||
variant="outlined"
|
||||
color="error"
|
||||
onClick={() => {
|
||||
closePopover();
|
||||
dispatch(
|
||||
slaughterDeleteAllocatedService({
|
||||
steward_allocation_key: item.key,
|
||||
role_key: checkPathStartsWith("steward")
|
||||
? selectedSubUser?.key
|
||||
: "",
|
||||
})
|
||||
).then(() => {
|
||||
dispatch(
|
||||
fetchSlaughterBroadcastAndProducts({
|
||||
role_key: checkPathStartsWith("steward")
|
||||
? selectedSubUser?.key
|
||||
: "",
|
||||
})
|
||||
);
|
||||
if (updateTable) updateTable(1);
|
||||
if (handleUpdate) handleUpdate();
|
||||
});
|
||||
}}
|
||||
>
|
||||
حذف
|
||||
</Button>
|
||||
)}
|
||||
</Grid>
|
||||
</div>
|
||||
</Popover>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,483 @@
|
||||
import React, {
|
||||
useContext,
|
||||
useEffect,
|
||||
useState,
|
||||
useImperativeHandle,
|
||||
forwardRef,
|
||||
} from "react";
|
||||
import axios from "axios";
|
||||
import moment from "moment";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { Button, TextField, Typography } from "@mui/material";
|
||||
import { DatePicker } from "@mui/x-date-pickers";
|
||||
import { RiSearchLine } from "react-icons/ri";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import {
|
||||
CLOSE_MODAL,
|
||||
LOADING_END,
|
||||
LOADING_START,
|
||||
OPEN_MODAL,
|
||||
} from "../../../../lib/redux/slices/appSlice";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import { formatJustDate, formatTime } from "../../../../utils/formatTime";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { slaughterInventoryFinalSubmitService } from "../../../slaughter-house/services/slaughter-inventory-final-submit";
|
||||
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
|
||||
import { StewardShowAllocationsOperations } from "../steward-show-allocations-operations/StewardShowAllocationsOperations";
|
||||
import { getAllocationType } from "../../../../utils/getAllocationType";
|
||||
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
// import { format } from "date-fns-jalali";
|
||||
|
||||
export const StewardShowAllocations = forwardRef(
|
||||
({ type, handleUpdate, priceInfo, remainWeight }, ref) => {
|
||||
const dispatch = useDispatch();
|
||||
const [
|
||||
,
|
||||
,
|
||||
selectedDate1,
|
||||
setSelectedDate1,
|
||||
selectedDate2,
|
||||
setSelectedDate2,
|
||||
] = useContext(AppContext);
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
useEffect(() => {
|
||||
const currentDate = moment(new Date()).format("YYYY-MM-DD");
|
||||
setSelectedDate1(currentDate);
|
||||
setSelectedDate2(currentDate);
|
||||
}, []);
|
||||
|
||||
const handleTextChange = (event) => {
|
||||
setTextValue(event.target.value);
|
||||
8;
|
||||
};
|
||||
|
||||
const [data, setData] = useState([]);
|
||||
const [totalRows, setTotalRows] = useState(0);
|
||||
const [perPage, setPerPage] = useState(10);
|
||||
const [textValue, setTextValue] = useState("");
|
||||
const [page, setPage] = useState(1);
|
||||
const [tableData, setTableData] = useState([]);
|
||||
const [openNotif] = useContext(AppContext);
|
||||
|
||||
const fetchApiData = async (pageParam = 1) => {
|
||||
try {
|
||||
dispatch(LOADING_START());
|
||||
const response = await axios.get(
|
||||
`steward-allocation/?role=${getRoleFromUrl()}${
|
||||
checkPathStartsWith("steward")
|
||||
? `&role_key=${selectedSubUser?.key}`
|
||||
: ""
|
||||
}&search=filter&value=${textValue}${
|
||||
type !== "not_entered"
|
||||
? `&date1=${selectedDate1}&date2=${selectedDate2}`
|
||||
: ""
|
||||
}&page=${pageParam}&page_size=${perPage}${
|
||||
type ? "&type=" + type : ""
|
||||
}`
|
||||
);
|
||||
dispatch(LOADING_END());
|
||||
setData(response.data.results || []);
|
||||
setTotalRows(response.data.count || 0);
|
||||
} catch (err) {
|
||||
dispatch(LOADING_END());
|
||||
console.error("Error fetching allocations:", err);
|
||||
}
|
||||
};
|
||||
|
||||
const updateTable = () => {
|
||||
fetchApiData(1);
|
||||
};
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
updateTable,
|
||||
}));
|
||||
|
||||
const handlePageChange = (newPage) => {
|
||||
fetchApiData(newPage);
|
||||
setPage(newPage);
|
||||
};
|
||||
|
||||
const getAllocationData = (item) => {
|
||||
let typeText = `${item?.toKillHouse?.name} - ${item?.toKillHouse?.killHouseOperator?.user?.fullname} (${item?.toKillHouse?.killHouseOperator?.user?.mobile})`;
|
||||
switch (item?.allocationType) {
|
||||
case "steward_killhouse":
|
||||
typeText = `${item?.toKillHouse?.name} - ${item?.toKillHouse?.killHouseOperator?.user?.fullname} (${item?.toKillHouse?.killHouseOperator?.user?.mobile})`;
|
||||
break;
|
||||
case "steward_steward":
|
||||
typeText = `${item?.toStewards?.name} - ${item?.toStewards?.user?.fullname} (${item?.toStewards?.user?.mobile})`;
|
||||
break;
|
||||
case "steward_guild":
|
||||
typeText = `${item?.toGuilds?.guildsName} - ${item?.toGuilds?.user?.fullname} (${item?.toGuilds?.user?.mobile})`;
|
||||
break;
|
||||
case "ColdHouse":
|
||||
typeText = `${item?.toColdHouse?.name}`;
|
||||
break;
|
||||
case "killhouse_steward":
|
||||
typeText = `${item?.toStewards?.name || "-"} - ${
|
||||
item?.toStewards?.user?.fullname || "-"
|
||||
} (${item?.toStewards?.user?.mobile || "-"})`;
|
||||
break;
|
||||
case "killhouse_guild":
|
||||
typeText = `${item?.toGuilds?.guildsName || "-"} - ${
|
||||
item?.toGuilds?.user?.fullname || "-"
|
||||
} (${item?.toGuilds?.user?.mobile || "-"})`;
|
||||
break;
|
||||
default:
|
||||
typeText = `${item?.toKillHouse?.name} - ${item?.toKillHouse?.killHouseOperator?.user?.fullname} (${item?.toKillHouse?.killHouseOperator?.user?.mobile})`;
|
||||
break;
|
||||
}
|
||||
return typeText;
|
||||
};
|
||||
|
||||
const getSellerName = (item) => {
|
||||
let type = "";
|
||||
switch (item?.allocationType) {
|
||||
case "steward_guild":
|
||||
case "steward_steward":
|
||||
type = `${!item?.stewards ? "-" : item?.stewards?.user?.fullname} (${
|
||||
item?.stewards?.user?.mobile
|
||||
})`;
|
||||
break;
|
||||
case "killhouse_steward":
|
||||
type = `${!item?.killHouse ? "-" : item?.killHouse?.name} (${
|
||||
item?.killHouse?.killHouseOperator?.user?.fullname
|
||||
} - ${item?.killHouse?.killHouseOperator?.user?.mobile})`;
|
||||
break;
|
||||
case "killhouse_guild":
|
||||
type = `${!item?.killHouse ? "-" : item?.killHouse?.name} (${
|
||||
item?.killHouse?.killHouseOperator?.user?.fullname
|
||||
} - ${item?.killHouse?.killHouseOperator?.user?.mobile})`;
|
||||
break;
|
||||
default:
|
||||
type = `${!item?.steward ? "-" : item?.steward?.user?.fullname} (${
|
||||
item?.steward?.user?.mobile
|
||||
})`;
|
||||
break;
|
||||
}
|
||||
return type;
|
||||
};
|
||||
|
||||
const handlePerRowsChange = (perRows) => {
|
||||
setPerPage(perRows);
|
||||
setPage(1);
|
||||
};
|
||||
|
||||
const getLastItem = () => {
|
||||
if (!type || type === "not_entered") {
|
||||
return ["عملیات"];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
};
|
||||
const getRegCodeItemData = (item) => {
|
||||
if (type === "not_entered") {
|
||||
return [];
|
||||
} else {
|
||||
return [
|
||||
item?.loggedRegistrationCode ? item.loggedRegistrationCode : "-",
|
||||
item?.registrationCode ? "ارسال شده" : "ارسال نشده",
|
||||
];
|
||||
}
|
||||
};
|
||||
const getRegCodeItemColumns = () => {
|
||||
if (type === "not_entered") {
|
||||
return [];
|
||||
} else {
|
||||
return ["کداحراز", "وضعیت کد احراز"];
|
||||
}
|
||||
};
|
||||
const getAprovedItemData = (item) => {
|
||||
if (!type) {
|
||||
return [item?.receiverRealWeightOfCarcasses?.toLocaleString()];
|
||||
} else if (type === "not_entered") {
|
||||
return [];
|
||||
} else {
|
||||
return [
|
||||
item?.receiverRealNumberOfCarcasses?.toLocaleString(),
|
||||
item?.receiverRealWeightOfCarcasses?.toLocaleString(),
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
const getAprovedItemColumns = () => {
|
||||
if (!type) {
|
||||
return ["وزن تایید شده"];
|
||||
} else if (type === "not_entered") {
|
||||
return [];
|
||||
} else {
|
||||
return ["حجم تایید شده", "وزن تایید شده"];
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const d = data?.map((item, i) => {
|
||||
return [
|
||||
page === 1 ? i + 1 : i + perPage * (page - 1) + 1,
|
||||
item?.date ? formatTime(item?.date) : "-",
|
||||
item?.productionDate ? formatJustDate(item?.productionDate) : "-",
|
||||
item?.distributionType === "web"
|
||||
? "سایت"
|
||||
: item?.distributionType === "app"
|
||||
? "موبایل"
|
||||
: item?.distributionType === "pos"
|
||||
? "پوز"
|
||||
: item?.distributionType || "-",
|
||||
getAllocationType(item),
|
||||
getAllocationData(item),
|
||||
getSellerName(item),
|
||||
item?.sellType === "exclusive" ? "اختصاصی" : "آزاد",
|
||||
item?.amount?.toLocaleString() + " ریال",
|
||||
item?.totalAmount?.toLocaleString() + " ریال",
|
||||
item?.realWeightOfCarcasses?.toLocaleString(),
|
||||
...getAprovedItemData(item),
|
||||
...getRegCodeItemData(item),
|
||||
item?.weightLossOfCarcasses?.toLocaleString(),
|
||||
item?.quota === "governmental"
|
||||
? "دولتی"
|
||||
: item?.quota === "free"
|
||||
? "آزاد"
|
||||
: "-",
|
||||
item?.approvedPriceStatus ? "دولتی" : "آزاد",
|
||||
item?.receiverState === "accepted"
|
||||
? "تایید شده"
|
||||
: item?.receiverState === "rejected"
|
||||
? "رد شده"
|
||||
: "در انتظار تایید",
|
||||
<StewardShowAllocationsOperations
|
||||
key={i}
|
||||
item={item}
|
||||
updateTable={updateTable}
|
||||
handleUpdate={handleUpdate}
|
||||
type={type}
|
||||
priceInfo={priceInfo}
|
||||
remainWeight={remainWeight}
|
||||
/>,
|
||||
];
|
||||
});
|
||||
|
||||
setTableData(d);
|
||||
}, [data]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchApiData(1);
|
||||
}, [dispatch, selectedDate1, selectedDate2, perPage]);
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
dispatch(LOADING_START());
|
||||
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`steward-allocation/?role=${getRoleFromUrl()}${
|
||||
checkPathStartsWith("steward")
|
||||
? `&role_key=${selectedSubUser?.key}`
|
||||
: ""
|
||||
}&search=filter&value=${textValue}${
|
||||
type !== "not_entered"
|
||||
? `&date1=${selectedDate1}&date2=${selectedDate2}`
|
||||
: ""
|
||||
}&page=${page}&page_size=${perPage}${type ? "&type=" + type : ""}`
|
||||
);
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
dispatch(LOADING_END());
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
dispatch(LOADING_END());
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid container justifyContent="start" alignItems="center" xs={12}>
|
||||
<Grid
|
||||
container
|
||||
xs={12}
|
||||
justifyContent="start"
|
||||
alignItems="center"
|
||||
gap={2}
|
||||
>
|
||||
<Grid
|
||||
container
|
||||
xs={12}
|
||||
justifyContent="start"
|
||||
alignItems="center"
|
||||
gap={2}
|
||||
>
|
||||
{type !== "not_entered" && (
|
||||
<>
|
||||
<Grid>
|
||||
<DatePicker
|
||||
label="از تاریخ"
|
||||
id="date"
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
style={{ width: "160px" }}
|
||||
{...params}
|
||||
size="small"
|
||||
/>
|
||||
)}
|
||||
value={selectedDate1}
|
||||
onChange={(e) => {
|
||||
setSelectedDate1(moment(e).format("YYYY-MM-DD"));
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<DatePicker
|
||||
label="تا تاریخ"
|
||||
id="date"
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
style={{ width: "160px" }}
|
||||
{...params}
|
||||
size="small"
|
||||
/>
|
||||
)}
|
||||
value={selectedDate2}
|
||||
onChange={(e) => {
|
||||
setSelectedDate2(moment(e).format("YYYY-MM-DD"));
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
</>
|
||||
)}
|
||||
<Grid>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<TextField
|
||||
id="outlined-basic"
|
||||
size="small"
|
||||
label="جستجو"
|
||||
variant="outlined"
|
||||
style={{ width: 250 }}
|
||||
onChange={handleTextChange}
|
||||
/>
|
||||
<Button
|
||||
type="submit"
|
||||
onClick={handleSubmit}
|
||||
endIcon={<RiSearchLine />}
|
||||
>
|
||||
جستجو
|
||||
</Button>
|
||||
</form>
|
||||
</Grid>
|
||||
|
||||
{!(type === "entered" || type === "not_entered") && (
|
||||
<Button
|
||||
variant="outlined"
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "ثبت نهایی",
|
||||
content: (
|
||||
<Grid container gap={SPACING.SMALL}>
|
||||
<Typography>
|
||||
در صورت ثبت نهایی انجام هیچگونه عملیاتی مانند حذف و
|
||||
ویرایش امکان پذیر نمی باشد.
|
||||
</Typography>
|
||||
<Grid
|
||||
container
|
||||
direction="column"
|
||||
gap={SPACING.TINY}
|
||||
width="100%"
|
||||
>
|
||||
<Button
|
||||
fullWidth
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
slaughterInventoryFinalSubmitService({
|
||||
steward_allocation_list: data.map(
|
||||
(item) => item.key
|
||||
),
|
||||
})
|
||||
).then((r) => {
|
||||
dispatch(CLOSE_MODAL());
|
||||
if (r.payload?.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.error,
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
updateTable();
|
||||
handleUpdate?.();
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
}
|
||||
});
|
||||
}}
|
||||
>
|
||||
تایید
|
||||
</Button>
|
||||
<Button
|
||||
fullWidth
|
||||
color="error"
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
dispatch(CLOSE_MODAL());
|
||||
}}
|
||||
>
|
||||
لغو
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
),
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
تایید نهایی (یکجا)
|
||||
</Button>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<ResponsiveTable
|
||||
data={tableData}
|
||||
columns={[
|
||||
"ردیف",
|
||||
"تاریخ ثبت",
|
||||
"تاریخ تولید گوشت",
|
||||
"ثبت شده",
|
||||
"نوع تخصیص",
|
||||
"مشخصات خریدار",
|
||||
"مشخصات فروشنده",
|
||||
"نوع فروش",
|
||||
"قیمت هر کیلو",
|
||||
"قیمت کل",
|
||||
"وزن تخصیصی",
|
||||
...getAprovedItemColumns(),
|
||||
...getRegCodeItemColumns(),
|
||||
"افت وزن(کیلوگرم)",
|
||||
"سهمیه",
|
||||
"نوع فروش",
|
||||
"وضعیت",
|
||||
...getLastItem(),
|
||||
]}
|
||||
handlePageChange={handlePageChange}
|
||||
totalRows={totalRows}
|
||||
page={page}
|
||||
perPage={perPage}
|
||||
handlePerRowsChange={handlePerRowsChange}
|
||||
title={
|
||||
type === "entered"
|
||||
? "وارد شده به انبار"
|
||||
: type === "not_entered"
|
||||
? "در انتظار ورود"
|
||||
: "تخصیصات صورت گرفته"
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
StewardShowAllocations.displayName = "StewardShowAllocations";
|
||||
@@ -0,0 +1,243 @@
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
|
||||
import {
|
||||
Button,
|
||||
FormControlLabel,
|
||||
IconButton,
|
||||
Radio,
|
||||
RadioGroup,
|
||||
TextField,
|
||||
Tooltip,
|
||||
} from "@mui/material";
|
||||
import SystemUpdateAltIcon from "@mui/icons-material/SystemUpdateAlt";
|
||||
import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice";
|
||||
import { DatePicker } from "@mui/x-date-pickers";
|
||||
import moment from "moment";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import axios from "axios";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { ROUTE_STEWARD_INVENTORY } from "../../../../routes/routes";
|
||||
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
|
||||
export const StewardShowProducts = () => {
|
||||
const { distributionInfo, stewardProducts } = useSelector(
|
||||
(state) => state.stewardSlice
|
||||
);
|
||||
const [productsTable, setProductsTable] = useState();
|
||||
const { pathname } = useLocation();
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const getWeight = (item) => {
|
||||
if (getRoleFromUrl() === "KillHouse") {
|
||||
return [
|
||||
item?.totalGovernmentalCarcassesWeight?.toLocaleString(),
|
||||
item?.provinceFreeCarcassesWeight?.toLocaleString(),
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
item?.receiveGovernmentalCarcassesWeight?.toLocaleString(),
|
||||
item?.receiveFreeCarcassesWeight?.toLocaleString(),
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const d = stewardProducts?.map((item, i) => {
|
||||
return [
|
||||
i + 1,
|
||||
item?.name,
|
||||
...getWeight(item),
|
||||
item?.freeBuyingCarcassesWeight?.toLocaleString(),
|
||||
item?.totalCarcassesWeight?.toLocaleString(),
|
||||
item?.realAllocatedWeight?.toLocaleString(),
|
||||
item?.totalRemainWeight?.toLocaleString(),
|
||||
distributionInfo?.totalGovernmentalRemainWeight?.toLocaleString(),
|
||||
distributionInfo?.totalFreeRemainWeight?.toLocaleString(),
|
||||
distributionInfo?.totalGovernmentalInputWeight?.toLocaleString(),
|
||||
distributionInfo?.totalFreeInputWeight?.toLocaleString(),
|
||||
];
|
||||
});
|
||||
|
||||
setProductsTable(d);
|
||||
}, [stewardProducts, distributionInfo]);
|
||||
|
||||
const getDistributionKeys = () => {
|
||||
if (pathname === ROUTE_STEWARD_INVENTORY) {
|
||||
return [];
|
||||
} else {
|
||||
return [
|
||||
"مانده دولتی (کیلوگرم)",
|
||||
" مانده آزاد (کیلوگرم)",
|
||||
"وزن دولتی (کیلوگرم)",
|
||||
"وزن آزاد (کیلوگرم)",
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid container xs={12} justifyContent="center" alignItems="center">
|
||||
<ResponsiveTable
|
||||
noPagination={productsTable?.length === 1}
|
||||
paginated={!productsTable?.length === 1}
|
||||
operation={
|
||||
<Grid container>
|
||||
{getRoleFromUrl() === "KillHouse" && (
|
||||
<Tooltip title="خروجی اکسل" placement="top">
|
||||
<IconButton
|
||||
color="primary"
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "دریافت خروجی اکسل",
|
||||
content: <HandleDownloadInventoryData />,
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
<SystemUpdateAltIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Grid>
|
||||
}
|
||||
title={"موجودی انبار"}
|
||||
columns={[
|
||||
"ردیف",
|
||||
"نام محصول",
|
||||
"وزن خریدهای دولتی داخل استان (کیلوگرم)",
|
||||
"وزن خریدهای آزاد داخل استان (کیلوگرم)",
|
||||
"وزن خریدهای خارج استان (کیلوگرم)",
|
||||
"کل ورودی به انبار (کیلوگرم)",
|
||||
"کل فروش (کیلوگرم)",
|
||||
"مانده انبار (کیلوگرم)",
|
||||
...getDistributionKeys(),
|
||||
]}
|
||||
data={productsTable}
|
||||
customColors={[
|
||||
{ name: "ردیف", color: "red" },
|
||||
{ name: "نام محصول", color: "red" },
|
||||
{ name: "کل ورودی به انبار (کیلوگرم)", color: "red" },
|
||||
{ name: "وزن خریدهای دولتی داخل استان (کیلوگرم)", color: "red" },
|
||||
{ name: "وزن خریدهای آزاد داخل استان (کیلوگرم)", color: "red" },
|
||||
{ name: "وزن خریدهای خارج استان (کیلوگرم)", color: "red" },
|
||||
{ name: "کل فروش (کیلوگرم)", color: "red" },
|
||||
{ name: "مانده انبار (کیلوگرم)", color: "green" },
|
||||
]}
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
const HandleDownloadInventoryData = () => {
|
||||
const [downloadType, setDownloadType] = useState("withdate");
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
const handleChange = (event) => {
|
||||
setDownloadType(event.target.value);
|
||||
};
|
||||
|
||||
const userKey = useSelector((state) => state.userSlice.userProfile.key);
|
||||
|
||||
const [selectedDate1, setSelectedDate1] = useState(
|
||||
moment(new Date()).format("YYYY-MM-DD")
|
||||
);
|
||||
const [selectedDate2, setSelectedDate2] = useState(
|
||||
moment(new Date()).format("YYYY-MM-DD")
|
||||
);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [openNotif] = useContext(AppContext);
|
||||
return (
|
||||
<Grid container xs={12} justifyContent="center" alignItems="center" gap={2}>
|
||||
<RadioGroup
|
||||
row
|
||||
aria-labelledby="radio-group-label"
|
||||
name="radio-buttons-group"
|
||||
value={downloadType}
|
||||
onChange={handleChange}
|
||||
>
|
||||
<FormControlLabel
|
||||
value="withdate"
|
||||
control={<Radio />}
|
||||
label="دانلود بر اساس بازه"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value="nodate"
|
||||
control={<Radio />}
|
||||
label="دانلود کلی"
|
||||
/>
|
||||
</RadioGroup>
|
||||
|
||||
{downloadType === "withdate" && (
|
||||
<Grid
|
||||
container
|
||||
xs={12}
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
gap={2}
|
||||
>
|
||||
<Grid>
|
||||
<DatePicker
|
||||
label="از تاریخ"
|
||||
id="date"
|
||||
renderInput={(params) => (
|
||||
<TextField style={{ width: "160px" }} {...params} />
|
||||
)}
|
||||
value={selectedDate1}
|
||||
onChange={(e) => {
|
||||
setSelectedDate1(moment(e).format("YYYY-MM-DD"));
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<DatePicker
|
||||
label="تا تاریخ"
|
||||
id="date"
|
||||
renderInput={(params) => (
|
||||
<TextField style={{ width: "160px" }} {...params} />
|
||||
)}
|
||||
value={selectedDate2}
|
||||
onChange={(e) => {
|
||||
setSelectedDate2(moment(e).format("YYYY-MM-DD"));
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
<Button
|
||||
fullWidth
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
dispatch(CLOSE_MODAL());
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "فایل اکسل در حال دانلود می باشد، این علمیات ممکن است زمان بر باشد لطفا صبر کنید.",
|
||||
severity: "success",
|
||||
});
|
||||
const link = `${
|
||||
axios.defaults.baseURL
|
||||
}kill_house_inventory_data/?role=${getRoleFromUrl()}${
|
||||
checkPathStartsWith("steward")
|
||||
? `&role_key=${selectedSubUser?.key}`
|
||||
: ""
|
||||
}&key=${userKey}${
|
||||
downloadType === "withdate"
|
||||
? `&date1=${selectedDate1}&date2=${selectedDate2}`
|
||||
: ``
|
||||
}`;
|
||||
window.location.href = link;
|
||||
}}
|
||||
>
|
||||
دانلود فایل اکسل
|
||||
</Button>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
116
src/features/steward/components/steward-stock/StewardStock.js
Normal file
116
src/features/steward/components/steward-stock/StewardStock.js
Normal file
@@ -0,0 +1,116 @@
|
||||
import React, { useEffect, useState, useRef } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
import {
|
||||
Accordion,
|
||||
AccordionSummary,
|
||||
AccordionDetails,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
|
||||
import { stewardGetBarsInfo } from "../../services/steward-get-bars-info";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { StewardShowProducts } from "../steward-show-products/StewardShowProducts";
|
||||
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
|
||||
import { StewardShowAllocations } from "../steward-show-allocations/StewardShowAllocations";
|
||||
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
|
||||
export const StewardStock = () => {
|
||||
const dispatch = useDispatch();
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
const [barsInfo, setBarsInfo] = useState([]);
|
||||
const notEnteredRef = useRef();
|
||||
const enteredRef = useRef();
|
||||
|
||||
const handleUpdate = () => {
|
||||
dispatch(
|
||||
stewardGetBarsInfo({
|
||||
role_key: checkPathStartsWith("steward") ? selectedSubUser?.key : "",
|
||||
})
|
||||
).then((r) => {
|
||||
setBarsInfo(r.payload.data);
|
||||
});
|
||||
|
||||
if (notEnteredRef.current) {
|
||||
notEnteredRef.current.updateTable();
|
||||
}
|
||||
if (enteredRef.current) {
|
||||
enteredRef.current.updateTable();
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
handleUpdate();
|
||||
}, [dispatch]);
|
||||
|
||||
return (
|
||||
<Grid container xs={12} justifyContent="end" alignItems="center">
|
||||
<Grid container width="100%" isDashboard>
|
||||
<StewardShowProducts />
|
||||
</Grid>
|
||||
|
||||
<Grid
|
||||
container
|
||||
xs={12}
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
mt={2}
|
||||
>
|
||||
<Grid container justifyContent="start" alignItems="center" xs={12}>
|
||||
<ResponsiveTable
|
||||
title="اطلاعات کلی بارها"
|
||||
noPagination
|
||||
data={[
|
||||
[
|
||||
barsInfo?.totalBars?.toLocaleString(),
|
||||
barsInfo?.totalBarsWeight?.toLocaleString(),
|
||||
barsInfo?.totalEnteredBars?.toLocaleString(),
|
||||
barsInfo?.totalEnteredBarsWeight?.toLocaleString(),
|
||||
barsInfo?.totalNotEnteredBars?.toLocaleString(),
|
||||
barsInfo?.totalNotEnteredKillHouseRequestsWeight?.toLocaleString(),
|
||||
barsInfo?.totalRejectedBars?.toLocaleString(),
|
||||
barsInfo?.totalRejectedBarsWeight?.toLocaleString(),
|
||||
],
|
||||
]}
|
||||
columns={[
|
||||
"تعداد کل بارها",
|
||||
"وزن کل بارها (کیلوگرم)",
|
||||
"تعداد کل بارهای وارد شده",
|
||||
"وزن کل بار وارد شده (کیلوگرم)",
|
||||
"تعداد کل بارهای وارد نشده",
|
||||
"وزن کل بار وارد نشده (کیلوگرم)",
|
||||
"تعداد کل بارهای رد شده",
|
||||
"وزن کل بارهای رد شده",
|
||||
]}
|
||||
allColors={{ color: "#f3bda3", text: "#332a3d" }}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<Grid container xs={12} mt={4}>
|
||||
<StewardShowAllocations
|
||||
ref={notEnteredRef}
|
||||
type="not_entered"
|
||||
handleUpdate={handleUpdate}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<Accordion sx={{ width: "100%", mt: 4 }}>
|
||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||
<Typography>بارهای وارد شده</Typography>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<Grid container xs={12}>
|
||||
<StewardShowAllocations
|
||||
ref={enteredRef}
|
||||
type="entered"
|
||||
handleUpdate={handleUpdate}
|
||||
/>
|
||||
</Grid>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,369 @@
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useFormik } from "formik";
|
||||
import moment from "moment";
|
||||
import { Autocomplete, Button, InputAdornment, TextField } from "@mui/material";
|
||||
import { Yup } from "../../../../lib/yup/yup";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { slaughterGetProductsService } from "../../../slaughter-house/services/slaughter-inventory-gets";
|
||||
import {
|
||||
slaughterGetCitiesService,
|
||||
slaughterGetProvinceService,
|
||||
} from "../../../slaughter-house/services/slaughter-get-provinces";
|
||||
import { fixBase64 } from "../../../../utils/toBase64";
|
||||
import { DRAWER } from "../../../../lib/redux/slices/appSlice";
|
||||
import {
|
||||
stewardEditFreeBarService,
|
||||
stewardSubmitFreeBarService,
|
||||
} from "../../../guild/services/steward-submit-free-bar-service";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { ImageUpload } from "../../../../components/image-upload/ImageUpload";
|
||||
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
|
||||
const ValidationSchema = Yup.object().shape({
|
||||
kill_house_name: Yup.string().required("نام فروشنده الزامی است"),
|
||||
kill_house_mobile: Yup.string()
|
||||
.required("شماره موبایل فروشنده الزامی است")
|
||||
.min(11, "شماره موبایل باید دقیقاً 11 رقم باشد")
|
||||
.max(11, "شماره موبایل باید دقیقاً 11 رقم باشد"),
|
||||
province: Yup.string().required("استان الزامی است"),
|
||||
city: Yup.string().required("شهر الزامی است"),
|
||||
bar_image: Yup.string().when("$isEdit", {
|
||||
is: true,
|
||||
then: Yup.string(),
|
||||
otherwise: Yup.string().required("عکس بار الزامی است"),
|
||||
}),
|
||||
number_of_carcasses: Yup.number()
|
||||
.required("حجم لاشه الزامی است")
|
||||
.min(1, "حجم لاشه باید بیشتر از 0 باشد"),
|
||||
weight_of_carcasses: Yup.number()
|
||||
.required("وزن لاشه الزامی است")
|
||||
.min(0.01, "وزن باید بیشتر از 0 باشد"),
|
||||
product_key: Yup.string().required("انتخاب محصول الزامی است"),
|
||||
});
|
||||
|
||||
export const StewardSubmitFreeBar = ({ updateTable, item }) => {
|
||||
const dispatch = useDispatch();
|
||||
const [openNotif] = useContext(AppContext);
|
||||
const [productData, setProductData] = useState([]);
|
||||
const [provinceData, setProvinceData] = useState([]);
|
||||
const [cityData, setCityData] = useState([]);
|
||||
const [profileImages, setProfileImages] = useState([]);
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
slaughterGetProductsService({
|
||||
role_key: checkPathStartsWith("steward")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
).then((r) => {
|
||||
// Handle both direct array response and nested data response
|
||||
const data = r.payload?.data;
|
||||
if (Array.isArray(data)) {
|
||||
setProductData(data);
|
||||
} else if (data?.data && Array.isArray(data.data)) {
|
||||
setProductData(data.data);
|
||||
} else {
|
||||
setProductData([]);
|
||||
}
|
||||
});
|
||||
dispatch(slaughterGetProvinceService()).then((r) => {
|
||||
setProvinceData(r.payload.data);
|
||||
});
|
||||
}, [dispatch, selectedSubUser]);
|
||||
const formik = useFormik({
|
||||
initialValues: {
|
||||
product_key: item?.productKey || "",
|
||||
kill_house_name: item?.killHouseName || "",
|
||||
kill_house_mobile: item?.killHouseMobile || "",
|
||||
province: item?.province || "",
|
||||
city: item?.city || "",
|
||||
bar_image: item?.barImage || "",
|
||||
number_of_carcasses: item?.numberOfCarcasses || "",
|
||||
weight_of_carcasses: item?.weightOfCarcasses || "",
|
||||
date: item?.date || moment(new Date()).format("YYYY-MM-DD HH:mm:ss"),
|
||||
role_key: checkPathStartsWith("steward")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
...(item?.key && { key: item.key }),
|
||||
},
|
||||
validationSchema: ValidationSchema,
|
||||
onSubmit: (values) => {
|
||||
if (item?.key) {
|
||||
if (profileImages.length && profileImages[0]?.data_url) {
|
||||
values.bar_image = fixBase64(profileImages[0]?.data_url);
|
||||
} else {
|
||||
values.bar_image = item.barImage;
|
||||
}
|
||||
}
|
||||
const thenCallback = (r) => {
|
||||
if (r.payload.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.error,
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
updateTable();
|
||||
dispatch(DRAWER({ right: false, bottom: false, content: null }));
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: item?.key
|
||||
? "اطلاعات خرید با موفقیت ویرایش شد"
|
||||
: "اطلاعات خرید جدید با موفقیت ثبت شد",
|
||||
severity: "success",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if (item?.key) {
|
||||
dispatch(stewardEditFreeBarService(values)).then(thenCallback);
|
||||
} else {
|
||||
dispatch(stewardSubmitFreeBarService(values)).then(thenCallback);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const factorPaymentHandler = (imageList) => {
|
||||
if (imageList[0]) {
|
||||
formik.setFieldValue("bar_image", fixBase64(imageList[0]?.data_url));
|
||||
}
|
||||
setProfileImages(imageList);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (formik.values.province) {
|
||||
dispatch(slaughterGetCitiesService(formik.values.province)).then((r) => {
|
||||
setCityData(r.payload.data);
|
||||
});
|
||||
}
|
||||
}, [formik.values.province]);
|
||||
useEffect(() => {
|
||||
if (item?.barImage) {
|
||||
setProfileImages([{ data_url: item?.barImage }]);
|
||||
}
|
||||
}, [item]);
|
||||
|
||||
return (
|
||||
<Grid container direction="column" justifyContent="center" gap={2}>
|
||||
<Grid container direction="column" justifyContent="center" gap={2}>
|
||||
<Grid xs={12} container gap={2}>
|
||||
<Autocomplete
|
||||
fullWidth
|
||||
style={{ minWidth: 210 }}
|
||||
disablePortal
|
||||
id="product_key"
|
||||
options={
|
||||
Array.isArray(productData) && productData.length > 0
|
||||
? productData.map((i) => ({
|
||||
id: i.key,
|
||||
label: i.name || "",
|
||||
}))
|
||||
: []
|
||||
}
|
||||
value={
|
||||
Array.isArray(productData) && productData.length > 0
|
||||
? productData
|
||||
.map((i) => ({ id: i.key, label: i.name || "" }))
|
||||
.find((opt) => opt.id === formik.values.product_key) || null
|
||||
: null
|
||||
}
|
||||
onChange={(event, value) => {
|
||||
formik.setFieldValue("product_key", value ? value.id : "");
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
{...params}
|
||||
label="انتخاب محصول"
|
||||
error={
|
||||
formik.touched.product_key &&
|
||||
Boolean(formik.errors.product_key)
|
||||
}
|
||||
helperText={
|
||||
formik.touched.product_key && formik.errors.product_key
|
||||
}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<form
|
||||
onSubmit={formik.handleSubmit}
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: SPACING.LARGE,
|
||||
}}
|
||||
>
|
||||
<TextField
|
||||
id="kill_house_name"
|
||||
name="kill_house_name"
|
||||
label="نام فروشنده"
|
||||
value={formik.values.kill_house_name}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
error={
|
||||
formik.touched.kill_house_name &&
|
||||
Boolean(formik.errors.kill_house_name)
|
||||
}
|
||||
helperText={
|
||||
formik.touched.kill_house_name && formik.errors.kill_house_name
|
||||
}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
id="kill_house_mobile"
|
||||
name="kill_house_mobile"
|
||||
label="تلفن فروشنده"
|
||||
value={formik.values.kill_house_mobile}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
error={
|
||||
formik.touched.kill_house_mobile &&
|
||||
Boolean(formik.errors.kill_house_mobile)
|
||||
}
|
||||
helperText={
|
||||
formik.touched.kill_house_mobile &&
|
||||
formik.errors.kill_house_mobile
|
||||
}
|
||||
/>
|
||||
<Autocomplete
|
||||
style={{ width: "100%" }}
|
||||
disablePortal
|
||||
id="province"
|
||||
options={provinceData.map((i) => ({
|
||||
id: i.name,
|
||||
label: i.name,
|
||||
}))}
|
||||
value={
|
||||
formik.values.province
|
||||
? {
|
||||
id: formik.values.province,
|
||||
label: formik.values.province,
|
||||
}
|
||||
: null
|
||||
}
|
||||
onChange={(e, value) => {
|
||||
formik.setFieldValue("province", value ? value.id : "");
|
||||
formik.setFieldValue("city", "");
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
{...params}
|
||||
label="استان را انتخاب کنید"
|
||||
error={
|
||||
formik.touched.province && Boolean(formik.errors.province)
|
||||
}
|
||||
helperText={formik.touched.province && formik.errors.province}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Autocomplete
|
||||
minWidth={210}
|
||||
style={{ width: "100%" }}
|
||||
disabled={!formik.values.province}
|
||||
disablePortal
|
||||
id="city"
|
||||
value={
|
||||
formik.values.city
|
||||
? {
|
||||
id: formik.values.city,
|
||||
label: formik.values.city,
|
||||
}
|
||||
: null
|
||||
}
|
||||
options={
|
||||
cityData
|
||||
? cityData.map((i) => ({ id: i.name, label: i.name }))
|
||||
: []
|
||||
}
|
||||
onChange={(e, value) => {
|
||||
formik.setFieldValue("city", value ? value.id : "");
|
||||
formik.setFieldValue("city", value ? value.id : "");
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField {...params} label="شهر را انتخاب کنید" />
|
||||
)}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
id="number_of_carcasses"
|
||||
name="number_of_carcasses"
|
||||
label="حجم لاشه"
|
||||
type="number"
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<InputAdornment position="end">قطعه</InputAdornment>
|
||||
),
|
||||
}}
|
||||
value={formik.values.number_of_carcasses}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
error={
|
||||
formik.touched.number_of_carcasses &&
|
||||
Boolean(formik.errors.number_of_carcasses)
|
||||
}
|
||||
helperText={
|
||||
formik.touched.number_of_carcasses &&
|
||||
formik.errors.number_of_carcasses
|
||||
}
|
||||
/>
|
||||
|
||||
<TextField
|
||||
id="weight_of_carcasses"
|
||||
name="weight_of_carcasses"
|
||||
label="وزن لاشه"
|
||||
type="number"
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<InputAdornment position="end">کیلوگرم</InputAdornment>
|
||||
),
|
||||
}}
|
||||
value={formik.values.weight_of_carcasses}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
error={
|
||||
formik.touched.weight_of_carcasses &&
|
||||
Boolean(formik.errors.weight_of_carcasses)
|
||||
}
|
||||
helperText={
|
||||
formik.touched.weight_of_carcasses &&
|
||||
formik.errors.weight_of_carcasses
|
||||
}
|
||||
/>
|
||||
|
||||
<ImageUpload
|
||||
onChange={factorPaymentHandler}
|
||||
images={profileImages}
|
||||
maxNumber={1}
|
||||
title={"تصویر بار"}
|
||||
/>
|
||||
|
||||
{!profileImages.length && item?.barImage && (
|
||||
<Grid container justifyContent="center">
|
||||
<img style={{ width: "60px" }} alt="bar" src={item?.barImage} />
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
fullWidth
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={!formik.isValid}
|
||||
>
|
||||
{item?.key ? "ویرایش خرید" : "ثبت خرید جدید"}
|
||||
</Button>
|
||||
</form>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
import { createAsyncThunk } from "@reduxjs/toolkit";
|
||||
import axios from "axios";
|
||||
import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice";
|
||||
import { getRoleFromUrl } from "../../../utils/getRoleFromUrl";
|
||||
|
||||
export const fetchStewardBroadcastAndProducts = createAsyncThunk(
|
||||
"STEWARD_FETCH_BROADCAST_AND_PRODUCTS",
|
||||
async (d, { dispatch }) => {
|
||||
try {
|
||||
dispatch(LOADING_START());
|
||||
const [broadcastResponse, productsResponse] = await Promise.all([
|
||||
axios.get("steward-sales-info-dashboard/", {
|
||||
params: {
|
||||
role: getRoleFromUrl(),
|
||||
role_key: d.role_key || "",
|
||||
},
|
||||
}),
|
||||
axios.get("roles-products", {
|
||||
params: {
|
||||
role: getRoleFromUrl(),
|
||||
role_key: d.role_key || "",
|
||||
},
|
||||
}),
|
||||
]);
|
||||
|
||||
dispatch(LOADING_END());
|
||||
|
||||
return {
|
||||
broadcastData: broadcastResponse.data,
|
||||
productsData: productsResponse.data,
|
||||
};
|
||||
} catch (error) {
|
||||
dispatch(LOADING_END());
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
);
|
||||
19
src/features/steward/services/steward-get-bars-info.js
Normal file
19
src/features/steward/services/steward-get-bars-info.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import { createAsyncThunk } from "@reduxjs/toolkit";
|
||||
import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice";
|
||||
import axios from "axios";
|
||||
import { getRoleFromUrl } from "../../../utils/getRoleFromUrl";
|
||||
|
||||
export const stewardGetBarsInfo = createAsyncThunk(
|
||||
"STEWARD_GET_BARS_INFO",
|
||||
async (d, { dispatch }) => {
|
||||
dispatch(LOADING_START());
|
||||
const { data, status } = await axios.get("bars_for_kill_house_dashboard/", {
|
||||
params: {
|
||||
role: getRoleFromUrl(),
|
||||
...d,
|
||||
},
|
||||
});
|
||||
dispatch(LOADING_END());
|
||||
return { data, status };
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,15 @@
|
||||
import { createAsyncThunk } from "@reduxjs/toolkit";
|
||||
import { getRoleFromUrl } from "../../../utils/getRoleFromUrl";
|
||||
import axios from "axios";
|
||||
|
||||
export const stewardGetVBroadcastInfo = createAsyncThunk(
|
||||
"STEWARD_GET_BROARDCAST_INFO",
|
||||
async (d, { dispatch }) => {
|
||||
const { data, status } = await axios.get("steward-sales-info-dashboard/", {
|
||||
params: {
|
||||
role: getRoleFromUrl(),
|
||||
},
|
||||
});
|
||||
return { data, status };
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,21 @@
|
||||
import { createAsyncThunk } from "@reduxjs/toolkit";
|
||||
import axios from "axios";
|
||||
import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice";
|
||||
|
||||
export const stewardResendOutProvinceRegistrationCodeService = createAsyncThunk(
|
||||
"STEWARD_RESEND_OUT_PROVINCE_REGISTRATION_CODE",
|
||||
async (d, { dispatch }) => {
|
||||
dispatch(LOADING_START());
|
||||
try {
|
||||
const { data, status } = await axios.post(
|
||||
"send_again_sms_steward_free_sale_bar/",
|
||||
d
|
||||
);
|
||||
dispatch(LOADING_END());
|
||||
return { data, status };
|
||||
} catch (e) {
|
||||
dispatch(LOADING_END());
|
||||
return { error: e.response?.data?.result || "خطا در ارسال مجدد کد" };
|
||||
}
|
||||
}
|
||||
);
|
||||
Reference in New Issue
Block a user