From 805c2db57cf029a98625b127fe88498585866629 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Tue, 21 Jan 2025 23:44:13 -0500 Subject: [PATCH 1/7] #3128: schema changes + migration + necessary backend changes --- .../reimbursement-requests.controllers.ts | 42 ++++++++- .../migration.sql | 93 +++++++++++++++++++ .../migration.sql | 60 ++++++++++++ src/backend/src/prisma/schema.prisma | 82 +++++++++++----- src/backend/src/prisma/seed.ts | 75 +++++++++++++-- src/backend/src/services/boms.services.ts | 4 +- .../reimbursement-requests.services.ts | 50 +++++++++- src/backend/tests/test-utils.ts | 22 ++++- 8 files changed, 391 insertions(+), 37 deletions(-) create mode 100644 src/backend/src/prisma/migrations/20250121204318_finance_redesign/migration.sql create mode 100644 src/backend/src/prisma/migrations/20250121220220_finance_redesign/migration.sql diff --git a/src/backend/src/controllers/reimbursement-requests.controllers.ts b/src/backend/src/controllers/reimbursement-requests.controllers.ts index cce6bc34c7..4da93332f6 100644 --- a/src/backend/src/controllers/reimbursement-requests.controllers.ts +++ b/src/backend/src/controllers/reimbursement-requests.controllers.ts @@ -200,8 +200,46 @@ export default class ReimbursementRequestsController { static async createVendor(req: Request, res: Response, next: NextFunction) { try { - const { name } = req.body; - const createdVendor = await ReimbursementRequestService.createVendor(req.currentUser, name, req.organization); + const { + name, + username, + password, + discountCode, + twoFactorContact, + notes, + addedByUserId, + status, + contacts, + tier, + value, + joinDate, + activeYears, + taxExempt, + dueDate, + notifyDate, + assignToUserId + } = req.body; + const createdVendor = await ReimbursementRequestService.createVendor( + req.currentUser, + name, + req.organization, + username, + password, + discountCode, + twoFactorContact, + notes, + addedByUserId, + status, + contacts, + tier, + value, + joinDate, + activeYears, + taxExempt, + dueDate, + notifyDate, + assignToUserId + ); res.status(200).json(createdVendor); } catch (error: unknown) { next(error); diff --git a/src/backend/src/prisma/migrations/20250121204318_finance_redesign/migration.sql b/src/backend/src/prisma/migrations/20250121204318_finance_redesign/migration.sql new file mode 100644 index 0000000000..35a666867c --- /dev/null +++ b/src/backend/src/prisma/migrations/20250121204318_finance_redesign/migration.sql @@ -0,0 +1,93 @@ +/* + Warnings: + + - Added the required column `reimbursementNumber` to the `Material` table without a default value. This is not possible if the table is not empty. + - Added the required column `activeYears` to the `Vendor` table without a default value. This is not possible if the table is not empty. + - Added the required column `addedByUserId` to the `Vendor` table without a default value. This is not possible if the table is not empty. + - Added the required column `assignToUserId` to the `Vendor` table without a default value. This is not possible if the table is not empty. + - Added the required column `contacts` to the `Vendor` table without a default value. This is not possible if the table is not empty. + - Added the required column `discountCode` to the `Vendor` table without a default value. This is not possible if the table is not empty. + - Added the required column `dueDate` to the `Vendor` table without a default value. This is not possible if the table is not empty. + - Added the required column `joinDate` to the `Vendor` table without a default value. This is not possible if the table is not empty. + - Added the required column `notes` to the `Vendor` table without a default value. This is not possible if the table is not empty. + - Added the required column `notifyDate` to the `Vendor` table without a default value. This is not possible if the table is not empty. + - Added the required column `password` to the `Vendor` table without a default value. This is not possible if the table is not empty. + - Added the required column `status` to the `Vendor` table without a default value. This is not possible if the table is not empty. + - Added the required column `taxExempt` to the `Vendor` table without a default value. This is not possible if the table is not empty. + - Added the required column `tier` to the `Vendor` table without a default value. This is not possible if the table is not empty. + - Added the required column `twoFactorContact` to the `Vendor` table without a default value. This is not possible if the table is not empty. + - Added the required column `username` to the `Vendor` table without a default value. This is not possible if the table is not empty. + - Added the required column `value` to the `Vendor` table without a default value. This is not possible if the table is not empty. + +*/ +-- CreateEnum +CREATE TYPE "Sponsor_Status" AS ENUM ('ACTIVE', 'INACTIVE'); + +-- CreateEnum +CREATE TYPE "Sponsor_Tier" AS ENUM ('GOLD', 'SILVER', 'BRONZE'); + +-- AlterTable +ALTER TABLE "Material" ADD COLUMN "reimbursementNumber" TEXT NOT NULL DEFAULT ''; + +-- AlterTable +ALTER TABLE "Vendor" ADD COLUMN "activeYears" INTEGER NOT NULL DEFAULT 0, +ADD COLUMN "addedByUserId" TEXT NOT NULL DEFAULT '', +ADD COLUMN "assignToUserId" TEXT NOT NULL DEFAULT '', +ADD COLUMN "contacts" TEXT NOT NULL DEFAULT '', +ADD COLUMN "discountCode" TEXT NOT NULL DEFAULT '', +ADD COLUMN "dueDate" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), +ADD COLUMN "joinDate" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), +ADD COLUMN "notes" TEXT NOT NULL DEFAULT '', +ADD COLUMN "notifyDate" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), +ADD COLUMN "password" TEXT NOT NULL DEFAULT '', +ADD COLUMN "status" "Sponsor_Status" NOT NULL DEFAULT 'ACTIVE', +ADD COLUMN "taxExempt" BOOLEAN NOT NULL DEFAULT TRUE, +ADD COLUMN "tier" "Sponsor_Tier" NOT NULL DEFAULT 'BRONZE', +ADD COLUMN "twoFactorContact" TEXT NOT NULL DEFAULT '', +ADD COLUMN "username" TEXT NOT NULL DEFAULT '', +ADD COLUMN "value" INTEGER NOT NULL DEFAULT 0; + +-- CreateTable +CREATE TABLE "_ProjectToReimbursement_Request" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL +); + +-- CreateIndex +CREATE UNIQUE INDEX "_ProjectToReimbursement_Request_AB_unique" ON "_ProjectToReimbursement_Request"("A", "B"); + +-- CreateIndex +CREATE INDEX "_ProjectToReimbursement_Request_B_index" ON "_ProjectToReimbursement_Request"("B"); + +-- AddForeignKey +ALTER TABLE "Vendor" ADD CONSTRAINT "Vendor_addedByUserId_fkey" FOREIGN KEY ("addedByUserId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Vendor" ADD CONSTRAINT "Vendor_assignToUserId_fkey" FOREIGN KEY ("assignToUserId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Material" ADD CONSTRAINT "Material_reimbursementNumber_fkey" FOREIGN KEY ("reimbursementNumber") REFERENCES "Reimbursement_Request"("reimbursementRequestId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_ProjectToReimbursement_Request" ADD CONSTRAINT "_ProjectToReimbursement_Request_A_fkey" FOREIGN KEY ("A") REFERENCES "Project"("projectId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_ProjectToReimbursement_Request" ADD CONSTRAINT "_ProjectToReimbursement_Request_B_fkey" FOREIGN KEY ("B") REFERENCES "Reimbursement_Request"("reimbursementRequestId") ON DELETE CASCADE ON UPDATE CASCADE; + +ALTER TABLE "_ProjectToReimbursement_Request" RENAME COLUMN "A" TO "projectId"; + +ALTER TABLE "_ProjectToReimbursement_Request" RENAME COLUMN "B" TO "reimbursementRequestId"; + +INSERT INTO "_ProjectToReimbursement_Request" ("projectId", "reimbursementRequestId") + +SELECT DISTINCT Project."projectId" as "projectId", "Reimbursement_Request"."reimbursementRequestId" as "reimbursementRequestId" + +FROM "Reimbursement_Request" + +JOIN "Reimbursement_Product" reimbursementProduct ON "Reimbursement_Request"."reimbursementRequestId" = reimbursementProduct."reimbursementRequestId" + +JOIN "Reimbursement_Product_Reason" reimbursementProductReason ON reimbursementProduct."reimbursementProductReasonId" = reimbursementProductReason."reimbursementProductReasonId" + +JOIN "WBS_Element" wbs_element ON reimbursementProductReason."wbsElementId" = wbs_element."wbsElementId" + +JOIN "Project" project ON project."wbsElementId" = wbs_element."wbsElementId" \ No newline at end of file diff --git a/src/backend/src/prisma/migrations/20250121220220_finance_redesign/migration.sql b/src/backend/src/prisma/migrations/20250121220220_finance_redesign/migration.sql new file mode 100644 index 0000000000..0c0f11cb3c --- /dev/null +++ b/src/backend/src/prisma/migrations/20250121220220_finance_redesign/migration.sql @@ -0,0 +1,60 @@ +/* + Warnings: + + - You are about to drop the column `projectId` on the `_ProjectToReimbursement_Request` table. All the data in the column will be lost. + - You are about to drop the column `reimbursementRequestId` on the `_ProjectToReimbursement_Request` table. All the data in the column will be lost. + - A unique constraint covering the columns `[A,B]` on the table `_ProjectToReimbursement_Request` will be added. If there are existing duplicate values, this will fail. + - Added the required column `A` to the `_ProjectToReimbursement_Request` table without a default value. This is not possible if the table is not empty. + - Added the required column `B` to the `_ProjectToReimbursement_Request` table without a default value. This is not possible if the table is not empty. + +*/ +-- DropForeignKey +ALTER TABLE "_ProjectToReimbursement_Request" DROP CONSTRAINT "_ProjectToReimbursement_Request_A_fkey"; + +-- DropForeignKey +ALTER TABLE "_ProjectToReimbursement_Request" DROP CONSTRAINT "_ProjectToReimbursement_Request_B_fkey"; + +-- DropIndex +DROP INDEX "_ProjectToReimbursement_Request_AB_unique"; + +-- DropIndex +DROP INDEX "_ProjectToReimbursement_Request_B_index"; + +-- AlterTable +ALTER TABLE "Material" ALTER COLUMN "reimbursementNumber" DROP DEFAULT; + +-- AlterTable +ALTER TABLE "Vendor" ALTER COLUMN "activeYears" DROP DEFAULT, +ALTER COLUMN "addedByUserId" DROP DEFAULT, +ALTER COLUMN "assignToUserId" DROP DEFAULT, +ALTER COLUMN "contacts" DROP DEFAULT, +ALTER COLUMN "discountCode" DROP DEFAULT, +ALTER COLUMN "dueDate" DROP DEFAULT, +ALTER COLUMN "joinDate" DROP DEFAULT, +ALTER COLUMN "notes" DROP DEFAULT, +ALTER COLUMN "notifyDate" DROP DEFAULT, +ALTER COLUMN "password" DROP DEFAULT, +ALTER COLUMN "status" DROP DEFAULT, +ALTER COLUMN "taxExempt" DROP DEFAULT, +ALTER COLUMN "tier" DROP DEFAULT, +ALTER COLUMN "twoFactorContact" DROP DEFAULT, +ALTER COLUMN "username" DROP DEFAULT, +ALTER COLUMN "value" DROP DEFAULT; + +-- AlterTable +ALTER TABLE "_ProjectToReimbursement_Request" DROP COLUMN "projectId", +DROP COLUMN "reimbursementRequestId", +ADD COLUMN "A" TEXT NOT NULL, +ADD COLUMN "B" TEXT NOT NULL; + +-- CreateIndex +CREATE UNIQUE INDEX "_ProjectToReimbursement_Request_AB_unique" ON "_ProjectToReimbursement_Request"("A", "B"); + +-- CreateIndex +CREATE INDEX "_ProjectToReimbursement_Request_B_index" ON "_ProjectToReimbursement_Request"("B"); + +-- AddForeignKey +ALTER TABLE "_ProjectToReimbursement_Request" ADD CONSTRAINT "_ProjectToReimbursement_Request_A_fkey" FOREIGN KEY ("A") REFERENCES "Project"("projectId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_ProjectToReimbursement_Request" ADD CONSTRAINT "_ProjectToReimbursement_Request_B_fkey" FOREIGN KEY ("B") REFERENCES "Reimbursement_Request"("reimbursementRequestId") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 12416a4a91..e4f681a1bb 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -151,6 +151,17 @@ enum Special_Permission { FINANCE_ONLY } +enum Sponsor_Status { + ACTIVE + INACTIVE +} + +enum Sponsor_Tier { + GOLD + SILVER + BRONZE +} + model User { userId String @id @default(uuid()) firstName String @@ -230,6 +241,8 @@ model User { deletedTeamTypes Team_Type[] @relation(name: "teamTypeDeleter") unreadAnnouncements Announcement[] @relation(name: "receivedAnnouncements") unreadPopUps PopUp[] @relation(name: "userPopUps") + vendorsAdded Vendor[] @relation(name: "vendorsCreator") + vendorsAssigned Vendor[] @relation(name: "assignedVendors") } model Role { @@ -432,18 +445,19 @@ model WBS_Element { } model Project { - projectId String @id @default(uuid()) - wbsElementId String @unique - wbsElement WBS_Element @relation(fields: [wbsElementId], references: [wbsElementId]) - budget Int @default(0) + projectId String @id @default(uuid()) + wbsElementId String @unique + wbsElement WBS_Element @relation(fields: [wbsElementId], references: [wbsElementId]) + budget Int @default(0) summary String workPackages Work_Package[] carId String - car Car @relation(fields: [carId], references: [carId]) - teams Team[] @relation(name: "assignedBy") - favoritedBy User[] @relation(name: "favoritedBy") + car Car @relation(fields: [carId], references: [carId]) + teams Team[] @relation(name: "assignedBy") + favoritedBy User[] @relation(name: "favoritedBy") featuredByOrganizationId String? - featuredByOrganization Organization? @relation(fields: [featuredByOrganizationId], references: [organizationId]) + featuredByOrganization Organization? @relation(fields: [featuredByOrganizationId], references: [organizationId]) + reimbursementRequests Reimbursement_Request[] } model Work_Package { @@ -596,6 +610,8 @@ model Reimbursement_Request { organizationId String organization Organization @relation(fields: [organizationId], references: [organizationId]) notificationSlackThreads Message_Info[] + materials Material[] + projects Project[] @@unique([identifier, organizationId], name: "uniqueReimbursementRequest") } @@ -622,13 +638,31 @@ model Reimbursement_Product { } model Vendor { - vendorId String @id @default(uuid()) - dateCreated DateTime @default(now()) - dateDeleted DateTime? - name String - requests Reimbursement_Request[] - organizationId String - organization Organization @relation(fields: [organizationId], references: [organizationId]) + vendorId String @id @default(uuid()) + dateCreated DateTime @default(now()) + dateDeleted DateTime? + name String + requests Reimbursement_Request[] + organizationId String + organization Organization @relation(fields: [organizationId], references: [organizationId]) + username String + password String + discountCode String + twoFactorContact String + notes String + addedBy User @relation(fields: [addedByUserId], references: [userId], name: "vendorsCreator") + addedByUserId String + status Sponsor_Status + contacts String + tier Sponsor_Tier + value Int + joinDate DateTime + activeYears Int + taxExempt Boolean + dueDate DateTime + notifyDate DateTime + assignTo User @relation(fields: [assignToUserId], references: [userId], name: "assignedVendors") + assignToUserId String @@unique([name, organizationId], name: "uniqueVendor") } @@ -700,32 +734,34 @@ model Assembly { } model Material { - materialId String @id @default(uuid()) - assembly Assembly? @relation(fields: [assemblyId], references: [assemblyId]) + materialId String @id @default(uuid()) + assembly Assembly? @relation(fields: [assemblyId], references: [assemblyId]) assemblyId String? name String - wbsElement WBS_Element @relation(fields: [wbsElementId], references: [wbsElementId]) + wbsElement WBS_Element @relation(fields: [wbsElementId], references: [wbsElementId]) wbsElementId String dateDeleted DateTime? - userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "materialDeleter") + userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "materialDeleter") userDeletedId String? dateCreated DateTime - userCreated User @relation(fields: [userCreatedId], references: [userId], name: "materialCreator") + userCreated User @relation(fields: [userCreatedId], references: [userId], name: "materialCreator") userCreatedId String status Material_Status - materialType Material_Type @relation(fields: [materialTypeId], references: [id]) + materialType Material_Type @relation(fields: [materialTypeId], references: [id]) materialTypeId String - manufacturer Manufacturer @relation(fields: [manufacturerId], references: [id]) + manufacturer Manufacturer @relation(fields: [manufacturerId], references: [id]) manufacturerId String manufacturerPartNumber String pdmFileName String? quantity Decimal - unit Unit? @relation(fields: [unitId], references: [id]) + unit Unit? @relation(fields: [unitId], references: [id]) unitId String? price Int subtotal Int linkUrl String notes String? + reimbursementRequest Reimbursement_Request @relation(fields: [reimbursementNumber], references: [reimbursementRequestId]) + reimbursementNumber String } model Material_Type { diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index ef0916a162..6dcd7934ef 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -1676,9 +1676,69 @@ const performSeed: () => Promise = async () => { * Reimbursements */ - const vendor = await ReimbursementRequestService.createVendor(thomasEmrax, 'Tesla', ner); - await ReimbursementRequestService.createVendor(thomasEmrax, 'Amazon', ner); - await ReimbursementRequestService.createVendor(thomasEmrax, 'Google', ner); + const vendor = await ReimbursementRequestService.createVendor( + thomasEmrax, + 'Tesla', + ner, + 'nershipping@gmail.com', + 'racecar228!', + 'SAVE50!', + 'Alex L.', + 'Tax exemption status?', + thomasEmrax.userId, + 'ACTIVE', + 'Jeni Hankon', + 'BRONZE', + 550, + new Date('2023-11-23T00:00:00-04:00'), + 3, + true, + new Date('2024-11-23T00:00:00-04:00'), + new Date('2024-01-15T00:00:00-04:00'), + regina.userId + ); + await ReimbursementRequestService.createVendor( + thomasEmrax, + 'Amazon', + ner, + 'amazon@gmail.com', + 'racecare228!', + 'SAVE20!', + 'Richard F.', + 'They want updates on work', + thomasEmrax.userId, + 'INACTIVE', + 'Rob', + 'SILVER', + 1500, + new Date('2023-11-23T00:00:00-04:00'), + 5, + true, + new Date('2024-11-23T00:00:00-04:00'), + new Date('2024-01-23T00:00:00-04:00'), + thomasEmrax.userId + ); + await ReimbursementRequestService.createVendor( + thomasEmrax, + 'Google', + ner, + 'google@gmail.com', + 'racecar228!', + 'SAVE50!', + 'Peyton', + 'Tax exemption ID NUMBER', + thomasEmrax.userId, + 'ACTIVE', + 'Boris P.', + 'GOLD', + 30000, + new Date('2021-11-25T00:00:00-04:00'), + 2, + true, + new Date('2022-11-25T00:00:00-04:00'), + new Date('2023-01-25T00:00:00-04:00'), + thomasEmrax.userId + ); const accountCode = await ReimbursementRequestService.createAccountCode( thomasEmrax, @@ -1689,7 +1749,7 @@ const performSeed: () => Promise = async () => { ner ); - await ReimbursementRequestService.createReimbursementRequest( + const reimbursement1 = await ReimbursementRequestService.createReimbursementRequest( thomasEmrax, vendor.vendorId, ClubAccount.CASH, @@ -1710,7 +1770,7 @@ const performSeed: () => Promise = async () => { ner ); - await ReimbursementRequestService.createReimbursementRequest( + const reimbursement2 = await ReimbursementRequestService.createReimbursementRequest( thomasEmrax, vendor.vendorId, ClubAccount.BUDGET, @@ -1766,6 +1826,7 @@ const performSeed: () => Promise = async () => { workPackageNumber: 0 }, ner, + reimbursement1.reimbursementRequestId, 'Here are some notes' ); @@ -1786,8 +1847,8 @@ const performSeed: () => Promise = async () => { workPackageNumber: 0 }, ner, - 'Here are some more notes', - assembly1.assemblyId + reimbursement2.reimbursementRequestId, + 'Here are some more notes' ); // Need to do this because the design review cannot be scheduled for a past day diff --git a/src/backend/src/services/boms.services.ts b/src/backend/src/services/boms.services.ts index 3c8209651e..95c2b11598 100644 --- a/src/backend/src/services/boms.services.ts +++ b/src/backend/src/services/boms.services.ts @@ -65,6 +65,7 @@ export default class BillOfMaterialsService { linkUrl: string, wbsNumber: WbsNumber, organization: Organization, + reimbursementNumber: string, notes?: string, assemblyId?: string, pdmFileName?: string, @@ -122,7 +123,8 @@ export default class BillOfMaterialsService { linkUrl, notes, dateCreated: new Date(), - wbsElementId: project.wbsElementId + wbsElementId: project.wbsElementId, + reimbursementNumber } }); diff --git a/src/backend/src/services/reimbursement-requests.services.ts b/src/backend/src/services/reimbursement-requests.services.ts index 6f7052106c..0ef6debcd5 100644 --- a/src/backend/src/services/reimbursement-requests.services.ts +++ b/src/backend/src/services/reimbursement-requests.services.ts @@ -4,7 +4,15 @@ */ // eslint-disable-next-line @typescript-eslint/no-unused-vars -import { Club_Accounts, Reimbursement_Request, Reimbursement_Status_Type, User, Organization } from '@prisma/client'; +import { + Club_Accounts, + Reimbursement_Request, + Reimbursement_Status_Type, + User, + Organization, + Sponsor_Status, + Sponsor_Tier +} from '@prisma/client'; import { ClubAccount, Reimbursement, @@ -558,7 +566,27 @@ export default class ReimbursementRequestService { * @param organizationId the organization the user is currently in * @returns the created vendor */ - static async createVendor(submitter: User, name: string, organization: Organization) { + static async createVendor( + submitter: User, + name: string, + organization: Organization, + username: string, + password: string, + discountCode: string, + twoFactorContact: string, + notes: string, + addedByUserId: string, + status: Sponsor_Status, + contacts: string, + tier: Sponsor_Tier, + value: number, + joinDate: Date, + activeYears: number, + taxExempt: boolean, + dueDate: Date, + notifyDate: Date, + assignToUserId: string + ) { const isAuthorized = (await userHasPermission(submitter.userId, organization.organizationId, isAdmin)) || (await isUserLeadOrHeadOfFinanceTeam(submitter, organization.organizationId)); @@ -579,7 +607,23 @@ export default class ReimbursementRequestService { const vendor = await prisma.vendor.create({ data: { name, - organizationId: organization.organizationId + organizationId: organization.organizationId, + username, + password, + discountCode, + twoFactorContact, + notes, + addedByUserId, + status, + contacts, + tier, + value, + joinDate, + activeYears, + taxExempt, + dueDate, + notifyDate, + assignToUserId } }); diff --git a/src/backend/tests/test-utils.ts b/src/backend/tests/test-utils.ts index 0665047826..e569434e68 100644 --- a/src/backend/tests/test-utils.ts +++ b/src/backend/tests/test-utils.ts @@ -393,7 +393,27 @@ export const createTestReimbursementRequest = async () => { const project = await createTestProject(user, organization.organizationId); - const vendor = await ReimbursementRequestService.createVendor(user, 'Tesla', organization); + const vendor = await ReimbursementRequestService.createVendor( + user, + 'Tesla', + organization, + 'nershipping@gmail.com', + 'racecar228!', + 'SAVE50!', + 'Alex L.', + 'Tax exemption status?', + user.userId, + 'ACTIVE', + 'Jeni Hankon', + 'BRONZE', + 550, + new Date('2023-11-23T00:00:00-04:00'), + 3, + true, + new Date('2024-11-23T00:00:00-04:00'), + new Date('2024-01-23T00:00:00-04:00'), + user.userId + ); const accountCode = await ReimbursementRequestService.createAccountCode( user, From 8c1aa30683b79a6f302383f63b218c7f31f0ec5e Mon Sep 17 00:00:00 2001 From: wavehassman Date: Wed, 22 Jan 2025 16:29:22 -0500 Subject: [PATCH 2/7] sponsor tier is now a table not enum --- .../migration.sql | 60 ------------------- .../migration.sql | 44 +++++--------- src/backend/src/prisma/schema.prisma | 15 ++--- src/backend/src/prisma/seed.ts | 13 +++- .../reimbursement-requests.services.ts | 2 +- src/backend/tests/test-utils.ts | 8 ++- 6 files changed, 41 insertions(+), 101 deletions(-) delete mode 100644 src/backend/src/prisma/migrations/20250121220220_finance_redesign/migration.sql rename src/backend/src/prisma/migrations/{20250121204318_finance_redesign => 20250122205420_finance_redesign}/migration.sql (55%) diff --git a/src/backend/src/prisma/migrations/20250121220220_finance_redesign/migration.sql b/src/backend/src/prisma/migrations/20250121220220_finance_redesign/migration.sql deleted file mode 100644 index 0c0f11cb3c..0000000000 --- a/src/backend/src/prisma/migrations/20250121220220_finance_redesign/migration.sql +++ /dev/null @@ -1,60 +0,0 @@ -/* - Warnings: - - - You are about to drop the column `projectId` on the `_ProjectToReimbursement_Request` table. All the data in the column will be lost. - - You are about to drop the column `reimbursementRequestId` on the `_ProjectToReimbursement_Request` table. All the data in the column will be lost. - - A unique constraint covering the columns `[A,B]` on the table `_ProjectToReimbursement_Request` will be added. If there are existing duplicate values, this will fail. - - Added the required column `A` to the `_ProjectToReimbursement_Request` table without a default value. This is not possible if the table is not empty. - - Added the required column `B` to the `_ProjectToReimbursement_Request` table without a default value. This is not possible if the table is not empty. - -*/ --- DropForeignKey -ALTER TABLE "_ProjectToReimbursement_Request" DROP CONSTRAINT "_ProjectToReimbursement_Request_A_fkey"; - --- DropForeignKey -ALTER TABLE "_ProjectToReimbursement_Request" DROP CONSTRAINT "_ProjectToReimbursement_Request_B_fkey"; - --- DropIndex -DROP INDEX "_ProjectToReimbursement_Request_AB_unique"; - --- DropIndex -DROP INDEX "_ProjectToReimbursement_Request_B_index"; - --- AlterTable -ALTER TABLE "Material" ALTER COLUMN "reimbursementNumber" DROP DEFAULT; - --- AlterTable -ALTER TABLE "Vendor" ALTER COLUMN "activeYears" DROP DEFAULT, -ALTER COLUMN "addedByUserId" DROP DEFAULT, -ALTER COLUMN "assignToUserId" DROP DEFAULT, -ALTER COLUMN "contacts" DROP DEFAULT, -ALTER COLUMN "discountCode" DROP DEFAULT, -ALTER COLUMN "dueDate" DROP DEFAULT, -ALTER COLUMN "joinDate" DROP DEFAULT, -ALTER COLUMN "notes" DROP DEFAULT, -ALTER COLUMN "notifyDate" DROP DEFAULT, -ALTER COLUMN "password" DROP DEFAULT, -ALTER COLUMN "status" DROP DEFAULT, -ALTER COLUMN "taxExempt" DROP DEFAULT, -ALTER COLUMN "tier" DROP DEFAULT, -ALTER COLUMN "twoFactorContact" DROP DEFAULT, -ALTER COLUMN "username" DROP DEFAULT, -ALTER COLUMN "value" DROP DEFAULT; - --- AlterTable -ALTER TABLE "_ProjectToReimbursement_Request" DROP COLUMN "projectId", -DROP COLUMN "reimbursementRequestId", -ADD COLUMN "A" TEXT NOT NULL, -ADD COLUMN "B" TEXT NOT NULL; - --- CreateIndex -CREATE UNIQUE INDEX "_ProjectToReimbursement_Request_AB_unique" ON "_ProjectToReimbursement_Request"("A", "B"); - --- CreateIndex -CREATE INDEX "_ProjectToReimbursement_Request_B_index" ON "_ProjectToReimbursement_Request"("B"); - --- AddForeignKey -ALTER TABLE "_ProjectToReimbursement_Request" ADD CONSTRAINT "_ProjectToReimbursement_Request_A_fkey" FOREIGN KEY ("A") REFERENCES "Project"("projectId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_ProjectToReimbursement_Request" ADD CONSTRAINT "_ProjectToReimbursement_Request_B_fkey" FOREIGN KEY ("B") REFERENCES "Reimbursement_Request"("reimbursementRequestId") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/src/backend/src/prisma/migrations/20250121204318_finance_redesign/migration.sql b/src/backend/src/prisma/migrations/20250122205420_finance_redesign/migration.sql similarity index 55% rename from src/backend/src/prisma/migrations/20250121204318_finance_redesign/migration.sql rename to src/backend/src/prisma/migrations/20250122205420_finance_redesign/migration.sql index 35a666867c..9dd25b4935 100644 --- a/src/backend/src/prisma/migrations/20250121204318_finance_redesign/migration.sql +++ b/src/backend/src/prisma/migrations/20250122205420_finance_redesign/migration.sql @@ -1,33 +1,8 @@ -/* - Warnings: - - - Added the required column `reimbursementNumber` to the `Material` table without a default value. This is not possible if the table is not empty. - - Added the required column `activeYears` to the `Vendor` table without a default value. This is not possible if the table is not empty. - - Added the required column `addedByUserId` to the `Vendor` table without a default value. This is not possible if the table is not empty. - - Added the required column `assignToUserId` to the `Vendor` table without a default value. This is not possible if the table is not empty. - - Added the required column `contacts` to the `Vendor` table without a default value. This is not possible if the table is not empty. - - Added the required column `discountCode` to the `Vendor` table without a default value. This is not possible if the table is not empty. - - Added the required column `dueDate` to the `Vendor` table without a default value. This is not possible if the table is not empty. - - Added the required column `joinDate` to the `Vendor` table without a default value. This is not possible if the table is not empty. - - Added the required column `notes` to the `Vendor` table without a default value. This is not possible if the table is not empty. - - Added the required column `notifyDate` to the `Vendor` table without a default value. This is not possible if the table is not empty. - - Added the required column `password` to the `Vendor` table without a default value. This is not possible if the table is not empty. - - Added the required column `status` to the `Vendor` table without a default value. This is not possible if the table is not empty. - - Added the required column `taxExempt` to the `Vendor` table without a default value. This is not possible if the table is not empty. - - Added the required column `tier` to the `Vendor` table without a default value. This is not possible if the table is not empty. - - Added the required column `twoFactorContact` to the `Vendor` table without a default value. This is not possible if the table is not empty. - - Added the required column `username` to the `Vendor` table without a default value. This is not possible if the table is not empty. - - Added the required column `value` to the `Vendor` table without a default value. This is not possible if the table is not empty. - -*/ -- CreateEnum CREATE TYPE "Sponsor_Status" AS ENUM ('ACTIVE', 'INACTIVE'); --- CreateEnum -CREATE TYPE "Sponsor_Tier" AS ENUM ('GOLD', 'SILVER', 'BRONZE'); - -- AlterTable -ALTER TABLE "Material" ADD COLUMN "reimbursementNumber" TEXT NOT NULL DEFAULT ''; +ALTER TABLE "Material" ADD COLUMN "reimbursementNumber" TEXT NOT NULL; -- AlterTable ALTER TABLE "Vendor" ADD COLUMN "activeYears" INTEGER NOT NULL DEFAULT 0, @@ -40,13 +15,21 @@ ADD COLUMN "joinDate" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), ADD COLUMN "notes" TEXT NOT NULL DEFAULT '', ADD COLUMN "notifyDate" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), ADD COLUMN "password" TEXT NOT NULL DEFAULT '', -ADD COLUMN "status" "Sponsor_Status" NOT NULL DEFAULT 'ACTIVE', -ADD COLUMN "taxExempt" BOOLEAN NOT NULL DEFAULT TRUE, -ADD COLUMN "tier" "Sponsor_Tier" NOT NULL DEFAULT 'BRONZE', +ADD COLUMN "sponsor_TierId" TEXT NOT NULL DEFAULT '', +ADD COLUMN "status" "Sponsor_Status" NOT NULL DEFAULT 'ACTIVE', +ADD COLUMN "taxExempt" BOOLEAN NOT NULL DEFAULT TRUE, ADD COLUMN "twoFactorContact" TEXT NOT NULL DEFAULT '', ADD COLUMN "username" TEXT NOT NULL DEFAULT '', ADD COLUMN "value" INTEGER NOT NULL DEFAULT 0; +-- CreateTable +CREATE TABLE "Sponsor_Tier" ( + "id" TEXT NOT NULL, + "name" TEXT NOT NULL, + + CONSTRAINT "Sponsor_Tier_pkey" PRIMARY KEY ("id") +); + -- CreateTable CREATE TABLE "_ProjectToReimbursement_Request" ( "A" TEXT NOT NULL, @@ -62,6 +45,9 @@ CREATE INDEX "_ProjectToReimbursement_Request_B_index" ON "_ProjectToReimburseme -- AddForeignKey ALTER TABLE "Vendor" ADD CONSTRAINT "Vendor_addedByUserId_fkey" FOREIGN KEY ("addedByUserId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; +-- AddForeignKey +ALTER TABLE "Vendor" ADD CONSTRAINT "Vendor_sponsor_TierId_fkey" FOREIGN KEY ("sponsor_TierId") REFERENCES "Sponsor_Tier"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + -- AddForeignKey ALTER TABLE "Vendor" ADD CONSTRAINT "Vendor_assignToUserId_fkey" FOREIGN KEY ("assignToUserId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index e4f681a1bb..9549d180fc 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -156,12 +156,6 @@ enum Sponsor_Status { INACTIVE } -enum Sponsor_Tier { - GOLD - SILVER - BRONZE -} - model User { userId String @id @default(uuid()) firstName String @@ -654,7 +648,8 @@ model Vendor { addedByUserId String status Sponsor_Status contacts String - tier Sponsor_Tier + tier Sponsor_Tier @relation(fields: [sponsor_TierId], references: [id]) + sponsor_TierId String value Int joinDate DateTime activeYears Int @@ -1088,3 +1083,9 @@ model PopUp { organizationId String organization Organization @relation(fields: [organizationId], references: [organizationId]) } + +model Sponsor_Tier { + id String @id @default(uuid()) + name String + vendors Vendor[] +} diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 6dcd7934ef..00b321016d 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -1676,6 +1676,13 @@ const performSeed: () => Promise = async () => { * Reimbursements */ + const tier = await prisma.sponsor_Tier.create({ + data: { + id: '0', + name: 'BRONZE' + } + }); + const vendor = await ReimbursementRequestService.createVendor( thomasEmrax, 'Tesla', @@ -1688,7 +1695,7 @@ const performSeed: () => Promise = async () => { thomasEmrax.userId, 'ACTIVE', 'Jeni Hankon', - 'BRONZE', + tier, 550, new Date('2023-11-23T00:00:00-04:00'), 3, @@ -1709,7 +1716,7 @@ const performSeed: () => Promise = async () => { thomasEmrax.userId, 'INACTIVE', 'Rob', - 'SILVER', + tier, 1500, new Date('2023-11-23T00:00:00-04:00'), 5, @@ -1730,7 +1737,7 @@ const performSeed: () => Promise = async () => { thomasEmrax.userId, 'ACTIVE', 'Boris P.', - 'GOLD', + tier, 30000, new Date('2021-11-25T00:00:00-04:00'), 2, diff --git a/src/backend/src/services/reimbursement-requests.services.ts b/src/backend/src/services/reimbursement-requests.services.ts index 0ef6debcd5..472f758425 100644 --- a/src/backend/src/services/reimbursement-requests.services.ts +++ b/src/backend/src/services/reimbursement-requests.services.ts @@ -616,7 +616,7 @@ export default class ReimbursementRequestService { addedByUserId, status, contacts, - tier, + sponsor_TierId: tier.id, value, joinDate, activeYears, diff --git a/src/backend/tests/test-utils.ts b/src/backend/tests/test-utils.ts index e569434e68..f472ad45d5 100644 --- a/src/backend/tests/test-utils.ts +++ b/src/backend/tests/test-utils.ts @@ -393,6 +393,12 @@ export const createTestReimbursementRequest = async () => { const project = await createTestProject(user, organization.organizationId); + const tier = await prisma.sponsor_Tier.create({ + data: { + name: 'GOLD' + } + }); + const vendor = await ReimbursementRequestService.createVendor( user, 'Tesla', @@ -405,7 +411,7 @@ export const createTestReimbursementRequest = async () => { user.userId, 'ACTIVE', 'Jeni Hankon', - 'BRONZE', + tier, 550, new Date('2023-11-23T00:00:00-04:00'), 3, From 20c81b9443c4f20d3632bd4126638846258c0ade Mon Sep 17 00:00:00 2001 From: wavehassman Date: Fri, 24 Jan 2025 13:59:07 -0500 Subject: [PATCH 3/7] #3128: split up vendor and sponsoring vendor and tasks --- .../reimbursement-requests.controllers.ts | 12 +- .../migration.sql | 79 ------------- .../migration.sql | 109 ++++++++++++++++++ src/backend/src/prisma/schema.prisma | 92 +++++++++------ src/backend/src/prisma/seed.ts | 39 +------ src/backend/src/services/boms.services.ts | 4 +- .../reimbursement-requests.services.ts | 29 +---- src/backend/tests/test-utils.ts | 12 +- 8 files changed, 176 insertions(+), 200 deletions(-) delete mode 100644 src/backend/src/prisma/migrations/20250122205420_finance_redesign/migration.sql create mode 100644 src/backend/src/prisma/migrations/20250124180446_finance_redesign/migration.sql diff --git a/src/backend/src/controllers/reimbursement-requests.controllers.ts b/src/backend/src/controllers/reimbursement-requests.controllers.ts index 4da93332f6..bce17f6d95 100644 --- a/src/backend/src/controllers/reimbursement-requests.controllers.ts +++ b/src/backend/src/controllers/reimbursement-requests.controllers.ts @@ -228,17 +228,7 @@ export default class ReimbursementRequestsController { discountCode, twoFactorContact, notes, - addedByUserId, - status, - contacts, - tier, - value, - joinDate, - activeYears, - taxExempt, - dueDate, - notifyDate, - assignToUserId + addedByUserId ); res.status(200).json(createdVendor); } catch (error: unknown) { diff --git a/src/backend/src/prisma/migrations/20250122205420_finance_redesign/migration.sql b/src/backend/src/prisma/migrations/20250122205420_finance_redesign/migration.sql deleted file mode 100644 index 9dd25b4935..0000000000 --- a/src/backend/src/prisma/migrations/20250122205420_finance_redesign/migration.sql +++ /dev/null @@ -1,79 +0,0 @@ --- CreateEnum -CREATE TYPE "Sponsor_Status" AS ENUM ('ACTIVE', 'INACTIVE'); - --- AlterTable -ALTER TABLE "Material" ADD COLUMN "reimbursementNumber" TEXT NOT NULL; - --- AlterTable -ALTER TABLE "Vendor" ADD COLUMN "activeYears" INTEGER NOT NULL DEFAULT 0, -ADD COLUMN "addedByUserId" TEXT NOT NULL DEFAULT '', -ADD COLUMN "assignToUserId" TEXT NOT NULL DEFAULT '', -ADD COLUMN "contacts" TEXT NOT NULL DEFAULT '', -ADD COLUMN "discountCode" TEXT NOT NULL DEFAULT '', -ADD COLUMN "dueDate" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), -ADD COLUMN "joinDate" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), -ADD COLUMN "notes" TEXT NOT NULL DEFAULT '', -ADD COLUMN "notifyDate" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), -ADD COLUMN "password" TEXT NOT NULL DEFAULT '', -ADD COLUMN "sponsor_TierId" TEXT NOT NULL DEFAULT '', -ADD COLUMN "status" "Sponsor_Status" NOT NULL DEFAULT 'ACTIVE', -ADD COLUMN "taxExempt" BOOLEAN NOT NULL DEFAULT TRUE, -ADD COLUMN "twoFactorContact" TEXT NOT NULL DEFAULT '', -ADD COLUMN "username" TEXT NOT NULL DEFAULT '', -ADD COLUMN "value" INTEGER NOT NULL DEFAULT 0; - --- CreateTable -CREATE TABLE "Sponsor_Tier" ( - "id" TEXT NOT NULL, - "name" TEXT NOT NULL, - - CONSTRAINT "Sponsor_Tier_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "_ProjectToReimbursement_Request" ( - "A" TEXT NOT NULL, - "B" TEXT NOT NULL -); - --- CreateIndex -CREATE UNIQUE INDEX "_ProjectToReimbursement_Request_AB_unique" ON "_ProjectToReimbursement_Request"("A", "B"); - --- CreateIndex -CREATE INDEX "_ProjectToReimbursement_Request_B_index" ON "_ProjectToReimbursement_Request"("B"); - --- AddForeignKey -ALTER TABLE "Vendor" ADD CONSTRAINT "Vendor_addedByUserId_fkey" FOREIGN KEY ("addedByUserId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Vendor" ADD CONSTRAINT "Vendor_sponsor_TierId_fkey" FOREIGN KEY ("sponsor_TierId") REFERENCES "Sponsor_Tier"("id") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Vendor" ADD CONSTRAINT "Vendor_assignToUserId_fkey" FOREIGN KEY ("assignToUserId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "Material" ADD CONSTRAINT "Material_reimbursementNumber_fkey" FOREIGN KEY ("reimbursementNumber") REFERENCES "Reimbursement_Request"("reimbursementRequestId") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_ProjectToReimbursement_Request" ADD CONSTRAINT "_ProjectToReimbursement_Request_A_fkey" FOREIGN KEY ("A") REFERENCES "Project"("projectId") ON DELETE CASCADE ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "_ProjectToReimbursement_Request" ADD CONSTRAINT "_ProjectToReimbursement_Request_B_fkey" FOREIGN KEY ("B") REFERENCES "Reimbursement_Request"("reimbursementRequestId") ON DELETE CASCADE ON UPDATE CASCADE; - -ALTER TABLE "_ProjectToReimbursement_Request" RENAME COLUMN "A" TO "projectId"; - -ALTER TABLE "_ProjectToReimbursement_Request" RENAME COLUMN "B" TO "reimbursementRequestId"; - -INSERT INTO "_ProjectToReimbursement_Request" ("projectId", "reimbursementRequestId") - -SELECT DISTINCT Project."projectId" as "projectId", "Reimbursement_Request"."reimbursementRequestId" as "reimbursementRequestId" - -FROM "Reimbursement_Request" - -JOIN "Reimbursement_Product" reimbursementProduct ON "Reimbursement_Request"."reimbursementRequestId" = reimbursementProduct."reimbursementRequestId" - -JOIN "Reimbursement_Product_Reason" reimbursementProductReason ON reimbursementProduct."reimbursementProductReasonId" = reimbursementProductReason."reimbursementProductReasonId" - -JOIN "WBS_Element" wbs_element ON reimbursementProductReason."wbsElementId" = wbs_element."wbsElementId" - -JOIN "Project" project ON project."wbsElementId" = wbs_element."wbsElementId" \ No newline at end of file diff --git a/src/backend/src/prisma/migrations/20250124180446_finance_redesign/migration.sql b/src/backend/src/prisma/migrations/20250124180446_finance_redesign/migration.sql new file mode 100644 index 0000000000..372669187f --- /dev/null +++ b/src/backend/src/prisma/migrations/20250124180446_finance_redesign/migration.sql @@ -0,0 +1,109 @@ +-- AlterTable +ALTER TABLE "Material" ADD COLUMN "reimbursementRequestId" TEXT NOT NULL DEFAULT ''; + +-- AlterTable +ALTER TABLE "Vendor" ADD COLUMN "addedByUserId" TEXT NOT NULL DEFAULT '', +ADD COLUMN "discountCode" TEXT NOT NULL DEFAULT '', +ADD COLUMN "notes" TEXT NOT NULL DEFAULT '', +ADD COLUMN "password" TEXT NOT NULL DEFAULT '', +ADD COLUMN "twoFactorContactId" TEXT NOT NULL DEFAULT '', +ADD COLUMN "username" TEXT NOT NULL DEFAULT ''; + +-- CreateTable +CREATE TABLE "Sponsoring_Vendor" ( + "sponsoringVendorId" TEXT NOT NULL, + "name" TEXT NOT NULL, + "organizationId" TEXT NOT NULL, + "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dateDeleted" TIMESTAMP(3), + "activeStatus" BOOLEAN NOT NULL, + "vendorContact" TEXT NOT NULL, + "sponsorTierId" TEXT NOT NULL, + "sponsorValue" INTEGER NOT NULL, + "joinDate" TIMESTAMP(3) NOT NULL, + "discountCode" TEXT NOT NULL, + "activeYears" INTEGER[], + "taxExempt" BOOLEAN NOT NULL, + + CONSTRAINT "Sponsoring_Vendor_pkey" PRIMARY KEY ("sponsoringVendorId") +); + +-- CreateTable +CREATE TABLE "Sponsoring_Vendor_Tasks" ( + "sponsoringVendorTasksId" TEXT NOT NULL, + "dueDate" TIMESTAMP(3) NOT NULL, + "notifyDate" TIMESTAMP(3) NOT NULL, + "assignToUserId" TEXT NOT NULL, + "notes" TEXT NOT NULL, + "vendorId" TEXT NOT NULL, + + CONSTRAINT "Sponsoring_Vendor_Tasks_pkey" PRIMARY KEY ("sponsoringVendorTasksId") +); + +-- CreateTable +CREATE TABLE "Sponsor_Tier" ( + "sponsorTierId" TEXT NOT NULL, + "name" TEXT NOT NULL, + + CONSTRAINT "Sponsor_Tier_pkey" PRIMARY KEY ("sponsorTierId") +); + +-- CreateTable +CREATE TABLE "_ProjectToReimbursement_Request" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL +); + +-- CreateIndex +CREATE UNIQUE INDEX "Sponsoring_Vendor_organizationId_key" ON "Sponsoring_Vendor"("organizationId"); + +-- CreateIndex +CREATE UNIQUE INDEX "_ProjectToReimbursement_Request_AB_unique" ON "_ProjectToReimbursement_Request"("A", "B"); + +-- CreateIndex +CREATE INDEX "_ProjectToReimbursement_Request_B_index" ON "_ProjectToReimbursement_Request"("B"); + +-- AddForeignKey +ALTER TABLE "Vendor" ADD CONSTRAINT "Vendor_twoFactorContactId_fkey" FOREIGN KEY ("twoFactorContactId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Vendor" ADD CONSTRAINT "Vendor_addedByUserId_fkey" FOREIGN KEY ("addedByUserId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Sponsoring_Vendor" ADD CONSTRAINT "Sponsoring_Vendor_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Sponsoring_Vendor" ADD CONSTRAINT "Sponsoring_Vendor_sponsorTierId_fkey" FOREIGN KEY ("sponsorTierId") REFERENCES "Sponsor_Tier"("sponsorTierId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Sponsoring_Vendor_Tasks" ADD CONSTRAINT "Sponsoring_Vendor_Tasks_assignToUserId_fkey" FOREIGN KEY ("assignToUserId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Sponsoring_Vendor_Tasks" ADD CONSTRAINT "Sponsoring_Vendor_Tasks_vendorId_fkey" FOREIGN KEY ("vendorId") REFERENCES "Sponsoring_Vendor"("sponsoringVendorId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Material" ADD CONSTRAINT "Material_reimbursementRequestId_fkey" FOREIGN KEY ("reimbursementRequestId") REFERENCES "Reimbursement_Request"("reimbursementRequestId") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_ProjectToReimbursement_Request" ADD CONSTRAINT "_ProjectToReimbursement_Request_A_fkey" FOREIGN KEY ("A") REFERENCES "Project"("projectId") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_ProjectToReimbursement_Request" ADD CONSTRAINT "_ProjectToReimbursement_Request_B_fkey" FOREIGN KEY ("B") REFERENCES "Reimbursement_Request"("reimbursementRequestId") ON DELETE CASCADE ON UPDATE CASCADE; + +ALTER TABLE "_ProjectToReimbursement_Request" RENAME COLUMN "A" TO "projectId"; + +ALTER TABLE "_ProjectToReimbursement_Request" RENAME COLUMN "B" TO "reimbursementRequestId"; + +INSERT INTO "_ProjectToReimbursement_Request" ("projectId", "reimbursementRequestId") + +SELECT DISTINCT Project."projectId" as "projectId", "Reimbursement_Request"."reimbursementRequestId" as "reimbursementRequestId" + +FROM "Reimbursement_Request" + +JOIN "Reimbursement_Product" reimbursementProduct ON "Reimbursement_Request"."reimbursementRequestId" = reimbursementProduct."reimbursementRequestId" + +JOIN "Reimbursement_Product_Reason" reimbursementProductReason ON reimbursementProduct."reimbursementProductReasonId" = reimbursementProductReason."reimbursementProductReasonId" + +JOIN "WBS_Element" wbs_element ON reimbursementProductReason."wbsElementId" = wbs_element."wbsElementId" + +JOIN "Project" project ON project."wbsElementId" = wbs_element."wbsElementId" diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 9549d180fc..300fdd958c 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -151,11 +151,6 @@ enum Special_Permission { FINANCE_ONLY } -enum Sponsor_Status { - ACTIVE - INACTIVE -} - model User { userId String @id @default(uuid()) firstName String @@ -236,7 +231,8 @@ model User { unreadAnnouncements Announcement[] @relation(name: "receivedAnnouncements") unreadPopUps PopUp[] @relation(name: "userPopUps") vendorsAdded Vendor[] @relation(name: "vendorsCreator") - vendorsAssigned Vendor[] @relation(name: "assignedVendors") + sponsoringVendorsAssigned Sponsoring_Vendor_Tasks[] @relation(name: "assignedSponsoringVendors") + vendorsTwoFactorContact Vendor[] @relation(name: "twoFactorContactVendors") } model Role { @@ -632,36 +628,57 @@ model Reimbursement_Product { } model Vendor { - vendorId String @id @default(uuid()) - dateCreated DateTime @default(now()) - dateDeleted DateTime? - name String - requests Reimbursement_Request[] - organizationId String - organization Organization @relation(fields: [organizationId], references: [organizationId]) - username String - password String - discountCode String - twoFactorContact String - notes String - addedBy User @relation(fields: [addedByUserId], references: [userId], name: "vendorsCreator") - addedByUserId String - status Sponsor_Status - contacts String - tier Sponsor_Tier @relation(fields: [sponsor_TierId], references: [id]) - sponsor_TierId String - value Int - joinDate DateTime - activeYears Int - taxExempt Boolean - dueDate DateTime - notifyDate DateTime - assignTo User @relation(fields: [assignToUserId], references: [userId], name: "assignedVendors") - assignToUserId String + vendorId String @id @default(uuid()) + dateCreated DateTime @default(now()) + dateDeleted DateTime? + name String + reimbursementRequests Reimbursement_Request[] + organizationId String + organization Organization @relation(fields: [organizationId], references: [organizationId]) + username String + password String + discountCode String + twoFactorContact User @relation(fields: [twoFactorContactId], references: [userId], name: "twoFactorContactVendors") + twoFactorContactId String + notes String + addedBy User @relation(fields: [addedByUserId], references: [userId], name: "vendorsCreator") + addedByUserId String @@unique([name, organizationId], name: "uniqueVendor") } +model Sponsoring_Vendor { + sponsoringVendorId String @id @default(uuid()) + name String + organizationId String + organization Organization @relation(fields: [organizationId], references: [organizationId]) + dateCreated DateTime @default(now()) + dateDeleted DateTime? + activeStatus Boolean + vendorContact String + tier Sponsor_Tier @relation(fields: [sponsorTierId], references: [sponsorTierId]) + sponsorTierId String + sponsorValue Int + joinDate DateTime + discountCode String + activeYears Int[] + taxExempt Boolean + vendorTasks Sponsoring_Vendor_Tasks[] + + @@unique([organizationId], name: "uniqueSponsoringVendor") +} + +model Sponsoring_Vendor_Tasks { + sponsoringVendorTasksId String @id @default(uuid()) + dueDate DateTime + notifyDate DateTime + assignTo User @relation(fields: [assignToUserId], references: [userId], name: "assignedSponsoringVendors") + assignToUserId String + notes String + vendor Sponsoring_Vendor @relation(fields: [vendorId], references: [sponsoringVendorId]) + vendorId String +} + model Account_Code { accountCodeId String @id @default(uuid()) name String @@ -755,8 +772,8 @@ model Material { subtotal Int linkUrl String notes String? - reimbursementRequest Reimbursement_Request @relation(fields: [reimbursementNumber], references: [reimbursementRequestId]) - reimbursementNumber String + reimbursementRequest Reimbursement_Request @relation(fields: [reimbursementRequestId], references: [reimbursementRequestId]) + reimbursementRequestId String } model Material_Type { @@ -990,6 +1007,7 @@ model Organization { featuredProjects Project[] popUps PopUp[] announcements Announcement[] + sponsoringVendors Sponsoring_Vendor[] } model FrequentlyAskedQuestion { @@ -1085,7 +1103,7 @@ model PopUp { } model Sponsor_Tier { - id String @id @default(uuid()) - name String - vendors Vendor[] + sponsorTierId String @id @default(uuid()) + name String + sponsoringVendor Sponsoring_Vendor[] } diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 00b321016d..3d82624b98 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -1678,7 +1678,6 @@ const performSeed: () => Promise = async () => { const tier = await prisma.sponsor_Tier.create({ data: { - id: '0', name: 'BRONZE' } }); @@ -1690,19 +1689,9 @@ const performSeed: () => Promise = async () => { 'nershipping@gmail.com', 'racecar228!', 'SAVE50!', - 'Alex L.', - 'Tax exemption status?', thomasEmrax.userId, - 'ACTIVE', - 'Jeni Hankon', - tier, - 550, - new Date('2023-11-23T00:00:00-04:00'), - 3, - true, - new Date('2024-11-23T00:00:00-04:00'), - new Date('2024-01-15T00:00:00-04:00'), - regina.userId + 'Tax exemption status?', + thomasEmrax.userId ); await ReimbursementRequestService.createVendor( thomasEmrax, @@ -1711,18 +1700,8 @@ const performSeed: () => Promise = async () => { 'amazon@gmail.com', 'racecare228!', 'SAVE20!', - 'Richard F.', - 'They want updates on work', thomasEmrax.userId, - 'INACTIVE', - 'Rob', - tier, - 1500, - new Date('2023-11-23T00:00:00-04:00'), - 5, - true, - new Date('2024-11-23T00:00:00-04:00'), - new Date('2024-01-23T00:00:00-04:00'), + 'They want updates on work', thomasEmrax.userId ); await ReimbursementRequestService.createVendor( @@ -1732,18 +1711,8 @@ const performSeed: () => Promise = async () => { 'google@gmail.com', 'racecar228!', 'SAVE50!', - 'Peyton', - 'Tax exemption ID NUMBER', thomasEmrax.userId, - 'ACTIVE', - 'Boris P.', - tier, - 30000, - new Date('2021-11-25T00:00:00-04:00'), - 2, - true, - new Date('2022-11-25T00:00:00-04:00'), - new Date('2023-01-25T00:00:00-04:00'), + 'Tax exemption ID NUMBER', thomasEmrax.userId ); diff --git a/src/backend/src/services/boms.services.ts b/src/backend/src/services/boms.services.ts index 95c2b11598..f30826a1f6 100644 --- a/src/backend/src/services/boms.services.ts +++ b/src/backend/src/services/boms.services.ts @@ -65,7 +65,7 @@ export default class BillOfMaterialsService { linkUrl: string, wbsNumber: WbsNumber, organization: Organization, - reimbursementNumber: string, + reimbursementRequestId: string, notes?: string, assemblyId?: string, pdmFileName?: string, @@ -124,7 +124,7 @@ export default class BillOfMaterialsService { notes, dateCreated: new Date(), wbsElementId: project.wbsElementId, - reimbursementNumber + reimbursementRequestId } }); diff --git a/src/backend/src/services/reimbursement-requests.services.ts b/src/backend/src/services/reimbursement-requests.services.ts index 472f758425..f5df45df62 100644 --- a/src/backend/src/services/reimbursement-requests.services.ts +++ b/src/backend/src/services/reimbursement-requests.services.ts @@ -10,7 +10,6 @@ import { Reimbursement_Status_Type, User, Organization, - Sponsor_Status, Sponsor_Tier } from '@prisma/client'; import { @@ -573,19 +572,9 @@ export default class ReimbursementRequestService { username: string, password: string, discountCode: string, - twoFactorContact: string, + twoFactorContactId: string, notes: string, - addedByUserId: string, - status: Sponsor_Status, - contacts: string, - tier: Sponsor_Tier, - value: number, - joinDate: Date, - activeYears: number, - taxExempt: boolean, - dueDate: Date, - notifyDate: Date, - assignToUserId: string + addedByUserId: string ) { const isAuthorized = (await userHasPermission(submitter.userId, organization.organizationId, isAdmin)) || @@ -611,19 +600,9 @@ export default class ReimbursementRequestService { username, password, discountCode, - twoFactorContact, + twoFactorContactId, notes, - addedByUserId, - status, - contacts, - sponsor_TierId: tier.id, - value, - joinDate, - activeYears, - taxExempt, - dueDate, - notifyDate, - assignToUserId + addedByUserId } }); diff --git a/src/backend/tests/test-utils.ts b/src/backend/tests/test-utils.ts index f472ad45d5..a3b18619df 100644 --- a/src/backend/tests/test-utils.ts +++ b/src/backend/tests/test-utils.ts @@ -406,18 +406,8 @@ export const createTestReimbursementRequest = async () => { 'nershipping@gmail.com', 'racecar228!', 'SAVE50!', - 'Alex L.', - 'Tax exemption status?', user.userId, - 'ACTIVE', - 'Jeni Hankon', - tier, - 550, - new Date('2023-11-23T00:00:00-04:00'), - 3, - true, - new Date('2024-11-23T00:00:00-04:00'), - new Date('2024-01-23T00:00:00-04:00'), + 'Tax exemption status?', user.userId ); From 6146d172642f96569d7c7cb472b35fa20ec06664 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Fri, 24 Jan 2025 14:05:22 -0500 Subject: [PATCH 4/7] #3128: linting --- .../reimbursement-requests.controllers.ts | 20 +------------------ .../reimbursement-requests.services.ts | 9 +-------- src/backend/tests/test-utils.ts | 6 ------ 3 files changed, 2 insertions(+), 33 deletions(-) diff --git a/src/backend/src/controllers/reimbursement-requests.controllers.ts b/src/backend/src/controllers/reimbursement-requests.controllers.ts index bce17f6d95..ba225fdb18 100644 --- a/src/backend/src/controllers/reimbursement-requests.controllers.ts +++ b/src/backend/src/controllers/reimbursement-requests.controllers.ts @@ -200,25 +200,7 @@ export default class ReimbursementRequestsController { static async createVendor(req: Request, res: Response, next: NextFunction) { try { - const { - name, - username, - password, - discountCode, - twoFactorContact, - notes, - addedByUserId, - status, - contacts, - tier, - value, - joinDate, - activeYears, - taxExempt, - dueDate, - notifyDate, - assignToUserId - } = req.body; + const { name, username, password, discountCode, twoFactorContact, notes, addedByUserId } = req.body; const createdVendor = await ReimbursementRequestService.createVendor( req.currentUser, name, diff --git a/src/backend/src/services/reimbursement-requests.services.ts b/src/backend/src/services/reimbursement-requests.services.ts index f5df45df62..49478b9924 100644 --- a/src/backend/src/services/reimbursement-requests.services.ts +++ b/src/backend/src/services/reimbursement-requests.services.ts @@ -4,14 +4,7 @@ */ // eslint-disable-next-line @typescript-eslint/no-unused-vars -import { - Club_Accounts, - Reimbursement_Request, - Reimbursement_Status_Type, - User, - Organization, - Sponsor_Tier -} from '@prisma/client'; +import { Club_Accounts, Reimbursement_Request, Reimbursement_Status_Type, User, Organization } from '@prisma/client'; import { ClubAccount, Reimbursement, diff --git a/src/backend/tests/test-utils.ts b/src/backend/tests/test-utils.ts index a3b18619df..e7b487a036 100644 --- a/src/backend/tests/test-utils.ts +++ b/src/backend/tests/test-utils.ts @@ -393,12 +393,6 @@ export const createTestReimbursementRequest = async () => { const project = await createTestProject(user, organization.organizationId); - const tier = await prisma.sponsor_Tier.create({ - data: { - name: 'GOLD' - } - }); - const vendor = await ReimbursementRequestService.createVendor( user, 'Tesla', From 372211997b0c8643b0dddf05de0a6afc4c0add15 Mon Sep 17 00:00:00 2001 From: wavehassman Date: Sat, 25 Jan 2025 10:31:15 -0500 Subject: [PATCH 5/7] #3128: renaming, added color field to tier --- .../migration.sql | 33 +++++---- src/backend/src/prisma/schema.prisma | 74 ++++++++++--------- src/backend/src/prisma/seed.ts | 9 --- src/backend/tests/test-utils.ts | 1 + 4 files changed, 59 insertions(+), 58 deletions(-) rename src/backend/src/prisma/migrations/{20250124180446_finance_redesign => 20250124231324_finance_redesign}/migration.sql (72%) diff --git a/src/backend/src/prisma/migrations/20250124180446_finance_redesign/migration.sql b/src/backend/src/prisma/migrations/20250124231324_finance_redesign/migration.sql similarity index 72% rename from src/backend/src/prisma/migrations/20250124180446_finance_redesign/migration.sql rename to src/backend/src/prisma/migrations/20250124231324_finance_redesign/migration.sql index 372669187f..d2883d9091 100644 --- a/src/backend/src/prisma/migrations/20250124180446_finance_redesign/migration.sql +++ b/src/backend/src/prisma/migrations/20250124231324_finance_redesign/migration.sql @@ -10,8 +10,8 @@ ADD COLUMN "twoFactorContactId" TEXT NOT NULL DEFAULT '', ADD COLUMN "username" TEXT NOT NULL DEFAULT ''; -- CreateTable -CREATE TABLE "Sponsoring_Vendor" ( - "sponsoringVendorId" TEXT NOT NULL, +CREATE TABLE "Sponsor" ( + "sponsorId" TEXT NOT NULL, "name" TEXT NOT NULL, "organizationId" TEXT NOT NULL, "dateCreated" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, @@ -25,25 +25,27 @@ CREATE TABLE "Sponsoring_Vendor" ( "activeYears" INTEGER[], "taxExempt" BOOLEAN NOT NULL, - CONSTRAINT "Sponsoring_Vendor_pkey" PRIMARY KEY ("sponsoringVendorId") + CONSTRAINT "Sponsor_pkey" PRIMARY KEY ("sponsorId") ); -- CreateTable -CREATE TABLE "Sponsoring_Vendor_Tasks" ( - "sponsoringVendorTasksId" TEXT NOT NULL, +CREATE TABLE "Sponsor_Task" ( + "sponsorTaskId" TEXT NOT NULL, "dueDate" TIMESTAMP(3) NOT NULL, - "notifyDate" TIMESTAMP(3) NOT NULL, - "assignToUserId" TEXT NOT NULL, + "notifyDate" TIMESTAMP(3), + "assignToUserId" TEXT, "notes" TEXT NOT NULL, - "vendorId" TEXT NOT NULL, + "sponsorId" TEXT NOT NULL, - CONSTRAINT "Sponsoring_Vendor_Tasks_pkey" PRIMARY KEY ("sponsoringVendorTasksId") + CONSTRAINT "Sponsor_Task_pkey" PRIMARY KEY ("sponsorTaskId") ); -- CreateTable CREATE TABLE "Sponsor_Tier" ( "sponsorTierId" TEXT NOT NULL, + "organizationId" TEXT NOT NULL, "name" TEXT NOT NULL, + "color" VARCHAR(7) NOT NULL, CONSTRAINT "Sponsor_Tier_pkey" PRIMARY KEY ("sponsorTierId") ); @@ -55,7 +57,7 @@ CREATE TABLE "_ProjectToReimbursement_Request" ( ); -- CreateIndex -CREATE UNIQUE INDEX "Sponsoring_Vendor_organizationId_key" ON "Sponsoring_Vendor"("organizationId"); +CREATE UNIQUE INDEX "Sponsor_name_organizationId_key" ON "Sponsor"("name", "organizationId"); -- CreateIndex CREATE UNIQUE INDEX "_ProjectToReimbursement_Request_AB_unique" ON "_ProjectToReimbursement_Request"("A", "B"); @@ -70,20 +72,23 @@ ALTER TABLE "Vendor" ADD CONSTRAINT "Vendor_twoFactorContactId_fkey" FOREIGN KEY ALTER TABLE "Vendor" ADD CONSTRAINT "Vendor_addedByUserId_fkey" FOREIGN KEY ("addedByUserId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "Sponsoring_Vendor" ADD CONSTRAINT "Sponsoring_Vendor_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; +ALTER TABLE "Sponsor" ADD CONSTRAINT "Sponsor_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "Sponsoring_Vendor" ADD CONSTRAINT "Sponsoring_Vendor_sponsorTierId_fkey" FOREIGN KEY ("sponsorTierId") REFERENCES "Sponsor_Tier"("sponsorTierId") ON DELETE RESTRICT ON UPDATE CASCADE; +ALTER TABLE "Sponsor" ADD CONSTRAINT "Sponsor_sponsorTierId_fkey" FOREIGN KEY ("sponsorTierId") REFERENCES "Sponsor_Tier"("sponsorTierId") ON DELETE RESTRICT ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "Sponsoring_Vendor_Tasks" ADD CONSTRAINT "Sponsoring_Vendor_Tasks_assignToUserId_fkey" FOREIGN KEY ("assignToUserId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; +ALTER TABLE "Sponsor_Task" ADD CONSTRAINT "Sponsor_Task_assignToUserId_fkey" FOREIGN KEY ("assignToUserId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "Sponsoring_Vendor_Tasks" ADD CONSTRAINT "Sponsoring_Vendor_Tasks_vendorId_fkey" FOREIGN KEY ("vendorId") REFERENCES "Sponsoring_Vendor"("sponsoringVendorId") ON DELETE RESTRICT ON UPDATE CASCADE; +ALTER TABLE "Sponsor_Task" ADD CONSTRAINT "Sponsor_Task_sponsorId_fkey" FOREIGN KEY ("sponsorId") REFERENCES "Sponsor"("sponsorId") ON DELETE RESTRICT ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "Material" ADD CONSTRAINT "Material_reimbursementRequestId_fkey" FOREIGN KEY ("reimbursementRequestId") REFERENCES "Reimbursement_Request"("reimbursementRequestId") ON DELETE RESTRICT ON UPDATE CASCADE; +-- AddForeignKey +ALTER TABLE "Sponsor_Tier" ADD CONSTRAINT "Sponsor_Tier_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; + -- AddForeignKey ALTER TABLE "_ProjectToReimbursement_Request" ADD CONSTRAINT "_ProjectToReimbursement_Request_A_fkey" FOREIGN KEY ("A") REFERENCES "Project"("projectId") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 300fdd958c..b2384cebe0 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -231,7 +231,7 @@ model User { unreadAnnouncements Announcement[] @relation(name: "receivedAnnouncements") unreadPopUps PopUp[] @relation(name: "userPopUps") vendorsAdded Vendor[] @relation(name: "vendorsCreator") - sponsoringVendorsAssigned Sponsoring_Vendor_Tasks[] @relation(name: "assignedSponsoringVendors") + sponsorsAssigned Sponsor_Task[] @relation(name: "assignedSponsors") vendorsTwoFactorContact Vendor[] @relation(name: "twoFactorContactVendors") } @@ -647,36 +647,36 @@ model Vendor { @@unique([name, organizationId], name: "uniqueVendor") } -model Sponsoring_Vendor { - sponsoringVendorId String @id @default(uuid()) - name String - organizationId String - organization Organization @relation(fields: [organizationId], references: [organizationId]) - dateCreated DateTime @default(now()) - dateDeleted DateTime? - activeStatus Boolean - vendorContact String - tier Sponsor_Tier @relation(fields: [sponsorTierId], references: [sponsorTierId]) - sponsorTierId String - sponsorValue Int - joinDate DateTime - discountCode String - activeYears Int[] - taxExempt Boolean - vendorTasks Sponsoring_Vendor_Tasks[] - - @@unique([organizationId], name: "uniqueSponsoringVendor") -} - -model Sponsoring_Vendor_Tasks { - sponsoringVendorTasksId String @id @default(uuid()) - dueDate DateTime - notifyDate DateTime - assignTo User @relation(fields: [assignToUserId], references: [userId], name: "assignedSponsoringVendors") - assignToUserId String - notes String - vendor Sponsoring_Vendor @relation(fields: [vendorId], references: [sponsoringVendorId]) - vendorId String +model Sponsor { + sponsorId String @id @default(uuid()) + name String + organizationId String + organization Organization @relation(fields: [organizationId], references: [organizationId]) + dateCreated DateTime @default(now()) + dateDeleted DateTime? + activeStatus Boolean + vendorContact String + tier Sponsor_Tier @relation(fields: [sponsorTierId], references: [sponsorTierId]) + sponsorTierId String + sponsorValue Int + joinDate DateTime + discountCode String + activeYears Int[] + taxExempt Boolean + sponsorTasks Sponsor_Task[] + + @@unique([name, organizationId], name: "uniqueSponsor") +} + +model Sponsor_Task { + sponsorTaskId String @id @default(uuid()) + dueDate DateTime + notifyDate DateTime? + assignee User? @relation(fields: [assignToUserId], references: [userId], name: "assignedSponsors") + assignToUserId String? + notes String + sponosor Sponsor @relation(fields: [sponsorId], references: [sponsorId]) + sponsorId String } model Account_Code { @@ -1007,7 +1007,8 @@ model Organization { featuredProjects Project[] popUps PopUp[] announcements Announcement[] - sponsoringVendors Sponsoring_Vendor[] + sponsors Sponsor[] + sponsorTiers Sponsor_Tier[] } model FrequentlyAskedQuestion { @@ -1103,7 +1104,10 @@ model PopUp { } model Sponsor_Tier { - sponsorTierId String @id @default(uuid()) - name String - sponsoringVendor Sponsoring_Vendor[] + sponsorTierId String @id @default(uuid()) + organization Organization @relation(fields: [organizationId], references: [organizationId]) + organizationId String + name String + color String @db.VarChar(7) + sponsors Sponsor[] } diff --git a/src/backend/src/prisma/seed.ts b/src/backend/src/prisma/seed.ts index 3d82624b98..390713e509 100644 --- a/src/backend/src/prisma/seed.ts +++ b/src/backend/src/prisma/seed.ts @@ -8,7 +8,6 @@ import { CR_Type, Club_Accounts, - Graph, Graph_Display_Type, Graph_Type, Measure, @@ -46,9 +45,7 @@ import { writeFileSync } from 'fs'; import WorkPackageTemplatesService from '../services/work-package-template.services'; import RecruitmentServices from '../services/recruitment.services'; import OrganizationsService from '../services/organizations.services'; -import StatisticsService from '../services/statistics.services'; import { seedGraph } from './seed-data/statistics.seed'; -import { graphCollectionTransformer } from '../transformers/statistics-graphCollection.transformer'; import AnnouncementService from '../services/announcement.service'; const prisma = new PrismaClient(); @@ -1676,12 +1673,6 @@ const performSeed: () => Promise = async () => { * Reimbursements */ - const tier = await prisma.sponsor_Tier.create({ - data: { - name: 'BRONZE' - } - }); - const vendor = await ReimbursementRequestService.createVendor( thomasEmrax, 'Tesla', diff --git a/src/backend/tests/test-utils.ts b/src/backend/tests/test-utils.ts index e7b487a036..1f8918e1ba 100644 --- a/src/backend/tests/test-utils.ts +++ b/src/backend/tests/test-utils.ts @@ -135,6 +135,7 @@ export const resetUsers = async () => { await prisma.graph_Collection.deleteMany(); await prisma.announcement.deleteMany(); await prisma.popUp.deleteMany(); + await prisma.sponsor_Tier.deleteMany(); await prisma.organization.deleteMany(); await prisma.user.deleteMany(); }; From 853b19b3e303b86cc9db381ddc57b5894fae703a Mon Sep 17 00:00:00 2001 From: wavehassman Date: Sun, 26 Jan 2025 20:50:30 -0500 Subject: [PATCH 6/7] #3128: optional fields and renaming --- .../migration.sql | 22 ++++++++--------- src/backend/src/prisma/schema.prisma | 24 +++++++++---------- 2 files changed, 23 insertions(+), 23 deletions(-) rename src/backend/src/prisma/migrations/{20250124231324_finance_redesign => 20250127014440_finance_redesign}/migration.sql (88%) diff --git a/src/backend/src/prisma/migrations/20250124231324_finance_redesign/migration.sql b/src/backend/src/prisma/migrations/20250127014440_finance_redesign/migration.sql similarity index 88% rename from src/backend/src/prisma/migrations/20250124231324_finance_redesign/migration.sql rename to src/backend/src/prisma/migrations/20250127014440_finance_redesign/migration.sql index d2883d9091..44bdaaa461 100644 --- a/src/backend/src/prisma/migrations/20250124231324_finance_redesign/migration.sql +++ b/src/backend/src/prisma/migrations/20250127014440_finance_redesign/migration.sql @@ -2,11 +2,11 @@ ALTER TABLE "Material" ADD COLUMN "reimbursementRequestId" TEXT NOT NULL DEFAULT ''; -- AlterTable -ALTER TABLE "Vendor" ADD COLUMN "addedByUserId" TEXT NOT NULL DEFAULT '', -ADD COLUMN "discountCode" TEXT NOT NULL DEFAULT '', -ADD COLUMN "notes" TEXT NOT NULL DEFAULT '', +ALTER TABLE "Vendor" ADD COLUMN "addedByUserId" TEXT, +ADD COLUMN "discountCode" TEXT, +ADD COLUMN "notes" TEXT, ADD COLUMN "password" TEXT NOT NULL DEFAULT '', -ADD COLUMN "twoFactorContactId" TEXT NOT NULL DEFAULT '', +ADD COLUMN "twoFactorContactId" TEXT, ADD COLUMN "username" TEXT NOT NULL DEFAULT ''; -- CreateTable @@ -21,7 +21,7 @@ CREATE TABLE "Sponsor" ( "sponsorTierId" TEXT NOT NULL, "sponsorValue" INTEGER NOT NULL, "joinDate" TIMESTAMP(3) NOT NULL, - "discountCode" TEXT NOT NULL, + "discountCode" TEXT, "activeYears" INTEGER[], "taxExempt" BOOLEAN NOT NULL, @@ -33,7 +33,7 @@ CREATE TABLE "Sponsor_Task" ( "sponsorTaskId" TEXT NOT NULL, "dueDate" TIMESTAMP(3) NOT NULL, "notifyDate" TIMESTAMP(3), - "assignToUserId" TEXT, + "assigneeUserId" TEXT, "notes" TEXT NOT NULL, "sponsorId" TEXT NOT NULL, @@ -45,7 +45,7 @@ CREATE TABLE "Sponsor_Tier" ( "sponsorTierId" TEXT NOT NULL, "organizationId" TEXT NOT NULL, "name" TEXT NOT NULL, - "color" VARCHAR(7) NOT NULL, + "colorHexCode" TEXT NOT NULL, CONSTRAINT "Sponsor_Tier_pkey" PRIMARY KEY ("sponsorTierId") ); @@ -66,10 +66,10 @@ CREATE UNIQUE INDEX "_ProjectToReimbursement_Request_AB_unique" ON "_ProjectToRe CREATE INDEX "_ProjectToReimbursement_Request_B_index" ON "_ProjectToReimbursement_Request"("B"); -- AddForeignKey -ALTER TABLE "Vendor" ADD CONSTRAINT "Vendor_twoFactorContactId_fkey" FOREIGN KEY ("twoFactorContactId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; +ALTER TABLE "Vendor" ADD CONSTRAINT "Vendor_twoFactorContactId_fkey" FOREIGN KEY ("twoFactorContactId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "Vendor" ADD CONSTRAINT "Vendor_addedByUserId_fkey" FOREIGN KEY ("addedByUserId") REFERENCES "User"("userId") ON DELETE RESTRICT ON UPDATE CASCADE; +ALTER TABLE "Vendor" ADD CONSTRAINT "Vendor_addedByUserId_fkey" FOREIGN KEY ("addedByUserId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "Sponsor" ADD CONSTRAINT "Sponsor_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("organizationId") ON DELETE RESTRICT ON UPDATE CASCADE; @@ -78,7 +78,7 @@ ALTER TABLE "Sponsor" ADD CONSTRAINT "Sponsor_organizationId_fkey" FOREIGN KEY ( ALTER TABLE "Sponsor" ADD CONSTRAINT "Sponsor_sponsorTierId_fkey" FOREIGN KEY ("sponsorTierId") REFERENCES "Sponsor_Tier"("sponsorTierId") ON DELETE RESTRICT ON UPDATE CASCADE; -- AddForeignKey -ALTER TABLE "Sponsor_Task" ADD CONSTRAINT "Sponsor_Task_assignToUserId_fkey" FOREIGN KEY ("assignToUserId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; +ALTER TABLE "Sponsor_Task" ADD CONSTRAINT "Sponsor_Task_assigneeUserId_fkey" FOREIGN KEY ("assigneeUserId") REFERENCES "User"("userId") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "Sponsor_Task" ADD CONSTRAINT "Sponsor_Task_sponsorId_fkey" FOREIGN KEY ("sponsorId") REFERENCES "Sponsor"("sponsorId") ON DELETE RESTRICT ON UPDATE CASCADE; @@ -111,4 +111,4 @@ JOIN "Reimbursement_Product_Reason" reimbursementProductReason ON reimbursementP JOIN "WBS_Element" wbs_element ON reimbursementProductReason."wbsElementId" = wbs_element."wbsElementId" -JOIN "Project" project ON project."wbsElementId" = wbs_element."wbsElementId" +JOIN "Project" project ON project."wbsElementId" = wbs_element."wbsElementId" \ No newline at end of file diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index b2384cebe0..479fbc4a2f 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -231,8 +231,8 @@ model User { unreadAnnouncements Announcement[] @relation(name: "receivedAnnouncements") unreadPopUps PopUp[] @relation(name: "userPopUps") vendorsAdded Vendor[] @relation(name: "vendorsCreator") - sponsorsAssigned Sponsor_Task[] @relation(name: "assignedSponsors") - vendorsTwoFactorContact Vendor[] @relation(name: "twoFactorContactVendors") + sponsorTasksAssigned Sponsor_Task[] @relation(name: "assignedSponsorTasks") + twoFactorContactVendors Vendor[] @relation(name: "twoFactorContactVendors") } model Role { @@ -637,12 +637,12 @@ model Vendor { organization Organization @relation(fields: [organizationId], references: [organizationId]) username String password String - discountCode String - twoFactorContact User @relation(fields: [twoFactorContactId], references: [userId], name: "twoFactorContactVendors") - twoFactorContactId String - notes String - addedBy User @relation(fields: [addedByUserId], references: [userId], name: "vendorsCreator") - addedByUserId String + discountCode String? + twoFactorContact User? @relation(fields: [twoFactorContactId], references: [userId], name: "twoFactorContactVendors") + twoFactorContactId String? + notes String? + addedBy User? @relation(fields: [addedByUserId], references: [userId], name: "vendorsCreator") + addedByUserId String? @@unique([name, organizationId], name: "uniqueVendor") } @@ -660,7 +660,7 @@ model Sponsor { sponsorTierId String sponsorValue Int joinDate DateTime - discountCode String + discountCode String? activeYears Int[] taxExempt Boolean sponsorTasks Sponsor_Task[] @@ -672,8 +672,8 @@ model Sponsor_Task { sponsorTaskId String @id @default(uuid()) dueDate DateTime notifyDate DateTime? - assignee User? @relation(fields: [assignToUserId], references: [userId], name: "assignedSponsors") - assignToUserId String? + assignee User? @relation(fields: [assigneeUserId], references: [userId], name: "assignedSponsorTasks") + assigneeUserId String? notes String sponosor Sponsor @relation(fields: [sponsorId], references: [sponsorId]) sponsorId String @@ -1108,6 +1108,6 @@ model Sponsor_Tier { organization Organization @relation(fields: [organizationId], references: [organizationId]) organizationId String name String - color String @db.VarChar(7) + colorHexCode String sponsors Sponsor[] } From 37095b83544bcc680be625e93e9a32cd070a99ab Mon Sep 17 00:00:00 2001 From: wavehassman Date: Wed, 29 Jan 2025 19:17:35 -0500 Subject: [PATCH 7/7] #3128: reimbiursement in material is optional --- .../migration.sql | 4 ++-- src/backend/src/prisma/schema.prisma | 24 +++++++++---------- .../reimbursement-requests.services.ts | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/backend/src/prisma/migrations/20250127014440_finance_redesign/migration.sql b/src/backend/src/prisma/migrations/20250127014440_finance_redesign/migration.sql index 44bdaaa461..c8cd0009c6 100644 --- a/src/backend/src/prisma/migrations/20250127014440_finance_redesign/migration.sql +++ b/src/backend/src/prisma/migrations/20250127014440_finance_redesign/migration.sql @@ -1,11 +1,11 @@ -- AlterTable -ALTER TABLE "Material" ADD COLUMN "reimbursementRequestId" TEXT NOT NULL DEFAULT ''; +ALTER TABLE "Material" ADD COLUMN "reimbursementRequestId" TEXT; -- AlterTable ALTER TABLE "Vendor" ADD COLUMN "addedByUserId" TEXT, ADD COLUMN "discountCode" TEXT, ADD COLUMN "notes" TEXT, -ADD COLUMN "password" TEXT NOT NULL DEFAULT '', +ADD COLUMN "passwordHash" TEXT NOT NULL DEFAULT '', ADD COLUMN "twoFactorContactId" TEXT, ADD COLUMN "username" TEXT NOT NULL DEFAULT ''; diff --git a/src/backend/src/prisma/schema.prisma b/src/backend/src/prisma/schema.prisma index 479fbc4a2f..e22cb632ee 100644 --- a/src/backend/src/prisma/schema.prisma +++ b/src/backend/src/prisma/schema.prisma @@ -636,7 +636,7 @@ model Vendor { organizationId String organization Organization @relation(fields: [organizationId], references: [organizationId]) username String - password String + passwordHash String discountCode String? twoFactorContact User? @relation(fields: [twoFactorContactId], references: [userId], name: "twoFactorContactVendors") twoFactorContactId String? @@ -675,7 +675,7 @@ model Sponsor_Task { assignee User? @relation(fields: [assigneeUserId], references: [userId], name: "assignedSponsorTasks") assigneeUserId String? notes String - sponosor Sponsor @relation(fields: [sponsorId], references: [sponsorId]) + sponsor Sponsor @relation(fields: [sponsorId], references: [sponsorId]) sponsorId String } @@ -746,34 +746,34 @@ model Assembly { } model Material { - materialId String @id @default(uuid()) - assembly Assembly? @relation(fields: [assemblyId], references: [assemblyId]) + materialId String @id @default(uuid()) + assembly Assembly? @relation(fields: [assemblyId], references: [assemblyId]) assemblyId String? name String - wbsElement WBS_Element @relation(fields: [wbsElementId], references: [wbsElementId]) + wbsElement WBS_Element @relation(fields: [wbsElementId], references: [wbsElementId]) wbsElementId String dateDeleted DateTime? - userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "materialDeleter") + userDeleted User? @relation(fields: [userDeletedId], references: [userId], name: "materialDeleter") userDeletedId String? dateCreated DateTime - userCreated User @relation(fields: [userCreatedId], references: [userId], name: "materialCreator") + userCreated User @relation(fields: [userCreatedId], references: [userId], name: "materialCreator") userCreatedId String status Material_Status - materialType Material_Type @relation(fields: [materialTypeId], references: [id]) + materialType Material_Type @relation(fields: [materialTypeId], references: [id]) materialTypeId String - manufacturer Manufacturer @relation(fields: [manufacturerId], references: [id]) + manufacturer Manufacturer @relation(fields: [manufacturerId], references: [id]) manufacturerId String manufacturerPartNumber String pdmFileName String? quantity Decimal - unit Unit? @relation(fields: [unitId], references: [id]) + unit Unit? @relation(fields: [unitId], references: [id]) unitId String? price Int subtotal Int linkUrl String notes String? - reimbursementRequest Reimbursement_Request @relation(fields: [reimbursementRequestId], references: [reimbursementRequestId]) - reimbursementRequestId String + reimbursementRequest Reimbursement_Request? @relation(fields: [reimbursementRequestId], references: [reimbursementRequestId]) + reimbursementRequestId String? } model Material_Type { diff --git a/src/backend/src/services/reimbursement-requests.services.ts b/src/backend/src/services/reimbursement-requests.services.ts index 49478b9924..96cbb6fa4f 100644 --- a/src/backend/src/services/reimbursement-requests.services.ts +++ b/src/backend/src/services/reimbursement-requests.services.ts @@ -563,7 +563,7 @@ export default class ReimbursementRequestService { name: string, organization: Organization, username: string, - password: string, + passwordHash: string, discountCode: string, twoFactorContactId: string, notes: string, @@ -591,7 +591,7 @@ export default class ReimbursementRequestService { name, organizationId: organization.organizationId, username, - password, + passwordHash, discountCode, twoFactorContactId, notes,