added Advance Payment
This commit is contained in:
parent
b35c39ca36
commit
e7fcfdb154
234
src/components/AdvancePayment/AdvancePaymentList.jsx
Normal file
234
src/components/AdvancePayment/AdvancePaymentList.jsx
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
|
||||||
|
import React, { useEffect, useMemo } from "react";
|
||||||
|
import { 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 }) => {
|
||||||
|
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 AdvancePaymentList;
|
||||||
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
import { boolean, z } from "zod";
|
import { boolean, z } from "zod";
|
||||||
import { INR_CURRENCY_CODE } from "../../utils/constants";
|
import { CREATE_EXEPENSE, EXPENSE_DRAFT, EXPENSE_STATUS, INR_CURRENCY_CODE } from "../../utils/constants";
|
||||||
const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
|
const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
|
||||||
const ALLOWED_TYPES = [
|
const ALLOWED_TYPES = [
|
||||||
"application/pdf",
|
"application/pdf",
|
||||||
@ -228,3 +228,10 @@ export const DefaultRequestedExpense = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export const STATUS_HEADING = {
|
||||||
|
[EXPENSE_STATUS.draft]: "Initiation",
|
||||||
|
[EXPENSE_STATUS.review_pending]: "Review & Validation",
|
||||||
|
[EXPENSE_STATUS.approve_pending]: "Approval",
|
||||||
|
[EXPENSE_STATUS.payment_pending]: "Processing & Disbursement",
|
||||||
|
[EXPENSE_STATUS.payment_processed]: "Payment Completed",
|
||||||
|
};
|
||||||
|
|||||||
@ -1,24 +1,24 @@
|
|||||||
import React from 'react'
|
import React from "react";
|
||||||
import { useRecurringExpenseDetail } from '../../hooks/useExpense';
|
import { useRecurringExpenseDetail } from "../../hooks/useExpense";
|
||||||
import { formatUTCToLocalTime } from '../../utils/dateUtils';
|
import { formatUTCToLocalTime } from "../../utils/dateUtils";
|
||||||
import { formatFigure, getColorNameFromHex } from '../../utils/appUtils';
|
import { formatFigure, getColorNameFromHex } from "../../utils/appUtils";
|
||||||
import Avatar from '../common/Avatar';
|
import Avatar from "../common/Avatar";
|
||||||
import { FREQUENCY_FOR_RECURRING } from '../../utils/constants';
|
import { FREQUENCY_FOR_RECURRING } from "../../utils/constants";
|
||||||
import { ExpenseDetailsSkeleton } from '../Expenses/ExpenseSkeleton';
|
import { ExpenseDetailsSkeleton } from "../Expenses/ExpenseSkeleton";
|
||||||
|
|
||||||
const ViewRecurringExpense = ({ RecurringId }) => {
|
const ViewRecurringExpense = ({ RecurringId }) => {
|
||||||
const { data, isLoading, isError, error, isFetching } = useRecurringExpenseDetail(RecurringId);
|
const { data, isLoading, isError, error, isFetching } =
|
||||||
|
useRecurringExpenseDetail(RecurringId);
|
||||||
|
|
||||||
const statusColorMap = {
|
const statusColorMap = {
|
||||||
"da462422-13b2-45cc-a175-910a225f6fc8": "primary", // Active
|
"da462422-13b2-45cc-a175-910a225f6fc8": "primary", // Active
|
||||||
"306856fb-5655-42eb-bf8b-808bb5e84725": "success", // Completed
|
"306856fb-5655-42eb-bf8b-808bb5e84725": "success", // Completed
|
||||||
"3ec864d2-8bf5-42fb-ba70-5090301dd816": "danger", // De-Activated
|
"3ec864d2-8bf5-42fb-ba70-5090301dd816": "danger", // De-Activated
|
||||||
"8bfc9346-e092-4a80-acbf-515ae1ef6868": "warning", // Paused
|
"8bfc9346-e092-4a80-acbf-515ae1ef6868": "warning", // Paused
|
||||||
};
|
};
|
||||||
if (isLoading) return <ExpenseDetailsSkeleton />;
|
if (isLoading) return <ExpenseDetailsSkeleton />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
<form className="container px-3">
|
<form className="container px-3">
|
||||||
<div className="col-12 mb-1">
|
<div className="col-12 mb-1">
|
||||||
<h5 className="fw-semibold m-0">Recurring Payment Details</h5>
|
<h5 className="fw-semibold m-0">Recurring Payment Details</h5>
|
||||||
@ -26,13 +26,14 @@ const ViewRecurringExpense = ({ RecurringId }) => {
|
|||||||
<div className="row mb-1">
|
<div className="row mb-1">
|
||||||
{/* <div className="col-12 col-lg-7 col-xl-8 mb-3"> */}
|
{/* <div className="col-12 col-lg-7 col-xl-8 mb-3"> */}
|
||||||
<div className="row">
|
<div className="row">
|
||||||
|
|
||||||
{/* Row 1 Recurring Id and Status */}
|
{/* Row 1 Recurring Id and Status */}
|
||||||
|
|
||||||
<div className="col-12 d-flex justify-content-between text-start fw-semibold my-2 mb-4">
|
<div className="col-12 d-flex justify-content-between text-start fw-semibold my-2 mb-4">
|
||||||
<span>{data?.recurringPaymentUID}</span>
|
<span>{data?.recurringPaymentUID}</span>
|
||||||
<span
|
<span
|
||||||
className={`badge bg-label-${statusColorMap[data?.status?.id] || "secondary"}`}
|
className={`badge bg-label-${
|
||||||
|
statusColorMap[data?.status?.id] || "secondary"
|
||||||
|
}`}
|
||||||
>
|
>
|
||||||
{data?.status?.name || "N/A"}
|
{data?.status?.name || "N/A"}
|
||||||
</span>
|
</span>
|
||||||
@ -48,12 +49,12 @@ const ViewRecurringExpense = ({ RecurringId }) => {
|
|||||||
>
|
>
|
||||||
Expense Category :
|
Expense Category :
|
||||||
</label>
|
</label>
|
||||||
<div className="text-muted">{data?.expenseCategory?.name || "N/A"}</div>
|
<div className="text-muted">
|
||||||
|
{data?.expenseCategory?.name || "N/A"}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{/* Row 3 Amount and Project */}
|
{/* Row 3 Amount and Project */}
|
||||||
|
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-6 mb-3">
|
||||||
@ -66,7 +67,9 @@ const ViewRecurringExpense = ({ RecurringId }) => {
|
|||||||
</label>
|
</label>
|
||||||
<div className="text-muted">
|
<div className="text-muted">
|
||||||
{data?.amount != null
|
{data?.amount != null
|
||||||
? `${data?.currency?.symbol ?? "¥"} ${Number(data.amount).toFixed(2)} ${data?.currency?.currencyCode ?? "CN"}`
|
? `${data?.currency?.symbol ?? "¥"} ${Number(
|
||||||
|
data.amount
|
||||||
|
).toFixed(2)} ${data?.currency?.currencyCode ?? "CN"}`
|
||||||
: "N/A"}
|
: "N/A"}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -144,11 +147,11 @@ const ViewRecurringExpense = ({ RecurringId }) => {
|
|||||||
<div className="text-muted" style={{ textAlign: "left" }}>
|
<div className="text-muted" style={{ textAlign: "left" }}>
|
||||||
{data?.notifyTo?.length > 0
|
{data?.notifyTo?.length > 0
|
||||||
? data.notifyTo?.map((user, index) => (
|
? data.notifyTo?.map((user, index) => (
|
||||||
<span key={user.id}>
|
<span key={user.id}>
|
||||||
{user.email}
|
{user.email}
|
||||||
{index < data?.notifyTo?.length - 1 && ", "}
|
{index < data?.notifyTo?.length - 1 && ", "}
|
||||||
</span>
|
</span>
|
||||||
))
|
))
|
||||||
: "N/A"}
|
: "N/A"}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -201,7 +204,9 @@ const ViewRecurringExpense = ({ RecurringId }) => {
|
|||||||
>
|
>
|
||||||
Payment Buffer Days :
|
Payment Buffer Days :
|
||||||
</label>
|
</label>
|
||||||
<div className="text-muted">{data?.paymentBufferDays || "N/A"}</div>
|
<div className="text-muted">
|
||||||
|
{data?.paymentBufferDays || "N/A"}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -231,11 +236,12 @@ const ViewRecurringExpense = ({ RecurringId }) => {
|
|||||||
>
|
>
|
||||||
Number of Iteration :
|
Number of Iteration :
|
||||||
</label>
|
</label>
|
||||||
<div className="text-muted">{data?.numberOfIteration || "N/A"}</div>
|
<div className="text-muted">
|
||||||
|
{data?.numberOfIteration || "N/A"}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{/* Row 9 Created By and Updated By*/}
|
{/* Row 9 Created By and Updated By*/}
|
||||||
|
|
||||||
<div className="col-md-6 text-start mb-6">
|
<div className="col-md-6 text-start mb-6">
|
||||||
@ -253,20 +259,22 @@ const ViewRecurringExpense = ({ RecurringId }) => {
|
|||||||
lastName={data?.createdBy?.lastName}
|
lastName={data?.createdBy?.lastName}
|
||||||
/>
|
/>
|
||||||
<span className="text-muted">
|
<span className="text-muted">
|
||||||
{`${data?.createdBy?.firstName ?? ""} ${data?.createdBy?.lastName ?? ""}`.trim() || "N/A"}
|
{`${data?.createdBy?.firstName ?? ""} ${
|
||||||
|
data?.createdBy?.lastName ?? ""
|
||||||
|
}`.trim() || "N/A"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 text-start mb-3">
|
{data?.updatedBy && (
|
||||||
<div className="d-flex align-items-center">
|
<div className="col-md-6 text-start mb-3">
|
||||||
<label
|
<div className="d-flex align-items-center">
|
||||||
className="form-label me-2 mb-0 fw-semibold"
|
<label
|
||||||
style={{ minWidth: "125px" }}
|
className="form-label me-2 mb-0 fw-semibold"
|
||||||
>
|
style={{ minWidth: "125px" }}
|
||||||
Updated By :
|
>
|
||||||
</label>
|
Updated By :
|
||||||
|
</label>
|
||||||
|
|
||||||
{data?.updatedBy ? (
|
|
||||||
<>
|
<>
|
||||||
<Avatar
|
<Avatar
|
||||||
size="xs"
|
size="xs"
|
||||||
@ -275,14 +283,14 @@ const ViewRecurringExpense = ({ RecurringId }) => {
|
|||||||
lastName={data.updatedBy.lastName}
|
lastName={data.updatedBy.lastName}
|
||||||
/>
|
/>
|
||||||
<span className="text-muted">
|
<span className="text-muted">
|
||||||
{`${data.updatedBy.firstName ?? ""} ${data.updatedBy.lastName ?? ""}`.trim() || "N/A"}
|
{`${data.updatedBy.firstName ?? ""} ${
|
||||||
|
data.updatedBy.lastName ?? ""
|
||||||
|
}`.trim() || "N/A"}
|
||||||
</span>
|
</span>
|
||||||
</>
|
</>
|
||||||
) : (
|
</div>
|
||||||
<span className="text-muted">N/A</span>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
|
|
||||||
{/* Row 10 Description */}
|
{/* Row 10 Description */}
|
||||||
|
|
||||||
@ -293,7 +301,10 @@ const ViewRecurringExpense = ({ RecurringId }) => {
|
|||||||
>
|
>
|
||||||
Description :
|
Description :
|
||||||
</label>
|
</label>
|
||||||
<div className="text-muted flex-grow-1" style={{ whiteSpace: "pre-wrap" }}>
|
<div
|
||||||
|
className="text-muted flex-grow-1"
|
||||||
|
style={{ whiteSpace: "pre-wrap" }}
|
||||||
|
>
|
||||||
{data?.description || "N/A"}
|
{data?.description || "N/A"}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -301,7 +312,7 @@ const ViewRecurringExpense = ({ RecurringId }) => {
|
|||||||
{/* </div> */}
|
{/* </div> */}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default ViewRecurringExpense
|
export default ViewRecurringExpense;
|
||||||
|
|||||||
96
src/pages/AdvancePayment/AdvancePaymentPage.jsx
Normal file
96
src/pages/AdvancePayment/AdvancePaymentPage.jsx
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
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/AdvancePaymentList";
|
||||||
|
import { employee } from "../../data/masters";
|
||||||
|
import { formatFigure } from "../../utils/appUtils";
|
||||||
|
|
||||||
|
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 [balance, setBalance] = useState(null);
|
||||||
|
const {control, reset, watch } = useForm({
|
||||||
|
defaultValues: {
|
||||||
|
employeeId: "",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const selectedEmployeeId = watch("employeeId");
|
||||||
|
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: "/" },
|
||||||
|
{ label: "Finance", link: "/advance-payment" },
|
||||||
|
{ label: "Advance Payment" },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
<div className="card px-4 py-2 page-min-h ">
|
||||||
|
<div className="row py-1">
|
||||||
|
<div className="col-12 col-md-4">
|
||||||
|
<div className="d-block text-start">
|
||||||
|
<EmployeeSearchInput
|
||||||
|
control={control}
|
||||||
|
name="employeeId"
|
||||||
|
projectId={null}
|
||||||
|
forAll={true}
|
||||||
|
placeholder={"Enter Employee Name"}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-8 d-flex align-items-center justify-content-end">
|
||||||
|
{balance ? (
|
||||||
|
<>
|
||||||
|
<label className="fs-5 fw-semibold">Total Balance : </label>
|
||||||
|
<span
|
||||||
|
className={`${
|
||||||
|
balance > 0 ? "text-success" : "text-danger"
|
||||||
|
} fs-5 fw-bold ms-1`}
|
||||||
|
>
|
||||||
|
{formatFigure(balance, {
|
||||||
|
type: "currency",
|
||||||
|
currency: "INR",
|
||||||
|
})}
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<AdvancePaymentList employeeId={selectedEmployeeId} />
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</AdvancePaymentContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AdvancePaymentPage;
|
||||||
@ -58,6 +58,7 @@ 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";
|
||||||
const router = createBrowserRouter(
|
const router = createBrowserRouter(
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@ -110,6 +111,7 @@ 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: <AdvancePaymentPage /> },
|
||||||
{ path: "/collection", element: <CollectionPage /> },
|
{ path: "/collection", element: <CollectionPage /> },
|
||||||
{ path: "/masters", element: <MasterPage /> },
|
{ path: "/masters", element: <MasterPage /> },
|
||||||
{ path: "/tenants", element: <TenantPage /> },
|
{ path: "/tenants", element: <TenantPage /> },
|
||||||
|
|||||||
@ -163,7 +163,7 @@ export const EXPENSE_STATUS = {
|
|||||||
review_pending: "6537018f-f4e9-4cb3-a210-6c3b2da999d7",
|
review_pending: "6537018f-f4e9-4cb3-a210-6c3b2da999d7",
|
||||||
payment_pending: "f18c5cfd-7815-4341-8da2-2c2d65778e27",
|
payment_pending: "f18c5cfd-7815-4341-8da2-2c2d65778e27",
|
||||||
approve_pending: "4068007f-c92f-4f37-a907-bc15fe57d4d8",
|
approve_pending: "4068007f-c92f-4f37-a907-bc15fe57d4d8",
|
||||||
|
payment_processed:"61578360-3a49-4c34-8604-7b35a3787b95",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const UUID_REGEX =
|
export const UUID_REGEX =
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user