From 6f228ed5f1279ec51a5c55b87e22a46a82fecbfd Mon Sep 17 00:00:00 2001 From: "pramod.mahajan" Date: Sat, 8 Nov 2025 09:10:35 +0530 Subject: [PATCH] added currency,rename of ExpenseType to expenseCategory - hooks,( expenseCategoryIds = fileter object) --- .../Expenses/ExpenseFilterChips.jsx | 6 +- .../Expenses/ExpenseFilterPanel.jsx | 6 +- src/components/Expenses/ExpenseList.jsx | 106 ++++++------ src/components/Expenses/ExpenseSchema.js | 14 +- src/components/Expenses/ManageExpense.jsx | 161 ++++++++---------- src/hooks/masterHook/useMaster.js | 12 +- src/pages/Expense/ExpensePage.jsx | 2 +- src/repositories/MastersRepository.jsx | 22 ++- 8 files changed, 167 insertions(+), 162 deletions(-) diff --git a/src/components/Expenses/ExpenseFilterChips.jsx b/src/components/Expenses/ExpenseFilterChips.jsx index c44dd7a5..77bec83e 100644 --- a/src/components/Expenses/ExpenseFilterChips.jsx +++ b/src/components/Expenses/ExpenseFilterChips.jsx @@ -4,21 +4,19 @@ const ExpenseFilterChips = ({ filters, filterData, removeFilterChip }) => { // Build chips from filters const filterChips = useMemo(() => { const chips = []; - const buildGroup = (ids, list, label, key) => { if (!ids?.length) return; const items = ids.map((id) => ({ id, - name: list.find((item) => item.id === id)?.name || id, + name: list?.find((item) => item.id === id)?.name || id, })); chips.push({ key, label, items }); }; - buildGroup(filters.projectIds, filterData.projects, "Project", "projectIds"); buildGroup(filters.createdByIds, filterData.createdBy, "Submitted By", "createdByIds"); buildGroup(filters.paidById, filterData.paidBy, "Paid By", "paidById"); buildGroup(filters.statusIds, filterData.status, "Status", "statusIds"); - buildGroup(filters.ExpenseTypeIds, filterData.expensesType, "Category", "ExpenseTypeIds"); + buildGroup(filters.expenseCategoryIds, filterData.expenseCategory, "Category", "expenseCategoryIds"); if (filters.startDate || filters.endDate) { const start = filters.startDate diff --git a/src/components/Expenses/ExpenseFilterPanel.jsx b/src/components/Expenses/ExpenseFilterPanel.jsx index 8b1f8bb6..61583902 100644 --- a/src/components/Expenses/ExpenseFilterPanel.jsx +++ b/src/components/Expenses/ExpenseFilterPanel.jsx @@ -31,7 +31,7 @@ const ExpenseFilterPanel = forwardRef(({ onApply, handleGroupBy, setFilterdata } { id: "submittedBy", name: "Submitted By" }, { id: "project", name: "Project" }, { id: "paymentMode", name: "Payment Mode" }, - { id: "expensesType", name: "Expense Category" }, + { id: "expenseCategory", name: "Expense Category" }, { id: "createdAt", name: "Submitted Date" }, ].sort((a, b) => a.name.localeCompare(b.name)); }, []); @@ -46,7 +46,7 @@ const ExpenseFilterPanel = forwardRef(({ onApply, handleGroupBy, setFilterdata } projectIds: defaultFilter.projectIds || [], createdByIds: defaultFilter.createdByIds || [], paidById: defaultFilter.paidById || [], - ExpenseCategoryIds: defaultFilter.ExpenseCategoryIds || [], + expenseCategoryIds: defaultFilter.expenseCategoryIds || [], isTransactionDate: defaultFilter.isTransactionDate ?? true, startDate: defaultFilter.startDate, endDate: defaultFilter.endDate, @@ -214,7 +214,7 @@ const ExpenseFilterPanel = forwardRef(({ onApply, handleGroupBy, setFilterdata } valueKey="id" /> item.name} diff --git a/src/components/Expenses/ExpenseList.jsx b/src/components/Expenses/ExpenseList.jsx index 92fd292b..48affa5e 100644 --- a/src/components/Expenses/ExpenseList.jsx +++ b/src/components/Expenses/ExpenseList.jsx @@ -129,7 +129,7 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => { align: "text-start mx-2", }, { - key: "expensesCategory", + key: "expenseCategory", label: "Expense Category", getValue: (e) => e.expenseCategory?.name || "N/A", align: "text-start", @@ -225,6 +225,7 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => { ]?.includes(groupBy); const canEditExpense = (expense) => { + debugger; return ( (expense?.status?.id === EXPENSE_DRAFT || EXPENSE_REJECTEDBY.includes(expense?.status?.id)) && @@ -352,61 +353,58 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => { }) } > - {canDetetExpense(expense) && - canEditExpense(expense) && ( -
- +
    +
  • + setManageExpenseModal({ + IsOpen: true, + expenseId: expense.id, + }) + } > - - -
      - {canDetetExpense(expense) && ( -
    • - setManageExpenseModal({ - IsOpen: true, - expenseId: expense.id, - }) - } - > - - - - Modify - - -
    • - )} + + + + Modify + + + - {canDetetExpense(expense) && ( -
    • { - setIsDeleteModalOpen(true); - setDeletingId(expense.id); - }} - > - - - - Delete - - -
    • - )} -
    -
- )} + {canDetetExpense(expense) && ( +
  • { + setIsDeleteModalOpen(true); + setDeletingId(expense.id); + }} + > + + + + Delete + + +
  • + )} + + + )} diff --git a/src/components/Expenses/ExpenseSchema.js b/src/components/Expenses/ExpenseSchema.js index cad4cb31..428ccf52 100644 --- a/src/components/Expenses/ExpenseSchema.js +++ b/src/components/Expenses/ExpenseSchema.js @@ -10,7 +10,7 @@ const ALLOWED_TYPES = [ "image/jpeg", ]; -export const ExpenseSchema = (ExpenseCategories) => { +export const ExpenseSchema = (expenseCategories) => { return z .object({ projectId: z.string().min(1, { message: "Project is required" }), @@ -70,12 +70,12 @@ export const ExpenseSchema = (ExpenseCategories) => { } ) .superRefine((data, ctx) => { - const ExpenseCategory = ExpenseCategories.find( - (et) => et.id === data.expenseCategoryId + const ExpenseCategory = expenseCategories?.find( + (et) => et.id === data?.expenseCategoryId ); if ( ExpenseCategory?.noOfPersonsRequired && - (!data.noOfPersons || data.noOfPersons < 1) + (!data?.noOfPersons || data?.noOfPersons < 1) ) { ctx.addIssue({ code: z.ZodIssueCode.custom, @@ -168,7 +168,7 @@ export const defaultActionValues = { reimburseDate: null, reimburseById: null, tdsPercentage: null, - baseAmount:null, + baseAmount: null, taxAmount: null, }; @@ -177,7 +177,7 @@ export const SearchSchema = z.object({ statusIds: z.array(z.string()).optional(), createdByIds: z.array(z.string()).optional(), paidById: z.array(z.string()).optional(), - ExpenseCategoryIds: z.array(z.string()).optional(), + expenseCategoryIds: z.array(z.string()).optional(), startDate: z.string().optional(), endDate: z.string().optional(), isTransactionDate: z.boolean().default(true), @@ -188,7 +188,7 @@ export const defaultFilter = { statusIds: [], createdByIds: [], paidById: [], - ExpenseCategoryIds: [], + expenseCategoryIds: [], isTransactionDate: true, startDate: null, endDate: null, diff --git a/src/components/Expenses/ManageExpense.jsx b/src/components/Expenses/ManageExpense.jsx index 7ea269ee..8963fdc4 100644 --- a/src/components/Expenses/ManageExpense.jsx +++ b/src/components/Expenses/ManageExpense.jsx @@ -3,10 +3,11 @@ import React, { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; import { defaultExpense, ExpenseSchema } from "./ExpenseSchema"; import { formatFileSize, localToUtc } from "../../utils/appUtils"; -import { useProjectName } from "../../hooks/useProjects"; +import { useProjectName } from "../../hooks/useProjects"; import { useDispatch, useSelector } from "react-redux"; import { changeMaster } from "../../slices/localVariablesSlice"; import useMaster, { + useCurrencies, useExpenseCategory, useExpenseStatus, usePaymentMode, @@ -29,6 +30,8 @@ import DatePicker from "../common/DatePicker"; import ErrorPage from "../../pages/ErrorPage"; import Label from "../common/Label"; import EmployeeSearchInput from "../common/EmployeeSearchInput"; +import Filelist from "./Filelist"; +import { DEFAULT_CURRENCY } from "../../utils/constants"; const ManageExpense = ({ closeModal, expenseToEdit = null }) => { const { @@ -36,7 +39,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => { isLoading, error: ExpenseErrorLoad, } = useExpense(expenseToEdit); - const [ExpenseType, setExpenseType] = useState(); + const [expenseCategory, setExpenseCategory] = useState(); const dispatch = useDispatch(); const { expenseCategories, @@ -65,7 +68,11 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => { error, isError: isProjectError, } = useProjectName(); - + const { + data: currencies, + isLoading: currencyLoading, + error: currencyError, + } = useCurrencies(); const { PaymentModes, loading: PaymentModeLoading, @@ -81,6 +88,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => { isLoading: EmpLoading, isError: isEmployeeError, } = useEmployeesNameByProject(selectedproject); + const files = watch("billAttachments"); const onFileChange = async (e) => { const newFiles = Array.from(e.target.files); @@ -146,7 +154,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => { if (expenseToEdit && data) { reset({ projectId: data.project.id || "", - expenseCategoryId: data?.expenseCategory?.id || "", + expenseCategoryId: data?.expenseCategory?.id || "", paymentModeId: data.paymentMode.id || "", paidById: data.paidBy.id || "", transactionDate: data.transactionDate?.slice(0, 10) || "", @@ -157,6 +165,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => { amount: data.amount || "", noOfPersons: data.noOfPersons || "", gstNumber: data.gstNumber || "", + currencyId: data.currencyId || DEFAULT_CURRENCY, billAttachments: data.documents ? data.documents.map((doc) => ({ fileName: doc.fileName, @@ -195,7 +204,9 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => { const expenseCategoryId = watch("expenseCategoryId"); useEffect(() => { - setExpenseType(expenseCategories?.find((type) => type.id === expenseCategoryId)); + setExpenseCategory( + expenseCategories?.find((type) => type.id === expenseCategoryId) + ); }, [expenseCategoryId]); const handleClose = () => { @@ -238,7 +249,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
    - {errors.expenseCategoryId && ( + {errors.expensesCategoryId && ( - {errors.expenseCategoryId.message} + {errors.expensesCategoryId.message} )}
    @@ -295,34 +306,10 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => { )} -
    - @@ -435,25 +423,53 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => { {errors.gstNumber.message} )}
    - - {ExpenseType?.noOfPersonsRequired && ( -
    - - - {errors.noOfPersons && ( - - {errors.noOfPersons.message} - - )} -
    - )} + +
    +
    + + + {errors.currencyId && ( + {errors.currencyId.message} + )} +
    + {expenseCategory?.noOfPersonsRequired && ( +
    + + + {errors.noOfPersons && ( + + {errors.noOfPersons.message} + + )} +
    + )} +
    @@ -510,40 +526,11 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => { )} {files.length > 0 && ( -
    - {files - .filter((file) => { - if (expenseToEdit) { - return file.isActive; - } - return true; - }) - .map((file, idx) => ( - -
    - - {file.fileName} - - - {file.fileSize ? formatFileSize(file.fileSize) : ""} - -
    - { - e.preventDefault(); - removeFile(expenseToEdit ? file.documentId : idx); - }} - > -
    - ))} -
    + )} {Array.isArray(errors.billAttachments) && diff --git a/src/hooks/masterHook/useMaster.js b/src/hooks/masterHook/useMaster.js index cc992d04..2903fde9 100644 --- a/src/hooks/masterHook/useMaster.js +++ b/src/hooks/masterHook/useMaster.js @@ -10,6 +10,16 @@ import { } from "@tanstack/react-query"; import showToast from "../../services/toastService"; +export const useCurrencies = () => { + return useQuery({ + queryKey: ["currencies"], + queryFn: async () => { + const resp = await MasterRespository.getCurrencies(); + return resp.data; + }, + }); +}; + export const usePaymentAjustmentHead = (isActive) => { return useQuery({ queryKey: ["paymentType",isActive], @@ -171,7 +181,7 @@ export const useExpenseCategory = () => { }, }); - return { ExpenseTypes, loading, error }; + return { expenseCategories, loading, error }; }; export const usePaymentMode = () => { const { diff --git a/src/pages/Expense/ExpensePage.jsx b/src/pages/Expense/ExpensePage.jsx index 09064cd8..034651c2 100644 --- a/src/pages/Expense/ExpensePage.jsx +++ b/src/pages/Expense/ExpensePage.jsx @@ -190,7 +190,7 @@ const ExpensePage = () => { {viewExpense.view && ( setViewExpense({ expenseId: null, view: false })} > diff --git a/src/repositories/MastersRepository.jsx b/src/repositories/MastersRepository.jsx index b2c56055..837ecdcd 100644 --- a/src/repositories/MastersRepository.jsx +++ b/src/repositories/MastersRepository.jsx @@ -50,7 +50,10 @@ export const MasterRespository = { "Contact Category": (id) => api.delete(`/api/master/contact-category/${id}`), "Contact Tag": (id) => api.delete(`/api/master/contact-tag/${id}`), "Expense Type": (id, isActive) => - api.delete(`/api/Master/expenses-category/delete/${id}`, (isActive = false)), + api.delete( + `/api/Master/expenses-category/delete/${id}`, + (isActive = false) + ), "Payment Mode": (id, isActive) => api.delete(`/api/Master/payment-mode/delete/${id}`, (isActive = false)), "Expense Status": (id, isActive) => @@ -58,7 +61,11 @@ export const MasterRespository = { "Document Type": (id) => api.delete(`/api/Master/document-type/delete/${id}`), "Document Category": (id) => api.delete(`/api/Master/document-category/delete/${id}`), - "Payment Adjustment Head":(id,isActive)=>api.delete(`/api/Master/payment-adjustment-head/delete/${id}`,(isActive=false)), + "Payment Adjustment Head": (id, isActive) => + api.delete( + `/api/Master/payment-adjustment-head/delete/${id}`, + (isActive = false) + ), getWorkCategory: () => api.get(`/api/master/work-categories`), createWorkCategory: (data) => api.post(`/api/master/work-category`, data), @@ -79,7 +86,8 @@ export const MasterRespository = { getAuditStatus: () => api.get("/api/Master/work-status"), getExpenseCategories: () => api.get("/api/Master/expenses-categories"), - createExpenseCategory: (data) => api.post("/api/Master/expenses-category", data), + createExpenseCategory: (data) => + api.post("/api/Master/expenses-category", data), updateExpenseCategory: (id, data) => api.put(`/api/Master/expenses-category/edit/${id}`, data), @@ -134,6 +142,10 @@ export const MasterRespository = { getPaymentAdjustmentHead: (isActive) => api.get(`/api/Master/payment-adjustment-head/list?isActive=${isActive}`), - createPaymentAjustmentHead:(data)=>api.post(`/api/Master/payment-adjustment-head`, data), - updatePaymentAjustmentHead:(id,data)=>api.put(`/api/Master/payment-adjustment-head/edit/${id}`, data) + createPaymentAjustmentHead: (data) => + api.post(`/api/Master/payment-adjustment-head`, data), + updatePaymentAjustmentHead: (id, data) => + api.put(`/api/Master/payment-adjustment-head/edit/${id}`, data), + + getCurrencies: () => api.get(`/api/Master/currencies/list`), };