234 lines
6.7 KiB
JavaScript
234 lines
6.7 KiB
JavaScript
|
|
import React, { useEffect, useMemo } from "react";
|
|
import { useExpenseAllTransactionsList, useExpenseTransactions } from "../../hooks/useExpense";
|
|
import Error from "../common/Error";
|
|
import { formatUTCToLocalTime } from "../../utils/dateUtils";
|
|
import Loader, { SpinnerLoader } from "../common/Loader";
|
|
import { useForm, useFormContext } from "react-hook-form";
|
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
import { z } from "zod";
|
|
import { employee } from "../../data/masters";
|
|
import { useAdvancePaymentContext } from "../../pages/AdvancePayment/AdvancePaymentPageDetails";
|
|
import { formatFigure } from "../../utils/appUtils";
|
|
|
|
const AdvancePaymentListDetails = ({ employeeId, searchString,tableRef }) => {
|
|
const { setBalance } = useAdvancePaymentContext();
|
|
const { data, isError, isLoading, error, isFetching } =
|
|
useExpenseTransactions(employeeId, { enabled: !!employeeId });
|
|
const records = Array.isArray(data) ? data : [];
|
|
|
|
let currentBalance = 0;
|
|
const rowsWithBalance = records.map((r) => {
|
|
const isCredit = r.amount > 0;
|
|
const credit = isCredit ? r.amount : 0;
|
|
const debit = !isCredit ? Math.abs(r.amount) : 0;
|
|
currentBalance += credit - debit;
|
|
return {
|
|
id: r.id,
|
|
description: r.title || "-",
|
|
projectName: r.project?.name || "-",
|
|
createdAt: r.createdAt,
|
|
credit,
|
|
debit,
|
|
financeUId: r.financeUId,
|
|
balance: currentBalance,
|
|
};
|
|
});
|
|
|
|
useEffect(() => {
|
|
if (!employeeId) {
|
|
setBalance(null);
|
|
return;
|
|
}
|
|
|
|
if (rowsWithBalance.length > 0) {
|
|
setBalance(rowsWithBalance[rowsWithBalance.length - 1].balance);
|
|
} else {
|
|
setBalance(0);
|
|
}
|
|
}, [employeeId, data, setBalance]);
|
|
|
|
if (!employeeId) {
|
|
return (
|
|
<div
|
|
className="d-flex justify-content-center align-items-center"
|
|
style={{ height: "200px" }}
|
|
>
|
|
<p className="text-muted m-0">Please select an employee</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (isLoading || isFetching) {
|
|
return (
|
|
<div
|
|
className="d-flex justify-content-center align-items-center"
|
|
style={{ height: "200px" }}
|
|
>
|
|
<SpinnerLoader />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (isError) {
|
|
return (
|
|
<div className="text-center py-3">
|
|
{error?.status === 404
|
|
? "No advance payment transactions found."
|
|
: <Error error={error} />}
|
|
</div>
|
|
);
|
|
}
|
|
const columns = [
|
|
{
|
|
key: "date",
|
|
label: (
|
|
<>
|
|
Date
|
|
</>
|
|
),
|
|
align: "text-start",
|
|
},
|
|
{ key: "description", label: "Description", align: "text-start" },
|
|
|
|
{
|
|
key: "credit",
|
|
label: (
|
|
<>
|
|
Credit <i className="bx bx-rupee text-success"></i>
|
|
</>
|
|
),
|
|
align: "text-end",
|
|
},
|
|
{
|
|
key: "debit",
|
|
label: (
|
|
<>
|
|
Debit <i className="bx bx-rupee text-danger"></i>
|
|
</>
|
|
),
|
|
align: "text-end",
|
|
},
|
|
|
|
{
|
|
key: "balance",
|
|
label: (
|
|
<>
|
|
Balance <i className="bi bi-currency-rupee text-primary"></i>
|
|
</>
|
|
),
|
|
align: "text-end fw-bold",
|
|
},
|
|
];
|
|
|
|
// Handle empty records
|
|
if (rowsWithBalance.length === 0) {
|
|
return (
|
|
<div className="text-center text-muted py-3">
|
|
No advance payment records found.
|
|
</div>
|
|
);
|
|
}
|
|
const DecideCreditOrDebit = ({ financeUId }) => {
|
|
if (!financeUId) return null;
|
|
|
|
const prefix = financeUId?.substring(0, 2).toUpperCase();
|
|
|
|
if (prefix === "PR") return <span className="text-success">+</span>;
|
|
if (prefix === "EX") return <span className="text-danger">-</span>;
|
|
|
|
return null;
|
|
};
|
|
|
|
return (
|
|
<div className="table-responsive">
|
|
<table className="table align-middle" ref={tableRef}>
|
|
<thead className="table_header_border">
|
|
<tr>
|
|
{columns.map((col) => (
|
|
<th key={col.key} className={col.align}>
|
|
{col.label}
|
|
</th>
|
|
))}
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{Array.isArray(data) && data.length > 0 ? (
|
|
data.map((row) => (
|
|
<tr key={row.id}>
|
|
{columns.map((col) => (
|
|
<td key={col.key} className={`${col.align} p-2`}>
|
|
{col.key === "credit" ? (
|
|
row.amount > 0 ? (
|
|
<span>{row.amount.toLocaleString("en-IN")}</span>
|
|
) : (
|
|
"-"
|
|
)
|
|
) : col.key === "debit" ? (
|
|
row.amount < 0 ? (
|
|
<span>
|
|
{Math.abs(row.amount).toLocaleString("en-IN")}
|
|
</span>
|
|
) : (
|
|
"-"
|
|
)
|
|
) : col.key === "balance" ? (
|
|
<div className="d-flex align-items-center justify-content-end">
|
|
{/* <DecideCreditOrDebit financeUId={row?.financeUId} /> */}
|
|
<span className="mx-2">
|
|
{formatFigure(row.currentBalance)}
|
|
</span>
|
|
</div>
|
|
) : col.key === "date" ? (
|
|
<small className="text-muted px-1">
|
|
{formatUTCToLocalTime(row.paidAt)}
|
|
</small>
|
|
) : (
|
|
<div className="d-flex flex-column text-start gap-1 py-1">
|
|
<small className="fw-semibold text-dark">
|
|
{row.project?.name || "-"}
|
|
</small>
|
|
<small>{row.title || "-"}</small>
|
|
</div>
|
|
)}
|
|
</td>
|
|
))}
|
|
</tr>
|
|
))
|
|
) : (
|
|
<tr>
|
|
<td
|
|
colSpan={columns.length}
|
|
className="text-center text-muted py-3"
|
|
>
|
|
No advance payment records found.
|
|
</td>
|
|
</tr>
|
|
)}
|
|
</tbody>
|
|
|
|
<tfoot className=" fw-bold">
|
|
<tr className="tr-group text-dark py-2">
|
|
<td className="text-start">
|
|
{" "}
|
|
<div className="d-flex align-items-center px-1 py-2">
|
|
Final Balance
|
|
</div>
|
|
</td>
|
|
<td className="text-end" colSpan="4">
|
|
<div className="d-flex align-items-center justify-content-end px-1 py-2">
|
|
{currentBalance.toLocaleString("en-IN", {
|
|
style: "currency",
|
|
currency: "INR",
|
|
})}
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default AdvancePaymentListDetails;
|