import { useEffect, useState, type FC } from "react"; import Button from "@/components/Button"; import { Add, TickSquare } from "iconsax-react"; import { toast } from "@/shared/toast"; import { useNavigate, useParams } from "react-router-dom"; import { Paths } from "@/config/Paths"; import { extractErrorMessage } from "@/config/func"; import { useFormik } from "formik"; import type { CreatePreInvoiceItemType, UpdatePreInvoiceType } from "./types/Types"; import InvoiceItemRow from "./components/InvoiceItemRow"; import { Checkbox } from "@/components/ui/checkbox"; import UploadBox from "@/components/UploadBox"; import Textarea from "@/components/Textarea"; import DatePickerComponent from "@/components/DatePicker"; import { useGetInvoiceDetail, useUpdateInvoice } from "./hooks/useInvoiceData"; import { useMultiUpload } from "../uploader/hooks/useUploader"; import moment from "moment-jalaali"; import { getItemLineTotal } from "./utils/invoiceItem"; const createEmptyItem = (): CreatePreInvoiceItemType => ({ productId: "", quantity: 1, unitPrice: 0, discount: 0, discountPercent: null, description: "", }); const UpdateInvoice: FC = () => { const { id } = useParams<{ id: string }>(); const navigate = useNavigate(); const { data: invoiceData, isLoading: isLoadingInvoice } = useGetInvoiceDetail(id); const { mutate: submitUpdate, isPending } = useUpdateInvoice(); const multiUpload = useMultiUpload(); const invoice = invoiceData?.data; const [items, setItems] = useState([ createEmptyItem(), ]); const [attachmentFiles, setAttachmentFiles] = useState([]); const formik = useFormik< Pick< UpdatePreInvoiceType, "enableTax" | "approvalDeadline" | "paymentMethod" | "description" > >({ initialValues: { enableTax: false, approvalDeadline: "", paymentMethod: "", description: "", }, onSubmit: async (values) => { const validItems = items.filter( (i) => i.productId && i.quantity > 0 && i.unitPrice >= 0 ); if (validItems.length === 0) { toast( "حداقل یک آیتم با محصول، تعداد و مبلغ واحد معتبر اضافه کنید.", "error" ); return; } const attachments: { type: string; url: string }[] = invoice?.attachments?.map((a) => ({ type: a.type, url: a.url })) ?? []; if (attachmentFiles.length) { const uploadResult = await multiUpload.mutateAsync(attachmentFiles); uploadResult?.data?.forEach((item) => { attachments.push({ type: "uploads_attach", url: item.url, }); }); } const params: UpdatePreInvoiceType = { items: validItems.map((i) => ({ ...(i.id ? { id: i.id } : {}), productId: i.productId, quantity: i.quantity, unitPrice: i.unitPrice, ...(i.discountPercent != null && i.discountPercent > 0 ? { discountPercent: i.discountPercent } : { discount: i.discount || 0 }), description: i.description || "", })), enableTax: values.enableTax, ...(values.approvalDeadline ? { approvalDeadline: moment( values.approvalDeadline, "jYYYY/jMM/jDD" ).format("YYYY-MM-DD"), } : {}), ...(values.paymentMethod?.trim() ? { paymentMethod: values.paymentMethod.trim() } : {}), description: values.description, ...(attachments.length ? { attachments } : {}), }; if (!id) return; submitUpdate( { id, params }, { onSuccess: () => { toast("پیش فاکتور با موفقیت ویرایش شد", "success"); navigate(Paths.perfomaInvoice.list); }, onError: (error) => { toast(extractErrorMessage(error), "error"); }, } ); }, }); useEffect(() => { if (invoice) { formik.setValues({ enableTax: invoice.enableTax ?? false, approvalDeadline: invoice.approvalDeadline ? moment(invoice.approvalDeadline).format("jYYYY/jMM/jDD") : "", paymentMethod: invoice.paymentMethod ?? "", description: invoice.description ?? "", }); const mappedItems: CreatePreInvoiceItemType[] = invoice.items?.length > 0 ? invoice.items.map((i) => ({ id: i.id, productId: i.product?.id ?? "", quantity: i.quantity ?? 1, unitPrice: i.unitPrice ?? 0, discount: i.discount ?? 0, discountPercent: i.discountPercent != null && i.discountPercent > 0 ? i.discountPercent : null, description: i.description ?? "", })) : [createEmptyItem()]; setItems(mappedItems); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [invoice]); const handleItemChange = ( index: number, field: keyof CreatePreInvoiceItemType, value: string | number | null ) => { setItems((prev) => prev.map((item, itemIndex) => itemIndex === index ? { ...item, [field]: value } : item ) ); }; const addItem = () => { const current = items[items.length - 1]; const hasProduct = !!current?.productId; const hasQuantity = (current?.quantity ?? 0) > 0; const hasUnitPrice = (current?.unitPrice ?? 0) > 0; if (!hasProduct || !hasQuantity || !hasUnitPrice) { toast("لطفاً محصول، تعداد و مبلغ واحد را وارد کنید.", "error"); return; } setItems([...items, createEmptyItem()]); }; const removeItem = (index: number) => { if (items.length <= 1) return; setItems(items.filter((_, i) => i !== index)); }; const totalAmount = items.reduce((sum, i) => sum + getItemLineTotal(i), 0); if (isLoadingInvoice || !invoice) { return (
در حال بارگذاری...
); } return (

ویرایش پیش فاکتور #{invoice.invoiceNumber}

اطلاعات پیش فاکتور
مشتری
{invoice.user?.firstName && invoice.user?.lastName ? `${invoice.user.firstName} ${invoice.user.lastName}` : invoice.user?.phone ?? "-"}
{items.map((item, index) => ( removeItem(index)} canRemove={items.length > 1} /> ))}
formik.setFieldValue("enableTax", !!checked) } />
{ formik.setFieldValue("approvalDeadline", date); formik.setFieldTouched("approvalDeadline", true); }} error_text={ formik.errors.approvalDeadline && formik.touched.approvalDeadline ? formik.errors.approvalDeadline : "" } />