This commit is contained in:
2026-05-29 16:21:46 +03:30
parent 1140fbae3c
commit 9db796b8e1
12 changed files with 285 additions and 71 deletions
+36 -11
View File
@@ -1,4 +1,4 @@
import { useState, type FC } from "react";
import { useEffect, useRef, useState, type FC } from "react";
import Button from "@/components/Button";
import Select from "@/components/Select";
import { TickSquare } from "iconsax-react";
@@ -16,14 +16,17 @@ import UploadBox from "@/components/UploadBox";
import Textarea from "@/components/Textarea";
import DatePickerComponent from "@/components/DatePicker";
import { useCreateInvoice } from "./hooks/useInvoiceData";
import { useGetRequestDetail } from "@/pages/requests/hooks/useRequestData";
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: "",
});
@@ -35,6 +38,8 @@ const CreateInvoice: FC = () => {
const { mutate: submitInvoice, isPending } = useCreateInvoice();
const { data: usersData } = useGetUsers();
const { data: requestData, isLoading: isLoadingRequest } = useGetRequestDetail(requestId ?? "");
const hydratedRequestId = useRef<string | null>(null);
const multiUpload = useMultiUpload()
const [items, setItems] = useState<CreatePreInvoiceItemType[]>([createEmptyItem()]);
@@ -81,7 +86,9 @@ const CreateInvoice: FC = () => {
productId: i.productId,
quantity: i.quantity,
unitPrice: i.unitPrice,
discount: i.discount || 0,
...(i.discountPercent != null && i.discountPercent > 0
? { discountPercent: i.discountPercent }
: { discount: i.discount || 0 }),
description: i.description || "",
})),
enableTax: values.enableTax,
@@ -103,14 +110,35 @@ const CreateInvoice: FC = () => {
},
});
useEffect(() => {
const request = requestData?.data;
if (!requestId || !request || hydratedRequestId.current === requestId) return;
const mappedItems: CreatePreInvoiceItemType[] = request.items?.length
? request.items.map((item) => ({
productId: item.product?.id ?? "",
quantity: item.quantity ?? 1,
unitPrice: 0,
discount: 0,
discountPercent: null,
description: item.description ?? "",
}))
: [createEmptyItem()];
setItems(mappedItems);
hydratedRequestId.current = requestId;
}, [requestData, requestId]);
const handleItemChange = (
index: number,
field: keyof CreatePreInvoiceItemType,
value: string | number
value: string | number | null
) => {
const next = [...items];
next[index] = { ...next[index], [field]: value };
setItems(next);
setItems((prev) =>
prev.map((item, itemIndex) =>
itemIndex === index ? { ...item, [field]: value } : item
)
);
};
const addItem = (currentIndex: number) => {
@@ -131,10 +159,7 @@ const CreateInvoice: FC = () => {
setItems(items.filter((_, i) => i !== index));
};
const totalAmount = items.reduce(
(sum, i) => sum + (i.quantity || 0) * (i.unitPrice || 0) - (i.discount || 0),
0
);
const totalAmount = items.reduce((sum, i) => sum + getItemLineTotal(i), 0);
const users = usersData?.data ?? [];
@@ -145,7 +170,7 @@ const CreateInvoice: FC = () => {
<Button
className="w-fit px-5"
onClick={() => formik.handleSubmit()}
isLoading={isPending || multiUpload.isPending}
isLoading={isPending || multiUpload.isPending || isLoadingRequest}
>
<div className="flex gap-2 items-center">
<TickSquare size={20} color="black" />