import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import ExpenseRepository from "../repositories/ExpsenseRepository"; import showToast from "../services/toastService"; import { queryClient } from "../layouts/AuthLayout"; import { useSelector } from "react-redux"; import moment from "moment"; // -------------------Query------------------------------------------------------ const cleanFilter = (filter) => { const cleaned = { ...filter }; ["projectIds", "statusIds", "createdByIds", "paidById"].forEach((key) => { if (Array.isArray(cleaned[key]) && cleaned[key].length === 0) { delete cleaned[key]; } }); // moment.utc() to get consistent UTC ISO strings // if (!cleaned.startDate) { // cleaned.startDate = moment.utc().subtract(7, "days").startOf("day").toISOString(); // } // if (!cleaned.endDate) { // cleaned.endDate = moment.utc().startOf("day").toISOString(); // } return cleaned; }; export const useExpenseList = ( pageSize, pageNumber, filter, searchString = "" ) => { return useQuery({ queryKey: ["Expenses", pageNumber, pageSize, filter, searchString], queryFn: async () => { const cleanedFilter = cleanFilter(filter); const response = await ExpenseRepository.GetExpenseList( pageSize, pageNumber, cleanedFilter, searchString ); return response.data; }, keepPreviousData: true, }); }; export const useExpense = (ExpenseId) => { return useQuery({ queryKey: ["Expense", ExpenseId], queryFn: async () => await ExpenseRepository.GetExpenseDetails(ExpenseId).then( (res) => res.data ), enabled: !!ExpenseId, }); }; export const useExpenseFilter = () => { return useQuery({ queryKey: ["ExpenseFilter"], queryFn: async () => await ExpenseRepository.GetExpenseFilter().then((res) => res.data), }); }; // ---------------------------Mutation--------------------------------------------- export const useCreateExpnse = (onSuccessCallBack) => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async (payload) => { await ExpenseRepository.CreateExpense(payload); }, onSuccess: (_, variables) => { queryClient.invalidateQueries({ queryKey: ["Expenses"] }); showToast("Expense Created Successfully", "success"); if (onSuccessCallBack) onSuccessCallBack(); }, onError: (error) => { showToast( error.message || "Something went wrong please try again !", "error" ); }, }); }; export const useUpdateExpense = (onSuccessCallBack) => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async ({ id, payload }) => { const response = await ExpenseRepository.UpdateExpense(id, payload); return response.data; }, onSuccess: (updatedExpense, variables) => { // queryClient.setQueriesData( // {queryKey:['expenses'],exact:true}, // (oldData) => { // if (!oldData || !oldData.data) return oldData; // const updatedList = oldData.data.map((expense) => { // if (expense.id !== variables.id) return expense; // return { // ...expense, // project: // expense.project.id !== updatedExpense.project.id // ? updatedExpense.project // : expense.project, // expensesType: // expense.expensesType.id !== updatedExpense.expensesType.id // ? updatedExpense.expensesType // : expense.expensesType, // paymentMode: // expense.paymentMode.id !== updatedExpense.paymentMode.id // ? updatedExpense.paymentMode // : expense.paymentMode, // paidBy: // expense.paidBy.id !== updatedExpense.paidBy.id // ? updatedExpense.paidBy // : expense.paidBy, // createdBy: // expense.createdBy.id !== updatedExpense.createdBy.id // ? updatedExpense.createdBy // : expense.createdBy, // createdAt: updatedExpense.createdAt, // status: updatedExpense.status, // nextStatus: updatedExpense.nextStatus, // preApproved: updatedExpense.preApproved, // transactionDate: updatedExpense.transactionDate, // amount: updatedExpense.amount, // }; // }); // return { // ...oldData, // data: updatedList, // }; // } // ); queryClient.removeQueries({ queryKey: ["Expense", variables.id] }); queryClient.invalidateQueries({ queryKey: ["Expenses"] }); showToast("Expense updated Successfully", "success"); if (onSuccessCallBack) onSuccessCallBack(); }, onError: (error) => { showToast("Something went wrong.Please try again later.", "error"); }, }); }; export const useActionOnExpense = (onSuccessCallBack) => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async (payload) => { const response = await ExpenseRepository.ActionOnExpense(payload); return response.data; }, onSuccess: (updatedExpense, variables) => { showToast("Request processed successfully.", "success"); // queryClient.setQueriesData( // { // queryKey: ["Expenses"], // exact: false, // }, // (oldData) => { // if (!oldData) return oldData; // return { // ...oldData, // data: oldData.data.map((item) => // item.id === updatedExpense.id // ? { // ...item, // nextStatus: updatedExpense.nextStatus, // status: updatedExpense.status, // } // : item // ), // }; // } // ); // queryClient.setQueriesData( // { queryKey: ["Expense", updatedExpense.id] }, // (oldData) => { // return { // ...oldData, // nextStatus: updatedExpense.nextStatus, // status: updatedExpense.status, // }; // } // ); queryClient.invalidateQueries({queryKey:["Expense",updatedExpense.id]}) queryClient.invalidateQueries({queryKey:["Expenses"]}) if (onSuccessCallBack) onSuccessCallBack(); }, onError: (error) => { showToast( error.response.data.message || "Something went wrong.Please try again later.", "error" ); }, }); }; export const useDeleteExpense = () => { const queryClient = useQueryClient(); return useMutation({ mutationFn: async ({ id }) => { const response = await ExpenseRepository.DeleteExpense(id); return response.data; }, onSuccess: (data, variables) => { queryClient.setQueryData(["Expenses"], (oldData) => { if (!oldData || !oldData.data) return queryClient.invalidateQueries({ queryKey: ["Expenses"] }); const updatedList = oldData.data.filter( (expense) => expense.id !== variables.id ); return { ...oldData, data: updatedList, }; }); showToast(data.message || "Expense deleted successfully", "success"); }, onError: (error) => { showToast( error.message || error.response.message || "Something went wrong.Please try again later.", "error" ); }, }); }; export const useHasAnyPermission = (permissionIdsInput) => { const permissions = useSelector((state) => state?.profile?.permissions || []); const permissionIds = Array.isArray(permissionIdsInput) ? permissionIdsInput : []; // No permission needed if (permissionIds.length === 0) return true; return permissionIds.some((id) => permissions.includes(id)); };