Skip to content
13 changes: 13 additions & 0 deletions docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion src/controllers/JobCandidateController.js
Original file line number Diff line number Diff line change
Expand Up @@ -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')

Expand Down Expand Up @@ -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)
}
Expand Down
15 changes: 14 additions & 1 deletion src/services/JobCandidateService.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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 = []
Expand Down Expand Up @@ -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()
Expand Down