Skip to content

Commit 156e098

Browse files
authored
Merge branch 'develop' into #1719-LaurenPhan-credits
2 parents 428fe4d + 19f9910 commit 156e098

73 files changed

Lines changed: 2904 additions & 1280 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.

.github/workflows/run-tests.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ jobs:
2020
steps:
2121
- name: Checkout repository
2222
uses: actions/checkout@v3
23+
- name: Set env variables
24+
run: touch .env && echo "FINANCE_TEAM_ID=0" >> .env
2325
- name: Set up Node.js
2426
uses: actions/setup-node@v3
2527
with:

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

Lines changed: 143 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { Project, validateWBS, WbsNumber, wbsPipe } from 'shared';
1+
import { Manufacturer, MaterialType, Project, validateWBS, WbsNumber, wbsPipe } from 'shared';
22
import { NextFunction, Request, Response } from 'express';
3-
import { Manufacturer, User } from '@prisma/client';
3+
import { User } from '@prisma/client';
44
import { getCurrentUser } from '../utils/auth.utils';
55
import ProjectsService from '../services/projects.services';
66

@@ -29,11 +29,38 @@ export default class ProjectsController {
2929
static async createProject(req: Request, res: Response, next: NextFunction) {
3030
try {
3131
const user: User = await getCurrentUser(res);
32-
const { crId, carNumber, name, summary, teamId } = req.body;
32+
const {
33+
name,
34+
crId,
35+
carNumber,
36+
teamIds,
37+
budget,
38+
summary,
39+
projectLeadId,
40+
projectManagerId,
41+
links,
42+
goals,
43+
features,
44+
otherConstraints,
45+
rules
46+
} = req.body;
3347

34-
const createdWbsNumber: WbsNumber = await ProjectsService.createProject(user, crId, carNumber, name, summary, [
35-
teamId
36-
]);
48+
const createdWbsNumber: WbsNumber = await ProjectsService.createProject(
49+
user,
50+
crId,
51+
carNumber,
52+
name,
53+
summary,
54+
teamIds,
55+
budget,
56+
links,
57+
rules,
58+
goals,
59+
features,
60+
otherConstraints,
61+
projectLeadId,
62+
projectManagerId
63+
);
3764

3865
return res.status(200).json(wbsPipe(createdWbsNumber));
3966
} catch (error: unknown) {
@@ -167,14 +194,14 @@ export default class ProjectsController {
167194
manufacturerName,
168195
manufacturerPartNumber,
169196
quantity,
170-
unitName,
171197
price,
172198
subtotal,
173199
linkUrl,
174200
notes,
175201
wbsNum,
176202
assemblyId,
177-
pdmFileName
203+
pdmFileName,
204+
unitName
178205
);
179206
return res.status(200).json(material);
180207
} catch (error: unknown) {
@@ -193,6 +220,17 @@ export default class ProjectsController {
193220
}
194221
}
195222

223+
static async deleteManufacturer(req: Request, res: Response, next: NextFunction) {
224+
try {
225+
const user: User = await getCurrentUser(res);
226+
const { manufacturerName } = req.params;
227+
const deletedManufacturer = await ProjectsService.deleteManufacturer(user, manufacturerName);
228+
res.status(200).json(deletedManufacturer);
229+
} catch (error: unknown) {
230+
next(error);
231+
}
232+
}
233+
196234
static async getAllManufacturers(req: Request, res: Response, next: NextFunction) {
197235
try {
198236
const user = await getCurrentUser(res);
@@ -203,6 +241,16 @@ export default class ProjectsController {
203241
}
204242
}
205243

244+
static async getAllMaterialTypes(req: Request, res: Response, next: NextFunction) {
245+
try {
246+
const user = await getCurrentUser(res);
247+
const materialTypes: MaterialType[] = await ProjectsService.getAllMaterialTypes(user);
248+
return res.status(200).json(materialTypes);
249+
} catch (error: unknown) {
250+
next(error);
251+
}
252+
}
253+
206254
static async createMaterialType(req: Request, res: Response, next: NextFunction) {
207255
try {
208256
const { name } = req.body;
@@ -213,4 +261,91 @@ export default class ProjectsController {
213261
next(error);
214262
}
215263
}
264+
265+
static async assignMaterialAssembly(req: Request, res: Response, next: NextFunction) {
266+
try {
267+
const { materialId } = req.params;
268+
const { assemblyId } = req.body;
269+
const user = await getCurrentUser(res);
270+
const updatedMaterial = await ProjectsService.assignMaterialAssembly(user, materialId, assemblyId);
271+
res.status(200).json(updatedMaterial);
272+
} catch (error: unknown) {
273+
next(error);
274+
}
275+
}
276+
277+
static async deleteAssemblyType(req: Request, res: Response, next: NextFunction) {
278+
try {
279+
const { assemblyId } = req.params;
280+
const user = await getCurrentUser(res);
281+
const deletedAssembly = await ProjectsService.deleteAssembly(assemblyId, user);
282+
res.status(200).json(deletedAssembly);
283+
} catch (error: unknown) {
284+
next(error);
285+
}
286+
}
287+
288+
static async deleteMaterialType(req: Request, res: Response, next: NextFunction) {
289+
try {
290+
const { materialTypeId } = req.params;
291+
const user = await getCurrentUser(res);
292+
const deletedMaterial = await ProjectsService.deleteMaterialType(materialTypeId, user);
293+
res.status(200).json(deletedMaterial);
294+
} catch (error: unknown) {
295+
next(error);
296+
}
297+
}
298+
299+
static async deleteMaterial(req: Request, res: Response, next: NextFunction) {
300+
try {
301+
const { materialId } = req.params;
302+
const user: User = await getCurrentUser(res);
303+
const updatedMaterial = await ProjectsService.deleteMaterial(user, materialId);
304+
res.status(200).json(updatedMaterial);
305+
} catch (error: unknown) {
306+
next(error);
307+
}
308+
}
309+
310+
static async editMaterial(req: Request, res: Response, next: NextFunction) {
311+
try {
312+
const user = await getCurrentUser(res);
313+
const { materialId } = req.params;
314+
const {
315+
name,
316+
assemblyId,
317+
status,
318+
materialTypeName,
319+
manufacturerName,
320+
manufacturerPartNumber,
321+
pdmFileName,
322+
quantity,
323+
unitName,
324+
price,
325+
subtotal,
326+
linkUrl,
327+
notes
328+
} = req.body;
329+
const updatedMaterial = await ProjectsService.editMaterial(
330+
user,
331+
materialId,
332+
name,
333+
status,
334+
materialTypeName,
335+
manufacturerName,
336+
manufacturerPartNumber,
337+
quantity,
338+
price,
339+
subtotal,
340+
linkUrl,
341+
notes,
342+
unitName,
343+
assemblyId,
344+
pdmFileName
345+
);
346+
res.status(200).json(updatedMaterial);
347+
} catch (error: unknown) {
348+
next(error);
349+
}
350+
}
216351
}

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

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,23 @@ export default class ReimbursementRequestsController {
5252

5353
static async createReimbursementRequest(req: Request, res: Response, next: NextFunction) {
5454
try {
55-
const { dateOfExpense, vendorId, account, reimbursementProducts, expenseTypeId, totalCost } = req.body;
55+
const {
56+
dateOfExpense,
57+
vendorId,
58+
account,
59+
otherReimbursementProducts,
60+
wbsReimbursementProducts,
61+
expenseTypeId,
62+
totalCost
63+
} = req.body;
5664
const user = await getCurrentUserWithUserSettings(res);
5765
const createdReimbursementRequest = await ReimbursementRequestService.createReimbursementRequest(
5866
user,
5967
dateOfExpense,
6068
vendorId,
6169
account,
62-
reimbursementProducts,
70+
otherReimbursementProducts,
71+
wbsReimbursementProducts,
6372
expenseTypeId,
6473
totalCost
6574
);
@@ -84,8 +93,16 @@ export default class ReimbursementRequestsController {
8493
static async editReimbursementRequest(req: Request, res: Response, next: NextFunction) {
8594
try {
8695
const { requestId } = req.params;
87-
const { dateOfExpense, vendorId, account, expenseTypeId, totalCost, reimbursementProducts, receiptPictures } =
88-
req.body;
96+
const {
97+
dateOfExpense,
98+
vendorId,
99+
account,
100+
expenseTypeId,
101+
totalCost,
102+
otherReimbursementProducts,
103+
wbsReimbursementProducts,
104+
receiptPictures
105+
} = req.body;
89106
const user = await getCurrentUser(res);
90107
const updatedReimbursementRequestId = await ReimbursementRequestService.editReimbursementRequest(
91108
requestId,
@@ -94,7 +111,8 @@ export default class ReimbursementRequestsController {
94111
account,
95112
expenseTypeId,
96113
totalCost,
97-
reimbursementProducts,
114+
otherReimbursementProducts,
115+
wbsReimbursementProducts,
98116
receiptPictures,
99117
user
100118
);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* This file is part of NER's FinishLine and licensed under GNU AGPLv3.
3+
* See the LICENSE file in the repository root folder for details.
4+
*/
5+
6+
import { Prisma } from '@prisma/client';
7+
8+
const materialTypeQueryArgs = Prisma.validator<Prisma.Material_TypeArgs>()({
9+
include: {
10+
materials: true
11+
}
12+
});
13+
14+
export default materialTypeQueryArgs;
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import { Prisma } from '@prisma/client';
22

3-
const reimbursementProductQueryArgs = Prisma.validator<Prisma.Reimbursement_ProductArgs>()({
3+
export const reimbursementProductReasonQueryArgs = Prisma.validator<Prisma.Reimbursement_Product_ReasonArgs>()({
44
include: {
55
wbsElement: true
66
}
77
});
88

9-
export default reimbursementProductQueryArgs;
9+
export const reimbursementProductQueryArgs = Prisma.validator<Prisma.Reimbursement_ProductArgs>()({
10+
include: {
11+
reimbursementProductReason: { ...reimbursementProductReasonQueryArgs }
12+
}
13+
});

src/backend/src/prisma-query-args/reimbursement-requests.query-args.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Prisma } from '@prisma/client';
2-
import reimbursementProductQueryArgs from './reimbursement-products.query-args';
32
import reimbursementStatusQueryArgs from './reimbursement-statuses.query-args';
43
import receiptQueryArgs from './receipt-query.args';
4+
import { reimbursementProductQueryArgs } from './reimbursement-products.query-args';
55

66
const reimbursementRequestQueryArgs = Prisma.validator<Prisma.Reimbursement_RequestArgs>()({
77
include: {
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
Warnings:
3+
4+
- You are about to drop the column `wbsElementId` on the `Reimbursement_Product` table. All the data in the column will be lost.
5+
- A unique constraint covering the columns `[reimbursementProductReasonId]` on the table `Reimbursement_Product` will be added. If there are existing duplicate values, this will fail.
6+
- Added the required column `reimbursementProductReasonId` to the `Reimbursement_Product` table without a default value. This is not possible if the table is not empty.
7+
8+
*/
9+
-- CreateEnum
10+
CREATE TYPE "Other_Reimbursement_Product_Reason" AS ENUM ('TOOLS_AND_EQUIPMENT', 'COMPETITION', 'CONSUMABLES', 'GENERAL_STOCK', 'SUBSCRIPTIONS_AND_MEMBERSHIPS');
11+
12+
-- AlterTable
13+
ALTER TABLE "Reimbursement_Product"
14+
ADD COLUMN "reimbursementProductReasonId" TEXT;
15+
16+
-- CreateTable
17+
CREATE TABLE "Reimbursement_Product_Reason" (
18+
"reimbursementProductReasonId" TEXT NOT NULL,
19+
"wbsElementId" INTEGER,
20+
"otherReason" "Other_Reimbursement_Product_Reason",
21+
"reimbursementProductId" TEXT,
22+
23+
CONSTRAINT "Reimbursement_Product_Reason_pkey" PRIMARY KEY ("reimbursementProductReasonId")
24+
);
25+
26+
INSERT INTO "Reimbursement_Product_Reason" ("reimbursementProductReasonId", "wbsElementId", "reimbursementProductId") SELECT gen_random_uuid(), "wbsElementId", "reimbursementProductId" FROM "Reimbursement_Product";
27+
28+
UPDATE "Reimbursement_Product"
29+
SET "reimbursementProductReasonId" = (
30+
SELECT "reimbursementProductReasonId"
31+
FROM "Reimbursement_Product_Reason"
32+
WHERE "Reimbursement_Product_Reason"."reimbursementProductId" = "Reimbursement_Product"."reimbursementProductId"
33+
);
34+
35+
-- CreateIndex
36+
CREATE UNIQUE INDEX "Reimbursement_Product_reimbursementProductReasonId_key" ON "Reimbursement_Product"("reimbursementProductReasonId");
37+
38+
39+
-- DropForeignKey
40+
ALTER TABLE "Reimbursement_Product" DROP CONSTRAINT "Reimbursement_Product_wbsElementId_fkey";
41+
42+
-- AlterTable
43+
ALTER TABLE "Reimbursement_Product" DROP COLUMN "wbsElementId";
44+
45+
-- AddForeignKey
46+
ALTER TABLE "Reimbursement_Product_Reason" ADD CONSTRAINT "Reimbursement_Product_Reason_wbsElementId_fkey" FOREIGN KEY ("wbsElementId") REFERENCES "WBS_Element"("wbsElementId") ON DELETE SET NULL ON UPDATE CASCADE;
47+
48+
-- AlterTable
49+
ALTER TABLE "Reimbursement_Product" ALTER COLUMN "reimbursementProductReasonId" SET NOT NULL;
50+
51+
-- AddForeignKey
52+
ALTER TABLE "Reimbursement_Product" ADD CONSTRAINT "Reimbursement_Product_reimbursementProductReasonId_fkey" FOREIGN KEY ("reimbursementProductReasonId") REFERENCES "Reimbursement_Product_Reason"("reimbursementProductReasonId") ON DELETE RESTRICT ON UPDATE CASCADE;
53+
54+
-- AlterTable
55+
ALTER TABLE "Reimbursement_Product_Reason"
56+
DROP COLUMN "reimbursementProductId";

src/backend/src/prisma/migrations/20231024124220_add_bom/migration.sql renamed to src/backend/src/prisma/migrations/20231119081759_add_bom/migration.sql

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ CREATE TABLE "Material" (
5151
CREATE TABLE "Material_Type" (
5252
"name" TEXT NOT NULL,
5353
"dateCreated" TIMESTAMP(3) NOT NULL,
54+
"dateDeleted" TIMESTAMP(3),
5455
"creatorId" INTEGER NOT NULL,
5556

5657
CONSTRAINT "Material_Type_pkey" PRIMARY KEY ("name")
@@ -61,16 +62,14 @@ CREATE TABLE "Manufacturer" (
6162
"name" TEXT NOT NULL,
6263
"dateCreated" TIMESTAMP(3) NOT NULL,
6364
"creatorId" INTEGER NOT NULL,
65+
"dateDeleted" TIMESTAMP(3),
6466

6567
CONSTRAINT "Manufacturer_pkey" PRIMARY KEY ("name")
6668
);
6769

6870
-- CreateIndex
6971
CREATE UNIQUE INDEX "Assembly_name_key" ON "Assembly"("name");
7072

71-
-- CreateIndex
72-
CREATE UNIQUE INDEX "Material_name_key" ON "Material"("name");
73-
7473
-- AddForeignKey
7574
ALTER TABLE "Assembly" ADD CONSTRAINT "Assembly_userDeletedId_fkey" FOREIGN KEY ("userDeletedId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE;
7675

0 commit comments

Comments
 (0)