import React, { useEffect, useState } from "react"; import { useCurrencies, useProjectName } from "../../hooks/useProjects"; import Label from "../common/Label"; import { Controller, useForm } from "react-hook-form"; import { useExpenseCategory } from "../../hooks/masterHook/useMaster"; import DatePicker from "../common/DatePicker"; import { useCreatePaymentRequest, usePayee, usePaymentRequestDetail, useUpdatePaymentRequest, } from "../../hooks/useExpense"; import { zodResolver } from "@hookform/resolvers/zod"; import { formatFileSize, localToUtc } from "../../utils/appUtils"; import { defaultPaymentRequest, PaymentRequestSchema, } from "./PaymentRequestSchema"; import { INR_CURRENCY_CODE } from "../../utils/constants"; import { useProfile } from "../../hooks/useProfile"; import Filelist from "../Expenses/Filelist"; import InputSuggestions from "../common/InputSuggestion"; function ManagePaymentRequest({ closeModal, requestToEdit = null }) { const { data, isLoading, isError, error: requestError, } = usePaymentRequestDetail(requestToEdit); const { projectNames, loading: projectLoading, error, isError: isProjectError, } = useProjectName(); const { data: currencyData, isLoading: currencyLoading, isError: currencyError, } = useCurrencies(); const { ExpenseCategories, loading: ExpenseLoading, error: ExpenseError, } = useExpenseCategory(); const { data: Payees, isLoading: isPayeeLoaing, isError: isPayeeError, error: payeeError, } = usePayee(); const schema = PaymentRequestSchema(ExpenseCategories); const { register, control, watch, handleSubmit, setValue, reset, formState: { errors }, } = useForm({ resolver: zodResolver(schema), defaultValues: defaultPaymentRequest, }); const [isItself, setisItself] = useState(false); const files = watch("billAttachments"); const onFileChange = async (e) => { const newFiles = Array.from(e.target.files); if (newFiles.length === 0) return; const existingFiles = watch("billAttachments") || []; const parsedFiles = await Promise.all( newFiles.map(async (file) => { const base64Data = await toBase64(file); return { fileName: file.name, base64Data, contentType: file.type, fileSize: file.size, description: "", isActive: true, }; }) ); const combinedFiles = [ ...existingFiles, ...parsedFiles.filter( (newFile) => !existingFiles.some( (f) => f.fileName === newFile.fileName && f.fileSize === newFile.fileSize ) ), ]; setValue("billAttachments", combinedFiles, { shouldDirty: true, shouldValidate: true, }); }; const toBase64 = (file) => new Promise((resolve, reject) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () => resolve(reader.result.split(",")[1]); reader.onerror = (error) => reject(error); }); const removeFile = (index) => { if (requestToEdit) { const newFiles = files.map((file, i) => { if (file.documentId !== index) return file; return { ...file, isActive: false, }; }); setValue("billAttachments", newFiles, { shouldValidate: true }); } else { const newFiles = files.filter((_, i) => i !== index); setValue("billAttachments", newFiles, { shouldValidate: true }); } }; const handleClose = () => { reset(); closeModal(); }; const { mutate: CreatePaymentRequest, isPending: createPending } = useCreatePaymentRequest(() => { handleClose(); }); const { mutate: PaymentRequestUpdate, isPending } = useUpdatePaymentRequest( () => handleClose() ); useEffect(() => { if (requestToEdit && data) { reset({ title: data.title || "", description: data.description || "", payee: data.payee || "", currencyId: data.currency.id || "", amount: data.amount || "", dueDate: data.dueDate?.slice(0, 10) || "", projectId: data.project.id || "", expenseCategoryId: data.expenseCategory.id || "", isAdvancePayment: data.isAdvancePayment || false, billAttachments: data.attachments ? data?.attachments?.map((doc) => ({ fileName: doc.fileName, base64Data: null, contentType: doc.contentType, documentId: doc.id, fileSize: 0, description: "", preSignedUrl: doc.preSignedUrl, isActive: doc.isActive ?? true, })) : [], }); } }, [data, reset]); useEffect(() => { if (!requestToEdit && currencyData && currencyData.length > 0) { const inrCurrency = currencyData.find((c) => c.id === INR_CURRENCY_CODE); if (inrCurrency) { setValue("currencyId", INR_CURRENCY_CODE, { shouldValidate: true }); } } }, [currencyData, requestToEdit, setValue]); const onSubmit = (fromdata) => { let payload = { ...fromdata, dueDate: localToUtc(fromdata.dueDate), payee: isItself ? `${profile?.employeeInfo?.firstName} ${profile?.employeeInfo?.lastName}` : fromdata.payee, }; if (requestToEdit) { const editPayload = { ...payload, id: data.id, payee: isItself ? `${profile?.employeeInfo?.firstName} ${profile?.employeeInfo?.lastName}` : fromdata.payee, }; PaymentRequestUpdate({ id: data.id, payload: editPayload }); } else { CreatePaymentRequest(payload); } }; const handleSetItSelf = (e) => { setisItself(e.target.value); let name = `${profile?.employeeInfo.firstName} ${profile?.employeeInfo.lastName}` setValue( "payee", name ); }; return (