22import validate from 'express-validation' ;
33import _ from 'lodash' ;
44import Joi from 'joi' ;
5+ import config from 'config' ;
6+ import moment from 'moment' ;
7+ import { Op } from 'sequelize' ;
58import { middleware as tcMiddleware } from 'tc-core-library-js' ;
69import models from '../../models' ;
710import util from '../../util' ;
8- import { EVENT , RESOURCES , PROJECT_MEMBER_ROLE , COPILOT_REQUEST_STATUS , COPILOT_OPPORTUNITY_STATUS , COPILOT_APPLICATION_STATUS } from '../../constants' ;
11+ import { EVENT , RESOURCES , PROJECT_MEMBER_ROLE , COPILOT_REQUEST_STATUS , COPILOT_OPPORTUNITY_STATUS , COPILOT_APPLICATION_STATUS , USER_ROLE , CONNECT_NOTIFICATION_EVENT , TEMPLATE_IDS } from '../../constants' ;
912import { PERMISSION , PROJECT_TO_TOPCODER_ROLES_MATRIX } from '../../permissions/constants' ;
10- import { Op } from 'sequelize' ;
13+ import { createEvent } from '../../services/busApi' ;
14+ import { getCopilotTypeLabel } from '../../utils/copilot' ;
15+
1116
1217/**
1318 * API to update a project member.
@@ -28,17 +33,24 @@ const updateProjectMemberValdiations = {
2833 PROJECT_MEMBER_ROLE . SOLUTION_ARCHITECT ,
2934 PROJECT_MEMBER_ROLE . PROJECT_MANAGER ,
3035 ) . required ( ) ,
31- action : Joi . string ( ) . optional ( ) ,
36+ action : Joi . string ( ) . allow ( '' ) . optional ( ) ,
3237 } ) ,
3338 query : {
3439 fields : Joi . string ( ) . optional ( ) ,
3540 } ,
3641} ;
3742
38- const completeAllCopilotRequests = async ( req , projectId , _transaction ) => {
43+ const completeAllCopilotRequests = async ( req , projectId , _transaction , _member ) => {
3944 const allCopilotRequests = await models . CopilotRequest . findAll ( {
4045 where : {
4146 projectId,
47+ status : {
48+ [ Op . in ] : [
49+ COPILOT_REQUEST_STATUS . APPROVED ,
50+ COPILOT_REQUEST_STATUS . NEW ,
51+ COPILOT_REQUEST_STATUS . SEEKING ,
52+ ] ,
53+ }
4254 } ,
4355 transaction : _transaction ,
4456 } ) ;
@@ -91,20 +103,68 @@ const completeAllCopilotRequests = async (req, projectId, _transaction) => {
91103 transaction : _transaction ,
92104 } ) ;
93105
106+ const memberApplication = allCopilotApplications . find ( app => app . userId === _member . userId ) ;
107+ const applicationsWithoutMemberApplication = allCopilotApplications . filter ( app => app . userId !== _member . userId ) ;
108+
94109 req . log . debug ( `all copilot applications ${ JSON . stringify ( allCopilotApplications ) } ` ) ;
95110
96111 await models . CopilotApplication . update ( {
97112 status : COPILOT_APPLICATION_STATUS . CANCELED ,
98113 } , {
99114 where : {
100115 id : {
101- [ Op . in ] : allCopilotApplications . map ( item => item . id ) ,
116+ [ Op . in ] : applicationsWithoutMemberApplication . map ( item => item . id ) ,
102117 } ,
103118 } ,
104119 transaction : _transaction ,
105120 } ) ;
106121
122+ // If the invited member
123+ if ( memberApplication ) {
124+ await models . CopilotApplication . update ( {
125+ status : COPILOT_APPLICATION_STATUS . ACCEPTED ,
126+ } , {
127+ where : {
128+ id : memberApplication . id ,
129+ } ,
130+ transaction : _transaction ,
131+ } ) ;
132+ }
133+
107134 req . log . debug ( `updated all copilot applications` ) ;
135+
136+ const memberDetails = await util . getMemberDetailsByUserIds ( [ _member . userId ] , req . log , req . id ) ;
137+ const member = memberDetails [ 0 ] ;
138+
139+ req . log . debug ( `member details: ${ JSON . stringify ( member ) } ` ) ;
140+
141+ const emailEventType = CONNECT_NOTIFICATION_EVENT . EXTERNAL_ACTION_EMAIL ;
142+ const copilotPortalUrl = config . get ( 'copilotPortalUrl' ) ;
143+ allCopilotRequests . forEach ( ( request ) => {
144+ const requestData = request . data ;
145+
146+ req . log . debug ( `Copilot request data: ${ JSON . stringify ( requestData ) } ` ) ;
147+ const opportunity = copilotOpportunites . find ( item => item . copilotRequestId === request . id ) ;
148+
149+ req . log . debug ( `Opportunity: ${ JSON . stringify ( opportunity ) } ` ) ;
150+ createEvent ( emailEventType , {
151+ data : {
152+ opportunity_details_url : `${ copilotPortalUrl } /opportunity/${ opportunity . id } ` ,
153+ work_manager_url : config . get ( 'workManagerUrl' ) ,
154+ opportunity_type : getCopilotTypeLabel ( requestData . projectType ) ,
155+ opportunity_title : requestData . opportunityTitle ,
156+ start_date : moment . utc ( requestData . startDate ) . format ( 'DD-MM-YYYY' ) ,
157+ user_name : member ? member . handle : "" ,
158+ } ,
159+ sendgrid_template_id : TEMPLATE_IDS . COPILOT_ALREADY_PART_OF_PROJECT ,
160+ recipients : [ member . email ] ,
161+ version : 'v3' ,
162+ } , req . log ) ;
163+
164+ req . log . debug ( `Sent email to ${ member . email } ` ) ;
165+ } ) ;
166+
167+ await _transaction . commit ( ) ;
108168} ;
109169
110170module . exports = [
@@ -125,7 +185,7 @@ module.exports = [
125185
126186 let previousValue ;
127187 // let newValue;
128- models . sequelize . transaction ( ( _transaction ) => models . ProjectMember . findOne ( {
188+ models . sequelize . transaction ( async ( _transaction ) => models . ProjectMember . findOne ( {
129189 where : { id : memberRecordId , projectId } ,
130190 } )
131191 . then ( async ( _member ) => {
@@ -157,7 +217,7 @@ module.exports = [
157217 if ( ( updatedProps . role === previousValue . role || action === 'complete-copilot-requests' ) &&
158218 ( _ . isUndefined ( updatedProps . isPrimary ) ||
159219 updatedProps . isPrimary === previousValue . isPrimary ) ) {
160- await completeAllCopilotRequests ( req , projectId , _transaction ) ;
220+ await completeAllCopilotRequests ( req , projectId , _transaction , _member ) ;
161221 return Promise . resolve ( ) ;
162222 }
163223
@@ -204,7 +264,7 @@ module.exports = [
204264 projectMember = _ . omit ( projectMember , [ 'deletedAt' ] ) ;
205265
206266 if ( [ 'observer' , 'customer' ] . includes ( updatedProps . role ) ) {
207- await completeAllCopilotRequests ( req , projectId , _transaction ) ;
267+ await completeAllCopilotRequests ( req , projectId , _transaction , _member ) ;
208268 }
209269 } )
210270 . then ( ( ) => (
@@ -227,6 +287,9 @@ module.exports = [
227287 req . log . debug ( 'updated project member' , projectMember ) ;
228288 res . json ( memberWithDetails || projectMember ) ;
229289 } )
230- . catch ( err => next ( err ) ) ) ;
290+ . catch ( async ( err ) => {
291+ await _transaction . rollback ( ) ;
292+ return next ( err ) ;
293+ } ) ) ;
231294 } ,
232295] ;
0 commit comments