Skip to content

Commit 5dd5abd

Browse files
committed
dates fix
1 parent ed6214a commit 5dd5abd

39 files changed

Lines changed: 212 additions & 228 deletions

src/backend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"concat-stream": "^2.0.0",
2323
"cookie-parser": "^1.4.5",
2424
"cors": "^2.8.5",
25+
"dayjs": "^1.11.19",
2526
"decimal.js": "^10.4.3",
2627
"dotenv": "^16.0.1",
2728
"express": "^5.0.0",
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
-- AlterTable: Change date-only fields from timestamp to date type
2+
-- PostgreSQL truncates the time portion automatically when casting timestamp to date
3+
4+
ALTER TABLE "Activation_CR" ALTER COLUMN "startDate" SET DATA TYPE date;
5+
ALTER TABLE "Work_Package" ALTER COLUMN "startDate" SET DATA TYPE date;
6+
ALTER TABLE "Task" ALTER COLUMN "deadline" SET DATA TYPE date;
7+
ALTER TABLE "Task" ALTER COLUMN "startDate" SET DATA TYPE date;
8+
ALTER TABLE "Reimbursement_Request" ALTER COLUMN "dateOfExpense" SET DATA TYPE date;
9+
ALTER TABLE "Reimbursement_Request" ALTER COLUMN "dateDelivered" SET DATA TYPE date;
10+
ALTER TABLE "Sponsor" ALTER COLUMN "joinDate" SET DATA TYPE date;
11+
ALTER TABLE "Sponsor_Task" ALTER COLUMN "dueDate" SET DATA TYPE date;
12+
ALTER TABLE "Sponsor_Task" ALTER COLUMN "notifyDate" SET DATA TYPE date;
13+
ALTER TABLE "Availability" ALTER COLUMN "dateSet" SET DATA TYPE date;
14+
ALTER TABLE "Event" ALTER COLUMN "initialDateScheduled" SET DATA TYPE date;
15+
ALTER TABLE "Milestone" ALTER COLUMN "dateOfEvent" SET DATA TYPE date;
16+
ALTER TABLE "Graph" ALTER COLUMN "startDate" SET DATA TYPE date;
17+
ALTER TABLE "Graph" ALTER COLUMN "endDate" SET DATA TYPE date;

src/backend/src/prisma/schema.prisma

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ model Activation_CR {
449449
lead User @relation(name: "markAsLead", fields: [leadId], references: [userId])
450450
managerId String
451451
manager User @relation(name: "markAsManager", fields: [managerId], references: [userId])
452-
startDate DateTime
452+
startDate DateTime @db.Date
453453
confirmDetails Boolean
454454
455455
@@index([changeRequestId])
@@ -551,7 +551,7 @@ model Work_Package {
551551
projectId String
552552
project Project @relation(fields: [projectId], references: [projectId])
553553
orderInProject Int
554-
startDate DateTime
554+
startDate DateTime @db.Date
555555
duration Int
556556
blockedBy WBS_Element[] @relation(name: "blockedBy")
557557
stage Work_Package_Stage?
@@ -649,8 +649,8 @@ model Task {
649649
taskId String @id @default(uuid())
650650
title String
651651
notes String
652-
deadline DateTime?
653-
startDate DateTime?
652+
deadline DateTime? @db.Date
653+
startDate DateTime? @db.Date
654654
assignees User[] @relation(name: "assignedTo")
655655
priority Task_Priority
656656
status Task_Status
@@ -700,7 +700,7 @@ model Reimbursement_Request {
700700
saboId Int? @unique
701701
dateCreated DateTime @default(now())
702702
dateDeleted DateTime?
703-
dateOfExpense DateTime?
703+
dateOfExpense DateTime? @db.Date
704704
reimbursementStatuses Reimbursement_Status[]
705705
recipientId String
706706
recipient User @relation(name: "reimbursementRequestRecipient", fields: [recipientId], references: [userId])
@@ -711,7 +711,7 @@ model Reimbursement_Request {
711711
totalCost Int
712712
receiptPictures Receipt[]
713713
reimbursementProducts Reimbursement_Product[]
714-
dateDelivered DateTime?
714+
dateDelivered DateTime? @db.Date
715715
accountCodeId String
716716
accountCode Account_Code @relation(fields: [accountCodeId], references: [accountCodeId])
717717
organizationId String
@@ -803,7 +803,7 @@ model Sponsor {
803803
tier Sponsor_Tier @relation(fields: [sponsorTierId], references: [sponsorTierId])
804804
sponsorTierId String
805805
sponsorValue Int
806-
joinDate DateTime
806+
joinDate DateTime @db.Date
807807
discountCode String?
808808
activeYears Int[]
809809
taxExempt Boolean
@@ -818,8 +818,8 @@ model Sponsor {
818818

819819
model Sponsor_Task {
820820
sponsorTaskId String @id @default(uuid())
821-
dueDate DateTime
822-
notifyDate DateTime?
821+
dueDate DateTime @db.Date
822+
notifyDate DateTime? @db.Date
823823
assignee User? @relation(fields: [assigneeUserId], references: [userId], name: "assignedSponsorTasks")
824824
assigneeUserId String?
825825
notes String
@@ -1090,7 +1090,7 @@ model Event {
10901090
workPackages Work_Package[]
10911091
documents Document[]
10921092
status Event_Status
1093-
initialDateScheduled DateTime?
1093+
initialDateScheduled DateTime? @db.Date
10941094
questionDocumentLink String?
10951095
description String?
10961096
notificationSlackThreads Message_Info[]
@@ -1173,7 +1173,7 @@ model Availability {
11731173
11741174
// Availibilies are integers between 0 and 11 from 10am - 10pm for a given day at hour intervals see meetingTime field in Design_Review
11751175
availability Int[]
1176-
dateSet DateTime
1176+
dateSet DateTime @db.Date
11771177
11781178
@@index([scheduleSettingsId])
11791179
}
@@ -1383,7 +1383,7 @@ model FrequentlyAskedQuestion {
13831383
model Milestone {
13841384
milestoneId String @id @default(uuid())
13851385
name String
1386-
dateOfEvent DateTime
1386+
dateOfEvent DateTime @db.Date
13871387
description String
13881388
userCreated User @relation(fields: [userCreatedId], references: [userId], name: "milestoneCreator")
13891389
userCreatedId String
@@ -1399,8 +1399,8 @@ model Milestone {
13991399

14001400
model Graph {
14011401
id String @id @default(uuid())
1402-
startDate DateTime?
1403-
endDate DateTime?
1402+
startDate DateTime? @db.Date
1403+
endDate DateTime? @db.Date
14041404
title String
14051405
graphType Graph_Type
14061406
displayGraphType Graph_Display_Type

src/backend/src/prisma/seed.ts

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import ProjectsService from '../services/projects.services.js';
3131
import { Decimal } from 'decimal.js';
3232
import BillOfMaterialsService from '../services/boms.services.js';
3333
import UsersService from '../services/users.services.js';
34-
import { transformDate } from '../utils/datetime.utils.js';
34+
import { toDateString } from 'shared';
3535
import { writeFileSync, readFileSync } from 'fs';
3636
import WbsElementTemplatesService from '../services/wbs-element-templates.services.js';
3737
import RecruitmentServices from '../services/recruitment.services.js';
@@ -1137,7 +1137,7 @@ const performSeed: () => Promise<void> = async () => {
11371137
'Bodywork Concept of Design',
11381138
changeRequestProject1Id,
11391139
WorkPackageStage.Design,
1140-
weeksAgo(12).toISOString().split('T')[0],
1140+
toDateString(weeksAgo(12)),
11411141
6,
11421142
[],
11431143
[],
@@ -1183,7 +1183,7 @@ const performSeed: () => Promise<void> = async () => {
11831183
'Adhesive Shear Strength Test',
11841184
changeRequestProject1Id,
11851185
WorkPackageStage.Research,
1186-
weeksAgo(10).toISOString().split('T')[0],
1186+
toDateString(weeksAgo(10)),
11871187
5,
11881188
[],
11891189
[],
@@ -1201,7 +1201,7 @@ const performSeed: () => Promise<void> = async () => {
12011201
'Manufacture Wiring Harness',
12021202
changeRequestProject5Id,
12031203
WorkPackageStage.Manufacturing,
1204-
weeksAgo(9).toISOString().split('T')[0],
1204+
toDateString(weeksAgo(9)),
12051205
4,
12061206
[],
12071207
[],
@@ -1234,7 +1234,7 @@ const performSeed: () => Promise<void> = async () => {
12341234
'Install Wiring Harness',
12351235
changeRequestProject5Id,
12361236
WorkPackageStage.Install,
1237-
weeksAgo(5).toISOString().split('T')[0],
1237+
toDateString(weeksAgo(5)),
12381238
6,
12391239
[],
12401240
[],
@@ -1267,7 +1267,7 @@ const performSeed: () => Promise<void> = async () => {
12671267
'Design Plush',
12681268
changeRequestProject6Id,
12691269
WorkPackageStage.Design,
1270-
weeksAgo(16).toISOString().split('T')[0],
1270+
toDateString(weeksAgo(16)),
12711271
7,
12721272
[],
12731273
[],
@@ -1300,7 +1300,7 @@ const performSeed: () => Promise<void> = async () => {
13001300
'Put Plush Together',
13011301
changeRequestProject6Id,
13021302
WorkPackageStage.Manufacturing,
1303-
weeksAgo(9).toISOString().split('T')[0],
1303+
toDateString(weeksAgo(9)),
13041304
5,
13051305
[],
13061306
[],
@@ -1333,7 +1333,7 @@ const performSeed: () => Promise<void> = async () => {
13331333
'Plush Testing',
13341334
changeRequestProject6Id,
13351335
WorkPackageStage.Testing,
1336-
weeksAgo(4).toISOString().split('T')[0],
1336+
toDateString(weeksAgo(4)),
13371337
4,
13381338
[],
13391339
[],
@@ -1367,7 +1367,7 @@ const performSeed: () => Promise<void> = async () => {
13671367
'Design Laser Canon',
13681368
changeRequestProject7Id,
13691369
WorkPackageStage.Design,
1370-
weeksAgo(8).toISOString().split('T')[0],
1370+
toDateString(weeksAgo(8)),
13711371
5,
13721372
[],
13731373
[],
@@ -1400,7 +1400,7 @@ const performSeed: () => Promise<void> = async () => {
14001400
'Laser Canon Research',
14011401
changeRequestProject7Id,
14021402
WorkPackageStage.Research,
1403-
weeksAgo(3).toISOString().split('T')[0],
1403+
toDateString(weeksAgo(3)),
14041404
6,
14051405
[],
14061406
[],
@@ -1418,7 +1418,7 @@ const performSeed: () => Promise<void> = async () => {
14181418
'Laser Canon Testing',
14191419
changeRequestProject7Id,
14201420
WorkPackageStage.Testing,
1421-
weeksFromNow(3).toISOString().split('T')[0],
1421+
toDateString(weeksFromNow(3)),
14221422
4,
14231423
[project3WP1.wbsNum, project3WP2.wbsNum],
14241424
[],
@@ -1437,7 +1437,7 @@ const performSeed: () => Promise<void> = async () => {
14371437
'Stadium Research',
14381438
changeRequestProject8Id,
14391439
WorkPackageStage.Research,
1440-
weeksAgo(14).toISOString().split('T')[0],
1440+
toDateString(weeksAgo(14)),
14411441
7,
14421442
[],
14431443
[],
@@ -1470,7 +1470,7 @@ const performSeed: () => Promise<void> = async () => {
14701470
'Stadium Install',
14711471
changeRequestProject8Id,
14721472
WorkPackageStage.Install,
1473-
weeksAgo(7).toISOString().split('T')[0],
1473+
toDateString(weeksAgo(7)),
14741474
6,
14751475
[],
14761476
[],
@@ -1488,7 +1488,7 @@ const performSeed: () => Promise<void> = async () => {
14881488
'Stadium Testing',
14891489
changeRequestProject8Id,
14901490
WorkPackageStage.Testing,
1491-
weeksAgo(1).toISOString().split('T')[0],
1491+
toDateString(weeksAgo(1)),
14921492
5,
14931493
[],
14941494
[],
@@ -2411,7 +2411,7 @@ const performSeed: () => Promise<void> = async () => {
24112411
leadId: batman.userId,
24122412
managerId: cyborg.userId,
24132413
duration: 5,
2414-
startDate: transformDate(new Date()),
2414+
startDate: toDateString(new Date()),
24152415
stage: WorkPackageStage.Design,
24162416
blockedBy: [],
24172417
descriptionBullets: [],
@@ -2425,7 +2425,7 @@ const performSeed: () => Promise<void> = async () => {
24252425
'Slim and Light Car',
24262426
newWorkPackageChangeRequest.crId,
24272427
WorkPackageStage.Design,
2428-
weeksAgo(2).toISOString().split('T')[0],
2428+
toDateString(weeksAgo(2)),
24292429
5,
24302430
[],
24312431
[],
@@ -2453,7 +2453,7 @@ const performSeed: () => Promise<void> = async () => {
24532453
leadId: batman.userId,
24542454
managerId: cyborg.userId,
24552455
duration: 5,
2456-
startDate: transformDate(new Date()),
2456+
startDate: toDateString(new Date()),
24572457
stage: WorkPackageStage.Design,
24582458
blockedBy: [],
24592459
descriptionBullets: [],

src/backend/src/services/notifications.services.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
EventWithAttendees
88
} from '../utils/notifications.utils.js';
99
import { sendMessage } from '../integrations/slack.js';
10-
import { daysBetween, meetingStartTimePipeNumbers, startOfDay, wbsPipe } from 'shared';
10+
import { daysBetween, startOfDay, wbsPipe, formatTimeForSlack } from 'shared';
1111
import { buildDueString, sendThreadResponse } from '../utils/slack.utils.js';
1212
import WorkPackagesService from './work-packages.services.js';
1313
import { addWeeksToDate } from 'shared';
@@ -196,15 +196,15 @@ export default class NotificationsService {
196196
// Get work package names for this event
197197
const workPackageNames = event.workPackages.map((wp) => wp.wbsElement.name).join(', ');
198198

199-
// Extract meeting times from scheduled slots
200-
const meetingTimes = event.scheduledTimes
201-
.map((slot) => (slot.startTime ? new Date(slot.startTime).getHours() : null))
202-
.filter((hour): hour is number => hour !== null)
203-
.sort((a, b) => a - b);
199+
// Get the earliest scheduled start time for display
200+
const earliestSlot = event.scheduledTimes
201+
.filter((slot) => slot.startTime)
202+
.sort((a, b) => new Date(a.startTime!).getTime() - new Date(b.startTime!).getTime())[0];
203+
const timeDisplay = earliestSlot ? formatTimeForSlack(new Date(earliestSlot.startTime!)) : 'TBD';
204204

205205
return (
206206
`${usersToSlackPings(event.attendees ?? [])} ${event.title} (${workPackageNames}) ` +
207-
`will be having an event today at ${meetingStartTimePipeNumbers(meetingTimes)} EST! ` +
207+
`will be having an event today at ${timeDisplay} ET! ` +
208208
zoomLink +
209209
questionDocLink
210210
);

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -330,10 +330,6 @@ export default class ReimbursementRequestService {
330330

331331
await validateRefund(submitter, amount, organization.organizationId);
332332

333-
// make the date object but add 12 hours so that the time isn't 00:00 to avoid timezone problems
334-
const dateCreated = new Date(dateReceived.split('T')[0]);
335-
dateCreated.setTime(dateCreated.getTime() + 12 * 60 * 60 * 1000);
336-
337333
const newReimbursement = await prisma.reimbursement.create({
338334
data: {
339335
purchaserId: submitter.userId,

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

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -233,10 +233,6 @@ export default class WorkPackagesService {
233233
.map((element) => element.wbsElement.workPackageNumber)
234234
.reduce((prev, curr) => Math.max(prev, curr), 0) + 1;
235235

236-
// make the date object but add 12 hours so that the time isn't 00:00 to avoid timezone problems
237-
const date = new Date(startDate.split('T')[0]);
238-
date.setTime(date.getTime() + 12 * 60 * 60 * 1000);
239-
240236
const changesToCreate = crId
241237
? [
242238
{
@@ -266,7 +262,7 @@ export default class WorkPackagesService {
266262
},
267263
stage,
268264
project: { connect: { projectId } },
269-
startDate: date,
265+
startDate: new Date(startDate),
270266
duration,
271267
orderInProject: project.workPackages.filter((wp) => !wp.wbsElement.dateDeleted).length + 1,
272268
blockedBy: { connect: blockedByElements.map((ele) => ({ wbsElementId: ele.wbsElementId })) }
@@ -389,10 +385,6 @@ export default class WorkPackagesService {
389385
userId
390386
);
391387

392-
// make the date object but add 12 hours so that the time isn't 00:00 to avoid timezone problems
393-
const date = new Date(startDate);
394-
date.setTime(date.getTime() + 12 * 60 * 60 * 1000);
395-
396388
// set the status of the wbs element to active if an edit is made to a completed version
397389
const status =
398390
originalWorkPackage.wbsElement.status === WbsElementStatus.Complete
@@ -403,7 +395,7 @@ export default class WorkPackagesService {
403395
const updatedWorkPackage = await prisma.work_Package.update({
404396
where: { wbsElementId },
405397
data: {
406-
startDate: date,
398+
startDate: new Date(startDate),
407399
duration,
408400
wbsElement: {
409401
update: {

0 commit comments

Comments
 (0)