1 PACKAGE BODY hri_oltp_disc_training AS
2 /* $Header: hriodtrn.pkb 120.0 2005/05/29 07:29:32 appldev noship $ */
3
4 ---------------------------
5 -- Package global variables
6 ---------------------------
7 g_bg_currency_code per_business_groups.currency_code%type;
8 g_business_group_id per_business_groups.business_group_id%type;
9 g_precision fnd_currencies.precision%type;
10 g_rate_type varchar2(30);
11 g_training_formula_id ff_formulas_f.formula_id%type;
12
13
14 /******************************************************************************/
15 /* Procedure to set package global variables for Training Analysis */
16 /******************************************************************************/
17 PROCEDURE set_training_globals(p_event_id IN NUMBER) IS
18
19 CURSOR bg_csr is
20 SELECT business_group_id
21 FROM ota_events
22 WHERE event_id = p_event_id;
23
24 CURSOR bg_currency_csr is
25 SELECT bg.currency_code, NVL(c.precision,2)
26 FROM fnd_currencies c
27 ,per_business_groups bg
28 WHERE bg.currency_code = c.currency_code
29 AND bg.business_group_id = g_business_group_id;
30
31 BEGIN
32
33 IF p_event_id IS NOT NULL THEN
34
35 -- Get Business Group Id
36 OPEN bg_csr;
37 FETCH bg_csr INTO g_business_group_id;
38 CLOSE bg_csr;
39
40 -- Get currency of business group
41 OPEN bg_currency_csr;
42 FETCH bg_currency_csr INTO g_bg_currency_code, g_precision;
43 CLOSE bg_currency_csr;
44
45 -- Determine Rate Type for BIS
46 g_rate_type := hr_currency_pkg.get_rate_type(
47 p_business_group_id => g_business_group_id
48 ,p_conversion_date => sysdate
49 ,p_processing_type => 'I');
50
51 -- Determine Formula Id of the Training Convert Duration FastFormula
52 g_training_formula_id := hr_disc_calculations.get_formula_id(
53 p_business_group_id => g_business_group_id
54 ,p_formula_name => 'BIS_TRAINING_CONVERT_DURATION');
55
56 END IF;
57
58 END set_training_globals;
59
60
61 /******************************************************************************/
62 /* Private function to pro-rate an amount held against a Programme training */
63 /* event across the members of the Programme */
64 /******************************************************************************/
65 FUNCTION pro_rata_amount(p_event_id IN NUMBER
66 ,p_program_event_id IN NUMBER
67 ,p_programme_amount IN NUMBER
68 ,p_currency_code IN VARCHAR2)
69 RETURN NUMBER IS
70
71 CURSOR program_member_csr( p_program_event_id NUMBER ) is
72 SELECT
73 evt.event_id
74 ,evt.duration
75 ,evt.duration_units
76 ,evt.title
77 ,tav.version_name
78 FROM
79 ota_activity_versions tav
80 ,ota_events evt
81 ,ota_program_memberships pm
82 WHERE evt.activity_version_id = tav.activity_version_id
83 AND evt.event_id = pm.event_id
84 AND pm.program_event_id = p_program_event_id;
85
86 program_member_rec program_member_csr%rowtype;
87
88 l_activity_version_name ota_activity_versions.version_name%type;
89 l_duration ota_events.duration%type := 0;
90 l_event_duration ota_events.duration%type := 0;
91 l_event_name ota_events.title%type;
92 l_pro_rata_amount number := 0;
93 l_pro_rata_total number := 0;
94 l_total_duration number := 0;
95
96 BEGIN
97
98 ------------------------------------
99 -- Have all parameters been passed ?
100 ------------------------------------
101 IF (p_event_id IS NULL) OR (p_program_event_id IS NULL) OR
102 (p_programme_amount IS NULL) OR (p_currency_code IS NULL) THEN
103 RETURN(0);
104 END IF;
105
106 -------------------------------------------------------------
107 -- Loop round all the events which are members of the program
108 -------------------------------------------------------------
109 FOR program_member_rec IN program_member_csr( p_program_event_id ) LOOP
110
111 IF program_member_rec.duration_units = 'H' THEN
112 l_duration := program_member_rec.duration;
113 ELSE
114
115 ----------------------------------
116 -- Convert event duration to hours
117 ----------------------------------
118 l_duration := hr_disc_calculations.training_convert_duration(
119 p_formula_id => g_training_formula_id
120 ,p_FROM_duration => program_member_rec.duration
121 ,p_FROM_duration_units => program_member_rec.duration_units
122 ,p_to_duration_units => 'H'
123 ,p_activity_version_name => program_member_rec.version_name
124 ,p_event_name => program_member_rec.title
125 ,p_session_date => sysdate);
126
127 IF program_member_rec.event_id = p_event_id then
128 l_event_duration := l_duration;
129 END IF;
130
131 END IF;
132
133 l_total_duration := l_total_duration + nvl(l_duration,0);
134
135 END loop;
136
137 -----------------------------------
138 -- Perform the pro-rata calculation
139 -----------------------------------
140 l_pro_rata_amount := l_event_duration * p_programme_amount / l_total_duration;
141
142 --------------------------------------------------------------------
143 -- Convert to currency of BG AND update total for all program events
144 --------------------------------------------------------------------
145 l_pro_rata_amount := hri_bpl_currency.convert_currency_amount(
146 p_from_currency => p_currency_code
147 ,p_to_currency => g_bg_currency_code
148 ,p_conversion_date => SYSDATE
149 ,p_amount => l_pro_rata_amount
150 ,p_rate_type => g_rate_type);
151
152 l_pro_rata_total := l_pro_rata_total + l_pro_rata_amount;
153
154 RETURN(l_pro_rata_total);
155
156 EXCEPTION
157 WHEN OTHERS THEN
158
159 RETURN(0);
160
161 END pro_rata_amount;
162
163
164 /******************************************************************************/
165 /* Public function to calculate the Budget Cost of a training event */
166 /******************************************************************************/
167 FUNCTION get_event_budget_cost(p_event_id IN NUMBER)
168 RETURN NUMBER IS
169
170 CURSOR budget_cost_csr(p_csr_event_id NUMBER) IS
171 SELECT
172 nvl(budget_cost,0) budget_cost
173 ,budget_currency_code
174 ,business_group_id
175 FROM ota_events
176 WHERE event_id = p_csr_event_id;
177
178 l_business_group_id ota_events.business_group_id%type;
179
180 CURSOR program_event_csr is
181 SELECT program_event_id
182 FROM ota_program_memberships
183 WHERE event_id = p_event_id;
184
185 program_event_rec program_event_csr%rowtype;
186 l_budget_cost ota_events.budget_cost%type := 0;
187 l_budget_currency_code ota_events.budget_currency_code%type;
188 l_converted_amount ota_events.budget_cost%type := 0;
189 l_pro_rata_amount NUMBER := 0;
190 l_total_budget_cost NUMBER := 0;
191 l_pro_rata_total NUMBER := 0;
192
193 BEGIN
194
195 IF p_event_id IS NULL THEN
196 RETURN(0);
197 END IF;
198
199 -- Get Budget Cost of the event
200 OPEN budget_cost_csr( p_event_id );
201 FETCH budget_cost_csr INTO
202 l_budget_cost, l_budget_currency_code, l_business_group_id;
203 CLOSE budget_cost_csr;
204
205 IF l_business_group_id IS NOT NULL THEN
206
207 -- Set package global variables
208 set_training_globals(p_event_id => p_event_id);
209
210 -- Convert Budget Cost to business group currency
211 l_converted_amount := hri_bpl_currency.convert_currency_amount(
212 p_from_currency => l_budget_currency_code
213 ,p_to_currency => g_bg_currency_code
214 ,p_conversion_date => SYSDATE
215 ,p_amount => l_budget_cost
216 ,p_rate_type => g_rate_type);
217
218 END IF;
219
220 -- Is the event a member of a programme(s) ?
221 FOR program_event_rec IN program_event_csr LOOP
222
223 -- Get Budget Cost of the programme event
224 OPEN budget_cost_csr( program_event_rec.program_event_id );
225 FETCH budget_cost_csr INTO
226 l_budget_cost, l_budget_currency_code, l_business_group_id;
227 CLOSE budget_cost_csr;
228
229 -- Pro-rate programme amount if necessary
230 IF l_budget_cost <> 0 THEN
231
232 l_pro_rata_amount := pro_rata_amount(
233 p_event_id => p_event_id
234 ,p_program_event_id => program_event_rec.program_event_id
235 ,p_programme_amount => l_budget_cost
236 ,p_currency_code => l_budget_currency_code);
237
238 END IF;
239
240 l_pro_rata_total := l_pro_rata_total + l_pro_rata_amount;
241
242 END LOOP;
243
244 l_total_budget_cost := l_converted_amount + l_pro_rata_total;
245
246 RETURN (ROUND(l_total_budget_cost, g_precision));
247
248 EXCEPTION
249 WHEN OTHERS THEN
250
251 RETURN(0);
252
253 END get_event_budget_cost;
254
255
256 /******************************************************************************/
257 /* Public function to calculate the Actual Cost of a training event */
258 /******************************************************************************/
259 FUNCTION get_event_actual_cost(p_event_id IN NUMBER)
260 RETURN NUMBER IS
261
262 -- This cursor won't work if the resource is priced in units other than Days
263 -- Need to fix this in a future release
264 CURSOR resource_bookings_csr(p_csr_event_id NUMBER) IS
265 SELECT
266 sr.currency_code
267 ,sr.cost_unit
268 ,nvl(sr.cost,0) * nvl(rb.quantity,0) *
269 nvl(trunc(rb.required_date_to - rb.required_date_FROM + 1),0) cost
270 FROM
271 ota_suppliable_resources sr
272 ,ota_resource_bookings rb
273 WHERE rb.supplied_resource_id = sr.supplied_resource_id
274 AND rb.event_id = p_csr_event_id
275 AND rb.status = 'C'; -- Confirmed bookings only
276
277 resource_bookings_rec resource_bookings_csr%rowtype;
278
279 CURSOR actual_cost_csr IS
280 SELECT
281 nvl(actual_cost,0)
282 ,budget_currency_code
283 ,business_group_id
284 FROM ota_events
285 WHERE event_id = p_event_id;
286
287 l_actual_cost NUMBER := 0;
288 l_actual_currency_code ota_events.budget_currency_code%type;
289 l_business_group_id ota_events.business_group_id%type;
290 l_event_cost NUMBER := 0;
291 l_resource_cost NUMBER := 0;
292
293 BEGIN
294
295 IF p_event_id IS NULL THEN
296 RETURN(0);
297 END IF;
298
299 -- Get Actual Cost of the event
300 OPEN actual_cost_csr;
301 FETCH actual_cost_csr INTO
302 l_actual_cost, l_actual_currency_code, l_business_group_id;
303 CLOSE actual_cost_csr;
304
305 -- Set package global variables
306 set_training_globals(p_event_id => p_event_id);
307
308 -- Calculate total cost of resource bookings against the event
309 FOR resource_bookings_rec IN resource_bookings_csr(p_event_id) LOOP
310
311 -- Convert to currency of BG
312 l_resource_cost := hri_bpl_currency.convert_currency_amount(
313 p_from_currency => resource_bookings_rec.currency_code
314 ,p_to_currency => g_bg_currency_code
315 ,p_conversion_date => SYSDATE
316 ,p_amount => resource_bookings_rec.cost
317 ,p_rate_type => g_rate_type);
318
319 l_event_cost := l_event_cost + l_resource_cost;
320
321 END loop;
322
323 -- Default to the actual cost on the event if necessary
324 IF l_event_cost = 0 THEN
325
326 l_event_cost := hri_bpl_currency.convert_currency_amount(
327 p_from_currency => l_actual_currency_code
328 ,p_to_currency => g_bg_currency_code
329 ,p_conversion_date => SYSDATE
330 ,p_amount => l_actual_cost
331 ,p_rate_type => g_rate_type);
332
333 END IF;
334
335 RETURN (ROUND(l_event_cost, g_precision));
336
337 EXCEPTION
338 WHEN OTHERS THEN
339
340 RETURN(0);
341
342 END get_event_actual_cost;
343
344
345 /******************************************************************************/
346 /* Private function to calculate the Internal Revenue generated by a training */
347 /* event */
348 /******************************************************************************/
349 FUNCTION get_internal_revenue(p_event_id IN NUMBER)
350 RETURN NUMBER IS
351
352 CURSOR event_csr is
353 SELECT
354 price_basis
355 ,nvl(stANDard_price,0)
356 ,currency_code
357 FROM ota_events
358 WHERE event_id = p_event_id;
359
360 CURSOR internal_bookings_csr is
361 SELECT NVL(SUM(NVL(tdb.number_of_places,1)),0)
362 FROM
363 ota_booking_status_types bst
364 ,ota_delegate_bookings tdb
365 WHERE tdb.booking_status_type_id = bst.booking_status_type_id
366 AND bst.type = 'A' -- Attended
367 AND tdb.organization_id IS NOT NULL
368 AND tdb.event_id = p_event_id;
369
370 l_currency_code ota_events.currency_code%type;
371 l_internal_revenue NUMBER := 0;
372 l_price_basis ota_events.price_basis%type;
373 l_standard_price ota_events.standard_price%type;
374 l_total_int_students NUMBER := 0;
375
376 BEGIN
377 -- Get event details
378 OPEN event_csr;
379 FETCH event_csr INTO
380 l_price_basis, l_standard_price, l_currency_code;
381 CLOSE event_csr;
382
383 -- Price Basis = 'Student' ?
384 IF (l_price_basis = 'S') AND (l_standard_price <> 0) then
385
386 OPEN internal_bookings_csr;
387 FETCH internal_bookings_csr INTO l_total_int_students;
388 CLOSE internal_bookings_csr;
389
390 -- Calculate internal revenue
391 l_internal_revenue := l_total_int_students * l_standard_price;
392
393 -- Convert to currency of business group
394 l_internal_revenue := hri_bpl_currency.convert_currency_amount(
395 p_from_currency => l_currency_code
396 ,p_to_currency => g_bg_currency_code
397 ,p_conversion_date => SYSDATE
398 ,p_amount => l_internal_revenue
399 ,p_rate_type => g_rate_type);
400
401 END IF;
402
403 RETURN(l_internal_revenue);
404
405 EXCEPTION
406 WHEN OTHERS THEN
407
408 RETURN(0);
409
410 END get_internal_revenue;
411
412
413 /******************************************************************************/
414 /* Private function to calculate the External Revenue generated by a training */
415 /* event */
416 /******************************************************************************/
417 FUNCTION get_external_revenue(p_event_id IN NUMBER)
418 RETURN NUMBER IS
419
420 CURSOR external_bookings_csr is
421 SELECT tdb.booking_id
422 FROM ota_booking_status_types bst
423 ,ota_delegate_bookings tdb
424 WHERE tdb.booking_status_type_id = bst.booking_status_type_id
425 AND bst.type = 'A' -- Attended
426 AND tdb.customer_id is not null
427 AND tdb.event_id = p_event_id;
428
429 external_bookings_rec external_bookings_csr%rowtype;
430
431 CURSOR finance_lines_csr( p_delegate_booking_id NUMBER ) is
432 SELECT
433 currency_code
434 ,SUM(NVL(money_amount,0)) amount
435 FROM ota_finance_lines
436 WHERE line_type = 'E' -- Enrollment
437 AND cancelled_flag = 'N'
438 AND booking_id = p_delegate_booking_id
439 GROUP BY currency_code;
440
441 finance_lines_rec finance_lines_csr%rowtype;
442
443 l_external_revenue NUMBER := 0;
444 l_line_amount NUMBER := 0;
445
446 BEGIN
447
448 FOR external_bookings_rec IN external_bookings_csr LOOP
449
450 FOR finance_lines_rec IN finance_lines_csr(external_bookings_rec.booking_id) LOOP
451
452 -- Convert to currency of business group
453 l_line_amount := hri_bpl_currency.convert_currency_amount(
454 p_FROM_currency => finance_lines_rec.currency_code
455 ,p_to_currency => g_bg_currency_code
456 ,p_conversion_date => SYSDATE
457 ,p_amount => finance_lines_rec.amount
458 ,p_rate_type => g_rate_type);
459
460 l_external_revenue := l_external_revenue + l_line_amount;
461
462 END LOOP;
463
464 END LOOP;
465
466 RETURN(l_external_revenue);
467
468 EXCEPTION
469 WHEN OTHERS THEN
470
471 RETURN(0);
472
473 END get_external_revenue;
474
475
476 /******************************************************************************/
477 /* cbridge, 13/09/20000, course ranking workbook functions */
478 /* Private function to calculate the Internal Revenue generated by a training */
479 /* event for a particular delegate booking where the delegate attended the */
480 /* event */
481 /******************************************************************************/
482 FUNCTION get_att_int_rev_booking(p_event_id IN NUMBER,
483 p_booking_id IN NUMBER)
484 RETURN NUMBER IS
485
486 CURSOR event_csr is
487 SELECT
488 price_basis
489 ,nvl(stANDard_price,0)
490 ,currency_code
491 FROM ota_events
492 WHERE event_id = p_event_id;
493
494 CURSOR internal_bookings_csr is
495 SELECT NVL(SUM(NVL(tdb.number_of_places,1)),0)
496 FROM ota_booking_status_types bst
497 ,ota_delegate_bookings tdb
498 WHERE tdb.booking_status_type_id = bst.booking_status_type_id
499 AND bst.type = 'A' -- AttENDed
500 AND tdb.organization_id IS NOT NULL
501 AND tdb.booking_id = p_booking_id
502 AND tdb.event_id = p_event_id;
503
504 l_currency_code ota_events.currency_code%type;
505 l_internal_revenue NUMBER := 0;
506 l_price_basis ota_events.price_basis%type;
507 l_standard_price ota_events.standard_price%type;
508 l_total_int_students NUMBER := 0;
509
510 BEGIN
511
512 ----------------------
513 -- Set package globals
514 ----------------------
515 set_training_globals(p_event_id => p_event_id);
516
517 -- Get event details
518 OPEN event_csr;
519 FETCH event_csr INTO
520 l_price_basis, l_stANDard_price, l_currency_code;
521 CLOSE event_csr;
522
523 -- Price Basis = 'Student' ?
524 IF (l_price_basis = 'S') AND (l_standard_price <> 0) THEN
525
526 OPEN internal_bookings_csr;
527 FETCH internal_bookings_csr INTO l_total_int_students;
528 CLOSE internal_bookings_csr;
529
530 -- Calculate internal revenue
531 l_internal_revenue := l_total_int_students * l_stANDard_price;
532
533 -- Convert to currency of business group
534 l_internal_revenue := hri_bpl_currency.convert_currency_amount(
535 p_from_currency => l_currency_code
536 ,p_to_currency => g_bg_currency_code
537 ,p_conversion_date => SYSDATE
538 ,p_amount => l_internal_revenue
539 ,p_rate_type => g_rate_type);
540
541 END IF;
542
543 RETURN(l_internal_revenue);
544
545 EXCEPTION
546 WHEN OTHERS THEN
547
548 RETURN(0);
549
550 END get_att_int_rev_booking;
551
552
553 /******************************************************************************/
554 /* Private function to calculate the External Revenue generated by a training */
555 /* event for a particular delegate booking where the delegate attended the */
556 /* event */
557 /******************************************************************************/
558 FUNCTION get_att_ext_rev_booking(p_event_id IN NUMBER,
559 p_booking_id IN NUMBER)
560 RETURN NUMBER IS
561
562 CURSOR external_bookings_csr IS
563 SELECT tdb.booking_id
564 FROM ota_booking_status_types bst
565 ,ota_delegate_bookings tdb
566 WHERE tdb.booking_status_type_id = bst.booking_status_type_id
567 AND bst.type = 'A' -- Attended
568 AND tdb.booking_id = p_booking_id
569 AND tdb.organization_id IS NULL -- bug fix 1432057
570 AND tdb.event_id = p_event_id;
571
572 external_bookings_rec external_bookings_csr%rowtype;
573
574 CURSOR finance_lines_csr(p_delegate_booking_id NUMBER) IS
575 SELECT
576 currency_code
577 ,sum(nvl(money_amount,0)) amount
578 FROM ota_finance_lines
579 WHERE line_type = 'E' -- Enrollment
580 AND cancelled_flag = 'N'
581 AND booking_id = p_delegate_booking_id
582 GROUP BY currency_code;
583
584 finance_lines_rec finance_lines_csr%rowtype;
585
586 l_external_revenue NUMBER := 0;
587 l_line_amount NUMBER := 0;
588
589 BEGIN
590
591 ----------------------
592 -- Set package globals
593 ----------------------
594 set_training_globals(p_event_id => p_event_id);
595
596 FOR external_bookings_rec IN external_bookings_csr LOOP
597
598 FOR finance_lines_rec IN finance_lines_csr(external_bookings_rec.booking_id) LOOP
599
600 -- Convert to currency of business group
601 l_line_amount := hri_bpl_currency.convert_currency_amount(
602 p_from_currency => finance_lines_rec.currency_code
603 ,p_to_currency => g_bg_currency_code
604 ,p_conversion_date => SYSDATE
605 ,p_amount => finance_lines_rec.amount
606 ,p_rate_type => g_rate_type);
607
608 l_external_revenue := l_external_revenue + l_line_amount;
609
610 END LOOP;
611
612 END LOOP;
613
614 RETURN(l_external_revenue);
615
616 EXCEPTION
617 WHEN OTHERS THEN
618
619 RETURN(0);
620
621 END get_att_ext_rev_booking;
622
623
624 /******************************************************************************/
625 /* Private function to calculate the Internal Revenue generated by a training */
626 /* event for a particular delegate booking where the delegate did not attend */
627 /* the event */
628 /******************************************************************************/
629 FUNCTION get_non_att_int_rev_booking(p_event_id IN NUMBER,
630 p_booking_id IN NUMBER)
631 RETURN NUMBER IS
632
633 CURSOR event_csr is
634 SELECT
635 price_basis
636 ,nvl(stANDard_price,0)
637 ,currency_code
638 FROM ota_events
639 WHERE event_id = p_event_id;
640
641 CURSOR internal_bookings_csr is
642 SELECT NVL(SUM(NVL(tdb.number_of_places,1)),0)
643 FROM ota_booking_status_types bst
644 ,ota_delegate_bookings tdb
645 WHERE tdb.booking_status_type_id = bst.booking_status_type_id
646 AND bst.type IN ('P','C') -- Placed, Cancelled
647 AND tdb.organization_id IS NOT NULL
648 AND tdb.booking_id = p_booking_id
649 AND tdb.event_id = p_event_id;
650
651 l_currency_code ota_events.currency_code%type;
652 l_internal_revenue NUMBER := 0;
653 l_price_basis ota_events.price_basis%type;
654 l_standard_price ota_events.standard_price%type;
655 l_total_int_students NUMBER := 0;
656
657 BEGIN
658
659 ----------------------
660 -- Set package globals
661 ----------------------
662 set_training_globals(p_event_id => p_event_id);
663
664 -- Get event details
665 OPEN event_csr;
666 FETCH event_csr INTO
667 l_price_basis, l_standard_price, l_currency_code;
668 CLOSE event_csr;
669
670 -- Price Basis = 'Student' ?
671 IF (l_price_basis = 'S') AND (l_standard_price <> 0) THEN
672
673 OPEN internal_bookings_csr;
674 FETCH internal_bookings_csr INTO l_total_int_students;
675 CLOSE internal_bookings_csr;
676
677 -- Calculate internal revenue
678 l_internal_revenue := l_total_int_students * l_stANDard_price;
679
680 -- Convert to currency of business group
681 l_internal_revenue := hri_bpl_currency.convert_currency_amount(
682 p_FROM_currency => l_currency_code
683 ,p_to_currency => g_bg_currency_code
684 ,p_conversion_date => SYSDATE
685 ,p_amount => l_internal_revenue
686 ,p_rate_type => g_rate_type);
687
688 END IF;
689
690 RETURN(l_internal_revenue);
691
692 EXCEPTION
693 WHEN OTHERS THEN
694
695 RETURN(0);
696
697 END get_non_att_int_rev_booking;
698
699
700 /******************************************************************************/
701 /* Private function to calculate the External Revenue generated by a training */
702 /* event for a particular delegate booking where the delegate did not attend */
703 /* the event */
704 /******************************************************************************/
705 FUNCTION get_non_att_ext_rev_booking(p_event_id IN NUMBER,
706 p_booking_id IN NUMBER)
707 RETURN NUMBER IS
708
709 CURSOR external_bookings_csr is
710 SELECT tdb.booking_id
711 FROM ota_booking_status_types bst
712 ,ota_delegate_bookings tdb
713 WHERE tdb.booking_status_type_id = bst.booking_status_type_id
714 AND bst.type IN ('P','C') -- Placed, Cancelled
715 AND tdb.booking_id = p_booking_id
716 AND tdb.organization_id IS NULL -- bug fix 1432057
717 AND tdb.event_id = p_event_id;
718
719 external_bookings_rec external_bookings_csr%rowtype;
720
721 CURSOR finance_lines_csr(p_delegate_booking_id NUMBER) IS
722 SELECT
723 currency_code
724 ,SUM(NVL(money_amount,0)) amount
725 FROM ota_finance_lines
726 WHERE line_type = 'E' -- Enrollment
727 AND cancelled_flag = 'N'
728 AND booking_id = p_delegate_booking_id
729 GROUP BY currency_code;
730
731 finance_lines_rec finance_lines_csr%rowtype;
732
733 l_external_revenue NUMBER := 0;
734 l_line_amount NUMBER := 0;
735
736 BEGIN
737
738 ----------------------
739 -- Set package globals
740 ----------------------
741 set_training_globals(p_event_id => p_event_id);
742
743 FOR external_bookings_rec IN external_bookings_csr LOOP
744
745 FOR finance_lines_rec IN finance_lines_csr(external_bookings_rec.booking_id) LOOP
746
747 -- Convert to currency of business group
748 l_line_amount := hri_bpl_currency.convert_currency_amount(
749 p_from_currency => finance_lines_rec.currency_code
750 ,p_to_currency => g_bg_currency_code
751 ,p_conversion_date => SYSDATE
752 ,p_amount => finance_lines_rec.amount
753 ,p_rate_type => g_rate_type);
754
755 l_external_revenue := l_external_revenue + l_line_amount;
756
757 END loop;
758
759 END loop;
760
761 RETURN(l_external_revenue);
762
763 EXCEPTION
764 WHEN OTHERS THEN
765
766 RETURN(0);
767
768 END get_non_att_ext_rev_booking;
769
770
771 /******************************************************************************/
772 /* Public function to calculate the Total Revenue generated by a training */
773 /* event */
774 /******************************************************************************/
775 FUNCTION get_event_revenue(p_event_id IN NUMBER)
776 RETURN NUMBER IS
777
778 CURSOR program_event_csr IS
779 SELECT program_event_id
780 FROM ota_program_memberships
781 WHERE event_id = p_event_id;
782
783 program_event_rec program_event_csr%rowtype;
784
785 l_external_revenue NUMBER := 0;
786 l_internal_revenue NUMBER := 0;
787 l_program_ext_revenue NUMBER := 0;
788 l_program_int_revenue NUMBER := 0;
789 l_program_prorata_revenue NUMBER := 0;
790 l_program_prorata_total NUMBER := 0;
791 l_program_revenue NUMBER := 0;
792 l_total_revenue NUMBER := 0;
793
794 BEGIN
795
796 IF p_event_id IS NULL THEN
797 RETURN(0);
798 END IF;
799
800 ----------------------
801 -- Set package globals
802 ----------------------
803 set_training_globals(p_event_id => p_event_id);
804
805 -------------------------------------
806 -- Get Internal Revenue for the event
807 -------------------------------------
808 l_internal_revenue := get_internal_revenue(p_event_id => p_event_id);
809
810 -------------------------------------
811 -- Get External Revenue for the event
812 -------------------------------------
813 l_external_revenue := get_external_revenue(p_event_id => p_event_id);
814
815 ----------------------------
816 -- Calculate program revenue
817 ----------------------------
818
819 -- Is the event a member of a programme ?
820 FOR program_event_rec IN program_event_csr LOOP
821
822 -- Determine internal revenue for the program event
823 l_program_int_revenue := get_internal_revenue
824 (p_event_id => program_event_rec.program_event_id);
825
826 -- Determine external revenue for the program event
827 l_program_ext_revenue := get_external_revenue
828 (p_event_id => program_event_rec.program_event_id);
829
830 -- Calculate total program revenue
831 l_program_revenue := l_program_int_revenue + l_program_ext_revenue;
832
833 -- Prorate the program revenue
834
835 l_program_prorata_revenue := pro_rata_amount(
836 p_event_id => p_event_id
837 ,p_program_event_id => program_event_rec.program_event_id
838 ,p_programme_amount => l_program_revenue
839 ,p_currency_code => g_bg_currency_code);
840
841 l_program_prorata_total := l_program_prorata_total + l_program_prorata_revenue;
842
843 END loop;
844
845 --------------------------
846 -- Calculate total revenue
847 --------------------------
848 l_total_revenue := l_internal_revenue + l_external_revenue + l_program_prorata_total;
849
850 RETURN (ROUND(l_total_revenue, g_precision) );
851
852 EXCEPTION
853 WHEN OTHERS THEN
854
855 RETURN(0);
856
857 END get_event_revenue;
858
859 /******************************************************************************/
860 /* Public function to convert Training Duration FROM one set of units to */
861 /* another */
862 /******************************************************************************/
863 FUNCTION convert_training_duration(p_formula_id IN NUMBER
864 ,p_from_duration IN NUMBER
865 ,p_from_duration_units IN VARCHAR2
866 ,p_to_duration_units IN VARCHAR2
867 ,p_activity_version_name IN VARCHAR2
868 ,p_event_name IN VARCHAR2
869 ,p_session_date IN DATE)
870 RETURN NUMBER IS
871
872 l_to_duration NUMBER := 0;
873
874 l_inputs FF_Exec.Inputs_T;
875 l_outputs FF_Exec.Outputs_T;
876
877 BEGIN
878
879 -- Check whether all mandatory parameters have been supplied
880 IF (p_formula_id IS NULL) OR (p_from_duration IS NULL) OR
881 (p_from_duration_units IS NULL) OR (p_to_duration_units IS NULL) OR
882 (p_event_name IS NULL) OR (p_session_date IS NULL) THEN
883 --
884 -- bug fix 1432188 remove check for (p_activity_version_name IS NULL)
885 --
886 RETURN(0);
887 END IF;
888
889 -- Initialise the Inputs and Outputs tables
890 FF_Exec.Init_Formula(
891 p_formula_id => p_formula_id
892 ,p_effective_date => sysdate
893 ,p_inputs => l_inputs
894 ,p_outputs => l_outputs);
895
896 IF (l_inputs.first IS NOT NULL) AND (l_inputs.last IS NOT NULL) THEN
897
898 -- Set up context values for the formula
899 FOR i IN l_inputs.first..l_inputs.last LOOP
900
901 IF l_inputs(i).name = 'FROM_DURATION' THEN
902 l_inputs(i).value := to_char(p_from_duration);
903
904 ELSIF l_inputs(i).name = 'FROM_DURATION_UNITS' THEN
905 l_inputs(i).value := p_FROM_duration_units;
906
907 ELSIF l_inputs(i).name = 'TO_DURATION_UNITS' THEN
908 l_inputs(i).value := p_to_duration_units;
909
910 ELSIF l_inputs(i).name = 'ACTIVITY_VERSION_NAME' THEN
911 -- bug fix 1432188, added NVL(p_activity_version_name,'X')
912 l_inputs(i).value := NVL(p_activity_version_name,'X');
913
914 ELSIF l_inputs(i).name = 'EVENT_NAME' THEN
915 l_inputs(i).value := p_event_name;
916
917 END IF;
918
919 END loop;
920
921 END IF;
922
923 -- Run the Fast Formula
924 FF_Exec.Run_Formula(
925 p_inputs => l_inputs
926 ,p_outputs => l_outputs);
927
928 l_to_duration := to_number(l_outputs(l_outputs.first).value);
929
930 RETURN(l_to_duration);
931
932 EXCEPTION
933 WHEN OTHERS THEN
934
935 RETURN(0);
936
937 END convert_training_duration;
938
939 END hri_oltp_disc_training;