"use client"; import { factory_api } from "@/features/pharm/lib/api"; import { pill_api } from "@/features/pill/lib/api"; import { order_api } from "@/features/specifications/lib/api"; import { type OrderCreateReq, type OrderListDataRes, type OrderUpdateReq, } from "@/features/specifications/lib/data"; import { SpecificationsForm, type SpecificationsFormType, } from "@/features/specifications/lib/form"; import { user_api } from "@/features/users/lib/api"; import formatPrice from "@/shared/lib/formatPrice"; import { cn } from "@/shared/lib/utils"; import { Button } from "@/shared/ui/button"; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from "@/shared/ui/command"; import { Form, FormControl, FormField, FormItem, FormMessage, } from "@/shared/ui/form"; import { Input } from "@/shared/ui/input"; import { Label } from "@/shared/ui/label"; import { Popover, PopoverContent, PopoverTrigger } from "@/shared/ui/popover"; import { zodResolver } from "@hookform/resolvers/zod"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import type { AxiosError } from "axios"; import { Check, ChevronsUpDown, Loader2 } from "lucide-react"; import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; import { toast } from "sonner"; interface Props { initialValues: OrderListDataRes | null; setDialogOpen: React.Dispatch>; } export const AddedSpecification = ({ initialValues, setDialogOpen }: Props) => { const queryClient = useQueryClient(); const { data: pill } = useQuery({ queryKey: ["pill_list", initialValues], queryFn: () => pill_api.list({ limit: 999, }), select(data) { return data.data.data; }, }); const [userSearch, setUserSearch] = useState(""); const [openUser, setOpenUser] = useState(false); const { data: user, isLoading: isUserLoading } = useQuery({ queryKey: ["user_list", userSearch, initialValues], queryFn: () => user_api.list({ search: userSearch }), select(data) { return data.data.data.results; }, }); const [factorySearch, setFactorySearch] = useState(""); const [openFactory, setOpenFactory] = useState(false); const { data: pharm, isLoading: isPharmLoading } = useQuery({ queryKey: ["factory_list", userSearch, initialValues], queryFn: () => factory_api.list({ name: factorySearch }), select(data) { return data.data.data.results; }, }); const { mutate: create, isPending: createPending } = useMutation({ mutationFn: (body: OrderCreateReq) => order_api.create(body), onSuccess: () => { setDialogOpen(false); queryClient.resetQueries({ queryKey: ["order_list"] }); }, onError: (err: AxiosError) => { const errMessage = err.response?.data as { message: string }; const messageText = errMessage.message; toast.error(messageText || "Xatolik yuz berdi", { richColors: true, position: "top-center", }); }, }); const { mutate: update, isPending: updatePending } = useMutation({ mutationFn: ({ body, id }: { id: number; body: OrderUpdateReq }) => order_api.update({ body, id }), onSuccess: () => { setDialogOpen(false); queryClient.resetQueries({ queryKey: ["order_list"] }); }, onError: (err: AxiosError) => { const errMessage = err.response?.data as { message: string }; const messageText = errMessage.message; toast.error(messageText || "Xatolik yuz berdi", { richColors: true, position: "top-center", }); }, }); const form = useForm({ resolver: zodResolver(SpecificationsForm), defaultValues: { client: "", pharm: "", user: "", percentage: 0, totalPrice: 0, paidPrice: 0, medicines: [], }, }); useEffect(() => { if (!pill) return; if (initialValues) { const mergedMedicines = [ ...initialValues.order_items.map((item) => { const pillItem = pill.results.find((p) => p.id === item.product); return { id: item.product, name: pillItem ? pillItem.name : "Unknown", price: pillItem ? Number(pillItem.price) : 0, count: Number(item.quantity), }; }), ...pill.results .filter( (p) => !initialValues.order_items.some((m) => m.product === p.id), ) .map((p) => ({ id: p.id, name: p.name, price: Number(p.price), count: 0, })), ]; form.reset({ client: initialValues.employee_name, pharm: String(initialValues.factory.id), percentage: initialValues.advance, totalPrice: Number(initialValues.total_price), paidPrice: Number(initialValues.paid_price), user: String(initialValues.user.id), medicines: mergedMedicines, }); return; } const fakeMedicines = pill.results.map((p) => ({ id: p.id, name: p.name, price: Number(p.price), count: 0, })); form.reset({ client: "", pharm: "", user: "", percentage: 0, totalPrice: 0, paidPrice: 0, medicines: fakeMedicines, }); }, [pill, initialValues, form]); const medicines = form.watch("medicines"); const calculateTotal = () => { const medicines = form.getValues("medicines"); const total = medicines.reduce( (acc, med) => acc + med.price * med.count, 0, ); form.setValue("totalPrice", total); const percentage = form.getValues("percentage") || 0; const paid = Math.round((total * percentage) / 100); form.setValue("paidPrice", paid); }; useEffect(() => { const subscription = form.watch((__, { name }) => { if (name?.startsWith("medicines") || name === "percentage") calculateTotal(); }); return () => subscription.unsubscribe(); }, [form]); const onSubmit = (values: SpecificationsFormType) => { if (!initialValues) { const items = medicines .filter((med) => med.count > 0) .map((med) => ({ product: med.id, quantity: med.count, total_price: (med.price * med.count).toFixed(2), })); const total_price = items .reduce((sum, item) => sum + parseFloat(item.total_price), 0) .toFixed(2); create({ advance: values.percentage, employee_name: values.client, factory_id: Number(values.pharm), paid_price: String(values.paidPrice), total_price, items, user_id: Number(values.user), }); } else if (initialValues) { const items = medicines .filter((med) => med.count > 0) .map((med) => ({ product_id: med.id, quantity: med.count, total_price: (med.price * med.count).toFixed(2), })); const total_price = items .reduce((sum, item) => sum + parseFloat(item.total_price), 0) .toFixed(2); update({ body: { advance: values.percentage, employee_name: values.client, paid_price: String(values.paidPrice), total_price, items: items, factory_id: Number(values.pharm), user_id: Number(values.user), }, id: initialValues.id, }); } }; return (
{ const selectedUser = pharm?.find( (u) => String(u.id) === field.value, ); return ( {isPharmLoading ? (
) : pharm && pharm.length > 0 ? ( {pharm.map((u) => ( { field.onChange(String(u.id)); setOpenFactory(false); }} > {u.name} ))} ) : ( Farmasevtika topilmadi )}
); }} /> { const selectedUser = user?.find( (u) => String(u.id) === field.value, ); return ( {isUserLoading ? (
) : user && user.length > 0 ? ( {user.map((u) => ( { field.onChange(String(u.id)); setOpenUser(false); }} > {u.first_name} {u.last_name} {u.region.name} ))} ) : ( Foydalanuvchi topilmadi )}
); }} /> ( {" "} )} /> {/* Medicines list */}
{medicines.map((med, index) => (

{med.name}

Narxi:{formatPrice(med.price)}

{ let value = parseInt(e.target.value, 10); if (isNaN(value)) value = 0; const updatedMedicines = [...medicines]; updatedMedicines[index].count = value; form.setValue("medicines", updatedMedicines); calculateTotal(); }} />
))}
( { let value = parseInt(e.target.value, 10); if (isNaN(value)) value = 0; if (value < 0) value = 0; if (value > 100) value = 100; field.onChange(value); calculateTotal(); }} /> )} />
( )} /> ( )} />
); };