diff --git a/src/components/PaymentRequest/handleExpenseExport.jsx b/src/components/PaymentRequest/handleExpenseExport.jsx index e51a95bf..e8f88786 100644 --- a/src/components/PaymentRequest/handleExpenseExport.jsx +++ b/src/components/PaymentRequest/handleExpenseExport.jsx @@ -1,61 +1,84 @@ +import ExpenseRepository from "../../repositories/ExpsenseRepository"; import moment from "moment"; import { exportToCSV, exportToExcel, exportToPDF, printTable } from "../../utils/tableExportUtils"; +import showToast from "../../services/toastService"; -/** - * Handles exporting expenses data to CSV, Excel, PDF, or Print - * @param {"csv"|"excel"|"pdf"|"print"} type - * @param {Array} expenses - List of expenses - * @param {React.RefObject} tableRef - Table reference for printing - */ -const handleExpenseExport = (type, expenses, tableRef) => { - if (!expenses || expenses.length === 0) return; +const handleExpenseExport = async ( + type, + filters = {}, + searchString = "", + tableRef = null, + setLoading = null +) => { + try { + if (setLoading) setLoading(true); - // Map export data - const exportData = expenses.map((item) => ({ - "Expense ID": item?.expenseUId ?? "-", - "Expense Category": item?.expenseCategory?.name ?? "-", - "Payment Mode": item?.paymentMode?.name ?? "-", - "Submitted By": `${item?.createdBy?.firstName ?? ""} ${item?.createdBy?.lastName ?? ""}`.trim() || "-", - "Submitted": item?.createdAt ? moment(item.createdAt).format("DD-MMM-YYYY") : "-", - "Amount": item?.amount?.toLocaleString() ?? "-", - "Currency": item?.currency?.currencyCode ?? "-", - "Status": item?.status?.name ?? "-", - "Project": item?.project?.name ?? "-", - })); + const safeSearchString = typeof searchString === "string" ? searchString : ""; + let allExpenses = []; + let pageNumber = 1; + const pageSize = 1000; // fetch 1000 per API call + let hasMore = true; - // Define column order - const columns = [ - "Expense ID", - "Expense Category", - "Payment Mode", - "Submitted By", - "Submitted", - "Amount", - "Currency", - "Status", - "Project", - ]; + while (hasMore) { + const response = await ExpenseRepository.GetExpenseList( + pageSize, + pageNumber, + filters, + safeSearchString + ); - switch (type) { - case "csv": - exportToCSV(exportData, "expenses", columns); - break; + const currentPageData = response?.data?.data || []; + allExpenses = allExpenses.concat(currentPageData); - case "excel": - exportToExcel(exportData, "expenses", columns); - break; + // If returned data length is less than pageSize, we reached the last page + if (currentPageData.length < pageSize) { + hasMore = false; + } else { + pageNumber += 1; // fetch next page + } + } - case "pdf": - exportToPDF(exportData, "expenses", columns); - break; + if (!allExpenses.length) { + showToast("No expenses found!", "warning"); + return; + } - case "print": - if (tableRef?.current) printTable(tableRef.current); - break; + // Map export data + const exportData = allExpenses.map((item) => ({ + "Expense ID": item?.expenseUId ?? "-", + "Expense Category": item?.expenseCategory?.name ?? "-", + "Payment Mode": item?.paymentMode?.name ?? "-", + "Submitted By": `${item?.createdBy?.firstName ?? ""} ${item?.createdBy?.lastName ?? ""}`.trim() || "-", + "Submitted": item?.createdAt ? moment(item.createdAt).format("DD-MMM-YYYY") : "-", + "Amount": item?.amount != null + ? `${item.amount.toLocaleString()} ${item.currency?.currencyCode ?? ""}` + : "-", + "Status": item?.status?.name ?? "-", + })); - default: - console.warn("Unhandled export type:", type); - break; + + switch (type) { + case "csv": + exportToCSV(exportData, "Expenses"); + break; + case "excel": + exportToExcel(exportData, "Expenses"); + break; + case "pdf": + exportToPDF(exportData, "Expenses"); + break; + case "print": + if (tableRef?.current) printTable(tableRef.current); + break; + default: + console.warn("Unknown export type:", type); + } + + } catch (err) { + console.error(err); + showToast("Failed to export expenses", "error"); + } finally { + if (setLoading) setLoading(false); } }; diff --git a/src/components/PaymentRequest/handlePaymentRequestExport.jsx b/src/components/PaymentRequest/handlePaymentRequestExport.jsx index 1cf0f433..7a77bcff 100644 --- a/src/components/PaymentRequest/handlePaymentRequestExport.jsx +++ b/src/components/PaymentRequest/handlePaymentRequestExport.jsx @@ -1,58 +1,84 @@ import moment from "moment"; import { exportToCSV, exportToExcel, exportToPDF, printTable } from "../../utils/tableExportUtils"; +import ExpenseRepository from "../../repositories/ExpsenseRepository"; -const handlePaymentRequestExport = (type, requests, tableRef) => { - if (!requests || requests.length === 0) return; +const handlePaymentRequestExport = async ( + type, + filters = {}, + searchString = "", + tableRef = null, + setLoading = null +) => { + try { + if (setLoading) setLoading(true); - // Map export data - const exportData = requests.map((item) => ({ - "Request ID": item?.paymentRequestUID ?? "-", - "Title": item?.title ?? "-", - "Payee": item?.payee ?? "-", - "Amount": item?.amount?.toLocaleString() ?? "-", - "Currency": item?.currency?.currencyCode ?? "-", - "Created At": item?.createdAt ? moment(item.createdAt).format("DD-MMM-YYYY") : "-", - "Due Date": item?.dueDate ? moment(item.dueDate).format("DD-MMM-YYYY") : "-", - "Status": item?.expenseStatus?.name ?? "-", - "Submitted By": `${item?.createdBy?.firstName ?? ""} ${item?.createdBy?.lastName ?? ""}`.trim() || "-", - "Project": item?.project?.name ?? "-", - })); + const safeSearchString = typeof searchString === "string" ? searchString : ""; + let allPaymentRequest = []; + let pageNumber = 1; + const pageSize = 1000; + let hasMore = true; - // Define column order - const columns = [ - "Request ID", - "Title", - "Payee", - "Amount", - "Currency", - "Created At", - "Due Date", - "Status", - "Submitted By", - "Project", - ]; + while (hasMore) { + const response = await ExpenseRepository.GetPaymentRequestList( + pageSize, + pageNumber, + filters, + true, // isActive + safeSearchString + ); - switch (type) { - case "csv": - exportToCSV(exportData, "payment-requests", columns); - break; + const currentPageData = response?.data?.data || []; + allPaymentRequest = allPaymentRequest.concat(currentPageData); - case "excel": - exportToExcel(exportData, "payment-requests", columns); - break; + if (currentPageData.length < pageSize) { + hasMore = false; + } else { + pageNumber += 1; + } + } - case "pdf": - exportToPDF(exportData, "payment-requests", columns); - break; + if (!allPaymentRequest.length) { + console.warn("No payment requests found!"); + return; + } - case "print": - if (tableRef?.current) printTable(tableRef.current); - break; + const exportData = allPaymentRequest.map((item) => ({ + "Request ID": item?.paymentRequestUID ?? "-", + "Title": item?.title ?? "-", + "Payee": item?.payee ?? "-", + "Amount": item?.amount != null ? Number(item.amount).toLocaleString() : "-", + "Currency": item?.currency?.currencyCode ?? "-", + "Created At": item?.createdAt ? moment(item.createdAt).format("DD-MMM-YYYY") : "-", + "Due Date": item?.dueDate ? moment(item.dueDate).format("DD-MMM-YYYY") : "-", + "Status": item?.expenseStatus?.name ?? "-", + "Submitted By": `${item?.createdBy?.firstName ?? ""} ${item?.createdBy?.lastName ?? ""}`.trim() || "-", + "Project": item?.project?.name ?? "-", + })); - default: - console.warn("Unhandled export type:", type); - break; + switch (type) { + case "csv": + exportToCSV(exportData, "PaymentRequests"); + break; + case "excel": + exportToExcel(exportData, "PaymentRequests"); + break; + case "pdf": + exportToPDF(exportData, "PaymentRequests"); + break; + case "print": + if (tableRef?.current) printTable(tableRef.current); + break; + default: + console.warn("Unknown export type:", type); + } + + } catch (err) { + console.error("Export failed:", err); + } finally { + if (setLoading) setLoading(false); } }; + + export default handlePaymentRequestExport; diff --git a/src/components/RecurringExpense/handleRecurringExpenseExport.jsx b/src/components/RecurringExpense/handleRecurringExpenseExport.jsx index af9537c7..358b9921 100644 --- a/src/components/RecurringExpense/handleRecurringExpenseExport.jsx +++ b/src/components/RecurringExpense/handleRecurringExpenseExport.jsx @@ -1,63 +1,160 @@ import moment from "moment"; -import { exportToCSV,exportToExcel,exportToPDF,printTable } from "../../utils/tableExportUtils"; +import { exportToCSV, exportToExcel, exportToPDF, printTable } from "../../utils/tableExportUtils"; import { FREQUENCY_FOR_RECURRING } from "../../utils/constants"; +import ExpenseRepository from "../../repositories/ExpsenseRepository"; -const handleRecurringExpenseExport = (type, expenses, tableRef) => { - if (!expenses || expenses.length === 0) return; +// const handleRecurringExpenseExport = (type, expenses, tableRef) => { +// if (!expenses || expenses.length === 0) return; - // Mapped Export Data - const exportData = expenses.map((item) => ({ - Category: item?.expenseCategory?.name ?? "-", - Title: item?.title ?? "-", - Payee: item?.payee ?? "-", - Frequency: - item?.frequency !== undefined && item?.frequency !== null - ? FREQUENCY_FOR_RECURRING[item?.frequency] ?? "-" +// // Mapped Export Data +// const exportData = expenses.map((item) => ({ +// Category: item?.expenseCategory?.name ?? "-", +// Title: item?.title ?? "-", +// Payee: item?.payee ?? "-", +// Frequency: +// item?.frequency !== undefined && item?.frequency !== null +// ? FREQUENCY_FOR_RECURRING[item?.frequency] ?? "-" +// : "-", +// Amount: item?.amount ? item.amount.toLocaleString() : "-", +// Currency: item?.currency?.symbol ?? "-", +// "Next Generation Date": item?.nextGenerationDate +// ? moment(item.nextGenerationDate).format("DD-MMM-YYYY") +// : "-", +// Status: item?.status?.name ?? "-", +// "Created At": item?.createdAt +// ? moment(item.createdAt).format("DD-MMM-YYYY") +// : "-", +// })); + +// // COLUMN ORDER +// const columns = [ +// "Category", +// "Title", +// "Payee", +// "Frequency", +// "Amount", +// "Currency", +// "Next Generation Date", +// "Status", +// "Created At", +// ]; + +// switch (type) { +// case "csv": +// exportToCSV(exportData, "recurring-expense", columns); +// break; + +// case "excel": +// exportToExcel(exportData, "recurring-expense", columns); +// break; + +// case "pdf": +// exportToPDF(exportData, "recurring-expense", columns); +// break; + +// case "print": +// if (tableRef?.current) printTable(tableRef.current); +// break; + +// default: +// console.warn("Unhandled export type:", type); +// break; +// } +// }; + +const handleRecurringExpenseExport = async ( + type, + filters = {}, + searchString = "", + tableRef = null, + setLoading = null +) => { + try { + if (setLoading) setLoading(true); + + const safeSearchString = typeof searchString === "string" ? searchString : ""; + let allRecurringExpense = []; + let pageNumber = 1; + const pageSize = 1000; + let hasMore = true; + + while (hasMore) { + const response = await ExpenseRepository.GetRecurringExpenseList( + pageSize, + pageNumber, + filters, + true, // isActive + safeSearchString + ); + + const currentPageData = response?.data?.data || []; + allRecurringExpense = allRecurringExpense.concat(currentPageData); + + if (currentPageData.length < pageSize) { + hasMore = false; + } else { + pageNumber += 1; + } + } + + if (!allRecurringExpense.length) { + console.warn("No payment requests found!"); + return; + } + + const exportData = allRecurringExpense.map((item) => ({ + Category: item?.expenseCategory?.name ?? "-", + Title: item?.title ?? "-", + Payee: item?.payee ?? "-", + Frequency: + item?.frequency !== undefined && item?.frequency !== null + ? FREQUENCY_FOR_RECURRING[item?.frequency] ?? "-" + : "-", + Amount: item?.amount ? item.amount.toLocaleString() : "-", + Currency: item?.currency?.symbol ?? "-", + "Next Generation Date": item?.nextGenerationDate + ? moment(item.nextGenerationDate).format("DD-MMM-YYYY") : "-", - Amount: item?.amount ? item.amount.toLocaleString() : "-", - Currency: item?.currency?.symbol ?? "-", - "Next Generation Date": item?.nextGenerationDate - ? moment(item.nextGenerationDate).format("DD-MMM-YYYY") - : "-", - Status: item?.status?.name ?? "-", - "Created At": item?.createdAt - ? moment(item.createdAt).format("DD-MMM-YYYY") - : "-", - })); + Status: item?.status?.name ?? "-", + "Created At": item?.createdAt + ? moment(item.createdAt).format("DD-MMM-YYYY") + : "-", + })); - // COLUMN ORDER - const columns = [ - "Category", - "Title", - "Payee", - "Frequency", - "Amount", - "Currency", - "Next Generation Date", - "Status", - "Created At", - ]; + // COLUMN ORDER + const columns = [ + "Category", + "Title", + "Payee", + "Frequency", + "Amount", + "Currency", + "Next Generation Date", + "Status", + "Created At", + ]; - switch (type) { - case "csv": - exportToCSV(exportData, "recurring-expense", columns); - break; + switch (type) { + case "csv": + exportToCSV(exportData, "recurring-expense", columns); + break; + case "excel": + exportToExcel(exportData, "recurring-expense", columns); + break; + case "pdf": + exportToPDF(exportData, "recurring-expense", columns); + break; + case "print": + if (tableRef?.current) printTable(tableRef.current); + break; + default: + console.warn("Unknown export type:", type); + } - case "excel": - exportToExcel(exportData, "recurring-expense", columns); - break; - - case "pdf": - exportToPDF(exportData, "recurring-expense", columns); - break; - - case "print": - if (tableRef?.current) printTable(tableRef.current); - break; - - default: - console.warn("Unhandled export type:", type); - break; + } catch (err) { + console.error("Export failed:", err); + } finally { + if (setLoading) setLoading(false); } }; diff --git a/src/pages/Expense/ExpensePage.jsx b/src/pages/Expense/ExpensePage.jsx index a58efc41..7f895157 100644 --- a/src/pages/Expense/ExpensePage.jsx +++ b/src/pages/Expense/ExpensePage.jsx @@ -118,9 +118,10 @@ const ExpensePage = () => { }; const handleExport = (type) => { - handleExpenseExport(type, filteredData, tableRef); // <-- corrected + handleExpenseExport(type, filters, searchText, tableRef); }; + return (
diff --git a/src/pages/PaymentRequest/PaymentRequestPage.jsx b/src/pages/PaymentRequest/PaymentRequestPage.jsx index 03be604a..19e15455 100644 --- a/src/pages/PaymentRequest/PaymentRequestPage.jsx +++ b/src/pages/PaymentRequest/PaymentRequestPage.jsx @@ -26,11 +26,13 @@ const PaymentRequestPage = () => { const [filters, setFilters] = useState(defaultPaymentRequestFilter); const [filterData, setFilterdata] = useState(null); const [ViewDocument, setDocumentView] = useState({ IsOpen: false, Image: null }); + const [searchText, setSearchText] = useState(""); const [isExpenseGenerate, setIsExpenseGenerate] = useState({ IsOpen: null, RequestId: null }); const [modalSize, setModalSize] = useState("md"); const [search, setSearch] = useState(""); const updatedRef = useRef(); const { setOffcanvasContent, setShowTrigger } = useFab(); + const [exportLoading, setExportLoading] = useState(false); const tableRef = useRef(null); const [filteredData, setFilteredData] = useState([]); const contextValue = { @@ -78,9 +80,9 @@ const PaymentRequestPage = () => { }); }; - const handleExport = (type) => { - handlePaymentRequestExport(type, filteredData, tableRef); // <-- corrected - }; + const handleExport = (type) => { + handlePaymentRequestExport(type, filters, search, tableRef, setExportLoading); +}; return ( diff --git a/src/pages/RecurringExpense/RecurringExpensePage.jsx b/src/pages/RecurringExpense/RecurringExpensePage.jsx index db923657..bd713edc 100644 --- a/src/pages/RecurringExpense/RecurringExpensePage.jsx +++ b/src/pages/RecurringExpense/RecurringExpensePage.jsx @@ -5,7 +5,7 @@ import { useFab } from "../../Context/FabContext"; import ManageRecurringExpense from "../../components/RecurringExpense/ManageRecurringExpense"; import RecurringExpenseList from "../../components/RecurringExpense/RecurringExpenseList"; import { PAYEE_RECURRING_EXPENSE } from "../../utils/constants"; -import { SearchRecurringExpenseSchema } from "../../components/RecurringExpense/RecurringExpenseSchema"; +import { defaultRecurringExpense, SearchRecurringExpenseSchema } from "../../components/RecurringExpense/RecurringExpenseSchema"; import ViewRecurringExpense from "../../components/RecurringExpense/ViewRecurringExpense"; import handleRecurringExpenseExport from "../../components/RecurringExpense/handleRecurringExpenseExport"; @@ -17,7 +17,7 @@ export const useRecurringExpenseContext = () => { "useRecurringExpenseContext must be used within an ExpenseProvider" ); } - return context; + return context; }; const RecurringExpensePage = () => { const [ManageRequest, setManageRequest] = useState({ @@ -27,7 +27,9 @@ const RecurringExpensePage = () => { const tableRef = useRef(null); const [filteredData, setFilteredData] = useState([]); - + const [exportLoading, setExportLoading] = useState(false); + const [searchText, setSearchText] = useState(""); + const [filters, setFilters] = useState(defaultRecurringExpense); const [viewRecurring, setViewRecurring] = useState({ view: false, recurringId: null, @@ -52,7 +54,7 @@ const RecurringExpensePage = () => { const handleExport = (type) => { - handleRecurringExpenseExport(type, filteredData, tableRef); + handleRecurringExpenseExport(type, filters, search, tableRef, setExportLoading); }; return (