diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 8156b661..7dd9c492 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -624,6 +624,11 @@ paths: schema: type: string description: The external id. + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/JobCandidateSearchBody" responses: "200": description: OK @@ -3996,6 +4001,14 @@ components: type: string example: "topcoder user" description: "The user who updated the job last time.(Will get the user info from the token)" + JobCandidateSearchBody: + properties: + statuses: + type: array + items: + type: string + enum: ["open", "placed", "selected", "client rejected - screening", "client rejected - interview", "rejected - other", "cancelled", "interview", "topcoder-rejected", "applied", "rejected-pre-screen", "skills-test", "phone-screen", "job-closed", "offered"] + description: "The array of job Candidates status" JobCandidateRequestBody: required: - jobId diff --git a/src/controllers/JobCandidateController.js b/src/controllers/JobCandidateController.js index 4f81c7ec..a6a31fbd 100644 --- a/src/controllers/JobCandidateController.js +++ b/src/controllers/JobCandidateController.js @@ -2,6 +2,7 @@ * Controller for JobCandidate endpoints */ const HttpStatus = require('http-status-codes') +const _ = require('lodash') const service = require('../services/JobCandidateService') const helper = require('../common/helper') @@ -57,7 +58,8 @@ async function deleteJobCandidate (req, res) { * @param res the response */ async function searchJobCandidates (req, res) { - const result = await service.searchJobCandidates(req.authUser, req.query) + const query = { ...req.query, statuses: _.get(req, 'body.statuses', []) } + const result = await service.searchJobCandidates(req.authUser, query) helper.setResHeaders(req, res, result) res.send(result.result) } diff --git a/src/services/JobCandidateService.js b/src/services/JobCandidateService.js index a46917aa..b08922e4 100644 --- a/src/services/JobCandidateService.js +++ b/src/services/JobCandidateService.js @@ -283,6 +283,15 @@ async function searchJobCandidates (currentUser, criteria) { } }) }) + + // if criteria contains statuses, filter statuses with this value + if (criteria.statuses && criteria.statuses.length > 0) { + esQuery.body.query.bool.filter.push({ + terms: { + status: criteria.statuses + } + }) + } logger.debug({ component: 'JobCandidateService', context: 'searchJobCandidates', message: `Query: ${JSON.stringify(esQuery)}` }) const { body } = await esClient.search(esQuery) @@ -301,10 +310,13 @@ async function searchJobCandidates (currentUser, criteria) { logger.logFullError(err, { component: 'JobCandidateService', context: 'searchJobCandidates' }) } logger.info({ component: 'JobCandidateService', context: 'searchJobCandidates', message: 'fallback to DB query' }) - const filter = {} + const filter = { [Op.and]: [] } _.each(_.pick(criteria, ['jobId', 'userId', 'status', 'externalId']), (value, key) => { filter[Op.and].push({ [key]: value }) }) + if (criteria.statuses && criteria.statuses.length > 0) { + filter[Op.and].push({ status: criteria.statuses }) + } // include interviews if user has permission const include = [] @@ -340,6 +352,7 @@ searchJobCandidates.schema = Joi.object().keys({ jobId: Joi.string().uuid(), userId: Joi.string().uuid(), status: Joi.jobCandidateStatus(), + statuses: Joi.array().items(Joi.jobCandidateStatus()), externalId: Joi.string() }).required() }).required()