push rasad front on new repo
This commit is contained in:
@@ -0,0 +1,408 @@
|
||||
import { Button, TextField, Typography } from "@mui/material";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import PlagiarismIcon from "@mui/icons-material/Plagiarism";
|
||||
// import { ROUTE_CITY_FILE } from "../../../../routes/routes";
|
||||
// import { avicultureGetRequests } from "../../../aviculture/services/aviculture-requests";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { PageTable } from "../../../../components/page-table/PageTable";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import axios from "axios";
|
||||
import { DatePicker } from "@mui/x-date-pickers";
|
||||
import moment from "moment/moment";
|
||||
import { formatJustDate } from "../../../../utils/formatTime";
|
||||
import { IconButton } from "@mui/material";
|
||||
import { ROUTE_CITY_FILE } from "../../../../routes/routes";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { RiSearchLine } from "react-icons/ri";
|
||||
|
||||
export const CityActiveRequests = () => {
|
||||
const navigate = useNavigate();
|
||||
const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] =
|
||||
useContext(AppContext);
|
||||
useEffect(() => {
|
||||
const currentDate = moment(new Date()).format("YYYY-MM-DD");
|
||||
setSelectedDate1(currentDate);
|
||||
setSelectedDate2(currentDate);
|
||||
}, []);
|
||||
|
||||
// page table
|
||||
const [data, setData] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [totalRows, setTotalRows] = useState(0);
|
||||
const [perPage, setPerPage] = useState(10);
|
||||
|
||||
const [textValue, setTextValue] = useState("");
|
||||
|
||||
const handleTextChange = (event) => {
|
||||
setTextValue(event.target.value);
|
||||
};
|
||||
|
||||
const fetchApiData = async (page, textValue) => {
|
||||
setLoading(true);
|
||||
let response = await axios.get(
|
||||
`Poultry_Request/?state=accepted&date1=${selectedDate1}&date2=${selectedDate2}&search=filter&value=${
|
||||
textValue ? textValue : ""
|
||||
}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}`
|
||||
);
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
const handlePageChange = (page) => {
|
||||
fetchApiData(page, textValue);
|
||||
};
|
||||
|
||||
const handlePerRowsChange = async (newPerPage, page) => {
|
||||
setLoading(true);
|
||||
let response = await axios.get(
|
||||
`Poultry_Request/?state=accepted&date1=${selectedDate1}&date2=${selectedDate2}&search=filter&value=${
|
||||
textValue ? textValue : ""
|
||||
}&page=${page}&page_size=${newPerPage}`
|
||||
);
|
||||
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
setPerPage(newPerPage);
|
||||
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchApiData(1);
|
||||
}, [selectedDate1, selectedDate2, perPage]);
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
setLoading(true);
|
||||
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`Poultry_Request/?state=accepted&date1=${selectedDate1}&date2=${selectedDate2}&role=${getRoleFromUrl()}&search=filter&value=${
|
||||
textValue ? textValue : ""
|
||||
}`
|
||||
);
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{
|
||||
name: "ردیف",
|
||||
selector: (item, i) => {
|
||||
return i + 1;
|
||||
},
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
width: "40px",
|
||||
},
|
||||
{
|
||||
name: "وضعیت",
|
||||
selector: (item) => (
|
||||
<Typography
|
||||
variant="body2"
|
||||
color={item.provinceState === "rejected" ? "error" : "promary"}
|
||||
>
|
||||
{item.provinceState === "pending"
|
||||
? "درانتظار تایید استان"
|
||||
: item.provinceState === "accepted"
|
||||
? "تایید شده توسط استان"
|
||||
: "رد شده"}
|
||||
</Typography>
|
||||
),
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
},
|
||||
{
|
||||
name: "کدسفارش",
|
||||
selector: (item) => item.orderCode,
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
},
|
||||
{
|
||||
name: "تاریخ ثبت درخواست",
|
||||
selector: (item) => formatJustDate(item.createDate),
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
},
|
||||
{
|
||||
name: "نوع کشتار",
|
||||
selector: (item) => {
|
||||
return item?.freezing ? "انجماد" : item?.export ? "صادرات" : "عادی";
|
||||
},
|
||||
sortable: true,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
width: "80px",
|
||||
},
|
||||
{
|
||||
name: "تاریخ کشتار",
|
||||
selector: (item) => formatJustDate(item.sendDate),
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
},
|
||||
{
|
||||
name: "مرغداری",
|
||||
selector: (item) =>
|
||||
`${item?.poultry?.unitName} (${item?.poultry?.user?.mobile})`,
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
},
|
||||
{
|
||||
name: "شهر",
|
||||
selector: (item) => item?.poultry?.address?.city?.name,
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
},
|
||||
{
|
||||
name: "استان",
|
||||
selector: (item) => item?.poultry?.address?.province?.name,
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
},
|
||||
{
|
||||
name: "تاریخ جوجه ریزی",
|
||||
selector: (item) => formatJustDate(item.hatching.hatchingDate),
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
},
|
||||
{
|
||||
name: "سن",
|
||||
selector: (item) => item.hatching.age,
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
},
|
||||
{
|
||||
name: "تعداد (قطعه)",
|
||||
selector: (item) => item?.quantity,
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
},
|
||||
{
|
||||
name: "مشاهده",
|
||||
selector: (item) => {
|
||||
return (
|
||||
<IconButton
|
||||
aria-label="delete"
|
||||
color="primary"
|
||||
onClick={() => navigate(ROUTE_CITY_FILE + item?.id)}
|
||||
>
|
||||
<PlagiarismIcon />
|
||||
</IconButton>
|
||||
);
|
||||
},
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
},
|
||||
];
|
||||
|
||||
// useEffect(() => {
|
||||
// dispatch(LOADING_START());
|
||||
// dispatch(avicultureGetRequests({ selectedDate1, selectedDate2 })).then(
|
||||
// (r) => {
|
||||
// dispatch(LOADING_END());
|
||||
// }
|
||||
// );
|
||||
// }, [selectedDate1, selectedDate2]);
|
||||
|
||||
// useEffect(() => {
|
||||
// const filteredData = avicultureRequests?.filter(
|
||||
// (item, i) => item.stateProcess === "pending"
|
||||
// );
|
||||
// const d = filteredData?.map((item, i) => {
|
||||
// return [
|
||||
// i + 1,
|
||||
// item.orderCode,
|
||||
// item.poultry.userprofile.baseOrder,
|
||||
// formatJustDate(item.createDate),
|
||||
// formatJustDate(item.sendDate),
|
||||
// item?.process?.poultry?.poultryName,
|
||||
// item?.process?.poultry?.poultryMobile,
|
||||
// item?.process?.poultry?.poultryCity,
|
||||
// item?.process?.poultry?.poultryProvince,
|
||||
// formatJustDate(item.hatching.date),
|
||||
// item?.process?.poultry?.age,
|
||||
// item?.process?.poultry?.poultryQuantity,
|
||||
// <IconButton
|
||||
// key={i}
|
||||
// color="primary"
|
||||
// onClick={() =>
|
||||
// dispatch(
|
||||
// DRAWER({
|
||||
// right: !(window.innerWidth <= 600),
|
||||
// bottom: window.innerWidth <= 600,
|
||||
// content: (
|
||||
// <CityFileOperations id={item.id} file={item?.process} />
|
||||
// ),
|
||||
// title: "انجام عملیات شهرستان",
|
||||
// })
|
||||
// )
|
||||
// }
|
||||
// >
|
||||
// <CreateIcon />
|
||||
// </IconButton>,
|
||||
// <IconButton
|
||||
// key={i}
|
||||
// aria-label="delete"
|
||||
// color="primary"
|
||||
// onClick={() =>
|
||||
// navigate(ROUTE_CITY_FILE + item?.process?.poultry?.poultryRequestId)
|
||||
// }
|
||||
// >
|
||||
// <PlagiarismIcon />
|
||||
// </IconButton>,
|
||||
// ];
|
||||
// });
|
||||
|
||||
// setDataTable(d);
|
||||
// }, [avicultureRequests]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* <AdvancedTable
|
||||
name={
|
||||
<Grid container alignItems="center" gap={SPACING.SMALL}>
|
||||
<Grid container gap={SPACING.TINY}>
|
||||
<Typography>درخواست های جدید فروش اتحادیه</Typography>
|
||||
</Grid>
|
||||
<Grid container gap={SPACING.SMALL}>
|
||||
<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>
|
||||
</Grid>
|
||||
}
|
||||
columns={columnsName}
|
||||
data={dataTable}
|
||||
/> */}
|
||||
|
||||
<Grid alignItems="center" justifyContent="center" mt={4}>
|
||||
<PageTable
|
||||
title={
|
||||
<Grid
|
||||
container
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
gap={2}
|
||||
paddingTop={2}
|
||||
mb={1}
|
||||
>
|
||||
<Grid container alignItems="center" gap={SPACING.SMALL}>
|
||||
<Typography>درخواست های فعال</Typography>
|
||||
<Grid container gap={SPACING.SMALL}>
|
||||
<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>
|
||||
<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>
|
||||
}
|
||||
columns={columns}
|
||||
data={data}
|
||||
progressPending={loading}
|
||||
pagination
|
||||
paginationServer
|
||||
paginationTotalRows={totalRows}
|
||||
onChangeRowsPerPage={handlePerRowsChange}
|
||||
onChangePage={handlePageChange}
|
||||
/>
|
||||
</Grid>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,87 @@
|
||||
import React, { useContext } from "react";
|
||||
import { useFormik } from "formik";
|
||||
import { Button, TextField } from "@mui/material";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { archiveHatchingService } from "../../services/archive-hatching";
|
||||
import { DRAWER } from "../../../../lib/redux/slices/appSlice";
|
||||
import * as Yup from "yup";
|
||||
// import { cityGetHatchingsByAge } from "../../services/city-get-hatchings-by-age";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import { cityGetHatchingsByAge } from "../../services/city-get-hatchings-by-age";
|
||||
|
||||
const validationSchema = Yup.object({
|
||||
name: Yup.string(),
|
||||
});
|
||||
|
||||
export const CityArchiveHatchingDrawer = ({
|
||||
item,
|
||||
selectedAge1,
|
||||
selectedAge2,
|
||||
updateTable,
|
||||
}) => {
|
||||
const [openNotif] = useContext(AppContext);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues: {
|
||||
name: "",
|
||||
},
|
||||
validationSchema,
|
||||
onSubmit: (values) => {
|
||||
dispatch(
|
||||
archiveHatchingService({
|
||||
key: item.key,
|
||||
archive_state: "",
|
||||
message: values.name,
|
||||
role: getRoleFromUrl(),
|
||||
})
|
||||
).then((r) => {
|
||||
if (r.payload.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.error,
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
dispatch(DRAWER({ right: false, bottom: false, content: null }));
|
||||
if (selectedAge1) {
|
||||
dispatch(cityGetHatchingsByAge({ selectedAge1, selectedAge2 }));
|
||||
}
|
||||
updateTable();
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<form onSubmit={formik.handleSubmit}>
|
||||
<TextField
|
||||
id="name"
|
||||
name="name"
|
||||
label="توضیحات"
|
||||
variant="outlined"
|
||||
multiline
|
||||
rows={4}
|
||||
fullWidth
|
||||
margin="normal"
|
||||
value={formik.values.name}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={formik.touched.name && formik.errors.name}
|
||||
error={formik.touched.name && Boolean(formik.errors.name)}
|
||||
/>
|
||||
<Button type="submit" variant="contained" color="primary" fullWidth>
|
||||
ثبت
|
||||
</Button>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,91 @@
|
||||
import {
|
||||
Button,
|
||||
FormControl,
|
||||
FormHelperText,
|
||||
TextField,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import { useFormik } from "formik";
|
||||
import { useContext } from "react";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice";
|
||||
import { Yup } from "../../../../lib/yup/yup";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import { archiveOldHatchingsService } from "../../services/archive-old-hatchings";
|
||||
|
||||
export const CityArchiveOldHatchings = () => {
|
||||
const dispatch = useDispatch();
|
||||
const [openNotif] = useContext(AppContext);
|
||||
const validationSchema = Yup.object().shape({
|
||||
numberField: Yup.number().typeError("عدد وارد کنید").required("اجباری است"),
|
||||
});
|
||||
|
||||
const initialValues = {
|
||||
numberField: "",
|
||||
};
|
||||
|
||||
const onSubmit = (values) => {
|
||||
dispatch(
|
||||
archiveOldHatchingsService({
|
||||
age: values.numberField,
|
||||
role: getRoleFromUrl(),
|
||||
})
|
||||
).then((r) => {
|
||||
dispatch(CLOSE_MODAL());
|
||||
if (r.payload.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.error,
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.data.msg,
|
||||
severity: "success",
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues,
|
||||
onSubmit,
|
||||
validationSchema,
|
||||
});
|
||||
|
||||
return (
|
||||
<form onSubmit={formik.handleSubmit}>
|
||||
<Grid container gap={SPACING.TINY}>
|
||||
<Typography variant="caption" color="error">
|
||||
توجه : تمام جوجه ریزی های فعالی که بیشتر از سن وارده شده در کادر زیر
|
||||
باشند به بایگانی منتقل میشوند.
|
||||
</Typography>
|
||||
<FormControl
|
||||
fullWidth
|
||||
error={formik.touched.numberField && formik.errors.numberField}
|
||||
>
|
||||
<TextField
|
||||
name="numberField"
|
||||
label="بایگانی کردن جوجه ریزی ها از سن"
|
||||
type="number"
|
||||
value={formik.values.numberField}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
{formik.touched.numberField && formik.errors.numberField && (
|
||||
<FormHelperText>{formik.errors.numberField}</FormHelperText>
|
||||
)}
|
||||
</FormControl>
|
||||
<Button type="submit" variant="contained" color="primary" fullWidth>
|
||||
ثبت
|
||||
</Button>
|
||||
</Grid>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,554 @@
|
||||
import {
|
||||
Autocomplete,
|
||||
Button,
|
||||
Chip,
|
||||
Divider,
|
||||
FormControl,
|
||||
InputLabel,
|
||||
MenuItem,
|
||||
Select,
|
||||
TextField,
|
||||
} from "@mui/material";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import React, { useEffect } from "react";
|
||||
import { Yup } from "../../../../lib/yup/yup";
|
||||
import { useFormik } from "formik";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { cityGetProvinces } from "../../services/CityGetProvinces";
|
||||
import {
|
||||
DRAWER,
|
||||
LOADING_END,
|
||||
LOADING_START,
|
||||
} from "../../../../lib/redux/slices/appSlice";
|
||||
import { useState } from "react";
|
||||
import { cityGetCity } from "../../services/city-get-city";
|
||||
import { cityEditAvicultureInfo } from "../../services/city-edit-avculture.info";
|
||||
import { useContext } from "react";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { PropTypes } from "prop-types";
|
||||
import { cityGetPoultryFarm } from "../../services/city-get-poultry-farms";
|
||||
|
||||
export const CityEditAvicultureInfoForm = ({ item }) => {
|
||||
const dispatch = useDispatch();
|
||||
const [openNotif] = useContext(AppContext);
|
||||
const [provinceData, setProvinceData] = useState();
|
||||
const [cityData, setCityData] = useState();
|
||||
const [provinceKey, setProvinceKey] = useState();
|
||||
const [cityKey, setCityKey] = useState();
|
||||
|
||||
const [isExistProvince, setIsExistProvince] = useState(true);
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues: {
|
||||
avicultureName: item?.unitName ? item?.unitName : "",
|
||||
postal: item?.address.postalCode ? item?.address.postalCode : "",
|
||||
address: item?.address.address ? item?.address.address : "",
|
||||
bankUser: item?.userBankInfo?.nameOfBankUser
|
||||
? item?.userBankInfo?.nameOfBankUser
|
||||
: "",
|
||||
card: item?.userBankInfo?.card ? item?.userBankInfo.card : "",
|
||||
account: item?.userBankInfo?.account ? item?.userBankInfo.account : "",
|
||||
bankName: "",
|
||||
shaba: item?.userBankInfo?.shaba ? item?.userBankInfo.shaba : "",
|
||||
hall: item?.numberOfHalls ? item?.numberOfHalls : "",
|
||||
breedingUniqueId: item?.breedingUniqueId ? item?.breedingUniqueId : "",
|
||||
systemCode: item?.systemCode ? item?.systemCode : "",
|
||||
epidemiologicalCode: item?.epidemiologicalCode
|
||||
? item?.epidemiologicalCode
|
||||
: "",
|
||||
totalCapacity: item?.totalCapacity ? item?.totalCapacity : "",
|
||||
healthCertificateNumber: item?.healthCertificateNumber
|
||||
? item?.healthCertificateNumber
|
||||
: "",
|
||||
},
|
||||
validationSchema: Yup.object({
|
||||
avicultureName: Yup.string().typeError(
|
||||
"لطفا فیلد را به درستی وارد کنید!"
|
||||
),
|
||||
address: Yup.string().typeError("لطفا فیلد را به درستی وارد کنید!"),
|
||||
card: Yup.number().typeError("لطفا فیلد را به درستی وارد کنید!"),
|
||||
|
||||
bankUser: Yup.string().typeError("لطفا فیلد را به درستی وارد کنید!"),
|
||||
postal: Yup.number().typeError("لطفا فیلد را به درستی وارد کنید!"),
|
||||
account: Yup.number().typeError("لطفا فیلد را به درستی وارد کنید!"),
|
||||
bankName: Yup.string().typeError("لطفا فیلد را به درستی وارد کنید!"),
|
||||
shaba: Yup.string().typeError("لطفا فیلد را به درستی وارد کنید!"),
|
||||
hall: Yup.number().typeError("لطفا فیلد را به درستی وارد کنید!"),
|
||||
breedingUniqueId: Yup.number().typeError(
|
||||
"لطفا فیلد را به درستی وارد کنید!"
|
||||
),
|
||||
systemCode: Yup.number().typeError("لطفا فیلد را به درستی وارد کنید!"),
|
||||
epidemiologicalCode: Yup.number().typeError(
|
||||
"لطفا فیلد را به درستی وارد کنید!"
|
||||
),
|
||||
totalCapacity: Yup.number().typeError("لطفا فیلد را به درستی وارد کنید!"),
|
||||
healthCertificateNumber: Yup.number().typeError(
|
||||
"لطفا فیلد را به درستی وارد کنید!"
|
||||
),
|
||||
}),
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
formik.validateForm();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(LOADING_START());
|
||||
dispatch(cityGetProvinces())?.then((r) => {
|
||||
dispatch(LOADING_END());
|
||||
setProvinceData(r.payload.data);
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (provinceKey) {
|
||||
dispatch(LOADING_START());
|
||||
dispatch(cityGetCity(provinceKey)).then((r) => {
|
||||
setCityData(r.payload.data);
|
||||
setIsExistProvince(false);
|
||||
dispatch(LOADING_END());
|
||||
});
|
||||
}
|
||||
}, [provinceKey]);
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
gap={SPACING.SMALL}
|
||||
direction="column"
|
||||
flex="1"
|
||||
height="100%"
|
||||
justifyContent="space-between"
|
||||
display="block"
|
||||
>
|
||||
<Grid container direction="column" gap={SPACING.SMALL}>
|
||||
<Grid>
|
||||
<TextField
|
||||
id="breedingUniqueId"
|
||||
label="شناسه یکتا"
|
||||
variant="outlined"
|
||||
sx={{ width: "100%" }}
|
||||
value={formik.values.breedingUniqueId}
|
||||
error={
|
||||
formik.touched.breedingUniqueId
|
||||
? Boolean(formik.errors.breedingUniqueId)
|
||||
: null
|
||||
}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.breedingUniqueId &&
|
||||
Boolean(formik.errors.breedingUniqueId)
|
||||
? formik.errors.breedingUniqueId
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<TextField
|
||||
id="systemCode"
|
||||
label="کد سیستمی"
|
||||
variant="outlined"
|
||||
sx={{ width: "100%" }}
|
||||
value={formik.values.systemCode}
|
||||
error={
|
||||
formik.touched.systemCode
|
||||
? Boolean(formik.errors.systemCode)
|
||||
: null
|
||||
}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.systemCode && Boolean(formik.errors.systemCode)
|
||||
? formik.errors.systemCode
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<TextField
|
||||
id="epidemiologicalCode"
|
||||
label="کد اپیدمیولوژیک"
|
||||
variant="outlined"
|
||||
sx={{ width: "100%" }}
|
||||
value={formik.values.epidemiologicalCode}
|
||||
error={
|
||||
formik.touched.epidemiologicalCode
|
||||
? Boolean(formik.errors.epidemiologicalCode)
|
||||
: null
|
||||
}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.epidemiologicalCode &&
|
||||
Boolean(formik.errors.epidemiologicalCode)
|
||||
? formik.errors.epidemiologicalCode
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<TextField
|
||||
id="avicultureName"
|
||||
label="نام مرغداری"
|
||||
variant="outlined"
|
||||
sx={{ width: "100%" }}
|
||||
value={formik.values.avicultureName}
|
||||
error={
|
||||
formik.touched.avicultureName
|
||||
? Boolean(formik.errors.avicultureName)
|
||||
: null
|
||||
}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.avicultureName &&
|
||||
Boolean(formik.errors.avicultureName)
|
||||
? formik.errors.avicultureName
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<Autocomplete
|
||||
disablePortal
|
||||
id="province"
|
||||
options={
|
||||
provinceData
|
||||
? provinceData?.map((i) => ({ id: i.key, label: i.name }))
|
||||
: []
|
||||
}
|
||||
onChange={(event, value) => {
|
||||
setProvinceKey(value.id);
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField {...params} label="استان را انتخاب کنید" />
|
||||
)}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<Autocomplete
|
||||
disabled={isExistProvince}
|
||||
disablePortal
|
||||
id="city"
|
||||
options={
|
||||
cityData
|
||||
? cityData.map((i) => ({ id: i.key, label: i.name }))
|
||||
: []
|
||||
}
|
||||
onChange={(event, value) => {
|
||||
setCityKey(value.id);
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField {...params} label="شهر را انتخاب کنید" />
|
||||
)}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<TextField
|
||||
id="address"
|
||||
label="آدرس"
|
||||
variant="outlined"
|
||||
sx={{ width: "100%" }}
|
||||
value={formik.values.address}
|
||||
error={
|
||||
formik.touched.address ? Boolean(formik.errors.address) : null
|
||||
}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.address && Boolean(formik.errors.address)
|
||||
? formik.errors.address
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<TextField
|
||||
id="postal"
|
||||
label="کد پستی"
|
||||
variant="outlined"
|
||||
sx={{ width: "100%" }}
|
||||
value={formik.values.postal}
|
||||
error={formik.touched.postal ? Boolean(formik.errors.postal) : null}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.postal && Boolean(formik.errors.postal)
|
||||
? formik.errors.postal
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<TextField
|
||||
id="hall"
|
||||
label="تعداد سالن"
|
||||
variant="outlined"
|
||||
sx={{ width: "100%" }}
|
||||
value={formik.values.hall}
|
||||
error={formik.touched.postal ? Boolean(formik.errors.hall) : null}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.hall && Boolean(formik.errors.hall)
|
||||
? formik.errors.hall
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<Grid>
|
||||
<TextField
|
||||
id="totalCapacity"
|
||||
label="ظرفیت کل"
|
||||
variant="outlined"
|
||||
sx={{ width: "100%" }}
|
||||
value={formik.values.totalCapacity}
|
||||
error={
|
||||
formik.touched.totalCapacity
|
||||
? Boolean(formik.errors.totalCapacity)
|
||||
: null
|
||||
}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.totalCapacity &&
|
||||
Boolean(formik.errors.totalCapacity)
|
||||
? formik.errors.totalCapacity
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<TextField
|
||||
id="healthCertificateNumber"
|
||||
label="شماره گواهی بهداشتی"
|
||||
variant="outlined"
|
||||
sx={{ width: "100%" }}
|
||||
value={formik.values.healthCertificateNumber}
|
||||
error={
|
||||
formik.touched.healthCertificateNumber
|
||||
? Boolean(formik.errors.healthCertificateNumber)
|
||||
: null
|
||||
}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.healthCertificateNumber &&
|
||||
Boolean(formik.errors.healthCertificateNumber)
|
||||
? formik.errors.healthCertificateNumber
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<Divider>
|
||||
<Chip label="اطلاعات بانکی" />
|
||||
</Divider>
|
||||
<Grid>
|
||||
<TextField
|
||||
id="bankUser"
|
||||
label="نام صاحب حساب"
|
||||
variant="outlined"
|
||||
sx={{ width: "100%" }}
|
||||
value={formik.values.bankUser}
|
||||
error={
|
||||
formik.touched.bankUser ? Boolean(formik.errors.bankUser) : null
|
||||
}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.bankUser && Boolean(formik.errors.bankUser)
|
||||
? formik.errors.bankUser
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel id="demo-simple-select-label">بانک</InputLabel>
|
||||
<Select
|
||||
id="bankName"
|
||||
label="نام بانک"
|
||||
value={formik.values.bankName}
|
||||
error={
|
||||
formik.touched.bankName ? Boolean(formik.errors.bankName) : null
|
||||
}
|
||||
onChange={(e) => {
|
||||
formik.setFieldValue("bankName", e.target.value);
|
||||
}}
|
||||
onBlur={formik.handleBlur}
|
||||
>
|
||||
<MenuItem value={"موسسه افضل توس"}>موسسه افضل توس</MenuItem>
|
||||
<MenuItem value={"انصار"}>انصار</MenuItem>
|
||||
<MenuItem value={"سپه"}>سپه</MenuItem>
|
||||
<MenuItem value={"دی"}>دی</MenuItem>
|
||||
<MenuItem value={"کاب"}>اقتصاد نوین</MenuItem>
|
||||
<MenuItem value={"گردشگری"}>گردشگری</MenuItem>
|
||||
<MenuItem value={"حکمت ایرانیان"}>حکمت ایرانیان</MenuItem>
|
||||
<MenuItem value={"ایران زمین"}>ایران زمین</MenuItem>
|
||||
<MenuItem value={"کشاورزی"}>کشاورزی</MenuItem>
|
||||
<MenuItem value={"مسکن"}>مسکن</MenuItem>
|
||||
<MenuItem value={"مهر ایران"}>مهر ایران</MenuItem>
|
||||
<MenuItem value={"مهر اقتصاد"}>مهر اقتصاد</MenuItem>
|
||||
<MenuItem value={"ملت"}>ملت</MenuItem>
|
||||
<MenuItem value={"ملی"}>ملی</MenuItem>
|
||||
<MenuItem value={"پارسیان"}>پارسیان</MenuItem>
|
||||
<MenuItem value={"پاسارگاد"}>پاسارگاد</MenuItem>
|
||||
<MenuItem value={"پست بانک ایران"}>پست بانک ایران</MenuItem>
|
||||
<MenuItem value={"صادرات"}>صادرات</MenuItem>
|
||||
<MenuItem value={"سامان"}>سامان</MenuItem>
|
||||
<MenuItem value={"صنعت و معدن"}>صنعت و معدن</MenuItem>
|
||||
<MenuItem value={"سرمایه"}>سرمایه</MenuItem>
|
||||
<MenuItem value={"شهر"}>شهر</MenuItem>
|
||||
<MenuItem value={"سینا"}>سینا</MenuItem>
|
||||
<MenuItem value={"تجارت"}>تجارت</MenuItem>
|
||||
<MenuItem value={"موسسه اعتباری توسعه"}>
|
||||
موسسه اعتباری توسعه
|
||||
</MenuItem>
|
||||
<MenuItem value={"خاورمیانه"}>خاورمیانه</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<TextField
|
||||
id="card"
|
||||
label="شماره کارت"
|
||||
variant="outlined"
|
||||
sx={{ width: "100%" }}
|
||||
value={formik.values.card}
|
||||
error={formik.touched.card ? Boolean(formik.errors.card) : null}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.card && Boolean(formik.errors.card)
|
||||
? formik.errors.card
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<TextField
|
||||
id="account"
|
||||
label="شماره حساب"
|
||||
variant="outlined"
|
||||
sx={{ width: "100%" }}
|
||||
value={formik.values.account}
|
||||
error={
|
||||
formik.touched.account ? Boolean(formik.errors.account) : null
|
||||
}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.account && Boolean(formik.errors.account)
|
||||
? formik.errors.account
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<TextField
|
||||
id="shaba"
|
||||
label="شماره شبا"
|
||||
variant="outlined"
|
||||
sx={{ width: "100%" }}
|
||||
value={formik.values.shaba}
|
||||
error={formik.touched.shaba ? Boolean(formik.errors.shaba) : null}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.shaba && Boolean(formik.errors.shaba)
|
||||
? formik.errors.shaba
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid mb={SPACING.SMALL}>
|
||||
<Button
|
||||
fullWidth
|
||||
variant="contained"
|
||||
disabled={!formik.validateForm}
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
cityEditAvicultureInfo({
|
||||
poultry_key: item.key,
|
||||
breedingUniqueId: formik.values.breedingUniqueId
|
||||
? formik.values.breedingUniqueId
|
||||
: null,
|
||||
systemCode: formik.values.systemCode
|
||||
? formik.values.systemCode
|
||||
: null,
|
||||
epidemiologicalCode: formik.values.epidemiologicalCode
|
||||
? formik.values.epidemiologicalCode
|
||||
: null,
|
||||
totalCapacity: formik.values.totalCapacity
|
||||
? formik.values.totalCapacity
|
||||
: null,
|
||||
healthCertificateNumber: formik.values.healthCertificateNumber
|
||||
? formik.values.healthCertificateNumber
|
||||
: null,
|
||||
address: {
|
||||
province: provinceKey ? provinceKey : null,
|
||||
city: cityKey ? cityKey : null,
|
||||
address: formik.values.address
|
||||
? formik.values.address
|
||||
: null,
|
||||
postal_code: formik.values.postal
|
||||
? formik.values.postal
|
||||
: null,
|
||||
},
|
||||
user_bank_info: {
|
||||
name_of_bank_user: formik.values.bankUser
|
||||
? formik.values.bankUser
|
||||
: null,
|
||||
bank_name: formik.values.bankName
|
||||
? formik.values.bankName
|
||||
: null,
|
||||
card: formik.values.card ? formik.values.card : null,
|
||||
shaba: formik.values.shaba ? formik.values.shaba : null,
|
||||
account: formik.values.account
|
||||
? formik.values.account
|
||||
: null,
|
||||
},
|
||||
unit_name: formik.values.avicultureName
|
||||
? formik.values.avicultureName
|
||||
: null,
|
||||
hall: formik.values.hall ? formik.values.hall : null,
|
||||
})
|
||||
).then((r) => {
|
||||
if (r.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "مشکلی پیش آمده است.",
|
||||
severity: "error",
|
||||
});
|
||||
dispatch(LOADING_END());
|
||||
} else {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
}
|
||||
dispatch(cityGetPoultryFarm());
|
||||
dispatch(
|
||||
DRAWER({ right: false, bottom: false, content: null })
|
||||
);
|
||||
});
|
||||
}}
|
||||
>
|
||||
ثبت اطلاعات
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
CityEditAvicultureInfoForm.propTypes = {
|
||||
item: PropTypes.any,
|
||||
};
|
||||
@@ -0,0 +1,110 @@
|
||||
import { Button, IconButton, TextField, Tooltip } from "@mui/material";
|
||||
import EditIcon from "@mui/icons-material/Edit";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice";
|
||||
import { useContext, useState } from "react";
|
||||
import { cityEditHatchingQuantityService } from "../../services/city-edit-hatching-quantity";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
// import { cityGetHatchings } from "../../services/city-get-hatchings";
|
||||
// import { cityGetHatchingsByAge } from "../../services/city-get-hatchings-by-age";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
|
||||
export const CityEditHatchingQuantity = ({
|
||||
quantity,
|
||||
hatchingKey,
|
||||
selectedAge1,
|
||||
selectedAge2,
|
||||
updateTable,
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
return (
|
||||
<Tooltip title={"ویرایش تعداد جوجه ریزی"} placement="left-start">
|
||||
<IconButton
|
||||
size="small"
|
||||
color="primary"
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "ویرایش تعداد جوجه ریزی",
|
||||
content: (
|
||||
<ModalContent
|
||||
selectedAge1={selectedAge1}
|
||||
selectedAge2={selectedAge2}
|
||||
quantity={quantity}
|
||||
hatchingKey={hatchingKey}
|
||||
updateTable={updateTable}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
<EditIcon fontSize="10" />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
const ModalContent = ({
|
||||
quantity,
|
||||
hatchingKey,
|
||||
selectedAge1,
|
||||
selectedAge2,
|
||||
updateTable,
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
const [openNotif] = useContext(AppContext);
|
||||
const [value, setValue] = useState(quantity);
|
||||
|
||||
const handleChange = (event) => {
|
||||
setValue(event.target.value);
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<TextField
|
||||
label="تعداد"
|
||||
type="number"
|
||||
variant="outlined"
|
||||
value={value}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
<Button
|
||||
disabled={!value}
|
||||
fullWidth
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
cityEditHatchingQuantityService({
|
||||
key: hatchingKey,
|
||||
quantity: Number(value),
|
||||
role: getRoleFromUrl(),
|
||||
})
|
||||
).then((r) => {
|
||||
if (r.payload.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.error,
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
// dispatch(cityGetHatchingsByAge({ selectedAge1, selectedAge2 }));
|
||||
// dispatch(cityGetHatchings({ selectedDate1, selectedDate2 }));
|
||||
updateTable();
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
dispatch(CLOSE_MODAL());
|
||||
}
|
||||
});
|
||||
}}
|
||||
>
|
||||
ثبت
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,291 @@
|
||||
import React, { useContext, useEffect } from "react";
|
||||
import {
|
||||
Button,
|
||||
TextField,
|
||||
Tooltip,
|
||||
Typography,
|
||||
Box,
|
||||
Divider,
|
||||
Chip,
|
||||
} from "@mui/material";
|
||||
import { DatePicker } from "@mui/x-date-pickers";
|
||||
import moment from "moment";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { cityGetHatchingInfo } from "../../services/city-get-hatching-info";
|
||||
import { cityGetHatchingInfoFull } from "../../services/city-get-hatching-info-full";
|
||||
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { RiFileExcel2Fill } from "react-icons/ri";
|
||||
import { useFormik } from "formik";
|
||||
import axios from "axios";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
|
||||
export const CityHatchingInfo = () => {
|
||||
const { hatchingInfoWithDate, hatchingInfoFull } = useSelector(
|
||||
(state) => state.citySlice
|
||||
);
|
||||
const dispatch = useDispatch();
|
||||
const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] =
|
||||
useContext(AppContext);
|
||||
|
||||
useEffect(() => {
|
||||
const currentDate = moment(new Date()).format("YYYY-MM-DD");
|
||||
setSelectedDate1(currentDate);
|
||||
setSelectedDate2(currentDate);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(cityGetHatchingInfoFull());
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(cityGetHatchingInfo({ selectedDate1, selectedDate2 }));
|
||||
}, [selectedDate1, selectedDate2]);
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues: {
|
||||
minAge: "",
|
||||
maxAge: "",
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<Box bgcolor="#f9f9f9" borderRadius={2} boxShadow={3}>
|
||||
<Divider style={{ width: "100%" }}>
|
||||
<Chip
|
||||
label={
|
||||
<Typography
|
||||
variant="body1"
|
||||
gutterBottom
|
||||
color="primary"
|
||||
fontWeight="bold"
|
||||
>
|
||||
اطلاعات جوجه ریزی
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
</Divider>
|
||||
|
||||
<Grid container spacing={3} m={0} pb={2}>
|
||||
{/* Full Summary Table */}
|
||||
<Grid item xs={12}>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
title="آمار جوجه ریزی"
|
||||
columns={[
|
||||
"تعداد فارم",
|
||||
"تعداد کل جوجه ریزی",
|
||||
"تعداد باقی مانده در سالن",
|
||||
"تعداد کشتار شده",
|
||||
"وزن کشتار شده",
|
||||
"مانده سالن (20 تا 30 روزه)",
|
||||
"مانده سالن (30 تا 40 روزه)",
|
||||
"مانده سالن (40 تا 50 روزه)",
|
||||
"مانده سالن (50 تا 60 روزه)",
|
||||
"بیشتر از 60 روزه",
|
||||
]}
|
||||
data={[
|
||||
[
|
||||
hatchingInfoFull?.poultries?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingQuantity?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingLeftOverQuantity?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingKilledQuantity?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingKilledWeight?.toLocaleString(),
|
||||
hatchingInfoFull?.age2030?.toLocaleString(),
|
||||
hatchingInfoFull?.age3040?.toLocaleString(),
|
||||
hatchingInfoFull?.age4050?.toLocaleString(),
|
||||
hatchingInfoFull?.age5060?.toLocaleString(),
|
||||
hatchingInfoFull?.ageMoreThan60?.toLocaleString(),
|
||||
],
|
||||
]}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<Divider style={{ width: "100%", marginTop: 8 }}>
|
||||
<Chip
|
||||
label={
|
||||
<Typography
|
||||
variant="body1"
|
||||
color="primary"
|
||||
gutterBottom
|
||||
fontWeight="medium"
|
||||
>
|
||||
بر اساس بازه
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
</Divider>
|
||||
|
||||
<Grid item xs={12} mt={2}>
|
||||
<Grid container alignItems="center" spacing={2}>
|
||||
<Grid item>
|
||||
<DatePicker
|
||||
label="از تاریخ"
|
||||
renderInput={(params) => (
|
||||
<TextField {...params} size="small" fullWidth />
|
||||
)}
|
||||
value={selectedDate1}
|
||||
onChange={(e) =>
|
||||
setSelectedDate1(moment(e).format("YYYY-MM-DD"))
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<DatePicker
|
||||
label="تا تاریخ"
|
||||
renderInput={(params) => (
|
||||
<TextField {...params} size="small" fullWidth />
|
||||
)}
|
||||
value={selectedDate2}
|
||||
onChange={(e) =>
|
||||
setSelectedDate2(moment(e).format("YYYY-MM-DD"))
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Tooltip title="خروجی اکسل">
|
||||
<a
|
||||
href={`${axios.defaults.baseURL}hatching_date_range_excel/?date1=${selectedDate1}&date2=${selectedDate2}`}
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Button variant="contained" color="success">
|
||||
<RiFileExcel2Fill size={24} />
|
||||
</Button>
|
||||
</a>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={12}>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
title="خلاصه آمار"
|
||||
columns={[
|
||||
"تعداد فارم های فعال",
|
||||
"تعداد کل جوجه ریزی",
|
||||
"تعداد باقی مانده در سالن",
|
||||
"تعداد کشتار شده",
|
||||
"وزن کشتار شده",
|
||||
]}
|
||||
data={[
|
||||
[
|
||||
hatchingInfoWithDate?.poultries?.toLocaleString(),
|
||||
hatchingInfoWithDate?.totalHatchingQuantity?.toLocaleString(),
|
||||
hatchingInfoWithDate?.totalHatchingLeftOverQuantity?.toLocaleString(),
|
||||
hatchingInfoWithDate?.totalHatchingKilledQuantity?.toLocaleString(),
|
||||
hatchingInfoWithDate?.totalHatchingKilledWeight?.toLocaleString(),
|
||||
],
|
||||
]}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<Divider
|
||||
style={{
|
||||
width: "100%",
|
||||
marginTop: 8,
|
||||
}}
|
||||
sx={{
|
||||
display: { xs: "none", sm: "block" },
|
||||
}}
|
||||
>
|
||||
<Chip
|
||||
label={
|
||||
<Typography
|
||||
variant="body1"
|
||||
color="primary"
|
||||
gutterBottom
|
||||
fontWeight="medium"
|
||||
mx="auto"
|
||||
>
|
||||
گزارش مانده سالن فارم های بیشتر از 10 درصد
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
</Divider>
|
||||
<Typography
|
||||
variant="body1"
|
||||
backgroundColor="rgba(0, 0, 0, 0.08)"
|
||||
color="primary"
|
||||
gutterBottom
|
||||
fontWeight="medium"
|
||||
mt={4}
|
||||
mx="auto"
|
||||
sx={{
|
||||
display: { xs: "block", sm: "none" },
|
||||
borderRadius: 2,
|
||||
}}
|
||||
width={{
|
||||
xs: "80%",
|
||||
sm: "auto",
|
||||
}}
|
||||
>
|
||||
گزارش مانده سالن فارم های بیشتر از 10 درصد
|
||||
</Typography>
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
container
|
||||
justifyContent="center"
|
||||
gap={2}
|
||||
alignItems="center"
|
||||
mt={4}
|
||||
px={1}
|
||||
>
|
||||
<Grid
|
||||
container
|
||||
sx={{
|
||||
gap: 2,
|
||||
}}
|
||||
alignItems="center"
|
||||
>
|
||||
<Grid
|
||||
item
|
||||
sx={{
|
||||
maxWidth: { xs: "46%", sm: "100px" },
|
||||
}}
|
||||
>
|
||||
<TextField
|
||||
id="minAge"
|
||||
label="از سن"
|
||||
variant="outlined"
|
||||
size="small"
|
||||
value={formik.values.minAge}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid
|
||||
item
|
||||
sx={{
|
||||
maxWidth: { xs: "46%", sm: "100px" },
|
||||
}}
|
||||
>
|
||||
<TextField
|
||||
id="maxAge"
|
||||
label="تا سن"
|
||||
variant="outlined"
|
||||
size="small"
|
||||
value={formik.values.maxAge}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Tooltip title="خروجی اکسل">
|
||||
<a
|
||||
href={`${axios.defaults.baseURL}hatching_by_age_range/?min_age=${formik.values.minAge}&max_age=${formik.values.maxAge}`}
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Button variant="contained" color="success">
|
||||
<RiFileExcel2Fill size={24} />
|
||||
</Button>
|
||||
</a>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { Button } from "@mui/material";
|
||||
import { NavLink } from "../../../../components/nav-link/NavLink";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import {
|
||||
ROUTE_CITY_HATCHING,
|
||||
ROUTE_CITY_NEW_REQUEST,
|
||||
} from "../../../../routes/routes";
|
||||
|
||||
export const CityHatchingOperations = () => {
|
||||
const { pathname } = useLocation();
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
gap={SPACING.SMALL}
|
||||
p={SPACING.SMALL}
|
||||
direction={{ xs: "column", md: "row" }}
|
||||
>
|
||||
<NavLink
|
||||
to={ROUTE_CITY_HATCHING}
|
||||
active={pathname === ROUTE_CITY_HATCHING ? "true" : null}
|
||||
>
|
||||
<Button variant="text" color="inherit">
|
||||
ثبت اطلاعات جوجه ریزی
|
||||
</Button>
|
||||
</NavLink>
|
||||
<NavLink
|
||||
to={ROUTE_CITY_NEW_REQUEST}
|
||||
active={pathname === ROUTE_CITY_NEW_REQUEST ? "true" : null}
|
||||
>
|
||||
<Button variant="text" color="inherit">
|
||||
ثبت درخواست کشتار
|
||||
</Button>
|
||||
</NavLink>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,691 @@
|
||||
import {
|
||||
Button,
|
||||
IconButton,
|
||||
TextField,
|
||||
Tooltip,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import axios from "axios";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { formatTime, formatJustDate } from "../../../../utils/formatTime";
|
||||
import { getFaUserRole } from "../../../../utils/getFaUserRole";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import { CityManageHatchingsArchiveActions } from "../city-manage-hatchings-operations/CityManageHatchingsOperations";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { cityGetHatchingInfoFull } from "../../services/city-get-hatching-info-full";
|
||||
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
|
||||
import {
|
||||
// DRAWER,
|
||||
LOADING_END,
|
||||
LOADING_START,
|
||||
OPEN_MODAL,
|
||||
} from "../../../../lib/redux/slices/appSlice";
|
||||
import { SimpleTable } from "../../../../components/simple-table/SimpleTable";
|
||||
import ShowImage from "../../../../components/show-image/ShowImage";
|
||||
import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye";
|
||||
import ArticleIcon from "@mui/icons-material/Article";
|
||||
import {
|
||||
ROUTE_ADMINXـHATCHINGS,
|
||||
ROUTE_CITY_JIHADـHATCHINGS,
|
||||
ROUTE_CITY_POULTRYـHATCHINGS,
|
||||
ROUTE_PROVINCE_SUPERVISORـHATCHINGS,
|
||||
ROUTE_PROVINCEـHATCHINGS,
|
||||
ROUTE_SUPER_ADMINـHATCHINGS,
|
||||
ROUTE_SUPPORTERـHATCHINGS,
|
||||
} from "../../../../routes/routes";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
// import { CityHatchingShowTableDetail } from "../city-hatching-show-table-detail/CityHatchingShowTableDetail";
|
||||
|
||||
export const CityHatchingUnassigned = ({ readOnly }) => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const isReadOnly = readOnly || false;
|
||||
const [selectedAge1, setSelectedAge1] = useState(0);
|
||||
const [selectedAge2, setSelectedAge2] = useState(0);
|
||||
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 userKey = useSelector((state) => state.userSlice.userProfile.key);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [openNotif] = useContext(AppContext);
|
||||
|
||||
const handleTextChange = (event) => {
|
||||
setTextValue(event.target.value);
|
||||
};
|
||||
|
||||
const hatchingAdded = useSelector((state) => state.citySlice.hatchingAdded);
|
||||
|
||||
useEffect(() => {
|
||||
fetchApiData();
|
||||
}, [hatchingAdded]);
|
||||
|
||||
const fetchApiData = async (pageParam = page, perPageParam = perPage) => {
|
||||
dispatch(LOADING_START());
|
||||
const response = await axios.get("poultry_hatching/", {
|
||||
params: {
|
||||
unknown: true,
|
||||
search: "filter",
|
||||
value: textValue,
|
||||
role: getRoleFromUrl(),
|
||||
page: pageParam,
|
||||
page_size: perPageParam,
|
||||
age1: selectedAge1 || 0,
|
||||
age2: selectedAge2 || 0,
|
||||
},
|
||||
});
|
||||
dispatch(LOADING_END());
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
};
|
||||
|
||||
const handlePageChange = (page) => {
|
||||
setPage(page);
|
||||
fetchApiData(page, perPage);
|
||||
};
|
||||
|
||||
const handlePerRowsChange = (perRows) => {
|
||||
setPerPage(perRows);
|
||||
setPage(1);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchApiData();
|
||||
}, [perPage]);
|
||||
|
||||
const updateTable = () => {
|
||||
fetchApiData();
|
||||
};
|
||||
|
||||
// const killedNumber = (item) => {
|
||||
// let killedNumber = "";
|
||||
// killedNumber = item.quantity - item.losses - item.leftOver;
|
||||
// return killedNumber;
|
||||
// };
|
||||
|
||||
useEffect(() => {
|
||||
const d = data?.map((item, i) => {
|
||||
return [
|
||||
<CityManageHatchingsArchiveActions
|
||||
selectedAge1={null}
|
||||
selectedAge2={null}
|
||||
updateTable={updateTable}
|
||||
item={item}
|
||||
key={"archive-actions"}
|
||||
readOnly={isReadOnly}
|
||||
/>,
|
||||
<Tooltip placement="left" title="جزئیات جوجه ریزی" key={item?.key}>
|
||||
<IconButton
|
||||
color="primary"
|
||||
onClick={() => {
|
||||
navigate(
|
||||
getRoleFromUrl() === "AdminX"
|
||||
? `${ROUTE_ADMINXـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "Supporter"
|
||||
? `${ROUTE_SUPPORTERـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "SuperAdmin"
|
||||
? `${ROUTE_SUPER_ADMINـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "CityPoultry"
|
||||
? `${ROUTE_CITY_POULTRYـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "ProvinceSupervisor"
|
||||
? `${ROUTE_PROVINCE_SUPERVISORـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "ProvinceOperator"
|
||||
? `${ROUTE_PROVINCEـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "CityJahad"
|
||||
? `${ROUTE_CITY_JIHADـHATCHINGS}/${item.key}`
|
||||
: ""
|
||||
);
|
||||
}}
|
||||
>
|
||||
<RemoveRedEyeIcon />
|
||||
</IconButton>
|
||||
</Tooltip>,
|
||||
page === 1 ? i + 1 : i + perPage * (page - 1) + 1,
|
||||
<Tooltip
|
||||
disableHoverListener={
|
||||
!(item?.killingInfo?.violationMessage && item?.violation)
|
||||
}
|
||||
key={item?.key}
|
||||
title={
|
||||
item?.violation
|
||||
? `متن گزارش تخلف: ${item?.killingInfo?.violationMessage}`
|
||||
: null
|
||||
}
|
||||
sx={{
|
||||
"&:hover": {
|
||||
cursor: item?.violation ? "pointer" : "default",
|
||||
},
|
||||
}}
|
||||
placement="top"
|
||||
>
|
||||
<Typography
|
||||
variant="body2"
|
||||
color={item?.violation ? "error" : "primary"}
|
||||
>
|
||||
{item?.violation ? "پیگیری" : "عادی"}
|
||||
</Typography>
|
||||
</Tooltip>,
|
||||
item?.licenceNumber,
|
||||
item?.poultry?.breedingUniqueId,
|
||||
item?.CertId,
|
||||
// item?.commitmentType === "free" ? "آزاد" : "دولتی",
|
||||
item?.poultry?.unitName || "-",
|
||||
`${item?.poultry?.userprofile?.fullName ?? "-"} (${
|
||||
item?.poultry?.userprofile?.mobile ?? "-"
|
||||
}) ${item?.violationReport ? "✉️" : ""}`,
|
||||
item?.InteractTypeName ? (
|
||||
<Typography
|
||||
variant="body2"
|
||||
color={item?.hasTenant ? "success.main" : ""}
|
||||
fontWeight={item?.hasTenant ? "bold" : "normal"}
|
||||
>
|
||||
{item?.InteractTypeName}
|
||||
</Typography>
|
||||
) : (
|
||||
"-"
|
||||
),
|
||||
item?.PersonTypeName,
|
||||
item?.UnionTypeName,
|
||||
`${item?.poultry?.address?.city?.name ?? "-"}/${
|
||||
item?.poultry?.cityOperator
|
||||
? item?.poultry?.cityOperator
|
||||
: "بدون تعاونی"
|
||||
}`,
|
||||
item?.vetFarm?.vetFarmMobile
|
||||
? `${item?.vetFarm?.vetFarmFullName} (${item?.vetFarm?.vetFarmMobile})`
|
||||
: "-",
|
||||
item.hall,
|
||||
item.period,
|
||||
formatTime(item?.createDate),
|
||||
formatTime(item?.date),
|
||||
item?.poultry?.killingAveAge?.toLocaleString(),
|
||||
item?.predicateDate ? formatJustDate(item?.predicateDate) : "-",
|
||||
item.chickenBreed,
|
||||
item.age,
|
||||
item?.quantity?.toLocaleString(),
|
||||
item?.increaseQuantity?.toLocaleString(),
|
||||
`${item.losses} (%${((item.losses * 100) / item.quantity).toFixed(0)})`,
|
||||
<Tooltip
|
||||
key={item?.key}
|
||||
placement="top"
|
||||
title="جهت مشاهده ثبت کننده تلفات کلیک کنید"
|
||||
>
|
||||
<Button
|
||||
// variant="outlined"
|
||||
style={{ color: "rgba(0,0,0,0.87)" }}
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "ویرایش تعداد جوجه ریزی",
|
||||
content: (
|
||||
<Grid container xs={12}>
|
||||
{!item?.directLossesInputer &&
|
||||
!item?.directLossesInputer ? (
|
||||
<Typography variant="body1">
|
||||
برای این جوجه ریزی تلفاتی ثبت نشده است.
|
||||
</Typography>
|
||||
) : (
|
||||
<Grid xs={12}>
|
||||
<Typography variant="body1">
|
||||
ثبت کننده تلفات اتحادیه:{" "}
|
||||
{item?.directLossesInputer
|
||||
? `${
|
||||
item?.directLossesInputer
|
||||
} در تاریخ ${formatJustDate(
|
||||
item?.directLossesDate
|
||||
)}`
|
||||
: " - "}
|
||||
</Typography>
|
||||
<Typography variant="body1">
|
||||
ویرایش کننده تلفات اتحادیه:
|
||||
{item?.directLossesEditor
|
||||
? `${
|
||||
item?.directLossesEditor
|
||||
} در تاریخ ${formatJustDate(
|
||||
item?.directLossesLastEditDate
|
||||
)}`
|
||||
: " - "}
|
||||
</Typography>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
),
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
{`${item?.directLosses?.toLocaleString()} (%${(
|
||||
(item.directLosses * 100) /
|
||||
item.quantity
|
||||
).toFixed(0)})`}
|
||||
</Button>
|
||||
</Tooltip>,
|
||||
`${item?.totalLosses?.toLocaleString()} (%${(
|
||||
(item.totalLosses * 100) /
|
||||
item.quantity
|
||||
).toFixed(0)})`,
|
||||
`${item?.totalCommitmentQuantity?.toLocaleString()}`,
|
||||
`${item?.totalFreeCommitmentQuantity?.toLocaleString()}`,
|
||||
`${item?.governmentalQuantity?.toLocaleString()}`,
|
||||
`${item?.governmentalKilledQuantity?.toLocaleString()}`,
|
||||
`${item?.freeQuantity?.toLocaleString()}`,
|
||||
`${item?.freeKilledQuantity?.toLocaleString()}`,
|
||||
`${item?.outProvinceKilledQuantity?.toLocaleString()}`,
|
||||
`${item?.outProvinceKilledWeight?.toLocaleString()}`,
|
||||
`${item?.barDifferenceRequestQuantity?.toLocaleString()}`,
|
||||
`${item?.barDifferenceRequestWeight?.toLocaleString()}`,
|
||||
`${item?.killingInfo?.provinceKillRequests?.toLocaleString()}`,
|
||||
`${item?.killingInfo?.provinceKillRequestsQuantity?.toLocaleString()}`,
|
||||
`${item?.killingInfo?.provinceKillRequestsWeight?.toLocaleString()}`,
|
||||
item?.killedQuantity?.toLocaleString() +
|
||||
` (%${((item?.killedQuantity * 100) / item.quantity).toFixed(0)})`,
|
||||
item?.leftOver?.toLocaleString(),
|
||||
`%${((item?.leftOver * 100) / item?.quantity).toFixed(0)}`,
|
||||
// item?.totalCommitment?.toLocaleString(),
|
||||
|
||||
`%${((item.totalLosses * 100) / item.quantity).toFixed(0)}`,
|
||||
`%${((item?.killedQuantity * 100) / item.quantity).toFixed(0)}`,
|
||||
`%${((item?.leftOver * 100) / item?.quantity).toFixed(0)}`,
|
||||
`%${(
|
||||
((item?.killedQuantity + item?.totalLosses) * 100) /
|
||||
item?.quantity
|
||||
).toFixed(0)}`,
|
||||
|
||||
item?.samasatDischargePercentage
|
||||
? `%${item?.samasatDischargePercentage}`
|
||||
: "-",
|
||||
item?.totalCommitment?.toLocaleString(),
|
||||
item?.governmentalKilledQuantity?.toLocaleString(),
|
||||
item?.freeKilledQuantity?.toLocaleString(),
|
||||
item?.totalAverageKilledWeight?.toLocaleString(),
|
||||
item?.totalKilledWeight?.toLocaleString(),
|
||||
item?.activeKill?.activeKill ? "دارد" : "ندارد",
|
||||
item?.activeKill?.countOfRequest ? item.activeKill.countOfRequest : "-",
|
||||
item?.killingInfo?.killHouseRequests?.toLocaleString(),
|
||||
item?.killingInfo?.killHouseRequestsFirstQuantity?.toLocaleString(),
|
||||
item?.killingInfo?.killHouseRequestsFirstWeight?.toLocaleString(),
|
||||
item?.killingInfo?.barCompleteWithKillHouse?.toLocaleString(),
|
||||
item?.killingInfo?.acceptedRealWightFinal?.toLocaleString(),
|
||||
item?.chainKilledQuantity?.toLocaleString(),
|
||||
item?.chainKilledWeight?.toLocaleString(),
|
||||
item?.exportKilledQuantity?.toLocaleString(),
|
||||
item?.exportKilledWeight?.toLocaleString(),
|
||||
item?.killingInfo?.wareHouseBars?.toLocaleString(),
|
||||
item?.killingInfo?.wareHouseBarsQuantity?.toLocaleString(),
|
||||
item?.killingInfo?.wareHouseBarsWeight?.toLocaleString(),
|
||||
item?.killingInfo?.wareHouseBarsWeightLose?.toFixed(2),
|
||||
item.lastChange
|
||||
? `${item.lastChange.fullName} (${getFaUserRole(
|
||||
item.lastChange.role
|
||||
)}) در تاریخ ${formatTime(item.lastChange.date)}`
|
||||
: "-",
|
||||
item.latestHatchingChange
|
||||
? `${item.latestHatchingChange.fullName} (${getFaUserRole(
|
||||
item.latestHatchingChange.role
|
||||
)}) در تاریخ ${formatTime(item.latestHatchingChange.date)}`
|
||||
: "-",
|
||||
item?.violationReport ? (
|
||||
<Tooltip title="مشاهده گزارش" placement="top" key={item?.key}>
|
||||
<IconButton
|
||||
color="primary"
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "گزارش ",
|
||||
content: (
|
||||
<SimpleTable
|
||||
columns={[
|
||||
"ثبت کننده",
|
||||
"تاریخ ثبت",
|
||||
"تخلف",
|
||||
"متن گزارش",
|
||||
"سند",
|
||||
]}
|
||||
data={[
|
||||
[
|
||||
item?.violationReporter,
|
||||
formatJustDate(item?.violationReportDate),
|
||||
item?.violation ? "دارد" : "ندارد",
|
||||
item?.violationReport,
|
||||
<Grid
|
||||
key={item?.key}
|
||||
container
|
||||
xs={12}
|
||||
justifyContent="center"
|
||||
gap={1}
|
||||
>
|
||||
{item?.violationImage?.map((option, index) => (
|
||||
<ShowImage
|
||||
key={`${option}-${index}`}
|
||||
src={option}
|
||||
/>
|
||||
))}
|
||||
</Grid>,
|
||||
],
|
||||
]}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
<ArticleIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
) : (
|
||||
"-"
|
||||
),
|
||||
];
|
||||
});
|
||||
|
||||
setTableData(d);
|
||||
}, [data]);
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
dispatch(LOADING_START());
|
||||
dispatch(
|
||||
cityGetHatchingInfoFull({
|
||||
age1: selectedAge1,
|
||||
age2: selectedAge2,
|
||||
tab: "unknown",
|
||||
textValue: textValue,
|
||||
})
|
||||
);
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`poultry_hatching/?role=${getRoleFromUrl()}&age1=${
|
||||
selectedAge1 ? selectedAge1 : 0
|
||||
}&age2=${
|
||||
selectedAge2 ? selectedAge2 : 0
|
||||
}&search=filter&value=${textValue}&page=${1}&page_size=${perPage}&unknown=true`
|
||||
);
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
dispatch(LOADING_END());
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleRemoveFilter = async (event) => {
|
||||
event.preventDefault();
|
||||
setSelectedAge1(0);
|
||||
setSelectedAge2(0);
|
||||
dispatch(LOADING_START());
|
||||
setTextValue("");
|
||||
dispatch(
|
||||
cityGetHatchingInfoFull({
|
||||
age1: 0,
|
||||
age2: 0,
|
||||
tab: "unknown",
|
||||
textValue: textValue,
|
||||
})
|
||||
);
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`poultry_hatching?role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&search=filter&value=${textValue}&unknown=true`
|
||||
);
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
} finally {
|
||||
dispatch(LOADING_END());
|
||||
}
|
||||
};
|
||||
|
||||
const [lastUpdateData, setLastUpdateData] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchData() {
|
||||
try {
|
||||
const response = await axios.get(`last_update/?type=poultry_hatching`);
|
||||
setLastUpdateData(response.data);
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
}
|
||||
}
|
||||
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
const tableTitle = (
|
||||
<Grid
|
||||
container
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
gap={2}
|
||||
paddingTop={2}
|
||||
mb={1}
|
||||
xs={12}
|
||||
mt={2}
|
||||
>
|
||||
<form onSubmit={handleSubmit} style={{ flex: 1 }}>
|
||||
<Grid container alignItems="center" gap={SPACING.SMALL}>
|
||||
<Grid sx={{ width: { xs: "72px", sm: "80px" } }}>
|
||||
<TextField
|
||||
size="small"
|
||||
label="از سن"
|
||||
id="outlined-controlled"
|
||||
value={selectedAge1}
|
||||
onChange={(event) => {
|
||||
setSelectedAge1(event.target.value);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid sx={{ width: { xs: "72px", sm: "80px" } }}>
|
||||
<TextField
|
||||
size="small"
|
||||
label="تا سن"
|
||||
id="outlined-controlled"
|
||||
value={selectedAge2}
|
||||
onChange={(event) => {
|
||||
setSelectedAge2(event.target.value);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<TextField
|
||||
id="outlined-basic"
|
||||
size="small"
|
||||
label="جستجو"
|
||||
variant="outlined"
|
||||
sx={{ maxWidth: { xs: "100%", sm: 250 } }}
|
||||
value={textValue}
|
||||
onChange={handleTextChange}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter") {
|
||||
handleSubmit(e);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
<Button type="submit" endIcon={<RiSearchLine />}>
|
||||
جستجو
|
||||
</Button>
|
||||
<Tooltip title="خروجی اکسل" px={0}>
|
||||
<Button
|
||||
color="success"
|
||||
onClick={() => {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "فایل اکسل در حال دانلود می باشد، این علمیات ممکن است زمان بر باشد لطفا صبر کنید.",
|
||||
severity: "success",
|
||||
});
|
||||
const link = `${
|
||||
axios.defaults.baseURL
|
||||
}0/hatching_excel/?unknown=true&role=${getRoleFromUrl()}&key=${userKey}&age1=${
|
||||
selectedAge1 ? selectedAge1 : 0
|
||||
}&age2=${
|
||||
selectedAge2 ? selectedAge2 : 0
|
||||
}&search=filter&value=${textValue}`;
|
||||
window.location.href = link;
|
||||
}}
|
||||
>
|
||||
<RiFileExcel2Fill size={32} />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
</form>
|
||||
<Button onClick={handleRemoveFilter} color="error">
|
||||
حذف فیلتر
|
||||
</Button>
|
||||
</Grid>
|
||||
);
|
||||
const { hatchingInfoFull } = useSelector((state) => state.citySlice);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
cityGetHatchingInfoFull({
|
||||
age1: selectedAge1,
|
||||
age2: selectedAge2,
|
||||
tab: "unknown",
|
||||
textValue: textValue,
|
||||
})
|
||||
);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Grid alignItems="center" justifyContent="center" mt={2} xs={12}>
|
||||
<Grid alignItems="center" justifyContent="center" isDashboard xs={12}>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
title={
|
||||
lastUpdateData &&
|
||||
`آخرین بروزرسانی : ${formatTime(lastUpdateData)} ${" "}`
|
||||
}
|
||||
columns={[
|
||||
"تعداد فارم",
|
||||
"تعداد جوجه ریزی",
|
||||
"حجم کل جوجه ریزی",
|
||||
"حجم باقی مانده در سالن",
|
||||
"حجم کشتار شده",
|
||||
"وزن کشتار شده",
|
||||
"حجم کل تلفات",
|
||||
"حجم تلفات اتحادیه",
|
||||
"حجم تلفات دامپزشک",
|
||||
"مانده سالن ( 20 تا 30 روزه)",
|
||||
"مانده سالن ( 30 تا 40 روزه)",
|
||||
"مانده سالن ( 40 تا 50 روزه)",
|
||||
"مانده سالن ( 50 تا 60 روزه)",
|
||||
"بیشتر از 60 روزه",
|
||||
]}
|
||||
data={[
|
||||
[
|
||||
hatchingInfoFull?.poultries?.toLocaleString(),
|
||||
hatchingInfoFull?.hatchings?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingQuantity?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingLeftOverQuantity?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingKilledQuantity?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingKilledWeight?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingAllLosses?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingUnionLosses?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingVetLosses?.toLocaleString(),
|
||||
hatchingInfoFull?.age2030?.toLocaleString(),
|
||||
hatchingInfoFull?.age3040?.toLocaleString(),
|
||||
hatchingInfoFull?.age4050?.toLocaleString(),
|
||||
hatchingInfoFull?.age5060?.toLocaleString(),
|
||||
hatchingInfoFull?.ageMoreThan60?.toLocaleString(),
|
||||
],
|
||||
]}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
{tableTitle}
|
||||
|
||||
<ResponsiveTable
|
||||
data={tableData}
|
||||
columns={[
|
||||
"عملیات",
|
||||
"جزئیات",
|
||||
"ردیف",
|
||||
"وضعیت",
|
||||
"شماره مجوز جوجه ریزی",
|
||||
"شناسه یکتا",
|
||||
"مجوز بهداشتی جوجه ریزی",
|
||||
// "نوع تعهد",
|
||||
"نام فارم",
|
||||
"مرغدار",
|
||||
"بهره برداری",
|
||||
"مالکیت",
|
||||
"ارتباط",
|
||||
"شهر/تعاونی",
|
||||
"دامپزشک فارم",
|
||||
"سالن",
|
||||
"دوره جوجه ریزی",
|
||||
"تاریخ ثبت جوجه ریزی",
|
||||
"تاریخ جوجه ریزی",
|
||||
"میانگین سن کشتار",
|
||||
"پیش بینی تاریخ کشتار",
|
||||
"نژاد",
|
||||
"سن",
|
||||
"حجم جوجه ریزی",
|
||||
"حجم افزایشی",
|
||||
"تلفات دامپزشک",
|
||||
"تلفات اتحادیه",
|
||||
"تلفات کل",
|
||||
"حجم تعهد دولتی",
|
||||
"حجم تعهد آزاد",
|
||||
"حجم کشتار دولتی",
|
||||
"وزن کشتار دولتی",
|
||||
"حجم کشتار آزاد",
|
||||
"وزن کشتار شده آزاد",
|
||||
"حجم فروش به خارج استان",
|
||||
"وزن فروش به خارج استان",
|
||||
"حجم اختلاف کشتار",
|
||||
"وزن اختلاف کشتار",
|
||||
"تخصیصات بدون بار",
|
||||
"حجم تخصیصات بدون بار",
|
||||
"وزن تخصیصات بدون بار",
|
||||
"حجم کشتار شده",
|
||||
"حجم مانده در سالن",
|
||||
" درصد مانده در سالن",
|
||||
" تلفات",
|
||||
" کشتار شده",
|
||||
" باقی مانده در سالن",
|
||||
"تایید تخلیه رصدیار",
|
||||
" تایید تخلیه در سماصط",
|
||||
"وزن تعهد دولتی",
|
||||
"وزن کشتار دولتی",
|
||||
"وزن کشتار آزاد",
|
||||
"میانگین وزن کشتار",
|
||||
"وزن کل کشتار شده",
|
||||
"تعداد کشتار فعال",
|
||||
"تعداد درخواست کشتار",
|
||||
"تعداد بارها",
|
||||
"حجم بارها",
|
||||
"وزن بارها",
|
||||
"حجم بارهای تحویلی",
|
||||
"وزن بارهای تحویلی",
|
||||
"حجم زنجیره",
|
||||
"وزن زنجیره",
|
||||
"حجم صادرات",
|
||||
"وزن صادرات",
|
||||
"بارهای ورودی به انبار",
|
||||
"حجم لاشه های انبار",
|
||||
"وزن لاشه های انبار",
|
||||
"درصد افت بارها",
|
||||
"آخرین تغییر",
|
||||
"سازنده جوجه ریزی",
|
||||
"گزارش",
|
||||
]}
|
||||
handlePageChange={handlePageChange}
|
||||
totalRows={totalRows}
|
||||
page={page}
|
||||
perPage={perPage}
|
||||
handlePerRowsChange={handlePerRowsChange}
|
||||
title="تعیین تکلیف نشدهها"
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,251 @@
|
||||
import {
|
||||
IconButton,
|
||||
Popover,
|
||||
List,
|
||||
ListItemButton,
|
||||
ListItemIcon,
|
||||
ListItemText,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import { useContext, useState } from "react";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import TuneIcon from "@mui/icons-material/Tune";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { hatchingUndoArchiveService } from "../../services/hatching-undo-archive";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import axios from "axios";
|
||||
import { RiFileExcel2Fill } from "react-icons/ri";
|
||||
import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice";
|
||||
import { CitySubmitHatchingReport } from "../city-submit-hatching-report/CitySubmitHatchingReport";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import InsertPageBreakIcon from "@mui/icons-material/InsertPageBreak";
|
||||
import { VetFarmSubmitFarmInfoLosses } from "../../../vet-farm/components/vet-farm-submit-farm-info-losses/VetFarmSubmitFarmInfoLosses";
|
||||
import AddIcon from "@mui/icons-material/Add";
|
||||
import KeyboardReturnIcon from "@mui/icons-material/KeyboardReturn";
|
||||
import SmsIcon from "@mui/icons-material/Sms";
|
||||
import { cityGetTicketDiffrentClearanceCode } from "../../services/city-get-ticket-different-clearance-code";
|
||||
export const CityHatchingsArchiveOperations = ({
|
||||
item,
|
||||
updateArchive,
|
||||
readOnly,
|
||||
}) => {
|
||||
const { userProfile } = useSelector((state) => state.userSlice);
|
||||
const dispatch = useDispatch();
|
||||
const [popoverOpen, setPopoverOpen] = useState(false);
|
||||
const [anchorEl, setAnchorEl] = useState(null);
|
||||
const [openNotif] = useContext(AppContext);
|
||||
const role = getRoleFromUrl();
|
||||
|
||||
const openPopover = (event) => {
|
||||
setPopoverOpen(true);
|
||||
setAnchorEl(event.currentTarget);
|
||||
};
|
||||
|
||||
const closePopover = () => {
|
||||
setPopoverOpen(false);
|
||||
setAnchorEl(null);
|
||||
};
|
||||
|
||||
const handleUndoArchive = () => {
|
||||
closePopover();
|
||||
dispatch(
|
||||
hatchingUndoArchiveService({
|
||||
key: item.key,
|
||||
type: "return_archive",
|
||||
})
|
||||
).then((r) => {
|
||||
if (r.payload.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.error,
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
updateArchive(1);
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleOpenReportModal = () => {
|
||||
closePopover();
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "ثبت گزارش",
|
||||
content: (
|
||||
<CitySubmitHatchingReport
|
||||
updateTable={updateArchive}
|
||||
item={item}
|
||||
isArchive
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const handleOpenLossesModal = () => {
|
||||
closePopover();
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "ثبت تلفات پایان دوره",
|
||||
content: (
|
||||
<VetFarmSubmitFarmInfoLosses
|
||||
item={item}
|
||||
updateTable={updateArchive}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const handleExcelExport = () => {
|
||||
closePopover();
|
||||
const url = `${axios.defaults.baseURL}process-for-each-hatching/?key=${item.key}`;
|
||||
window.open(url, "_blank");
|
||||
};
|
||||
|
||||
const handleCreateTicket = () => {
|
||||
closePopover();
|
||||
dispatch(
|
||||
cityGetTicketDiffrentClearanceCode({
|
||||
licence_number: item?.licenceNumber,
|
||||
mobile: userProfile?.mobile,
|
||||
})
|
||||
).then((r) => {
|
||||
if (r.payload.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "مشکلی پیش آمده است!",
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
updateArchive(1);
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const provinceAndAdminRoles = [
|
||||
"ProvinceOperator",
|
||||
"CityOperator",
|
||||
"AdminX",
|
||||
"SuperAdmin",
|
||||
];
|
||||
const vetRoles = ["VetFarm", "CityVet", "VetSupervisor"];
|
||||
|
||||
const options = [
|
||||
!readOnly && {
|
||||
key: "undo",
|
||||
label: "بازگشت جوجه ریزی",
|
||||
color: "primary.main",
|
||||
icon: <KeyboardReturnIcon sx={{ fontSize: { xs: 20, md: 18 } }} />,
|
||||
action: handleUndoArchive,
|
||||
},
|
||||
provinceAndAdminRoles.includes(role) && {
|
||||
key: "report",
|
||||
label: "ثبت گزارش",
|
||||
color: "secondary.main",
|
||||
icon: <AddIcon sx={{ fontSize: { xs: 20, md: 18 } }} />,
|
||||
action: handleOpenReportModal,
|
||||
},
|
||||
vetRoles.includes(role) && {
|
||||
key: "losses",
|
||||
label: "ثبت تلفات پایان دوره",
|
||||
color: "error.main",
|
||||
icon: <InsertPageBreakIcon sx={{ fontSize: { xs: 20, md: 18 } }} />,
|
||||
action: handleOpenLossesModal,
|
||||
},
|
||||
{
|
||||
key: "excel",
|
||||
label: "خروجی اکسل",
|
||||
color: "success.main",
|
||||
icon: <RiFileExcel2Fill size={18} style={{ color: "inherit" }} />,
|
||||
action: handleExcelExport,
|
||||
},
|
||||
{
|
||||
key: "ticket",
|
||||
label: "تیکت گزارش کشتار جوجه ریزی",
|
||||
color: "error.main",
|
||||
icon: <SmsIcon sx={{ fontSize: { xs: 20, md: 18 } }} />,
|
||||
action: handleCreateTicket,
|
||||
},
|
||||
].filter(Boolean);
|
||||
|
||||
return (
|
||||
<Grid>
|
||||
<IconButton variant="contained" color="primary" onClick={openPopover}>
|
||||
<TuneIcon />
|
||||
</IconButton>
|
||||
<Popover
|
||||
open={popoverOpen}
|
||||
anchorEl={anchorEl}
|
||||
onClose={closePopover}
|
||||
anchorOrigin={{
|
||||
vertical: "bottom",
|
||||
horizontal: "right",
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: "top",
|
||||
horizontal: "left",
|
||||
}}
|
||||
>
|
||||
<List sx={{ width: 200, p: 1 }}>
|
||||
{options.map((option) => (
|
||||
<ListItemButton
|
||||
key={option.key}
|
||||
onClick={() => {
|
||||
if (option.disabled) {
|
||||
return;
|
||||
}
|
||||
option.action();
|
||||
}}
|
||||
disabled={Boolean(option.disabled)}
|
||||
sx={{
|
||||
borderRadius: 1,
|
||||
mb: 0.5,
|
||||
color: option.disabled ? "text.disabled" : option.color,
|
||||
"&:last-of-type": {
|
||||
mb: 0,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<ListItemIcon
|
||||
sx={{
|
||||
color: option.disabled ? "text.disabled" : option.color,
|
||||
minWidth: 36,
|
||||
}}
|
||||
>
|
||||
{option.icon}
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary={
|
||||
<Typography
|
||||
sx={{
|
||||
color: option.disabled ? "text.disabled" : option.color,
|
||||
fontWeight: 600,
|
||||
fontSize: { xs: "13px", md: "14px" },
|
||||
}}
|
||||
>
|
||||
{option.label}
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
</ListItemButton>
|
||||
))}
|
||||
</List>
|
||||
</Popover>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,585 @@
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
IconButton,
|
||||
TextField,
|
||||
Tooltip,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import { DatePicker } from "@mui/x-date-pickers";
|
||||
import moment from "moment";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import axios from "axios";
|
||||
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import {
|
||||
LOADING_END,
|
||||
LOADING_START,
|
||||
OPEN_MODAL,
|
||||
} from "../../../../lib/redux/slices/appSlice";
|
||||
import { getFaUserRole } from "../../../../utils/getFaUserRole";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import { CityHatchingsArchiveOperations } from "../city-hatchings-archive-operations/CityHatchingsArchiveOperations";
|
||||
import { cityGetHatchingInfoFull } from "../../services/city-get-hatching-info-full";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { SimpleTable } from "../../../../components/simple-table/SimpleTable";
|
||||
import ShowImage from "../../../../components/show-image/ShowImage";
|
||||
import { formatJustDate, formatTime } from "../../../../utils/formatTime";
|
||||
import { RiFileExcel2Fill } from "react-icons/ri";
|
||||
import { RiSearchLine } from "react-icons/ri";
|
||||
import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined";
|
||||
import ToggleOnIcon from "@mui/icons-material/ToggleOn";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import {
|
||||
ROUTE_ADMINXـHATCHINGS,
|
||||
ROUTE_CITY_POULTRYـHATCHINGS,
|
||||
ROUTE_CITY_VISOR_STATICSـHATCHINGS_DETAILS,
|
||||
ROUTE_PROVINCE_SUPERVISORـHATCHINGS,
|
||||
ROUTE_PROVINCEـHATCHINGS,
|
||||
ROUTE_SUPER_ADMINـHATCHINGS,
|
||||
ROUTE_SUPPORTERـHATCHINGS,
|
||||
} from "../../../../routes/routes";
|
||||
import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye";
|
||||
|
||||
export const CityHatchingsArchive = ({ readOnly }) => {
|
||||
const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] =
|
||||
useContext(AppContext);
|
||||
const userKey = useSelector((state) => state.userSlice.userProfile.key);
|
||||
const { hatchingInfoFull } = useSelector((state) => state.citySlice);
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
useEffect(() => {
|
||||
const currentDate = moment(new Date()).format("YYYY-MM-DD");
|
||||
setSelectedDate1(currentDate);
|
||||
setSelectedDate2(currentDate);
|
||||
}, []);
|
||||
|
||||
const handleTextChange = (event) => {
|
||||
setTextValue(event.target.value);
|
||||
};
|
||||
|
||||
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 [withDate, setWithDate] = useState(false);
|
||||
|
||||
const fetchApiData = async (page) => {
|
||||
dispatch(LOADING_START());
|
||||
const response = await axios.get(
|
||||
`poultry_hatching/?archive=true&search=filter&value=${textValue}&role=${getRoleFromUrl()}
|
||||
&key=${userKey}&page=${page}&page_size=${perPage}${
|
||||
withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : ``
|
||||
}`
|
||||
);
|
||||
|
||||
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 [
|
||||
<CityHatchingsArchiveOperations
|
||||
key={i}
|
||||
item={item}
|
||||
updateArchive={updateTable}
|
||||
readOnly={readOnly}
|
||||
/>,
|
||||
<Tooltip placement="left" title=" جزئیات" key={i}>
|
||||
<IconButton
|
||||
color="primary"
|
||||
onClick={() => {
|
||||
navigate(
|
||||
getRoleFromUrl() === "AdminX"
|
||||
? `${ROUTE_ADMINXـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "Supporter"
|
||||
? `${ROUTE_SUPPORTERـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "SuperAdmin"
|
||||
? `${ROUTE_SUPER_ADMINـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "CityPoultry"
|
||||
? `${ROUTE_CITY_POULTRYـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "ProvinceSupervisor"
|
||||
? `${ROUTE_PROVINCE_SUPERVISORـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "province"
|
||||
? `${ROUTE_PROVINCEـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "CityJahad"
|
||||
? `${ROUTE_CITY_VISOR_STATICSـHATCHINGS_DETAILS}/${item.key}`
|
||||
: ""
|
||||
);
|
||||
}}
|
||||
>
|
||||
<RemoveRedEyeIcon />
|
||||
</IconButton>
|
||||
</Tooltip>,
|
||||
page === 1 ? i + 1 : i + perPage * (page - 1) + 1,
|
||||
<Tooltip
|
||||
disableHoverListener={
|
||||
!(item?.killingInfo?.violationMessage && item?.violation)
|
||||
}
|
||||
key={i}
|
||||
title={
|
||||
item?.violation
|
||||
? `متن گزارش تخلف: ${item?.killingInfo?.violationMessage}`
|
||||
: null
|
||||
}
|
||||
sx={{
|
||||
"&:hover": {
|
||||
cursor: item?.violation ? "pointer" : "default",
|
||||
},
|
||||
}}
|
||||
placement="top"
|
||||
>
|
||||
<Typography
|
||||
variant="body2"
|
||||
color={item?.violation ? "error" : "primary"}
|
||||
>
|
||||
{item?.violation ? "متخلف" : "عادی"}
|
||||
</Typography>
|
||||
</Tooltip>,
|
||||
item?.licenceNumber,
|
||||
item?.poultry?.breedingUniqueId,
|
||||
item?.CertId || "-",
|
||||
item?.poultry?.unitName || "-",
|
||||
`${item?.poultry?.userprofile?.fullName ?? "-"} (${
|
||||
item?.poultry?.userprofile?.mobile ?? "-"
|
||||
})`,
|
||||
item?.InteractTypeName,
|
||||
item?.PersonTypeName,
|
||||
item?.UnionTypeName,
|
||||
`${item?.poultry?.address?.city?.name ?? "-"}/${
|
||||
item?.poultry?.cityOperator
|
||||
? item?.poultry?.cityOperator
|
||||
: "بدون تعاونی"
|
||||
}`,
|
||||
|
||||
item?.vetFarm?.vetFarmMobile
|
||||
? `${item?.vetFarm?.vetFarmFullName} (${item?.vetFarm?.vetFarmMobile})`
|
||||
: "-",
|
||||
item?.hall || "-",
|
||||
item?.period || "-",
|
||||
formatTime(item?.createDate),
|
||||
formatTime(item?.date),
|
||||
item?.poultry?.killingAveAge?.toLocaleString(),
|
||||
item?.predicateDate ? formatJustDate(item?.predicateDate) : "-",
|
||||
|
||||
item.chickenBreed || "-",
|
||||
item?.age || "-",
|
||||
item?.archiveDate ? formatTime(item?.archiveDate) : "-",
|
||||
item.nowAge || "-",
|
||||
item?.quantity?.toLocaleString(),
|
||||
item?.increaseQuantity?.toLocaleString() || "-",
|
||||
|
||||
`${item.losses} (%${((item.losses * 100) / item.quantity).toFixed(0)})`,
|
||||
`${item?.directLosses?.toLocaleString()} (%${(
|
||||
(item.directLosses * 100) /
|
||||
item.quantity
|
||||
).toFixed(0)})`,
|
||||
`${item?.totalLosses?.toLocaleString()} (%${(
|
||||
(item.totalLosses * 100) /
|
||||
item.quantity
|
||||
).toFixed(0)})`,
|
||||
`${item?.totalCommitmentQuantity?.toLocaleString()}`,
|
||||
`${item?.totalFreeCommitmentQuantity?.toLocaleString()}`,
|
||||
`${item?.governmentalQuantity?.toLocaleString()}`,
|
||||
`${item?.governmentalKilledQuantity?.toLocaleString()}`,
|
||||
`${item?.freeQuantity?.toLocaleString()}`,
|
||||
`${item?.freeKilledQuantity?.toLocaleString()}`,
|
||||
`${item?.outProvinceKilledQuantity?.toLocaleString()}`,
|
||||
`${item?.outProvinceKilledWeight?.toLocaleString()}`,
|
||||
`${item?.barDifferenceRequestQuantity?.toLocaleString()}`,
|
||||
`${item?.barDifferenceRequestWeight?.toLocaleString()}`,
|
||||
`${item?.killingInfo?.provinceKillRequests?.toLocaleString()}`,
|
||||
`${item?.killingInfo?.provinceKillRequestsQuantity?.toLocaleString()}`,
|
||||
`${item?.killingInfo?.provinceKillRequestsWeight?.toLocaleString()}`,
|
||||
item?.killedQuantity?.toLocaleString() +
|
||||
` (%${((item?.killedQuantity * 100) / item.quantity).toFixed(0)})`,
|
||||
|
||||
`${item?.leftOver?.toLocaleString()} (%${(
|
||||
(item.leftOver * 100) /
|
||||
item.quantity
|
||||
).toFixed(0)})`,
|
||||
`${item?.quantity?.toLocaleString()}`,
|
||||
// item?.totalCommitment?.toLocaleString(),
|
||||
|
||||
`%${((item.totalLosses * 100) / item.quantity).toFixed(0)}`,
|
||||
`%${((item?.killedQuantity * 100) / item.quantity).toFixed(0)}`,
|
||||
`%${(
|
||||
((item?.killedQuantity + item?.totalLosses) * 100) /
|
||||
item?.quantity
|
||||
).toFixed(0)}`,
|
||||
item?.samasatDischargePercentage
|
||||
? `%${item?.samasatDischargePercentage}`
|
||||
: "-",
|
||||
|
||||
item?.totalCommitment?.toLocaleString(),
|
||||
item?.governmentalKilledQuantity?.toLocaleString(),
|
||||
item?.freeKilledQuantity?.toLocaleString(),
|
||||
item?.totalAverageKilledWeight?.toLocaleString(),
|
||||
item?.totalKilledWeight?.toLocaleString(),
|
||||
item?.activeKill?.activeKill ? "دارد" : "ندارد",
|
||||
item?.activeKill?.countOfRequest ? item.activeKill.countOfRequest : "-",
|
||||
item?.killingInfo?.killHouseRequests?.toLocaleString(),
|
||||
item?.killingInfo?.killHouseRequestsFirstQuantity?.toLocaleString(),
|
||||
item?.killingInfo?.killHouseRequestsFirstWeight?.toLocaleString(),
|
||||
item?.killingInfo?.barCompleteWithKillHouse?.toLocaleString(),
|
||||
item?.killingInfo?.acceptedRealWightFinal?.toLocaleString(),
|
||||
item?.chainKilledQuantity?.toLocaleString(),
|
||||
item?.chainKilledWeight?.toLocaleString(),
|
||||
item?.exportKilledQuantity?.toLocaleString(),
|
||||
item?.exportKilledWeight?.toLocaleString(),
|
||||
item?.killingInfo?.wareHouseBars?.toLocaleString(),
|
||||
item?.killingInfo?.wareHouseBarsQuantity?.toLocaleString(),
|
||||
item?.killingInfo?.wareHouseBarsWeight?.toLocaleString(),
|
||||
item?.killingInfo?.wareHouseBarsWeightLose?.toFixed(2),
|
||||
|
||||
item.lastChange
|
||||
? `${item.lastChange.fullName} (${getFaUserRole(
|
||||
item.lastChange.role
|
||||
)}) در تاریخ ${formatTime(item.lastChange.date)}`
|
||||
: "-",
|
||||
item.latestHatchingChange
|
||||
? `${item.latestHatchingChange.fullName} (${getFaUserRole(
|
||||
item.latestHatchingChange.role
|
||||
)}) در تاریخ ${formatTime(item.latestHatchingChange.date)}`
|
||||
: "-",
|
||||
item?.violationReport ? (
|
||||
<Button
|
||||
key={i}
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "گزارش ",
|
||||
content: (
|
||||
<SimpleTable
|
||||
columns={[
|
||||
"ثبت کننده",
|
||||
"تاریخ ثبت",
|
||||
"تخلف",
|
||||
"متن گزارش",
|
||||
"سند",
|
||||
]}
|
||||
data={[
|
||||
[
|
||||
item?.violationReporter,
|
||||
formatJustDate(item?.violationReportDate),
|
||||
item?.violation ? "دارد" : "ندارد",
|
||||
item?.violationReport,
|
||||
<ShowImage key={i} src={item?.violationImage} />,
|
||||
],
|
||||
]}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
نمایش
|
||||
</Button>
|
||||
) : (
|
||||
"بدون گزارش"
|
||||
),
|
||||
];
|
||||
});
|
||||
|
||||
setTableData(d);
|
||||
}, [data]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchApiData(1);
|
||||
}, [selectedDate1, selectedDate2, perPage, withDate]);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
cityGetHatchingInfoFull(
|
||||
withDate
|
||||
? {
|
||||
tab: "archive",
|
||||
date1: selectedDate1,
|
||||
date2: selectedDate2,
|
||||
textValue: textValue,
|
||||
}
|
||||
: { tab: "archive", textValue: textValue }
|
||||
)
|
||||
);
|
||||
}, [dispatch, withDate, selectedDate1, selectedDate2]);
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
dispatch(LOADING_START());
|
||||
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`poultry_hatching/?archive=true&search=filter&value=${textValue}&role=${getRoleFromUrl()}&key=${userKey}&page=${1}&page_size=${perPage}${
|
||||
withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : ``
|
||||
}`
|
||||
);
|
||||
dispatch(
|
||||
cityGetHatchingInfoFull(
|
||||
withDate
|
||||
? {
|
||||
tab: "archive",
|
||||
date1: selectedDate1,
|
||||
date2: selectedDate2,
|
||||
textValue: textValue,
|
||||
}
|
||||
: { tab: "archive", textValue: textValue }
|
||||
)
|
||||
);
|
||||
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 alignItems="center" justifyContent="center" isDashboard xs={12}>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
title={null}
|
||||
columns={[
|
||||
"تعداد فارم",
|
||||
"تعداد جوجه ریزی",
|
||||
"حجم کل جوجه ریزی",
|
||||
"حجم باقی مانده در سالن",
|
||||
"حجم کشتار شده",
|
||||
"وزن کشتار شده",
|
||||
"حجم کل تلفات",
|
||||
"حجم تلفات اتحادیه",
|
||||
"حجم تلفات دامپزشک",
|
||||
"مانده سالن ( 20 تا 30 روزه)",
|
||||
"مانده سالن ( 30 تا 40 روزه)",
|
||||
"مانده سالن ( 40 تا 50 روزه)",
|
||||
"مانده سالن ( 50 تا 60 روزه)",
|
||||
"بیشتر از 60 روزه",
|
||||
]}
|
||||
data={[
|
||||
[
|
||||
hatchingInfoFull?.poultries?.toLocaleString(),
|
||||
hatchingInfoFull?.hatchings?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingQuantity?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingLeftOverQuantity?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingKilledQuantity?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingKilledWeight?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingAllLosses?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingUnionLosses?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingVetLosses?.toLocaleString(),
|
||||
hatchingInfoFull?.age2030?.toLocaleString(),
|
||||
hatchingInfoFull?.age3040?.toLocaleString(),
|
||||
hatchingInfoFull?.age4050?.toLocaleString(),
|
||||
hatchingInfoFull?.age5060?.toLocaleString(),
|
||||
hatchingInfoFull?.ageMoreThan60?.toLocaleString(),
|
||||
],
|
||||
]}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<Grid
|
||||
container
|
||||
xs={12}
|
||||
justifyContent="start"
|
||||
alignItems="center"
|
||||
gap={2}
|
||||
>
|
||||
<Grid
|
||||
container
|
||||
gap={1}
|
||||
style={{
|
||||
borderStyle: "solid",
|
||||
borderWidth: "1px",
|
||||
padding: "5px",
|
||||
borderRadius: "15px",
|
||||
borderColor: "gray",
|
||||
justifyContent: "left",
|
||||
}}
|
||||
alignItems="center"
|
||||
>
|
||||
<Checkbox
|
||||
icon={<ToggleOffOutlinedIcon />}
|
||||
checkedIcon={<ToggleOnIcon />}
|
||||
checked={withDate}
|
||||
onChange={() => setWithDate(!withDate)}
|
||||
color="primary"
|
||||
size="large"
|
||||
/>
|
||||
<Grid>
|
||||
<DatePicker
|
||||
disabled={!withDate}
|
||||
label="از تاریخ"
|
||||
id="date"
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
size="small"
|
||||
style={{ width: "160px" }}
|
||||
{...params}
|
||||
/>
|
||||
)}
|
||||
value={selectedDate1}
|
||||
onChange={(e) => {
|
||||
setSelectedDate1(moment(e).format("YYYY-MM-DD"));
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<DatePicker
|
||||
disabled={!withDate}
|
||||
label="تا تاریخ"
|
||||
id="date"
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
size="small"
|
||||
style={{ width: "160px" }}
|
||||
{...params}
|
||||
/>
|
||||
)}
|
||||
value={selectedDate2}
|
||||
onChange={(e) => {
|
||||
setSelectedDate2(moment(e).format("YYYY-MM-DD"));
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
</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
|
||||
}archive_hatching_excel/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&key=${userKey}${
|
||||
withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : ``
|
||||
}`}
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Button color="success">
|
||||
<RiFileExcel2Fill size={32} />
|
||||
</Button>
|
||||
</a>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
|
||||
<ResponsiveTable
|
||||
data={tableData}
|
||||
columns={[
|
||||
"عملیات",
|
||||
"جزئیات",
|
||||
"ردیف",
|
||||
"وضعیت",
|
||||
"شماره مجوز جوجه ریزی",
|
||||
"شناسه یکتا",
|
||||
"مجوز بهداشتی جوجه ریزی",
|
||||
"نام فارم",
|
||||
"مرغدار",
|
||||
"بهره برداری",
|
||||
"مالکیت",
|
||||
"ارتباط",
|
||||
"شهر/تعاونی",
|
||||
"دامپزشک فارم",
|
||||
"سالن",
|
||||
"دوره جوجه ریزی",
|
||||
"تاریخ ثبت جوجه ریزی",
|
||||
"تاریخ جوجه ریزی",
|
||||
"میانگین سن کشتار",
|
||||
"پیش بینی تاریخ کشتار",
|
||||
"نژاد",
|
||||
"سن ورود به بایگانی",
|
||||
"تاریخ ورود به بایگانی",
|
||||
"سن فعلی",
|
||||
"حجم جوجه ریزی",
|
||||
"حجم افزایشی",
|
||||
"تلفات دامپزشک",
|
||||
"تلفات اتحادیه",
|
||||
"تلفات کل",
|
||||
"حجم تعهد دولتی",
|
||||
"حجم تعهد آزاد",
|
||||
"حجم کشتار دولتی",
|
||||
"وزن کشتار دولتی",
|
||||
"حجم کشتار آزاد",
|
||||
"وزن کشتار شده آزاد",
|
||||
"حجم فروش به خارج استان",
|
||||
"وزن فروش به خارج استان",
|
||||
"حجم اختلاف کشتار",
|
||||
"وزن اختلاف کشتار",
|
||||
"تخصیصات بدون بار",
|
||||
"حجم تخصیصات بدون بار",
|
||||
"وزن تخصیصات بدون بار",
|
||||
"حجم کشتار شده",
|
||||
" حجم مانده در سالن",
|
||||
" درصد مانده در سالن",
|
||||
" تلفات",
|
||||
" کشتار شده",
|
||||
"تایید تخلیه رصدیار",
|
||||
" تایید تخلیه در سماصط",
|
||||
"وزن تعهد دولتی",
|
||||
"وزن کشتار دولتی",
|
||||
"وزن کشتار آزاد",
|
||||
"میانگین وزن کشتار",
|
||||
"وزن کل کشتار شده",
|
||||
"تعداد کشتار فعال",
|
||||
"تعداد درخواست کشتار",
|
||||
"تعداد بارها",
|
||||
"حجم بارها",
|
||||
"وزن بارها",
|
||||
"حجم بارهای تحویلی",
|
||||
"وزن بارهای تحویلی",
|
||||
"حجم زنجیره",
|
||||
"وزن زنجیره",
|
||||
"حجم صادرات",
|
||||
"وزن صادرات",
|
||||
"بارهای ورودی به انبار",
|
||||
"حجم لاشه های انبار",
|
||||
"وزن لاشه های انبار",
|
||||
"درصد افت بارها",
|
||||
"آخرین تغییر",
|
||||
"سازنده جوجه ریزی",
|
||||
"گزارش",
|
||||
]}
|
||||
handlePageChange={handlePageChange}
|
||||
totalRows={totalRows}
|
||||
page={page}
|
||||
perPage={perPage}
|
||||
handlePerRowsChange={handlePerRowsChange}
|
||||
title="بایگانی جوجه ریزی"
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,672 @@
|
||||
import {
|
||||
Button,
|
||||
IconButton,
|
||||
TextField,
|
||||
Tooltip,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import axios from "axios";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { formatTime, formatJustDate } from "../../../../utils/formatTime";
|
||||
import { getFaUserRole } from "../../../../utils/getFaUserRole";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import { CityManageHatchingsOperations } from "../city-manage-hatchings-operations/CityManageHatchingsOperations";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { cityGetHatchingInfoFull } from "../../services/city-get-hatching-info-full";
|
||||
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
|
||||
import {
|
||||
LOADING_END,
|
||||
LOADING_START,
|
||||
OPEN_MODAL,
|
||||
} from "../../../../lib/redux/slices/appSlice";
|
||||
import { SimpleTable } from "../../../../components/simple-table/SimpleTable";
|
||||
import ShowImage from "../../../../components/show-image/ShowImage";
|
||||
import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye";
|
||||
import ArticleIcon from "@mui/icons-material/Article";
|
||||
import {
|
||||
ROUTE_ADMINXـHATCHINGS,
|
||||
ROUTE_CITY_JIHADـHATCHINGS,
|
||||
ROUTE_CITY_POULTRYـHATCHINGS,
|
||||
ROUTE_PROVINCE_SUPERVISORـHATCHINGS,
|
||||
ROUTE_PROVINCEـHATCHINGS,
|
||||
ROUTE_SUPER_ADMINـHATCHINGS,
|
||||
ROUTE_SUPPORTERـHATCHINGS,
|
||||
} from "../../../../routes/routes";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
export const CityHatchingsTotal = ({ readOnly }) => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const isReadOnly = readOnly || false;
|
||||
const [selectedAge1, setSelectedAge1] = useState(0);
|
||||
const [selectedAge2, setSelectedAge2] = useState(0);
|
||||
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 userKey = useSelector((state) => state.userSlice.userProfile.key);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [openNotif] = useContext(AppContext);
|
||||
|
||||
const handleTextChange = (event) => {
|
||||
setTextValue(event.target.value);
|
||||
};
|
||||
|
||||
const hatchingAdded = useSelector((state) => state.citySlice.hatchingAdded);
|
||||
|
||||
useEffect(() => {
|
||||
fetchApiData(1);
|
||||
}, [hatchingAdded]);
|
||||
|
||||
const fetchApiData = async (page) => {
|
||||
dispatch(LOADING_START());
|
||||
const response = await axios.get(
|
||||
`poultry_hatching?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&age1=${
|
||||
selectedAge1 ? selectedAge1 : 0
|
||||
}&age2=${selectedAge2 ? selectedAge2 : 0}&all_active_and_archive`
|
||||
);
|
||||
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);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchApiData(1);
|
||||
}, [dispatch, perPage]);
|
||||
|
||||
const updateTable = () => {
|
||||
fetchApiData(page !== 0 ? page : 1);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const d = data?.map((item, i) => {
|
||||
return [
|
||||
<CityManageHatchingsOperations
|
||||
selectedAge1={null}
|
||||
selectedAge2={null}
|
||||
updateTable={updateTable}
|
||||
item={item}
|
||||
key={"4"}
|
||||
readOnly={isReadOnly}
|
||||
/>,
|
||||
<Tooltip placement="left" title="جزئیات جوجه ریزی" key={i}>
|
||||
<IconButton
|
||||
color="primary"
|
||||
onClick={() => {
|
||||
navigate(
|
||||
getRoleFromUrl() === "AdminX"
|
||||
? `${ROUTE_ADMINXـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "Supporter"
|
||||
? `${ROUTE_SUPPORTERـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "SuperAdmin"
|
||||
? `${ROUTE_SUPER_ADMINـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "CityPoultry"
|
||||
? `${ROUTE_CITY_POULTRYـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "ProvinceSupervisor"
|
||||
? `${ROUTE_PROVINCE_SUPERVISORـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "ProvinceOperator"
|
||||
? `${ROUTE_PROVINCEـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "CityJahad"
|
||||
? `${ROUTE_CITY_JIHADـHATCHINGS}/${item.key}`
|
||||
: ""
|
||||
);
|
||||
}}
|
||||
>
|
||||
<RemoveRedEyeIcon />
|
||||
</IconButton>
|
||||
</Tooltip>,
|
||||
page === 1 ? i + 1 : i + perPage * (page - 1) + 1,
|
||||
<Tooltip
|
||||
disableHoverListener={
|
||||
!(item?.killingInfo?.violationMessage && item?.violation)
|
||||
}
|
||||
key={i}
|
||||
title={
|
||||
item?.violation
|
||||
? `متن گزارش تخلف: ${item?.killingInfo?.violationMessage}`
|
||||
: null
|
||||
}
|
||||
sx={{
|
||||
"&:hover": {
|
||||
cursor: item?.violation ? "pointer" : "default",
|
||||
},
|
||||
}}
|
||||
placement="top"
|
||||
>
|
||||
<Typography
|
||||
variant="body2"
|
||||
color={item?.violation ? "error" : "primary"}
|
||||
>
|
||||
{item?.violation ? "پیگیری" : "عادی"}
|
||||
</Typography>
|
||||
</Tooltip>,
|
||||
item?.licenceNumber,
|
||||
item?.poultry?.breedingUniqueId,
|
||||
item?.CertId,
|
||||
item?.poultry?.unitName || "-",
|
||||
`${item?.poultry?.userprofile?.fullName ?? "-"} (${
|
||||
item?.poultry?.userprofile?.mobile ?? "-"
|
||||
}) ${item?.violationReport ? "✉️" : ""}`,
|
||||
item?.InteractTypeName ? (
|
||||
<Typography
|
||||
variant="body2"
|
||||
color={item?.hasTenant ? "success.main" : ""}
|
||||
fontWeight={item?.hasTenant ? "bold" : "normal"}
|
||||
>
|
||||
{item?.InteractTypeName}
|
||||
</Typography>
|
||||
) : (
|
||||
"-"
|
||||
),
|
||||
item?.PersonTypeName,
|
||||
item?.UnionTypeName,
|
||||
`${item?.poultry?.address?.city?.name ?? "-"}/${
|
||||
item?.poultry?.cityOperator
|
||||
? item?.poultry?.cityOperator
|
||||
: "بدون تعاونی"
|
||||
}`,
|
||||
item?.vetFarm?.vetFarmMobile
|
||||
? `${item?.vetFarm?.vetFarmFullName} (${item?.vetFarm?.vetFarmMobile})`
|
||||
: "-",
|
||||
item.hall,
|
||||
item.period,
|
||||
formatTime(item?.createDate),
|
||||
formatTime(item?.date),
|
||||
item?.poultry?.killingAveAge?.toLocaleString(),
|
||||
item?.predicateDate ? formatJustDate(item?.predicateDate) : "-",
|
||||
item.chickenBreed,
|
||||
item.age,
|
||||
item?.quantity?.toLocaleString(),
|
||||
item?.increaseQuantity?.toLocaleString(),
|
||||
`${item.losses} (%${((item.losses * 100) / item.quantity).toFixed(0)})`,
|
||||
<Tooltip
|
||||
key={i}
|
||||
placement="top"
|
||||
title="جهت مشاهده ثبت کننده تلفات کلیک کنید"
|
||||
>
|
||||
<Button
|
||||
style={{ color: "rgba(0,0,0,0.87)" }}
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "ویرایش تعداد جوجه ریزی",
|
||||
content: (
|
||||
<Grid container xs={12}>
|
||||
{!item?.directLossesInputer &&
|
||||
!item?.directLossesInputer ? (
|
||||
<Typography variant="body1">
|
||||
برای این جوجه ریزی تلفاتی ثبت نشده است.
|
||||
</Typography>
|
||||
) : (
|
||||
<Grid xs={12}>
|
||||
<Typography variant="body1">
|
||||
ثبت کننده تلفات اتحادیه:{" "}
|
||||
{item?.directLossesInputer
|
||||
? `${
|
||||
item?.directLossesInputer
|
||||
} در تاریخ ${formatJustDate(
|
||||
item?.directLossesDate
|
||||
)}`
|
||||
: " - "}
|
||||
</Typography>
|
||||
<Typography variant="body1">
|
||||
ویرایش کننده تلفات اتحادیه:
|
||||
{item?.directLossesEditor
|
||||
? `${
|
||||
item?.directLossesEditor
|
||||
} در تاریخ ${formatJustDate(
|
||||
item?.directLossesLastEditDate
|
||||
)}`
|
||||
: " - "}
|
||||
</Typography>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
),
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
{`${item?.directLosses?.toLocaleString()} (%${(
|
||||
(item.directLosses * 100) /
|
||||
item.quantity
|
||||
).toFixed(0)})`}
|
||||
</Button>
|
||||
</Tooltip>,
|
||||
`${item?.totalLosses?.toLocaleString()} (%${(
|
||||
(item.totalLosses * 100) /
|
||||
item.quantity
|
||||
).toFixed(0)})`,
|
||||
`${item?.totalCommitmentQuantity?.toLocaleString()}`,
|
||||
`${item?.totalFreeCommitmentQuantity?.toLocaleString()}`,
|
||||
`${item?.governmentalQuantity?.toLocaleString()}`,
|
||||
`${item?.governmentalKilledQuantity?.toLocaleString()}`,
|
||||
`${item?.freeQuantity?.toLocaleString()}`,
|
||||
`${item?.freeKilledQuantity?.toLocaleString()}`,
|
||||
`${item?.outProvinceKilledQuantity?.toLocaleString()}`,
|
||||
`${item?.outProvinceKilledWeight?.toLocaleString()}`,
|
||||
`${item?.barDifferenceRequestQuantity?.toLocaleString()}`,
|
||||
`${item?.barDifferenceRequestWeight?.toLocaleString()}`,
|
||||
`${item?.killingInfo?.provinceKillRequests?.toLocaleString()}`,
|
||||
`${item?.killingInfo?.provinceKillRequestsQuantity?.toLocaleString()}`,
|
||||
`${item?.killingInfo?.provinceKillRequestsWeight?.toLocaleString()}`,
|
||||
item?.killedQuantity?.toLocaleString() +
|
||||
` (%${((item?.killedQuantity * 100) / item.quantity).toFixed(0)})`,
|
||||
item?.leftOver?.toLocaleString(),
|
||||
`%${((item?.leftOver * 100) / item?.quantity).toFixed(0)}`,
|
||||
|
||||
`%${((item.totalLosses * 100) / item.quantity).toFixed(0)}`,
|
||||
`%${((item?.killedQuantity * 100) / item.quantity).toFixed(0)}`,
|
||||
`%${((item?.leftOver * 100) / item?.quantity).toFixed(0)}`,
|
||||
`%${(
|
||||
((item?.killedQuantity + item?.totalLosses) * 100) /
|
||||
item?.quantity
|
||||
).toFixed(0)}`,
|
||||
|
||||
item?.samasatDischargePercentage
|
||||
? `%${item?.samasatDischargePercentage}`
|
||||
: "-",
|
||||
item?.totalCommitment?.toLocaleString(),
|
||||
item?.governmentalKilledQuantity?.toLocaleString(),
|
||||
item?.freeKilledQuantity?.toLocaleString(),
|
||||
item?.totalAverageKilledWeight?.toLocaleString(),
|
||||
item?.totalKilledWeight?.toLocaleString(),
|
||||
item?.activeKill?.activeKill ? "دارد" : "ندارد",
|
||||
item?.activeKill?.countOfRequest ? item.activeKill.countOfRequest : "-",
|
||||
item?.killingInfo?.killHouseRequests?.toLocaleString(),
|
||||
item?.killingInfo?.killHouseRequestsFirstQuantity?.toLocaleString(),
|
||||
item?.killingInfo?.killHouseRequestsFirstWeight?.toLocaleString(),
|
||||
item?.killingInfo?.barCompleteWithKillHouse?.toLocaleString(),
|
||||
item?.killingInfo?.acceptedRealWightFinal?.toLocaleString(),
|
||||
item?.chainKilledQuantity?.toLocaleString(),
|
||||
item?.chainKilledWeight?.toLocaleString(),
|
||||
item?.exportKilledQuantity?.toLocaleString(),
|
||||
item?.exportKilledWeight?.toLocaleString(),
|
||||
item?.killingInfo?.wareHouseBars?.toLocaleString(),
|
||||
item?.killingInfo?.wareHouseBarsQuantity?.toLocaleString(),
|
||||
item?.killingInfo?.wareHouseBarsWeight?.toLocaleString(),
|
||||
item?.killingInfo?.wareHouseBarsWeightLose?.toFixed(2),
|
||||
item.lastChange
|
||||
? `${item.lastChange.fullName} (${getFaUserRole(
|
||||
item.lastChange.role
|
||||
)}) در تاریخ ${formatTime(item.lastChange.date)}`
|
||||
: "-",
|
||||
item.latestHatchingChange
|
||||
? `${item.latestHatchingChange.fullName} (${getFaUserRole(
|
||||
item.latestHatchingChange.role
|
||||
)}) در تاریخ ${formatTime(item.latestHatchingChange.date)}`
|
||||
: "-",
|
||||
item?.violationReport ? (
|
||||
<Tooltip title="مشاهده گزارش" placement="top" key={i}>
|
||||
<IconButton
|
||||
color="primary"
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "گزارش ",
|
||||
content: (
|
||||
<SimpleTable
|
||||
columns={[
|
||||
"ثبت کننده",
|
||||
"تاریخ ثبت",
|
||||
"تخلف",
|
||||
"متن گزارش",
|
||||
"سند",
|
||||
]}
|
||||
data={[
|
||||
[
|
||||
item?.violationReporter,
|
||||
formatJustDate(item?.violationReportDate),
|
||||
item?.violation ? "دارد" : "ندارد",
|
||||
item?.violationReport,
|
||||
<Grid
|
||||
key={i}
|
||||
container
|
||||
xs={12}
|
||||
justifyContent="center"
|
||||
gap={1}
|
||||
>
|
||||
{item?.violationImage?.map((option, index) => (
|
||||
<ShowImage
|
||||
key={`${option}-${index}`}
|
||||
src={option}
|
||||
/>
|
||||
))}
|
||||
</Grid>,
|
||||
],
|
||||
]}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
<ArticleIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
) : (
|
||||
"-"
|
||||
),
|
||||
];
|
||||
});
|
||||
|
||||
setTableData(d);
|
||||
}, [data]);
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
dispatch(LOADING_START());
|
||||
dispatch(
|
||||
cityGetHatchingInfoFull({
|
||||
age1: selectedAge1,
|
||||
age2: selectedAge2,
|
||||
tab: "all",
|
||||
textValue: textValue,
|
||||
})
|
||||
);
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`poultry_hatching/?role=${getRoleFromUrl()}&age1=${
|
||||
selectedAge1 ? selectedAge1 : 0
|
||||
}&age2=${
|
||||
selectedAge2 ? selectedAge2 : 0
|
||||
}&search=filter&value=${textValue}&page=${1}&page_size=${perPage}&all_active_and_archive`
|
||||
);
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
dispatch(LOADING_END());
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleRemoveFilter = async (event) => {
|
||||
event.preventDefault();
|
||||
setSelectedAge1(0);
|
||||
setSelectedAge2(0);
|
||||
dispatch(LOADING_START());
|
||||
setTextValue("");
|
||||
dispatch(
|
||||
cityGetHatchingInfoFull({
|
||||
age1: 0,
|
||||
age2: 0,
|
||||
tab: "all",
|
||||
textValue: textValue,
|
||||
})
|
||||
);
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`poultry_hatching?role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&all_active_and_archive&search=filter&value=${textValue}`
|
||||
);
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
} finally {
|
||||
dispatch(LOADING_END());
|
||||
}
|
||||
};
|
||||
|
||||
const [lastUpdateData, setLastUpdateData] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchData() {
|
||||
try {
|
||||
const response = await axios.get(`last_update/?type=poultry_hatching`);
|
||||
setLastUpdateData(response.data);
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
}
|
||||
}
|
||||
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
const tableTitle = (
|
||||
<Grid
|
||||
container
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
gap={2}
|
||||
paddingTop={2}
|
||||
mb={1}
|
||||
mt={2}
|
||||
xs={12}
|
||||
>
|
||||
<form onSubmit={handleSubmit} style={{ flex: 1 }}>
|
||||
<Grid container alignItems="center" gap={SPACING.SMALL} xs={12}>
|
||||
<Grid sx={{ width: { xs: "72px", sm: "80px" } }}>
|
||||
<TextField
|
||||
fullWidth
|
||||
size="small"
|
||||
label="از سن"
|
||||
id="outlined-controlled"
|
||||
value={selectedAge1}
|
||||
onChange={(event) => {
|
||||
setSelectedAge1(event.target.value);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid sx={{ width: { xs: "72px", sm: "80px" } }}>
|
||||
<TextField
|
||||
fullWidth
|
||||
size="small"
|
||||
label="تا سن"
|
||||
id="outlined-controlled"
|
||||
value={selectedAge2}
|
||||
onChange={(event) => {
|
||||
setSelectedAge2(event.target.value);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<TextField
|
||||
id="outlined-basic"
|
||||
size="small"
|
||||
label="جستجو"
|
||||
variant="outlined"
|
||||
value={textValue}
|
||||
sx={{ maxWidth: { xs: "100%", sm: 250 } }}
|
||||
onChange={handleTextChange}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter") {
|
||||
handleSubmit(e);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Button type="submit" endIcon={<RiSearchLine />}>
|
||||
جستجو
|
||||
</Button>
|
||||
<Tooltip title="خروجی اکسل" px={0}>
|
||||
<Button
|
||||
color="success"
|
||||
onClick={() => {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "فایل اکسل در حال دانلود می باشد، این علمیات ممکن است زمان بر باشد لطفا صبر کنید.",
|
||||
severity: "success",
|
||||
});
|
||||
const link = `${
|
||||
axios.defaults.baseURL
|
||||
}0/hatching_excel/?role=${getRoleFromUrl()}&key=${userKey}&age1=${
|
||||
selectedAge1 ? selectedAge1 : 0
|
||||
}&age2=${
|
||||
selectedAge2 ? selectedAge2 : 0
|
||||
}&search=filter&value=${textValue}&all_active_and_archive`;
|
||||
window.location.href = link;
|
||||
}}
|
||||
>
|
||||
<RiFileExcel2Fill size={32} />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
</form>
|
||||
<Button onClick={handleRemoveFilter} color="error">
|
||||
حذف فیلتر
|
||||
</Button>
|
||||
</Grid>
|
||||
);
|
||||
const { hatchingInfoFull } = useSelector((state) => state.citySlice);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
cityGetHatchingInfoFull({
|
||||
age1: selectedAge1,
|
||||
age2: selectedAge2,
|
||||
tab: "all",
|
||||
textValue: textValue,
|
||||
})
|
||||
);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Grid alignItems="center" justifyContent="center" mt={2}>
|
||||
<Grid alignItems="center" justifyContent="center" isDashboard xs={12}>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
title={
|
||||
lastUpdateData &&
|
||||
`آخرین بروزرسانی : ${formatTime(lastUpdateData)} ${" "}`
|
||||
}
|
||||
columns={[
|
||||
"تعداد فارم",
|
||||
"تعداد جوجه ریزی",
|
||||
"حجم کل جوجه ریزی",
|
||||
"حجم باقی مانده در سالن",
|
||||
"حجم کشتار شده",
|
||||
"وزن کشتار شده",
|
||||
"حجم کل تلفات",
|
||||
"حجم تلفات اتحادیه",
|
||||
"حجم تلفات دامپزشک",
|
||||
"مانده سالن ( 20 تا 30 روزه)",
|
||||
"مانده سالن ( 30 تا 40 روزه)",
|
||||
"مانده سالن ( 40 تا 50 روزه)",
|
||||
"مانده سالن ( 50 تا 60 روزه)",
|
||||
"بیشتر از 60 روزه",
|
||||
]}
|
||||
data={[
|
||||
[
|
||||
hatchingInfoFull?.poultries?.toLocaleString(),
|
||||
hatchingInfoFull?.hatchings?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingQuantity?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingLeftOverQuantity?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingKilledQuantity?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingKilledWeight?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingAllLosses?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingUnionLosses?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingVetLosses?.toLocaleString(),
|
||||
hatchingInfoFull?.age2030?.toLocaleString(),
|
||||
hatchingInfoFull?.age3040?.toLocaleString(),
|
||||
hatchingInfoFull?.age4050?.toLocaleString(),
|
||||
hatchingInfoFull?.age5060?.toLocaleString(),
|
||||
hatchingInfoFull?.ageMoreThan60?.toLocaleString(),
|
||||
],
|
||||
]}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
{tableTitle}
|
||||
|
||||
<ResponsiveTable
|
||||
data={tableData}
|
||||
columns={[
|
||||
"عملیات",
|
||||
"جزئیات",
|
||||
"ردیف",
|
||||
"وضعیت",
|
||||
"شماره مجوز جوجه ریزی",
|
||||
"شناسه یکتا",
|
||||
"مجوز بهداشتی جوجه ریزی",
|
||||
"نام فارم",
|
||||
"مرغدار",
|
||||
"بهره برداری",
|
||||
"مالکیت",
|
||||
"ارتباط",
|
||||
"شهر/تعاونی",
|
||||
"دامپزشک فارم",
|
||||
"سالن",
|
||||
"دوره جوجه ریزی",
|
||||
"تاریخ ثبت جوجه ریزی",
|
||||
"تاریخ جوجه ریزی",
|
||||
"میانگین سن کشتار",
|
||||
"پیش بینی تاریخ کشتار",
|
||||
"نژاد",
|
||||
"سن",
|
||||
"حجم جوجه ریزی",
|
||||
"حجم افزایشی",
|
||||
"تلفات دامپزشک",
|
||||
"تلفات اتحادیه",
|
||||
"تلفات کل",
|
||||
"حجم تعهد دولتی",
|
||||
"حجم تعهد آزاد",
|
||||
"حجم کشتار دولتی",
|
||||
"وزن کشتار دولتی",
|
||||
"حجم کشتار آزاد",
|
||||
"وزن کشتار شده آزاد",
|
||||
"حجم فروش به خارج استان",
|
||||
"وزن فروش به خارج استان",
|
||||
"حجم اختلاف کشتار",
|
||||
"وزن اختلاف کشتار",
|
||||
"تخصیصات بدون بار",
|
||||
"حجم تخصیصات بدون بار",
|
||||
"وزن تخصیصات بدون بار",
|
||||
"حجم کشتار شده",
|
||||
"حجم مانده در سالن",
|
||||
" درصد مانده در سالن",
|
||||
" تلفات",
|
||||
" کشتار شده",
|
||||
" باقی مانده در سالن",
|
||||
"تایید تخلیه رصدیار",
|
||||
" تایید تخلیه در سماصط",
|
||||
"وزن تعهد دولتی",
|
||||
"وزن کشتار دولتی",
|
||||
"وزن کشتار آزاد",
|
||||
"میانگین وزن کشتار",
|
||||
"وزن کل کشتار شده",
|
||||
"تعداد کشتار فعال",
|
||||
"تعداد درخواست کشتار",
|
||||
"تعداد بارها",
|
||||
"حجم بارها",
|
||||
"وزن بارها",
|
||||
"حجم بارهای تحویلی",
|
||||
"وزن بارهای تحویلی",
|
||||
"حجم زنجیره",
|
||||
"وزن زنجیره",
|
||||
"حجم صادرات",
|
||||
"وزن صادرات",
|
||||
"بارهای ورودی به انبار",
|
||||
"حجم لاشه های انبار",
|
||||
"وزن لاشه های انبار",
|
||||
"درصد افت بارها",
|
||||
"آخرین تغییر",
|
||||
"سازنده جوجه ریزی",
|
||||
"گزارش",
|
||||
]}
|
||||
handlePageChange={handlePageChange}
|
||||
totalRows={totalRows}
|
||||
page={page}
|
||||
perPage={perPage}
|
||||
handlePerRowsChange={handlePerRowsChange}
|
||||
title="کل جوجه ریزی ها (فعال و بایگانی شده)"
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
681
src/features/city/components/city-hatchings/CityHatchings.js
Normal file
681
src/features/city/components/city-hatchings/CityHatchings.js
Normal file
@@ -0,0 +1,681 @@
|
||||
import {
|
||||
Button,
|
||||
IconButton,
|
||||
TextField,
|
||||
Tooltip,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import axios from "axios";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { formatTime, formatJustDate } from "../../../../utils/formatTime";
|
||||
import { getFaUserRole } from "../../../../utils/getFaUserRole";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import { CityManageHatchingsOperations } from "../city-manage-hatchings-operations/CityManageHatchingsOperations";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { cityGetHatchingInfoFull } from "../../services/city-get-hatching-info-full";
|
||||
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
|
||||
import {
|
||||
// DRAWER,
|
||||
LOADING_END,
|
||||
LOADING_START,
|
||||
OPEN_MODAL,
|
||||
} from "../../../../lib/redux/slices/appSlice";
|
||||
import { SimpleTable } from "../../../../components/simple-table/SimpleTable";
|
||||
import ShowImage from "../../../../components/show-image/ShowImage";
|
||||
import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye";
|
||||
import {
|
||||
ROUTE_ADMINXـHATCHINGS,
|
||||
ROUTE_CITY_JIHADـHATCHINGS,
|
||||
ROUTE_CITY_POULTRYـHATCHINGS,
|
||||
ROUTE_PROVINCE_SUPERVISORـHATCHINGS,
|
||||
ROUTE_PROVINCEـHATCHINGS,
|
||||
ROUTE_SUPER_ADMINـHATCHINGS,
|
||||
ROUTE_SUPPORTERـHATCHINGS,
|
||||
} from "../../../../routes/routes";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
// import { CityHatchingShowTableDetail } from "../city-hatching-show-table-detail/CityHatchingShowTableDetail";
|
||||
|
||||
export const CityHatchings = ({ readOnly }) => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const isReadOnly = readOnly || false;
|
||||
const [selectedAge1, setSelectedAge1] = useState(0);
|
||||
const [selectedAge2, setSelectedAge2] = useState(0);
|
||||
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 userKey = useSelector((state) => state.userSlice.userProfile.key);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [openNotif] = useContext(AppContext);
|
||||
|
||||
const handleTextChange = (event) => {
|
||||
setTextValue(event.target.value);
|
||||
};
|
||||
|
||||
const hatchingAdded = useSelector((state) => state.citySlice.hatchingAdded);
|
||||
|
||||
useEffect(() => {
|
||||
fetchApiData(1);
|
||||
}, [hatchingAdded]);
|
||||
|
||||
const fetchApiData = async (page) => {
|
||||
dispatch(LOADING_START());
|
||||
const response = await axios.get(
|
||||
`poultry_hatching?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&age1=${
|
||||
selectedAge1 ? selectedAge1 : 0
|
||||
}&age2=${
|
||||
selectedAge2 ? selectedAge2 : 0
|
||||
}&search=filter&value=${textValue}`
|
||||
);
|
||||
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);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchApiData(1);
|
||||
}, [dispatch, perPage]);
|
||||
|
||||
const updateTable = () => {
|
||||
fetchApiData(page !== 0 ? page : 1);
|
||||
};
|
||||
|
||||
// const killedNumber = (item) => {
|
||||
// let killedNumber = "";
|
||||
// killedNumber = item.quantity - item.losses - item.leftOver;
|
||||
// return killedNumber;
|
||||
// };
|
||||
|
||||
useEffect(() => {
|
||||
const d = data?.map((item, i) => {
|
||||
return [
|
||||
<CityManageHatchingsOperations
|
||||
selectedAge1={null}
|
||||
selectedAge2={null}
|
||||
updateTable={updateTable}
|
||||
item={item}
|
||||
key={"4"}
|
||||
readOnly={isReadOnly}
|
||||
/>,
|
||||
<Tooltip placement="left" title="جزئیات جوجه ریزی" key={item?.key}>
|
||||
<IconButton
|
||||
color="primary"
|
||||
onClick={() => {
|
||||
navigate(
|
||||
getRoleFromUrl() === "AdminX"
|
||||
? `${ROUTE_ADMINXـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "Supporter"
|
||||
? `${ROUTE_SUPPORTERـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "SuperAdmin"
|
||||
? `${ROUTE_SUPER_ADMINـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "CityPoultry"
|
||||
? `${ROUTE_CITY_POULTRYـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "ProvinceSupervisor"
|
||||
? `${ROUTE_PROVINCE_SUPERVISORـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "ProvinceOperator"
|
||||
? `${ROUTE_PROVINCEـHATCHINGS}/${item.key}`
|
||||
: getRoleFromUrl() === "CityJahad"
|
||||
? `${ROUTE_CITY_JIHADـHATCHINGS}/${item.key}`
|
||||
: ""
|
||||
);
|
||||
}}
|
||||
>
|
||||
<RemoveRedEyeIcon />
|
||||
</IconButton>
|
||||
</Tooltip>,
|
||||
page === 1 ? i + 1 : i + perPage * (page - 1) + 1,
|
||||
<Tooltip
|
||||
disableHoverListener={
|
||||
!(item?.killingInfo?.violationMessage && item?.violation)
|
||||
}
|
||||
key={item?.key}
|
||||
title={
|
||||
item?.violation
|
||||
? `متن گزارش تخلف: ${item?.killingInfo?.violationMessage}`
|
||||
: null
|
||||
}
|
||||
sx={{
|
||||
"&:hover": {
|
||||
cursor: item?.violation ? "pointer" : "default",
|
||||
},
|
||||
}}
|
||||
placement="top"
|
||||
>
|
||||
<Typography
|
||||
variant="body2"
|
||||
color={item?.violation ? "error" : "primary"}
|
||||
>
|
||||
{item?.violation ? "پیگیری" : "عادی"}
|
||||
</Typography>
|
||||
</Tooltip>,
|
||||
item?.licenceNumber,
|
||||
item?.poultry?.breedingUniqueId,
|
||||
item?.CertId,
|
||||
// item?.commitmentType === "free" ? "آزاد" : "دولتی",
|
||||
item?.poultry?.unitName || "-",
|
||||
`${item?.poultry?.userprofile?.fullName ?? "-"} (${
|
||||
item?.poultry?.userprofile?.mobile ?? "-"
|
||||
}) ${item?.violationReport ? "✉️" : ""}`,
|
||||
item?.InteractTypeName ? (
|
||||
<Typography
|
||||
variant="body2"
|
||||
color={item?.hasTenant ? "success.main" : ""}
|
||||
fontWeight={item?.hasTenant ? "bold" : "normal"}
|
||||
>
|
||||
{item?.InteractTypeName}
|
||||
</Typography>
|
||||
) : (
|
||||
"-"
|
||||
),
|
||||
item?.PersonTypeName,
|
||||
item?.UnionTypeName,
|
||||
`${item?.poultry?.address?.city?.name ?? "-"}/${
|
||||
item?.poultry?.cityOperator
|
||||
? item?.poultry?.cityOperator
|
||||
: "بدون تعاونی"
|
||||
}`,
|
||||
item?.vetFarm?.vetFarmMobile
|
||||
? `${item?.vetFarm?.vetFarmFullName} (${item?.vetFarm?.vetFarmMobile})`
|
||||
: "-",
|
||||
item.hall,
|
||||
item.period,
|
||||
formatTime(item?.createDate),
|
||||
formatTime(item?.date),
|
||||
item?.poultry?.killingAveAge?.toLocaleString(),
|
||||
item?.predicateDate ? formatJustDate(item?.predicateDate) : "-",
|
||||
item.chickenBreed,
|
||||
item.age,
|
||||
item?.quantity?.toLocaleString(),
|
||||
item?.increaseQuantity?.toLocaleString(),
|
||||
`${item.losses} (%${((item.losses * 100) / item.quantity).toFixed(0)})`,
|
||||
<Tooltip
|
||||
key={item?.key}
|
||||
placement="top"
|
||||
title="جهت مشاهده ثبت کننده تلفات کلیک کنید"
|
||||
>
|
||||
<Button
|
||||
// variant="outlined"
|
||||
style={{ color: "rgba(0,0,0,0.87)" }}
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "ویرایش تعداد جوجه ریزی",
|
||||
content: (
|
||||
<Grid container xs={12}>
|
||||
{!item?.directLossesInputer &&
|
||||
!item?.directLossesInputer ? (
|
||||
<Typography variant="body1">
|
||||
برای این جوجه ریزی تلفاتی ثبت نشده است.
|
||||
</Typography>
|
||||
) : (
|
||||
<Grid xs={12}>
|
||||
<Typography variant="body1">
|
||||
ثبت کننده تلفات اتحادیه:{" "}
|
||||
{item?.directLossesInputer
|
||||
? `${
|
||||
item?.directLossesInputer
|
||||
} در تاریخ ${formatJustDate(
|
||||
item?.directLossesDate
|
||||
)}`
|
||||
: " - "}
|
||||
</Typography>
|
||||
<Typography variant="body1">
|
||||
ویرایش کننده تلفات اتحادیه:
|
||||
{item?.directLossesEditor
|
||||
? `${
|
||||
item?.directLossesEditor
|
||||
} در تاریخ ${formatJustDate(
|
||||
item?.directLossesLastEditDate
|
||||
)}`
|
||||
: " - "}
|
||||
</Typography>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
),
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
{`${item?.directLosses?.toLocaleString()} (%${(
|
||||
(item.directLosses * 100) /
|
||||
item.quantity
|
||||
).toFixed(0)})`}
|
||||
</Button>
|
||||
</Tooltip>,
|
||||
`${item?.totalLosses?.toLocaleString()} (%${(
|
||||
(item.totalLosses * 100) /
|
||||
item.quantity
|
||||
).toFixed(0)})`,
|
||||
`${item?.totalCommitmentQuantity?.toLocaleString()}`,
|
||||
`${item?.totalFreeCommitmentQuantity?.toLocaleString()}`,
|
||||
`${item?.governmentalQuantity?.toLocaleString()}`,
|
||||
`${item?.governmentalKilledQuantity?.toLocaleString()}`,
|
||||
`${item?.freeQuantity?.toLocaleString()}`,
|
||||
`${item?.freeKilledQuantity?.toLocaleString()}`,
|
||||
`${item?.outProvinceKilledQuantity?.toLocaleString()}`,
|
||||
`${item?.outProvinceKilledWeight?.toLocaleString()}`,
|
||||
`${item?.barDifferenceRequestQuantity?.toLocaleString()}`,
|
||||
`${item?.barDifferenceRequestWeight?.toLocaleString()}`,
|
||||
`${item?.killingInfo?.provinceKillRequests?.toLocaleString()}`,
|
||||
`${item?.killingInfo?.provinceKillRequestsQuantity?.toLocaleString()}`,
|
||||
`${item?.killingInfo?.provinceKillRequestsWeight?.toLocaleString()}`,
|
||||
item?.killedQuantity?.toLocaleString() +
|
||||
` (%${((item?.killedQuantity * 100) / item.quantity).toFixed(0)})`,
|
||||
item?.leftOver?.toLocaleString(),
|
||||
`%${((item?.leftOver * 100) / item?.quantity).toFixed(0)}`,
|
||||
// item?.totalCommitment?.toLocaleString(),
|
||||
|
||||
`%${((item.totalLosses * 100) / item.quantity).toFixed(0)}`,
|
||||
`%${((item?.killedQuantity * 100) / item.quantity).toFixed(0)}`,
|
||||
`%${((item?.leftOver * 100) / item?.quantity).toFixed(0)}`,
|
||||
`%${(
|
||||
((item?.killedQuantity + item?.totalLosses) * 100) /
|
||||
item?.quantity
|
||||
).toFixed(0)}`,
|
||||
|
||||
item?.samasatDischargePercentage
|
||||
? `%${item?.samasatDischargePercentage}`
|
||||
: "-",
|
||||
item?.totalCommitment?.toLocaleString(),
|
||||
item?.governmentalKilledQuantity?.toLocaleString(),
|
||||
item?.freeKilledQuantity?.toLocaleString(),
|
||||
item?.totalAverageKilledWeight?.toLocaleString(),
|
||||
item?.totalKilledWeight?.toLocaleString(),
|
||||
item?.activeKill?.activeKill ? "دارد" : "ندارد",
|
||||
item?.activeKill?.countOfRequest ? item.activeKill.countOfRequest : "-",
|
||||
item?.killingInfo?.killHouseRequests?.toLocaleString(),
|
||||
item?.killingInfo?.killHouseRequestsFirstQuantity?.toLocaleString(),
|
||||
item?.killingInfo?.killHouseRequestsFirstWeight?.toLocaleString(),
|
||||
item?.killingInfo?.barCompleteWithKillHouse?.toLocaleString(),
|
||||
item?.killingInfo?.acceptedRealWightFinal?.toLocaleString(),
|
||||
item?.chainKilledQuantity?.toLocaleString(),
|
||||
item?.chainKilledWeight?.toLocaleString(),
|
||||
item?.exportKilledQuantity?.toLocaleString(),
|
||||
item?.exportKilledWeight?.toLocaleString(),
|
||||
item?.killingInfo?.wareHouseBars?.toLocaleString(),
|
||||
item?.killingInfo?.wareHouseBarsQuantity?.toLocaleString(),
|
||||
item?.killingInfo?.wareHouseBarsWeight?.toLocaleString(),
|
||||
item?.killingInfo?.wareHouseBarsWeightLose?.toFixed(2),
|
||||
item.lastChange
|
||||
? `${item.lastChange.fullName} (${getFaUserRole(
|
||||
item.lastChange.role
|
||||
)}) در تاریخ ${formatTime(item.lastChange.date)}`
|
||||
: "-",
|
||||
item.latestHatchingChange
|
||||
? `${item.latestHatchingChange.fullName} (${getFaUserRole(
|
||||
item.latestHatchingChange.role
|
||||
)}) در تاریخ ${formatTime(item.latestHatchingChange.date)}`
|
||||
: "-",
|
||||
item?.violationReport ? (
|
||||
<Button
|
||||
key={item?.key}
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "گزارش ",
|
||||
content: (
|
||||
<SimpleTable
|
||||
columns={[
|
||||
"ثبت کننده",
|
||||
"تاریخ ثبت",
|
||||
"تخلف",
|
||||
"متن گزارش",
|
||||
"سند",
|
||||
]}
|
||||
data={[
|
||||
[
|
||||
item?.violationReporter,
|
||||
formatJustDate(item?.violationReportDate),
|
||||
item?.violation ? "دارد" : "ندارد",
|
||||
item?.violationReport,
|
||||
<Grid
|
||||
key={item?.key}
|
||||
container
|
||||
xs={12}
|
||||
justifyContent="center"
|
||||
gap={1}
|
||||
>
|
||||
{item?.violationImage?.map((option) => (
|
||||
<ShowImage key={i} src={option} />
|
||||
))}
|
||||
</Grid>,
|
||||
],
|
||||
]}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
مشاهده گزارش
|
||||
</Button>
|
||||
) : (
|
||||
"بدون گزارش"
|
||||
),
|
||||
];
|
||||
});
|
||||
|
||||
setTableData(d);
|
||||
}, [data]);
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
dispatch(LOADING_START());
|
||||
dispatch(
|
||||
cityGetHatchingInfoFull({
|
||||
age1: selectedAge1,
|
||||
age2: selectedAge2,
|
||||
tab: "active",
|
||||
textValue: textValue,
|
||||
})
|
||||
);
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`poultry_hatching/?role=${getRoleFromUrl()}&age1=${
|
||||
selectedAge1 ? selectedAge1 : 0
|
||||
}&age2=${
|
||||
selectedAge2 ? selectedAge2 : 0
|
||||
}&search=filter&value=${textValue}&page=${1}&page_size=${perPage}`
|
||||
);
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
dispatch(LOADING_END());
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleRemoveFilter = async (event) => {
|
||||
event.preventDefault();
|
||||
setSelectedAge1(0);
|
||||
setSelectedAge2(0);
|
||||
dispatch(LOADING_START());
|
||||
setTextValue("");
|
||||
dispatch(
|
||||
cityGetHatchingInfoFull({
|
||||
age1: 0,
|
||||
age2: 0,
|
||||
tab: "active",
|
||||
textValue: textValue,
|
||||
})
|
||||
);
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`poultry_hatching?role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&search=filter&value=${textValue}`
|
||||
);
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
} finally {
|
||||
dispatch(LOADING_END());
|
||||
}
|
||||
};
|
||||
|
||||
const [lastUpdateData, setLastUpdateData] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchData() {
|
||||
try {
|
||||
const response = await axios.get(`last_update/?type=poultry_hatching`);
|
||||
setLastUpdateData(response.data);
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
}
|
||||
}
|
||||
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
const tableTitle = (
|
||||
<Grid
|
||||
container
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
gap={2}
|
||||
paddingTop={2}
|
||||
mb={1}
|
||||
xs={12}
|
||||
mt={2}
|
||||
>
|
||||
<form onSubmit={handleSubmit} style={{ flex: 1 }}>
|
||||
<Grid container alignItems="center" gap={SPACING.SMALL} xs={12}>
|
||||
<Grid sx={{ width: { xs: "72px", sm: "80px" } }}>
|
||||
<TextField
|
||||
fullWidth
|
||||
size="small"
|
||||
label="از سن"
|
||||
id="outlined-controlled"
|
||||
value={selectedAge1}
|
||||
onChange={(event) => {
|
||||
setSelectedAge1(event.target.value);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid sx={{ width: { xs: "72px", sm: "80px" } }}>
|
||||
<TextField
|
||||
fullWidth
|
||||
size="small"
|
||||
label="تا سن"
|
||||
id="outlined-controlled"
|
||||
value={selectedAge2}
|
||||
onChange={(event) => {
|
||||
setSelectedAge2(event.target.value);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<TextField
|
||||
id="outlined-basic"
|
||||
size="small"
|
||||
label="جستجو"
|
||||
variant="outlined"
|
||||
value={textValue}
|
||||
sx={{ maxWidth: { xs: "100%", sm: 250 } }}
|
||||
onChange={handleTextChange}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter") {
|
||||
handleSubmit(e);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Button type="submit" endIcon={<RiSearchLine />}>
|
||||
جستجو
|
||||
</Button>
|
||||
<Tooltip title="خروجی اکسل" px={0}>
|
||||
<Button
|
||||
color="success"
|
||||
onClick={() => {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "فایل اکسل در حال دانلود می باشد، این علمیات ممکن است زمان بر باشد لطفا صبر کنید.",
|
||||
severity: "success",
|
||||
});
|
||||
const link = `${
|
||||
axios.defaults.baseURL
|
||||
}0/hatching_excel/?role=${getRoleFromUrl()}&key=${userKey}&age1=${
|
||||
selectedAge1 ? selectedAge1 : 0
|
||||
}&age2=${
|
||||
selectedAge2 ? selectedAge2 : 0
|
||||
}&search=filter&value=${textValue}`;
|
||||
window.location.href = link;
|
||||
}}
|
||||
>
|
||||
<RiFileExcel2Fill size={32} />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
</form>
|
||||
<Button onClick={handleRemoveFilter} color="error">
|
||||
حذف فیلتر
|
||||
</Button>
|
||||
</Grid>
|
||||
);
|
||||
const { hatchingInfoFull } = useSelector((state) => state.citySlice);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
cityGetHatchingInfoFull({
|
||||
age1: selectedAge1,
|
||||
age2: selectedAge2,
|
||||
tab: "active",
|
||||
textValue: textValue,
|
||||
})
|
||||
);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Grid alignItems="center" justifyContent="center" mt={2}>
|
||||
<Grid alignItems="center" justifyContent="center" isDashboard xs={12}>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
title={
|
||||
lastUpdateData &&
|
||||
`آخرین بروزرسانی : ${formatTime(lastUpdateData)} ${" "}`
|
||||
}
|
||||
columns={[
|
||||
"تعداد فارم",
|
||||
"تعداد جوجه ریزی",
|
||||
"حجم کل جوجه ریزی",
|
||||
"حجم باقی مانده در سالن",
|
||||
"حجم کشتار شده",
|
||||
"وزن کشتار شده",
|
||||
"حجم کل تلفات",
|
||||
"حجم تلفات اتحادیه",
|
||||
"حجم تلفات دامپزشک",
|
||||
"مانده سالن ( 20 تا 30 روزه)",
|
||||
"مانده سالن ( 30 تا 40 روزه)",
|
||||
"مانده سالن ( 40 تا 50 روزه)",
|
||||
"مانده سالن ( 50 تا 60 روزه)",
|
||||
"بیشتر از 60 روزه",
|
||||
]}
|
||||
data={[
|
||||
[
|
||||
hatchingInfoFull?.poultries?.toLocaleString(),
|
||||
hatchingInfoFull?.hatchings?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingQuantity?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingLeftOverQuantity?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingKilledQuantity?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingKilledWeight?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingAllLosses?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingUnionLosses?.toLocaleString(),
|
||||
hatchingInfoFull?.totalHatchingVetLosses?.toLocaleString(),
|
||||
hatchingInfoFull?.age2030?.toLocaleString(),
|
||||
hatchingInfoFull?.age3040?.toLocaleString(),
|
||||
hatchingInfoFull?.age4050?.toLocaleString(),
|
||||
hatchingInfoFull?.age5060?.toLocaleString(),
|
||||
hatchingInfoFull?.ageMoreThan60?.toLocaleString(),
|
||||
],
|
||||
]}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
{tableTitle}
|
||||
|
||||
<ResponsiveTable
|
||||
data={tableData}
|
||||
columns={[
|
||||
"عملیات",
|
||||
"جزئیات",
|
||||
"ردیف",
|
||||
"وضعیت",
|
||||
"شماره مجوز جوجه ریزی",
|
||||
"شناسه یکتا",
|
||||
"مجوز بهداشتی جوجه ریزی",
|
||||
// "نوع تعهد",
|
||||
"نام فارم",
|
||||
"مرغدار",
|
||||
"بهره برداری",
|
||||
"مالکیت",
|
||||
"ارتباط",
|
||||
"شهر/تعاونی",
|
||||
"دامپزشک فارم",
|
||||
"سالن",
|
||||
"دوره جوجه ریزی",
|
||||
"تاریخ ثبت جوجه ریزی",
|
||||
"تاریخ جوجه ریزی",
|
||||
"میانگین سن کشتار",
|
||||
"پیش بینی تاریخ کشتار",
|
||||
"نژاد",
|
||||
"سن",
|
||||
"حجم جوجه ریزی",
|
||||
"حجم افزایشی",
|
||||
"تلفات دامپزشک",
|
||||
"تلفات اتحادیه",
|
||||
"تلفات کل",
|
||||
"حجم تعهد دولتی",
|
||||
"حجم تعهد آزاد",
|
||||
"حجم کشتار دولتی",
|
||||
"وزن کشتار دولتی",
|
||||
"حجم کشتار آزاد",
|
||||
"وزن کشتار شده آزاد",
|
||||
"حجم فروش به خارج استان",
|
||||
"وزن فروش به خارج استان",
|
||||
"حجم اختلاف کشتار",
|
||||
"وزن اختلاف کشتار",
|
||||
"تخصیصات بدون بار",
|
||||
"حجم تخصیصات بدون بار",
|
||||
"وزن تخصیصات بدون بار",
|
||||
"حجم کشتار شده",
|
||||
"حجم مانده در سالن",
|
||||
"درصد مانده در سالن",
|
||||
" تلفات",
|
||||
" کشتار شده",
|
||||
" باقی مانده در سالن",
|
||||
"تایید تخلیه رصدیار",
|
||||
" تایید تخلیه در سماصط",
|
||||
"وزن تعهد دولتی",
|
||||
"وزن کشتار دولتی",
|
||||
"وزن کشتار آزاد",
|
||||
"میانگین وزن کشتار",
|
||||
"وزن کل کشتار شده",
|
||||
"تعداد کشتار فعال",
|
||||
"تعداد درخواست کشتار",
|
||||
"تعداد بارها",
|
||||
"حجم بارها",
|
||||
"وزن بارها",
|
||||
"حجم بارهای تحویلی",
|
||||
"وزن بارهای تحویلی",
|
||||
"حجم زنجیره",
|
||||
"وزن زنجیره",
|
||||
"حجم صادرات",
|
||||
"وزن صادرات",
|
||||
"بارهای ورودی به انبار",
|
||||
"حجم لاشه های انبار",
|
||||
"وزن لاشه های انبار",
|
||||
"درصد افت بارها",
|
||||
"آخرین تغییر",
|
||||
"سازنده جوجه ریزی",
|
||||
"گزارش",
|
||||
]}
|
||||
handlePageChange={handlePageChange}
|
||||
totalRows={totalRows}
|
||||
page={page}
|
||||
perPage={perPage}
|
||||
handlePerRowsChange={handlePerRowsChange}
|
||||
title="جوجه ریزی های فعال"
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,119 @@
|
||||
import { Button, IconButton, Popover, Tooltip } from "@mui/material";
|
||||
import { useContext, useState } from "react";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import TuneIcon from "@mui/icons-material/Tune";
|
||||
import DeleteIcon from "@mui/icons-material/Delete";
|
||||
import { CLOSE_MODAL, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { cityDeleteIncreaseHatchingeService } from "../../services/city-increase-hatching";
|
||||
|
||||
export const CityIncreaseHatchingOperation = ({ item, updateTable }) => {
|
||||
const dispatch = useDispatch();
|
||||
const [anchorEl, setAnchorEl] = useState(null);
|
||||
const [openNotif] = useContext(AppContext);
|
||||
|
||||
const handleClick = (event) => {
|
||||
setAnchorEl(event.currentTarget);
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setAnchorEl(null);
|
||||
};
|
||||
|
||||
const open = Boolean(anchorEl);
|
||||
const id = open ? "popover" : undefined;
|
||||
|
||||
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">
|
||||
<Tooltip title={"حذف"} placement="left-start">
|
||||
<IconButton
|
||||
aria-label="delete"
|
||||
color="error"
|
||||
onClick={() => {
|
||||
handleClose();
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "آیا مطمئن هستید؟",
|
||||
content: (
|
||||
<Grid container spacing={2}>
|
||||
<Grid item>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="error"
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
cityDeleteIncreaseHatchingeService(item?.key)
|
||||
).then((r) => {
|
||||
if (r.payload.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.error,
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
updateTable();
|
||||
dispatch(CLOSE_MODAL());
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.data.result,
|
||||
severity: "success",
|
||||
});
|
||||
}
|
||||
});
|
||||
}}
|
||||
>
|
||||
تایید
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Button
|
||||
onClick={() => {
|
||||
dispatch(CLOSE_MODAL());
|
||||
}}
|
||||
>
|
||||
لغو
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
),
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
</div>
|
||||
</Popover>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,240 @@
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import {
|
||||
Autocomplete,
|
||||
Button,
|
||||
Stack,
|
||||
TextField,
|
||||
Typography,
|
||||
Paper,
|
||||
} from "@mui/material";
|
||||
import { useFormik } from "formik";
|
||||
import { Yup } from "../../../../lib/yup/yup";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { DRAWER } from "../../../../lib/redux/slices/appSlice";
|
||||
import { slaughterGetPoultriesService } from "../../../slaughter-house/services/salughter-get-poultries";
|
||||
import { avicultureGetHatchingDataForIncreaseHatching } from "../../../aviculture/services/aviculture-get-hatching-data";
|
||||
import {
|
||||
cityEditIncreaseHatchingeService,
|
||||
cityIncreaseHatchingeService,
|
||||
} from "../../services/city-increase-hatching";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
|
||||
export const CityIncreaseHatchingSubmitDiffrence = ({
|
||||
updateTable,
|
||||
isEdit,
|
||||
item,
|
||||
}) => {
|
||||
const [poultryData, setPoultryData] = useState([]);
|
||||
const [selectedPoultryInfo, setSelectedPoultryInfo] = useState(null);
|
||||
const [openNotif] = useContext(AppContext);
|
||||
const dispatch = useDispatch();
|
||||
const { slaughterGetPoultries } = useSelector(
|
||||
(state) => state.slaughterSlice
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(slaughterGetPoultriesService());
|
||||
}, []);
|
||||
|
||||
const initialValues = {
|
||||
poultry: item?.poultrykey || null,
|
||||
hatching_key: item?.hatchingkey || null,
|
||||
quantity: item?.quantity || null,
|
||||
message: item?.message || null,
|
||||
};
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
poultry: Yup.string().required("انتخاب مرغدار الزامی است"),
|
||||
hatching_key: Yup.string().required("انتخاب محل پرورش الزامی است"),
|
||||
quantity: Yup.number()
|
||||
.typeError("عدد وارد کنید")
|
||||
.required("حجم الزامی است"),
|
||||
message: Yup.string()
|
||||
.typeError("پر کردن این فیلد الزامی است")
|
||||
.required("پیام الزامی است"),
|
||||
});
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues,
|
||||
validationSchema,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (formik.values.poultry) {
|
||||
dispatch(
|
||||
avicultureGetHatchingDataForIncreaseHatching(formik.values.poultry, {
|
||||
increase: true,
|
||||
})
|
||||
).then((res) => {
|
||||
setPoultryData(res.payload.data || []);
|
||||
});
|
||||
}
|
||||
}, [formik.values.poultry]);
|
||||
|
||||
return (
|
||||
<Stack spacing={2}>
|
||||
<Autocomplete
|
||||
id="poultry"
|
||||
disableClearable
|
||||
options={slaughterGetPoultries?.map((item) => ({
|
||||
label: `${item.unitName} (${item.user?.fullname})(${item.user?.mobile})`,
|
||||
value: item.key,
|
||||
}))}
|
||||
getOptionLabel={(option) => option.label}
|
||||
onChange={(_, value) => {
|
||||
formik.setFieldValue("poultry", value.value);
|
||||
formik.setFieldValue("hatching_key", null);
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
{...params}
|
||||
label="انتخاب مرغدار"
|
||||
error={formik.touched.poultry && Boolean(formik.errors.poultry)}
|
||||
helperText={formik.touched.poultry && formik.errors.poultry}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
<Autocomplete
|
||||
id="hatching_key"
|
||||
disableClearable
|
||||
disabled={!formik.values.poultry}
|
||||
options={poultryData?.map((item) => ({
|
||||
label: item?.poultry?.unitName || "-",
|
||||
value: item?.key,
|
||||
}))}
|
||||
getOptionLabel={(option) => option.label}
|
||||
onChange={(_, value) => {
|
||||
formik.setFieldValue("hatching_key", value?.value);
|
||||
const selected = poultryData.find((i) => i.key === value?.value);
|
||||
setSelectedPoultryInfo(selected);
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
{...params}
|
||||
label="انتخاب محل پرورش"
|
||||
error={
|
||||
formik.touched.hatching_key && Boolean(formik.errors.hatching_key)
|
||||
}
|
||||
helperText={
|
||||
formik.touched.hatching_key && formik.errors.hatching_key
|
||||
}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
{selectedPoultryInfo && (
|
||||
<Paper variant="outlined" sx={{ p: 2, borderRadius: 2 }}>
|
||||
<Typography>
|
||||
شماره مجوز جوجه ریزی:{" "}
|
||||
{selectedPoultryInfo?.licenceNumber?.toLocaleString()}
|
||||
</Typography>
|
||||
<Typography>
|
||||
شناسه یکتا مرغدار :{" "}
|
||||
{selectedPoultryInfo?.poultry?.breedingUniqueId?.toLocaleString()}
|
||||
</Typography>
|
||||
<Typography>
|
||||
حجم جوجه ریزی:
|
||||
{selectedPoultryInfo?.quantity?.toLocaleString()}قطعه
|
||||
</Typography>
|
||||
|
||||
<Typography>
|
||||
سن جوجه: {selectedPoultryInfo?.chickenAge?.toLocaleString()} روز
|
||||
</Typography>
|
||||
<Typography>
|
||||
مانده در سالن: {selectedPoultryInfo?.leftOver?.toLocaleString()}
|
||||
قطعه
|
||||
</Typography>
|
||||
<Typography>
|
||||
حجم کشتار شده:
|
||||
{selectedPoultryInfo?.killedQuantity?.toLocaleString()} قطعه
|
||||
</Typography>
|
||||
<Typography>
|
||||
نژاد: {selectedPoultryInfo?.chickenBreed?.toLocaleString()}
|
||||
</Typography>
|
||||
|
||||
<Typography>
|
||||
تلفات: {selectedPoultryInfo?.totalLosses?.toLocaleString("fa-IR")}
|
||||
قطعه
|
||||
</Typography>
|
||||
</Paper>
|
||||
)}
|
||||
|
||||
<TextField
|
||||
label="تعداد (قطعه)"
|
||||
name="quantity"
|
||||
value={formik.values.quantity}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
error={formik.touched.quantity && Boolean(formik.errors.quantity)}
|
||||
helperText={formik.touched.quantity && formik.errors.quantity}
|
||||
fullWidth
|
||||
/>
|
||||
|
||||
<TextField
|
||||
label="دلیل افزایش حجم"
|
||||
name="message"
|
||||
multiline
|
||||
rows={3}
|
||||
value={formik.values.message}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
error={formik.touched.message && Boolean(formik.errors.message)}
|
||||
helperText={formik.touched.message && formik.errors.message}
|
||||
fullWidth
|
||||
/>
|
||||
|
||||
<Button
|
||||
variant="contained"
|
||||
fullWidth
|
||||
disabled={
|
||||
!(
|
||||
formik.isValid &&
|
||||
formik.values.poultry &&
|
||||
formik.values.hatching_key &&
|
||||
formik.values.quantity &&
|
||||
formik.values.message
|
||||
)
|
||||
}
|
||||
onClick={() => {
|
||||
const payload = {
|
||||
hatching_key: formik.values.hatching_key,
|
||||
quantity: parseInt(formik.values.quantity),
|
||||
message: formik.values.message,
|
||||
registerer_role: getRoleFromUrl(),
|
||||
};
|
||||
|
||||
const action = isEdit
|
||||
? cityEditIncreaseHatchingeService({
|
||||
...payload,
|
||||
key: item?.key,
|
||||
})
|
||||
: cityIncreaseHatchingeService(payload);
|
||||
|
||||
dispatch(action).then((res) => {
|
||||
if (res.payload.error) {
|
||||
openNotif({
|
||||
msg: "مشکلی پیش آمده است!",
|
||||
severity: "error",
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
});
|
||||
} else {
|
||||
openNotif({
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
});
|
||||
updateTable();
|
||||
dispatch(DRAWER({ right: false, bottom: false, content: null }));
|
||||
}
|
||||
});
|
||||
}}
|
||||
>
|
||||
{isEdit ? "ویرایش" : "ثبت"}
|
||||
</Button>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,182 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Button, TextField } from "@mui/material";
|
||||
import { useDispatch } from "react-redux";
|
||||
import axios from "axios";
|
||||
import { RiSearchLine } from "react-icons/ri";
|
||||
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 { formatTime } from "../../../../utils/formatTime";
|
||||
|
||||
import { CityIncreaseHatchingOperation } from "../city-increase-hatching-operation/CityIncreaseHatchingOperation";
|
||||
import { CityIncreaseHatchingSubmitDiffrence } from "../city-increase-hatching-submit-diffrence/CityIncreaseHatchingSubmitDiffrence";
|
||||
|
||||
export const CityIncreaseHatching = ({ state }) => {
|
||||
const dispatch = useDispatch();
|
||||
const handleTextChange = (event) => {
|
||||
setTextValue(event.target.value);
|
||||
};
|
||||
|
||||
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 fetchApiData = async (page) => {
|
||||
dispatch(LOADING_START());
|
||||
const response = await axios.get(
|
||||
`hatching-increase-request/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}`
|
||||
);
|
||||
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?.hatching?.poultry?.unitName} (${item?.hatching?.poultry?.user?.mobile})`,
|
||||
item?.hatching?.licenceNumber,
|
||||
item?.hatching?.poultry?.breedingUniqueId,
|
||||
item?.hatchingQuantity?.toLocaleString(),
|
||||
item?.hatchingKillQuantity?.toLocaleString(),
|
||||
item?.hatchingLosses?.toLocaleString(),
|
||||
item?.hatchingLeftOver?.toLocaleString(),
|
||||
item?.quantity?.toLocaleString(),
|
||||
`${item?.registererName} (${item?.registererMobile})`,
|
||||
formatTime(item?.date),
|
||||
item?.message,
|
||||
<CityIncreaseHatchingOperation
|
||||
key={i}
|
||||
updateTable={updateTable}
|
||||
item={item}
|
||||
/>,
|
||||
];
|
||||
});
|
||||
|
||||
setTableData(d);
|
||||
}, [data, state]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchApiData(1);
|
||||
}, [dispatch, perPage, state]);
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
dispatch(LOADING_START());
|
||||
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`hatching-increase-request/?role=${getRoleFromUrl()}&search=filter&value=${textValue}&page=${1}&page_size=${perPage}`
|
||||
);
|
||||
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}
|
||||
>
|
||||
{getRoleFromUrl() !== "KillHouse" && (
|
||||
<Grid>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
DRAWER({
|
||||
right: !(window.innerWidth <= 600),
|
||||
bottom: window.innerWidth <= 600,
|
||||
content: (
|
||||
<CityIncreaseHatchingSubmitDiffrence
|
||||
updateTable={updateTable}
|
||||
/>
|
||||
),
|
||||
title: "افزایش جوجه ریزی",
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
افزایش جوجه ریزی
|
||||
</Button>
|
||||
</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>
|
||||
</Grid>
|
||||
|
||||
<ResponsiveTable
|
||||
data={tableData}
|
||||
columns={[
|
||||
"ردیف",
|
||||
"مرغدار",
|
||||
"شماره مجوز جوجه ریزی",
|
||||
"شناسه یکتا فارم",
|
||||
"حجم جوجه ریزی",
|
||||
"حجم کشتار",
|
||||
"حجم تلفات",
|
||||
"مانده در سالن",
|
||||
"حجم افزایشی",
|
||||
"ثبت کننده",
|
||||
"تاریخ ثبت",
|
||||
"پیغام",
|
||||
"عملیات",
|
||||
]}
|
||||
handlePageChange={handlePageChange}
|
||||
totalRows={totalRows}
|
||||
page={page}
|
||||
perPage={perPage}
|
||||
handlePerRowsChange={handlePerRowsChange}
|
||||
title="افزایش حجم جوجه ریزی"
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,240 @@
|
||||
import React, { useContext, useState } from "react";
|
||||
import {
|
||||
Grid,
|
||||
TextField,
|
||||
Button,
|
||||
Paper,
|
||||
IconButton,
|
||||
Typography,
|
||||
Box,
|
||||
} from "@mui/material";
|
||||
import EditIcon from "@mui/icons-material/Edit";
|
||||
import DeleteIcon from "@mui/icons-material/Delete";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { useFormik } from "formik";
|
||||
import * as Yup from "yup";
|
||||
|
||||
import { citySubmitManageHatchingRenterService } from "../../services/city-submit-manage-hatching-renter";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import {
|
||||
CLOSE_MODAL,
|
||||
LOADING_END,
|
||||
LOADING_START,
|
||||
} from "../../../../lib/redux/slices/appSlice";
|
||||
import { cityHatchingDeleteRenterService } from "../../services/city-delete-manage-hatching-renter";
|
||||
|
||||
export const CityManageHatchingRenter = ({ item, updateTable, readOnly }) => {
|
||||
const [editing, setEditing] = useState(false);
|
||||
const dispatch = useDispatch();
|
||||
const [openNotif] = useContext(AppContext);
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues: {
|
||||
fullName: item?.tenantFullname || "",
|
||||
nationalCode: item?.tenantNationalCode || "",
|
||||
phoneNumber: item?.tenantMobile || "",
|
||||
city: item?.tenantCity || "",
|
||||
},
|
||||
validationSchema: Yup.object({
|
||||
fullName: Yup.string().required("نام و نام خانوادگی الزامی است"),
|
||||
nationalCode: Yup.string()
|
||||
.required("کد ملی الزامی است")
|
||||
.matches(/^[0-9]{10}$/, "کد ملی باید 10 رقم باشد"),
|
||||
phoneNumber: Yup.string()
|
||||
.required("شماره تلفن الزامی است")
|
||||
.matches(/^[0-9]{11}$/, "شماره تلفن باید 11 رقم باشد"),
|
||||
city: Yup.string().required("شهر الزامی است"),
|
||||
}),
|
||||
onSubmit: (values) => {
|
||||
dispatch(LOADING_START());
|
||||
dispatch(
|
||||
citySubmitManageHatchingRenterService({
|
||||
key: item?.key,
|
||||
tenant_fullname: values.fullName,
|
||||
tenant_national_code: values.nationalCode,
|
||||
tenant_mobile: values.phoneNumber,
|
||||
tenant_city: values.city,
|
||||
has_tenant: true,
|
||||
})
|
||||
).then((r) => {
|
||||
dispatch(CLOSE_MODAL());
|
||||
if (r.payload.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "مشکلی پیش آمده است!",
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
formik.resetForm();
|
||||
updateTable();
|
||||
setEditing(false);
|
||||
}
|
||||
dispatch(LOADING_END());
|
||||
});
|
||||
},
|
||||
enableReinitialize: true,
|
||||
});
|
||||
|
||||
const handleEdit = () => {
|
||||
setEditing(true);
|
||||
};
|
||||
|
||||
const handleDelete = () => {
|
||||
dispatch(LOADING_START());
|
||||
|
||||
dispatch(
|
||||
cityHatchingDeleteRenterService({ delete_tenant: true, key: item?.key })
|
||||
).then((r) => {
|
||||
dispatch(CLOSE_MODAL());
|
||||
if (!r.payload.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "مستاجر با موفقیت حذف شد.",
|
||||
severity: "success",
|
||||
});
|
||||
formik.resetForm();
|
||||
updateTable();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const hasRenter = item?.hasTenant && item?.tenantFullname;
|
||||
|
||||
return (
|
||||
<Grid container spacing={3} direction="column">
|
||||
{hasRenter && !editing ? (
|
||||
<Grid item>
|
||||
<Paper elevation={3}>
|
||||
<Box
|
||||
p={2}
|
||||
display="flex"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
>
|
||||
<div>
|
||||
<Typography variant="subtitle1">
|
||||
<strong>نام مستاجر:</strong> {item.tenantFullname}
|
||||
</Typography>
|
||||
<Typography variant="body2">
|
||||
<strong>کد ملی:</strong> {item.tenantNationalCode}
|
||||
</Typography>
|
||||
<Typography variant="body2">
|
||||
<strong>شماره تلفن:</strong> {item.tenantMobile}
|
||||
</Typography>
|
||||
<Typography variant="body2">
|
||||
<strong>شهر:</strong> {item.tenantCity}
|
||||
</Typography>
|
||||
</div>
|
||||
{!readOnly && (
|
||||
<div>
|
||||
<IconButton onClick={handleEdit} color="primary">
|
||||
<EditIcon />
|
||||
</IconButton>
|
||||
<IconButton onClick={handleDelete} color="error">
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
</div>
|
||||
)}
|
||||
</Box>
|
||||
</Paper>
|
||||
</Grid>
|
||||
) : (
|
||||
<Grid item>
|
||||
<Paper elevation={3}>
|
||||
<Box p={2} component="form" onSubmit={formik.handleSubmit}>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12} md={4}>
|
||||
<TextField
|
||||
fullWidth
|
||||
label="نام و نام خانوادگی"
|
||||
name="fullName"
|
||||
value={formik.values.fullName}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
error={
|
||||
formik.touched.fullName && Boolean(formik.errors.fullName)
|
||||
}
|
||||
helperText={
|
||||
formik.touched.fullName && formik.errors.fullName
|
||||
}
|
||||
disabled={readOnly}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={4}>
|
||||
<TextField
|
||||
fullWidth
|
||||
label="کد ملی"
|
||||
name="nationalCode"
|
||||
value={formik.values.nationalCode}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
error={
|
||||
formik.touched.nationalCode &&
|
||||
Boolean(formik.errors.nationalCode)
|
||||
}
|
||||
helperText={
|
||||
formik.touched.nationalCode && formik.errors.nationalCode
|
||||
}
|
||||
disabled={readOnly}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={4}>
|
||||
<TextField
|
||||
fullWidth
|
||||
label="شماره تلفن"
|
||||
name="phoneNumber"
|
||||
value={formik.values.phoneNumber}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
error={
|
||||
formik.touched.phoneNumber &&
|
||||
Boolean(formik.errors.phoneNumber)
|
||||
}
|
||||
helperText={
|
||||
formik.touched.phoneNumber && formik.errors.phoneNumber
|
||||
}
|
||||
disabled={readOnly}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} md={4}>
|
||||
<TextField
|
||||
fullWidth
|
||||
label="شهر"
|
||||
name="city"
|
||||
value={formik.values.city}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
error={formik.touched.city && Boolean(formik.errors.city)}
|
||||
helperText={formik.touched.city && formik.errors.city}
|
||||
disabled={readOnly}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
{!readOnly && (
|
||||
<Box mt={2}>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={formik.isSubmitting}
|
||||
>
|
||||
{hasRenter ? "ذخیره تغییرات" : "ثبت اطلاعات"}
|
||||
</Button>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
</Paper>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,551 @@
|
||||
import {
|
||||
IconButton,
|
||||
Popover,
|
||||
Tooltip,
|
||||
List,
|
||||
ListItemButton,
|
||||
ListItemIcon,
|
||||
ListItemText,
|
||||
} from "@mui/material";
|
||||
import { useContext, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
// import DeleteIcon from "@mui/icons-material/Delete";
|
||||
import ArchiveIcon from "@mui/icons-material/Archive";
|
||||
import AddIcon from "@mui/icons-material/Add";
|
||||
import {
|
||||
DRAWER,
|
||||
OPEN_MODAL,
|
||||
LOADING_START,
|
||||
LOADING_END,
|
||||
} from "../../../../lib/redux/slices/appSlice";
|
||||
import { CityNewKillRequest } from "../city-new-kill-request/CityNewKillRequest";
|
||||
import { CityArchiveHatchingDrawer } from "../city-archive-hatching-drawer/CityArchiveHatchingDrawer";
|
||||
import TuneIcon from "@mui/icons-material/Tune";
|
||||
// import { CityEditHatchingQuantity } from "../city-edit-hatching-quantity/CityEditHatchingQuantity";
|
||||
import axios from "axios";
|
||||
import { RiFileExcel2Fill } from "react-icons/ri";
|
||||
import SmsIcon from "@mui/icons-material/Sms";
|
||||
import { CitySubmitHatchingReport } from "../city-submit-hatching-report/CitySubmitHatchingReport";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
// import { cityGetHatchingsByAge } from "../../services/city-get-hatchings-by-age";
|
||||
import EditIcon from "@mui/icons-material/Edit";
|
||||
import AssignmentReturnedIcon from "@mui/icons-material/AssignmentReturned";
|
||||
import KeyboardReturnIcon from "@mui/icons-material/KeyboardReturn";
|
||||
import { archiveHatchingService } from "../../services/archive-hatching";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { CitySubmitLooses } from "../city-submit-looses/CitySubmitLooses";
|
||||
import PlaylistRemoveIcon from "@mui/icons-material/PlaylistRemove";
|
||||
import { VetFarmSubmitFarmInfoLosses } from "../../../vet-farm/components/vet-farm-submit-farm-info-losses/VetFarmSubmitFarmInfoLosses";
|
||||
import InsertPageBreakIcon from "@mui/icons-material/InsertPageBreak";
|
||||
import { CityManageHatchingRenter } from "../city-manage-hatching-renter/CityManageHatchingRenter";
|
||||
import PersonAddAlt1Icon from "@mui/icons-material/PersonAddAlt1";
|
||||
import { cityGetTicketDiffrentClearanceCode } from "../../services/city-get-ticket-different-clearance-code";
|
||||
import PlayArrowIcon from "@mui/icons-material/PlayArrow";
|
||||
export const CityManageHatchingsOperations = ({
|
||||
item,
|
||||
selectedAge1,
|
||||
selectedAge2,
|
||||
updateTable,
|
||||
readOnly,
|
||||
}) => {
|
||||
const { userProfile } = useSelector((state) => state.userSlice);
|
||||
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 [openNotif] = useContext(AppContext);
|
||||
|
||||
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}
|
||||
>
|
||||
<List sx={{ py: 1, minWidth: 200 }}>
|
||||
{!readOnly && (
|
||||
<>
|
||||
<Tooltip title={"ثبت درخواست کشتار"} placement="left-start">
|
||||
<ListItemButton
|
||||
onClick={() => {
|
||||
handleClose();
|
||||
dispatch(
|
||||
DRAWER({
|
||||
right: !(window.innerWidth <= 600),
|
||||
bottom: window.innerWidth <= 600,
|
||||
title: "ثبت درخواست کشتار جدید",
|
||||
content: (
|
||||
<CityNewKillRequest
|
||||
selectedAge1={selectedAge1}
|
||||
selectedAge2={selectedAge2}
|
||||
userCheck={item.poultry.userprofile.baseOrder}
|
||||
updateTable={updateTable}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
<ListItemIcon sx={{ minWidth: 36, color: "secondary.main" }}>
|
||||
<AddIcon fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary="ثبت درخواست کشتار"
|
||||
primaryTypographyProps={{ variant: "body2" }}
|
||||
/>
|
||||
</ListItemButton>
|
||||
</Tooltip>
|
||||
|
||||
{item?.InteractTypeName === "مستاجر" && (
|
||||
<Tooltip title={"ثبت مستاجر"} placement="left-start">
|
||||
<ListItemButton
|
||||
onClick={() => {
|
||||
handleClose();
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "ثبت مستاجر ",
|
||||
content: (
|
||||
<CityManageHatchingRenter
|
||||
item={item}
|
||||
updateTable={updateTable}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
<ListItemIcon sx={{ minWidth: 36, color: "primary.main" }}>
|
||||
<PersonAddAlt1Icon fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary="ثبت مستاجر"
|
||||
primaryTypographyProps={{ variant: "body2" }}
|
||||
/>
|
||||
</ListItemButton>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
{(getRoleFromUrl() === "ProvinceOperator" ||
|
||||
getRoleFromUrl() === "CityOperator" ||
|
||||
getRoleFromUrl() === "CityPoultry" ||
|
||||
getRoleFromUrl() === "CityJahad" ||
|
||||
getRoleFromUrl() === "CityCommerce" ||
|
||||
getRoleFromUrl() === "AdminX" ||
|
||||
getRoleFromUrl() === "SuperAdmin") && (
|
||||
<Tooltip
|
||||
title={item?.violationReport ? "ویرایش گزارش" : "ثبت گزارش"}
|
||||
placement="left-start"
|
||||
>
|
||||
<ListItemButton
|
||||
onClick={() => {
|
||||
handleClose();
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: item?.violationReport
|
||||
? "ویرایش گزارش"
|
||||
: "ثبت گزارش",
|
||||
content: (
|
||||
<CitySubmitHatchingReport
|
||||
updateTable={updateTable}
|
||||
item={item}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
<ListItemIcon sx={{ minWidth: 36, color: "primary.main" }}>
|
||||
<EditIcon fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary={
|
||||
item?.violationReport ? "ویرایش گزارش" : "ثبت گزارش"
|
||||
}
|
||||
primaryTypographyProps={{ variant: "body2" }}
|
||||
/>
|
||||
</ListItemButton>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
<Tooltip title={"انتقال به بایگانی"} placement="left-start">
|
||||
<ListItemButton
|
||||
onClick={() => {
|
||||
handleClose();
|
||||
dispatch(
|
||||
DRAWER({
|
||||
title: "انتقال به آرشیو",
|
||||
right: !(window.innerWidth <= 600),
|
||||
bottom: window.innerWidth <= 600,
|
||||
content: (
|
||||
<CityArchiveHatchingDrawer
|
||||
selectedAge1={selectedAge1}
|
||||
selectedAge2={selectedAge2}
|
||||
item={item}
|
||||
updateTable={updateTable}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
<ListItemIcon sx={{ minWidth: 36, color: "primary.main" }}>
|
||||
<ArchiveIcon fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary="انتقال به بایگانی"
|
||||
primaryTypographyProps={{ variant: "body2" }}
|
||||
/>
|
||||
</ListItemButton>
|
||||
</Tooltip>
|
||||
|
||||
{(getRoleFromUrl() === "ProvinceOperator" ||
|
||||
getRoleFromUrl() === "CityOperator" ||
|
||||
getRoleFromUrl() === "AdminX" ||
|
||||
getRoleFromUrl() === "SuperAdmin") && (
|
||||
<Tooltip title={"ثبت تلفات"} placement="left-start">
|
||||
<ListItemButton
|
||||
onClick={() => {
|
||||
handleClose();
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "ثبت تلفات",
|
||||
content: (
|
||||
<CitySubmitLooses
|
||||
updateTable={updateTable}
|
||||
item={item}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
<ListItemIcon sx={{ minWidth: 36, color: "error.main" }}>
|
||||
<PlaylistRemoveIcon fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary="ثبت تلفات"
|
||||
primaryTypographyProps={{ variant: "body2" }}
|
||||
/>
|
||||
</ListItemButton>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
<Tooltip
|
||||
title={item?.violation ? "بازگشت از تخلف" : "جوجه ریزی متخلف"}
|
||||
placement="left-start"
|
||||
>
|
||||
<ListItemButton
|
||||
onClick={() => {
|
||||
handleClose();
|
||||
dispatch(
|
||||
archiveHatchingService({
|
||||
key: item?.key,
|
||||
violation: item?.violation ? false : true,
|
||||
})
|
||||
).then((r) => {
|
||||
if (r.payload.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "مشکلی پیش آمده است!",
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
updateTable();
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
}
|
||||
});
|
||||
}}
|
||||
>
|
||||
<ListItemIcon
|
||||
sx={{
|
||||
minWidth: 36,
|
||||
color: item?.violation ? "primary.main" : "error.main",
|
||||
}}
|
||||
>
|
||||
{item?.violation ? (
|
||||
<KeyboardReturnIcon fontSize="small" />
|
||||
) : (
|
||||
<AssignmentReturnedIcon fontSize="small" />
|
||||
)}
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary={
|
||||
item?.violation ? "بازگشت از تخلف" : "جوجه ریزی متخلف"
|
||||
}
|
||||
primaryTypographyProps={{ variant: "body2" }}
|
||||
/>
|
||||
</ListItemButton>
|
||||
</Tooltip>
|
||||
</>
|
||||
)}
|
||||
|
||||
{(getRoleFromUrl() === "VetFarm" ||
|
||||
getRoleFromUrl() === "CityVet" ||
|
||||
getRoleFromUrl() === "VetSupervisor") && (
|
||||
<Tooltip title={"ثبت تلفات پایان دوره"} placement="left-start">
|
||||
<ListItemButton
|
||||
onClick={() => {
|
||||
handleClose();
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "ثبت تلفات پایان دوره",
|
||||
content: (
|
||||
<VetFarmSubmitFarmInfoLosses
|
||||
item={item}
|
||||
updateTable={updateTable}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
<ListItemIcon sx={{ minWidth: 36, color: "error.main" }}>
|
||||
<InsertPageBreakIcon fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary="ثبت تلفات پایان دوره"
|
||||
primaryTypographyProps={{ variant: "body2" }}
|
||||
/>
|
||||
</ListItemButton>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
<Tooltip title="خروجی اکسل" placement="left-start">
|
||||
<ListItemButton
|
||||
component="a"
|
||||
href={`${axios.defaults.baseURL}process-for-each-hatching/?key=${item.key}`}
|
||||
rel="noreferrer"
|
||||
>
|
||||
<ListItemIcon sx={{ minWidth: 36, color: "success.main" }}>
|
||||
<RiFileExcel2Fill size={18} />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary="خروجی اکسل"
|
||||
primaryTypographyProps={{ variant: "body2" }}
|
||||
/>
|
||||
</ListItemButton>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip title="تیکت گزارش کشتار جوجه ریزی" placement="left-start">
|
||||
<ListItemButton
|
||||
onClick={() => {
|
||||
handleClose();
|
||||
dispatch(
|
||||
cityGetTicketDiffrentClearanceCode({
|
||||
licence_number: item?.licenceNumber,
|
||||
mobile: userProfile?.mobile,
|
||||
})
|
||||
).then((r) => {
|
||||
if (r.payload.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "مشکلی پیش آمده است!",
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
updateTable();
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
}
|
||||
});
|
||||
}}
|
||||
>
|
||||
<ListItemIcon sx={{ minWidth: 36, color: "error.main" }}>
|
||||
<SmsIcon fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary="تیکت گزارش کشتار"
|
||||
primaryTypographyProps={{ variant: "body2" }}
|
||||
/>
|
||||
</ListItemButton>
|
||||
</Tooltip>
|
||||
</List>
|
||||
</Popover>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const CityManageHatchingsArchiveActions = ({
|
||||
item,
|
||||
selectedAge1,
|
||||
selectedAge2,
|
||||
updateTable,
|
||||
readOnly,
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
const [openNotif] = useContext(AppContext);
|
||||
const [anchorEl, setAnchorEl] = useState(null);
|
||||
|
||||
const open = Boolean(anchorEl);
|
||||
const popoverId = open ? "archive-activate-popover" : undefined;
|
||||
|
||||
const handleOpen = (event) => {
|
||||
if (readOnly) {
|
||||
return;
|
||||
}
|
||||
setAnchorEl(event.currentTarget);
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setAnchorEl(null);
|
||||
};
|
||||
|
||||
const handleArchiveClick = () => {
|
||||
if (readOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
handleClose();
|
||||
dispatch(
|
||||
DRAWER({
|
||||
title: "انتقال به آرشیو",
|
||||
right: !(window.innerWidth <= 600),
|
||||
bottom: window.innerWidth <= 600,
|
||||
content: (
|
||||
<CityArchiveHatchingDrawer
|
||||
selectedAge1={selectedAge1}
|
||||
selectedAge2={selectedAge2}
|
||||
item={item}
|
||||
updateTable={updateTable}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const handleActivateClick = async () => {
|
||||
if (readOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(LOADING_START());
|
||||
try {
|
||||
const { data } = await axios.put("poultry_hatching/0/", {
|
||||
key: item?.key,
|
||||
unknown: false,
|
||||
});
|
||||
|
||||
dispatch(LOADING_END());
|
||||
|
||||
if (data?.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: data?.error || "فعالسازی ناموفق بود.",
|
||||
severity: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
updateTable();
|
||||
handleClose();
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "فعالسازی با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
} catch (error) {
|
||||
dispatch(LOADING_END());
|
||||
const message =
|
||||
error?.response?.data?.result ||
|
||||
error?.response?.data?.error ||
|
||||
error?.message ||
|
||||
"فعالسازی ناموفق بود.";
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: message,
|
||||
severity: "error",
|
||||
});
|
||||
handleClose();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<IconButton
|
||||
aria-describedby={popoverId}
|
||||
color="primary"
|
||||
onClick={handleOpen}
|
||||
size="small"
|
||||
disabled={readOnly}
|
||||
>
|
||||
<TuneIcon />
|
||||
</IconButton>
|
||||
<Popover
|
||||
id={popoverId}
|
||||
open={open}
|
||||
anchorEl={anchorEl}
|
||||
onClose={handleClose}
|
||||
anchorOrigin={{
|
||||
vertical: "bottom",
|
||||
horizontal: "right",
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: "top",
|
||||
horizontal: "left",
|
||||
}}
|
||||
>
|
||||
<List sx={{ py: 1, minWidth: 160 }}>
|
||||
<ListItemButton onClick={handleArchiveClick} disabled={readOnly}>
|
||||
<ListItemIcon sx={{ minWidth: 36, color: "primary.main" }}>
|
||||
<ArchiveIcon fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary="بایگانی"
|
||||
primaryTypographyProps={{ variant: "body2" }}
|
||||
/>
|
||||
</ListItemButton>
|
||||
<ListItemButton onClick={handleActivateClick} disabled={readOnly}>
|
||||
<ListItemIcon sx={{ minWidth: 36, color: "success.main" }}>
|
||||
<PlayArrowIcon fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary="فعال سازی"
|
||||
primaryTypographyProps={{ variant: "body2" }}
|
||||
/>
|
||||
</ListItemButton>
|
||||
</List>
|
||||
</Popover>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,589 @@
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
// FormControl,
|
||||
// InputLabel,
|
||||
// MenuItem,
|
||||
// Select,
|
||||
// TextField,
|
||||
Tab,
|
||||
Tabs,
|
||||
// Tooltip,
|
||||
// Typography,
|
||||
} from "@mui/material";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
// import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable";
|
||||
// import { ExcelUploadButton } from "../../../../components/excel-upload-button/ExcelUploadButton";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { OPEN_MODAL } from "../../../../lib/redux/slices/appSlice";
|
||||
// import { formatJustDate } from "../../../../utils/formatTime";
|
||||
// import { cityGetHatchings } from "../../services/city-get-hatchings";
|
||||
// import { getSlaughtersKillRequestService } from "../../services/get-slaughters-kill-request";
|
||||
// import { avicultureHatchingRequestsService } from "../../../aviculture/services/aviculture-hatching-requests";
|
||||
import { useFormik } from "formik";
|
||||
// import { RiFileExcel2Fill } from "react-icons/ri";
|
||||
// import axios from "axios";
|
||||
// import { DatePicker } from "@mui/x-date-pickers";
|
||||
// import moment from "moment/moment";
|
||||
// import { CityManageHatchingsOperations } from "../city-manage-hatchings-operations/CityManageHatchingsOperations";
|
||||
// import { cityGetHatchingsByAge } from "../../services/city-get-hatchings-by-age";
|
||||
// import { getFaUserRole } from "../../../../utils/getFaUserRole";
|
||||
import { CityArchiveOldHatchings } from "../city-archive-old-hatchings/CityArchvieOldHatchings";
|
||||
import { cityGetArchiveHatchingsService } from "../../services/city-get-archive-hatchings";
|
||||
import { CityHatchings } from "../city-hatchings/CityHatchings";
|
||||
import { CityHatchingsArchive } from "../city-hatchings-archive/CityHatchingsArchive";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import { CityHatchingInfo } from "../city-hatching-info/CityHatchingInfo";
|
||||
import { CityUpdateHatching } from "../city-update-hatching/CityUpdateHatching";
|
||||
import { ProvinceBarDifference } from "../../../province/components/province-bar-difference/ProvinceBarDifference";
|
||||
import { TransportChickens } from "../transport-chickens/TransportChickens";
|
||||
import { CityHatchingsTotal } from "../city-hatchings-total/CityHatchingsTotal";
|
||||
import { CityHatchingUnassigned } from "../city-hatching-unassigned/CityHatchingUnassigned";
|
||||
|
||||
export const CityManageHatchings = () => {
|
||||
const dispatch = useDispatch();
|
||||
const [, , selectedDate1, , selectedDate2] = useContext(AppContext);
|
||||
// const [dataTable, setDataTable] = useState([]);
|
||||
|
||||
// const [searchClick, setSearchClick] = useState(true);
|
||||
|
||||
// const [dataTableHatchingArchive, setDataTableHatchingArchive] = useState([]);
|
||||
// const [selectedAge1, setSelectedAge1] = useState(45);
|
||||
// const [selectedAge2, setSelectedAge2] = useState(75);
|
||||
|
||||
// const [filterType, setFilterType] = useState("سن");
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues: {
|
||||
numberInput: 0,
|
||||
},
|
||||
});
|
||||
|
||||
const { hatchings, poultryRequestsTotalQuantity, cityGetArchiveHatchings } =
|
||||
useSelector((state) => state.citySlice);
|
||||
|
||||
// const { hourLimitKillRequest } = useSelector((state) => state.citySlice);
|
||||
const { getSlaughtersKillRequest } = useSelector((state) => state.citySlice);
|
||||
|
||||
// useEffect(() => {
|
||||
// dispatch(getSlaughtersKillRequestService());
|
||||
// dispatch(
|
||||
// avicultureHatchingRequestsService({ selectedDate1, selectedDate2 })
|
||||
// );
|
||||
// }, [selectedDate1, selectedDate2]);
|
||||
|
||||
// useEffect(() => {
|
||||
// const past50Day = new Date();
|
||||
// past50Day.setDate(past50Day.getDate() - 45);
|
||||
// setSelectedDate1(moment(past50Day).format("YYYY-MM-DD"));
|
||||
// return () => {
|
||||
// const date = new Date();
|
||||
// setSelectedDate1(moment(date).format("YYYY-MM-DD"));
|
||||
// };
|
||||
// }, []);
|
||||
|
||||
// useEffect(() => {
|
||||
// dispatch(cityGetHatchings({ selectedDate1, selectedDate2 }));
|
||||
// }, [searchClick]);
|
||||
|
||||
// useEffect(() => {
|
||||
// if (searchClick) {
|
||||
// dispatch(cityGetHatchings({ selectedDate1, selectedDate2 }));
|
||||
// setSearchClick(false);
|
||||
// }
|
||||
// }, [selectedDate1]);
|
||||
|
||||
useEffect(() => {
|
||||
if (poultryRequestsTotalQuantity) {
|
||||
formik.setFieldValue(
|
||||
"numberInput",
|
||||
poultryRequestsTotalQuantity?.quantity
|
||||
);
|
||||
}
|
||||
}, [poultryRequestsTotalQuantity]);
|
||||
|
||||
useEffect(() => {
|
||||
// const d = hatchings
|
||||
// ?.filter((item) => item.allowHatching === "pending")
|
||||
// ?.map((item, i) => {
|
||||
// const killedNumber = item.quantity - item.losses - item.leftOver;
|
||||
// const lastChange =
|
||||
// item.lastChange &&
|
||||
// `${item.lastChange.fullName} (${getFaUserRole(
|
||||
// item.lastChange.role
|
||||
// )}) در تاریخ ${formatJustDate(item.lastChange.date)}`;
|
||||
// return [
|
||||
// i + 1,
|
||||
// item.poultry.unitName,
|
||||
// `${item.poultry.userprofile.fullName} (${item.poultry.userprofile.mobile})`,
|
||||
// `${item?.poultry?.address.city.name}/${
|
||||
// item?.poultry?.cityOperator
|
||||
// ? item?.poultry?.cityOperator
|
||||
// : "بدون تعاونی"
|
||||
// }`,
|
||||
// item?.vetFarm?.vetFarmMobile
|
||||
// ? `${item?.vetFarm?.vetFarmFullName} (${item?.vetFarm?.vetFarmMobile})`
|
||||
// : "-",
|
||||
// item.hall,
|
||||
// item.period,
|
||||
// formatJustDate(item?.createDate),
|
||||
// formatJustDate(item?.date),
|
||||
// item.chickenBreed,
|
||||
// item.age,
|
||||
// item.quantity.toLocaleString(),
|
||||
// `${item.losses} (%${((item.losses * 100) / item.quantity).toFixed(
|
||||
// 0
|
||||
// )})`,
|
||||
// killedNumber.toLocaleString() +
|
||||
// ` (%${((killedNumber * 100) / item.quantity).toFixed(0)})`,
|
||||
// `${item.leftOver.toLocaleString()} (%${(
|
||||
// (item.leftOver * 100) /
|
||||
// item.quantity
|
||||
// ).toFixed(0)})`,
|
||||
// item?.activeKill?.activeKill ? "دارد" : "ندارد",
|
||||
// item?.activeKill?.countOfRequest
|
||||
// ? item.activeKill.countOfRequest
|
||||
// : "-",
|
||||
// item.lastChange ? lastChange : "-",
|
||||
// // <CityManageHatchingsOperations
|
||||
// // selectedAge1={selectedAge1}
|
||||
// // selectedAge2={selectedAge2}
|
||||
// // item={item}
|
||||
// // key={i}
|
||||
// // />,
|
||||
// ];
|
||||
// });
|
||||
// setDataTable(d);
|
||||
// const hatchingArchiveData = cityGetArchiveHatchings?.map((item, i) => {
|
||||
// const killedNumber = item.quantity - item.losses - item.leftOver;
|
||||
// return [
|
||||
// i + 1,
|
||||
// item.poultry.unitName,
|
||||
// item.poultry.userprofile.baseOrder,
|
||||
// item.poultry.userprofile.mobile,
|
||||
// item.hall,
|
||||
// item.period,
|
||||
// formatJustDate(item?.createDate),
|
||||
// formatJustDate(item?.date),
|
||||
// item.chickenBreed,
|
||||
// item.age,
|
||||
// item.quantity,
|
||||
// `${item.losses} (%${((item.losses * 100) / item.quantity).toFixed(0)})`,
|
||||
// killedNumber +
|
||||
// ` (%${((killedNumber * 100) / item.quantity).toFixed(0)})`,
|
||||
// `${item.leftOver} (%${((item.leftOver * 100) / item.quantity).toFixed(
|
||||
// 0
|
||||
// )})`,
|
||||
// ];
|
||||
// });
|
||||
// setDataTableHatchingArchive(hatchingArchiveData);
|
||||
}, [hatchings, getSlaughtersKillRequest, cityGetArchiveHatchings]);
|
||||
|
||||
const [view, setView] = useState("active");
|
||||
|
||||
const handleChange = (event, newValue) => {
|
||||
setView(newValue);
|
||||
};
|
||||
|
||||
// const selectAges = Array.from({ length: 75 }, (_, i) => i + 1);
|
||||
|
||||
// useEffect(() => {
|
||||
// dispatch(cityGetHatchingsByAge({ selectedAge1, selectedAge2 }));
|
||||
// }, [selectedAge1, selectedAge2]);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(cityGetArchiveHatchingsService({ selectedDate1, selectedDate2 }));
|
||||
}, [selectedDate1, selectedDate2]);
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
gap={SPACING.SMALL}
|
||||
// justifyContent={{ xs: "center", lg: "space-between" }}
|
||||
alignSelf="center"
|
||||
alignItems="center"
|
||||
style={{ display: "block" }}
|
||||
// direction={{ xs: "column", lg: "row" }}
|
||||
>
|
||||
<Grid container alignItems="center" justifyContent="center">
|
||||
<Tabs
|
||||
value={view}
|
||||
onChange={handleChange}
|
||||
centered
|
||||
aria-label="hatching tabs"
|
||||
scrollButtons="auto"
|
||||
variant="scrollable"
|
||||
allowScrollButtonsMobile
|
||||
sx={{
|
||||
width: "100%",
|
||||
overflow: "hidden",
|
||||
borderBottom: "1px solid #E0E0E0",
|
||||
}}
|
||||
>
|
||||
<Tab label="جوجه ریزی های فعال" value="active" />
|
||||
<Tab label="تعیین تکلیف نشدهها" value="pending" />
|
||||
<Tab label="بایگانی جوجه ریزی ها" value="archive" />
|
||||
<Tab label="کل جوجه ریزیها" value="total" />
|
||||
{getRoleFromUrl() !== "CityPoultry" && (
|
||||
<Tab label="گزارش فارم ها" value="info" />
|
||||
)}
|
||||
{/* {(getRoleFromUrl() === "CityOperator" ||
|
||||
getRoleFromUrl() === "ProvinceOperator" ||
|
||||
getRoleFromUrl() === "AdminX" ||
|
||||
getRoleFromUrl() === "SuperAdmin") && (
|
||||
<Tab label="اختلاف کشتار" value="bar-difference" />
|
||||
)} */}
|
||||
{/* {(getRoleFromUrl() === "AdminX" ||
|
||||
getRoleFromUrl() === "SuperAdmin") && (
|
||||
<Tab label="آپدیت جوجه ریزی" value="hatchingUpdate" />
|
||||
)} */}
|
||||
{/* {(getRoleFromUrl() === "AdminX" ||
|
||||
getRoleFromUrl() === "SuperAdmin") && (
|
||||
<Tab label="گزارش حمل مرغ زنده" value="transport-chickens" />
|
||||
)} */}
|
||||
{/* {(getRoleFromUrl() === "AdminX" ||
|
||||
getRoleFromUrl() === "SuperAdmin") && (
|
||||
<Tab label="پایش کشوری" value="national-info" />
|
||||
)}*/}
|
||||
</Tabs>
|
||||
</Grid>
|
||||
{view === "hatchingUpdate" && <CityUpdateHatching />}
|
||||
{view === "transport-chickens" && <TransportChickens />}
|
||||
{/* {view === "national-info" && <NationalInfo />} */}
|
||||
{view === "active" && (
|
||||
<Box
|
||||
container
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
// display="flex"
|
||||
style={{ width: "100%" }}
|
||||
pt={2}
|
||||
>
|
||||
<Grid
|
||||
container
|
||||
gap={SPACING.SMALL}
|
||||
justifyContent="space-between"
|
||||
mt={SPACING.TINY}
|
||||
px={{
|
||||
xs: 2,
|
||||
sm: 0,
|
||||
}}
|
||||
>
|
||||
{/* <Button
|
||||
className="first-step"
|
||||
variant={"contained"}
|
||||
disabled={true}
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
DRAWER({
|
||||
title: "ثبت اطلاعات جوجه ریزی",
|
||||
right: !(window.innerWidth <= 600),
|
||||
bottom: window.innerWidth <= 600,
|
||||
content: <CityNewHatchingRequest />,
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
ثبت جوجه ریزی جدید
|
||||
</Button> */}
|
||||
{getRoleFromUrl() !== "CityOperator" && (
|
||||
<Button
|
||||
className="first-step"
|
||||
variant={"contained"}
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "انتقال به بایگانی",
|
||||
content: <CityArchiveOldHatchings />,
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
انتقال به بایگانی
|
||||
</Button>
|
||||
)}
|
||||
</Grid>
|
||||
{/* <ExcelUploadButton uploadUrl={""} /> */}
|
||||
</Box>
|
||||
)}
|
||||
<Grid
|
||||
alignItems={"center"}
|
||||
gap={SPACING.SMALL}
|
||||
direction={"column"}
|
||||
px={1}
|
||||
>
|
||||
<Grid container mt={SPACING.SMALL}>
|
||||
{view === "active" && <CityHatchings />}
|
||||
{view === "info" && <CityHatchingInfo />}
|
||||
{view === "bar-difference" && <ProvinceBarDifference />}
|
||||
{view === "total" && <CityHatchingsTotal />}
|
||||
{view === "pending" && <CityHatchingUnassigned />}
|
||||
{/* {view === "active" && (
|
||||
<Grid container xs={12}>
|
||||
<AdvancedTable
|
||||
name={
|
||||
<Grid
|
||||
container
|
||||
alignItems="center"
|
||||
gap={SPACING.SMALL}
|
||||
justifyContent="space-between"
|
||||
>
|
||||
<Grid container alignItems="center" gap={SPACING.SMALL}>
|
||||
<Grid>
|
||||
<Typography fontWeight={"bold"}>
|
||||
دوره های فعال جوجه ریزی
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<Button
|
||||
variant="outlined"
|
||||
onClick={() => {
|
||||
if (filterType === "سن") {
|
||||
setFilterType("تاریخ");
|
||||
} else {
|
||||
setFilterType("سن");
|
||||
}
|
||||
}}
|
||||
>
|
||||
فیلتر جستجو
|
||||
</Button>
|
||||
</Grid>
|
||||
{filterType === "سن" && (
|
||||
<Grid container alignItems="center" gap={SPACING.SMALL}>
|
||||
<Grid>
|
||||
<Typography variant="caption">
|
||||
فیلتر براساس سن:
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid style={{ width: "80px" }}>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel id="demo-simple-select-label">
|
||||
از سن
|
||||
</InputLabel>
|
||||
<Select
|
||||
MenuProps={{
|
||||
PaperProps: {
|
||||
style: {
|
||||
maxHeight: 200, // Change the maximum height as needed
|
||||
width: 80, // Change the width as needed
|
||||
},
|
||||
},
|
||||
}}
|
||||
labelId="demo-simple-select-label"
|
||||
id="demo-simple-select"
|
||||
value={selectedAge1}
|
||||
label="از سن"
|
||||
onChange={(event) =>
|
||||
setSelectedAge1(event.target.value)
|
||||
}
|
||||
>
|
||||
{selectAges.map((age) => (
|
||||
<MenuItem key={age} value={age}>
|
||||
{age}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Grid>
|
||||
<Grid style={{ width: "80px" }}>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel id="demo-simple-select-label">
|
||||
تا سن
|
||||
</InputLabel>
|
||||
<Select
|
||||
MenuProps={{
|
||||
PaperProps: {
|
||||
style: {
|
||||
maxHeight: 200, // Change the maximum height as needed
|
||||
width: 80, // Change the width as needed
|
||||
},
|
||||
},
|
||||
}}
|
||||
labelId="demo-simple-select-label"
|
||||
id="demo-simple-select"
|
||||
value={selectedAge2}
|
||||
label="تا سن"
|
||||
onChange={(event) =>
|
||||
setSelectedAge2(event.target.value)
|
||||
}
|
||||
>
|
||||
{selectAges.map((age) => (
|
||||
<MenuItem key={age} value={age}>
|
||||
{age}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
|
||||
{filterType === "تاریخ" && (
|
||||
<Grid container alignItems="center" gap={SPACING.SMALL}>
|
||||
<Grid>
|
||||
<Typography variant="caption">
|
||||
فیلتر براساس تاریخ:
|
||||
</Typography>
|
||||
</Grid>
|
||||
<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
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
cityGetHatchings({
|
||||
selectedDate1,
|
||||
selectedDate2,
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
جستجو
|
||||
</Button>
|
||||
</Grid>
|
||||
<Tooltip title="خروجی اکسل">
|
||||
<a
|
||||
href={`${axios.defaults.baseURL}0/hatching_excel/?start=${selectedDate1}&end=${selectedDate2}`}
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Button color="success">
|
||||
<RiFileExcel2Fill size={32} />
|
||||
</Button>
|
||||
</a>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
}
|
||||
data={dataTable}
|
||||
columns={[
|
||||
"ردیف",
|
||||
"نام فارم",
|
||||
"مرغدار",
|
||||
"شهر/تعاونی",
|
||||
"دامپزشک فارم",
|
||||
"سالن",
|
||||
"دوره جوجه ریزی",
|
||||
"تاریخ ثبت جوجه ریزی",
|
||||
"تاریخ جوجه ریزی",
|
||||
"نژاد",
|
||||
"سن",
|
||||
"تعداد جوجه ریزی",
|
||||
"تلفات دوره",
|
||||
"کشتار شده",
|
||||
"مانده در سالن",
|
||||
"کشتار فعال",
|
||||
"تعداد درخواست کشتار",
|
||||
"آخرین تغییر",
|
||||
"عملیات",
|
||||
]}
|
||||
/>
|
||||
</Grid>
|
||||
)} */}
|
||||
{view === "archive" && (
|
||||
<CityHatchingsArchive />
|
||||
// <Grid container width="100%" flex="1">
|
||||
// <AdvancedTable
|
||||
// name={
|
||||
// <Grid container alignItems="center" gap={SPACING.SMALL}>
|
||||
// <Grid>
|
||||
// <Typography>بایگانی جوجه ریزی</Typography>
|
||||
// </Grid>
|
||||
// <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="خروجی اکسل">
|
||||
// <a
|
||||
// href={`${axios.defaults.baseURL}0/hatching_excel/?start=${selectedDate1}&end=${selectedDate2}`}
|
||||
// rel="noreferrer"
|
||||
// >
|
||||
// <Button color="success">
|
||||
// <RiFileExcel2Fill size={32} />
|
||||
// </Button>
|
||||
// </a>
|
||||
// </Tooltip>
|
||||
// </Grid>
|
||||
// }
|
||||
// data={dataTableHatchingArchive}
|
||||
// columns={[
|
||||
// "ردیف",
|
||||
// "نام فارم",
|
||||
// "کدکاربری",
|
||||
// "تلفن",
|
||||
// "سالن",
|
||||
// "دوره جوجه ریزی",
|
||||
// "تاریخ ثبت جوجه ریزی",
|
||||
// "تاریخ جوجه ریزی",
|
||||
// "نژاد",
|
||||
// "سن",
|
||||
// "تعداد جوجه ریزی",
|
||||
// "تلفات دوره",
|
||||
// "کشتار شده",
|
||||
// "مانده در سالن",
|
||||
// ]}
|
||||
// />
|
||||
// </Grid>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,326 @@
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import {
|
||||
Autocomplete,
|
||||
Button,
|
||||
FormControl,
|
||||
FormHelperText,
|
||||
IconButton,
|
||||
InputLabel,
|
||||
MenuItem,
|
||||
Select,
|
||||
TextField,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import { useFormik } from "formik";
|
||||
import { Yup } from "../../../../lib/yup/yup";
|
||||
import { useEffect } from "react";
|
||||
import moment from "moment/moment";
|
||||
import { DatePicker } from "@mui/x-date-pickers";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { useState } from "react";
|
||||
import {
|
||||
DRAWER,
|
||||
LOADING_END,
|
||||
LOADING_START,
|
||||
} from "../../../../lib/redux/slices/appSlice";
|
||||
import SearchIcon from "@mui/icons-material/Search";
|
||||
|
||||
import { useContext } from "react";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom";
|
||||
import { cityGetPoultryData } from "../../services/city-get-poultry-data";
|
||||
import { avicultureNewHatching } from "../../../aviculture/services/aviculture-new-hatching";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import { cityGetHatchings } from "../../services/city-get-hatchings";
|
||||
import { reloadHatchings } from "../../../../lib/redux/slices/citySlice";
|
||||
|
||||
export const CityNewHatchingRequest = () => {
|
||||
const dispatch = useDispatch();
|
||||
const [poultryKey, setPolutryKey] = useState("");
|
||||
const [polutryData, setpolutryData] = useState("");
|
||||
const [enableHall, setEnableHall] = useState(true);
|
||||
const [numberOfhalls, setNumberOfHalls] = useState(1);
|
||||
const [numberOfhallSelected, setNumberOfHallSelected] = useState(null);
|
||||
const [openNotif, , selectedDate1, , selectedDate2] = useContext(AppContext);
|
||||
|
||||
const formik2 = useFormik({
|
||||
initialValues: {
|
||||
userInfoCheck: "",
|
||||
},
|
||||
validationSchema: Yup.object({
|
||||
userInfoCheck: Yup.number()
|
||||
.required("این فیلد اجباری است!")
|
||||
.typeError("لطفا فیلد را به درستی وارد کنید!"),
|
||||
}),
|
||||
});
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues: {
|
||||
quantity: "",
|
||||
hatchingDate: moment(Date()).format("YYYY-MM-DD hh:mm:ss"),
|
||||
race: "آرین",
|
||||
},
|
||||
validationSchema: Yup.object({
|
||||
quantity: Yup.number()
|
||||
.required("این فیلد اجباری است!")
|
||||
.typeError("لطفا عدد وارد کنید!"),
|
||||
}),
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
formik.validateForm();
|
||||
formik2.validateForm();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (poultryKey) {
|
||||
if (numberOfhalls === 0) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "ابتدا برای این مرغداری جوجه ریزی ثبت کنید.",
|
||||
severity: "error",
|
||||
});
|
||||
dispatch(DRAWER({ right: false, bottom: false, content: null }));
|
||||
} else {
|
||||
setEnableHall(false);
|
||||
}
|
||||
}
|
||||
}, [poultryKey]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{!polutryData ? (
|
||||
<Grid>
|
||||
<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)
|
||||
: null
|
||||
}
|
||||
onChange={formik2.handleChange}
|
||||
onBlur={formik2.handleBlur}
|
||||
helperText={
|
||||
formik2.touched.userInfoCheck &&
|
||||
Boolean(formik2.errors.userInfoCheck)
|
||||
? formik2.errors.userInfoCheck
|
||||
: null
|
||||
}
|
||||
/>
|
||||
|
||||
<IconButton
|
||||
disabled={!formik2.isValid}
|
||||
aria-label="delete"
|
||||
color="primary"
|
||||
onClick={() => {
|
||||
dispatch(LOADING_START());
|
||||
dispatch(cityGetPoultryData(formik2.values.userInfoCheck)).then(
|
||||
(r) => {
|
||||
dispatch(LOADING_END());
|
||||
if (r.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "کاربر یافت نشد",
|
||||
severity: "error",
|
||||
});
|
||||
}
|
||||
setpolutryData(r.payload.data);
|
||||
}
|
||||
);
|
||||
}}
|
||||
>
|
||||
<SearchIcon />
|
||||
</IconButton>
|
||||
</Grid>
|
||||
<FormHelperText>شماره موبایل با صفر شروع میشود!</FormHelperText>
|
||||
</Grid>
|
||||
) : (
|
||||
<Grid
|
||||
container
|
||||
gap={SPACING.SMALL}
|
||||
direction="column"
|
||||
flex="1"
|
||||
height="100%"
|
||||
justifyContent="space-between"
|
||||
>
|
||||
<Grid container direction="column" gap={SPACING.SMALL}>
|
||||
<Grid>
|
||||
<Autocomplete
|
||||
disablePortal
|
||||
id="hatching"
|
||||
options={
|
||||
polutryData
|
||||
? polutryData.map((i) => ({
|
||||
id: i.key,
|
||||
label: i.unitName,
|
||||
halls: i.numberOfHalls,
|
||||
}))
|
||||
: []
|
||||
}
|
||||
onChange={(event, value) => {
|
||||
setPolutryKey(value.id);
|
||||
setNumberOfHalls(value.halls);
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField {...params} label="محل پرورش" />
|
||||
)}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<Autocomplete
|
||||
disabled={enableHall}
|
||||
disablePortal
|
||||
options={[...Array(numberOfhalls)].map((e, i) => ({
|
||||
label: "سالن شماره " + (i + 1),
|
||||
id: i,
|
||||
}))}
|
||||
onChange={(event, value) => {
|
||||
setNumberOfHallSelected(value.id + 1);
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField {...params} label="سالن را انتخاب کنید" />
|
||||
)}
|
||||
/>
|
||||
</Grid>
|
||||
<NumberInput
|
||||
allowLeadingZeros
|
||||
thousandSeparator=","
|
||||
id="quantity"
|
||||
value={formik.values.quantity}
|
||||
error={
|
||||
formik.touched.quantity ? Boolean(formik.errors.quantity) : null
|
||||
}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.quantity && Boolean(formik.errors.quantity)
|
||||
? formik.errors.quantity
|
||||
: null
|
||||
}
|
||||
label="تعداد"
|
||||
variant="outlined"
|
||||
/>
|
||||
<DatePicker
|
||||
label="تاریخ جوجه ریزی"
|
||||
id="hatchingDate"
|
||||
renderInput={(params) => <TextField {...params} />}
|
||||
value={formik.values.hatchingDate}
|
||||
error={
|
||||
formik.touched.hatchingDate
|
||||
? Boolean(formik.errors.hatchingDate)
|
||||
: null
|
||||
}
|
||||
onChange={(e) => {
|
||||
formik.setFieldValue(
|
||||
"hatchingDate",
|
||||
moment(e).format("YYYY-MM-DD hh:mm:ss")
|
||||
);
|
||||
}}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.hatchingDate &&
|
||||
Boolean(formik.errors.hatchingDate)
|
||||
? formik.errors.hatchingDate
|
||||
: null
|
||||
}
|
||||
/>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel id="demo-simple-select-label">نژاد مرغ</InputLabel>
|
||||
<Select
|
||||
labelId="demo-simple-select-label"
|
||||
id="race"
|
||||
label="نژاد مرغ"
|
||||
value={formik.values.race}
|
||||
error={formik.touched.race ? Boolean(formik.errors.race) : null}
|
||||
onChange={(e) => {
|
||||
formik.setFieldValue("race", e.target.value);
|
||||
}}
|
||||
onBlur={formik.handleBlur}
|
||||
>
|
||||
<MenuItem value={"آرین"}>آرین</MenuItem>
|
||||
<MenuItem value={"راس"}>راس</MenuItem>
|
||||
<MenuItem value={"آربراکرز (آپلاس)"}>آربراکرز (آپلاس)</MenuItem>
|
||||
<MenuItem value={"کاب"}>کاب</MenuItem>
|
||||
<MenuItem value={"هوبارد"}>هوبارد</MenuItem>
|
||||
<MenuItem value={"ترکیبی"}>ترکیبی</MenuItem>
|
||||
<MenuItem value={"وارداتی"}>وارداتی</MenuItem>
|
||||
</Select>
|
||||
<FormHelperText>
|
||||
{formik.touched.race && Boolean(formik.errors.race)
|
||||
? formik.errors.race
|
||||
: null}
|
||||
</FormHelperText>
|
||||
</FormControl>
|
||||
</Grid>
|
||||
|
||||
<Grid>
|
||||
<Button
|
||||
disabled={
|
||||
formik.isValid && poultryKey.length && numberOfhallSelected
|
||||
? false
|
||||
: true
|
||||
}
|
||||
fullWidth
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
dispatch(LOADING_START());
|
||||
dispatch(
|
||||
avicultureNewHatching({
|
||||
role: getRoleFromUrl(),
|
||||
key: poultryKey,
|
||||
quantity: formik.values.quantity,
|
||||
date: formik.values.hatchingDate,
|
||||
chicken_breed: formik.values.race,
|
||||
hall: numberOfhallSelected,
|
||||
})
|
||||
).then((r) => {
|
||||
dispatch(reloadHatchings());
|
||||
dispatch(cityGetHatchings({ selectedDate1, selectedDate2 }));
|
||||
if (r.error) {
|
||||
if (r.error.message.includes("403")) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "قبلا برای این تاریخ یا این سالن جوجه ریزی ثبت شده است.",
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "مشکلی پیش آمده است!",
|
||||
severity: "error",
|
||||
});
|
||||
}
|
||||
} else {
|
||||
dispatch(
|
||||
DRAWER({ right: false, bottom: false, content: null })
|
||||
);
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
}
|
||||
dispatch(LOADING_END());
|
||||
});
|
||||
}}
|
||||
>
|
||||
ثبت اطلاعات
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,77 @@
|
||||
import { Tab, Tabs } from "@mui/material";
|
||||
import { useState } from "react";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { ProvinceManagePoultryRequest } from "../../../province/components/province-manage-poultry-request/ProvinceManagePoultryRequest";
|
||||
import { ProvinceManageSlaughterRequest } from "../../../province/components/province-manage-slaughter-request/ProvinceManageSlaughterRequest";
|
||||
import { CityManageHatchings } from "../city-manage-hatchings/CityManageHatchings";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
|
||||
export const CityHatching = () => {
|
||||
// const handleSubmit = (event) => {
|
||||
// event.preventDefault();
|
||||
// // Handle form submission here
|
||||
// dispatch(
|
||||
// updatePoultryRequestsTotalQuantityService({
|
||||
// key: poultryRequestsTotalQuantity?.key,
|
||||
// input_quantity: Number(formik.values.numberInput),
|
||||
// })
|
||||
// ).then((r) => {
|
||||
// openNotif({
|
||||
// vertical: "top",
|
||||
// horizontal: "center",
|
||||
// msg: "عملیات با موفقیت انجام شد.",
|
||||
// severity: "success",
|
||||
// });
|
||||
// });
|
||||
// };
|
||||
|
||||
const [activeTab, setActiveTab] = useState(0);
|
||||
|
||||
const handleTabChange = (event, newValue) => {
|
||||
setActiveTab(newValue);
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid container gap={SPACING.MEDIUM} alignItems="center" direction="column">
|
||||
<>
|
||||
<Tabs
|
||||
scrollButtons="auto"
|
||||
variant="scrollable"
|
||||
allowScrollButtonsMobile
|
||||
value={activeTab}
|
||||
onChange={handleTabChange}
|
||||
>
|
||||
<Tab label="درخواست مرغدار" />
|
||||
{getRoleFromUrl() !== "CityPoultry" && (
|
||||
<Tab label="درخواست کشتارگاه" />
|
||||
)}
|
||||
{/* <Tab label="جوجه ریزی" /> */}
|
||||
</Tabs>
|
||||
<TabPanel value={activeTab} index={2}>
|
||||
<CityManageHatchings />
|
||||
</TabPanel>
|
||||
<TabPanel value={activeTab} index={0}>
|
||||
<ProvinceManagePoultryRequest />
|
||||
</TabPanel>
|
||||
<TabPanel value={activeTab} index={1}>
|
||||
{getRoleFromUrl() !== "CityPoultry" ? (
|
||||
<ProvinceManageSlaughterRequest />
|
||||
) : (
|
||||
<CityManageHatchings />
|
||||
)}
|
||||
</TabPanel>
|
||||
</>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
function TabPanel(props) {
|
||||
const { children, value, index } = props;
|
||||
|
||||
return (
|
||||
<div role="tabpanel" hidden={value !== index}>
|
||||
{value === index && <>{children}</>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,62 @@
|
||||
import { Button, Card } from "@mui/material";
|
||||
import React from "react";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { columnsName } from "../../../../data/columnsName";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { DRAWER } from "../../../../lib/redux/slices/appSlice";
|
||||
import { AvicultureNewRequest } from "../../../aviculture/components/aviculture-new-request/AvicultureNewRequest";
|
||||
|
||||
export const CityNewRequest = () => {
|
||||
const dispatch = useDispatch();
|
||||
return (
|
||||
<Grid container gap={SPACING.MEDIUM} direction="column" xs={12}>
|
||||
<Grid
|
||||
container
|
||||
gap={SPACING.SMALL}
|
||||
justifyContent={{ xs: "center", lg: "space-between" }}
|
||||
alignSelf="center"
|
||||
alignItems="center"
|
||||
xs={12}
|
||||
direction={{ xs: "column", lg: "row" }}
|
||||
>
|
||||
<Grid
|
||||
container
|
||||
xs={12}
|
||||
gap={SPACING.SMALL}
|
||||
alignItems={"start"}
|
||||
direction={"column"}
|
||||
>
|
||||
<Grid container width="100%" justifyContent="space-between">
|
||||
<Button
|
||||
className="avicultureNewRequestBtn"
|
||||
variant={"contained"}
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
DRAWER({
|
||||
right: !(window.innerWidth <= 600),
|
||||
bottom: window.innerWidth <= 600,
|
||||
title: "اطلاعات جوجه ریزی",
|
||||
content: <AvicultureNewRequest />,
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
ثبت درخواست کشتار جدید
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid width="100%" className="avicultureActiveRequestsView">
|
||||
<Card>
|
||||
<AdvancedTable
|
||||
name={"درخواست های فعال کشتار"}
|
||||
columns={columnsName}
|
||||
data={[["sjsjsj"]]}
|
||||
/>
|
||||
</Card>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,461 @@
|
||||
import { Button, TextField, Typography } from "@mui/material";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import PlagiarismIcon from "@mui/icons-material/Plagiarism";
|
||||
// import { ROUTE_CITY_FILE } from "../../../../routes/routes";
|
||||
// import { avicultureGetRequests } from "../../../aviculture/services/aviculture-requests";
|
||||
import CreateIcon from "@mui/icons-material/Create";
|
||||
import CityFileOperations from "../../../file/components/city-file-operations/CityFileOperations";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { PageTable } from "../../../../components/page-table/PageTable";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import axios from "axios";
|
||||
import { DatePicker } from "@mui/x-date-pickers";
|
||||
import moment from "moment/moment";
|
||||
import { formatJustDate } from "../../../../utils/formatTime";
|
||||
import { IconButton } from "@mui/material";
|
||||
import { DRAWER } from "../../../../lib/redux/slices/appSlice";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { ROUTE_CITY_FILE } from "../../../../routes/routes";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { RiSearchLine } from "react-icons/ri";
|
||||
|
||||
export const CityNewRequests = () => {
|
||||
const dispatch = useDispatch();
|
||||
const navigate = useNavigate();
|
||||
const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] =
|
||||
useContext(AppContext);
|
||||
useEffect(() => {
|
||||
const currentDate = moment(new Date()).format("YYYY-MM-DD");
|
||||
setSelectedDate1(currentDate);
|
||||
setSelectedDate2(currentDate);
|
||||
}, []);
|
||||
|
||||
// page table
|
||||
const [data, setData] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [totalRows, setTotalRows] = useState(0);
|
||||
const [perPage, setPerPage] = useState(10);
|
||||
|
||||
const [textValue, setTextValue] = useState("");
|
||||
|
||||
const handleTextChange = (event) => {
|
||||
setTextValue(event.target.value);
|
||||
};
|
||||
|
||||
const fetchApiData = async (page, textValue) => {
|
||||
setLoading(true);
|
||||
let response = await axios.get(
|
||||
`Poultry_Request/?state=pending&date1=${selectedDate1}&date2=${selectedDate2}&search=filter&value=${
|
||||
textValue ? textValue : ""
|
||||
}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}`
|
||||
);
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
const handlePageChange = (page) => {
|
||||
fetchApiData(page, textValue);
|
||||
};
|
||||
|
||||
const handlePerRowsChange = async (newPerPage, page) => {
|
||||
setLoading(true);
|
||||
let response = await axios.get(
|
||||
`Poultry_Request/?state=pending&date1=${selectedDate1}&date2=${selectedDate2}&search=filter&value=${
|
||||
textValue ? textValue : ""
|
||||
}&page=${page}&page_size=${newPerPage}`
|
||||
);
|
||||
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
setPerPage(newPerPage);
|
||||
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchApiData(1);
|
||||
}, [selectedDate1, selectedDate2, perPage]);
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
setLoading(true);
|
||||
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`Poultry_Request/?state=pending&date1=${selectedDate1}&date2=${selectedDate2}&role=${getRoleFromUrl()}&search=filter&value=${
|
||||
textValue ? textValue : ""
|
||||
}`
|
||||
);
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const updateTable = () => {
|
||||
fetchApiData(1);
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{
|
||||
name: "کدسفارش",
|
||||
selector: (item) => item?.orderCode,
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
width: "90px",
|
||||
},
|
||||
{
|
||||
name: "تاریخ ثبت درخواست",
|
||||
selector: (item) => formatJustDate(item?.createDate),
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
width: "90px",
|
||||
},
|
||||
{
|
||||
name: "نوع کشتار",
|
||||
selector: (item) => {
|
||||
return item?.freezing ? "انجماد" : item?.export ? "صادرات" : "عادی";
|
||||
},
|
||||
sortable: true,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
width: "90px",
|
||||
},
|
||||
{
|
||||
name: "تاریخ کشتار",
|
||||
selector: (item) => formatJustDate(item?.sendDate),
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
width: "90px",
|
||||
},
|
||||
{
|
||||
name: "مرغداری",
|
||||
selector: (item) =>
|
||||
`${item?.poultry?.unitName} (${item?.poultry?.user?.mobile})`,
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
width: "90px",
|
||||
},
|
||||
{
|
||||
name: "دامپزشک فارم",
|
||||
selector: (item) =>
|
||||
`${item?.vetFarm?.vetFarmFullname} (${item?.vetFarm?.vetFarmMobile})`,
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
width: "90px",
|
||||
},
|
||||
{
|
||||
name: "استان/شهر",
|
||||
selector: (item) =>
|
||||
`${item?.poultry?.address?.province?.name}/${item?.poultry?.address?.city?.name}`,
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
width: "90px",
|
||||
},
|
||||
{
|
||||
name: "تعاونی",
|
||||
selector: (item) => {
|
||||
return item?.poultry?.cityOperator;
|
||||
},
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
width: "90px",
|
||||
},
|
||||
{
|
||||
name: "تاریخ جوجه ریزی",
|
||||
selector: (item) => formatJustDate(item?.hatching?.hatchingDate),
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
width: "90px",
|
||||
},
|
||||
{
|
||||
name: "سن",
|
||||
selector: (item) => item?.hatching?.age,
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
width: "90px",
|
||||
},
|
||||
{
|
||||
name: "میانگین وزن (کیلوگرم)",
|
||||
selector: (item) => {
|
||||
return item?.IndexWeight;
|
||||
},
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
width: "90px",
|
||||
},
|
||||
{
|
||||
name: "تعداد (قطعه)",
|
||||
selector: (item) => item?.quantity,
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
width: "90px",
|
||||
},
|
||||
{
|
||||
name: "وزن بار (کیلوگرم)",
|
||||
selector: (item) => (item?.quantity * item?.IndexWeight).toLocaleString(),
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
width: "90px",
|
||||
},
|
||||
{
|
||||
name: "عملیات",
|
||||
selector: (item) => {
|
||||
return (
|
||||
<IconButton
|
||||
color="primary"
|
||||
onClick={() =>
|
||||
dispatch(
|
||||
DRAWER({
|
||||
right: !(window.innerWidth <= 600),
|
||||
bottom: window.innerWidth <= 600,
|
||||
content: (
|
||||
<CityFileOperations
|
||||
updateTable={updateTable}
|
||||
id={item.id}
|
||||
file={item}
|
||||
/>
|
||||
),
|
||||
title: "انجام عملیات شهرستان",
|
||||
})
|
||||
)
|
||||
}
|
||||
>
|
||||
<CreateIcon />
|
||||
</IconButton>
|
||||
);
|
||||
},
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
},
|
||||
{
|
||||
name: "مشاهده",
|
||||
selector: (item) => {
|
||||
return (
|
||||
<IconButton
|
||||
aria-label="delete"
|
||||
color="primary"
|
||||
onClick={() => navigate(ROUTE_CITY_FILE + item?.id)}
|
||||
>
|
||||
<PlagiarismIcon />
|
||||
</IconButton>
|
||||
);
|
||||
},
|
||||
sortable: false,
|
||||
wrap: true,
|
||||
allowOverflow: true,
|
||||
center: true,
|
||||
},
|
||||
];
|
||||
|
||||
// useEffect(() => {
|
||||
// dispatch(LOADING_START());
|
||||
// dispatch(avicultureGetRequests({ selectedDate1, selectedDate2 })).then(
|
||||
// (r) => {
|
||||
// dispatch(LOADING_END());
|
||||
// }
|
||||
// );
|
||||
// }, [selectedDate1, selectedDate2]);
|
||||
|
||||
// useEffect(() => {
|
||||
// const filteredData = avicultureRequests?.filter(
|
||||
// (item, i) => item.stateProcess === "pending"
|
||||
// );
|
||||
// const d = filteredData?.map((item, i) => {
|
||||
// return [
|
||||
// i + 1,
|
||||
// item.orderCode,
|
||||
// item.poultry.userprofile.baseOrder,
|
||||
// formatJustDate(item.createDate),
|
||||
// formatJustDate(item.sendDate),
|
||||
// item?.process?.poultry?.poultryName,
|
||||
// item?.process?.poultry?.poultryMobile,
|
||||
// item?.process?.poultry?.poultryCity,
|
||||
// item?.process?.poultry?.poultryProvince,
|
||||
// formatJustDate(item.hatching.date),
|
||||
// item?.process?.poultry?.age,
|
||||
// item?.process?.poultry?.poultryQuantity,
|
||||
// <IconButton
|
||||
// key={i}
|
||||
// color="primary"
|
||||
// onClick={() =>
|
||||
// dispatch(
|
||||
// DRAWER({
|
||||
// right: !(window.innerWidth <= 600),
|
||||
// bottom: window.innerWidth <= 600,
|
||||
// content: (
|
||||
// <CityFileOperations id={item.id} file={item?.process} />
|
||||
// ),
|
||||
// title: "انجام عملیات شهرستان",
|
||||
// })
|
||||
// )
|
||||
// }
|
||||
// >
|
||||
// <CreateIcon />
|
||||
// </IconButton>,
|
||||
// <IconButton
|
||||
// key={i}
|
||||
// aria-label="delete"
|
||||
// color="primary"
|
||||
// onClick={() =>
|
||||
// navigate(ROUTE_CITY_FILE + item?.process?.poultry?.poultryRequestId)
|
||||
// }
|
||||
// >
|
||||
// <PlagiarismIcon />
|
||||
// </IconButton>,
|
||||
// ];
|
||||
// });
|
||||
|
||||
// setDataTable(d);
|
||||
// }, [avicultureRequests]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* <AdvancedTable
|
||||
name={
|
||||
<Grid container alignItems="center" gap={SPACING.SMALL}>
|
||||
<Grid container gap={SPACING.TINY}>
|
||||
<Typography>درخواست های جدید فروش اتحادیه</Typography>
|
||||
</Grid>
|
||||
<Grid container gap={SPACING.SMALL}>
|
||||
<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>
|
||||
</Grid>
|
||||
}
|
||||
columns={columnsName}
|
||||
data={dataTable}
|
||||
/> */}
|
||||
|
||||
<Grid alignItems="center" justifyContent="center" mt={4}>
|
||||
<PageTable
|
||||
title={
|
||||
<Grid
|
||||
container
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
gap={2}
|
||||
paddingTop={2}
|
||||
mb={1}
|
||||
>
|
||||
<Grid container alignItems="center" gap={SPACING.SMALL}>
|
||||
<Typography>درخواست های جدید فروش اتحادیه</Typography>
|
||||
<Grid container gap={SPACING.SMALL}>
|
||||
<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>
|
||||
<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>
|
||||
}
|
||||
columns={columns}
|
||||
data={data}
|
||||
progressPending={loading}
|
||||
pagination
|
||||
paginationServer
|
||||
paginationTotalRows={totalRows}
|
||||
onChangeRowsPerPage={handlePerRowsChange}
|
||||
onChangePage={handlePageChange}
|
||||
/>
|
||||
</Grid>
|
||||
</>
|
||||
);
|
||||
};
|
||||
135
src/features/city/components/city-operations/CityOperations.js
Normal file
135
src/features/city/components/city-operations/CityOperations.js
Normal file
@@ -0,0 +1,135 @@
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { NavLink } from "../../../../components/nav-link/NavLink";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import {
|
||||
ROUTE_CITY_ACTIVE_REQUESTS,
|
||||
ROUTE_CITY_ARCHIVED_REQUESTS,
|
||||
ROUTE_CITY_AWAITING_INSPECTION_REQUESTS,
|
||||
ROUTE_CITY_REJECTED_REQUESTS,
|
||||
ROUTE_CITY_AWAITING_PAYMENT_REQUESTS,
|
||||
ROUTE_CITY_NEW_REQUESTS,
|
||||
ROUTE_CITY_FREE_SALES_REQUESTS,
|
||||
} from "../../../../routes/routes";
|
||||
import LinkItem from "../../../../components/link-item/LinkItem";
|
||||
import { VscFolderActive, VscNewFolder } from "react-icons/vsc";
|
||||
import { GiMoneyStack } from "react-icons/gi";
|
||||
import { GrInspect } from "react-icons/gr";
|
||||
import { RiFolderWarningLine } from "react-icons/ri";
|
||||
import { FaArchive } from "react-icons/fa";
|
||||
|
||||
export const CityOperations = () => {
|
||||
const { pathname } = useLocation();
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
gap={SPACING.SMALL}
|
||||
p={SPACING.SMALL}
|
||||
direction={{ xs: "column", md: "row" }}
|
||||
justifyContent="center"
|
||||
style={{ placeContent: "baseline" }}
|
||||
>
|
||||
<Grid container direction="column" style={{ width: "100%" }}>
|
||||
<Grid container gap={SPACING.SMALL} justifyContent="center">
|
||||
<NavLink
|
||||
to={ROUTE_CITY_NEW_REQUESTS}
|
||||
active={pathname === ROUTE_CITY_NEW_REQUESTS ? "true" : null}
|
||||
>
|
||||
<LinkItem
|
||||
icon={<VscNewFolder size={30} color="#244CCC" />}
|
||||
title="درخواست های جدید"
|
||||
description="درخواست های در انتظار بررسی"
|
||||
/>
|
||||
</NavLink>
|
||||
<NavLink
|
||||
to={ROUTE_CITY_ACTIVE_REQUESTS}
|
||||
active={pathname === ROUTE_CITY_ACTIVE_REQUESTS ? "true" : null}
|
||||
>
|
||||
<LinkItem
|
||||
icon={<VscFolderActive size={30} color="#244CCC" />}
|
||||
title="درخواست های فعال"
|
||||
description="مشاهده درخواست های در جریان"
|
||||
/>
|
||||
</NavLink>
|
||||
|
||||
<NavLink
|
||||
to={ROUTE_CITY_AWAITING_PAYMENT_REQUESTS}
|
||||
active={
|
||||
pathname === ROUTE_CITY_AWAITING_PAYMENT_REQUESTS ? "true" : null
|
||||
}
|
||||
>
|
||||
<LinkItem
|
||||
icon={<GiMoneyStack size={30} color="#244CCC" />}
|
||||
title="در انتظار پرداخت"
|
||||
description="مشاهده درخواست های در انتظار پرداخت کشتارگاه"
|
||||
/>
|
||||
</NavLink>
|
||||
<NavLink
|
||||
to={ROUTE_CITY_AWAITING_INSPECTION_REQUESTS}
|
||||
active={
|
||||
pathname === ROUTE_CITY_AWAITING_INSPECTION_REQUESTS
|
||||
? "true"
|
||||
: null
|
||||
}
|
||||
>
|
||||
<LinkItem
|
||||
icon={
|
||||
<GrInspect
|
||||
className="svg-icon-color"
|
||||
color="#244CCC"
|
||||
size={30}
|
||||
/>
|
||||
}
|
||||
title="در انتظار بازرسی"
|
||||
description="درخواست های در انتظار بررسی بازرس"
|
||||
/>
|
||||
</NavLink>
|
||||
|
||||
<NavLink
|
||||
to={ROUTE_CITY_REJECTED_REQUESTS}
|
||||
active={pathname === ROUTE_CITY_REJECTED_REQUESTS ? "true" : null}
|
||||
>
|
||||
<LinkItem
|
||||
icon={
|
||||
<RiFolderWarningLine
|
||||
className="svg-icon-color"
|
||||
color="#244CCC"
|
||||
size={30}
|
||||
/>
|
||||
}
|
||||
title="درخواست های رد شده"
|
||||
description="مشاهده درخواست هایی که به دلایل مختلف توسط اتحادیه رد شده است"
|
||||
/>
|
||||
</NavLink>
|
||||
<NavLink
|
||||
to={ROUTE_CITY_FREE_SALES_REQUESTS}
|
||||
active={pathname === ROUTE_CITY_FREE_SALES_REQUESTS ? "true" : null}
|
||||
>
|
||||
<LinkItem
|
||||
icon={<VscFolderActive size={30} color="#244CCC" />}
|
||||
title="فروش خارج از استان"
|
||||
/>
|
||||
</NavLink>
|
||||
|
||||
<NavLink
|
||||
to={ROUTE_CITY_ARCHIVED_REQUESTS}
|
||||
active={pathname === ROUTE_CITY_ARCHIVED_REQUESTS ? "true" : null}
|
||||
>
|
||||
<LinkItem
|
||||
icon={
|
||||
<FaArchive
|
||||
className="svg-icon-color"
|
||||
color="#244CCC"
|
||||
size={30}
|
||||
/>
|
||||
}
|
||||
title="بایگانی"
|
||||
description="درخواست های پایان یافته"
|
||||
/>
|
||||
</NavLink>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,197 @@
|
||||
import {
|
||||
Grid,
|
||||
IconButton,
|
||||
List,
|
||||
ListItemButton,
|
||||
ListItemIcon,
|
||||
ListItemText,
|
||||
Popover,
|
||||
} from "@mui/material";
|
||||
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { DRAWER, OPEN_MODAL } from "../../../../lib/redux/slices/appSlice";
|
||||
import { CitySubmitTenantForm } from "../city-submit-tenant-form/CitySubmitTenantForm";
|
||||
import { CityEditAvicultureInfoForm } from "../city-edit-aviculture-info-form/CityEditAvicultureInfoForm";
|
||||
import { cityGetPoultryFarm } from "../../services/city-get-poultry-farms";
|
||||
import { CityTenantOwnerInfo } from "../city-tenant-owner-info/CityTenantOwnerInfo";
|
||||
import TuneIcon from "@mui/icons-material/Tune";
|
||||
import PersonAddAltIcon from "@mui/icons-material/PersonAddAlt";
|
||||
import InfoOutlinedIcon from "@mui/icons-material/InfoOutlined";
|
||||
import EditOutlinedIcon from "@mui/icons-material/EditOutlined";
|
||||
|
||||
const PoultryFarmActions = ({ item }) => {
|
||||
const dispatch = useDispatch();
|
||||
const [anchorPosition, setAnchorPosition] = useState(null);
|
||||
|
||||
const hasTenant = Object.keys(item.poultryTenant).length !== 0;
|
||||
|
||||
const handleOpen = (event) => {
|
||||
const rect = event.currentTarget.getBoundingClientRect();
|
||||
setAnchorPosition({
|
||||
top: rect.bottom + window.scrollY,
|
||||
left: rect.left + rect.width / 2 + window.scrollX,
|
||||
});
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setAnchorPosition(null);
|
||||
};
|
||||
|
||||
const handleAddTenant = () => {
|
||||
dispatch(
|
||||
DRAWER({
|
||||
right: !(window.innerWidth <= 600),
|
||||
bottom: window.innerWidth <= 600,
|
||||
title: "ایجاد مستاجر جدید",
|
||||
content: <CitySubmitTenantForm id={item.key} />,
|
||||
})
|
||||
);
|
||||
handleClose();
|
||||
};
|
||||
|
||||
const handleShowTenantInfo = () => {
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "اطلاعات مستاجر",
|
||||
content: <CityTenantOwnerInfo item={item} />,
|
||||
})
|
||||
);
|
||||
handleClose();
|
||||
};
|
||||
|
||||
const handleEditInfo = () => {
|
||||
dispatch(
|
||||
DRAWER({
|
||||
right: !(window.innerWidth <= 600),
|
||||
bottom: window.innerWidth <= 600,
|
||||
title: "ویرایش اطلاعات مرغدار",
|
||||
content: <CityEditAvicultureInfoForm item={item} />,
|
||||
})
|
||||
);
|
||||
handleClose();
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid container justifyContent="center">
|
||||
<IconButton color="primary" size="small" onClick={handleOpen}>
|
||||
<TuneIcon />
|
||||
</IconButton>
|
||||
<Popover
|
||||
anchorReference="anchorPosition"
|
||||
anchorPosition={anchorPosition || undefined}
|
||||
open={Boolean(anchorPosition)}
|
||||
onClose={handleClose}
|
||||
anchorOrigin={{
|
||||
vertical: "bottom",
|
||||
horizontal: "right",
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: "top",
|
||||
horizontal: "left",
|
||||
}}
|
||||
>
|
||||
<List sx={{ p: 0 }}>
|
||||
{hasTenant ? (
|
||||
<ListItemButton onClick={handleShowTenantInfo}>
|
||||
<ListItemIcon sx={{ minWidth: 36, color: "info.main" }}>
|
||||
<InfoOutlinedIcon fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary="اطلاعات مستاجر"
|
||||
primaryTypographyProps={{
|
||||
variant: "body2",
|
||||
color: "info",
|
||||
}}
|
||||
/>
|
||||
</ListItemButton>
|
||||
) : (
|
||||
<ListItemButton onClick={handleAddTenant}>
|
||||
<ListItemIcon sx={{ minWidth: 36, color: "success.main" }}>
|
||||
<PersonAddAltIcon fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary="افزودن مستاجر"
|
||||
primaryTypographyProps={{
|
||||
variant: "body2",
|
||||
color: "success",
|
||||
}}
|
||||
/>
|
||||
</ListItemButton>
|
||||
)}
|
||||
<ListItemButton onClick={handleEditInfo}>
|
||||
<ListItemIcon sx={{ minWidth: 36, color: "warning.main" }}>
|
||||
<EditOutlinedIcon fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary="ویرایش اطلاعات"
|
||||
primaryTypographyProps={{
|
||||
variant: "body2",
|
||||
color: "warning",
|
||||
}}
|
||||
/>
|
||||
</ListItemButton>
|
||||
</List>
|
||||
</Popover>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
export const CityPoultryFarms = () => {
|
||||
const [dataTable, setDataTable] = useState([]);
|
||||
const { poultryFarms } = useSelector((state) => state.citySlice);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(cityGetPoultryFarm());
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const d = poultryFarms
|
||||
?.filter((item) => Object.keys(item.poultryOwner).length === 0)
|
||||
.map((item, i) => {
|
||||
return [
|
||||
i + 1,
|
||||
item.unitName,
|
||||
item.userprofile.fullName,
|
||||
item.userprofile.breedingUniqueId,
|
||||
item.address.province.name,
|
||||
item.address.city.name,
|
||||
item.userprofile.mobile,
|
||||
<PoultryFarmActions key={`operation-${item.key}`} item={item} />,
|
||||
];
|
||||
});
|
||||
|
||||
setDataTable(d);
|
||||
}, [poultryFarms]);
|
||||
|
||||
const [tableDataCol] = useState([
|
||||
"ردیف",
|
||||
"نام مرغداری",
|
||||
"نام صاحب",
|
||||
"شناسه یکتا",
|
||||
"استان",
|
||||
"شهر",
|
||||
"تلفن همراه",
|
||||
"عملیات",
|
||||
]);
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
gap={SPACING.SMALL}
|
||||
mt={SPACING.MEDIUM}
|
||||
>
|
||||
<ResponsiveTable
|
||||
title="مرغداران زیرمجموعه"
|
||||
columns={tableDataCol}
|
||||
data={dataTable}
|
||||
customWidth="100%"
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
61
src/features/city/components/city-profile/CityProfile.js
Normal file
61
src/features/city/components/city-profile/CityProfile.js
Normal file
@@ -0,0 +1,61 @@
|
||||
import { Box } from "@mui/system";
|
||||
import { useEffect } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { SimpleTable } from "../../../../components/simple-table/SimpleTable";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import {
|
||||
LOADING_END,
|
||||
LOADING_START,
|
||||
} from "../../../../lib/redux/slices/appSlice";
|
||||
import { ChangeCardInfo } from "../../../authentication/components/change-card-info/ChangeCardInfo";
|
||||
// import { ChangeCardInfo } from "../../../authentication/components/change-card-info/ChangeCardInfo";
|
||||
// import { ChangeCardInfo } from "../../../authentication/components/change-card-info/ChangeCardInfo";
|
||||
import { cityGetProfile } from "../../services/city-get-profile";
|
||||
|
||||
export const CityProfile = () => {
|
||||
const { profile } = useSelector((state) => state.citySlice);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(LOADING_START());
|
||||
dispatch(cityGetProfile()).then((r) => {
|
||||
dispatch(LOADING_END());
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Grid container gap={SPACING.LARGE}>
|
||||
<Grid container direction="column" xs={12}>
|
||||
<Grid
|
||||
container
|
||||
direction="column"
|
||||
justifyContent="space-between"
|
||||
gap={SPACING.SMALL}
|
||||
>
|
||||
<>
|
||||
<Grid>
|
||||
<SimpleTable
|
||||
name={`اطلاعات شهرستان ${profile?.user.fullname}`}
|
||||
columns={["نام کامل", "تلفن", "آدرس", "کد پستی"]}
|
||||
data={[
|
||||
[
|
||||
profile?.user.fullname,
|
||||
profile?.user.mobile,
|
||||
profile?.address.address,
|
||||
profile?.address.postalCode,
|
||||
],
|
||||
]}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<ChangeCardInfo item={profile} />
|
||||
</Grid>
|
||||
</>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,74 @@
|
||||
import { Card, IconButton } from "@mui/material";
|
||||
import { useEffect, useState } from "react";
|
||||
import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable";
|
||||
import PlagiarismIcon from "@mui/icons-material/Plagiarism";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { ROUTE_CITY_FILE } from "../../../../routes/routes";
|
||||
import { FileInformation } from "../../../file/components/file-information/FileInformation";
|
||||
import useAvicultureRequests from "../../../aviculture/hooks/useAvicultureRequests";
|
||||
import { formatJustDate } from "../../../../utils/formatTime";
|
||||
|
||||
export const CityRejectedRequests = () => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [dataTable, setDataTable] = useState([]);
|
||||
const avicultureRequests = useAvicultureRequests("CityOperator");
|
||||
useEffect(() => {
|
||||
const filteredData = avicultureRequests?.filter(
|
||||
(item, i) => item.stateProcess === "rejected"
|
||||
);
|
||||
const d = filteredData?.map((item, i) => {
|
||||
return [
|
||||
i + 1,
|
||||
item.orderCode,
|
||||
formatJustDate(item?.createDate),
|
||||
formatJustDate(item?.sendDate),
|
||||
item?.process?.poultry?.poultryName,
|
||||
item?.process?.poultry?.poultryMobile,
|
||||
item?.process?.poultry?.poultryCity,
|
||||
item?.process?.poultry?.poultryProvince,
|
||||
item?.process?.poultry?.age,
|
||||
item?.process?.poultry?.poultryQuantity,
|
||||
<IconButton
|
||||
key={i}
|
||||
aria-label="delete"
|
||||
color="primary"
|
||||
onClick={() =>
|
||||
navigate(ROUTE_CITY_FILE + item?.process?.poultry?.poultryRequestId)
|
||||
}
|
||||
>
|
||||
<PlagiarismIcon />
|
||||
</IconButton>,
|
||||
];
|
||||
});
|
||||
|
||||
setDataTable(d);
|
||||
}, []);
|
||||
|
||||
const [tableDataCol] = useState([
|
||||
"ردیف",
|
||||
"کد سفارش",
|
||||
"تاریخ ثبت درخواست",
|
||||
"تاریخ درخواست",
|
||||
"مرغدار",
|
||||
"تلفن مرغدار",
|
||||
"شهر",
|
||||
"استان",
|
||||
"سن مرغ",
|
||||
"تعداد",
|
||||
"مشاهده",
|
||||
]);
|
||||
return (
|
||||
<Card>
|
||||
<AdvancedTable
|
||||
expandable
|
||||
name={"درخواست های رد شده"}
|
||||
columns={tableDataCol}
|
||||
expandedComponentHandler={(rowData) => (
|
||||
<FileInformation id={rowData[0]} />
|
||||
)}
|
||||
data={dataTable}
|
||||
/>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,192 @@
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import {
|
||||
Button,
|
||||
FormControlLabel,
|
||||
Switch,
|
||||
TextField,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import { useFormik } from "formik";
|
||||
import { Yup } from "../../../../lib/yup/yup";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { archiveHatchingService } from "../../services/archive-hatching";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice";
|
||||
import { FileUploader } from "../../../../components/file-uploader/FileUploader";
|
||||
|
||||
export const CitySubmitHatchingReport = ({ item, updateTable, isArchive }) => {
|
||||
const [checked, setChecked] = useState(item?.violation);
|
||||
const [sendToArchive, setSendToArchive] = useState(false);
|
||||
const dispatch = useDispatch();
|
||||
const handleChange = (event) => {
|
||||
setChecked(event.target.checked);
|
||||
};
|
||||
const handleChangeArchive = (event) => {
|
||||
setSendToArchive(event.target.checked);
|
||||
};
|
||||
|
||||
const [openNotif] = useContext(AppContext);
|
||||
|
||||
const [filesList, setFilesList] = useState([]);
|
||||
|
||||
const hanleFilesChange = (e) => {
|
||||
setFilesList(e);
|
||||
};
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues: {
|
||||
reportText: item?.violationReport,
|
||||
bar_image: "",
|
||||
},
|
||||
validationSchema: Yup.object({
|
||||
reportText: Yup.string()
|
||||
.required("این فیلد اجباری است!")
|
||||
.typeError("لطفا گزارش خود را بیان کنید."),
|
||||
bar_image: Yup.array(),
|
||||
}),
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
formik.validateForm();
|
||||
}, []);
|
||||
|
||||
// const factorPaymentHandler = (imageList, addUpdateIndex) => {
|
||||
// if (imageList[0]) {
|
||||
// formik.setFieldValue(
|
||||
// "bar_image",
|
||||
// imageList.map((img) => fixBase64(img.data_url))
|
||||
// );
|
||||
// }
|
||||
// setProfileImages(imageList);
|
||||
// };
|
||||
|
||||
return (
|
||||
<Grid container xs={12} justifyContent="center" alignItems="center" gap={2}>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Switch checked={checked} onChange={handleChange} color="primary" />
|
||||
}
|
||||
label={checked ? "متخلف" : "بدون تخلف"}
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
}}
|
||||
/>
|
||||
{!isArchive && (
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Switch
|
||||
checked={sendToArchive}
|
||||
onChange={handleChangeArchive}
|
||||
color="primary"
|
||||
/>
|
||||
}
|
||||
label={"انتقال به بایگانی"}
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<TextField
|
||||
multiline
|
||||
rows={4}
|
||||
fullWidth
|
||||
id="reportText"
|
||||
label="متن گزارش"
|
||||
variant="outlined"
|
||||
value={formik.values.reportText}
|
||||
error={
|
||||
formik.touched.reportText ? Boolean(formik.errors.reportText) : null
|
||||
}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.reportText && Boolean(formik.errors.reportText)
|
||||
? formik.errors.reportText
|
||||
: null
|
||||
}
|
||||
/>
|
||||
<Typography color="error">
|
||||
در صورت آپلود فایل جدید، سندهای پیشین حذف میشوند!
|
||||
</Typography>
|
||||
|
||||
{/* <ImageUpload
|
||||
onChange={factorPaymentHandler}
|
||||
images={profileImages}
|
||||
maxNumber={5}
|
||||
title={"بارگذاری سند"}
|
||||
/> */}
|
||||
|
||||
<FileUploader onChange={hanleFilesChange} />
|
||||
{/* {item?.violationImage?.length && !profileImages?.length && (
|
||||
<>
|
||||
{item?.violationImage?.map((option, i) => (
|
||||
<img
|
||||
key={i}
|
||||
src={option}
|
||||
alt="تصویر گزارش"
|
||||
style={{ width: "100px", borderRadius: "5px" }}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
)} */}
|
||||
|
||||
<Button
|
||||
mt={2}
|
||||
disabled={!formik.isValid || formik.isSubmitting}
|
||||
fullWidth
|
||||
variant="contained"
|
||||
onClick={async () => {
|
||||
try {
|
||||
const req = {
|
||||
key: item?.key,
|
||||
violation_check: true,
|
||||
violation: checked,
|
||||
violation_report: formik.values.reportText,
|
||||
archive: sendToArchive,
|
||||
};
|
||||
|
||||
const formData = new FormData();
|
||||
Object.entries(req).forEach(([key, value]) => {
|
||||
formData.append(key, value);
|
||||
});
|
||||
|
||||
filesList.forEach((file, index) => {
|
||||
formData.append(`violation_image_${index}`, file);
|
||||
});
|
||||
|
||||
const response = await dispatch(
|
||||
archiveHatchingService(filesList.length ? formData : req)
|
||||
);
|
||||
|
||||
if (response.error) {
|
||||
throw new Error(response.error);
|
||||
}
|
||||
|
||||
updateTable(1);
|
||||
dispatch(CLOSE_MODAL());
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
} catch (error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: error.message || "خطا در ارسال اطلاعات",
|
||||
severity: "error",
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
{formik.isSubmitting ? "در حال ثبت..." : "ثبت"}
|
||||
</Button>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,77 @@
|
||||
import React, { useContext } from "react";
|
||||
import { TextField, Button } from "@mui/material";
|
||||
import { Formik, Form, Field, ErrorMessage } from "formik";
|
||||
import * as Yup from "yup";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { archiveHatchingService } from "../../services/archive-hatching";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice";
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
looses_amount: Yup.number()
|
||||
.required("این فیلد اجباری است!")
|
||||
.min(0, "عدد مثبت وارد کنید!"),
|
||||
});
|
||||
|
||||
export const CitySubmitLooses = ({ updateTable, item }) => {
|
||||
const dispatch = useDispatch();
|
||||
const [openNotif] = useContext(AppContext);
|
||||
|
||||
const handleSubmit = (values, { resetForm }) => {
|
||||
dispatch(
|
||||
archiveHatchingService({
|
||||
key: item?.key,
|
||||
direct_losses: values.looses_amount,
|
||||
})
|
||||
).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",
|
||||
});
|
||||
updateTable();
|
||||
dispatch(CLOSE_MODAL());
|
||||
}
|
||||
});
|
||||
resetForm();
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Formik
|
||||
initialValues={{ looses_amount: "" }}
|
||||
validationSchema={validationSchema}
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
{({ handleChange, handleBlur }) => (
|
||||
<Form>
|
||||
<Field
|
||||
as={TextField}
|
||||
name="looses_amount"
|
||||
label="حجم تلفات"
|
||||
type="number"
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
margin="normal"
|
||||
helperText={<ErrorMessage name="looses_amount" />}
|
||||
/>
|
||||
<Button type="submit" variant="contained" color="primary" fullWidth>
|
||||
ثبت
|
||||
</Button>
|
||||
</Form>
|
||||
)}
|
||||
</Formik>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,378 @@
|
||||
import { Autocomplete, Button, TextField } from "@mui/material";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import React, { useEffect } from "react";
|
||||
import { Yup } from "../../../../lib/yup/yup";
|
||||
import { useFormik } from "formik";
|
||||
import { useState } from "react";
|
||||
import { useDispatch } from "react-redux";
|
||||
import {
|
||||
DRAWER,
|
||||
LOADING_END,
|
||||
LOADING_START,
|
||||
} from "../../../../lib/redux/slices/appSlice";
|
||||
import { cityGetProvinces } from "../../services/CityGetProvinces";
|
||||
import { cityGetCity } from "../../services/city-get-city";
|
||||
import { citySubmitNewTenant } from "../../services/city-submit-new-tenant";
|
||||
import { useContext } from "react";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { PropTypes } from "prop-types";
|
||||
import { provinceGetUserByKey } from "../../../province/services/province-get-user-by-key";
|
||||
|
||||
export const CitySubmitTenantForm = ({ id, userid }) => {
|
||||
const [openNotif] = useContext(AppContext);
|
||||
const dispatch = useDispatch();
|
||||
const [provinceData, setProvinceData] = useState();
|
||||
const [cityData, setCityData] = useState();
|
||||
const [provinceKey, setProvinceKey] = useState();
|
||||
const [cityKey, setCityKey] = useState();
|
||||
|
||||
const [isExistProvince, setIsExistProvince] = useState(true);
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues: {
|
||||
mobile: "",
|
||||
fname: "",
|
||||
lname: "",
|
||||
nationalcode: "",
|
||||
address: "",
|
||||
postal: "",
|
||||
password: "",
|
||||
uniqueID: "",
|
||||
},
|
||||
validationSchema: Yup.object({
|
||||
mobile: Yup.number()
|
||||
.required("این فیلد اجباری است!")
|
||||
.typeError("لطفا فیلد را به صورت عددی وارد کنید!")
|
||||
.test("len", "شماره تلفن باید با 0 شروع شود", (val, context) => {
|
||||
return context.originalValue && context.originalValue.startsWith("0");
|
||||
})
|
||||
.test("len", "شماره تماس 11 رقم باید باشد", (val, context) => {
|
||||
if (context.originalValue) {
|
||||
return context.originalValue.length === 11;
|
||||
}
|
||||
}),
|
||||
fname: Yup.string()
|
||||
.required("این فیلد اجباری است!")
|
||||
.typeError("لطفا فیلد را پر کنید!"),
|
||||
lname: Yup.string()
|
||||
.required("این فیلد اجباری است!")
|
||||
.typeError("لطفا فیلد را پر کنید!"),
|
||||
nationalcode: Yup.number()
|
||||
.required("این فیلد اجباری است!")
|
||||
.test("len", "کد ملی میبایست ده رقم باشد.", (val, context) => {
|
||||
if (context.originalValue) {
|
||||
return context.originalValue.length === 10;
|
||||
}
|
||||
}),
|
||||
|
||||
address: Yup.string()
|
||||
.required("این فیلد اجباری است!")
|
||||
.typeError("لطفا فیلد را پر کنید!"),
|
||||
postal: Yup.number()
|
||||
.required("این فیلد اجباری است!")
|
||||
.typeError("لطفا فیلد را به صورت عددی وارد کنید!"),
|
||||
uniqueID: Yup.number()
|
||||
.required("این فیلد اجباری است!")
|
||||
.typeError("لطفا فیلد را به صورت عددی وارد کنید!"),
|
||||
password: Yup.string()
|
||||
.required("این فیلد اجباری است!")
|
||||
.typeError("لطفا مقادیر را به درستی وارد کنید!")
|
||||
.test(
|
||||
"len",
|
||||
"لطفا حداقل 5 حرف و حداکثر 12 حرف وارد کنید",
|
||||
(val) => val.toString().length >= 5 && val.toString().length <= 12
|
||||
),
|
||||
}),
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
formik.validateForm();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(LOADING_START());
|
||||
dispatch(cityGetProvinces())?.then((r) => {
|
||||
dispatch(LOADING_END());
|
||||
setProvinceData(r.payload.data);
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
formik.validateForm();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (provinceKey) {
|
||||
dispatch(LOADING_START());
|
||||
dispatch(cityGetCity(provinceKey)).then((r) => {
|
||||
setCityData(r.payload.data);
|
||||
setIsExistProvince(false);
|
||||
dispatch(LOADING_END());
|
||||
});
|
||||
}
|
||||
}, [provinceKey]);
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
display="block"
|
||||
gap={SPACING.SMALL}
|
||||
direction="column"
|
||||
flex="1"
|
||||
height="100%"
|
||||
justifyContent="space-between"
|
||||
>
|
||||
<Grid container direction="column" gap={SPACING.SMALL}>
|
||||
<Grid>
|
||||
<Autocomplete
|
||||
disablePortal
|
||||
id="province"
|
||||
options={
|
||||
provinceData
|
||||
? provinceData?.map((i) => ({ id: i.key, label: i.name }))
|
||||
: []
|
||||
}
|
||||
onChange={(event, value) => {
|
||||
setProvinceKey(value.id);
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField {...params} label="استان را انتخاب کنید" />
|
||||
)}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<Autocomplete
|
||||
disabled={isExistProvince}
|
||||
disablePortal
|
||||
id="city"
|
||||
options={
|
||||
cityData
|
||||
? cityData.map((i) => ({ id: i.key, label: i.name }))
|
||||
: []
|
||||
}
|
||||
onChange={(event, value) => {
|
||||
setCityKey(value.id);
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField {...params} label="شهر را انتخاب کنید" />
|
||||
)}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<TextField
|
||||
id="uniqueID"
|
||||
label="شناسه یکتا مرغدار"
|
||||
variant="outlined"
|
||||
sx={{ width: "100%" }}
|
||||
value={formik.values.uniqueID}
|
||||
error={
|
||||
formik.touched.uniqueID ? Boolean(formik.errors.uniqueID) : null
|
||||
}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.uniqueID && Boolean(formik.errors.uniqueID)
|
||||
? formik.errors.uniqueID
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<TextField
|
||||
id="fname"
|
||||
label="نام"
|
||||
variant="outlined"
|
||||
sx={{ width: "100%" }}
|
||||
value={formik.values.fname}
|
||||
error={formik.touched.fname ? Boolean(formik.errors.fname) : null}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.fname && Boolean(formik.errors.fname)
|
||||
? formik.errors.fname
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<TextField
|
||||
id="lname"
|
||||
label="نام خانوادگی "
|
||||
variant="outlined"
|
||||
sx={{ width: "100%" }}
|
||||
value={formik.values.lname}
|
||||
error={formik.touched.lname ? Boolean(formik.errors.lname) : null}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.lname && Boolean(formik.errors.lname)
|
||||
? formik.errors.lname
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<TextField
|
||||
id="password"
|
||||
label="رمز عبور"
|
||||
type="password"
|
||||
variant="outlined"
|
||||
sx={{ width: "100%" }}
|
||||
value={formik.values.password}
|
||||
error={
|
||||
formik.touched.password ? Boolean(formik.errors.password) : null
|
||||
}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.password && Boolean(formik.errors.password)
|
||||
? formik.errors.password
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<TextField
|
||||
id="mobile"
|
||||
label="موبایل"
|
||||
variant="outlined"
|
||||
sx={{ width: "100%" }}
|
||||
value={formik.values.mobile}
|
||||
error={formik.touched.mobile ? Boolean(formik.errors.mobile) : null}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.mobile && Boolean(formik.errors.mobile)
|
||||
? formik.errors.mobile
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<TextField
|
||||
id="nationalcode"
|
||||
label="کد ملی"
|
||||
variant="outlined"
|
||||
sx={{ width: "100%" }}
|
||||
value={formik.values.nationalcode}
|
||||
error={
|
||||
formik.touched.nationalcode
|
||||
? Boolean(formik.errors.nationalcode)
|
||||
: null
|
||||
}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.nationalcode && Boolean(formik.errors.nationalcode)
|
||||
? formik.errors.nationalcode
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<TextField
|
||||
id="address"
|
||||
label="آدرس"
|
||||
variant="outlined"
|
||||
sx={{ width: "100%" }}
|
||||
value={formik.values.address}
|
||||
error={
|
||||
formik.touched.address ? Boolean(formik.errors.address) : null
|
||||
}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.address && Boolean(formik.errors.address)
|
||||
? formik.errors.address
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<TextField
|
||||
id="postal"
|
||||
label="کد پستی"
|
||||
variant="outlined"
|
||||
sx={{ width: "100%" }}
|
||||
value={formik.values.postal}
|
||||
error={formik.touched.postal ? Boolean(formik.errors.postal) : null}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
helperText={
|
||||
formik.touched.postal && Boolean(formik.errors.postal)
|
||||
? formik.errors.postal
|
||||
: null
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid mb={SPACING.SMALL}>
|
||||
<Button
|
||||
fullWidth
|
||||
variant="contained"
|
||||
disabled={!formik.isValid}
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
citySubmitNewTenant({
|
||||
username: formik.values.mobile,
|
||||
password: formik.values.password,
|
||||
api_key: "11d89a11-bd11-2111-a02f-2cc1cbf4e1d4",
|
||||
role: "Poultry",
|
||||
tenant: {
|
||||
poultry_key: id,
|
||||
unique_id: formik.values.uniqueID,
|
||||
province: provinceKey,
|
||||
city: cityKey,
|
||||
first_name: formik.values.fname,
|
||||
last_name: formik.values.lname,
|
||||
national_code: formik.values.nationalcode,
|
||||
address: formik.values.address,
|
||||
postal_code: formik.values.postal,
|
||||
},
|
||||
})
|
||||
).then((r) => {
|
||||
dispatch(LOADING_END());
|
||||
dispatch(provinceGetUserByKey(userid));
|
||||
if (r.error) {
|
||||
dispatch(LOADING_END());
|
||||
if (r.error.message.includes("403")) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "این مستاجر موجود است!",
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "مشکلی پیش آمده است!",
|
||||
severity: "error",
|
||||
});
|
||||
}
|
||||
} else {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
dispatch(
|
||||
DRAWER({ right: false, bottom: false, content: null })
|
||||
);
|
||||
}
|
||||
});
|
||||
}}
|
||||
>
|
||||
ثبت اطلاعات
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
CitySubmitTenantForm.propTypes = {
|
||||
id: PropTypes.any,
|
||||
userid: PropTypes.any,
|
||||
};
|
||||
@@ -0,0 +1,64 @@
|
||||
import { Divider, List, ListItem, ListItemText } from "@mui/material";
|
||||
import React from "react";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { PropTypes } from "prop-types";
|
||||
|
||||
export const CityTenantOwnerInfo = ({ item }) => {
|
||||
return (
|
||||
<>
|
||||
<Divider />
|
||||
<Grid container direction="row" flexWrap="nowrap" flex="1">
|
||||
<Grid>
|
||||
<List
|
||||
sx={{
|
||||
width: "100%",
|
||||
maxWidth: 360,
|
||||
bgcolor: "background.paper",
|
||||
}}
|
||||
>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary="نام"
|
||||
secondary={item?.poultryTenant.fullName}
|
||||
/>
|
||||
</ListItem>{" "}
|
||||
<Divider />
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary="شناسه یکتا"
|
||||
secondary={item?.poultryTenant.breedingUniqueId}
|
||||
/>
|
||||
</ListItem>{" "}
|
||||
</List>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<List
|
||||
sx={{
|
||||
width: "100%",
|
||||
maxWidth: 360,
|
||||
bgcolor: "background.paper",
|
||||
}}
|
||||
>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary="موبایل"
|
||||
secondary={item?.poultryTenant.mobile}
|
||||
/>
|
||||
</ListItem>{" "}
|
||||
<Divider />
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary="کد ملی"
|
||||
secondary={item?.poultryTenant.nationalId}
|
||||
/>
|
||||
</ListItem>
|
||||
</List>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
CityTenantOwnerInfo.propTypes = {
|
||||
item: PropTypes.object,
|
||||
};
|
||||
@@ -0,0 +1,180 @@
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import { styled } from "@mui/material/styles";
|
||||
import Button from "@mui/material/Button";
|
||||
import CloudUploadIcon from "@mui/icons-material/CloudUpload";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { Typography } from "@mui/material";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { cityUpdateHatchingService } from "../../services/city-update-hatching";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { SimpleTable } from "../../../../components/simple-table/SimpleTable";
|
||||
import { cityUpdateChickenBreedService } from "../../services/city-update-chicken-breen";
|
||||
|
||||
const VisuallyHiddenInput = styled("input")({
|
||||
clip: "rect(0 0 0 0)",
|
||||
clipPath: "inset(50%)",
|
||||
height: 1,
|
||||
overflow: "hidden",
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
whiteSpace: "nowrap",
|
||||
width: 1,
|
||||
});
|
||||
|
||||
export const CityUpdateHatching = () => {
|
||||
const dispatch = useDispatch();
|
||||
const [openNotif] = useContext(AppContext);
|
||||
const [response, setResponse] = useState();
|
||||
const [tableData, setTableData] = useState();
|
||||
const handleFileUpload = async (event) => {
|
||||
const file = event.target.files[0];
|
||||
if (!file) return;
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("file", file);
|
||||
|
||||
dispatch(cityUpdateHatchingService(formData))
|
||||
.unwrap()
|
||||
.then((r) => {
|
||||
setResponse(r.data);
|
||||
if (r.status === 201) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
} else {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "فایل اکسل به درستی ارسال نشده است!",
|
||||
severity: "error",
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
const handleUpdateChickenBreed = async (event) => {
|
||||
const file = event.target.files[0];
|
||||
if (!file) return;
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("file", file);
|
||||
|
||||
dispatch(cityUpdateChickenBreedService(formData))
|
||||
.unwrap()
|
||||
.then((r) => {
|
||||
if (r.status === 201) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
} else {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "فایل اکسل به درستی ارسال نشده است!",
|
||||
severity: "error",
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
useEffect(() => {
|
||||
const d = response?.map((item, i) => {
|
||||
return [i + 1, item];
|
||||
});
|
||||
setTableData(d);
|
||||
}, [response]);
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
spacing={2}
|
||||
mb={1}
|
||||
style={{ width: "80vw" }}
|
||||
>
|
||||
<Grid
|
||||
xs={12}
|
||||
md={6}
|
||||
sm={6}
|
||||
container
|
||||
alignItems="center"
|
||||
mt={6}
|
||||
spacing={2}
|
||||
justifyContent="center"
|
||||
style={
|
||||
window.innerWidth >= 800 && {
|
||||
borderStyle: "solid",
|
||||
borderWidth: "0px 0px 0px 1px",
|
||||
borderColor: "gray",
|
||||
}
|
||||
}
|
||||
>
|
||||
<Grid>
|
||||
<Typography variant="body1" style={{ color: "gray" }}>
|
||||
آپدیت جوجه ریزی
|
||||
</Typography>
|
||||
</Grid>
|
||||
|
||||
<Grid>
|
||||
<Button
|
||||
component="label"
|
||||
role={undefined}
|
||||
variant="contained"
|
||||
tabIndex={-1}
|
||||
startIcon={<CloudUploadIcon />}
|
||||
>
|
||||
آپلود فایل اکسل
|
||||
<VisuallyHiddenInput type="file" onChange={handleFileUpload} />
|
||||
</Button>
|
||||
{response?.length ? (
|
||||
<Grid container xs={12} justifyContent="start">
|
||||
<SimpleTable
|
||||
columns={["ردیف", "شناسه یکتا"]}
|
||||
name={"مرغداران ناموجود در سامانه"}
|
||||
data={tableData}
|
||||
/>
|
||||
</Grid>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid
|
||||
xs={12}
|
||||
md={6}
|
||||
sm={6}
|
||||
container
|
||||
alignItems="center"
|
||||
mt={6}
|
||||
spacing={2}
|
||||
justifyContent="center"
|
||||
>
|
||||
<Grid>
|
||||
<Typography variant="body1" style={{ color: "gray" }}>
|
||||
آپدیت نژاد
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<Button
|
||||
component="label"
|
||||
role={undefined}
|
||||
variant="contained"
|
||||
tabIndex={-1}
|
||||
startIcon={<CloudUploadIcon />}
|
||||
>
|
||||
آپلود فایل اکسل
|
||||
<VisuallyHiddenInput
|
||||
type="file"
|
||||
onChange={handleUpdateChickenBreed}
|
||||
/>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,111 @@
|
||||
import { Button, Grid } from "@mui/material";
|
||||
import { useFormik } from "formik";
|
||||
import { useContext, useEffect } from "react";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { NumberInput } from "../../../../components/number-format-custom/NumberFormatCustom";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import { avicultureHatchingRequestsService } from "../../../aviculture/services/aviculture-hatching-requests";
|
||||
import { avicultureGetRequests } from "../../../aviculture/services/aviculture-requests";
|
||||
import { updateKillPoultryRequest } from "../../../province/services/update-kill-poultry-request";
|
||||
import { cityGetHatchings } from "../../services/city-get-hatchings";
|
||||
import { getSlaughtersKillRequestService } from "../../services/get-slaughters-kill-request";
|
||||
|
||||
export const CityUpdateKillRequest = ({ item, updateTable }) => {
|
||||
const [openNotif] = useContext(AppContext);
|
||||
const dispatch = useDispatch();
|
||||
const [, , selectedDate1, , selectedDate2] = useContext(AppContext);
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues: {
|
||||
quantity: "",
|
||||
},
|
||||
validate: (values) => {
|
||||
const errors = {};
|
||||
|
||||
if (!values.quantity) {
|
||||
errors.quantity = "Required";
|
||||
} else if (isNaN(values.quantity)) {
|
||||
errors.quantity = "Must be a number";
|
||||
}
|
||||
// else if (
|
||||
// values.quantity > item.process?.poultry?.poultryPreviousQuantity
|
||||
// ) {
|
||||
// errors.quantity =
|
||||
// "Quantity cannot be greater than poultryPreviousQuantity";
|
||||
// } else if (0 >= item.process?.poultry?.poultryRemainQuantity) {
|
||||
// errors.quantity =
|
||||
// "Quantity cannot be greater than poultryPreviousQuantity";
|
||||
// }
|
||||
|
||||
return errors;
|
||||
},
|
||||
onSubmit: (values) => {
|
||||
// console.log(values);
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
formik.validateForm();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
formik.setFieldValue("quantity", item.quantity);
|
||||
}, [item.quantity]);
|
||||
|
||||
return (
|
||||
<Grid direction="row" display="flex" key="ooo">
|
||||
<NumberInput
|
||||
allowLeadingZeros
|
||||
thousandSeparator=","
|
||||
id="quantity"
|
||||
onChange={formik.handleChange}
|
||||
value={formik.values.quantity}
|
||||
style={{ width: 80, textAlign: "center" }}
|
||||
/>
|
||||
<Button
|
||||
disabled={!formik.isValid}
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
updateKillPoultryRequest({
|
||||
key: item.key,
|
||||
quantity: Number(formik.values.quantity),
|
||||
state: "accepted_quantity",
|
||||
})
|
||||
).then((r) => {
|
||||
if (r.payload.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.error,
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
dispatch(CLOSE_MODAL());
|
||||
updateTable();
|
||||
dispatch(
|
||||
avicultureHatchingRequestsService({
|
||||
selectedDate1,
|
||||
selectedDate2,
|
||||
})
|
||||
);
|
||||
dispatch(getSlaughtersKillRequestService());
|
||||
dispatch(avicultureGetRequests());
|
||||
dispatch(cityGetHatchings(getRoleFromUrl()));
|
||||
dispatch(avicultureGetRequests());
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
}
|
||||
});
|
||||
}}
|
||||
>
|
||||
ثبت
|
||||
</Button>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,411 @@
|
||||
import {
|
||||
Button,
|
||||
FormControlLabel,
|
||||
IconButton,
|
||||
Switch,
|
||||
Tooltip,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import React from "react";
|
||||
import { useEffect } from "react";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import NavigateNextIcon from "@mui/icons-material/NavigateNext";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useState } from "react";
|
||||
import EditIcon from "@mui/icons-material/Edit";
|
||||
import InfoIcon from "@mui/icons-material/Info";
|
||||
import {
|
||||
DRAWER,
|
||||
LOADING_END,
|
||||
LOADING_START,
|
||||
} from "../../../../lib/redux/slices/appSlice";
|
||||
import { provinceGetUserByKey } from "../../../province/services/province-get-user-by-key";
|
||||
import { InspectorEditUserProfile } from "../../../inspector/components/inspector-edit-user-profile/InspectorEditUserProfile";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { SimpleTable } from "../../../../components/simple-table/SimpleTable";
|
||||
import { inspectorChangeUserState } from "../../../inspector/services/inspector-change-user-state";
|
||||
import { CitySubmitTenantForm } from "../city-submit-tenant-form/CitySubmitTenantForm";
|
||||
import { InspectorEditAviculture } from "../../../inspector/components/inspector-edit-aviculture/InspectorEditAviculture";
|
||||
import { format } from "date-fns-jalali";
|
||||
|
||||
// import { inspectorUpdateUserProfile } from "../../services/inspector-update-user-profile";
|
||||
|
||||
export const CityUserFileInfo = () => {
|
||||
const { userid } = useParams();
|
||||
const dispatch = useDispatch();
|
||||
const navigate = useNavigate();
|
||||
const [dataTable, setDataTable] = useState([]);
|
||||
const { provinceUserInfo } = useSelector((state) => state.provinceSlice);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(LOADING_START());
|
||||
dispatch(provinceGetUserByKey(userid)).then(() => {
|
||||
dispatch(LOADING_END());
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const userRoles = provinceUserInfo?.profile.role?.map((item, i) => {
|
||||
let name = "";
|
||||
switch (item) {
|
||||
case "ProvinceOperator":
|
||||
name = "اپراتور تخصیص استان";
|
||||
break;
|
||||
case "CityOperator":
|
||||
name = "اپراتور شهرستان";
|
||||
break;
|
||||
case "KillHouseVet":
|
||||
name = "دامپزشک کشتارگاه";
|
||||
break;
|
||||
case "VetFarm":
|
||||
name = "دامپزشک";
|
||||
break;
|
||||
case "Poultry":
|
||||
name = "مرغدار";
|
||||
break;
|
||||
case "KillHouse":
|
||||
name = "کشتارگاه";
|
||||
break;
|
||||
case "Vet":
|
||||
name = "دامپزشک";
|
||||
break;
|
||||
case "ProvinceInspector":
|
||||
name = "بازرس استان";
|
||||
break;
|
||||
case "ProvinceFinancial":
|
||||
name = "اپراتور مالی";
|
||||
break;
|
||||
case "Driver":
|
||||
name = "راننده";
|
||||
break;
|
||||
case "Admin":
|
||||
name = "ادمین";
|
||||
break;
|
||||
default:
|
||||
name = "کاربر پایه";
|
||||
break;
|
||||
}
|
||||
return <div key={i}>{name}</div>;
|
||||
});
|
||||
const userProfilePic =
|
||||
provinceUserInfo?.profile?.image > 5 ? (
|
||||
<a href={provinceUserInfo?.profile.image}>
|
||||
<img
|
||||
width="80"
|
||||
height="80"
|
||||
alt="img"
|
||||
src={provinceUserInfo?.profile.image}
|
||||
/>
|
||||
</a>
|
||||
) : (
|
||||
"موجود نیست"
|
||||
);
|
||||
const b = [
|
||||
[
|
||||
provinceUserInfo?.profile?.fullname
|
||||
? provinceUserInfo?.profile?.fullname
|
||||
: provinceUserInfo?.profile?.firstName +
|
||||
" " +
|
||||
provinceUserInfo?.profile?.lastName,
|
||||
userRoles,
|
||||
provinceUserInfo?.profile?.mobile,
|
||||
provinceUserInfo?.profile?.birthday
|
||||
? format(new Date(provinceUserInfo?.profile?.birthday), "yyyy/MM/dd")
|
||||
: "نامشخص",
|
||||
provinceUserInfo?.profile?.city,
|
||||
<Typography variant="caption" key="password">
|
||||
{provinceUserInfo?.profile?.password}
|
||||
</Typography>,
|
||||
userProfilePic,
|
||||
<IconButton
|
||||
key={provinceUserInfo}
|
||||
aria-label="delete"
|
||||
color="primary"
|
||||
className="avicultureActiveRequestsBtn"
|
||||
onClick={() => {
|
||||
// dispatch(inspectorUpdateUserProfile());
|
||||
dispatch(
|
||||
DRAWER({
|
||||
title: "ویرایش پروفایل کاربر",
|
||||
right: !(window.innerWidth <= 600),
|
||||
bottom: window.innerWidth <= 600,
|
||||
content: (
|
||||
<InspectorEditUserProfile
|
||||
id={provinceUserInfo?.profile?.key}
|
||||
birthday={provinceUserInfo?.profile?.birthday}
|
||||
nationalCode={provinceUserInfo?.profile?.nationalCode}
|
||||
nationalId={provinceUserInfo?.profile?.nationalId}
|
||||
firstName={provinceUserInfo?.profile?.firstName}
|
||||
lastName={provinceUserInfo?.profile?.lastName}
|
||||
password={provinceUserInfo?.profile?.password}
|
||||
phone={provinceUserInfo?.profile?.mobile}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
<EditIcon />
|
||||
</IconButton>,
|
||||
],
|
||||
];
|
||||
|
||||
setDataTable(b);
|
||||
}, [provinceUserInfo]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Grid container alignItems="center" mt={SPACING.SMALL}>
|
||||
<IconButton
|
||||
aria-label="delete"
|
||||
color="primary"
|
||||
onClick={() => navigate(-1)}
|
||||
>
|
||||
<NavigateNextIcon />
|
||||
<Typography>بازگشت</Typography>
|
||||
</IconButton>
|
||||
</Grid>
|
||||
|
||||
<Grid
|
||||
container
|
||||
xs={12}
|
||||
alignItems={"start"}
|
||||
gap={SPACING.SMALL}
|
||||
direction={"column"}
|
||||
>
|
||||
<Grid
|
||||
width="100%"
|
||||
container
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
>
|
||||
<Grid width="100%" className="second">
|
||||
<SimpleTable
|
||||
name="اطلاعات پایه کاربر"
|
||||
columns={[
|
||||
"نام کامل",
|
||||
"نوع کاربری",
|
||||
"شمار تلفن",
|
||||
"تاریخ تولد",
|
||||
"شهر",
|
||||
"کلمه عبور",
|
||||
"تصویر پروفایل",
|
||||
"ویرایش",
|
||||
]}
|
||||
data={dataTable}
|
||||
/>
|
||||
|
||||
{provinceUserInfo?.rolesData?.map((item, i) => {
|
||||
if (Object.keys(item).includes("Poultry")) {
|
||||
return (
|
||||
<>
|
||||
<SimpleTable
|
||||
key={i}
|
||||
name="اطلاعات مرغدار"
|
||||
columns={[
|
||||
"نام فارم",
|
||||
"آدرس",
|
||||
"استان",
|
||||
"شهر",
|
||||
"کد پستی",
|
||||
"موبایل",
|
||||
"شناسه یکتا",
|
||||
"کد اقتصادی",
|
||||
"کد اپیدمیولوژیک",
|
||||
"تعداد سالن",
|
||||
"ویرایش",
|
||||
"وضعیت",
|
||||
]}
|
||||
data={[
|
||||
[
|
||||
item.Poultry?.unitName,
|
||||
item.Poultry.address?.address,
|
||||
item.Poultry.address?.province?.name,
|
||||
item.Poultry.address?.city?.name,
|
||||
Number(item.Poultry.address?.postalCode),
|
||||
item.Poultry.address?.phone,
|
||||
item.Poultry.breedingUniqueId,
|
||||
item.Poultry.economicCode,
|
||||
item.Poultry.epidemiologicalCode,
|
||||
item.Poultry.numberOfHalls,
|
||||
<Tooltip
|
||||
key={i}
|
||||
title={"ویرایش کاربر"}
|
||||
placement="bottom-start"
|
||||
>
|
||||
<IconButton
|
||||
aria-label="delete"
|
||||
color="primary"
|
||||
className="avicultureActiveRequestsBtn"
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
DRAWER({
|
||||
title: "ویرایش اطلاعات مرغدار",
|
||||
right: !(window.innerWidth <= 600),
|
||||
bottom: window.innerWidth <= 600,
|
||||
content: (
|
||||
<InspectorEditAviculture
|
||||
farmName={item.Poultry?.unitName}
|
||||
id={provinceUserInfo?.profile.key}
|
||||
type="Poultry"
|
||||
uniqueId={
|
||||
item.Poultry?.breedingUniqueId
|
||||
}
|
||||
address={item.Poultry.address?.address}
|
||||
poultry={item.Poultry?.key}
|
||||
halls={item.Poultry.numberOfHalls}
|
||||
postal={Number(
|
||||
item.Poultry.address?.postalCode
|
||||
)}
|
||||
accountHolder={
|
||||
item.Poultry.userBankInfo
|
||||
?.nameOfBankUser
|
||||
}
|
||||
card={item.Poultry.userBankInfo?.card}
|
||||
shaba={item.Poultry.userBankInfo?.shaba}
|
||||
account={
|
||||
item.Poultry.userBankInfo?.account
|
||||
}
|
||||
name_of_bank_user={
|
||||
item.Poultry.userBankInfo?.bankName
|
||||
}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
<EditIcon />
|
||||
</IconButton>
|
||||
</Tooltip>,
|
||||
<Tooltip
|
||||
key={i}
|
||||
title={
|
||||
item.Poultry.trash === true
|
||||
? "فعالسازی کاربر"
|
||||
: "غیر فعال کردن کاربر"
|
||||
}
|
||||
placement="bottom-start"
|
||||
>
|
||||
<FormControlLabel
|
||||
label={
|
||||
item.Poultry.trash === true
|
||||
? "غیرفعال"
|
||||
: " فعال"
|
||||
}
|
||||
control={
|
||||
<Switch
|
||||
checked={!item.Poultry.trash}
|
||||
onClick={() => {
|
||||
dispatch(LOADING_START());
|
||||
dispatch(
|
||||
inspectorChangeUserState({
|
||||
type:
|
||||
item.Poultry.trash === true
|
||||
? "Activate"
|
||||
: "Deactivate",
|
||||
role_data_key: item.Poultry.key,
|
||||
role: "Poultry",
|
||||
})
|
||||
).then((r) => {
|
||||
dispatch(LOADING_END());
|
||||
window.location.reload(false);
|
||||
});
|
||||
}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</Tooltip>,
|
||||
],
|
||||
]}
|
||||
/>
|
||||
|
||||
<SimpleTable
|
||||
key={i}
|
||||
name="اطلاعات بانکی مرغدار"
|
||||
expandable
|
||||
columns={[
|
||||
"نام صاحب حساب",
|
||||
"نام بانک",
|
||||
"شماره حساب",
|
||||
"شماره کارت",
|
||||
"شماره شبا",
|
||||
]}
|
||||
data={[
|
||||
[
|
||||
item.Poultry.userBankInfo?.nameOfBankUser,
|
||||
item.Poultry.userBankInfo?.bankName,
|
||||
Number(item.Poultry.userBankInfo?.account),
|
||||
Number(item.Poultry.userBankInfo?.card),
|
||||
item.Poultry.userBankInfo?.shaba,
|
||||
],
|
||||
]}
|
||||
/>
|
||||
{Object.keys(item.Poultry?.poultryTenant).length > 0 ? (
|
||||
<SimpleTable
|
||||
key={i}
|
||||
name="اطلاعات مستاجر مرغدار"
|
||||
expandable
|
||||
columns={[
|
||||
"شناسه یکتا",
|
||||
"نام کامل",
|
||||
"تلفن همراه",
|
||||
"کد ملی",
|
||||
]}
|
||||
data={[
|
||||
[
|
||||
item.Poultry.poultryTenant?.breedingUniqueId,
|
||||
item.Poultry.poultryTenant?.fullName,
|
||||
item.Poultry.poultryTenant?.mobile,
|
||||
item.Poultry.poultryTenant?.nationalId,
|
||||
],
|
||||
]}
|
||||
/>
|
||||
) : (
|
||||
!item.Poultry.poultryOwner.length > 0 && (
|
||||
<Grid
|
||||
display="flex"
|
||||
mt={SPACING.MEDIUM}
|
||||
gap={SPACING.SMALL}
|
||||
alignItems="center"
|
||||
mb={SPACING.MEDIUM}
|
||||
>
|
||||
<Grid display="flex" gap={SPACING.TINY}>
|
||||
<InfoIcon color="primary" />
|
||||
<Typography>مرغدار مستاجر ندارد</Typography>
|
||||
</Grid>
|
||||
<Button
|
||||
variant="outlined"
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
DRAWER({
|
||||
right: !(window.innerWidth <= 600),
|
||||
bottom: window.innerWidth <= 600,
|
||||
title: "ایجاد مستاجر جدید",
|
||||
content: (
|
||||
<CitySubmitTenantForm
|
||||
id={item.Poultry.key}
|
||||
userid={userid}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
افزودن مستاجر
|
||||
</Button>
|
||||
</Grid>
|
||||
)
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
})}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</>
|
||||
);
|
||||
};
|
||||
199
src/features/city/components/city-users/CityUsers.js
Normal file
199
src/features/city/components/city-users/CityUsers.js
Normal file
@@ -0,0 +1,199 @@
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
FormControlLabel,
|
||||
IconButton,
|
||||
Tooltip,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import { useState } from "react";
|
||||
import { useEffect } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
import ContactPageIcon from "@mui/icons-material/ContactPage";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { ROUTE_CITY_USER_FILE } from "../../../../routes/routes";
|
||||
import {
|
||||
DRAWER,
|
||||
LOADING_END,
|
||||
LOADING_START,
|
||||
} from "../../../../lib/redux/slices/appSlice";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable";
|
||||
import { CitySubmitAviculture } from "../city-submit-aviculture/CitySubmitAviculture";
|
||||
import { cityGetUserProfiles } from "../../services/city-get-user-profiles";
|
||||
|
||||
export const CityUsers = () => {
|
||||
const dispatch = useDispatch();
|
||||
const [dataTable, setDataTable] = useState([]);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { cityUsers } = useSelector((state) => state.citySlice);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(LOADING_START());
|
||||
dispatch(cityGetUserProfiles()).then((r) => {
|
||||
dispatch(LOADING_END());
|
||||
});
|
||||
}, []);
|
||||
|
||||
const [justBaseUsers, setJustBaseUsers] = useState(false);
|
||||
|
||||
const handleChange = (event) => {
|
||||
setJustBaseUsers(!justBaseUsers);
|
||||
};
|
||||
const [filteredData, setFilteredData] = useState(cityUsers);
|
||||
|
||||
useEffect(() => {
|
||||
if (justBaseUsers) {
|
||||
const newUsers = cityUsers?.filter((item, i) => {
|
||||
return item?.profile?.role.length === 0;
|
||||
});
|
||||
setFilteredData(newUsers);
|
||||
} else {
|
||||
setFilteredData(cityUsers);
|
||||
}
|
||||
const d = filteredData?.map((item, i) => {
|
||||
return [
|
||||
i + 1,
|
||||
item?.profile?.fullname
|
||||
? item?.profile?.fullname
|
||||
: item?.profile?.firstName + " " + item?.profile?.lastName,
|
||||
<Grid key={i}>
|
||||
{!(item?.profile?.role.length > 0) && "کاربر پایه"}
|
||||
{item?.profile?.role?.map((item, i) => {
|
||||
var name = "";
|
||||
switch (item) {
|
||||
case "ProvinceOperator":
|
||||
name = "اپراتور تخصیص استان";
|
||||
break;
|
||||
case "CityOperator":
|
||||
name = "اپراتور شهرستان";
|
||||
break;
|
||||
case "KillHouseVet":
|
||||
name = "دامپزشک کشتارگاه";
|
||||
break;
|
||||
case "VetFarm":
|
||||
name = "دامپزشک";
|
||||
break;
|
||||
case "Poultry":
|
||||
name = "مرغدار";
|
||||
break;
|
||||
case "KillHouse":
|
||||
name = "کشتارگاه";
|
||||
break;
|
||||
case "Vet":
|
||||
name = "دامپزشک";
|
||||
break;
|
||||
case "ProvinceInspector":
|
||||
name = "بازرس استان";
|
||||
break;
|
||||
case "ProvinceFinancial":
|
||||
name = "اپراتور مالی";
|
||||
break;
|
||||
case "Driver":
|
||||
name = "راننده";
|
||||
break;
|
||||
case "Admin":
|
||||
name = "ادمین";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return [<Grid key={i}>{name}</Grid>];
|
||||
})}
|
||||
</Grid>,
|
||||
item?.profile?.mobile,
|
||||
item?.profile?.baseOrder,
|
||||
item?.profile?.city,
|
||||
<Typography key="s" variant="caption">
|
||||
{item?.profile?.password}
|
||||
</Typography>,
|
||||
<Grid key={i}>
|
||||
<Tooltip key={i} title={"پرونده کاربر"} placement="right-start">
|
||||
<IconButton
|
||||
aria-label="delete"
|
||||
color="primary"
|
||||
className="avicultureActiveRequestsBtn"
|
||||
onClick={() => {
|
||||
navigate(ROUTE_CITY_USER_FILE + item?.profile?.key);
|
||||
}}
|
||||
>
|
||||
<ContactPageIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</Grid>,
|
||||
];
|
||||
});
|
||||
|
||||
setDataTable(d);
|
||||
}, [cityUsers, justBaseUsers, filteredData]);
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
xs={12}
|
||||
alignItems={"start"}
|
||||
gap={SPACING.SMALL}
|
||||
direction={"column"}
|
||||
>
|
||||
<Grid
|
||||
width="100%"
|
||||
container
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
>
|
||||
<Grid
|
||||
alignItems="center"
|
||||
flexDirection="inherit"
|
||||
container
|
||||
mt={SPACING.MEDIUM}
|
||||
gap={SPACING.SMALL}
|
||||
>
|
||||
<Button
|
||||
className="first-step"
|
||||
variant={"contained"}
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
DRAWER({
|
||||
title: "ثبت کاربر جدید",
|
||||
right: !(window.innerWidth <= 600),
|
||||
bottom: window.innerWidth <= 600,
|
||||
content: <CitySubmitAviculture />,
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
ثبت کاربر جدید
|
||||
</Button>
|
||||
|
||||
<FormControlLabel
|
||||
mt={SPACING.SMALL}
|
||||
control={<Checkbox />}
|
||||
label="فقط نمایش کاربران پایه"
|
||||
onChange={handleChange}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<Grid width="100%" className="second">
|
||||
<AdvancedTable
|
||||
expandable
|
||||
columns={[
|
||||
"ردیف",
|
||||
"نام کامل",
|
||||
"نوع کاربری",
|
||||
"شمار تلفن",
|
||||
"کد کاربری",
|
||||
"شهر",
|
||||
"کلمه عبور",
|
||||
"پرونده",
|
||||
]}
|
||||
data={dataTable}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,67 @@
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { NavLink } from "../../../../components/nav-link/NavLink";
|
||||
|
||||
import LinkItem from "../../../../components/link-item/LinkItem";
|
||||
import { VscCompassDot } from "react-icons/vsc";
|
||||
import { IoIosArrowDropupCircle } from "react-icons/io";
|
||||
import {
|
||||
ROUTE_ADMINX_DIFFRENCE_KILLER_SLAUGHTER,
|
||||
ROUTE_ADMINX_INCREASE_HATCHING,
|
||||
ROUTE_CITY_DIFFRENCE_KILLER_SLAUGHTER,
|
||||
ROUTE_CITY_INCREASE_HATCHING,
|
||||
ROUTE_PROVINCE_DIFFRENCE_KILLER_SLAUGHTER,
|
||||
ROUTE_PROVINCE_INCREASE_HATCHING,
|
||||
ROUTE_SUPER_ADMIN_DIFFRENCE_KILLER_SLAUGHTER,
|
||||
ROUTE_SUPER_ADMIN_INCREASE_HATCHING,
|
||||
} from "../../../../routes/routes";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
|
||||
export const CityManageDiffrenceKillerOperation = () => {
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
gap={SPACING.SMALL}
|
||||
p={SPACING.SMALL}
|
||||
direction={{ xs: "row", md: "row" }}
|
||||
justifyContent="center"
|
||||
>
|
||||
<NavLink
|
||||
to={
|
||||
getRoleFromUrl() === "AdminX"
|
||||
? ROUTE_ADMINX_DIFFRENCE_KILLER_SLAUGHTER
|
||||
: getRoleFromUrl() === "SuperAdmin"
|
||||
? ROUTE_SUPER_ADMIN_DIFFRENCE_KILLER_SLAUGHTER
|
||||
: getRoleFromUrl() === "ProvinceOperator"
|
||||
? ROUTE_PROVINCE_DIFFRENCE_KILLER_SLAUGHTER
|
||||
: getRoleFromUrl() === "CityOperator"
|
||||
? ROUTE_CITY_DIFFRENCE_KILLER_SLAUGHTER
|
||||
: ""
|
||||
}
|
||||
>
|
||||
<LinkItem
|
||||
icon={<VscCompassDot size={30} color="#244CCC" />}
|
||||
title="اختلاف کشتار در کشتارگاه"
|
||||
/>
|
||||
</NavLink>
|
||||
<NavLink
|
||||
to={
|
||||
getRoleFromUrl() === "AdminX"
|
||||
? ROUTE_ADMINX_INCREASE_HATCHING
|
||||
: getRoleFromUrl() === "SuperAdmin"
|
||||
? ROUTE_SUPER_ADMIN_INCREASE_HATCHING
|
||||
: getRoleFromUrl() === "ProvinceOperator"
|
||||
? ROUTE_PROVINCE_INCREASE_HATCHING
|
||||
: getRoleFromUrl() === "CityOperator"
|
||||
? ROUTE_CITY_INCREASE_HATCHING
|
||||
: ""
|
||||
}
|
||||
>
|
||||
<LinkItem
|
||||
icon={<IoIosArrowDropupCircle size={30} color="#244CCC" />}
|
||||
title="افزایش حجم جوجه ریزی"
|
||||
/>
|
||||
</NavLink>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
|
||||
import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable";
|
||||
import { CheckCleanceCode } from "../../../../components/check-clearance-code/ChechClearanceCode";
|
||||
|
||||
export const NationalInfoDetails = ({ data }) => {
|
||||
const [tableData, setTableData] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
const d = data?.bars?.map((item, i) => {
|
||||
return [
|
||||
i + 1,
|
||||
<CheckCleanceCode key={i} clearanceCode={item?.TrackingCode} />,
|
||||
item?.IssueDatePersian,
|
||||
item?.GoodAmount?.toLocaleString(),
|
||||
item?.TrackingStatusDescription,
|
||||
item?.GoodName,
|
||||
item?.DesPartIdCode,
|
||||
item?.DesUnitName,
|
||||
item?.ResideDatePersian,
|
||||
];
|
||||
});
|
||||
setTableData(d);
|
||||
}, [data]);
|
||||
return (
|
||||
<Grid xs={12} container justifyContent="center">
|
||||
<AdvancedTable
|
||||
name="اطلاعات حمل مرغ زنده"
|
||||
columns={[
|
||||
"ردیف",
|
||||
"کد رهگیری",
|
||||
"تاریخ ثبت وضعیت",
|
||||
"تعداد",
|
||||
"وضعیت",
|
||||
"نام کالا",
|
||||
"شناسه یکتا کشتارگاه",
|
||||
"کشتارگاه",
|
||||
"تاریخ ثبت وضعیت",
|
||||
]}
|
||||
data={tableData}
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,394 @@
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import {
|
||||
Autocomplete,
|
||||
Button,
|
||||
Checkbox,
|
||||
IconButton,
|
||||
TextField,
|
||||
Tooltip,
|
||||
} from "@mui/material";
|
||||
import { DatePicker } from "@mui/x-date-pickers";
|
||||
import moment from "moment";
|
||||
import { useDispatch } from "react-redux";
|
||||
import axios from "axios";
|
||||
import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import {
|
||||
LOADING_END,
|
||||
LOADING_START,
|
||||
} from "../../../../lib/redux/slices/appSlice";
|
||||
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
|
||||
import { CheckCleanceCode } from "../../../../components/check-clearance-code/ChechClearanceCode";
|
||||
import { provinceNationalTransportManagementInfoDashboardService } from "../../../province/services/province-national-transport-managemant-info-dashboard-service";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { getSamasatProvinces } from "../../../../utils/getSamasatProvinces";
|
||||
import { formatJustDate } from "../../../../utils/formatTime";
|
||||
import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined";
|
||||
import ToggleOnIcon from "@mui/icons-material/ToggleOn";
|
||||
|
||||
export const NationalInfoTransports = () => {
|
||||
const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] =
|
||||
useContext(AppContext);
|
||||
const [selectedProvince, setSelectedProvince] = useState("");
|
||||
|
||||
const getProvince = () => {
|
||||
if (key === undefined) {
|
||||
return selectedProvince === "همه" ? "" : selectedProvince;
|
||||
} else {
|
||||
return key;
|
||||
}
|
||||
};
|
||||
|
||||
const getDashboardData = () => {
|
||||
dispatch(
|
||||
provinceNationalTransportManagementInfoDashboardService({
|
||||
date1: withDate ? selectedDate1 : null,
|
||||
date2: withDate ? selectedDate2 : null,
|
||||
search: textValue,
|
||||
province: getProvince(),
|
||||
PartIdCode: unitkey !== undefined ? unitkey : null,
|
||||
})
|
||||
).then((r) => {
|
||||
setDashboardData(r.payload.data);
|
||||
});
|
||||
};
|
||||
|
||||
const dispatch = useDispatch();
|
||||
useEffect(() => {
|
||||
const currentDate = moment(new Date()).format("YYYY-MM-DD");
|
||||
setSelectedDate1(currentDate);
|
||||
setSelectedDate2(currentDate);
|
||||
}, []);
|
||||
|
||||
const handleTextChange = (event) => {
|
||||
setTextValue(event.target.value);
|
||||
};
|
||||
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 [withDate, setWithDate] = useState(true);
|
||||
const [dashboardData, setDashboardData] = useState([]);
|
||||
const { key, unitkey, name } = useParams();
|
||||
|
||||
const fetchApiData = async (page) => {
|
||||
let response;
|
||||
dispatch(LOADING_START());
|
||||
response = await axios.get(
|
||||
`https://rsibackend.rasadyar.com/app/transporting-detail/?search=${textValue}${
|
||||
withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : ``
|
||||
}&page=${page}&page_size=${perPage}${
|
||||
unitkey !== undefined ? "&PartIdCode=" + unitkey : ""
|
||||
}&province=${getProvince()}`
|
||||
);
|
||||
dispatch(LOADING_END());
|
||||
getDashboardData();
|
||||
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,
|
||||
<CheckCleanceCode key={i} clearanceCode={item?.TrackingCode} />,
|
||||
formatJustDate(item?.Date),
|
||||
item?.DesUnitName,
|
||||
item?.DesPartIdCode,
|
||||
item?.Province,
|
||||
item?.City,
|
||||
item?.GoodAmount?.toLocaleString(),
|
||||
item?.TrackingStatusDescription,
|
||||
item?.Out ? "خارج استان" : "داخل استان",
|
||||
item?.SourceUnitName,
|
||||
item?.hatching?.poultry?.PartIdCode,
|
||||
item?.hatching?.RequestCode,
|
||||
item?.hatching?.poultry?.Province,
|
||||
item?.hatching?.poultry?.City,
|
||||
item?.Age,
|
||||
item?.hatching?.PedigreeName,
|
||||
// <Button
|
||||
// key={i}
|
||||
// variant="contained"
|
||||
// size="small"
|
||||
// color="primary"
|
||||
// onClick={() => {
|
||||
// dispatch(
|
||||
// DRAWER({
|
||||
// top: true,
|
||||
// content: <NationalInfoDetails data={item} size={1000} />,
|
||||
// title: "گزارش حمل مرغ زنده",
|
||||
// })
|
||||
// );
|
||||
// }}
|
||||
// >
|
||||
// مشاهده
|
||||
// </Button>,
|
||||
];
|
||||
});
|
||||
|
||||
setTableData(d);
|
||||
}, [data]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchApiData(1);
|
||||
}, [
|
||||
dispatch,
|
||||
selectedDate1,
|
||||
selectedDate2,
|
||||
perPage,
|
||||
withDate,
|
||||
selectedProvince,
|
||||
]);
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
getDashboardData();
|
||||
dispatch(LOADING_START());
|
||||
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`https://rsibackend.rasadyar.com/app/transporting-detail/?search=${textValue}${
|
||||
withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : ``
|
||||
}&page=${1}&page_size=${perPage}${
|
||||
unitkey !== undefined ? "&PartIdCode=" + unitkey : ""
|
||||
}&province=${getProvince()}`
|
||||
);
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
dispatch(LOADING_END());
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const getProvinceList = () => {
|
||||
return [{ name: "همه" }, ...getSamasatProvinces()];
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
xs={12}
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
gap={2}
|
||||
mt={4}
|
||||
>
|
||||
<Grid
|
||||
container
|
||||
xs={12}
|
||||
justifyContent="start"
|
||||
alignItems="center"
|
||||
gap={2}
|
||||
>
|
||||
{key === undefined && unitkey === undefined && name === undefined && (
|
||||
<Grid minWidth={210}>
|
||||
<Autocomplete
|
||||
size="small"
|
||||
disablePortal
|
||||
id="hatching"
|
||||
options={getProvinceList().map((i) => {
|
||||
return {
|
||||
label: i.name,
|
||||
};
|
||||
})}
|
||||
onChange={(event, value) => {
|
||||
if (value.label !== "همه") {
|
||||
setSelectedProvince(value.label);
|
||||
} else {
|
||||
setSelectedProvince("");
|
||||
}
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField {...params} label="انتخاب استان" />
|
||||
)}
|
||||
/>
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
<Grid
|
||||
container
|
||||
gap={1}
|
||||
style={{
|
||||
borderStyle: "solid",
|
||||
borderWidth: "1px",
|
||||
padding: "5px",
|
||||
borderRadius: "15px",
|
||||
borderColor: "gray",
|
||||
justifyContent: "left",
|
||||
}}
|
||||
alignItems="center"
|
||||
>
|
||||
<Checkbox
|
||||
icon={<ToggleOffOutlinedIcon />}
|
||||
checkedIcon={<ToggleOnIcon />}
|
||||
checked={withDate}
|
||||
onChange={() => setWithDate(!withDate)}
|
||||
color="primary"
|
||||
size="large"
|
||||
/>
|
||||
<Grid>
|
||||
<DatePicker
|
||||
disabled={!withDate}
|
||||
label="از تاریخ"
|
||||
id="date"
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
size="small"
|
||||
sx={{ width: { xs: "126px", md: "160px" } }}
|
||||
{...params}
|
||||
/>
|
||||
)}
|
||||
value={selectedDate1}
|
||||
onChange={(e) => {
|
||||
setSelectedDate1(moment(e).format("YYYY-MM-DD"));
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<DatePicker
|
||||
disabled={!withDate}
|
||||
label="تا تاریخ"
|
||||
id="date"
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
size="small"
|
||||
sx={{ width: { xs: "126px", md: "160px" } }}
|
||||
{...params}
|
||||
/>
|
||||
)}
|
||||
value={selectedDate2}
|
||||
onChange={(e) => {
|
||||
setSelectedDate2(moment(e).format("YYYY-MM-DD"));
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
</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>
|
||||
<Grid>
|
||||
<Tooltip
|
||||
placement="right"
|
||||
title={
|
||||
withDate
|
||||
? "دانلود اکسل"
|
||||
: "برای دانلود اکسل، بازه تاریخی را فعال کنید"
|
||||
}
|
||||
>
|
||||
<IconButton
|
||||
size="small"
|
||||
color="success"
|
||||
component="a"
|
||||
href={`https://rsibackend.rasadyar.com/app/all_send_different_bar_excel/?search=${textValue}${
|
||||
withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : ``
|
||||
}&province=${getProvince()}`}
|
||||
disabled={!withDate}
|
||||
>
|
||||
<RiFileExcel2Fill size={36} style={{ cursor: "pointer" }} />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid container mt={2} mb={4} isDashboard xs={12}>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
columns={[
|
||||
"تعداد بار",
|
||||
"حجم بار",
|
||||
"میانگین سن کشتار",
|
||||
"تعداد بار داخل استان",
|
||||
"حجم بار داخل استان",
|
||||
"درصد داخل استان",
|
||||
"تعداد بار خارج استان",
|
||||
"حجم بار خارج استان",
|
||||
"درصد خارج استان",
|
||||
]}
|
||||
data={[
|
||||
[
|
||||
dashboardData?.barCount?.toLocaleString(),
|
||||
dashboardData?.barQuantity?.toLocaleString(),
|
||||
Math.floor(dashboardData?.totalBarKillingAge),
|
||||
dashboardData?.inputBarCount?.toLocaleString(),
|
||||
dashboardData?.inputBarQuantity?.toLocaleString(),
|
||||
dashboardData?.inputBarPercent?.toFixed(1),
|
||||
dashboardData?.outputBar?.toLocaleString(),
|
||||
dashboardData?.outputBarQuantity?.toLocaleString(),
|
||||
dashboardData?.outputBarPercent?.toFixed(1),
|
||||
],
|
||||
]}
|
||||
title={"خلاصه اطلاعات"}
|
||||
/>
|
||||
</Grid>
|
||||
<ResponsiveTable
|
||||
data={tableData}
|
||||
columns={[
|
||||
"ردیف",
|
||||
"کد رهگیری قرنطینه",
|
||||
"تاریخ کشتار",
|
||||
"نام کشتارگاه",
|
||||
"شناسه یکتا کشتار گاه",
|
||||
"استان کشتارگاه",
|
||||
"شهر کشتارگاه",
|
||||
"تعداد ",
|
||||
"وضعیت ",
|
||||
"مقصد کشتار",
|
||||
"نام مرغدار",
|
||||
"شناسه یکتا مرغداری",
|
||||
"شناسه جوجه ریزی",
|
||||
"استان مرغدار",
|
||||
"شهرستان مرغدار",
|
||||
"سن کشتار",
|
||||
"نژاد",
|
||||
]}
|
||||
handlePageChange={handlePageChange}
|
||||
totalRows={totalRows}
|
||||
page={page}
|
||||
perPage={perPage}
|
||||
handlePerRowsChange={handlePerRowsChange}
|
||||
title={
|
||||
key || name
|
||||
? `گزارش اطلاعات بار ${key || name} `
|
||||
: `گزارش اطلاعات بار`
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,284 @@
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import { Button, Checkbox, FormControlLabel, TextField } from "@mui/material";
|
||||
import { DatePicker } from "@mui/x-date-pickers";
|
||||
import moment from "moment";
|
||||
import { useDispatch } from "react-redux";
|
||||
import axios from "axios";
|
||||
import { RiSearchLine } from "react-icons/ri";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import {
|
||||
LOADING_END,
|
||||
LOADING_START,
|
||||
} from "../../../../lib/redux/slices/appSlice";
|
||||
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
|
||||
import { CheckCleanceCode } from "../../../../components/check-clearance-code/ChechClearanceCode";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { formatJustDate } from "../../../../utils/formatTime";
|
||||
import { provinceNationalTransportManagementInfoDashboardService } from "../../../province/services/province-national-transport-managemant-info-dashboard-service";
|
||||
|
||||
export const NationalInfoHatchingDetails = () => {
|
||||
const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] =
|
||||
useContext(AppContext);
|
||||
|
||||
const getDashboardData = () => {
|
||||
dispatch(
|
||||
provinceNationalTransportManagementInfoDashboardService({
|
||||
date1: withDate ? selectedDate1 : null,
|
||||
date2: withDate ? selectedDate2 : null,
|
||||
search: textValue,
|
||||
RequestCode: key,
|
||||
})
|
||||
).then((r) => {
|
||||
setDashboardData(r.payload.data);
|
||||
});
|
||||
};
|
||||
|
||||
const dispatch = useDispatch();
|
||||
useEffect(() => {
|
||||
const currentDate = moment(new Date()).format("YYYY-MM-DD");
|
||||
setSelectedDate1(currentDate);
|
||||
setSelectedDate2(currentDate);
|
||||
}, []);
|
||||
|
||||
const handleTextChange = (event) => {
|
||||
setTextValue(event.target.value);
|
||||
};
|
||||
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 [withDate, setWithDate] = useState(false);
|
||||
const [dashboardData, setDashboardData] = useState([]);
|
||||
const { key, name } = useParams();
|
||||
|
||||
const fetchApiData = async (page) => {
|
||||
dispatch(LOADING_START());
|
||||
const response = await axios.get(
|
||||
`https://rsibackend.rasadyar.com/app/transporting-detail/?search=${textValue}${
|
||||
withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : ``
|
||||
}&page=${page}&page_size=${perPage}&RequestCode=${key}`
|
||||
);
|
||||
dispatch(LOADING_END());
|
||||
getDashboardData();
|
||||
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,
|
||||
<CheckCleanceCode key={i} clearanceCode={item?.TrackingCode} />,
|
||||
formatJustDate(item?.Date),
|
||||
item?.DesUnitName,
|
||||
item?.DesPartIdCode,
|
||||
item?.Province,
|
||||
item?.City,
|
||||
item?.GoodAmount?.toLocaleString(),
|
||||
item?.TrackingStatusDescription,
|
||||
item?.Out ? "خارج استان" : "داخل استان",
|
||||
item?.SourceUnitName,
|
||||
item?.hatching?.poultry?.PartIdCode,
|
||||
item?.hatching?.RequestCode,
|
||||
item?.hatching?.poultry?.Province,
|
||||
item?.hatching?.poultry?.City,
|
||||
item?.Age,
|
||||
item?.hatching?.PedigreeName,
|
||||
];
|
||||
});
|
||||
|
||||
setTableData(d);
|
||||
}, [data]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchApiData(1);
|
||||
}, [dispatch, selectedDate1, selectedDate2, perPage, withDate]);
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
dispatch(LOADING_START());
|
||||
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`https://rsibackend.rasadyar.com/app/transporting-detail/?search=${textValue}${
|
||||
withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : ``
|
||||
}&page=${1}&page_size=${perPage}&RequestCode=${key}`
|
||||
);
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
getDashboardData();
|
||||
dispatch(LOADING_END());
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid container xs={12} justifyContent="center" mt={3}>
|
||||
<Grid
|
||||
container
|
||||
xs={12}
|
||||
justifyContent="start"
|
||||
alignItems="center"
|
||||
gap={2}
|
||||
>
|
||||
<Grid
|
||||
container
|
||||
style={{
|
||||
borderStyle: "solid",
|
||||
borderWidth: "1px",
|
||||
padding: "10px",
|
||||
borderRadius: "15px",
|
||||
borderColor: "gray",
|
||||
justifyContent: "left",
|
||||
}}
|
||||
>
|
||||
<Grid>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={withDate}
|
||||
onChange={() => setWithDate(!withDate)}
|
||||
color="primary"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<DatePicker
|
||||
disabled={!withDate}
|
||||
label="از تاریخ"
|
||||
id="date"
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
size="small"
|
||||
style={{ width: "160px" }}
|
||||
{...params}
|
||||
/>
|
||||
)}
|
||||
value={selectedDate1}
|
||||
onChange={(e) => {
|
||||
setSelectedDate1(moment(e).format("YYYY-MM-DD"));
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<DatePicker
|
||||
disabled={!withDate}
|
||||
label="تا تاریخ"
|
||||
id="date"
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
size="small"
|
||||
style={{ width: "160px" }}
|
||||
{...params}
|
||||
/>
|
||||
)}
|
||||
value={selectedDate2}
|
||||
onChange={(e) => {
|
||||
setSelectedDate2(moment(e).format("YYYY-MM-DD"));
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
</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>
|
||||
</Grid>
|
||||
|
||||
<Grid container mt={2} mb={4} isDashboard xs={12}>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
columns={[
|
||||
"تعداد بار",
|
||||
"حجم بار",
|
||||
"میانگین سن کشتار",
|
||||
"تعداد بار داخل استان",
|
||||
"حجم بار داخل استان",
|
||||
"درصد داخل استان",
|
||||
"تعداد بار خارج استان",
|
||||
"حجم بار خارج استان",
|
||||
"درصد خارج استان",
|
||||
]}
|
||||
data={[
|
||||
[
|
||||
dashboardData?.barCount?.toLocaleString(),
|
||||
dashboardData?.barQuantity?.toLocaleString(),
|
||||
Math.floor(dashboardData?.totalBarKillingAge),
|
||||
dashboardData?.inputBarCount?.toLocaleString(),
|
||||
dashboardData?.inputBarQuantity?.toLocaleString(),
|
||||
dashboardData?.inputBarPercent?.toFixed(1),
|
||||
dashboardData?.outputBar?.toLocaleString(),
|
||||
dashboardData?.outputBarQuantity?.toLocaleString(),
|
||||
dashboardData?.outputBarPercent?.toFixed(1),
|
||||
],
|
||||
]}
|
||||
title={"خلاصه اطلاعات"}
|
||||
/>
|
||||
</Grid>
|
||||
<ResponsiveTable
|
||||
data={tableData}
|
||||
columns={[
|
||||
"ردیف",
|
||||
"کد رهگیری قرنطینه",
|
||||
"تاریخ کشتار",
|
||||
"نام کشتارگاه",
|
||||
"شناسه یکتا کشتار گاه",
|
||||
"استان کشتارگاه",
|
||||
"شهر کشتارگاه",
|
||||
"تعداد ",
|
||||
"وضعیت ",
|
||||
"مقصد کشتار",
|
||||
"نام مرغدار",
|
||||
"شناسه یکتا مرغداری",
|
||||
"شناسه جوجه ریزی",
|
||||
"استان مرغدار",
|
||||
"شهرستان مرغدار",
|
||||
"سن کشتار",
|
||||
"نژاد",
|
||||
]}
|
||||
handlePageChange={handlePageChange}
|
||||
totalRows={totalRows}
|
||||
page={page}
|
||||
perPage={perPage}
|
||||
handlePerRowsChange={handlePerRowsChange}
|
||||
title={`جزئیات مجوز جوجه ریزی ${name}`}
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,458 @@
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import {
|
||||
Autocomplete,
|
||||
Button,
|
||||
Checkbox,
|
||||
IconButton,
|
||||
Tab,
|
||||
Tabs,
|
||||
TextField,
|
||||
Tooltip,
|
||||
} from "@mui/material";
|
||||
import { DatePicker } from "@mui/x-date-pickers";
|
||||
import moment from "moment";
|
||||
import { useDispatch } from "react-redux";
|
||||
import axios from "axios";
|
||||
import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import {
|
||||
LOADING_END,
|
||||
LOADING_START,
|
||||
} from "../../../../lib/redux/slices/appSlice";
|
||||
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { formatJustDate } from "../../../../utils/formatTime";
|
||||
import { nationalInfoGetDashboardService } from "../../services/national-info-get-dashboard-info-service";
|
||||
import { getSamasatProvinces } from "../../../../utils/getSamasatProvinces";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import {
|
||||
ROUTE_ADMINX_ROUTE_NATIONAL_INFO,
|
||||
ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO,
|
||||
ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO,
|
||||
} from "../../../../routes/routes";
|
||||
import ToggleOffOutlinedIcon from "@mui/icons-material/ToggleOffOutlined";
|
||||
import ToggleOnIcon from "@mui/icons-material/ToggleOn";
|
||||
import VisibilityIcon from "@mui/icons-material/Visibility";
|
||||
|
||||
export const NationalInfoHatchings = () => {
|
||||
const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] =
|
||||
useContext(AppContext);
|
||||
const dispatch = useDispatch();
|
||||
useEffect(() => {
|
||||
const currentDate = moment(new Date()).format("YYYY-MM-DD");
|
||||
setSelectedDate1(currentDate);
|
||||
setSelectedDate2(currentDate);
|
||||
}, []);
|
||||
|
||||
const handleTextChange = (event) => {
|
||||
setTextValue(event.target.value);
|
||||
};
|
||||
|
||||
const [selectedProvince, setSelectedProvince] = useState("");
|
||||
|
||||
const { key } = useParams();
|
||||
|
||||
const [dashboardData, setDashboardData] = useState([]);
|
||||
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 [withDate, setWithDate] = useState(false);
|
||||
const [value, setValue] = useState("0");
|
||||
|
||||
const handleChange = (event, newValue) => {
|
||||
setValue(newValue);
|
||||
};
|
||||
|
||||
const getDashboardData = () => {
|
||||
dispatch(
|
||||
nationalInfoGetDashboardService({
|
||||
date1: withDate ? selectedDate1 : null,
|
||||
date2: withDate ? selectedDate2 : null,
|
||||
search: textValue,
|
||||
province: selectedProvince === "همه" ? "" : selectedProvince,
|
||||
})
|
||||
).then((r) => {
|
||||
setDashboardData(r.payload.data);
|
||||
});
|
||||
};
|
||||
|
||||
const fetchApiData = async (page) => {
|
||||
let response;
|
||||
dispatch(LOADING_START());
|
||||
response = await axios.get(
|
||||
`https://rsibackend.rasadyar.com/app/hatchings/?search=${textValue}${
|
||||
withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : ``
|
||||
}&page=${page}&page_size=${perPage}&province=${
|
||||
key || selectedProvince ? selectedProvince : ""
|
||||
}&state=${value === "0" ? "pending" : "archive"}`
|
||||
);
|
||||
dispatch(LOADING_END());
|
||||
getDashboardData();
|
||||
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?.poultry?.Province || "-",
|
||||
item?.poultry?.City || "-",
|
||||
item?.poultry?.UnitName,
|
||||
`${item?.poultry?.FirstName} ${item?.poultry?.LastName || ""}`,
|
||||
item?.RequestCode,
|
||||
item?.CertId,
|
||||
item?.CapacityFemale?.toLocaleString(),
|
||||
formatJustDate(item?.Date),
|
||||
Math.floor(item?.Age),
|
||||
item?.PedigreeName,
|
||||
item?.ChickCountSum?.toLocaleString(),
|
||||
item?.Period?.toLocaleString(),
|
||||
item?.Evacuation?.toLocaleString(),
|
||||
item?.info?.percentHatchingLicense?.toFixed(2),
|
||||
item?.LeftOver?.toLocaleString(),
|
||||
Math.floor(item?.KillingAve),
|
||||
item?.info?.numberLoads?.toLocaleString(),
|
||||
item?.info?.loadVolume?.toLocaleString(),
|
||||
<Tooltip placement="right" title="جزئیات" key={i}>
|
||||
<IconButton
|
||||
size="small"
|
||||
color="success"
|
||||
onClick={() =>
|
||||
window.open(
|
||||
getRoleFromUrl() === "AdminX"
|
||||
? `${ROUTE_ADMINX_ROUTE_NATIONAL_INFO}/${item.RequestCode}/${item?.poultry?.UnitName}`
|
||||
: getRoleFromUrl() === "SuperAdmin"
|
||||
? `${ROUTE_SUPER_ADMIN_ROUTE_NATIONAL_INFO}/${item.RequestCode}/${item?.poultry?.UnitName}`
|
||||
: `${ROUTE_PROVINCE_SUPERVISOR_ROUTE_NATIONAL_INFO}/${item.RequestCode}/${item?.poultry?.UnitName}`,
|
||||
"_blank"
|
||||
)
|
||||
}
|
||||
>
|
||||
<VisibilityIcon />
|
||||
</IconButton>
|
||||
</Tooltip>,
|
||||
];
|
||||
});
|
||||
|
||||
setTableData(d);
|
||||
}, [data]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchApiData(1);
|
||||
}, [
|
||||
dispatch,
|
||||
selectedDate1,
|
||||
selectedDate2,
|
||||
perPage,
|
||||
withDate,
|
||||
value,
|
||||
selectedProvince,
|
||||
]);
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
dispatch(LOADING_START());
|
||||
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`https://rsibackend.rasadyar.com/app/hatchings/?search=${textValue}${
|
||||
withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : ``
|
||||
}&page=${1}&page_size=${perPage}&province=${
|
||||
key || selectedProvince ? selectedProvince : ""
|
||||
}&state=${value === "0" ? "pending" : "archive"}`
|
||||
);
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
|
||||
dispatch(LOADING_END());
|
||||
getDashboardData();
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
}
|
||||
};
|
||||
|
||||
const getProvinceList = () => {
|
||||
return [{ name: "همه" }, ...getSamasatProvinces()];
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
xs={12}
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
gap={2}
|
||||
mt={2}
|
||||
>
|
||||
<Grid
|
||||
container
|
||||
xs={12}
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
gap={2}
|
||||
>
|
||||
<Tabs value={value} onChange={handleChange}>
|
||||
<Tab value="0" label="فعال" />
|
||||
<Tab value="1" label="بایگانی شده" />
|
||||
</Tabs>
|
||||
</Grid>
|
||||
<Grid container xs={12} alignItems="center" gap={2}>
|
||||
{!key && (
|
||||
<Grid minWidth={210}>
|
||||
<Autocomplete
|
||||
size="small"
|
||||
disablePortal
|
||||
id="hatching"
|
||||
options={getProvinceList().map((i) => {
|
||||
return {
|
||||
label: i.name,
|
||||
};
|
||||
})}
|
||||
onChange={(event, value) => {
|
||||
if (value.label !== "همه") {
|
||||
setSelectedProvince(value.label);
|
||||
} else {
|
||||
setSelectedProvince("");
|
||||
}
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField {...params} label="انتخاب استان" />
|
||||
)}
|
||||
/>
|
||||
</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>
|
||||
<Grid
|
||||
container
|
||||
gap={1}
|
||||
style={{
|
||||
borderStyle: "solid",
|
||||
borderWidth: "1px",
|
||||
padding: "5px",
|
||||
borderRadius: "15px",
|
||||
borderColor: "gray",
|
||||
justifyContent: "left",
|
||||
}}
|
||||
alignItems="center"
|
||||
sx={{
|
||||
width: { xs: "auto", md: "auto" },
|
||||
}}
|
||||
>
|
||||
<Checkbox
|
||||
icon={<ToggleOffOutlinedIcon />}
|
||||
checkedIcon={<ToggleOnIcon />}
|
||||
checked={withDate}
|
||||
onChange={() => setWithDate(!withDate)}
|
||||
color="primary"
|
||||
size="large"
|
||||
/>
|
||||
<Grid>
|
||||
<DatePicker
|
||||
disabled={!withDate}
|
||||
label="از تاریخ"
|
||||
id="date"
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
size="small"
|
||||
sx={{ width: { xs: "126px", md: "160px" } }}
|
||||
{...params}
|
||||
/>
|
||||
)}
|
||||
value={selectedDate1}
|
||||
onChange={(e) => {
|
||||
setSelectedDate1(moment(e).format("YYYY-MM-DD"));
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid>
|
||||
<DatePicker
|
||||
disabled={!withDate}
|
||||
label="تا تاریخ"
|
||||
id="date"
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
size="small"
|
||||
sx={{ width: { xs: "126px", md: "160px" } }}
|
||||
{...params}
|
||||
/>
|
||||
)}
|
||||
value={selectedDate2}
|
||||
onChange={(e) => {
|
||||
setSelectedDate2(moment(e).format("YYYY-MM-DD"));
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Tooltip placement="right" title="دانلود اکسل">
|
||||
<IconButton
|
||||
size="small"
|
||||
color="success"
|
||||
component="a"
|
||||
href={`https://rsibackend.rasadyar.com/app/all_hatching_excel/?search=${textValue}${
|
||||
withDate ? `&date1=${selectedDate1}&date2=${selectedDate2}` : ``
|
||||
}&province=${
|
||||
key || selectedProvince ? selectedProvince : ""
|
||||
}&state=${value === "0" ? "pending" : "archive"}`}
|
||||
>
|
||||
<RiFileExcel2Fill size={36} />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
|
||||
<Grid container mt={2} mb={4} isDashboard gap={3}>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
columns={[
|
||||
"تعداد دوره جوجه ریزی",
|
||||
"حجم کل جوجه ریزی",
|
||||
"تلفات",
|
||||
"درصد تلفات",
|
||||
"کشتار شده",
|
||||
" درصد کشتار شده",
|
||||
"میانگین سن کشتار",
|
||||
"تعداد بارها",
|
||||
"کمترین سن",
|
||||
"بیشترین سن",
|
||||
"مانده در سالن",
|
||||
"درصد مانده در سالن نسبت به جوجه ریزی",
|
||||
]}
|
||||
data={[
|
||||
[
|
||||
dashboardData?.totalHatchingCount?.toLocaleString(),
|
||||
dashboardData?.totalHatchingQuantity?.toLocaleString(),
|
||||
dashboardData?.totalHatchingEvacuation?.toLocaleString(),
|
||||
dashboardData?.totalHatchingEvacuationPercent?.toLocaleString(),
|
||||
dashboardData?.totalHatchingKillingQuantity?.toLocaleString(),
|
||||
dashboardData?.totalHatchingKillingQuantityPercent?.toLocaleString(),
|
||||
Math.floor(dashboardData?.totalHatchingKillingAge),
|
||||
dashboardData?.totalHatchingBars?.toLocaleString(),
|
||||
Math.floor(dashboardData?.leastAge),
|
||||
Math.floor(dashboardData?.mostAge),
|
||||
dashboardData?.totalHatchingLeftOver?.toLocaleString(),
|
||||
dashboardData?.totalHatchingLeftOverPercent?.toLocaleString(),
|
||||
],
|
||||
]}
|
||||
title={"خلاصه اطلاعات کل جوجه ریزی ها"}
|
||||
/>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
columns={[
|
||||
"تعداد دوره جوجه ریزی",
|
||||
"حجم کل جوجه ریزی",
|
||||
"تلفات",
|
||||
"درصد تلفات",
|
||||
"کشتار شده",
|
||||
"درصد کشتار شده",
|
||||
"میانگین سن کشتار",
|
||||
"تعداد بارها",
|
||||
"حجم جوجه ریزی فعال",
|
||||
"کمترین سن",
|
||||
"بیشترین سن",
|
||||
"مانده در سالن",
|
||||
"درصد مانده در سالن",
|
||||
"مانده در سالن آماده به کشتار",
|
||||
"درصد مانده در سالن آماده به کشتار",
|
||||
]}
|
||||
data={[
|
||||
[
|
||||
dashboardData?.totalActiveHatchingCount?.toLocaleString(),
|
||||
dashboardData?.totalActiveHatchingQuantity?.toLocaleString(),
|
||||
dashboardData?.totalActiveHatchingEvacuation?.toLocaleString(),
|
||||
dashboardData?.totalActiveHatchingEvacuationPercent?.toLocaleString(),
|
||||
dashboardData?.totalActiveHatchingKillingQuantity?.toLocaleString(),
|
||||
dashboardData?.totalActiveHatchingKillingQuantityPercent?.toLocaleString(),
|
||||
Math.floor(dashboardData?.totalActiveHatchingKillingAge),
|
||||
dashboardData?.totalActiveHatchingBars?.toLocaleString(),
|
||||
// dashboardData?.totalActiveHatchingCount?.toLocaleString(),
|
||||
dashboardData?.totalActiveHatchingQuantity?.toLocaleString(),
|
||||
Math.floor(dashboardData?.leastAge),
|
||||
Math.floor(dashboardData?.mostAge),
|
||||
dashboardData?.totalActiveHatchingLeftOver?.toLocaleString(),
|
||||
dashboardData?.totalActiveHatchingLeftOverPercent?.toLocaleString(),
|
||||
dashboardData?.totalReadyActiveHatchingLeftOver?.toLocaleString(),
|
||||
dashboardData?.totalReadyHatchingLeftOverPercent?.toLocaleString(),
|
||||
],
|
||||
]}
|
||||
title={"خلاصه اطلاعات جوجه ریزی های فعال"}
|
||||
customColors={[{ rest: true, color: "#6262c4" }]}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<ResponsiveTable
|
||||
data={tableData}
|
||||
columns={[
|
||||
"ردیف",
|
||||
"استان",
|
||||
"شهرستان",
|
||||
"نام واحد",
|
||||
"نام مالک",
|
||||
"شماره مجوز",
|
||||
"شماره گواهی بهداشتی",
|
||||
"ظرفیت",
|
||||
"تاریخ جوجه ریزی",
|
||||
"سن گله",
|
||||
"نژاد",
|
||||
"تعداد جوجه ریزی",
|
||||
"دوره جوجه ریزی",
|
||||
"مجموع تلفات",
|
||||
"درصد جوجه ریزی به مجوز",
|
||||
"مانده در سالن",
|
||||
"میانگین سن کشتار",
|
||||
"تعداد بارها",
|
||||
"حجم بارها",
|
||||
"جزئیات",
|
||||
]}
|
||||
handlePageChange={handlePageChange}
|
||||
totalRows={totalRows}
|
||||
page={page}
|
||||
perPage={perPage}
|
||||
handlePerRowsChange={handlePerRowsChange}
|
||||
title={
|
||||
value === "0"
|
||||
? `پایش جوجه ریزی ${key || ""}`
|
||||
: `بایگانی جوجه ریزی ${key || ""}`
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
66
src/features/city/components/national-info/NationalInfo.js
Normal file
66
src/features/city/components/national-info/NationalInfo.js
Normal file
@@ -0,0 +1,66 @@
|
||||
import React, { useState } from "react";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { Tab, Tabs } from "@mui/material";
|
||||
import { NationalInfoHatchings } from "../national-info-hatchings/NationalInfoHatchings";
|
||||
import { NationalInfoTransports } from "../national-info-bars/NationalInfoTransports";
|
||||
// import { NationalinfokillingReport } from "../national-info-killing-report/NationalinfokillingReport";
|
||||
import NationalMap from "../national-map/NationalMap";
|
||||
import { ProvinceNationalInfoFarms } from "../../../province/components/province-national-info-farms/ProvinceNationalInfoFarms";
|
||||
import { ProvinceNationalInfoSlaughterhouse } from "../../../province/components/province-national-info-Slaughterhouse/ProvinceNationalInfoSlaughterhouse";
|
||||
import { ProvinceChickenDistributionsAndSales } from "../../../province/components/province-chicken-distribution-and-sales/ProvinceChickenDistributionsAndSales";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import { ProvinceChickenStewardSales } from "../../../province/components/province-chicken-steward-sales/ProvinceChickenStewardSales";
|
||||
import { TotalCargoInformation } from "../../../province/components/total-cargo-information/TotalCargoInformation";
|
||||
|
||||
export const NationalInfo = () => {
|
||||
const [value, setValue] = useState(0);
|
||||
|
||||
const ableToSee =
|
||||
getRoleFromUrl() === "AdminX" ||
|
||||
getRoleFromUrl() === "SuperAdmin" ||
|
||||
getRoleFromUrl() === "ProvinceOperator";
|
||||
|
||||
const handleChange = (event, newValue) => {
|
||||
setValue(newValue);
|
||||
};
|
||||
return (
|
||||
<Grid container xs={12} justifyContent="center" alignItems="center">
|
||||
<Grid
|
||||
container
|
||||
xs={12}
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
mt={4}
|
||||
>
|
||||
<Tabs
|
||||
value={value}
|
||||
onChange={handleChange}
|
||||
aria-label="simple tabs example"
|
||||
scrollButtons="auto"
|
||||
variant="scrollable"
|
||||
allowScrollButtonsMobile
|
||||
>
|
||||
<Tab value={0} label="مدیریت فارم ها" />
|
||||
<Tab value={1} label="جوجه ریزی ها " />
|
||||
<Tab value={2} label="اطلاعات بارها " />
|
||||
<Tab value={3} label="پایش کشتارگاه ها " />
|
||||
<Tab value={4} label="نقشه کشوری" />
|
||||
{ableToSee && <Tab value={5} label="توزیع / فروش گوشت مرغ" />}
|
||||
{ableToSee && <Tab value={6} label="خرید صنوف" />}
|
||||
{ableToSee && <Tab value={7} label="اطلاعات حمل محصولات" />}
|
||||
</Tabs>
|
||||
</Grid>
|
||||
|
||||
<Grid container xs={12} justifyContent="center" mt={2} px={2}>
|
||||
{value === 0 && <ProvinceNationalInfoFarms />}
|
||||
{value === 1 && <NationalInfoHatchings />}
|
||||
{value === 2 && <NationalInfoTransports />}
|
||||
{value === 3 && <ProvinceNationalInfoSlaughterhouse />}
|
||||
{value === 4 && <NationalMap />}
|
||||
{value === 5 && <ProvinceChickenDistributionsAndSales />}
|
||||
{value === 6 && <ProvinceChickenStewardSales />}
|
||||
{value === 7 && <TotalCargoInformation />}
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
142
src/features/city/components/national-map/NationalMap.js
Normal file
142
src/features/city/components/national-map/NationalMap.js
Normal file
@@ -0,0 +1,142 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { AllProvinceDetailsForMap } from "../../services/all-province-details-for-map";
|
||||
import NationalMapOverview from "./NationalMapOverview";
|
||||
import NationalMapGuidline from "./NationalMapGuidline";
|
||||
|
||||
import NationalMapSumTotal from "./NationalMapSumTotal";
|
||||
|
||||
import NationalMapRadioBtn from "./NationalMapRadioBtn";
|
||||
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
|
||||
const NationalMap = () => {
|
||||
const [tableData, setTableData] = useState([]);
|
||||
const [percentageType, setPercentageType] = useState("hatching"); // hatching or active
|
||||
const [provinceData, setProvinceData] = useState([]);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const fetchTableData = () => {
|
||||
dispatch(AllProvinceDetailsForMap()).then((r) => {
|
||||
const data = r.payload?.data || [];
|
||||
setProvinceData(data);
|
||||
|
||||
// const sum = data.reduce((total, item) => {
|
||||
// return total + (item?.totalQuantity || 0);
|
||||
// }, 0);
|
||||
|
||||
const d = data.map((item, i) => {
|
||||
return [
|
||||
i + 1,
|
||||
item?.provinceName || "",
|
||||
item?.totalQuantity?.toLocaleString() || "0",
|
||||
item?.totalKilledQuantity?.toLocaleString() || "0",
|
||||
item?.totalLeftOver?.toLocaleString() || "0",
|
||||
// sum.toLocaleString(),
|
||||
`% ${item?.totalHatchingLeftOverPercent.toLocaleString()} `,
|
||||
item?.totalActiveLeft.toLocaleString(),
|
||||
` % ${item?.totalActiveLeftPercent.toLocaleString()}`,
|
||||
];
|
||||
});
|
||||
|
||||
setTableData(d);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchTableData();
|
||||
}, []);
|
||||
|
||||
const getColorByPercentage = (percent) => {
|
||||
if (percent < 25) return "#F18989";
|
||||
if (percent < 50) return "#FF944D";
|
||||
if (percent < 75) return "#F4C430";
|
||||
return "#61D8BA";
|
||||
};
|
||||
|
||||
const provincePercentages = {};
|
||||
provinceData.forEach((item) => {
|
||||
if (item?.provinceName && item?.totalHatchingLeftOverPercent) {
|
||||
provincePercentages[item?.provinceName] =
|
||||
item?.totalHatchingLeftOverPercent;
|
||||
}
|
||||
});
|
||||
|
||||
const getProvinceColor = (provinceName) => {
|
||||
const province = provinceData.find((p) => p?.provinceName === provinceName);
|
||||
if (!province) return "#B0B0B0";
|
||||
|
||||
const percent =
|
||||
percentageType === "hatching"
|
||||
? province?.totalHatchingLeftOverPercent
|
||||
: province?.totalActiveLeftPercent;
|
||||
|
||||
return percent ? getColorByPercentage(percent) : "#B0B0B0";
|
||||
};
|
||||
|
||||
const handlePercentageTypeChange = (type) => {
|
||||
setPercentageType(type);
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid xs={12} md={12} container spacing={2} justifyContent="center">
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
md={4}
|
||||
gap={2}
|
||||
sx={{
|
||||
maxHeight: { xs: "auto", md: "668px" },
|
||||
overflowY: "scroll",
|
||||
}}
|
||||
>
|
||||
<ResponsiveTable
|
||||
title="اطلاعات کشتار زنده کشتارگاه"
|
||||
columns={[
|
||||
"ردیف",
|
||||
" استان",
|
||||
" جوجه ریزی",
|
||||
"کشتار شده",
|
||||
"مانده در سالن",
|
||||
" مانده در سالن",
|
||||
"آماده کشتار",
|
||||
" آماده کشتار",
|
||||
]}
|
||||
data={tableData}
|
||||
sx={{
|
||||
"& .MuiTableCell-root": {
|
||||
fontSize: "0.75rem",
|
||||
padding: "8px",
|
||||
},
|
||||
"& .MuiTableHead-root": {
|
||||
"& .MuiTableCell-root": {
|
||||
fontWeight: 600,
|
||||
},
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<Grid
|
||||
xs={12}
|
||||
md={7}
|
||||
gap={2}
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
marginLeft: { xs: "0px", md: "33px" },
|
||||
}}
|
||||
>
|
||||
<NationalMapSumTotal />
|
||||
<NationalMapRadioBtn
|
||||
onPercentageTypeChange={handlePercentageTypeChange}
|
||||
selectedPercentageType={percentageType}
|
||||
/>
|
||||
<NationalMapOverview getProvinceColor={getProvinceColor} />
|
||||
|
||||
<NationalMapGuidline />
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
export default NationalMap;
|
||||
142
src/features/city/components/national-map/NationalMapGuidline.js
Normal file
142
src/features/city/components/national-map/NationalMapGuidline.js
Normal file
@@ -0,0 +1,142 @@
|
||||
import { Grid, Typography } from "@mui/material";
|
||||
|
||||
function NationalMapGuidline() {
|
||||
return (
|
||||
<Grid
|
||||
xs={12}
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "rowReverse",
|
||||
border: "1px solid #A8A8A8",
|
||||
borderRadius: "20px",
|
||||
padding: "10px",
|
||||
gap: "5px",
|
||||
alignItems: "center",
|
||||
marginLeft: {
|
||||
xs: "0px",
|
||||
md: "173px",
|
||||
},
|
||||
width: {
|
||||
xs: "100%",
|
||||
md: "480px",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Grid
|
||||
xs={6}
|
||||
item
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
marginLeft: "10px",
|
||||
}}
|
||||
>
|
||||
<Grid
|
||||
sx={{
|
||||
backgroundColor: "#F18989",
|
||||
width: "15px",
|
||||
height: "15px",
|
||||
borderRadius: "8px",
|
||||
}}
|
||||
></Grid>
|
||||
<Typography
|
||||
sx={{
|
||||
marginLeft: "10px",
|
||||
color: "#717171",
|
||||
fontWeight: "400",
|
||||
fontSize: "14px",
|
||||
}}
|
||||
>
|
||||
کمتر از 25%
|
||||
</Typography>
|
||||
</Grid>
|
||||
|
||||
<Grid
|
||||
xs={6}
|
||||
item
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
marginLeft: "10px",
|
||||
}}
|
||||
>
|
||||
<Grid
|
||||
sx={{
|
||||
backgroundColor: "#FF944D",
|
||||
width: "15px",
|
||||
height: "15px",
|
||||
borderRadius: "8px",
|
||||
}}
|
||||
></Grid>
|
||||
<Typography
|
||||
sx={{
|
||||
marginLeft: "10px",
|
||||
color: "#717171",
|
||||
fontWeight: "400",
|
||||
fontSize: "14px",
|
||||
}}
|
||||
>
|
||||
25% تا 50%
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid
|
||||
xs={6}
|
||||
item
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
marginLeft: "10px",
|
||||
}}
|
||||
>
|
||||
<Grid
|
||||
sx={{
|
||||
backgroundColor: "#F4C430",
|
||||
width: "15px",
|
||||
height: "15px",
|
||||
borderRadius: "8px",
|
||||
}}
|
||||
></Grid>
|
||||
<Typography
|
||||
sx={{
|
||||
marginLeft: "10px",
|
||||
color: "#717171",
|
||||
fontWeight: "400",
|
||||
fontSize: "14px",
|
||||
}}
|
||||
>
|
||||
50% تا 75%
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid
|
||||
xs={6}
|
||||
item
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
marginLeft: "10px",
|
||||
}}
|
||||
>
|
||||
<Grid
|
||||
sx={{
|
||||
backgroundColor: "#61D8BA",
|
||||
width: "15px",
|
||||
height: "15px",
|
||||
borderRadius: "8px",
|
||||
}}
|
||||
></Grid>
|
||||
<Typography
|
||||
sx={{
|
||||
marginLeft: "10px",
|
||||
color: "#717171",
|
||||
fontWeight: "400",
|
||||
fontSize: "14px",
|
||||
}}
|
||||
>
|
||||
75% تا 100%
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
|
||||
export default NationalMapGuidline;
|
||||
433
src/features/city/components/national-map/NationalMapOverview.js
Normal file
433
src/features/city/components/national-map/NationalMapOverview.js
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,40 @@
|
||||
import * as React from "react";
|
||||
import Radio from "@mui/material/Radio";
|
||||
import RadioGroup from "@mui/material/RadioGroup";
|
||||
import FormControlLabel from "@mui/material/FormControlLabel";
|
||||
import FormControl from "@mui/material/FormControl";
|
||||
|
||||
export default function NationalMapRadioBtn({
|
||||
onPercentageTypeChange,
|
||||
selectedPercentageType,
|
||||
}) {
|
||||
const handleChange = (event) => {
|
||||
onPercentageTypeChange(event.target.value);
|
||||
};
|
||||
|
||||
return (
|
||||
<FormControl>
|
||||
<RadioGroup
|
||||
sx={{
|
||||
justifyContent: "center",
|
||||
}}
|
||||
aria-labelledby="percentage-type-radio-buttons-group"
|
||||
name="percentage-type-radio-buttons-group"
|
||||
value={selectedPercentageType}
|
||||
onChange={handleChange}
|
||||
row
|
||||
>
|
||||
<FormControlLabel
|
||||
value="hatching"
|
||||
control={<Radio />}
|
||||
label="مانده در سالن"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value="active"
|
||||
control={<Radio />}
|
||||
label="آماده کشتار"
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
);
|
||||
}
|
||||
173
src/features/city/components/national-map/NationalMapSumTotal.js
Normal file
173
src/features/city/components/national-map/NationalMapSumTotal.js
Normal file
@@ -0,0 +1,173 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { DashboardProvinceDetailsForMap } from "../../services/dashboard-province-details-for-map";
|
||||
|
||||
const NationalMapSumTotal = () => {
|
||||
const [data, setData] = useState({
|
||||
totalQuantity: 0,
|
||||
totalLeftOver: 0,
|
||||
totalKilledQuantity: 0,
|
||||
totalHatchingLeftOverPercent: 0,
|
||||
totalActiveLeft: 0,
|
||||
totalActiveLeftPercent: 0,
|
||||
});
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const fetchData = () => {
|
||||
dispatch(DashboardProvinceDetailsForMap()).then((r) => {
|
||||
if (r.payload?.data) {
|
||||
setData(r.payload.data);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Grid
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
border: "1px solid #A8A8A8",
|
||||
borderRadius: "20px",
|
||||
padding: "10px",
|
||||
maxHeight: "156px",
|
||||
marginTop: "20px",
|
||||
backgroundColor: "white",
|
||||
flexWrap: "wrap",
|
||||
}}
|
||||
>
|
||||
<Grid item sx={{ marginTop: "10px", display: "flex" }}>
|
||||
<Typography
|
||||
sx={{ color: "#717171", fontWeight: "600", fontSize: "12px" }}
|
||||
>
|
||||
حجم کل جوجه ریزی:
|
||||
</Typography>
|
||||
<Typography
|
||||
sx={{
|
||||
color: "#333",
|
||||
fontWeight: "700",
|
||||
fontSize: "12px",
|
||||
marginLeft: "10px",
|
||||
}}
|
||||
>
|
||||
{data?.totalQuantity.toLocaleString()} قطعه
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid
|
||||
item
|
||||
sx={{ marginTop: "10px", display: "flex", marginRight: "10px" }}
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
color: "#717171",
|
||||
fontWeight: "600",
|
||||
fontSize: "12px",
|
||||
marginLeft: "10px",
|
||||
}}
|
||||
>
|
||||
حجم مانده در سالن:
|
||||
</Typography>
|
||||
<Typography
|
||||
sx={{
|
||||
color: "#333",
|
||||
fontWeight: "700",
|
||||
fontSize: "12px",
|
||||
marginLeft: "10px",
|
||||
}}
|
||||
>
|
||||
{data?.totalLeftOver?.toLocaleString()} قطعه
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item sx={{ marginTop: "10px", display: "flex" }}>
|
||||
<Typography
|
||||
sx={{
|
||||
color: "#333",
|
||||
fontWeight: "700",
|
||||
fontSize: "12px",
|
||||
marginLeft: "10px",
|
||||
}}
|
||||
>
|
||||
حجم کل کشتار شده:
|
||||
</Typography>
|
||||
<Typography
|
||||
sx={{
|
||||
color: "#333",
|
||||
fontWeight: "700",
|
||||
fontSize: "12px",
|
||||
marginLeft: "10px",
|
||||
}}
|
||||
>
|
||||
{data?.totalKilledQuantity.toLocaleString()}
|
||||
</Typography>
|
||||
</Grid>
|
||||
|
||||
<Grid item sx={{ marginTop: "10px", display: "flex" }}>
|
||||
<Typography
|
||||
sx={{
|
||||
color: "#333",
|
||||
fontWeight: "700",
|
||||
fontSize: "12px",
|
||||
marginLeft: "10px",
|
||||
}}
|
||||
>
|
||||
درصد مانده در سالن :
|
||||
</Typography>
|
||||
<Grid sx={{ display: "flex", alignItems: "center" }}>
|
||||
<Grid
|
||||
sx={{
|
||||
borderRadius: "8px",
|
||||
marginLeft: "5px",
|
||||
}}
|
||||
/>
|
||||
<Typography
|
||||
sx={{
|
||||
color: "#333",
|
||||
fontWeight: "700",
|
||||
fontSize: "12px",
|
||||
}}
|
||||
>
|
||||
{data?.totalHatchingLeftOverPercent}%
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid item sx={{ marginTop: "10px", display: "flex" }}>
|
||||
<Typography
|
||||
sx={{
|
||||
color: "#333",
|
||||
fontWeight: "700",
|
||||
fontSize: "12px",
|
||||
marginLeft: "10px",
|
||||
}}
|
||||
>
|
||||
درصد آماده کشتار:
|
||||
</Typography>
|
||||
<Grid sx={{ display: "flex", alignItems: "center" }}>
|
||||
<Grid
|
||||
sx={{
|
||||
borderRadius: "8px",
|
||||
marginLeft: "5px",
|
||||
}}
|
||||
/>
|
||||
<Typography
|
||||
sx={{
|
||||
color: "#333",
|
||||
fontWeight: "700",
|
||||
fontSize: "12px",
|
||||
marginLeft: "10px",
|
||||
}}
|
||||
>
|
||||
{data.totalActiveLeftPercent}%
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
export default NationalMapSumTotal;
|
||||
@@ -0,0 +1,293 @@
|
||||
import {
|
||||
Button,
|
||||
Switch,
|
||||
TextField,
|
||||
Typography,
|
||||
Radio,
|
||||
RadioGroup,
|
||||
FormControlLabel,
|
||||
FormControl,
|
||||
} from "@mui/material";
|
||||
import DoneIcon from "@mui/icons-material/Done";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { useContext, useState, useEffect } from "react";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { provincePolicyWagesEditKillhouse } from "../../../province/services/province-policy-wages-edit-killhouse";
|
||||
|
||||
export const ProvinceManageSellingForceGovernmentalBuy = ({
|
||||
item,
|
||||
fetchdata,
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
const [openNotif] = useContext(AppContext);
|
||||
|
||||
const [state, setState] = useState({
|
||||
minimumSaleState: item?.quota || false,
|
||||
quotaOption: item?.quotaMaxKillLimit
|
||||
? "max_kill_limit"
|
||||
: item?.quotaRequest
|
||||
? "request"
|
||||
: item?.quotaCustom
|
||||
? "custom"
|
||||
: "",
|
||||
qoutaCustomQuntity: item?.quotaCustomQuantity || 0,
|
||||
percent: item?.governmentalQuota || 0,
|
||||
});
|
||||
|
||||
const [errors, setErrors] = useState({
|
||||
percent: false,
|
||||
qoutaCustomQuntity: false,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!state.minimumSaleState) {
|
||||
setState((prev) => ({
|
||||
...prev,
|
||||
quotaOption: "",
|
||||
qoutaCustomQuntity: 0,
|
||||
percent: 0,
|
||||
}));
|
||||
setErrors({ percent: false, qoutaCustomQuntity: false });
|
||||
}
|
||||
}, [state.minimumSaleState]);
|
||||
|
||||
const handleToggle = (key, value) => {
|
||||
setState((prev) => ({ ...prev, [key]: value }));
|
||||
};
|
||||
|
||||
const handleRadioChange = (event) => {
|
||||
const newOption = event.target.value;
|
||||
setState((prev) => ({
|
||||
...prev,
|
||||
quotaOption: newOption,
|
||||
...(newOption !== "custom" && { qoutaCustomQuntity: 0 }),
|
||||
...(newOption === "custom" && { percent: 0 }),
|
||||
}));
|
||||
setErrors({ percent: false, qoutaCustomQuntity: false });
|
||||
};
|
||||
|
||||
const handleInputChange = (field, value) => {
|
||||
setState((prev) => ({ ...prev, [field]: value }));
|
||||
setErrors((prev) => ({ ...prev, [field]: false }));
|
||||
};
|
||||
|
||||
const validateForm = () => {
|
||||
const newErrors = {
|
||||
percent: false,
|
||||
qoutaCustomQuntity: false,
|
||||
};
|
||||
|
||||
if (state.minimumSaleState) {
|
||||
if (
|
||||
(state.quotaOption === "max_kill_limit" ||
|
||||
state.quotaOption === "request") &&
|
||||
(!state.percent || state.percent <= 0 || state.percent > 100)
|
||||
) {
|
||||
newErrors.percent = true;
|
||||
}
|
||||
|
||||
if (
|
||||
state.quotaOption === "custom" &&
|
||||
(!state.qoutaCustomQuntity || state.qoutaCustomQuntity <= 0)
|
||||
) {
|
||||
newErrors.qoutaCustomQuntity = true;
|
||||
}
|
||||
}
|
||||
|
||||
setErrors(newErrors);
|
||||
return !Object.values(newErrors).some((error) => error);
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
if (!validateForm()) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "لطفاً مقادیر الزامی را به درستی وارد کنید",
|
||||
severity: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(
|
||||
provincePolicyWagesEditKillhouse({
|
||||
kill_house_key: item?.key,
|
||||
quota: state.minimumSaleState,
|
||||
quota_max_kill_limit: state.quotaOption === "max_kill_limit",
|
||||
quota_request: state.quotaOption === "request",
|
||||
quota_custom: state.quotaOption === "custom",
|
||||
quota_custom_quantity: state.qoutaCustomQuntity,
|
||||
governmental_quota: state.percent,
|
||||
})
|
||||
).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",
|
||||
});
|
||||
fetchdata();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const isFormValid = () => {
|
||||
if (!state.minimumSaleState) return true;
|
||||
|
||||
if (
|
||||
state.quotaOption === "max_kill_limit" ||
|
||||
state.quotaOption === "request"
|
||||
) {
|
||||
return state.percent > 0 && state.percent <= 100;
|
||||
}
|
||||
|
||||
if (state.quotaOption === "custom") {
|
||||
return state.qoutaCustomQuntity > 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid xs={12} container direction="column" gap={SPACING.SMALL}>
|
||||
<Grid xs={12} container alignItems="center" gap={1}>
|
||||
<Grid item>
|
||||
<Switch
|
||||
checked={state.minimumSaleState}
|
||||
onChange={(e) => {
|
||||
handleToggle("minimumSaleState", e.target.checked);
|
||||
|
||||
if (!e.target.checked) {
|
||||
dispatch(
|
||||
provincePolicyWagesEditKillhouse({
|
||||
kill_house_key: item?.key,
|
||||
quota: false,
|
||||
quota_max_kill_limit: false,
|
||||
quota_request: false,
|
||||
quota_custom: false,
|
||||
quota_custom_quantity: 0,
|
||||
governmental_quota: 0,
|
||||
})
|
||||
).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",
|
||||
});
|
||||
fetchdata();
|
||||
}
|
||||
});
|
||||
}
|
||||
}}
|
||||
inputProps={{
|
||||
"aria-label": "in-province-selling-limitation-switch",
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Typography>الزام به خرید دولتی</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
{state.minimumSaleState && (
|
||||
<Grid xs={12} container direction="column" gap={1}>
|
||||
<Grid item>
|
||||
<FormControl component="fieldset" fullWidth>
|
||||
<RadioGroup
|
||||
value={state.quotaOption}
|
||||
onChange={handleRadioChange}
|
||||
>
|
||||
<FormControlLabel
|
||||
value="max_kill_limit"
|
||||
control={<Radio />}
|
||||
label="بر اساس سقف کشتار"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value="request"
|
||||
control={<Radio />}
|
||||
label="بر اساس اعلام نیازها"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value="custom"
|
||||
control={<Radio />}
|
||||
label="بر اساس حجم از سقف کشتار"
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
</Grid>
|
||||
|
||||
{(state.quotaOption === "max_kill_limit" ||
|
||||
state.quotaOption === "request") && (
|
||||
<TextField
|
||||
label="درصد خرید دولتی"
|
||||
size="small"
|
||||
fullWidth
|
||||
type="number"
|
||||
value={state.percent}
|
||||
onChange={(e) =>
|
||||
handleInputChange(
|
||||
"percent",
|
||||
Math.max(0, Math.min(100, e.target.value))
|
||||
)
|
||||
}
|
||||
inputProps={{ min: 1, max: 100 }}
|
||||
error={errors.percent}
|
||||
helperText={errors.percent ? "درصد باید بین ۱ تا ۱۰۰ باشد" : ""}
|
||||
/>
|
||||
)}
|
||||
|
||||
{state.quotaOption === "custom" && (
|
||||
<TextField
|
||||
label="حجم"
|
||||
size="small"
|
||||
fullWidth
|
||||
type="number"
|
||||
value={state.qoutaCustomQuntity}
|
||||
onChange={(e) =>
|
||||
handleInputChange(
|
||||
"qoutaCustomQuntity",
|
||||
Math.max(0, e.target.value)
|
||||
)
|
||||
}
|
||||
inputProps={{ min: 1 }}
|
||||
error={errors.qoutaCustomQuntity}
|
||||
helperText={
|
||||
errors.qoutaCustomQuntity ? "حجم باید بزرگتر از صفر باشد" : ""
|
||||
}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Button
|
||||
fullWidth
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={handleSubmit}
|
||||
disabled={!isFormValid()}
|
||||
startIcon={<DoneIcon />}
|
||||
>
|
||||
ذخیره تغییرات
|
||||
</Button>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,125 @@
|
||||
import { Switch, TextField, Typography, Button } from "@mui/material";
|
||||
import DoneIcon from "@mui/icons-material/Done";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { useContext, useState } from "react";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { provincePolicyWagesEditKillhouse } from "../../../province/services/province-policy-wages-edit-killhouse";
|
||||
|
||||
export const ProvinceManageSellingMaxLimitation = ({ item, fetchdata }) => {
|
||||
const dispatch = useDispatch();
|
||||
const [openNotif] = useContext(AppContext);
|
||||
|
||||
const [percent, setPercent] = useState(
|
||||
item?.outProvinceSellingLimitationPercent
|
||||
);
|
||||
const [minimumSaleState, setMinimumSaleState] = useState(
|
||||
item?.outProvinceSellingLimitation
|
||||
);
|
||||
|
||||
const handleToggle = (value) => {
|
||||
dispatch(
|
||||
provincePolicyWagesEditKillhouse({
|
||||
kill_house_key: item?.key,
|
||||
out_province_selling_limitation: value,
|
||||
out_province_selling_limitation_percent: value ? percent || 0 : 0,
|
||||
})
|
||||
).then((r) => {
|
||||
setMinimumSaleState(value);
|
||||
|
||||
if (r.payload?.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.error,
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
fetchdata();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleUpdatePercent = () => {
|
||||
if (percent > 100 || percent < 1) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "درصد باید بین ۱ تا ۱۰۰ باشد.",
|
||||
severity: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(
|
||||
provincePolicyWagesEditKillhouse({
|
||||
kill_house_key: item?.key,
|
||||
out_province_selling_limitation: true,
|
||||
out_province_selling_limitation_percent: percent,
|
||||
})
|
||||
).then((r) => {
|
||||
if (r.payload?.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: r.payload.error,
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
fetchdata();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid container direction="column" gap={SPACING.SMALL}>
|
||||
<Grid container alignItems="center" spacing={1}>
|
||||
<Grid item>
|
||||
<Switch
|
||||
checked={minimumSaleState}
|
||||
onChange={(e) => handleToggle(e.target.checked)}
|
||||
inputProps={{
|
||||
"aria-label": "in-province-selling-limitation-switch",
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Typography>حداکثر فروش به خارج استان</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
{minimumSaleState && (
|
||||
<Grid container alignItems="center" spacing={1}>
|
||||
<Grid item xs container alignItems="center" spacing={1}>
|
||||
<Grid item xs>
|
||||
<TextField
|
||||
label="درصد فروش"
|
||||
size="small"
|
||||
fullWidth
|
||||
value={percent}
|
||||
onChange={(e) => {
|
||||
setPercent(e.target.value);
|
||||
}}
|
||||
inputProps={{ min: 1, max: 100 }}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={handleUpdatePercent}
|
||||
disabled={percent > 100 || percent < 1}
|
||||
sx={{
|
||||
minWidth: "40px",
|
||||
}}
|
||||
>
|
||||
<DoneIcon />
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,66 @@
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { cityFetchSamasatTransportChickensDetails } from "../../../visors/services/fetch-samasat-transport-chickens";
|
||||
import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
|
||||
export const TransportChickensDetails = ({ code, cookie }) => {
|
||||
const dispatch = useDispatch();
|
||||
const [openNotif] = useContext(AppContext);
|
||||
|
||||
const [tableData, setTableData] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
cityFetchSamasatTransportChickensDetails({
|
||||
cookie,
|
||||
certId: code,
|
||||
})
|
||||
).then((r) => {
|
||||
if (r.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "کوکی معتبر نیست!",
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
const d = r.payload.data?.map((item, i) => {
|
||||
return [
|
||||
i + 1,
|
||||
item?.TrackingCode,
|
||||
item?.ResideDatePersian,
|
||||
item?.GoodAmount?.toLocaleString(),
|
||||
item?.TrackingStatusDescription,
|
||||
item?.GoodName,
|
||||
item?.DesPartIdCode,
|
||||
item?.DesUnitName,
|
||||
item?.IssueDatePersian,
|
||||
];
|
||||
});
|
||||
setTableData(d);
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Grid container xs={12}>
|
||||
<AdvancedTable
|
||||
columns={[
|
||||
"ردیف",
|
||||
"کد رهگیری",
|
||||
"تاریخ ثبت",
|
||||
"تعداد",
|
||||
"وضعیت",
|
||||
"نام کالا",
|
||||
"شناسه یکتا کشتارگاه مقصد",
|
||||
"نام کشتارگاه",
|
||||
"تاریخ ثبت وضعیت",
|
||||
]}
|
||||
data={tableData}
|
||||
name="جزئیات حمل مرغ زنده"
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,131 @@
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import { IconButton, Tooltip } from "@mui/material";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { useDispatch } from "react-redux";
|
||||
import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye";
|
||||
import {
|
||||
cityFetchSamasatTransportChickens,
|
||||
visorsGetSamasatCookieService,
|
||||
} from "../../../visors/services/fetch-samasat-transport-chickens";
|
||||
import { DRAWER, LOADING_END } from "../../../../lib/redux/slices/appSlice";
|
||||
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
|
||||
import { TransportChickensDetails } from "../transport-chickens-details/TransportChickensDetails";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { useProvinceName } from "../../../../utils/getProvinceName";
|
||||
|
||||
export const TransportChickens = () => {
|
||||
const [tableData, setTableData] = useState([]);
|
||||
const [openNotif] = useContext(AppContext);
|
||||
const [data, setData] = useState([]);
|
||||
const dispatch = useDispatch();
|
||||
const province = useProvinceName();
|
||||
const [cookie, setCookie] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(visorsGetSamasatCookieService()).then((r) => {
|
||||
setCookie(r.payload.data.cookie);
|
||||
dispatch(
|
||||
cityFetchSamasatTransportChickens({
|
||||
cookie: r.payload.data.cookie,
|
||||
province:
|
||||
province === "hamedan"
|
||||
? "65550"
|
||||
: province === "bushehr"
|
||||
? "65527"
|
||||
: "65548",
|
||||
})
|
||||
).then((r) => {
|
||||
dispatch(LOADING_END());
|
||||
if (r.error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "کوکی معتبر نیست!",
|
||||
severity: "error",
|
||||
});
|
||||
} else {
|
||||
setData(r.payload.data);
|
||||
}
|
||||
});
|
||||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const d = data?.map((item, i) => {
|
||||
return [
|
||||
i + 1,
|
||||
item?.LocationNameProvince,
|
||||
item?.LocationNameCity,
|
||||
item?.PersonFullName,
|
||||
item?.PartIdCode,
|
||||
item?.UnitName,
|
||||
item?.EpidemiologicCode,
|
||||
item?.PostalCode,
|
||||
item?.CapacityFemale.toLocaleString(),
|
||||
item?.RequestCode,
|
||||
item?.SourceCertId,
|
||||
item?.HatchingDatePersian,
|
||||
item?.HatchingCount?.toLocaleString(),
|
||||
item?.RemoveCount,
|
||||
item?.RemoveCountTakhlie,
|
||||
item?.RemovePartyCount,
|
||||
<Tooltip placement="right" title="جزئیات" key={i}>
|
||||
<IconButton
|
||||
size="small"
|
||||
color="primary"
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
DRAWER({
|
||||
right: false,
|
||||
top: true,
|
||||
content: (
|
||||
<TransportChickensDetails
|
||||
code={item?.SourceCertId}
|
||||
cookie={cookie}
|
||||
/>
|
||||
),
|
||||
title: "جزئیات حمل مرغ زنده",
|
||||
})
|
||||
);
|
||||
}}
|
||||
>
|
||||
<RemoveRedEyeIcon />
|
||||
</IconButton>
|
||||
</Tooltip>,
|
||||
];
|
||||
});
|
||||
|
||||
setTableData(d);
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<Grid container xs={12} mt={2} justifyContent="center">
|
||||
<Grid container xs={12} mt={2} justifyContent="center">
|
||||
<ResponsiveTable
|
||||
paginated
|
||||
data={tableData}
|
||||
columns={[
|
||||
"ردیف",
|
||||
"استان",
|
||||
"شهر",
|
||||
"نام مالک",
|
||||
"شناسه یکتا واحد",
|
||||
"نام واحد",
|
||||
"کد اپیدمیولوژیک واحد",
|
||||
"کد پستی",
|
||||
"ظرفیت",
|
||||
"شماره مجوز",
|
||||
"شماره گواهی بهداشتی",
|
||||
"تاریخ جوجه ریزی",
|
||||
"تعداد جوجه ریزی",
|
||||
"مجموع حمل مرغ (تخلیه/ بارگیری)",
|
||||
"مجموع حمل مرغ (تایید تخلیه)",
|
||||
"تعداد ماشین حمل",
|
||||
"جزئیات",
|
||||
]}
|
||||
title="گزارش حمل مرغ زنده گله ها بر اساس حمل "
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user