DBA Data[Home] [Help]

PACKAGE BODY: APPS.HR_BIS_ALERTS

Source


1 PACKAGE BODY HR_BIS_ALERTS AS
2 /* $Header: hrbistr.pkb 115.32 2003/12/29 02:14:11 prasharm ship $ */
3 
4 c_ampersand			constant VARCHAR2(1) := fnd_global.local_chr(38);
5 
6 g_orgprc_const                VARCHAR2(4) := 'SINR';
7 
8 --Package Global Exceptions
9 e_g_fatal_error    exception;
10 
11 --Targets etc...
12 e_g_no_tr_found    exception;
13 e_g_no_pm_found    exception;
14 e_g_no_pm_known    exception;
15 e_g_no_tl_found    exception;
16 e_g_no_tv_found    exception;
17 e_g_no_pd_found    exception;
18 
19 --Others...
20 e_g_no_ff_bg      exception; -- bg for a ff
21 e_g_no_ff         exception; -- fast formula
22 e_g_no_bg         exception; -- business group
23 e_g_no_sg         exception; -- security group
24 e_g_bad_freq_code exception;
25 e_g_no_ap         exception; -- application_id for a resp
26 e_g_bmt_invalid   exception; -- Budget Meas type is not a lookup and hence not valid
27 
28 --Function specific
29 e_g_tr_not_populated exception; -- Get_target_rec
30 
31 e_g_bis_fn_error  exception; -- Error calling a bis function
32 
33 -- Records
34 
35 --Record to store the session details
36 TYPE hri_session_rec_type IS RECORD
37        (user_id           NUMBER --fnd_GLOBAL.USER_ID
38        ,resp_id           NUMBER
39        ,resp_appl_id      NUMBER
40        ,security_group_id NUMBER);
41 
42 --Details of session at start
43 g_session_rec                hri_session_rec_type;
44 
45 --Record to store the required Information pertaining to a target
46 TYPE hri_target_rec_type IS RECORD
47       (measure_short_name          bisbv_performance_measures.measure_short_name%TYPE
48       ,target_id                   bis_target_values.target_id%TYPE
49       ,target_level_id             bisfv_target_levels.target_level_id%TYPE
50       ,target_level_short_name     bisfv_target_levels.target_level_short_name%TYPE
51       ,measure_id                  bisbv_performance_measures.measure_id%TYPE
52       ,plan_id                     bis_target_values.plan_id%TYPE
53       ,org_level_short_name        bisfv_target_levels.org_level_short_name%TYPE
54       ,org_level_value_id          bisbv_targets.org_level_value_id%TYPE
55       ,time_level_value_id         bisbv_targets.time_level_value_id%TYPE
56       ,time_level_short_name       bisfv_target_levels.time_level_short_name%TYPE
57       ,dim1_level_short_name       bisfv_target_levels.dimension1_level_short_name%TYPE
58       ,dim1_level_value_id         bisbv_targets.dim1_level_value_id%TYPE
59       ,dim2_level_short_name       bisfv_target_levels.dimension2_level_short_name%TYPE
60       ,dim2_level_value_id         bisbv_targets.dim2_level_value_id%TYPE
61       ,dim3_level_short_name       bisfv_target_levels.dimension3_level_short_name%TYPE
62       ,dim3_level_value_id         bisbv_targets.dim3_level_value_id%TYPE
63       ,dim4_level_short_name       bisfv_target_levels.dimension4_level_short_name%TYPE
64       ,dim4_level_value_id         bisbv_targets.dim4_level_value_id%TYPE
65       ,dim5_level_short_name	   bisfv_target_levels.dimension5_level_short_name%TYPE
66       ,dim5_level_value_id         bisbv_targets.dim5_level_value_id%TYPE
67       ,unit_of_measure             bisbv_target_levels.unit_of_measure%TYPE
68       ,workflow_item_type          bisfv_target_levels.workflow_item_type%TYPE
69       ,workflow_process_short_name bisfv_target_levels.workflow_process_short_name%TYPE
70       ,target                      bisfv_targets.target%TYPE
71       ,range1_low                  bisfv_targets.range1_low%TYPE
72       ,range1_high                 bisfv_targets.range1_high%TYPE
73       ,range2_low                  bisfv_targets.range2_low%TYPE
74       ,range2_high                 bisfv_targets.range2_high%TYPE
75       ,range3_low                  bisfv_targets.range3_low%TYPE
76       ,range3_high                 bisfv_targets.range3_high%TYPE
77       ,notify_resp1_id             fnd_responsibility.responsibility_id%TYPE
78       ,notify_resp1_appl_id        fnd_responsibility.application_id%TYPE
79       ,notify_resp1_short_name     bisfv_targets.notify_resp1_short_name%TYPE
80       ,notify_resp1_name           bisfv_targets.notify_resp1_name%TYPE
81       ,notify_resp2_id             fnd_responsibility.responsibility_id%TYPE
82       ,notify_resp2_appl_id        fnd_responsibility.application_id%TYPE
83       ,notify_resp2_short_name     bisfv_targets.notify_resp2_short_name%TYPE
84       ,notify_resp2_name           bisfv_targets.notify_resp2_name%TYPE
85       ,notify_resp3_id             fnd_responsibility.responsibility_id%TYPE
86       ,notify_resp3_appl_id        fnd_responsibility.application_id%TYPE
87       ,notify_resp3_short_name     bisfv_targets.notify_resp3_short_name%TYPE
88       ,notify_resp3_name           bisfv_targets.notify_resp3_name%TYPE
89      -- ,budget_measurement_type     hr_lookups.lookup_code%TYPE
90       ,period_start_DATE	       DATE
91       ,period_end_DATE             DATE);
92 
93 --**********************************************************************
94 -- COMMON FUNCTIONS AND PROCEDURES
95 --**********************************************************************
96 
97 --DEBUG FUNCTIONS--
98 -------------------------------------------------------------------------
99 --  pl - put line
100 --  NOTE all code must be commented out except NULL when delivered
101 -------------------------------------------------------------------------
102 
103 PROCEDURE pl(p_text IN VARCHAR2,
104              p_text2 IN VARCHAR2 DEFAULT NULL)
105  IS
106 
107 BEGIN
108   --dbms_output.put_line(p_text);   -- *** NOTE THIS LINE MUST BE COMMENTED OUT BEFORE RETURNinG TO ARCS
109   /*
110   INSERT INTO hri.hri_debug
111     (text1
112     ,text2
113     ,insert_date
114     )
115    VALUES
116     (substr(p_text,1,239)
117     ,substr(p_text2,1,239)
118     ,sysdate
119     )
120    ;
121    COMMIT;
122   /**/
123   /*
124   CREATE TABLE HRI.HRI_DEBUG
125   (
126     TEXT1       VARCHAR2(240)
127    ,TEXT2       VARCHAR2(240)
128    ,INSERT_DATE DATE
129   );
130   /**/
131   null;
132 END;
133 
134 -------------------------------------------------------------------------
135 --  debug_hri_target_rec
136 --
137 --  UtilISes pl to debug target record
138 -------------------------------------------------------------------------
139 PROCEDURE debug_hri_target_rec
140            (p_target_rec       IN hri_target_rec_type)
141   IS
142 BEGIN
143   pl('HRI TARGET REC => ');
144   pl('  measure_short_name',p_target_rec.measure_short_name);
145   pl('  target_id',to_char(p_target_rec.target_id));
146   pl('  target_level_id',to_char(p_target_rec.target_level_id));
147   pl('  indicator_id',to_char(p_target_rec.measure_id));
148   pl('  Plan id ',to_char(p_target_rec.plan_id));
149   pl('  Org     ',p_target_rec.org_level_short_name);
150   pl('  Org id  ',p_target_rec.org_level_value_id);
151   pl('  Time    ',p_target_rec.time_level_short_name);
152   pl('  Time id ',p_target_rec.time_level_value_id);
153   pl('  Dim1    ',p_target_rec.dim1_level_short_name);
154   pl('  Dim1 id ',p_target_rec.dim1_level_value_id);
155   pl('  Dim2    ',p_target_rec.dim2_level_short_name);
156   pl('  Dim2 id ',p_target_rec.dim2_level_value_id);
157   pl('  Dim3    ',p_target_rec.dim3_level_short_name);
158   pl('  Dim3 id ',p_target_rec.dim3_level_value_id);
159   pl('  Dim4    ',p_target_rec.dim4_level_short_name);
160   pl('  Dim4 id ',p_target_rec.dim4_level_value_id);
161   pl('  Dim5    ',p_target_rec.dim5_level_short_name);
162   pl('  Dim5 id ',p_target_rec.dim5_level_value_id);
163   pl('  Uom     ',p_target_rec.unit_of_measure);
164   pl('  Workflow',p_target_rec.workflow_process_short_name);
165   pl('  Range 1 Low',to_char(p_target_rec.RANGE1_LOW));
166   pl('  Range 1 High',to_char(p_target_rec.RANGE1_HIGH));
167   pl('  Range 2 Low',to_char(p_target_rec.RANGE2_LOW));
168   pl('  Range 2 High',to_char(p_target_rec.RANGE2_HIGH));
169   pl('  Range 3 Low',to_char(p_target_rec.RANGE3_LOW));
170   pl('  Range 3 High',to_char(p_target_rec.RANGE3_HIGH));
171  -- pl('  Bdgt M Type ',p_target_rec.budget_measurement_type); Bug 2530846
172 
173   pl('  Start date',to_char(p_target_rec.period_start_date));
174   pl('  End Date',to_char(p_target_rec.period_END_date));
175 
176   pl('  Resp 1 ID',p_target_rec.notify_resp1_id);
177   pl('  Resp 1 SN',p_target_rec.notify_resp1_short_name);
178   pl('  Resp 1 LN',p_target_rec.notify_resp1_name);
179   pl('  Resp 2 ID',p_target_rec.notify_resp2_id);
180   pl('  Resp 2 SN',p_target_rec.notify_resp2_short_name);
181   pl('  Resp 2 LN',p_target_rec.notify_resp2_name);
182   pl('  Resp 3 ID',p_target_rec.notify_resp3_id);
183   pl('  Resp 3 SN',p_target_rec.notify_resp3_short_name);
184   pl('  Resp 3 LN',p_target_rec.notify_resp3_name);
185 
186 
187 END debug_hri_target_rec;
188 
189 -------------------------------------------------------------------------
190 --  debug_bis_actual_rec
191 --
192 --  Utilises pl to debug bis actual record
193 -------------------------------------------------------------------------
194 PROCEDURE debug_bis_actual_rec
195            (p_actual_rec         IN bis_actual_pub.actual_rec_type)
196   IS
197 BEGIN
198 
199   pl('BIS ACTUAL REC => ');
200   pl('  Actual ', p_actual_rec.actual);
201   pl('  Target Lvl id ', to_char(p_actual_rec.target_level_id));
202   pl('  Target Lvl SN ', p_actual_rec.target_level_short_name);
203   pl('  Target Lvl LN ', p_actual_rec.target_level_name);
204   pl('  Time V ID ',p_actual_rec.time_level_value_id);
205   pl('  Time V N ',p_actual_rec.time_level_value_name);
206   pl('  Org  V ID ',p_actual_rec.org_level_value_id);
207   pl('  Org  V N ',p_actual_rec.org_level_value_name);
208   pl('  Dim1 V ID ',p_actual_rec.dim1_level_value_id);
209   pl('  Dim1 V N ',p_actual_rec.dim1_level_value_name);
210   pl('  Dim2 V ID ',p_actual_rec.dim2_level_value_id);
211   pl('  Dim2 V N ',p_actual_rec.dim2_level_value_name);
212   pl('  Dim3 V ID ',p_actual_rec.dim3_level_value_id);
213   pl('  Dim3 V N ',p_actual_rec.dim3_level_value_name);
214   pl('  Dim4 V ID ',p_actual_rec.dim4_level_value_id);
215   pl('  Dim4 V N ',p_actual_rec.dim4_level_value_name);
216   pl('  Dim5 V ID ',p_actual_rec.dim5_level_value_id);
217   pl('  Dim5 V N ',p_actual_rec.dim5_level_value_name);
218   pl('  Resp ID ', to_char(p_actual_rec.responsibility_id));
219   pl('  Resp SN ', p_actual_rec.responsibility_short_name);
220   pl('  Resp LN ', p_actual_rec.responsibility_name);
221 
222 END debug_bis_actual_rec;
223 --**********************************************************************
224 -- PRIVATE FUNCTIONS
225 --**********************************************************************
226 ------------------------------------------------------------------------
227 --  Procedure:    Get_Dates_from_Time_Dim
228 --
229 --  Parameters:   Target_id
230 --
231 --  Description:  Returns the start and end date for the time dimension
232 ------------------------------------------------------------------------
233 PROCEDURE get_dates_from_time_dim
234           (p_time_level_value_id  IN     VARCHAR2
235           ,o_period_start_date       OUT NOCOPY DATE
236           ,o_period_end_date         OUT  NOCOPY DATE)
237  IS
238   --
239   -- get the target start and end dates
240   --
241   CURSOR pd_cur (p_c_time_level_value_id VARCHAR2) IS
242    SELECT start_date
243         , end_date
244      FROM bis_hr_months_v
245     WHERE id = p_c_time_level_value_id
246    UNION
247    SELECT start_date
248         , end_date
249      FROM bis_hr_bimonths_v
250     WHERE id = p_c_time_level_value_id
251    UNION
252    SELECT start_date
253         , end_date
254      FROM bis_hr_quarters_v
255     WHERE id = p_c_time_level_value_id
256    UNION
257    SELECT start_date
258         , end_date
259      FROM bis_hr_semiyears_v
260     WHERE id = p_c_time_level_value_id
261    UNION
262    SELECT start_date
263         , end_date
264      FROM bis_hr_years_v
265     WHERE id = p_c_time_level_value_id;
266 
267 BEGIN
268 
269   pl(' Time Level Value ID: ',p_time_level_value_id);
270   --
271   -- get the target period dates
272   --
273   OPEN pd_cur(p_time_level_value_id);
274   FETCH pd_cur INTO
275      o_period_start_date
276     ,o_period_end_date;
277   IF pd_cur%NOTFOUND THEN
278      CLOSE pd_cur;
279      RAISE e_g_no_pd_found;
280   END IF;
281   CLOSE pd_cur;
282 
283   pl(' Start Date: ',to_char(o_period_start_date));
284   pl(' End Date: '  ,to_char(o_period_end_date));
285 
286 END;
287 ------------------------------------------------------------------------
288 --  Procedure:    Get_Target_rec
289 --
290 --  RETURN:       HRI_Target_Rec_Type - details derived FROM the target_id
291 --
292 --  Parameters:   Target_id
293 --
294 --  Description
295 --                This function queries all the relevant information
296 --                required concerning the target, including info at these
297 --                levels:
298 --                  indicator
299 --                  target level
300 --                  target
301 --                  time dimension calendars
302 ------------------------------------------------------------------------
303 FUNCTION get_target_rec
304           (p_target_id IN NUMBER)
305  RETURN hri_target_rec_type
306   IS
307 
308   --records from the cursors to be deleted
309   l_bis_tarlev_rec bisfv_target_levels%rowtype;
310   l_bis_target_rec bisfv_targets%rowtype;
311   l_target_rec     hri_target_rec_type;
312 
313   --
314   -- get the performance measure
315   --
316   CURSOR pm_cur (p_target_level_id IN NUMBER) IS
317    SELECT pm.measure_id
318         , pm.measure_short_name
319      FROM bisbv_performance_measures pm
320         , bisbv_target_levels tl
321     WHERE pm.measure_id = tl.measure_id
322       AND tl.target_level_id = p_target_level_id;
323   --
324   -- get the target level
325   --
326   CURSOR tl_cur (p_target_level_id IN NUMBER) IS
327    SELECT *
328      FROM bisfv_target_levels
329     WHERE target_level_id = p_target_level_id;
330   --
331   -- get the target value
332   --
333   CURSOR tv_cur (p_target_id  IN NUMBER) IS
334    SELECT *
335      FROM bisfv_targets trg
336     WHERE trg.target_id = p_target_id;
337 
338   -- Cursor to verify validity of the budget meaurement type
339   -- at least one row returned if valid
340   CURSOR  bmt_cur
341            (p_c_bmt IN VARCHAR2)
342    IS
343    SELECT lookup_code
344      FROM hr_lookups
345     WHERE lookup_type = 'BUDGET_MEASUREMENT_TYPE'
346       AND lookup_code = p_c_bmt;
347 
348   -- Cursor to obtain fnd_responsibility_id
349   -- from role short name and ensure that the
350   -- role currently exists as an FND responsibility
351   CURSOR resp_id_cur
352            (p_c_role_name IN VARCHAR2)
353    IS
354    SELECT wfr.orig_system_id
355         , rsp.application_id
356      FROM wf_roles           wfr
357         , fnd_responsibility rsp
358     WHERE wfr.orig_system_id = rsp.responsibility_id
359       AND wfr.name = p_c_role_name
360       AND wfr.orig_system like 'FND_RESP%';
361 
362 ------------------------------------------------------
363 BEGIN
364   pl('--------------------');
365   pl('*Get Target Rec','Start');
366   pl(' Get Target ',to_char(p_target_id));
367 
368   --
369   -- get the target value for this target
370   --
371   OPEN tv_cur(p_target_id);
372   FETCH tv_cur INTO l_bis_target_rec;
373   IF tv_cur%NOTFOUND THEN
374     CLOSE tv_cur;
375     RAISE e_g_no_tr_found;
376   END IF;
377   CLOSE tv_cur;
378   --
379   -- get the target level
380   --
381   OPEN tl_cur(l_bis_target_rec.target_level_id);
382   FETCH tl_cur INTO l_bis_tarlev_rec;
383   IF tl_cur%NOTFOUND THEN
384      CLOSE tl_cur;
385      RAISE e_g_no_tl_found;
386   END IF;
387   CLOSE tl_cur;
388   --
389   -- get the performance measure
390   --
394      ,l_target_rec.measure_short_name;
391   OPEN pm_cur(l_bis_target_rec.target_level_id);
392   FETCH pm_cur INTO
393       l_target_rec.measure_id
395   IF pm_cur%NOTFOUND THEN
396      CLOSE pm_cur;
397      RAISE e_g_no_pm_found;
398   END IF;
399   CLOSE pm_cur;
400 
401   -- FiX FOR BUG 1578137
402   --Get the 3 fnd resp ids from the role
403   -- and confirm they are FND RESPs
404   --Get ROLE 1 ID
405   OPEN resp_id_cur (l_bis_target_rec.notify_resp1_short_name);
406   FETCH resp_id_cur INTO
407      l_target_rec.notify_resp1_id
408     ,l_target_rec.notify_resp1_appl_id;
409   -- Make sure the ID is NULL
410   -- this will be used later as a check whether to verify
411   -- whether a responsibility and target has been setup
412   -- for role 1
413   IF resp_id_cur%NOTFOUND THEN
414     l_target_rec.notify_resp1_id := NULL;
415   END IF;
416   CLOSE resp_id_cur;
417 
418   --Get ROLE 2 ID
419   OPEN resp_id_cur (l_bis_target_rec.notify_resp2_short_name);
420   FETCH resp_id_cur INTO
421      l_target_rec.notify_resp2_id
422     ,l_target_rec.notify_resp2_appl_id;
423   -- Make sure the ID is NULL
424   -- this will be used later as a check whether to verify
425   -- whether a responsibility and target has been setup
426   -- for role 2
427   IF resp_id_cur%NOTFOUND THEN
428     l_target_rec.notify_resp2_id := NULL;
429   END IF;
430   CLOSE resp_id_cur;
431 
432   --Get ROLE 3 ID
433   OPEN resp_id_cur (l_bis_target_rec.notify_resp3_short_name);
434   FETCH resp_id_cur INTO
435      l_target_rec.notify_resp3_id
436     ,l_target_rec.notify_resp3_appl_id;
437   -- Make sure the ID is NULL
438   -- this will be used later as a check whether to verify
439   -- whether a responsibility and target has been setup
440   -- for role 3
441   IF resp_id_cur%NOTFOUND THEN
442     l_target_rec.notify_resp3_id := NULL;
443   END IF;
444   CLOSE resp_id_cur;
445 
446   --
447   -- get the target period dates
448   --
449   get_dates_from_time_dim
450     (l_bis_target_rec.time_level_value_id
451     ,l_target_rec.period_start_date
452     ,l_target_rec.period_end_date);
453 
454   --
455   -- copy the target dimensions to the target record. This will be passed as a parameter
456   -- to the calculate actuals procedure
457   --
458 
459   --  measure_short_name  and id - done
460   l_target_rec.target_id                   := p_target_id;
461   l_target_rec.target_level_id             := l_bis_tarlev_rec.target_level_id;
462   l_target_rec.target_level_short_name     := l_bis_tarlev_rec.target_level_short_name;
463 
464   l_target_rec.plan_id                     := l_bis_target_rec.plan_id;
465   l_target_rec.org_level_short_name        := l_bis_tarlev_rec.org_level_short_name;
466   l_target_rec.org_level_value_id          := l_bis_target_rec.org_level_value_id;
467   l_target_rec.time_level_value_id         := l_bis_target_rec.time_level_value_id;
468   l_target_rec.time_level_short_name       := l_bis_tarlev_rec.time_level_short_name;
469   l_target_rec.dim1_level_short_name       := l_bis_tarlev_rec.dimension1_level_short_name;
470   l_target_rec.dim1_level_value_id         := l_bis_target_rec.dim1_level_value_id;
471   l_target_rec.dim2_level_short_name       := l_bis_tarlev_rec.dimension2_level_short_name;
472   l_target_rec.dim2_level_value_id         := l_bis_target_rec.dim2_level_value_id;
473   l_target_rec.dim3_level_short_name       := l_bis_tarlev_rec.dimension3_level_short_name;
474   l_target_rec.dim3_level_value_id         := l_bis_target_rec.dim3_level_value_id;
475   l_target_rec.dim4_level_short_name       := l_bis_tarlev_rec.dimension4_level_short_name;
476   l_target_rec.dim4_level_value_id         := l_bis_target_rec.dim4_level_value_id;
477   l_target_rec.dim5_level_short_name       := l_bis_tarlev_rec.dimension5_level_short_name;
478   l_target_rec.dim5_level_value_id         := l_bis_target_rec.dim5_level_value_id;
479   l_target_rec.unit_of_measure             := l_bis_tarlev_rec.unit_of_measure;
480   l_target_rec.workflow_item_type          := l_bis_tarlev_rec.workflow_item_type;
481   l_target_rec.workflow_process_short_name := l_bis_tarlev_rec.workflow_process_short_name;
482   l_target_rec.target                      := l_bis_target_rec.target;
483   l_target_rec.range1_low                  := l_bis_target_rec.range1_low;
484   l_target_rec.range1_high                 := l_bis_target_rec.range1_high;
485   l_target_rec.range2_low                  := l_bis_target_rec.range2_low;
486   l_target_rec.range2_high                 := l_bis_target_rec.range2_high;
487   l_target_rec.range3_low                  := l_bis_target_rec.range3_low;
488   l_target_rec.range3_high                 := l_bis_target_rec.range3_high;
489   l_target_rec.notify_resp1_short_name     := l_bis_target_rec.notify_resp1_short_name;
490   l_target_rec.notify_resp1_name           := l_bis_target_rec.notify_resp1_name;
491   l_target_rec.notify_resp2_short_name     := l_bis_target_rec.notify_resp2_short_name;
492   l_target_rec.notify_resp2_name           := l_bis_target_rec.notify_resp2_name;
493   l_target_rec.notify_resp3_short_name     := l_bis_target_rec.notify_resp3_short_name;
494   l_target_rec.notify_resp3_name           := l_bis_target_rec.notify_resp3_name;
495 
496   -- Get the Budget Meas Type
497   --  Required for:
498   --  1) Key to ABV if exists
499   --  2) Compiling name of budget FF
500 
504   -- then a budget is required
501   -- Can't use uom because that is translated and is un-reliable
502   -- If the measure is
503   --  manpower variance, manpower separation or recruitment
505   --  otherwise set it to null
506   IF l_target_rec.measure_short_name
507        IN ('HRMSPFTE','HRMSPHEAD'
508           ,'HRMVRFTE','HRMVRHEAD'
509           ,'HRRCSFTE','HRRCSHEAD')
510     THEN
511     -- Best way to find budget code is to strip it from the measure name
512     --  measure name composed <APP Name(2 Char)><Measure type(4 Char)><Budget Type>
513     --  I don't like this because the code could have spaces in it,
514     --  could be v long and relies on the code representing the budget!!
515     OPEN bmt_cur(substr(l_target_rec.measure_short_name,6));
516     -- Bug 2530846 replacing use of budget_measurement_type with Unit_of_measure
517     FETCH bmt_cur INTO l_target_rec.unit_of_measure;
518     IF bmt_cur%NOTFOUND THEN
519       CLOSE bmt_cur;
520       pl(' Budget Measurement Type not valid :', substr(l_target_rec.measure_short_name,6));
521       RAISE e_g_bmt_invalid;
522     END IF;
523     CLOSE bmt_cur;
524 
525   ELSE
526     -- Bug 2530846 replacing use of budget_measurement_type with Unit_of_measure
527     l_target_rec.unit_of_measure   := to_char(NULL);
528   END IF;
529 
530   --debug_hri_target_rec(l_target_rec);
531 
532   pl('*Get Target Rec','End');
533   pl('--------------------');
534   RETURN l_target_rec;
535 
536 
537 EXCEPTION
538   WHEN e_g_no_tr_found THEN
539     pl('*Get Target Rec','NO TR Exception - End');
540     RAISE e_g_tr_not_populated;
541   WHEN e_g_no_pm_found THEN
542     pl('*Get Target Rec','NO PM Exception - End');
543     RAISE e_g_tr_not_populated;
544   WHEN e_g_no_tl_found THEN
545     pl('*Get Target Rec','NO TL Exception - End');
546     RAISE e_g_tr_not_populated;
547   WHEN e_g_no_tv_found THEN
548     pl('*Get Target Rec','NO TV Exception - End');
549     RAISE e_g_tr_not_populated;
550   WHEN e_g_no_pd_found THEN
551     pl('*Get Target Rec','NO PD Exception - End');
552     RAISE e_g_tr_not_populated;
553   WHEN e_g_bmt_invalid THEN
554     pl('*Get Target Rec','BMT Invalid Exception - End');
555     RAISE e_g_tr_not_populated;
556   WHEN OTHERS THEN
557     pl('*Get Target Rec','Other Exception - End');
558     RAISE e_g_tr_not_populated;
559 
560 END Get_Target_rec;
561 ------------------------------------------------------------------------
562 --  Function:     Get_bis_actual_rec
563 --
564 --  RETURN:       bis_actual_pub.actual_rec_type
565 --
566 --  Description:  This function returns the data in the bis actual
567 --                record format required for calculating the actuals
568 --
569 ------------------------------------------------------------------------
570 FUNCTION get_bis_actual_rec
571            (p_target_rec   IN     hri_target_rec_type)
572   RETURN
573    bis_actual_pub.actual_rec_type
574   IS
575 
576   l_actual_rec  bis_actual_pub.actual_rec_type;
577 
578 BEGIN
579   l_actual_rec.target_level_id           := p_target_rec.target_level_id;
580   l_actual_rec.target_level_short_name   := p_target_rec.target_level_short_name;
581   --l_actual_rec.target_level_name         := p_target_rec.target_level_name;
582   l_actual_rec.time_level_value_id       := p_target_rec.time_level_value_id;
583   l_actual_rec.time_level_value_name     := p_target_rec.time_level_short_name;
584   l_actual_rec.org_level_value_id        := p_target_rec.org_level_value_id;
585   l_actual_rec.org_level_value_name      := p_target_rec.org_level_short_name;
586   l_actual_rec.dim1_level_value_id       := p_target_rec.dim1_level_value_id;
587   l_actual_rec.dim1_level_value_name     := p_target_rec.dim1_level_short_name;
588   l_actual_rec.dim2_level_value_id       := p_target_rec.dim2_level_value_id;
589   l_actual_rec.dim2_level_value_name     := p_target_rec.dim2_level_short_name;
590   l_actual_rec.dim3_level_value_id       := p_target_rec.dim3_level_value_id;
591   l_actual_rec.dim3_level_value_name     := p_target_rec.dim3_level_short_name;
592   l_actual_rec.dim4_level_value_id       := p_target_rec.dim4_level_value_id;
593   l_actual_rec.dim4_level_value_name     := p_target_rec.dim4_level_short_name;
594   l_actual_rec.dim5_level_value_id       := p_target_rec.dim5_level_value_id;
595   l_actual_rec.dim5_level_value_name     := p_target_rec.dim5_level_short_name;
596   --l_actual_rec.responsibility_id         := p_target_rec.responsibility_id;
597   --l_actual_rec.responsibility_short_name := p_target_rec.responsibility_short_name;
598   --l_actual_rec.responsibility_name       := p_target_rec.responsibility_name;
599 
600   RETURN l_actual_rec;
601 
602 END get_bis_actual_rec;
603 ------------------------------------------------------------------------
604 --  Procedure:    Get_Session
605 --
606 --  RETURN:       HRI_Session_Rec_Type - details of session
607 --
608 --  Parameters:   None session is setup of global variables
609 --
610 --  Description
611 --                This function queries all the relevant information
612 --                required concerning the current session allowing the
613 --                session to be recreated exactly. includes:
614 --                  USER
615 --                  Responsibility
616 --
617 ------------------------------------------------------------------------
618 FUNCTION get_session
619  RETURN HRI_Session_Rec_Type
620  IS
624   l_session_rec.user_id           :=  fnd_global.user_id;
621   l_session_rec hri_session_rec_type;
622 
623 BEGIN
625   l_session_rec.resp_id           :=  fnd_global.resp_id;
626   l_session_rec.resp_appl_id      :=  fnd_global.resp_appl_id;
627   l_session_rec.security_group_id :=  fnd_global.security_group_id;
628 
629   RETURN l_session_rec;
630 
631 END get_session;
632 ------------------------------------------------------------------------
633 --  Procedure:    set_session
634 --
635 --  Parameters:   HRI_Session_Rec_Type
636 --
637 --  Description
638 --                This function recreates session specIFied IN Session
639 --                Rec.
640 --                  USER
641 --                  Responsibility
642 --
643 ------------------------------------------------------------------------
644 PROCEDURE set_session
645             (p_session_rec IN  hri_session_rec_type)
646  IS
647 BEGIN
648 
649   fnd_global.apps_initialize
650      (p_session_rec.user_id
651      ,p_session_rec.resp_id
652      ,p_session_rec.resp_appl_id
653      ,p_session_rec.security_group_id
654      );
655 
656 END set_session;
657 
658 PROCEDURE debug_session
659             (p_session_rec IN hri_session_rec_type)
660  IS
661 BEGIN
662   pl(' Session USER_ID',to_char(p_session_rec.user_id));
663   pl(' Session RESP_ID',to_char(p_session_rec.resp_id));
664   pl(' Session resp_appl_id',to_char(p_session_rec.resp_appl_id));
665   pl(' Session security_group_id',to_char(p_session_rec.security_group_id));
666 END debug_session;
667 -------------------------------------------------------------------------
668 --  hr_budget
669 -------------------------------------------------------------------------
670 --
671 -- This is function is required  for targets where the target value is
672 -- obtained from the database and not entered by the user. An example of
673 -- this is manpower variance where the target value is obtained from a
674 -- HR budget.
675 --
676 --
677 FUNCTION hr_budget(p_rec IN bis_target_pub.target_rec_type) RETURN NUMBER IS
678 
679 BEGIN
680   RETURN 1;
681 END;
682 
683 -------------------------------------------------------------------------
684 --  Calculate percentage
685 -------------------------------------------------------------------------
686 
687 FUNCTION percent(p_target IN NUMBER, p_percent IN NUMBER) RETURN NUMBER IS
688 
689 BEGIN
690   RETURN (p_target/100)*nvl(p_percent,0);
691 END;
692 
693 
694 --**********************************************************************
695 -- TEXT TRANSLATIONS
696 --**********************************************************************
697 
698 -------------------------------------------------------------------------
699 -- Translate All
700 -------------------------------------------------------------------------
701 
702 
703 function translate_all RETURN VARCHAR2 IS
704 BEGIN
705   fnd_message.set_name ('HRI','HR_BIS_ALL');
706   RETURN fnd_message.get;
707 END;
708 
709 
710 -------------------------------------------------------------------------
711 -- Translate Location
712 -------------------------------------------------------------------------
713 
714 function translate_location(p_location_id IN NUMBER) RETURN VARCHAR2 IS
715 BEGIN
716  IF p_location_id = -1 THEN
717    RETURN translate_all;
718  ELSE
719    RETURN hr_general.decode_location(p_location_id);
720  END IF;
721 END;
722 
723 -------------------------------------------------------------------------
724 -- Translate Job
725 -------------------------------------------------------------------------
726 -- This function accepts the job ID as a parameter and will RETURN the
727 -- job name. IF the job id is -1 THEN 'All' is RETURNed.
728 --
729 FUNCTION translate_job(p_job_id IN NUMBER) RETURN VARCHAR2 IS
730 BEGIN
731  IF p_job_id = -1 THEN
732    RETURN translate_all;
733  ELSE
734    RETURN hr_reports.get_job(p_job_id);
735  END IF;
736 END;
737 
738 
739 -------------------------------------------------------------------------
740 -- Translate Job Category
741 -------------------------------------------------------------------------
742 -- This function accepts the job category ID as a parameter and will return the
743 -- name of the job category. IF the job category id is -1 then 'All' is returned.
744 --
745 FUNCTION translate_job_category(p_jobcat_id IN VARCHAR2) RETURN VARCHAR2 IS
746 BEGIN
747  IF p_jobcat_id = '-1' THEN
748    RETURN translate_all;
749  ELSE
750    RETURN hr_reports.get_lookup_meaning('JOB_CATEGORIES',p_jobcat_id);
751  END IF;
752 END;
753 
754 
755 -------------------------------------------------------------------------
756 -- Translate include Subordinate indicator
757 -------------------------------------------------------------------------
758 
759 FUNCTION translate_orgprc(p_orgprc IN VARCHAR2) RETURN VARCHAR2 IS
760 
761   l_text hr_lookups.meaning%TYPE;
762 
763 BEGIN
764   IF p_orgprc = 'SINR' THEN
765      l_text := Hr_General.Decode_Lookup('YES_NO','N');
766   ELSIF p_orgprc = 'SINR' THEN
767      l_text := Hr_General.Decode_Lookup('YES_NO','Y');
768   ELSE
772 END;
769      l_text := '';
770   END IF;
771   RETURN l_text;
773 
774 -------------------------------------------------------------------------
775 -- Get Activity Version Name
776 -------------------------------------------------------------------------
777 
778 FUNCTION get_activity_version_name
779           (p_activity_version_id IN NUMBER)
780  RETURN VARCHAR2
781  IS
782 
783  l_activity_version_name ota_activity_versions.version_name%TYPE;
784 
785  CURSOR av_cur (p_activity_version_id IN NUMBER) IS
786  SELECT version_name
787    FROM ota_activity_versions
788   WHERE activity_version_id = p_activity_version_id;
789 
790 
791 BEGIN
792 
793  IF p_activity_version_id = -1 THEN
794     l_activity_version_name := translate_all;
795  ELSE
796     OPEN av_cur(p_activity_version_id);
797     FETCH av_cur INTO l_activity_version_name;
798     CLOSE av_cur;
799  END IF;
800 
801  RETURN l_activity_version_name;
802 
803 END;
804 
805 -------------------------------------------------------------------------
806 --
807 --  Function:    ORG_SECURITY_GROUP
808 --
809 --
810 --  Descrition:  Get the security group of the target organzation.
811 --               This is required as a parametr when calling
812 --               apps_initialize and as a parameter on the report url.
813 --
814 -------------------------------------------------------------------------
815 FUNCTION get_org_security_group_id
816           (p_organization_id IN NUMBER)
817  RETURN NUMBER
818  IS
819 
820    l_security_group_id per_business_groups.security_group_id%TYPE; --Varchar2
821   --
822   -- get the security group id
823   --
824   CURSOR sg_cur(p_organization_id IN VARCHAR2) IS
825   SELECT b.security_group_id
826     FROM per_business_groups b
827        , hr_all_organization_units o
828    where o.business_group_id = b.business_group_id
829      AND o.organization_id = p_organization_id;
830 
831 BEGIN
832 
833  pl('*Get_org_security_group_id','Start');
834  pl(' org_id',to_char(p_organization_id));
835 
836  OPEN sg_cur(p_organization_id);
837  FETCH sg_cur INTO l_security_group_id;
838  IF sg_cur%NOTFOUND THEN
839     CLOSE sg_cur;
840     RAISE e_g_no_sg;
841  END IF;
842  CLOSE sg_cur;
843 
844  pl(' security_group_id',l_security_group_id);
845  pl('*Get_org_security_group_id','End');
846  RETURN to_number(l_security_group_id);
847 
848 END get_org_security_group_id;
849 -------------------------------------------------------------------------
850 --
851 --  VALIDATE THE RESPONSIBLITIES ORGANIZATION SECURITY
852 --
853 -------------------------------------------------------------------------
854 --
855 -- Verify that notify responsibility is authorized to access details from
856 -- the target organization. If the responsibility does not have access to
857 -- the organization processing will be aborted.
858 -------------------------------------------------------------------------
859 FUNCTION validate_resp_org_security
860           (p_responsibility_id   IN fnd_responsibility.responsibility_id%TYPE
861           ,p_application_id      IN fnd_responsibility.application_id%TYPE
862           ,p_organization_id     IN hr_all_organization_units.organization_id%TYPE)
863  RETURN BOOLEAN
864  IS
865 
866   l_dummy        NUMBER;
867   l_status       boolean;
868 
869   l_business_group_id           per_business_groups.business_group_id%TYPE;
870   l_security_group_id           NUMBER; -- Not per_business_groups.security_group_id%TYPE this is varchar2
871   l_org_structure_version_id 	per_org_structure_versions.org_structure_version_id%TYPE;
872 
873   -- Holds the session at the start of the function
874   --  used to return the session back to original
875   l_session_rec                 hri_session_rec_type;
876 
877   --
878   -- OH_CUR ORGANIZATION IN HIERARCHY
879   --
880   CURSOR oh_cur(p_org_structure_version_id IN NUMBER
881                ,p_organization_id          IN NUMBER) IS
882    SELECT  1
883      FROM  per_org_structure_elements ose
884      WHERE ose.org_structure_version_id     = p_org_structure_version_id
885       AND (ose.organization_id_child        = p_organization_id
886             or ose.organization_id_parent   = p_organization_id
887           ) ;
888 
889 BEGIN
890 
891   pl('*Validate Resp Org Security', 'Start');
892    -- Get current session
893   l_session_rec := get_session;
894   pl('Session changed at start: ');
895   debug_session(l_session_rec);
896 
897   pl(' Alert - Responsibility id: ',to_char(p_responsibility_id));
898   pl(' Alert - Organization id: ',to_char(p_organization_id));
899   pl(' Alert - Resp Appl id: ',to_char(p_application_id));
900 
901   l_security_group_id := get_org_security_group_id(p_organization_id);
902 
903   pl(' Alert - Security Group id: ',to_char(l_security_group_id));
904   --
905   -- Changes the session globals
906   -- and get the business group and organization structure version id
907 
908   -- NOTE:
909   -- Solution to issues in bug 1413300 (not inserting into actuals table)
910   -- USER_ID can not be NULL because of issues of inserting a value into a NOT NULL column
914   		(-2
911   -- USER_ID can not be -1 because of condition in HR_GENERAL.Get_Business_Group
912   -- Using -2
913   hrFastAnswers.initialize
915   		,p_responsibility_id
916   		,p_application_id
917   		,l_business_group_id
918   		,l_org_structure_version_id
919         ,l_security_group_id);
920 
921   pl(' Alert - Business group id: ',to_char(l_business_group_id));
922   pl(' Alert - Org structure version id: ',to_char(l_org_structure_version_id));
923   --put out current session for debug purposes
924   pl('Session changed to: ');
925   debug_session(get_session);
926 
927   --
928   -- check that the organization is part of the responsibilities hierarchy
929   --
930 
931   OPEN oh_cur (l_org_structure_version_id
932               ,p_organization_id);
933   FETCH oh_cur INTO l_dummy;
934   IF oh_cur%NOTFOUND THEN
935     l_status := FALSE;
936     pl('False');
937   ELSE
938     l_status := TRUE;
939     pl('True');
940   END IF;
941   CLOSE oh_cur;
942 
943   --Return the session back to original
944   set_session(l_session_rec);
945   pl('Session returned to conditions at start: ');
946   debug_session(l_session_rec);
947 
948   pl('*Validate Resp Org Security', 'End');
949 
950   RETURN l_status;
951 
952 END validate_resp_org_security;
953 
954 -------------------------------------------------------------------------
955 --
956 --  PROCEDURE:     get resp details
957 --  Parameter:     p_resp_no
958 --                 p_target_rec  - hri target record type
959 --  Return params  o_resp_id
960 --                 o_resp_short_name
961 --                 o_resp_name
962 --
963 --  Description:   Simplet Proc to cut down coding.
964 --                 Returns the appropriate resp detail columns for a
965 --                 resp number.  Resp number corresponds to the target
966 --                 responsibility number.
967 -------------------------------------------------------------------------
968 PROCEDURE get_resp_details
969             (p_resp_no          IN  NUMBER
970             ,p_target_rec       IN  hri_target_rec_type
971             ,o_resp_id          OUT NOCOPY fnd_responsibility.responsibility_id%TYPE
972             ,o_resp_appl_id     OUT NOCOPY fnd_responsibility.application_id%TYPE
973             ,o_resp_short_name  OUT NOCOPY bisfv_targets.notify_resp1_short_name%TYPE
974             ,o_resp_name        OUT NOCOPY bisfv_targets.notify_resp1_name%TYPE)
975  IS
976 BEGIN
977   IF p_resp_no = 1 THEN
978     o_resp_id          := p_target_rec.notify_resp1_id;
979     o_resp_appl_id     := p_target_rec.notify_resp1_appl_id;
980     o_resp_short_name  := p_target_rec.notify_resp1_short_name;
981     o_resp_name        := p_target_rec.notify_resp1_name;
982   ELSIF p_resp_no = 2 THEN
983     o_resp_id          := p_target_rec.notify_resp2_id;
984     o_resp_appl_id     := p_target_rec.notify_resp2_appl_id;
985     o_resp_short_name  := p_target_rec.notify_resp2_short_name;
986     o_resp_name        := p_target_rec.notify_resp2_name;
987   ELSIF p_resp_no = 3 THEN
988     o_resp_id          := p_target_rec.notify_resp3_id;
989     o_resp_appl_id     := p_target_rec.notify_resp3_appl_id;
990     o_resp_short_name  := p_target_rec.notify_resp3_short_name;
991     o_resp_name        := p_target_rec.notify_resp3_name;
992   ELSE
993     RAISE no_data_found;
994   END IF;
995 
996 END get_resp_details;
997 -------------------------------------------------------------------------
998 --
999 --  FUNCTION:      FREQUENCY_CODE
1000 --  Description:   This procedure returns the name of the time
1001 --                 dimension and the equivalent HR frequency
1002 --
1003 --  Parameter:     p_time_short_name - freq. name HR BIS dim code
1004 --
1005 --  Return:        frequency code from FREQUENCY lookup
1006 --
1007 -------------------------------------------------------------------------
1008 
1009 FUNCTION frequency_code (p_time_short_name IN VARCHAR2)
1010  RETURN VARCHAR2
1011  IS
1012 
1013   l_frequency VARCHAR2(2);
1014 
1015 BEGIN
1016 
1017   IF p_time_short_name = 'HR MONTH' THEN
1018    l_frequency := 'CM';
1019   ELSIF p_time_short_name = 'HR BIMONTH' THEN
1020    l_frequency := 'BM';
1021   ELSIF p_time_short_name = 'HR QUARTER' THEN
1022    l_frequency := 'Q';
1023   ELSIF p_time_short_name = 'HR SEMIYEAR' THEN
1024    l_frequency := 'SY';
1025   ELSIF p_time_short_name = 'HR YEAR' THEN
1026    l_frequency := 'Y';
1027   ELSE
1028     RAISE e_g_bad_freq_code;
1029   END IF;
1030 
1031   RETURN l_frequency;
1032 
1033 END frequency_code;
1034 
1035 -------------------------------------------------------------------------
1036 --
1037 --  PROCEDURE:     get_report_date_params
1038 --
1039 --  Description:   This procedure returns the report start date and freq
1040 --                 code for the time short name and period start
1041 --                 date.
1042 --
1043 -------------------------------------------------------------------------
1044 PROCEDURE get_report_date_params
1045           (p_time_level_short_name IN     VARCHAR2
1046           ,p_period_start_date     IN     DATE
1047           ,o_freq_code                OUT NOCOPY VARCHAR2
1051   l_report_start_date DATE;
1048           ,o_start_date               OUT NOCOPY VARCHAR2)
1049  IS
1050   l_freq              VARCHAR2(2);
1052 
1053 BEGIN
1054 
1055   l_freq := frequency_code(p_time_level_short_name);
1056 
1057   IF l_freq = 'CM' THEN
1058     l_report_start_date  := add_months(p_period_start_date,-12);
1059   ELSIF l_freq = 'BM' THEN
1060     l_report_start_date  := add_months(p_period_start_date,-12);
1061   ELSIF l_freq = 'Q' THEN
1062     l_report_start_date  := add_months(p_period_start_date,-24);
1063   ELSIF l_freq = 'SY' THEN
1064     l_report_start_date  := add_months(p_period_start_date,-24);
1065   ELSIF l_freq = 'Y' THEN
1066     l_report_start_date  := add_months(p_period_start_date,-48);
1067   END IF;
1068 
1069   pl('frequency: ',l_freq);
1070   pl('start date: ',to_char(l_report_start_date,'DD-MON-YYYY'));
1071 
1072   o_freq_code  := l_freq;
1073   o_start_date := l_report_start_date;
1074 
1075 END get_report_date_params;
1076 
1077 -------------------------------------------------------------------------
1078 --                                                                     --
1079 --  FUNCTION:     GET_FORMULA_ID                                       --
1080 --                                                                     --
1081 -------------------------------------------------------------------------
1082 FUNCTION get_formula_id
1083 		(p_business_group_id IN NUMBER
1084 		,p_budget_type       IN VARCHAR2)
1085  RETURN ff_formulas.formula_id%TYPE
1086  IS
1087 
1088   CURSOR formula_cur
1089           (p_c_business_group_id NUMBER
1090           ,p_c_formula_name      VARCHAR2)
1091    IS
1092    SELECT formula_id
1093      FROM ff_formulas_f
1094     WHERE ( (p_c_business_group_id IS null
1095               AND business_group_id IS null )
1096             OR
1097            p_c_business_group_id = business_group_id
1098           )
1099       AND trunc(sysdate) BETWEEN
1100             effective_start_date AND effective_end_date
1101       AND formula_name = p_c_formula_name;
1102 
1103   l_formula_id ff_formulas.formula_id%TYPE;
1104 
1105 BEGIN
1106   pl('*Get Formula id','Start');
1107   pl('  Budgt Type : ', p_budget_type);
1108 
1109   IF p_budget_type IN ('FTE','HEAD') THEN
1110    OPEN formula_cur(p_business_group_id
1111                    ,'BUDGET_'||p_budget_type);
1112    FETCH formula_cur INTO l_formula_id;
1113    IF formula_cur%NOTFOUND THEN
1114      pl(' Custom ff not found: ','BUDGET_'||p_budget_type);
1115      CLOSE formula_cur;
1116      OPEN formula_cur(NULL
1117                      ,'TEMPLATE_'||p_budget_type);
1118      FETCH formula_cur INTO l_formula_id;
1119        IF formula_cur%NOTFOUND THEN
1120          CLOSE formula_cur;
1121          RAISE e_g_no_ff;
1122        END IF;
1123      CLOSE formula_cur;
1124    ELSE
1125      CLOSE formula_cur;
1126    END IF;
1127 
1128   -- IF the fast formula was not an FTE or HEAD FF then
1129   ELSE
1130    OPEN formula_cur(p_business_group_id
1131                    ,p_budget_type);
1132    FETCH formula_cur INTO l_formula_id;
1133    IF formula_cur%NOTFOUND THEN
1134      pl(' Custom ff not found: ',p_budget_type);
1135      CLOSE formula_cur;
1136      OPEN formula_cur(null
1137                      ,'TEMPLATE_'||p_budget_type);
1138      FETCH formula_cur INTO l_formula_id;
1139        IF formula_cur%NOTFOUND THEN
1140          CLOSE formula_cur;
1141          RAISE e_g_no_ff;
1142        END IF;
1143      CLOSE formula_cur;
1144    ELSE
1145      CLOSE formula_cur;
1146    END IF;
1147   END IF;
1148   RETURN l_formula_id;
1149 
1150 EXCEPTION
1151   WHEN e_g_no_ff THEN
1152     pl('*Get Formula',' Exception - No FF Found - End');
1153     RAISE e_g_no_ff;
1154 
1155 END get_formula_id;
1156 
1157 -------------------------------------------------------------------------
1158 --
1159 --  FUNCTION:     get_ORG_BUSINESS_GROUP_id(p_org_id)
1160 --
1161 --  Parameters    organization id
1162 --
1163 --  RETURNs       business group id
1164 --
1165 --  Description:  This function returns the business group of a given
1166 --                organization. the function is used when posting
1167 --                actuals as the business group is required when
1168 --                getting the fast formula id. The fast formula ID IS
1169 --                required when calculating the assignmnet budget
1170 --                measurement value.
1171 --
1172 -------------------------------------------------------------------------
1173 
1174 FUNCTION get_org_business_group_id
1175           (p_org_id IN NUMBER)
1176  RETURN NUMBER
1177  IS
1178 --
1179 -- This cursor gets the organizations business group
1180 --
1181 CURSOR c_bg_id
1182        (p_c_org_id NUMBER)
1183  IS
1184   SELECT business_group_id
1185     FROM hr_all_organization_units
1186    WHERE sysdate
1187           BETWEEN date_from
1188               AND nvl(date_to, hr_general.end_of_time)
1189      AND organization_id = p_c_org_id;
1190 
1191 l_business_group_id  hr_all_organization_units.business_group_id%TYPE;
1192 
1193 BEGIN
1194 
1195   pl('*Get Org Business Group id','Start');
1196   pl('p_org_id',to_char(p_org_id));
1197   OPEN c_bg_id(p_org_id);
1198   FETCH c_bg_id INTO l_business_group_id;
1199   pl('p_org_id',to_char(l_business_group_id));
1200   IF c_bg_id%NOTFOUND THEN
1201     CLOSE c_bg_id;
1202     pl('raise e_g_no_bg');
1203     RAISE e_g_no_bg;
1204    END IF;
1205   CLOSE c_bg_id;
1206   pl('Business Group id',to_char(l_business_group_id));
1207   pl('*Get Org Business Group id','End');
1208   RETURN l_business_group_id;
1209 
1210 END get_org_business_group_id;
1211 -------------------------------------------------------------------------
1212 --
1213 --  Post Actuals
1214 --
1215 -------------------------------------------------------------------------
1216 PROCEDURE post_actual
1217            (p_actual_rec IN bis_ACTUAL_PUB.Actual_Rec_Type)
1218  IS
1219 
1220  x_error_Tbl     bis_UTILITIES_PUB.Error_Tbl_Type;
1221  x_msg_count     NUMBER;
1222  x_msg_data      VARCHAR2(30);
1223  x_return_status VARCHAR2(30);
1224 
1225  l_Measure_short_name bis_indicators.short_name%TYPE;
1226 
1227 BEGIN
1228 
1229   pl('*Post Actual','Start');
1230 
1231   debug_bis_actual_rec(p_actual_rec);
1232 
1233   IF p_actual_rec.actual IS NOT NULL THEN
1234     pl(' Posting actual...');
1235     bis_ACTUAL_PUB.Post_Actual( p_api_version   => 1.0
1236                               , p_commit        => FND_API.G_TRUE
1237                               , p_Actual_Rec    => p_actual_rec
1238                               , x_return_status => x_return_status
1239                               , x_msg_count     => x_msg_count
1240                               , x_msg_data      => x_msg_data
1241                               , x_error_Tbl     => x_error_Tbl);
1242 
1243     IF x_return_status = fnd_api.g_ret_sts_unexp_error THEN
1244       RAISE e_g_bis_fn_error;
1245     END IF;
1246     pl(' BIS Post actual return status ', x_return_status);
1247   END IF;
1248 
1249   pl('*Post Actual','End');
1250 
1251 EXCEPTION
1252   WHEN OTHERS THEN
1253     -- carry on because this may be called many times
1254     pl('*Post Actual','Exception Raised - End');
1255 
1256 END;
1257 -------------------------------------------------------------------------
1258 -- ********************************************************************
1259 -------------------------------------------------------------------------
1260 -- *********************************************************************
1261 --
1262 --                        START OF PMF DEFINITIONS
1263 --
1264 -- *********************************************************************
1265 -------------------------------------------------------------------------
1266 -- *********************************************************************
1267 -------------------------------------------------------------------------
1268 
1269 -- **********************************************************************
1270 --
1271 --                M A N P O W E R   S E P A R A T I O N S
1272 --
1273 -- **********************************************************************
1274 
1275 -------------------------------------------------------------------------
1276 -- SEND MANPOWER SEPARATION notification
1277 -------------------------------------------------------------------------
1278 -- This procedure is called when the actual manpower separations exceed
1279 -- the target value. The procedure will build the notification message
1280 -- text, which includes a hypertext link to run the manpower losses report,
1281 -- and will then pass the notification to the workflow engine for
1282 -- dIStribution.
1283 --
1284 PROCEDURE send_notification_hrmsp
1285            (p_resp_no     IN NUMBER
1286            ,p_target      IN NUMBER
1287            ,p_actual      IN NUMBER
1288            ,p_target_rec  IN hri_target_rec_type)
1289  IS
1290 
1291 l_bmt_name	      hr_lookups.meaning%TYPE;
1292 l_dummy           VARCHAR2(2000);
1293 l_freq_code       VARCHAR2(4);
1294 l_subject         fnd_new_messages.message_text%TYPE;
1295 l_message         VARCHAR2(2000);
1296 l_org_name        per_organization_units.name%TYPE;
1297 l_period_name     VARCHAR2(50);
1298 l_param           VARCHAR2(2000);
1299 l_report_name     VARCHAR2(8) := 'HRMNPLOS';
1300 l_return_status   VARCHAR2(2000);
1301 
1302 l_start_date      DATE;
1303 
1304 l_error           VARCHAR2(2000);
1305 
1306 -- Session params
1307 l_security_group_id  per_business_groups.security_group_id%TYPE;
1308 l_business_group_id  hr_all_organization_units.business_group_id%TYPE;
1309 l_resp_id            fnd_responsibility.responsibility_id%TYPE;
1310 l_resp_short_name    bisfv_targets.notify_resp1_short_name%TYPE;
1311 l_resp_name          bisfv_targets.notify_resp1_name%TYPE;
1312 l_resp_appl_id       fnd_responsibility.application_id%TYPE;
1313 
1314 l_formula_id         ff_formulas_f.formula_id%TYPE;
1315 
1316 BEGIN
1317   pl('----------------------------------');
1318   pl('*SEND MPS notification','Start');
1319   pl('----------------------------------');
1320   -----------------------------------------------------------------------
1321   -- Build the notification subject line and message text
1322   -----------------------------------------------------------------------
1323   --
1324   -- Get the following information that will be shown on the notification
1325   -- and populate the relevant tokens in the message HR_BIS_PMF_SUBJECT
1326   --
1327   -- 1. Get Session parameters for the report
1328   -- 2. Get Parameter Names:
1332   -- 3. build notification text
1329   --    Organzation
1330   --    Budget Measurement Type
1331   --    Period
1333   -- 4. get the report frequency, number of periods and start date
1334   -- 5. build the report parameter string
1335   -- 6. start the workflow process
1336   --
1337   -- ---------------------------------------------------------------------
1338   -- 1. Get Session parameters for the report
1339   -- ---------------------------------------------------------------------
1340   get_resp_details(p_resp_no
1341                   ,p_target_rec
1342                   ,l_resp_id
1343                   ,l_resp_appl_id
1344                   ,l_resp_short_name
1345                   ,l_resp_name);
1346   l_business_group_id := get_org_business_group_id(p_target_rec.org_level_value_id);
1347   l_security_group_id := get_org_security_group_id(p_target_rec.org_level_value_id);
1348   -- ---------------------------------------------------------------------
1349   -- 2. Get the parameter names
1350   -- ---------------------------------------------------------------------
1351   --
1352   -- Organization
1353   --
1354   hr_reports.get_organization(p_target_rec.org_level_value_id
1355                              ,l_org_name
1356                              ,l_dummy);
1357   pl(' org name : ',l_org_name);
1358   --
1359   -- Budget Name
1360   --
1361   -- Bug 2530846 replacing use of budget_measurement_type with Unit_of_measure
1362   l_bmt_name := hr_reports.get_lookup_meaning('BUDGET_MEASUREMENT_TYPE'
1363                                              ,p_target_rec.unit_of_measure);
1364   pl(' bmt name : ',l_bmt_name);
1365   --
1366   -- Period Name
1367   --
1368   l_period_name := to_char(p_target_rec.period_start_date,'DD-MON-YYYY')
1369                            ||' - '||to_char(p_target_rec.period_END_date,'DD-MON-YYYY');
1370   pl(' period name :',l_period_name);
1371   -- ---------------------------------------------------------------------
1372   -- 3. Build the notification text
1373   -- ---------------------------------------------------------------------
1374   --
1375   -- Build subject message text
1376   --
1377   fnd_message.set_name('HRI','HR_BIS_PMF_HRMSP_SUBJECT');
1378   l_subject := fnd_message.get;
1379   --
1380   -- Build the body message text
1381   --
1382   fnd_message.set_name('HRI','HR_BIS_PMF_HRMSP_MSG');
1383   fnd_message.set_token('ORGANIZATION',l_org_name);
1384   fnd_message.set_token('PERIOD', l_period_name);
1385   fnd_message.set_token('BUDGET',l_bmt_name);
1386   fnd_message.set_token('TARGET',p_target);
1387   fnd_message.set_token('ACTUAL',p_actual);
1388   --fnd_message.set_token('ROLE',l_resp_name);
1389   l_message := fnd_message.get;
1390   pl(' Message:',l_message);
1391   -- ---------------------------------------------------------------------
1392   -- 4. build the report parameter string
1393   -- ---------------------------------------------------------------------
1394   -- Build the url that will be used to run the report from the
1395   -- notification.
1396   l_report_name := 'HRMNPLOS';
1397 
1398   get_report_date_params(p_target_rec.time_level_short_name
1399                         ,p_target_rec.period_start_date
1400                         ,l_freq_code
1401                         ,l_start_date);
1402   pl(' Frequency: ',l_freq_code);
1403   pl(' Start date: ',to_char(l_start_date,'DD-MON-YYYY'));
1404 
1405   -- Added formula id as Workforce Losses requires it for fast formula
1406   -- Bug 2530846
1407   l_formula_id := get_formula_id(l_business_group_id
1408                                 ,p_target_rec.unit_of_measure);
1409   pl(' Formula_id: ',to_char(l_formula_id));
1410 
1411 
1412   -- Bug 2530846 replacing use of budget_measurement_type with Unit_of_measure
1413   l_param := 'org_id='        ||p_target_rec.org_level_value_id   ||'*'||
1414              'orgprc='        ||g_orgprc_const                    ||'*'||
1415              'bpl_id='        ||p_target_rec.plan_id        ||'*'||
1416              'bgttyp='        ||p_target_rec.unit_of_measure||'*'||
1417              'bus_id='        ||to_char(l_business_group_id)||'*'||
1418              'formul='        ||to_char(l_formula_id)       ||'*'||
1419              'frqncy='        ||l_freq_code                 ||'*'||
1420              'geolvl=1*'      ||
1421              'geoval=-1*'     ||
1422              'job_id=-1*'     ||
1423              'jobcat=__ALL__*'||
1424              'prodid=-1*'     ||
1425              'startd='        ||to_char(l_start_date,'YYYY-MM-DD')||'*'||
1426              'end_dt='        ||to_char(p_target_rec.period_end_date,'YYYY-MM-DD')  ||'*'||
1427              'viewby=HR_BIS_TIME*'||
1428                        c_ampersand||'responsibility_application_id='
1429                                   ||to_char(l_resp_appl_id)||
1430   	                   c_ampersand||'security_group_id='
1431                                   ||l_security_group_id;
1432 
1433   pl('wf      ',p_target_rec.workflow_item_type);
1434   pl('process ',p_target_rec.workflow_process_short_name);
1435   pl('resp    ',l_resp_short_name);
1436   pl('resp id ',to_char(l_resp_id));
1437   pl('applic  ',to_char(l_resp_appl_id));
1438   pl('secgrp  ',l_security_group_id);
1439   pl('param   ',substr(l_param,1,240));
1440   pl('report  ',l_report_name);
1441   pl('message ',substr(l_message,1,240));
1442   pl('subject ',l_subject);
1443   -- ---------------------------------------------------------------------
1447   bis_util.strt_wf_process
1444   -- 5. start the workflow process
1445   -- ---------------------------------------------------------------------
1446   pl('start workflow process');
1448 		(p_exception_message    => l_message
1449 		,p_msg_subject          => l_subject
1450 		,p_exception_date	    => sysdate
1451  	    ,p_item_type            => p_target_rec.workflow_item_type
1452 		,p_wf_process		    => p_target_rec.workflow_process_short_name
1453 		,p_notify_resp_name     => l_resp_short_name
1454 		,p_report_name1		    => l_report_name
1455 		,p_report_param1	    => l_param
1456         ,p_report_resp1_id     	=> l_resp_id
1457         ,x_return_status       	=> l_return_status);
1458 
1459   pl(' Resp id',to_char(l_resp_id));
1460 
1461   pl(' Workflow return status: ',l_return_status);
1462 
1463   IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
1464      RAISE e_g_bis_fn_error;
1465   END IF;
1466 
1467   pl('*SEND Manpower Separation notification','End');
1468 
1469 END send_notification_hrmsp;
1470 
1471 -----------------------------------------------------------------------
1472 --  CALCULATE ACTUAL MANPOWER SEPARATIONS
1473 -----------------------------------------------------------------------
1474 
1475 FUNCTION hrmsp_actual
1476           (p_actual_rec  IN bis_actual_pub.actual_rec_type
1477           ,p_bmtype      IN VARCHAR2)
1478  RETURN NUMBER
1479  IS
1480 
1481 l_budget_value		NUMBER(38,2);			-- budget measurement value
1482 l_loss_type 		VARCHAR2(20);	 		-- type of separation
1483 l_separated_count 	NUMBER(38,2);			-- count of separated people
1484 
1485 l_period_start_date DATE;
1486 l_period_end_date   DATE;
1487 
1488 l_business_group_id NUMBER;
1489 
1490 l_formula_id        ff_formulas_f.formula_id%TYPE;
1491 
1492 --
1493 -- get each assignment that has separated IN the period defined
1494 -- by the target time dimension
1495 --
1496 -- This Cursor has been changed due to bug 1718083 to be exactly the same
1497 -- as the Workforce Seperations report. JRHYDE
1498 --
1499 -- A Loss occurs when the last day of a person's assignment occurs prior to
1500 -- the date of the period and the asg start date is prior to the first day of
1501 -- the period
1502 CURSOR asg_cur
1503 	(p_c_organization_id   IN NUMBER
1504 	,p_c_period_start_date IN date
1505 	,p_c_period_end_date   IN date) IS
1506  SELECT asg.assignment_id
1507       , asg.effective_end_date
1508    FROM per_all_assignments_f asg
1509       , per_assignment_status_types ast
1510   WHERE p_c_period_start_date-1 between
1511            asg.effective_start_date and
1512            asg.effective_end_date
1513     AND asg.assignment_type           = 'E'
1514     AND asg.organization_id           = p_c_organization_id
1515     AND asg.assignment_status_type_id = ast.assignment_status_type_id
1516     AND ast.per_system_status         = 'ACTIVE_ASSIGN'
1517     AND NOT EXISTS
1518   	 (SELECT null
1519 	    FROM per_all_assignments_f asg2,
1520  		     per_assignment_status_types ast2
1521 	   WHERE p_c_period_end_date between
1522                      asg2.effective_start_date and
1523                      asg2.effective_end_date
1524            AND asg2.assignment_type           = 'E'
1525            AND asg2.assignment_id             = asg.assignment_id
1526            AND asg2.assignment_status_type_id = ast2.assignment_status_type_id
1527            AND ast2.per_system_status         = 'ACTIVE_ASSIGN'
1528            AND asg2.organization_id           = p_c_organization_id);
1529 
1530 BEGIN
1531   pl('*HRMSP ACTUAL','Start');
1532 
1533   --
1534   -- Get the fast formula ID of the FTE or HEAD. This is used to
1535   -- calculate the budget measurement value of an employees assignment.
1536   --
1537 
1538   --Business Group is that of the organization of the - JRHYDE
1539   l_business_group_id := get_org_business_group_id(to_number(p_actual_rec.org_level_value_id));
1540 
1541   l_formula_id        := get_formula_id(l_business_group_id
1542                                        ,p_bmtype);
1543 
1544   pl('fast formula id: ',to_char(l_formula_id));
1545 
1546   --Get start and end dates from the time dim
1547   get_dates_from_time_dim
1548     (p_actual_rec.time_level_value_id
1549     ,l_period_start_date
1550     ,l_period_end_date);
1551 
1552   --
1553   -- Loop through each employee assignment that separated in the period defined
1554   -- by the PMF time dimesnion and then calculate the budget measurement value
1555   -- using the budget measurement type specified as a unit of measurement.
1556   --
1557   pl('Loop through employees separated in the target period');
1558   l_separated_count := 0;
1559   FOR asg_rec IN asg_cur
1560   		(to_number(p_actual_rec.org_level_value_id)
1561   		,l_period_start_date
1562   		,l_period_end_date) LOOP
1563 
1564     pl(' asg id: ',to_char(asg_rec.assignment_id));
1565     l_loss_type := hrfastanswers.getassignmentcategory
1566   	                 (p_assignment_id      => asg_rec.assignment_id
1567   	                 ,p_period_start_date  => l_period_start_date
1568   	                 ,p_period_END_date    => l_period_end_date
1569   	                 ,p_top_org  	       => p_actual_rec.org_level_value_id
1570   	                 ,p_movement_type      => 'OUT');
1571 
1572    pl(' loss: ',l_loss_type);
1573 
1574    IF l_loss_type = 'SEPARATED' THEN
1575 
1576      l_budget_value := hrfastanswers.getbudgetvalue
1577                             (p_budget_metric_formula_id => l_formula_id
1578        	                    ,p_budget_metric            => p_bmtype
1579                	            ,p_assignment_id            => asg_rec.assignment_id
1580                        	    ,p_effective_date           => asg_rec.effective_end_date
1581                 		    ,p_session_date             => sysdate);
1582 
1583      pl(p_bmtype
1584        ,to_char(l_budget_value));
1585 
1586      l_separated_count := l_separated_count + l_budget_value;
1587    END IF;
1588 
1589   END LOOP;
1590 
1591  pl('actual = ',to_char(l_separated_count));
1592  pl('*HRMSP ACTUAL','End');
1593 
1594  RETURN l_separated_count;
1595 
1596 EXCEPTION
1597   WHEN e_g_no_bg THEN
1598     pl('No BG found for FF');
1599     RAISE e_g_no_ff_bg;
1600 
1601 END;
1602 
1603 -------------------------------------------------------------------------
1604 -- PROCESS MANPOWER SEPARATION TARGETS
1605 -------------------------------------------------------------------------
1606 
1607 PROCEDURE process_hrmsp
1608            (p_target_rec  IN hri_target_rec_type)
1609  IS
1610 
1611 l_actual  NUMBER(22,2);
1612 l_mod_target bisfv_targets.target%TYPE;
1613 
1614 l_actual_rec        bis_actual_pub.actual_rec_type;
1615 
1616 BEGIN
1617 
1618   pl('*PROCESS MANPOWER SEPARATION TARGET','Start');
1619 
1620 /* IS THIS ACTUALLY NEEDED -JRHYDE 20/12/00
1621    hrFastAnswers.LoadOrgHierarchy(p_target_rec.org_level_value_id
1622                                ,g_org_structure_version_id);*/
1623 
1624   -- Convert the data from target record format into an actual record format
1625   l_actual_rec := get_bis_actual_rec(p_target_rec);
1626 
1627   IF p_target_rec.measure_short_name = 'HRMSPFTE' THEN
1628     l_actual := hrmsp_actual(l_actual_rec,'FTE');
1629   ELSIF p_target_rec.measure_short_name = 'HRMSPHEAD' THEN
1630     l_actual := hrmsp_actual(l_actual_rec,'HEAD');
1631   END IF;
1632 
1633   pl('actual: ',to_char(l_actual));
1634   pl('target: ',to_char(p_target_rec.target));
1635 
1636   --
1637   -- Send a notification if
1638   -- The actual value of workforce separations is
1639   -- greater than the target.
1640   -- If a value of -1 has been returned
1641   -- then abort processing as an error has occurred.
1642   --
1643   -- This process will be repeated for each of the three levels
1644   -- of notification that are available
1645   --
1646   IF l_actual = -1 THEN
1647     pl('Actual = -1','No workflow');
1648     null;
1649   ELSE
1650     IF p_target_rec.notify_resp1_id IS NOT NULL THEN
1651     /* 115.11 */
1652       IF validate_resp_org_security
1653            (p_target_rec.notify_resp1_id
1654            ,p_target_rec.notify_resp1_appl_id
1655            ,to_number(p_target_rec.org_level_value_id)) THEN
1656         l_mod_target := p_target_rec.target
1657                          + ((p_target_rec.target/100)*nvl(p_target_rec.range1_high,0));
1658         pl(' Processing responsibility 1: ',p_target_rec.notify_resp1_short_name);
1659         pl(' Modified target: ',l_mod_target);
1660         pl(' Actual: ',l_actual);
1661         IF l_actual > l_mod_target THEN
1662           send_notification_hrmsp(1
1663                                  ,l_mod_target
1664                                  ,l_actual
1665                                  ,p_target_rec);
1666         END IF;  -- actual < target
1667       END IF;  -- valid resp1_id security
1668     END IF;  --notify_resp1_id not null
1669 
1670     IF p_target_rec.notify_resp2_id IS NOT NULL THEN
1671       IF validate_resp_org_security
1672            (p_target_rec.notify_resp2_id
1673            ,p_target_rec.notify_resp2_appl_id
1674            ,to_number(p_target_rec.org_level_value_id)) THEN
1675         l_mod_target := p_target_rec.target
1676                          + ((p_target_rec.target/100)*nvl(p_target_rec.range2_high,0));
1677         pl(' Processing responsibility 2: ',p_target_rec.notify_resp2_short_name);
1678         pl(' Modified target: ',l_mod_target);
1679         pl(' Actual: ',l_actual);
1680         IF l_actual > l_mod_target THEN
1681           send_notification_hrmsp(2
1682                                  ,l_mod_target
1683                                  ,l_actual
1684                                  ,p_target_rec);
1685         END IF;  -- actual < target
1686       END IF;  -- valid resp2_id security
1687     END IF;  --notify_resp2_id not null
1688 
1689     IF p_target_rec.notify_resp3_id IS NOT NULL THEN
1690       IF validate_resp_org_security
1691            (p_target_rec.notify_resp3_id
1692            ,p_target_rec.notify_resp3_appl_id
1693            ,to_number(p_target_rec.org_level_value_id)) THEN
1694         l_mod_target := p_target_rec.target
1695                          + ((p_target_rec.target/100)*nvl(p_target_rec.range3_high,0));
1696         pl(' Processing responsibility 3: ',p_target_rec.notify_resp3_short_name);
1697         pl(' Modified target: ',l_mod_target);
1698         pl(' Actual: ',l_actual);
1699         IF l_actual > l_mod_target THEN
1700           send_notification_hrmsp(3
1701                                  ,l_mod_target
1702                                  ,l_actual
1703                                  ,p_target_rec);
1704         END IF;  -- actual < target
1705       END IF;  -- valid resp3_id security
1706     END IF;  --notify_resp3_id not null
1707   END IF; --actual = -1
1711 -- **********************************************************************
1708  pl('*PROCESS MANPOWER SEPARATION TARGET','End');
1709 END;
1710 
1712 --
1713 --                    M A N P O W E R   V A R I A N C E
1714 --
1715 -- **********************************************************************
1716 
1717 -------------------------------------------------------------------------
1718 --
1719 --  SEND A MANPOWER VARIANCE notification
1720 --
1721 -------------------------------------------------------------------------
1722 --
1723 -- This procedure builds the notification message including the URL
1724 -- to run the manpoiwer variance report and issues a call to the workflow
1725 -- engine to send the notification.
1726 --
1727 
1728 PROCEDURE send_notification_hrmvr
1729            (p_type       IN VARCHAR2
1730            ,p_resp_no    IN NUMBER  --No. between 1-3 signifying which resp
1731            ,p_target     IN NUMBER
1732            ,p_actual     IN NUMBER
1733            ,p_target_rec IN hri_target_rec_type)
1734  IS
1735 
1736   l_subject 	    fnd_new_messages.message_text%TYPE;
1737   l_message         VARCHAR2(2000);
1738   l_freq_code       VARCHAR2(4);
1739   l_dummy   	    VARCHAR2(2000);
1740   l_start_date      date;
1741   l_report_name     VARCHAR2(8);
1742   l_return_status   VARCHAR2(2000);
1743   l_error	        VARCHAR2(2000);
1744   l_param	        VARCHAR2(2000);
1745 
1746   -- Dimension Params
1747   l_org_name	    per_organization_units.name%TYPE;
1748   l_org_type	    hr_lookups.meaning%TYPE;
1749   l_orgprc  	    hr_lookups.meaning%TYPE;
1750   l_bmt_name        hr_lookups.meaning%TYPE;
1751   l_job_name        per_jobs.name%TYPE;
1752   l_job_cat         hr_lookups.meaning%TYPE;
1753   l_loc_name        hr_locations.location_code%TYPE;
1754 
1755   l_period_name     VARCHAR2(50);
1756 
1757   -- Session params
1758   l_security_group_id  per_business_groups.security_group_id%TYPE;
1759   l_business_group_id  hr_all_organization_units.business_group_id%TYPE;
1760   l_resp_id            fnd_responsibility.responsibility_id%TYPE;
1761   l_resp_short_name    bisfv_targets.notify_resp1_short_name%TYPE;
1762   l_resp_name          bisfv_targets.notify_resp1_name%TYPE;
1763   l_resp_appl_id       fnd_responsibility.application_id%TYPE;
1764 
1765 BEGIN
1766 
1767   pl('-----------------------------------');
1768   pl('*SEND Manpower Variance notification','Start');
1769   pl('-----------------------------------');
1770   pl(' type: ',p_type);
1771   pl(' responsibility no',to_char(p_resp_no));
1772   pl(' actual: ',to_char(p_actual));
1773   -----------------------------------------------------------------------
1774   -- Build the notification subject line and message text
1775   -----------------------------------------------------------------------
1776   --
1777   -- Get the following information that will be shown on the notification
1778   -- and populate the relevant tokens in the message HR_BIS_PMF_SUBJECT
1779   --
1780   -- 1. Get Session parameters for the report
1781   -- 2. Get Parameter Names:
1782   --    Organzation name
1783   --    Location
1784   --    Job or Job Category
1785   --    Budget Measurement Type Name
1786   --    Period name
1787   -- 3. build notification text
1788   -- 4. get the report frequency, number of periods and start date
1789   -- 5. build the report parameter string
1790   -- 6. start the workflow process
1791   --
1792    -- ---------------------------------------------------------------------
1793   -- 1. Get Session parameters for the report
1794   -- ---------------------------------------------------------------------
1795   get_resp_details(p_resp_no
1796                   ,p_target_rec
1797                   ,l_resp_id
1798                   ,l_resp_appl_id
1799                   ,l_resp_short_name
1800                   ,l_resp_name);
1801   l_business_group_id := get_org_business_group_id(p_target_rec.org_level_value_id);
1802   l_security_group_id := get_org_security_group_id(p_target_rec.org_level_value_id);
1803   -- ---------------------------------------------------------------------
1804   -- 2. Get the parameter names
1805   -- ---------------------------------------------------------------------
1806   --
1807   -- Organization
1808   --
1809   hr_reports.get_organization(p_target_rec.org_level_value_id,l_org_name,l_org_type);
1810   l_orgprc   := translate_orgprc(g_orgprc_const);
1811   pl(' org name: ',l_org_name);
1812   --
1813   -- Location
1814   --
1815   l_loc_name := translate_location(p_target_rec.dim1_level_value_id);
1816   pl(' loc name: ',l_loc_name);
1817   --
1818   -- Job / Job Category
1819   --
1820   IF p_target_rec.dim2_level_short_name = 'TOTAL GEOGRAPHY' THEN
1821     l_job_name := translate_all;
1822     l_job_cat  := translate_all;
1823   ELSIF p_target_rec.dim2_level_short_name = 'JOB' THEN
1824     l_job_name := translate_job(p_target_rec.dim2_level_value_id);
1825     l_job_cat  := translate_all;
1826   ELSIF p_target_rec.dim2_level_short_name = 'JOB CATEGORY' THEN
1827     l_job_name := translate_all;
1828     l_job_cat  := translate_job_category(p_target_rec.dim2_level_value_id);
1829   END IF;
1830   pl(' job name: ',l_job_name);
1831   pl(' job category name: ',l_job_cat);
1832   --
1833   -- Budget
1834   --
1835   l_bmt_name := hr_reports.get_lookup_meaning
1836                 ('BUDGET_MEASUREMENT_TYPE',p_target_rec.unit_of_measure);
1837   pl(' bmt name: ',l_bmt_name);
1841   l_period_name := to_char(p_target_rec.period_start_date,'DD-MON-YYYY')
1838   --
1839   -- Period
1840   --
1842                            ||' - '||to_char(p_target_rec.period_END_date,'DD-MON-YYYY');
1843   pl(' Period Name:',l_period_name);
1844   -- ---------------------------------------------------------------------
1845   -- 2. Build the notification text
1846   -- ---------------------------------------------------------------------
1847   --
1848   -- Build subject message text
1849   --
1850   IF p_type = 'ABOVE' THEN
1851    fnd_message.set_name('HRI','HR_BIS_PMF_HRMVR_HIGH_SUBJECT');
1852    l_subject := fnd_message.get;
1853   ELSE
1854    fnd_message.set_name('HRI','HR_BIS_PMF_HRMVR_LOW_SUBJECT');
1855    l_subject := fnd_message.get;
1856   END IF;
1857   --
1858   -- Build the body message text
1859   --
1860   IF p_type = 'ABOVE' THEN
1861    fnd_message.set_name('HRI','HR_BIS_PMF_HRMVR_HIGH_MSG');
1862   ELSE
1863    fnd_message.set_name('HRI','HR_BIS_PMF_HRMVR_LOW_MSG');
1864   END IF;
1865   fnd_message.set_token('ORGANIZATION',l_org_name);
1866   fnd_message.set_token('JOB',l_job_name);
1867   fnd_message.set_token('CATEGORY',l_job_cat);
1868   fnd_message.set_token('LOCATION',l_loc_name);
1869   fnd_message.set_token('PERIOD',l_period_name);
1870   fnd_message.set_token('BUDGET',l_bmt_name);
1871   fnd_message.set_token('TARGET',p_target);
1872   fnd_message.set_token('ACTUAL',p_actual);
1873   --fnd_message.set_token('ROLE',l_resp_name);
1874   l_message := fnd_message.get;
1875   pl(' Message:',l_message);
1876 
1877   -- ---------------------------------------------------------------------
1878   -- 4. build the report parameter string
1879   -- ---------------------------------------------------------------------
1880   -- Build the url that will be used to run the report from the
1881   -- notification.
1882   l_report_name := 'HRMNPSUM';
1883 
1884   get_report_date_params(p_target_rec.time_level_short_name
1885                         ,p_target_rec.period_start_date
1886                         ,l_freq_code
1887                         ,l_start_date);
1888   pl(' Frequency: ',l_freq_code);
1889   pl(' Start date: ',to_char(l_start_date,'DD-MON-YYYY'));
1890 
1891   l_param := 'org_id='             ||p_target_rec.org_level_value_id   ||'*'||
1892              'orgprc='             ||g_orgprc_const                    ||'*'||
1893              'bpl_id='             ||p_target_rec.plan_id              ||'*'||
1894              'bgttyp='             ||p_target_rec.unit_of_measure      ||'*'||
1895              'frqncy='             ||l_freq_code                       ||'*'||
1896              'geolvl=1*'           ||
1897              'geoval=-1*'          ||
1898              'bus_id='             ||to_char(l_business_group_id)      ||'*'||
1899              'prodid=-1*'          ||
1900              'startd='             ||to_char(l_start_date,'YYYY-MM-DD')||'*'||
1901              'end_dt='             ||to_char(p_target_rec.period_END_date,'YYYY-MM-DD')||'*'||
1902              'viewby=HR_BIS_TIME*';
1903 
1904   IF p_target_rec.dim2_level_short_name = 'JOB' THEN
1905     l_param := l_param          ||
1906                'job_id='        ||p_target_rec.dim2_level_value_id    ||'*'||
1907                'jobcat=__ALL__*';
1908   ELSIF p_target_rec.dim1_level_short_name = 'JOB CATEGORY' THEN
1909     l_param := l_param          ||
1910                'job_id=-1*'     ||
1911                'jobcat='        ||p_target_rec.dim2_level_value_id    ||'*';
1912   ELSE
1913     l_param := l_param          ||
1914                'job_id=-1*'     ||
1915                'jobcat=__ALL__*';
1916   END IF;
1917 
1918   l_param := l_param ||
1919             c_ampersand||'responsibility_application_id='
1920                        ||to_char(l_resp_appl_id)||
1921             c_ampersand||'security_group_id='
1922                        ||l_security_group_id;
1923 
1924   pl('wf      ',p_target_rec.workflow_item_type);
1925   pl('process ',p_target_rec.workflow_process_short_name);
1926   pl('resp    ',l_resp_short_name);
1927   pl('resp id ',to_char(l_resp_id));
1928   pl('applic  ',to_char(l_resp_appl_id));
1929   pl('secgrp  ',l_security_group_id);
1930   pl('param   ',substr(l_param,1,240));
1931   pl('report  ',l_report_name);
1932   pl('message ',substr(l_message,1,240));
1933   pl('subject ',l_subject);
1934   -- ---------------------------------------------------------------------
1935   -- 5. start the workflow process
1936   -- ---------------------------------------------------------------------
1937   pl('start workflow process');
1938   bis_util.strt_wf_process
1939 		(p_exception_message	=> l_message
1940 		,p_msg_subject		    => l_subject
1941 		,p_exception_date	    => sysdate
1942  	    ,p_item_type            => p_target_rec.workflow_item_type
1943 		,p_wf_process		    => p_target_rec.workflow_process_short_name
1944 		,p_notify_resp_name     => l_resp_short_name
1945 		,p_report_name1		    => l_report_name
1946 		,p_report_param1	    => l_param
1947         ,p_report_resp1_id     	=> l_resp_id
1948         ,x_return_status       	=> l_return_status);
1949 
1950   pl(' Resp id : ',to_char(l_resp_id));
1951 
1952   pl(' Workflow return status : ',l_return_status);
1953 
1954   IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
1955     RAISE e_g_bis_fn_error;
1956   END IF;
1957 
1958   pl('*SEND Manpower Variance notification','End');
1959 
1960 END;
1961 -------------------------------------------------------------------------
1962 --
1963 --  Compare actual to target
1964 --
1965 -------------------------------------------------------------------------
1966 PROCEDURE hrmvr_compare_values
1967             (p_target_rec IN hri_target_rec_type
1968             ,p_actual     IN NUMBER) IS
1969 
1970  l_mod_target 	bisfv_targets.target%TYPE;
1971 
1972 BEGIN
1973 --
1974 -- process range 1
1975 --
1976   IF p_target_rec.notify_resp1_id IS NOT NULL THEN
1977     IF validate_resp_org_security
1978        (p_target_rec.notify_resp1_id
1979        ,p_target_rec.notify_resp1_appl_id
1980        ,to_number(p_target_rec.org_level_value_id)) THEN
1981       IF p_target_rec.range1_high IS NOT NULL THEN
1982         l_mod_target := p_target_rec.target + ((p_target_rec.target/100)*p_target_rec.range1_high);
1983         pl(' Processing responsibility 1: ',p_target_rec.notify_resp1_short_name);
1984         pl(' Modified target: ',l_mod_target);
1985         pl(' Actual: ',p_actual);
1986         IF p_actual > l_mod_target THEN
1987           send_notification_hrmvr('ABOVE'
1988                                  ,1
1989                                  ,l_mod_target
1990                                  ,p_actual
1991                                  ,p_target_rec);
1992         END IF;
1993       END IF;  --range high
1994       IF p_target_rec.range1_low IS NOT NULL THEN
1995          l_mod_target := p_target_rec.target
1996                          -  ((p_target_rec.target/100)*p_target_rec.range1_low);
1997         pl(' Processing responsibility 1: ',p_target_rec.notify_resp1_short_name);
1998         pl(' Modified target: ',l_mod_target);
1999         pl(' Actual: ',p_actual);
2000         IF p_actual < l_mod_target THEN
2001             send_notification_hrmvr('BELOW'
2002                                     ,1
2003                                     ,l_mod_target
2004                                     ,p_actual
2005                                     ,p_target_rec);
2006         END IF;
2007       END IF;  -- range low
2008     END IF;  -- valid resp1_id security
2009   END IF;  --notify_resp1_id not null
2010 
2011   --
2012   -- process range 2
2013   --
2014   IF p_target_rec.notify_resp2_id IS NOT NULL THEN
2015     IF validate_resp_org_security
2016          (p_target_rec.notify_resp2_id
2017          ,p_target_rec.notify_resp2_appl_id
2018          ,to_number(p_target_rec.org_level_value_id)) THEN
2019       IF p_target_rec.range2_high IS NOT NULL THEN
2020         l_mod_target := p_target_rec.target
2021                         + ((p_target_rec.target/100)*p_target_rec.range2_high);
2022         pl(' Processing responsibility 2: ',p_target_rec.notify_resp2_short_name);
2023         pl(' Modified target: ',l_mod_target);
2024         pl(' Actual: ',p_actual);
2025         IF p_actual > l_mod_target THEN
2026           send_notification_hrmvr('ABOVE'
2027                                  ,2
2028                                  ,l_mod_target
2029                                  ,p_actual
2030                                  ,p_target_rec);
2031         END IF;
2032       END IF;  -- range high
2033       IF p_target_rec.range2_low IS NOT NULL THEN
2034         l_mod_target := p_target_rec.target
2035                          - ((p_target_rec.target/100)*p_target_rec.range2_low);
2036         pl(' Processing responsibility 2: ',p_target_rec.notify_resp2_short_name);
2037         pl(' Modified target: ',l_mod_target);
2038         pl(' Actual: ',p_actual);
2039         IF p_actual < l_mod_target THEN
2040           send_notification_hrmvr('BELOW'
2041                                  ,2
2042                                  ,l_mod_target
2043                                  ,p_actual
2044                                  ,p_target_rec);
2045         END IF;
2046       END IF;  -- range low
2047     END IF;  -- valid resp2_id security
2048   END IF;  --notify_resp2_id not null
2049 
2050 --
2051 -- process range 3
2052 --
2053   IF p_target_rec.notify_resp3_id IS NOT NULL THEN
2054     IF validate_resp_org_security
2055          (p_target_rec.notify_resp3_id
2056          ,p_target_rec.notify_resp3_appl_id
2057          ,to_number(p_target_rec.org_level_value_id)) THEN
2058       IF p_target_rec.range3_high IS NOT NULL THEN
2059         l_mod_target := p_target_rec.target
2060                          + ((p_target_rec.target/100)*p_target_rec.range3_high);
2061         pl(' Processing responsibility 3: ',p_target_rec.notify_resp3_short_name);
2062         pl(' Modified target: ',l_mod_target);
2063         pl(' Actual: ',p_actual);
2064         IF p_actual > l_mod_target THEN
2065           send_notification_hrmvr('ABOVE'
2066                                  ,3
2067                                  ,l_mod_target
2068                                  ,p_actual
2069                                  ,p_target_rec);
2070         END IF;
2071       END IF;  -- range high
2072       IF p_target_rec.range3_low IS NOT NULL THEN
2073         l_mod_target := p_target_rec.target
2074                          - ((p_target_rec.target/100)*p_target_rec.range3_low);
2075         pl(' Processing responsibility 3: ',p_target_rec.notify_resp3_short_name);
2076         pl(' Modified target: ',l_mod_target);
2077         pl(' Actual: ',p_actual);
2078         IF p_actual < l_mod_target THEN
2079           send_notification_hrmvr('BELOW'
2080                                  ,3
2081                                  ,l_mod_target
2082                                  ,p_actual
2083                                  ,p_target_rec);
2084         END IF;
2085       END IF;  -- range low
2086     END IF;  -- valid resp3_id security
2087   END IF;  --notify_resp3_id not null
2088 
2089 END hrmvr_compare_values;
2090 
2091 -------------------------------------------------------------------------
2092 --
2093 --  CALCULATE THE ACTUAL MANPOWER VARIANCE
2094 --
2095 -------------------------------------------------------------------------
2096 --
2097 -- This procedure will calculate the total actual manpower as of today
2098 -- filtered using the target dimensions.
2099 --
2100 
2101 FUNCTION hrmvr_actual
2102            (p_actual_rec   IN bis_actual_pub.actual_rec_type
2103            ,p_bmtype       IN VARCHAR2)
2104  RETURN NUMBER
2105  IS
2106 
2107 l_budget_value		NUMBER(20,2) := 0;
2108 l_total_manpower	NUMBER(20,2) := 0;
2109 
2110 l_business_group_id NUMBER;
2111 
2112 l_period_start_date DATE;
2113 l_period_end_date   DATE;
2114 
2115 l_formula_id 		ff_formulas.formula_id%TYPE;
2116 
2117 --
2118 -- Get the total manpower matching the target dimensions
2119 --
2120 -- This Cursor has been changed due to bug 1718083 to be exactly the same
2121 -- as the Workforce Total report. JRHYDE
2122 --
2123 -- To make this the same as the report have to calculate the abv at the end
2124 -- of the period. As total workforce is counted when an assignment exists
2125 -- on the end date and the start date. Regardless of whether it is the same date track row,
2126 -- as long as it is the same assignment. But the report also factors in any
2127 -- Gains occuring during the period.  So this equates to all assignments at the
2128 -- end of a period.
2129   CURSOR mv_cur
2130           (p_c_business_group_id  NUMBER
2131           ,p_c_actual_rec         bis_actual_pub.actual_rec_type
2132           ,p_c_period_start_date  DATE
2133           ,p_c_period_end_date    DATE)
2134      IS
2135     SELECT asg.assignment_id
2136          , asg.effective_start_date
2137       FROM per_all_assignments_f asg
2138          , per_assignment_status_types ast
2139      WHERE ( (p_c_actual_rec.dim2_level_value_name = 'JOB CATEGORY'
2140                AND   asg.job_id IN (SELECT jei.job_id
2141                                       FROM per_job_extra_info jei
2142                                      WHERE jei.jei_information1 = p_c_actual_rec.dim2_level_value_id)
2143              )
2144              OR
2145              (p_c_actual_rec.dim2_level_value_name = 'JOB'
2146                AND
2147               asg.job_id = to_number(p_c_actual_rec.dim2_level_value_id) )
2148              OR
2149              (p_c_actual_rec.dim2_level_value_name = 'TOTAL JOBS')
2150            )
2151        AND ( (p_c_actual_rec.dim1_level_value_name = 'LOCATION'
2152                AND
2153               asg.location_id = to_number(p_c_actual_rec.dim3_level_value_id))
2154              OR
2155             p_c_actual_rec.dim1_level_value_name = 'TOTAL GEOGRAPHY'
2156            )
2157        AND asg.business_group_id = p_c_business_group_id
2158        AND asg.organization_id = to_number(p_c_actual_rec.org_level_value_id)
2159        AND asg.assignment_status_type_id = ast.assignment_status_type_id
2160        AND ast.per_system_status = 'ACTIVE_ASSIGN'
2161        AND asg.assignment_type = 'E' -- Bug 2357061
2162        AND p_c_period_end_date BETWEEN
2163             asg.effective_start_date AND
2164             asg.effective_end_date
2165        /* Commented out because of the method in HRMNPSUM used to calc TOTAL
2166        AND EXISTS
2167            (SELECT null
2168               FROM per_all_assignments_f asg2
2169                  , per_assignment_status_types ast2
2170              WHERE p_c_period_start_date-1 BETWEEN
2171                      asg2.effective_start_date AND
2172                      asg2.effective_end_date
2173                AND asg2.assignment_id             = asg.assignment_id
2174                AND asg2.assignment_status_type_id = ast2.assignment_status_type_id
2175                AND ast2.per_system_status         = 'ACTIVE_ASSIGN'
2176                AND asg2.organization_id           = p_c_actual_rec.org_level_value_id
2177            )
2178        */
2179        ;
2180 
2181 BEGIN
2182 
2183   pl('*HRMVR actual','Start');
2184   --
2185   -- If a fast formula exists this will be used to calculate the
2186   -- manpower value
2187   --
2188   l_business_group_id := get_org_business_group_id(to_number(p_actual_rec.org_level_value_id));
2189   pl(' Business Group id',to_char(l_business_group_id));
2190   pl(' unit of measure ',p_bmtype);
2191   l_formula_id        := get_formula_id(l_business_group_id
2192                                        ,p_bmtype);
2193   pl(' formula id ',to_char(l_formula_id));
2194   pl(' dim1 ',p_actual_rec.dim1_level_value_id);
2195   pl(' dim2 ',p_actual_rec.dim2_level_value_id);
2196   pl(' dim3 ',p_actual_rec.dim3_level_value_id);
2197   pl(' dim1 ',p_actual_rec.dim1_level_value_name);
2198   pl(' dim2 ',p_actual_rec.dim2_level_value_name);
2199   pl(' dim3 ',p_actual_rec.dim3_level_value_name);
2200 
2201 
2202   --Get start and end dates from the time dim
2203   get_dates_from_time_dim
2204     (p_actual_rec.time_level_value_id
2205     ,l_period_start_date
2206     ,l_period_end_date);
2207   --
2208   -- get all the eligible assignments
2209   --
2210   pl('loop through assignments');
2211 
2212   FOR mv_rec IN mv_cur
2213                  (l_business_group_id
2214                  ,p_actual_rec
2215                  ,l_period_start_date
2216                  ,l_period_end_date)
2217     LOOP
2218     pl(' assignment id ',to_char(mv_rec.assignment_id));
2219 
2220     l_budget_value := HrFastAnswers.GetBudgetValue
2221                             (p_budget_metric_formula_id => l_formula_id
2222                             ,p_budget_metric            => p_bmtype
2223                             ,p_assignment_id            => mv_rec.assignment_id
2224                             ,p_effective_date           => mv_rec.effective_start_date
2225                             ,p_session_date             => sysdate);
2226 
2227     pl(p_bmtype
2228       ,to_char(l_budget_value));
2229 
2230     l_total_manpower := l_total_manpower + l_budget_value;
2231   END LOOP;
2232 
2233   pl('Actual = ',to_char(l_total_manpower));
2234   pl('*HRMVR actual','End');
2235 
2236   RETURN  l_total_manpower;
2237 
2238 END hrmvr_actual;
2239 
2240 -------------------------------------------------------------------------
2241 --
2242 --  PROCESS MANPOWER VARIANCE TARGETS
2243 --
2244 -------------------------------------------------------------------------
2245 
2246 PROCEDURE process_hrmvr
2247              (p_target_rec IN hri_target_rec_type)
2248  IS
2249 
2250 l_actual            NUMBER(22,2);
2251 l_budget_value	  NUMBER(22,2);
2252 l_budget_id         per_budgets_v.budget_id%TYPE;
2253 l_business_group_id NUMBER;
2254 
2255 l_actual_rec        bis_actual_pub.actual_rec_type;
2256 
2257 --
2258 -- get the budget value
2259 --
2260 
2261 CURSOR bv_cur(p_budget_id         IN NUMBER
2262              ,p_business_group_id IN NUMBER
2263              ,p_target_rec        IN hri_target_rec_type) IS
2264    SELECT sum(bval.value) budget_value
2265      FROM per_budget_values	bval
2266         , per_budget_elements	be
2267         , per_budget_versions	bver
2268         , per_time_periods	tp
2269   	    , per_budgets_v		bud
2270      where	bud.unit                = p_target_rec.unit_of_measure
2271        AND  bud.business_group_id	= l_business_group_id
2272        AND	bud.budget_id		    = p_budget_id
2273        AND	bud.budget_id		    = bver.budget_id
2274        AND  trunc(sysdate) BETWEEN
2275               bver.date_FROM AND nvl( bver.date_to, SYSDATE+1 )
2276        AND	be.budget_version_id	= bver.budget_version_id
2277        AND	be.budget_element_id	= bval.budget_element_id
2278        AND	tp.time_period_id	    = bval.time_period_id
2279        AND 	be.organization_id      = p_target_rec.org_level_value_id
2280        AND  ((p_target_rec.dim2_level_short_name = 'JOB CATEGORY'
2281        AND   be.job_id IN (SELECT jei.job_id
2282                              FROM per_job_extra_info jei
2283                             WHERE jei.jei_information1 = p_target_rec.dim2_level_value_id))
2284        OR    (p_target_rec.dim2_level_short_name = 'JOB'
2285                AND  be.job_id = p_target_rec.dim2_level_value_id)
2286        OR    (p_target_rec.dim2_level_short_name = 'TOTAL JOBS'))
2287                AND	tp.start_date = p_target_rec.period_start_date
2288        AND	tp.END_date   = p_target_rec.period_END_date;
2289 
2290 BEGIN
2291 
2292   pl('*Processing manpower variance','Start');
2293   pl(' Dim3 (budget) ',p_target_rec.dim3_level_value_id);
2294 
2295   -- Convert the date from target record format into an actual record format
2296   l_actual_rec := get_bis_actual_rec(p_target_rec);
2297 
2298   --
2299   -- IF the target based on a HR budget (i.e. dimension 3 is populate)
2300   -- then get the target value from the budget
2301   -- otherwise use the value from the target itself.
2302   -- Note: If the target contains both the name
2303   -- of a budget and a target value, the target value is ignored.
2304   --
2305 
2306   -- hrFastAnswers.LoadOrgHierarchy(p_target_rec.org_level_value_id,g_org_structure_version_id);
2307 
2308   IF (p_target_rec.dim3_level_value_id = '-1'
2309        OR
2310       p_target_rec.dim3_level_value_id IS NULL )
2311     THEN
2312 
2313     pl(' Budget not specified so using target values');
2314 
2315     IF p_target_rec.measure_short_name = 'HRMVRFTE' THEN
2316        l_actual := hrmvr_actual(l_actual_rec,'FTE');
2317     ELSIF p_target_rec.measure_short_name = 'HRMVRHEAD' THEN
2318        l_actual := hrmvr_actual(l_actual_rec,'HEAD');
2319     END IF;
2320     pl(' actual ',to_char(l_actual));
2321     hrmvr_compare_values(p_target_rec
2322                         ,l_actual);
2323   ELSE
2324     l_budget_id := to_NUMBER(substr(p_target_rec.dim3_level_value_id
2325                                    ,instr(p_target_rec.dim3_level_value_id,'+')+1));
2326     l_business_group_id := get_org_business_group_id(to_number(p_target_rec.org_level_value_id));
2327     pl(' Budget used so querying budget');
2328     OPEN bv_cur(l_budget_id
2329                ,l_business_group_id
2330                ,p_target_rec);
2331     FETCH bv_cur
2332       INTO l_actual;
2333 
2334     IF bv_cur%NOTFOUND THEN
2335        CLOSE bv_cur;
2336     ELSE
2337        CLOSE bv_cur;
2338        pl(' budget target ',to_char(p_target_rec.target));
2339 
2340        IF p_target_rec.measure_short_name = 'HRMVRFTE' THEN
2341          l_actual := hrmvr_actual(l_actual_rec,'FTE');
2342        ELSIF p_target_rec.measure_short_name = 'HRMVRHEAD' THEN
2346        hrmvr_compare_values(p_target_rec
2343          l_actual := hrmvr_actual(l_actual_rec,'HEAD');
2344        END IF;
2345 
2347                            ,l_actual);
2348     END IF;
2349  END IF;
2350  pl('*Processing manpower variance','End');
2351 
2352 END;
2353 
2354 -- **********************************************************************
2355 --
2356 --                       RECRUITMENT SUCCESS
2357 --
2358 -- **********************************************************************
2359 
2360 
2361 -------------------------------------------------------------------------
2362 --
2363 --  SEND RECRUITMENT SUCCESS notification
2364 --
2365 -------------------------------------------------------------------------
2366 -- This procedure will build and send a recruitment success notification.
2367 -- It is called from the procedure hrrcs_process if the actual recruitment
2368 -- success rate is less than the targeted success rate.
2369 --
2370 
2371 PROCEDURE send_notification_hrrcs
2372            (p_resp_no    IN NUMBER
2373            ,p_target     IN NUMBER
2374            ,p_actual     IN NUMBER
2375            ,p_target_rec hri_target_rec_type)
2376  IS
2377 
2378 l_subject       fnd_new_messages.message_text%TYPE;
2379 l_message       VARCHAR2(2000);
2380 l_freq_code     VARCHAR2(4);
2381 l_dummy         VARCHAR2(2000);
2382 l_param         VARCHAR2(2000);
2383 l_error         VARCHAR2(2000);
2384 
2385 l_start_date    DATE;
2386 l_report_name   VARCHAR2(8) := 'HRCOMREC';
2387 l_return_status VARCHAR2(2000);
2388 
2389 l_actual        VARCHAR2(30);
2390 l_target        VARCHAR2(30);
2391 
2392 l_org_name	    per_organization_units.name%TYPE;
2393 l_org_type	    hr_lookups.meaning%TYPE;
2394 l_orgprc    	hr_lookups.meaning%TYPE;
2395 l_bmt_name  	hr_lookups.meaning%TYPE;
2396 l_job_name  	per_jobs.name%TYPE;
2397 l_job_cat   	hr_lookups.meaning%TYPE  := '';
2398 l_loc_name  	hr_locations.location_code%TYPE;
2399 
2400 l_period_name  VARCHAR2(50);
2401 
2402 -- Session params
2403 l_security_group_id  per_business_groups.security_group_id%TYPE;
2404 l_business_group_id  hr_all_organization_units.business_group_id%TYPE;
2405 l_resp_id            fnd_responsibility.responsibility_id%TYPE;
2406 l_resp_short_name    bisfv_targets.notify_resp1_short_name%TYPE;
2407 l_resp_name          bisfv_targets.notify_resp1_name%TYPE;
2408 l_resp_appl_id       fnd_responsibility.application_id%TYPE;
2409 
2410 BEGIN
2411 
2412   pl('-------------------------------------');
2413   pl('*SEND recruitment success notification','Start');
2414 
2415   -----------------------------------------------------------------------
2416   -- Build the notification subject line and message text
2417   -----------------------------------------------------------------------
2418   --
2419   -- Get the following information that will be shown on the notification
2420   -- and populate the relevant tokens in the message HR_BIS_PMF_SUBJECT
2421   --
2422   -- 1. Get Session parameters for the report
2423   -- 2. Get Parameter Names:
2424   --    Organzation name
2425   --    Location
2426   --    Job or Job Category
2427   --    Budget Measurement Type Name
2428   --    Period name
2429   -- 3. build notification text
2430   -- 4. get the report frequency, number of periods and start date
2431   -- 5. build the report parameter string
2432   -- 6. start the workflow process
2433   --
2434   -- ---------------------------------------------------------------------
2435   -- 1. Get Session parameters for the report
2436   -- ---------------------------------------------------------------------
2437   get_resp_details(p_resp_no
2438                   ,p_target_rec
2439                   ,l_resp_id
2440                   ,l_resp_appl_id
2441                   ,l_resp_short_name
2442                   ,l_resp_name);
2443   l_business_group_id := get_org_business_group_id(p_target_rec.org_level_value_id);
2444   l_security_group_id := get_org_security_group_id(p_target_rec.org_level_value_id);
2445   -- ---------------------------------------------------------------------
2446   -- 1. Get the parameter names
2447   -- ---------------------------------------------------------------------
2448   --
2449   -- Organization
2450   --
2451   hr_reports.get_organization(p_target_rec.org_level_value_id,l_org_name,l_org_type);
2452   l_orgprc   := translate_orgprc(g_orgprc_const);
2453   pl(' org name: ',l_org_name);
2454   --
2455   -- Location
2456   --
2457   l_loc_name          := translate_location(p_target_rec.dim1_level_value_id);
2458   pl(' loc name : ',l_loc_name);
2459   --
2460   -- Job / Job Category
2461   --
2462   IF p_target_rec.dim2_level_short_name = 'JOB' THEN
2463      l_job_name := translate_job(p_target_rec.dim2_level_value_id);
2464      l_job_cat  := translate_all;
2465   ELSIF p_target_rec.dim2_level_short_name = 'JOB CATEGORY' THEN
2466      l_job_name := translate_all;
2467      l_job_cat  := translate_job_category(p_target_rec.dim2_level_value_id);
2468   ELSIF p_target_rec.dim2_level_short_name = 'TOTAL JOBS' THEN
2469      l_job_name := translate_all;
2470      l_job_cat  := translate_all;
2471   END IF;
2472   pl(' job name: ',l_job_name);
2473   pl(' job category name: ',l_job_cat);
2474   --
2475   -- Budget Name
2476   --
2477   -- Bug 2530846 replacing use of budget_measurement_type with Unit_of_measure
2481   --
2478   l_bmt_name := hr_reports.get_lookup_meaning('BUDGET_MEASUREMENT_TYPE'
2479                                              ,p_target_rec.unit_of_measure);
2480   pl(' bmt name: ',l_bmt_name);
2482   -- Period Name
2483   --
2484   l_period_name := to_char(p_target_rec.period_start_date,'DD-MON-YYYY')
2485                            ||' - '||to_char(p_target_rec.period_END_date,'DD-MON-YYYY');
2486   pl(' period name: ',l_period_name);
2487   -- ---------------------------------------------------------------------
2488   -- 2. Build the notification text
2489   -- ---------------------------------------------------------------------
2490   --
2491   -- Build subject message text
2492   --
2493   fnd_message.set_name('HRI','HR_BIS_PMF_HRRCS_SUBJECT');
2494   l_subject := fnd_message.get;
2495   --
2496   -- Add Percent signs to actual values
2497   --
2498   l_actual := to_char(p_actual)||'%';
2499   l_target := to_char(p_target)||'%';
2500   --
2501   -- Build the body message text
2502   --
2503   fnd_message.set_name('HRI','HR_BIS_PMF_HRRCS_MSG');
2504   fnd_message.set_token('ORGANIZATION',l_org_name);
2505   fnd_message.set_token('LOCATION',l_loc_name);
2506   fnd_message.set_token('JOB',l_job_name);
2507   fnd_message.set_token('CATEGORY',l_job_cat);
2508   fnd_message.set_token('PERIOD',l_period_name);
2509   fnd_message.set_token('TARGET',l_target);
2510   fnd_message.set_token('ACTUAL',l_actual);
2511   -- Bug 2530846 replacing use of budget_measurement_type with Unit_of_measure
2512   fnd_message.set_token('BUDGET',l_bmt_name);
2513   --fnd_message.set_token('ROLE',l_resp_name);
2514   l_message := fnd_message.get;
2515   pl(' Message:',l_message);
2516 
2517   -- ---------------------------------------------------------------------
2518   -- 4. build the report parameter string
2519   -- ---------------------------------------------------------------------
2520   -- Build the url that will be used to run the report from the
2521   -- notification.
2522   l_report_name := 'HRCOMREC';
2523 
2524   get_report_date_params(p_target_rec.time_level_short_name
2525                         ,p_target_rec.period_start_date
2526                         ,l_freq_code
2527                         ,l_start_date);
2528   pl(' Frequency: ',l_freq_code);
2529   pl('Start date: ',to_char(l_start_date,'DD-MON-YYYY'));
2530 
2531   -- Bug 2530846 replacing use of budget_measurement_type with Unit_of_measure
2532   l_param := 'org_id=' 	||p_target_rec.org_level_value_id   ||'*'||
2533              'orgprc='  ||g_orgprc_const                    ||'*'||
2534              'bus_id='  ||to_char(l_business_group_id)      ||'*'||
2535              'bpl_id='  ||p_target_rec.plan_id              ||'*'||
2536              'bgttyp='  ||p_target_rec.unit_of_measure      ||'*'||
2537              'frqncy='  ||l_freq_code                       ||'*'||
2538              'startd='  ||to_char(l_start_date,'YYYY-MM-DD')||'*'||
2539              'end_dt='  ||to_char(p_target_rec.period_END_date,'YYYY-MM-DD')||'*';
2540 
2541   IF p_target_rec.dim2_level_short_name = 'JOB' THEN
2542      l_param := l_param||
2543                'job_id='  ||p_target_rec.dim2_level_value_id    ||'*'||
2544                'jobcat=__ALL__*';
2545   ELSIF p_target_rec.dim2_level_short_name = 'JOB CATEGORY' THEN
2546      l_param := l_param||
2547                'job_id=-1*'||
2548                'jobcat='  ||p_target_rec.dim2_level_value_id    ||'*';
2549   ELSE
2550      l_param := l_param||
2551                'job_id=-1*'||
2552                'jobcat=__ALL__*';
2553   END IF;
2554   --
2555   -- Append the responsibility and security group ID to the URL. This is used by
2556   -- ICX to switch the responsibility when running the report.
2557   --
2558   l_param := l_param ||
2559              c_ampersand||'responsibility_application_id='
2560                         ||to_char(l_resp_appl_id)||
2561              c_ampersand||'security_group_id='
2562                         ||l_security_group_id;
2563 
2564   pl('wf      ',p_target_rec.workflow_item_type);
2565   pl('process ',p_target_rec.workflow_process_short_name);
2566   pl('resp    ',l_resp_short_name);
2567   pl('resp id ',to_char(l_resp_id));
2568   pl('applic  ',to_char(l_resp_appl_id));
2569   pl('secgrp  ',l_security_group_id);
2570   pl('param   ',substr(l_param,1,240));
2571   pl('report  ',l_report_name);
2572   pl('message ',substr(l_message,1,240));
2573   pl('subject ',l_subject);
2574   -- ---------------------------------------------------------------------
2575   -- 5. start the workflow process
2576   -- ---------------------------------------------------------------------
2577   pl('start workflow process');
2578   bis_util.strt_wf_process
2579 		(p_exception_message	=> l_message
2580 		,p_msg_subject		    => l_subject
2581 		,p_exception_date	    => sysdate
2582  	    ,p_item_type            => p_target_rec.workflow_item_type
2583 		,p_wf_process		    => p_target_rec.workflow_process_short_name
2584 		,p_notify_resp_name     => l_resp_short_name
2585 		,p_report_name1		    => l_report_name
2586 		,p_report_param1	    => l_param
2587         ,p_report_resp1_id     	=> l_resp_id
2588         ,x_return_status       	=> l_return_status);
2589 
2590   pl(' Resp id : ',to_char(l_resp_id));
2591 
2592   pl(' Workflow return status : ',l_return_status);
2593 
2594   IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
2595      RAISE e_g_bis_fn_error;
2599 
2596   END IF;
2597 
2598   pl('*SEND Recruitment Success notification','End');
2600 END;
2601 
2602 -------------------------------------------------------------------------
2603 --
2604 --  CALCULATE RECRUITMENT SUCCESS ACTUAL
2605 --
2606 -------------------------------------------------------------------------
2607 --
2608 -- This function will calculate and return the recruitment success rate. the
2609 -- recruitment success rate is the percentage of vacant places that were
2610 -- successfully filled.
2611 --
2612 FUNCTION hrrcs_actual
2613            (p_actual_rec  IN bis_actual_pub.actual_rec_type
2614            ,p_bmtype      IN VARCHAR2)
2615   RETURN NUMBER
2616   IS
2617 
2618   l_success_rate	    NUMBER;
2619   l_total_vacancies     NUMBER;
2620   l_total_assignments	NUMBER;
2621 
2622   l_period_start_date   DATE;
2623   l_period_end_date     DATE;
2624 
2625   l_business_group_id	NUMBER;
2626   l_budget_value        NUMBER;
2627 
2628   l_formula_id           ff_formulas_f.formula_id%TYPE;
2629 
2630 --
2631 -- This cursor gets each vacancy that closed in period defined by the
2632 -- pmf time dimension
2633 --
2634 
2635 CURSOR vac_cur(p_c_actual_rec         bis_actual_pub.actual_rec_type
2636               ,p_c_bmtype             VARCHAR2
2637               ,p_c_period_start_date  DATE
2638               ,p_c_period_end_date    DATE)
2639   IS
2640  SELECT  v.budget_measurement_value
2641       ,  v.vacancy_id
2642    FROM  per_vacancies v
2643   WHERE  ( (p_c_actual_rec.dim2_level_value_name = 'JOB CATEGORY'
2644              AND  v.job_id IN
2645                  (SELECT jei.job_id
2646                   FROM per_job_extra_info jei
2647                   WHERE jei.jei_information1
2648                       = p_c_actual_rec.dim2_level_value_id)
2649            )
2650             OR
2651            (p_c_actual_rec.dim2_level_value_name = 'JOB'
2652              AND v.job_id = to_number(p_c_actual_rec.dim2_level_value_id)
2653            )
2654             OR
2655            (p_c_actual_rec.dim2_level_value_name = 'TOTAL JOBS')
2656          )
2657     AND  ( (p_c_actual_rec.dim1_level_value_name = 'LOCATION'
2658              AND v.location_id = to_number(p_c_actual_rec.dim1_level_value_id)
2659            )
2660              OR
2661            (p_c_actual_rec.dim1_level_value_name = 'TOTAL GEOGRAPHY')
2662          )
2663     AND v.budget_measurement_type = p_c_bmtype
2664     AND v.status = 'CLOSED'  --Closed vacancy, bug 2449031
2665     AND v.date_to BETWEEN
2666            p_c_period_start_date AND p_c_period_end_date
2667     AND v.organization_id = p_actual_rec.org_level_value_id;
2668 
2669 --
2670 -- This cursor gets the first instance of an employee assignment that
2671 -- was created from a given vacancy
2672 --
2673 CURSOR asg_cur (p_vacancy_id IN NUMBER) IS
2674  SELECT a.assignment_id
2675       , a.vacancy_id
2676       , a.effective_start_date
2677    FROM per_all_assignments_f a
2678   WHERE (a.assignment_id, a.effective_start_date) IN
2679           (SELECT b.assignment_id,min(b.effective_start_date)
2680              FROM per_all_assignments_f b
2681             WHERE b.assignment_type = 'E'
2682               AND b.vacancy_id = p_vacancy_id
2683            GROUP BY b.assignment_id);
2684 
2685 BEGIN
2686 
2687   pl('*HRRCS Actual','Start');
2688   --
2689   -- Get the fast formula ID of the FTE or HEAD. This is used to
2690   -- calculate the budget measurement value of an employees assignment
2691   --
2692   l_business_group_id :=
2693   get_org_business_group_id(to_number(p_actual_rec.org_level_value_id));
2694 
2695   pl('Business Group id: ',  l_business_group_id);
2696   l_formula_id        := get_formula_id(l_business_group_id
2697                                        ,p_bmtype);
2698   pl('Formula id ',to_char(l_formula_id));
2699 
2700   --Get start and end dates from the time dim
2701   get_dates_from_time_dim
2702     (p_actual_rec.time_level_value_id
2703     ,l_period_start_date
2704     ,l_period_end_date);
2705 
2706   --
2707   -- Loop through each vacancy that closed in the period defined by the pmf
2708   -- time dimension and calculate the total number of vacancies.
2709   --
2710   l_total_vacancies   := 0;
2711   l_total_assignments := 0;
2712 
2713   FOR vac_rec IN vac_cur(p_actual_rec
2714                         ,p_bmtype
2715                         ,l_period_start_date
2716                         ,l_period_end_date)
2717     LOOP
2718 
2719     pl('Vacancy  ',to_char(vac_rec.vacancy_id));
2720     pl('Openings ',to_char(vac_rec.budget_measurement_value));
2721 
2722     l_total_vacancies := l_total_vacancies+vac_rec.budget_measurement_value;
2723     --
2724     -- get the budget value for each employee assignment created from
2725     -- this vacancy
2726     --
2727     FOR asg_rec IN asg_cur(vac_rec.vacancy_id) LOOP
2728       pl(' Asg ',to_char(asg_rec.assignment_id));
2729 
2730       l_budget_value := hrFastAnswers.getBudgetValue
2731   	                       (p_budget_metric_formula_id => l_formula_id
2732         	               ,p_budget_metric            => p_bmtype
2733                 	       ,p_assignment_id            => asg_rec.assignment_id
2737       l_total_assignments := l_total_assignments + l_budget_value;
2734                            ,p_effective_date           => asg_rec.effective_start_date
2735                        	   ,p_session_date             => sysdate);
2736 
2738       pl(p_bmtype,to_char(l_budget_value));
2739 
2740     END LOOP;
2741   END LOOP;
2742   --
2743   -- Calculate the recruitment success rate
2744   --
2745   pl('Total vacancies: ',to_char(l_total_vacancies));
2746   pl('Total assignments: ',to_char(l_total_assignments));
2747 
2748   IF l_total_vacancies = 0 THEN
2749     l_success_rate := null;
2750   ELSIF l_total_assignments = 0  THEN
2751     l_success_rate := 0;
2752   ELSE
2753     l_success_rate := round((l_total_assignments / l_total_vacancies ) * 100,1);
2754   END IF;
2755 
2756   pl('+Success rate: ',to_char(l_success_rate));
2757   pl('*HRRCS Actual','End');
2758 
2759   RETURN l_success_rate;
2760 
2761 END hrrcs_actual;
2762 
2763 -------------------------------------------------------------------------
2764 --
2765 --  PROCESS RECRUITMENT SUCCESS TARGETS
2766 --
2767 -------------------------------------------------------------------------
2768 --
2769 -- This procedure will calculate the actual recruitment success rates
2770 -- using the target dimensions and will compare it to the target value. If
2771 -- that actual value is below the target value then a notification is sent. The
2772 -- notification is sent to the notIFy responsibility specIFied IN the target.
2773 --
2774 --
2775 PROCEDURE process_hrrcs
2776             (p_target_rec IN hri_target_rec_type)
2777  IS
2778 
2779  l_actual            NUMBER;
2780  l_mod_target        bisfv_targets.target%TYPE;
2781  l_actual_rec        bis_actual_pub.actual_rec_type;
2782 
2783 BEGIN
2784 
2785   pl('*Process Recruitment Success Target','Start');
2786 
2787   -- Convert the data from target record format into an actual record format
2788   l_actual_rec := get_bis_actual_rec(p_target_rec);
2789 
2790   IF p_target_rec.measure_short_name = 'HRRCSFTE' THEN
2791      l_actual := hrrcs_actual(l_actual_rec,'FTE');
2792   ELSIF p_target_rec.measure_short_name = 'HRRCSHEAD' THEN
2793      l_actual := hrrcs_actual(l_actual_rec,'HEAD');
2794   END IF;
2795 
2796   --
2797   -- Send a notification if the actual success rate is below the
2798   -- the target success rate.
2799   -- If a value of -1 has been returned
2800   -- then abort processing as an error has occurred.
2801   --
2802   IF l_actual = -1 THEN
2803     null;
2804   ELSE
2805     IF p_target_rec.notify_resp1_id IS NOT NULL THEN
2806       IF validate_resp_org_security
2807            (p_target_rec.notify_resp1_id
2808            ,p_target_rec.notify_resp1_appl_id
2809            ,to_number(p_target_rec.org_level_value_id)) THEN
2810         l_mod_target := p_target_rec.target - percent(p_target_rec.target,p_target_rec.range1_low);
2811         pl(' Processing responsibility 1: ',p_target_rec.notify_resp1_short_name);
2812         pl(' Modified target: ',l_mod_target);
2813         pl(' Actual: ',l_actual);
2814         IF l_actual < l_mod_target THEN
2815           send_notification_hrrcs(1
2816                                  ,l_mod_target
2817                                  ,l_actual
2818                                  ,p_target_rec);
2819         END IF;  -- actual < target
2820       END IF;  -- valid resp1_id security
2821     END IF;  --notify_resp1_id not null
2822     --
2823     IF p_target_rec.notify_resp2_id IS NOT NULL THEN
2824       IF validate_resp_org_security
2825            (p_target_rec.notify_resp2_id
2826            ,p_target_rec.notify_resp2_appl_id
2827            ,to_number(p_target_rec.org_level_value_id)) THEN
2828         l_mod_target := p_target_rec.target - percent(p_target_rec.target,p_target_rec.range2_low);
2829         pl(' Processing responsibility 2: ',p_target_rec.notify_resp2_short_name);
2830         pl(' Modified target: ',l_mod_target);
2831         pl(' Actual: ',l_actual);
2832         IF l_actual < l_mod_target THEN
2833         send_notification_hrrcs(2
2834                                ,l_mod_target
2835                                ,l_actual
2836                                ,p_target_rec);
2837         END IF;  -- actual < target
2838       END IF;  -- valid resp2_id security
2839     END IF;  --notify_resp2_id not null
2840     --
2841     IF p_target_rec.notify_resp3_id IS NOT NULL THEN
2842       IF validate_resp_org_security
2843            (p_target_rec.notify_resp3_id
2844            ,p_target_rec.notify_resp3_appl_id
2845            ,to_number(p_target_rec.org_level_value_id)) THEN
2846         l_mod_target := p_target_rec.target - percent(p_target_rec.target,p_target_rec.range3_low);
2847         pl(' Processing responsibility 3: ',p_target_rec.notify_resp3_short_name);
2848         pl(' Modified target: ',l_mod_target);
2849         pl(' Actual: ',l_actual);
2850         IF l_actual < l_mod_target THEN
2851         send_notification_hrrcs(3
2852                                ,l_mod_target
2853                                ,l_actual
2854                                ,p_target_rec);
2855         END IF;  -- actual < target
2856       END IF;  -- valid resp3_id security
2857     END IF;  --notify_resp3_id not null
2858   END IF;  -- actual = -1
2859 
2860   pl('*Process Recruitment Success Target','End');
2861 
2865 --
2862 END process_hrrcs;
2863 
2864 -- **********************************************************************
2866 --                       TRAINING SUCCESS
2867 --
2868 -- **********************************************************************
2869 
2870 -------------------------------------------------------------------------
2871 --
2872 --  Procedure: send_notification_HRTRS
2873 --
2874 -------------------------------------------------------------------------
2875 
2876 
2877 PROCEDURE send_notification_hrtrs
2878            (p_resp_no     IN NUMBER
2879            ,p_target      IN NUMBER
2880            ,p_actual      IN NUMBER
2881            ,p_target_rec  IN hri_target_rec_type)
2882  IS
2883 
2884  l_subject          fnd_new_messages.message_text%TYPE;
2885  l_message          VARCHAR2(2000);
2886  l_freq_code        VARCHAR2(4);
2887  l_periods          NUMBER;
2888  l_dummy            VARCHAR2(2000);
2889  l_start_date       date;
2890  l_return_status    VARCHAR2(2000);
2891  l_param            VARCHAR2(2000);
2892  l_error            VARCHAR2(2000);
2893 
2894  l_report_name      VARCHAR2(8) := 'HRTRNSUC';
2895 
2896  l_activity_version_name  	ota_activity_versions.version_name%TYPE;	-- name of training course (activity version)
2897  l_actual           VARCHAR2(80);                      -- Actual value (e.g. 25%)
2898  l_job_cat          hr_lookups.meaning%TYPE;           -- Job category
2899  l_job_name         per_jobs.name%TYPE;	               -- Job name
2900  l_loc_name         hr_locations.location_code%TYPE;   -- Location name
2901  l_org_name         per_organization_units.name%TYPE;  -- Organization name
2902  l_org_type         hr_lookups.meaning%TYPE;           --
2903  l_orgprc           hr_lookups.meaning%TYPE;           -- include subordinate indicator (yes/no)
2904  l_target			VARCHAR2(80);                      -- Target value (e.g. 75%)
2905  l_period_name      VARCHAR2(50);
2906 
2907  -- Session params
2908  l_security_group_id  per_business_groups.security_group_id%TYPE;
2909  l_business_group_id  hr_all_organization_units.business_group_id%TYPE;
2910  l_resp_id            fnd_responsibility.responsibility_id%TYPE;
2911  l_resp_short_name    bisfv_targets.notify_resp1_short_name%TYPE;
2912  l_resp_name          bisfv_targets.notify_resp1_name%TYPE;
2913  l_resp_appl_id       fnd_responsibility.application_id%TYPE;
2914 
2915 BEGIN
2916 
2917   pl('----------------------------------');
2918   pl('*SEND Training Success notification','Start');
2919   pl('----------------------------------');
2920   -----------------------------------------------------------------------
2921   -- Build the notification subject line and message text
2922   -----------------------------------------------------------------------
2923   --
2924   -- Get the following information that will be shown on the notification
2925   -- and populate the relevant tokens in the message HR_BIS_PMF_SUBJECT
2926   --
2927   -- 1. Get Session parameters for the report
2928   -- 2. Get Parameter Names:
2929   --    Organzation
2930   --    Location
2931   --    Job or Job Category
2932   --    Training Activity
2933   --    Period
2934   -- 3. build notification text
2935   -- 4. get the report frequency, number of periods and start date
2936   -- 5. build the report parameter string
2937   -- 6. start the workflow process
2938   --
2939   -- ---------------------------------------------------------------------
2940   -- 1. Get Session parameters for the report
2941   -- ---------------------------------------------------------------------
2942   get_resp_details(p_resp_no
2943                   ,p_target_rec
2944                   ,l_resp_id
2945                   ,l_resp_appl_id
2946                   ,l_resp_short_name
2947                   ,l_resp_name);
2948   l_business_group_id := get_org_business_group_id(p_target_rec.org_level_value_id);
2949   l_security_group_id := get_org_security_group_id(p_target_rec.org_level_value_id);
2950   -- ---------------------------------------------------------------------
2951   -- 2. Get the parameter names
2952   -- ---------------------------------------------------------------------
2953   --
2954   -- Organization
2955   --
2956   hr_reports.get_organization(p_target_rec.org_level_value_id,l_org_name,l_dummy);
2957   l_orgprc   := translate_orgprc(g_orgprc_const);
2958   pl(' org name: ',l_org_name);
2959   --
2960   -- Location
2961   --
2962   l_loc_name := translate_location(p_target_rec.dim1_level_value_id);
2963   pl(' loc name: ',l_loc_name);
2964   --
2965   -- Job / Job Category
2966   --
2967   IF p_target_rec.dim2_level_short_name = 'JOB' THEN
2968      l_job_name := hr_reports.get_job(p_target_rec.dim2_level_value_id);
2969      l_job_cat  := translate_all;
2970   ELSIF p_target_rec.dim2_level_short_name = 'JOB CATEGORY' THEN
2971      l_job_name := translate_all;
2972      l_job_cat  := hr_reports.get_lookup_meaning('JOB_CATEGORIES',p_target_rec.dim2_level_value_id);
2973   ELSIF p_target_rec.dim2_level_short_name = 'TOTAL JOBS' THEN
2974      l_job_name := translate_all;
2975      l_job_cat  := translate_all;
2976   END IF;
2977   pl(' job name: ',l_job_name);
2978   pl(' jobcat name: ',l_job_cat);
2979   --
2980   -- Training Activity Version
2981   --
2982   l_activity_version_name := get_activity_version_name(p_target_rec.dim3_level_value_id);
2986   --
2983   pl(' Train Act Ver name: ',l_activity_version_name);
2984   --
2985   -- Period Name
2987   l_period_name := to_char(p_target_rec.period_start_date,'DD-MON-YYYY')
2988                            ||' - '||to_char(p_target_rec.period_END_date,'DD-MON-YYYY');
2989   pl(' Period Name:',l_period_name);
2990   --
2991   -- Include % on target and actual values
2992   --
2993   l_actual := to_char(p_actual)||'%';
2994   l_target := to_char(p_target)||'%';
2995   -- ---------------------------------------------------------------------
2996   -- 2. Build the notification text
2997   -- ---------------------------------------------------------------------
2998   --
2999   -- Build subject message text
3000   --
3001   fnd_message.set_name('HRI','HR_BIS_PMF_HRTRS_SUBJECT');
3002   l_subject := fnd_message.get;
3003   --
3004   -- Build the body message text
3005   --
3006   -- If the target has the activity version (i.e. the name of the training course) set
3007   -- then we need to use the notification that does not include the link to the
3008   -- training report this is because the training report does not have the activity
3009   -- version as a parameter
3010   --
3011   IF p_target_rec.dim3_level_short_name = 'TOTAL ACTIVITY VERSIONS' THEN
3012      fnd_message.set_name('HRI','HR_BIS_PMF_HRTRS_MSG');
3013   ELSE
3014      fnd_message.set_name('HRI','HR_BIS_PMF_HRTRS_MSG_NO_URL');
3015   END IF;
3016   fnd_message.set_token('ORGANIZATION',l_org_name);
3017   fnd_message.set_token('LOCATION',l_loc_name);
3018   fnd_message.set_token('JOB',l_job_name);
3019   fnd_message.set_token('CATEGORY',l_job_cat);
3020   fnd_message.set_token('ACTIVITY',l_activity_version_name);
3021   fnd_message.set_token('PERIOD',l_period_name);
3022   fnd_message.set_token('TARGET',l_target);
3023   fnd_message.set_token('ACTUAL',l_actual);
3024   --fnd_message.set_token('ROLE',l_resp_name);
3025   l_message := fnd_message.get;
3026   pl(' Message:', l_message);
3027 
3028   -- ---------------------------------------------------------------------
3029   -- 4. build the report parameter string
3030   -- ---------------------------------------------------------------------
3031   -- Build the url that will be used to run the report from the
3032   -- notification.
3033   l_report_name := 'HRTRNSUC';
3034 
3035   get_report_date_params(p_target_rec.time_level_short_name
3036                         ,p_target_rec.period_start_date
3037                         ,l_freq_code
3038                         ,l_start_date);
3039 
3040   pl(' Frequency: ',l_freq_code);
3041   pl(' Start date: ',to_char(l_start_date,'DD-MON-YYYY'));
3042 
3043   l_param   :=  'org_id='   ||p_target_rec.org_level_value_id   ||'*'||
3044                 'orgprc='   ||g_orgprc_const                    ||'*'||
3045                 'bpl_id='   ||p_target_rec.plan_id              ||'*'||
3046                 'loc_id='   ||p_target_rec.dim1_level_value_id  ||'*'||
3047                 'frqncy='   ||l_freq_code                       ||'*'||
3048                 'startd='   ||to_char(l_start_date,'YYYY-MM-DD')||'*'||
3049                 'end_dt='   ||to_char(p_target_rec.period_end_date,'YYYY-MM-DD')||'*';
3050 
3051    IF p_target_rec.dim2_level_short_name = 'JOB' THEN
3052      l_param := l_param ||
3053                 'job_id='||p_target_rec.dim2_level_value_id||'*'||
3054                 'jobcat=__ALL__*';
3055    ELSIF p_target_rec.dim2_level_short_name = 'JOB CATEGORY' THEN
3056      l_param := l_param ||
3057                 'jobcat='||p_target_rec.dim2_level_value_id||'*'||
3058                 'job_id=-1*';
3059    ELSIF p_target_rec.dim2_level_short_name = 'TOTAL JOBS' THEN
3060      l_param := l_param ||
3061                 'jobcat=__ALL__*'||
3062                 'job_id=-1*';
3063    END IF;
3064 
3065    l_param := l_param ||
3066               c_ampersand||'responsibility_application_id='
3067                          ||to_char(l_resp_appl_id)||
3068               c_ampersand||'security_group_id='
3069                          ||l_security_group_id;
3070 
3071   pl('wf      ',p_target_rec.workflow_item_type);
3072   pl('process ',p_target_rec.workflow_process_short_name);
3073   pl('resp    ',l_resp_short_name);
3074   pl('resp id ',to_char(l_resp_id));
3075   pl('applic  ',to_char(l_resp_appl_id));
3076   pl('secgrp  ',l_security_group_id);
3077   pl('param   ',substr(l_param,1,240));
3078   pl('report  ',l_report_name);
3079   pl('message ',substr(l_message,1,240));
3080   pl('subject ',l_subject);
3081   -- ---------------------------------------------------------------------
3082   -- 5. start the workflow process
3083   -- ---------------------------------------------------------------------
3084   pl(' start workflow process');
3085   bis_util.strt_wf_process
3086 		(p_exception_message	=> l_message
3087 		,p_msg_subject		    => l_subject
3088 		,p_exception_date	    => sysdate
3089  	    ,p_item_type            => p_target_rec.workflow_item_type
3090 		,p_wf_process		    => p_target_rec.workflow_process_short_name
3091 		,p_notify_resp_name     => l_resp_short_name
3092 		,p_report_name1		    => l_report_name
3093 		,p_report_param1	    => l_param
3094         ,p_report_resp1_id     	=> l_resp_id
3095         ,x_return_status       	=> l_return_status);
3096 
3097   pl(' Resp id',to_char(l_resp_id));
3098 
3099   pl(' Workflow return status: ',l_return_status);
3100 
3101   IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
3102     RAISE e_g_bis_fn_error;
3103   END IF;
3104 
3108 
3105   pl('*SEND Training Success notification','End');
3106 
3107 END;
3109 -------------------------------------------------------------------------
3110 --
3111 --  CALCULATE ACTUAL TRAINING SUCCESS
3112 --
3113 -------------------------------------------------------------------------
3114 --
3115 -- This function will return the actual training success rate based on
3116 -- the dimensions held in the p_target_rec record. This record is either
3117 -- populated from infrmation contained in the target or when posting actuals
3118 -- it is populated from the performance measure section of the configurable
3119 -- home page. The actual training success rate is expressed as a percentage of
3120 -- successful training hours against total training hours
3121 --
3122 
3123 
3124 FUNCTION hrtrs_actual
3125            (p_actual_rec  IN bis_actual_pub.actual_rec_type)
3126  RETURN NUMBER
3127  IS
3128 
3129 l_actual              NUMBER;
3130 l_these_hours         NUMBER;
3131 l_total_delivered     NUMBER;
3132 l_total_success       NUMBER;
3133 
3134 l_period_start_date   DATE;
3135 l_period_end_date     DATE;
3136 
3137 l_business_group_id   NUMBER;
3138 
3139 l_formula_id          ff_formulas_f.formula_id%TYPE;
3140 
3141 -- get the training duration for each attendance to a scheduled event
3142 -- that start date lies between the period start and end date
3143 --
3144 -- This Cursor has been changed due to bug 1718083 to be exactly the same
3145 -- as the Workforce Total report. JRHYDE
3146 --
3147 CURSOR train_dur_cur(p_c_actual_rec         bis_actual_pub.actual_rec_type
3148                     ,p_c_period_start_date  DATE
3149                     ,p_c_period_end_date    DATE)
3150   IS
3151  SELECT asg.assignment_id
3152       , asg.organization_id
3153       , evt.duration
3154       , evt.duration_units
3155       , ver.version_name
3156       , evt.title
3157       , dbk.successful_attendance_flag
3158    FROM per_assignments_f        asg
3159       , ota_booking_status_types bst
3160       , ota_activity_versions    ver
3161       , ota_events               evt
3162       , ota_delegate_bookings    dbk
3163   WHERE dbk.delegate_assignment_id = asg.assignment_id
3164     AND evt.course_start_date BETWEEN
3165            asg.effective_start_date AND asg.effective_end_date
3166     AND dbk.booking_status_type_id = bst.booking_status_type_id
3167     AND bst.type = 'A'  -- Attended
3168     AND dbk.event_id = evt.event_id
3169     AND asg.assignment_type = 'E'
3170     AND evt.event_type = 'SCHEDULED'
3171     AND evt.activity_version_id = ver.activity_version_id
3172     AND nvl(evt.event_status, 'X') <> 'C' /*Not Cancelled*/
3173     /* Time Dim */
3174     AND evt.course_end_date < trunc(sysdate)
3175     AND evt.course_end_date BETWEEN
3176           p_c_period_start_date AND
3177           p_c_period_end_date
3178     /* Org Dim*/
3179     AND asg.organization_id = p_c_actual_rec.org_level_value_id
3180     /* Dim 1  Location*/
3181     AND (  (p_c_actual_rec.dim1_level_value_name = 'LOCATION'
3182         AND asg.location_id = p_c_actual_rec.dim1_level_value_id)
3183       OR   (p_c_actual_rec.dim1_level_value_name = 'TOTAL GEOGRAPHY')
3184         )
3185     /* Dim 2 Job or Job Category*/
3186     AND (  (p_c_actual_rec.dim2_level_value_name = 'TOTAL JOBS')
3187        OR  (p_c_actual_rec.dim2_level_value_name = 'JOB CATEGORY'
3188         AND asg.job_id IN (SELECT jei.job_id
3189                              FROM per_job_extra_info jei
3190                             WHERE jei.jei_information1 = p_c_actual_rec.dim2_level_value_id))
3191       OR   (p_c_actual_rec.dim2_level_value_name = 'JOB'
3192        AND  asg.job_id = p_c_actual_rec.dim2_level_value_id)
3193         )
3194     /* Dim 3 Activity Version */
3195     AND (  (p_c_actual_rec.dim3_level_value_name = 'ACTIVITY VERSION'
3196         AND evt.activity_version_id = p_c_actual_rec.dim3_level_value_id)
3197       OR   (p_c_actual_rec.dim3_level_value_name = 'TOTAL ACTIVITY VERSIONS')
3198         );
3199 
3200 BEGIN
3201 
3202   pl('*HRTRS actual','Start');
3203 
3204   -- Initialise the hours counters
3205   l_total_delivered := 0;
3206   l_total_success   := 0;
3207 
3208   l_business_group_id := get_org_business_group_id(to_number(p_actual_rec.org_level_value_id));
3209 
3210   l_formula_id        := get_formula_id(l_business_group_id
3211                                       ,'BIS_TRAINING_CONVERT_DURATION');
3212   pl(' Formula id: ',to_char(l_formula_id));
3213 
3214   --Get start and end dates from the time dim
3215   get_dates_from_time_dim
3216     (p_actual_rec.time_level_value_id
3217     ,l_period_start_date
3218     ,l_period_end_date);
3219 
3220 
3221   --
3222   -- Loop through all training duration rows
3223   --
3224   FOR evt_dur_rec IN train_dur_cur(p_actual_rec
3225                                   ,l_period_start_date
3226                                   ,l_period_end_date)
3227     LOOP
3228     pl(' Asg id: ',to_char(evt_dur_rec.assignment_id));
3229     pl(' Duration: ', to_char(evt_dur_rec.duration));
3230     pl(' Duration Units: ', evt_dur_rec.duration_units);
3231     -- Run FF to convert duration to hours
3232     l_these_hours := HrFastAnswers.TrainingConvertDuration
3233                       (l_formula_id
3234                       ,evt_dur_rec.duration
3235                       ,evt_dur_rec.duration_units
3236                       ,'H'
3237                       ,evt_dur_rec.version_name
3241     -- the total isn't corrupted
3238                       ,evt_dur_rec.title
3239                       ,sysdate);
3240     -- Ensure that if the fast formula returns null
3242     IF l_these_hours IS NOT NULL THEN
3243       l_total_delivered := l_total_delivered + l_these_hours;
3244       pl(' Successful Attendance: ', evt_dur_rec.successful_attendance_flag);
3245       IF evt_dur_rec.successful_attendance_flag = 'Y' THEN
3246         l_total_success := l_total_success + l_these_hours;
3247       END IF;
3248     END IF;
3249   END LOOP;
3250 
3251   pl('Total delivered: ',to_char(l_total_delivered));
3252   pl('Total success: ',to_char(l_total_success));
3253   --
3254   -- Calculate the success rate and return value
3255   --
3256   IF l_total_delivered = 0 THEN
3257     l_actual := NULL;
3258   ELSIF l_total_success = 0 THEN
3259     l_actual := 0;
3260   ELSE
3261     l_actual := round(( l_total_success / l_total_delivered  ) * 100,1);
3262   END IF;
3263 
3264   pl('Actual : ',to_char(l_actual));
3265   pl('*HRTRS actual','End');
3266   RETURN l_actual;
3267 
3268 END;
3269 
3270 -------------------------------------------------------------------------
3271 --
3272 -- PROCESS TRAINING SUCCESS TARGETS
3273 --
3274 -------------------------------------------------------------------------
3275 
3276 PROCEDURE process_hrtrs
3277            (p_target_rec  IN hri_target_rec_type)
3278  IS
3279 
3280 l_actual                NUMBER;
3281 l_mod_target            NUMBER;
3282 l_org_struct_version_id per_org_structure_versions.org_structure_version_id%TYPE;
3283 
3284 l_actual_rec            bis_actual_pub.actual_rec_type;
3285 
3286 BEGIN
3287 
3288   pl('*Processing Training Success Target','Start');
3289 
3290   -- hrFastAnswers.LoadOrgHierarchy(p_target_rec.org_level_value_id,l_org_struct_version_id);
3291 
3292   -- Convert the data from target record format into an actual record format
3293   l_actual_rec := get_bis_actual_rec(p_target_rec);
3294 
3295   l_actual := hrtrs_actual(l_actual_rec);
3296 
3297   --
3298   -- Send a notification if the actual success rate is below the
3299   -- the target success rate. If a value of -1 has been returned
3300   -- then abort processing as an error has occurred.
3301   --
3302 
3303   IF l_actual = -1 THEN
3304     null;
3305   ELSE
3306     IF p_target_rec.notify_resp1_id IS NOT NULL THEN
3307       IF validate_resp_org_security
3308          (p_target_rec.notify_resp1_id
3309          ,p_target_rec.notify_resp1_appl_id
3310          ,to_number(p_target_rec.org_level_value_id)) THEN
3311         l_mod_target := p_target_rec.target - percent(p_target_rec.target,p_target_rec.range1_low);
3312         pl(' Processing responsibility 1: ',p_target_rec.notify_resp1_short_name);
3313         pl(' Modified target: ',l_mod_target);
3314         pl(' Actual: ',l_actual);
3315         IF l_actual < l_mod_target THEN
3316           send_notification_hrtrs(1
3317                                  ,l_mod_target
3318                                  ,l_actual
3319                                  ,p_target_rec);
3320         END IF;  -- actual < target
3321       END IF;  -- valid resp1_id security
3322     END IF;  --notify_resp1_id not null
3323     --
3324     IF p_target_rec.notify_resp2_id IS NOT NULL THEN
3325       IF validate_resp_org_security
3326          (p_target_rec.notify_resp2_id
3327          ,p_target_rec.notify_resp2_appl_id
3328          ,to_number(p_target_rec.org_level_value_id)) THEN
3329         l_mod_target := p_target_rec.target - percent(p_target_rec.target,p_target_rec.range2_low);
3330         pl(' Processing responsibility 2: ',p_target_rec.notify_resp2_short_name);
3331         pl(' Modified target: ',l_mod_target);
3332         pl(' Actual: ',l_actual);
3333         IF l_actual < l_mod_target THEN
3334           send_notification_hrtrs(2
3335                                  ,l_mod_target
3336                                  ,l_actual
3337                                  ,p_target_rec);
3338         END IF;  -- actual < target
3339       END IF;  -- valid resp2_id security
3340     END IF;  --notify_resp2_id not null
3341     --
3342     IF p_target_rec.notify_resp3_id IS NOT NULL THEN
3343       IF validate_resp_org_security
3344          (p_target_rec.notify_resp3_id
3345          ,p_target_rec.notify_resp3_appl_id
3346          ,to_number(p_target_rec.org_level_value_id)) THEN
3347         l_mod_target := p_target_rec.target - percent(p_target_rec.target,p_target_rec.range1_low);
3348         pl(' Processing responsibility 3: ',p_target_rec.notify_resp3_short_name);
3349         pl(' Modified target: ',l_mod_target);
3350         pl(' Actual: ',l_actual);
3351         IF l_actual < l_mod_target THEN
3352           send_notification_hrtrs(3
3353                                  ,l_mod_target
3354                                  ,l_actual
3355                                  ,p_target_rec);
3356         END IF;  -- actual < target
3357       END IF;  -- valid resp3_id security
3358     END IF;  --notify_resp3_id not null
3359   END IF; -- actual = -1
3360 
3361   pl('*Processing Training Success Target','End');
3362 
3363 END;
3364 -------------------------------------------------------------------------
3365 -- *********************************************************************
3369 --                        END OF PMF DEFINITIONS
3366 -------------------------------------------------------------------------
3367 -- *********************************************************************
3368 --
3370 --
3371 -- *********************************************************************
3372 -------------------------------------------------------------------------
3373 -- *********************************************************************
3374 -------------------------------------------------------------------------
3375 
3376 -------------------------------------------------------------------------
3377 --  Procedure:    Post_target_level_actuals
3378 --
3379 --  Parameters:   Target_rec - Target Record containing all required
3380 --                information pertaining to the original target param
3381 --
3382 --  Description
3383 --                This procedure loops through all the user selections
3384 --                i.e. the required actuals, and calculates the
3385 --                corresponding actuals for each and posts to the actuals
3386 --                table (using post_actuals).
3387 --
3388 -------------------------------------------------------------------------
3389 PROCEDURE post_target_level_actuals
3390            (p_target_rec  IN hri_target_rec_type)
3391   IS
3392 
3393   --Table of records containing the users indicator selections
3394   -- i.e. what the users want to see on their home page
3395   l_user_selection_tbl       bis_INDICATOR_REGION_PUB.indicator_Region_Tbl_Type;
3396 
3397   --Needed to pass target_level_short_name into the bis record
3398   --bis_actual_pub.retrieve_user_selections
3399   l_target_level_rec         bis_TARGET_LEVEL_PUB.Target_Level_Rec_Type;
3400 
3401   -- Needed to pass specification to post_actuals
3402   l_actual_rec               bis_ACTUAL_PUB.Actual_Rec_Type;
3403 
3404   l_return_status            VARCHAR2(1);
3405   l_msg_count                NUMBER;
3406   l_msg_data                 VARCHAR2(250);
3407   l_error_tbl                bis_UTILITIES_PUB.Error_Tbl_Type;
3408   i                          NUMBER := 0;
3409   l_actual                   NUMBER(38,2);
3410 
3411   l_security_group_id  per_business_groups.security_group_id%TYPE;
3412 
3413 BEGIN
3414   pl('--------------------');
3415   pl('*POST TARGET LEVEL ACTUALS','Start');
3416   --
3417   -- Get all the user selections (these are the performance measures that the user
3418   -- has setup on their home page). We only get the ones for the current target level
3419   -- this means that to dISplay actuals on the home page providing they have targets
3420   -- set up.
3421   --
3422   pl('Retreive User Selections');
3423   l_target_level_rec.target_Level_Short_Name  := p_target_rec.target_level_short_name;
3424   pl(' target_level_short_name',p_target_rec.target_level_short_name);
3425 
3426   bis_actual_pub.Retrieve_User_Selections
3427     ( p_api_version                  => 1.0
3428      ,p_Target_Level_Rec             => l_Target_Level_Rec
3429      ,x_indicator_Region_Tbl         => l_user_selection_Tbl
3430      ,x_return_status                => l_return_status
3431      ,x_msg_count                    => l_msg_count
3432      ,x_msg_data                     => l_msg_data
3433      ,x_error_Tbl                    => l_error_tbl
3434     );
3435   pl('return status: ',l_return_status);
3436 
3437   IF l_return_status = fnd_api.g_ret_sts_unexp_error THEN
3438     -- One reason for excpetion may be that 0 rows are returned
3439     -- hence the use of an exception to stop this bombing the
3440     -- whole process and not calcing the targets
3441     RAISE e_g_bis_fn_error;
3442   END IF;
3443 
3444   -- Preparring the actual record
3445   -- Using p_target_rec VALUES for l_target_rec to stop any un necessary
3446   -- re querying of this target level data that is correct for the target.
3447   -- Don't use l_user_selection_tbl.dimx_Level_Value_Name to supply
3448   -- dimensionx_level_short_name because:
3449   -- The base table bis_user_ind_selections doesn't contain the short_names
3450   -- and bis_actual_pub.retrieve_user_selections which calls
3451   -- bis_indicator_region_pvt.rectrieve_user_ind_selections - doesn't
3452   -- actually query this from bis_target_levels and put it in the
3453   -- l_user_selection_tbl!! So have to query these ourselves.
3454   -- Using the p_target_rec becuase this data is target level info
3455   -- which is common to all user selections
3456   l_actual_rec.time_level_value_id       := p_target_rec.time_level_value_id;
3457   l_actual_rec.org_level_value_name      := p_target_rec.org_level_short_name;
3458   l_actual_rec.dim1_level_value_name     := p_target_rec.dim1_level_short_name;
3459   l_actual_rec.dim2_level_value_name     := p_target_rec.dim2_level_short_name;
3460   l_actual_rec.dim3_level_value_name     := p_target_rec.dim3_level_short_name;
3461   l_actual_rec.dim4_level_value_name     := p_target_rec.dim4_level_short_name;
3462   l_actual_rec.dim5_level_value_name     := p_target_rec.dim5_level_short_name;
3463 
3464   pl('Count of user selections ', to_char(l_user_selection_Tbl.COUNT));
3465 
3466   -- Loop through all user selections (for this target level)
3467   -- calculating and publishing the actuals for each
3468   FOR i IN 1..l_user_selection_Tbl.count LOOP
3469 
3470     l_actual_rec.target_level_id           := l_user_selection_tbl(i).target_level_id;
3471     l_actual_rec.target_level_short_name   := l_user_selection_tbl(i).target_level_short_name;
3472     l_actual_rec.Responsibility_id         := l_user_selection_tbl(i).Responsibility_id;
3476     l_actual_rec.org_level_value_id        := l_user_selection_tbl(i).org_level_value_id;
3473     l_actual_rec.Responsibility_short_name := l_user_selection_tbl(i).Responsibility_short_name;
3474     l_actual_rec.Responsibility_name       := l_user_selection_tbl(i).Responsibility_name;
3475     l_actual_rec.target_level_id           := l_user_selection_tbl(i).target_level_id;
3477     l_actual_rec.dim1_level_value_id       := l_user_selection_tbl(i).dim1_level_value_id;
3478     l_actual_rec.dim2_level_value_id       := l_user_selection_tbl(i).dim2_level_value_id;
3479     l_actual_rec.dim3_level_value_id       := l_user_selection_tbl(i).dim3_level_value_id;
3480     l_actual_rec.dim4_level_value_id       := l_user_selection_tbl(i).dim4_level_value_id;
3481     l_actual_rec.dim5_level_value_id       := l_user_selection_tbl(i).dim5_level_value_id;
3482 
3483     --l_actual_rec.Responsibility_ID         := p_target_rec.notify_resp1_id;
3484     --l_actual_rec.Responsibility_Short_Name := p_target_rec.notify_resp1_short_name;
3485     --l_actual_rec.Responsibility_Name       := p_target_rec.notify_resp1_name;
3486 
3487     --debug_bis_actual_rec(l_actual_rec);
3488 
3489     -- Transfer control to the appropriate module which will calculate
3490     -- and post the actual values to the users home page.
3491     --
3492     -- Note: The function retrieve_user_ind_selections does not RETURN
3493     -- the responsibility AND we are therefore unable to verIFy that
3494     -- the user is authorized to access information on the given
3495     -- organization. Core bis have been requested to provide the
3496     -- responsibility.
3497     --
3498 
3499     pl('Target Measure Short Name =',p_target_rec.measure_short_name);
3500 
3501     IF p_target_rec.measure_short_name = 'HRMSPFTE' THEN
3502        l_actual_rec.actual := hrmsp_actual(l_actual_rec,'FTE');
3503        post_actual(l_actual_rec);
3504     ELSIF p_target_rec.measure_short_name = 'HRMSPHEAD' THEN
3505        l_actual_rec.actual := hrmsp_actual(l_actual_rec,'HEAD');
3506        post_actual(l_actual_rec);
3507     ELSIF p_target_rec.measure_short_name = 'HRMVRFTE' THEN
3508        l_actual_rec.actual := hrmvr_actual(l_actual_rec,'FTE');
3509        post_actual(l_actual_rec);
3510     ELSIF p_target_rec.measure_short_name = 'HRMVRHEAD' THEN
3511        l_actual_rec.actual := hrmvr_actual(l_actual_rec,'HEAD');
3512        post_actual(l_actual_rec);
3513     ELSIF p_target_rec.measure_short_name = 'HRRCSFTE' THEN
3514        l_actual_rec.actual := hrrcs_actual(l_actual_rec,'FTE');
3515        post_actual(l_actual_rec);
3516     ELSIF p_target_rec.measure_short_name = 'HRRCSHEAD' THEN
3517        l_actual_rec.actual := hrrcs_actual(l_actual_rec,'HEAD');
3518        post_actual(l_actual_rec);
3519     ELSIF p_target_rec.measure_short_name = 'HRTRS' THEN
3520        l_actual_rec.actual := hrtrs_actual(l_actual_rec);
3521        post_actual(l_actual_rec);
3522     END IF;
3523 
3524   END LOOP;
3525 
3526   pl('*POST TARGET LEVEL ACTUALS','End');
3527   pl('--------------------');
3528 EXCEPTION
3529 -- Need to continue if this exceptions so the process can continue
3530 -- with processing the targets
3531  WHEN OTHERS THEN
3532   NULL;
3533 
3534 END post_target_level_actuals;
3535 
3536 --***********************************************************************
3537 --
3538 --    PUBLIC FUNCTIONS AND PROCEDURE
3539 --
3540 --***********************************************************************
3541 
3542 ------------------------------------------------------------------------------------------------
3543 --
3544 --  Procedure:    Calc_and_post_target_actuals
3545 --
3546 --  Parameters:   Target id
3547 --
3548 --  Description:  This procedure is design as a method of debugging the actual posting methods.
3549 --                Calculates the actuals for the target specified without first calculating the
3550 --                targets.
3551 --
3552 ------------------------------------------------------------------------------------------------
3553 PROCEDURE calc_and_post_target_actuals
3554            (p_target_id IN NUMBER
3555            ,p_date      IN DATE DEFAULT SYSDATE)
3556   IS
3557 
3558   l_target_rec  hri_target_rec_type;
3559   l_session_rec hri_session_rec_type;
3560 
3561 BEGIN
3562   pl('*Calc and Post Target Actuals', 'Start');
3563   pl('Target id',to_char(p_target_id));
3564   l_session_rec := get_session;
3565   debug_session(l_session_rec);
3566 
3567   l_target_rec  := get_target_rec(p_target_id);
3568   post_target_level_actuals(l_target_rec);
3569 
3570 END calc_and_post_target_actuals;
3571 ------------------------------------------------------------------------------------------------
3572 --
3573 --  Procedure:    PROCESS_PMF_ALERT
3574 --
3575 --  Parameters:   Target id
3576 --
3577 --  Description
3578 --                This procedure is the common entry point for all HR target values. It IS
3579 --                called by the HR alerts for each target value selected for processing (refer
3580 --                to the HR alerts for more details of the selection procedure). The procedure
3581 --                will retreive details of the target AND pass control to the relevant routine.
3582 --
3583 --                The performance measures currently supported are:
3584 --
3585 --                MSP = Manpower separation
3586 --                MVR = Manpower variance
3587 --                TRS = Training success
3588 --                RCS = Recruitment success
3589 --
3590 --
3591 --  Note
3592 --                To verify that the actual has been posted check in:
3593 --                   BIS.BIS_ACTUAL_VALUES
3594 --                To verify that the notification has been posted check in:
3595 --                   APPLSYS.WF
3596 ------------------------------------------------------------------------------------------------
3597 
3598 PROCEDURE process_target
3599            (p_target_id IN NUMBER)
3600   IS
3601 
3602 l_subject	VARCHAR2(80);
3603 l_message	VARCHAR2(2000);
3604 l_date		date;
3605 l_param		VARCHAR2(2000);
3606 
3607 l_target_rec  hri_target_rec_type;
3608 l_session_rec hri_session_rec_type;
3609 
3610 e_fatal_error       exception;
3611 e_pm_not_found 		exception;
3612 e_pm_not_known		exception;
3613 e_tl_not_found  	exception;
3614 e_tv_not_found  	exception;
3615 e_pd_not_found  	exception;
3616 
3617 BEGIN
3618 
3619   pl('*PROCESS TARGET ','Start');
3620   pl(' TARGET = ',to_char(p_target_id));
3621 
3622   --get the session, record to package globals and output details to debug
3623   g_session_rec := get_session;
3624   debug_session(g_session_rec);
3625 
3626   ----------------------------------------------------------------------------------
3627   -- Get the target's details
3628   ----------------------------------------------------------------------------------
3629   l_target_rec := Get_Target_Rec(p_target_id);
3630 
3631   debug_hri_target_rec(l_target_rec);
3632 
3633   ---------------------------------------------------------------------------------
3634   -- Rerieve user selections and calculate the respective actuals
3635   -- This is prior to the target calculations as a precution
3636   --  because in the target calculations the apps globals may be changed
3637   --  causing issues with inserting actuals see bug 1413300
3638   ----------------------------------------------------------------------------------
3639   post_target_level_actuals(l_target_rec);
3640 
3641   -- Check if any of the responsibilities exist
3642   -- Otherwise skip the target processing and exit
3643   IF (l_target_rec.notify_resp1_id IS NOT NULL
3644      OR
3645     l_target_rec.notify_resp2_id IS NOT NULL
3646      OR
3647     l_target_rec.notify_resp3_id IS NOT NULL
3648     ) THEN
3649 
3650     pl('Checking responsibilities of targets');
3651     ----------------------------------------------------------------------------------
3652     -- Transfer control to the correct module
3653     ----------------------------------------------------------------------------------
3654     -- PROCESS_HRMSP Manpower separation
3655     -- PROCESS_HRMVR Manpower variance
3656     -- PROCESS_HRRCS Recruitment success
3657     -- PROCESS_HRTRS Training success
3658     IF l_target_rec.measure_short_name IN ('HRMSPFTE','HRMSPHEAD') THEN
3659         process_hrmsp(l_target_rec);
3660     ELSIF l_target_rec.measure_short_name IN ('HRMVRFTE','HRMVRHEAD') THEN
3661         process_hrmvr(l_target_rec);
3662     ELSIF l_target_rec.measure_short_name IN ('HRRCSFTE','HRRCSHEAD') THEN
3663         process_hrrcs(l_target_rec);
3664     ELSIF l_target_rec.measure_short_name = 'HRTRS' THEN
3665         process_hrtrs(l_target_rec);
3666     END IF;
3667   END IF; -- A target resp exists
3668 
3669   pl('*PROCESS TARGET ','END');
3670 /*
3671 EXCEPTION
3672  WHEN OTHERS THEN
3673   g_error_msg := substr(sqlerrm,1,2000);
3674   RAISE;
3675 */
3676 END process_target;
3677 
3678 END;