DBA Data[Home] [Help]

PACKAGE BODY: APPS.PA_CANDIDATE_UTILS

Source


1 PACKAGE BODY PA_CANDIDATE_UTILS AS
2 -- $Header: PARCANUB.pls 120.5.12010000.2 2010/03/23 12:45:32 vgovvala ship $
3 
4 /* --------------------------------------------------------------------
5 FUNCTION: Get_Active_Candidates_Number
6 PURPOSE:
7 -------------------------------------------------------------------- */
8 FUNCTION Get_Active_Candidates_Number(p_assignment_id IN NUMBER)
9 RETURN NUMBER
10 IS
11 l_no_of_active_candidates NUMBER := 0;
12 BEGIN
13   SELECT no_of_active_candidates
14   INTO l_no_of_active_candidates
15   FROM pa_project_assignments
16   WHERE assignment_id = p_assignment_id;
17 
18   IF l_no_of_active_candidates is null THEN
19      RETURN 0;
20   ELSE
21      RETURN l_no_of_active_candidates;
22   END IF;
23 EXCEPTION
24    WHEN OTHERS THEN
25       RETURN 0;
26 END Get_Active_Candidates_Number;
27 
28 /* --------------------------------------------------------------------
29 FUNCTION: Get_Requirements_Of_Candidate
30 PURPOSE:
31 -------------------------------------------------------------------- */
32 FUNCTION Get_Requirements_Of_Candidate(p_resource_id IN NUMBER)
33 RETURN requirements_tbl
34 IS
35 i NUMBER := 0;
36 l_candidate_req_table requirements_tbl;
37 
38 BEGIN
39   SELECT
40   assignment_id
41   BULK COLLECT INTO l_candidate_req_table
42   FROM pa_candidates
43   WHERE resource_id = p_resource_id;
44 
45   RETURN l_candidate_req_table;
46 EXCEPTION
47      WHEN OTHERS THEN RAISE;
48 
49 END Get_Requirements_Of_Candidate;
50 
51 
52 /* --------------------------------------------------------------------
53 FUNCTION: Get_Resource_Id
54 PURPOSE:
55 -------------------------------------------------------------------- */
56 FUNCTION Get_Resource_Id(p_person_id IN NUMBER)
57 RETURN NUMBER
58 IS
59 l_resource_id NUMBER := null;
60 BEGIN
61   SELECT resource_id
62   INTO l_resource_id
63   FROM pa_resources_denorm
64   WHERE person_id = p_person_id and rownum=1;
65 
66   RETURN l_resource_id;
67 EXCEPTION
68    WHEN OTHERS THEN
69       RETURN null;
70 END Get_Resource_Id;
71 
72 /* --------------------------------------------------------------------
73 FUNCTION: Check_Resource_Is_Candidate
74 PURPOSE:  This API checks to see if the resource p_resource_id is a
75           candidate on the assignment p_assignment_id.
76           It returns 'Y', if the resource is a candidate.
77           It returns 'N', if the resource is not a candidate.
78 -------------------------------------------------------------------- */
79 FUNCTION Check_Resource_Is_Candidate(p_resource_id   IN NUMBER,
80                                      p_assignment_id IN NUMBER)
81 RETURN VARCHAR2
82 IS
83 l_exists VARCHAR2(1) := 'N';
84 BEGIN
85   SELECT 'Y'
86   into l_exists
87   from pa_candidates
88   where assignment_id = p_assignment_id
89   and resource_id = p_resource_id;
90 
91   RETURN 'Y';
92 
93 EXCEPTION
94   WHEN OTHERS THEN
95     RETURN 'N';
96 END Check_Resource_Is_Candidate;
97 
98 /* --------------------------------------------------------------------
99 PROCEDURE: Reverse_Candidate_Status
100 PURPOSE: This procedure will restore given candidate's status
101          to PENDING_REVIEW. It is called when when the cancel button on
102          page PA_SUBMIT_ASMT_APR_LAYOUT is clicked.
103  -------------------------------------------------------------------- */
104 
105 PROCEDURE Reverse_Candidate_Status
106 (p_assignment_id        IN NUMBER,
107  p_resource_id          IN NUMBER,
108  x_return_status        OUT NOCOPY VARCHAR2, --File.Sql.39 bug 4440895
109  x_error_message_code   OUT NOCOPY VARCHAR2) --File.Sql.39 bug 4440895
110 IS
111 l_candidate_id          NUMBER;
112 l_candidate_ranking     NUMBER;
113 l_record_version_number NUMBER;
114 l_msg_count             NUMBER := 0;
115 l_project_status_code   VARCHAR2(30);
116 l_return_status         VARCHAR2(1);
117 l_msg_data              VARCHAR2(2000);
118 
119 -- 4537865
120 l_new_record_version_number NUMBER;
121 
122 l_candidate_in_rec	PA_RES_MANAGEMENT_AMG_PUB.CANDIDATE_IN_REC_TYPE;  -- Added for bug 8339510
123 
124 
125 BEGIN
126 
127  -- Initialize the Error Stack
128  PA_DEBUG.init_err_stack('PA_CANDIDATE_PUB.Reverse_Candidate_Status');
129 
130  -- initialize return_status to success
131  x_return_status := FND_API.G_RET_STS_SUCCESS;
132  x_error_message_code := NULL;
133 
134  BEGIN
135  SELECT candidate_id,
136         candidate_ranking,
137         record_version_number
138  INTO   l_candidate_id,
139         l_candidate_ranking,
140         l_record_version_number
141  FROM   pa_candidates
142  WHERE  assignment_id = p_assignment_id
143  AND    resource_id = p_resource_id;
144  EXCEPTION
145    WHEN NO_DATA_FOUND THEN
146         -- No candiddate record exist for given resource_id
147         RETURN;
148  END;
149 
150  SELECT project_status_code
151  INTO   l_project_status_code
152  FROM   PA_PROJECT_STATUSES
153  WHERE  project_system_status_code = 'CANDIDATE_PENDING_REVIEW'
154  AND  PREDEFINED_FLAG = 'Y'  -- Added for bug 5222893
155  AND status_type = 'CANDIDATE';     -- Bug 4773033 CANDIDATE ROUTINES JOIN FOR PROJECT STATUSES
156 
157  PA_CANDIDATE_PUB.Update_Candidate
158    (p_candidate_id               => l_candidate_id,
159     p_status_code                => l_project_status_code,
160     p_ranking                    => l_candidate_ranking,
161     p_change_reason_code         => null,
162     p_record_version_number      => l_record_version_number,
163     -- Added for bug 8339510
164     p_attribute_category    => l_candidate_in_rec.attribute_category,
165     p_attribute1            => l_candidate_in_rec.attribute1,
166     p_attribute2            => l_candidate_in_rec.attribute2,
167     p_attribute3            => l_candidate_in_rec.attribute3,
168     p_attribute4            => l_candidate_in_rec.attribute4,
169     p_attribute5            => l_candidate_in_rec.attribute5,
170     p_attribute6            => l_candidate_in_rec.attribute6,
171     p_attribute7            => l_candidate_in_rec.attribute7,
172     p_attribute8            => l_candidate_in_rec.attribute8,
173     p_attribute9            => l_candidate_in_rec.attribute9,
174     p_attribute10           => l_candidate_in_rec.attribute10,
175     p_attribute11           => l_candidate_in_rec.attribute11,
176     p_attribute12           => l_candidate_in_rec.attribute12,
177     p_attribute13           => l_candidate_in_rec.attribute13,
178     p_attribute14           => l_candidate_in_rec.attribute14,
179     p_attribute15           => l_candidate_in_rec.attribute15,
180     x_record_version_number      => l_new_record_version_number, -- 4537865 : Changed from l_record_version_number to new variable
181     x_msg_count                  => l_msg_count,
182     x_msg_data                   => l_msg_data,
183     x_return_status              => l_return_status);
184 
185     -- 4537865 : Start
186     IF l_return_status = FND_API.G_RET_STS_SUCCESS THEN
187 	l_record_version_number := l_new_record_version_number ;
188     END IF;
189     -- End : 4537865
190  IF(l_return_status =  FND_API.G_RET_STS_ERROR) THEN
191     RAISE FND_API.G_EXC_ERROR;
192  ELSIF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
193     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
194  END IF;
195 
196 EXCEPTION
197   WHEN FND_API.G_EXC_ERROR THEN
198        x_return_status := FND_API.G_RET_STS_ERROR;
199        x_error_message_code := l_msg_data;
200 
201    WHEN OTHERS THEN
202         x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
203 	x_error_message_code := SQLCODE; -- 4537865
204         RAISE;
205 
206 END Reverse_Candidate_Status;
207 
208 
209 /* --------------------------------------------------------------------
210 FUNCTION: Get_Candidate_Score
211 PURPOSE:  This API calculates the candidate score of a resource.
212           Expects p_resource_id, p_person_id, p_assignment_id
213            and p_resource_job_level to be always passed in.
214           It returns the Candidate Score.
215 -------------------------------------------------------------------- */
216 FUNCTION Get_Candidate_Score(p_resource_id               IN NUMBER,
217                              p_person_id                 IN NUMBER,
218                              p_assignment_id             IN NUMBER,
219                              p_project_id                IN NUMBER,
220                              p_competence_match_count    IN VARCHAR2,
221                              p_competence_match          IN NUMBER,
222                              p_competence_count          IN NUMBER,
223                              p_availability              IN NUMBER,
224                              p_resource_job_level        IN NUMBER,
225                              p_min_job_level             IN NUMBER,
226                              p_max_job_level             IN NUMBER,
227                              p_comp_match_weighting      IN NUMBER,
228                              p_avail_match_weighting     IN NUMBER,
229                              p_job_level_match_weighting IN NUMBER)
230 RETURN NUMBER
231 IS
232 
233 l_candidate_score    NUMBER := null;
234 l_competence_count   NUMBER := null;
235 l_competence_match   NUMBER := null;
236 l_availability       NUMBER := null;
237 l_min_job_level  NUMBER := null;
238 l_max_job_level  NUMBER := null;
239 l_comp_match_weighting  NUMBER := null;
240 l_avail_match_weighting NUMBER := null;
241 l_job_level_match_weighting  NUMBER := null;
242 l_comp_match_count  VARCHAR2(20) := null;
243 l_target_job_level  NUMBER := null;
244 l_job_level_match_denorm  NUMBER := null;
245 l_job_level_match   NUMBER := null;
246 l_total_weightings  NUMBER := 0;
247 
248 CURSOR get_requirement_details IS
249 SELECT min_resource_job_level, max_resource_job_level, competence_match_weighting, availability_match_weighting, job_level_match_weighting
250 FROM   pa_project_assignments
251 WHERE  assignment_id = p_assignment_id;
252 
253 BEGIN
254 
255   --get max min job levels and match weightings from the requirement
256   --if any of these are not passed in
257   IF (p_min_job_level IS NULL OR p_max_job_level IS NULL OR
258       p_comp_match_weighting IS NULL OR p_avail_match_weighting IS NULL OR
259       p_job_level_match_weighting IS NULL) THEN
260 
261     OPEN get_requirement_details;
262     FETCH get_requirement_details into l_min_job_level, l_max_job_level, l_comp_match_weighting, l_avail_match_weighting, l_job_level_match_weighting;
263     CLOSE get_requirement_details;
264 
265   END IF;
266 
267   --use the parameter values for job levels if they are passed in
268   IF p_min_job_level IS NOT NULL AND p_max_job_level IS NOT NULL THEN
269     l_min_job_level := p_min_job_level;
270     l_max_job_level := p_max_job_level;
271   END IF;
272 
273   --use the parameter values for match weightings if they are passed in
274   IF p_comp_match_weighting IS NOT NULL AND
275      p_avail_match_weighting IS NOT NULL AND
276      p_job_level_match_weighting IS NOT NULL THEN
277     l_comp_match_weighting := p_comp_match_weighting;
278     l_avail_match_weighting := p_avail_match_weighting;
279     l_job_level_match_weighting := p_job_level_match_weighting;
280   END IF;
281 
282   -- return candidate score = 0 if the weightings add up to zero
283   l_total_weightings := l_comp_match_weighting + l_avail_match_weighting + l_job_level_match_weighting;
284 
285   IF l_total_weightings = 0 THEN
286     l_candidate_score := 0;
287     RETURN l_candidate_score;
288   END IF;
289 
290   --obtain competence match and count
291   IF p_competence_count IS NULL OR p_competence_match IS NULL THEN
292 
293     IF p_competence_match_count IS NULL THEN
294       l_comp_match_count := PA_CANDIDATE_PUB.Get_Competence_Match(p_person_id,
295                                                               p_assignment_id);
296     ELSE
297       l_comp_match_count := p_competence_match_count;
298     END IF;
299 
300     l_competence_match := TO_NUMBER(SUBSTR(l_comp_match_count, 1, INSTR(l_comp_match_count, '/') -1));
301     l_competence_count := TO_NUMBER(SUBSTR(l_comp_match_count, INSTR(l_comp_match_count, '/')+1, LENGTH(l_comp_match_count)));
302 
303   ELSE
304     l_competence_match := p_competence_match;
305     l_competence_count := p_competence_count;
306   END IF;
307 
308   IF l_competence_count = 0 THEN
309     l_competence_count := 1;
310   END IF;
311 
312   --obtain availability
313   IF p_availability IS NULL THEN
314     l_availability := nvl(PA_CANDIDATE_PUB.Check_Availability(p_resource_id,
315                                                               p_assignment_id,
316                                                               p_project_id),
317                           0);
318 
319   ELSE
320     l_availability := p_availability;
321   END IF;
322 
323   -- Job Level Match is zero if resource does not have a job level
324   IF p_resource_job_level IS NOT NULL THEN
325 
326     --calculate target Job Level
327     l_target_job_level := (l_max_job_level + l_min_job_level)/2;
328 
329     --calculate the job level match value
330     IF p_resource_job_level > l_max_job_level OR
331        p_resource_job_level < l_min_job_level THEN
332       l_job_level_match := 0;
333     ELSE
334       l_job_level_match := 100;
335     END IF;
336 
337 /*
338     -- Temporarily give either 0 or 100 as job level match
339     -- instead of calculating job level match using a formula
340     -- due to open issue about HR job level ranges
341 
342     ELSIF p_resource_job_level = l_target_job_level THEN
343       l_job_level_match := 100;
344     ELSE
345       --calculate the denominator of the job level match formula
346       l_job_level_match_denorm := (l_max_job_level - l_target_job_level) * 1.01;
347 
348       l_job_level_match := (1- ABS(p_resource_job_level-l_target_job_level)/l_job_level_match_denorm) * 100;
349     END IF;
350 */
351 
352   ELSE
353     l_job_level_match := 0;
354   END IF;
355 
356 
357   --calculate candidate score
358   l_candidate_score := TRUNC( 100 * (
359     (l_competence_match/l_competence_count * 100 * l_comp_match_weighting +
360      l_availability * l_avail_match_weighting +
361      l_job_level_match * l_job_level_match_weighting) /
362     ((l_comp_match_weighting +
363       l_avail_match_weighting +
364       l_job_level_match_weighting) * 100)));
365 
366   RETURN l_candidate_score;
367 EXCEPTION
368    WHEN OTHERS THEN
369       RAISE;
370 
371 END  Get_Candidate_Score;
372 
373 /* --------------------------------------------------------------------
374 FUNCTION: Get_Nominator_Name
375 PURPOSE:  This API returns nominator of the candidate
376           Expects nominator's person Id
377           It returns the name of the nominator.
378 -------------------------------------------------------------------- */
379 
380 FUNCTION Get_Nominator_Name(p_nominated_by_person_id IN NUMBER)
381 RETURN VARCHAR2
382 IS
383 l_nominator_name    VARCHAR2(100) := null;
384 BEGIN
385 
386   IF p_nominated_by_person_id IS NULL THEN
387      l_nominator_name := FND_MESSAGE.GET_STRING('PA', 'PA_AUTOMATED_SEARCH_PROCESS');
388      /*
389      SELECT message_text
390      INTO   l_nominator_name
391      FROM   fnd_new_messages
392      WHERE  message_name = 'PA_AUTOMATED_SEARCH_PROCESS';
393      */
394   ELSE
395      SELECT full_name
396      INTO   l_nominator_name
397      FROM   per_people_x
398      WHERE  person_id = p_nominated_by_person_id;
399   END IF;
400 
401   RETURN l_nominator_name;
402 EXCEPTION
403    WHEN OTHERS THEN
404       RETURN null;
405 END Get_Nominator_Name;
406 
407 /* --------------------------------------------------------------------
408 FUNCTION: Get_Candidate_Nominations
409 PURPOSE:  This API returns how many times he/she has been
410           nominated among all REQUIREMENTS.
411 -------------------------------------------------------------------- */
412 FUNCTION Get_Candidate_Nominations (p_resource_id IN NUMBER)
413 RETURN NUMBER
414 IS
415 l_num_nomination    NUMBER := 0;
416 BEGIN
417 
418   SELECT count(*)
419   INTO   l_num_nomination
420   FROM   pa_candidates can,
421          pa_project_assignments asmt,
422          pa_project_statuses ps
423   WHERE  can.assignment_id = asmt.assignment_id
424   AND    can.status_code = ps.project_status_code
425   AND    can.resource_id = p_resource_id
426   AND    asmt.assignment_type = 'OPEN_ASSIGNMENT'
427   AND    ps.status_type = 'CANDIDATE'
428   AND    ps.project_system_status_code IN ('CANDIDATE_PENDING_REVIEW',
429                                            'CANDIDATE_UNDER_REVIEW',
430                                            'CANDIDATE_SUITABLE',
431                                            'CANDIDATE_SYSTEM_NOMINATED');
432 
433   RETURN l_num_nomination;
434 EXCEPTION
435    WHEN OTHERS THEN
436       RETURN 0;
437 END Get_Candidate_Nominations;
438 
439 /* --------------------------------------------------------------------
440 FUNCTION: Get_Candidate_Qualifieds
441 PURPOSE:  This API returns how many times he/she has been
442           nominated as qualified assignment for REQUIREMENTS.
443 -------------------------------------------------------------------- */
444 FUNCTION Get_Candidate_Qualifieds (p_resource_id IN NUMBER)
445 RETURN NUMBER
446 IS
447 l_num_qualifieds    NUMBER := 0;
448 BEGIN
449 
450   SELECT count(*)
451   INTO   l_num_qualifieds
452   FROM   pa_candidates can,
453          pa_project_assignments asmt,
454          pa_project_statuses ps
455   WHERE  can.assignment_id = asmt.assignment_id
456   AND    can.status_code = ps.project_status_code
457   AND    asmt.assignment_type = 'OPEN_ASSIGNMENT'
458   AND    can.resource_id = p_resource_id
459   AND    ps.status_type = 'CANDIDATE'
460   AND    ps.project_system_status_code = 'CANDIDATE_SYSTEM_QUALIFIED';
461 
462   RETURN l_num_qualifieds;
463 EXCEPTION
464    WHEN OTHERS THEN
465       RETURN 0;
466 END Get_Candidate_Qualifieds;
467 
468 /* --------------------------------------------------------------------
469 FUNCTION: Update_No_Of_Active_Candidates
470 PURPOSE:  This API updates the no_of_active_candidates column in the
471           pa_project_assignments table. It will be called when the user
472           changes the duration for the requirements.
473 -------------------------------------------------------------------- */
474 PROCEDURE Update_No_Of_Active_Candidates (p_assignment_id IN NUMBER,
475                                           x_return_status OUT NOCOPY VARCHAR2) --File.Sql.39 bug 4440895
476 IS
477 l_no_of_active_candidates    NUMBER := 0;
478 l_record_version_number      NUMBER := 0;
479 l_return_status              VARCHAR2(1);
480 BEGIN
481 
482   PA_DEBUG.init_err_stack('PA_CANDIDATE_UTIL.Update_No_Of_Active_Candidates');
483 
484   x_return_status := FND_API.G_RET_STS_SUCCESS;
485 
486   SELECT count(*)
487   INTO   l_no_of_active_candidates
488   FROM   pa_candidates cand,
489          pa_project_assignments asmt,
490          pa_resources_denorm res,
491          pa_project_statuses ps
492   WHERE  cand.assignment_id = p_assignment_id
493   AND    cand.assignment_id = asmt.assignment_id
494   AND    cand.resource_id = res.resource_id
495   AND    asmt.start_date BETWEEN res.resource_effective_start_date AND
496                          NVL(res.resource_effective_end_date, asmt.start_date+1)
497   AND    cand.status_code = ps.project_status_code
498   AND    ps.status_type = 'CANDIDATE'
499   AND    ps.project_system_status_code in ('CANDIDATE_PENDING_REVIEW',
500                                            'CANDIDATE_UNDER_REVIEW',
501                                            'CANDIDATE_SYSTEM_NOMINATED',
502                                            'CANDIDATE_SUITABLE')
503   AND    res.schedulable_flag = 'Y';
504 
505   SELECT record_version_number
506   INTO   l_record_version_number
507   FROM   pa_project_assignments
508   WHERE  assignment_id = p_assignment_id;
509 
510   pa_project_assignments_pkg.Update_row(
511                              p_assignment_id           => p_assignment_id,
512                              p_no_of_active_candidates => l_no_of_active_candidates,
513                              p_record_version_number   => l_record_version_number,
514                              x_return_status           => l_return_status );
515 
516   IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
517      RAISE FND_API.G_EXC_ERROR;
518   END IF;
519 
520 EXCEPTION
521    WHEN OTHERS THEN
522         x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
523 
524         fnd_msg_pub.add_exc_msg
525                 (p_pkg_name       => 'PA_CANDIDATE_UTIL',
526                  p_procedure_name => 'Update_No_Of_Active_Candidates' );
527 
528 RAISE;
529 END Update_No_Of_Active_Candidates;
530 
531 END PA_CANDIDATE_UTILS ;
532