Merge branch 'release/v1.3.5'

This commit is contained in:
AmirHossein Mahmoodi
2025-05-31 15:29:39 +03:30
11 changed files with 297 additions and 144 deletions

View File

@@ -1,4 +1,4 @@
HOST="rms.witel.ir" HOST="rms.witel.ir"
NEXT_PUBLIC_VERSION="1.3.0" NEXT_PUBLIC_VERSION="1.3.5"
NEXT_PUBLIC_API_URL="https://rms.witel.ir" NEXT_PUBLIC_API_URL="https://rms.witel.ir"
NEXT_PUBLIC_MAPTILE_ENDPOINT="https://rmsmap.rmto.ir/141map" NEXT_PUBLIC_MAPTILE_ENDPOINT="https://rmsmap.rmto.ir/141map"

View File

@@ -32,29 +32,48 @@ const validationSchema = object({
province_id: number().required("لطفا استان را وارد کنید!!!"), province_id: number().required("لطفا استان را وارد کنید!!!"),
city_id: number().required("لطفا شهرستان را وارد کنید!!!"), city_id: number().required("لطفا شهرستان را وارد کنید!!!"),
axis_name: string().required("لطفا نام محور را وارد کنید!!!"), axis_name: string().required("لطفا نام محور را وارد کنید!!!"),
driver_name: string().required("لطفا نام و نام خانوادگی را وارد کنید!!!"), driver_name: string().when('isForeign', {
is: "0",
then: (schema) => schema.required("لطفا نام و نام خانوادگی را وارد کنید!!!"),
}),
phone_number: string() phone_number: string()
.matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شده و 11 رقم باشد") .when('isForeign', {
.required("لطفا تلفن همراه را وارد کنید!!!"), is: "0",
national_code: mixed() then: (schema) => schema.matches(/^09\d{9}$/, "شماره موبایل باید با 09 شروع شده و 11 رقم باشد")
.test("max", "کد ملی باید شامل 10 رقم باشد", (value) => value.toString().length === 10) .required("لطفا تلفن همراه را وارد کنید!!!"),
.test("validation", "کد ملی صحیح نمی باشد", (value) => validateNationalCode(value)) }),
.required("لطفا کد ملی را وارد کنید!!!"), national_code: mixed().when('isForeign', {
is: "0",
then: (schema) => schema.test("max", "کد ملی باید شامل 10 رقم باشد", (value) => value.toString().length === 10)
.test("validation", "کد ملی صحیح نمی باشد", (value) => validateNationalCode(value))
.required("لطفا کد ملی را وارد کنید!!!"),
}),
start_point: mixed() start_point: mixed()
.test("start-point-required", "لطفاً نقطه تصادف را مشخص کنید!", function (value) { .test("start-point-required", "لطفاً نقطه تصادف را مشخص کنید!", function (value) {
return !!value; return !!value;
}) })
.required("لطفاً نقطه تصادف را مشخص کنید!"), .required("لطفاً نقطه تصادف را مشخص کنید!"),
plate_part1: mixed() plate_part1: mixed()
.test("max", "2رقم", (value) => value.toString().length === 2) .when('isForeign', {
.required("plate_part1 الزامیست"), is: "0",
plate_part2: mixed().required("plate_part2 الزامیست"), then: (schema) => schema.test("max", "2رقم", (value) => value.toString().length === 2)
plate_part3: mixed() .required("plate_part1 الزامیست"),
.test("max", "3رقم", (value) => value.toString().length === 3) }),
.required("plate_part3الزامیست"), plate_part2: mixed().when('isForeign', {
plate_part4: mixed() is: "0",
.test("max", "2رقم", (value) => value.toString().length === 2) then: (schema) => schema.required("plate_part2 الزامیست"),
.required("plate_part4الزامیست"), }),
plate_part3: mixed().when('isForeign', {
is: "0",
then: (schema) => schema.test("max", "3رقم", (value) => value.toString().length === 3)
.required("plate_part3الزامیست"),
}),
plate_part4: mixed().when('isForeign', {
is: "0",
then: (schema) => schema.test("max", "2رقم", (value) => value.toString().length === 2)
.required("plate_part4الزامیست"),
}),
damage_picture1: mixed().nullable().required("لطفا عکس تصادف را بارگذاری کنید!"), damage_picture1: mixed().nullable().required("لطفا عکس تصادف را بارگذاری کنید!"),
damage_picture2: mixed().nullable().required("لطفا عکس تصادف را بارگذاری کنید!"), damage_picture2: mixed().nullable().required("لطفا عکس تصادف را بارگذاری کنید!"),
police_serial: string().when("radio_button", { police_serial: string().when("radio_button", {
@@ -75,6 +94,7 @@ const validationSchema = object({
const CreateFormContent = ({ setOpen, SubmitDamage, defaultData }) => { const CreateFormContent = ({ setOpen, SubmitDamage, defaultData }) => {
const defaultValues = { const defaultValues = {
isForeign: defaultData.isForeign,
accident_date: defaultData.accident_date, accident_date: defaultData.accident_date,
accident_time: defaultData.accident_time, accident_time: defaultData.accident_time,
accident_type: defaultData.accident_type, accident_type: defaultData.accident_type,

View File

@@ -1,5 +1,5 @@
import { Controller, useWatch } from "react-hook-form"; import { Controller, useWatch } from "react-hook-form";
import { Grid, Stack, TextField } from "@mui/material"; import { Grid, Stack, TextField, ToggleButton, ToggleButtonGroup } from "@mui/material";
import MuiDatePicker from "@/core/components/MuiDatePicker"; import MuiDatePicker from "@/core/components/MuiDatePicker";
import MuiTimePicker from "@/core/components/MuiTimePicker"; import MuiTimePicker from "@/core/components/MuiTimePicker";
import SelectBox from "@/core/components/SelectBox"; import SelectBox from "@/core/components/SelectBox";
@@ -11,104 +11,129 @@ import LogesticController from "./LogesticController";
const DamageInfo = ({ control, setValue, errors }) => { const DamageInfo = ({ control, setValue, errors }) => {
const StartPoint = useWatch({ control, name: "start_point" }); const StartPoint = useWatch({ control, name: "start_point" });
const IsForeign = useWatch({ control, name: "isForeign" });
return ( return (
<Stack> <Stack>
<LogesticController control={control} /> <LogesticController control={control} />
<Grid sx={{ mt: 2 }} container spacing={2}> <Stack sx={{ mt: 2 }} alignItems={'center'} justifyContent={'center'}>
<Grid item xs={12} md={6}> <Controller
<Controller name="isForeign"
name="driver_name" control={control}
control={control} render={({ field, fieldState: { error } }) => (
render={({ field, fieldState: { error } }) => ( <ToggleButtonGroup
<PersianTextField value={field.value}
value={field.value} exclusive
variant="outlined" onChange={(event, newAlignment) => field.onChange(newAlignment)}
>
<ToggleButton value="0">
ناوگان داخلی
</ToggleButton>
<ToggleButton value="1">
ناوگان خارجی
</ToggleButton>
</ToggleButtonGroup>
)}
/>
</Stack>
{IsForeign == "0" && (
<>
<Grid sx={{ mt: 2 }} container spacing={2}>
<Grid item xs={12} md={6}>
<Controller
name="driver_name" name="driver_name"
onChange={field.onChange} control={control}
label="نام و نام خانوادگی راننده" render={({ field, fieldState: { error } }) => (
placeholder={"نام و نام خانوادگی فارسی را وارد کنید"} <PersianTextField
fullWidth value={field.value}
size="small" variant="outlined"
error={error} name="driver_name"
helperText={error?.message} onChange={field.onChange}
InputLabelProps={{ shrink: true }} label="نام و نام خانوادگی راننده"
placeholder={"نام و نام خانوادگی فارسی را وارد کنید"}
fullWidth
size="small"
error={error}
helperText={error?.message}
InputLabelProps={{ shrink: true }}
/>
)}
/> />
)} </Grid>
/> <Grid item xs={12} md={6}>
</Grid> <Controller
<Grid item xs={12} md={6}>
<Controller
name="national_code"
control={control}
render={({ field, fieldState: { error } }) => (
<TextField
value={field.value}
variant="outlined"
name="national_code" name="national_code"
type={"tel"} control={control}
inputProps={{ render={({ field, fieldState: { error } }) => (
inputMode: "number", <TextField
min: 0, value={field.value}
pattern: "[0-9]*", variant="outlined"
}} name="national_code"
onChange={(event) => { type={"tel"}
const inputValue = event.target.value; inputProps={{
if (isNaN(Number(inputValue))) { inputMode: "number",
return; min: 0,
} pattern: "[0-9]*",
field.onChange(inputValue); }}
}} onChange={(event) => {
label="کد ملی راننده" const inputValue = event.target.value;
placeholder={"کد ملی راننده را وارد کنید"} if (isNaN(Number(inputValue))) {
fullWidth return;
size="small" }
error={error} field.onChange(inputValue);
helperText={error?.message} }}
InputLabelProps={{ shrink: true }} label="کد ملی راننده"
placeholder={"کد ملی راننده را وارد کنید"}
fullWidth
size="small"
error={error}
helperText={error?.message}
InputLabelProps={{ shrink: true }}
/>
)}
/> />
)} </Grid>
/> </Grid>
</Grid> <Grid sx={{ mt: 2 }} container spacing={2}>
</Grid> <Grid item xs={12} md={6}>
<Grid sx={{ mt: 2 }} container spacing={2}> <Controller
<Grid item xs={12} md={6}>
<Controller
name="phone_number"
control={control}
render={({ field, fieldState: { error } }) => (
<TextField
value={field.value}
variant="outlined"
name="phone_number" name="phone_number"
type={"tel"} control={control}
inputProps={{ render={({ field, fieldState: { error } }) => (
inputMode: "number", <TextField
min: 0, value={field.value}
pattern: "[0-9]*", variant="outlined"
}} name="phone_number"
onChange={(event) => { type={"tel"}
const inputValue = event.target.value; inputProps={{
if (isNaN(Number(inputValue))) { inputMode: "number",
return; min: 0,
} pattern: "[0-9]*",
field.onChange(inputValue); }}
}} onChange={(event) => {
label="شماره موبایل راننده" const inputValue = event.target.value;
placeholder={"شماره موبایل راننده را وارد کنید"} if (isNaN(Number(inputValue))) {
fullWidth return;
size="small" }
error={error} field.onChange(inputValue);
helperText={error?.message} }}
InputLabelProps={{ shrink: true }} label="شماره موبایل راننده"
placeholder={"شماره موبایل راننده را وارد کنید"}
fullWidth
size="small"
error={error}
helperText={error?.message}
InputLabelProps={{ shrink: true }}
/>
)}
/> />
)} </Grid>
/> <Grid item xs={12} md={6}>
</Grid> <PlateNumber control={control} />
<Grid item xs={12} md={6}> </Grid>
<PlateNumber control={control} /> </Grid>
</Grid> </>
</Grid> )}
<Grid sx={{ mt: 1 }} container spacing={2}> <Grid sx={{ mt: 1 }} container spacing={2}>
<Grid item xs={12} md={4}> <Grid item xs={12} md={4}>
<Controller <Controller

View File

@@ -22,10 +22,13 @@ const OperatorCreateForm = ({ open, setOpen, mutate }) => {
formData.append("province_id", result.province_id); formData.append("province_id", result.province_id);
formData.append("city_id", result.city_id); formData.append("city_id", result.city_id);
formData.append("axis_name", result.axis_name); formData.append("axis_name", result.axis_name);
formData.append("driver_name", result.driver_name); formData.append("is_foreign", result.isForeign);
formData.append("driver_phone_number", result.phone_number); if (result.isForeign == '0') {
formData.append("driver_national_code", result.national_code); formData.append("driver_name", result.driver_name);
formData.append("plaque", PlateNumber); formData.append("driver_phone_number", result.phone_number);
formData.append("driver_national_code", result.national_code);
formData.append("plaque", PlateNumber);
}
formData.append("damage_picture1", result.damage_picture1); formData.append("damage_picture1", result.damage_picture1);
formData.append("damage_picture2", result.damage_picture2); formData.append("damage_picture2", result.damage_picture2);
formData.append("lat", result.start_point.lat); formData.append("lat", result.start_point.lat);
@@ -51,9 +54,10 @@ const OperatorCreateForm = ({ open, setOpen, mutate }) => {
mutate(); mutate();
setOpen(false); setOpen(false);
}) })
.catch(() => {}); .catch(() => { });
}; };
const defaultData = { const defaultData = {
isForeign: "0",
accident_date: "", accident_date: "",
accident_time: "", accident_time: "",
accident_type: "", accident_type: "",

View File

@@ -21,7 +21,11 @@ const OperatorList = () => {
const { data: userPermissions } = usePermissions(); const { data: userPermissions } = usePermissions();
const hasCountryPermission = userPermissions?.includes("show-receipt"); const hasCountryPermission = userPermissions?.includes("show-receipt");
const { user } = useAuth(); const { user } = useAuth();
const foreginOptions = [
{ value: "", label: "همه ناوگان ها" },
{ value: 0, label: "داخلی" },
{ value: 1, label: "خارجی" },
];
const statusOptions = [ const statusOptions = [
{ value: "", label: "همه وضعیت ها" }, { value: "", label: "همه وضعیت ها" },
{ value: 0, label: "بدون اقدام" }, { value: 0, label: "بدون اقدام" },
@@ -158,8 +162,8 @@ const OperatorList = () => {
props.dependencyFieldValue?.value === "" props.dependencyFieldValue?.value === ""
? "empty" ? "empty"
: loadingCityList : loadingCityList
? "loading" ? "loading"
: props.filterParameters.value : props.filterParameters.value
} }
columnSelectOption={getColumnSelectOptions} columnSelectOption={getColumnSelectOptions}
/> />
@@ -179,6 +183,25 @@ const OperatorList = () => {
grow: false, grow: false,
size: 120, size: 120,
}, },
{
accessorKey: "is_foreign",
header: "نوع ناوگان",
id: "is_foreign",
enableColumnFilter: true,
datatype: "numeric",
filterMode: "equals",
grow: false,
size: 100,
columnSelectOption: () => {
return foreginOptions.map((status) => ({
value: status.value,
label: status.label,
}));
},
Cell: ({ row }) => {
return <Typography variant={"body2"}>{row.original.is_foreign == "0" ? "داخلی" : "خارجی"}</Typography>;
},
},
{ {
accessorKey: "driver_name", accessorKey: "driver_name",
header: "نام راننده", header: "نام راننده",
@@ -225,7 +248,7 @@ const OperatorList = () => {
enableSorting: false, enableSorting: false,
grow: false, grow: false,
size: 100, size: 100,
Cell: ({ renderedCellValue }) => <ShowPlate plate={renderedCellValue} />, Cell: ({ row, renderedCellValue }) => row.original.is_foreign == "0" ? <ShowPlate plate={renderedCellValue} /> : '',
}, },
{ {
accessorKey: "accident_type", accessorKey: "accident_type",

View File

@@ -23,10 +23,10 @@ const RowActions = ({ row, mutate }) => {
<RegisterInsurance mutate={mutate} row={row} rowId={row.getValue("id")} /> <RegisterInsurance mutate={mutate} row={row} rowId={row.getValue("id")} />
)} )}
{[0, 1, 2].includes(row.original?.status) && <SendToInsurance mutate={mutate} rowId={row.getValue("id")} />} {[0, 1, 2].includes(row.original?.status) && <SendToInsurance mutate={mutate} rowId={row.getValue("id")} />}
{hasEditPermission && [0, 1, 2].includes(row.original?.status) && ( {hasEditPermission && [0].includes(row.original?.status) && (
<EditForm row={row} mutate={mutate} rowId={row.getValue("id")} /> <EditForm row={row} mutate={mutate} rowId={row.getValue("id")} />
)} )}
{hasDeletePermission && <DeleteDialog mutate={mutate} rowId={row.getValue("id")} />} {(hasDeletePermission && [0].includes(row.original?.status)) && <DeleteDialog mutate={mutate} rowId={row.getValue("id")} />}
</Box> </Box>
); );
}; };

View File

@@ -18,30 +18,111 @@ const ReportLists = ({ data, specialFilter }) => {
size: 50, size: 50,
}, },
{ {
accessorKey: "tedade", header: "تعداد خسارات ثبت شده",
header: "تعداد کل", id: 'countAll',
id: "tedade",
enableColumnFilter: false, enableColumnFilter: false,
enableSorting: false, enableSorting: false,
datatype: "text", datatype: "text",
grow: false, grow: false,
size: 50, size: 50,
muiTableBodyCellProps: { columns: [
sx: { {
textAlign: "center", accessorKey: "tedade",
borderLeft: "1px solid #e1e1e1", header: "کل",
py: 0, id: "tedade",
"&:first-of-type": { enableColumnFilter: false,
borderLeft: "unset", enableSorting: false,
datatype: "text",
grow: false,
size: 50,
muiTableBodyCellProps: {
sx: {
textAlign: "center",
borderLeft: "1px solid #e1e1e1",
py: 0,
"&:first-of-type": {
borderLeft: "unset",
},
},
},
Cell: ({ renderedCellValue }) => {
return (renderedCellValue / 1).toLocaleString();
}, },
}, },
}, {
Cell: ({ renderedCellValue }) => { accessorKey: "egdam",
return (renderedCellValue / 1).toLocaleString(); header: "در دست اقدام",
}, id: "egdam",
enableColumnFilter: false,
enableSorting: false,
datatype: "text",
grow: false,
size: 50,
muiTableBodyCellProps: {
sx: {
textAlign: "center",
borderLeft: "1px solid #e1e1e1",
py: 0,
"&:first-of-type": {
borderLeft: "unset",
},
},
},
Cell: ({ renderedCellValue }) => {
return (renderedCellValue / 1).toLocaleString();
},
},
{
accessorKey: "pardakht",
header: "در حال پرداخت",
id: "pardakht",
enableColumnFilter: false,
enableSorting: false,
datatype: "text",
grow: false,
size: 50,
muiTableBodyCellProps: {
sx: {
textAlign: "center",
borderLeft: "1px solid #e1e1e1",
py: 0,
"&:first-of-type": {
borderLeft: "unset",
},
},
},
Cell: ({ renderedCellValue }) => {
return (renderedCellValue / 1).toLocaleString();
},
},
{
accessorKey: "khatm",
header: "خاتمه یافته",
id: "khatm",
enableColumnFilter: false,
enableSorting: false,
datatype: "text",
grow: false,
size: 50,
muiTableBodyCellProps: {
sx: {
textAlign: "center",
borderLeft: "1px solid #e1e1e1",
py: 0,
"&:first-of-type": {
borderLeft: "unset",
},
},
},
Cell: ({ renderedCellValue }) => {
return (renderedCellValue / 1).toLocaleString();
},
},
]
}, },
{ {
header: "تعداد نحوه شناسایی خسارت", header: "تعداد نحوه شناسایی خسارت",
id: 'police_rah_All',
enableColumnFilter: false, enableColumnFilter: false,
enableSorting: false, enableSorting: false,
datatype: "text", datatype: "text",
@@ -152,7 +233,7 @@ const ReportLists = ({ data, specialFilter }) => {
columns: [ columns: [
{ {
accessorKey: "vasel_shode_final", accessorKey: "vasel_shode_final",
header: یش", header: اکتور",
id: "vasel_shode_final", id: "vasel_shode_final",
enableColumnFilter: false, enableColumnFilter: false,
enableSorting: false, enableSorting: false,

View File

@@ -240,7 +240,7 @@ const ComplaintListTable = ({ open, setOpen, mutate }) => {
accessorFn: (row) => moment(row.StartTime_DateTime).locale("fa").format("HH:mm | yyyy/MM/DD"), accessorFn: (row) => moment(row.StartTime_DateTime).locale("fa").format("HH:mm | yyyy/MM/DD"),
header: "تاریخ ثبت", header: "تاریخ ثبت",
id: "StartTime_DateTime", id: "StartTime_DateTime",
enableColumnFilter: false, enableColumnFilter: true,
datatype: "date", datatype: "date",
filterMode: "between", filterMode: "between",
grow: false, grow: false,

View File

@@ -152,7 +152,7 @@ const OperatorList = () => {
accessorFn: (row) => moment(row.StartTime_DateTime).locale("fa").format("HH:mm | yyyy/MM/DD"), accessorFn: (row) => moment(row.StartTime_DateTime).locale("fa").format("HH:mm | yyyy/MM/DD"),
header: "تاریخ ثبت", header: "تاریخ ثبت",
id: "StartTime_DateTime", id: "StartTime_DateTime",
enableColumnFilter: false, enableColumnFilter: true,
datatype: "date", datatype: "date",
filterMode: "between", filterMode: "between",
grow: false, grow: false,

View File

@@ -253,7 +253,7 @@ const SupervisorList = () => {
accessorFn: (row) => moment(row.StartTime_DateTime).locale("fa").format("HH:mm | yyyy/MM/DD"), accessorFn: (row) => moment(row.StartTime_DateTime).locale("fa").format("HH:mm | yyyy/MM/DD"),
header: "تاریخ ثبت", header: "تاریخ ثبت",
id: "StartTime_DateTime", id: "StartTime_DateTime",
enableColumnFilter: false, enableColumnFilter: true,
datatype: "date", datatype: "date",
filterMode: "between", filterMode: "between",
grow: false, grow: false,

View File

@@ -114,19 +114,19 @@ export const EXPORT_PROVINCE_RECEIPT_REPORT = api + "/api/v3/receipt_reports/pro
export const ACTIVITY_LOG = api + "/api/v3/profile/add_activity"; export const ACTIVITY_LOG = api + "/api/v3/profile/add_activity";
// fast react // fast react
export const GET_FAST_REACT_SUPERVISOR = api + "/api/v3/road_observations/supervisor_index"; export const GET_FAST_REACT_SUPERVISOR = api + "/api/v3/road_observations/supervisor/index";
export const GET_FAST_REACT_COMPLAINTS = api + "/api/v3/road_observations/complaints_index"; export const GET_FAST_REACT_COMPLAINTS = api + "/api/v3/road_observations/complaints_index";
export const VERIFY_BY_FAST_REACT_SUPERVISOR = api + "/api/v3/road_observations/verify"; export const VERIFY_BY_FAST_REACT_SUPERVISOR = api + "/api/v3/road_observations/supervisor/verify";
export const REJECT_BY_FAST_REACT_SUPERVISOR = api + "/api/v3/road_observations/verify"; export const REJECT_BY_FAST_REACT_SUPERVISOR = api + "/api/v3/road_observations/supervisor/verify";
export const REGISTER_COMPLAINTS_LIST = api + "/api/v3/road_observations/register"; export const REGISTER_COMPLAINTS_LIST = api + "/api/v3/road_observations/operator/register";
export const GET_FAST_REACT_OPERATOR = api + "/api/v3/road_observations/operator_index"; export const GET_FAST_REACT_OPERATOR = api + "/api/v3/road_observations/operator/cartable";
export const GET_FAST_REACT_REFER_LIST = api + "/api/v3/road_observations/refer_list"; export const GET_FAST_REACT_REFER_LIST = api + "/api/v3/road_observations/refer_list";
export const REFER_FAST_REACT = api + "/api/v3/road_observations/refer"; export const REFER_FAST_REACT = api + "/api/v3/road_observations/refer";
export const RESTORE_FAST_REACT = api + "/api/v3/road_observations/restore"; export const RESTORE_FAST_REACT = api + "/api/v3/road_observations/supervisor/restore";
export const GET_FAST_REACT_ITEM_DETAIL = api + "/api/v3/road_observations"; export const GET_FAST_REACT_ITEM_DETAIL = api + "/api/v3/road_observations";
export const UPDATE_FAST_REACT = api + "/api/v3/road_observations/modify_registration"; export const UPDATE_FAST_REACT = api + "/api/v3/road_observations/operator/modify_registration";
export const EXPORT_FAST_REACT_SUPERVISOR_LIST = api + "/api/v3/road_observations/supervisor_report"; export const EXPORT_FAST_REACT_SUPERVISOR_LIST = api + "/api/v3/road_observations/supervisor/report";
export const EXPORT_FAST_REACT_OPERATOR_LIST = api + "/api/v3/road_observations/operator_report"; export const EXPORT_FAST_REACT_OPERATOR_LIST = api + "/api/v3/road_observations/operator/report";
export const EXPORT_FAST_REACT_COMPLAINT_LIST = api + "/api/v3/road_observations/complaints_report"; export const EXPORT_FAST_REACT_COMPLAINT_LIST = api + "/api/v3/road_observations/complaints_report";
// road safety // road safety