Skip to content

Commit 14f15bf

Browse files
committed
#4102 upload sponsor endpoint
1 parent 2784ce6 commit 14f15bf

3 files changed

Lines changed: 54 additions & 17 deletions

File tree

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { NextFunction, Request, Response } from 'express';
22
import FinanceServices from '../services/finance.services.js';
3+
import { HttpException } from '../utils/errors.utils.js';
34

45
export default class FinanceController {
56
static async createSponsor(req: Request, res: Response, next: NextFunction) {
@@ -43,8 +44,7 @@ export default class FinanceController {
4344
contactPhone,
4445
contactPosition,
4546
stockDescription,
46-
discountDescription,
47-
req.file
47+
discountDescription
4848
);
4949
res.status(200).json(sponsor);
5050
} catch (error: unknown) {
@@ -384,8 +384,7 @@ export default class FinanceController {
384384
contactPhone,
385385
contactPosition,
386386
stockDescription,
387-
discountDescription,
388-
req.file
387+
discountDescription
389388
);
390389

391390
res.status(200).json(updatedSponsor);
@@ -432,4 +431,15 @@ export default class FinanceController {
432431
next(error);
433432
}
434433
}
434+
435+
static async uploadSponsorLogo(req: Request, res: Response, next: NextFunction) {
436+
try {
437+
const { sponsorId } = req.params as Record<string, string>;
438+
if (!req.file) throw new HttpException(400, 'Invalid or undefined image data');
439+
const updatedSponsor = await FinanceServices.uploadSponsorLogo(req.currentUser, req.organization, sponsorId, req.file);
440+
res.status(200).json(updatedSponsor);
441+
} catch (error: unknown) {
442+
next(error);
443+
}
444+
}
435445
}

src/backend/src/routes/finance.routes.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ const upload = multer({ limits: { fileSize: MAX_FILE_SIZE }, storage: memoryStor
1717

1818
financeRouter.post(
1919
'/sponsor/create',
20-
upload.single('logoImage'),
2120
nonEmptyString(body('name')),
2221
body('activeStatus').isBoolean(),
2322
body('valueTypes').isArray(),
@@ -52,6 +51,8 @@ financeRouter.get('/sponsor/:sponsorId/sponsorTasks', FinanceController.getSpons
5251

5352
financeRouter.post('/sponsor/:sponsorId/delete', FinanceController.deleteSponsor);
5453

54+
financeRouter.post('/sponsor/:sponsorId/uploadLogo', upload.single('logoImage'), FinanceController.uploadSponsorLogo);
55+
5556
financeRouter.post(
5657
'/sponsorTier/create',
5758
nonEmptyString(body('name')),
@@ -146,7 +147,6 @@ financeRouter.get('/sponsorTiers', FinanceController.getAllSponsorTiers);
146147

147148
financeRouter.post(
148149
'/sponsor/:sponsorId/edit',
149-
upload.single('logoImage'),
150150
nonEmptyString(body('name')),
151151
body('activeStatus').isBoolean(),
152152
body('valueTypes').isArray(),

src/backend/src/services/finance.services.ts

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,7 @@ export default class FinanceServices {
8181
contactPhone?: string,
8282
contactPosition?: string,
8383
stockDescription?: string,
84-
discountDescription?: string,
85-
logoImage?: Express.Multer.File
84+
discountDescription?: string
8685
) {
8786
if (!(await userHasPermission(submitter.userId, organization.organizationId, isHead)))
8887
throw new AccessDeniedException('Only heads can create a sponsor');
@@ -106,8 +105,6 @@ export default class FinanceServices {
106105
data: { name: contactName, email: contactEmail, phone: contactPhone, position: contactPosition }
107106
});
108107

109-
const { id: logoImageId } = logoImage ? await uploadFile(logoImage) : { id: undefined };
110-
111108
const sponsor = await prisma.sponsor.create({
112109
data: {
113110
name,
@@ -122,7 +119,6 @@ export default class FinanceServices {
122119
taxExempt,
123120
discountCode,
124121
sponsorNotes,
125-
logoImageId,
126122
contactId: contact.sponsorContactId,
127123
sponsorTasks: {
128124
create: sponsorTasks.map((task) => ({
@@ -1230,8 +1226,7 @@ export default class FinanceServices {
12301226
contactPhone?: string,
12311227
contactPosition?: string,
12321228
stockDescription?: string,
1233-
discountDescription?: string,
1234-
logoImage?: Express.Multer.File
1229+
discountDescription?: string
12351230
): Promise<Sponsor> {
12361231
if (!(await userHasPermission(submitter.userId, organization.organizationId, isHead)))
12371232
throw new AccessDeniedException('Only heads can edit sponsors.');
@@ -1329,8 +1324,6 @@ export default class FinanceServices {
13291324
data: { name: contactName, email: contactEmail, phone: contactPhone, position: contactPosition }
13301325
});
13311326

1332-
const { id: logoImageId } = logoImage ? await uploadFile(logoImage) : { id: undefined };
1333-
13341327
const updatedSponsor = await prisma.sponsor.update({
13351328
where: { sponsorId: oldSponsor.sponsorId },
13361329
data: {
@@ -1345,15 +1338,49 @@ export default class FinanceServices {
13451338
tier: sponsorTierId ? { connect: { sponsorTierId } } : { disconnect: true },
13461339
taxExempt,
13471340
discountCode,
1348-
sponsorNotes,
1349-
...(logoImageId && { logoImageId })
1341+
sponsorNotes
13501342
},
13511343
...getSponsorQueryArgs(organization.organizationId)
13521344
});
13531345

13541346
return sponsorTransformer(updatedSponsor);
13551347
}
13561348

1349+
/**
1350+
* Uploads a logo image for a sponsor and stores the resulting image ID.
1351+
*
1352+
* @param submitter The user performing the upload
1353+
* @param organization The organization the sponsor belongs to
1354+
* @param sponsorId The id of the sponsor
1355+
* @param logoImage The logo image file to upload
1356+
* @returns The updated sponsor
1357+
*/
1358+
static async uploadSponsorLogo(
1359+
submitter: User,
1360+
organization: Organization,
1361+
sponsorId: string,
1362+
logoImage: Express.Multer.File
1363+
): Promise<Sponsor> {
1364+
if (!(await userHasPermission(submitter.userId, organization.organizationId, isHead)))
1365+
throw new AccessDeniedException('Only heads can update a sponsor logo');
1366+
1367+
const sponsor = await prisma.sponsor.findUnique({
1368+
where: { sponsorId, organizationId: organization.organizationId }
1369+
});
1370+
1371+
if (!sponsor) throw new NotFoundException('Sponsor', sponsorId);
1372+
1373+
const { id } = await uploadFile(logoImage);
1374+
1375+
const updatedSponsor = await prisma.sponsor.update({
1376+
where: { sponsorId },
1377+
data: { logoImageId: id },
1378+
...getSponsorQueryArgs(organization.organizationId)
1379+
});
1380+
1381+
return sponsorTransformer(updatedSponsor);
1382+
}
1383+
13571384
/**
13581385
* Toggles the done status of a sponsor task
13591386
* @param submitter The user toggling the task

0 commit comments

Comments
 (0)