Adding TDS Calculation in ViewExpense.

This commit is contained in:
Kartik Sharma 2025-11-17 10:31:41 +05:30
parent a21bec943d
commit b568188a3e
3 changed files with 112 additions and 77 deletions

View File

@ -10,6 +10,7 @@ import { zodResolver } from "@hookform/resolvers/zod";
import { defaultActionValues, ExpenseActionScheam } from "./ExpenseSchema";
import { useExpenseContext } from "../../pages/Expense/ExpensePage";
import {
calculateTDSPercentage,
formatCurrency,
formatFigure,
getColorNameFromHex,
@ -54,12 +55,22 @@ const ViewExpense = ({ ExpenseId }) => {
setValue,
reset,
control,
watch,
formState: { errors },
} = useForm({
resolver: zodResolver(ActionSchema),
defaultValues: defaultActionValues,
});
const baseAmount = Number(watch("baseAmount")) || 0;
const taxAmount = Number(watch("taxAmount")) || 0;
const tdsPercentage = Number(watch("tdsPercentage")) || 0;
const { grossAmount, tdsAmount, netPayable } = useMemo(() => {
return calculateTDSPercentage(baseAmount, taxAmount, tdsPercentage);
}, [baseAmount, taxAmount, tdsPercentage]);
const userPermissions = useSelector(
(state) => state?.globalVariables?.loginUser?.featurePermissions || []
);
@ -132,8 +143,7 @@ const ViewExpense = ({ ExpenseId }) => {
<span>{data?.expenseUId}</span>
</div>{" "}
<span
className={`badge bg-label-${
getColorNameFromHex(data?.status?.color) || "secondary"
className={`badge bg-label-${getColorNameFromHex(data?.status?.color) || "secondary"
}`}
t
>
@ -307,8 +317,7 @@ const ViewExpense = ({ ExpenseId }) => {
lastName={data.createdBy?.lastName}
/>
<span className="text-muted">
{`${data.createdBy?.firstName ?? ""} ${
data.createdBy?.lastName ?? ""
{`${data.createdBy?.firstName ?? ""} ${data.createdBy?.lastName ?? ""
}`.trim() || "N/A"}
</span>
</div>
@ -355,8 +364,7 @@ const ViewExpense = ({ ExpenseId }) => {
lastName={data.paidBy?.lastName}
/>
<span className="text-muted">
{`${data.paidBy?.firstName ?? ""} ${
data.paidBy?.lastName ?? ""
{`${data.paidBy?.firstName ?? ""} ${data.paidBy?.lastName ?? ""
}`.trim() || "N/A"}
</span>
</div>
@ -493,19 +501,7 @@ const ViewExpense = ({ ExpenseId }) => {
projectId={null}
/>
</div>
<div className="col-12 col-md-6 text-start">
<Label className="form-label">TDS Percentage</Label>
<input
type="text"
className="form-control form-control-sm"
{...register("tdsPercentage")}
/>
{errors.tdsPercentage && (
<small className="danger-text">
{errors.tdsPercentage.message}
</small>
)}
</div>
<div className="col-12 col-md-6 text-start">
<Label className="form-label" required>
Base Amount
@ -536,7 +532,32 @@ const ViewExpense = ({ ExpenseId }) => {
</small>
)}
</div>
<div className="col-12 col-md-6 text-start">
<Label className="form-label">TDS Percentage</Label>
<input
type="text"
className="form-control form-control-sm"
{...register("tdsPercentage")}
/>
{errors.tdsPercentage && (
<small className="danger-text">
{errors.tdsPercentage.message}
</small>
)}
</div>
<div className="col-12 d-flex align-items-center gap-4 mb-2 mt-1">
<div>
<span className="fw-semibold">TDS Amount: </span>
<span className="badge bg-label-secondary">{tdsAmount.toFixed(2)}</span>
</div>
<div>
<span className="fw-semibold">Net Payable: </span>
<span className="badge bg-label-secondary">{netPayable.toFixed(2)}</span>
</div>
</div>
</div>
)}
<div className="col-12 mb-3 text-start mt-1">
{((nextStatusWithPermission.length > 0 &&

View File

@ -24,7 +24,7 @@ import { useNavigate } from "react-router-dom";
import { useForm } from "react-hook-form";
import { useSelector } from "react-redux";
import { usePaymentRequestContext } from "../../pages/PaymentRequest/PaymentRequestPage";
import { localToUtc } from "../../utils/appUtils";
import { calculateTDSPercentage, localToUtc } from "../../utils/appUtils";
import { usePaymentMode } from "../../hooks/masterHook/useMaster";
import Filelist from "../Expenses/Filelist";
@ -69,15 +69,10 @@ const ActionPaymentRequest = ({ requestId }) => {
const taxAmount = watch("taxAmount") || 0;
const tdsPercentage = watch("tdsPercentage") || 0;
const grossAmount = baseAmount + taxAmount;
const tdsAmount = useMemo(() => (baseAmount * tdsPercentage) / 100, [
baseAmount,
tdsPercentage,
]);
const netPayable = useMemo(() => grossAmount - tdsAmount, [grossAmount, tdsAmount]);
const { grossAmount, tdsAmount, netPayable } = useMemo(() => {
return calculateTDSPercentage(baseAmount, taxAmount, tdsPercentage);
}, [baseAmount, taxAmount, tdsPercentage]);
const userPermissions = useSelector(
(state) => state?.globalVariables?.loginUser?.featurePermissions || []
@ -428,6 +423,7 @@ const ActionPaymentRequest = ({ requestId }) => {
<span className="badge bg-label-secondary">{netPayable.toFixed(2)}</span>
</div>
</div>
</div>
)}

View File

@ -228,3 +228,21 @@ export function daysLeft(startDate, dueDate) {
return { days, color };
}
export function calculateTDSPercentage(baseAmount = 0, taxAmount = 0, tdsPercentage = 0) {
baseAmount = Number(baseAmount) || 0;
taxAmount = Number(taxAmount) || 0;
tdsPercentage = Number(tdsPercentage) || 0;
const grossAmount = baseAmount + taxAmount;
const tdsAmount = (baseAmount * tdsPercentage) / 100;
const netPayable = grossAmount - tdsAmount;
return {
grossAmount,
tdsAmount,
netPayable,
};
}