@@ -28,7 +28,7 @@ const esClient = helper.getESClient()
28
28
* @param {String } jobId the job id
29
29
* @returns {Array } the list of candidates
30
30
*/
31
- async function _getJobCandidates ( jobId ) {
31
+ async function _getJobCandidates ( jobId ) {
32
32
const { body } = await esClient . search ( {
33
33
index : config . get ( 'esConfig.ES_INDEX_JOB_CANDIDATE' ) ,
34
34
body : {
@@ -60,7 +60,7 @@ async function _getJobCandidates (jobId) {
60
60
* @param {Array } skills the list of skills
61
61
* @returns {undefined }
62
62
*/
63
- async function _validateSkills ( skills ) {
63
+ async function _validateSkills ( skills ) {
64
64
const responses = await Promise . all (
65
65
skills . map (
66
66
skill => helper . getSkillById ( skill . skillId )
@@ -81,13 +81,31 @@ async function _validateSkills (skills) {
81
81
}
82
82
}
83
83
84
+ /**
85
+ * Validate by exact match on name field if all skills exist.
86
+ *
87
+ * @param {Array } skillNames the list of skill names to validate
88
+ * @returns {Array } the list of matching skill objects
89
+ */
90
+ async function _validateAndGetSkillsByNames ( skillNames ) {
91
+ const skills = await helper . getSkillsByExactNames ( skillNames )
92
+
93
+ if ( skills . length !== skillNames . length ) {
94
+ const foundSkillNames = skills . map ( skill => skill . name )
95
+ const notFoundSkillNames = _ . difference ( skillNames , foundSkillNames )
96
+ throw new errors . BadRequestError ( `Invalid skills: [${ notFoundSkillNames } ]` )
97
+ }
98
+
99
+ return skills
100
+ }
101
+
84
102
/**
85
103
* Validate if all roles exist.
86
104
*
87
105
* @param {Array } roles the list of roles
88
106
* @returns {undefined }
89
107
*/
90
- async function _validateRoles ( roles ) {
108
+ async function _validateRoles ( roles ) {
91
109
const foundRolesObj = await models . Role . findAll ( {
92
110
where : {
93
111
id : roles
@@ -109,7 +127,7 @@ async function _validateRoles (roles) {
109
127
* @param {String } projectId the project id
110
128
* @returns {undefined }
111
129
*/
112
- async function _checkUserPermissionForGetJob ( currentUser , projectId ) {
130
+ async function _checkUserPermissionForGetJob ( currentUser , projectId ) {
113
131
if ( ! currentUser . hasManagePermission && ! currentUser . isMachine && ! currentUser . isConnectManager ) {
114
132
await helper . checkIsMemberOfProject ( currentUser . userId , projectId )
115
133
}
@@ -122,7 +140,7 @@ async function _checkUserPermissionForGetJob (currentUser, projectId) {
122
140
* @param {Boolean } fromDb flag if query db for data or not
123
141
* @returns {Object } the job
124
142
*/
125
- async function getJob ( currentUser , id , fromDb = false ) {
143
+ async function getJob ( currentUser , id , fromDb = false ) {
126
144
if ( ! fromDb ) {
127
145
try {
128
146
const job = await esClient . get ( {
@@ -170,7 +188,7 @@ getJob.schema = Joi.object().keys({
170
188
* @params {Object} job the job to be created
171
189
* @returns {Object } the created job
172
190
*/
173
- async function createJob ( currentUser , job , onTeamCreating ) {
191
+ async function createJob ( currentUser , job , onTeamCreating ) {
174
192
// check user permission
175
193
if ( ! currentUser . hasManagePermission && ! currentUser . isMachine ) {
176
194
await helper . checkIsMemberOfProject ( currentUser . userId , job . projectId )
@@ -258,10 +276,26 @@ createJob.schema = Joi.object()
258
276
* @params {Object} data the data to be updated
259
277
* @returns {Object } the updated job
260
278
*/
261
- async function updateJob ( currentUser , id , data ) {
279
+ async function updateJob ( currentUser , id , data ) {
280
+ logger . debug ( { component : 'JobService' , context : 'updateJob start' , message : `Arguments: ${ JSON . stringify ( currentUser ) } job id: ${ id } data: ${ JSON . stringify ( data ) } ` } )
281
+
282
+ let skills = data . skills
283
+
262
284
if ( data . skills ) {
263
285
await _validateSkills ( data . skills )
286
+
287
+ // Compact the skills to *just* the IDs for saving to ES
288
+ data . skills = _ . chain ( skills ) . map ( 'skillId' ) . uniq ( ) . compact ( ) . value ( )
289
+ }
290
+ if ( data . skillNames ) {
291
+ skills = await _validateAndGetSkillsByNames ( data . skillNames )
292
+
293
+ data = _ . omit ( data , 'skillNames' )
294
+
295
+ // Compact the skills to *just* the IDs for saving to ES
296
+ data . skills = _ . chain ( skills ) . map ( 'id' ) . uniq ( ) . compact ( ) . value ( )
264
297
}
298
+
265
299
if ( data . roleIds ) {
266
300
data . roleIds = _ . uniq ( data . roleIds )
267
301
await _validateRoles ( data . roleIds )
@@ -288,10 +322,13 @@ async function updateJob (currentUser, id, data) {
288
322
289
323
let entity
290
324
try {
325
+ logger . debug ( { component : 'JobService' , context : 'updateJob update transaction' , message : `Data: ${ JSON . stringify ( data ) } ` } )
326
+
291
327
await sequelize . transaction ( async ( t ) => {
292
328
const updated = await job . update ( data , { transaction : t } )
293
329
entity = updated . toJSON ( )
294
330
await processUpdate ( entity )
331
+ await helper . registerSkills ( job )
295
332
} )
296
333
} catch ( e ) {
297
334
if ( entity ) {
@@ -312,7 +349,7 @@ async function updateJob (currentUser, id, data) {
312
349
* @params {Object} data the data to be updated
313
350
* @returns {Object } the updated job
314
351
*/
315
- async function partiallyUpdateJob ( currentUser , id , data ) {
352
+ async function partiallyUpdateJob ( currentUser , id , data ) {
316
353
return updateJob ( currentUser , id , data , false )
317
354
}
318
355
@@ -332,7 +369,8 @@ partiallyUpdateJob.schema = Joi.object()
332
369
resourceType : Joi . stringAllowEmpty ( ) . allow ( null ) ,
333
370
rateType : Joi . rateType ( ) . allow ( null ) ,
334
371
workload : Joi . workload ( ) . allow ( null ) ,
335
- skills : Joi . array ( ) . items ( Joi . string ( ) . uuid ( ) ) ,
372
+ skills : Joi . array ( ) . allow ( null ) ,
373
+ skillNames : Joi . array ( ) . allow ( null ) ,
336
374
isApplicationPageActive : Joi . boolean ( ) ,
337
375
minSalary : Joi . number ( ) . integer ( ) ,
338
376
maxSalary : Joi . number ( ) . integer ( ) ,
@@ -359,7 +397,7 @@ partiallyUpdateJob.schema = Joi.object()
359
397
* @params {Object} data the data to be updated
360
398
* @returns {Object } the updated job
361
399
*/
362
- async function fullyUpdateJob ( currentUser , id , data ) {
400
+ async function fullyUpdateJob ( currentUser , id , data ) {
363
401
return updateJob ( currentUser , id , data , true )
364
402
}
365
403
@@ -401,7 +439,7 @@ fullyUpdateJob.schema = Joi.object().keys({
401
439
* @params {Object} currentUser the user who perform this operation
402
440
* @params {String} id the job id
403
441
*/
404
- async function deleteJob ( currentUser , id ) {
442
+ async function deleteJob ( currentUser , id ) {
405
443
// check user permission
406
444
if ( ! currentUser . hasManagePermission && ! currentUser . isMachine ) {
407
445
throw new errors . ForbiddenError ( 'You are not allowed to perform this action!' )
@@ -432,7 +470,7 @@ deleteJob.schema = Joi.object().keys({
432
470
* @params {Object} options the extra options to control the function
433
471
* @returns {Object } the search result, contain total/page/perPage and result array
434
472
*/
435
- async function searchJobs ( currentUser , criteria , options = { returnAll : false } ) {
473
+ async function searchJobs ( currentUser , criteria , options = { returnAll : false } ) {
436
474
// check user permission
437
475
if ( ! currentUser . hasManagePermission && ! currentUser . isMachine && ! currentUser . isConnectManager && ! options . returnAll ) {
438
476
if ( ! criteria . projectId ) { // regular user can only search with filtering by "projectId"
0 commit comments