[Home] [Help]
PACKAGE BODY: APPS.JTF_BRM_PVT
Source
1 PACKAGE BODY JTF_BRM_PVT AS
2 /* $Header: jtfvbrmb.pls 120.2.12010000.2 2008/11/05 06:01:37 rkamasam ship $ */
3
4 -----------------------------------------------------------------------------
5 --
6 -- PROCEDURE selector
7 --
8 -- Determine which process to run.
9 --
10 -- IN
11 -- itemtype - type of the current item
12 -- itemkey - key of the current item
13 -- actid - process activity instance id
14 -- funcmode - function execution mode. this is set by the engine
15 -- as either 'RUN', 'CANCEL', 'TIMEOUT'
16 -- OUT
17 -- result - name of Workflow process to run
18 --
19 PROCEDURE selector
20 (
21 itemtype IN VARCHAR2,
22 itemkey IN VARCHAR2,
23 actid IN NUMBER,
24 funcmode IN VARCHAR2,
25 result IN OUT NOCOPY VARCHAR2
26 ) IS
27 --
28 BEGIN
29 --
30 -- RUN mode - normal process execution
31 --
32 IF (funcmode = 'RUN') THEN
33 result := 'MONITOR_RULES';
34 RETURN;
35 END IF;
36 --
37 EXCEPTION
38 WHEN OTHERS THEN
39 wf_core.context('JTF_BRM_PVT', 'SELECTOR',
40 itemtype, itemkey, to_char(actid), funcmode);
41 RAISE;
42 END selector;
43 -----------------------------------------------------------------------------
44 --
45 -- FUNCTION init_monitor
46 --
47 -- Create an instance of the Business Rule Monitor, initialize it, and
48 -- start the instance. Return TRUE if successful; otherwise return FALSE.
49 --
50 -- IN
51 -- itemkey - key of the current item
52 -- uom_type - unit of measure type for timer interval
53 -- uom_code - unit of measure code for timer interval
54 -- timer_units - number of units for timer interval
55 -- OUT
56 -- TRUE - success
57 -- FALSE - failure
58 --
59 FUNCTION init_monitor
60 (
61 itemkey IN NUMBER,
62 uom_type IN VARCHAR2,
63 uom_code IN VARCHAR2,
64 timer_units IN NUMBER
65 ) RETURN BOOLEAN IS
66 --
67 l_itemtype VARCHAR2(10) := 'JTFBRM';
68 l_itemkey VARCHAR2(100);
69 l_admin VARCHAR2(80) := FND_PROFILE.Value(name => 'JTF_BRM_WF_ADMINISTRATOR');
70
71 --
72 BEGIN
73 --
74 IF itemkey IS NULL OR uom_type IS NULL OR
75 uom_code IS NULL OR timer_units IS NULL OR
76 l_admin IS NULL THEN
77 RETURN FALSE;
78 END IF;
79 --
80 l_itemkey := to_char(itemkey);
81 --
82 wf_engine.CreateProcess(
83 itemtype => l_itemtype,
84 itemkey => l_itemkey,
85 process => 'MONITOR_RULES');
86 --
87 wf_engine.SetItemAttrText(
88 itemtype => l_itemtype,
89 itemkey => l_itemkey,
90 aname => 'WF_ADMINISTRATOR',
91 avalue => l_admin);
92 --
93 wf_engine.SetItemOwner(
94 itemtype => l_itemtype,
95 itemkey => l_itemkey,
96 owner => l_admin);
97 --
98 wf_engine.SetItemAttrText(
99 itemtype => l_itemtype,
100 itemkey => l_itemkey,
101 aname => 'UOM_TYPE',
102 avalue => uom_type);
103 --
104 wf_engine.SetItemAttrText(
105 itemtype => l_itemtype,
106 itemkey => l_itemkey,
107 aname => 'UOM_CODE',
108 avalue => uom_code);
109 --
110 wf_engine.SetItemAttrNumber(
111 itemtype => l_itemtype,
112 itemkey => l_itemkey,
113 aname => 'TIMER_UNITS',
114 avalue => timer_units);
115 --
116 wf_engine.SetItemAttrDate(
117 itemtype => l_itemtype,
118 itemkey => l_itemkey,
119 aname => 'MONITOR_START_TIME',
120 avalue => SYSDATE);
121 --
122 wf_engine.StartProcess(
123 itemtype => l_itemtype,
124 itemkey => l_itemkey);
125 --
126 COMMIT;
127 RETURN TRUE;
128 --
129 EXCEPTION
130 WHEN OTHERS THEN
131 wf_core.context('JTF_BRM_PVT', 'INIT_MONITOR');
132 raise;
133 END init_monitor;
134 -----------------------------------------------------------------------------
135 --
136 -- PROCEDURE start_monitor
137 --
138 -- Set the START command and PROCESS_ID item attributes and update the
139 -- record in the JTF_BRM_PARAMETERS table to indicate the start of the
140 -- Business Rule Monitor. The WORKFLOW_PROCESS_ID is set to be the same
141 -- as the itemkey.
142 --
143 -- IN
144 -- itemtype - type of the current item
145 -- itemkey - key of the current item
146 -- actid - process activity instance id
147 -- funcmode - function execution mode. this is set by the engine
148 -- as either 'RUN', 'CANCEL', 'TIMEOUT'
149 -- OUT
150 -- result - activity has completed with the indicated result:
151 --
152 -- COMPLETE:NOERROR
153 -- COMPLETE:NONCRITICAL
154 -- COMPLETE:CRITICAL
155 --
156 PROCEDURE start_monitor
157 (
158 itemtype IN VARCHAR2,
159 itemkey IN VARCHAR2,
160 actid IN NUMBER,
161 funcmode IN VARCHAR2,
162 result IN OUT NOCOPY VARCHAR2
163 ) IS
164 --
165 l_api_version NUMBER := 1.0;
166 l_init_msg_list VARCHAR2(1) := fnd_api.g_true;
167 l_commit VARCHAR2(1) := fnd_api.g_false;
168 l_validation_level NUMBER := fnd_api.g_valid_level_full;
169 l_return_status VARCHAR2(1);
170 l_msg_count NUMBER;
171 l_msg_data VARCHAR2(2000);
172 l_bp_rec JTF_BRMParameter_PVT.BRM_Parameter_rec_type;
173 l_found BOOLEAN;
174 --
175 CURSOR c_parameters IS
176 SELECT *
177 FROM jtf_brm_parameters
178 WHERE parameter_id = 1;
179 --
180 BEGIN
181 --
182 -- RUN mode - normal process execution
183 --
184 IF (funcmode = 'RUN') THEN
185 --
186 wf_engine.SetItemAttrText(
187 itemtype => itemtype,
188 itemkey => itemkey,
189 aname => 'SUBPROCESS_NAME',
190 avalue => 'START_MONITOR');
191 --
192 wf_engine.SetItemAttrText(
193 itemtype => itemtype,
194 itemkey => itemkey,
195 aname => 'COMMAND_TYPE',
196 avalue => 'JTF_BRM_WF_COMMAND_TYPE');
197 --
198 wf_engine.SetItemAttrText(
199 itemtype => itemtype,
200 itemkey => itemkey,
201 aname => 'COMMAND_CODE',
202 avalue => 'START');
203 --
204 wf_engine.SetItemAttrText(
205 itemtype => itemtype,
206 itemkey => itemkey,
207 aname => 'COMMAND',
208 avalue => 'START');
209 --
210 wf_engine.SetItemAttrText(
211 itemtype => itemtype,
212 itemkey => itemkey,
213 aname => 'PROCESS_ID',
214 avalue => itemkey);
215 --
216 -- Update columns in the JTF_BRM_PARAMETERS table to indicate
217 -- the start of the Business Rule Monitor. But first select the
218 -- record so as not to overwrite good data.
219 --
220 OPEN c_parameters;
221 FETCH c_parameters INTO l_bp_rec;
222 l_found := c_parameters%FOUND;
223 CLOSE c_parameters;
224 --
225 IF NOT l_found THEN
226 result := 'COMPLETE:CRITICAL';
227 RETURN;
228 END IF;
229 --
230 l_bp_rec.workflow_process_id := itemkey;
231 l_bp_rec.workflow_item_type := 'JTFBRM';
232 l_bp_rec.workflow_process_name := 'MONITOR_RULES';
233 l_bp_rec.brm_wf_command_type := 'JTF_BRM_WF_COMMAND_TYPE';
234 l_bp_rec.brm_wf_command_code := 'START';
235 --
236 JTF_BRMParameter_PVT.Update_BRMParameter(
237 p_api_version => l_api_version,
238 p_init_msg_list => l_init_msg_list,
239 p_commit => l_commit,
240 p_validation_level => l_validation_level,
241 x_return_status => l_return_status,
242 x_msg_count => l_msg_count,
243 x_msg_data => l_msg_data,
244 p_bp_rec => l_bp_rec);
245 --
246 IF l_msg_count > 0 THEN
247 result := 'COMPLETE:CRITICAL';
248 RETURN;
249 END IF;
250 result := 'COMPLETE:NOERROR';
251 RETURN;
252 END IF;
253 --
254 -- CANCEL mode - activity 'compensation'
255 --
256 IF (funcmode = 'CANCEL') THEN
257 result := 'COMPLETE:NOERROR';
258 RETURN;
259 END IF;
260 --
261 -- TIMEOUT mode
262 --
263 IF (funcmode = 'TIMEOUT') THEN
264 result := 'COMPLETE:NOERROR';
265 RETURN;
266 END IF;
267 --
268 EXCEPTION
269 WHEN OTHERS THEN
270 IF c_parameters%ISOPEN THEN
271 CLOSE c_parameters;
272 END IF;
273 wf_core.context('JTF_BRM_PVT', 'START_MONITOR',
274 itemtype, itemkey, to_char(actid), funcmode);
275 RAISE;
276 END start_monitor;
277 -----------------------------------------------------------------------------
278 --
279 -- PROCEDURE calculate_interval
280 --
281 -- Get the number of hours or minutes for the timer interval and convert to
282 -- <days>.<fraction_of_a_day>. Set the timer interval.
283 --
284 -- IN
285 -- itemtype - type of the current item
286 -- itemkey - key of the current item
287 -- actid - process activity instance id
288 -- funcmode - function execution mode. this is set by the engine
289 -- as either 'RUN', 'CANCEL', 'TIMEOUT'
290 -- OUT
291 -- result - activity has completed with the indicated result:
292 --
293 -- COMPLETE:NOERROR
294 -- COMPLETE:NONCRITICAL
295 -- COMPLETE:CRITICAL
296 --
297 PROCEDURE calculate_interval
298 (
299 itemtype IN VARCHAR2,
300 itemkey IN VARCHAR2,
301 actid IN NUMBER,
302 funcmode IN VARCHAR2,
303 result IN OUT NOCOPY VARCHAR2
304 ) IS
305 l_uom_type fnd_lookups.lookup_type%TYPE;
306 l_uom_code fnd_lookups.lookup_code%TYPE;
307 l_timer_units NUMBER;
308 l_timer_interval NUMBER;
309 l_meaning fnd_lookups.meaning%TYPE;
310 l_conversion NUMBER;
311 l_found BOOLEAN;
312 l_now DATE := SYSDATE;
313 --
314 CURSOR c_lookups(b_uom_type fnd_lookups.lookup_type%TYPE,
315 b_uom_code fnd_lookups.lookup_code%TYPE,
316 b_now DATE) IS
317 SELECT meaning
318 FROM fnd_lookups
319 WHERE lookup_type = b_uom_type
320 AND lookup_code = b_uom_code
321 AND enabled_flag = 'Y'
322 AND start_date_active <= b_now
323 AND nvl(end_date_active, b_now) >= b_now;
324 --
325 BEGIN
326 --
327 -- RUN mode - normal process execution
328 --
329 IF (funcmode = 'RUN') THEN
330 --
331 wf_engine.SetItemAttrText(
332 itemtype => itemtype,
333 itemkey => itemkey,
334 aname => 'SUBPROCESS_NAME',
335 avalue => 'CALCULATE_INTERVAL');
336 --
337 -- Get the timer unit of measure, and the number of units.
338 --
339 l_uom_type := wf_engine.GetItemAttrText(
340 itemtype => itemtype,
341 itemkey => itemkey,
342 aname => 'UOM_TYPE');
343 --
344 l_uom_code := wf_engine.GetItemAttrText(
345 itemtype => itemtype,
346 itemkey => itemkey,
347 aname => 'UOM_CODE');
348 --
349 l_timer_units := wf_engine.GetItemAttrNumber(
350 itemtype => itemtype,
351 itemkey => itemkey,
352 aname => 'TIMER_UNITS');
353 --
354 IF l_uom_type IS NULL OR l_uom_code IS NULL OR l_timer_units IS NULL THEN
355 result := 'COMPLETE:CRITICAL';
356 RETURN;
357 END IF;
358 --
359 OPEN c_lookups(l_uom_type, l_uom_code, l_now);
360 FETCH c_lookups
361 INTO l_meaning;
362 l_found := c_lookups%FOUND;
363 CLOSE c_lookups;
364 --
365 IF NOT l_found THEN
366 result := 'COMPLETE:CRITICAL';
367 RETURN;
368 END IF;
369 --
370 -- Convert interval to days.
371 --
372 IF l_uom_code = 'HOURS' THEN
373 l_timer_interval := l_timer_units / 24;
374 ELSIF l_uom_code = 'MINUTES' THEN
375 l_timer_interval := l_timer_units / 1440;
376 ELSE
377 result := 'COMPLETE:CRITICAL';
378 RETURN;
379 END IF;
380 --
381 wf_engine.SetItemAttrNumber(
382 itemtype => itemtype,
383 itemkey => itemkey,
384 aname => 'TIMER_INTERVAL',
385 avalue => l_timer_interval);
386 --
387 result := 'COMPLETE:NOERROR';
388 RETURN;
389 END IF;
390 --
391 -- CANCEL mode - activity 'compensation'
392 --
393 IF (funcmode = 'CANCEL') THEN
394 result := 'COMPLETE:NOERROR';
395 RETURN;
396 END IF;
397 --
398 -- TIMEOUT mode
399 --
400 IF (funcmode = 'TIMEOUT') THEN
401 result := 'COMPLETE:NOERROR';
402 RETURN;
403 END IF;
404 --
405 EXCEPTION
406 WHEN OTHERS THEN
407 IF c_lookups%ISOPEN THEN
408 CLOSE c_lookups;
409 END IF;
410 wf_core.context('JTF_BRM_PVT', 'CALCULATE_INTERVAL',
411 itemtype, itemkey, to_char(actid), funcmode);
412 RAISE;
413 END calculate_interval;
414 -----------------------------------------------------------------------------
415 --
416 -- FUNCTION get_activity_id
417 --
418 -- Return a unique ID for an activity.
419 --
420 FUNCTION get_activity_id RETURN NUMBER IS
421 --
422 CURSOR c_activity IS
423 SELECT jtf_brm_activities_s.nextval
424 FROM DUAL;
425 l_activity_id NUMBER;
426 --
427 BEGIN
428 OPEN c_activity;
429 FETCH c_activity INTO l_activity_id;
430 CLOSE c_activity;
431 RETURN l_activity_id;
432 EXCEPTION
433 WHEN OTHERS THEN
434 IF c_activity%ISOPEN THEN
435 CLOSE c_activity;
436 END IF;
437 END;
438 -----------------------------------------------------------------------------
439 --
440 -- PROCEDURE process_rules
441 --
442 -- Get the active business rules and process them.
443 --
444 -- IN
445 -- itemtype - type of the current item
446 -- itemkey - key of the current item
447 -- actid - process activity instance id
448 -- funcmode - function execution mode. this is set by the engine
449 -- as either 'RUN', 'CANCEL', 'TIMEOUT'
450 -- OUT
451 -- result - activity has completed with the indicated result:
452 --
453 -- COMPLETE:NOERROR
454 -- COMPLETE:NONCRITICAL
455 -- COMPLETE:CRITICAL
456 --
457 PROCEDURE process_rules
458 (
459 itemtype IN VARCHAR2,
460 itemkey IN VARCHAR2,
461 actid IN NUMBER,
462 funcmode IN VARCHAR2,
463 result IN OUT NOCOPY VARCHAR2
464 ) IS
465 CURSOR c_active_rules(b_now DATE) IS
466 SELECT jbr.view_name,
467 jbr.rule_id,
468 jbp.rowid,
469 jbp.workflow_item_type,
470 jbp.workflow_process_name
471 FROM jtf_brm_processes jbp,
472 jtf_brm_rules_vl jbr
473 WHERE jbp.rule_id = jbr.rule_id
474 AND nvl(jbr.start_date_active, b_now + 1) <= b_now
475 AND nvl(jbr.end_date_active, b_now) >= b_now
476 AND nvl(jbp.brm_uom_type,'JTF_BRM_UOM_TYPE') = 'JTF_BRM_UOM_TYPE'
477 AND nvl(jbp.last_brm_check_date, b_now - 100) +
478 (jbp.brm_check_interval / decode(jbp.brm_check_uom_code,
479 'MINUTES', 1440,
480 'HOURS', 24)) <= b_now
481 AND jbr.view_name IS NOT NULL
482 and jbp.workflow_item_type is not null;
483 --
484 TYPE cur_type IS REF CURSOR;
485 c_object cur_type;
486 l_active_rules c_active_rules%ROWTYPE;
487 l_found BOOLEAN;
488 l_view VARCHAR2(30);
489 l_object_type VARCHAR2(30);
490 l_object_id NUMBER;
491 l_now DATE := SYSDATE;
492 l_query VARCHAR2(1000);
493 l_activity_id NUMBER;
494 l_save_threshold NUMBER;
495 --
496 BEGIN
497 --
498 -- RUN mode - normal process execution
499 --
500 IF (funcmode = 'RUN') THEN
501 --
502 wf_engine.SetItemAttrText(
503 itemtype => itemtype,
504 itemkey => itemkey,
505 aname => 'SUBPROCESS_NAME',
506 avalue => 'PROCESS_RULES');
507 --
508 wf_engine.SetItemAttrDate(
509 itemtype => itemtype,
510 itemkey => itemkey,
511 aname => 'PROCESS_RULES_START_TIME',
512 avalue => l_now);
513 --
514 FOR i in c_active_rules(l_now) LOOP
515 --
516 -- Set the time the rule was last checked.
517 --
518 -- Get the object_type and object_id for each object in each view
519 -- and launch the appropriate Workflow activity. The user-friendly
520 -- key will be <object_type><object_id>, e.g., DF13579.
521 --
522 UPDATE jtf_brm_processes
523 SET last_brm_check_date = l_now
524 WHERE rowid = i.rowid;
525 --
526 l_query := 'SELECT object_type, object_id FROM ' || i.view_name;
527 --
528 OPEN c_object FOR l_query;
529 LOOP
530 FETCH c_object INTO l_object_type, l_object_id;
531 EXIT WHEN c_object%NOTFOUND;
532 --
533 l_activity_id := get_activity_id;
534 --
535 -- Temporarily overriding the defer threshold to make sure
536 -- the process is executed in the background.
537 --
538 l_save_threshold := WF_ENGINE.threshold;
539 WF_ENGINE.threshold := -1;
540 --
541 wf_engine.CreateProcess(
542 itemtype => i.workflow_item_type,
543 itemkey => l_activity_id,
544 process => i.workflow_process_name);
545 --
546 wf_engine.SetItemUserKey(
547 itemtype => i.workflow_item_type,
548 itemkey => l_activity_id,
549 userkey => l_object_type || to_char(l_object_id));
550 --
551 wf_engine.SetItemAttrText(
552 itemtype => i.workflow_item_type,
553 itemkey => l_activity_id,
554 aname => 'PROCESS_ID',
555 avalue => itemkey);
556 --
557 wf_engine.SetItemAttrText(
558 itemtype => i.workflow_item_type,
559 itemkey => l_activity_id,
560 aname => 'SUBPROCESS_NAME',
561 avalue => 'PROCESS_RULES');
562 --
563 wf_engine.SetItemAttrText(
564 itemtype => i.workflow_item_type,
565 itemkey => l_activity_id,
566 aname => 'OBJECT_TYPE',
567 avalue => l_object_type);
568 --
569 wf_engine.SetItemAttrText(
570 itemtype => itemtype,
571 itemkey => itemkey,
572 aname => 'OBJECT_TYPE',
573 avalue => l_object_type);
574 --
575 wf_engine.SetItemAttrNumber(
576 itemtype => i.workflow_item_type,
577 itemkey => l_activity_id,
578 aname => 'OBJECT_ID',
579 avalue => l_object_id);
580 --
581 wf_engine.SetItemAttrNumber(
582 itemtype => itemtype,
583 itemkey => itemkey,
584 aname => 'OBJECT_ID',
585 avalue => l_object_id);
586 --
587 wf_engine.SetItemAttrNumber(
588 itemtype => i.workflow_item_type,
589 itemkey => l_activity_id,
590 aname => 'RULE_ID',
591 avalue => i.rule_id);
592 --
593 wf_engine.StartProcess(
594 itemtype => i.workflow_item_type,
595 itemkey => l_activity_id);
596 --
597 -- Restoring the defer threshold
598 --
599 WF_ENGINE.threshold := l_save_threshold;
600
601 END LOOP;
602 CLOSE c_object;
603 END LOOP;
604 --
605 wf_engine.SetItemAttrDate(
606 itemtype => itemtype,
607 itemkey => itemkey,
608 aname => 'PROCESS_RULES_STOP_TIME',
609 avalue => SYSDATE);
610 --
611 result := 'COMPLETE:NOERROR';
612 RETURN;
613 END IF;
614 --
615 -- CANCEL mode - activity 'compensation'
616 --
617 IF (funcmode = 'CANCEL') THEN
618 result := 'COMPLETE:NOERROR';
619 RETURN;
620 END IF;
621 --
622 -- TIMEOUT mode
623 --
624 IF (funcmode = 'TIMEOUT') THEN
625 result := 'COMPLETE:NOERROR';
626 RETURN;
627 END IF;
628 --
629 EXCEPTION
630 WHEN OTHERS THEN
631 IF c_object%ISOPEN THEN
632 CLOSE c_object;
633 END IF;
634 wf_core.context('JTF_BRM_PVT', 'PROCESS_RULES',
635 itemtype, itemkey, to_char(actid), funcmode);
636 RAISE;
637 END process_rules;
638 -----------------------------------------------------------------------------
639 --
640 -- PROCEDURE check_interval
641 --
642 -- Check the difference between the timer interval and the actual interval
643 -- needed to process the current set of active business rules. A negative
644 -- difference stops the Business Rule Monitor so that the timer interval can
645 -- be increased. No difference or a positive difference sets the time to
646 -- wait before the next set of rules is processed.
647 --
648 -- IN
649 -- itemtype - type of the current item
650 -- itemkey - key of the current item
651 -- actid - process activity instance id
652 -- funcmode - function execution mode. this is set by the engine
653 -- as either 'RUN', 'CANCEL', 'TIMEOUT'
654 -- OUT
655 -- result - activity has completed with the indicated result:
656 --
657 -- COMPLETE:NOERROR
658 -- COMPLETE:NONCRITICAL
659 -- COMPLETE:CRITICAL
660 --
661 PROCEDURE check_interval
662 (
663 itemtype IN VARCHAR2,
664 itemkey IN VARCHAR2,
665 actid IN NUMBER,
666 funcmode IN VARCHAR2,
667 result IN OUT NOCOPY VARCHAR2
668 ) IS
669 l_start_time DATE;
670 l_timer_interval NUMBER;
671 l_difference NUMBER;
672 --
673 BEGIN
674 --
675 -- RUN mode - normal process execution
676 --
677 IF (funcmode = 'RUN') THEN
678 --
679 wf_engine.SetItemAttrText(
680 itemtype => itemtype,
681 itemkey => itemkey,
682 aname => 'SUBPROCESS_NAME',
683 avalue => 'CHECK_INTERVAL');
684 --
685 -- Get the start time and the actual interval and compute the
686 -- difference between the timer interval and the actual interval.
687 --
688 l_start_time := wf_engine.GetItemAttrDate(
689 itemtype => itemtype,
690 itemkey => itemkey,
691 aname => 'PROCESS_RULES_START_TIME');
692 --
693 l_timer_interval := wf_engine.GetItemAttrNumber(
694 itemtype => itemtype,
695 itemkey => itemkey,
696 aname => 'TIMER_INTERVAL');
697 --
698 IF l_start_time IS NULL OR l_timer_interval is NULL THEN
699 result := 'COMPLETE:NONCRITICAL';
700 RETURN;
701 END IF;
702 --
703 l_difference := l_timer_interval - (SYSDATE - l_start_time);
704 --
705 wf_engine.SetItemAttrNumber(
706 itemtype => itemtype,
707 itemkey => itemkey,
708 aname => 'INTERVAL_DIFF',
709 avalue => l_difference);
710 --
711 -- A negative difference stops the Business Rule Monitor so that the
712 -- system administrator can increase the timer interval and restart it.
713 --
714 IF l_difference < 0 THEN
715 result := 'COMPLETE:CRITICAL';
716 RETURN;
717 ELSE
718 --
719 -- Time allotted was enough or more than enough. Set the time to wait
720 -- before processing the next set of rules.
721 --
722 wf_engine.SetItemAttrNumber(
723 itemtype => itemtype,
724 itemkey => itemkey,
725 aname => 'WAIT_TIME',
726 avalue => l_difference);
727 --
728 result := 'COMPLETE:NOERROR';
729 RETURN;
730 END IF;
731 END IF;
732 --
733 -- CANCEL mode - activity 'compensation'
734 --
735 IF (funcmode = 'CANCEL') THEN
736 result := 'COMPLETE:NOERROR';
737 RETURN;
738 END IF;
739 --
740 -- TIMEOUT mode
741 --
742 IF (funcmode = 'TIMEOUT') THEN
743 result := 'COMPLETE:NOERROR';
744 RETURN;
745 END IF;
746 --
747 EXCEPTION
748 WHEN OTHERS THEN
749 wf_core.context('JTF_BRM_PVT', 'CHECK_INTERVAL',
750 itemtype, itemkey, to_char(actid), funcmode);
751 RAISE;
752 END check_interval;
753 -----------------------------------------------------------------------------
754 --
755 -- PROCEDURE get_brm_command
756 --
757 -- Get the current Business Rule Monitor command.
758 --
759 -- IN
760 -- itemtype - type of the current item
761 -- itemkey - key of the current item
762 -- actid - process activity instance id
763 -- funcmode - function execution mode. this is set by the engine
764 -- as either 'RUN', 'CANCEL', 'TIMEOUT'
765 -- OUT
766 -- result - activity has completed with the indicated result:
767 --
768 -- COMPLETE:NOERROR
769 -- COMPLETE:NONCRITICAL
770 -- COMPLETE:CRITICAL
771 --
772 PROCEDURE get_brm_command
773 (
774 itemtype IN VARCHAR2,
775 itemkey IN VARCHAR2,
776 actid IN NUMBER,
777 funcmode IN VARCHAR2,
778 result IN OUT NOCOPY VARCHAR2
779 ) IS
780 l_command_type fnd_lookups.lookup_type%TYPE;
781 l_command_code fnd_lookups.lookup_code%TYPE;
782 l_meaning fnd_lookups.meaning%TYPE;
783 l_found BOOLEAN;
784 l_now DATE := SYSDATE;
785 --
786 CURSOR c_command IS
787 SELECT brm_wf_command_type, brm_wf_command_code
788 FROM jtf_brm_parameters
789 WHERE workflow_process_id = itemkey;
790 --
791 CURSOR c_lookups(b_command_type fnd_lookups.lookup_type%TYPE,
792 b_command_code fnd_lookups.lookup_code%TYPE,
793 b_now DATE) IS
794 SELECT meaning
795 FROM fnd_lookups
796 WHERE lookup_type = b_command_type
797 AND lookup_code = b_command_code
798 AND enabled_flag = 'Y'
799 AND start_date_active <= b_now
800 AND nvl(end_date_active, b_now) >= b_now;
801 --
802 BEGIN
803 --
804 -- RUN mode - normal process execution
805 --
806 IF (funcmode = 'RUN') THEN
807 --
808 wf_engine.SetItemAttrText(
809 itemtype => itemtype,
810 itemkey => itemkey,
811 aname => 'SUBPROCESS_NAME',
812 avalue => 'GET_BRM_COMMAND');
813 --
814 OPEN c_command;
815 FETCH c_command
816 INTO l_command_type, l_command_code;
817 l_found := c_command%FOUND;
818 CLOSE c_command;
819 --
820 IF NOT l_found THEN
821 result := 'COMPLETE:CRITICAL';
822 RETURN;
823 ELSE
824 wf_engine.SetItemAttrText(
825 itemtype => itemtype,
826 itemkey => itemkey,
827 aname => 'COMMAND_TYPE',
828 avalue => l_command_type);
829 --
830 wf_engine.SetItemAttrText(
831 itemtype => itemtype,
832 itemkey => itemkey,
833 aname => 'COMMAND_CODE',
834 avalue => l_command_code);
835 --
836 OPEN c_lookups(l_command_type, l_command_code, l_now);
837 FETCH c_lookups INTO l_meaning;
838 l_found := c_lookups%FOUND;
839 CLOSE c_lookups;
840 --
841 IF NOT l_found THEN
842 result := 'COMPLETE:CRITICAL';
843 ELSE
844 wf_engine.SetItemAttrText(
845 itemtype => itemtype,
846 itemkey => itemkey,
847 aname => 'COMMAND',
848 avalue => l_meaning);
849 result := 'COMPLETE:NOERROR';
850 END IF;
851 RETURN;
852 END IF;
853 END IF;
854 --
855 -- CANCEL mode - activity 'compensation'
856 --
857 IF (funcmode = 'CANCEL') THEN
858 result := 'COMPLETE:NOERROR';
859 return;
860 END IF;
861 --
862 -- TIMEOUT mode
863 --
864 IF (funcmode = 'TIMEOUT') THEN
865 result := 'COMPLETE:NOERROR';
866 RETURN;
867 END IF;
868 --
869 EXCEPTION
870 WHEN OTHERS THEN
871 IF c_command%ISOPEN THEN
872 CLOSE c_command;
873 END IF;
874 IF c_lookups%ISOPEN THEN
875 CLOSE c_lookups;
876 END IF;
877 wf_core.context('JTF_BRM_PVT', 'GET_BRM_COMMAND',
878 itemtype, itemkey, to_char(actid), funcmode);
879 RAISE;
880 END get_brm_command;
881 -----------------------------------------------------------------------------
882 --
883 -- PROCEDURE stop_monitor
884 --
885 -- Check if there is a request to stop the Business Rule Monitor.
886 -- If so, set the stop time for the process.
887 --
888 -- IN
889 -- itemtype - type of the current item
890 -- itemkey - key of the current item
891 -- actid - process activity instance id
892 -- funcmode - function execution mode. this is set by the engine
893 -- as either 'RUN', 'CANCEL', 'TIMEOUT'
894 -- OUT
895 -- result - activity has completed with the indicated result:
896 --
897 -- COMPLETE:T
898 -- COMPLETE:F
899 --
900 PROCEDURE stop_monitor
901 (
902 itemtype IN VARCHAR2,
903 itemkey IN VARCHAR2,
904 actid IN NUMBER,
905 funcmode IN VARCHAR2,
906 result IN OUT NOCOPY VARCHAR2
907 ) IS
908 l_command VARCHAR2(30);
909 --
910 BEGIN
911 --
912 -- RUN mode - normal process execution
913 --
914 IF (funcmode = 'RUN') THEN
915 --
916 wf_engine.SetItemAttrText(
917 itemtype => itemtype,
918 itemkey => itemkey,
919 aname => 'SUBPROCESS_NAME',
920 avalue => 'STOP_MONITOR');
921 --
922 l_command := wf_engine.GetItemAttrText(
923 itemtype => itemtype,
924 itemkey => itemkey,
925 aname => 'COMMAND_CODE');
926 --
927 IF l_command = 'STOP' THEN
928 wf_engine.SetItemAttrDate(
929 itemtype => itemtype,
930 itemkey => itemkey,
931 aname => 'MONITOR_STOP_TIME',
932 avalue => SYSDATE);
933 --
934 result := 'COMPLETE:T';
935 ELSE
936 result := 'COMPLETE:F';
937 END IF;
938 RETURN;
939 END IF;
940 --
941 -- CANCEL mode - activity 'compensation'
942 --
943 IF (funcmode = 'CANCEL') THEN
944 result := 'COMPLETE:F';
945 RETURN;
946 END IF;
947 --
948 -- TIMEOUT mode
949 --
950 IF (funcmode = 'TIMEOUT') THEN
951 result := 'COMPLETE:T';
952 RETURN;
953 END IF;
954 --
955 EXCEPTION
956 WHEN OTHERS THEN
957 wf_core.context('JTF_BRM_PVT', 'STOP_MONITOR',
958 itemtype, itemkey, to_char(actid), funcmode);
959 RAISE;
960 END stop_monitor;
961 -----------------------------------------------------------------------------
962 --
963 -- PROCEDURE commit_wf
964 --
965 -- commits all runtime WF-data for the complete scan cycle and resets the
966 -- wf_savepoint. This will prevent the rollback segments from growing to
967 -- rediculous size
968 --
969 -- IN
970 -- itemtype - type of the current item
971 -- itemkey - key of the current item
972 -- actid - process activity instance id
973 -- funcmode - function execution mode ('RUN', 'CANCEL', 'TIMEOUT')
974 -- OUT
975 -- result - activity has completed with the indicated result:
976 --
977 -- COMPLETE:True
978 -- COMPLETE:False
979 --
980 PROCEDURE commit_wf(
981 itemtype IN VARCHAR2,
982 itemkey IN VARCHAR2,
983 actid IN NUMBER,
984 funcmode IN VARCHAR2,
985 result IN OUT NOCOPY VARCHAR2)
986 IS
987 BEGIN
988 --
989 -- RUN mode - normal process execution
990 --
991 IF (funcmode = 'RUN')
992 THEN
993 COMMIT;
994 SAVEPOINT wf_savepoint;
995 result := 'COMPLETE:T';
996 ELSE
997 result := 'COMPLETE:F';
998 END IF;
999 RETURN;
1000 EXCEPTION
1001 WHEN OTHERS THEN
1002 wf_core.context('JTF_BRM_PVT', 'COMMIT_WF',
1003 itemtype, itemkey, to_char(actid), funcmode);
1004 RAISE;
1005 END commit_wf;
1006 -----------------------------------------------------------------------------
1007
1008 END JTF_BRM_PVT;