Adding Create API for Payment Request.
This commit is contained in:
parent
196069b39a
commit
c123373892
@ -1,5 +1,5 @@
|
|||||||
import React, { useEffect } from 'react'
|
import React, { useEffect } from 'react'
|
||||||
import { useProjectName } from '../../hooks/useProjects';
|
import { useCurrencies, useProjectName } from '../../hooks/useProjects';
|
||||||
import Label from '../common/Label';
|
import Label from '../common/Label';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { useExpenseType } from '../../hooks/masterHook/useMaster';
|
import { useExpenseType } from '../../hooks/masterHook/useMaster';
|
||||||
@ -11,8 +11,14 @@ import { formatFileSize, localToUtc } from '../../utils/appUtils';
|
|||||||
|
|
||||||
function ManagePaymentRequest({ closeModal, expenseToEdit = null }) {
|
function ManagePaymentRequest({ closeModal, expenseToEdit = null }) {
|
||||||
|
|
||||||
|
const { data } = {}
|
||||||
|
|
||||||
const { projectNames, loading: projectLoading, error, isError: isProjectError,
|
const { projectNames, loading: projectLoading, error, isError: isProjectError,
|
||||||
} = useProjectName();
|
} = useProjectName();
|
||||||
|
|
||||||
|
const { data: currencyData, isLoading: currencyLoading, isError: currencyError } = useCurrencies();
|
||||||
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
ExpenseTypes,
|
ExpenseTypes,
|
||||||
loading: ExpenseLoading,
|
loading: ExpenseLoading,
|
||||||
@ -98,39 +104,39 @@ function ManagePaymentRequest({ closeModal, expenseToEdit = null }) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// useEffect(() => {
|
useEffect(() => {
|
||||||
// if (expenseToEdit && data) {
|
if (expenseToEdit && data) {
|
||||||
// reset({
|
reset({
|
||||||
// title: data.title || "",
|
title: data.title || "",
|
||||||
// description: data.description || "",
|
description: data.description || "",
|
||||||
// payee: data.payee || "",
|
payee: data.payee || "",
|
||||||
// currencyId: data.currencyId.id || "",
|
currencyId: data.currencyId.id || "",
|
||||||
// amount: data.amount || "",
|
amount: data.amount || "",
|
||||||
// dueDate: data.dueDate?.slice(0, 10) || "",
|
dueDate: data.dueDate?.slice(0, 10) || "",
|
||||||
// projectId: data.project.id || "",
|
projectId: data.project.id || "",
|
||||||
// expenseCategoryId: data.expenseCategoryId.id || "",
|
expenseCategoryId: data.expenseCategoryId.id || "",
|
||||||
// isAdvancePayment: data.isAdvancePayment || "",
|
isAdvancePayment: data.isAdvancePayment || false,
|
||||||
// billAttachments: data.documents
|
billAttachments: data.documents
|
||||||
// ? data.documents.map((doc) => ({
|
? data.documents.map((doc) => ({
|
||||||
// fileName: doc.fileName,
|
fileName: doc.fileName,
|
||||||
// base64Data: null,
|
base64Data: null,
|
||||||
// contentType: doc.contentType,
|
contentType: doc.contentType,
|
||||||
// documentId: doc.documentId,
|
documentId: doc.documentId,
|
||||||
// fileSize: 0,
|
fileSize: 0,
|
||||||
// description: "",
|
description: "",
|
||||||
// preSignedUrl: doc.preSignedUrl,
|
preSignedUrl: doc.preSignedUrl,
|
||||||
// isActive: doc.isActive ?? true,
|
isActive: doc.isActive ?? true,
|
||||||
// }))
|
}))
|
||||||
// : [],
|
: [],
|
||||||
|
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
// }, [data, reset, employees]);
|
}, [data, reset]);
|
||||||
|
|
||||||
const onSubmit = (fromdata) => {
|
const onSubmit = (fromdata) => {
|
||||||
let payload = {
|
let payload = {
|
||||||
...fromdata,
|
...fromdata,
|
||||||
transactionDate: localToUtc(fromdata.transactionDate),
|
dueDate: localToUtc(fromdata.dueDate),
|
||||||
};
|
};
|
||||||
if (expenseToEdit) {
|
if (expenseToEdit) {
|
||||||
const editPayload = { ...payload, id: data.id };
|
const editPayload = { ...payload, id: data.id };
|
||||||
@ -140,6 +146,7 @@ function ManagePaymentRequest({ closeModal, expenseToEdit = null }) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="container p-3">
|
<div className="container p-3">
|
||||||
<h5 className="m-0">
|
<h5 className="m-0">
|
||||||
@ -172,13 +179,13 @@ function ManagePaymentRequest({ closeModal, expenseToEdit = null }) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-md-6">
|
<div className="col-md-6">
|
||||||
<Label htmlFor="expensesTypeId" className="form-label" required>
|
<Label htmlFor="expenseCategoryId" className="form-label" required>
|
||||||
Expense Category
|
Expense Category
|
||||||
</Label>
|
</Label>
|
||||||
<select
|
<select
|
||||||
className="form-select form-select-sm"
|
className="form-select form-select-sm"
|
||||||
id="expensesTypeId"
|
id="expenseCategoryId"
|
||||||
{...register("expensesTypeId")}
|
{...register("expenseCategoryId")}
|
||||||
>
|
>
|
||||||
<option value="" disabled>
|
<option value="" disabled>
|
||||||
Select Type
|
Select Type
|
||||||
@ -193,9 +200,9 @@ function ManagePaymentRequest({ closeModal, expenseToEdit = null }) {
|
|||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
</select>
|
</select>
|
||||||
{errors.expensesTypeId && (
|
{errors.expenseCategoryId && (
|
||||||
<small className="danger-text">
|
<small className="danger-text">
|
||||||
{errors.expensesTypeId.message}
|
{errors.expenseCategoryId.message}
|
||||||
</small>
|
</small>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -204,18 +211,18 @@ function ManagePaymentRequest({ closeModal, expenseToEdit = null }) {
|
|||||||
|
|
||||||
<div className="row my-2 text-start">
|
<div className="row my-2 text-start">
|
||||||
<div className="col-md-6">
|
<div className="col-md-6">
|
||||||
<Label htmlFor="transactionDate" className="form-label" required>
|
<Label htmlFor="dueDate" className="form-label" required>
|
||||||
Transaction Date
|
Transaction Date
|
||||||
</Label>
|
</Label>
|
||||||
<DatePicker
|
<DatePicker
|
||||||
name="transactionDate"
|
name="dueDate"
|
||||||
control={control}
|
control={control}
|
||||||
maxDate={new Date()}
|
maxDate={new Date()}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{errors.transactionDate && (
|
{errors.dueDate && (
|
||||||
<small className="danger-text">
|
<small className="danger-text">
|
||||||
{errors.transactionDate.message}
|
{errors.dueDate.message}
|
||||||
</small>
|
</small>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -241,36 +248,48 @@ function ManagePaymentRequest({ closeModal, expenseToEdit = null }) {
|
|||||||
|
|
||||||
<div className="row my-2 text-start">
|
<div className="row my-2 text-start">
|
||||||
<div className="col-md-6">
|
<div className="col-md-6">
|
||||||
<Label htmlFor="supplerName" className="form-label" required>
|
<Label htmlFor="payee" className="form-label" required>
|
||||||
Supplier Name/Transporter Name/Other
|
Supplier Name/Transporter Name/Other
|
||||||
</Label>
|
</Label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
id="supplerName"
|
id="payee"
|
||||||
className="form-control form-control-sm"
|
className="form-control form-control-sm"
|
||||||
{...register("supplerName")}
|
{...register("payee")}
|
||||||
/>
|
/>
|
||||||
{errors.supplerName && (
|
{errors.payee && (
|
||||||
<small className="danger-text">
|
<small className="danger-text">
|
||||||
{errors.supplerName.message}
|
{errors.payee.message}
|
||||||
</small>
|
</small>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-md-6">
|
<div className="col-md-6">
|
||||||
<Label htmlFor="location" className="form-label" required>
|
<Label htmlFor="currencyId" className="form-label" required>
|
||||||
Location
|
Currency
|
||||||
</Label>
|
</Label>
|
||||||
<input
|
<select
|
||||||
type="text"
|
id="currencyId"
|
||||||
id="location"
|
className="form-select form-select-sm"
|
||||||
className="form-control form-control-sm"
|
{...register("currencyId")}
|
||||||
{...register("location")}
|
>
|
||||||
/>
|
<option value="">Select Currency</option>
|
||||||
{errors.location && (
|
|
||||||
<small className="danger-text">{errors.location.message}</small>
|
{currencyLoading && <option>Loading...</option>}
|
||||||
|
|
||||||
|
{!currencyLoading &&
|
||||||
|
!currencyError &&
|
||||||
|
currencyData?.map((currency) => (
|
||||||
|
<option key={currency.id} value={currency.id}>
|
||||||
|
{`${currency.currencyName} (${currency.symbol})`}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
{errors.currencyId && (
|
||||||
|
<small className="danger-text">{errors.currencyId.message}</small>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="row my-2 text-start">
|
<div className="row my-2 text-start">
|
||||||
@ -285,9 +304,33 @@ function ManagePaymentRequest({ closeModal, expenseToEdit = null }) {
|
|||||||
{...register("title")}
|
{...register("title")}
|
||||||
/>
|
/>
|
||||||
{errors.title && (
|
{errors.title && (
|
||||||
<small className="danger-text">{errors.title.message}</small>
|
<small className="danger-text">
|
||||||
|
{errors.title.message}
|
||||||
|
</small>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Label htmlFor="isAdvancePayment" className="form-label" required>
|
||||||
|
Advance Payment
|
||||||
|
</Label>
|
||||||
|
<select
|
||||||
|
id="isAdvancePayment"
|
||||||
|
className="form-select form-select-sm"
|
||||||
|
{...register("isAdvancePayment", {
|
||||||
|
setValueAs: (v) => v === "true" ? true : v === "false" ? false : undefined,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<option value="">Select Option</option>
|
||||||
|
<option value="true">True</option>
|
||||||
|
<option value="false">False</option>
|
||||||
|
</select>
|
||||||
|
{errors.isAdvancePayment && (
|
||||||
|
<small className="danger-text">{errors.isAdvancePayment.message}</small>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="row my-2 text-start">
|
<div className="row my-2 text-start">
|
||||||
|
|||||||
@ -4,13 +4,15 @@ import showToast from "../services/toastService";
|
|||||||
|
|
||||||
export const useCreatePaymentRequest = (onSuccessCallBack) => {
|
export const useCreatePaymentRequest = (onSuccessCallBack) => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: async (payload) => {
|
mutationFn: async (payload) => {
|
||||||
await PaymentRequestRepository.CreatePaymentRequest(payload);
|
await PaymentRequestRepository.CreatePaymentRequest(payload);
|
||||||
},
|
},
|
||||||
|
|
||||||
onSuccess: (_, variables) => {
|
onSuccess: (_, variables) => {
|
||||||
queryClient.invalidateQueries({ queryKey: ["Expenses"] });
|
queryClient.invalidateQueries({ queryKey: ["PaymentRequest"] });
|
||||||
showToast("Expense Created Successfully", "success");
|
showToast("Payment Created Successfully", "success");
|
||||||
if (onSuccessCallBack) onSuccessCallBack();
|
if (onSuccessCallBack) onSuccessCallBack();
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
|
|||||||
@ -689,3 +689,14 @@ export const useUpdateProjectLevelEmployeePermission = () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export const useCurrencies = () => {
|
||||||
|
return useQuery({
|
||||||
|
queryKey: ["currencies"],
|
||||||
|
queryFn: async () => {
|
||||||
|
const resp = await ProjectRepository.getCurrencies();
|
||||||
|
return resp.data;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import { z } from "zod";
|
import { boolean, z } from "zod";
|
||||||
const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
|
const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
|
||||||
const ALLOWED_TYPES = [
|
const ALLOWED_TYPES = [
|
||||||
"application/pdf",
|
"application/pdf",
|
||||||
@ -14,6 +14,9 @@ export const PaymentRequestSchema = (expenseTypes) => {
|
|||||||
expenseCategoryId: z
|
expenseCategoryId: z
|
||||||
.string()
|
.string()
|
||||||
.min(1, { message: "Expense Category is required" }),
|
.min(1, { message: "Expense Category is required" }),
|
||||||
|
currencyId: z
|
||||||
|
.string()
|
||||||
|
.min(1, { message: "Currency is required" }),
|
||||||
dueDate: z.string().min(1, { message: "Date is required" }),
|
dueDate: z.string().min(1, { message: "Date is required" }),
|
||||||
description: z.string().min(1, { message: "Description is required" }),
|
description: z.string().min(1, { message: "Description is required" }),
|
||||||
payee: z.string().min(1, { message: "Supplier name is required" }),
|
payee: z.string().min(1, { message: "Supplier name is required" }),
|
||||||
@ -46,32 +49,6 @@ export const PaymentRequestSchema = (expenseTypes) => {
|
|||||||
)
|
)
|
||||||
.nonempty({ message: "At least one file attachment is required" }),
|
.nonempty({ message: "At least one file attachment is required" }),
|
||||||
})
|
})
|
||||||
.refine(
|
|
||||||
(data) => {
|
|
||||||
return (
|
|
||||||
!data.projectId || (data.paidById && data.paidById.trim() !== "")
|
|
||||||
);
|
|
||||||
},
|
|
||||||
{
|
|
||||||
message: "Please select who paid (employee)",
|
|
||||||
path: ["paidById"],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.superRefine((data, ctx) => {
|
|
||||||
const expenseType = expenseTypes.find(
|
|
||||||
(et) => et.id === data.expensesTypeId
|
|
||||||
);
|
|
||||||
if (
|
|
||||||
expenseType?.noOfPersonsRequired &&
|
|
||||||
(!data.noOfPersons || data.noOfPersons < 1)
|
|
||||||
) {
|
|
||||||
ctx.addIssue({
|
|
||||||
code: z.ZodIssueCode.custom,
|
|
||||||
message: "No. of Persons is required and must be at least 1",
|
|
||||||
path: ["noOfPersons"],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultPaymentRequest = {
|
export const defaultPaymentRequest = {
|
||||||
@ -83,7 +60,7 @@ export const defaultPaymentRequest = {
|
|||||||
dueDate: "",
|
dueDate: "",
|
||||||
projectId: "",
|
projectId: "",
|
||||||
expenseCategoryId: "",
|
expenseCategoryId: "",
|
||||||
isAdvancePayment:"",
|
isAdvancePayment:boolean,
|
||||||
billAttachments: [],
|
billAttachments: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -97,6 +97,9 @@ const ProjectRepository = {
|
|||||||
}
|
}
|
||||||
return api.get(url);
|
return api.get(url);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getCurrencies: () =>
|
||||||
|
api.get(`/api/Master/currencies/list`),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const TasksRepository = {
|
export const TasksRepository = {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user