From bac9f25df1dc5096ada54451020dad51c6cb249a Mon Sep 17 00:00:00 2001 From: "pramod.mahajan" Date: Wed, 5 Nov 2025 20:10:19 +0530 Subject: [PATCH] added advance payment api --- .../AdvancePayment/AdvancePaymentList.jsx | 152 +++++++----------- src/components/Expenses/ExpenseSchema.js | 4 +- .../PaymentRequest/PaymentRequestSchema.js | 81 ++++++---- .../PaymentRequest/PaymentStatusLogs.jsx | 1 - .../PaymentRequest/ViewPaymentRequest.jsx | 96 ++++++++--- src/hooks/useExpense.js | 4 +- .../AdvancePayment/AdvancePaymentPage.jsx | 8 +- src/repositories/ExpsenseRepository.jsx | 6 +- 8 files changed, 195 insertions(+), 157 deletions(-) diff --git a/src/components/AdvancePayment/AdvancePaymentList.jsx b/src/components/AdvancePayment/AdvancePaymentList.jsx index 4bbe830a..a1bf31a7 100644 --- a/src/components/AdvancePayment/AdvancePaymentList.jsx +++ b/src/components/AdvancePayment/AdvancePaymentList.jsx @@ -1,82 +1,31 @@ import React from "react"; import { useExpenseTransactions } from "../../hooks/useExpense"; +import Error from "../common/Error"; +import { formatUTCToLocalTime } from "../../utils/dateUtils"; const AdvancePaymentList = ({ employeeId }) => { - const {data,isError, isLoading,isFetching,error} = useExpenseTransactions(employeeId) - const record = { - openingBalance: 25000.0, - rows: [ - { id: 1, description: "Opening Balance", credit: 0.0, debit: 0.0 }, - { - id: 2, - description: "Sales Invoice #INV-001", - credit: 15000.0, - debit: 0.0, - }, - { - id: 3, - description: "Sales Invoice #INV-002", - credit: 12000.0, - debit: 0.0, - }, - { - id: 4, - description: "Purchase - Raw Materials", - credit: 0.0, - debit: 8000.0, - }, - { id: 5, description: "Office Rent - June", credit: 0.0, debit: 5000.0 }, - { - id: 6, - description: "Client Payment Received (Bank)", - credit: 10000.0, - debit: 0.0, - }, - { - id: 7, - description: "Supplier Payment - ABC Corp", - credit: 0.0, - debit: 6000.0, - }, - { id: 8, description: "Interest Income", credit: 750.0, debit: 0.0 }, - { id: 9, description: "Bank Charges", credit: 0.0, debit: 250.0 }, - { - id: 10, - description: "Utilities - Electricity", - credit: 0.0, - debit: 1800.0, - }, - { - id: 11, - description: "Service Income - Project Alpha", - credit: 5000.0, - debit: 0.0, - }, - { id: 12, description: "Misc Expense", credit: 0.0, debit: 450.0 }, - { - id: 13, - description: "Adjustment - Prior Year", - credit: 0.0, - debit: 500.0, - }, - { id: 14, description: "Commission Earned", credit: 1200.0, debit: 0.0 }, - { - id: 15, - description: "Employee Salary - June", - credit: 0.0, - debit: 9500.0, - }, - { id: 16, description: "GST Refund", credit: 2000.0, debit: 0.0 }, - { id: 17, description: "Insurance Premium", credit: 0.0, debit: 3000.0 }, - { id: 18, description: "Late Fee Collected", credit: 350.0, debit: 0.0 }, - { id: 19, description: "Maintenance Expense", credit: 0.0, debit: 600.0 }, - { id: 20, description: "Closing Balance", credit: 0.0, debit: 0.0 }, - ], - }; - let currentBalance = record.openingBalance; - const rowsWithBalance = record.rows.map((r) => { - currentBalance += r.credit - r.debit; - return { ...r, balance: currentBalance }; + const { data, isError, isLoading, error } = + useExpenseTransactions(employeeId); + + const records = data?.json || []; + + let currentBalance = 0; + + const rowsWithBalance = data?.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, + balance: currentBalance, + }; }); const columns = [ @@ -110,10 +59,16 @@ const AdvancePaymentList = ({ employeeId }) => { }, ]; + if (isLoading) return
Loading...
; + if (isError){ + return
{error.status === 404 ? "No advance payment transactions found." : }
+ }; + return ( -
- - +
+
+ {employeeId ? (
+ {columns.map((col) => ( - {rowsWithBalance.map((row) => ( + {rowsWithBalance?.map((row) => ( {columns.map((col) => ( - ))} ))} - + -
@@ -123,28 +78,32 @@ const AdvancePaymentList = ({ employeeId }) => {
- {col.key === "balance" || - col.key === "credit" || - col.key === "debit" - ? row[col.key].toLocaleString("en-IN", { - style: "currency", - currency: "INR", - }) - : (
- {new Date().toISOString()} - Projec Name - {row[col.key]} -
)} +
+ {["balance", "credit", "debit"].includes(col.key) ? ( + row[col.key].toLocaleString("en-IN", { + style: "currency", + currency: "INR", + }) + ) : ( +
+ + {formatUTCToLocalTime(row.createdAt)} + + + {row.projectName} + + {row.description} +
+ )}
Final Balance @@ -155,7 +114,12 @@ const AdvancePaymentList = ({ employeeId }) => {
+ ):( +
+

Please Select Employee

+
+ )} +
); }; diff --git a/src/components/Expenses/ExpenseSchema.js b/src/components/Expenses/ExpenseSchema.js index 04110339..78b0510d 100644 --- a/src/components/Expenses/ExpenseSchema.js +++ b/src/components/Expenses/ExpenseSchema.js @@ -167,9 +167,9 @@ export const defaultActionValues = { reimburseTransactionId: null, reimburseDate: null, reimburseById: null, - tdsPercentage: null, + tdsPercentage: 0, baseAmount:null, - taxAmount: null, + taxAmount: 0, }; export const SearchSchema = z.object({ diff --git a/src/components/PaymentRequest/PaymentRequestSchema.js b/src/components/PaymentRequest/PaymentRequestSchema.js index d89fe7d2..12e6eec1 100644 --- a/src/components/PaymentRequest/PaymentRequestSchema.js +++ b/src/components/PaymentRequest/PaymentRequestSchema.js @@ -93,6 +93,9 @@ export const PaymentRequestActionScheam = ( paidTransactionId: z.string().nullable().optional(), paidAt: z.string().nullable().optional(), paidById: z.string().nullable().optional(), + tdsPercentage: z.string().nullable().optional(), + baseAmount: z.string().nullable().optional(), + taxAmount: z.string().nullable().optional(), }) .superRefine((data, ctx) => { if (isTransaction) { @@ -110,7 +113,7 @@ export const PaymentRequestActionScheam = ( message: "Transacion Date is required", }); } - + if (!data.paidById) { ctx.addIssue({ code: z.ZodIssueCode.custom, @@ -118,6 +121,20 @@ export const PaymentRequestActionScheam = ( message: "Paid By is required", }); } + if (!data.baseAmount) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + path: ["baseAmount"], + message: "Base Amount i required", + }); + } + if (!data.taxAmount) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + path: ["taxAmount"], + message: "Tax is required", + }); + } } }); }; @@ -128,40 +145,38 @@ export const defaultPaymentRequestActionValues = { paidTransactionId: null, paidAt: null, paidById: null, + tdsPercentage:"0", + baseAmount: null, + taxAmount:null, }; - -export const RequestedExpenseSchema = - - z.object({ - paymentModeId: z.string().min(1, { message: "Payment mode is required" }), - location: z.string().min(1, { message: "Location is required" }), - gstNumber: z.string().optional(), - billAttachments: z - .array( - z.object({ - fileName: z.string().min(1, { message: "Filename is required" }), - base64Data: z.string().nullable(), - contentType: z - .string() - .refine((val) => ALLOWED_TYPES.includes(val), { - message: "Only PDF, PNG, JPG, or JPEG files are allowed", - }), - documentId: z.string().optional(), - fileSize: z.number().max(MAX_FILE_SIZE, { - message: "File size must be less than or equal to 5MB", - }), - description: z.string().optional(), - isActive: z.boolean().default(true), - }) - ) - .nonempty({ message: "At least one file attachment is required" }), - }) +export const RequestedExpenseSchema = z.object({ + paymentModeId: z.string().min(1, { message: "Payment mode is required" }), + location: z.string().min(1, { message: "Location is required" }), + gstNumber: z.string().optional(), + billAttachments: z + .array( + z.object({ + fileName: z.string().min(1, { message: "Filename is required" }), + base64Data: z.string().nullable(), + contentType: z.string().refine((val) => ALLOWED_TYPES.includes(val), { + message: "Only PDF, PNG, JPG, or JPEG files are allowed", + }), + documentId: z.string().optional(), + fileSize: z.number().max(MAX_FILE_SIZE, { + message: "File size must be less than or equal to 5MB", + }), + description: z.string().optional(), + isActive: z.boolean().default(true), + }) + ) + .nonempty({ message: "At least one file attachment is required" }), +}); export const DefaultRequestedExpense = { - paymentModeId:"", - location:"", - gstNumber:"", + paymentModeId: "", + location: "", + gstNumber: "", // amount:"", - billAttachments:[] -} \ No newline at end of file + billAttachments: [], +}; diff --git a/src/components/PaymentRequest/PaymentStatusLogs.jsx b/src/components/PaymentRequest/PaymentStatusLogs.jsx index 1793d90e..9abb3fa5 100644 --- a/src/components/PaymentRequest/PaymentStatusLogs.jsx +++ b/src/components/PaymentRequest/PaymentStatusLogs.jsx @@ -20,7 +20,6 @@ const PaymentStatusLogs = ({ data }) => { ); const timelineData = useMemo(() => { - console.log(logsToShow) return logsToShow.map((log, index) => ({ id: index + 1, title: log.nextStatus?.name || "Status Updated", diff --git a/src/components/PaymentRequest/ViewPaymentRequest.jsx b/src/components/PaymentRequest/ViewPaymentRequest.jsx index a94a003b..ca6b7e90 100644 --- a/src/components/PaymentRequest/ViewPaymentRequest.jsx +++ b/src/components/PaymentRequest/ViewPaymentRequest.jsx @@ -50,7 +50,8 @@ const ViewPaymentRequest = ({ requestId }) => { const IsReview = useHasUserPermission(REVIEW_EXPENSE); const [imageLoaded, setImageLoaded] = useState({}); - const { setDocumentView, setModalSize,setVieRequest ,setIsExpenseGenerate} = usePaymentRequestContext(); + const { setDocumentView, setModalSize, setVieRequest, setIsExpenseGenerate } = + usePaymentRequestContext(); const ActionSchema = PaymentRequestActionScheam(IsPaymentProcess, data?.createdAt) ?? z.object({}); @@ -118,14 +119,15 @@ const ViewPaymentRequest = ({ requestId }) => { const handleImageLoad = (id) => { setImageLoaded((prev) => ({ ...prev, [id]: true })); }; - const handleExpense = ()=>{ - - setIsExpenseGenerate({IsOpen:true,requestId:requestId}) - setVieRequest({IsOpen:true,requestId:requestId}) - } - + const handleExpense = () => { + setIsExpenseGenerate({ IsOpen: true, requestId: requestId }); + setVieRequest({ IsOpen: true, requestId: requestId }); + }; return ( -
+
Payment Request Details
@@ -201,7 +203,10 @@ const ViewPaymentRequest = ({ requestId }) => { Amount :
- {formatFigure(data?.amount,{type:"currency",currency : data?.currency?.currencyCode})} + {formatFigure(data?.amount, { + type: "currency", + currency: data?.currency?.currencyCode, + })}
@@ -312,10 +317,14 @@ const ViewPaymentRequest = ({ requestId }) => {
- - {data?.attachments?.length > 0 ? ( - - ):(

No Attachment

)} + {data?.attachments?.length > 0 ? ( + + ) : ( +

No Attachment

+ )}
@@ -372,7 +381,7 @@ const ViewPaymentRequest = ({ requestId }) => { )} -
+
{ projectId={null} />
+
+ + + {errors.tdsPercentage && ( + + {errors.tdsPercentage.message} + + )} +
+
+ + + {errors.baseAmount && ( + + {errors.baseAmount.message} + + )} +
+
+ + + {errors.taxAmount && ( + + {errors.taxAmount.message} + + )} +
)}
@@ -441,10 +493,18 @@ const ViewPaymentRequest = ({ requestId }) => { )}
- ): !data?.isExpenseCreated ? (
- -
):(<>)} - + ) : !data?.isExpenseCreated ? ( +
+ +
+ ) : ( + <> + )}
diff --git a/src/hooks/useExpense.js b/src/hooks/useExpense.js index 9823095f..00e99fda 100644 --- a/src/hooks/useExpense.js +++ b/src/hooks/useExpense.js @@ -436,7 +436,6 @@ export const useExpenseTransactions = (employeeId)=>{ return useQuery({ queryKey:["transaction",employeeId], queryFn:async()=> { - debugger const resp = await ExpenseRepository.GetTranctionList(employeeId); return resp.data }, @@ -466,4 +465,5 @@ export const useCreateRecurringExpense = (onSuccessCallBack) => { ); }, }); -}; \ No newline at end of file +}; + diff --git a/src/pages/AdvancePayment/AdvancePaymentPage.jsx b/src/pages/AdvancePayment/AdvancePaymentPage.jsx index 305df58e..d03ac49a 100644 --- a/src/pages/AdvancePayment/AdvancePaymentPage.jsx +++ b/src/pages/AdvancePayment/AdvancePaymentPage.jsx @@ -23,16 +23,16 @@ const AdvancePaymentPage = () => { { label: "Advance Payment" }, ]} /> -
+
-
-
- +
+
diff --git a/src/repositories/ExpsenseRepository.jsx b/src/repositories/ExpsenseRepository.jsx index 231d8b78..4a5cedc9 100644 --- a/src/repositories/ExpsenseRepository.jsx +++ b/src/repositories/ExpsenseRepository.jsx @@ -49,11 +49,11 @@ const ExpenseRepository = { CreateRecurringExpense: (data) => api.post("/api/Expense/recurring-payment/create", data), //#endregion - - + //#region Advance Payment - GetTranctionList: () => api.get(`/get/transactions/${employeeId}`), + GetTranctionList: (employeeId)=>api.get(`/api/Expense/get/transactions/${employeeId}`), //#endregion + }; export default ExpenseRepository;