fixed Transaction details inside request payment
This commit is contained in:
parent
0dc68eb20d
commit
ecf34b499e
@ -24,7 +24,7 @@ const ExpenseStatusLogs = ({ data }) => {
|
|||||||
id: index + 1,
|
id: index + 1,
|
||||||
title: log.nextStatus?.name || "Status Updated",
|
title: log.nextStatus?.name || "Status Updated",
|
||||||
description: log.nextStatus?.description || "",
|
description: log.nextStatus?.description || "",
|
||||||
timeAgo: moment.utc(log?.updatedAt).local().fromNow(),
|
timeAgo: log.updatedAt,
|
||||||
color: getColorNameFromHex(log.nextStatus?.color) || "primary",
|
color: getColorNameFromHex(log.nextStatus?.color) || "primary",
|
||||||
users: log.updatedBy
|
users: log.updatedBy
|
||||||
? [
|
? [
|
||||||
|
|||||||
@ -90,16 +90,16 @@ export const PaymentRequestActionScheam = (
|
|||||||
.object({
|
.object({
|
||||||
comment: z.string().min(1, { message: "Please leave comment" }),
|
comment: z.string().min(1, { message: "Please leave comment" }),
|
||||||
statusId: z.string().min(1, { message: "Please select a status" }),
|
statusId: z.string().min(1, { message: "Please select a status" }),
|
||||||
paymentRequestId: z.string().nullable().optional(),
|
paidTransactionId: z.string().nullable().optional(),
|
||||||
paidAt: z.string().nullable().optional(),
|
paidAt: z.string().nullable().optional(),
|
||||||
paidById: z.string().nullable().optional(),
|
paidById: z.string().nullable().optional(),
|
||||||
})
|
})
|
||||||
.superRefine((data, ctx) => {
|
.superRefine((data, ctx) => {
|
||||||
if (isTransaction) {
|
if (isTransaction) {
|
||||||
if (!data.paymentRequestId?.trim()) {
|
if (!data.paidTransactionId?.trim()) {
|
||||||
ctx.addIssue({
|
ctx.addIssue({
|
||||||
code: z.ZodIssueCode.custom,
|
code: z.ZodIssueCode.custom,
|
||||||
path: ["paymentRequestId"],
|
path: ["paidTransactionId"],
|
||||||
message: "Reimburse Transaction ID is required",
|
message: "Reimburse Transaction ID is required",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -110,15 +110,7 @@ export const PaymentRequestActionScheam = (
|
|||||||
message: "Transacion Date is required",
|
message: "Transacion 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.paidById) {
|
if (!data.paidById) {
|
||||||
ctx.addIssue({
|
ctx.addIssue({
|
||||||
code: z.ZodIssueCode.custom,
|
code: z.ZodIssueCode.custom,
|
||||||
@ -130,7 +122,7 @@ export const PaymentRequestActionScheam = (
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultActionValues = {
|
export const defaultPaymentRequestActionValues = {
|
||||||
comment: "",
|
comment: "",
|
||||||
statusId: "",
|
statusId: "",
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useMemo, useState } from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import {
|
import {
|
||||||
useActionOnExpense,
|
useActionOnExpense,
|
||||||
useActionOnPaymentRequest,
|
useActionOnPaymentRequest,
|
||||||
@ -28,11 +28,16 @@ import { useNavigate } from "react-router-dom";
|
|||||||
import { usePaymentRequestContext } from "../../pages/PaymentRequest/PaymentRequestPage";
|
import { usePaymentRequestContext } from "../../pages/PaymentRequest/PaymentRequestPage";
|
||||||
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
||||||
import {
|
import {
|
||||||
|
EXPENSE_DRAFT,
|
||||||
EXPENSE_REJECTEDBY,
|
EXPENSE_REJECTEDBY,
|
||||||
PROCESS_EXPENSE,
|
PROCESS_EXPENSE,
|
||||||
REVIEW_EXPENSE,
|
REVIEW_EXPENSE,
|
||||||
} from "../../utils/constants";
|
} from "../../utils/constants";
|
||||||
import Label from "../common/Label";
|
import Label from "../common/Label";
|
||||||
|
import {
|
||||||
|
defaultPaymentRequestActionValues,
|
||||||
|
PaymentRequestActionScheam,
|
||||||
|
} from "./PaymentRequestSchema";
|
||||||
|
|
||||||
const ViewPaymentRequest = ({ requestId }) => {
|
const ViewPaymentRequest = ({ requestId }) => {
|
||||||
const { data, isLoading, isError, error, isFetching } =
|
const { data, isLoading, isError, error, isFetching } =
|
||||||
@ -42,9 +47,10 @@ const ViewPaymentRequest = ({ requestId }) => {
|
|||||||
|
|
||||||
const IsReview = useHasUserPermission(REVIEW_EXPENSE);
|
const IsReview = useHasUserPermission(REVIEW_EXPENSE);
|
||||||
const [imageLoaded, setImageLoaded] = useState({});
|
const [imageLoaded, setImageLoaded] = useState({});
|
||||||
const { setDocumentView } = usePaymentRequestContext();
|
const { setDocumentView, setModalSize } = usePaymentRequestContext();
|
||||||
const ActionSchema =
|
const ActionSchema =
|
||||||
ExpenseActionScheam(IsPaymentProcess, data?.createdAt) ?? z.object({});
|
PaymentRequestActionScheam(IsPaymentProcess, data?.createdAt) ??
|
||||||
|
z.object({});
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
@ -55,7 +61,7 @@ const ViewPaymentRequest = ({ requestId }) => {
|
|||||||
formState: { errors },
|
formState: { errors },
|
||||||
} = useForm({
|
} = useForm({
|
||||||
resolver: zodResolver(ActionSchema),
|
resolver: zodResolver(ActionSchema),
|
||||||
defaultValues: defaultActionValues,
|
defaultValues: defaultPaymentRequestActionValues,
|
||||||
});
|
});
|
||||||
|
|
||||||
const userPermissions = useSelector(
|
const userPermissions = useSelector(
|
||||||
@ -97,7 +103,7 @@ const ViewPaymentRequest = ({ requestId }) => {
|
|||||||
const onSubmit = (formData) => {
|
const onSubmit = (formData) => {
|
||||||
const Payload = {
|
const Payload = {
|
||||||
...formData,
|
...formData,
|
||||||
paidAt: localToUtc(formData.reimburseDate),
|
paidAt: localToUtc(formData.paidAt),
|
||||||
paymentRequestId: data.id,
|
paymentRequestId: data.id,
|
||||||
comment: formData.comment,
|
comment: formData.comment,
|
||||||
};
|
};
|
||||||
@ -111,18 +117,25 @@ const ViewPaymentRequest = ({ requestId }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form className="container-xl px-3" onSubmit={handleSubmit(onSubmit)}>
|
<form className="container px-3" onSubmit={handleSubmit(onSubmit)}>
|
||||||
<div className="col-12 mb-1">
|
<div className="col-12 mb-2 text-center ">
|
||||||
<h5 className="fw-semibold m-0">Payment Request Details</h5>
|
<h5 className="fw-semibold m-0">Payment Request Details</h5>
|
||||||
<hr />
|
|
||||||
</div>
|
</div>
|
||||||
<div className="row mb-1">
|
<div className="row text-start">
|
||||||
<div className="col-12 col-sm-6 col-md-8">
|
<div className=" col-sm-12 col-md-7 border-none border-md-end">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-12 text-start fw-semibold mb-2">
|
<div className="col-12 d-flex justify-content-between text-start fw-semibold mb-2">
|
||||||
{data?.paymentRequestUID}
|
{data?.paymentRequestUID}
|
||||||
|
|
||||||
|
<span
|
||||||
|
className={`badge bg-label-${
|
||||||
|
getColorNameFromHex(data?.expenseStatus?.color) || "secondary"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{data?.expenseStatus?.name}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-12 mb-3">
|
||||||
<div className="d-block d-md-flex align-items-center">
|
<div className="d-block d-md-flex align-items-center">
|
||||||
<label
|
<label
|
||||||
className="form-label me-2 mb-0 fw-semibold text-start"
|
className="form-label me-2 mb-0 fw-semibold text-start"
|
||||||
@ -134,7 +147,7 @@ const ViewPaymentRequest = ({ requestId }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-12 mb-3">
|
||||||
<div className="d-flex">
|
<div className="d-flex">
|
||||||
<label
|
<label
|
||||||
className="form-label me-2 mb-0 fw-semibold text-start"
|
className="form-label me-2 mb-0 fw-semibold text-start"
|
||||||
@ -147,7 +160,7 @@ const ViewPaymentRequest = ({ requestId }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-12 mb-3">
|
||||||
<div className="d-flex">
|
<div className="d-flex">
|
||||||
<label
|
<label
|
||||||
className="form-label me-2 mb-0 fw-semibold text-start"
|
className="form-label me-2 mb-0 fw-semibold text-start"
|
||||||
@ -160,7 +173,7 @@ const ViewPaymentRequest = ({ requestId }) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Row 2 */}
|
{/* Row 2 */}
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-12 mb-3">
|
||||||
<div className="d-flex">
|
<div className="d-flex">
|
||||||
<label
|
<label
|
||||||
className="form-label me-2 mb-0 fw-semibold text-start"
|
className="form-label me-2 mb-0 fw-semibold text-start"
|
||||||
@ -171,7 +184,7 @@ const ViewPaymentRequest = ({ requestId }) => {
|
|||||||
<div className="text-muted">{data?.payee}</div>
|
<div className="text-muted">{data?.payee}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-1 mb-3">
|
||||||
<div className="d-flex">
|
<div className="d-flex">
|
||||||
<label
|
<label
|
||||||
className="form-label me-2 mb-0 fw-semibold text-start"
|
className="form-label me-2 mb-0 fw-semibold text-start"
|
||||||
@ -185,20 +198,8 @@ const ViewPaymentRequest = ({ requestId }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Row 3 */}
|
|
||||||
{/* <div className="col-md-6 mb-3">
|
|
||||||
<div className="d-flex">
|
|
||||||
<label
|
|
||||||
className="form-label me-2 mb-0 fw-semibold text-start"
|
|
||||||
style={{ minWidth: "130px" }}
|
|
||||||
>
|
|
||||||
Payment Mode :
|
|
||||||
</label>
|
|
||||||
<div className="text-muted">{data?.paymentMode?.name}</div>
|
|
||||||
</div>
|
|
||||||
</div> */}
|
|
||||||
{data?.gstNumber && (
|
{data?.gstNumber && (
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-12 mb-3">
|
||||||
<div className="d-flex">
|
<div className="d-flex">
|
||||||
<label
|
<label
|
||||||
className="form-label me-2 mb-0 fw-semibold text-start"
|
className="form-label me-2 mb-0 fw-semibold text-start"
|
||||||
@ -212,25 +213,8 @@ const ViewPaymentRequest = ({ requestId }) => {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Row 4 */}
|
{/* Row 4 */}
|
||||||
<div className="col-md-6 mb-3">
|
|
||||||
<div className="d-flex">
|
<div className="col-md-12 mb-3">
|
||||||
<label
|
|
||||||
className="form-label me-2 mb-0 fw-semibold text-start"
|
|
||||||
style={{ minWidth: "130px" }}
|
|
||||||
>
|
|
||||||
Status :
|
|
||||||
</label>
|
|
||||||
<span
|
|
||||||
className={`badge bg-label-${
|
|
||||||
getColorNameFromHex(data?.expenseStatus?.color) ||
|
|
||||||
"secondary"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{data?.expenseStatus?.name}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="col-md-6 mb-3">
|
|
||||||
<div className="d-flex">
|
<div className="d-flex">
|
||||||
<label
|
<label
|
||||||
className="form-label me-2 mb-0 fw-semibold text-start"
|
className="form-label me-2 mb-0 fw-semibold text-start"
|
||||||
@ -244,18 +228,7 @@ const ViewPaymentRequest = ({ requestId }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-12 mb-3">
|
||||||
<div className="d-flex">
|
|
||||||
<label
|
|
||||||
className="form-label me-2 mb-0 fw-semibold text-start"
|
|
||||||
style={{ minWidth: "130px" }}
|
|
||||||
>
|
|
||||||
Project :
|
|
||||||
</label>
|
|
||||||
<div className="text-muted">{data?.project?.name}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="col-md-6 mb-3">
|
|
||||||
<div className="d-flex">
|
<div className="d-flex">
|
||||||
<label
|
<label
|
||||||
className="form-label me-2 mb-0 fw-semibold text-start"
|
className="form-label me-2 mb-0 fw-semibold text-start"
|
||||||
@ -271,7 +244,7 @@ const ViewPaymentRequest = ({ requestId }) => {
|
|||||||
|
|
||||||
{/* Row 6 */}
|
{/* Row 6 */}
|
||||||
{data?.createdBy && (
|
{data?.createdBy && (
|
||||||
<div className="col-md-6 text-start">
|
<div className="col-md-12 text-start">
|
||||||
<div className="d-flex align-items-center">
|
<div className="d-flex align-items-center">
|
||||||
<label
|
<label
|
||||||
className="form-label me-2 mb-0 fw-semibold"
|
className="form-label me-2 mb-0 fw-semibold"
|
||||||
@ -296,7 +269,7 @@ const ViewPaymentRequest = ({ requestId }) => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{data?.paidBy && (
|
{data?.paidBy && (
|
||||||
<div className="col-md-6 text-start">
|
<div className="col-md-12 text-start">
|
||||||
<div className="d-flex align-items-center">
|
<div className="d-flex align-items-center">
|
||||||
<label
|
<label
|
||||||
className="form-label me-2 mb-0 fw-semibold"
|
className="form-label me-2 mb-0 fw-semibold"
|
||||||
@ -496,7 +469,11 @@ const ViewPaymentRequest = ({ requestId }) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-12 col-sm-6 col-md-4">
|
<div className=" col-sm-12 my-2 my-md-0 border-top border-md-none col-md-5">
|
||||||
|
<div className="d-flex my-2">
|
||||||
|
<i className="bx bx-time-five me-2 "></i>{" "}
|
||||||
|
<p className="fw-medium">TimeLine</p>
|
||||||
|
</div>
|
||||||
<ExpenseStatusLogs data={data} />
|
<ExpenseStatusLogs data={data} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import Avatar from "./Avatar";
|
import Avatar from "./Avatar";
|
||||||
|
import Tooltip from "./Tooltip";
|
||||||
|
import { formatUTCToLocalTime } from "../../utils/dateUtils";
|
||||||
|
import moment from "moment";
|
||||||
|
|
||||||
const Timeline = ({ items = [], transparent = true }) => {
|
const Timeline = ({ items = [], transparent = true }) => {
|
||||||
return (
|
return (
|
||||||
@ -8,7 +11,7 @@ const Timeline = ({ items = [], transparent = true }) => {
|
|||||||
transparent ? "timeline-transparent text-start" : ""
|
transparent ? "timeline-transparent text-start" : ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{items.map((item) => (
|
{items && items?.map((item) => (
|
||||||
<li
|
<li
|
||||||
key={item.id}
|
key={item.id}
|
||||||
className={`timeline-item ${
|
className={`timeline-item ${
|
||||||
@ -24,7 +27,7 @@ const Timeline = ({ items = [], transparent = true }) => {
|
|||||||
<div className="timeline-event">
|
<div className="timeline-event">
|
||||||
<div className="timeline-header mb-3 d-flex justify-content-between">
|
<div className="timeline-header mb-3 d-flex justify-content-between">
|
||||||
<h6 className="mb-0 text-body">{item.title}</h6>
|
<h6 className="mb-0 text-body">{item.title}</h6>
|
||||||
<small className="text-body-secondary">{item.timeAgo}</small>
|
<small className="text-body-secondary"><Tooltip text={formatUTCToLocalTime(item.timeAgo,true)}>{moment.utc(item.timeAgo).local().fromNow()}</Tooltip></small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{item.description && <p className="mb-2">{item.description}</p>}
|
{item.description && <p className="mb-2">{item.description}</p>}
|
||||||
@ -64,7 +67,8 @@ const Timeline = ({ items = [], transparent = true }) => {
|
|||||||
height="32"
|
height="32"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Avatar size="xs"
|
<Avatar
|
||||||
|
size="xs"
|
||||||
firstName={user.firstName}
|
firstName={user.firstName}
|
||||||
lastName={user.lastName}
|
lastName={user.lastName}
|
||||||
/>
|
/>
|
||||||
@ -84,6 +88,16 @@ const Timeline = ({ items = [], transparent = true }) => {
|
|||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
|
{!items || items.length == 0 && (
|
||||||
|
<li
|
||||||
|
className={`timeline-item text-center ${
|
||||||
|
transparent ? "timeline-item-transparent" : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
Not action yet.
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
</ul>
|
</ul>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -14,7 +14,7 @@ export const PaymentRequestContext = createContext();
|
|||||||
export const usePaymentRequestContext = () => {
|
export const usePaymentRequestContext = () => {
|
||||||
const context = useContext(PaymentRequestContext);
|
const context = useContext(PaymentRequestContext);
|
||||||
if (!context) {
|
if (!context) {
|
||||||
throw new Error("usePaymentRequestContext must be used within an ExpenseProvider");
|
throw new Error("usePaymentRequestContext must be used within an RequestPaymentProvider");
|
||||||
}
|
}
|
||||||
return context;
|
return context;
|
||||||
};
|
};
|
||||||
@ -30,12 +30,14 @@ const PaymentRequestPage = () => {
|
|||||||
IsOpen: false,
|
IsOpen: false,
|
||||||
Image: null,
|
Image: null,
|
||||||
});
|
});
|
||||||
|
const [modalSize,setModalSize] = useState("md")
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
|
|
||||||
const contextValue = {
|
const contextValue = {
|
||||||
setManageRequest,
|
setManageRequest,
|
||||||
setVieRequest,
|
setVieRequest,
|
||||||
setDocumentView
|
setDocumentView,
|
||||||
|
setModalSize
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -125,7 +127,7 @@ const PaymentRequestPage = () => {
|
|||||||
{ViewRequest.view && (
|
{ViewRequest.view && (
|
||||||
<GlobalModel
|
<GlobalModel
|
||||||
isOpen
|
isOpen
|
||||||
|
size="xl"
|
||||||
modalType="top"
|
modalType="top"
|
||||||
closeModal={() => setVieRequest({ requestId: null, view: false })}
|
closeModal={() => setVieRequest({ requestId: null, view: false })}
|
||||||
>
|
>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user