Implementing Payee api for Payee.

This commit is contained in:
Kartik Sharma 2025-11-05 13:02:46 +05:30
parent 00f405069b
commit c0f30397ef
2 changed files with 68 additions and 96 deletions

View File

@ -7,7 +7,8 @@ import { zodResolver } from '@hookform/resolvers/zod';
import { defaultRecurringExpense, PaymentRecurringExpense } from './RecurringExpenseSchema'; import { defaultRecurringExpense, PaymentRecurringExpense } from './RecurringExpenseSchema';
import { FREQUENCY_FOR_RECURRING, INR_CURRENCY_CODE } from '../../utils/constants'; import { FREQUENCY_FOR_RECURRING, INR_CURRENCY_CODE } from '../../utils/constants';
import { useCurrencies, useProjectName } from '../../hooks/useProjects'; import { useCurrencies, useProjectName } from '../../hooks/useProjects';
import { useCreateRecurringExpense, useUpdateRecurringExpense } from '../../hooks/useExpense'; import { useCreateRecurringExpense, usePayee, useUpdateRecurringExpense } from '../../hooks/useExpense';
import InputSuggestions from '../common/InputSuggestion';
function ManageRecurringExpense({ closeModal, requestToEdit = null }) { function ManageRecurringExpense({ closeModal, requestToEdit = null }) {
@ -18,7 +19,7 @@ function ManageRecurringExpense({ closeModal, requestToEdit = null }) {
const { data: currencyData, isLoading: currencyLoading, isError: currencyError } = useCurrencies(); const { data: currencyData, isLoading: currencyLoading, isError: currencyError } = useCurrencies();
const { data: statusData, isLoading: statusLoading, isError: statusError } = useRecurringStatus(); const { data: statusData, isLoading: statusLoading, isError: statusError } = useRecurringStatus();
const { data: Payees, isLoading: isPayeeLoaing, isError: isPayeeError, error: payeeError } = usePayee()
const { const {
ExpenseCategories, ExpenseCategories,
@ -238,7 +239,7 @@ function ManageRecurringExpense({ closeModal, requestToEdit = null }) {
{/* Payee and Currency */} {/* Payee and Currency */}
<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="payee" className="form-label" required> <Label htmlFor="payee" className="form-label" required>
Payee (Supplier Name/Transporter Name/Other) Payee (Supplier Name/Transporter Name/Other)
</Label> </Label>
@ -254,6 +255,20 @@ function ManageRecurringExpense({ closeModal, requestToEdit = null }) {
{errors.payee.message} {errors.payee.message}
</small> </small>
)} )}
</div> */}
<div className="col-md-6">
<Label htmlFor="payee" className="form-label" required>
Payee (Supplier Name/Transporter Name/Other)
</Label>
<InputSuggestions
organizationList={Payees}
value={watch("payee") || ""}
onChange={(val) =>
setValue("payee", val, { shouldValidate: true })
}
error={errors.payee?.message}
/>
</div> </div>
@ -289,23 +304,25 @@ function ManageRecurringExpense({ closeModal, requestToEdit = null }) {
{/* Notify To and Status Id */} {/* Notify To and Status Id */}
<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="notifyTo" className="form-label" required> <Label htmlFor="frequency" className="form-label" required>
Notify (E-mail) Frequency
</Label> </Label>
<input <select
type="text" id="frequency"
id="notifyTo" className="form-select form-select-sm"
className="form-control form-control-sm" {...register("frequency", { valueAsNumber: true })}
{...register("notifyTo")} >
<option value="">Select Frequency</option>
/> {Object.entries(FREQUENCY_FOR_RECURRING).map(([key, label]) => (
{errors.notifyTo && ( <option key={key} value={key}>
<small className="danger-text"> {label}
{errors.notifyTo.message} </option>
</small> ))}
</select>
{errors.frequency && (
<small className="danger-text">{errors.frequency.message}</small>
)} )}
</div> </div>
<div className="col-md-6"> <div className="col-md-6">
<Label htmlFor="statusId" className="form-label" required> <Label htmlFor="statusId" className="form-label" required>
Status Status
@ -369,27 +386,26 @@ function ManageRecurringExpense({ closeModal, requestToEdit = null }) {
{/* Frequency */} {/* Frequency */}
<div className="col-md-6 text-start">
<Label htmlFor="frequency" className="form-label" required> <div className="row my-2 text-start">
Frequency <div className="col-md-6">
<Label htmlFor="notifyTo" className="form-label" required>
Notify (E-mail)
</Label> </Label>
<select <input
id="frequency" type="text"
className="form-select form-select-sm" id="notifyTo"
{...register("frequency", { valueAsNumber: true })} className="form-control form-control-sm"
> {...register("notifyTo")}
<option value="">Select Frequency</option>
{Object.entries(FREQUENCY_FOR_RECURRING).map(([key, label]) => ( />
<option key={key} value={key}> {errors.notifyTo && (
{label} <small className="danger-text">
</option> {errors.notifyTo.message}
))} </small>
</select>
{errors.frequency && (
<small className="danger-text">{errors.frequency.message}</small>
)} )}
</div> </div>
</div>
{/* Description */} {/* Description */}
<div className="row my-2 text-start"> <div className="row my-2 text-start">

View File

@ -1,65 +1,16 @@
import { boolean, z } from "zod"; import { boolean, z } from "zod";
import { INR_CURRENCY_CODE } from "../../utils/constants"; import { INR_CURRENCY_CODE } from "../../utils/constants";
// export const PaymentRecurringExpense = (expenseTypes) => {
// return z
// .object({
// title: z.string().min(1, { message: "Project is required" }),
// description: z.string().min(1, { message: "Description is required" }),
// payee: z.string().min(1, { message: "Supplier name is required" }),
// notifyTo: z.string().min(1, { message: "Notification is required" }),
// currencyId: z
// .string()
// .min(1, { message: "Currency is required" }),
// amount: z.coerce
// .number({
// invalid_type_error: "Amount is required and must be a number",
// })
// .min(1, "Amount must be Enter")
// .refine((val) => /^\d+(\.\d{1,2})?$/.test(val.toString()), {
// message: "Amount must have at most 2 decimal places",
// }),
// strikeDate: z.string().min(1, { message: "Date is required" }),
// projectId: z.string().min(1, { message: "Project is required" }),
// paymentBufferDays: z.string().min(1, { message: "Buffer days is required" }),
// numberOfIteration: z.string().min(1, { message: "Iteration is required" }),
// expenseCategoryId: z
// .string()
// .min(1, { message: "Expense Category is required" }),
// statusId: z.string().min(1, { message: "Please select a status" }),
// frequency: z.string().min(1, { message: "Frequency is required" }),
// isVariable: z.boolean().optional(),
// })
// };
export const PaymentRecurringExpense = (expenseTypes) => { export const PaymentRecurringExpense = (expenseTypes) => {
return z.object({ return z.object({
title: z.string().min(1, { message: "Project is required" }), title: z.string().min(1, { message: "Title is required" }).transform((val) => val.trim()),
description: z.string().min(1, { message: "Description is required" }).transform((val) => val.trim()),
description: z.string().min(1, { message: "Description is required" }), payee: z.string().min(1, { message: "Payee name is required" }).transform((val) => val.trim()),
notifyTo: z.string().min(1, { message: "Notification e-mail is required" }).transform((val) => val.trim()),
payee: z.string().min(1, { message: "Supplier name is required" }),
notifyTo: z.string().min(1, { message: "Notification is required" }),
currencyId: z currencyId: z
.string() .string()
.min(1, { message: "Currency is required" }), .min(1, { message: "Currency is required" })
.transform((val) => val.trim()),
amount: z amount: z
.number({ .number({
@ -76,11 +27,13 @@ export const PaymentRecurringExpense = (expenseTypes) => {
.min(1, { message: "Date is required" }) .min(1, { message: "Date is required" })
.refine((val) => !isNaN(Date.parse(val)), { .refine((val) => !isNaN(Date.parse(val)), {
message: "Invalid date format", message: "Invalid date format",
}), })
.transform((val) => val.trim()),
projectId: z projectId: z
.string() .string()
.min(1, { message: "Project is required" }), .min(1, { message: "Project is required" })
.transform((val) => val.trim()),
paymentBufferDays: z paymentBufferDays: z
.number({ .number({
@ -98,11 +51,13 @@ export const PaymentRecurringExpense = (expenseTypes) => {
expenseCategoryId: z expenseCategoryId: z
.string() .string()
.min(1, { message: "Expense Category is required" }), .min(1, { message: "Expense Category is required" })
.transform((val) => val.trim()),
statusId: z statusId: z
.string() .string()
.min(1, { message: "Please select a status" }), .min(1, { message: "Please select a status" })
.transform((val) => val.trim()),
frequency: z frequency: z
.number({ .number({
@ -115,6 +70,7 @@ export const PaymentRecurringExpense = (expenseTypes) => {
}); });
}; };
export const defaultRecurringExpense = { export const defaultRecurringExpense = {
title: "", title: "",
description: "", description: "",