Skip to content

Commit da95268

Browse files
author
Madalynn Nenninger
committed
Merge branch 'develop' of https://github.com/Northeastern-Electric-Racing/FinishLine into #3991-rr-form-order-account-code
merge
2 parents e5b56a0 + a8c2a4f commit da95268

25 files changed

Lines changed: 377 additions & 276 deletions

File tree

src/backend/src/controllers/recruitment.controllers.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,16 @@ export default class RecruitmentController {
116116
}
117117
}
118118

119+
static async deleteGuestDefinition(req: Request, res: Response, next: NextFunction) {
120+
try {
121+
const { definitionId } = req.params as Record<string, string>;
122+
await RecruitmentServices.deleteGuestDefinition(req.currentUser, definitionId, req.organization);
123+
res.status(200).json({ message: `Successfully deleted guestDefinition with id ${definitionId}` });
124+
} catch (error: unknown) {
125+
next(error);
126+
}
127+
}
128+
119129
static async getAllGuestDefintions(req: Request, res: Response, next: NextFunction) {
120130
try {
121131
const allDefinitons = await RecruitmentServices.getAllGuestDefinitions(req.organization);

src/backend/src/prisma-query-args/teams.query-args.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export const getTeamPreviewQueryArgs = (organizationId: string) =>
3838
include: {
3939
members: getUserQueryArgs(organizationId),
4040
head: getUserQueryArgs(organizationId),
41-
leads: getUserQueryArgs(organizationId)
41+
leads: getUserQueryArgs(organizationId),
42+
teamType: true
4243
}
4344
});

src/backend/src/prisma/seed.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3892,6 +3892,17 @@ const performSeed: () => Promise<void> = async () => {
38923892
undefined
38933893
);
38943894

3895+
/* Guest Definitions */
3896+
const guestDef1 = await prisma.guest_Definition.create({
3897+
data: {
3898+
term: 'NER',
3899+
description: 'A really awesome organization!',
3900+
order: 0,
3901+
organizationId,
3902+
userCreatedId: batman.userId
3903+
}
3904+
});
3905+
38953906
await RecruitmentServices.createGuestDefinition(
38963907
thomasEmrax,
38973908
ner,

src/backend/src/routes/recruitment.routes.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ recruitmentRouter.post(
5050

5151
recruitmentRouter.delete('/faq/:faqId/delete', RecruitmentController.deleteFaq);
5252

53+
/* Guest Definition Section */
54+
5355
recruitmentRouter.post(
5456
'/guestdefinition/create',
5557
nonEmptyString(body('term')),
@@ -62,6 +64,7 @@ recruitmentRouter.post(
6264
RecruitmentController.createGuestDefinition
6365
);
6466

67+
recruitmentRouter.delete('/guestdefinition/:definitionId/delete', RecruitmentController.deleteGuestDefinition);
6568
recruitmentRouter.get('/guestdefinitions', RecruitmentController.getAllGuestDefintions);
6669

6770
export default recruitmentRouter;

src/backend/src/services/recruitment.services.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,4 +261,25 @@ export default class RecruitmentServices {
261261

262262
return allGuestDefintions.map(guestDefinitionTransformer);
263263
}
264+
265+
/**
266+
* Deletes a guestDefinition with the given organization Id and definitionId
267+
* @param deleter the user requesting to delete the guestDefinition
268+
* @param organizationId the organization ID of the deleter
269+
*/
270+
static async deleteGuestDefinition(deleter: User, definitionId: string, organization: Organization): Promise<void> {
271+
if (!(await userHasPermission(deleter.userId, organization.organizationId, isAdmin))) {
272+
throw new AccessDeniedAdminOnlyException('delete a guestDefinition');
273+
}
274+
275+
const def = await prisma.guest_Definition.findUnique({ where: { definitionId } });
276+
277+
if (!def) throw new NotFoundException('Guest Definition', definitionId);
278+
if (def.dateDeleted) throw new DeletedException('Guest Definition', definitionId);
279+
280+
await prisma.guest_Definition.update({
281+
where: { definitionId },
282+
data: { dateDeleted: new Date(), userDeletedId: deleter.userId }
283+
});
284+
}
264285
}

src/backend/src/services/reimbursement-requests.services.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -426,17 +426,6 @@ export default class ReimbursementRequestService {
426426
//set any deleted receipts with a dateDeleted
427427
await removeDeletedReceiptPictures(receiptPictures, oldReimbursementRequest.receiptPictures || [], submitter);
428428

429-
try {
430-
await sendPendingSaboSubmissionNotification(
431-
updatedReimbursementRequest.notificationSlackThreads,
432-
submitter.userId,
433-
updatedReimbursementRequest.recipientId,
434-
updatedReimbursementRequest.reimbursementRequestId
435-
);
436-
} catch (e: unknown) {
437-
console.error('Error sending pending SABO submission notification:', e);
438-
}
439-
440429
return updatedReimbursementRequest;
441430
}
442431

src/backend/src/transformers/teams.transformer.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ export const teamPreviewTransformer = (team: Prisma.TeamGetPayload<TeamPreviewQu
3838
leads: team.leads.map(userTransformer),
3939
members: team.members.map(userTransformer),
4040
head: userTransformer(team.head),
41-
dateArchived: team.dateArchived ?? undefined
41+
dateArchived: team.dateArchived ?? undefined,
42+
teamType: team.teamType ? teamTypeTransformer(team.teamType) : undefined
4243
};
4344
};
4445

src/backend/src/utils/errors.utils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ export type ExceptionObjectNames =
211211
| 'Event Type'
212212
| 'Event'
213213
| 'Schedule Slot'
214+
| 'Guest Definition'
214215
| 'ProspectiveSponsor'
215216
| 'SponsorTier'
216217
| 'Meeting Attendance';

src/backend/tests/test-utils.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,3 +945,20 @@ export const createMinimalPartReviewForReview = async (
945945

946946
return { review, partId: part.partId };
947947
};
948+
949+
export const createTestGuestDefinition = async (user: User, organizationId: string) => {
950+
if (!organizationId) organizationId = await createTestOrganization().then((org) => org.organizationId);
951+
if (!organizationId) throw new Error('Failed to create organization');
952+
953+
const def = await prisma.guest_Definition.create({
954+
data: {
955+
term: 'Term',
956+
description: 'Description',
957+
order: 0,
958+
organizationId,
959+
userCreatedId: user.userId
960+
}
961+
});
962+
963+
return def;
964+
};

src/backend/tests/unit/recruitment.test.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Organization, User } from '@prisma/client';
33
import RecruitmentServices from '../../src/services/recruitment.services.js';
44
import { AccessDeniedAdminOnlyException, DeletedException, NotFoundException } from '../../src/utils/errors.utils.js';
55
import {
6+
createTestGuestDefinition,
67
createTestMilestone,
78
createTestFaq,
89
createTestFAQ,
@@ -341,6 +342,7 @@ describe('Recruitment Tests', () => {
341342
expect(deletedTestFaq?.dateDeleted).not.toBe(null);
342343
});
343344
});
345+
344346
describe('Create Guest Definitions', () => {
345347
it('Successful guest definition creation', async () => {
346348
const def = await RecruitmentServices.createGuestDefinition(
@@ -378,6 +380,49 @@ describe('Recruitment Tests', () => {
378380
});
379381
});
380382

383+
describe('Delete Guest Definition', () => {
384+
it('Fails if user is not an admin', async () => {
385+
const admin = await createTestUser(batmanAppAdmin, orgId);
386+
const guest = await createTestUser(wonderwomanGuest, orgId);
387+
const testDef = await createTestGuestDefinition(admin, orgId);
388+
389+
await expect(
390+
async () => await RecruitmentServices.deleteGuestDefinition(guest, testDef.definitionId, organization)
391+
).rejects.toThrow(new AccessDeniedAdminOnlyException('delete a guestDefinition'));
392+
});
393+
394+
it('Fails if definition does not exist', async () => {
395+
const admin = await createTestUser(batmanAppAdmin, orgId);
396+
397+
await expect(
398+
async () => await RecruitmentServices.deleteGuestDefinition(admin, 'fake-id', organization)
399+
).rejects.toThrow(new NotFoundException('Guest Definition', 'fake-id'));
400+
});
401+
402+
it('Fails if definition is already deleted', async () => {
403+
const admin = await createTestUser(batmanAppAdmin, orgId);
404+
const testDef = await createTestGuestDefinition(admin, orgId);
405+
await RecruitmentServices.deleteGuestDefinition(admin, testDef.definitionId, organization);
406+
407+
await expect(
408+
async () => await RecruitmentServices.deleteGuestDefinition(admin, testDef.definitionId, organization)
409+
).rejects.toThrow(new DeletedException('Guest Definition', testDef.definitionId));
410+
});
411+
412+
it('Successfully deletes a guest definition', async () => {
413+
const admin = await createTestUser(batmanAppAdmin, orgId);
414+
const testDef = await createTestGuestDefinition(admin, orgId);
415+
416+
await RecruitmentServices.deleteGuestDefinition(admin, testDef.definitionId, organization);
417+
418+
const deletedTestDef = await prisma.guest_Definition.findUnique({
419+
where: { definitionId: testDef.definitionId }
420+
});
421+
422+
expect(deletedTestDef?.dateDeleted).not.toBe(null);
423+
});
424+
});
425+
381426
describe('Get All Guest Definitions', () => {
382427
it('Succeeds and gets all the guest definitions', async () => {
383428
const def = await RecruitmentServices.createGuestDefinition(

0 commit comments

Comments
 (0)