Skip to content

Commit 3628604

Browse files
committed
Verify complete engagement date override ranges are valid
1 parent dd6381f commit 3628604

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

src/components/engagement/engagement.service.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import { forwardRef, Inject, Injectable } from '@nestjs/common';
22
import {
3+
CalendarDate,
34
ID,
45
InputException,
56
ObjectView,
7+
Range,
8+
RangeException,
69
SecuredList,
710
Session,
811
UnsecuredDto,
@@ -16,6 +19,7 @@ import {
1619
Logger,
1720
ResourceLoader,
1821
} from '~/core';
22+
import { AnyChangesOf } from '~/core/database/changes';
1923
import { Privileges } from '../authorization';
2024
import { CeremonyService } from '../ceremony';
2125
import { ProductService } from '../product';
@@ -67,6 +71,7 @@ export class EngagementService {
6771
): Promise<LanguageEngagement> {
6872
await this.verifyCreateEngagement(input.projectId, session);
6973
this.verifyCreationStatus(input.status);
74+
EngagementDateRangeException.throwIfInvalid(input);
7075

7176
const engagement = await this.repo.createLanguageEngagement(
7277
input,
@@ -87,6 +92,7 @@ export class EngagementService {
8792
): Promise<InternshipEngagement> {
8893
await this.verifyCreateEngagement(input.projectId, session);
8994
this.verifyCreationStatus(input.status);
95+
EngagementDateRangeException.throwIfInvalid(input);
9096

9197
const { id } = await this.repo.createInternshipEngagement(
9298
input,
@@ -172,6 +178,7 @@ export class EngagementService {
172178
this.privileges
173179
.for(session, LanguageEngagement, object)
174180
.verifyChanges(changes);
181+
EngagementDateRangeException.throwIfInvalid(previous, changes);
175182

176183
const updated = await this.repo.updateLanguage(
177184
{
@@ -218,6 +225,7 @@ export class EngagementService {
218225
this.privileges
219226
.for(session, InternshipEngagement, object)
220227
.verifyChanges(changes, { pathPrefix: 'engagement' });
228+
EngagementDateRangeException.throwIfInvalid(previous, changes);
221229

222230
const updated = await this.repo.updateInternship(
223231
{ id: object.id, ...changes },
@@ -310,3 +318,33 @@ export class EngagementService {
310318
return ids.length > 0;
311319
}
312320
}
321+
322+
class EngagementDateRangeException extends RangeException {
323+
static throwIfInvalid(
324+
current: Partial<
325+
Pick<UnsecuredDto<Engagement>, 'startDateOverride' | 'endDateOverride'>
326+
>,
327+
changes: AnyChangesOf<Engagement> = {},
328+
) {
329+
const start =
330+
changes.startDateOverride !== undefined
331+
? changes.startDateOverride
332+
: current.startDateOverride;
333+
const end =
334+
changes.endDateOverride !== undefined
335+
? changes.endDateOverride
336+
: current.endDateOverride;
337+
if (start && end && start > end) {
338+
const field =
339+
changes.endDateOverride !== undefined
340+
? 'engagement.endDateOverride'
341+
: 'engagement.startDateOverride';
342+
throw new EngagementDateRangeException({ start, end }, field);
343+
}
344+
}
345+
346+
constructor(readonly value: Range<CalendarDate>, readonly field: string) {
347+
const message = "Engagement's start date must be before the end date";
348+
super({ message, field });
349+
}
350+
}

0 commit comments

Comments
 (0)