1
1
import _ from 'lodash' ;
2
2
import validate from 'express-validation' ;
3
3
import Joi from 'joi' ;
4
+ import config from 'config' ;
4
5
5
6
import models from '../../models' ;
6
7
import util from '../../util' ;
7
8
import { PERMISSION } from '../../permissions/constants' ;
8
- import { COPILOT_APPLICATION_STATUS , COPILOT_OPPORTUNITY_STATUS , COPILOT_REQUEST_STATUS , EVENT , INVITE_STATUS , PROJECT_MEMBER_ROLE , RESOURCES } from '../../constants' ;
9
+ import { CONNECT_NOTIFICATION_EVENT , COPILOT_APPLICATION_STATUS , COPILOT_OPPORTUNITY_STATUS , COPILOT_REQUEST_STATUS , EVENT , INVITE_STATUS , PROJECT_MEMBER_ROLE , RESOURCES , TEMPLATE_IDS } from '../../constants' ;
10
+ import { getCopilotTypeLabel } from '../../utils/copilot' ;
11
+ import { createEvent } from '../../services/busApi' ;
12
+ import moment from 'moment' ;
9
13
10
14
const assignCopilotOpportunityValidations = {
11
15
body : Joi . object ( ) . keys ( {
@@ -45,11 +49,17 @@ module.exports = [
45
49
throw err ;
46
50
}
47
51
52
+ const copilotRequest = await models . CopilotRequest . findOne ( {
53
+ where : { id : opportunity . copilotRequestId } ,
54
+ transaction : t ,
55
+ } ) ;
56
+
48
57
const application = await models . CopilotApplication . findOne ( {
49
58
where : { id : applicationId , opportunityId : copilotOpportunityId } ,
50
59
transaction : t ,
51
60
} ) ;
52
61
62
+
53
63
if ( ! application ) {
54
64
const err = new Error ( 'No such application available' ) ;
55
65
err . status = 400 ;
@@ -65,12 +75,101 @@ module.exports = [
65
75
const projectId = opportunity . projectId ;
66
76
const userId = application . userId ;
67
77
const activeMembers = await models . ProjectMember . getActiveProjectMembers ( projectId , t ) ;
68
-
69
- const existingUser = activeMembers . find ( item => item . userId === userId ) ;
70
- if ( existingUser && existingUser . role === 'copilot' ) {
71
- const err = new Error ( `User is already a copilot of this project` ) ;
72
- err . status = 400 ;
73
- throw err ;
78
+ const updateCopilotOpportunity = async ( ) => {
79
+ const transaction = await models . sequelize . transaction ( ) ;
80
+ const memberDetails = await util . getMemberDetailsByUserIds ( [ application . userId ] , req . log , req . id ) ;
81
+ const member = memberDetails [ 0 ] ;
82
+ req . log . debug ( `Updating opportunity: ${ JSON . stringify ( opportunity ) } ` ) ;
83
+ await opportunity . update ( {
84
+ status : COPILOT_OPPORTUNITY_STATUS . COMPLETED ,
85
+ } , {
86
+ transaction,
87
+ } ) ;
88
+ req . log . debug ( `Updating application: ${ JSON . stringify ( application ) } ` ) ;
89
+ await application . update ( {
90
+ status : COPILOT_APPLICATION_STATUS . ACCEPTED ,
91
+ } , {
92
+ transaction,
93
+ } ) ;
94
+
95
+ req . log . debug ( `Updating request: ${ JSON . stringify ( copilotRequest ) } ` ) ;
96
+ await copilotRequest . update ( {
97
+ status : COPILOT_REQUEST_STATUS . FULFILLED ,
98
+ } , {
99
+ transaction,
100
+ } ) ;
101
+
102
+ req . log . debug ( `Updating other applications: ${ JSON . stringify ( copilotRequest ) } ` ) ;
103
+ await models . CopilotApplication . update ( {
104
+ status : COPILOT_APPLICATION_STATUS . CANCELED ,
105
+ } , {
106
+ where : {
107
+ opportunityId : opportunity . id ,
108
+ id : {
109
+ $ne : application . id ,
110
+ } ,
111
+ }
112
+ } ) ;
113
+
114
+ req . log . debug ( `All updations done` ) ;
115
+ transaction . commit ( ) ;
116
+
117
+ req . log . debug ( `Sending email notification` ) ;
118
+ const emailEventType = CONNECT_NOTIFICATION_EVENT . EXTERNAL_ACTION_EMAIL ;
119
+ const copilotPortalUrl = config . get ( 'copilotPortalUrl' ) ;
120
+ const requestData = copilotRequest . data ;
121
+ createEvent ( emailEventType , {
122
+ data : {
123
+ opportunity_details_url : `${ copilotPortalUrl } /opportunity/${ opportunity . id } ` ,
124
+ work_manager_url : config . get ( 'workManagerUrl' ) ,
125
+ opportunity_type : getCopilotTypeLabel ( requestData . projectType ) ,
126
+ opportunity_title : requestData . opportunityTitle ,
127
+ start_date : moment . utc ( requestData . startDate ) . format ( 'DD-MM-YYYY' ) ,
128
+ user_name : member ? member . handle : "" ,
129
+ } ,
130
+ sendgrid_template_id : TEMPLATE_IDS . COPILOT_ALREADY_PART_OF_PROJECT ,
131
+ recipients : [ member . email ] ,
132
+ version : 'v3' ,
133
+ } , req . log ) ;
134
+
135
+ req . log . debug ( `Email sent` ) ;
136
+ } ;
137
+
138
+ const existingMember = activeMembers . find ( item => item . userId === userId ) ;
139
+ if ( existingMember ) {
140
+ req . log . debug ( `User already part of project: ${ JSON . stringify ( existingMember ) } ` ) ;
141
+ if ( [ 'copilot' , 'manager' ] . includes ( existingMember . role ) ) {
142
+ req . log . debug ( `User is a copilot or manager` ) ;
143
+ await updateCopilotOpportunity ( ) ;
144
+ } else {
145
+ req . log . debug ( `User has read/write role` ) ;
146
+ await models . ProjectMember . update ( {
147
+ role : 'copilot' ,
148
+ } , {
149
+ where : {
150
+ id : existingMember . id ,
151
+ } ,
152
+ } ) ;
153
+
154
+ const projectMember = await models . ProjectMember . findOne ( {
155
+ where : {
156
+ id : existingMember . id ,
157
+ } ,
158
+ } ) ;
159
+
160
+ req . log . debug ( `Updated project member: ${ JSON . stringify ( projectMember . get ( { plain : true } ) ) } ` ) ;
161
+
162
+ util . sendResourceToKafkaBus (
163
+ req ,
164
+ EVENT . ROUTING_KEY . PROJECT_MEMBER_UPDATED ,
165
+ RESOURCES . PROJECT_MEMBER ,
166
+ projectMember . get ( { plain : true } ) ,
167
+ existingMember ) ;
168
+ req . log . debug ( `Member updated in kafka` ) ;
169
+ await updateCopilotOpportunity ( ) ;
170
+ }
171
+ res . status ( 200 ) . send ( { id : applicationId } ) ;
172
+ return ;
74
173
}
75
174
76
175
const existingInvite = await models . ProjectMemberInvite . findAll ( {
0 commit comments