Change the Name of AdvancePayment Component.
This commit is contained in:
parent
d4582c101a
commit
833cb98dd3
@ -1,233 +1,100 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import Avatar from "../common/Avatar"; // <-- ADD THIS
|
||||||
|
import { useExpenseAllTransactionsList } from '../../hooks/useExpense';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { formatFigure } from '../../utils/appUtils';
|
||||||
|
|
||||||
import React, { useEffect, useMemo } from "react";
|
const AdvancePaymentList = ({ searchString }) => {
|
||||||
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/AdvancePaymentPage";
|
|
||||||
import { formatFigure } from "../../utils/appUtils";
|
|
||||||
|
|
||||||
const AdvancePaymentList = ({ employeeId, searchString }) => {
|
const { data, isError, isLoading, error } =
|
||||||
const { setBalance } = useAdvancePaymentContext();
|
useExpenseAllTransactionsList(searchString);
|
||||||
const { data, isError, isLoading, error, isFetching } =
|
|
||||||
useExpenseTransactions(employeeId, { enabled: !!employeeId });
|
|
||||||
const records = Array.isArray(data) ? data : [];
|
|
||||||
|
|
||||||
let currentBalance = 0;
|
const rows = data || [];
|
||||||
const rowsWithBalance = records.map((r) => {
|
const navigate = useNavigate();
|
||||||
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(() => {
|
const columns = [
|
||||||
if (!employeeId) {
|
{
|
||||||
setBalance(null);
|
key: "employee",
|
||||||
return;
|
label: "Employee Name",
|
||||||
}
|
align: "text-start",
|
||||||
|
customRender: (r) => (
|
||||||
|
<div className="d-flex align-items-center gap-2" onClick={() => navigate(`/advance-payment/${r.id}`)}
|
||||||
|
style={{ cursor: "pointer" }}>
|
||||||
|
<Avatar firstName={r.firstName} lastName={r.lastName} />
|
||||||
|
|
||||||
if (rowsWithBalance.length > 0) {
|
<span className="fw-medium">
|
||||||
setBalance(rowsWithBalance[rowsWithBalance.length - 1].balance);
|
{r.firstName} {r.lastName}
|
||||||
} else {
|
</span>
|
||||||
setBalance(0);
|
</div>
|
||||||
}
|
),
|
||||||
}, [employeeId, data, setBalance]);
|
},
|
||||||
|
{
|
||||||
|
key: "jobRoleName",
|
||||||
|
label: "Job Role",
|
||||||
|
align: "text-start",
|
||||||
|
customRender: (r) => (
|
||||||
|
<span className="fw-semibold">
|
||||||
|
{r.jobRoleName}
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "balanceAmount",
|
||||||
|
label: "Balance (₹)",
|
||||||
|
align: "text-end",
|
||||||
|
customRender: (r) => (
|
||||||
|
<span className="fw-semibold fs-6">
|
||||||
|
{formatFigure(r.balanceAmount, {
|
||||||
|
// type: "currency",
|
||||||
|
currency: "INR",
|
||||||
|
})}
|
||||||
|
</span>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
if (isLoading) return <p className="text-center py-4">Loading...</p>;
|
||||||
|
if (isError) return <p className="text-center py-4 text-danger">{error.message}</p>;
|
||||||
|
|
||||||
if (!employeeId) {
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className="card-datatable" id="payment-request-table">
|
||||||
className="d-flex justify-content-center align-items-center"
|
<div className="mx-2">
|
||||||
style={{ height: "200px" }}
|
<table className="table border-top dataTable text-nowrap align-middle">
|
||||||
>
|
<thead>
|
||||||
<p className="text-muted m-0">Please select an employee</p>
|
<tr>
|
||||||
</div>
|
{columns.map((col) => (
|
||||||
);
|
<th key={col.key} className={`sorting ${col.align}`}>
|
||||||
}
|
{col.label}
|
||||||
|
</th>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
if (isLoading || isFetching) {
|
<tbody>
|
||||||
return (
|
{rows.length > 0 ? (
|
||||||
<div
|
rows.map((row) => (
|
||||||
className="d-flex justify-content-center align-items-center"
|
<tr key={row.id} className="align-middle" style={{ height: "40px" }}>
|
||||||
style={{ height: "200px" }}
|
{columns.map((col) => (
|
||||||
>
|
<td key={col.key} className={`d-table-cell ${col.align} py-3`}>
|
||||||
<SpinnerLoader />
|
{col.customRender
|
||||||
</div>
|
? col.customRender(row)
|
||||||
);
|
: col.getValue(row)}
|
||||||
}
|
</td>
|
||||||
|
))}
|
||||||
if (isError) {
|
</tr>
|
||||||
return (
|
))
|
||||||
<div className="text-center py-3">
|
) : (
|
||||||
{error?.status === 404
|
<tr>
|
||||||
? "No advance payment transactions found."
|
<td colSpan={columns.length} className="text-center border-0 py-3">
|
||||||
: <Error error={error} />}
|
No Employees Found
|
||||||
</div>
|
</td>
|
||||||
);
|
</tr>
|
||||||
}
|
)}
|
||||||
const columns = [
|
</tbody>
|
||||||
{
|
</table>
|
||||||
key: "date",
|
</div>
|
||||||
label: (
|
</div>
|
||||||
<>
|
)
|
||||||
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">
|
|
||||||
<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 AdvancePaymentList;
|
export default AdvancePaymentList;
|
||||||
|
|||||||
@ -1,100 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import Avatar from "../../components/common/Avatar"; // <-- ADD THIS
|
|
||||||
import { useExpenseAllTransactionsList } from '../../hooks/useExpense';
|
|
||||||
import { useNavigate } from 'react-router-dom';
|
|
||||||
import { formatFigure } from '../../utils/appUtils';
|
|
||||||
|
|
||||||
const AdvancePaymentList1 = ({ searchString }) => {
|
|
||||||
|
|
||||||
const { data, isError, isLoading, error } =
|
|
||||||
useExpenseAllTransactionsList(searchString);
|
|
||||||
|
|
||||||
const rows = data || [];
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
const columns = [
|
|
||||||
{
|
|
||||||
key: "employee",
|
|
||||||
label: "Employee Name",
|
|
||||||
align: "text-start",
|
|
||||||
customRender: (r) => (
|
|
||||||
<div className="d-flex align-items-center gap-2" onClick={() => navigate(`/advance-payment/${r.id}`)}
|
|
||||||
style={{ cursor: "pointer" }}>
|
|
||||||
<Avatar firstName={r.firstName} lastName={r.lastName} />
|
|
||||||
|
|
||||||
<span className="fw-medium">
|
|
||||||
{r.firstName} {r.lastName}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "jobRoleName",
|
|
||||||
label: "Job Role",
|
|
||||||
align: "text-start",
|
|
||||||
customRender: (r) => (
|
|
||||||
<span className="fw-semibold">
|
|
||||||
{r.jobRoleName}
|
|
||||||
</span>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "balanceAmount",
|
|
||||||
label: "Balance (₹)",
|
|
||||||
align: "text-end",
|
|
||||||
customRender: (r) => (
|
|
||||||
<span className="fw-semibold fs-6">
|
|
||||||
{formatFigure(r.balanceAmount, {
|
|
||||||
// type: "currency",
|
|
||||||
currency: "INR",
|
|
||||||
})}
|
|
||||||
</span>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
if (isLoading) return <p className="text-center py-4">Loading...</p>;
|
|
||||||
if (isError) return <p className="text-center py-4 text-danger">{error.message}</p>;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="card-datatable" id="payment-request-table">
|
|
||||||
<div className="mx-2">
|
|
||||||
<table className="table border-top dataTable text-nowrap align-middle">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
{columns.map((col) => (
|
|
||||||
<th key={col.key} className={`sorting ${col.align}`}>
|
|
||||||
{col.label}
|
|
||||||
</th>
|
|
||||||
))}
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
|
|
||||||
<tbody>
|
|
||||||
{rows.length > 0 ? (
|
|
||||||
rows.map((row) => (
|
|
||||||
<tr key={row.id} className="align-middle" style={{ height: "40px" }}>
|
|
||||||
{columns.map((col) => (
|
|
||||||
<td key={col.key} className={`d-table-cell ${col.align} py-3`}>
|
|
||||||
{col.customRender
|
|
||||||
? col.customRender(row)
|
|
||||||
: col.getValue(row)}
|
|
||||||
</td>
|
|
||||||
))}
|
|
||||||
</tr>
|
|
||||||
))
|
|
||||||
) : (
|
|
||||||
<tr>
|
|
||||||
<td colSpan={columns.length} className="text-center border-0 py-3">
|
|
||||||
No Employees Found
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default AdvancePaymentList1;
|
|
||||||
233
src/components/AdvancePayment/AdvancePaymentListDetails.jsx
Normal file
233
src/components/AdvancePayment/AdvancePaymentListDetails.jsx
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
|
||||||
|
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"; // All data
|
||||||
|
import { formatFigure } from "../../utils/appUtils";
|
||||||
|
|
||||||
|
const AdvancePaymentListDetails = ({ employeeId, searchString }) => {
|
||||||
|
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">
|
||||||
|
<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;
|
||||||
@ -1,108 +1,34 @@
|
|||||||
import React, {
|
import React from 'react'
|
||||||
createContext,
|
import Breadcrumb from '../../components/common/Breadcrumb'
|
||||||
useContext,
|
import AdvancePaymentList1 from '../../components/AdvancePayment/AdvancePaymentList'
|
||||||
useEffect,
|
import { useForm } from 'react-hook-form';
|
||||||
useMemo,
|
import EmployeeSearchInput from '../../components/common/EmployeeSearchInput';
|
||||||
useState,
|
|
||||||
} from "react";
|
|
||||||
import Breadcrumb from "../../components/common/Breadcrumb";
|
|
||||||
import { useEmployee } from "../../hooks/useEmployees";
|
|
||||||
import EmployeeSearchInput from "../../components/common/EmployeeSearchInput";
|
|
||||||
import { useForm } from "react-hook-form";
|
|
||||||
import Label from "../../components/common/Label";
|
|
||||||
import AdvancePaymentList from "../../components/AdvancePayment/AdvancePaymentList";
|
|
||||||
import { employee } from "../../data/masters";
|
|
||||||
import { formatFigure } from "../../utils/appUtils";
|
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
import { useExpenseTransactions } from "../../hooks/useExpense";
|
|
||||||
|
|
||||||
export const AdvancePaymentContext = createContext();
|
|
||||||
export const useAdvancePaymentContext = () => {
|
|
||||||
const context = useContext(AdvancePaymentContext);
|
|
||||||
if (!context) {
|
|
||||||
throw new Error(
|
|
||||||
"useAdvancePaymentContext must be used within an AdvancePaymentProvider"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return context;
|
|
||||||
};
|
|
||||||
const AdvancePaymentPage = () => {
|
const AdvancePaymentPage = () => {
|
||||||
const { employeeId } = useParams();
|
const { control, reset, watch } = useForm({
|
||||||
|
defaultValues: {
|
||||||
const { data: transactionData } = useExpenseTransactions(employeeId, {
|
searchString: "",
|
||||||
enabled: !!employeeId
|
},
|
||||||
});
|
|
||||||
|
|
||||||
const employeeName = useMemo(() => {
|
|
||||||
if (Array.isArray(transactionData) && transactionData.length > 0) {
|
|
||||||
const emp = transactionData[0].employee;
|
|
||||||
if (emp) return `${emp.firstName} ${emp.lastName}`;
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}, [transactionData]);
|
|
||||||
|
|
||||||
const [balance, setBalance] = useState(null);
|
|
||||||
const { control, reset, watch } = useForm({
|
|
||||||
defaultValues: {
|
|
||||||
employeeId: employeeId || "",
|
|
||||||
searchString: "",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const selectedEmployeeId = employeeId || watch("employeeId");
|
|
||||||
|
|
||||||
const searchString = watch("searchString");
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const selectedEmpoyee = sessionStorage.getItem("transaction-empId");
|
|
||||||
reset({
|
|
||||||
employeeId: selectedEmpoyee || "",
|
|
||||||
});
|
});
|
||||||
}, [reset]);
|
const searchString = watch("searchString");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AdvancePaymentContext.Provider value={{ setBalance }}>
|
<div className="container-fluid">
|
||||||
<div className="container-fluid">
|
<Breadcrumb
|
||||||
<Breadcrumb
|
data={[
|
||||||
data={[
|
{ label: "Home", link: "/dashboard" },
|
||||||
{ label: "Home", link: "/dashboard" },
|
{ label: "Finance", link: "/advance-payment" },
|
||||||
{ label: "Finance", link: "/advance-payment" },
|
{ label: "Advance Payment" },
|
||||||
{ label: "Advance Payment", link: "/advance-payment" },
|
]}
|
||||||
employeeName && { label: employeeName, link: "" },
|
/>
|
||||||
].filter(Boolean)}
|
<div className="card px-4 py-2 page-min-h">
|
||||||
/>
|
<div className="row py-1">
|
||||||
|
<AdvancePaymentList1 searchString={searchString} />
|
||||||
<div className="card px-4 py-2 page-min-h ">
|
</div>
|
||||||
<div className="row py-1 justify-content-end">
|
|
||||||
<div className="col-md-8 d-flex align-items-center justify-content-end">
|
|
||||||
{balance ? (
|
|
||||||
<>
|
|
||||||
<label className="fs-5 fw-semibold">Current Balance : </label>
|
|
||||||
<span
|
|
||||||
className={`${balance > 0 ? "text-success" : "text-danger"
|
|
||||||
} fs-5 fw-bold ms-1`}
|
|
||||||
>
|
|
||||||
{balance > 0 ? (
|
|
||||||
<i className="bx bx-plus b-sm"></i>
|
|
||||||
) : (
|
|
||||||
<i className="bx bx-minus b-sm"></i>
|
|
||||||
)}{" "}
|
|
||||||
{formatFigure(balance, {
|
|
||||||
type: "currency",
|
|
||||||
currency: "INR",
|
|
||||||
})}
|
|
||||||
</span>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<></>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<AdvancePaymentList employeeId={selectedEmployeeId} searchString={searchString} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</AdvancePaymentContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AdvancePaymentPage;
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AdvancePaymentPage
|
||||||
|
|||||||
@ -1,34 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import Breadcrumb from '../../components/common/Breadcrumb'
|
|
||||||
import AdvancePaymentList1 from '../../components/AdvancePayment/AdvancePaymentList1'
|
|
||||||
import { useForm } from 'react-hook-form';
|
|
||||||
import EmployeeSearchInput from '../../components/common/EmployeeSearchInput';
|
|
||||||
|
|
||||||
const AdvancePaymentPage1 = () => {
|
|
||||||
const { control, reset, watch } = useForm({
|
|
||||||
defaultValues: {
|
|
||||||
searchString: "",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const searchString = watch("searchString");
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="container-fluid">
|
|
||||||
<Breadcrumb
|
|
||||||
data={[
|
|
||||||
{ label: "Home", link: "/dashboard" },
|
|
||||||
{ label: "Finance", link: "/advance-payment" },
|
|
||||||
{ label: "Advance Payment" },
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
<div className="card px-4 py-2 page-min-h">
|
|
||||||
<div className="row py-1">
|
|
||||||
<AdvancePaymentList1 searchString={searchString} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default AdvancePaymentPage1
|
|
||||||
108
src/pages/AdvancePayment/AdvancePaymentPageDetails.jsx
Normal file
108
src/pages/AdvancePayment/AdvancePaymentPageDetails.jsx
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
import React, {
|
||||||
|
createContext,
|
||||||
|
useContext,
|
||||||
|
useEffect,
|
||||||
|
useMemo,
|
||||||
|
useState,
|
||||||
|
} from "react";
|
||||||
|
import Breadcrumb from "../../components/common/Breadcrumb";
|
||||||
|
import { useEmployee } from "../../hooks/useEmployees";
|
||||||
|
import EmployeeSearchInput from "../../components/common/EmployeeSearchInput";
|
||||||
|
import { useForm } from "react-hook-form";
|
||||||
|
import Label from "../../components/common/Label";
|
||||||
|
import AdvancePaymentList from "../../components/AdvancePayment/AdvancePaymentListDetails";
|
||||||
|
import { employee } from "../../data/masters";
|
||||||
|
import { formatFigure } from "../../utils/appUtils";
|
||||||
|
import { useParams } from "react-router-dom";
|
||||||
|
import { useExpenseTransactions } from "../../hooks/useExpense";
|
||||||
|
|
||||||
|
export const AdvancePaymentContext = createContext();
|
||||||
|
export const useAdvancePaymentContext = () => {
|
||||||
|
const context = useContext(AdvancePaymentContext);
|
||||||
|
if (!context) {
|
||||||
|
throw new Error(
|
||||||
|
"useAdvancePaymentContext must be used within an AdvancePaymentProvider"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
};
|
||||||
|
const AdvancePaymentPageDetails = () => {
|
||||||
|
const { employeeId } = useParams();
|
||||||
|
|
||||||
|
const { data: transactionData } = useExpenseTransactions(employeeId, {
|
||||||
|
enabled: !!employeeId
|
||||||
|
});
|
||||||
|
|
||||||
|
const employeeName = useMemo(() => {
|
||||||
|
if (Array.isArray(transactionData) && transactionData.length > 0) {
|
||||||
|
const emp = transactionData[0].employee;
|
||||||
|
if (emp) return `${emp.firstName} ${emp.lastName}`;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}, [transactionData]);
|
||||||
|
|
||||||
|
const [balance, setBalance] = useState(null);
|
||||||
|
const { control, reset, watch } = useForm({
|
||||||
|
defaultValues: {
|
||||||
|
employeeId: employeeId || "",
|
||||||
|
searchString: "",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const selectedEmployeeId = employeeId || watch("employeeId");
|
||||||
|
|
||||||
|
const searchString = watch("searchString");
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const selectedEmpoyee = sessionStorage.getItem("transaction-empId");
|
||||||
|
reset({
|
||||||
|
employeeId: selectedEmpoyee || "",
|
||||||
|
});
|
||||||
|
}, [reset]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AdvancePaymentContext.Provider value={{ setBalance }}>
|
||||||
|
<div className="container-fluid">
|
||||||
|
<Breadcrumb
|
||||||
|
data={[
|
||||||
|
{ label: "Home", link: "/dashboard" },
|
||||||
|
{ label: "Finance", link: "/advance-payment" },
|
||||||
|
{ label: "Advance Payment", link: "/advance-payment" },
|
||||||
|
employeeName && { label: employeeName, link: "" },
|
||||||
|
].filter(Boolean)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="card px-4 py-2 page-min-h ">
|
||||||
|
<div className="row py-1 justify-content-end">
|
||||||
|
<div className="col-md-8 d-flex align-items-center justify-content-end">
|
||||||
|
{balance ? (
|
||||||
|
<>
|
||||||
|
<label className="fs-5 fw-semibold">Current Balance : </label>
|
||||||
|
<span
|
||||||
|
className={`${balance > 0 ? "text-success" : "text-danger"
|
||||||
|
} fs-5 fw-bold ms-1`}
|
||||||
|
>
|
||||||
|
{balance > 0 ? (
|
||||||
|
<i className="bx bx-plus b-sm"></i>
|
||||||
|
) : (
|
||||||
|
<i className="bx bx-minus b-sm"></i>
|
||||||
|
)}{" "}
|
||||||
|
{formatFigure(balance, {
|
||||||
|
type: "currency",
|
||||||
|
currency: "INR",
|
||||||
|
})}
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<AdvancePaymentList employeeId={selectedEmployeeId} searchString={searchString} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</AdvancePaymentContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AdvancePaymentPageDetails;
|
||||||
@ -58,10 +58,10 @@ import SubscriptionSummary from "../pages/Home/SubscriptionSummary";
|
|||||||
import MakeSubscription from "../pages/Home/MakeSubscription";
|
import MakeSubscription from "../pages/Home/MakeSubscription";
|
||||||
import PaymentRequestPage from "../pages/PaymentRequest/PaymentRequestPage";
|
import PaymentRequestPage from "../pages/PaymentRequest/PaymentRequestPage";
|
||||||
import RecurringExpensePage from "../pages/RecurringExpense/RecurringExpensePage";
|
import RecurringExpensePage from "../pages/RecurringExpense/RecurringExpensePage";
|
||||||
import AdvancePaymentPage from "../pages/AdvancePayment/AdvancePaymentPage";
|
|
||||||
import ServiceProjectDetail from "../pages/ServiceProject/ServiceProjectDetail";
|
import ServiceProjectDetail from "../pages/ServiceProject/ServiceProjectDetail";
|
||||||
import ManageJob from "../components/ServiceProject/ServiceProjectJob/ManageJob";
|
import ManageJob from "../components/ServiceProject/ServiceProjectJob/ManageJob";
|
||||||
import AdvancePaymentPage1 from "../pages/AdvancePayment/AdvancePaymentPage1";
|
import AdvancePaymentPageDetails from "../pages/AdvancePayment/AdvancePaymentPageDetails";
|
||||||
|
import AdvancePaymentPage from "../pages/AdvancePayment/AdvancePaymentPage";
|
||||||
const router = createBrowserRouter(
|
const router = createBrowserRouter(
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@ -97,7 +97,7 @@ const router = createBrowserRouter(
|
|||||||
{ path: "/projects/details", element: <ProjectDetails /> },
|
{ path: "/projects/details", element: <ProjectDetails /> },
|
||||||
{ path: "/project/manage/:projectId", element: <ManageProject /> },
|
{ path: "/project/manage/:projectId", element: <ManageProject /> },
|
||||||
{ path: "/service-projects/:projectId", element: <ServiceProjectDetail /> },
|
{ path: "/service-projects/:projectId", element: <ServiceProjectDetail /> },
|
||||||
{path:"/service/job",element:<ManageJob/>},
|
{ path: "/service/job", element: <ManageJob /> },
|
||||||
|
|
||||||
{ path: "/employees", element: <EmployeeList /> },
|
{ path: "/employees", element: <EmployeeList /> },
|
||||||
{ path: "/employee/:employeeId", element: <EmployeeProfile /> },
|
{ path: "/employee/:employeeId", element: <EmployeeProfile /> },
|
||||||
@ -117,8 +117,11 @@ const router = createBrowserRouter(
|
|||||||
{ path: "/expenses", element: <ExpensePage /> },
|
{ path: "/expenses", element: <ExpensePage /> },
|
||||||
{ path: "/payment-request", element: <PaymentRequestPage /> },
|
{ path: "/payment-request", element: <PaymentRequestPage /> },
|
||||||
{ path: "/recurring-payment", element: <RecurringExpensePage /> },
|
{ path: "/recurring-payment", element: <RecurringExpensePage /> },
|
||||||
{ path: "/advance-payment", element: <AdvancePaymentPage1 /> },
|
// { path: "/advance-payment", element: <AdvancePaymentPage1 /> },
|
||||||
{ path: "/advance-payment/:employeeId", element: <AdvancePaymentPage /> },
|
// { path: "/advance-payment/:employeeId", element: <AdvancePaymentPage /> },
|
||||||
|
|
||||||
|
{ path: "/advance-payment", element: <AdvancePaymentPage /> },
|
||||||
|
{ path: "/advance-payment/:employeeId", element: <AdvancePaymentPageDetails /> },
|
||||||
{ path: "/collection", element: <CollectionPage /> },
|
{ path: "/collection", element: <CollectionPage /> },
|
||||||
{ path: "/masters", element: <MasterPage /> },
|
{ path: "/masters", element: <MasterPage /> },
|
||||||
{ path: "/tenants", element: <TenantPage /> },
|
{ path: "/tenants", element: <TenantPage /> },
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user