fixed currency format list - Expense, PR

This commit is contained in:
pramod.mahajan 2025-11-07 17:09:07 +05:30
parent 4cbac98986
commit e962e02fbc
2 changed files with 95 additions and 48 deletions

View File

@ -12,6 +12,7 @@ import {
} from "../../utils/constants"; } from "../../utils/constants";
import { import {
formatCurrency, formatCurrency,
formatFigure,
getColorNameFromHex, getColorNameFromHex,
useDebounce, useDebounce,
} from "../../utils/appUtils"; } from "../../utils/appUtils";
@ -26,14 +27,18 @@ import { useNavigate } from "react-router-dom";
const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => { const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => {
const [deletingId, setDeletingId] = useState(null); const [deletingId, setDeletingId] = useState(null);
const [IsDeleteModalOpen, setIsDeleteModalOpen] = useState(false); const [IsDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
const { setViewExpense, setManageExpenseModal, filterData, removeFilterChip } = useExpenseContext(); const {
setViewExpense,
setManageExpenseModal,
filterData,
removeFilterChip,
} = useExpenseContext();
const IsExpenseEditable = useHasUserPermission(); const IsExpenseEditable = useHasUserPermission();
const IsExpesneApprpve = useHasUserPermission(APPROVE_EXPENSE); const IsExpesneApprpve = useHasUserPermission(APPROVE_EXPENSE);
const [currentPage, setCurrentPage] = useState(1); const [currentPage, setCurrentPage] = useState(1);
const debouncedSearch = useDebounce(searchText, 500); const debouncedSearch = useDebounce(searchText, 500);
const navigate = useNavigate(); const navigate = useNavigate();
const { mutate: DeleteExpense, isPending } = useDeleteExpense(); const { mutate: DeleteExpense, isPending } = useDeleteExpense();
const { data, isLoading, isError, isInitialLoading, error } = useExpenseList( const { data, isLoading, isError, isInitialLoading, error } = useExpenseList(
ITEMS_PER_PAGE, ITEMS_PER_PAGE,
@ -80,8 +85,9 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => {
displayField = "Status"; displayField = "Status";
break; break;
case "submittedBy": case "submittedBy":
key = `${item?.createdBy?.firstName ?? ""} ${item.createdBy?.lastName ?? "" key = `${item?.createdBy?.firstName ?? ""} ${
}`.trim(); item.createdBy?.lastName ?? ""
}`.trim();
displayField = "Submitted By"; displayField = "Submitted By";
break; break;
case "project": case "project":
@ -139,11 +145,14 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => {
label: "Submitted By", label: "Submitted By",
align: "text-start", align: "text-start",
getValue: (e) => getValue: (e) =>
`${e.createdBy?.firstName ?? ""} ${e.createdBy?.lastName ?? "" `${e.createdBy?.firstName ?? ""} ${
}`.trim() || "N/A", e.createdBy?.lastName ?? ""
}`.trim() || "N/A",
customRender: (e) => ( customRender: (e) => (
<div className="d-flex align-items-center cursor-pointer" <div
onClick={() => navigate(`/employee/${e.createdBy?.id}`)}> className="d-flex align-items-center cursor-pointer"
onClick={() => navigate(`/employee/${e.createdBy?.id}`)}
>
<Avatar <Avatar
size="xs" size="xs"
classAvatar="m-0" classAvatar="m-0"
@ -151,8 +160,9 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => {
lastName={e.createdBy?.lastName} lastName={e.createdBy?.lastName}
/> />
<span className="text-truncate"> <span className="text-truncate">
{`${e.createdBy?.firstName ?? ""} ${e.createdBy?.lastName ?? "" {`${e.createdBy?.firstName ?? ""} ${
}`.trim() || "N/A"} e.createdBy?.lastName ?? ""
}`.trim() || "N/A"}
</span> </span>
</div> </div>
), ),
@ -166,7 +176,15 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => {
{ {
key: "amount", key: "amount",
label: "Amount", label: "Amount",
getValue: (e) => <>{formatCurrency(e?.amount)}</>, getValue: (e) => (
<>
{" "}
{formatFigure(e?.amount, {
type: "currency",
currency: e?.currency?.currencyCode,
})}
</>
),
isAlwaysVisible: true, isAlwaysVisible: true,
align: "text-end", align: "text-end",
}, },
@ -176,16 +194,26 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => {
align: "text-center", align: "text-center",
getValue: (e) => ( getValue: (e) => (
<span <span
className={`badge bg-label-${getColorNameFromHex(e?.status?.color) || "secondary" className={`badge bg-label-${
}`} getColorNameFromHex(e?.status?.color) || "secondary"
}`}
> >
{e.status?.name || "Unknown"} {e.status?.name || "Unknown"}
</span> </span>
), ),
}, },
]; ];
const headers = ["Expense Category","Payment Mode","Submitted By","Submitted","Amount","Status","Action"] const headers = [
if (isInitialLoading && !data) return <ExpenseTableSkeleton headers={headers} />; "Expense Category",
"Payment Mode",
"Submitted By",
"Submitted",
"Amount",
"Status",
"Action",
];
if (isInitialLoading && !data)
return <ExpenseTableSkeleton headers={headers} />;
if (isError) return <div>{error?.message}</div>; if (isError) return <div>{error?.message}</div>;
const grouped = groupBy const grouped = groupBy
@ -210,7 +238,6 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => {
); );
}; };
return ( return (
<> <>
{IsDeleteModalOpen && ( {IsDeleteModalOpen && (
@ -238,9 +265,6 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => {
className="card-datatable table-responsive " className="card-datatable table-responsive "
id="horizontal-example" id="horizontal-example"
> >
<div className="dataTables_wrapper no-footer px-2 "> <div className="dataTables_wrapper no-footer px-2 ">
<table className="table border-top dataTable text-nowrap"> <table className="table border-top dataTable text-nowrap">
<thead> <thead>
@ -288,15 +312,32 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => {
(col.isAlwaysVisible || groupBy !== col.key) && ( (col.isAlwaysVisible || groupBy !== col.key) && (
<td <td
key={col.key} key={col.key}
className={`d-table-cell ml-2 ${col.align ?? ""} `} className={`d-table-cell ml-2 ${
col.align ?? ""
} `}
> >
<div className={`d-flex px-2 ${col.key === "status" ? "justify-content-center":""} <div
${col.key === "amount" ? "justify-content-end":""} className={`d-flex px-2 ${
${col.key === "submitted" ? "justify-content-center":""} col.key === "status"
`}>{col.customRender ? "justify-content-center"
? col.customRender(expense) : ""
: col.getValue(expense)} }
</div> ${
col.key === "amount"
? "justify-content-end"
: ""
}
${
col.key === "submitted"
? "justify-content-center"
: ""
}
`}
>
{col.customRender
? col.customRender(expense)
: col.getValue(expense)}
</div>
</td> </td>
) )
)} )}
@ -385,13 +426,13 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => {
</table> </table>
</div> </div>
</div> </div>
{data?.data?.length > 0 && ( {data?.data?.length > 0 && (
<Pagination <Pagination
currentPage={currentPage} currentPage={currentPage}
totalPages={data.totalPages} totalPages={data.totalPages}
onPageChange={paginate} onPageChange={paginate}
/> />
)} )}
</div> </div>
</> </>
); );

View File

@ -6,6 +6,7 @@ import {
} from "../../utils/constants"; } from "../../utils/constants";
import { import {
formatCurrency, formatCurrency,
formatFigure,
getColorNameFromHex, getColorNameFromHex,
useDebounce, useDebounce,
} from "../../utils/appUtils"; } from "../../utils/appUtils";
@ -43,8 +44,9 @@ const PaymentRequestList = ({ filters, groupBy = "submittedBy", search }) => {
displayField = "Status"; displayField = "Status";
break; break;
case "submittedBy": case "submittedBy":
key = `${item?.createdBy?.firstName ?? ""} ${item.createdBy?.lastName ?? "" key = `${item?.createdBy?.firstName ?? ""} ${
}`.trim(); item.createdBy?.lastName ?? ""
}`.trim();
displayField = "Submitted By"; displayField = "Submitted By";
break; break;
case "project": case "project":
@ -97,8 +99,9 @@ const PaymentRequestList = ({ filters, groupBy = "submittedBy", search }) => {
label: "Submitted By", label: "Submitted By",
align: "text-start", align: "text-start",
getValue: (e) => getValue: (e) =>
`${e.createdBy?.firstName ?? ""} ${e.createdBy?.lastName ?? "" `${e.createdBy?.firstName ?? ""} ${
}`.trim() || "N/A", e.createdBy?.lastName ?? ""
}`.trim() || "N/A",
customRender: (e) => ( customRender: (e) => (
<div <div
className="d-flex align-items-center cursor-pointer" className="d-flex align-items-center cursor-pointer"
@ -111,8 +114,9 @@ const PaymentRequestList = ({ filters, groupBy = "submittedBy", search }) => {
lastName={e.createdBy?.lastName} lastName={e.createdBy?.lastName}
/> />
<span className="text-truncate"> <span className="text-truncate">
{`${e.createdBy?.firstName ?? ""} ${e.createdBy?.lastName ?? "" {`${e.createdBy?.firstName ?? ""} ${
}`.trim() || "N/A"} e.createdBy?.lastName ?? ""
}`.trim() || "N/A"}
</span> </span>
</div> </div>
), ),
@ -128,9 +132,10 @@ const PaymentRequestList = ({ filters, groupBy = "submittedBy", search }) => {
label: "Amount", label: "Amount",
align: "text-end", align: "text-end",
getValue: (e) => getValue: (e) =>
e?.amount formatFigure(e?.amount, {
? `${e?.currency?.symbol ? e.currency.symbol + " " : ""}${e.amount.toLocaleString()}` type: "currency",
: "N/A", currency: e?.currency?.currencyCode,
}),
}, },
{ {
key: "expenseStatus", key: "expenseStatus",
@ -138,8 +143,9 @@ const PaymentRequestList = ({ filters, groupBy = "submittedBy", search }) => {
align: "text-center", align: "text-center",
getValue: (e) => ( getValue: (e) => (
<span <span
className={`badge bg-label-${getColorNameFromHex(e?.expenseStatus?.color) || "secondary" className={`badge bg-label-${
}`} getColorNameFromHex(e?.expenseStatus?.color) || "secondary"
}`}
> >
{e?.expenseStatus?.name || "Unknown"} {e?.expenseStatus?.name || "Unknown"}
</span> </span>
@ -175,10 +181,10 @@ const PaymentRequestList = ({ filters, groupBy = "submittedBy", search }) => {
const grouped = groupBy const grouped = groupBy
? Object.fromEntries( ? Object.fromEntries(
Object.entries(groupByField(data?.data ?? [], groupBy)).sort(([keyA], [keyB]) => Object.entries(groupByField(data?.data ?? [], groupBy)).sort(
keyA.localeCompare(keyB) ([keyA], [keyB]) => keyA.localeCompare(keyB)
)
) )
)
: { All: data?.data ?? [] }; : { All: data?.data ?? [] };
const IsGroupedByDate = [ const IsGroupedByDate = [