Skip to content

Commit d37c9cb

Browse files
authored
Merge pull request #3984 from Northeastern-Electric-Racing/#3893-add-create-rr-button-for-unlinked-materials
#3893: added create RR button for materials wout linked RR
2 parents ed869ad + bcd9b18 commit d37c9cb

2 files changed

Lines changed: 80 additions & 11 deletions

File tree

src/frontend/src/pages/FinancePage/CreateReimbursementRequest.tsx

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,23 @@
22
* This file is part of NER's FinishLine and licensed under GNU AGPLv3.
33
* See the LICENSE file in the repository root folder for details.
44
*/
5-
import { useHistory } from 'react-router-dom';
5+
import { useHistory, useLocation } from 'react-router-dom';
6+
import { WbsNumber, CreateRefundSourceArgs, ReimbursementReceiptUploadArgs } from 'shared';
7+
import { ReimbursementRequestFormInput } from './ReimbursementRequestForm/ReimbursementRequestForm';
68
import PageLayout from '../../components/PageLayout';
79
import { useCreateReimbursementRequest, useUploadManyReceipts } from '../../hooks/finance.hooks';
810
import { routes } from '../../utils/routes';
911
import ReimbursementRequestForm, {
1012
ReimbursementRequestDataSubmission
1113
} from './ReimbursementRequestForm/ReimbursementRequestForm';
1214

15+
type CreateRRPrefillState = {
16+
projectWbsNum: WbsNumber;
17+
materialId: string;
18+
materialName: string;
19+
prefillCost?: number;
20+
};
21+
1322
const CreateReimbursementRequestPage: React.FC = () => {
1423
const { isLoading: createReimbursementRequestIsLoading, mutateAsync: createReimbursementRequest } =
1524
useCreateReimbursementRequest();
@@ -31,6 +40,31 @@ const CreateReimbursementRequestPage: React.FC = () => {
3140

3241
const isSubmitting = createReimbursementRequestIsLoading || receiptsIsLoading;
3342

43+
// for pre-filling the form when user clicks "Create Reimbursement Request" from a material in the BOM table
44+
const location = useLocation<CreateRRPrefillState | undefined>();
45+
const prefill = location.state;
46+
47+
const defaultValues: ReimbursementRequestFormInput | undefined =
48+
prefill?.projectWbsNum && prefill?.materialId
49+
? {
50+
vendorId: '',
51+
dateOfExpense: undefined,
52+
accountCodeId: '',
53+
indexCodeId: '',
54+
secondaryAccount: undefined,
55+
receiptFiles: [] as ReimbursementReceiptUploadArgs[],
56+
reimbursementProducts: [
57+
{
58+
name: prefill.materialName,
59+
materialId: prefill.materialId,
60+
reason: prefill.projectWbsNum,
61+
cost: prefill.prefillCost ?? 0,
62+
refundSources: [] as CreateRefundSourceArgs[]
63+
}
64+
]
65+
}
66+
: undefined;
67+
3468
return (
3569
<PageLayout
3670
title="Create Reimbursement Request"
@@ -41,6 +75,7 @@ const CreateReimbursementRequestPage: React.FC = () => {
4175
submitText="Submit"
4276
submitData={onSubmit}
4377
isSubmitting={isSubmitting}
78+
defaultValues={defaultValues}
4479
/>
4580
</PageLayout>
4681
);

src/frontend/src/pages/ProjectDetailPage/ProjectViewContainer/BOM/BOMTableWrapper.tsx

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { useToast } from '../../../../hooks/toasts.hooks';
1111
import { useAssignMaterialToAssembly, useDeleteAssembly, useDeleteMaterial } from '../../../../hooks/bom.hooks';
1212
import LoadingIndicator from '../../../../components/LoadingIndicator';
1313
import EditMaterialModal from './MaterialForm/EditMaterialModal';
14-
import { Link, Typography } from '@mui/material';
14+
import { Button, Link, Typography } from '@mui/material';
1515
import { bomBaseColDef } from '../../../../utils/bom.utils';
1616
import NERModal from '../../../../components/NERModal';
1717
import { renderStatusBOM } from './BOMTableCustomCells';
@@ -217,20 +217,54 @@ const BOMTableWrapper: React.FC<BOMTableWrapperProps> = ({
217217
hide: hideColumn[0],
218218
renderCell: (params) => {
219219
const material = materials.find((m) => m.materialId === params.row.materialId);
220-
const reimbursementRequest = material?.reimbursementRequest;
220+
if (!material) return null;
221221

222-
if (!reimbursementRequest) return null;
222+
const { reimbursementRequest } = material;
223+
224+
// case 1 (if reimbursement request exists): link to the reimbursement request page
225+
if (reimbursementRequest) {
226+
return (
227+
<Link
228+
component={RouterLink}
229+
to={`${routes.REIMBURSEMENT_REQUESTS}/view/${reimbursementRequest.reimbursementRequestId}`}
230+
underline="hover"
231+
sx={{ color: '#dd514c', fontWeight: 'bold', cursor: 'pointer' }}
232+
onClick={(e) => e.stopPropagation()}
233+
>
234+
{reimbursementRequest.identifier}
235+
</Link>
236+
);
237+
}
238+
239+
// case 2 (if reimbursement request does not exist): link to the create reimbursement request page with pre-filled info
240+
const { quantity, price } = material;
241+
242+
const prefillCost = quantity != null && price != null ? (Number(quantity) * Number(price)) / 100 : undefined;
223243

224244
return (
225-
<Link
245+
<Button
226246
component={RouterLink}
227-
to={`${routes.REIMBURSEMENT_REQUESTS}/view/${reimbursementRequest.reimbursementRequestId}`}
228-
underline="hover"
229-
sx={{ color: '#dd514c', fontWeight: 'bold', cursor: 'pointer' }}
230-
onClick={(e) => e.stopPropagation()}
247+
to={{
248+
pathname: routes.NEW_REIMBURSEMENT_REQUEST,
249+
state: {
250+
projectWbsNum: project.wbsNum,
251+
materialId: material.materialId,
252+
materialName: material.name,
253+
prefillCost
254+
}
255+
}}
256+
variant="contained"
257+
size="small"
258+
onClick={(e: React.MouseEvent<HTMLElement>) => e.stopPropagation()}
259+
sx={{
260+
backgroundColor: '#dd514c',
261+
textTransform: 'none',
262+
fontWeight: 600,
263+
'&:hover': { backgroundColor: '#c7443f' }
264+
}}
231265
>
232-
{reimbursementRequest.identifier}
233-
</Link>
266+
Create RR
267+
</Button>
234268
);
235269
}
236270
},

0 commit comments

Comments
 (0)