-
Notifications
You must be signed in to change notification settings - Fork 55
feat(PM-1168): Added API to assign an opportunity with an applicant #805
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
aeb7b48
af846ab
709601f
4543e5e
9f7dc48
7f40cdb
8e2881d
2ee4f9b
2fd1652
f181533
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| module.exports = { | ||
| up: async (queryInterface, Sequelize) => { | ||
| await queryInterface.addColumn('copilot_applications', 'status', { | ||
| type: Sequelize.STRING(16), | ||
| allowNull: true, | ||
hentrymartin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }); | ||
|
|
||
| await queryInterface.sequelize.query( | ||
| `UPDATE copilot_applications SET status = 'pending' WHERE status IS NULL` | ||
| ); | ||
|
|
||
| await queryInterface.changeColumn('copilot_applications', 'status', { | ||
| type: Sequelize.STRING(16), | ||
| allowNull: false, | ||
| }); | ||
| }, | ||
|
|
||
| down: async (queryInterface) => { | ||
| await queryInterface.removeColumn('copilot_applications', 'status'); | ||
| }, | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| import _ from 'lodash'; | ||
| import validate from 'express-validation'; | ||
| import Joi from 'joi'; | ||
|
|
||
| import models from '../../models'; | ||
| import util from '../../util'; | ||
| import { PERMISSION } from '../../permissions/constants'; | ||
| import { COPILOT_APPLICATION_STATUS, COPILOT_OPPORTUNITY_STATUS } from '../../constants'; | ||
|
|
||
| const assignCopilotOpportunityValidations = { | ||
| body: Joi.object().keys({ | ||
| applicationId: Joi.string(), | ||
| }), | ||
| }; | ||
|
|
||
| module.exports = [ | ||
| validate(assignCopilotOpportunityValidations), | ||
| async (req, res, next) => { | ||
| const { applicationId } = req.body; | ||
| const copilotOpportunityId = _.parseInt(req.params.id); | ||
| if (!util.hasPermissionByReq(PERMISSION.ASSIGN_COPILOT_OPPORTUNITY, req)) { | ||
| const err = new Error('Unable to assign copilot opportunity'); | ||
| _.assign(err, { | ||
| details: JSON.stringify({ message: 'You do not have permission to assign a copilot opportunity' }), | ||
| status: 403, | ||
| }); | ||
| return next(err); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is |
||
| } | ||
|
|
||
| return models.sequelize.transaction(() => { | ||
| models.CopilotOpportunity.findOne({ | ||
| where: { | ||
| id: copilotOpportunityId, | ||
| }, | ||
| }).then(async (opportunity) => { | ||
| if (!opportunity) { | ||
| const err = new Error('No opportunity found'); | ||
| err.status = 404; | ||
| return next(err); | ||
| } | ||
|
|
||
| if (opportunity.status !== COPILOT_OPPORTUNITY_STATUS.ACTIVE) { | ||
| const err = new Error('Opportunity is not active'); | ||
| err.status = 400; | ||
| return next(err); | ||
| } | ||
|
|
||
| const application = models.CopilotApplication.findOne({ | ||
hentrymartin marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| where: { | ||
| id: applicationId, | ||
| }, | ||
| }); | ||
|
|
||
| if (!application) { | ||
hentrymartin marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| const err = new Error('No such application available'); | ||
| err.status = 400; | ||
| return next(err); | ||
| } | ||
|
|
||
| if (application.status === COPILOT_APPLICATION_STATUS.ACCEPTED) { | ||
| const err = new Error('Application already accepted'); | ||
| err.status = 400; | ||
| return next(err); | ||
| } | ||
|
|
||
| const projectId = opportunity.projectId; | ||
| const userId = application.userId; | ||
|
|
||
| const activeMembers = await models.ProjectMember.getActiveProjectMembers(projectId); | ||
|
|
||
| const existingUser = activeMembers.find(item => item.userId === userId); | ||
|
|
||
| if (existingUser) { | ||
|
||
| const err = new Error(`User is already part of the project as ${existingUser.role}`); | ||
| err.status = 400; | ||
| return next(err); | ||
| } | ||
|
|
||
|
|
||
hentrymartin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return opportunity.update({status: COPILOT_OPPORTUNITY_STATUS.COMPLETED}) | ||
| }) | ||
| .then(async () => { | ||
hentrymartin marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| await models.CopilotApplication.update({ | ||
hentrymartin marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| status: COPILOT_APPLICATION_STATUS.ACCEPTED, | ||
| }, { | ||
| where: { | ||
| id: applicationId, | ||
| } | ||
| }); | ||
|
|
||
| res.status(200).send({id: applicationId}); | ||
hentrymartin marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return Promise.resolve() | ||
| }) | ||
| }) | ||
| .catch(err => next(err)); | ||
| }, | ||
| ]; | ||
Uh oh!
There was an error while loading. Please reload this page.