DBA Data[Home] [Help]

PACKAGE BODY: APPS.PA_CANDIDATE_UTILS

Source


1 PACKAGE BODY PA_CANDIDATE_UTILS AS
2 -- $Header: PARCANUB.pls 120.5 2006/05/29 08:55:47 avaithia 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 BEGIN
122 
123  -- Initialize the Error Stack
124  PA_DEBUG.init_err_stack('PA_CANDIDATE_PUB.Reverse_Candidate_Status');
125 
126  -- initialize return_status to success
127  x_return_status := FND_API.G_RET_STS_SUCCESS;
128  x_error_message_code := NULL;
129 
130  BEGIN
131  SELECT candidate_id,
132         candidate_ranking,
133         record_version_number
134  INTO   l_candidate_id,
135         l_candidate_ranking,
136         l_record_version_number
137  FROM   pa_candidates
138  WHERE  assignment_id = p_assignment_id
139  AND    resource_id = p_resource_id;
140  EXCEPTION
141    WHEN NO_DATA_FOUND THEN
142         -- No candiddate record exist for given resource_id
143         RETURN;
144  END;
145 
146  SELECT project_status_code
147  INTO   l_project_status_code
148  FROM   PA_PROJECT_STATUSES
149  WHERE  project_system_status_code = 'CANDIDATE_PENDING_REVIEW'
150  AND  PREDEFINED_FLAG = 'Y'  -- Added for bug 5222893
151  AND status_type = 'CANDIDATE';     -- Bug 4773033 CANDIDATE ROUTINES JOIN FOR PROJECT STATUSES
152 
153  PA_CANDIDATE_PUB.Update_Candidate
154    (p_candidate_id               => l_candidate_id,
155     p_status_code                => l_project_status_code,
156     p_ranking                    => l_candidate_ranking,
157     p_change_reason_code         => null,
158     p_record_version_number      => l_record_version_number,
159     x_record_version_number      => l_new_record_version_number, -- 4537865 : Changed from l_record_version_number to new variable
160     x_msg_count                  => l_msg_count,
161     x_msg_data                   => l_msg_data,
162     x_return_status              => l_return_status);
163 
164     -- 4537865 : Start
165     IF l_return_status = FND_API.G_RET_STS_SUCCESS THEN
166 	l_record_version_number := l_new_record_version_number ;
167     END IF;
168     -- End : 4537865
169  IF(l_return_status =  FND_API.G_RET_STS_ERROR) THEN
170     RAISE FND_API.G_EXC_ERROR;
171  ELSIF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
172     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
173  END IF;
174 
175 EXCEPTION
176   WHEN FND_API.G_EXC_ERROR THEN
177        x_return_status := FND_API.G_RET_STS_ERROR;
178        x_error_message_code := l_msg_data;
179 
180    WHEN OTHERS THEN
181         x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
182 	x_error_message_code := SQLCODE; -- 4537865
183         RAISE;
184 
185 END Reverse_Candidate_Status;
186 
187 
188 /* --------------------------------------------------------------------
189 FUNCTION: Get_Candidate_Score
190 PURPOSE:  This API calculates the candidate score of a resource.
191           Expects p_resource_id, p_person_id, p_assignment_id
192            and p_resource_job_level to be always passed in.
193           It returns the Candidate Score.
194 -------------------------------------------------------------------- */
195 FUNCTION Get_Candidate_Score(p_resource_id               IN NUMBER,
196                              p_person_id                 IN NUMBER,
197                              p_assignment_id             IN NUMBER,
198                              p_project_id                IN NUMBER,
199                              p_competence_match_count    IN VARCHAR2,
200                              p_competence_match          IN NUMBER,
201                              p_competence_count          IN NUMBER,
202                              p_availability              IN NUMBER,
203                              p_resource_job_level        IN NUMBER,
204                              p_min_job_level             IN NUMBER,
205                              p_max_job_level             IN NUMBER,
206                              p_comp_match_weighting      IN NUMBER,
207                              p_avail_match_weighting     IN NUMBER,
208                              p_job_level_match_weighting IN NUMBER)
209 RETURN NUMBER
210 IS
211 
212 l_candidate_score    NUMBER := null;
213 l_competence_count   NUMBER := null;
214 l_competence_match   NUMBER := null;
215 l_availability       NUMBER := null;
216 l_min_job_level  NUMBER := null;
217 l_max_job_level  NUMBER := null;
218 l_comp_match_weighting  NUMBER := null;
219 l_avail_match_weighting NUMBER := null;
220 l_job_level_match_weighting  NUMBER := null;
221 l_comp_match_count  VARCHAR2(20) := null;
222 l_target_job_level  NUMBER := null;
223 l_job_level_match_denorm  NUMBER := null;
224 l_job_level_match   NUMBER := null;
225 l_total_weightings  NUMBER := 0;
226 
227 CURSOR get_requirement_details IS
228 SELECT min_resource_job_level, max_resource_job_level, competence_match_weighting, availability_match_weighting, job_level_match_weighting
229 FROM   pa_project_assignments
230 WHERE  assignment_id = p_assignment_id;
231 
232 BEGIN
233 
234   --get max min job levels and match weightings from the requirement
235   --if any of these are not passed in
236   IF (p_min_job_level IS NULL OR p_max_job_level IS NULL OR
237       p_comp_match_weighting IS NULL OR p_avail_match_weighting IS NULL OR
238       p_job_level_match_weighting IS NULL) THEN
239 
240     OPEN get_requirement_details;
241     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;
242     CLOSE get_requirement_details;
243 
244   END IF;
245 
246   --use the parameter values for job levels if they are passed in
247   IF p_min_job_level IS NOT NULL AND p_max_job_level IS NOT NULL THEN
248     l_min_job_level := p_min_job_level;
249     l_max_job_level := p_max_job_level;
250   END IF;
251 
252   --use the parameter values for match weightings if they are passed in
253   IF p_comp_match_weighting IS NOT NULL AND
254      p_avail_match_weighting IS NOT NULL AND
255      p_job_level_match_weighting IS NOT NULL THEN
256     l_comp_match_weighting := p_comp_match_weighting;
257     l_avail_match_weighting := p_avail_match_weighting;
258     l_job_level_match_weighting := p_job_level_match_weighting;
259   END IF;
260 
261   -- return candidate score = 0 if the weightings add up to zero
262   l_total_weightings := l_comp_match_weighting + l_avail_match_weighting + l_job_level_match_weighting;
263 
264   IF l_total_weightings = 0 THEN
265     l_candidate_score := 0;
266     RETURN l_candidate_score;
267   END IF;
268 
269   --obtain competence match and count
270   IF p_competence_count IS NULL OR p_competence_match IS NULL THEN
271 
272     IF p_competence_match_count IS NULL THEN
273       l_comp_match_count := PA_CANDIDATE_PUB.Get_Competence_Match(p_person_id,
274                                                               p_assignment_id);
275     ELSE
276       l_comp_match_count := p_competence_match_count;
277     END IF;
278 
279     l_competence_match := TO_NUMBER(SUBSTR(l_comp_match_count, 1, INSTR(l_comp_match_count, '/') -1));
280     l_competence_count := TO_NUMBER(SUBSTR(l_comp_match_count, INSTR(l_comp_match_count, '/')+1, LENGTH(l_comp_match_count)));
281 
282   ELSE
283     l_competence_match := p_competence_match;
284     l_competence_count := p_competence_count;
285   END IF;
286 
287   IF l_competence_count = 0 THEN
288     l_competence_count := 1;
289   END IF;
290 
291   --obtain availability
292   IF p_availability IS NULL THEN
293     l_availability := nvl(PA_CANDIDATE_PUB.Check_Availability(p_resource_id,
294                                                               p_assignment_id,
295                                                               p_project_id),
296                           0);
297 
298   ELSE
299     l_availability := p_availability;
300   END IF;
301 
302   -- Job Level Match is zero if resource does not have a job level
303   IF p_resource_job_level IS NOT NULL THEN
304 
305     --calculate target Job Level
306     l_target_job_level := (l_max_job_level + l_min_job_level)/2;
307 
308     --calculate the job level match value
309     IF p_resource_job_level > l_max_job_level OR
310        p_resource_job_level < l_min_job_level THEN
311       l_job_level_match := 0;
312     ELSE
313       l_job_level_match := 100;
314     END IF;
315 
316 /*
317     -- Temporarily give either 0 or 100 as job level match
318     -- instead of calculating job level match using a formula
319     -- due to open issue about HR job level ranges
320 
321     ELSIF p_resource_job_level = l_target_job_level THEN
322       l_job_level_match := 100;
323     ELSE
324       --calculate the denominator of the job level match formula
325       l_job_level_match_denorm := (l_max_job_level - l_target_job_level) * 1.01;
326 
327       l_job_level_match := (1- ABS(p_resource_job_level-l_target_job_level)/l_job_level_match_denorm) * 100;
328     END IF;
329 */
330 
331   ELSE
332     l_job_level_match := 0;
333   END IF;
334 
335 
336   --calculate candidate score
337   l_candidate_score := TRUNC( 100 * (
338     (l_competence_match/l_competence_count * 100 * l_comp_match_weighting +
339      l_availability * l_avail_match_weighting +
340      l_job_level_match * l_job_level_match_weighting) /
341     ((l_comp_match_weighting +
342       l_avail_match_weighting +
343       l_job_level_match_weighting) * 100)));
344 
345   RETURN l_candidate_score;
346 EXCEPTION
347    WHEN OTHERS THEN
348       RAISE;
349 
350 END  Get_Candidate_Score;
351 
352 /* --------------------------------------------------------------------
353 FUNCTION: Get_Nominator_Name
354 PURPOSE:  This API returns nominator of the candidate
355           Expects nominator's person Id
356           It returns the name of the nominator.
357 -------------------------------------------------------------------- */
358 
359 FUNCTION Get_Nominator_Name(p_nominated_by_person_id IN NUMBER)
360 RETURN VARCHAR2
361 IS
362 l_nominator_name    VARCHAR2(100) := null;
363 BEGIN
364 
365   IF p_nominated_by_person_id IS NULL THEN
366      l_nominator_name := FND_MESSAGE.GET_STRING('PA', 'PA_AUTOMATED_SEARCH_PROCESS');
367      /*
368      SELECT message_text
369      INTO   l_nominator_name
370      FROM   fnd_new_messages
371      WHERE  message_name = 'PA_AUTOMATED_SEARCH_PROCESS';
372      */
373   ELSE
374      SELECT full_name
375      INTO   l_nominator_name
376      FROM   per_people_x
377      WHERE  person_id = p_nominated_by_person_id;
378   END IF;
379 
380   RETURN l_nominator_name;
381 EXCEPTION
382    WHEN OTHERS THEN
383       RETURN null;
384 END Get_Nominator_Name;
385 
386 /* --------------------------------------------------------------------
387 FUNCTION: Get_Candidate_Nominations
388 PURPOSE:  This API returns how many times he/she has been
389           nominated among all REQUIREMENTS.
390 -------------------------------------------------------------------- */
391 FUNCTION Get_Candidate_Nominations (p_resource_id IN NUMBER)
392 RETURN NUMBER
393 IS
394 l_num_nomination    NUMBER := 0;
395 BEGIN
396 
397   SELECT count(*)
398   INTO   l_num_nomination
399   FROM   pa_candidates can,
400          pa_project_assignments asmt,
401          pa_project_statuses ps
402   WHERE  can.assignment_id = asmt.assignment_id
403   AND    can.status_code = ps.project_status_code
404   AND    can.resource_id = p_resource_id
405   AND    asmt.assignment_type = 'OPEN_ASSIGNMENT'
406   AND    ps.status_type = 'CANDIDATE'
407   AND    ps.project_system_status_code IN ('CANDIDATE_PENDING_REVIEW',
408                                            'CANDIDATE_UNDER_REVIEW',
409                                            'CANDIDATE_SUITABLE',
410                                            'CANDIDATE_SYSTEM_NOMINATED');
411 
412   RETURN l_num_nomination;
413 EXCEPTION
414    WHEN OTHERS THEN
415       RETURN 0;
416 END Get_Candidate_Nominations;
417 
418 /* --------------------------------------------------------------------
422 -------------------------------------------------------------------- */
419 FUNCTION: Get_Candidate_Qualifieds
420 PURPOSE:  This API returns how many times he/she has been
421           nominated as qualified assignment for REQUIREMENTS.
423 FUNCTION Get_Candidate_Qualifieds (p_resource_id IN NUMBER)
424 RETURN NUMBER
425 IS
426 l_num_qualifieds    NUMBER := 0;
427 BEGIN
428 
429   SELECT count(*)
430   INTO   l_num_qualifieds
431   FROM   pa_candidates can,
432          pa_project_assignments asmt,
433          pa_project_statuses ps
434   WHERE  can.assignment_id = asmt.assignment_id
435   AND    can.status_code = ps.project_status_code
436   AND    asmt.assignment_type = 'OPEN_ASSIGNMENT'
437   AND    can.resource_id = p_resource_id
438   AND    ps.status_type = 'CANDIDATE'
439   AND    ps.project_system_status_code = 'CANDIDATE_SYSTEM_QUALIFIED';
440 
441   RETURN l_num_qualifieds;
442 EXCEPTION
443    WHEN OTHERS THEN
444       RETURN 0;
445 END Get_Candidate_Qualifieds;
446 
447 /* --------------------------------------------------------------------
448 FUNCTION: Update_No_Of_Active_Candidates
449 PURPOSE:  This API updates the no_of_active_candidates column in the
450           pa_project_assignments table. It will be called when the user
451           changes the duration for the requirements.
452 -------------------------------------------------------------------- */
453 PROCEDURE Update_No_Of_Active_Candidates (p_assignment_id IN NUMBER,
454                                           x_return_status OUT NOCOPY VARCHAR2) --File.Sql.39 bug 4440895
455 IS
456 l_no_of_active_candidates    NUMBER := 0;
457 l_record_version_number      NUMBER := 0;
458 l_return_status              VARCHAR2(1);
459 BEGIN
460 
461   PA_DEBUG.init_err_stack('PA_CANDIDATE_UTIL.Update_No_Of_Active_Candidates');
462 
463   x_return_status := FND_API.G_RET_STS_SUCCESS;
464 
465   SELECT count(*)
466   INTO   l_no_of_active_candidates
467   FROM   pa_candidates cand,
468          pa_project_assignments asmt,
469          pa_resources_denorm res,
470          pa_project_statuses ps
471   WHERE  cand.assignment_id = p_assignment_id
472   AND    cand.assignment_id = asmt.assignment_id
473   AND    cand.resource_id = res.resource_id
474   AND    asmt.start_date BETWEEN res.resource_effective_start_date AND
475                          NVL(res.resource_effective_end_date, asmt.start_date+1)
476   AND    cand.status_code = ps.project_status_code
477   AND    ps.status_type = 'CANDIDATE'
478   AND    ps.project_system_status_code in ('CANDIDATE_PENDING_REVIEW',
479                                            'CANDIDATE_UNDER_REVIEW',
480                                            'CANDIDATE_SYSTEM_NOMINATED',
481                                            'CANDIDATE_SUITABLE')
482   AND    res.schedulable_flag = 'Y';
483 
484   SELECT record_version_number
485   INTO   l_record_version_number
486   FROM   pa_project_assignments
487   WHERE  assignment_id = p_assignment_id;
488 
489   pa_project_assignments_pkg.Update_row(
490                              p_assignment_id           => p_assignment_id,
491                              p_no_of_active_candidates => l_no_of_active_candidates,
492                              p_record_version_number   => l_record_version_number,
493                              x_return_status           => l_return_status );
494 
495   IF (l_return_status <> FND_API.G_RET_STS_SUCCESS) THEN
496      RAISE FND_API.G_EXC_ERROR;
497   END IF;
498 
499 EXCEPTION
500    WHEN OTHERS THEN
501         x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
502 
503         fnd_msg_pub.add_exc_msg
504                 (p_pkg_name       => 'PA_CANDIDATE_UTIL',
505                  p_procedure_name => 'Update_No_Of_Active_Candidates' );
506 
507 RAISE;
508 END Update_No_Of_Active_Candidates;
509 
510 END PA_CANDIDATE_UTILS ;
511