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