Skip to content

Commit 040e5ff

Browse files
authored
Merge pull request #1548 from Northeastern-Electric-Racing/#1417-Get-Many-Work-Packages
#1417 - get many work packages endpoint
2 parents 06abc2d + 895241d commit 040e5ff

5 files changed

Lines changed: 79 additions & 1 deletion

File tree

src/backend/src/controllers/work-packages.controllers.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ export default class WorkPackagesController {
2929
}
3030
}
3131

32+
static async getManyWorkPackages(req: Request, res: Response, next: NextFunction) {
33+
try {
34+
const { wbsNums } = req.body;
35+
const workPackages: WorkPackage[] = await WorkPackagesService.getManyWorkPackages(wbsNums);
36+
res.status(200).json(workPackages);
37+
} catch (error: unknown) {
38+
next(error);
39+
}
40+
}
41+
3242
// Create a work package with the given details
3343
static async createWorkPackage(req: Request, res: Response, next: NextFunction) {
3444
try {

src/backend/src/routes/work-packages.routes.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ import { intMinZero, isDate, isWorkPackageStageOrNone, nonEmptyString } from '..
66
const workPackagesRouter = express.Router();
77

88
workPackagesRouter.get('/', WorkPackagesController.getAllWorkPackages);
9+
workPackagesRouter.get(
10+
'/get-many',
11+
body('wbsNums').isArray(),
12+
intMinZero(body('wbsNums.*.carNumber')),
13+
intMinZero(body('wbsNums.*.projectNumber')),
14+
intMinZero(body('wbsNums.*.workPackageNumber')),
15+
validateInputs,
16+
WorkPackagesController.getManyWorkPackages
17+
);
918
workPackagesRouter.get('/:wbsNum', WorkPackagesController.getSingleWorkPackage);
1019
workPackagesRouter.post(
1120
'/create',

src/backend/src/services/work-packages.services.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,53 @@ export default class WorkPackagesService {
108108
return workPackageTransformer(wp);
109109
}
110110

111+
/**
112+
* Retrieve a subset of work packages.
113+
* @param wbsNums the WBS numbers of the work packages to retrieve
114+
* @returns the work packages with the given WBS numbers
115+
* @throws if any of the work packages are not found
116+
*/
117+
static async getManyWorkPackages(wbsNums: WbsNumber[]): Promise<WorkPackage[]> {
118+
wbsNums.forEach((wbsNum) => {
119+
if (isProject(wbsNum)) {
120+
throw new HttpException(
121+
404,
122+
`WBS Number ${wbsNum.carNumber}.${wbsNum.projectNumber}.${wbsNum.workPackageNumber} is a project WBS#, not a Work Package WBS#`
123+
);
124+
}
125+
});
126+
127+
const workPackagePromises = wbsNums.map(async (wbsNum) => {
128+
const workPackage = await prisma.work_Package.findFirst({
129+
where: {
130+
AND: [
131+
{
132+
wbsElement: {
133+
dateDeleted: null
134+
}
135+
},
136+
{
137+
wbsElement: {
138+
carNumber: wbsNum.carNumber,
139+
projectNumber: wbsNum.projectNumber,
140+
workPackageNumber: wbsNum.workPackageNumber
141+
}
142+
}
143+
]
144+
},
145+
...workPackageQueryArgs
146+
});
147+
148+
if (!workPackage) {
149+
throw new NotFoundException('Work Package', wbsPipe(wbsNum));
150+
}
151+
return workPackageTransformer(workPackage);
152+
});
153+
154+
const resolvedWorkPackages = await Promise.all(workPackagePromises);
155+
return resolvedWorkPackages;
156+
}
157+
111158
/**
112159
* Creates a Work_Package in the database
113160
* @param user the user creating the work package

src/backend/src/transformers/work-packages.transformer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { convertStatus, wbsNumOf } from '../utils/utils';
66
import { calculateWorkPackageProgress } from '../utils/work-packages.utils';
77
import userTransformer from './user.transformer';
88

9-
const workPackageTransformer = (wpInput: Prisma.Work_PackageGetPayload<typeof workPackageQueryArgs>) => {
9+
const workPackageTransformer = (wpInput: Prisma.Work_PackageGetPayload<typeof workPackageQueryArgs>): WorkPackage => {
1010
const expectedProgress = calculatePercentExpectedProgress(wpInput.startDate, wpInput.duration, wpInput.wbsElement.status);
1111
const wbsNum = wbsNumOf(wpInput.wbsElement);
1212
const progress = calculateWorkPackageProgress(wpInput.deliverables, wpInput.expectedActivities);

src/backend/tests/work-packages.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,18 @@ describe('Work Packages', () => {
292292
});
293293
});
294294

295+
describe('getManyWorkPackages', () => {
296+
test('should retrieve an empty array for an empty WBS numbers array', async () => {
297+
const wbsNums: WbsNumber[] = [];
298+
299+
vi.spyOn(prisma.work_Package, 'findMany').mockResolvedValue([]);
300+
301+
const result = await WorkPackageService.getManyWorkPackages(wbsNums);
302+
303+
expect(result).toStrictEqual([]);
304+
});
305+
});
306+
295307
describe('slackMessageUpcomingDeadlines', () => {
296308
beforeEach(() => {
297309
vi.spyOn(slackUtils, 'sendSlackUpcomingDeadlineNotification').mockImplementation(async () => {});

0 commit comments

Comments
 (0)