Skip to content

Commit 6867beb

Browse files
committed
checks
1 parent 5c0b192 commit 6867beb

15 files changed

Lines changed: 130 additions & 159 deletions

src/backend/src/controllers/finance.controllers.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -414,11 +414,7 @@ export default class FinanceController {
414414
static async toggleSponsorTaskDone(req: Request, res: Response, next: NextFunction) {
415415
try {
416416
const { sponsorTaskId } = req.params as Record<string, string>;
417-
const updatedTask = await FinanceServices.toggleSponsorTaskDone(
418-
req.currentUser,
419-
req.organization,
420-
sponsorTaskId
421-
);
417+
const updatedTask = await FinanceServices.toggleSponsorTaskDone(req.currentUser, req.organization, sponsorTaskId);
422418
res.status(200).json(updatedTask);
423419
} catch (error: unknown) {
424420
next(error);

src/backend/src/routes/prospective-sponsor.routes.ts

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
import express from 'express';
22
import { body } from 'express-validator';
3-
import {
4-
nonEmptyString,
5-
validateInputs,
6-
isDate,
7-
isOptionalDate,
8-
intMinZero
9-
} from '../utils/validation.utils.js';
3+
import { nonEmptyString, validateInputs, isDate, isOptionalDate, intMinZero } from '../utils/validation.utils.js';
104
import ProspectiveSponsorController from '../controllers/prospective-sponsor.controllers.js';
115

126
const prospectiveSponsorRouter = express.Router();
@@ -63,16 +57,10 @@ prospectiveSponsorRouter.post(
6357
);
6458

6559
// Delete prospective sponsor
66-
prospectiveSponsorRouter.post(
67-
'/:prospectiveSponsorId/delete',
68-
ProspectiveSponsorController.deleteProspectiveSponsor
69-
);
60+
prospectiveSponsorRouter.post('/:prospectiveSponsorId/delete', ProspectiveSponsorController.deleteProspectiveSponsor);
7061

7162
// Get tasks for prospective sponsor
72-
prospectiveSponsorRouter.get(
73-
'/:prospectiveSponsorId/tasks',
74-
ProspectiveSponsorController.getProspectiveSponsorTasks
75-
);
63+
prospectiveSponsorRouter.get('/:prospectiveSponsorId/tasks', ProspectiveSponsorController.getProspectiveSponsorTasks);
7664

7765
// Create task for prospective sponsor
7866
prospectiveSponsorRouter.post(

src/backend/src/services/notifications.services.ts

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -244,25 +244,56 @@ export default class NotificationsService {
244244
});
245245

246246
const promises = sponsorTasks.map(async (sponsorTask) => {
247-
const sponsor = await prisma.sponsor.findUnique({
248-
where: { sponsorId: sponsorTask.sponsorId }
249-
});
247+
const slackMention = sponsorTask.assignee?.userSettings?.slackId
248+
? `<@${sponsorTask.assignee.userSettings.slackId}>`
249+
: '';
250250

251-
const organization = await prisma.organization.findUnique({
252-
where: { organizationId: sponsor?.organizationId }
253-
});
251+
if (sponsorTask.sponsorId) {
252+
const sponsor = await prisma.sponsor.findUnique({
253+
where: { sponsorId: sponsorTask.sponsorId }
254+
});
254255

255-
if (!sponsor || !organization) return;
256+
if (!sponsor) return;
256257

257-
const message = `${sponsorTask.assignee?.userSettings?.slackId ? `<@${sponsorTask.assignee?.userSettings?.slackId}>` : ''} Reminder for your task for ${sponsor.name}: ${sponsorTask.notes}`;
258+
const organization = await prisma.organization.findUnique({
259+
where: { organizationId: sponsor.organizationId ?? undefined }
260+
});
258261

259-
if (organization.sponsorshipNotificationsSlackChannelId) {
260-
await sendMessage(
261-
organization.sponsorshipNotificationsSlackChannelId,
262-
message,
263-
`finishlinebyner.com/finance/companies/sponsors/${sponsor.sponsorId}`,
264-
`View Tasks for ${sponsor.name}`
265-
);
262+
if (!organization) return;
263+
264+
const message = `${slackMention} Reminder for your task for ${sponsor.name}: ${sponsorTask.notes}`;
265+
266+
if (organization.sponsorshipNotificationsSlackChannelId) {
267+
await sendMessage(
268+
organization.sponsorshipNotificationsSlackChannelId,
269+
message,
270+
`finishlinebyner.com/finance/companies/sponsors/${sponsor.sponsorId}`,
271+
`View Tasks for ${sponsor.name}`
272+
);
273+
}
274+
} else if (sponsorTask.prospectiveSponsorId) {
275+
const prospectiveSponsor = await prisma.prospective_Sponsor.findUnique({
276+
where: { prospectiveSponsorId: sponsorTask.prospectiveSponsorId }
277+
});
278+
279+
if (!prospectiveSponsor) return;
280+
281+
const organization = await prisma.organization.findUnique({
282+
where: { organizationId: prospectiveSponsor.organizationId }
283+
});
284+
285+
if (!organization) return;
286+
287+
const message = `${slackMention} Reminder for your task for prospective sponsor ${prospectiveSponsor.organizationName}: ${sponsorTask.notes}`;
288+
289+
if (organization.sponsorshipNotificationsSlackChannelId) {
290+
await sendMessage(
291+
organization.sponsorshipNotificationsSlackChannelId,
292+
message,
293+
`finishlinebyner.com/finance/companies/sponsors`,
294+
`View Prospective Sponsors`
295+
);
296+
}
266297
}
267298
});
268299

src/backend/src/services/prospective-sponsor.services.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,6 @@ export default class ProspectiveSponsorServices {
249249
},
250250
...getProspectiveSponsorQueryArgs(organization.organizationId)
251251
});
252-
253252
return prospectiveSponsorTransformer(updatedProspectiveSponsor);
254253
}
255254

@@ -287,10 +286,7 @@ export default class ProspectiveSponsorServices {
287286
/**
288287
* Gets tasks for a prospective sponsor.
289288
*/
290-
static async getProspectiveSponsorTasks(
291-
prospectiveSponsorId: string,
292-
organizationId: string
293-
): Promise<SponsorTask[]> {
289+
static async getProspectiveSponsorTasks(prospectiveSponsorId: string, organizationId: string): Promise<SponsorTask[]> {
294290
const prospectiveSponsor = await prisma.prospective_Sponsor.findUnique({
295291
where: { prospectiveSponsorId, dateDeleted: null }
296292
});

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

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -808,11 +808,7 @@ describe('Finance Tests', () => {
808808

809809
expect(sponsorTask.done).toBe(false);
810810

811-
const toggledTask = await FinanceServices.toggleSponsorTaskDone(
812-
user,
813-
organization,
814-
sponsorTask.sponsorTaskId
815-
);
811+
const toggledTask = await FinanceServices.toggleSponsorTaskDone(user, organization, sponsorTask.sponsorTaskId);
816812

817813
expect(toggledTask.done).toBe(true);
818814
});
@@ -849,11 +845,7 @@ describe('Finance Tests', () => {
849845
await FinanceServices.toggleSponsorTaskDone(user, organization, sponsorTask.sponsorTaskId);
850846

851847
// Toggle back to false
852-
const toggledTask = await FinanceServices.toggleSponsorTaskDone(
853-
user,
854-
organization,
855-
sponsorTask.sponsorTaskId
856-
);
848+
const toggledTask = await FinanceServices.toggleSponsorTaskDone(user, organization, sponsorTask.sponsorTaskId);
857849

858850
expect(toggledTask.done).toBe(false);
859851
});
@@ -888,17 +880,17 @@ describe('Finance Tests', () => {
888880
sponsor.sponsorId
889881
);
890882

891-
await expect(
892-
FinanceServices.toggleSponsorTaskDone(guest, organization, sponsorTask.sponsorTaskId)
893-
).rejects.toThrow(new AccessDeniedException('Only finance team members, heads, or the task assignee can toggle task status'));
883+
await expect(FinanceServices.toggleSponsorTaskDone(guest, organization, sponsorTask.sponsorTaskId)).rejects.toThrow(
884+
new AccessDeniedException('Only finance team members, heads, or the task assignee can toggle task status')
885+
);
894886
});
895887

896888
it('Fails if sponsor task does not exist', async () => {
897889
const user = await createTestUser(supermanAdmin, orgId);
898890

899-
await expect(
900-
FinanceServices.toggleSponsorTaskDone(user, organization, 'nonexistent-id')
901-
).rejects.toThrow(new NotFoundException('SponsorTask', 'nonexistent-id'));
891+
await expect(FinanceServices.toggleSponsorTaskDone(user, organization, 'nonexistent-id')).rejects.toThrow(
892+
new NotFoundException('SponsorTask', 'nonexistent-id')
893+
);
902894
});
903895

904896
it('Fails if sponsor task is deleted', async () => {
@@ -931,9 +923,9 @@ describe('Finance Tests', () => {
931923

932924
await FinanceServices.deleteSponsorTask(sponsorTask.sponsorTaskId, user, organization);
933925

934-
await expect(
935-
FinanceServices.toggleSponsorTaskDone(user, organization, sponsorTask.sponsorTaskId)
936-
).rejects.toThrow(new NotFoundException('SponsorTask', sponsorTask.sponsorTaskId));
926+
await expect(FinanceServices.toggleSponsorTaskDone(user, organization, sponsorTask.sponsorTaskId)).rejects.toThrow(
927+
new NotFoundException('SponsorTask', sponsorTask.sponsorTaskId)
928+
);
937929
});
938930
});
939931
});

src/backend/tests/unit/prospective-sponsor.test.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
import { Organization } from '@prisma/client';
22
import ProspectiveSponsorServices from '../../src/services/prospective-sponsor.services.js';
33
import FinanceServices from '../../src/services/finance.services.js';
4-
import {
5-
AccessDeniedException,
6-
DeletedException,
7-
HttpException,
8-
NotFoundException
9-
} from '../../src/utils/errors.utils.js';
10-
import { batmanAppAdmin, wonderwomanGuest, supermanAdmin, theVisitorGuest } from '../test-data/users.test-data.js';
4+
import { AccessDeniedException, DeletedException, HttpException, NotFoundException } from '../../src/utils/errors.utils.js';
5+
import { batmanAppAdmin, wonderwomanGuest, supermanAdmin } from '../test-data/users.test-data.js';
116
import { createTestOrganization, createTestUser, resetUsers } from '../test-utils.js';
127
import prisma from '../../src/prisma/prisma.js';
138
import { FirstContactMethod, ProspectiveSponsorStatus } from 'shared';
@@ -599,9 +594,9 @@ describe('Prospective Sponsor Tests', () => {
599594

600595
describe('Get Prospective Sponsor Tasks', () => {
601596
it('Fails if prospective sponsor does not exist', async () => {
602-
await expect(
603-
ProspectiveSponsorServices.getProspectiveSponsorTasks('nonexistent-id', orgId)
604-
).rejects.toThrow(new NotFoundException('ProspectiveSponsor', 'nonexistent-id'));
597+
await expect(ProspectiveSponsorServices.getProspectiveSponsorTasks('nonexistent-id', orgId)).rejects.toThrow(
598+
new NotFoundException('ProspectiveSponsor', 'nonexistent-id')
599+
);
605600
});
606601

607602
it('Returns tasks for prospective sponsor', async () => {
@@ -668,7 +663,9 @@ describe('Prospective Sponsor Tests', () => {
668663
new Date(),
669664
'Follow up'
670665
)
671-
).rejects.toThrow(new AccessDeniedException('Only finance team members or heads can create prospective sponsor tasks'));
666+
).rejects.toThrow(
667+
new AccessDeniedException('Only finance team members or heads can create prospective sponsor tasks')
668+
);
672669
});
673670

674671
it('Fails if prospective sponsor does not exist', async () => {

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,13 @@ import {
4444
SponsorTask,
4545
ReimbursementRequestData,
4646
SpendingBarData,
47-
SponsorTier
47+
SponsorTier,
48+
ProspectiveSponsor,
49+
FirstContactMethod,
50+
ProspectiveSponsorStatus,
51+
CreateSponsorTask
4852
} from 'shared';
53+
import { prospectiveSponsorTransformer } from './transformers/prospective-sponsor.transformer';
4954

5055
enum AllowedFileType {
5156
JPEG = 'image/jpeg',
@@ -784,9 +789,6 @@ export const toggleSponsorTaskDone = (sponsorTaskId: string) => {
784789

785790
/**************** Prospective Sponsors API ****************/
786791

787-
import { ProspectiveSponsor, FirstContactMethod, ProspectiveSponsorStatus, CreateSponsorTask } from 'shared';
788-
import { prospectiveSponsorTransformer } from './transformers/prospective-sponsor.transformer';
789-
790792
export interface CreateProspectiveSponsorPayload {
791793
organizationName: string;
792794
lastContactDate: Date;

src/frontend/src/pages/FinancePage/FinanceComponents/AcceptProspectiveSponsorModal.tsx

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,7 @@ const AcceptProspectiveSponsorModal = ({
9393
showModal
9494
}: AcceptProspectiveSponsorModalProps) => {
9595
const { isLoading, isError, error, mutateAsync } = useAcceptProspectiveSponsor();
96-
const {
97-
isLoading: tiersLoading,
98-
isError: tiersIsError,
99-
error: tiersError,
100-
data: sponsorTiers
101-
} = useGetAllSponsorTiers();
96+
const { isLoading: tiersLoading, isError: tiersIsError, error: tiersError, data: sponsorTiers } = useGetAllSponsorTiers();
10297
const toast = useToast();
10398

10499
const [datePickerOpen, setDatePickerOpen] = useState(false);
@@ -231,9 +226,7 @@ const AcceptProspectiveSponsorModal = ({
231226
<TextField {...params} placeholder="Select Value Types" error={!!errors.valueTypes} />
232227
)}
233228
renderTags={(tagValue, getTagProps) =>
234-
tagValue.map((option, index) => (
235-
<Chip label={option.label} {...getTagProps({ index })} size="small" />
236-
))
229+
tagValue.map((option, index) => <Chip label={option.label} {...getTagProps({ index })} size="small" />)
237230
}
238231
isOptionEqualToValue={(option, val) => option.value === val.value}
239232
disableCloseOnSelect
@@ -332,9 +325,7 @@ const AcceptProspectiveSponsorModal = ({
332325
getOptionLabel={(option) => option.toString()}
333326
onChange={(_, data) => field.onChange(data)}
334327
size="small"
335-
renderInput={(params) => (
336-
<TextField {...params} placeholder="Select Years" error={!!errors.activeYears} />
337-
)}
328+
renderInput={(params) => <TextField {...params} placeholder="Select Years" error={!!errors.activeYears} />}
338329
isOptionEqualToValue={(option, value) => option === value}
339330
disableCloseOnSelect
340331
/>
@@ -349,11 +340,7 @@ const AcceptProspectiveSponsorModal = ({
349340
control={control}
350341
name="taxExempt"
351342
render={({ field: { onChange, value } }) => (
352-
<Checkbox
353-
checked={!!value}
354-
onChange={(e) => onChange(e.target.checked)}
355-
sx={{ p: 0 }}
356-
/>
343+
<Checkbox checked={!!value} onChange={(e) => onChange(e.target.checked)} sx={{ p: 0 }} />
357344
)}
358345
/>
359346
<Typography variant="subtitle2" color="#EF4345">
@@ -366,12 +353,7 @@ const AcceptProspectiveSponsorModal = ({
366353
<Typography variant="subtitle2" color="#EF4345">
367354
Discount Code:
368355
</Typography>
369-
<ReactHookTextField
370-
name="discountCode"
371-
control={control}
372-
size="small"
373-
placeholder="Enter Code"
374-
/>
356+
<ReactHookTextField name="discountCode" control={control} size="small" placeholder="Enter Code" />
375357
</FormControl>
376358

377359
<FormControl fullWidth>

src/frontend/src/pages/FinancePage/FinanceComponents/CreateProspectiveSponsorPage.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,7 @@ import { useCreateProspectiveSponsor } from '../../../hooks/finance.hooks';
1313
import SidePage from './SidePagePopup';
1414
import NERFailButton from '../../../components/NERFailButton';
1515
import NERSuccessButton from '../../../components/NERSuccessButton';
16-
import {
17-
ProspectiveSponsorForm,
18-
ProspectiveSponsorFormInputs,
19-
prospectiveSponsorSchema
20-
} from './ProspectiveSponsorForm';
16+
import { ProspectiveSponsorForm, ProspectiveSponsorFormInputs, prospectiveSponsorSchema } from './ProspectiveSponsorForm';
2117
import { FirstContactMethod } from 'shared';
2218

2319
interface CreateProspectiveSponsorPageProps {

src/frontend/src/pages/FinancePage/FinanceComponents/EditProspectiveSponsorPage.tsx

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,7 @@ import { useEditProspectiveSponsor } from '../../../hooks/finance.hooks';
1313
import SidePage from './SidePagePopup';
1414
import NERFailButton from '../../../components/NERFailButton';
1515
import NERSuccessButton from '../../../components/NERSuccessButton';
16-
import {
17-
ProspectiveSponsorForm,
18-
ProspectiveSponsorFormInputs,
19-
prospectiveSponsorSchema
20-
} from './ProspectiveSponsorForm';
16+
import { ProspectiveSponsorForm, ProspectiveSponsorFormInputs, prospectiveSponsorSchema } from './ProspectiveSponsorForm';
2117
import { ProspectiveSponsor } from 'shared';
2218

2319
interface EditProspectiveSponsorPageProps {
@@ -26,11 +22,7 @@ interface EditProspectiveSponsorPageProps {
2622
prospectiveSponsor: ProspectiveSponsor;
2723
}
2824

29-
const EditProspectiveSponsorPage = ({
30-
showPage,
31-
handleClose,
32-
prospectiveSponsor
33-
}: EditProspectiveSponsorPageProps) => {
25+
const EditProspectiveSponsorPage = ({ showPage, handleClose, prospectiveSponsor }: EditProspectiveSponsorPageProps) => {
3426
const toast = useToast();
3527
const { isLoading, mutateAsync } = useEditProspectiveSponsor();
3628

@@ -106,12 +98,7 @@ const EditProspectiveSponsorPage = ({
10698
title="Edit Prospective Sponsor"
10799
component={
108100
<Box display="flex" flexDirection="column" alignItems="flex-end">
109-
<ProspectiveSponsorForm
110-
control={control}
111-
errors={errors}
112-
defaultValues={prospectiveSponsor}
113-
isEditMode
114-
/>
101+
<ProspectiveSponsorForm control={control} errors={errors} defaultValues={prospectiveSponsor} isEditMode />
115102
{submitError && (
116103
<Box color="error.main" mb={2} fontWeight="bold">
117104
{submitError}

0 commit comments

Comments
 (0)