@@ -19,6 +19,7 @@ const paymentService = require('./paymentService')
19
19
const { createOrSetNumberOfReviewers } = require ( './selfServiceReviewerService' )
20
20
const { disableTimelineNotifications } = require ( './selfServiceNotificationService' )
21
21
const legacyChallengeService = require ( './legacyChallengeService' )
22
+ const legacyChallengeReviewService = require ( './legacyChallengeReviewService' )
22
23
23
24
/**
24
25
* Drop and recreate phases in ifx
@@ -51,6 +52,30 @@ async function recreatePhases (legacyId, v5Phases, createdBy) {
51
52
phase . duration * 1000 ,
52
53
createdBy
53
54
)
55
+ //Handle checkpoint phases
56
+ //Magic numbers: 15=checkpoint submission, 16=checkpoint screen, 17=checkpoint review, 1=registration
57
+ //For dependencyStart: 1=start, 0=end
58
+ if ( phaseLegacyId == 17 ) {
59
+ logger . info ( `Creating phase dependencies for checkpoint phases` )
60
+
61
+ const registrationPhaseId = await timelineService . getProjectPhaseId ( legacyId , 1 )
62
+ const checkpointSubmissionPhaseId = await timelineService . getProjectPhaseId ( legacyId , 15 )
63
+ const checkpointScreeningPhaseId = await timelineService . getProjectPhaseId ( legacyId , 16 )
64
+ const checkpointReviewPhaseId = await timelineService . getProjectPhaseId ( legacyId , 17 )
65
+
66
+ await timelineService . insertPhaseDependency ( registrationPhaseId , checkpointSubmissionPhaseId , 1 , createdBy )
67
+ await timelineService . insertPhaseDependency ( checkpointSubmissionPhaseId , checkpointScreeningPhaseId , 0 , createdBy )
68
+ await timelineService . insertPhaseDependency ( checkpointScreeningPhaseId , checkpointReviewPhaseId , 0 , createdBy )
69
+
70
+ logger . info ( `Creating default scorecard records for checkpoint phases` )
71
+ //30001364 is the default checkpoint screening scorecard for studio (https://software.topcoder-dev.com/review/actions/ViewScorecard?scid=30001364)
72
+ await timelineService . insertScorecardId ( checkpointScreeningPhaseId , 30001364 , createdBy )
73
+
74
+ //30001364 is the default checkpoint review scorecard for studio (https://software.topcoder-dev.com/review/actions/ViewScorecard?scid=30001004)
75
+ await timelineService . insertScorecardId ( checkpointReviewPhaseId , 30001004 , createdBy )
76
+
77
+
78
+ }
54
79
} else if ( ! phaseLegacyId ) {
55
80
logger . warn ( `Could not create phase ${ phase . name } on legacy!` )
56
81
}
@@ -79,42 +104,53 @@ async function syncChallengePhases (legacyId, v5Phases, createdBy, isSelfService
79
104
const phasesFromIFx = await timelineService . getChallengePhases ( legacyId )
80
105
logger . debug ( `Phases from v5: ${ JSON . stringify ( v5Phases ) } ` )
81
106
logger . debug ( `Phases from IFX: ${ JSON . stringify ( phasesFromIFx ) } ` )
82
- for ( const phase of phasesFromIFx ) {
83
- const phaseName = _ . get ( _ . find ( phaseTypes , pt => pt . phase_type_id === phase . phase_type_id ) , 'name' )
84
- const v5Equivalent = _ . find ( v5Phases , p => p . name === phaseName )
85
- logger . info ( `v4 Phase: ${ JSON . stringify ( phase ) } , v5 Equiv: ${ JSON . stringify ( v5Equivalent ) } ` )
86
- if ( v5Equivalent ) {
87
- // Compare duration and status
88
- // if (v5Equivalent.duration * 1000 !== phase.duration * 1 || isSelfService) {
89
- // ||
90
- // (v5Equivalent.isOpen && _.toInteger(phase.phase_status_id) === constants.PhaseStatusTypes.Closed) ||
91
- // (!v5Equivalent.isOpen && _.toInteger(phase.phase_status_id) === constants.PhaseStatusTypes.Open)) {
92
- // const newStatus = v5Equivalent.isOpen
93
- // ? constants.PhaseStatusTypes.Open
94
- // : (new Date().getTime() <= new Date(v5Equivalent.scheduledEndDate).getTime() ? constants.PhaseStatusTypes.Scheduled : constants.PhaseStatusTypes.Closed)
95
- // update phase
96
- logger . debug ( `Will update phase ${ phaseName } /${ v5Equivalent . name } from ${ phase . duration } to duration ${ v5Equivalent . duration * 1000 } milli` )
97
- const newStatus = v5Equivalent . isOpen
98
- ? constants . PhaseStatusTypes . Open
99
- : ( _ . toInteger ( phase . phase_status_id ) === constants . PhaseStatusTypes . Scheduled ? constants . PhaseStatusTypes . Scheduled : constants . PhaseStatusTypes . Closed )
100
- await timelineService . updatePhase (
101
- phase . project_phase_id ,
102
- legacyId ,
103
- v5Equivalent . scheduledStartDate ,
104
- v5Equivalent . scheduledEndDate ,
105
- v5Equivalent . duration * 1000 ,
106
- newStatus // phase.phase_status_id
107
- )
108
- // newStatus)
109
- // } else {
110
- // logger.info(`Durations for ${phaseName} match: ${v5Equivalent.duration * 1000} === ${phase.duration}`)
111
- // }
112
- } else {
113
- logger . info ( `No v5 Equivalent Found for ${ phaseName } ` )
107
+ let phaseGroups = { }
108
+ _ . forEach ( phasesFromIFx , p => {
109
+ if ( ! phaseGroups [ p . phase_type_id ] ) {
110
+ phaseGroups [ p . phase_type_id ] = [ ]
114
111
}
115
- if ( isSelfService && phaseName === 'Review' ) {
116
- // make sure to set the required reviewers to 2
117
- await createOrSetNumberOfReviewers ( _ . toString ( phase . project_phase_id ) , _ . toString ( numOfReviewers ) , _ . toString ( createdBy ) )
112
+ phaseGroups [ p . phase_type_id ] . push ( p )
113
+ } )
114
+ _ . forEach ( _ . cloneDeep ( phaseGroups ) , ( pg , pt ) => {
115
+ phaseGroups [ pt ] = _ . sortBy ( pg , 'scheduled_start_time' )
116
+ } )
117
+
118
+ for ( const key of _ . keys ( phaseGroups ) ) {
119
+ let phaseOrder = 0
120
+ let v5Equivalents = undefined
121
+ for ( const phase of phaseGroups [ key ] ) {
122
+ const phaseName = _ . get ( _ . find ( phaseTypes , pt => pt . phase_type_id === phase . phase_type_id ) , 'name' )
123
+ if ( _ . isUndefined ( v5Equivalents ) ) {
124
+ v5Equivalents = _ . sortBy ( _ . filter ( v5Phases , p => p . name === phaseName ) , 'scheduledStartDate' )
125
+ }
126
+ if ( v5Equivalents . length > 0 ) {
127
+ if ( v5Equivalents . length === phaseGroups [ key ] . length ) {
128
+ const v5Equivalent = v5Equivalents [ phaseOrder ]
129
+ logger . debug ( `Will update phase ${ phaseName } /${ v5Equivalent . name } from ${ phase . duration } to duration ${ v5Equivalent . duration * 1000 } milli` )
130
+ let newStatus = _ . toInteger ( phase . phase_status_id )
131
+ if ( v5Equivalent . isOpen && _ . toInteger ( phase . phase_status_id ) === constants . PhaseStatusTypes . Closed ) {
132
+ newStatus = constants . PhaseStatusTypes . Scheduled
133
+ }
134
+ await timelineService . updatePhase (
135
+ phase . project_phase_id ,
136
+ legacyId ,
137
+ phase . fixed_start_time ? v5Equivalent . scheduledStartDate : null ,
138
+ v5Equivalent . scheduledStartDate ,
139
+ v5Equivalent . scheduledEndDate ,
140
+ v5Equivalent . duration * 1000 ,
141
+ newStatus
142
+ )
143
+ } else {
144
+ logger . info ( `number of ${ phaseName } does not match` )
145
+ }
146
+ } else {
147
+ logger . info ( `No v5 Equivalent Found for ${ phaseName } ` )
148
+ }
149
+ if ( isSelfService && phaseName === 'Review' ) {
150
+ // make sure to set the required reviewers to 2
151
+ await createOrSetNumberOfReviewers ( _ . toString ( phase . project_phase_id ) , _ . toString ( numOfReviewers ) , _ . toString ( createdBy ) )
152
+ }
153
+ phaseOrder = phaseOrder + 1
118
154
}
119
155
}
120
156
// TODO: What about iterative reviews? There can be many for the same challenge.
@@ -701,6 +737,28 @@ async function processMessage (message) {
701
737
throw new Error ( `Error getting challenge by id - Error: ${ JSON . stringify ( e ) } ` )
702
738
}
703
739
740
+ // If iterative review is open
741
+ if ( _ . find ( _ . get ( message . payload , 'phases' ) , p => p . isOpen && p . name === 'Iterative Review' ) ) {
742
+ // Try to read reviews and insert them into informix DB
743
+ if ( message . payload . metadata && message . payload . legacy . reviewScorecardId ) {
744
+ let orReviewFeedback = _ . find ( message . payload . metadata , meta => meta . name === 'or_review_feedback' )
745
+ let orReviewScore = _ . find ( message . payload . metadata , meta => meta . name === 'or_review_score' )
746
+ if ( ! _ . isUndefined ( orReviewFeedback ) && ! _ . isUndefined ( orReviewScore ) ) {
747
+ orReviewFeedback = JSON . parse ( orReviewFeedback )
748
+ const reviewResponses = [ ]
749
+ _ . each ( orReviewFeedback , ( value , key ) => {
750
+ const questionId = _ . get ( _ . find ( constants . scorecardQuestionMapping [ message . payload . legacy . reviewScorecardId ] , item => _ . toString ( item . questionId ) === _ . toString ( key ) || _ . toLower ( item . description ) === _ . toLower ( key ) ) , 'questionId' )
751
+ reviewResponses . push ( {
752
+ questionId,
753
+ answer : value
754
+ } )
755
+ } )
756
+ orReviewScore = _ . toNumber ( orReviewFeedback )
757
+ await legacyChallengeReviewService . insertReview ( legacyId , message . payload . legacy . reviewScorecardId , orReviewScore , reviewResponses , createdByUserId )
758
+ }
759
+ }
760
+ }
761
+
704
762
if ( message . payload . status && challenge ) {
705
763
// Whether we need to sync v4 ES again
706
764
let needSyncV4ES = false
@@ -788,7 +846,7 @@ processMessage.schema = {
788
846
prizeSets : Joi . array ( ) . items ( Joi . object ( ) . keys ( {
789
847
type : Joi . string ( ) . valid ( _ . values ( constants . prizeSetTypes ) ) . required ( ) ,
790
848
prizes : Joi . array ( ) . items ( Joi . object ( ) . keys ( {
791
- value : Joi . number ( ) . positive ( ) . required ( )
849
+ value : Joi . number ( ) . min ( 0 ) . required ( )
792
850
} ) . unknown ( true ) )
793
851
} ) . unknown ( true ) ) . min ( 1 ) ,
794
852
tags : Joi . array ( ) . items ( Joi . string ( ) . required ( ) ) . min ( 1 ) , // tag names
0 commit comments