diff --git a/src/components/AdvancePayment/AdvancePaymentList.jsx b/src/components/AdvancePayment/AdvancePaymentList.jsx index 4bbe830a..0f975ab5 100644 --- a/src/components/AdvancePayment/AdvancePaymentList.jsx +++ b/src/components/AdvancePayment/AdvancePaymentList.jsx @@ -1,82 +1,68 @@ import React from "react"; import { useExpenseTransactions } from "../../hooks/useExpense"; +import Error from "../common/Error"; +import { formatUTCToLocalTime } from "../../utils/dateUtils"; +import Loader, { SpinnerLoader } from "../common/Loader"; 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, isFetching } = + useExpenseTransactions(employeeId, { enabled: !!employeeId }); + + // Handle no employee selected + if (!employeeId) { + return ( +
Please select an employee
+| @@ -126,25 +121,28 @@ const AdvancePaymentList = ({ employeeId }) => { {rowsWithBalance.map((row) => ( | |||||
|---|---|---|---|---|---|
|
- {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")}
+
+ ) : (
+
+
+ {formatUTCToLocalTime(row.createdAt)}
+
+
+ {row.projectName}
+
+ {row.description}
+
+ )}
|
))}
||||
| Final Balance |
diff --git a/src/components/Expenses/ExpenseList.jsx b/src/components/Expenses/ExpenseList.jsx
index 3b58316e..d7a0a1b4 100644
--- a/src/components/Expenses/ExpenseList.jsx
+++ b/src/components/Expenses/ExpenseList.jsx
@@ -123,9 +123,9 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => {
align: "text-start mx-2",
},
{
- key: "expensesType",
+ key: "expensesCategory",
label: "Expense Category",
- getValue: (e) => e.expensesType?.name || "N/A",
+ getValue: (e) => e.expenseCategory?.name || "N/A",
align: "text-start",
},
{
@@ -253,7 +253,7 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => {
className={`sorting d-table-cell `}
aria-sort="descending"
>
- {col.label}
+ {col.label}
)
)}
@@ -288,16 +288,20 @@ const ExpenseList = ({ filters, groupBy = "transactionDate", searchText }) => {
(col.isAlwaysVisible || groupBy !== col.key) && (
|
- {col.customRender
+ {col.customRender
? col.customRender(expense)
: col.getValue(expense)}
+
|
)
)}
-
+
diff --git a/src/components/Expenses/ExpenseSchema.js b/src/components/Expenses/ExpenseSchema.js
index 46173f1a..ad22e67a 100644
--- a/src/components/Expenses/ExpenseSchema.js
+++ b/src/components/Expenses/ExpenseSchema.js
@@ -1,5 +1,6 @@
import { z } from "zod";
import { localToUtc } from "../../utils/appUtils";
+import { DEFAULT_CURRENCY } from "../../utils/constants";
const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
const ALLOWED_TYPES = [
@@ -24,6 +25,10 @@ export const ExpenseSchema = (expenseTypes) => {
location: z.string().min(1, { message: "Location is required" }),
supplerName: z.string().min(1, { message: "Supplier name is required" }),
gstNumber: z.string().optional(),
+ currencyId: z
+ .string()
+ .min(1, { message: "currency is required" })
+ .default(DEFAULT_CURRENCY),
amount: z.coerce
.number({
invalid_type_error: "Amount is required and must be a number",
@@ -94,6 +99,7 @@ export const defaultExpense = {
amount: "",
noOfPersons: "",
gstNumber: "",
+ currencyId: DEFAULT_CURRENCY,
billAttachments: [],
};
@@ -108,6 +114,9 @@ export const ExpenseActionScheam = (
reimburseTransactionId: z.string().nullable().optional(),
reimburseDate: z.string().nullable().optional(),
reimburseById: z.string().nullable().optional(),
+ tdsPercentage: z.number().nullable().optional(),
+ baseAmount: z.string().nullable().optional(),
+ taxAmount: z.string().nullable().optional(),
})
.superRefine((data, ctx) => {
if (isReimbursement) {
@@ -125,15 +134,7 @@ export const ExpenseActionScheam = (
message: "Reimburse Date is required",
});
}
- // let reimburse_Date = localToUtc(data.reimburseDate);
- // if (transactionDate > reimburse_Date) {
- // ctx.addIssue({
- // code: z.ZodIssueCode.custom,
- // path: ["reimburseDate"],
- // message:
- // "Reimburse Date must be greater than or equal to Expense created Date",
- // });
- // }
+
if (!data.reimburseById) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
@@ -141,6 +142,20 @@ export const ExpenseActionScheam = (
message: "Reimburse 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",
+ });
+ }
}
});
};
@@ -152,6 +167,9 @@ export const defaultActionValues = {
reimburseTransactionId: null,
reimburseDate: null,
reimburseById: null,
+ tdsPercentage: 0,
+ baseAmount:null,
+ taxAmount: 0,
};
export const SearchSchema = z.object({
diff --git a/src/components/Expenses/ExpenseStatusLogs.jsx b/src/components/Expenses/ExpenseStatusLogs.jsx
index 2baaa643..c7be711b 100644
--- a/src/components/Expenses/ExpenseStatusLogs.jsx
+++ b/src/components/Expenses/ExpenseStatusLogs.jsx
@@ -8,9 +8,9 @@ const ExpenseStatusLogs = ({ data }) => {
const [visibleCount, setVisibleCount] = useState(4);
const sortedLogs = useMemo(() => {
- if (!data?.updateLogs) return [];
- return [...data.updateLogs].sort(
- (a, b) => new Date(b.updatedAt) - new Date(a.updatedAt)
+ if (!data?.expenseLogs) return [];
+ return [...data.expenseLogs].sort(
+ (a, b) => new Date(b.updateAt) - new Date(a.updateAt)
);
}, [data?.updateLogs]);
@@ -20,11 +20,12 @@ const ExpenseStatusLogs = ({ data }) => {
);
const timelineData = useMemo(() => {
+
return logsToShow.map((log, index) => ({
id: index + 1,
- title: log.nextStatus?.name || "Status Updated",
- description: log.nextStatus?.description || "",
- timeAgo: moment.utc(log?.updatedAt).local().fromNow(),
+ title: log.action || "Status Updated",
+ description: log.comment || "",
+ timeAgo: log.updateAt,
color: getColorNameFromHex(log.nextStatus?.color) || "primary",
users: log.updatedBy
? [
@@ -44,46 +45,8 @@ const ExpenseStatusLogs = ({ data }) => {
};
return (
-
- {/*
- {logsToShow.map((log) => (
-
-
- {sortedLogs.length > visibleCount && (
-
-
- ))}
-
-
-
-
-
- {`${log.updatedBy.firstName} ${log.updatedBy.lastName}`}
-
- {log.action}
-
-
- {formatUTCToLocalTime(log.updateAt, true)}
-
-
-
- {log.comment}
-
-
-
-
- )} */}
+
+
diff --git a/src/components/Expenses/Filelist.jsx b/src/components/Expenses/Filelist.jsx
index 2b1ce74e..15fe9fc3 100644
--- a/src/components/Expenses/Filelist.jsx
+++ b/src/components/Expenses/Filelist.jsx
@@ -12,19 +12,19 @@ const Filelist = ({ files, removeFile, expenseToEdit }) => {
return true;
})
.map((file, idx) => (
-
-
+
+
+
-
- {/*
{/* File icon and info */}
-
))}
diff --git a/src/components/Expenses/ManageExpense.jsx b/src/components/Expenses/ManageExpense.jsx
index f3872614..ce392463 100644
--- a/src/components/Expenses/ManageExpense.jsx
+++ b/src/components/Expenses/ManageExpense.jsx
@@ -3,7 +3,7 @@ import React, { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { defaultExpense, ExpenseSchema } from "./ExpenseSchema";
import { formatFileSize, localToUtc } from "../../utils/appUtils";
-import { useProjectName } from "../../hooks/useProjects";
+import { useCurrencies, useProjectName } from "../../hooks/useProjects";
import { useDispatch, useSelector } from "react-redux";
import { changeMaster } from "../../slices/localVariablesSlice";
import useMaster, {
@@ -30,6 +30,7 @@ import ErrorPage from "../../pages/ErrorPage";
import Label from "../common/Label";
import EmployeeSearchInput from "../common/EmployeeSearchInput";
import Filelist from "./Filelist";
+import { DEFAULT_CURRENCY } from "../../utils/constants";
const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
const {
@@ -66,7 +67,11 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
error,
isError: isProjectError,
} = useProjectName();
-
+ const {
+ data: currencies,
+ isLoading: currencyLoading,
+ error: currencyError,
+ } = useCurrencies();
const {
PaymentModes,
loading: PaymentModeLoading,
@@ -82,7 +87,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
isLoading: EmpLoading,
isError: isEmployeeError,
} = useEmployeesNameByProject(selectedproject);
-
+
const files = watch("billAttachments");
const onFileChange = async (e) => {
const newFiles = Array.from(e.target.files);
@@ -129,6 +134,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
reader.onerror = (error) => reject(error);
});
const removeFile = (index) => {
+ documentId;
if (expenseToEdit) {
const newFiles = files.map((file, i) => {
if (file.documentId !== index) return file;
@@ -159,6 +165,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
amount: data.amount || "",
noOfPersons: data.noOfPersons || "",
gstNumber: data.gstNumber || "",
+ currencyId: data.currencyId || DEFAULT_CURRENCY,
billAttachments: data.documents
? data.documents.map((doc) => ({
fileName: doc.fileName,
@@ -197,7 +204,9 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
const ExpenseTypeId = watch("expensesCategoryId");
useEffect(() => {
- setExpenseType(ExpenseCategories?.find((type) => type.id === ExpenseTypeId));
+ setExpenseType(
+ ExpenseCategories?.find((type) => type.id === ExpenseTypeId)
+ );
}, [ExpenseTypeId]);
const handleClose = () => {
@@ -297,37 +306,8 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
)}
+
-
+
{file.fileName}
@@ -33,16 +33,17 @@ const Filelist = ({ files, removeFile, expenseToEdit }) => {
+ {/* Delete icon */}
+
+
-
-
- {errors.paidById && (
- {errors.paidById.message}
- )}
- */}
-
-
+
)}
+
+
+ {errors.currencyId && (
+ {errors.currencyId.message}
+ )}
+
@@ -515,7 +521,13 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
{errors.billAttachments.message}
)}
- {files.length > 0 && | ||