Skip to content

Commit 69fe32b

Browse files
authored
Merge pull request #825 from topcoder-platform/pm-1378
feat(PM-1379): cancel copilot opportunity
2 parents 8e30d1b + 852c89a commit 69fe32b

File tree

5 files changed

+99
-2
lines changed

5 files changed

+99
-2
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ workflows:
149149
context : org-global
150150
filters:
151151
branches:
152-
only: ['develop', 'migration-setup', 'pm-1273']
152+
only: ['develop', 'migration-setup', 'pm-1378']
153153
- deployProd:
154154
context : org-global
155155
filters:

src/permissions/constants.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,19 @@ export const PERMISSION = { // eslint-disable-line import/prefer-default-export
288288
],
289289
scopes: SCOPES_PROJECTS_WRITE,
290290
},
291+
292+
CANCEL_COPILOT_OPPORTUNITY: {
293+
meta: {
294+
title: 'Cancel copilot opportunity',
295+
group: 'Cancel copilot opportunity',
296+
description: 'Who can cancel copilot opportunity.',
297+
},
298+
topcoderRoles: [
299+
USER_ROLE.PROJECT_MANAGER,
300+
USER_ROLE.TOPCODER_ADMIN,
301+
],
302+
scopes: SCOPES_PROJECTS_WRITE,
303+
},
291304

292305
LIST_COPILOT_OPPORTUNITY: {
293306
meta: {
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import _ from 'lodash';
2+
3+
import models from '../../models';
4+
import util from '../../util';
5+
import { COPILOT_APPLICATION_STATUS, COPILOT_OPPORTUNITY_STATUS, COPILOT_REQUEST_STATUS } from '../../constants';
6+
import { PERMISSION } from '../../permissions/constants';
7+
8+
module.exports = [
9+
(req, res, next) => {
10+
if (!util.hasPermissionByReq(PERMISSION.CANCEL_COPILOT_OPPORTUNITY, req)) {
11+
const err = new Error('Unable to cancel copilot opportunity');
12+
_.assign(err, {
13+
details: JSON.stringify({ message: 'You do not have permission to cancel copilot opportunity' }),
14+
status: 403,
15+
});
16+
return Promise.reject(err);
17+
}
18+
// default values
19+
const opportunityId = _.parseInt(req.params.id);
20+
21+
return models.sequelize.transaction(async (transaction) => {
22+
req.log.debug('Canceling Copilot opportunity transaction', opportunityId);
23+
const opportunity = await models.CopilotOpportunity.findOne({
24+
where: { id: opportunityId },
25+
transaction,
26+
});
27+
28+
if (!opportunity) {
29+
const err = new Error(`No opportunity available for id ${opportunityId}`);
30+
err.status = 404;
31+
throw err;
32+
}
33+
34+
const copilotRequest = await models.CopilotRequest.findOne({
35+
where: {
36+
id: opportunity.copilotRequestId,
37+
},
38+
transaction,
39+
});
40+
41+
const applications = await models.CopilotApplication.findAll({
42+
where: {
43+
opportunityId: opportunity.id,
44+
},
45+
transaction,
46+
});
47+
48+
const promises = [];
49+
applications.forEach((application) => {
50+
promises.push(application.update({
51+
status: COPILOT_APPLICATION_STATUS.CANCELED,
52+
}, {
53+
transaction,
54+
}));
55+
});
56+
57+
await Promise.all(promises);
58+
59+
await copilotRequest.update({
60+
status: COPILOT_REQUEST_STATUS.CANCELED,
61+
}, {
62+
transaction,
63+
});
64+
65+
await opportunity.update({
66+
status: COPILOT_OPPORTUNITY_STATUS.CANCELED,
67+
}, {
68+
transaction,
69+
});
70+
71+
res.status(200).send({ id: opportunity.id });
72+
})
73+
74+
.catch((err) => {
75+
if (err.message) {
76+
_.assign(err, { details: err.message });
77+
}
78+
util.handleError('Error canceling copilot opportunity', err, req, next);
79+
});
80+
},
81+
];

src/routes/copilotOpportunity/get.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ module.exports = [
3232
})
3333
.then((copilotOpportunity) => {
3434
const plainOpportunity = copilotOpportunity.get({ plain: true });
35-
req.log.info("authUser", req.authUser);
3635
const memberIds = plainOpportunity.project.members && plainOpportunity.project.members.map((member) => member.userId);
3736
let canApplyAsCopilot = false;
3837
if (req.authUser) {

src/routes/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,10 @@ router.route('/v5/projects/copilots/opportunity/:id(\\d+)/applications')
419419
router.route('/v5/projects/copilots/opportunity/:id(\\d+)/assign')
420420
.post(require('./copilotOpportunity/assign'));
421421

422+
// Cancel Copilot opportunity
423+
router.route('/v5/projects/copilots/opportunity/:id(\\d+)/cancel')
424+
.delete(require('./copilotOpportunity/delete'));
425+
422426
// Project Estimation Items
423427
router.route('/v5/projects/:projectId(\\d+)/estimations/:estimationId(\\d+)/items')
424428
.get(require('./projectEstimationItems/list'));

0 commit comments

Comments
 (0)