1
- import { isNotFalsy , NonEmptyArray } from '@seedcompany/common' ;
2
- import { CalendarDate , ID , RangeException , type UnsecuredDto } from '~/common' ;
1
+ import { DateOverrideConflictException , EnhancedResource } from '~/common' ;
3
2
import { EventsHandler , IEventHandler } from '~/core' ;
4
- import type { Project } from '../../project/dto' ;
5
3
import { ProjectUpdatedEvent } from '../../project/events' ;
6
4
import { EngagementService } from '../engagement.service' ;
7
5
@@ -12,84 +10,37 @@ export class ValidateEngDateOverridesOnProjectChangeHandler
12
10
constructor ( private readonly engagements : EngagementService ) { }
13
11
14
12
async handle ( event : ProjectUpdatedEvent ) {
15
- const { changes , updated , session } = event ;
13
+ const { updated : project , changes , session } = event ;
16
14
17
15
if ( changes . mouStart === undefined && changes . mouEnd === undefined ) {
18
16
return ;
19
17
}
20
18
21
- const project = {
22
- id : updated . id ,
23
- name : updated . name ,
24
- mouStart : updated . mouStart ,
25
- mouEnd : updated . mouEnd ,
26
- } ;
27
19
const engagements = await this . engagements . listAllByProjectId (
28
20
project . id ,
29
21
session ,
30
22
) ;
31
- const errors = engagements
32
- . flatMap <
33
- EngagementDateOverrideConflictException [ 'engagements' ] [ 0 ] | null
34
- > ( ( eng ) => {
35
- const common = {
36
- id : eng . id ,
37
- label : ( eng . label . language ?? eng . label . intern ) ! ,
38
- } as const ;
39
- const { startDateOverride : start , endDateOverride : end } = eng ;
40
- return [
41
- project . mouStart && start && project . mouStart > start
42
- ? {
43
- ...common ,
44
- point : 'start' as const ,
45
- date : start ,
46
- }
47
- : null ,
48
- project . mouEnd && end && project . mouEnd < end
49
- ? {
50
- ...common ,
51
- point : 'end' as const ,
52
- date : end ,
53
- }
54
- : null ,
55
- ] ;
56
- } )
57
- . filter ( isNotFalsy ) ;
58
- if ( errors . length === 0 ) {
59
- return ;
60
- }
61
- throw new EngagementDateOverrideConflictException ( project , [
62
- errors [ 0 ] ! ,
63
- ...errors . slice ( 1 ) ,
64
- ] ) ;
65
- }
66
- }
67
-
68
- class EngagementDateOverrideConflictException extends RangeException {
69
- constructor (
70
- readonly project : Pick <
71
- UnsecuredDto < Project > ,
72
- 'id' | 'name' | 'mouStart' | 'mouEnd'
73
- > ,
74
- readonly engagements : NonEmptyArray <
75
- Readonly < {
76
- id : ID < 'Engagement' > ;
77
- label : string ;
78
- point : 'start' | 'end' ;
79
- date : CalendarDate ;
80
- } >
81
- > ,
82
- ) {
83
- const message = [
84
- engagements . length === 1
85
- ? 'An engagement has a date outside the new range'
86
- : 'Some engagements have dates outside the new range' ,
87
- ...engagements . map ( ( eng ) => {
88
- const pointStr = eng . point === 'start' ? 'Start' : 'End' ;
89
- const dateStr = eng . date . toISO ( ) ;
90
- return ` - ${ pointStr } date of ${ eng . label } is ${ dateStr } ` ;
91
- } ) ,
92
- ] . join ( '\n' ) ;
93
- super ( { message } ) ;
23
+ const canonical = { start : project . mouStart , end : project . mouEnd } ;
24
+ const conflicts = DateOverrideConflictException . findConflicts (
25
+ canonical ,
26
+ engagements . map ( ( eng ) => ( {
27
+ __typename : EnhancedResource . resolve ( eng . __typename ) . name ,
28
+ id : eng . id ,
29
+ label : ( eng . label . language ?? eng . label . intern ) ! ,
30
+ start : eng . startDateOverride ,
31
+ end : eng . endDateOverride ,
32
+ } ) ) ,
33
+ ) ;
34
+ if ( ! conflicts ) return ;
35
+ throw new DateOverrideConflictException (
36
+ {
37
+ __typename : event . resource . name ,
38
+ id : project . id ,
39
+ name : project . name ,
40
+ } ,
41
+ canonical ,
42
+ [ 'An engagement' , 'Some engagements' ] ,
43
+ conflicts ,
44
+ ) ;
94
45
}
95
46
}
0 commit comments