Compare commits
14 Commits
cb87251d62
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
| f8d2da4f28 | |||
| bb1d5b3315 | |||
| d8d415a8f5 | |||
| f58c8e6c58 | |||
| 3a17fcb448 | |||
| 6e219aca1a | |||
| 9b74be078f | |||
| 5fd55c4b10 | |||
| 6b5276ce36 | |||
| e465843eb9 | |||
| e5402f9037 | |||
| e342a7cdd5 | |||
| f5de2f68b5 | |||
| 44ea5974eb |
150
src/Pages/TagDistributionDetails.tsx
Normal file
150
src/Pages/TagDistributionDetails.tsx
Normal file
@@ -0,0 +1,150 @@
|
||||
import { useParams } from "@tanstack/react-router";
|
||||
import { Bars3Icon, CubeIcon, SparklesIcon } from "@heroicons/react/24/outline";
|
||||
import { useApiRequest } from "../utils/useApiRequest";
|
||||
import { formatJustDate, formatJustTime } from "../utils/formatTime";
|
||||
import ShowMoreInfo from "../components/ShowMoreInfo/ShowMoreInfo";
|
||||
import { Grid } from "../components/Grid/Grid";
|
||||
import Typography from "../components/Typography/Typography";
|
||||
import Table from "../components/Table/Table";
|
||||
|
||||
const speciesMap: Record<number, string> = {
|
||||
1: "گاو",
|
||||
2: "گاومیش",
|
||||
3: "شتر",
|
||||
4: "گوسفند",
|
||||
5: "بز",
|
||||
};
|
||||
|
||||
export default function TagDistribtutionDetails() {
|
||||
const { id } = useParams({ strict: false });
|
||||
|
||||
const { data } = useApiRequest({
|
||||
api: `/tag/web/api/v1/tag_distribution_batch/${id}/`,
|
||||
method: "get",
|
||||
queryKey: ["tagBatchInnerDashboard", id],
|
||||
enabled: !!id,
|
||||
});
|
||||
|
||||
const dist = data?.distributions;
|
||||
|
||||
return (
|
||||
<Grid container column className="gap-4 mt-2">
|
||||
<Grid isDashboard>
|
||||
<Table
|
||||
isDashboard
|
||||
title="مشخصات توزیع پلاک"
|
||||
noSearch
|
||||
noPagination
|
||||
columns={[
|
||||
"شناسه توزیع",
|
||||
"تاریخ ثبت",
|
||||
"توزیع کننده",
|
||||
"دریافت کننده",
|
||||
"تعداد کل پلاک",
|
||||
"پلاک های توزیع شده",
|
||||
"پلاک های باقیمانده",
|
||||
"نوع توزیع",
|
||||
"جزئیات توزیع",
|
||||
]}
|
||||
rows={[
|
||||
[
|
||||
data?.dist_batch_identity ?? "-",
|
||||
`${formatJustDate(data?.create_date) ?? "-"} (${
|
||||
formatJustDate(data?.create_date)
|
||||
? (formatJustTime(data?.create_date) ?? "-")
|
||||
: "-"
|
||||
})`,
|
||||
data?.assigner_org?.name ?? "-",
|
||||
data?.assigned_org?.name ?? "-",
|
||||
data?.total_tag_count?.toLocaleString() ?? "-",
|
||||
data?.total_distributed_tag_count?.toLocaleString() ?? "-",
|
||||
data?.remaining_tag_count?.toLocaleString() ?? "-",
|
||||
data?.distribution_type === "batch"
|
||||
? "توزیع گروهی"
|
||||
: "توزیع تصادفی",
|
||||
<ShowMoreInfo key={data?.id} title="جزئیات توزیع">
|
||||
<Grid container column className="gap-4 w-full">
|
||||
{dist?.map((opt: any, index: number) => (
|
||||
<Grid
|
||||
key={index}
|
||||
container
|
||||
column
|
||||
className="gap-3 w-full rounded-xl border border-gray-200 dark:border-gray-700 p-4"
|
||||
>
|
||||
<Grid container className="gap-2 items-center">
|
||||
<SparklesIcon className="w-5 h-5 text-gray-500 dark:text-gray-300" />
|
||||
<Typography variant="body2" className="font-medium">
|
||||
گونه:
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="body2"
|
||||
className="text-gray-700 dark:text-gray-300"
|
||||
>
|
||||
{speciesMap[opt?.species_code] ?? "-"}
|
||||
</Typography>
|
||||
</Grid>
|
||||
|
||||
{data?.distribution_type === "batch" &&
|
||||
opt?.serial_from != null && (
|
||||
<Grid container className="gap-2 items-center">
|
||||
<Bars3Icon className="w-5 h-5 text-gray-500 dark:text-gray-300" />
|
||||
<Typography variant="body2" className="font-medium">
|
||||
بازه سریال:
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="body2"
|
||||
className="text-gray-600 dark:text-gray-400"
|
||||
>
|
||||
از {opt?.serial_from ?? "-"} تا{" "}
|
||||
{opt?.serial_to ?? "-"}
|
||||
</Typography>
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
<Grid container className="gap-2 items-center">
|
||||
<CubeIcon className="w-5 h-5 text-gray-500 dark:text-gray-300" />
|
||||
<Typography variant="body2" className="font-medium">
|
||||
تعداد پلاک:
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="body2"
|
||||
className="text-gray-700 dark:text-gray-300"
|
||||
>
|
||||
{opt?.total_tag_count?.toLocaleString() ?? "-"}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid container className="gap-2 items-center">
|
||||
<CubeIcon className="w-5 h-5 text-gray-500 dark:text-gray-300" />
|
||||
<Typography variant="body2" className="font-medium">
|
||||
پلاک های توزیع شده:
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="body2"
|
||||
className="text-gray-700 dark:text-gray-300"
|
||||
>
|
||||
{opt?.distributed_number?.toLocaleString() ?? "-"}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid container className="gap-2 items-center">
|
||||
<CubeIcon className="w-5 h-5 text-gray-500 dark:text-gray-300" />
|
||||
<Typography variant="body2" className="font-medium">
|
||||
پلاک های باقیمانده:
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="body2"
|
||||
className="text-gray-700 dark:text-gray-300"
|
||||
>
|
||||
{opt?.remaining_number?.toLocaleString() ?? "-"}
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
</ShowMoreInfo>,
|
||||
],
|
||||
]}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
@@ -62,14 +62,14 @@ export default function Tagging() {
|
||||
item?.species_code === 1
|
||||
? "گاو"
|
||||
: item?.species_code === 2
|
||||
? "گاومیش"
|
||||
: item?.species_code === 3
|
||||
? "شتر"
|
||||
: item?.species_code === 4
|
||||
? "گوسفند"
|
||||
: item?.species_code === 5
|
||||
? "بز"
|
||||
: "نامشخص",
|
||||
? "گاومیش"
|
||||
: item?.species_code === 3
|
||||
? "شتر"
|
||||
: item?.species_code === 4
|
||||
? "گوسفند"
|
||||
: item?.species_code === 5
|
||||
? "بز"
|
||||
: "نامشخص",
|
||||
item?.serial_from || "-",
|
||||
item?.serial_to || "-",
|
||||
item?.total_distributed_tags || 0,
|
||||
@@ -167,6 +167,7 @@ export default function Tagging() {
|
||||
columns={[
|
||||
"تعداد گروه پلاک",
|
||||
"پلاکهای تولیدشده",
|
||||
"گروه پلاک های دارای توزیع",
|
||||
"پلاک توزیع شده",
|
||||
"پلاک باقیمانده",
|
||||
"جزئیات گونه ها",
|
||||
@@ -176,6 +177,8 @@ export default function Tagging() {
|
||||
tagDashboardData?.batch_count?.toLocaleString() || 0,
|
||||
tagDashboardData?.tag_count_created_by_batch?.toLocaleString() ||
|
||||
0,
|
||||
tagDashboardData?.has_distributed_batches_number?.toLocaleString() ||
|
||||
0,
|
||||
tagDashboardData?.total_distributed_tags?.toLocaleString() || 0,
|
||||
tagDashboardData?.total_remaining_tags?.toLocaleString() || 0,
|
||||
<TableButton
|
||||
|
||||
@@ -10,6 +10,7 @@ import { DeleteButtonForPopOver } from "../components/PopOverButtons/PopOverButt
|
||||
import { TagDetails } from "../partials/tagging/TagDetails";
|
||||
import { useParams } from "@tanstack/react-router";
|
||||
import { TableButton } from "../components/TableButton/TableButton";
|
||||
import AutoComplete from "../components/AutoComplete/AutoComplete";
|
||||
|
||||
const speciesMap: Record<number, string> = {
|
||||
1: "گاو",
|
||||
@@ -19,18 +20,26 @@ const speciesMap: Record<number, string> = {
|
||||
5: "بز",
|
||||
};
|
||||
|
||||
const statusOptions = [
|
||||
{ key: "F", value: "آزاد" },
|
||||
{ key: "A", value: "پلاک شده" },
|
||||
{ key: "R", value: "رزرو" },
|
||||
];
|
||||
|
||||
export default function Tags() {
|
||||
const { openModal } = useModalStore();
|
||||
const [tableInfo, setTableInfo] = useState({ page: 1, page_size: 10 });
|
||||
const [tagsTableData, setTagsTableData] = useState([]);
|
||||
const { id, from, to } = useParams({ strict: false });
|
||||
const [selectedStatus, setSelectedStatus] = useState<(string | number)[]>([]);
|
||||
|
||||
const { data: tagsData, refetch } = useApiRequest({
|
||||
api: `/tag/web/api/v1/tag/${id ? id + "/tags_by_batch" : ""}`,
|
||||
method: "get",
|
||||
queryKey: ["tagsList", tableInfo],
|
||||
queryKey: ["tagsList", tableInfo, selectedStatus],
|
||||
params: {
|
||||
...tableInfo,
|
||||
status: selectedStatus.length ? selectedStatus[0] : undefined,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -236,6 +245,17 @@ export default function Tags() {
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
<Grid container className="items-center gap-2">
|
||||
<Grid>
|
||||
<AutoComplete
|
||||
data={statusOptions}
|
||||
selectedKeys={selectedStatus}
|
||||
onChange={setSelectedStatus}
|
||||
title="فیلتر پلاک ها"
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Table
|
||||
className="mt-2"
|
||||
onChange={setTableInfo}
|
||||
|
||||
@@ -7,6 +7,7 @@ import React, {
|
||||
} from "react";
|
||||
import clsx from "clsx";
|
||||
import {
|
||||
ArrowUpCircleIcon,
|
||||
ChartBarIcon,
|
||||
DocumentChartBarIcon,
|
||||
EyeIcon,
|
||||
@@ -56,7 +57,8 @@ type ButtonProps = {
|
||||
| "view"
|
||||
| "info"
|
||||
| "chart"
|
||||
| "set";
|
||||
| "set"
|
||||
| "share";
|
||||
page?: string;
|
||||
access?: string;
|
||||
height?: string | number;
|
||||
@@ -161,6 +163,10 @@ const Button: React.FC<ButtonProps> = ({
|
||||
return (
|
||||
<WrenchIcon className="w-5 h-5 text-purple-400 dark:text-purple-100" />
|
||||
);
|
||||
case "share":
|
||||
return (
|
||||
<ArrowUpCircleIcon className="w-5 h-5 text-purple-400 dark:text-purple-100" />
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -181,7 +187,7 @@ const Button: React.FC<ButtonProps> = ({
|
||||
return true;
|
||||
} else {
|
||||
const finded = profile?.permissions?.find(
|
||||
(item: any) => item.page_name === page
|
||||
(item: any) => item.page_name === page,
|
||||
);
|
||||
if (finded && finded.page_access.includes(access)) {
|
||||
return true;
|
||||
@@ -237,7 +243,7 @@ const Button: React.FC<ButtonProps> = ({
|
||||
sizeStyles.padding,
|
||||
sizeStyles.text,
|
||||
className,
|
||||
checkIsMobile() && !icon && !variant && children && mobileBorders
|
||||
checkIsMobile() && !icon && !variant && children && mobileBorders,
|
||||
)}
|
||||
style={{ height }}
|
||||
>
|
||||
@@ -256,7 +262,7 @@ const Button: React.FC<ButtonProps> = ({
|
||||
.then((response) => {
|
||||
closeBackdrop();
|
||||
const url = window.URL.createObjectURL(
|
||||
new Blob([response.data])
|
||||
new Blob([response.data]),
|
||||
);
|
||||
|
||||
const link = document.createElement("a");
|
||||
|
||||
254
src/partials/tagging/DistributeFromDistribution.tsx
Normal file
254
src/partials/tagging/DistributeFromDistribution.tsx
Normal file
@@ -0,0 +1,254 @@
|
||||
import { z } from "zod";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { Grid } from "../../components/Grid/Grid";
|
||||
import Button from "../../components/Button/Button";
|
||||
import Textfield from "../../components/Textfeild/Textfeild";
|
||||
import { FormApiBasedAutoComplete } from "../../components/FormItems/FormApiBasedAutoComplete";
|
||||
import AutoComplete from "../../components/AutoComplete/AutoComplete";
|
||||
import { zValidateAutoComplete } from "../../data/getFormTypeErrors";
|
||||
import { useApiMutation, useApiRequest } from "../../utils/useApiRequest";
|
||||
import { useToast } from "../../hooks/useToast";
|
||||
import { useModalStore } from "../../context/zustand-store/appStore";
|
||||
|
||||
const schema = z.object({
|
||||
organization: zValidateAutoComplete("سازمان"),
|
||||
});
|
||||
|
||||
type FormValues = z.infer<typeof schema>;
|
||||
|
||||
type ParentDistItem = {
|
||||
id: number;
|
||||
dist_identity?: number;
|
||||
batch_identity: string | number | null;
|
||||
species_code: number;
|
||||
maxCount: number;
|
||||
label?: string;
|
||||
};
|
||||
|
||||
export const DistributeFromDistribution = ({ item, getData }: any) => {
|
||||
const showToast = useToast();
|
||||
const { closeModal } = useModalStore();
|
||||
|
||||
const [dists, setDists] = useState<ParentDistItem[]>([]);
|
||||
const [selectedSpeciesKeys, setSelectedSpeciesKeys] = useState<
|
||||
(string | number)[]
|
||||
>([]);
|
||||
const [counts, setCounts] = useState<Record<number, number | "">>({});
|
||||
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
setValue,
|
||||
trigger,
|
||||
formState: { errors },
|
||||
} = useForm<FormValues>({
|
||||
resolver: zodResolver(schema),
|
||||
defaultValues: {
|
||||
organization: [],
|
||||
},
|
||||
});
|
||||
|
||||
const { data: batchDetail } = useApiRequest({
|
||||
api: `/tag/web/api/v1/tag_distribution_batch/${item?.id}/`,
|
||||
method: "get",
|
||||
queryKey: ["tagDistributionBatchDetail", item?.id],
|
||||
enabled: !!item?.id,
|
||||
});
|
||||
|
||||
const mutation = useApiMutation({
|
||||
api: `/tag/web/api/v1/tag_distribution/${item?.id}/distribute_distribution/`,
|
||||
method: "post",
|
||||
});
|
||||
|
||||
const { data: speciesData } = useApiRequest({
|
||||
api: "/livestock/web/api/v1/livestock_species",
|
||||
method: "get",
|
||||
params: { page: 1, pageSize: 1000 },
|
||||
queryKey: ["species"],
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const sourceDistributions = item?.distributions?.length
|
||||
? item.distributions
|
||||
: batchDetail?.distributions;
|
||||
|
||||
if (!sourceDistributions?.length) {
|
||||
setDists([]);
|
||||
setCounts({});
|
||||
return;
|
||||
}
|
||||
|
||||
const parentDists: ParentDistItem[] = sourceDistributions.map((d: any) => {
|
||||
const maxCount = d?.remaining_number || 0;
|
||||
return {
|
||||
id: d?.id ?? d?.dist_identity,
|
||||
dist_identity: d?.dist_identity,
|
||||
batch_identity: d?.batch_identity ?? null,
|
||||
species_code: d?.species_code,
|
||||
maxCount: Number(maxCount) || 0,
|
||||
label:
|
||||
d?.serial_from != null && d?.serial_to != null
|
||||
? `از ${d.serial_from} تا ${d.serial_to}`
|
||||
: undefined,
|
||||
};
|
||||
});
|
||||
|
||||
setDists(parentDists);
|
||||
setCounts({});
|
||||
setSelectedSpeciesKeys([]);
|
||||
}, [item?.distributions, batchDetail?.distributions]);
|
||||
|
||||
const speciesOptions = () =>
|
||||
speciesData?.results?.map((opt: any) => ({
|
||||
key: opt?.value,
|
||||
value: opt?.name,
|
||||
})) ?? [];
|
||||
|
||||
const getSpeciesName = (speciesCode: number) =>
|
||||
speciesOptions().find((s: any) => s.key === speciesCode)?.value ?? "نامشخص";
|
||||
|
||||
const visibleDists = dists.filter((d) =>
|
||||
selectedSpeciesKeys.includes(d.species_code),
|
||||
);
|
||||
|
||||
const onSubmit = async (data: FormValues) => {
|
||||
const distsPayload = visibleDists
|
||||
.filter((d) => {
|
||||
const c = counts[d.id];
|
||||
return c !== "" && c !== undefined && c !== null && Number(c) > 0;
|
||||
})
|
||||
.map((d) => {
|
||||
const fromItem = item?.distributions?.find(
|
||||
(x: any) => x.id === d.id || x.dist_identity === d.id,
|
||||
);
|
||||
const batch_identity =
|
||||
fromItem != null ? fromItem.batch_identity : d.batch_identity;
|
||||
return {
|
||||
parent_tag_distribution: d.id,
|
||||
batch_identity: batch_identity != null ? batch_identity : null,
|
||||
species_code: d.species_code,
|
||||
count: Number(counts[d.id] ?? 0),
|
||||
};
|
||||
});
|
||||
|
||||
if (distsPayload.length === 0) {
|
||||
showToast("حداقل یک گونه با تعداد معتبر وارد کنید", "error");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await mutation.mutateAsync({
|
||||
assigned_org: data.organization[0],
|
||||
parent_distribution_batch: item.id,
|
||||
dists: distsPayload,
|
||||
});
|
||||
|
||||
showToast("توزیع از توزیع با موفقیت انجام شد", "success");
|
||||
getData();
|
||||
closeModal();
|
||||
} catch (error: any) {
|
||||
showToast(
|
||||
error?.response?.data?.message || "خطا در ثبت اطلاعات!",
|
||||
"error",
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCountChange = (distId: number, value: number | "") => {
|
||||
setCounts((prev) => ({ ...prev, [distId]: value }));
|
||||
};
|
||||
|
||||
const isValidCount = (dist: ParentDistItem) => {
|
||||
const c = counts[dist.id];
|
||||
if (c === "" || c === undefined || c === null) return false;
|
||||
const num = Number(c);
|
||||
return num > 0 && num <= dist.maxCount;
|
||||
};
|
||||
|
||||
const speciesOptionsFromParent = () => {
|
||||
const uniqueSpecies = Array.from(
|
||||
new Map(dists.map((d) => [d.species_code, d])).values(),
|
||||
);
|
||||
return uniqueSpecies.map((d) => ({
|
||||
key: d.species_code,
|
||||
value: getSpeciesName(d.species_code),
|
||||
}));
|
||||
};
|
||||
|
||||
const hasValidDists =
|
||||
visibleDists.length > 0 && visibleDists.every((d) => isValidCount(d));
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<Grid container column className="gap-3">
|
||||
<Controller
|
||||
name="organization"
|
||||
control={control}
|
||||
render={() => (
|
||||
<FormApiBasedAutoComplete
|
||||
title="انتخاب سازمان (دریافتکننده)"
|
||||
api={`auth/api/v1/organization/organizations_by_province?exclude=PSP&province=${item?.assigner_org?.province}`}
|
||||
keyField="id"
|
||||
valueField="name"
|
||||
error={!!errors.organization}
|
||||
errorMessage={errors.organization?.message}
|
||||
onChange={(r) => {
|
||||
setValue("organization", [r]);
|
||||
trigger("organization");
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
{dists.length > 0 && speciesData?.results && (
|
||||
<>
|
||||
<AutoComplete
|
||||
data={speciesOptionsFromParent()}
|
||||
multiselect
|
||||
selectedKeys={selectedSpeciesKeys}
|
||||
onChange={(keys: (string | number)[]) => {
|
||||
setSelectedSpeciesKeys(keys);
|
||||
}}
|
||||
title="گونه"
|
||||
/>
|
||||
{visibleDists.map((dist) => {
|
||||
const countVal = counts[dist.id];
|
||||
const numCount =
|
||||
countVal !== "" && countVal !== undefined && countVal !== null
|
||||
? Number(countVal)
|
||||
: null;
|
||||
const isOverMax = numCount !== null && numCount > dist.maxCount;
|
||||
const isEmpty = countVal === "" || countVal === undefined;
|
||||
const helperText = isOverMax
|
||||
? `تعداد نباید بیشتر از ${dist.maxCount.toLocaleString()} باشد`
|
||||
: isEmpty
|
||||
? "لطفا تعداد را وارد کنید"
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<Textfield
|
||||
key={dist.id}
|
||||
fullWidth
|
||||
formattedNumber
|
||||
placeholder={`تعداد ${getSpeciesName(dist.species_code)}${dist.label ? ` (${dist.label})` : ""} — حداکثر: ${dist.maxCount.toLocaleString()}`}
|
||||
value={counts[dist.id] ?? ""}
|
||||
onChange={(e) =>
|
||||
handleCountChange(dist.id, Number(e.target.value))
|
||||
}
|
||||
error={isOverMax}
|
||||
helperText={helperText}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
)}
|
||||
|
||||
<Button disabled={!hasValidDists} type="submit">
|
||||
ثبت
|
||||
</Button>
|
||||
</Grid>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
@@ -42,7 +42,7 @@ export const SubmitTagDistribution = ({ item, getData }: any) => {
|
||||
? item?.distribution_type === "random"
|
||||
? "random"
|
||||
: "group"
|
||||
: "group"
|
||||
: "group",
|
||||
);
|
||||
const [batches, setBatches] = useState<BatchItem[]>([]);
|
||||
|
||||
@@ -116,25 +116,25 @@ export const SubmitTagDistribution = ({ item, getData }: any) => {
|
||||
|
||||
showToast(
|
||||
isEdit ? "ویرایش با موفقیت انجام شد" : "ثبت با موفقیت انجام شد",
|
||||
"success"
|
||||
"success",
|
||||
);
|
||||
getData();
|
||||
closeModal();
|
||||
} catch (error: any) {
|
||||
showToast(
|
||||
error?.response?.data?.message || "خطا در ثبت اطلاعات!",
|
||||
"error"
|
||||
"error",
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const speciesOptions = () => {
|
||||
return speciesData?.results?.map((opt: any) => {
|
||||
return {
|
||||
return (
|
||||
speciesData?.results?.map((opt: any) => ({
|
||||
key: opt?.value,
|
||||
value: opt?.name,
|
||||
};
|
||||
});
|
||||
})) ?? []
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -195,14 +195,14 @@ export const SubmitTagDistribution = ({ item, getData }: any) => {
|
||||
items?.map((r: any) => {
|
||||
const existing = batches.find(
|
||||
(b) =>
|
||||
b.batch_identity === r.key1 && b.species_code === r.key2
|
||||
b.batch_identity === r.key1 && b.species_code === r.key2,
|
||||
);
|
||||
return {
|
||||
batch_identity: r.key1,
|
||||
species_code: r.key2,
|
||||
count: existing?.count ?? "",
|
||||
};
|
||||
}) || []
|
||||
}) || [],
|
||||
);
|
||||
}}
|
||||
onChangeValue={(labels) => {
|
||||
@@ -210,7 +210,7 @@ export const SubmitTagDistribution = ({ item, getData }: any) => {
|
||||
prev.map((item, index) => ({
|
||||
...item,
|
||||
label: labels[index],
|
||||
}))
|
||||
})),
|
||||
);
|
||||
}}
|
||||
/>
|
||||
@@ -229,7 +229,7 @@ export const SubmitTagDistribution = ({ item, getData }: any) => {
|
||||
species_code: k as number,
|
||||
count: prev?.count ?? "",
|
||||
};
|
||||
})
|
||||
}),
|
||||
);
|
||||
}}
|
||||
title="گونه"
|
||||
@@ -245,12 +245,12 @@ export const SubmitTagDistribution = ({ item, getData }: any) => {
|
||||
distributionType === "group"
|
||||
? `تعداد ${
|
||||
speciesOptions().find(
|
||||
(s: any) => s.key === batch.species_code
|
||||
(s: any) => s.key === batch.species_code,
|
||||
)?.value
|
||||
} (${batch.label}) `
|
||||
: `تعداد ${
|
||||
speciesOptions().find(
|
||||
(s: any) => s.key === batch.species_code
|
||||
(s: any) => s.key === batch.species_code,
|
||||
)?.value
|
||||
}`
|
||||
}
|
||||
@@ -271,7 +271,7 @@ export const SubmitTagDistribution = ({ item, getData }: any) => {
|
||||
b.count === "" ||
|
||||
b.count === undefined ||
|
||||
b.count === null ||
|
||||
Number(b.count) <= 0
|
||||
Number(b.count) <= 0,
|
||||
)
|
||||
}
|
||||
type="submit"
|
||||
|
||||
@@ -16,15 +16,19 @@ import Button from "../../components/Button/Button";
|
||||
import { Tooltip } from "../../components/Tooltip/Tooltip";
|
||||
import { DeleteButtonForPopOver } from "../../components/PopOverButtons/PopOverButtons";
|
||||
import { SubmitTagDistribution } from "./SubmitTagDistribution";
|
||||
import { DistributeFromDistribution } from "./DistributeFromDistribution";
|
||||
import Table from "../../components/Table/Table";
|
||||
import { BooleanQuestion } from "../../components/BooleanQuestion/BooleanQuestion";
|
||||
import { TableButton } from "../../components/TableButton/TableButton";
|
||||
import { DistributionSpeciesModal } from "./DistributionSpeciesModal";
|
||||
import { useNavigate } from "@tanstack/react-router";
|
||||
import { TAG_DISTRIBUTION } from "../../routes/paths";
|
||||
|
||||
export default function TagActiveDistributions() {
|
||||
const { openModal } = useModalStore();
|
||||
const [tableInfo, setTableInfo] = useState({ page: 1, page_size: 10 });
|
||||
const [tagsTableData, setTagsTableData] = useState([]);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { data: tagsData, refetch } = useApiRequest({
|
||||
api: "/tag/web/api/v1/tag_distribution_batch",
|
||||
@@ -71,6 +75,8 @@ export default function TagActiveDistributions() {
|
||||
item?.assigner_org?.name,
|
||||
item?.assigned_org?.name,
|
||||
item?.total_tag_count,
|
||||
item?.total_distributed_tag_count,
|
||||
item?.remaining_tag_count,
|
||||
item?.distribution_type === "batch" ? "توزیع گروهی" : "توزیع تصادفی",
|
||||
<ShowMoreInfo key={item?.id} title="جزئیات توزیع">
|
||||
<Grid container column className="gap-4 w-full">
|
||||
@@ -81,6 +87,19 @@ export default function TagActiveDistributions() {
|
||||
column
|
||||
className="gap-3 w-full rounded-xl border border-gray-200 dark:border-gray-700 p-4"
|
||||
>
|
||||
<Grid container className="gap-2 items-center">
|
||||
<SparklesIcon className="w-5 h-5 text-gray-500 dark:text-gray-300" />
|
||||
<Typography variant="body2" className="font-medium">
|
||||
گونه:
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="body2"
|
||||
className="text-gray-700 dark:text-gray-300"
|
||||
>
|
||||
{speciesMap[opt?.species_code] ?? "-"}
|
||||
</Typography>
|
||||
</Grid>
|
||||
|
||||
{item?.distribution_type === "batch" && opt?.serial_from && (
|
||||
<Grid container className="gap-2 items-center">
|
||||
<Bars3Icon className="w-5 h-5 text-gray-500 dark:text-gray-300" />
|
||||
@@ -105,20 +124,31 @@ export default function TagActiveDistributions() {
|
||||
variant="body2"
|
||||
className="text-gray-700 dark:text-gray-300"
|
||||
>
|
||||
{opt?.distributed_number?.toLocaleString()}
|
||||
{opt?.total_tag_count?.toLocaleString()}
|
||||
</Typography>
|
||||
</Grid>
|
||||
|
||||
<Grid container className="gap-2 items-center">
|
||||
<SparklesIcon className="w-5 h-5 text-gray-500 dark:text-gray-300" />
|
||||
<CubeIcon className="w-5 h-5 text-gray-500 dark:text-gray-300" />
|
||||
<Typography variant="body2" className="font-medium">
|
||||
گونه:
|
||||
پلاک های توزیع شده:
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="body2"
|
||||
className="text-gray-700 dark:text-gray-300"
|
||||
>
|
||||
{speciesMap[opt?.species_code] ?? "-"}
|
||||
{opt?.distributed_number?.toLocaleString()}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid container className="gap-2 items-center">
|
||||
<CubeIcon className="w-5 h-5 text-gray-500 dark:text-gray-300" />
|
||||
<Typography variant="body2" className="font-medium">
|
||||
پلاک های باقیمانده:
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="body2"
|
||||
className="text-gray-700 dark:text-gray-300"
|
||||
>
|
||||
{opt?.remaining_number?.toLocaleString()}
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
@@ -126,6 +156,22 @@ export default function TagActiveDistributions() {
|
||||
</Grid>
|
||||
</ShowMoreInfo>,
|
||||
<Popover key={index}>
|
||||
<Tooltip title="جزيٓیات توزیع" position="right">
|
||||
<Button
|
||||
variant="detail"
|
||||
page="tag_distribution_detail"
|
||||
access="Show-Tag-Distribution-Detail"
|
||||
onClick={() => {
|
||||
const path =
|
||||
TAG_DISTRIBUTION +
|
||||
"/" +
|
||||
item?.dist_batch_identity +
|
||||
"/" +
|
||||
item?.id;
|
||||
navigate({ to: path });
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
<Tooltip title="ویرایش توزیع" position="right">
|
||||
<Button
|
||||
variant="edit"
|
||||
@@ -144,6 +190,24 @@ export default function TagActiveDistributions() {
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
<Tooltip title="توزیع مجدد" position="right">
|
||||
<Button
|
||||
variant="share"
|
||||
page="tag_distribution"
|
||||
access="Distribute-From-Distribution"
|
||||
onClick={() => {
|
||||
openModal({
|
||||
title: "توزیع مجدد",
|
||||
content: (
|
||||
<DistributeFromDistribution
|
||||
getData={handleUpdate}
|
||||
item={item}
|
||||
/>
|
||||
),
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
<Tooltip title={"لغو توزیع"} position="right">
|
||||
<Button
|
||||
page="tag_distribution"
|
||||
@@ -253,6 +317,8 @@ export default function TagActiveDistributions() {
|
||||
"توزیع کننده",
|
||||
"دریافت کننده",
|
||||
"تعداد کل پلاک",
|
||||
"پلاک های توزیع شده",
|
||||
"پلاک های باقیمانده",
|
||||
"نوع توزیع",
|
||||
"جزئیات توزیع",
|
||||
"عملیات",
|
||||
|
||||
@@ -54,4 +54,5 @@ export const UNITS_SETTINGS = "/unit-settings";
|
||||
export const TAGGING = "/tagging";
|
||||
export const TAGS = "/tags";
|
||||
export const TAG_DISTRIBUTION = "/tag-distribution";
|
||||
export const TAG_DISTRIBUTION_DETAIL = "/tag-distribution/$identity/$id";
|
||||
export const TAGS_BATCH = "/tags/$id/$from/$to";
|
||||
|
||||
@@ -25,6 +25,7 @@ import SettingsOfUnits from "../Pages/SettingsOfUnits";
|
||||
import Tagging from "../Pages/Tagging";
|
||||
import Tags from "../Pages/Tags";
|
||||
import TagDistribtution from "../Pages/TagDistribution";
|
||||
import TagDistribtutionDetails from "../Pages/TagDistributionDetails";
|
||||
|
||||
export const managementCategoryItems = [
|
||||
{
|
||||
@@ -188,6 +189,11 @@ export const taggingCategoryItems = [
|
||||
path: R.TAG_DISTRIBUTION,
|
||||
component: TagDistribtution,
|
||||
},
|
||||
{
|
||||
name: "tag_distribution_detail",
|
||||
path: R.TAG_DISTRIBUTION_DETAIL,
|
||||
component: TagDistribtutionDetails,
|
||||
},
|
||||
];
|
||||
|
||||
export const posCategoryItems = [
|
||||
|
||||
@@ -103,6 +103,9 @@ export function getFaPermissions(permission: string) {
|
||||
case "tag_distribution":
|
||||
faPermission = "توزیع پلاک";
|
||||
break;
|
||||
case "tag_distribution_detail":
|
||||
faPermission = "جزئیات توزیع پلاک";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
02.58
|
||||
02.64
|
||||
|
||||
Reference in New Issue
Block a user