user can not select reimburseDate before transaction date
This commit is contained in:
parent
28fb1c9387
commit
e0f130e6a6
@ -57,7 +57,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
|
||||
(store) => store.localVariables.projectId
|
||||
);
|
||||
const { projectNames, loading: projectLoading, error } = useProjectName();
|
||||
|
||||
debugger
|
||||
const {
|
||||
PaymentModes,
|
||||
loading: PaymentModeLoading,
|
||||
|
@ -12,7 +12,11 @@ import { useExpenseContext } from "../../pages/Expense/ExpensePage";
|
||||
import { getColorNameFromHex } from "../../utils/appUtils";
|
||||
import { ExpenseDetailsSkeleton } from "./ExpenseSkeleton";
|
||||
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
||||
import { EXPENSE_REJECTEDBY, PROCESS_EXPENSE, REVIEW_EXPENSE } from "../../utils/constants";
|
||||
import {
|
||||
EXPENSE_REJECTEDBY,
|
||||
PROCESS_EXPENSE,
|
||||
REVIEW_EXPENSE,
|
||||
} from "../../utils/constants";
|
||||
import { useProfile } from "../../hooks/useProfile";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
@ -69,22 +73,25 @@ const ViewExpense = ({ ExpenseId }) => {
|
||||
});
|
||||
}, [data, userPermissions]);
|
||||
|
||||
const IsRejectedExpense = useMemo(()=>{
|
||||
return EXPENSE_REJECTEDBY.includes(data?.status?.id)
|
||||
},[data])
|
||||
const IsRejectedExpense = useMemo(() => {
|
||||
return EXPENSE_REJECTEDBY.includes(data?.status?.id);
|
||||
}, [data]);
|
||||
|
||||
const isCreatedBy = useMemo(() => {
|
||||
return data?.createdBy.id === CurrentUser?.id;
|
||||
}, [data, CurrentUser]);
|
||||
return data?.createdBy.id === CurrentUser?.id;
|
||||
}, [data, CurrentUser]);
|
||||
|
||||
const { mutate: MakeAction,isPending } = useActionOnExpense(() => {
|
||||
const { mutate: MakeAction, isPending } = useActionOnExpense(() => {
|
||||
setClickedStatusId(null);
|
||||
reset()});
|
||||
reset();
|
||||
});
|
||||
|
||||
const onSubmit = (formData) => {
|
||||
const Payload = {
|
||||
...formData,
|
||||
reimburseDate:moment.utc(formData.reimburseDate, "DD-MM-YYYY").toISOString(),
|
||||
reimburseDate: moment
|
||||
.utc(formData.reimburseDate, "DD-MM-YYYY")
|
||||
.toISOString(),
|
||||
expenseId: ExpenseId,
|
||||
comment: formData.comment,
|
||||
};
|
||||
@ -340,42 +347,51 @@ const ViewExpense = ({ ExpenseId }) => {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{data.expensesReimburse && (<div className="row text-start">
|
||||
<div className="col-md-6 mb-3">
|
||||
<strong>Transaction ID :</strong> {data.expensesReimburse.reimburseTransactionId || "N/A"}
|
||||
</div>
|
||||
<div className="col-md-6 mb-3">
|
||||
<strong>Reimburse Date :</strong>{" "}
|
||||
{ moment(data.expensesReimburse.reimburseDate).format("DD-MM-YYYY") }
|
||||
</div>
|
||||
{data.expensesReimburse && (
|
||||
<div className="row text-start">
|
||||
<div className="col-md-6 mb-3">
|
||||
<label className="form-label me-2 mb-0 fw-semibold">
|
||||
Transaction ID :
|
||||
</label>
|
||||
{data.expensesReimburse.reimburseTransactionId || "N/A"}
|
||||
</div>
|
||||
<div className="col-md-6 mb-3">
|
||||
<label className="form-label me-2 mb-0 fw-semibold">
|
||||
Reimburse Date :
|
||||
</label>
|
||||
{formatUTCToLocalTime(data.expensesReimburse.reimburseDate)}
|
||||
</div>
|
||||
|
||||
{data.expensesReimburse && (
|
||||
<>
|
||||
<div className="col-md-6 mb-3 d-flex align-items-center">
|
||||
<strong className="me-2">Reimburse By :</strong>
|
||||
<Avatar
|
||||
size="xs"
|
||||
classAvatar="m-0 me-1"
|
||||
firstName={data?.expensesReimburse?.reimburseBy?.firstName}
|
||||
lastName={data?.expensesReimburse?.reimburseBy?.lastName}
|
||||
/>
|
||||
<span className="text-muted">
|
||||
{`${data?.expensesReimburse?.reimburseBy?.firstName} ${data?.expensesReimburse?.reimburseBy?.lastName}`.trim()}
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{data.expensesReimburse && (
|
||||
<>
|
||||
<div className="col-md-6 mb-3 d-flex align-items-center">
|
||||
<label className="form-label me-2 mb-0 fw-semibold">
|
||||
Reimburse By :
|
||||
</label>
|
||||
<Avatar
|
||||
size="xs"
|
||||
classAvatar="m-0 me-1"
|
||||
firstName={data?.expensesReimburse?.reimburseBy?.firstName}
|
||||
lastName={data?.expensesReimburse?.reimburseBy?.lastName}
|
||||
/>
|
||||
<span className="text-muted">
|
||||
{`${data?.expensesReimburse?.reimburseBy?.firstName} ${data?.expensesReimburse?.reimburseBy?.lastName}`.trim()}
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
<div className="col-md-6 mb-3">
|
||||
<strong>Note :</strong> {data.expensesReimburse.reimburseNote}
|
||||
</div>
|
||||
|
||||
</div>)}
|
||||
|
||||
|
||||
<div className="col-md-6 mb-3">
|
||||
<label className="form-label me-2 mb-0 fw-semibold"> Note :</label>{" "}
|
||||
{data.expensesReimburse.reimburseNote}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="text-start">
|
||||
<label className="form-label me-2 mb-0 fw-semibold">Description :</label>
|
||||
<label className="form-label me-2 mb-0 fw-semibold">
|
||||
Description :
|
||||
</label>
|
||||
<div className="text-muted">{data?.description}</div>
|
||||
</div>
|
||||
<div className="col-12 my-2 text-start">
|
||||
@ -443,7 +459,7 @@ const ViewExpense = ({ ExpenseId }) => {
|
||||
|
||||
{Array.isArray(data?.nextStatus) && data.nextStatus.length > 0 && (
|
||||
<>
|
||||
{(IsPaymentProcess && nextStatusWithPermission?.length > 0) && (
|
||||
{IsPaymentProcess && nextStatusWithPermission?.length > 0 && (
|
||||
<div className="row">
|
||||
<div className="col-12 col-md-6 text-start">
|
||||
<label className="form-label">Transaction Id </label>
|
||||
@ -460,7 +476,11 @@ const ViewExpense = ({ ExpenseId }) => {
|
||||
</div>
|
||||
<div className="col-12 col-md-6 text-start">
|
||||
<label className="form-label">Transaction Date </label>
|
||||
<DatePicker name="reimburseDate" control={control} />
|
||||
<DatePicker
|
||||
name="reimburseDate"
|
||||
control={control}
|
||||
minDate={data?.transactionDate}
|
||||
/>
|
||||
{errors.reimburseDate && (
|
||||
<small className="danger-text">
|
||||
{errors.reimburseDate.message}
|
||||
@ -477,49 +497,47 @@ const ViewExpense = ({ ExpenseId }) => {
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="col-12 mb-3 text-start">
|
||||
{(
|
||||
(nextStatusWithPermission.length > 0 && !IsRejectedExpense) ||
|
||||
(IsRejectedExpense && isCreatedBy)
|
||||
) && (
|
||||
<>
|
||||
<label className="form-label me-2 mb-0">Comment:</label>
|
||||
<textarea
|
||||
className="form-control form-control-sm"
|
||||
{...register("comment")}
|
||||
rows="2"
|
||||
/>
|
||||
{errors.comment && (
|
||||
<small className="danger-text">
|
||||
{errors.comment.message}
|
||||
</small>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
{(nextStatusWithPermission?.length > 0 && (!IsRejectedExpense || isCreatedBy)) && (
|
||||
<div className="text-center flex-wrap gap-2 my-2">
|
||||
{nextStatusWithPermission.map((status, index) => (
|
||||
<button
|
||||
key={status.id || index}
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setClickedStatusId(status.id);
|
||||
setValue("statusId", status.id);
|
||||
handleSubmit(onSubmit)();
|
||||
}}
|
||||
disabled={isPending}
|
||||
className="btn btn-primary btn-sm cursor-pointer mx-2 border-0"
|
||||
>
|
||||
{isPending && clickedStatusId === status.id
|
||||
? "Please Wait..."
|
||||
: status.displayName || status.name}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="col-12 mb-3 text-start">
|
||||
{((nextStatusWithPermission.length > 0 && !IsRejectedExpense) ||
|
||||
(IsRejectedExpense && isCreatedBy)) && (
|
||||
<>
|
||||
<label className="form-label me-2 mb-0">Comment:</label>
|
||||
<textarea
|
||||
className="form-control form-control-sm"
|
||||
{...register("comment")}
|
||||
rows="2"
|
||||
/>
|
||||
{errors.comment && (
|
||||
<small className="danger-text">
|
||||
{errors.comment.message}
|
||||
</small>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
{nextStatusWithPermission?.length > 0 &&
|
||||
(!IsRejectedExpense || isCreatedBy) && (
|
||||
<div className="text-center flex-wrap gap-2 my-2">
|
||||
{nextStatusWithPermission.map((status, index) => (
|
||||
<button
|
||||
key={status.id || index}
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setClickedStatusId(status.id);
|
||||
setValue("statusId", status.id);
|
||||
handleSubmit(onSubmit)();
|
||||
}}
|
||||
disabled={isPending}
|
||||
className="btn btn-primary btn-sm cursor-pointer mx-2 border-0"
|
||||
>
|
||||
{isPending && clickedStatusId === status.id
|
||||
? "Please Wait..."
|
||||
: status.displayName || status.name}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</form>
|
||||
|
@ -9,6 +9,7 @@ const DatePicker = ({
|
||||
className = "",
|
||||
allowText = false,
|
||||
maxDate=new Date(),
|
||||
minDate,
|
||||
...rest
|
||||
}) => {
|
||||
const inputRef = useRef(null);
|
||||
@ -29,6 +30,7 @@ const DatePicker = ({
|
||||
? flatpickr.parseDate(value, "Y-m-d")
|
||||
: null,
|
||||
maxDate:maxDate,
|
||||
minDate:new Date(minDate?.split("T")[0]) ?? undefined,
|
||||
onChange: function (selectedDates, dateStr) {
|
||||
onChange(dateStr);
|
||||
},
|
||||
|
@ -45,7 +45,7 @@ const EmployeeSearchInput = ({ control, name, projectId }) => {
|
||||
onChange={(e) => {
|
||||
setSearch(e.target.value);
|
||||
setShowDropdown(true);
|
||||
onChange(""); // Clear previous selection
|
||||
onChange("");
|
||||
}}
|
||||
onFocus={() => {
|
||||
if (search) setShowDropdown(true);
|
||||
|
Loading…
x
Reference in New Issue
Block a user