Skip to content

Commit 1a365e9

Browse files
committed
#1611 added deny rr to dropdown
1 parent 01f2af0 commit 1a365e9

5 files changed

Lines changed: 82 additions & 1 deletion

File tree

src/frontend/src/apis/finance.api.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,16 @@ export const approveReimbursementRequest = (id: string) => {
158158
return axios.post(apiUrls.financeApproveReimbursementRequest(id));
159159
};
160160

161+
/**
162+
* Deny Reimbursement Request
163+
*
164+
* @param id of the reimbursement request being denied by finance
165+
* @returns the reimbursement request with the given id
166+
*/
167+
export const denyReimbursementRequest = (id: string) => {
168+
return axios.post(apiUrls.financeDenyReimbursementRequest(id));
169+
};
170+
161171
/**
162172
* Downloads a given fileId from google drive into a blob
163173
*

src/frontend/src/hooks/finance.hooks.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
approveReimbursementRequest,
88
createReimbursementRequest,
99
deleteReimbursementRequest,
10+
denyReimbursementRequest,
1011
downloadBlobsToPdf,
1112
downloadGoogleImage,
1213
editReimbursementRequest,
@@ -260,6 +261,28 @@ export const useApproveReimbursementRequest = (id: string) => {
260261
);
261262
};
262263

264+
/**
265+
* Custom react hook to deny a reimbursement request for the finance team
266+
*
267+
* @param id id of the reimbursement request to deny
268+
* @returns the denied reimbursement request
269+
*/
270+
export const useDenyReimbursementRequest = (id: string) => {
271+
const queryClient = useQueryClient();
272+
return useMutation<ReimbursementStatus, Error>(
273+
['reimbursement-requests', 'edit'],
274+
async () => {
275+
const { data } = await denyReimbursementRequest(id);
276+
return data;
277+
},
278+
{
279+
onSuccess: () => {
280+
queryClient.invalidateQueries(['reimbursement-requests', id]);
281+
}
282+
}
283+
);
284+
};
285+
263286
/**
264287
* Custom react hook to download images from google drive into a pdf
265288
*

src/frontend/src/pages/FinancePage/ReimbursementRequestDetailPage/ReimbursementRequestDetailsView.tsx

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import { expenseTypePipe } from '../../../utils/pipes';
77
import { Edit } from '@mui/icons-material';
88
import CheckIcon from '@mui/icons-material/Check';
9+
import CloseIcon from '@mui/icons-material/Close';
910
import ConfirmationNumberIcon from '@mui/icons-material/ConfirmationNumber';
1011
import DeleteIcon from '@mui/icons-material/Delete';
1112
import LocalShippingIcon from '@mui/icons-material/LocalShipping';
@@ -18,7 +19,11 @@ import ActionsMenu, { ButtonInfo } from '../../../components/ActionsMenu';
1819
import NERModal from '../../../components/NERModal';
1920
import PageLayout from '../../../components/PageLayout';
2021
import VerticalDetailDisplay from '../../../components/VerticalDetailDisplay';
21-
import { useDeleteReimbursementRequest, useMarkReimbursementRequestAsDelivered } from '../../../hooks/finance.hooks';
22+
import {
23+
useDeleteReimbursementRequest,
24+
useDenyReimbursementRequest,
25+
useMarkReimbursementRequestAsDelivered
26+
} from '../../../hooks/finance.hooks';
2227
import { useToast } from '../../../hooks/toasts.hooks';
2328
import { useCurrentUser } from '../../../hooks/users.hooks';
2429
import {
@@ -32,6 +37,7 @@ import {
3237
import {
3338
imagePreviewUrl,
3439
isReimbursementRequestAdvisorApproved,
40+
isReimbursementRequestReimbursed,
3541
isReimbursementRequestSaboSubmitted
3642
} from '../../../utils/reimbursement-request.utils';
3743
import { routes } from '../../../utils/routes';
@@ -51,11 +57,13 @@ const ReimbursementRequestDetailsView: React.FC<ReimbursementRequestDetailsViewP
5157
const [addSaboNumberModalShow, setAddSaboNumberModalShow] = useState<boolean>(false);
5258
const toast = useToast();
5359
const [showDeleteModal, setShowDeleteModal] = useState(false);
60+
const [showDenyModal, setShowDenyModal] = useState(false);
5461
const [showMarkDelivered, setShowMarkDelivered] = useState(false);
5562
const [showSubmitToSaboModal, setShowSubmitToSaboModal] = useState(false);
5663
const { mutateAsync: deleteReimbursementRequest } = useDeleteReimbursementRequest(
5764
reimbursementRequest.reimbursementRequestId
5865
);
66+
const { mutateAsync: denyReimbursementRequest } = useDenyReimbursementRequest(reimbursementRequest.reimbursementRequestId);
5967
const { mutateAsync: markDelivered } = useMarkReimbursementRequestAsDelivered(reimbursementRequest.reimbursementRequestId);
6068

6169
const handleDelete = () => {
@@ -69,6 +77,16 @@ const ReimbursementRequestDetailsView: React.FC<ReimbursementRequestDetailsViewP
6977
}
7078
};
7179

80+
const handleDeny = () => {
81+
try {
82+
denyReimbursementRequest();
83+
} catch (e: unknown) {
84+
if (e instanceof Error) {
85+
toast.error(e.message, 3000);
86+
}
87+
}
88+
};
89+
7290
const handleMarkDelivered = () => {
7391
try {
7492
markDelivered();
@@ -95,6 +113,21 @@ const ReimbursementRequestDetailsView: React.FC<ReimbursementRequestDetailsViewP
95113
);
96114
};
97115

116+
const DenyModal = () => {
117+
return (
118+
<NERModal
119+
open={showDenyModal}
120+
onHide={() => setShowDenyModal(false)}
121+
title="Warning!"
122+
cancelText="No"
123+
submitText="Yes"
124+
onSubmit={handleDeny}
125+
>
126+
<Typography>Are you sure you want to deny this reimbursement request?</Typography>
127+
</NERModal>
128+
);
129+
};
130+
98131
const MarkDeliveredModal = () => (
99132
<NERModal
100133
open={showMarkDelivered}
@@ -219,6 +252,12 @@ const ReimbursementRequestDetailsView: React.FC<ReimbursementRequestDetailsViewP
219252
onClick: () => setShowSubmitToSaboModal(true),
220253
icon: <CheckIcon />,
221254
disabled: !user.isFinance || isReimbursementRequestSaboSubmitted(reimbursementRequest)
255+
},
256+
{
257+
title: 'Deny',
258+
onClick: () => setShowDenyModal(true),
259+
icon: <CloseIcon />,
260+
disabled: !user.isFinance || isReimbursementRequestReimbursed(reimbursementRequest)
222261
}
223262
];
224263

@@ -234,6 +273,7 @@ const ReimbursementRequestDetailsView: React.FC<ReimbursementRequestDetailsViewP
234273
headerRight={<ActionsMenu buttons={buttons} />}
235274
>
236275
<DeleteModal />
276+
<DenyModal />
237277
<MarkDeliveredModal />
238278
<SubmitToSaboModal
239279
open={showSubmitToSaboModal}

src/frontend/src/utils/reimbursement-request.utils.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ export const isReimbursementRequestSaboSubmitted = (reimbursementRequest: Reimbu
8181
.includes(ReimbursementStatusType.SABO_SUBMITTED);
8282
};
8383

84+
export const isReimbursementRequestReimbursed = (reimbursementRequest: ReimbursementRequest) => {
85+
return reimbursementRequest.reimbursementStatuses
86+
.map((status) => status.type)
87+
.includes(ReimbursementStatusType.REIMBURSED);
88+
};
89+
8490
export const getReimbursementRequestDateSubmittedToSabo = (reimbursementRequest: ReimbursementRequest) => {
8591
const saboStatus = reimbursementRequest.reimbursementStatuses.find(
8692
(status) => status.type === ReimbursementStatusType.SABO_SUBMITTED

src/frontend/src/utils/urls.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ const financeSetSaboNumber = (id: string) => `${financeEndpoints()}/${id}/set-sa
9999
const financeDeleteReimbursement = (id: string) => `${financeEndpoints()}/${id}/delete`;
100100
const financeMarkAsDelivered = (id: string) => `${financeEndpoints()}/${id}/delivered`;
101101
const financeApproveReimbursementRequest = (id: string) => `${financeEndpoints()}/${id}/approve`;
102+
const financeDenyReimbursementRequest = (id: string) => `${financeEndpoints()}/${id}/deny`;
102103
const financeGetPendingAdvisorList = () => `${financeEndpoints()}/pending-advisor/list`;
103104
const financeSendPendingAdvisorList = () => `${financeEndpoints()}/pending-advisor/send`;
104105
const financeEditExpenseType = (expenseId: string) => `${financeEndpoints()}/${expenseId}/expense-types/edit`;
@@ -184,6 +185,7 @@ export const apiUrls = {
184185
financeDeleteReimbursement,
185186
financeMarkAsDelivered,
186187
financeApproveReimbursementRequest,
188+
financeDenyReimbursementRequest,
187189
financeGetPendingAdvisorList,
188190
financeSendPendingAdvisorList,
189191
financeEditExpenseType,

0 commit comments

Comments
 (0)