11import _ from 'lodash' ;
22import validate from 'express-validation' ;
33import Joi from 'joi' ;
4+ import config from 'config' ;
45
56import models from '../../models' ;
67import util from '../../util' ;
78import { 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' ;
913
1014const assignCopilotOpportunityValidations = {
1115 body : Joi . object ( ) . keys ( {
@@ -45,11 +49,17 @@ module.exports = [
4549 throw err ;
4650 }
4751
52+ const copilotRequest = await models . CopilotRequest . findOne ( {
53+ where : { id : opportunity . copilotRequestId } ,
54+ transaction : t ,
55+ } ) ;
56+
4857 const application = await models . CopilotApplication . findOne ( {
4958 where : { id : applicationId , opportunityId : copilotOpportunityId } ,
5059 transaction : t ,
5160 } ) ;
5261
62+
5363 if ( ! application ) {
5464 const err = new Error ( 'No such application available' ) ;
5565 err . status = 400 ;
@@ -65,12 +75,101 @@ module.exports = [
6575 const projectId = opportunity . projectId ;
6676 const userId = application . userId ;
6777 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 ;
74173 }
75174
76175 const existingInvite = await models . ProjectMemberInvite . findAll ( {
0 commit comments