diff --git a/src/components/RecurringExpense/ManageRecurringExpense.jsx b/src/components/RecurringExpense/ManageRecurringExpense.jsx index a9f3c913..9ba9146a 100644 --- a/src/components/RecurringExpense/ManageRecurringExpense.jsx +++ b/src/components/RecurringExpense/ManageRecurringExpense.jsx @@ -7,25 +7,26 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { defaultRecurringExpense, PaymentRecurringExpense } from './RecurringExpenseSchema'; import { INR_CURRENCY_CODE } from '../../utils/constants'; import { useCurrencies, useProjectName } from '../../hooks/useProjects'; -import { useCreateRecurringExpense } from '../../hooks/useExpense'; +import { useCreateRecurringExpense, usePayee, useRecurringExpenseDetail, useUpdateRecurringExpense } from '../../hooks/useExpense'; +import InputSuggestions from '../common/InputSuggestion'; +import MultiEmployeeSearchInput from '../common/MultiEmployeeSearchInput'; function ManageRecurringExpense({ closeModal, requestToEdit = null }) { - - const data = {} - const { projectNames, loading: projectLoading, error, isError: isProjectError, - } = useProjectName(); - - const { data: currencyData, isLoading: currencyLoading, isError: currencyError } = useCurrencies(); - - const { - ExpenseCategories, - loading: ExpenseLoading, - error: ExpenseError, - } = useExpenseCategory(); + data, + isLoading, + isError, + error: requestError, + } = useRecurringExpenseDetail(requestToEdit); + + //APIs + const { projectNames, loading: projectLoading, error, isError: isProjectError, } = useProjectName(); + const { data: currencyData, isLoading: currencyLoading, isError: currencyError } = useCurrencies(); + const { data: statusData, isLoading: statusLoading, isError: statusError } = useRecurringStatus(); + const { data: Payees, isLoading: isPayeeLoaing, isError: isPayeeError, error: payeeError } = usePayee() + const { ExpenseCategories, loading: ExpenseLoading, error: ExpenseError } = useExpenseCategory(); const schema = PaymentRecurringExpense(); - const { register, control, watch, handleSubmit, setValue, reset, formState: { errors }, } = useForm({ resolver: zodResolver(schema), defaultValues: defaultRecurringExpense, @@ -69,7 +70,6 @@ function ManageRecurringExpense({ closeModal, requestToEdit = null }) { // console.log("Veer",data) const onSubmit = (fromdata) => { - let payload = { ...fromdata, // strikeDate: localToUtc(fromdata.strikeDate), @@ -144,7 +144,6 @@ function ManageRecurringExpense({ closeModal, requestToEdit = null }) { )} - {/* Title and Is Variable */} @@ -158,6 +157,7 @@ function ManageRecurringExpense({ closeModal, requestToEdit = null }) { id="title" className="form-control form-control-sm" {...register("title")} + placeholder="Enter title" /> {errors.title && ( @@ -166,7 +166,7 @@ function ManageRecurringExpense({ closeModal, requestToEdit = null }) { )} -
+ {/*
@@ -183,10 +183,53 @@ function ManageRecurringExpense({ closeModal, requestToEdit = null }) { {errors.isVariable && ( {errors.isVariable.message} )} +
*/} + +
+ + + ( +
+
+ field.onChange(true)} + /> + +
+ +
+ field.onChange(false)} + /> + +
+
+ )} + /> + {errors.isVariable && ( + {errors.isVariable.message} + )}
- {/* Date and Amount */}
@@ -199,7 +242,6 @@ function ManageRecurringExpense({ closeModal, requestToEdit = null }) { minDate={new Date()} className='w-100' /> - {errors.strikeDate && ( {errors.strikeDate.message} @@ -219,6 +261,7 @@ function ManageRecurringExpense({ closeModal, requestToEdit = null }) { step="0.01" inputMode="decimal" {...register("amount", { valueAsNumber: true })} + placeholder="Enter amount" /> {errors.amount && ( {errors.amount.message} @@ -232,22 +275,17 @@ function ManageRecurringExpense({ closeModal, requestToEdit = null }) { - + setValue("payee", val, { shouldValidate: true }) + } + error={errors.payee?.message} + placeholder="Select or enter payee" /> - {errors.payee && ( - - {errors.payee.message} - - )} -
-
-
- {/* Notify To and Status Id */} + {/* Frequency To and Status Id */}
-
@@ -323,7 +363,6 @@ function ManageRecurringExpense({ closeModal, requestToEdit = null }) { {errors.statusId.message} )}
- {/* Payment Buffer Days and Number of Iteration */} @@ -340,6 +379,7 @@ function ManageRecurringExpense({ closeModal, requestToEdit = null }) { min="0" step="1" {...register("paymentBufferDays", { valueAsNumber: true })} + placeholder="Enter payment buffer days" /> {errors.paymentBufferDays && ( {errors.paymentBufferDays.message} @@ -356,6 +396,7 @@ function ManageRecurringExpense({ closeModal, requestToEdit = null }) { min="1" step="1" {...register("numberOfIteration", { valueAsNumber: true })} + placeholder="Enter number of iterations" /> {errors.numberOfIteration && ( {errors.numberOfIteration.message} @@ -363,6 +404,43 @@ function ManageRecurringExpense({ closeModal, requestToEdit = null }) { + {/* Notify */} + {/*
+
+ + + {errors.notifyTo && ( + + {errors.notifyTo.message} + + )} +
+
*/} + +
+
+ + + +
+
+ {/* Description */}
@@ -383,28 +461,6 @@ function ManageRecurringExpense({ closeModal, requestToEdit = null }) {
- {/*
- - -
*/} -
- - ) diff --git a/src/components/RecurringExpense/RecurringExpenseList.jsx b/src/components/RecurringExpense/RecurringExpenseList.jsx new file mode 100644 index 00000000..c5a6a4f4 --- /dev/null +++ b/src/components/RecurringExpense/RecurringExpenseList.jsx @@ -0,0 +1,283 @@ +import React, { useState } from "react"; +import { + EXPENSE_DRAFT, + EXPENSE_REJECTEDBY, + FREQUENCY_FOR_RECURRING, + ITEMS_PER_PAGE, +} from "../../utils/constants"; +import { + formatCurrency, + useDebounce, +} from "../../utils/appUtils"; +import { formatUTCToLocalTime } from "../../utils/dateUtils"; +import { ExpenseTableSkeleton } from "../Expenses/ExpenseSkeleton"; +import ConfirmModal from "../common/ConfirmModal"; +import { useNavigate } from "react-router-dom"; +import { useSelector } from "react-redux"; +import Error from "../common/Error"; +import { useRecurringExpenseContext } from "../../pages/RecurringExpense/RecurringExpensePage"; +import { useRecurringExpenseList } from "../../hooks/useExpense"; + +const RecurringExpenseList = ({ search, filterStatuses }) => { + const { setManageRequest, setVieRequest } = useRecurringExpenseContext(); + const navigate = useNavigate(); + const [IsDeleteModalOpen, setIsDeleteModalOpen] = useState(false); + const [deletingId, setDeletingId] = useState(null); + + const SelfId = useSelector( + (store) => store?.globalVariables?.loginUser?.employeeInfo?.id + ); + + const recurringExpenseColumns = [ + { + key: "expenseCategory", + label: "Category", + align: "text-start", + getValue: (e) => e?.expenseCategory?.name || "N/A", + }, + { + key: "title", + label: "Title", + align: "text-start", + getValue: (e) => e?.title || "N/A", + }, + { + key: "payee", + label: "Payee", + align: "text-start", + getValue: (e) => e?.payee || "N/A", + }, + { + key: "frequency", + label: "Frequency", + align: "text-start", + getValue: (e) => + e?.frequency !== undefined && e?.frequency !== null + ? FREQUENCY_FOR_RECURRING[e.frequency] || "N/A" + : "N/A", + }, + { + key: "amount", + label: "Amount", + align: "text-end", + getValue: (e) => + e?.amount + ? `${e?.currency?.symbol || ""}${e.amount.toLocaleString()}` + : "N/A", + }, + { + key: "createdAt", + label: "Next Generation Date", + align: "text-center", + getValue: (e) => + e?.createdAt ? formatUTCToLocalTime(e.createdAt) : "N/A", + }, + { + key: "status", + label: "Status", + align: "text-start", + getValue: (e) => e?.status?.name || "N/A", + }, + + ]; + + + const [currentPage, setCurrentPage] = useState(1); + const debouncedSearch = useDebounce(search, 500); + + const { data, isLoading, isError, error, isRefetching, refetch } = + useRecurringExpenseList( + ITEMS_PER_PAGE, + currentPage, + {}, + true, + debouncedSearch + ); + + const recurringExpenseData = data?.data || []; + const totalPages = data?.totalPages || 1; + + if (isError) { + return ; + } + + const header = [ + "Category", + "Title", + "Amount", + "Payee", + "Frequency", + "Next Generation", + "Status", + "Action", + ]; + + if (isLoading) return ; + + const canEditExpense = (recurringExpense) => { + // return ( + // (recurringExpense?.expenseStatus?.id === EXPENSE_DRAFT || + // EXPENSE_REJECTEDBY.includes(recurringExpense?.expenseStatus.id)) && + // recurringExpense?.createdBy?.id === SelfId + // ); + }; + + const canDeleteExpense = (request) => { + return ( + request?.expenseStatus?.id === EXPENSE_DRAFT && + request?.createdBy?.id === SelfId + ); + }; + + const filteredData = recurringExpenseData.filter((item) => + filterStatuses.includes(item?.status?.id) + ); + + const handleDelete = (id) => { + setDeletingId(id); + DeleteExpense( + { id }, + { + onSettled: () => { + setDeletingId(null); + setIsDeleteModalOpen(false); + }, + } + ); + }; + + return ( + <> + {IsDeleteModalOpen && ( + setIsDeleteModalOpen(false)} + paramData={deletingId} + /> + )} + +
+
+ + + + {recurringExpenseColumns.map((col) => ( + + ))} + + + + + + {filteredData.length > 0 ? ( + filteredData.map((recurringExpense) => ( + + {recurringExpenseColumns.map((col) => ( + + ))} + + + )) + ) : ( + + + + )} + +
+ {col.label} + Action
+ {col?.customRender + ? col?.customRender(recurringExpense) + : col?.getValue(recurringExpense)} + +
+ + // setVieRequest({ + // requestId: recurringExpense.id, + // view: true, + // }) + // } + > + {/* Uncomment for edit/delete actions */} + +
+ +
    +
  • + setManageRequest({ + IsOpen: true, + RecurringId: recurringExpense.id, + }) + } + > + + + Modify + +
  • + +
  • { + setIsDeleteModalOpen(true); + setDeletingId(recurringExpense.id); + }} + > + + + Delete + +
  • + +
+
+
+
+

No Recurring Expense Found

+
+
+ + {/* Pagination */} + {totalPages > 1 && ( +
+ +
+ )} +
+ + ); +}; + +export default RecurringExpenseList; diff --git a/src/components/RecurringExpense/RecurringExpenseSchema.js b/src/components/RecurringExpense/RecurringExpenseSchema.js index 7c5e3b9e..b7c312a2 100644 --- a/src/components/RecurringExpense/RecurringExpenseSchema.js +++ b/src/components/RecurringExpense/RecurringExpenseSchema.js @@ -1,65 +1,16 @@ import { boolean, z } from "zod"; 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) => { 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" }), - + 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()), + 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()), currencyId: z .string() - .min(1, { message: "Currency is required" }), + .min(1, { message: "Currency is required" }) + .transform((val) => val.trim()), amount: z .number({ @@ -76,11 +27,13 @@ export const PaymentRecurringExpense = (expenseTypes) => { .min(1, { message: "Date is required" }) .refine((val) => !isNaN(Date.parse(val)), { message: "Invalid date format", - }), + }) + .transform((val) => val.trim()), projectId: z .string() - .min(1, { message: "Project is required" }), + .min(1, { message: "Project is required" }) + .transform((val) => val.trim()), paymentBufferDays: z .number({ @@ -98,23 +51,28 @@ export const PaymentRecurringExpense = (expenseTypes) => { expenseCategoryId: z .string() - .min(1, { message: "Expense Category is required" }), + .min(1, { message: "Expense Category is required" }) + .transform((val) => val.trim()), statusId: z .string() - .min(1, { message: "Please select a status" }), + .min(1, { message: "Please select a status" }) + .transform((val) => val.trim()), frequency: z .number({ required_error: "Frequency is required", invalid_type_error: "Frequency must be a number", }) - .min(1, { message: "Frequency must be greater than 0" }), + .refine((val) => [0, 1, 2, 3, 4, 5].includes(val), { + message: "Invalid frequency selected", + }), isVariable: z.boolean().optional(), }); }; + export const defaultRecurringExpense = { title: "", description: "", @@ -129,30 +87,26 @@ export const defaultRecurringExpense = { expenseCategoryId: "", statusId: "", frequency: 1, - isVariable: false, + isVariable: true, }; -// export const SearchPaymentRequestSchema = z.object({ -// projectIds: z.array(z.string()).optional(), -// statusIds: z.array(z.string()).optional(), -// createdByIds: z.array(z.string()).optional(), -// currencyIds: z.array(z.string()).optional(), -// expenseCategoryIds: z.array(z.string()).optional(), -// payees: z.array(z.string()).optional(), -// startDate: z.string().optional(), -// endDate: z.string().optional(), -// }); - -// export const defaultPaymentRequestFilter = { -// projectIds: [], -// statusIds: [], -// createdByIds: [], -// currencyIds: [], -// expenseCategoryIds: [], -// payees: [], -// startDate: null, -// endDate: null, -// }; +export const SearchRecurringExpenseSchema = z.object({ + title: z.array(z.string()).optional(), + description: z.array(z.string()).optional(), + payee: z.array(z.string()).optional(), + notifyTo: z.array(z.string()).optional(), + currencyId: z.array(z.string()).optional(), + amount: z.array(z.string()).optional(), + strikeDate: z.string().optional(), + projectId: z.string().optional(), + paymentBufferDays: z.string().optional(), + numberOfIteration: z.string().optional(), + expenseCategoryId: z.string().optional(), + statusId: z.string().optional(), + frequency: z.string().optional(), + isVariable: z.string().optional(), +}); + diff --git a/src/components/common/EmployeeSearchInput.jsx b/src/components/common/EmployeeSearchInput.jsx index ede14c41..aa33c077 100644 --- a/src/components/common/EmployeeSearchInput.jsx +++ b/src/components/common/EmployeeSearchInput.jsx @@ -3,9 +3,6 @@ import { useEmployeesName } from "../../hooks/useEmployees"; import { useDebounce } from "../../utils/appUtils"; import { useController } from "react-hook-form"; import Avatar from "./Avatar"; - - - const EmployeeSearchInput = ({ control, name, diff --git a/src/components/common/MultiEmployeeSearchInput.jsx b/src/components/common/MultiEmployeeSearchInput.jsx new file mode 100644 index 00000000..bb42e2b2 --- /dev/null +++ b/src/components/common/MultiEmployeeSearchInput.jsx @@ -0,0 +1,181 @@ +import { useState, useEffect, useRef } from "react"; +import { useEmployeesName } from "../../hooks/useEmployees"; +import { useDebounce } from "../../utils/appUtils"; +import { useController } from "react-hook-form"; +import Avatar from "../common/Avatar"; + +const MultiEmployeeSearchInput = ({ + control, + name, + projectId, + placeholder, + forAll, +}) => { + const { + field: { onChange, value, ref }, + fieldState: { error }, + } = useController({ name, control }); + + const [search, setSearch] = useState(""); + const [showDropdown, setShowDropdown] = useState(false); + const [selectedEmployees, setSelectedEmployees] = useState([]); + const dropdownRef = useRef(null); + + const debouncedSearch = useDebounce(search, 500); + + const { data: employees, isLoading } = useEmployeesName( + projectId, + debouncedSearch, + forAll + ); + +useEffect(() => { + if (value && employees?.data) { + // Ensure value is a string (sometimes it may come as array/object) + const stringValue = + typeof value === "string" + ? value + : Array.isArray(value) + ? value.join(",") + : ""; + + const emails = stringValue.split(",").filter(Boolean); + const foundEmps = employees.data.filter((emp) => + emails.includes(emp.email) + ); + + setSelectedEmployees(foundEmps); + + if (forAll && foundEmps.length > 0) { + setSearch(""); // clear search field + } + } +}, [value, employees?.data, forAll]); + + + const handleSelect = (employee) => { + if (!selectedEmployees.find((emp) => emp.email === employee.email)) { + const newSelected = [...selectedEmployees, employee]; + setSelectedEmployees(newSelected); + // Store emails instead of IDs + onChange( + newSelected + .map((e) => e.email) + .filter(Boolean) + .join(",") + ); + setSearch(""); + setShowDropdown(false); + } + }; + + const handleRemove = (email) => { + const newSelected = selectedEmployees.filter((e) => e.email !== email); + setSelectedEmployees(newSelected); + onChange( + newSelected + .map((e) => e.email) + .filter(Boolean) + .join(",") + ); + }; + + useEffect(() => { + const handleClickOutside = (event) => { + if (dropdownRef.current && !dropdownRef.current.contains(event.target)) { + setShowDropdown(false); + } + }; + const handleEsc = (event) => { + if (event.key === "Escape") setShowDropdown(false); + }; + + document.addEventListener("mousedown", handleClickOutside); + document.addEventListener("keydown", handleEsc); + + return () => { + document.removeEventListener("mousedown", handleClickOutside); + document.removeEventListener("keydown", handleEsc); + }; + }, []); + + return ( +
+
+ {selectedEmployees.map((emp) => ( +
+ + {emp.firstName} {emp.lastName} + handleRemove(emp.email)} + > + × + +
+ ))} +
+ + + { + setSearch(e.target.value); + setShowDropdown(true); + }} + onFocus={() => setShowDropdown(true)} + /> + + {showDropdown && (employees?.data?.length > 0 || isLoading) && ( +
    + {isLoading ? ( +
  • Searching...
  • + ) : ( + employees?.data + ?.filter((emp) => !selectedEmployees.find((e) => e.email === emp.email)) + .map((emp) => ( +
  • handleSelect(emp)} + > +
    + + {`${emp.firstName} ${emp.lastName}`} +
    +
  • + )) + )} +
+ )} + + {error && {error.message}} +
+ ); +}; + +export default MultiEmployeeSearchInput; + diff --git a/src/hooks/useExpense.js b/src/hooks/useExpense.js index 4f38de56..b9fa6f11 100644 --- a/src/hooks/useExpense.js +++ b/src/hooks/useExpense.js @@ -407,4 +407,53 @@ export const useCreateRecurringExpense = (onSuccessCallBack) => { ); }, }); -}; \ No newline at end of file +}; + +export const useUpdateRecurringExpense = (onSuccessCallBack) => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: async ({ id, payload }) => { + const response = await ExpenseRepository.UpdateRecurringExpense(id, payload); + return response.data; + }, + onSuccess: (updatedExpense, variables) => { + queryClient.removeQueries({ queryKey: ["recurringExpense", variables.id] }); + queryClient.invalidateQueries({ queryKey: ["recurringExpenseList"] }); + showToast("Recurring Expense updated Successfully", "success"); + + if (onSuccessCallBack) onSuccessCallBack(); + }, + onError: (error) => { + showToast("Something went wrong.Please try again later.", "error"); + }, + }); +}; + +export const useRecurringExpenseList = ( + pageSize, + pageNumber, + filter, + isActive, + searchString = "", +) => { + return useQuery({ + queryKey: ["recurringExpenseList",pageSize,pageNumber,filter,isActive,searchString], + queryFn: async()=>{ + const resp = await ExpenseRepository.GetRecurringExpenseList(pageSize,pageNumber,filter,isActive,searchString); + return resp.data; + }, + keepPreviousData: true, + }); +}; + +export const useRecurringExpenseDetail =(RequestId)=>{ + return useQuery({ + queryKey:['recurringExpense',RequestId], + queryFn:async()=>{ + RequestId + const resp = await ExpenseRepository.GetRecurringExpense(RequestId); + return resp.data; + }, + enabled:!!RequestId + }) +} diff --git a/src/pages/RecurringExpense/RecurringExpensePage.jsx b/src/pages/RecurringExpense/RecurringExpensePage.jsx index 60da6be8..0fd5ceb2 100644 --- a/src/pages/RecurringExpense/RecurringExpensePage.jsx +++ b/src/pages/RecurringExpense/RecurringExpensePage.jsx @@ -4,7 +4,9 @@ import GlobalModel from "../../components/common/GlobalModel"; import { useFab } from "../../Context/FabContext"; // import { defaultPaymentRequestFilter,SearchPaymentRequestSchema } from "../../components/PaymentRequest/PaymentRequestSchema"; import ManageRecurringExpense from "../../components/RecurringExpense/ManageRecurringExpense"; -import RecurringExpenseList from "../../components/RecurringExpense/RecurringRexpenseList"; +import RecurringExpenseList from "../../components/RecurringExpense/RecurringExpenseList"; +import { PAYEE_RECURRING_EXPENSE } from "../../utils/constants"; +import { SearchRecurringExpenseSchema } from "../../components/RecurringExpense/RecurringExpenseSchema"; export const RecurringExpenseContext = createContext(); export const useRecurringExpenseContext = () => { @@ -20,8 +22,10 @@ const RecurringExpensePage = () => { RequestId: null, }); const [ViewRequest, setVieRequest] = useState({ view: false, requestId: null }) - const { setOffcanvasContent, setShowTrigger } = useFab(); - // const [filters, setFilters] = useState(defaultPaymentRequestFilter); + + const [selectedStatuses, setSelectedStatuses] = useState( + PAYEE_RECURRING_EXPENSE.map((s) => s.id) + ); const [search, setSearch] = useState(""); @@ -30,19 +34,13 @@ const RecurringExpensePage = () => { setVieRequest }; - useEffect(() => { - - setShowTrigger(true); - setOffcanvasContent( - "Payment Request Filters", - // + const handleStatusChange = (id) => { + setSelectedStatuses((prev) => + prev.includes(id) + ? prev.filter((s) => s !== id) + : [...prev, id] ); - - return () => { - setShowTrigger(false); - setOffcanvasContent("", null); - }; - }, []); + }; return ( @@ -57,19 +55,47 @@ const RecurringExpensePage = () => { {/* Top Bar */}
-
-
-
+
+
+ {/* Left side: Search + Filter */} +
setSearch(e.target.value)} + onChange={(e) => setSearch(e.target.value)} /> + +
+ +
    + {PAYEE_RECURRING_EXPENSE.map(({ id, label }) => ( +
  • +
    + handleStatusChange(id)} + /> + +
    +
  • + ))} +
+
-
+ {/* Right side: Add Button */} +
- {/* */} - + + {/* Add/Edit Modal */} {ManageRequest.IsOpen && ( diff --git a/src/repositories/ExpsenseRepository.jsx b/src/repositories/ExpsenseRepository.jsx index 2bcc5596..09db8ac8 100644 --- a/src/repositories/ExpsenseRepository.jsx +++ b/src/repositories/ExpsenseRepository.jsx @@ -31,7 +31,8 @@ const ExpenseRepository = { //#region Recurring Expense CreateRecurringExpense: (data) => api.post("/api/Expense/recurring-payment/create", data), - + UpdateRecurringExpense: (id, data) => api.put(`/api/Expense/recurring-payment/edit/${id}`, data), + GetRecurringExpense: (id) => api.get(`/api/Expense/get/recurring-payment/details/${id}`), //#endregion diff --git a/src/utils/constants.jsx b/src/utils/constants.jsx index b264207c..67aa189e 100644 --- a/src/utils/constants.jsx +++ b/src/utils/constants.jsx @@ -159,10 +159,10 @@ export const PROJECT_STATUS = [ export const EXPENSE_STATUS = { - daft:"297e0d8f-f668-41b5-bfea-e03b354251c8", - review_pending:"6537018f-f4e9-4cb3-a210-6c3b2da999d7", - payment_pending:"f18c5cfd-7815-4341-8da2-2c2d65778e27", - approve_pending:"4068007f-c92f-4f37-a907-bc15fe57d4d8", + daft: "297e0d8f-f668-41b5-bfea-e03b354251c8", + review_pending: "6537018f-f4e9-4cb3-a210-6c3b2da999d7", + payment_pending: "f18c5cfd-7815-4341-8da2-2c2d65778e27", + approve_pending: "4068007f-c92f-4f37-a907-bc15fe57d4d8", } @@ -177,4 +177,32 @@ export const ALLOW_PROJECTSTATUS_ID = [ export const DEFAULT_EMPTY_STATUS_ID = "00000000-0000-0000-0000-000000000000"; +export const FREQUENCY_FOR_RECURRING = { + 0: "Monthly", + 1: "Quarterly", + 2: "Half-Yearly", + 3: "Yearly", + 4: "Daily", + 5: "Weekly" +}; + +export const PAYEE_RECURRING_EXPENSE = [ + { + id: "da462422-13b2-45cc-a175-910a225f6fc8", + label: "Active", + }, + { + id: "306856fb-5655-42eb-bf8b-808bb5e84725", + label: "Completed", + }, + { + id: "3ec864d2-8bf5-42fb-ba70-5090301dd816", + label: "De-Activited", + }, + { + id: "8bfc9346-e092-4a80-acbf-515ae1ef6868", + label: "Paused", + }, +]; +