feat: allocate incentive plan to rancher
This commit is contained in:
@@ -61,10 +61,10 @@ export default function LiveStockFarmers() {
|
||||
item?.activity === "V"
|
||||
? "روستایی"
|
||||
: item?.activity === "I"
|
||||
? "صنعتی"
|
||||
: item?.activity === "R"
|
||||
? "عشایری"
|
||||
: "-",
|
||||
? "صنعتی"
|
||||
: item?.activity === "R"
|
||||
? "عشایری"
|
||||
: "-",
|
||||
item?.province?.name || "-",
|
||||
item?.city?.name || "-",
|
||||
item?.address,
|
||||
@@ -137,7 +137,7 @@ export default function LiveStockFarmers() {
|
||||
"/plans/" +
|
||||
item.id +
|
||||
"/" +
|
||||
item?.ranching_farm;
|
||||
`${item?.first_name.replace(":", " ") || ""} ${item?.last_name || ""} ${item?.ranching_farm ? " (" + item?.ranching_farm + ") " : ""}`;
|
||||
navigate({ to: path });
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
import { useState } from "react";
|
||||
import { useToast } from "../../hooks/useToast";
|
||||
import { useModalStore } from "../../context/zustand-store/appStore";
|
||||
import { useApiMutation, useApiRequest } from "../../utils/useApiRequest";
|
||||
import { Grid } from "../../components/Grid/Grid";
|
||||
import Button from "../../components/Button/Button";
|
||||
import Textfield from "../../components/Textfeild/Textfeild";
|
||||
import AutoComplete from "../../components/AutoComplete/AutoComplete";
|
||||
import { FormApiBasedAutoComplete } from "../../components/FormItems/FormApiBasedAutoComplete";
|
||||
|
||||
type Props = {
|
||||
getData: () => void;
|
||||
rancher: string | number;
|
||||
};
|
||||
|
||||
type LivestockEntry = {
|
||||
livestock_type: number;
|
||||
allowed_quantity: number | "";
|
||||
};
|
||||
|
||||
type PlanAllocation = {
|
||||
plan: string | number;
|
||||
plan_name: string;
|
||||
livestock_entries: LivestockEntry[];
|
||||
};
|
||||
|
||||
export const LiveStockRancherAllocateIncentivePlan = ({
|
||||
getData,
|
||||
rancher,
|
||||
}: Props) => {
|
||||
const showToast = useToast();
|
||||
const { closeModal } = useModalStore();
|
||||
|
||||
const [planAllocations, setPlanAllocations] = useState<PlanAllocation[]>([]);
|
||||
|
||||
const { data: speciesData } = useApiRequest({
|
||||
api: "/livestock/web/api/v1/livestock_type",
|
||||
method: "get",
|
||||
params: { page: 1, page_size: 1000 },
|
||||
queryKey: ["livestock_species"],
|
||||
});
|
||||
|
||||
const speciesOptions = () => {
|
||||
return (
|
||||
speciesData?.results?.map((opt: any) => ({
|
||||
key: opt?.id,
|
||||
value: opt?.name,
|
||||
})) ?? []
|
||||
);
|
||||
};
|
||||
|
||||
const mutation = useApiMutation({
|
||||
api: "/product/web/api/v1/rancher_incentive_plan/",
|
||||
method: "post",
|
||||
});
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
const payload = planAllocations.flatMap((pa) =>
|
||||
pa.livestock_entries.map((entry) => ({
|
||||
plan: pa.plan,
|
||||
rancher: Number(rancher),
|
||||
livestock_type: entry.livestock_type,
|
||||
allowed_quantity: Number(entry.allowed_quantity),
|
||||
})),
|
||||
);
|
||||
|
||||
if (payload.length === 0) {
|
||||
showToast("لطفاً حداقل یک طرح و نوع دام انتخاب کنید!", "error");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await mutation.mutateAsync({ data: payload });
|
||||
showToast("تخصیص طرح تشویقی با موفقیت انجام شد", "success");
|
||||
getData();
|
||||
closeModal();
|
||||
} catch (error: any) {
|
||||
showToast(
|
||||
error?.response?.data?.message || "خطا در ثبت اطلاعات!",
|
||||
"error",
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Grid container column className="gap-3">
|
||||
<FormApiBasedAutoComplete
|
||||
title="انتخاب طرح تشویقی"
|
||||
api="product/web/api/v1/incentive_plan/active_plans/"
|
||||
keyField="id"
|
||||
valueField="name"
|
||||
secondaryKey="name"
|
||||
multiple
|
||||
onChange={(items) => {
|
||||
const selectedItems = Array.isArray(items) ? items : [];
|
||||
setPlanAllocations((prev) =>
|
||||
selectedItems.map((item: any) => {
|
||||
const existing = prev.find((pa) => pa.plan === item.key1);
|
||||
return (
|
||||
existing || {
|
||||
plan: item.key1,
|
||||
plan_name: item.key2,
|
||||
livestock_entries: [],
|
||||
}
|
||||
);
|
||||
}),
|
||||
);
|
||||
}}
|
||||
onChangeValue={(names) => {
|
||||
setPlanAllocations((prev) =>
|
||||
prev.map((pa, i) => ({
|
||||
...pa,
|
||||
plan_name: names[i] || pa.plan_name,
|
||||
})),
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
||||
{planAllocations.map((pa, planIndex) => (
|
||||
<Grid
|
||||
key={pa.plan}
|
||||
container
|
||||
column
|
||||
className="gap-2 border p-3 rounded-lg"
|
||||
>
|
||||
<span className="font-bold text-sm">{pa.plan_name}</span>
|
||||
|
||||
{speciesData?.results && (
|
||||
<AutoComplete
|
||||
data={speciesOptions()}
|
||||
multiselect
|
||||
selectedKeys={pa.livestock_entries.map((e) => e.livestock_type)}
|
||||
onChange={(keys: (string | number)[]) => {
|
||||
setPlanAllocations((prev) => {
|
||||
const next = [...prev];
|
||||
next[planIndex] = {
|
||||
...next[planIndex],
|
||||
livestock_entries: keys.map((k) => {
|
||||
const existing = next[planIndex].livestock_entries.find(
|
||||
(e) => e.livestock_type === k,
|
||||
);
|
||||
return {
|
||||
livestock_type: k as number,
|
||||
allowed_quantity: existing?.allowed_quantity ?? "",
|
||||
};
|
||||
}),
|
||||
};
|
||||
return next;
|
||||
});
|
||||
}}
|
||||
title="نوع دام"
|
||||
/>
|
||||
)}
|
||||
|
||||
{pa.livestock_entries.map((entry, entryIndex) => (
|
||||
<Textfield
|
||||
key={entry.livestock_type}
|
||||
fullWidth
|
||||
formattedNumber
|
||||
placeholder={`تعداد مجاز ${
|
||||
speciesOptions().find(
|
||||
(s: any) => s.key === entry.livestock_type,
|
||||
)?.value || ""
|
||||
}`}
|
||||
value={entry.allowed_quantity}
|
||||
onChange={(e) => {
|
||||
setPlanAllocations((prev) => {
|
||||
const next = [...prev];
|
||||
const entries = [...next[planIndex].livestock_entries];
|
||||
entries[entryIndex] = {
|
||||
...entries[entryIndex],
|
||||
allowed_quantity: Number(e.target.value),
|
||||
};
|
||||
next[planIndex] = {
|
||||
...next[planIndex],
|
||||
livestock_entries: entries,
|
||||
};
|
||||
return next;
|
||||
});
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</Grid>
|
||||
))}
|
||||
|
||||
<Button
|
||||
disabled={
|
||||
planAllocations.length === 0 ||
|
||||
planAllocations.some((pa) => pa.livestock_entries.length === 0) ||
|
||||
planAllocations.some((pa) =>
|
||||
pa.livestock_entries.some(
|
||||
(e) =>
|
||||
e.allowed_quantity === "" || Number(e.allowed_quantity) <= 0,
|
||||
),
|
||||
)
|
||||
}
|
||||
type="submit"
|
||||
>
|
||||
ثبت
|
||||
</Button>
|
||||
</Grid>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user