Skip to content

Commit a9b2478

Browse files
Merge branch 'develop' into #1425-allow-leads-edit-vendors
2 parents 4c7bb93 + 56aa6d8 commit a9b2478

113 files changed

Lines changed: 3406 additions & 574 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ A project management web application built in Typescript, React, and Express.
88

99
All of our documentation is on [our Confluence page](https://nerdocs.atlassian.net/wiki/spaces/NER/pages/5603329/Software). Start there to learn what the project is all about.
1010

11-
All questions can be directed to `#software` in the [NER Slack](https://nu-electric-racing.slack.com) (backup contact: [`@anthonybernardi`](https://github.com/anthonybernardi)).
11+
All questions can be directed to `#software` in the [NER Slack](https://nu-electric-racing.slack.com) (backup contact: [`@RChandler234`](https://github.com/RChandler234)).
1212

1313
## Environment Setup
1414

src/backend/src/controllers/change-requests.controllers.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,18 +75,19 @@ export default class ChangeRequestsController {
7575

7676
static async createStandardChangeRequest(req: Request, res: Response, next: NextFunction) {
7777
try {
78-
const { wbsNum, type, what, why } = req.body;
78+
const { wbsNum, type, what, why, proposedSolutions } = req.body;
7979
const submitter = await getCurrentUser(res);
80-
const id = await ChangeRequestsService.createStandardChangeRequest(
80+
const createdCR = await ChangeRequestsService.createStandardChangeRequest(
8181
submitter,
8282
wbsNum.carNumber,
8383
wbsNum.projectNumber,
8484
wbsNum.workPackageNumber,
8585
type,
8686
what,
87-
why
87+
why,
88+
proposedSolutions
8889
);
89-
return res.status(200).json({ message: `${id}` });
90+
return res.status(200).json(createdCR);
9091
} catch (error: unknown) {
9192
next(error);
9293
}

src/backend/src/controllers/projects.controllers.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,4 +127,80 @@ export default class ProjectsController {
127127
next(error);
128128
}
129129
}
130+
131+
static async createAssembly(req: Request, res: Response, next: NextFunction) {
132+
try {
133+
const user: User = await getCurrentUser(res);
134+
const wbsNum: WbsNumber = validateWBS(req.params.wbsNum);
135+
const { name, pdmFileName } = req.body;
136+
const createAssembly = await ProjectsService.createAssembly(name, user, wbsNum, pdmFileName);
137+
res.status(200).json(createAssembly);
138+
} catch (error: unknown) {
139+
next(error);
140+
}
141+
}
142+
143+
static async createMaterial(req: Request, res: Response, next: NextFunction) {
144+
try {
145+
const {
146+
name,
147+
assemblyId,
148+
status,
149+
materialTypeName,
150+
manufacturerName,
151+
manufacturerPartNumber,
152+
pdmFileName,
153+
quantity,
154+
unitName,
155+
price,
156+
subtotal,
157+
linkUrl,
158+
notes
159+
} = req.body;
160+
const creator = await getCurrentUser(res);
161+
const wbsNum = validateWBS(req.params.wbsNum);
162+
const material = await ProjectsService.createMaterial(
163+
creator,
164+
name,
165+
status,
166+
materialTypeName,
167+
manufacturerName,
168+
manufacturerPartNumber,
169+
quantity,
170+
unitName,
171+
price,
172+
subtotal,
173+
linkUrl,
174+
notes,
175+
wbsNum,
176+
assemblyId,
177+
pdmFileName
178+
);
179+
return res.status(200).json(material);
180+
} catch (error: unknown) {
181+
next(error);
182+
}
183+
}
184+
185+
static async createManufacturer(req: Request, res: Response, next: NextFunction) {
186+
try {
187+
const { name } = req.body;
188+
const user = await getCurrentUser(res);
189+
const createdManufacturer = await ProjectsService.createManufacturer(user, name);
190+
res.status(200).json(createdManufacturer);
191+
} catch (error: unknown) {
192+
next(error);
193+
}
194+
}
195+
196+
static async createMaterialType(req: Request, res: Response, next: NextFunction) {
197+
try {
198+
const { name } = req.body;
199+
const user = await getCurrentUser(res);
200+
const createdMaterialType = await ProjectsService.createMaterialType(name, user);
201+
res.status(200).json(createdMaterialType);
202+
} catch (error: unknown) {
203+
next(error);
204+
}
205+
}
130206
}

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,15 @@ export default class ReimbursementRequestsController {
162162

163163
static async createExpenseType(req: Request, res: Response, next: NextFunction) {
164164
try {
165-
const { name, code, allowed } = req.body;
165+
const { name, code, allowed, allowedRefundSources } = req.body;
166166
const user = await getCurrentUser(res);
167-
const createdExpenseType = await ReimbursementRequestService.createExpenseType(user, name, code, allowed);
167+
const createdExpenseType = await ReimbursementRequestService.createExpenseType(
168+
user,
169+
name,
170+
code,
171+
allowed,
172+
allowedRefundSources
173+
);
168174
res.status(200).json(createdExpenseType);
169175
} catch (error: unknown) {
170176
next(error);
@@ -269,14 +275,15 @@ export default class ReimbursementRequestsController {
269275
static async editExpenseTypeCode(req: Request, res: Response, next: NextFunction) {
270276
try {
271277
const { expenseTypeId } = req.params;
272-
const { name, code, allowed } = req.body;
278+
const { name, code, allowed, allowedRefundSources } = req.body;
273279
const submitter = await getCurrentUser(res);
274280
const expenseTypeUpdated = await ReimbursementRequestService.editExpenseType(
275281
expenseTypeId,
276282
code,
277283
name,
278284
allowed,
279-
submitter
285+
submitter,
286+
allowedRefundSources
280287
);
281288
res.status(200).json(expenseTypeUpdated);
282289
} catch (error: unknown) {

src/backend/src/controllers/teams.controllers.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,38 @@ export default class TeamsController {
6262
next(error);
6363
}
6464
}
65+
66+
static async createTeam(req: Request, res: Response, next: NextFunction) {
67+
try {
68+
const { teamName, headId, slackId, description } = req.body;
69+
const submitter = await getCurrentUser(res);
70+
const team = await TeamsService.createTeam(submitter, teamName, headId, slackId, description);
71+
return res.status(200).json(team);
72+
} catch (error: unknown) {
73+
next(error);
74+
}
75+
}
76+
77+
static async setTeamLeads(req: Request, res: Response, next: NextFunction) {
78+
try {
79+
const { userIds } = req.body;
80+
const { teamId } = req.params;
81+
const submitter = await getCurrentUser(res);
82+
const team = await TeamsService.setTeamLeads(submitter, teamId, userIds);
83+
return res.status(200).json(team);
84+
} catch (error: unknown) {
85+
next(error);
86+
}
87+
}
88+
89+
static async deleteTeam(req: Request, res: Response, next: NextFunction) {
90+
try {
91+
const { teamId } = req.params;
92+
const deleter = await getCurrentUser(res);
93+
await TeamsService.deleteTeam(deleter, teamId);
94+
return res.status(204).json({ message: `Successfully deleted team with id ${teamId}` });
95+
} catch (error: unknown) {
96+
next(error);
97+
}
98+
}
6599
}

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ export default class WorkPackagesController {
7272
blockedBy,
7373
expectedActivities,
7474
deliverables,
75-
projectLead,
76-
projectManager
75+
projectLeadId,
76+
projectManagerId
7777
} = req.body;
7878

7979
let { stage } = req.body;
@@ -94,8 +94,8 @@ export default class WorkPackagesController {
9494
blockedBy,
9595
expectedActivities,
9696
deliverables,
97-
projectLead,
98-
projectManager
97+
projectLeadId,
98+
projectManagerId
9999
);
100100
return res.status(200).json({ message: 'Work package updated successfully' });
101101
} catch (error: unknown) {

src/backend/src/integrations/slack.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { WebClient } from '@slack/web-api';
2+
import { HttpException } from '../utils/errors.utils';
23

34
const slack = new WebClient(process.env.SLACK_BOT_TOKEN);
45

@@ -40,13 +41,17 @@ export const sendMessage = async (slackId: string, message: string, link?: strin
4041
}
4142
};
4243

43-
await slack.chat.postMessage({
44-
token: SLACK_BOT_TOKEN,
45-
channel: slackId,
46-
text: message,
47-
blocks: [block],
48-
unfurl_links: false
49-
});
44+
try {
45+
await slack.chat.postMessage({
46+
token: SLACK_BOT_TOKEN,
47+
channel: slackId,
48+
text: message,
49+
blocks: [block],
50+
unfurl_links: false
51+
});
52+
} catch (error) {
53+
throw new HttpException(500, 'Error sending slack message, reason: ' + (error as any).data.error);
54+
}
5055
};
5156

5257
export default slack;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- AlterTable
2+
ALTER TABLE "Expense_Type" ADD COLUMN "allowedRefundSources" "Club_Accounts"[];
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
-- AlterEnum
2+
CREATE TYPE "Work_Package_Stage_new" AS ENUM ('RESEARCH', 'DESIGN', 'MANUFACTURING', 'INSTALL');
3+
ALTER TABLE "Work_Package" ALTER COLUMN "stage" TYPE "Work_Package_Stage_new" USING (
4+
CASE "stage"::text
5+
WHEN 'INTEGRATION' THEN 'INSTALL'::"Work_Package_Stage_new"
6+
ELSE "stage"::text::"Work_Package_Stage_new"
7+
END);
8+
ALTER TYPE "Work_Package_Stage" RENAME TO "Work_Package_Stage_old";
9+
ALTER TYPE "Work_Package_Stage_new" RENAME TO "Work_Package_Stage";
10+
DROP TYPE "Work_Package_Stage_old";
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
-- CreateEnum
2+
CREATE TYPE "Material_Status" AS ENUM ('RECEIVED', 'ORDERED', 'SHIPPED', 'UNORDERED');
3+
4+
-- CreateTable
5+
CREATE TABLE "Unit" (
6+
"name" TEXT NOT NULL,
7+
8+
CONSTRAINT "Unit_pkey" PRIMARY KEY ("name")
9+
);
10+
11+
-- CreateTable
12+
CREATE TABLE "Assembly" (
13+
"assemblyId" TEXT NOT NULL,
14+
"name" TEXT NOT NULL,
15+
"pdmFileName" TEXT,
16+
"dateDeleted" TIMESTAMP(3),
17+
"userDeletedId" INTEGER,
18+
"dateCreated" TIMESTAMP(3) NOT NULL,
19+
"userCreatedId" INTEGER NOT NULL,
20+
"wbsElementId" INTEGER NOT NULL,
21+
22+
CONSTRAINT "Assembly_pkey" PRIMARY KEY ("assemblyId")
23+
);
24+
25+
-- CreateTable
26+
CREATE TABLE "Material" (
27+
"materialId" TEXT NOT NULL,
28+
"assemblyId" TEXT,
29+
"name" TEXT NOT NULL,
30+
"wbsElementId" INTEGER NOT NULL,
31+
"dateDeleted" TIMESTAMP(3),
32+
"userDeletedId" INTEGER,
33+
"dateCreated" TIMESTAMP(3) NOT NULL,
34+
"userCreatedId" INTEGER NOT NULL,
35+
"status" "Material_Status" NOT NULL,
36+
"materialTypeName" TEXT NOT NULL,
37+
"manufacturerName" TEXT NOT NULL,
38+
"manufacturerPartNumber" TEXT NOT NULL,
39+
"pdmFileName" TEXT,
40+
"quantity" INTEGER NOT NULL,
41+
"unitName" TEXT,
42+
"price" INTEGER NOT NULL,
43+
"subtotal" INTEGER NOT NULL,
44+
"linkUrl" TEXT NOT NULL,
45+
"notes" TEXT NOT NULL,
46+
47+
CONSTRAINT "Material_pkey" PRIMARY KEY ("materialId")
48+
);
49+
50+
-- CreateTable
51+
CREATE TABLE "Material_Type" (
52+
"name" TEXT NOT NULL,
53+
"dateCreated" TIMESTAMP(3) NOT NULL,
54+
"creatorId" INTEGER NOT NULL,
55+
56+
CONSTRAINT "Material_Type_pkey" PRIMARY KEY ("name")
57+
);
58+
59+
-- CreateTable
60+
CREATE TABLE "Manufacturer" (
61+
"name" TEXT NOT NULL,
62+
"dateCreated" TIMESTAMP(3) NOT NULL,
63+
"creatorId" INTEGER NOT NULL,
64+
65+
CONSTRAINT "Manufacturer_pkey" PRIMARY KEY ("name")
66+
);
67+
68+
-- CreateIndex
69+
CREATE UNIQUE INDEX "Assembly_name_key" ON "Assembly"("name");
70+
71+
-- CreateIndex
72+
CREATE UNIQUE INDEX "Material_name_key" ON "Material"("name");
73+
74+
-- AddForeignKey
75+
ALTER TABLE "Assembly" ADD CONSTRAINT "Assembly_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE;
76+
77+
-- AddForeignKey
78+
ALTER TABLE "Assembly" ADD CONSTRAINT "Assembly_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE;
79+
80+
-- AddForeignKey
81+
ALTER TABLE "Assembly" ADD CONSTRAINT "Assembly_wbsElementId_fkey" FOREIGN KEY ("wbsElementId") REFERENCES "WBS_Element"("wbsElementId") ON DELETE RESTRICT ON UPDATE CASCADE;
82+
83+
-- AddForeignKey
84+
ALTER TABLE "Material" ADD CONSTRAINT "Material_assemblyId_fkey" FOREIGN KEY ("assemblyId") REFERENCES "Assembly"("assemblyId") ON DELETE SET NULL ON UPDATE CASCADE;
85+
86+
-- AddForeignKey
87+
ALTER TABLE "Material" ADD CONSTRAINT "Material_wbsElementId_fkey" FOREIGN KEY ("wbsElementId") REFERENCES "WBS_Element"("wbsElementId") ON DELETE RESTRICT ON UPDATE CASCADE;
88+
89+
-- AddForeignKey
90+
ALTER TABLE "Material" ADD CONSTRAINT "Material_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE;
91+
92+
-- AddForeignKey
93+
ALTER TABLE "Material" ADD CONSTRAINT "Material_userCreatedId_fkey" FOREIGN KEY ("userCreatedId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE;
94+
95+
-- AddForeignKey
96+
ALTER TABLE "Material" ADD CONSTRAINT "Material_materialTypeName_fkey" FOREIGN KEY ("materialTypeName") REFERENCES "Material_Type"("name") ON DELETE RESTRICT ON UPDATE CASCADE;
97+
98+
-- AddForeignKey
99+
ALTER TABLE "Material" ADD CONSTRAINT "Material_manufacturerName_fkey" FOREIGN KEY ("manufacturerName") REFERENCES "Manufacturer"("name") ON DELETE RESTRICT ON UPDATE CASCADE;
100+
101+
-- AddForeignKey
102+
ALTER TABLE "Material" ADD CONSTRAINT "Material_unitName_fkey" FOREIGN KEY ("unitName") REFERENCES "Unit"("name") ON DELETE SET NULL ON UPDATE CASCADE;

0 commit comments

Comments
 (0)