main
This commit is contained in:
@@ -38,7 +38,7 @@ function AdvancedTablePage({ columns, list, api }) {
|
||||
setPage(0);
|
||||
};
|
||||
|
||||
const codeList = eval(list);
|
||||
let codeList = eval(list);
|
||||
|
||||
function replacePlaceholders(inputHTML, item) {
|
||||
const replacedHTML = inputHTML.replace(
|
||||
@@ -60,7 +60,7 @@ function AdvancedTablePage({ columns, list, api }) {
|
||||
|
||||
useEffect(() => {
|
||||
const d = tableData?.map((item) => {
|
||||
const result = codeList.map((option) => {
|
||||
const result = codeList.map((option, i) => {
|
||||
const properties = option.split(".");
|
||||
let value = item;
|
||||
for (const property of properties) {
|
||||
|
||||
@@ -19,8 +19,8 @@ export const AdvancedTable = ({ columns, data, name, pagination }) => {
|
||||
}, [data]);
|
||||
|
||||
useEffect(() => {
|
||||
const d = data?.map((item) => {
|
||||
return item?.map((row) => {
|
||||
const d = data?.map((item, i) => {
|
||||
return item?.map((row, index) => {
|
||||
if (!row && row !== 0) {
|
||||
return "";
|
||||
} else {
|
||||
|
||||
@@ -4,8 +4,6 @@ import { Grid } from "../grid/Grid";
|
||||
import { SPACING } from "../../data/spacing";
|
||||
import { LabelField } from "../label-field/LabelField";
|
||||
import CloseIcon from "@mui/icons-material/Close";
|
||||
import PictureAsPdfIcon from "@mui/icons-material/PictureAsPdf";
|
||||
import axios from "axios";
|
||||
|
||||
export const InspectionDetailsModal = ({ item }) => {
|
||||
const [statusTab, setStatusTab] = useState(0);
|
||||
@@ -23,12 +21,6 @@ export const InspectionDetailsModal = ({ item }) => {
|
||||
setFullscreenMedia(null);
|
||||
};
|
||||
|
||||
const handleDownloadPdf = () => {
|
||||
const baseUrl = axios.defaults.baseURL || "";
|
||||
const url = `${baseUrl}poultry_science_report_pdf/?key=${item?.key}`;
|
||||
window.open(url, "_blank");
|
||||
};
|
||||
|
||||
const formatDate = (dateString) => {
|
||||
if (!dateString) return "---";
|
||||
try {
|
||||
@@ -433,25 +425,9 @@ export const InspectionDetailsModal = ({ item }) => {
|
||||
p: 2,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
mb: 2,
|
||||
}}
|
||||
>
|
||||
<Typography variant="h5" sx={{ fontWeight: "bold" }}>
|
||||
<Typography variant="h5" sx={{ fontWeight: "bold", mb: 2 }}>
|
||||
اطلاعات
|
||||
</Typography>
|
||||
<IconButton
|
||||
onClick={handleDownloadPdf}
|
||||
color="error"
|
||||
title="دانلود PDF"
|
||||
>
|
||||
<PictureAsPdfIcon />
|
||||
</IconButton>
|
||||
</Box>
|
||||
<Divider sx={{ mb: 3 }} />
|
||||
{renderInformationTab()}
|
||||
|
||||
|
||||
@@ -224,7 +224,7 @@ const ResponsiveTable = ({
|
||||
justifyContent="space-between"
|
||||
xs={12}
|
||||
style={{
|
||||
width: "100%",
|
||||
width: "85vw",
|
||||
}}
|
||||
>
|
||||
<Grid gap={2} alignItems="center">
|
||||
@@ -442,7 +442,7 @@ const ResponsiveTable = ({
|
||||
id="startoftable"
|
||||
display={{ xs: "none", sm: "grid" }}
|
||||
style={{
|
||||
width: customWidth ? customWidth : "100%",
|
||||
width: customWidth ? customWidth : "85vw",
|
||||
}}
|
||||
>
|
||||
<TableContainer
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
/**
|
||||
* Hook to get the currently selected sub user from Redux state
|
||||
* @returns {Object|null} - The selected sub user object with { key, name, unit, mobile, fullname } or null
|
||||
*/
|
||||
export const useSelectedSubUser = () => {
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
return selectedSubUser;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook to get only the selected sub user key
|
||||
* @returns {string|null} - The sub user key or null
|
||||
*/
|
||||
export const useSelectedSubUserKey = () => {
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
return selectedSubUser?.key || null;
|
||||
};
|
||||
|
||||
export default useSelectedSubUser;
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
import { createAsyncThunk } from "@reduxjs/toolkit";
|
||||
import axios from "axios";
|
||||
import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice";
|
||||
|
||||
export const getUserRoleInfo = createAsyncThunk(
|
||||
"GET_USER_ROLE_INFO",
|
||||
async ({ userKey, role }, { dispatch }) => {
|
||||
try {
|
||||
dispatch(LOADING_START());
|
||||
const { data, status } = await axios.get("user-role-info/", {
|
||||
params: {
|
||||
user_key: userKey,
|
||||
role: role,
|
||||
},
|
||||
});
|
||||
dispatch(LOADING_END());
|
||||
return { data, status };
|
||||
} catch (error) {
|
||||
dispatch(LOADING_END());
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -39,7 +39,7 @@ export const AvicultureActiveRequests = () => {
|
||||
const filteredData =
|
||||
Array.isArray(avicultureRequests) &&
|
||||
avicultureRequests?.filter(
|
||||
(item) =>
|
||||
(item, i) =>
|
||||
(item.stateProcess === "accepted" ||
|
||||
item.stateProcess === "pending") &&
|
||||
item.finalState !== "archive"
|
||||
|
||||
@@ -365,7 +365,7 @@ export const AvicultureFreeSaleNewRequest = () => {
|
||||
useEffect(() => {
|
||||
if (poultryKey) {
|
||||
dispatch(LOADING_START());
|
||||
dispatch(avicultureGetHatchingData({ key: poultryKey })).then((r) => {
|
||||
dispatch(avicultureGetHatchingData(poultryKey)).then((r) => {
|
||||
if (r.payload.data) {
|
||||
setHatchingData(r.payload.data);
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ export const AvicultureNewRequest = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const removeInput = () => {
|
||||
const removeInput = (e) => {
|
||||
const number = arr.length - 1;
|
||||
|
||||
if (number !== 0) {
|
||||
@@ -381,7 +381,7 @@ export const AvicultureNewRequest = () => {
|
||||
useEffect(() => {
|
||||
if (poultryKey) {
|
||||
dispatch(LOADING_START());
|
||||
dispatch(avicultureGetHatchingData({ key: poultryKey })).then((r) => {
|
||||
dispatch(avicultureGetHatchingData(poultryKey)).then((r) => {
|
||||
if (r.payload.data) {
|
||||
setHatchingData(r.payload.data);
|
||||
|
||||
|
||||
@@ -487,7 +487,7 @@ export const ProvinceFreeSaleNewRequest = ({ fetchApiData }) => {
|
||||
useEffect(() => {
|
||||
if (poultryKey) {
|
||||
dispatch(LOADING_START());
|
||||
dispatch(avicultureGetHatchingData({ key: poultryKey })).then((r) => {
|
||||
dispatch(avicultureGetHatchingData(poultryKey)).then((r) => {
|
||||
if (r.payload.data) {
|
||||
setHatchingData(r.payload.data);
|
||||
|
||||
|
||||
@@ -3,12 +3,8 @@ import axios from "axios";
|
||||
|
||||
export const avicultureGetHatchingData = createAsyncThunk(
|
||||
"VET_GET_HATCHING",
|
||||
async (d) => {
|
||||
const { data, status } = await axios.get("poultry_hatching/", {
|
||||
params: {
|
||||
key: d.key || "",
|
||||
},
|
||||
});
|
||||
async (key) => {
|
||||
const { data, status } = await axios.get("poultry_hatching/?key=" + key);
|
||||
return { data, status };
|
||||
}
|
||||
);
|
||||
|
||||
@@ -864,7 +864,7 @@ export const CityHatchingShowTableDetail = ({ keyItem }) => {
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Grid>
|
||||
<Accordion sx={{ width: "100%" }}>
|
||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||
<Typography>اطلاعات بارهای قرنطینه</Typography>
|
||||
@@ -895,7 +895,7 @@ export const CityHatchingShowTableDetail = ({ keyItem }) => {
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Grid>
|
||||
<Accordion sx={{ width: "100%" }}>
|
||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||
<Typography>اطلاعات بارهای بازگشتی</Typography>
|
||||
@@ -942,7 +942,7 @@ export const CityHatchingShowTableDetail = ({ keyItem }) => {
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Grid>
|
||||
<Accordion sx={{ width: "100%" }}>
|
||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||
<Typography>اطلاعات تخصیصات بازگشتی</Typography>
|
||||
@@ -982,7 +982,7 @@ export const CityHatchingShowTableDetail = ({ keyItem }) => {
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Grid>
|
||||
<Accordion sx={{ width: "100%" }}>
|
||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||
<Typography>اطلاعات بارهای خارج استان</Typography>
|
||||
@@ -1016,7 +1016,7 @@ export const CityHatchingShowTableDetail = ({ keyItem }) => {
|
||||
</Accordion>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={12}>
|
||||
<Grid>
|
||||
<Accordion sx={{ width: "100%" }}>
|
||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||
<Typography>مدیریت بار زنجیره</Typography>
|
||||
@@ -1052,7 +1052,7 @@ export const CityHatchingShowTableDetail = ({ keyItem }) => {
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Grid>
|
||||
<Accordion sx={{ width: "100%" }}>
|
||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||
<Typography>اختلاف کشتار</Typography>
|
||||
@@ -1086,7 +1086,7 @@ export const CityHatchingShowTableDetail = ({ keyItem }) => {
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Grid>
|
||||
<Accordion sx={{ width: "100%" }}>
|
||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||
<Typography>گزارش تلفات</Typography>
|
||||
|
||||
@@ -556,7 +556,7 @@ export const CityHatchingUnassigned = ({ readOnly }) => {
|
||||
|
||||
return (
|
||||
<Grid alignItems="center" justifyContent="center" mt={2} xs={12}>
|
||||
<Grid alignItems="center" justifyContent="center" isDashboard xs={12}>
|
||||
<Grid alignItems="center" justifyContent="center" isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -354,7 +354,7 @@ export const CityHatchingsArchive = ({ readOnly }) => {
|
||||
|
||||
return (
|
||||
<Grid container xs={12} justifyContent="center" alignItems="center" gap={2}>
|
||||
<Grid alignItems="center" justifyContent="center" isDashboard xs={12}>
|
||||
<Grid alignItems="center" justifyContent="center" isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -538,7 +538,7 @@ export const CityHatchingsTotal = ({ readOnly }) => {
|
||||
|
||||
return (
|
||||
<Grid alignItems="center" justifyContent="center" mt={2}>
|
||||
<Grid alignItems="center" justifyContent="center" isDashboard xs={12}>
|
||||
<Grid alignItems="center" justifyContent="center" isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -546,7 +546,7 @@ export const CityHatchings = ({ readOnly }) => {
|
||||
|
||||
return (
|
||||
<Grid alignItems="center" justifyContent="center" mt={2}>
|
||||
<Grid alignItems="center" justifyContent="center" isDashboard xs={12}>
|
||||
<Grid alignItems="center" justifyContent="center" isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -30,8 +30,9 @@ export const CityIncreaseHatching = ({ state }) => {
|
||||
const [tableData, setTableData] = useState([]);
|
||||
|
||||
const fetchApiData = async (page) => {
|
||||
let response;
|
||||
dispatch(LOADING_START());
|
||||
const response = await axios.get(
|
||||
response = await axios.get(
|
||||
`hatching-increase-request/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}`
|
||||
);
|
||||
dispatch(LOADING_END());
|
||||
|
||||
@@ -668,7 +668,7 @@ export const CityNewKillRequest = ({
|
||||
);
|
||||
}
|
||||
});
|
||||
dispatch(avicultureGetHatchingData({ key: poultryKey })).then((r) => {
|
||||
dispatch(avicultureGetHatchingData(poultryKey)).then((r) => {
|
||||
if (r.payload.data) {
|
||||
setHatchingData(r.payload.data);
|
||||
} else {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
Card,
|
||||
Grid,
|
||||
IconButton,
|
||||
List,
|
||||
@@ -7,7 +8,7 @@ import {
|
||||
ListItemText,
|
||||
Popover,
|
||||
} from "@mui/material";
|
||||
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
|
||||
import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
@@ -186,12 +187,13 @@ export const CityPoultryFarms = () => {
|
||||
gap={SPACING.SMALL}
|
||||
mt={SPACING.MEDIUM}
|
||||
>
|
||||
<ResponsiveTable
|
||||
title="مرغداران زیرمجموعه"
|
||||
<Card sx={{ width: "100%" }}>
|
||||
<AdvancedTable
|
||||
name="مرغداران زیرمجموعه"
|
||||
columns={tableDataCol}
|
||||
data={dataTable}
|
||||
customWidth="100%"
|
||||
/>
|
||||
</Card>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -326,7 +326,7 @@ export const NationalInfoTransports = () => {
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid container mt={2} mb={4} isDashboard xs={12}>
|
||||
<Grid container mt={2} mb={4} isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -220,7 +220,7 @@ export const NationalInfoHatchingDetails = () => {
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid container mt={2} mb={4} isDashboard xs={12}>
|
||||
<Grid container mt={2} mb={4} isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -101,7 +101,8 @@ export const BarChartSection = ({ boxStats }) => {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
flex: { xs: "1 1 100%", md: "1 1 25%" },
|
||||
minWidth: { xs: "100%", sm: 300 },
|
||||
borderRadius: 2,
|
||||
border: "1px solid",
|
||||
borderColor: "divider",
|
||||
@@ -111,13 +112,12 @@ export const BarChartSection = ({ boxStats }) => {
|
||||
flexDirection: "column",
|
||||
boxSizing: "border-box",
|
||||
overflow: "hidden",
|
||||
maxHeight: "fit-content",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
variant="subtitle1"
|
||||
color="text.primary"
|
||||
sx={{ mb: 2, fontWeight: 600, fontSize: "1rem" }}
|
||||
variant="h6"
|
||||
color="primary.main"
|
||||
sx={{ mb: 2 }}
|
||||
textAlign="left"
|
||||
>
|
||||
گزارش انبار کشتارگاه
|
||||
|
||||
@@ -1,74 +1,17 @@
|
||||
import { Box, Typography } from "@mui/material";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
|
||||
const reportItems = [
|
||||
{ label: "حجم درخواست کشتار مرغدار:", key: "quantity" },
|
||||
{ label: "وزن درخواست کشتار مرغدار:", key: "totalWeight" },
|
||||
{ label: "حجم خرید های مستقیم :", key: "killRequestQuantity" },
|
||||
{ label: "وزن خرید های مستقیم :", key: "killRequestWeight" },
|
||||
{
|
||||
label: "حجم خرید های خارج از استان (زنده) :",
|
||||
key: "quantityKillHouseFreeBarLive",
|
||||
},
|
||||
{
|
||||
label: "وزن خرید های خارج از استان (زنده) :",
|
||||
key: "WeightKillHouseFreeBarLive",
|
||||
},
|
||||
{
|
||||
label: "وزن خرید های خارج از استان (لاشه) :",
|
||||
key: "WeightKillHouseFreeBarCarcass",
|
||||
},
|
||||
{
|
||||
label: "حجم کل تخصیصات (خرید مستقیم/ مرغدار ):",
|
||||
key: "provinceKillRequestQuantity",
|
||||
},
|
||||
{
|
||||
label: "وزن کل تخصیصات (خرید مستقیم/ مرغدار ):",
|
||||
key: "provinceKillRequestWeightCarcass",
|
||||
},
|
||||
{ label: "حجم فروش به خارج استان:", key: "poultryOutProvinceQuantity" },
|
||||
{ label: "وزن فروش به خارج استان:", key: "poultryOutProvinceWeight" },
|
||||
{ label: "حجم بارها:", key: "KillHouseRequestQuantity" },
|
||||
{ label: "وزن بارها:", key: "KillHouseRequestWeight" },
|
||||
{
|
||||
label: "لاشه تولیدی امروز با احتساب 25درصد افت کشتار :",
|
||||
key: "totalLossWeight",
|
||||
},
|
||||
];
|
||||
|
||||
const ReportRow = ({ label, value }) => (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
minHeight: 40,
|
||||
px: 2,
|
||||
py: 0.5,
|
||||
borderRadius: 1,
|
||||
backgroundColor: "rgba(147, 112, 219, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
color="text.primary"
|
||||
sx={{ fontSize: "0.85rem", textAlign: "left" }}
|
||||
>
|
||||
{label}
|
||||
</Typography>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
fontWeight="bold"
|
||||
sx={{ fontSize: "0.85rem", textAlign: "left" }}
|
||||
>
|
||||
{value?.toLocaleString() || 0}
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
|
||||
export const DailykillingReport = ({ boxStats }) => (
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
flex: "1 1 30%",
|
||||
minWidth: {
|
||||
md: "620px",
|
||||
},
|
||||
maxWidth: {
|
||||
md: "32%",
|
||||
},
|
||||
|
||||
borderRadius: 2,
|
||||
border: "1px solid",
|
||||
borderColor: "divider",
|
||||
@@ -77,16 +20,18 @@ export const DailykillingReport = ({ boxStats }) => (
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 2,
|
||||
height: "600px",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
textAlign="start"
|
||||
variant="subtitle1"
|
||||
color="text.primary"
|
||||
sx={{ fontWeight: 600, fontSize: "1rem" }}
|
||||
variant="h6"
|
||||
sx={{ fontSize: { xs: "1rem", lg: "1rem" } }}
|
||||
color="primary.main"
|
||||
>
|
||||
گزارش کشتار امروز مرغ گوشتی استان
|
||||
</Typography>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
@@ -94,16 +39,439 @@ export const DailykillingReport = ({ boxStats }) => (
|
||||
gap: 1,
|
||||
overflowY: "auto",
|
||||
flex: 1,
|
||||
maxHeight: "500px",
|
||||
}}
|
||||
>
|
||||
{reportItems.map((item) => (
|
||||
<ReportRow
|
||||
key={item.key}
|
||||
label={item.label}
|
||||
value={boxStats?.killing?.[item.key]}
|
||||
/>
|
||||
))}
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: { xs: "inherit", md: 48 },
|
||||
px: 2,
|
||||
py: 1,
|
||||
backgroundColor: "rgba(147, 112, 219, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
sx={{
|
||||
fontSize: { xs: "0.875rem", lg: "1rem" },
|
||||
textAlign: "left",
|
||||
}}
|
||||
>
|
||||
حجم درخواست کشتار مرغدار:
|
||||
</Typography>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
fontWeight="bold"
|
||||
sx={{
|
||||
fontSize: { xs: "0.825rem", sm: "1rem" },
|
||||
}}
|
||||
>
|
||||
{boxStats?.killing?.quantity?.toLocaleString() || 0}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: { xs: "inherit", md: 48 },
|
||||
px: 2,
|
||||
py: 1,
|
||||
backgroundColor: "rgba(147, 112, 219, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
sx={{
|
||||
fontSize: { xs: "0.875rem", lg: "1rem" },
|
||||
textAlign: "left",
|
||||
}}
|
||||
>
|
||||
وزن درخواست کشتار مرغدار:
|
||||
</Typography>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
fontWeight="bold"
|
||||
sx={{
|
||||
fontSize: { xs: "0.825rem", sm: "1rem" },
|
||||
}}
|
||||
>
|
||||
{boxStats?.killing?.totalWeight?.toLocaleString() || 0}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: { xs: "inherit", md: 48 },
|
||||
px: 2,
|
||||
py: 1,
|
||||
backgroundColor: "rgba(147, 112, 219, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
sx={{
|
||||
fontSize: { xs: "0.875rem", lg: "1rem" },
|
||||
textAlign: "left",
|
||||
}}
|
||||
>
|
||||
حجم خرید های مستقیم :
|
||||
</Typography>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
fontWeight="bold"
|
||||
sx={{
|
||||
fontSize: { xs: "0.825rem", sm: "1rem" },
|
||||
}}
|
||||
>
|
||||
{boxStats?.killing?.killRequestQuantity?.toLocaleString() || 0}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: { xs: "inherit", md: 48 },
|
||||
px: 2,
|
||||
py: 1,
|
||||
backgroundColor: "rgba(147, 112, 219, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
sx={{
|
||||
fontSize: { xs: "0.875rem", lg: "1rem" },
|
||||
textAlign: "left",
|
||||
}}
|
||||
>
|
||||
وزن خرید های مستقیم :
|
||||
</Typography>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
fontWeight="bold"
|
||||
sx={{
|
||||
fontSize: { xs: "0.825rem", sm: "1rem" },
|
||||
}}
|
||||
>
|
||||
{boxStats?.killing?.killRequestWeight?.toLocaleString() || 0}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: { xs: "inherit", md: 48 },
|
||||
px: 2,
|
||||
py: 1,
|
||||
backgroundColor: "rgba(147, 112, 219, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
sx={{
|
||||
fontSize: { xs: "0.875rem", lg: "1rem" },
|
||||
textAlign: "left",
|
||||
}}
|
||||
>
|
||||
حجم خرید های خارج از استان (زنده) :
|
||||
</Typography>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
fontWeight="bold"
|
||||
sx={{
|
||||
fontSize: { xs: "0.825rem", sm: "1rem" },
|
||||
}}
|
||||
>
|
||||
{boxStats?.killing?.quantityKillHouseFreeBarLive?.toLocaleString() ||
|
||||
0}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: { xs: "inherit", md: 48 },
|
||||
px: 2,
|
||||
py: 1,
|
||||
backgroundColor: "rgba(147, 112, 219, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
sx={{
|
||||
fontSize: { xs: "0.875rem", lg: "1rem" },
|
||||
textAlign: "left",
|
||||
}}
|
||||
>
|
||||
وزن خرید های خارج از استان (زنده) :
|
||||
</Typography>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
fontWeight="bold"
|
||||
sx={{
|
||||
fontSize: { xs: "0.825rem", sm: "1rem" },
|
||||
}}
|
||||
>
|
||||
{boxStats?.killing?.WeightKillHouseFreeBarLive?.toLocaleString() || 0}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: { xs: "inherit", md: 48 },
|
||||
px: 2,
|
||||
py: 1,
|
||||
backgroundColor: "rgba(147, 112, 219, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
sx={{
|
||||
fontSize: { xs: "0.875rem", lg: "1rem" },
|
||||
textAlign: "left",
|
||||
}}
|
||||
>
|
||||
وزن خرید های خارج از استان (لاشه) :
|
||||
</Typography>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
fontWeight="bold"
|
||||
sx={{
|
||||
fontSize: { xs: "0.825rem", sm: "1rem" },
|
||||
}}
|
||||
>
|
||||
{boxStats?.killing?.WeightKillHouseFreeBarCarcass?.toLocaleString() ||
|
||||
0}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: { xs: "inherit", md: 48 },
|
||||
px: 2,
|
||||
py: 1,
|
||||
backgroundColor: "rgba(147, 112, 219, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
sx={{
|
||||
fontSize: { xs: "0.875rem", lg: "1rem" },
|
||||
textAlign: "left",
|
||||
}}
|
||||
>
|
||||
حجم کل تخصیصات (خرید مستقیم/ مرغدار ):
|
||||
</Typography>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
fontWeight="bold"
|
||||
sx={{
|
||||
fontSize: { xs: "0.825rem", sm: "1rem" },
|
||||
}}
|
||||
>
|
||||
{boxStats?.killing?.provinceKillRequestQuantity?.toLocaleString() ||
|
||||
0}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: { xs: "inherit", md: 48 },
|
||||
px: 2,
|
||||
py: 1,
|
||||
backgroundColor: "rgba(147, 112, 219, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
sx={{
|
||||
fontSize: { xs: "0.875rem", lg: "1rem" },
|
||||
textAlign: "left",
|
||||
}}
|
||||
>
|
||||
وزن کل تخصیصات (خرید مستقیم/ مرغدار ):
|
||||
</Typography>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
fontWeight="bold"
|
||||
sx={{
|
||||
fontSize: { xs: "0.825rem", sm: "1rem" },
|
||||
}}
|
||||
>
|
||||
{boxStats?.killing?.provinceKillRequestWeightCarcass?.toLocaleString() ||
|
||||
0}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: { xs: "inherit", md: 48 },
|
||||
px: 2,
|
||||
py: 1,
|
||||
backgroundColor: "rgba(147, 112, 219, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
sx={{
|
||||
fontSize: { xs: "0.875rem", lg: "1rem" },
|
||||
textAlign: "left",
|
||||
}}
|
||||
>
|
||||
حجم فروش به خارج استان:
|
||||
</Typography>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
fontWeight="bold"
|
||||
sx={{
|
||||
fontSize: { xs: "0.825rem", sm: "1rem" },
|
||||
}}
|
||||
>
|
||||
{boxStats?.killing?.poultryOutProvinceQuantity?.toLocaleString() || 0}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: { xs: "inherit", md: 48 },
|
||||
px: 2,
|
||||
py: 1,
|
||||
backgroundColor: "rgba(147, 112, 219, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
sx={{
|
||||
fontSize: { xs: "0.875rem", lg: "1rem" },
|
||||
textAlign: "left",
|
||||
}}
|
||||
>
|
||||
وزن فروش به خارج استان:
|
||||
</Typography>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
fontWeight="bold"
|
||||
sx={{
|
||||
fontSize: { xs: "0.825rem", sm: "1rem" },
|
||||
}}
|
||||
>
|
||||
{boxStats?.killing?.poultryOutProvinceWeight?.toLocaleString() || 0}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: { xs: "inherit", md: 48 },
|
||||
px: 2,
|
||||
py: 1,
|
||||
backgroundColor: "rgba(147, 112, 219, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
sx={{
|
||||
fontSize: { xs: "0.875rem", lg: "1rem" },
|
||||
textAlign: "left",
|
||||
}}
|
||||
>
|
||||
حجم بارها:
|
||||
</Typography>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
fontWeight="bold"
|
||||
sx={{
|
||||
fontSize: { xs: "0.825rem", sm: "1rem" },
|
||||
}}
|
||||
>
|
||||
{boxStats?.killing?.KillHouseRequestQuantity?.toLocaleString() || 0}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: { xs: "inherit", md: 48 },
|
||||
px: 2,
|
||||
py: 1,
|
||||
backgroundColor: "rgba(147, 112, 219, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
sx={{
|
||||
fontSize: { xs: "0.875rem", lg: "1rem" },
|
||||
textAlign: "left",
|
||||
}}
|
||||
>
|
||||
وزن بارها:
|
||||
</Typography>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
fontWeight="bold"
|
||||
sx={{
|
||||
fontSize: { xs: "0.825rem", sm: "1rem" },
|
||||
}}
|
||||
>
|
||||
{boxStats?.killing?.KillHouseRequestWeight?.toLocaleString() || 0}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: { xs: "inherit", md: 48 },
|
||||
px: 2,
|
||||
py: 1,
|
||||
borderRadius: 1,
|
||||
backgroundColor: "rgba(147, 112, 219, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
sx={{
|
||||
fontSize: { xs: "0.875rem", lg: "1rem" },
|
||||
textAlign: "left",
|
||||
// maxWidth: "70%",
|
||||
}}
|
||||
>
|
||||
لاشه تولیدی امروز با احتساب 25درصد افت کشتار :
|
||||
</Typography>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
fontWeight="bold"
|
||||
sx={{
|
||||
fontSize: { xs: "0.825rem", sm: "1rem" },
|
||||
}}
|
||||
>
|
||||
{boxStats?.killing?.totalLossWeight?.toLocaleString() || 0}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -1,87 +1,60 @@
|
||||
import { Box, Typography } from "@mui/material";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
|
||||
const inventoryItems = [
|
||||
{
|
||||
label: "حجم آماده کشتار بزرگتر از 40 روز (قطعه) :",
|
||||
key: "leftOverBetweenFortySeventyFive",
|
||||
},
|
||||
{
|
||||
label: "وزن تقریبی کشتار بزرگتر از 40 روز (کیلوگرم) :",
|
||||
key: "weightBetweenFortySeventyFive",
|
||||
},
|
||||
{
|
||||
label: "میانگین وزن مرغداریهای آماده کشتار:",
|
||||
key: "aveWeight",
|
||||
suffix: " کیلوگرم",
|
||||
},
|
||||
{ label: "وزن گوشت قابل تولید:", key: "carcassWeight", suffix: " کیلوگرم" },
|
||||
];
|
||||
|
||||
const InventoryRow = ({ label, value, suffix = "" }) => (
|
||||
export const InventorySection = ({ boxStats }) => (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
minHeight: 40,
|
||||
px: 2,
|
||||
py: 0.5,
|
||||
borderRadius: 1,
|
||||
backgroundColor: "rgba(0, 128, 0, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
color="text.primary"
|
||||
sx={{ fontSize: "0.85rem", textAlign: "left" }}
|
||||
>
|
||||
{label}
|
||||
</Typography>
|
||||
<Typography
|
||||
fontWeight="bold"
|
||||
color="success.main"
|
||||
sx={{ fontSize: "0.85rem" }}
|
||||
>
|
||||
{value?.toLocaleString() || 0}
|
||||
{suffix}
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
|
||||
export const InventorySection = ({ boxStats, sx }) => (
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
flex: "1 1 30%",
|
||||
minWidth: { xs: "100%", sm: "340px" },
|
||||
maxWidth: { xs: "100%", md: "16%" },
|
||||
borderRadius: 2,
|
||||
border: "1px solid",
|
||||
borderColor: "divider",
|
||||
px: SPACING.MEDIUM,
|
||||
py: SPACING.SMALL,
|
||||
p: SPACING.MEDIUM,
|
||||
pt: 4,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
boxSizing: "border-box",
|
||||
backgroundColor: "rgba(0, 128, 0, 0.05)",
|
||||
textAlign: "left",
|
||||
...sx,
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
variant="subtitle1"
|
||||
color="text.primary"
|
||||
sx={{ mb: 2, fontWeight: 600, fontSize: "1rem" }}
|
||||
variant="h6"
|
||||
color="primary.main"
|
||||
sx={{ mb: 2, fontSize: { xs: "1rem", lg: "1rem" } }}
|
||||
>
|
||||
موجودی
|
||||
</Typography>
|
||||
|
||||
<Box sx={{ display: "flex", flexDirection: "column", gap: 1 }}>
|
||||
{inventoryItems.map((item) => (
|
||||
<InventoryRow
|
||||
key={item.key}
|
||||
label={item.label}
|
||||
value={boxStats?.inventory?.[item.key]}
|
||||
suffix={item.suffix}
|
||||
/>
|
||||
))}
|
||||
</Box>
|
||||
<Typography variant="body2" mt={3} bgGreen>
|
||||
حجم آماده کشتار بزرگتر از 40 روز (قطعه) :
|
||||
</Typography>
|
||||
<Typography variant="h6" mt={2} color="success.main">
|
||||
{boxStats?.inventory?.leftOverBetweenFortySeventyFive?.toLocaleString() ||
|
||||
0}
|
||||
</Typography>
|
||||
|
||||
<Typography variant="body2" mt={3} bgGreen>
|
||||
وزن تقریبی کشتار بزرگتر از 40 روز (کیلوگرم) :
|
||||
</Typography>
|
||||
<Typography variant="h6" mt={2} color="success.main">
|
||||
{boxStats?.inventory?.weightBetweenFortySeventyFive?.toLocaleString() ||
|
||||
0}
|
||||
</Typography>
|
||||
|
||||
<Typography variant="body2" mt={3} bgGreen>
|
||||
میانگین وزن مرغداریهای آماده کشتار:
|
||||
</Typography>
|
||||
<Typography variant="h6" mt={2} color="success.main">
|
||||
{boxStats?.inventory?.aveWeight?.toLocaleString() || 0} کیلوگرم
|
||||
</Typography>
|
||||
|
||||
<Typography variant="body2" mt={3} bgGreen>
|
||||
وزن گوشت قابل تولید:
|
||||
</Typography>
|
||||
<Typography variant="h6" mt={2} color="success.main">
|
||||
{boxStats?.inventory?.carcassWeight?.toLocaleString() || 0} کیلوگرم
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -87,7 +87,8 @@ export const PieChartSection = ({ boxStats }) => {
|
||||
<Box
|
||||
sx={{
|
||||
flex: "1 1 20%",
|
||||
width: "100%",
|
||||
minWidth: "300px",
|
||||
maxWidth: "100%",
|
||||
borderRadius: 2,
|
||||
border: "1px solid",
|
||||
borderColor: "divider",
|
||||
@@ -100,9 +101,9 @@ export const PieChartSection = ({ boxStats }) => {
|
||||
>
|
||||
<Typography
|
||||
textAlign="start"
|
||||
variant="subtitle1"
|
||||
color="text.primary"
|
||||
sx={{ mb: 2, fontWeight: 600, fontSize: "1rem" }}
|
||||
variant="h6"
|
||||
color="primary.main"
|
||||
sx={{ mb: 2 }}
|
||||
>
|
||||
آمار روز گذشته کشتار مرغ گوشتی استان
|
||||
</Typography>
|
||||
|
||||
@@ -13,18 +13,12 @@ export const PriceChartSection = ({ boxStats }) => (
|
||||
border: "1px solid",
|
||||
borderColor: "divider",
|
||||
p: 2,
|
||||
mt: 3,
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
variant="subtitle1"
|
||||
sx={{
|
||||
width: "100%",
|
||||
textAlign: "start",
|
||||
fontWeight: 600,
|
||||
fontSize: "1rem",
|
||||
mb: 1,
|
||||
}}
|
||||
color="text.primary"
|
||||
sx={{ width: "100%", textAlign: "start", fontWeight: "400", mb: 1 }}
|
||||
color="primary.main"
|
||||
>
|
||||
نمودار قیمت مرغ در هفته گذشته (میانگین قیمت)
|
||||
</Typography>
|
||||
|
||||
@@ -120,7 +120,12 @@ export const SlaughterDashboard = () => {
|
||||
];
|
||||
|
||||
return (
|
||||
<Grid container alignItems="center" justifyContent="flex-start">
|
||||
<Grid
|
||||
container
|
||||
direction="column"
|
||||
alignItems="center"
|
||||
justifyContent="flex-start"
|
||||
>
|
||||
<Grid
|
||||
container
|
||||
xs={12}
|
||||
|
||||
@@ -15,7 +15,7 @@ export const DashboardTab = () => {
|
||||
setValue(newValue);
|
||||
};
|
||||
return (
|
||||
<Grid container xs={12}>
|
||||
<Grid container justifyContent="center" alignItems="center">
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
@@ -44,7 +44,13 @@ export const DashboardTab = () => {
|
||||
<Tab label="پایش کشتار" value={2} />
|
||||
{/* <Tab label="گزارش عملکرد دوره ای" value={3} /> */}
|
||||
</Tabs>
|
||||
<Grid container xs={12} pt={3}>
|
||||
<Grid
|
||||
container
|
||||
xs={12}
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
p={1}
|
||||
>
|
||||
{value === 0 && <Dashboard />}
|
||||
{value === 1 && <SlaughterDashboard />}
|
||||
{value === 2 && <DashboardPeriodicPerformance />}
|
||||
|
||||
@@ -1,65 +1,26 @@
|
||||
import { Box, Typography } from "@mui/material";
|
||||
|
||||
const warehouseItems = [
|
||||
{ label: "وزن ورودی به انبار:", key: "enterWarehouseWeight" },
|
||||
{ label: "وزن فروش به خارج استان:", key: "outSellWeight" },
|
||||
{ label: "وزن توزیع به داخل استان:", key: "allocationWeight" },
|
||||
{ label: "وزن مانده در انبار کشتارگاه:", key: "leftOverWarehouseWeight" },
|
||||
];
|
||||
|
||||
const WarehouseRow = ({ label, value }) => (
|
||||
export const WarehouseInfoSection = ({ boxStats }) => (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
minHeight: 40,
|
||||
px: 2,
|
||||
py: 0.5,
|
||||
borderRadius: 1,
|
||||
backgroundColor: "rgba(147, 112, 219, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
color="text.primary"
|
||||
sx={{ fontSize: "0.85rem", textAlign: "left" }}
|
||||
>
|
||||
{label}
|
||||
</Typography>
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: 0.5 }}>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
fontWeight="bold"
|
||||
sx={{ fontSize: "0.85rem" }}
|
||||
>
|
||||
{value?.toLocaleString() || 0}
|
||||
</Typography>
|
||||
<Typography sx={{ fontSize: "0.75rem" }} color="text.secondary">
|
||||
کیلوگرم
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
||||
export const WarehouseInfoSection = ({ boxStats, sx }) => (
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
flex: { xs: "1 1 100%", md: "1 1 30%" },
|
||||
minWidth: { xs: "100%", sm: "340px" },
|
||||
borderRadius: 2,
|
||||
border: "1px solid",
|
||||
borderColor: "divider",
|
||||
p: "16px",
|
||||
// backgroundColor: "#EAEFFF",
|
||||
boxSizing: "border-box",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 2,
|
||||
...sx,
|
||||
// height: "100%",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
variant="subtitle1"
|
||||
color="text.primary"
|
||||
sx={{ fontWeight: 600, fontSize: "1rem" }}
|
||||
variant="h6"
|
||||
color="primary.main"
|
||||
sx={{ fontSize: { xs: "1rem", lg: "1rem" } }}
|
||||
textAlign="left"
|
||||
>
|
||||
اطلاعات انبار و توزیع امروز
|
||||
@@ -70,16 +31,114 @@ export const WarehouseInfoSection = ({ boxStats, sx }) => (
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 1,
|
||||
overflowY: "auto",
|
||||
flex: 1,
|
||||
pr: 1,
|
||||
}}
|
||||
>
|
||||
{warehouseItems.map((item) => (
|
||||
<WarehouseRow
|
||||
key={item.key}
|
||||
label={item.label}
|
||||
value={boxStats?.warehouseInformation?.[item.key]}
|
||||
/>
|
||||
))}
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: 48,
|
||||
px: 2,
|
||||
borderRadius: 1,
|
||||
backgroundColor: "rgba(147, 112, 219, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
sx={{ fontSize: { xs: "0.875rem", lg: "1rem" } }}
|
||||
>
|
||||
وزن ورودی به انبار:
|
||||
</Typography>
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
|
||||
<Typography color="primary.main" fontWeight="bold">
|
||||
{boxStats?.warehouseInformation?.enterWarehouseWeight?.toLocaleString() ||
|
||||
0}
|
||||
</Typography>
|
||||
<Typography variant="caption">کیلوگرم</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: 48,
|
||||
px: 2,
|
||||
borderRadius: 1,
|
||||
backgroundColor: "rgba(147, 112, 219, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
sx={{ fontSize: { xs: "0.875rem", lg: "1rem" } }}
|
||||
>
|
||||
وزن فروش به خارج استان:
|
||||
</Typography>
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
|
||||
<Typography color="primary.main" fontWeight="bold">
|
||||
{boxStats?.warehouseInformation?.outSellWeight?.toLocaleString() ||
|
||||
0}
|
||||
</Typography>
|
||||
<Typography variant="caption">کیلوگرم</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: 48,
|
||||
px: 2,
|
||||
borderRadius: 1,
|
||||
backgroundColor: "rgba(147, 112, 219, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
sx={{ fontSize: { xs: "0.875rem", lg: "1rem" } }}
|
||||
>
|
||||
وزن توزیع به داخل استان:
|
||||
</Typography>
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
|
||||
<Typography color="primary.main" fontWeight="bold">
|
||||
{boxStats?.warehouseInformation?.allocationWeight?.toLocaleString() ||
|
||||
0}
|
||||
</Typography>
|
||||
<Typography variant="caption">کیلوگرم</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: 48,
|
||||
px: 2,
|
||||
borderRadius: 1,
|
||||
backgroundColor: "rgba(147, 112, 219, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
sx={{ fontSize: { xs: "0.875rem", lg: "1rem" } }}
|
||||
>
|
||||
وزن مانده در انبار کشتارگاه:
|
||||
</Typography>
|
||||
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
|
||||
<Typography color="primary.main" fontWeight="bold">
|
||||
{boxStats?.warehouseInformation?.leftOverWarehouseWeight?.toLocaleString() ||
|
||||
0}
|
||||
</Typography>
|
||||
<Typography variant="caption">کیلوگرم</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -1,80 +1,17 @@
|
||||
import { Box, Typography } from "@mui/material";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
|
||||
const reportItems = [
|
||||
{ label: "حجم درخواست کشتار مرغدار:", key: "quantityYesterday" },
|
||||
{ label: "وزن درخواست کشتار مرغدار:", key: "totalWeightYesterday" },
|
||||
{ label: "حجم خرید های مستقیم :", key: "killRequestQuantityYesterday" },
|
||||
{ label: "وزن خرید های مستقیم :", key: "killRequestWeightYesterday" },
|
||||
{
|
||||
label: "حجم خرید های خارج از استان (زنده) :",
|
||||
key: "quantityKillHouseFreeBarLiveYesterday",
|
||||
},
|
||||
{
|
||||
label: "وزن خرید های خارج از استان (زنده) :",
|
||||
key: "WeightKillHouseFreeBarLiveYesterday",
|
||||
},
|
||||
{
|
||||
label: "وزن خرید های خارج از استان (لاشه) :",
|
||||
key: "WeightKillHouseFreeBarCarcassYesterday",
|
||||
},
|
||||
{
|
||||
label: "حجم کل تخصیصات (خرید مستقیم/ مرغدار ):",
|
||||
key: "provinceKillRequestQuantityYesterday",
|
||||
},
|
||||
{
|
||||
label: "وزن کل تخصیصات (خرید مستقیم/ مرغدار ):",
|
||||
key: "provinceKillRequestWeightCarcassYesterday",
|
||||
},
|
||||
{
|
||||
label: "حجم فروش به خارج استان:",
|
||||
key: "poultryOutProvinceQuantityYesterday",
|
||||
},
|
||||
{
|
||||
label: "وزن فروش به خارج استان:",
|
||||
key: "poultryOutProvinceWeightYesterday",
|
||||
},
|
||||
{ label: "حجم بارها:", key: "KillHouseRequestQuantityYesterday" },
|
||||
{ label: "وزن بارها:", key: "KillHouseRequestWeightYesterday" },
|
||||
{
|
||||
label: "لاشه تولیدی با احتساب 25درصد افت کشتار :",
|
||||
key: "totalLossWeightYesterday",
|
||||
},
|
||||
];
|
||||
|
||||
const ReportRow = ({ label, value }) => (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
minHeight: 40,
|
||||
px: 2,
|
||||
py: 0.5,
|
||||
borderRadius: 1,
|
||||
backgroundColor: "rgba(86, 156, 221, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
color="text.primary"
|
||||
sx={{ fontSize: "0.85rem", textAlign: "left" }}
|
||||
>
|
||||
{label}
|
||||
</Typography>
|
||||
<Typography
|
||||
color="primary.main"
|
||||
fontWeight="bold"
|
||||
sx={{ fontSize: "0.85rem", textAlign: "left" }}
|
||||
>
|
||||
{value?.toLocaleString() || 0}
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
|
||||
export const YesterdayKillingReport = ({ boxStats }) => (
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
flex: "1 1 20%",
|
||||
|
||||
minWidth: {
|
||||
md: "500px",
|
||||
},
|
||||
maxWidth: {
|
||||
md: "25%",
|
||||
},
|
||||
borderRadius: 2,
|
||||
border: "1px solid",
|
||||
borderColor: "divider",
|
||||
@@ -83,14 +20,10 @@ export const YesterdayKillingReport = ({ boxStats }) => (
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 2,
|
||||
height: "700px",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
textAlign="start"
|
||||
variant="subtitle1"
|
||||
color="text.primary"
|
||||
sx={{ fontWeight: 600, fontSize: "1rem" }}
|
||||
>
|
||||
<Typography textAlign="start" variant="h6" color="primary.main">
|
||||
گزارش کشتار دیروز مرغ گوشتی استان
|
||||
</Typography>
|
||||
|
||||
@@ -101,16 +34,262 @@ export const YesterdayKillingReport = ({ boxStats }) => (
|
||||
gap: 1,
|
||||
overflowY: "auto",
|
||||
flex: 1,
|
||||
maxHeight: "500px",
|
||||
}}
|
||||
>
|
||||
{reportItems.map((item, index) => (
|
||||
<ReportRow
|
||||
key={index}
|
||||
label={item.label}
|
||||
value={boxStats?.killingYesterday?.[item.key]}
|
||||
/>
|
||||
))}
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: 48,
|
||||
px: 2,
|
||||
borderRadius: 1,
|
||||
backgroundColor: "rgba(86, 156, 221, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography color="primary.main">حجم درخواست کشتار مرغدار:</Typography>
|
||||
<Typography color="primary.main" fontWeight="bold">
|
||||
{boxStats?.killingYesterday?.quantityYesterday?.toLocaleString() || 0}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: 48,
|
||||
px: 2,
|
||||
borderRadius: 1,
|
||||
backgroundColor: "rgba(86, 156, 221, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography color="primary.main">وزن درخواست کشتار مرغدار:</Typography>
|
||||
<Typography color="primary.main" fontWeight="bold">
|
||||
{boxStats?.killingYesterday?.totalWeightYesterday?.toLocaleString() ||
|
||||
0}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: 48,
|
||||
px: 2,
|
||||
borderRadius: 1,
|
||||
backgroundColor: "rgba(86, 156, 221, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography color="primary.main">حجم خرید های مستقیم :</Typography>
|
||||
<Typography color="primary.main" fontWeight="bold">
|
||||
{boxStats?.killingYesterday?.killRequestQuantityYesterday?.toLocaleString() ||
|
||||
0}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: 48,
|
||||
px: 2,
|
||||
borderRadius: 1,
|
||||
backgroundColor: "rgba(86, 156, 221, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography color="primary.main">وزن خرید های مستقیم :</Typography>
|
||||
<Typography color="primary.main" fontWeight="bold">
|
||||
{boxStats?.killingYesterday?.killRequestWeightYesterday?.toLocaleString() ||
|
||||
0}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: 48,
|
||||
px: 2,
|
||||
borderRadius: 1,
|
||||
backgroundColor: "rgba(86, 156, 221, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography color="primary.main">
|
||||
حجم خرید های خارج از استان (زنده) :
|
||||
</Typography>
|
||||
<Typography color="primary.main" fontWeight="bold">
|
||||
{boxStats?.killingYesterday?.quantityKillHouseFreeBarLiveYesterday?.toLocaleString() ||
|
||||
0}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: 48,
|
||||
px: 2,
|
||||
borderRadius: 1,
|
||||
backgroundColor: "rgba(86, 156, 221, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography color="primary.main">
|
||||
وزن خرید های خارج از استان (زنده) :
|
||||
</Typography>
|
||||
<Typography color="primary.main" fontWeight="bold">
|
||||
{boxStats?.killingYesterday?.WeightKillHouseFreeBarLiveYesterday?.toLocaleString() ||
|
||||
0}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: 48,
|
||||
px: 2,
|
||||
borderRadius: 1,
|
||||
backgroundColor: "rgba(86, 156, 221, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography color="primary.main">
|
||||
وزن خرید های خارج از استان (لاشه) :
|
||||
</Typography>
|
||||
<Typography color="primary.main" fontWeight="bold">
|
||||
{boxStats?.killingYesterday?.WeightKillHouseFreeBarCarcassYesterday?.toLocaleString() ||
|
||||
0}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: 48,
|
||||
px: 2,
|
||||
borderRadius: 1,
|
||||
backgroundColor: "rgba(86, 156, 221, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography color="primary.main">
|
||||
حجم کل تخصیصات (خرید مستقیم/ مرغدار ):
|
||||
</Typography>
|
||||
<Typography color="primary.main" fontWeight="bold">
|
||||
{boxStats?.killingYesterday?.provinceKillRequestQuantityYesterday?.toLocaleString() ||
|
||||
0}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: 48,
|
||||
px: 2,
|
||||
borderRadius: 1,
|
||||
backgroundColor: "rgba(86, 156, 221, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography color="primary.main">
|
||||
وزن کل تخصیصات (خرید مستقیم/ مرغدار ):
|
||||
</Typography>
|
||||
<Typography color="primary.main" fontWeight="bold">
|
||||
{boxStats?.killingYesterday?.provinceKillRequestWeightCarcassYesterday?.toLocaleString() ||
|
||||
0}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: 48,
|
||||
px: 2,
|
||||
borderRadius: 1,
|
||||
backgroundColor: "rgba(86, 156, 221, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography color="primary.main">حجم فروش به خارج استان:</Typography>
|
||||
<Typography color="primary.main" fontWeight="bold">
|
||||
{boxStats?.killingYesterday?.poultryOutProvinceQuantityYesterday?.toLocaleString() ||
|
||||
0}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: 48,
|
||||
px: 2,
|
||||
borderRadius: 1,
|
||||
backgroundColor: "rgba(86, 156, 221, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography color="primary.main">وزن فروش به خارج استان:</Typography>
|
||||
<Typography color="primary.main" fontWeight="bold">
|
||||
{boxStats?.killingYesterday?.poultryOutProvinceWeightYesterday?.toLocaleString() ||
|
||||
0}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: 48,
|
||||
px: 2,
|
||||
borderRadius: 1,
|
||||
backgroundColor: "rgba(86, 156, 221, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography color="primary.main">حجم بارها:</Typography>
|
||||
<Typography color="primary.main" fontWeight="bold">
|
||||
{boxStats?.killingYesterday?.KillHouseRequestQuantityYesterday?.toLocaleString() ||
|
||||
0}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: 48,
|
||||
px: 2,
|
||||
borderRadius: 1,
|
||||
backgroundColor: "rgba(86, 156, 221, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography color="primary.main">وزن بارها:</Typography>
|
||||
<Typography color="primary.main" fontWeight="bold">
|
||||
{boxStats?.killingYesterday?.KillHouseRequestWeightYesterday?.toLocaleString() ||
|
||||
0}
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
height: 48,
|
||||
px: 2,
|
||||
borderRadius: 1,
|
||||
backgroundColor: "rgba(86, 156, 221, 0.1)",
|
||||
}}
|
||||
>
|
||||
<Typography color="primary.main">
|
||||
لاشه تولیدی با احتساب 25درصد افت کشتار :
|
||||
</Typography>
|
||||
<Typography color="primary.main" fontWeight="bold">
|
||||
{boxStats?.killingYesterday?.totalLossWeightYesterday?.toLocaleString() ||
|
||||
0}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -154,6 +154,7 @@ export const Dashboard = () => {
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
direction="column"
|
||||
alignItems="center"
|
||||
justifyContent="flex-start"
|
||||
gap={SPACING.SMALL}
|
||||
@@ -236,13 +237,7 @@ export const Dashboard = () => {
|
||||
<Typography variant="body1" textAlign="left">
|
||||
{notification.title}
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="caption"
|
||||
textAlign="left"
|
||||
sx={{
|
||||
textAlign: "left",
|
||||
}}
|
||||
>
|
||||
<Typography variant="caption" textAlign="left">
|
||||
{notification.message}
|
||||
</Typography>
|
||||
</Box>
|
||||
@@ -450,16 +445,14 @@ export const Dashboard = () => {
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
variant="subtitle1"
|
||||
sx={{
|
||||
width: "100%",
|
||||
textAlign: "start",
|
||||
fontWeight: "600",
|
||||
fontWeight: "400",
|
||||
mb: 2,
|
||||
px: 1,
|
||||
fontSize: "1rem",
|
||||
}}
|
||||
color="text.primary"
|
||||
color="primary.main"
|
||||
>
|
||||
آمار جوجه ریزی استان
|
||||
</Typography>
|
||||
@@ -496,7 +489,7 @@ export const Dashboard = () => {
|
||||
))}
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12} my={SPACING.MEDIUM}>
|
||||
|
||||
<ResponsiveTable
|
||||
isDashboard
|
||||
noPagination
|
||||
@@ -546,45 +539,44 @@ export const Dashboard = () => {
|
||||
]}
|
||||
title="مانده در سالن (قطعه)"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid container item xs={12} spacing={2} sx={{ alignItems: "stretch" }}>
|
||||
<Grid item xs={12} xl={4} sx={{ display: "flex" }}>
|
||||
<DailykillingReport boxStats={boxStats} />
|
||||
</Grid>
|
||||
<Grid item xs={12} xl={4}>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 2,
|
||||
height: "100%",
|
||||
}}
|
||||
>
|
||||
<WarehouseInfoSection boxStats={boxStats} sx={{ flex: 1 }} />
|
||||
<InventorySection boxStats={boxStats} sx={{ flex: 1 }} />
|
||||
</Box>
|
||||
</Grid>
|
||||
<Grid item xs={12} xl={4} sx={{ display: "flex" }}>
|
||||
<YesterdayKillingReport boxStats={boxStats} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid
|
||||
container
|
||||
item
|
||||
xs={12}
|
||||
spacing={2}
|
||||
sx={{ mt: 2, alignItems: "stretch" }}
|
||||
sx={{
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
gap: SPACING.SMALL,
|
||||
justifyContent: "center",
|
||||
alignItems: "stretch",
|
||||
mt: 2,
|
||||
}}
|
||||
>
|
||||
<DailykillingReport boxStats={boxStats} />
|
||||
<WarehouseInfoSection boxStats={boxStats} />
|
||||
<InventorySection boxStats={boxStats} />
|
||||
</Grid>
|
||||
|
||||
<Grid
|
||||
container
|
||||
spacing={4}
|
||||
sx={{
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
gap: "20px",
|
||||
justifyContent: "center",
|
||||
alignItems: "stretch",
|
||||
mt: 2,
|
||||
}}
|
||||
>
|
||||
<Grid item xs={12} lg={4} sx={{ display: "flex" }}>
|
||||
<BarChartSection boxStats={boxStats} />
|
||||
</Grid>
|
||||
<Grid item xs={12} lg={4} sx={{ display: "flex" }}>
|
||||
<PieChartSection boxStats={boxStats} />
|
||||
<YesterdayKillingReport boxStats={boxStats} />
|
||||
</Grid>
|
||||
<Grid item xs={12} lg={4} sx={{ display: "flex" }}>
|
||||
|
||||
<PriceChartSection boxStats={boxStats} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
import { checkRequestBySlaughter } from "../../services/checkRequestBySlaughter";
|
||||
import { useFormik } from "formik";
|
||||
import { Yup } from "../../../../lib/yup/yup";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { PropTypes } from "prop-types";
|
||||
import { getAllocationInformation } from "../../services/get-allocation-information";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
@@ -22,16 +22,13 @@ import { useContext } from "react";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import { slaughterGetActiveRequests } from "../../../slaughter-house/services/slaughter-get-active-requests";
|
||||
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
|
||||
export default function CheckRequestItem({ reqKey, poultryRequestKey }) {
|
||||
const [openNotif] = useContext(AppContext);
|
||||
const [isDenyed, setisDenyed] = useState(false);
|
||||
const dispatch = useDispatch();
|
||||
const { id } = useParams();
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
|
||||
const [, , selectedDate1, , selectedDate2] = useContext(AppContext);
|
||||
|
||||
const formik = useFormik({
|
||||
@@ -134,30 +131,17 @@ export default function CheckRequestItem({ reqKey, poultryRequestKey }) {
|
||||
})
|
||||
);
|
||||
// getFileFromApi(roles, id, dispatch);
|
||||
dispatch(
|
||||
getAcceptedSlaughterRequest({
|
||||
id,
|
||||
role_key: checkPathStartsWith("slaughter")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
);
|
||||
dispatch(getAcceptedSlaughterRequest({ id }));
|
||||
setisDenyed(false);
|
||||
dispatch(
|
||||
getAllocationInformation({
|
||||
key: poultryRequestKey,
|
||||
role_key: checkPathStartsWith("slaughter")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
);
|
||||
dispatch(
|
||||
slaughterGetActiveRequests({
|
||||
selectedDate1,
|
||||
selectedDate2,
|
||||
role_key: checkPathStartsWith("slaughter")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
);
|
||||
openNotif({
|
||||
@@ -215,29 +199,14 @@ export default function CheckRequestItem({ reqKey, poultryRequestKey }) {
|
||||
content: null,
|
||||
})
|
||||
);
|
||||
dispatch(getAcceptedSlaughterRequest({ id }));
|
||||
dispatch(
|
||||
getAcceptedSlaughterRequest({
|
||||
id,
|
||||
role_key: checkPathStartsWith("slaughter")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
);
|
||||
dispatch(
|
||||
getAllocationInformation({
|
||||
key: poultryRequestKey,
|
||||
role_key: checkPathStartsWith("slaughter")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
getAllocationInformation({ key: poultryRequestKey })
|
||||
);
|
||||
dispatch(
|
||||
slaughterGetActiveRequests({
|
||||
selectedDate1,
|
||||
selectedDate2,
|
||||
role_key: checkPathStartsWith("slaughter")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
);
|
||||
openNotif({
|
||||
|
||||
@@ -26,7 +26,6 @@ import { NumberInput } from "../../../../components/number-format-custom/NumberF
|
||||
import { resizeImage } from "../../../../utils/resizeImage";
|
||||
import { slaughterGetExlusiveKillers } from "../../services/slaughterGetExlusiveKillers";
|
||||
import { isValidIndexWeight } from "../../../../utils/isValidIndexWeight";
|
||||
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
|
||||
export const SlaughterEnterBarItem = ({
|
||||
data,
|
||||
@@ -42,9 +41,7 @@ export const SlaughterEnterBarItem = ({
|
||||
const [weightWithBarImages, setWeightWithBarImages] = React.useState([]);
|
||||
const [weightWithBarImg, setWeightWithBarImg] = React.useState(null);
|
||||
const { weightRange } = useSelector((state) => state.provinceSlice);
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
|
||||
const weightWithBarImgHandler = (imageList) => {
|
||||
setWeightWithBarImages(imageList);
|
||||
formik.setFieldValue("weightWithBarImg", "");
|
||||
@@ -147,18 +144,11 @@ export const SlaughterEnterBarItem = ({
|
||||
|
||||
const [exclusiveKillers, setExclusiveKillers] = useState();
|
||||
const [selectedOption, setSelectedOption] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
slaughterGetExlusiveKillers({
|
||||
role_key: checkPathStartsWith("slaughter")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
).then((r) => {
|
||||
dispatch(slaughterGetExlusiveKillers()).then((r) => {
|
||||
setExclusiveKillers(r.payload.data);
|
||||
});
|
||||
}, [selectedSubUser?.key]);
|
||||
}, []);
|
||||
|
||||
const handleOptionChange = (event) => {
|
||||
setSelectedOption(event?.target.value);
|
||||
|
||||
@@ -13,14 +13,10 @@ import TimelineItem from "@mui/lab/TimelineItem";
|
||||
import { SlaughterEnterBarItem } from "../slaughter-enter-bar-item/SlaughterEnterBarItem";
|
||||
import { format } from "date-fns-jalali";
|
||||
import { provincePolicyGetWeightRange } from "../../../province/services/province-policy-get-weight-range";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
import { useDispatch } from "react-redux";
|
||||
|
||||
export const SlaughterEnterBarWeight = ({ item, updateTable }) => {
|
||||
const dispatch = useDispatch();
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
const sum = item?.acceptedRealWeight / item?.acceptedRealQuantity;
|
||||
const data = [
|
||||
[
|
||||
@@ -41,15 +37,8 @@ export const SlaughterEnterBarWeight = ({ item, updateTable }) => {
|
||||
];
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
provincePolicyGetWeightRange({
|
||||
role_key: checkPathStartsWith("slaughter")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
);
|
||||
}, [selectedSubUser?.key]);
|
||||
|
||||
dispatch(provincePolicyGetWeightRange());
|
||||
}, []);
|
||||
return (
|
||||
<TimelineItem sx={{ alignSelf: "flex-start", width: "100%" }}>
|
||||
<TimelineSeparator>
|
||||
|
||||
@@ -4,12 +4,11 @@ import { getRoleFromUrl } from "../../../utils/getRoleFromUrl";
|
||||
|
||||
export const getAcceptedSlaughterRequest = createAsyncThunk(
|
||||
"GET_ACCEPTED_SLAUGHTER_REQUEST",
|
||||
async ({ id, role_key }) => {
|
||||
async ({ id }) => {
|
||||
const { data, status } = await axios.get("province_kill_request", {
|
||||
params: {
|
||||
id,
|
||||
role: getRoleFromUrl(),
|
||||
role_key: role_key || "",
|
||||
},
|
||||
});
|
||||
return { data, status };
|
||||
|
||||
@@ -7,10 +7,7 @@ export const slaughterGetExlusiveKillers = createAsyncThunk(
|
||||
async (d, { dispatch }) => {
|
||||
dispatch(LOADING_START());
|
||||
const { data, status } = await axios.get(
|
||||
"kill_house/?exclusive-killers=true",
|
||||
{
|
||||
params: d,
|
||||
}
|
||||
"kill_house/?exclusive-killers=true"
|
||||
);
|
||||
dispatch(LOADING_END());
|
||||
return { data, status };
|
||||
|
||||
@@ -42,7 +42,7 @@ export const GuildReceiveBarOperation = ({ item }) => {
|
||||
authCode: Yup.string().required("کداحراز اجباری است"),
|
||||
});
|
||||
|
||||
const onSubmit = () => {
|
||||
const onSubmit = (values) => {
|
||||
// Handle form submission here
|
||||
// console.log("Form submitted with values:", values);
|
||||
};
|
||||
@@ -65,6 +65,9 @@ export const GuildReceiveBarOperation = ({ item }) => {
|
||||
weight: "",
|
||||
},
|
||||
validationSchema: Yup.object({
|
||||
number: Yup.number()
|
||||
.required("این فیلد اجباری است!")
|
||||
.typeError("لطفا عدد وارد کنید!"),
|
||||
weight: Yup.number()
|
||||
.required("این فیلد اجباری است!")
|
||||
.typeError("لطفا وزن را وارد کنید!"),
|
||||
@@ -114,7 +117,6 @@ export const GuildReceiveBarOperation = ({ item }) => {
|
||||
size="small"
|
||||
label="وزن"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
disabled={!isChecked}
|
||||
onChange={formikRealInfo.handleChange}
|
||||
onBlur={formikRealInfo.handleBlur}
|
||||
@@ -130,6 +132,27 @@ export const GuildReceiveBarOperation = ({ item }) => {
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<TextField
|
||||
id="number"
|
||||
size="small"
|
||||
label="تعداد"
|
||||
variant="outlined"
|
||||
disabled={!isChecked}
|
||||
onChange={formikRealInfo.handleChange}
|
||||
onBlur={formikRealInfo.handleBlur}
|
||||
value={formikRealInfo.values.number}
|
||||
error={
|
||||
formikRealInfo.touched.number &&
|
||||
Boolean(formikRealInfo.errors.number)
|
||||
}
|
||||
helperText={
|
||||
formikRealInfo.touched.number
|
||||
? formikRealInfo.errors.number
|
||||
: ""
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<FormControl component="fieldset">
|
||||
@@ -181,7 +204,9 @@ export const GuildReceiveBarOperation = ({ item }) => {
|
||||
if (getRoleFromUrl() === "senf") {
|
||||
reqObj = {
|
||||
guild_check_allocation: true,
|
||||
receiver_real_number_of_carcasses: 0,
|
||||
receiver_real_number_of_carcasses: formikRealInfo.values.number
|
||||
? formikRealInfo.values.number
|
||||
: item.numberOfCarcasses,
|
||||
receiver_real_weight_of_carcasses: formikRealInfo.values.weight
|
||||
? formikRealInfo.values.weight
|
||||
: item.weightOfCarcasses,
|
||||
@@ -193,7 +218,9 @@ export const GuildReceiveBarOperation = ({ item }) => {
|
||||
reqObj = {
|
||||
steward_check_allocation: true,
|
||||
allocation_key: item.key,
|
||||
receiver_real_number_of_carcasses: 0,
|
||||
receiver_real_number_of_carcasses: formikRealInfo.values.number
|
||||
? formikRealInfo.values.number
|
||||
: item.numberOfCarcasses,
|
||||
receiver_real_weight_of_carcasses: formikRealInfo.values.weight
|
||||
? formikRealInfo.values.weight
|
||||
: item.weightOfCarcasses,
|
||||
@@ -206,7 +233,9 @@ export const GuildReceiveBarOperation = ({ item }) => {
|
||||
reqObj = {
|
||||
guild_check_allocation: true,
|
||||
allocation_key: item.key,
|
||||
receiver_real_number_of_carcasses: 0,
|
||||
receiver_real_number_of_carcasses: formikRealInfo.values.number
|
||||
? formikRealInfo.values.number
|
||||
: item.numberOfCarcasses,
|
||||
receiver_real_weight_of_carcasses: formikRealInfo.values.weight
|
||||
? formikRealInfo.values.weight
|
||||
: item.weightOfCarcasses,
|
||||
@@ -216,7 +245,9 @@ export const GuildReceiveBarOperation = ({ item }) => {
|
||||
reqObj = {
|
||||
steward_check_allocation: true,
|
||||
allocation_key: item.key,
|
||||
receiver_real_number_of_carcasses: 0,
|
||||
receiver_real_number_of_carcasses: formikRealInfo.values.number
|
||||
? formikRealInfo.values.number
|
||||
: item.numberOfCarcasses,
|
||||
receiver_real_weight_of_carcasses: formikRealInfo.values.weight
|
||||
? formikRealInfo.values.weight
|
||||
: item.weightOfCarcasses,
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Button, InputAdornment, TextField } from "@mui/material";
|
||||
import { Yup } from "../../../lib/yup/yup";
|
||||
import { useContext, useEffect } from "react";
|
||||
import { SPACING } from "../../../data/spacing";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { guildUpdateAllocatedStockService } from "../services/guild-update-allocated-stock";
|
||||
import { AppContext } from "../../../contexts/AppContext";
|
||||
import { guildGetInventoryStockService } from "../services/guild-get-inventory-stock";
|
||||
@@ -13,7 +13,6 @@ import { CLOSE_MODAL } from "../../../lib/redux/slices/appSlice";
|
||||
import { getRoleFromUrl } from "../../../utils/getRoleFromUrl";
|
||||
import { senfGetInventoryStockService } from "../services/senf-get-inventory-stock";
|
||||
import { senfGetInventoryAllocatedService } from "../services/senf-get-inventory-allocated";
|
||||
import { checkPathStartsWith } from "../../../utils/checkPathStartsWith";
|
||||
|
||||
const schema = Yup.object().shape({
|
||||
quantity: Yup.number().required("وارد کردن تعداد اجباری است"),
|
||||
@@ -24,9 +23,6 @@ export const RegisterEditDeliveryNumberAndWeight = ({ item }) => {
|
||||
const [openNotif] = useContext(AppContext);
|
||||
const [, , selectedDate1] = useContext(AppContext);
|
||||
const dispatch = useDispatch();
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
const formik = useFormik({
|
||||
initialValues: {
|
||||
quantity: item?.receiverRealNumberOfCarcasses,
|
||||
@@ -65,17 +61,11 @@ export const RegisterEditDeliveryNumberAndWeight = ({ item }) => {
|
||||
dispatch(
|
||||
guildGetInventoryStockService({
|
||||
date: selectedDate1,
|
||||
role_key: checkPathStartsWith("senf")
|
||||
? selectedSubUser?.key
|
||||
: "",
|
||||
})
|
||||
);
|
||||
dispatch(
|
||||
guildGetInventoryAllocatedService({
|
||||
date: selectedDate1,
|
||||
role_key: checkPathStartsWith("senf")
|
||||
? selectedSubUser?.key
|
||||
: "",
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
TextField,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { useFormik } from "formik";
|
||||
import { DatePicker } from "@mui/x-date-pickers";
|
||||
import moment from "moment";
|
||||
@@ -36,7 +36,6 @@ import PersianDate from "persian-date";
|
||||
import axios from "axios";
|
||||
import { LabelField } from "../../../components/label-field/LabelField";
|
||||
import { SPACING } from "../../../data/spacing";
|
||||
import { checkPathStartsWith } from "../../../utils/checkPathStartsWith";
|
||||
|
||||
export const StewardAllocationToGuild = ({
|
||||
item,
|
||||
@@ -80,9 +79,6 @@ export const StewardAllocationToGuild = ({
|
||||
const [selectedDate1, setSelectedDate1] = useState(
|
||||
moment(new Date()).format("YYYY-MM-DD")
|
||||
);
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
|
||||
const handleChange = (event) => {
|
||||
setValue(event.target.value);
|
||||
@@ -164,10 +160,13 @@ export const StewardAllocationToGuild = ({
|
||||
return transformedData;
|
||||
}, []);
|
||||
|
||||
const updateCalendarData = useCallback((dataArray) => {
|
||||
const updateCalendarData = useCallback(
|
||||
(dataArray) => {
|
||||
const transformed = transformCalendarData(dataArray);
|
||||
setCalendarDayData(transformed);
|
||||
}, []);
|
||||
},
|
||||
[transformCalendarData]
|
||||
);
|
||||
|
||||
const fetchCalendarData = useCallback(
|
||||
async (dateParam = selectedDate1) => {
|
||||
@@ -175,9 +174,6 @@ export const StewardAllocationToGuild = ({
|
||||
const response = await axios.get("/steward-remain-weight/", {
|
||||
params: {
|
||||
date: dateParam,
|
||||
role_key: checkPathStartsWith("steward")
|
||||
? selectedSubUser?.key
|
||||
: "",
|
||||
},
|
||||
});
|
||||
if (response.data) {
|
||||
@@ -195,7 +191,7 @@ export const StewardAllocationToGuild = ({
|
||||
console.error("Error fetching calendar data:", error);
|
||||
}
|
||||
},
|
||||
[selectedInventory, updateCalendarData, selectedDate1, selectedSubUser]
|
||||
[selectedInventory, updateCalendarData, selectedDate1]
|
||||
);
|
||||
|
||||
const [buyerData, setBuyerData] = useState({
|
||||
@@ -213,7 +209,7 @@ export const StewardAllocationToGuild = ({
|
||||
|
||||
useEffect(() => {
|
||||
fetchCalendarData(selectedDate1);
|
||||
}, [selectedDate1]);
|
||||
}, [fetchCalendarData, selectedDate1]);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
@@ -229,41 +225,30 @@ export const StewardAllocationToGuild = ({
|
||||
setProductionDate(null);
|
||||
setSelectedDateAmount(null);
|
||||
}
|
||||
}, [selectedInventory, calendarRawData]);
|
||||
}, [selectedInventory, calendarRawData, updateCalendarData]);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
provincePolicyGetUploadImageService({
|
||||
role_key: checkPathStartsWith("steward") ? selectedSubUser?.key : "",
|
||||
})
|
||||
).then((r) => {
|
||||
dispatch(provincePolicyGetUploadImageService()).then((r) => {
|
||||
if (r.payload?.data) {
|
||||
setImageUploadLimit(r.payload.data.killHouseAllocation);
|
||||
}
|
||||
});
|
||||
|
||||
if (!editData) {
|
||||
dispatch(
|
||||
slaughterGetProductsService({
|
||||
role_key: checkPathStartsWith("steward") ? selectedSubUser?.key : "",
|
||||
})
|
||||
).then((r) => {
|
||||
dispatch(slaughterGetProductsService()).then((r) => {
|
||||
setProductData(r.payload.data);
|
||||
});
|
||||
if (!item) {
|
||||
dispatch(
|
||||
slaughterGetGuildsForAllocateService({
|
||||
free: value === "free" ? true : false,
|
||||
role_key: checkPathStartsWith("steward")
|
||||
? selectedSubUser?.key
|
||||
: "",
|
||||
})
|
||||
).then((r) => {
|
||||
setGuildsData(r.payload.data);
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [value, selectedSubUser?.key]);
|
||||
}, [dispatch, value]);
|
||||
|
||||
const validationSchema = Yup.object({
|
||||
mobile: Yup.string().when([], {
|
||||
@@ -350,11 +335,14 @@ export const StewardAllocationToGuild = ({
|
||||
}, [formik.values.price, formik.values.weight]);
|
||||
|
||||
const successSubmit = () => {
|
||||
dispatch(
|
||||
fetchSlaughterBroadcastAndProducts({
|
||||
role_key: checkPathStartsWith("steward") ? selectedSubUser?.key : "",
|
||||
})
|
||||
);
|
||||
dispatch(CLOSE_MODAL());
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
dispatch(fetchSlaughterBroadcastAndProducts());
|
||||
dispatch(
|
||||
DRAWER({
|
||||
right: false,
|
||||
@@ -366,13 +354,6 @@ export const StewardAllocationToGuild = ({
|
||||
fetchApiData && fetchApiData(1);
|
||||
updateTable && updateTable();
|
||||
fetchData && fetchData(1);
|
||||
dispatch(CLOSE_MODAL());
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
};
|
||||
|
||||
const [dateRangeError, setDateRangeError] = useState(null);
|
||||
@@ -472,9 +453,13 @@ export const StewardAllocationToGuild = ({
|
||||
<FormControlLabel
|
||||
value="own"
|
||||
control={<Radio />}
|
||||
label="اختصاصی"
|
||||
label="صنوف اختصاصی"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value="free"
|
||||
control={<Radio />}
|
||||
label="صنوف آزاد"
|
||||
/>
|
||||
<FormControlLabel value="free" control={<Radio />} label="آزاد" />
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
</LabelField>
|
||||
@@ -492,7 +477,9 @@ export const StewardAllocationToGuild = ({
|
||||
? guildsData.map((i) => {
|
||||
return {
|
||||
data: i,
|
||||
label: `${i?.guildsName} ${i?.user?.fullname} (${i?.user?.mobile})`,
|
||||
label: `${i?.steward ? "مباشر" : "صنف"} ${
|
||||
i?.guildsName
|
||||
} ${i?.user?.fullname} (${i?.user?.mobile})`,
|
||||
};
|
||||
})
|
||||
: []
|
||||
@@ -501,8 +488,10 @@ export const StewardAllocationToGuild = ({
|
||||
setBuyerData({
|
||||
item: value?.data,
|
||||
key: value?.data?.key,
|
||||
allocationType: "steward_guild",
|
||||
buyerType: "Guild",
|
||||
allocationType: value?.data?.steward
|
||||
? "steward_steward"
|
||||
: "steward_guild",
|
||||
buyerType: value?.data?.steward ? "Steward" : "Guild",
|
||||
});
|
||||
formik.setFieldValue("mobile", value?.data?.user?.mobile);
|
||||
formik.setFieldTouched("mobile", true, false);
|
||||
@@ -513,7 +502,7 @@ export const StewardAllocationToGuild = ({
|
||||
}
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField fullWidth {...params} label="انتخاب صنف" />
|
||||
<TextField fullWidth {...params} label="انتخاب مباشر / صنف" />
|
||||
)}
|
||||
/>
|
||||
</Grid>
|
||||
@@ -538,7 +527,7 @@ export const StewardAllocationToGuild = ({
|
||||
checked={changeMobile}
|
||||
onChange={() => setChangeMobile(!changeMobile)}
|
||||
/>
|
||||
از این قسمت میتوانید تلفن صنف را ویرایش کنید.
|
||||
از این قسمت میتوانید تلفن مباشر/صنف را ویرایش کنید.
|
||||
</Typography>
|
||||
|
||||
{buyerData?.key && changeMobile && (
|
||||
@@ -786,21 +775,31 @@ export const StewardAllocationToGuild = ({
|
||||
weight_of_carcasses: formik.values.weight,
|
||||
amount: formik.values.price,
|
||||
total_amount: formik.values.wholePrice,
|
||||
role_key: checkPathStartsWith("steward")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
distribution_type: "web",
|
||||
...(imageChanged && { image: formik.values.image }),
|
||||
};
|
||||
} else if (!editData) {
|
||||
req = {
|
||||
seller_type: sellerType,
|
||||
buyer_type: "Guild",
|
||||
guild_key: buyerData?.item?.key,
|
||||
buyer_type: buyerData?.buyerType,
|
||||
guild_key:
|
||||
buyerData?.buyerType === "Guild"
|
||||
? buyerData?.item?.key
|
||||
: null,
|
||||
steward_key:
|
||||
buyerData?.buyerType === "Steward"
|
||||
? buyerData?.item?.key
|
||||
: null,
|
||||
kill_house_key:
|
||||
buyerData?.buyerType === "KillHouse"
|
||||
? buyerData?.item?.key
|
||||
: null,
|
||||
cold_house_key: coldHouseKey || null,
|
||||
product_key: coldHouseKey ? null : productKey.key,
|
||||
type: "manual",
|
||||
allocation_type: coldHouseKey ? "ColdHouse" : "steward_guild",
|
||||
allocation_type: coldHouseKey
|
||||
? "ColdHouse"
|
||||
: buyerData?.allocationType,
|
||||
number_of_carcasses: 0,
|
||||
weight_of_carcasses: formik.values.weight,
|
||||
sell_type: sellType,
|
||||
@@ -811,9 +810,6 @@ export const StewardAllocationToGuild = ({
|
||||
quota: selectedInventory,
|
||||
date: selectedDate1,
|
||||
production_date: productionDate,
|
||||
role_key: checkPathStartsWith("steward")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
distribution_type: "web",
|
||||
...(buyerData?.item?.user?.mobile !== formik.values.mobile
|
||||
? { interface_number: formik.values.mobile }
|
||||
@@ -831,9 +827,6 @@ export const StewardAllocationToGuild = ({
|
||||
number_of_carcasses: 0,
|
||||
weight_of_carcasses: formik.values.weight,
|
||||
amount: formik.values.price,
|
||||
role_key: checkPathStartsWith("steward")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
total_amount: formik.values.wholePrice,
|
||||
distribution_type: "web",
|
||||
...(imageChanged && { image: formik.values.image }),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useContext, useEffect, useRef, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useDispatch } from "react-redux";
|
||||
import InfoIcon from "@mui/icons-material/Info";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import InputAdornment from "@mui/material/InputAdornment";
|
||||
@@ -35,7 +35,6 @@ import { Grid } from "../../../components/grid/Grid";
|
||||
import { NumberInput } from "../../../components/number-format-custom/NumberFormatCustom";
|
||||
import ResponsiveTable from "../../../components/responsive-table/ResponsiveTable";
|
||||
import { AppContext } from "../../../contexts/AppContext";
|
||||
import { checkPathStartsWith } from "../../../utils/checkPathStartsWith";
|
||||
|
||||
export const StewardDailyList = () => {
|
||||
const [productsTable, setProductsTable] = useState();
|
||||
@@ -49,9 +48,7 @@ export const StewardDailyList = () => {
|
||||
const [filteredData, setFilteredData] = useState([]);
|
||||
|
||||
const [openNotif] = useContext(AppContext);
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
|
||||
const priceRefs = useRef([]);
|
||||
const weightRefs = useRef([]);
|
||||
|
||||
@@ -138,25 +135,16 @@ export const StewardDailyList = () => {
|
||||
}
|
||||
};
|
||||
const fetchPriceStatus = async () => {
|
||||
dispatch(
|
||||
slaughterGetPriceService({
|
||||
role: getRoleFromUrl(),
|
||||
role_key: checkPathStartsWith("steward") ? selectedSubUser?.key : "",
|
||||
})
|
||||
).then((r) => {
|
||||
dispatch(slaughterGetPriceService({ role: getRoleFromUrl() })).then((r) => {
|
||||
setPriceState(r.payload.data);
|
||||
});
|
||||
};
|
||||
|
||||
const fetchApiData = async () => {
|
||||
const fetchApiData = async (page) => {
|
||||
dispatch(LOADING_START());
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`commonly-used/?search=filter&value=&role=${getRoleFromUrl()}${
|
||||
checkPathStartsWith("steward")
|
||||
? `&role_key=${selectedSubUser?.key}`
|
||||
: ""
|
||||
}&page=1&page_size=10000`
|
||||
`commonly-used/?search=filter&value=&role=${getRoleFromUrl()}&page=1&page_size=10000`
|
||||
);
|
||||
setrendered(true);
|
||||
setData(response.data.results || []);
|
||||
@@ -222,10 +210,10 @@ export const StewardDailyList = () => {
|
||||
dispatch(slaughterGetProductsService()).then((r) => {
|
||||
setSlaughterProducts(r.payload.data);
|
||||
});
|
||||
}, [selectedSubUser?.key]);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const d = slaughterProducts?.map((item) => {
|
||||
const d = slaughterProducts?.map((item, i) => {
|
||||
return [item?.name, item?.totalRemainWeight?.toLocaleString()];
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { AppContext } from "../../../contexts/AppContext";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useDispatch } from "react-redux";
|
||||
import ResponsiveTable from "../../../components/responsive-table/ResponsiveTable";
|
||||
import { Grid } from "../../../components/grid/Grid";
|
||||
import moment from "moment";
|
||||
@@ -20,7 +20,6 @@ import { stewardGetOutSellService } from "../services/steward-get-sell-out-servi
|
||||
import { formatJustDate, formatTime } from "../../../utils/formatTime";
|
||||
import { StewardSegmentOperation } from "./StewardSegmentOperation";
|
||||
import { stawardGetSegmentDashboardService } from "../services/steward-get-dashboard-service";
|
||||
import { checkPathStartsWith } from "../../../utils/checkPathStartsWith";
|
||||
|
||||
export const StewardSegmant = () => {
|
||||
const [data, setData] = useState([]);
|
||||
@@ -34,9 +33,6 @@ export const StewardSegmant = () => {
|
||||
const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] =
|
||||
useContext(AppContext);
|
||||
const dispatch = useDispatch();
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
|
||||
// const userKey = useSelector((state) => state.userSlice.userProfile.key);
|
||||
|
||||
@@ -46,7 +42,6 @@ export const StewardSegmant = () => {
|
||||
value: textValue,
|
||||
date1: selectedDate1,
|
||||
date2: selectedDate2,
|
||||
role_key: checkPathStartsWith("steward") ? selectedSubUser?.key : "",
|
||||
})
|
||||
).then((r) => {
|
||||
setDashboardData(r.payload.data);
|
||||
@@ -62,11 +57,7 @@ export const StewardSegmant = () => {
|
||||
const fetchApiData = async (page) => {
|
||||
dispatch(LOADING_START());
|
||||
const response = await axios.get(
|
||||
`app-segmentation/?search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}&role=${getRoleFromUrl()}${
|
||||
checkPathStartsWith("steward")
|
||||
? `&role_key=${selectedSubUser?.key}`
|
||||
: ""
|
||||
}`
|
||||
`app-segmentation/?search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&page_size=${perPage}&role=${getRoleFromUrl()}`
|
||||
);
|
||||
|
||||
getDashboardData();
|
||||
@@ -98,14 +89,10 @@ export const StewardSegmant = () => {
|
||||
|
||||
useEffect(() => {
|
||||
fetchApiData(1);
|
||||
dispatch(
|
||||
stewardGetOutSellService({
|
||||
role_key: checkPathStartsWith("steward") ? selectedSubUser?.key : "",
|
||||
})
|
||||
).then((r) => {
|
||||
dispatch(stewardGetOutSellService()).then((r) => {
|
||||
setProducts(r.payload.data);
|
||||
});
|
||||
}, [selectedSubUser?.key]);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const d = data?.map((item, i) => {
|
||||
@@ -157,11 +144,7 @@ export const StewardSegmant = () => {
|
||||
dispatch(LOADING_START());
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`app-segmentation/?search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&role=${getRoleFromUrl()}${
|
||||
checkPathStartsWith("steward")
|
||||
? `&role_key=${selectedSubUser?.key}`
|
||||
: ""
|
||||
}`
|
||||
`app-segmentation/?search=filter&value=${textValue}&date1=${selectedDate1}&date2=${selectedDate2}&page=${page}&role=${getRoleFromUrl()}`
|
||||
);
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
@@ -181,7 +164,7 @@ export const StewardSegmant = () => {
|
||||
gap={SPACING.SMALL}
|
||||
justifyContent="flex-start"
|
||||
>
|
||||
<Grid container mt={2} mb={4} isDashboard xs={12}>
|
||||
<Grid container mt={2} mb={4} isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -12,23 +12,18 @@ import { SPACING } from "../../../data/spacing";
|
||||
import { Grid } from "../../../components/grid/Grid";
|
||||
import { DRAWER } from "../../../lib/redux/slices/appSlice";
|
||||
import { stewardSegmentSubmitService } from "../services/steward-segment-submit-service";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { useContext, useEffect, useState, useCallback } from "react";
|
||||
import { AppContext } from "../../../contexts/AppContext";
|
||||
import { useFormik } from "formik";
|
||||
import { Yup } from "../../../lib/yup/yup";
|
||||
import { stawardGetSegmantRoleService } from "../services/steward-get-segmant-role";
|
||||
import { getRoleFromUrl } from "../../../utils/getRoleFromUrl";
|
||||
import { stewardEditSegmentService } from "../services/steward-segment-edit-operation";
|
||||
import MonthlyDataCalendar from "../../../components/date-picker/MonthlyDataCalendar";
|
||||
import PersianDate from "persian-date";
|
||||
import axios from "axios";
|
||||
import { LabelField } from "../../../components/label-field/LabelField";
|
||||
import { checkPathStartsWith } from "../../../utils/checkPathStartsWith";
|
||||
import {
|
||||
slaughterGetGuildsForAllocateService,
|
||||
slaughterGetStewardsForAllocateService,
|
||||
} from "../../slaughter-house/services/slaughter-get-guilds-for-allocate";
|
||||
import { Typography } from "@mui/material";
|
||||
|
||||
const getValidationSchema = (selectedDateAmount) =>
|
||||
Yup.object().shape({
|
||||
@@ -59,22 +54,13 @@ export const StewardSegmentSubmitOperation = ({
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
const [openNotif] = useContext(AppContext);
|
||||
const [stewardData, setStewardData] = useState([]);
|
||||
const [segmentType, setSegmentType] = useState("own");
|
||||
const [selectedInventory] = useState("free");
|
||||
const [approvedStatus, setApprovedStatus] = useState("governmental");
|
||||
const [buyerCategory, setBuyerCategory] = useState(""); // "stewards" or "guilds"
|
||||
const [guildsData, setGuildsData] = useState([]);
|
||||
const [stewardsData, setStewardsData] = useState([]);
|
||||
const [buyerData, setBuyerData] = useState({
|
||||
key: "",
|
||||
item: "",
|
||||
buyerType: "",
|
||||
allocationType: "",
|
||||
});
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
const [selectedBuyer, setSelectedBuyer] = useState(null);
|
||||
|
||||
// Calendar states
|
||||
const [selectedCalendarDate, setSelectedCalendarDate] = useState(null);
|
||||
const [calendarDayData, setCalendarDayData] = useState({});
|
||||
const [productionDate, setProductionDate] = useState(null);
|
||||
@@ -130,7 +116,7 @@ export const StewardSegmentSubmitOperation = ({
|
||||
distribution_type: "web",
|
||||
};
|
||||
} else {
|
||||
if (!buyerData?.key) {
|
||||
if (!selectedBuyer) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
@@ -141,9 +127,7 @@ export const StewardSegmentSubmitOperation = ({
|
||||
}
|
||||
|
||||
req = {
|
||||
guild_key: buyerData?.buyerType === "Guild" ? buyerData?.key : null,
|
||||
steward_key:
|
||||
buyerData?.buyerType === "Steward" ? buyerData?.key : null,
|
||||
guild_key: selectedBuyer.key,
|
||||
weight: values.weight,
|
||||
product_key: productKey || "",
|
||||
sale_type: selectedInventory,
|
||||
@@ -151,9 +135,6 @@ export const StewardSegmentSubmitOperation = ({
|
||||
production_date: productionDate,
|
||||
distribution_type: "web",
|
||||
};
|
||||
req = Object.fromEntries(
|
||||
Object.entries(req).filter(([, val]) => val !== null)
|
||||
);
|
||||
}
|
||||
|
||||
dispatch(stewardSegmentSubmitService(req)).then((r) => {
|
||||
@@ -195,19 +176,6 @@ export const StewardSegmentSubmitOperation = ({
|
||||
setApprovedStatus(newType);
|
||||
};
|
||||
|
||||
const handleBuyerCategoryChange = (event) => {
|
||||
const newCategory = event.target.value;
|
||||
setBuyerCategory(newCategory);
|
||||
setBuyerData({
|
||||
key: "",
|
||||
item: "",
|
||||
buyerType: "",
|
||||
allocationType: "",
|
||||
});
|
||||
setGuildsData([]);
|
||||
setStewardsData([]);
|
||||
};
|
||||
|
||||
// Calendar functions
|
||||
const handleDateSelect = (dateInfo) => {
|
||||
if (dateInfo && dateInfo.formattedDate) {
|
||||
@@ -216,6 +184,7 @@ export const StewardSegmentSubmitOperation = ({
|
||||
// Get the data for the selected date
|
||||
const data = calendarDayData[dateInfo.formattedDate];
|
||||
|
||||
// Use the original Gregorian date from the API data for production_date
|
||||
if (data && data.originalDay) {
|
||||
setProductionDate(data.originalDay);
|
||||
}
|
||||
@@ -229,24 +198,30 @@ export const StewardSegmentSubmitOperation = ({
|
||||
}
|
||||
};
|
||||
|
||||
// Transform calendar data from array format to object format
|
||||
// Input: [{day: "2025-10-10", amount: 100}]
|
||||
// Output: {"1404/07/19": {value1: 100, originalDay: "2025-10-10"}}
|
||||
const transformCalendarData = useCallback((dataArray) => {
|
||||
if (!Array.isArray(dataArray)) return {};
|
||||
|
||||
const transformedData = {};
|
||||
dataArray.forEach((item) => {
|
||||
if (item.day && item.amount !== undefined) {
|
||||
// Convert Gregorian date to Persian date
|
||||
const persianDate = new PersianDate(new Date(item.day));
|
||||
const persianDateStr = persianDate.format("YYYY/MM/DD");
|
||||
// Calendar expects 'value1' property, also store the original day
|
||||
transformedData[persianDateStr] = {
|
||||
value1: item.amount,
|
||||
originalDay: item.day,
|
||||
active: item.active === true,
|
||||
originalDay: item.day, // Store the original Gregorian date
|
||||
active: item.active === true, // Store active status
|
||||
};
|
||||
}
|
||||
});
|
||||
return transformedData;
|
||||
}, []);
|
||||
|
||||
// Function to update calendar data from API response
|
||||
const updateCalendarData = useCallback(
|
||||
(dataArray) => {
|
||||
const transformed = transformCalendarData(dataArray);
|
||||
@@ -258,30 +233,17 @@ export const StewardSegmentSubmitOperation = ({
|
||||
// Fetch calendar data from API
|
||||
const fetchCalendarData = useCallback(async () => {
|
||||
try {
|
||||
const currentRole = getRoleFromUrl();
|
||||
console.log(getRoleFromUrl());
|
||||
let remainWeightEndpoint = "kill-house-remain-weight";
|
||||
if (currentRole === "Steward") {
|
||||
remainWeightEndpoint = "steward-remain-weight";
|
||||
} else if (currentRole === "Guilds") {
|
||||
remainWeightEndpoint = "guild-remain-weight";
|
||||
}
|
||||
|
||||
const response = await axios.get(`${remainWeightEndpoint}/`, {
|
||||
params: {
|
||||
role_key:
|
||||
checkPathStartsWith("slaughter") ||
|
||||
checkPathStartsWith("steward") ||
|
||||
checkPathStartsWith("senf")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
},
|
||||
});
|
||||
const response = await axios.get(
|
||||
`/${
|
||||
getRoleFromUrl() === "Steward" ? "steward" : "kill-house"
|
||||
}-remain-weight/`
|
||||
);
|
||||
if (response.data) {
|
||||
setCalendarRawData({
|
||||
governmental: response.data.governmental || [],
|
||||
free: response.data.free || [],
|
||||
});
|
||||
// Update calendar based on current inventory type
|
||||
const dataToShow =
|
||||
approvedStatus === "governmental"
|
||||
? response.data.governmental
|
||||
@@ -291,42 +253,21 @@ export const StewardSegmentSubmitOperation = ({
|
||||
} catch (error) {
|
||||
console.error("Error fetching calendar data:", error);
|
||||
}
|
||||
}, [approvedStatus, updateCalendarData, selectedSubUser]);
|
||||
}, [approvedStatus, updateCalendarData]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!editData) {
|
||||
dispatch(stawardGetSegmantRoleService({ role: getRoleFromUrl() })).then(
|
||||
(r) => {
|
||||
setStewardData(r.payload.data);
|
||||
}
|
||||
);
|
||||
}
|
||||
// Fetch calendar data on mount
|
||||
fetchCalendarData();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!editData && buyerCategory) {
|
||||
if (buyerCategory === "guilds") {
|
||||
dispatch(
|
||||
slaughterGetGuildsForAllocateService({
|
||||
free: true,
|
||||
role_key:
|
||||
checkPathStartsWith("slaughter") || checkPathStartsWith("steward")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
).then((r) => {
|
||||
setGuildsData(r.payload.data || []);
|
||||
});
|
||||
} else if (buyerCategory === "stewards") {
|
||||
dispatch(
|
||||
slaughterGetStewardsForAllocateService({
|
||||
free: true,
|
||||
role_key:
|
||||
checkPathStartsWith("slaughter") || checkPathStartsWith("steward")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
).then((r) => {
|
||||
setStewardsData(r.payload.data || []);
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [buyerCategory, selectedSubUser?.key, editData]);
|
||||
}, [dispatch, editData, fetchCalendarData]);
|
||||
|
||||
// Update calendar when inventory type changes
|
||||
useEffect(() => {
|
||||
if (
|
||||
calendarRawData.governmental.length > 0 ||
|
||||
@@ -337,25 +278,18 @@ export const StewardSegmentSubmitOperation = ({
|
||||
? calendarRawData.governmental
|
||||
: calendarRawData.free;
|
||||
updateCalendarData(dataToShow);
|
||||
// Reset selected date when inventory type changes
|
||||
setSelectedCalendarDate(null);
|
||||
setProductionDate(null);
|
||||
setSelectedDateAmount(null);
|
||||
}
|
||||
}, [approvedStatus, calendarRawData, updateCalendarData]);
|
||||
|
||||
// Validate form when selectedDateAmount changes
|
||||
useEffect(() => {
|
||||
formik.validateForm();
|
||||
}, [selectedDateAmount]);
|
||||
|
||||
// Set segmentType to "own" for Guilds role
|
||||
useEffect(() => {
|
||||
const currentRole = getRoleFromUrl();
|
||||
if (currentRole === "Guilds" && !editData) {
|
||||
setSegmentType("own");
|
||||
formik.setFieldValue("segmentType", "own");
|
||||
}
|
||||
}, [editData]);
|
||||
|
||||
return (
|
||||
<Grid container direction="column" justifyContent="center" gap={2}>
|
||||
<Grid container direction="column" justifyContent="center" gap={2} pt={2}>
|
||||
@@ -367,7 +301,7 @@ export const StewardSegmentSubmitOperation = ({
|
||||
gap: SPACING.LARGE + 4,
|
||||
}}
|
||||
>
|
||||
{!editData && getRoleFromUrl() !== "Guilds" && (
|
||||
{!editData && (
|
||||
<LabelField label="قطعه بندی (کاربر)">
|
||||
<FormControl>
|
||||
<RadioGroup
|
||||
@@ -396,120 +330,45 @@ export const StewardSegmentSubmitOperation = ({
|
||||
)}
|
||||
|
||||
{!editData && segmentType === "free" && (
|
||||
<>
|
||||
<LabelField label="خریداران">
|
||||
<FormControl fullWidth>
|
||||
<RadioGroup
|
||||
row
|
||||
aria-labelledby="buyer-category-radio-group"
|
||||
name="buyerCategory"
|
||||
value={buyerCategory}
|
||||
onChange={handleBuyerCategoryChange}
|
||||
sx={{
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<FormControlLabel
|
||||
value="stewards"
|
||||
control={<Radio />}
|
||||
label="مباشرین"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value="guilds"
|
||||
control={<Radio />}
|
||||
label="اصناف"
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
</LabelField>
|
||||
|
||||
{buyerCategory && (
|
||||
<Grid xs={12} container>
|
||||
{(() => {
|
||||
const currentData =
|
||||
buyerCategory === "guilds" ? guildsData : stewardsData;
|
||||
const isEmpty = !currentData || currentData.length === 0;
|
||||
|
||||
if (isEmpty) {
|
||||
return (
|
||||
<Typography
|
||||
variant="body2"
|
||||
color="text.secondary"
|
||||
sx={{
|
||||
width: "100%",
|
||||
textAlign: "center",
|
||||
padding: 2,
|
||||
fontStyle: "italic",
|
||||
}}
|
||||
>
|
||||
{buyerCategory === "guilds"
|
||||
? "هیچ صنفی یافت نشد"
|
||||
: "هیچ مباشری یافت نشد"}
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Autocomplete
|
||||
fullWidth
|
||||
style={{ minWidth: 210 }}
|
||||
disablePortal
|
||||
id="buyer-selection"
|
||||
id="steward-select"
|
||||
options={
|
||||
buyerCategory === "guilds"
|
||||
? guildsData.map((i) => {
|
||||
stewardData
|
||||
? stewardData.map((i) => {
|
||||
return {
|
||||
data: i,
|
||||
label: `${i?.guildsName} ${i?.user?.fullname} (${i?.user?.mobile})`,
|
||||
};
|
||||
})
|
||||
: stewardsData.map((i) => {
|
||||
return {
|
||||
data: i,
|
||||
label: `${i?.name || ""} - ${
|
||||
i?.user?.fullname || ""
|
||||
} (${i?.user?.mobile || ""})`,
|
||||
label: `${i?.steward ? "مباشر" : "صنف"} ${
|
||||
i?.guildsName
|
||||
} ${i?.user?.fullname} (${i?.user?.mobile})`,
|
||||
};
|
||||
})
|
||||
: []
|
||||
}
|
||||
onChange={(event, value) => {
|
||||
if (buyerCategory === "guilds") {
|
||||
setBuyerData({
|
||||
if (value) {
|
||||
setSelectedBuyer({
|
||||
item: value?.data,
|
||||
key: value?.data?.key,
|
||||
allocationType: value?.data?.steward
|
||||
? "steward_steward"
|
||||
: "steward_guild",
|
||||
buyerType: value?.data?.steward
|
||||
? "Steward"
|
||||
: "Guild",
|
||||
});
|
||||
} else if (buyerCategory === "stewards") {
|
||||
setBuyerData({
|
||||
item: value?.data,
|
||||
key: value?.data?.key,
|
||||
allocationType: "steward_steward",
|
||||
buyerType: "Steward",
|
||||
});
|
||||
} else {
|
||||
setSelectedBuyer(null);
|
||||
}
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
fullWidth
|
||||
{...params}
|
||||
label={
|
||||
buyerCategory === "guilds"
|
||||
? "انتخاب صنف"
|
||||
: "انتخاب مباشر"
|
||||
}
|
||||
label="انتخاب مباشر / صنف"
|
||||
required={segmentType === "free"}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
})()}
|
||||
</Grid>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* {!editData && (
|
||||
<LabelField label="نوع فروش">
|
||||
@@ -625,8 +484,7 @@ export const StewardSegmentSubmitOperation = ({
|
||||
!editData &&
|
||||
(!productionDate ||
|
||||
(selectedDateAmount &&
|
||||
formik.values.weight > selectedDateAmount) ||
|
||||
(segmentType === "free" && !buyerData?.key))
|
||||
formik.values.weight > selectedDateAmount))
|
||||
}
|
||||
>
|
||||
{editData ? "ویرایش" : "ثبت"}
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
import { useContext, useState } from "react";
|
||||
import { useDispatch } from "react-redux";
|
||||
import {
|
||||
Button,
|
||||
FormControl,
|
||||
Grid,
|
||||
InputLabel,
|
||||
MenuItem,
|
||||
Select,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import axios from "axios";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { getFaUserRole } from "../../../../utils/getFaUserRole";
|
||||
|
||||
export const AddAccessLevelModal = ({ device, onSuccess }) => {
|
||||
const dispatch = useDispatch();
|
||||
const [openNotif] = useContext(AppContext);
|
||||
const [selectedAccessLevel, setSelectedAccessLevel] = useState("");
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
|
||||
const accessLevelOptions = ["Steward", "KillHouse", "Guilds"];
|
||||
|
||||
const handleCloseModal = () => {
|
||||
dispatch(CLOSE_MODAL());
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!selectedAccessLevel) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
severity: "error",
|
||||
msg: "لطفاً یک سطح دسترسی را انتخاب کنید.",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!device?.key && !device?.id) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
severity: "error",
|
||||
msg: "شناسه دستگاه یافت نشد. لطفاً دوباره تلاش کنید.",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setSubmitting(true);
|
||||
try {
|
||||
const payload = {
|
||||
pos_key: device?.key || device?.id,
|
||||
name: selectedAccessLevel,
|
||||
};
|
||||
|
||||
await axios.post("/pos-access-level/", payload);
|
||||
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
severity: "success",
|
||||
msg: "سطح دسترسی با موفقیت افزوده شد.",
|
||||
});
|
||||
|
||||
if (onSuccess) {
|
||||
onSuccess();
|
||||
}
|
||||
handleCloseModal();
|
||||
} catch (error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
severity: "error",
|
||||
msg:
|
||||
error?.response?.data?.result ||
|
||||
error?.response?.data?.detail ||
|
||||
"افزودن سطح دسترسی با خطا مواجه شد.",
|
||||
});
|
||||
} finally {
|
||||
setSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
direction="column"
|
||||
gap={SPACING.SMALL}
|
||||
width="100%"
|
||||
alignItems="stretch"
|
||||
sx={{ minWidth: 300 }}
|
||||
>
|
||||
<Typography variant="body2">
|
||||
دستگاه انتخاب شده:{" "}
|
||||
{device?.serial ||
|
||||
device?.pos_unique_id ||
|
||||
device?.pos_id ||
|
||||
device?.posId ||
|
||||
"-"}
|
||||
</Typography>
|
||||
<FormControl fullWidth size="small">
|
||||
<InputLabel id="access-level-label">سطح دسترسی</InputLabel>
|
||||
<Select
|
||||
labelId="access-level-label"
|
||||
id="access-level-select"
|
||||
value={selectedAccessLevel}
|
||||
label="سطح دسترسی"
|
||||
onChange={(e) => setSelectedAccessLevel(e.target.value)}
|
||||
>
|
||||
<MenuItem value="">
|
||||
<em>انتخاب سطح دسترسی</em>
|
||||
</MenuItem>
|
||||
{accessLevelOptions.map((option) => (
|
||||
<MenuItem key={option} value={option}>
|
||||
{getFaUserRole(option)}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
<Grid container justifyContent="flex-end" gap={SPACING.SMALL} mt={2}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
onClick={handleCloseModal}
|
||||
disabled={submitting}
|
||||
>
|
||||
انصراف
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={handleSubmit}
|
||||
disabled={!selectedAccessLevel || submitting}
|
||||
>
|
||||
{submitting ? "در حال ثبت..." : "ثبت"}
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -1,354 +0,0 @@
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import {
|
||||
Autocomplete,
|
||||
Button,
|
||||
CircularProgress,
|
||||
FormControl,
|
||||
FormControlLabel,
|
||||
Grid,
|
||||
MenuItem,
|
||||
Radio,
|
||||
RadioGroup,
|
||||
Select,
|
||||
TextField,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import axios from "axios";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice";
|
||||
import { LabelField } from "../../../../components/label-field/LabelField";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import { getFaUserRole } from "../../../../utils/getFaUserRole";
|
||||
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
|
||||
export const AssignSubUserModal = ({ device, onSuccess }) => {
|
||||
const dispatch = useDispatch();
|
||||
const [openNotif] = useContext(AppContext);
|
||||
const [options, setOptions] = useState([]);
|
||||
const [selectedUser, setSelectedUser] = useState(null);
|
||||
const [selectedAccessLevel, setSelectedAccessLevel] = useState("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const [fetchError, setFetchError] = useState("");
|
||||
const [userType, setUserType] = useState("delegate");
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
useEffect(() => {
|
||||
let isMounted = true;
|
||||
|
||||
const fetchUsers = async () => {
|
||||
setLoading(true);
|
||||
setFetchError("");
|
||||
setSelectedUser(null);
|
||||
setSelectedAccessLevel("");
|
||||
try {
|
||||
let response;
|
||||
const role = getRoleFromUrl();
|
||||
|
||||
if (userType === "delegate") {
|
||||
response = await axios.get(
|
||||
`/get_representatives/?role=${role}${
|
||||
checkPathStartsWith("slaughter") || checkPathStartsWith("steward")
|
||||
? `&role_key=${selectedSubUser?.key}`
|
||||
: ""
|
||||
}`
|
||||
);
|
||||
} else {
|
||||
response = await axios.get(
|
||||
`/get_dispensers/?role=${role}${
|
||||
checkPathStartsWith("slaughter") || checkPathStartsWith("steward")
|
||||
? `&role_key=${selectedSubUser?.key}`
|
||||
: ""
|
||||
}`
|
||||
);
|
||||
}
|
||||
|
||||
if (isMounted) {
|
||||
const rawOptions = Array.isArray(response?.data?.results)
|
||||
? response?.data?.results
|
||||
: Array.isArray(response?.data)
|
||||
? response?.data
|
||||
: Array.isArray(response?.data?.data)
|
||||
? response?.data?.data
|
||||
: Array.isArray(response)
|
||||
? response
|
||||
: [];
|
||||
|
||||
// Normalize the data - both delegates and dispensers have the same structure
|
||||
const normalizedOptions = rawOptions.map((item) => {
|
||||
const fullname = item?.fullname || "-";
|
||||
const mobile = item?.mobile || "";
|
||||
const mobileLabel = mobile ? ` (${mobile})` : "";
|
||||
const label = `${fullname}${mobileLabel}`;
|
||||
|
||||
return {
|
||||
...item,
|
||||
label: label || "-",
|
||||
};
|
||||
});
|
||||
|
||||
setOptions(normalizedOptions);
|
||||
}
|
||||
} catch (error) {
|
||||
if (isMounted) {
|
||||
setFetchError("دریافت لیست کاربران با خطا مواجه شد.");
|
||||
console.error("Error fetching users:", error);
|
||||
}
|
||||
} finally {
|
||||
if (isMounted) {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
fetchUsers();
|
||||
|
||||
return () => {
|
||||
isMounted = false;
|
||||
};
|
||||
}, [userType, selectedSubUser?.key]);
|
||||
|
||||
const handleCloseModal = () => {
|
||||
dispatch(CLOSE_MODAL());
|
||||
};
|
||||
|
||||
const getSubAccessLevels = (user) => {
|
||||
if (!user) return [];
|
||||
|
||||
const subAccessLevels = [];
|
||||
|
||||
// Common excluded boolean fields that are not access levels
|
||||
const excludedFields = [
|
||||
"active",
|
||||
"trash",
|
||||
"deleted",
|
||||
"isActive",
|
||||
"isDeleted",
|
||||
];
|
||||
|
||||
// Get all boolean fields that represent sub access levels
|
||||
// These are fields in the object that are boolean and indicate sub access levels
|
||||
Object.keys(user).forEach((key) => {
|
||||
if (typeof user[key] === "boolean" && user[key] === true) {
|
||||
// Exclude common boolean fields that aren't access levels
|
||||
if (!excludedFields.includes(key.toLowerCase())) {
|
||||
// Use getFaUserRole to get the Persian translation
|
||||
const translatedLabel = getFaUserRole(key);
|
||||
subAccessLevels.push({
|
||||
key: key,
|
||||
label: translatedLabel || key,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return subAccessLevels;
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!selectedUser) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
severity: "error",
|
||||
msg: "لطفاً یک کاربر را انتخاب کنید.",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!device?.key && !device?.id) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
severity: "error",
|
||||
msg: "شناسه دستگاه یافت نشد. لطفاً دوباره تلاش کنید.",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setSubmitting(true);
|
||||
try {
|
||||
const payload = {
|
||||
key: device?.key || device?.id,
|
||||
recipient_type:
|
||||
userType === "delegate" ? "representative" : "dispenser",
|
||||
recipient_key: selectedUser?.key || selectedUser?.id,
|
||||
};
|
||||
|
||||
await axios.put("/user-pos-machine/0/", payload);
|
||||
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
severity: "success",
|
||||
msg: "دستگاه با موفقیت به کاربر فرعی اختصاص داده شد.",
|
||||
});
|
||||
|
||||
if (onSuccess) {
|
||||
onSuccess();
|
||||
}
|
||||
handleCloseModal();
|
||||
} catch (error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
severity: "error",
|
||||
msg:
|
||||
error?.response?.data?.result ||
|
||||
error?.response?.data?.detail ||
|
||||
"اختصاص دستگاه با خطا مواجه شد.",
|
||||
});
|
||||
} finally {
|
||||
setSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
const selectedUserSubAccessLevels = selectedUser
|
||||
? getSubAccessLevels(selectedUser)
|
||||
: [];
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
direction="column"
|
||||
gap={SPACING.SMALL}
|
||||
width="100%"
|
||||
alignItems="stretch"
|
||||
sx={{ minWidth: 400 }}
|
||||
>
|
||||
<Typography variant="body2">
|
||||
دستگاه انتخاب شده:{" "}
|
||||
{device?.serial ||
|
||||
device?.pos_unique_id ||
|
||||
device?.pos_id ||
|
||||
device?.posId ||
|
||||
"-"}
|
||||
</Typography>
|
||||
<LabelField label="نوع کاربر">
|
||||
<FormControl fullWidth>
|
||||
<RadioGroup
|
||||
row
|
||||
sx={{ gap: 2 }}
|
||||
value={userType}
|
||||
onChange={(e) => setUserType(e.target.value)}
|
||||
>
|
||||
<FormControlLabel
|
||||
value="delegate"
|
||||
control={<Radio />}
|
||||
label="نمایندهها"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value="dispenser"
|
||||
control={<Radio />}
|
||||
label="پخشکنندگان"
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
</LabelField>
|
||||
{loading ? (
|
||||
<Grid container justifyContent="center">
|
||||
<CircularProgress size={24} />
|
||||
</Grid>
|
||||
) : (
|
||||
<Autocomplete
|
||||
disablePortal
|
||||
fullWidth
|
||||
size="small"
|
||||
options={options}
|
||||
value={selectedUser}
|
||||
loading={loading}
|
||||
loadingText="در حال دریافت..."
|
||||
noOptionsText="موردی یافت نشد."
|
||||
onChange={(event, value) => {
|
||||
setSelectedUser(value);
|
||||
setSelectedAccessLevel("");
|
||||
}}
|
||||
isOptionEqualToValue={(option, value) =>
|
||||
option?.key === value?.key || option?.id === value?.id
|
||||
}
|
||||
getOptionLabel={(option) => option?.label || ""}
|
||||
renderOption={(props, option) => {
|
||||
if (!option) return null;
|
||||
return (
|
||||
<li {...props} key={option?.key || option?.id}>
|
||||
<Grid container direction="column">
|
||||
<Typography variant="body2" fontWeight={600}>
|
||||
{option?.label || "-"}
|
||||
</Typography>
|
||||
{option?.city && (
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
{option.city}
|
||||
</Typography>
|
||||
)}
|
||||
</Grid>
|
||||
</li>
|
||||
);
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField
|
||||
{...params}
|
||||
label="انتخاب کاربر"
|
||||
placeholder="نام یا شماره تماس"
|
||||
InputProps={{
|
||||
...params.InputProps,
|
||||
endAdornment: (
|
||||
<>
|
||||
{loading ? (
|
||||
<CircularProgress color="inherit" size={16} />
|
||||
) : null}
|
||||
{params.InputProps.endAdornment}
|
||||
</>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
{fetchError && (
|
||||
<Typography variant="caption" color="error">
|
||||
{fetchError}
|
||||
</Typography>
|
||||
)}
|
||||
{selectedUser && selectedUserSubAccessLevels.length > 0 && (
|
||||
<LabelField label="سطح دسترسی فرعی">
|
||||
<Select
|
||||
fullWidth
|
||||
size="small"
|
||||
value={selectedAccessLevel}
|
||||
onChange={(e) => setSelectedAccessLevel(e.target.value)}
|
||||
displayEmpty
|
||||
>
|
||||
<MenuItem value="">
|
||||
<em>انتخاب سطح دسترسی</em>
|
||||
</MenuItem>
|
||||
{selectedUserSubAccessLevels.map((level) => (
|
||||
<MenuItem key={level.key} value={level.key}>
|
||||
{level.label}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</LabelField>
|
||||
)}
|
||||
<Grid container justifyContent="flex-end" gap={SPACING.SMALL} mt={2}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
onClick={handleCloseModal}
|
||||
disabled={submitting}
|
||||
>
|
||||
انصراف
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={handleSubmit}
|
||||
disabled={!selectedUser || submitting || loading}
|
||||
>
|
||||
{submitting ? "در حال ثبت..." : "ثبت"}
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -1,266 +0,0 @@
|
||||
import { useContext, useState } from "react";
|
||||
import { useDispatch } from "react-redux";
|
||||
import {
|
||||
Box,
|
||||
Grid,
|
||||
IconButton,
|
||||
List,
|
||||
ListItemButton,
|
||||
ListItemIcon,
|
||||
ListItemText,
|
||||
Popover,
|
||||
Typography,
|
||||
Button,
|
||||
} from "@mui/material";
|
||||
import TuneIcon from "@mui/icons-material/Tune";
|
||||
import PersonAddAlt1RoundedIcon from "@mui/icons-material/PersonAddAlt1Rounded";
|
||||
import AddIcon from "@mui/icons-material/Add";
|
||||
import EditIcon from "@mui/icons-material/Edit";
|
||||
import DeleteIcon from "@mui/icons-material/Delete";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import {
|
||||
LOADING_START,
|
||||
LOADING_END,
|
||||
CLOSE_MODAL,
|
||||
OPEN_MODAL,
|
||||
} from "../../../../lib/redux/slices/appSlice";
|
||||
import axios from "axios";
|
||||
import { getFaUserRole } from "../../../../utils/getFaUserRole";
|
||||
import { AssignSubUserModal } from "./AssignSubUserModal";
|
||||
import { AddAccessLevelModal } from "./AddAccessLevelModal";
|
||||
import { EditSubSectionsModal } from "./EditSubSectionsModal";
|
||||
|
||||
export const DeviceOperations = ({
|
||||
device,
|
||||
onSubUserAssigned,
|
||||
fetchApiData,
|
||||
page,
|
||||
}) => {
|
||||
const [anchorEl, setAnchorEl] = useState(null);
|
||||
const dispatch = useDispatch();
|
||||
const [openNotif] = useContext(AppContext);
|
||||
|
||||
const handleOpen = (event) => {
|
||||
setAnchorEl(event.currentTarget);
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setAnchorEl(null);
|
||||
};
|
||||
|
||||
const handleAssignSubUser = () => {
|
||||
handleClose();
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "اختصاص دستگاه به کاربر فرعی",
|
||||
width: "auto",
|
||||
content: (
|
||||
<AssignSubUserModal device={device} onSuccess={onSubUserAssigned} />
|
||||
),
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const handleAddAccessLevel = () => {
|
||||
handleClose();
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "افزودن سطح دسترسی",
|
||||
width: "auto",
|
||||
content: (
|
||||
<AddAccessLevelModal device={device} onSuccess={onSubUserAssigned} />
|
||||
),
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const handleEditSubSections = (accessLevel) => {
|
||||
handleClose();
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "ویرایش زیربخشهای سطح دسترسی",
|
||||
width: "auto",
|
||||
content: (
|
||||
<EditSubSectionsModal
|
||||
accessLevel={accessLevel}
|
||||
device={device}
|
||||
onSuccess={() => fetchApiData(page)}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const handleDeleteAccessLevel = (accessLevel) => {
|
||||
handleClose();
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "حذف سطح دسترسی",
|
||||
size: 320,
|
||||
content: (
|
||||
<Grid container spacing={2}>
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
container
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
mb={2}
|
||||
>
|
||||
<Typography variant="body2" color="default">
|
||||
آیا از حذف سطح دسترسی{" "}
|
||||
{getFaUserRole(accessLevel?.name) || accessLevel?.name} مطمئن
|
||||
هستید؟
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Button
|
||||
fullWidth
|
||||
variant="contained"
|
||||
color="error"
|
||||
onClick={async () => {
|
||||
try {
|
||||
dispatch(LOADING_START());
|
||||
await axios.delete(
|
||||
`/pos-access-level/0/?key=${accessLevel?.key}`
|
||||
);
|
||||
dispatch(LOADING_END());
|
||||
dispatch(CLOSE_MODAL());
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
severity: "success",
|
||||
msg: "سطح دسترسی با موفقیت حذف شد.",
|
||||
});
|
||||
if (fetchApiData) {
|
||||
fetchApiData(page);
|
||||
}
|
||||
} catch (error) {
|
||||
dispatch(LOADING_END());
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
severity: "error",
|
||||
msg:
|
||||
error?.response?.data?.result ||
|
||||
error?.response?.data?.detail ||
|
||||
"حذف سطح دسترسی با خطا مواجه شد.",
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
تایید
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Button
|
||||
fullWidth
|
||||
variant="outlined"
|
||||
onClick={() => dispatch(CLOSE_MODAL())}
|
||||
>
|
||||
انصراف
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
),
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const open = Boolean(anchorEl);
|
||||
const id = open ? "device-operations-popover" : undefined;
|
||||
|
||||
const accessLevels = Array.isArray(device?.accessLevels)
|
||||
? device.accessLevels.filter((level) => !level?.trash)
|
||||
: [];
|
||||
|
||||
return (
|
||||
<>
|
||||
<IconButton
|
||||
aria-describedby={id}
|
||||
color="primary"
|
||||
onClick={handleOpen}
|
||||
size="small"
|
||||
>
|
||||
<TuneIcon fontSize="small" />
|
||||
</IconButton>
|
||||
<Popover
|
||||
id={id}
|
||||
open={open}
|
||||
anchorEl={anchorEl}
|
||||
onClose={handleClose}
|
||||
anchorOrigin={{
|
||||
vertical: "bottom",
|
||||
horizontal: "right",
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: "top",
|
||||
horizontal: "left",
|
||||
}}
|
||||
>
|
||||
<List sx={{ minWidth: 200, p: 0 }}>
|
||||
<ListItemButton onClick={handleAssignSubUser}>
|
||||
<ListItemIcon sx={{ minWidth: 36, color: "success.main" }}>
|
||||
<PersonAddAlt1RoundedIcon fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary="اختصاص به کاربر"
|
||||
primaryTypographyProps={{
|
||||
sx: { color: "success.main", fontSize: "0.875rem" },
|
||||
}}
|
||||
/>
|
||||
</ListItemButton>
|
||||
<ListItemButton onClick={handleAddAccessLevel}>
|
||||
<ListItemIcon sx={{ minWidth: 36, color: "info.main" }}>
|
||||
<AddIcon fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary="افزودن سطح دسترسی"
|
||||
primaryTypographyProps={{
|
||||
sx: { color: "info.main", fontSize: "0.875rem" },
|
||||
}}
|
||||
/>
|
||||
</ListItemButton>
|
||||
{accessLevels.length > 0 && (
|
||||
<>
|
||||
<Box sx={{ pl: 1.5, py: 0.5, bgcolor: "action.hover" }}>
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
مدیریت سطح دسترسی:
|
||||
</Typography>
|
||||
</Box>
|
||||
{accessLevels.map((level, idx) => (
|
||||
<Box key={level?.key || idx} sx={{ pl: 1, pr: 0.5 }}>
|
||||
<Grid
|
||||
container
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
>
|
||||
<Typography variant="body2" sx={{ py: 0.5, pl: 0.5 }}>
|
||||
{getFaUserRole(level?.name) || level?.name || "-"}
|
||||
</Typography>
|
||||
<Grid gap={0.5}>
|
||||
<IconButton
|
||||
size="small"
|
||||
color="primary"
|
||||
onClick={() => handleEditSubSections(level)}
|
||||
>
|
||||
<EditIcon fontSize="small" />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
size="small"
|
||||
color="error"
|
||||
onClick={() => handleDeleteAccessLevel(level)}
|
||||
>
|
||||
<DeleteIcon fontSize="small" />
|
||||
</IconButton>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Box>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</List>
|
||||
</Popover>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,202 +0,0 @@
|
||||
import { useContext, useState } from "react";
|
||||
import { useDispatch } from "react-redux";
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
FormControlLabel,
|
||||
Grid,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import axios from "axios";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { CLOSE_MODAL } from "../../../../lib/redux/slices/appSlice";
|
||||
import { LabelField } from "../../../../components/label-field/LabelField";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { getFaUserRole } from "../../../../utils/getFaUserRole";
|
||||
|
||||
export const EditSubSectionsModal = ({ accessLevel, device, onSuccess }) => {
|
||||
const dispatch = useDispatch();
|
||||
const [openNotif] = useContext(AppContext);
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const [values, setValues] = useState({
|
||||
in_province_sale: accessLevel?.in_province_sale || false,
|
||||
out_province_sale: accessLevel?.out_province_sale || false,
|
||||
cutting: accessLevel?.cutting || false,
|
||||
freezing: accessLevel?.freezing || false,
|
||||
warehouse: accessLevel?.warehouse || false,
|
||||
retail: accessLevel?.retail || false,
|
||||
});
|
||||
|
||||
const handleCloseModal = () => {
|
||||
dispatch(CLOSE_MODAL());
|
||||
};
|
||||
|
||||
const handleChange = (field) => (event) => {
|
||||
setValues((prev) => ({
|
||||
...prev,
|
||||
[field]: event.target.checked,
|
||||
}));
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!accessLevel?.key) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
severity: "error",
|
||||
msg: "شناسه سطح دسترسی یافت نشد. لطفاً دوباره تلاش کنید.",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setSubmitting(true);
|
||||
try {
|
||||
const payload = {
|
||||
key: accessLevel.key,
|
||||
in_province_sale: values.in_province_sale,
|
||||
out_province_sale: values.out_province_sale,
|
||||
cutting: values.cutting,
|
||||
freezing: values.freezing,
|
||||
warehouse: values.warehouse,
|
||||
retail: values.retail,
|
||||
};
|
||||
|
||||
await axios.put("/pos-access-level/0/", payload);
|
||||
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
severity: "success",
|
||||
msg: "زیربخشهای سطح دسترسی با موفقیت ویرایش شد.",
|
||||
});
|
||||
|
||||
if (onSuccess) {
|
||||
onSuccess();
|
||||
}
|
||||
handleCloseModal();
|
||||
} catch (error) {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
severity: "error",
|
||||
msg:
|
||||
error?.response?.data?.result ||
|
||||
error?.response?.data?.detail ||
|
||||
"ویرایش زیربخشها با خطا مواجه شد.",
|
||||
});
|
||||
} finally {
|
||||
setSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
direction="column"
|
||||
gap={SPACING.SMALL}
|
||||
width="100%"
|
||||
alignItems="stretch"
|
||||
sx={{ minWidth: 400 }}
|
||||
>
|
||||
<Typography variant="body2">
|
||||
سطح دسترسی:{" "}
|
||||
{getFaUserRole(accessLevel?.name) || accessLevel?.name || "-"}
|
||||
</Typography>
|
||||
<Typography variant="body2">
|
||||
دستگاه:{" "}
|
||||
{device?.serial ||
|
||||
device?.pos_unique_id ||
|
||||
device?.pos_id ||
|
||||
device?.posId ||
|
||||
"-"}
|
||||
</Typography>
|
||||
<LabelField label="تنظیمات زیربخشها">
|
||||
<Grid container p={1}>
|
||||
<Grid item xs={6}>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={values.in_province_sale}
|
||||
onChange={handleChange("in_province_sale")}
|
||||
/>
|
||||
}
|
||||
label="فروش داخل استان"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={values.out_province_sale}
|
||||
onChange={handleChange("out_province_sale")}
|
||||
/>
|
||||
}
|
||||
label="فروش خارج استان"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={values.cutting}
|
||||
onChange={handleChange("cutting")}
|
||||
/>
|
||||
}
|
||||
label="قطعه بندی"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={values.freezing}
|
||||
onChange={handleChange("freezing")}
|
||||
/>
|
||||
}
|
||||
label="انجماد"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={values.warehouse}
|
||||
onChange={handleChange("warehouse")}
|
||||
/>
|
||||
}
|
||||
label="انبار"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={values.retail}
|
||||
onChange={handleChange("retail")}
|
||||
/>
|
||||
}
|
||||
label="خردهفروشی"
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</LabelField>
|
||||
<Grid container justifyContent="flex-end" gap={SPACING.SMALL} mt={2}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
onClick={handleCloseModal}
|
||||
disabled={submitting}
|
||||
>
|
||||
انصراف
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={handleSubmit}
|
||||
disabled={submitting}
|
||||
>
|
||||
{submitting ? "در حال ثبت..." : "ثبت"}
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -1,284 +0,0 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import {
|
||||
LOADING_END,
|
||||
LOADING_START,
|
||||
} from "../../../../lib/redux/slices/appSlice";
|
||||
import axios from "axios";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { BackButton } from "../../../../components/back-button/BackButton";
|
||||
import { Autocomplete, Button, TextField, Box, Chip } from "@mui/material";
|
||||
import { RiSearchLine } from "react-icons/ri";
|
||||
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import { formatJustDate } from "../../../../utils/formatTime";
|
||||
import { getFaUserRole } from "../../../../utils/getFaUserRole";
|
||||
import { DeviceOperations } from "./DeviceOperations";
|
||||
import { Lock } from "@mui/icons-material";
|
||||
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
|
||||
const GuildPspDevices = () => {
|
||||
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 [brands, setBrands] = useState([]);
|
||||
const [selectedBrand, setSelectedBrand] = useState("");
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const fetchBrands = async () => {
|
||||
try {
|
||||
dispatch(LOADING_START());
|
||||
const response = await axios.get(
|
||||
`/get_all_pos_company/?role=${getRoleFromUrl()}${
|
||||
checkPathStartsWith("slaughter") || checkPathStartsWith("steward")
|
||||
? `&role_key=${selectedSubUser?.key}`
|
||||
: ""
|
||||
}`
|
||||
);
|
||||
setBrands(response.data);
|
||||
dispatch(LOADING_END());
|
||||
} catch (error) {
|
||||
console.error("Error fetching brands:", error);
|
||||
dispatch(LOADING_END());
|
||||
}
|
||||
};
|
||||
|
||||
const canDoAction = (item) => {
|
||||
if (item?.owner?.role?.includes("KillHouse")) {
|
||||
return getRoleFromUrl() === "KillHouse";
|
||||
}
|
||||
if (item?.owner?.includes("Steward")) {
|
||||
return getRoleFromUrl() === "Steward";
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const fetchApiData = async (page) => {
|
||||
try {
|
||||
dispatch(LOADING_START());
|
||||
let url = `/user-pos-machine/?search=filter&value=${textValue}&role=${getRoleFromUrl()}${
|
||||
checkPathStartsWith("slaughter") || checkPathStartsWith("steward")
|
||||
? `&role_key=${selectedSubUser?.key}`
|
||||
: ""
|
||||
}&page=${page}&page_size=${perPage}`;
|
||||
if (selectedBrand) {
|
||||
url += `&company=${selectedBrand}`;
|
||||
}
|
||||
const response = await axios.get(url);
|
||||
|
||||
setData(response.data?.results || []);
|
||||
setTotalRows(response.data?.count || 0);
|
||||
} catch (error) {
|
||||
console.error("Error fetching devices:", error);
|
||||
} finally {
|
||||
dispatch(LOADING_END());
|
||||
}
|
||||
};
|
||||
|
||||
const handlePageChange = (page) => {
|
||||
fetchApiData(page);
|
||||
setPage(page);
|
||||
};
|
||||
|
||||
const handlePerRowsChange = (perRows) => {
|
||||
setPerPage(perRows);
|
||||
setPage(1);
|
||||
};
|
||||
|
||||
const handleTextChange = (event) => {
|
||||
setTextValue(event.target.value);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const d = data?.map((item, i) => {
|
||||
const owner = item?.owner || {};
|
||||
const posCompany = item?.posCompany || {};
|
||||
|
||||
// Format recipient information
|
||||
const recipientDisplay = item?.recipient
|
||||
? `${item?.recipient?.firstName || ""} ${
|
||||
item?.recipient?.lastName || ""
|
||||
}`.trim() +
|
||||
(item?.recipient?.mobile
|
||||
? ` (${item?.recipient?.mobile} - ${
|
||||
item?.recipient?.agentType === "dispenser"
|
||||
? "توزیع کننده"
|
||||
: "نماینده"
|
||||
})`
|
||||
: "")
|
||||
: "-";
|
||||
|
||||
// Format access_levels to display as chips only (filter out trash items)
|
||||
const activeAccessLevels = Array.isArray(item?.accessLevels)
|
||||
? item.accessLevels.filter((level) => !level?.trash)
|
||||
: [];
|
||||
const accessLevelsDisplay =
|
||||
activeAccessLevels.length > 0 ? (
|
||||
<Grid container gap={0.5} flexWrap="wrap">
|
||||
{activeAccessLevels.map((level, idx) => (
|
||||
<Chip
|
||||
key={level?.key || idx}
|
||||
label={getFaUserRole(level?.name) || level?.name || "-"}
|
||||
size="small"
|
||||
/>
|
||||
))}
|
||||
</Grid>
|
||||
) : (
|
||||
"-"
|
||||
);
|
||||
|
||||
return [
|
||||
page === 1 ? i + 1 : i + perPage * (page - 1) + 1,
|
||||
posCompany?.name || "-",
|
||||
item?.serial ?? "-",
|
||||
item?.receiverNumber ?? "-",
|
||||
item?.terminalNumber ?? "-",
|
||||
item?.password ?? "-",
|
||||
item?.posUniqueId || item?.posId || "-",
|
||||
owner?.fullname ? `${owner?.fullname} (${owner?.mobile ?? "-"})` : "-",
|
||||
owner?.nationalId || owner?.nationalCode || "-",
|
||||
item?.createDate ? formatJustDate(item?.createDate) : "-",
|
||||
accessLevelsDisplay,
|
||||
recipientDisplay,
|
||||
item?.active ? "فعال" : "غیرفعال",
|
||||
canDoAction(item) ? (
|
||||
<DeviceOperations
|
||||
key={item?.id || item?.key || `device-${i}`}
|
||||
device={item}
|
||||
/>
|
||||
) : (
|
||||
<Lock sx={{ fontSize: 20, mt: 1, color: "gray" }} />
|
||||
),
|
||||
];
|
||||
});
|
||||
|
||||
setTableData(d);
|
||||
}, [data, page, perPage]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchBrands();
|
||||
}, [dispatch, selectedSubUser?.key]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchApiData(page);
|
||||
}, [selectedBrand, perPage, selectedSubUser?.key]);
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
fetchApiData(1);
|
||||
};
|
||||
|
||||
const tableTitle = (
|
||||
<Grid
|
||||
container
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
gap={2}
|
||||
mb={1}
|
||||
padding={2}
|
||||
width="100%"
|
||||
>
|
||||
<Grid
|
||||
container
|
||||
width="100%"
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
gap={SPACING.SMALL}
|
||||
>
|
||||
<Grid
|
||||
container
|
||||
alignItems="center"
|
||||
gap={SPACING.SMALL}
|
||||
xs={12}
|
||||
md="auto"
|
||||
>
|
||||
<Autocomplete
|
||||
size="small"
|
||||
style={{ minWidth: 210 }}
|
||||
disablePortal
|
||||
id="brand"
|
||||
options={
|
||||
Array.isArray(brands)
|
||||
? brands.map((i) => {
|
||||
return {
|
||||
data: i,
|
||||
label: `${i?.name || ""}`,
|
||||
};
|
||||
})
|
||||
: []
|
||||
}
|
||||
onChange={(event, value) => {
|
||||
setSelectedBrand(value?.data?.key);
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField fullWidth {...params} label="انتخاب برند دستگاه" />
|
||||
)}
|
||||
/>
|
||||
|
||||
<Grid container alignItems="center" gap={SPACING.SMALL}>
|
||||
<TextField
|
||||
size="small"
|
||||
autoComplete="off"
|
||||
label="جستجو"
|
||||
variant="outlined"
|
||||
style={{ width: 250 }}
|
||||
value={textValue}
|
||||
onChange={handleTextChange}
|
||||
/>
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
onClick={handleSubmit}
|
||||
endIcon={<RiSearchLine />}
|
||||
>
|
||||
جستجو
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
|
||||
return (
|
||||
<Box display="flex" justifyContent="center">
|
||||
<Grid container xs={12} lg={10}>
|
||||
<BackButton />
|
||||
{tableTitle}
|
||||
<ResponsiveTable
|
||||
data={tableData}
|
||||
columns={[
|
||||
"ردیف",
|
||||
"برند دستگاه",
|
||||
"شماره سریال",
|
||||
"شماره پذیرنده",
|
||||
"شماره ترمینال",
|
||||
"کلمه عبور امنیتی",
|
||||
"کلید پوز",
|
||||
"مالک",
|
||||
"کدملی",
|
||||
"تاریخ ایجاد",
|
||||
"سطوح دسترسی",
|
||||
"تحویل گیرنده",
|
||||
"فعال / غیرفعال",
|
||||
"عملیات",
|
||||
]}
|
||||
handlePageChange={handlePageChange}
|
||||
totalRows={totalRows}
|
||||
page={page}
|
||||
perPage={perPage}
|
||||
handlePerRowsChange={handlePerRowsChange}
|
||||
title="مدیریت دستگاه ها"
|
||||
/>
|
||||
</Grid>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default GuildPspDevices;
|
||||
@@ -7,7 +7,7 @@ export const guildGetInventoryAllocatedService = createAsyncThunk(
|
||||
async (d, { dispatch }) => {
|
||||
dispatch(LOADING_START());
|
||||
const { data, status } = await axios.get("steward-allocation/", {
|
||||
params: { date: d.date, steward: true, role_key: d.role_key || "" },
|
||||
params: { date: d.date, steward: true },
|
||||
});
|
||||
dispatch(LOADING_END());
|
||||
return { data, status };
|
||||
|
||||
@@ -7,7 +7,7 @@ export const guildGetInventoryStockService = createAsyncThunk(
|
||||
async (d, { dispatch }) => {
|
||||
dispatch(LOADING_START());
|
||||
const { data, status } = await axios.get("steward_warehouse/", {
|
||||
params: { date: d.date, role_key: d.role_key || "" },
|
||||
params: { date: d.date },
|
||||
});
|
||||
dispatch(LOADING_END());
|
||||
return { data, status };
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
import { createAsyncThunk } from "@reduxjs/toolkit";
|
||||
import axios from "axios";
|
||||
import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice";
|
||||
import { getRoleFromUrl } from "../../../utils/getRoleFromUrl";
|
||||
|
||||
export const guildSalesInfoDashboardService = createAsyncThunk(
|
||||
"GUILD_SALES_INFO_DASHBOARD_SERVICE",
|
||||
async (d, { dispatch }) => {
|
||||
dispatch(LOADING_START());
|
||||
try {
|
||||
const { data, status } = await axios.get("guild-sales-info-dashboard/", {
|
||||
params: {
|
||||
role: d.role || getRoleFromUrl(),
|
||||
role_key: d.role_key || "",
|
||||
},
|
||||
});
|
||||
dispatch(LOADING_END());
|
||||
return { data, status };
|
||||
} catch (e) {
|
||||
dispatch(LOADING_END());
|
||||
return { error: e.response?.data?.result };
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -1,15 +0,0 @@
|
||||
import { createAsyncThunk } from "@reduxjs/toolkit";
|
||||
import axios from "axios";
|
||||
import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice";
|
||||
|
||||
export const senfGetAllocationDashboardService = createAsyncThunk(
|
||||
"SENF_GET_ALLOCATION_DASHBOARD_SERVICE",
|
||||
async (d, { dispatch }) => {
|
||||
dispatch(LOADING_START());
|
||||
const { data, status } = await axios.get("guild-allocation-dashbord/", {
|
||||
params: d,
|
||||
});
|
||||
dispatch(LOADING_END());
|
||||
return { data, status };
|
||||
}
|
||||
);
|
||||
@@ -1,21 +1,13 @@
|
||||
import { createAsyncThunk } from "@reduxjs/toolkit";
|
||||
import axios from "axios";
|
||||
import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice";
|
||||
import { getRoleFromUrl } from "../../../utils/getRoleFromUrl";
|
||||
|
||||
export const senfGetInventoryAllocatedService = createAsyncThunk(
|
||||
"SENF_GET_INVENTORY_ALLOCATED_SERVICE",
|
||||
async (d, { dispatch }) => {
|
||||
dispatch(LOADING_START());
|
||||
const { data, status } = await axios.get("steward-allocation/", {
|
||||
params: {
|
||||
date1: d.date1,
|
||||
date2: d.date2,
|
||||
type: d.type || "",
|
||||
role_key: d.role_key || "",
|
||||
role: getRoleFromUrl(),
|
||||
search: d.search,
|
||||
},
|
||||
params: { date: d.date, guild: true },
|
||||
});
|
||||
dispatch(LOADING_END());
|
||||
return { data, status };
|
||||
|
||||
@@ -7,7 +7,7 @@ export const senfGetInventoryStockService = createAsyncThunk(
|
||||
async (d, { dispatch }) => {
|
||||
dispatch(LOADING_START());
|
||||
const { data, status } = await axios.get("guilds_warehouse/", {
|
||||
params: d,
|
||||
params: { date: d.date },
|
||||
});
|
||||
dispatch(LOADING_END());
|
||||
return { data, status };
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { createAsyncThunk } from "@reduxjs/toolkit";
|
||||
import { LOADING_END, LOADING_START } from "../../../lib/redux/slices/appSlice";
|
||||
import axios from "axios";
|
||||
import { getRoleFromUrl } from "../../../utils/getRoleFromUrl";
|
||||
|
||||
export const stawardGetOutDashboardService = createAsyncThunk(
|
||||
"STEWARD-GET-OUT_DASHBOARD_SERVICE",
|
||||
@@ -10,7 +9,6 @@ export const stawardGetOutDashboardService = createAsyncThunk(
|
||||
const { data, status } = await axios.get("steward_free_bar_dashboard", {
|
||||
params: {
|
||||
...d,
|
||||
role: getRoleFromUrl(),
|
||||
},
|
||||
});
|
||||
dispatch(LOADING_END());
|
||||
|
||||
@@ -7,12 +7,9 @@ export const stewardGetOutSellService = createAsyncThunk(
|
||||
"STEWRD_GET_OUT_SELL_SERVICE",
|
||||
async (d, { dispatch }) => {
|
||||
dispatch(LOADING_START());
|
||||
const { data, status } = await axios.get("roles-products", {
|
||||
params: {
|
||||
role: getRoleFromUrl(),
|
||||
...d,
|
||||
},
|
||||
});
|
||||
const { data, status } = await axios.get(
|
||||
"roles-products/?role=" + getRoleFromUrl()
|
||||
);
|
||||
dispatch(LOADING_END());
|
||||
return { data, status };
|
||||
}
|
||||
|
||||
@@ -5,14 +5,10 @@ import { createAsyncThunk } from "@reduxjs/toolkit";
|
||||
|
||||
export const stewardSellOutGetBuyers = createAsyncThunk(
|
||||
"STEWARD_GET_BUYERS_SELL_OUT",
|
||||
async (d, { dispatch }) => {
|
||||
async (id, { dispatch }) => {
|
||||
dispatch(LOADING_START());
|
||||
const { data, status } = await axios.get("out-province-carcasses-buyer/", {
|
||||
params: {
|
||||
role: getRoleFromUrl(),
|
||||
role_key: d?.role_key || "",
|
||||
mobile: d?.mobile,
|
||||
},
|
||||
params: { role: getRoleFromUrl() },
|
||||
});
|
||||
dispatch(LOADING_END());
|
||||
return { data, status };
|
||||
|
||||
@@ -14,7 +14,6 @@ export const stewardSellOutGetDashboard = createAsyncThunk(
|
||||
date1: d.selectedDate1,
|
||||
date2: d.selectedDate2,
|
||||
role: getRoleFromUrl(),
|
||||
role_key: d.role_key || "",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
@@ -57,7 +57,7 @@ export const ProvinceJahadBranDistributionsAllocation = ({ product }) => {
|
||||
|
||||
return (
|
||||
<Grid container xs={12} justifyContent="center" alignItems="center" gap={2}>
|
||||
<Grid container mt={2} mb={4} isDashboard xs={12}>
|
||||
<Grid container mt={2} mb={4} isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -176,7 +176,7 @@ export const ProvinceJahadBranDistributionsPolicy = ({ product }) => {
|
||||
return (
|
||||
<Grid container xs={12} justifyContent="center" alignItems="center" gap={2}>
|
||||
{getRoleFromUrl() === "LiveStockProvinceJahad" && (
|
||||
<Grid container mt={2} mb={4} isDashboard xs={12}>
|
||||
<Grid container mt={2} mb={4} isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -211,7 +211,7 @@ export const ProvinceJahadHerds = () => {
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
|
||||
<Grid container mt={2} mb={4} isDashboard xs={12}>
|
||||
<Grid container mt={2} mb={4} isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -184,7 +184,7 @@ export const ProvinceJahadRanchers = () => {
|
||||
</a>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
<Grid container mt={2} mb={4} isDashboard xs={12}>
|
||||
<Grid container mt={2} mb={4} isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -354,7 +354,7 @@ export const ProvinceJahadTransactions = ({ product }) => {
|
||||
</a>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
<Grid container mt={2} mb={4} isDashboard xs={12}>
|
||||
<Grid container mt={2} mb={4} isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,45 +0,0 @@
|
||||
import React from "react";
|
||||
import {
|
||||
Button,
|
||||
Typography,
|
||||
ListItem,
|
||||
ListItemIcon,
|
||||
ListItemText,
|
||||
} from "@mui/material";
|
||||
import { Grid } from "../../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../../data/spacing";
|
||||
import { DialogAlert } from "../../../../../components/dialog-alert/DialogAlert";
|
||||
import { Done } from "@mui/icons-material";
|
||||
|
||||
export const ConfirmationDialog = ({ isAccepted, onAccept, onReject }) => {
|
||||
return (
|
||||
<Grid item pb={2} mt={2}>
|
||||
<DialogAlert
|
||||
title="تعهد نامه"
|
||||
content={
|
||||
<>
|
||||
<ListItem>
|
||||
<ListItemIcon>
|
||||
<Done />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="لطفا صحت اطلاعات وارد شده را بررسی نمایید. پس از تکمیل و ثبت درخواست، یک کد احراز هویت از طریق پیامک برای صنف یا مباشر به شماره تلفن اعلامی ارسال میگردد." />
|
||||
</ListItem>
|
||||
<Typography></Typography>
|
||||
</>
|
||||
}
|
||||
actions={
|
||||
<Grid container gap={SPACING.TINY}>
|
||||
<Button variant="outlined" color="error" onClick={onReject}>
|
||||
رد
|
||||
</Button>
|
||||
<Button variant="contained" color="success" onClick={onAccept}>
|
||||
موافقم
|
||||
</Button>
|
||||
</Grid>
|
||||
}
|
||||
btnTitle="تایید صحت اطلاعات"
|
||||
isAccepted={isAccepted}
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -1,69 +0,0 @@
|
||||
import React from "react";
|
||||
import { Button, Typography, Checkbox, FormControlLabel } from "@mui/material";
|
||||
import { Grid } from "../../../../../components/grid/Grid";
|
||||
|
||||
export const FormActions = ({
|
||||
formik,
|
||||
onClose,
|
||||
showCloseButton,
|
||||
isKillHouse,
|
||||
onSubmit,
|
||||
}) => {
|
||||
if (showCloseButton) {
|
||||
return (
|
||||
<Grid item xs={12} mt={4}>
|
||||
<Button color="primary" fullWidth variant="contained" onClick={onClose}>
|
||||
متوجه شدم
|
||||
</Button>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
|
||||
// For KillHouse: check if area_activity contains "مرغ"
|
||||
const isAreaActivityValid = isKillHouse
|
||||
? formik.values.area_activity && formik.values.area_activity.includes("مرغ")
|
||||
: true;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Grid item xs={12}>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={formik.values.verify_mobile}
|
||||
onChange={formik.handleChange}
|
||||
name="verify_mobile"
|
||||
color="primary"
|
||||
/>
|
||||
}
|
||||
label="احراز شماره موبایل"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Button
|
||||
disabled={
|
||||
formik.errors.isAccepted ||
|
||||
Boolean(formik.errors.national_id) ||
|
||||
!isAreaActivityValid
|
||||
}
|
||||
color="primary"
|
||||
fullWidth
|
||||
variant="contained"
|
||||
onClick={onSubmit}
|
||||
type="button"
|
||||
>
|
||||
ثبت
|
||||
</Button>
|
||||
{isKillHouse && !isAreaActivityValid && (
|
||||
<Typography
|
||||
variant="caption"
|
||||
color="error"
|
||||
sx={{ mt: 1, display: "block" }}
|
||||
>
|
||||
رسته واحد صنفی باید شامل کلمه "مرغ" باشد
|
||||
</Typography>
|
||||
)}
|
||||
</Grid>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,97 +0,0 @@
|
||||
import React from "react";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionSummary,
|
||||
AccordionDetails,
|
||||
Typography,
|
||||
IconButton,
|
||||
} from "@mui/material";
|
||||
import {
|
||||
ExpandMore as ExpandMoreIcon,
|
||||
Delete as DeleteIcon,
|
||||
} from "@mui/icons-material";
|
||||
import { GuildInfoSection } from "./GuildInfoSection";
|
||||
|
||||
export const GuildInfoAccordionItem = ({
|
||||
guildIndex,
|
||||
guildData,
|
||||
guildActive,
|
||||
isAdmin,
|
||||
cities,
|
||||
typeActivities,
|
||||
onDelete,
|
||||
canDelete,
|
||||
guildFormValues,
|
||||
onGuildValuesChange,
|
||||
expanded,
|
||||
onChange,
|
||||
}) => {
|
||||
// Create a formik-like object for this guild's values
|
||||
const guildFormik = {
|
||||
values: guildFormValues || {},
|
||||
setFieldValue: (fieldName, value) => {
|
||||
onGuildValuesChange(guildIndex, fieldName, value);
|
||||
},
|
||||
handleChange: (e) => {
|
||||
onGuildValuesChange(guildIndex, e.target.name, e.target.value);
|
||||
},
|
||||
handleBlur: () => {},
|
||||
errors: {},
|
||||
touched: {},
|
||||
};
|
||||
const getGuildTitle = () => {
|
||||
if (guildData?.guildsName) {
|
||||
return guildData.guildsName;
|
||||
}
|
||||
if (guildData?.title) {
|
||||
return guildData.title;
|
||||
}
|
||||
if (guildFormik.values.guild_name) {
|
||||
return guildFormik.values.guild_name;
|
||||
}
|
||||
return `واحد صنفی ${guildIndex + 1}`;
|
||||
};
|
||||
|
||||
return (
|
||||
<Accordion expanded={expanded} onChange={onChange}>
|
||||
<AccordionSummary
|
||||
expandIcon={<ExpandMoreIcon />}
|
||||
sx={{
|
||||
"& .MuiAccordionSummary-content": {
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Typography variant="h6" sx={{ flexGrow: 1, fontSize: 18 }}>
|
||||
{getGuildTitle()}
|
||||
</Typography>
|
||||
{canDelete && (
|
||||
<IconButton
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onDelete();
|
||||
}}
|
||||
color="error"
|
||||
size="small"
|
||||
sx={{ mr: 1 }}
|
||||
>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<GuildInfoSection
|
||||
formik={guildFormik}
|
||||
guild={guildData}
|
||||
guildActive={guildActive}
|
||||
isAdmin={isAdmin}
|
||||
cities={cities}
|
||||
typeActivities={typeActivities}
|
||||
hideTitle={true}
|
||||
noGridWrapper={true}
|
||||
/>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
);
|
||||
};
|
||||
@@ -1,566 +0,0 @@
|
||||
import React from "react";
|
||||
import {
|
||||
TextField,
|
||||
Typography,
|
||||
RadioGroup,
|
||||
FormControl,
|
||||
Radio,
|
||||
FormControlLabel,
|
||||
Select,
|
||||
MenuItem,
|
||||
InputLabel,
|
||||
Checkbox,
|
||||
} from "@mui/material";
|
||||
import { DatePicker } from "@mui/x-date-pickers";
|
||||
import moment from "moment";
|
||||
import BusinessIcon from "@mui/icons-material/Business";
|
||||
import PublicIcon from "@mui/icons-material/Public";
|
||||
import LocationCityIcon from "@mui/icons-material/LocationCity";
|
||||
import DateRangeIcon from "@mui/icons-material/DateRange";
|
||||
import ConfirmationNumberIcon from "@mui/icons-material/ConfirmationNumber";
|
||||
import AccountBalanceIcon from "@mui/icons-material/AccountBalance";
|
||||
import LocalPostOfficeIcon from "@mui/icons-material/LocalPostOffice";
|
||||
import PhoneIcon from "@mui/icons-material/Phone";
|
||||
import BadgeIcon from "@mui/icons-material/Badge";
|
||||
import CheckCircleIcon from "@mui/icons-material/CheckCircle";
|
||||
import HomeIcon from "@mui/icons-material/Home";
|
||||
import CorporateFareIcon from "@mui/icons-material/CorporateFare";
|
||||
import { Grid } from "../../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../../data/spacing";
|
||||
import { LabelField } from "../../../../../components/label-field/LabelField";
|
||||
import { InfoBox } from "./InfoBox";
|
||||
import { STATUS_VALUES } from "../constants";
|
||||
import {
|
||||
convertPersianToGregorian,
|
||||
convertGregorianToPersian,
|
||||
} from "../utils/dateUtils";
|
||||
|
||||
export const GuildInfoSection = ({
|
||||
formik,
|
||||
guild,
|
||||
guildActive,
|
||||
isAdmin,
|
||||
cities,
|
||||
typeActivities,
|
||||
hideTitle = false,
|
||||
noGridWrapper = false,
|
||||
}) => {
|
||||
const getForeignerDisplay = (isForeigner) => {
|
||||
if (isForeigner === STATUS_VALUES.NO || isForeigner === false)
|
||||
return STATUS_VALUES.NO;
|
||||
if (isForeigner === STATUS_VALUES.YES || isForeigner === true)
|
||||
return STATUS_VALUES.YES;
|
||||
return "-";
|
||||
};
|
||||
|
||||
const getLicenseExpireDateDisplay = () => {
|
||||
return formik.values.license_expire_date || "-";
|
||||
};
|
||||
|
||||
const getActiveStatusDisplay = () => {
|
||||
const activeValue =
|
||||
formik.values.active !== null
|
||||
? formik.values.active
|
||||
: guild?.active === true || guildActive === true;
|
||||
return activeValue === true ? "فعال" : "غیر فعال";
|
||||
};
|
||||
|
||||
const content = (
|
||||
<Grid container gap={SPACING.TINY} direction="column">
|
||||
{!hideTitle && (
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="h6" gutterBottom>
|
||||
اطلاعات صنفی
|
||||
</Typography>
|
||||
</Grid>
|
||||
)}
|
||||
<Grid container xs={12}>
|
||||
<Grid
|
||||
container
|
||||
direction="column"
|
||||
xs={12}
|
||||
md={6}
|
||||
px={SPACING.TINY}
|
||||
gap={SPACING.TINY}
|
||||
>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="نام واحد"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="guild_name"
|
||||
name="guild_name"
|
||||
value={formik.values.guild_name}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={BusinessIcon}
|
||||
label="نام واحد"
|
||||
value={formik.values.guild_name}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<FormControl fullWidth>
|
||||
<InputLabel id="area-activity-select-label">
|
||||
رسته واحد صنفی
|
||||
</InputLabel>
|
||||
<Select
|
||||
labelId="area-activity-select-label"
|
||||
id="area_activity"
|
||||
name="area_activity"
|
||||
value={formik.values.area_activity || ""}
|
||||
label="رسته واحد صنفی"
|
||||
onChange={(e) => {
|
||||
formik.setFieldValue("area_activity", e.target.value);
|
||||
}}
|
||||
onBlur={formik.handleBlur}
|
||||
>
|
||||
{typeActivities.map((activity) => (
|
||||
<MenuItem key={activity.key} value={activity.title}>
|
||||
{activity.title}
|
||||
</MenuItem>
|
||||
))}
|
||||
{/* Show current value if it doesn't exist in options */}
|
||||
{formik.values.area_activity &&
|
||||
!typeActivities.some(
|
||||
(activity) =>
|
||||
activity.title === formik.values.area_activity
|
||||
) && (
|
||||
<MenuItem
|
||||
key="current-value"
|
||||
value={formik.values.area_activity}
|
||||
>
|
||||
{formik.values.area_activity}
|
||||
</MenuItem>
|
||||
)}
|
||||
</Select>
|
||||
</FormControl>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={BusinessIcon}
|
||||
label="رسته واحد صنفی"
|
||||
value={formik.values.area_activity}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="استان"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="state"
|
||||
name="state"
|
||||
value={formik.values.state}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={PublicIcon}
|
||||
label="استان"
|
||||
value={formik.values.state}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<FormControl fullWidth>
|
||||
<InputLabel id="city-select-label">شهرستان</InputLabel>
|
||||
<Select
|
||||
labelId="city-select-label"
|
||||
id="city"
|
||||
name="city"
|
||||
value={formik.values.city || ""}
|
||||
label="شهرستان"
|
||||
onChange={(e) => {
|
||||
formik.setFieldValue("city", e.target.value);
|
||||
}}
|
||||
onBlur={formik.handleBlur}
|
||||
>
|
||||
{cities.map((city) => (
|
||||
<MenuItem key={city.key} value={city.name}>
|
||||
{city.name}
|
||||
</MenuItem>
|
||||
))}
|
||||
{/* Show current value if it doesn't exist in options */}
|
||||
{formik.values.city &&
|
||||
!cities.some(
|
||||
(city) => city.name === formik.values.city
|
||||
) && (
|
||||
<MenuItem key="current-value" value={formik.values.city}>
|
||||
{formik.values.city}
|
||||
</MenuItem>
|
||||
)}
|
||||
</Select>
|
||||
</FormControl>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={LocationCityIcon}
|
||||
label="شهرستان"
|
||||
value={formik.values.city}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<DatePicker
|
||||
label="تاریخ انقضا مجوز"
|
||||
value={
|
||||
formik.values.license_expire_date
|
||||
? moment(
|
||||
convertPersianToGregorian(
|
||||
formik.values.license_expire_date
|
||||
)
|
||||
)
|
||||
: null
|
||||
}
|
||||
onChange={(newValue) => {
|
||||
if (newValue) {
|
||||
const gregorianDate = moment(newValue).format("YYYY-MM-DD");
|
||||
const persianDate =
|
||||
convertGregorianToPersian(gregorianDate);
|
||||
formik.setFieldValue("license_expire_date", persianDate);
|
||||
} else {
|
||||
formik.setFieldValue("license_expire_date", "");
|
||||
}
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField {...params} fullWidth variant="outlined" />
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={DateRangeIcon}
|
||||
label="تاریخ انقضا مجوز"
|
||||
value={getLicenseExpireDateDisplay()}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="شماره مجوز"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="license_number"
|
||||
name="license_number"
|
||||
value={formik.values.license_number}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={ConfirmationNumberIcon}
|
||||
label="شماره مجوز"
|
||||
value={formik.values.license_number}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="نام اتحادیه"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="union_name"
|
||||
name="union_name"
|
||||
value={formik.values.union_name}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={AccountBalanceIcon}
|
||||
label="نام اتحادیه"
|
||||
value={formik.values.union_name}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<LabelField label="وضعیت">
|
||||
<FormControl fullWidth>
|
||||
<RadioGroup
|
||||
row
|
||||
name="active"
|
||||
value={
|
||||
formik.values.active === true
|
||||
? "true"
|
||||
: formik.values.active === false
|
||||
? "false"
|
||||
: ""
|
||||
}
|
||||
onChange={(e) => {
|
||||
formik.setFieldValue(
|
||||
"active",
|
||||
e.target.value === "true" ? true : false
|
||||
);
|
||||
}}
|
||||
sx={{ justifyContent: "space-around" }}
|
||||
>
|
||||
<FormControlLabel
|
||||
value="true"
|
||||
control={<Radio />}
|
||||
label="فعال"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value="false"
|
||||
control={<Radio />}
|
||||
label="غیر فعال"
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
</LabelField>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={CheckCircleIcon}
|
||||
label="وضعیت"
|
||||
value={getActiveStatusDisplay()}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid
|
||||
container
|
||||
xs={12}
|
||||
md={6}
|
||||
px={SPACING.TINY}
|
||||
direction="column"
|
||||
gap={SPACING.TINY}
|
||||
>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="کد پستی"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="postal_code"
|
||||
name="postal_code"
|
||||
value={formik.values.postal_code}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={LocalPostOfficeIcon}
|
||||
label="کد پستی"
|
||||
value={formik.values.postal_code}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="شماره تلفن"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="phone_number"
|
||||
name="phone_number"
|
||||
value={formik.values.phone_number}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={PhoneIcon}
|
||||
label="شماره تلفن"
|
||||
value={formik.values.phone_number}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<LabelField label="آیا اتباع است؟">
|
||||
<FormControl fullWidth>
|
||||
<RadioGroup
|
||||
row
|
||||
name="is_foreigner"
|
||||
value={
|
||||
formik.values.is_foreigner === "بلی" ||
|
||||
formik.values.is_foreigner === true
|
||||
? "بلی"
|
||||
: formik.values.is_foreigner === "خیر" ||
|
||||
formik.values.is_foreigner === false
|
||||
? "خیر"
|
||||
: ""
|
||||
}
|
||||
onChange={(e) => {
|
||||
formik.setFieldValue(
|
||||
"is_foreigner",
|
||||
e.target.value === "بلی" ? "بلی" : "خیر"
|
||||
);
|
||||
}}
|
||||
sx={{ justifyContent: "space-around" }}
|
||||
>
|
||||
<FormControlLabel
|
||||
value="بلی"
|
||||
control={<Radio />}
|
||||
label="بلی"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value="خیر"
|
||||
control={<Radio />}
|
||||
label="خیر"
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
</LabelField>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={PublicIcon}
|
||||
label="آیا اتباع است؟"
|
||||
value={getForeignerDisplay(formik.values.is_foreigner)}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="نام شرکت"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="corporation_name"
|
||||
name="corporation_name"
|
||||
value={formik.values.corporation_name}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={CorporateFareIcon}
|
||||
label="نام شرکت"
|
||||
value={formik.values.corporation_name}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="شناسه ملی شرکت"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="guild_national_id"
|
||||
name="guild_national_id"
|
||||
value={formik.values.guild_national_id}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={BadgeIcon}
|
||||
label="شناسه ملی شرکت"
|
||||
value={formik.values.guild_national_id}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="وضعیت مجوز"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="license_status"
|
||||
name="license_status"
|
||||
value={formik.values.license_status}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={CheckCircleIcon}
|
||||
label="وضعیت مجوز"
|
||||
value={formik.values.license_status}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="آدرس"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
multiline
|
||||
rows={3}
|
||||
id="address"
|
||||
name="address"
|
||||
value={formik.values.address}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={HomeIcon}
|
||||
label="آدرس"
|
||||
value={formik.values.address}
|
||||
iconSx={{ mt: 0.5 }}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12} sx={{ display: "flex", mt: 2, pl: 2, mb: 2 }}>
|
||||
{isAdmin ? (
|
||||
<>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={formik.values.steward || false}
|
||||
onChange={(e) =>
|
||||
formik.setFieldValue("steward", e.target.checked)
|
||||
}
|
||||
name="steward"
|
||||
color="primary"
|
||||
/>
|
||||
}
|
||||
label="مباشر"
|
||||
/>
|
||||
<FormControlLabel
|
||||
sx={{ ml: 3 }}
|
||||
control={
|
||||
<Checkbox
|
||||
checked={formik.values.guild || false}
|
||||
onChange={(e) =>
|
||||
formik.setFieldValue("guild", e.target.checked)
|
||||
}
|
||||
name="guild"
|
||||
color="primary"
|
||||
/>
|
||||
}
|
||||
label="صنف"
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<InfoBox
|
||||
icon={CheckCircleIcon}
|
||||
label="مباشر"
|
||||
value={formik.values.steward ? "بلی" : "خیر"}
|
||||
/>
|
||||
<InfoBox
|
||||
icon={CheckCircleIcon}
|
||||
label="صنف"
|
||||
value={formik.values.guild ? "بلی" : "خیر"}
|
||||
sx={{ ml: 3 }}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
|
||||
if (noGridWrapper) {
|
||||
return <>{content}</>;
|
||||
}
|
||||
|
||||
return (
|
||||
<Grid item xs={12} lg={6} pr={{ xs: 0, md: 2 }} pl={{ xs: 0, md: 3 }}>
|
||||
{content}
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -1,23 +0,0 @@
|
||||
import React from "react";
|
||||
import { Box, Typography } from "@mui/material";
|
||||
|
||||
export const InfoBox = ({ icon: Icon, label, value, iconSx }) => (
|
||||
<Box
|
||||
display="flex"
|
||||
alignItems={iconSx ? "flex-start" : "center"}
|
||||
gap={1}
|
||||
px={1.5}
|
||||
py={0.5}
|
||||
bgcolor="#f5f5f5"
|
||||
borderRadius={1}
|
||||
>
|
||||
<Icon color="action" sx={iconSx} />
|
||||
<Box>
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
{label}
|
||||
</Typography>
|
||||
<Typography variant="body1">{value || "-"}</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
import React from "react";
|
||||
import { TextField, Button } from "@mui/material";
|
||||
|
||||
export const InquiryForm = ({
|
||||
inquiryNationalCode,
|
||||
setInquiryNationalCode,
|
||||
onInquiry,
|
||||
isAdmin,
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<TextField
|
||||
label="کد ملی برای استعلام"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
value={inquiryNationalCode}
|
||||
onChange={(e) => setInquiryNationalCode(e.target.value)}
|
||||
placeholder={
|
||||
isAdmin ? "کد ملی را وارد کنید" : "کد ملی 10 رقمی را وارد کنید"
|
||||
}
|
||||
inputProps={isAdmin ? {} : { maxLength: 10 }}
|
||||
/>
|
||||
<Button
|
||||
color="primary"
|
||||
fullWidth
|
||||
variant="contained"
|
||||
onClick={onInquiry}
|
||||
disabled={!isAdmin && inquiryNationalCode.length !== 10}
|
||||
>
|
||||
استعلام
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,369 +0,0 @@
|
||||
import React from "react";
|
||||
import {
|
||||
TextField,
|
||||
Typography,
|
||||
RadioGroup,
|
||||
FormControl,
|
||||
Radio,
|
||||
FormControlLabel,
|
||||
} from "@mui/material";
|
||||
import { DatePicker } from "@mui/x-date-pickers";
|
||||
import moment from "moment";
|
||||
import PersonIcon from "@mui/icons-material/Person";
|
||||
import PhoneIcon from "@mui/icons-material/Phone";
|
||||
import BadgeIcon from "@mui/icons-material/Badge";
|
||||
import CakeIcon from "@mui/icons-material/Cake";
|
||||
import FaceIcon from "@mui/icons-material/Face";
|
||||
import LocationCityIcon from "@mui/icons-material/LocationCity";
|
||||
import FavoriteIcon from "@mui/icons-material/Favorite";
|
||||
import { Grid } from "../../../../../components/grid/Grid";
|
||||
import { SPACING } from "../../../../../data/spacing";
|
||||
import { LabelField } from "../../../../../components/label-field/LabelField";
|
||||
import { InfoBox } from "./InfoBox";
|
||||
import { GENDER_VALUES, ALIVE_STATUS } from "../constants";
|
||||
import {
|
||||
convertPersianToGregorian,
|
||||
convertGregorianToPersian,
|
||||
} from "../utils/dateUtils";
|
||||
|
||||
export const PersonalInfoSection = ({
|
||||
formik,
|
||||
guild,
|
||||
hasInquiry,
|
||||
isAdmin,
|
||||
isSuperAdmin,
|
||||
isKillHouse,
|
||||
}) => {
|
||||
const getGenderDisplay = (gender) => {
|
||||
if (gender === "True" || gender === true) return GENDER_VALUES.MALE;
|
||||
if (gender === "False" || gender === false) return GENDER_VALUES.FEMALE;
|
||||
return "-";
|
||||
};
|
||||
|
||||
const getAliveStatusDisplay = (isAlive) => {
|
||||
if (isAlive === ALIVE_STATUS.YES || isAlive === true)
|
||||
return ALIVE_STATUS.YES;
|
||||
if (isAlive === ALIVE_STATUS.NO || isAlive === false)
|
||||
return ALIVE_STATUS.NO;
|
||||
return "-";
|
||||
};
|
||||
|
||||
const getBirthDateDisplay = () => {
|
||||
return formik.values.birth_date || "-";
|
||||
};
|
||||
|
||||
return (
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
lg={6}
|
||||
pl={{ xs: 0, md: 2 }}
|
||||
pr={{ xs: 0, md: 3 }}
|
||||
mb={2}
|
||||
>
|
||||
<Grid container direction="column" gap={SPACING.SMALL}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="h6" gutterBottom>
|
||||
اطلاعات شخصی
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid container xs={12}>
|
||||
<Grid container xs={12} md={6} gap={SPACING.TINY} px={SPACING.TINY}>
|
||||
<Grid item xs={12}>
|
||||
{guild || isAdmin ? (
|
||||
<TextField
|
||||
label="کد ملی"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="national_id"
|
||||
name="national_id"
|
||||
value={formik.values.national_id}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
error={Boolean(formik.errors.national_id)}
|
||||
helperText={formik.errors.national_id}
|
||||
inputProps={{ maxLength: 10 }}
|
||||
disabled={!isAdmin || isKillHouse}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={BadgeIcon}
|
||||
label="کد ملی"
|
||||
value={formik.values.national_id}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="نام"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="first_name"
|
||||
name="first_name"
|
||||
value={formik.values.first_name}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={PersonIcon}
|
||||
label="نام"
|
||||
value={formik.values.first_name}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="نام خانوادگی"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="last_name"
|
||||
name="last_name"
|
||||
value={formik.values.last_name}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={PersonIcon}
|
||||
label="نام خانوادگی"
|
||||
value={formik.values.last_name}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="شماره شناسنامه"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="national_code"
|
||||
name="national_code"
|
||||
value={formik.values.national_code}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={BadgeIcon}
|
||||
label="شماره شناسنامه"
|
||||
value={formik.values.national_code}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<LabelField label="در قید حیات">
|
||||
<FormControl fullWidth>
|
||||
<RadioGroup
|
||||
row
|
||||
name="is_alive"
|
||||
value={
|
||||
formik.values.is_alive === "بلی" ||
|
||||
formik.values.is_alive === true
|
||||
? "بلی"
|
||||
: formik.values.is_alive === "خیر" ||
|
||||
formik.values.is_alive === false
|
||||
? "خیر"
|
||||
: ""
|
||||
}
|
||||
onChange={(e) => {
|
||||
formik.setFieldValue(
|
||||
"is_alive",
|
||||
e.target.value === "بلی" ? "بلی" : "خیر"
|
||||
);
|
||||
}}
|
||||
sx={{ justifyContent: "space-around" }}
|
||||
>
|
||||
<FormControlLabel
|
||||
value="بلی"
|
||||
control={<Radio />}
|
||||
label="بلی"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value="خیر"
|
||||
control={<Radio />}
|
||||
label="خیر"
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
</LabelField>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={FavoriteIcon}
|
||||
label="در قید حیات"
|
||||
value={getAliveStatusDisplay(formik.values.is_alive)}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid
|
||||
container
|
||||
xs={12}
|
||||
md={6}
|
||||
gap={SPACING.TINY}
|
||||
px={SPACING.TINY}
|
||||
mt={{ xs: 1, md: 0 }}
|
||||
>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<DatePicker
|
||||
label="تاریخ تولد"
|
||||
value={
|
||||
formik.values.birth_date
|
||||
? moment(
|
||||
convertPersianToGregorian(formik.values.birth_date)
|
||||
)
|
||||
: null
|
||||
}
|
||||
onChange={(newValue) => {
|
||||
if (newValue) {
|
||||
const gregorianDate =
|
||||
moment(newValue).format("YYYY-MM-DD");
|
||||
const persianDate =
|
||||
convertGregorianToPersian(gregorianDate);
|
||||
formik.setFieldValue("birth_date", persianDate);
|
||||
} else {
|
||||
formik.setFieldValue("birth_date", "");
|
||||
}
|
||||
}}
|
||||
renderInput={(params) => (
|
||||
<TextField {...params} fullWidth variant="outlined" />
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={CakeIcon}
|
||||
label="تاریخ تولد"
|
||||
value={getBirthDateDisplay()}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="نام پدر"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="father_name"
|
||||
name="father_name"
|
||||
value={formik.values.father_name}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={PersonIcon}
|
||||
label="نام پدر"
|
||||
value={formik.values.father_name}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<LabelField label="جنسیت">
|
||||
<FormControl fullWidth>
|
||||
<RadioGroup
|
||||
row
|
||||
name="gender"
|
||||
value={
|
||||
formik.values.gender === "True" ||
|
||||
formik.values.gender === true
|
||||
? "True"
|
||||
: formik.values.gender === "False" ||
|
||||
formik.values.gender === false
|
||||
? "False"
|
||||
: ""
|
||||
}
|
||||
onChange={(e) => {
|
||||
formik.setFieldValue("gender", e.target.value);
|
||||
}}
|
||||
sx={{ justifyContent: "space-around" }}
|
||||
>
|
||||
<FormControlLabel
|
||||
value="True"
|
||||
control={<Radio />}
|
||||
label="مرد"
|
||||
/>
|
||||
<FormControlLabel
|
||||
value="False"
|
||||
control={<Radio />}
|
||||
label="زن"
|
||||
/>
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
</LabelField>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={FaceIcon}
|
||||
label="جنسیت"
|
||||
value={getGenderDisplay(formik.values.gender)}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{isAdmin ? (
|
||||
<TextField
|
||||
label="شهر"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="person_city"
|
||||
name="person_city"
|
||||
value={formik.values.person_city}
|
||||
onChange={formik.handleChange}
|
||||
onBlur={formik.handleBlur}
|
||||
/>
|
||||
) : (
|
||||
<InfoBox
|
||||
icon={LocationCityIcon}
|
||||
label="شهر"
|
||||
value={formik.values.person_city}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12} mt={{ xs: 1, md: 0 }}>
|
||||
{!guild &&
|
||||
hasInquiry &&
|
||||
!isAdmin &&
|
||||
!isSuperAdmin &&
|
||||
!isKillHouse ? (
|
||||
<InfoBox
|
||||
icon={PhoneIcon}
|
||||
label="شماره همراه"
|
||||
value={formik.values.mobile}
|
||||
/>
|
||||
) : isKillHouse &&
|
||||
formik.values.mobile &&
|
||||
/^[0-9]{11}$/.test(formik.values.mobile) ? (
|
||||
<InfoBox
|
||||
icon={PhoneIcon}
|
||||
label="شماره همراه"
|
||||
value={formik.values.mobile}
|
||||
/>
|
||||
) : (
|
||||
<TextField
|
||||
label="شماره همراه"
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
id="mobile"
|
||||
name="mobile"
|
||||
value={formik.values.mobile}
|
||||
onChange={formik.handleChange}
|
||||
error={formik.touched.mobile && Boolean(formik.errors.mobile)}
|
||||
helperText={formik.touched.mobile && formik.errors.mobile}
|
||||
disabled={
|
||||
isKillHouse &&
|
||||
formik.values.mobile &&
|
||||
/^[0-9]{11}$/.test(formik.values.mobile)
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -1,19 +0,0 @@
|
||||
import React from "react";
|
||||
import { Button } from "@mui/material";
|
||||
import { Refresh } from "@mui/icons-material";
|
||||
import { Grid } from "../../../../../components/grid/Grid";
|
||||
|
||||
export const UpdateFromExternalButton = ({ onUpdate, disabled }) => {
|
||||
return (
|
||||
<Grid container xs={12} justifyContent="flex-end">
|
||||
<Button
|
||||
onClick={onUpdate}
|
||||
disabled={disabled}
|
||||
color="primary"
|
||||
size="small"
|
||||
>
|
||||
بروزرسانی از سامانه واحد <Refresh />
|
||||
</Button>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -1,17 +0,0 @@
|
||||
export const STATUS_VALUES = {
|
||||
YES: "بلی",
|
||||
NO: "خیر",
|
||||
TRUE: "True",
|
||||
FALSE: "False",
|
||||
};
|
||||
|
||||
export const GENDER_VALUES = {
|
||||
MALE: "مرد",
|
||||
FEMALE: "زن",
|
||||
};
|
||||
|
||||
export const ALIVE_STATUS = {
|
||||
YES: "بلی",
|
||||
NO: "خیر",
|
||||
};
|
||||
|
||||
@@ -1,232 +0,0 @@
|
||||
import { getRoleFromUrl } from "../../../../../utils/getRoleFromUrl";
|
||||
import { normalizeExternalApiDate, normalizeDatabaseDate } from "./dateUtils";
|
||||
import { formatDateForSubmit } from "./dateUtils";
|
||||
|
||||
export const prepareSubmitData = (
|
||||
values,
|
||||
guild,
|
||||
originalPhoneNumber,
|
||||
hasInquiry
|
||||
) => {
|
||||
const baseData = {
|
||||
national_id: values.national_id,
|
||||
mobile: values.mobile,
|
||||
mobilenumber: values.mobile,
|
||||
steward: !!values.steward,
|
||||
guild: !!values.guild,
|
||||
active_register_code: !!values.verify_mobile,
|
||||
firstName: values.first_name || "",
|
||||
lastName: values.last_name || "",
|
||||
fatherName: values.father_name || "",
|
||||
gender: values.gender || "",
|
||||
identityNo: values.national_code || "",
|
||||
isLive: values.is_alive === "بلی" || values.is_alive === true,
|
||||
birthDate: formatDateForSubmit(
|
||||
values.birth_date || "",
|
||||
hasInquiry === true
|
||||
),
|
||||
city: values.city || "",
|
||||
address: values.address || "",
|
||||
postalcode: values.postal_code || "",
|
||||
licenseNumber: values.license_number || "",
|
||||
licenseExpireDate: formatDateForSubmit(
|
||||
values.license_expire_date || "",
|
||||
hasInquiry === true
|
||||
),
|
||||
licenseIssueDate: formatDateForSubmit(
|
||||
values.license_issue_date || "",
|
||||
hasInquiry === true
|
||||
),
|
||||
licenseType: values.license_type || "",
|
||||
licenseStatus: values.license_status || "",
|
||||
isicname: values.area_activity || "",
|
||||
corporationName: values.corporation_name || "",
|
||||
nationalId: values.guild_national_id || "",
|
||||
unionName: values.union_name || "",
|
||||
phonenumber: values.phone_number || "",
|
||||
hasPartner: values.has_partner === true || values.has_partner === "بلی",
|
||||
isForeigner: values.is_foreigner === true || values.is_foreigner === "بلی",
|
||||
title: values.guild_name || "",
|
||||
role: getRoleFromUrl(),
|
||||
has_inquiry: hasInquiry !== null ? hasInquiry : false,
|
||||
...(values.active !== null && { active: values.active }),
|
||||
};
|
||||
|
||||
if (guild) {
|
||||
baseData.guilds_key = guild.key;
|
||||
if (values.mobile !== originalPhoneNumber) {
|
||||
baseData.mobile = values.mobile;
|
||||
baseData.mobilenumber = values.mobile;
|
||||
}
|
||||
}
|
||||
|
||||
return baseData;
|
||||
};
|
||||
|
||||
export const mapResponseDataToFormFields = (
|
||||
responseData,
|
||||
inquiryNationalCode,
|
||||
formik
|
||||
) => {
|
||||
const isExternalApi = responseData.dbRegister === false;
|
||||
|
||||
// New structure: user is at top level, guilds is an array
|
||||
const userData = responseData.user || {};
|
||||
// For personal info, we use the first guild's data if available, or empty
|
||||
const firstGuild =
|
||||
Array.isArray(responseData.guilds) && responseData.guilds.length > 0
|
||||
? responseData.guilds[0]
|
||||
: {};
|
||||
const guildData = firstGuild || {};
|
||||
const layerTwo = guildData.layerTwo || {};
|
||||
const addressData = firstGuild?.address || guildData.address || {};
|
||||
const provinceData = addressData.province || {};
|
||||
const cityData = addressData.city || {};
|
||||
|
||||
const nationalIdValue = isExternalApi
|
||||
? String(
|
||||
layerTwo.nationalcode || userData.nationalCode || inquiryNationalCode
|
||||
).trim()
|
||||
: String(userData.nationalId || inquiryNationalCode).trim();
|
||||
|
||||
const birthDatePersian = isExternalApi
|
||||
? normalizeExternalApiDate(userData.birthDate || "")
|
||||
: normalizeDatabaseDate(userData.birthday || "");
|
||||
|
||||
const licenseExpireDatePersian = isExternalApi
|
||||
? normalizeExternalApiDate(guildData.licenseExpireDate || "")
|
||||
: normalizeDatabaseDate(firstGuild.licenseExpireDate || "");
|
||||
|
||||
const licenseIssueDatePersian = isExternalApi
|
||||
? normalizeExternalApiDate(layerTwo.licenseIssueDate || "")
|
||||
: normalizeDatabaseDate(responseData.licenseIssueDate || "");
|
||||
|
||||
const genderValue = isExternalApi
|
||||
? userData.gender === true
|
||||
? "True"
|
||||
: userData.gender === false
|
||||
? "False"
|
||||
: ""
|
||||
: userData.gender || "";
|
||||
|
||||
const isAliveValue = isExternalApi
|
||||
? userData.isLive === true
|
||||
? "بلی"
|
||||
: userData.isLive === false
|
||||
? "خیر"
|
||||
: ""
|
||||
: userData.isAlive === false
|
||||
? "خیر"
|
||||
: userData.isAlive === true
|
||||
? "بلی"
|
||||
: "";
|
||||
|
||||
const isForeignerValue = isExternalApi
|
||||
? layerTwo.isForeigner === "خیر"
|
||||
? false
|
||||
: layerTwo.isForeigner === "بلی"
|
||||
? true
|
||||
: ""
|
||||
: responseData.isForeignNational === false
|
||||
? false
|
||||
: responseData.isForeignNational === true
|
||||
? true
|
||||
: "";
|
||||
|
||||
const hasStewardValue = isExternalApi
|
||||
? layerTwo.hasSteward === "خیر"
|
||||
? false
|
||||
: layerTwo.hasSteward === "بلی"
|
||||
? true
|
||||
: ""
|
||||
: responseData.steward === false
|
||||
? false
|
||||
: responseData.steward === true
|
||||
? true
|
||||
: "";
|
||||
|
||||
const hasPartnerValue = isExternalApi
|
||||
? layerTwo.hasPartner === "خیر"
|
||||
? false
|
||||
: layerTwo.hasPartner === "بلی"
|
||||
? true
|
||||
: ""
|
||||
: responseData.hasPartner === false
|
||||
? false
|
||||
: responseData.hasPartner === true
|
||||
? true
|
||||
: "";
|
||||
|
||||
const values = {
|
||||
first_name: userData.firstName || "",
|
||||
last_name: userData.lastName || "",
|
||||
national_id: nationalIdValue,
|
||||
national_code: isExternalApi
|
||||
? userData.identityNo || ""
|
||||
: userData.nationalCode || "",
|
||||
birth_date: birthDatePersian,
|
||||
father_name: userData.fatherName || "",
|
||||
gender: genderValue,
|
||||
person_city: userData.city || "",
|
||||
is_alive: isAliveValue,
|
||||
// Guild fields - will be set per guild in accordion, so we set empty or first guild's data
|
||||
guild_name: isExternalApi
|
||||
? guildData.title || ""
|
||||
: firstGuild.guildsName || "",
|
||||
area_activity: isExternalApi
|
||||
? guildData.isicname || ""
|
||||
: firstGuild.areaActivity || "",
|
||||
state: isExternalApi ? guildData.state || "" : provinceData.name || "",
|
||||
city: isExternalApi ? guildData.city || "" : cityData.name || "",
|
||||
address: isExternalApi
|
||||
? guildData.address || ""
|
||||
: addressData.address || "",
|
||||
license_expire_date: licenseExpireDatePersian,
|
||||
license_status: isExternalApi
|
||||
? guildData.licenseStatus || ""
|
||||
: firstGuild.licenseStatus || "",
|
||||
license_type: isExternalApi
|
||||
? guildData.licenseType || ""
|
||||
: firstGuild.licenseType || "",
|
||||
license_number: isExternalApi
|
||||
? guildData.licenseNumber || ""
|
||||
: firstGuild.licenseNumber || "",
|
||||
union_name: isExternalApi
|
||||
? layerTwo.unionName || ""
|
||||
: firstGuild.unionName || "",
|
||||
postal_code: isExternalApi
|
||||
? layerTwo.postalcode || ""
|
||||
: addressData.postalCode || "",
|
||||
phone_number: isExternalApi
|
||||
? layerTwo.phonenumber || ""
|
||||
: firstGuild.phoneNumber || "",
|
||||
mobile: isExternalApi ? layerTwo.mobilenumber || "" : userData.mobile || "",
|
||||
guild_national_id: isExternalApi
|
||||
? layerTwo.nationalId || ""
|
||||
: firstGuild.nationalCode || "",
|
||||
is_foreigner: isForeignerValue,
|
||||
corporation_name: isExternalApi
|
||||
? layerTwo.corporationName || ""
|
||||
: firstGuild.companyName || "",
|
||||
has_steward: hasStewardValue,
|
||||
has_partner: hasPartnerValue,
|
||||
steward: isExternalApi ? false : firstGuild.isSteward || false,
|
||||
guild: isExternalApi
|
||||
? typeof guildData.guild === "boolean"
|
||||
? guildData.guild
|
||||
: false
|
||||
: typeof firstGuild.guild === "boolean"
|
||||
? firstGuild.guild
|
||||
: false,
|
||||
license_issue_date: licenseIssueDatePersian,
|
||||
...(isExternalApi
|
||||
? {}
|
||||
: {
|
||||
company_name: firstGuild.companyName || "",
|
||||
company_identifier: firstGuild.companyIdentifier || "",
|
||||
type_activity_name: firstGuild.typeActivity || "",
|
||||
}),
|
||||
};
|
||||
|
||||
formik.setValues({ ...formik.values, ...values });
|
||||
};
|
||||
@@ -1,158 +0,0 @@
|
||||
import {
|
||||
convertToIranianTime,
|
||||
convertPersianToEnglishNumerals,
|
||||
} from "../../../../../utils/formatTime";
|
||||
import { fromJalali } from "../../../../../utils/jalali";
|
||||
|
||||
export const convertGregorianToPersian = (gregorianDateString) => {
|
||||
if (!gregorianDateString || typeof gregorianDateString !== "string") {
|
||||
return "";
|
||||
}
|
||||
|
||||
// Check if the date is already in Persian format (YYYY/MM/DD with year < 1500)
|
||||
const persianPattern = /^\d{4}\/\d{2}\/\d{2}$/;
|
||||
if (persianPattern.test(gregorianDateString)) {
|
||||
const year = parseInt(gregorianDateString.split("/")[0]);
|
||||
// If year is < 1500, it's likely Persian, return as is
|
||||
if (year < 1500) {
|
||||
return gregorianDateString;
|
||||
}
|
||||
}
|
||||
|
||||
// Try to convert using convertToIranianTime
|
||||
try {
|
||||
return convertToIranianTime(gregorianDateString);
|
||||
} catch (error) {
|
||||
console.error("Error converting Gregorian date to Persian:", error);
|
||||
return gregorianDateString; // Return original on error
|
||||
}
|
||||
};
|
||||
|
||||
export const convertPersianToGregorian = (persianDateString) => {
|
||||
if (!persianDateString || typeof persianDateString !== "string") {
|
||||
return "";
|
||||
}
|
||||
|
||||
const normalizedDateString =
|
||||
convertPersianToEnglishNumerals(persianDateString);
|
||||
|
||||
const gregorianPattern = /^\d{4}[-/]\d{2}[-/]\d{2}$/;
|
||||
if (gregorianPattern.test(normalizedDateString)) {
|
||||
const year = parseInt(normalizedDateString.split(/[-/]/)[0]);
|
||||
if (year > 1500) {
|
||||
return normalizedDateString.replace(/\//g, "-");
|
||||
}
|
||||
}
|
||||
|
||||
const parts = normalizedDateString.split("/");
|
||||
if (parts.length !== 3) {
|
||||
return persianDateString;
|
||||
}
|
||||
|
||||
const py = parseInt(parts[0]);
|
||||
const pm = parseInt(parts[1]);
|
||||
const pd = parseInt(parts[2]);
|
||||
|
||||
if (isNaN(py) || isNaN(pm) || isNaN(pd)) {
|
||||
return persianDateString;
|
||||
}
|
||||
|
||||
try {
|
||||
const gregorianDate = fromJalali(py, pm, pd);
|
||||
const year = gregorianDate.getFullYear();
|
||||
const month = String(gregorianDate.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(gregorianDate.getDate()).padStart(2, "0");
|
||||
return `${year}-${month}-${day}`;
|
||||
} catch (error) {
|
||||
console.error("Error converting Persian date to Gregorian:", error);
|
||||
return persianDateString;
|
||||
}
|
||||
};
|
||||
|
||||
export const normalizeExternalApiDate = (dateString) => {
|
||||
if (!dateString || typeof dateString !== "string") {
|
||||
return "";
|
||||
}
|
||||
return convertPersianToEnglishNumerals(dateString);
|
||||
};
|
||||
|
||||
export const normalizeDatabaseDate = (dateString) => {
|
||||
if (!dateString || typeof dateString !== "string") {
|
||||
return "";
|
||||
}
|
||||
const first10Chars = dateString.substring(0, 10);
|
||||
const normalizedDate = first10Chars.replace(/-/g, "/");
|
||||
return convertToIranianTime(normalizedDate);
|
||||
};
|
||||
|
||||
export const formatDateForSubmitExternal = (dateString) => {
|
||||
if (!dateString || typeof dateString !== "string") {
|
||||
return "";
|
||||
}
|
||||
return convertPersianToEnglishNumerals(dateString);
|
||||
};
|
||||
|
||||
export const formatDateForSubmitDatabase = (dateString) => {
|
||||
if (!dateString || typeof dateString !== "string") {
|
||||
return "";
|
||||
}
|
||||
|
||||
const normalizedDate = convertPersianToEnglishNumerals(dateString);
|
||||
const persianPattern = /^\d{4}\/\d{2}\/\d{2}$/;
|
||||
|
||||
if (persianPattern.test(normalizedDate)) {
|
||||
const year = parseInt(normalizedDate.split("/")[0]);
|
||||
if (year < 1500) {
|
||||
const parts = normalizedDate.split("/");
|
||||
const py = parseInt(parts[0]);
|
||||
const pm = parseInt(parts[1]);
|
||||
const pd = parseInt(parts[2]);
|
||||
|
||||
if (!isNaN(py) && !isNaN(pm) && !isNaN(pd)) {
|
||||
try {
|
||||
const gregorianDate = fromJalali(py, pm, pd);
|
||||
const gy = gregorianDate.getFullYear();
|
||||
const gm = String(gregorianDate.getMonth() + 1).padStart(2, "0");
|
||||
const gd = String(gregorianDate.getDate()).padStart(2, "0");
|
||||
return `${gy}/${gm}/${gd}`;
|
||||
} catch (error) {
|
||||
console.error("Error converting Persian to Gregorian:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const gregorianPattern = /^\d{4}[-/]\d{2}[-/]\d{2}$/;
|
||||
if (gregorianPattern.test(normalizedDate)) {
|
||||
const year = parseInt(normalizedDate.split(/[-/]/)[0]);
|
||||
if (year > 1900) {
|
||||
return normalizedDate.replace(/-/g, "/");
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const date = new Date(normalizedDate);
|
||||
if (!isNaN(date.getTime())) {
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(date.getDate()).padStart(2, "0");
|
||||
return `${year}/${month}/${day}`;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error formatting database date:", error);
|
||||
}
|
||||
|
||||
return normalizedDate.replace(/-/g, "/");
|
||||
};
|
||||
|
||||
export const formatDateForSubmit = (dateString, isExternalApi = false) => {
|
||||
if (!dateString || typeof dateString !== "string") {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (isExternalApi) {
|
||||
return formatDateForSubmitExternal(dateString);
|
||||
} else {
|
||||
return formatDateForSubmitDatabase(dateString);
|
||||
}
|
||||
};
|
||||
@@ -1,95 +0,0 @@
|
||||
import * as yup from "yup";
|
||||
import { normalizeDatabaseDate } from "./dateUtils";
|
||||
|
||||
export const getValidationSchema = (isEditMode) =>
|
||||
yup.object({
|
||||
national_id: yup
|
||||
.string()
|
||||
.required("کد ملی الزامی است")
|
||||
.matches(/^[0-9]{10}$/, "کد ملی باید 10 رقم باشد"),
|
||||
mobile: isEditMode
|
||||
? yup
|
||||
.string()
|
||||
.nullable()
|
||||
.test(
|
||||
"mobile-format",
|
||||
"شماره تلفن باید 11 رقم باشد",
|
||||
(value) => !value || /^[0-9]{11}$/.test(value)
|
||||
)
|
||||
: yup
|
||||
.string()
|
||||
.required("شماره تلفن الزامی است")
|
||||
.matches(/^[0-9]{11}$/, "شماره تلفن باید 11 رقم باشد"),
|
||||
first_name: yup.string(),
|
||||
last_name: yup.string(),
|
||||
guild_name: yup.string(),
|
||||
guild_category: yup.string(),
|
||||
state: yup.string(),
|
||||
city: yup.string(),
|
||||
address: yup.string(),
|
||||
license_expire_date: yup.string(),
|
||||
license_status: yup.string(),
|
||||
union_name: yup.string(),
|
||||
postal_code: yup.string(),
|
||||
guild_national_id: yup.string(),
|
||||
is_foreigner: yup.string(),
|
||||
national_code: yup.string(),
|
||||
has_steward: yup.string(),
|
||||
has_partner: yup.string(),
|
||||
license_number: yup.string(),
|
||||
isAccepted: yup
|
||||
.boolean()
|
||||
.test("req", "باید تعهد نامه را بپذیرید!", (val) => {
|
||||
return val === true;
|
||||
})
|
||||
.required("این فیلد اجباری است!"),
|
||||
});
|
||||
|
||||
export const getInitialValues = (guild) => ({
|
||||
first_name: guild?.user?.firstName || "",
|
||||
last_name: guild?.user?.lastName || "",
|
||||
corporation_name: guild?.companyName || "",
|
||||
national_id: guild?.user?.nationalId || "",
|
||||
national_code: guild?.user?.nationalCode || "",
|
||||
birth_date: normalizeDatabaseDate(guild?.user?.birthday || ""),
|
||||
father_name: guild?.user?.fatherName || "",
|
||||
gender: guild?.user?.gender || "",
|
||||
person_city: guild?.user?.city || "",
|
||||
is_alive: guild?.user?.isAlive || "",
|
||||
guild_name: guild?.guildsName || "",
|
||||
area_activity: guild?.areaActivity || "",
|
||||
state: guild?.address?.province?.name || "",
|
||||
city: guild?.address?.city?.name || "",
|
||||
address: guild?.address?.address || "",
|
||||
license_expire_date: normalizeDatabaseDate(guild?.licenseExpireDate || ""),
|
||||
license_status: guild?.licenseStatus || "",
|
||||
license_type: guild?.licenseType || "",
|
||||
union_name: guild?.unionName || "",
|
||||
postal_code: guild?.address?.postalCode || "",
|
||||
phone_number: guild?.phoneNumber || "",
|
||||
mobile: guild?.user?.mobile || "",
|
||||
is_foreigner: guild?.is_foreign_national || "",
|
||||
has_steward: guild?.hasSteward || "",
|
||||
has_partner: guild?.hasPartner || "",
|
||||
license_number: guild?.licenseNumber || "",
|
||||
isAccepted: guild?.provinceAcceptState === "accepted" || false,
|
||||
steward:
|
||||
typeof guild?.steward === "boolean"
|
||||
? guild.steward
|
||||
: typeof guild?.isSteward === "boolean"
|
||||
? guild.isSteward
|
||||
: false,
|
||||
guild:
|
||||
typeof guild?.guild === "boolean"
|
||||
? guild.guild
|
||||
: typeof guild?.isGuild === "boolean"
|
||||
? guild.isGuild
|
||||
: false,
|
||||
verify_mobile: guild?.verifyMobile || false,
|
||||
guild_national_id: guild?.nationalId || "",
|
||||
license_issue_date: normalizeDatabaseDate(guild?.licenseIssueDate || ""),
|
||||
company_name: guild?.companyName || "",
|
||||
company_identifier: guild?.companyIdentifier || "",
|
||||
type_activity_name: guild?.typeActivityName || "",
|
||||
active: guild?.active ?? null,
|
||||
});
|
||||
@@ -1,45 +0,0 @@
|
||||
import {
|
||||
CLOSE_MODAL,
|
||||
OPEN_MODAL,
|
||||
} from "../../../../../lib/redux/slices/appSlice";
|
||||
import { ProvinceManageGuildsSubmitRegisterCode } from "../../province-manage-guilds-submit-register-code/ProvinceManageGuildsSubmitRegisterCode";
|
||||
|
||||
export const handleSubmitSuccess = (
|
||||
dispatch,
|
||||
openNotif,
|
||||
updateTable,
|
||||
values,
|
||||
responseData
|
||||
) => {
|
||||
updateTable();
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: "عملیات با موفقیت انجام شد.",
|
||||
severity: "success",
|
||||
});
|
||||
dispatch(CLOSE_MODAL());
|
||||
|
||||
if (values.verify_mobile && responseData) {
|
||||
dispatch(
|
||||
OPEN_MODAL({
|
||||
title: "ثبت کد احراز",
|
||||
content: (
|
||||
<ProvinceManageGuildsSubmitRegisterCode
|
||||
item={responseData}
|
||||
updateTable={updateTable}
|
||||
/>
|
||||
),
|
||||
})
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export const handleSubmitError = (openNotif, error) => {
|
||||
openNotif({
|
||||
vertical: "top",
|
||||
horizontal: "center",
|
||||
msg: error,
|
||||
severity: "error",
|
||||
});
|
||||
};
|
||||
@@ -19,7 +19,6 @@ import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import { provinceChangeActiveGuildService } from "../../services/province-change-active-guild";
|
||||
import { provinceGetBuyersService } from "../../services/province-get-buyers";
|
||||
import { provinceGetStewardsService } from "../../services/province-get-stewards";
|
||||
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
// agreed: Yup.boolean().oneOf([true], 'You must agree to the terms and conditions'),
|
||||
@@ -29,9 +28,6 @@ export const GuildLimitaion = ({ guild, updateTable }) => {
|
||||
const { provinceGetStewardsOptions, provinceGetBuyersOptions } = useSelector(
|
||||
(state) => state.provinceSlice
|
||||
);
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
const [warehouses, setWarehouses] = useState(
|
||||
guild.centersAllocation ? guild.centersAllocation : []
|
||||
);
|
||||
@@ -81,21 +77,9 @@ export const GuildLimitaion = ({ guild, updateTable }) => {
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
provinceGetStewardsService({
|
||||
role_key: checkPathStartsWith("province")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
);
|
||||
dispatch(
|
||||
provinceGetBuyersService({
|
||||
role_key: checkPathStartsWith("province")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
);
|
||||
}, [selectedSubUser?.key]);
|
||||
dispatch(provinceGetStewardsService());
|
||||
dispatch(provinceGetBuyersService());
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<form onSubmit={formik.handleSubmit} style={{ width: "100%" }}>
|
||||
@@ -161,7 +145,7 @@ export const GuildLimitaion = ({ guild, updateTable }) => {
|
||||
{!warehouses.length && (
|
||||
<Typography variant="caption">محدودیتی وجود ندارد</Typography>
|
||||
)}
|
||||
{warehouses?.map((item) => {
|
||||
{warehouses?.map((item, i) => {
|
||||
return (
|
||||
<>
|
||||
{item !== null && (
|
||||
@@ -220,7 +204,7 @@ export const GuildLimitaion = ({ guild, updateTable }) => {
|
||||
{!buyers.length && (
|
||||
<Typography variant="caption">محدودیتی وجود ندارد</Typography>
|
||||
)}
|
||||
{buyers?.map((item) => {
|
||||
{buyers?.map((item, i) => {
|
||||
return (
|
||||
<>
|
||||
{item !== null && (
|
||||
|
||||
@@ -4,19 +4,25 @@ import { NavLink } from "../../../../components/nav-link/NavLink";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import {
|
||||
// ROUTE_ADMINX_ROUTE_GUILDS,
|
||||
ROUTE_ADMINX_ROUTE_IN_PROVINCE_GUILDS_DISTRIBUTIONS,
|
||||
ROUTE_ADMINX_ROUTE_IN_PROVINCE_GUILDS_REQUESTS,
|
||||
ROUTE_ADMINX_ROUTE_IN_PROVINCE_GUILDS,
|
||||
ROUTE_ADMINX_ROUTE_MANAGE_GUILDS,
|
||||
ROUTE_ADMINX_ROUTE_OUT_PROVINCE_GUILDS,
|
||||
ROUTE_ADMINX_ROUTE_IN_PROVINCE_STEWARDS,
|
||||
ROUTE_PROVINCE_ROUTE_GUILDS,
|
||||
ROUTE_PROVINCE_ROUTE_IN_PROVINCE_GUILDS_REQUESTS,
|
||||
ROUTE_PROVINCE_ROUTE_IN_PROVINCE_GUILDS,
|
||||
ROUTE_PROVINCE_ROUTE_MANAGE_GUILDS,
|
||||
ROUTE_PROVINCE_ROUTE_OUT_PROVINCE_GUILDS,
|
||||
ROUTE_PROVINCE_ROUTE_IN_PROVINCE_STEWARDS,
|
||||
// ROUTE_SUPER_ADMIN_ROUTE_GUILDS,
|
||||
ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_GUILDS_DISTRIBUTIONS,
|
||||
ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_GUILDS_REQUESTS,
|
||||
ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_GUILDS,
|
||||
ROUTE_SUPER_ADMIN_ROUTE_MANAGE_GUILDS,
|
||||
ROUTE_SUPER_ADMIN_ROUTE_OUT_PROVINCE_GUILDS,
|
||||
ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_STEWARDS,
|
||||
ROUTE_SUPER_ADMIN_ROUTE_OUT_PROVINCE_TRUE_GUILDS,
|
||||
ROUTE_ADMINX_ROUTE_OUT_PROVINCE_TRUE_GUILDS,
|
||||
ROUTE_PROVINCE_ROUTE_OUT_PROVINCE_TRUE_GUILDS,
|
||||
@@ -32,7 +38,9 @@ import {
|
||||
} from "../../../../routes/routes";
|
||||
import LinkItem from "../../../../components/link-item/LinkItem";
|
||||
import { MdCorporateFare } from "react-icons/md";
|
||||
import { IoIosPeople } from "react-icons/io";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import { VscLiveShare } from "react-icons/vsc";
|
||||
import { BackButton } from "../../../../components/back-button/BackButton";
|
||||
|
||||
export const GuildsOperations = () => {
|
||||
@@ -156,7 +164,7 @@ export const GuildsOperations = () => {
|
||||
title="اصناف حقوقی"
|
||||
/>
|
||||
</NavLink>
|
||||
{/* <NavLink
|
||||
<NavLink
|
||||
to={
|
||||
getRoleFromUrl() === "SuperAdmin"
|
||||
? ROUTE_SUPER_ADMIN_ROUTE_IN_PROVINCE_STEWARDS
|
||||
@@ -191,7 +199,7 @@ export const GuildsOperations = () => {
|
||||
title="مدیریت مباشرین"
|
||||
/>
|
||||
</NavLink>
|
||||
)} */}
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
|
||||
@@ -315,7 +315,7 @@ export const ManageGuildDistributions = () => {
|
||||
|
||||
return (
|
||||
<Grid container xs={12} justifyContent="center" alignItems="center" gap={2}>
|
||||
<Grid container mt={2} mb={4} isDashboard xs={12}>
|
||||
<Grid container mt={2} mb={4} isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Button, TextField, Tooltip, MenuItem } from "@mui/material";
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
FormControlLabel,
|
||||
TextField,
|
||||
Tooltip,
|
||||
MenuItem,
|
||||
} from "@mui/material";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import axios from "axios";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
@@ -12,24 +19,22 @@ import { RiFileExcel2Fill, RiSearchLine } from "react-icons/ri";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
import { SimpleTable } from "../../../../components/simple-table/SimpleTable";
|
||||
import { CreateGuilds } from "../create-guilds/CreateGuilds";
|
||||
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
|
||||
export const MaangeGuilds = () => {
|
||||
const userKey = useSelector((state) => state.userSlice?.userProfile?.key);
|
||||
const dispatch = useDispatch();
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
|
||||
const [data, setData] = useState([]);
|
||||
const [totalRows, setTotalRows] = useState(0);
|
||||
const [perPage, setPerPage] = useState(10);
|
||||
const [textValue, setTextValue] = useState("");
|
||||
const [page, setPage] = useState(1);
|
||||
const [tableData, setTableData] = useState([]);
|
||||
const [isSteward, setIsSteward] = useState(false);
|
||||
const [activeState, setActiveState] = useState("active");
|
||||
|
||||
const handleTextChange = (e) => setTextValue(e.target.value);
|
||||
// const handleCheckboxChange = () => setIsSteward(!isSteward);
|
||||
const handleCheckboxChange = () => setIsSteward(!isSteward);
|
||||
|
||||
const fetchApiData = async (page) => {
|
||||
const response = await dispatch(
|
||||
@@ -38,12 +43,9 @@ export const MaangeGuilds = () => {
|
||||
value: textValue,
|
||||
page: page,
|
||||
page_size: perPage,
|
||||
steward: false,
|
||||
steward: isSteward,
|
||||
active_state: activeState,
|
||||
is_real_person: true,
|
||||
role_key: checkPathStartsWith("province")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
);
|
||||
|
||||
@@ -73,7 +75,7 @@ export const MaangeGuilds = () => {
|
||||
|
||||
useEffect(() => {
|
||||
fetchApiData(1);
|
||||
}, [perPage, selectedSubUser?.key, activeState]);
|
||||
}, [dispatch, isSteward, activeState]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!data || !Array.isArray(data)) {
|
||||
@@ -205,6 +207,10 @@ export const MaangeGuilds = () => {
|
||||
setTableData(d);
|
||||
}, [data]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchApiData(1);
|
||||
}, [perPage]);
|
||||
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
const response = await dispatch(
|
||||
@@ -213,12 +219,9 @@ export const MaangeGuilds = () => {
|
||||
value: textValue,
|
||||
page: page,
|
||||
page_size: perPage,
|
||||
steward: false,
|
||||
steward: isSteward,
|
||||
active_state: activeState,
|
||||
is_real_person: true,
|
||||
role_key: checkPathStartsWith("province")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
);
|
||||
|
||||
@@ -250,7 +253,7 @@ export const MaangeGuilds = () => {
|
||||
>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Grid container alignItems="center" gap={SPACING.SMALL}>
|
||||
{["KillHouse", "GuildRoom"].includes(getRoleFromUrl()) && (
|
||||
{["GuildRoom", "KillHouse"].includes(getRoleFromUrl()) && (
|
||||
<Button
|
||||
variant="contained"
|
||||
onClick={() => {
|
||||
@@ -278,7 +281,7 @@ export const MaangeGuilds = () => {
|
||||
onChange={handleTextChange}
|
||||
/>
|
||||
|
||||
{/* <FormControlLabel
|
||||
<FormControlLabel
|
||||
style={{ marginRight: 4 }}
|
||||
control={
|
||||
<Checkbox
|
||||
@@ -289,7 +292,7 @@ export const MaangeGuilds = () => {
|
||||
/>
|
||||
}
|
||||
label="نمایش مباشرین"
|
||||
/> */}
|
||||
/>
|
||||
{getRoleFromUrl() !== "KillHouse" && (
|
||||
<TextField
|
||||
select
|
||||
@@ -320,11 +323,7 @@ export const MaangeGuilds = () => {
|
||||
<a
|
||||
href={`${
|
||||
axios.defaults.baseURL
|
||||
}guilds_excel/?key=${userKey}&search=filter&value=${textValue}&role=${getRoleFromUrl()}${
|
||||
checkPathStartsWith("province")
|
||||
? `&role_key=${selectedSubUser?.key}`
|
||||
: ""
|
||||
}&active_state=${activeState}`}
|
||||
}guilds_excel/?key=${userKey}&search=filter&value=${textValue}&role=${getRoleFromUrl()}&active_state=${activeState}`}
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Button color="success">
|
||||
|
||||
@@ -583,7 +583,7 @@ export const ManagePoultries = () => {
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
|
||||
<Grid container mt={2} mb={4} isDashboard xs={12}>
|
||||
<Grid container mt={2} mb={4} isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -427,7 +427,7 @@ export const PoultriesDetails = () => {
|
||||
</Tabs>
|
||||
</Grid>
|
||||
{dashboardData && (
|
||||
<Grid container mt={2} mb={4} isDashboard xs={12}>
|
||||
<Grid container mt={2} mb={4} isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -56,8 +56,9 @@ export const ProvinceAllocateRequests = () => {
|
||||
const fetchApiData = async (page) => {
|
||||
dispatch(getPoultryRequestsTotalQuantityService(selectedDate1)).then(
|
||||
async () => {
|
||||
let response;
|
||||
dispatch(LOADING_START());
|
||||
const response = await axios.get(
|
||||
response = await axios.get(
|
||||
`city_operator_check_request_new/?state=waiting&date=${selectedDate1}&page=${page}&page_size=${perPage}&search=filter&value=${
|
||||
textValue ? textValue : ""
|
||||
}`
|
||||
@@ -298,9 +299,6 @@ export const ProvinceAllocateRequests = () => {
|
||||
))}
|
||||
</Grid>
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
}}
|
||||
px={{
|
||||
xs: 1,
|
||||
sm: 0,
|
||||
|
||||
@@ -24,16 +24,13 @@ import { ProvinceGetDeletedAllocatedRequests } from "../province-get-deleted-all
|
||||
import { provinceGetDashboardKillRequestService } from "../../services/get-dahsnoard-province-kill-request";
|
||||
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
|
||||
export const ProvinceAllocatedRequests = () => {
|
||||
const dispatch = useDispatch();
|
||||
const [dataTable, setDataTable] = useState();
|
||||
const [hasDocumentState, setHasDocumentState] = useState(false);
|
||||
|
||||
const [selectedTab, setSelectedTab] = useState(0);
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
const userKey = useSelector((state) => state.userSlice.userProfile.key);
|
||||
|
||||
const [textValue, setTextValue] = useState("");
|
||||
@@ -47,9 +44,6 @@ export const ProvinceAllocatedRequests = () => {
|
||||
|
||||
dispatch(
|
||||
provinceGetAllocatedRequestsService({
|
||||
role_key: checkPathStartsWith("province")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
selectedDate1,
|
||||
selectedDate2,
|
||||
textValue,
|
||||
@@ -84,9 +78,6 @@ export const ProvinceAllocatedRequests = () => {
|
||||
selectedDate2,
|
||||
textValue,
|
||||
hasDocumentState: checked,
|
||||
role_key: checkPathStartsWith("province")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
};
|
||||
|
||||
dispatch(provinceGetDashboardKillRequestService(params)).then((r) => {
|
||||
@@ -98,9 +89,6 @@ export const ProvinceAllocatedRequests = () => {
|
||||
if (selectedTab === 0) {
|
||||
dispatch(
|
||||
provinceGetAllocatedRequestsService({
|
||||
role_key: checkPathStartsWith("province")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
selectedDate1,
|
||||
selectedDate2,
|
||||
textValue,
|
||||
@@ -109,15 +97,12 @@ export const ProvinceAllocatedRequests = () => {
|
||||
);
|
||||
fetchDashboard();
|
||||
}
|
||||
}, [selectedDate1, selectedDate2, selectedTab, selectedSubUser?.key]);
|
||||
}, [selectedDate1, selectedDate2, selectedTab]);
|
||||
|
||||
const handleSubmit = () => {
|
||||
if (selectedTab === 0) {
|
||||
dispatch(
|
||||
provinceGetAllocatedRequestsService({
|
||||
role_key: checkPathStartsWith("province")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
selectedDate1,
|
||||
selectedDate2,
|
||||
textValue,
|
||||
@@ -287,11 +272,7 @@ export const ProvinceAllocatedRequests = () => {
|
||||
<a
|
||||
href={`${
|
||||
axios.defaults.baseURL
|
||||
}allocated_excel/?start=${selectedDate1}&end=${selectedDate2}&role=${getRoleFromUrl()}${
|
||||
checkPathStartsWith("province")
|
||||
? `&role_key=${selectedSubUser?.key}`
|
||||
: ""
|
||||
}&key=${userKey}&filter=search&value=${textValue}`}
|
||||
}allocated_excel/?start=${selectedDate1}&end=${selectedDate2}&role=${getRoleFromUrl()}&key=${userKey}&filter=search&value=${textValue}`}
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Button color="success">
|
||||
@@ -312,7 +293,7 @@ export const ProvinceAllocatedRequests = () => {
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
<Grid container mt={2} mb={4} isDashboard xs={12}>
|
||||
<Grid container mt={2} mb={4} isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -3,7 +3,7 @@ import { DatePicker } from "@mui/x-date-pickers";
|
||||
import moment from "moment/moment";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
|
||||
import { AdvancedTable } from "../../../../components/advanced-table/AdvancedTable";
|
||||
import { Grid } from "../../../../components/grid/Grid";
|
||||
import { AppContext } from "../../../../contexts/AppContext";
|
||||
import { SPACING } from "../../../../data/spacing";
|
||||
@@ -62,7 +62,8 @@ export const ProvinceAutoAllocationArchive = () => {
|
||||
return (
|
||||
<Grid mt={SPACING.SMALL} xs={12} px={2}>
|
||||
{!isSingleView && (
|
||||
<>
|
||||
<AdvancedTable
|
||||
name={
|
||||
<Grid container alignItems="center" gap={SPACING.SMALL} mb={2}>
|
||||
<Grid>
|
||||
<Typography>بایگانی تخصیصات خودکار</Typography>
|
||||
@@ -94,8 +95,7 @@ export const ProvinceAutoAllocationArchive = () => {
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<ResponsiveTable
|
||||
title="بایگانی تخصیصات خودکار"
|
||||
}
|
||||
columns={[
|
||||
"ردیف",
|
||||
"کد تخصیص خودکار",
|
||||
@@ -108,7 +108,6 @@ export const ProvinceAutoAllocationArchive = () => {
|
||||
]}
|
||||
data={dataTable}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
{isSingleView && (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
import { Button, IconButton, TextField } from "@mui/material";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useDispatch } from "react-redux";
|
||||
import axios from "axios";
|
||||
import { RiSearchLine } from "react-icons/ri";
|
||||
import { DatePicker } from "@mui/x-date-pickers";
|
||||
@@ -21,7 +21,6 @@ import { ProvinceBarDifferencesOperations } from "../province-bar-differences-op
|
||||
// import EmailIcon from "@mui/icons-material/Email";
|
||||
import { provinceGetDashboardBarDiffrenceRequest } from "../../services/province-dashboard-bar-diffrence-get-request";
|
||||
import { ProvinceBarDifferencesModal } from "../province-bar-differences-modal/ProvinceBarDifferencesModal";
|
||||
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
|
||||
export const ProvinceBarDifferenceRequests = ({ state }) => {
|
||||
const dispatch = useDispatch();
|
||||
@@ -34,18 +33,12 @@ export const ProvinceBarDifferenceRequests = ({ state }) => {
|
||||
const [page, setPage] = useState(1);
|
||||
const [tableData, setTableData] = useState([]);
|
||||
const [dashboardData, setDashboardData] = useState([]);
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
|
||||
const fetchApiData = async (page) => {
|
||||
dispatch(LOADING_START());
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`bar-difference-request/?search=filter&value=${textValue}&role=${getRoleFromUrl()}${
|
||||
checkPathStartsWith("province")
|
||||
? `&role_key=${selectedSubUser?.key}`
|
||||
: ""
|
||||
}&page=${page}&page_size=${perPage}&state=${state}&date1=${selectedDate1}&date2=${selectedDate2}`
|
||||
`bar-difference-request/?search=filter&value=${textValue}&role=${getRoleFromUrl()}&page=${page}&page_size=${perPage}&state=${state}&date1=${selectedDate1}&date2=${selectedDate2}`
|
||||
);
|
||||
setData(response.data.results);
|
||||
setTotalRows(response.data.count);
|
||||
@@ -60,9 +53,6 @@ export const ProvinceBarDifferenceRequests = ({ state }) => {
|
||||
dispatch(
|
||||
provinceGetDashboardBarDiffrenceRequest({
|
||||
role: getRoleFromUrl(),
|
||||
role_key: checkPathStartsWith("slaughter")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
state: state,
|
||||
filter: "search",
|
||||
value: textValue,
|
||||
@@ -156,7 +146,7 @@ export const ProvinceBarDifferenceRequests = ({ state }) => {
|
||||
useEffect(() => {
|
||||
fetchApiData(1);
|
||||
fetchDashboardData();
|
||||
}, [state, perPage, selectedDate1, selectedDate2, selectedSubUser?.key]);
|
||||
}, [state, perPage, selectedDate1, selectedDate2]);
|
||||
|
||||
const handleTextChange = (event) => {
|
||||
setTextValue(event.target.value);
|
||||
@@ -177,7 +167,7 @@ export const ProvinceBarDifferenceRequests = ({ state }) => {
|
||||
alignItems="center"
|
||||
gap={2}
|
||||
>
|
||||
<Grid container mt={2} mb={4} isDashboard xs={12}>
|
||||
<Grid container mt={2} mb={4} isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -130,7 +130,7 @@ export const ProvinceBuyersAllocations = () => {
|
||||
</a>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
<Grid mb={SPACING.SMALL} isDashboard xs={12}>
|
||||
<Grid mb={SPACING.SMALL} isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -196,7 +196,7 @@ export const ProvinceChickenDistributionsAndSales = () => {
|
||||
|
||||
return (
|
||||
<Grid container xs={12} justifyContent="center" alignItems="center" gap={2}>
|
||||
<Grid container mt={2} mb={4} isDashboard xs={12}>
|
||||
<Grid container mt={2} mb={4} isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -172,7 +172,7 @@ export const ProvinceChickenStewardSales = () => {
|
||||
|
||||
return (
|
||||
<Grid container xs={12} justifyContent="center" alignItems="center" gap={2}>
|
||||
<Grid container mt={2} mb={4} isDashboard xs={12}>
|
||||
<Grid container mt={2} mb={4} isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -89,9 +89,9 @@ export const ProvinceDispenserAcceptedSaleWithInProvince = ({ priceInfo }) => {
|
||||
item?.toKillHouse?.killHouseOperator?.user?.fullname || "-"
|
||||
} (${item?.toKillHouse?.killHouseOperator?.user?.mobile || "-"})`;
|
||||
case "killhouse_steward":
|
||||
return `${item?.toStewards?.name || "-"} - ${
|
||||
item?.toStewards?.user?.fullname || "-"
|
||||
} (${item?.toStewards?.user?.mobile || "-"})`;
|
||||
return `${item?.toSteward?.guildsName || "-"} - ${
|
||||
item?.toSteward?.user?.fullname || "-"
|
||||
} (${item?.toSteward?.user?.mobile || "-"})`;
|
||||
case "killhouse_guild":
|
||||
return `${item?.toGuilds?.guildsName || "-"} - ${
|
||||
item?.toGuilds?.user?.fullname || "-"
|
||||
|
||||
@@ -89,9 +89,9 @@ export const ProvinceDispenserRejectedSaleWithInProvince = ({ priceInfo }) => {
|
||||
item?.toKillHouse?.killHouseOperator?.user?.fullname || "-"
|
||||
} (${item?.toKillHouse?.killHouseOperator?.user?.mobile || "-"})`;
|
||||
case "killhouse_steward":
|
||||
return `${item?.toStewards?.name || "-"} - ${
|
||||
item?.toStewards?.user?.fullname || "-"
|
||||
} (${item?.toStewards?.user?.mobile || "-"})`;
|
||||
return `${item?.toSteward?.guildsName || "-"} - ${
|
||||
item?.toSteward?.user?.fullname || "-"
|
||||
} (${item?.toSteward?.user?.mobile || "-"})`;
|
||||
case "killhouse_guild":
|
||||
return `${item?.toGuilds?.guildsName || "-"} - ${
|
||||
item?.toGuilds?.user?.fullname || "-"
|
||||
|
||||
@@ -88,9 +88,9 @@ export const ProvinceDispenserReturnedSaleWithInProvince = ({ priceInfo }) => {
|
||||
item?.toKillHouse?.killHouseOperator?.user?.fullname || "-"
|
||||
} (${item?.toKillHouse?.killHouseOperator?.user?.mobile || "-"})`;
|
||||
case "killhouse_steward":
|
||||
return `${item?.toStewards?.name || "-"} - ${
|
||||
item?.toStewards?.user?.fullname || "-"
|
||||
} (${item?.toStewards?.user?.mobile || "-"})`;
|
||||
return `${item?.toSteward?.guildsName || "-"} - ${
|
||||
item?.toSteward?.user?.fullname || "-"
|
||||
} (${item?.toSteward?.user?.mobile || "-"})`;
|
||||
case "killhouse_guild":
|
||||
return `${item?.toGuilds?.guildsName || "-"} - ${
|
||||
item?.toGuilds?.user?.fullname || "-"
|
||||
|
||||
@@ -144,7 +144,7 @@ export const ProvinceDispenserSegmentation = ({
|
||||
gap={2}
|
||||
mt={4}
|
||||
>
|
||||
<Grid container width="100%" isDashboard xs={12}>
|
||||
<Grid container width="100%" isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -102,7 +102,7 @@ export const ProvinceDispensersSellCarcassSellOut = () => {
|
||||
</Tooltip> */}
|
||||
</Grid>
|
||||
|
||||
<Grid container xs={12} mt={2} mb={4} isDashboard xs={12}>
|
||||
<Grid container xs={12} mt={2} mb={4} isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -220,7 +220,7 @@ export const ProvinceFreeSalesTransactions = () => {
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container mt={2} mb={4} isDashboard xs={12}>
|
||||
<Grid container mt={2} mb={4} isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -14,16 +14,13 @@ import ResponsiveTable from "../../../../components/responsive-table/ResponsiveT
|
||||
import { provinceGetDashboardDeletedKillRequestService } from "../../services/get-dahsnoard-province-kill-request";
|
||||
import { getRoleFromUrl } from "../../../../utils/getRoleFromUrl";
|
||||
import { RiSearchLine } from "react-icons/ri";
|
||||
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
|
||||
export const ProvinceGetDeletedAllocatedRequests = () => {
|
||||
const dispatch = useDispatch();
|
||||
const [dataTable, setDataTable] = useState();
|
||||
const [, , selectedDate1, setSelectedDate1, selectedDate2, setSelectedDate2] =
|
||||
useContext(AppContext);
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
|
||||
const userKey = useSelector((state) => state.userSlice.userProfile.key);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -45,22 +42,16 @@ export const ProvinceGetDeletedAllocatedRequests = () => {
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
provinceGetDeletedAllocatedRequestsService({
|
||||
role_key: checkPathStartsWith("slaughter")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
selectedDate1,
|
||||
selectedDate2,
|
||||
textValue,
|
||||
})
|
||||
);
|
||||
}, [selectedDate1, selectedDate2, selectedSubUser?.key]);
|
||||
}, [selectedDate1, selectedDate2]);
|
||||
|
||||
const handleSubmit = () => {
|
||||
dispatch(
|
||||
provinceGetDeletedAllocatedRequestsService({
|
||||
role_key: checkPathStartsWith("slaughter")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
selectedDate1,
|
||||
selectedDate2,
|
||||
textValue,
|
||||
@@ -72,9 +63,6 @@ export const ProvinceGetDeletedAllocatedRequests = () => {
|
||||
selectedDate1,
|
||||
selectedDate2,
|
||||
textValue,
|
||||
role_key: checkPathStartsWith("slaughter")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
).then((r) => {
|
||||
setDashboardData(r.payload.data);
|
||||
@@ -122,14 +110,11 @@ export const ProvinceGetDeletedAllocatedRequests = () => {
|
||||
selectedDate1,
|
||||
selectedDate2,
|
||||
textValue,
|
||||
role_key: checkPathStartsWith("slaughter")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
).then((r) => {
|
||||
setDashboardData(r.payload.data);
|
||||
});
|
||||
}, [selectedDate1, selectedDate2, selectedSubUser?.key]);
|
||||
}, [selectedDate1, selectedDate2]);
|
||||
|
||||
return (
|
||||
<Grid>
|
||||
@@ -185,11 +170,7 @@ export const ProvinceGetDeletedAllocatedRequests = () => {
|
||||
<a
|
||||
href={`${
|
||||
axios.defaults.baseURL
|
||||
}allocated_excel/?start=${selectedDate1}&end=${selectedDate2}&type=deleted&role=${getRoleFromUrl()}${
|
||||
checkPathStartsWith("province")
|
||||
? `&role_key=${selectedSubUser?.key}`
|
||||
: ""
|
||||
}&key=${userKey}&filter=search&value=${textValue}`}
|
||||
}allocated_excel/?start=${selectedDate1}&end=${selectedDate2}&type=deleted&role=${getRoleFromUrl()}&key=${userKey}&filter=search&value=${textValue}`}
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Button color="success">
|
||||
@@ -199,7 +180,7 @@ export const ProvinceGetDeletedAllocatedRequests = () => {
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
|
||||
<Grid container mt={2} mb={4} isDashboard xs={12}>
|
||||
<Grid container mt={2} mb={4} isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -37,7 +37,6 @@ import EditOutlinedIcon from "@mui/icons-material/EditOutlined";
|
||||
import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline";
|
||||
import ResponsiveTable from "../../../../components/responsive-table/ResponsiveTable";
|
||||
import { provinceCarsDashboardService } from "../../services/province-cars-dashboard";
|
||||
import { checkPathStartsWith } from "../../../../utils/checkPathStartsWith";
|
||||
|
||||
export const ProvinceManageCars = () => {
|
||||
const dispatch = useDispatch();
|
||||
@@ -46,32 +45,18 @@ export const ProvinceManageCars = () => {
|
||||
const { provinceCars } = useSelector((state) => state.provinceSlice);
|
||||
// const userInfo = useSelector((state) => state.userSlice);
|
||||
const userKey = useSelector((state) => state.userSlice.userProfile.key);
|
||||
const selectedSubUser = useSelector(
|
||||
(state) => state.userSlice.selectedSubUser
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
provinceGetCars({
|
||||
role_key: checkPathStartsWith("province")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
);
|
||||
}, [selectedSubUser?.key]);
|
||||
dispatch(provinceGetCars());
|
||||
}, []);
|
||||
|
||||
const [dashboardData, setDashboardData] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
provinceCarsDashboardService({
|
||||
role_key: checkPathStartsWith("province")
|
||||
? selectedSubUser?.key || ""
|
||||
: "",
|
||||
})
|
||||
).then((r) => {
|
||||
dispatch(provinceCarsDashboardService()).then((r) => {
|
||||
setDashboardData(r.payload.data);
|
||||
});
|
||||
}, [dispatch, provinceCars, selectedSubUser?.key]);
|
||||
}, [dispatch, provinceCars]);
|
||||
|
||||
useEffect(() => {
|
||||
const d = provinceCars?.map((item, i) => {
|
||||
@@ -162,11 +147,7 @@ export const ProvinceManageCars = () => {
|
||||
<a
|
||||
href={`${
|
||||
axios.defaults.baseURL
|
||||
}car_province_excel/?key=${userKey}&role=${getRoleFromUrl()}${
|
||||
checkPathStartsWith("province")
|
||||
? `&role_key=${selectedSubUser?.key}`
|
||||
: ""
|
||||
}`}
|
||||
}car_province_excel/?key=${userKey}&role=${getRoleFromUrl()}`}
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Button color="success">
|
||||
@@ -175,7 +156,7 @@ export const ProvinceManageCars = () => {
|
||||
</a>
|
||||
</Tooltip>
|
||||
<Card sx={{ width: "100%" }}>
|
||||
<Grid container mt={2} mb={4} isDashboard xs={12}>
|
||||
<Grid container mt={2} mb={4} isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -60,7 +60,7 @@ export const ProvinceManageContradictions = () => {
|
||||
};
|
||||
const userInfo = useSelector((state) => state.userSlice);
|
||||
|
||||
const setPdfOptions = () => {
|
||||
const setPdfOptions = (item) => {
|
||||
dispatch(LOADING_START());
|
||||
dispatch(
|
||||
provinceGetContradictionsData({ selectedDate1, selectedDate2 })
|
||||
|
||||
@@ -425,7 +425,7 @@ export const ProvinceNationalInfoSlaughterhouse = () => {
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container mt={2} mb={4} isDashboard xs={12}>
|
||||
<Grid container mt={2} mb={4} isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
@@ -278,7 +278,7 @@ export const ProvinceNationalInfoFarm = () => {
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid container mt={2} mb={4} isDashboard xs={12}>
|
||||
<Grid container mt={2} mb={4} isDashboard>
|
||||
<ResponsiveTable
|
||||
noPagination
|
||||
isDashboard
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user