DBA Data[Home] [Help]

PACKAGE BODY: APPS.FND_CONC_PRIVATE_UTILS

Source


1 package body FND_CONC_PRIVATE_UTILS as
2 /* $Header: AFCPSCRB.pls 120.6 2005/09/16 17:43:09 pferguso ship $ */
3 
4 -- FUNCTION get_fs_svc_name:
5 -- Gets the service name based on given node and the value of FS_SVC_PREVIX
6 -- profile option.
7 --
8 -- node is the node on which FNDFS is running
9 --
10 FUNCTION get_fs_svc_name(node IN VARCHAR2) RETURN VARCHAR2
11   IS
12      svc     varchar2(254);
13 
14 BEGIN
15    if (fnd_profile.defined('FS_SVC_PREFIX')) then
16      fnd_profile.get('FS_SVC_PREFIX', svc);
17      if (svc is not null) then
18        svc := substr(svc || node, 1, 254);
19      else
20        svc := 'FNDFS_' || node;
21      end if;
22    else
23      svc := 'FNDFS_' || node;
24    end if;
25 
26    RETURN svc;
27 
28 END get_fs_svc_name;
29 
30 
31 -- FUNCTION generate_req_out_URL:
32 -- Creates a URL for a report file, given a request ID.
33 --
34 -- req_id is the request id
35 --    So we know what file we're securing
36 --
37 -- lifetime is the number of minutes for which the URL is valid
38 --    After this time, VERIFY_ID will no longer consider the token
39 --    generated by the call to CREATE_ID to be valid.
40 --    Here we default to 1440 minutes = one day, since we're using this
41 --    function to secure a file which multiple users may want to see.
42 --
43 FUNCTION generate_req_out_URL(req_id IN NUMBER,
44 			                  lifetime IN NUMBER DEFAULT 1440) RETURN VARCHAR2
45   IS
46      base	VARCHAR2(257);
47      url	VARCHAR2(512);
48      fname      VARCHAR2(255);
49      node       VARCHAR2(50);
50      id	        VARCHAR2(32);
51      mtype  VARCHAR2(80);
52      fs_enabled VARCHAR2(2);
53      pos     number;
54      svc     varchar2(254);
55 BEGIN
56 
57    fnd_profile.get('APPS_WEB_AGENT', base);
58 
59    IF(base IS NULL) THEN
60       RETURN NULL;
61    END IF;
62 
63    SELECT fcr.outfile_name, fcr.outfile_node_name, fmt.mime_type
64      INTO fname, node, mtype
65      FROM fnd_concurrent_requests fcr, fnd_mime_types_vl fmt
66      WHERE fcr.request_id = req_id
67      AND   fcr.output_file_type = fmt.file_format_code
68      AND   rownum = 1;
69 
70    /* Bug 3322395: No longer limit FNDFS service prefix to 9
71       characters. Logic to get the service name for FNDFS is now
72       split into new function. Avoids duplication of code.  */
73 
74    svc := get_fs_svc_name(node);
75 
76    id := fnd_webfile.create_id(fname,
77                                svc,
78                                lifetime,
79                                mtype,
80                                req_id);
81 
82    base := Ltrim(Rtrim(base));
83 
84    -- Strip any file path from the base URL by truncating at the
85    -- third '/'.
86    -- This leaves us with something like 'http://ap363sun:8000'.
87 
88    pos := instr(base, '/', 1, 3);
89    if (pos > 0) then
90      base := substr(base, 1, pos - 1);
91    end if;
92 
93    -- 2638328 - security violation - removing login information from URL
94    url := base || '/OA_CGI/FNDWRR.exe?' || 'temp_id=' || id ;
95 
96    RETURN url;
97 
98 END generate_req_out_URL;
99 
100 
101 /*returns either error or (possibly null) resubmission time */
102 function get_resub_time(req_id in number) Return varchar2 is
103 
104 my_resub   varchar2(100);
105 dummy 	   number;
106 unit_code  varchar2(100);
107 type_code  varchar2(100);
108 resub_time varchar2(8);
109 resub_end  date;
110 req_sdate  date;
111 interval   number;
112 sysd	   date;
113 class_id   number;
114 class_app_id number;
115 class_type varchar2(1);
116 class_info varchar2(64);
117 found      number;
118 offset     number;
119 temp_date  date;
120 dow        number;
121 dom        number;
122 nextdom    number;
123 
124 begin
125 
126   /* are we wasting our time? */
127   select count(*) into dummy
128   from fnd_concurrent_requests
129   where request_id = req_id;
130 
131   if dummy = 0 then
132     return 'CONC-Request missing';
133   end if;
134 
135   /* get info */
136   select Resubmit_Time, Resubmit_Interval_Type_Code, Requested_Start_Date,
137          Resubmit_Interval_Unit_Code, Resubmit_Interval, sysdate,
138 	 RELEASE_CLASS_ID, RELEASE_CLASS_APP_ID, Resubmit_End_Date
139   into resub_time, type_code, req_sdate,
140 	unit_code, interval, sysd,
141 	class_id, class_app_id,resub_end
142   from fnd_concurrent_requests
143   where request_id = req_id;
144 
145 
146   /* get class info */
147   class_type := NULL;
148   class_info := NULL;
149 
150   if class_id is not null then
151     select C.class_type, C.class_info
152     into class_type, class_info
153     from fnd_conc_release_classes C
154     where RELEASE_CLASS_ID = class_id
155     and APPLICATION_ID = class_app_id;
156   end if;
157 
158   /* hack to take care of 'SMART' resubmission with complex schedules
159      basiclly we return the earliest period start  (of the periods involved
160      in the schedule) that is greater thensysdate.  If none then return sysdate
161      +1 ... Some nice to have improvements would be to use the stop times
162      for negated periods (instead of start times).  Also updating the start/stop
163      times so that at least the stop time occurs in the future.
164   */
165 
166   if (unit_code= 'SMART') then
167     select to_char(nvl(min(p.PERIOD_START_TIME),sysdate+1),
168 	'DD-MON-YYYY HH24:MI:SS')
169       into my_resub
170       from fnd_conc_rel_conj_members cm,
171       fnd_conc_rel_disj_members dm,
172       fnd_conc_release_periods p
173       where cm.DISJUNCTION_ID = dm.DISJUNCTION_ID
174       and cm.DISJUNCTION_APPLICATION_ID = dm.DISJUNCTION_APPLICATION_ID
175       and cm.release_class_id=class_id
176       and cm.class_APPLICATION_ID=class_app_id
177       and dm.PERIOD_OR_STATE_FLAG = 'P'
178       and dm.PERIOD_APPLICATION_ID = p.APPLICATION_ID
179       and dm.PERIOD_ID = p.concurrent_PERIOD_ID
180       and  P.PERIOD_START_TIME>sysdate;
181 
182     return my_resub;
183   end if;
184 
185 
186 
187   if class_type = 'S' then
188     temp_date := fnd_conc_release_class_utils.calc_specific_startdate(req_sdate, class_info);
189     if temp_date is null then
190        return null;
191     end if;
192     my_resub := to_char(temp_date, 'DD-MON-YYYY HH24:MI:SS');
193 
194 
195   else
196 
197     /* this will be resub time for all but type 'S' class types */
198 
199     select TO_CHAR(DECODE(resub_time,
200                    NULL, DECODE (type_code, 'START', req_sdate, sysd)
201 			  + DECODE(unit_code,
202 		/*		'MINUTES', GREATEST(interval, 1)/1440, */
203 				'MINUTES', interval/1440,
204 				'HOURS', interval/24,
205                                 'DAYS', interval,
206  				'MONTHS', ADD_MONTHS(
207 				   DECODE(type_code, 'START', req_sdate, sysd),
208 					interval) -
209 			           DECODE(type_code, 'START', req_sdate, sysd)),
210                   /*TIME*/ TO_DATE (TO_CHAR (sysd, 'DD-MON-YYYY')
211                       || ' ' || resub_time, 'DD-MON-YYYY HH24:MI:SS')
212                      + Decode(
213                   Sign(To_Date(To_Char(sysd, 'HH24:MI:SS'), 'HH24:MI:SS')
214                        - To_Date(resub_time, 'HH24:MI:SS')
215                       ), 1, 1, 0)), 'DD-MON-YYYY HH24:MI:SS')
216        into my_resub
217        from dual;
218 
219   end if;
220 
221   /* some fairly obvious reasons to quit */
222   if (interval is null  and resub_time is null and (class_type <> 'S')) or
223      (NVL(resub_end,sysd) < sysd) or
224      (NVL(resub_end,TO_DATE(my_resub,
225                                    'DD-MON-YYYY HH24:MI:SS')) <
226          TO_DATE(my_resub,
227                         'DD-MON-YYYY HH24:MI:SS')) then
228      return null;
229   end if;
230 
231  /***------------------------------------------------------------------
232  ** Make sure the requested_start_date for the next request is greater
233  ** than sysdate (e.g. if the system went down for a week, then cycle
234  ** through resub dates until we get one after sysdate.  */
235 
236  /* this will only be necessary for type_code = 'START' */
237 
238  while (sysd > to_date(my_resub,
239                               'DD-MON-YYYY HH24:MI:SS')) loop
240 
241     select TO_CHAR(TO_DATE(my_resub,
242                                   'DD-MON-YYYY HH24:MI:SS') +
243    /*  		DECODE(unit_code, 'MINUTES', GREATEST(interval, 1)/1440, */
244   		DECODE(unit_code, 'MINUTES', interval/1440,
245                                   'HOURS', interval/24,
246                                   'DAYS', interval,
247                                   'MONTHS', ADD_MONTHS(
248                                                 To_Date(my_resub,
249                                                                'DD-MON-YYYY HH24:MI:SS'),
250                                                 interval)
251                                            -  To_Date(my_resub,
252                                                              'DD-MON-YYYY HH24:MI:SS'))
253 		,'DD-MON-YYYY HH24:MI:SS')
254       into my_resub
255       from dual;
256  end loop;
257 
258  if (NVL(resub_end,TO_DATE(my_resub,
259                                   'DD-MON-YYYY HH24:MI:SS')) <
260                    TO_DATE(my_resub,
261                                   'DD-MON-YYYY HH24:MI:SS')) then
262     return null;
263  else return my_resub;
264  end if;
265 
266 end get_resub_time;
267 
268 -- Procedure added as bug fix for bug#4172657
269 Procedure set_notification_attr (nid in number ,
270 				requrl in varchar2,
271 				req_id in number,
272 				stat in varchar2,
273 				completion in date) is
274 
275 pname    varchar2(512);
276 user     varchar2(255);
277 pdesc    varchar2(240);
278 e_addr   varchar2(240);
279 wf_error exception;
280 begin
281 	   select u.user_name, r.description,
282 		   p.user_concurrent_program_name, u.email_address
283 	    into   user, pdesc, pname, e_addr
284 	    from   fnd_concurrent_requests r, fnd_concurrent_programs_vl p,
285 		   fnd_user u
286 	    where  r.program_application_id = p.application_id
287 	    and    r.concurrent_program_id = p.concurrent_program_id
288 	    and    r.request_id = req_id
289 	    and    u.user_id = r.requested_by;
290 
291 	    if (pdesc is not null) then
292 		pname := pdesc || '(' || pname || ')';
293 	    end if;
294 
295 
296 	    begin
297 
298 		if ( requrl is not NULL ) then
299 		    wf_notification.setattrtext(nid, 'REQ_URL', requrl);
300 		end if;
301 
302 		wf_notification.setattrnumber(nid, 'REQID', req_id);
303 		wf_notification.setattrtext(nid, 'STAT', RTRIM(stat));
304 		wf_notification.setattrtext(nid, 'PROGNAME', pname);
305 		wf_notification.setattrdate(nid, 'TIME', completion);
306 		wf_notification.setattrdate(nid, 'DATE', completion);
307 		wf_notification.setattrtext(nid, 'SUBMITTER', user);
308 		wf_notification.setattrtext(nid, '#FROM_ROLE', user);
309 		wf_notification.setattrtext(nid, '#WFM_REPLYTO', e_addr);
310 		wf_notification.denormalize_notification(nid);
311 	    exception
312 		when others then
313 		    raise wf_error;
314 	    end;
315 
316 
317 end set_notification_attr;
318 
319 function send_simple_done_msg(req_id     in number,
320                               stat in    varchar2,
321                               recip in   varchar2,
322                               completion in date,
323                               etext      out NOCOPY  varchar2,
324                               estack     out NOCOPY  varchar2
325                              ) return number is
326 
327 nid      number;         /*notification id*/
328 pname    varchar2(512);  /*progname*/
329 user     varchar2(255);  /*submitter*/
330 pdesc    varchar2(240);  /* prog description */
331 profbuf  varchar2(255);  /* buffer for profile value */
332 requrl   varchar2(255) := NULL;  /* URL for output */
333 url_ttl  number;         /* Time to live for url - in minutes */
334 ename    varchar2(30);   /* Error name returned by wf_core.get_error */
335 e_addr   varchar2(240);  /* email address of user */
336 wf_error exception;
337 msgname  varchar2(255);
338 msgtype  varchar2(255) := 'FNDCMMSG';
339 send_url boolean;
340 -- for bug 4535714
341 ofilesize      number;
342 saveoutputflag varchar2(1);
343 -- for bug 4172657
344 notify_id number;
345 
346 cursor nids_cursor is
347 	    select notification_id
348 	    from wf_notifications
349 	    where group_id = nid;
350 -- code for bug 4172657 ends
351 
352 begin
353     estack := '';
354     etext := '';
355 
356 -- bug4535714
357 -- get the output file size and save output flag here
358 -- output file may exist at this point but deleted later depending on flag
359 -- handling null as zero
360 
361     select decode(ofile_size,NULL,0,ofile_size), save_output_flag
362       into ofilesize, saveoutputflag
363     from fnd_concurrent_requests
364     where request_id = req_id;
365 
366 -- bug453714 ends
370     if profbuf = 'Y' then
367 
368     fnd_profile.get ('CONC_ATTACH_URL', profbuf);
369 
371 
372         fnd_profile.get ('CONC_URL_LIFETIME', profbuf);
373         url_ttl := to_number(profbuf);
374 
375         /* Note, we must set a default value for url_ttl.        *
376          * Stored procedure defaults only work for missing args, *
377          * not for null args.                                    */
378         if (url_ttl is null) then
379             url_ttl := 1440;
380         end if;
381 
382 -- bug4535714
383 -- if the filesize is zero or saveoutputflag is not set, don't send URL
384 -- as it will point to a zero size file and error
385 
386         if ofilesize > 0 and saveoutputflag='Y' then
387            msgname := 'REQ_COMPLETION_W_URL';
388            send_url := true;
389         else
390            msgname := 'SIMPLE_REQ_COMPLETION';
391            send_url := false;
392         end if;
393 -- bug4535714 end
394 
395     else
396         msgname := 'SIMPLE_REQ_COMPLETION';
397         send_url := false;
398 
399     end if;
400 
401     -- If this profile option is set, use the Workflow 'sendgroup' API
402     -- to send a notification to all members of the role.
403     fnd_profile.get('CONC_NOTIFY_GROUP', profbuf);
404 
405     begin
406         if profbuf = 'Y' then
407 	    nid := wf_notification.sendgroup(recip, msgtype, msgname);
408 	    open nids_cursor;
409 		LOOP
410 			fetch nids_cursor into notify_id;
411                            -- Get a unique file name each time
412                            if (send_url) then
413                               requrl := fnd_webfile.get_url(
414                                            fnd_webfile.request_out,
415                                            req_id, null, null, url_ttl);
416                            end if;
417 			   set_notification_attr (notify_id ,requrl,
418                                            req_id,stat,completion);
419 			 exit when nids_cursor%NOTFOUND;
420 		end LOOP;
421 
422 	    close nids_cursor;
423 	else
424            nid := wf_notification.send(recip, msgtype, msgname);
425 
426            -- Get a unique file name each time
427            if (send_url) then
428               requrl := fnd_webfile.get_url( fnd_webfile.request_out,
429                                            req_id, null, null, url_ttl);
430            end if;
431            set_notification_attr (nid ,requrl,req_id,stat,completion);
432 
433 	end if;
434 
435     exception
436         when others then
437             raise wf_error;
438     end;
439 
440 
441     return(nid);
442 
443 
444 exception
445     when wf_error then
446         wf_core.get_error(ename, etext, estack);
447         return(-1);
448     when others then
449         return(-2);
450 
451 end send_simple_done_msg;
452 
453 
454 procedure record_temp_file_use_pvt (filename in varchar2, type in varchar2,
455 	req_id in number, sess_id in number, node in varchar2) is
456 PRAGMA AUTONOMOUS_TRANSACTION;
457 
458 begin
459 	insert into fnd_temp_files
460 	   (FILENAME, TYPE, REQUEST_ID, SESSION_ID, NODE)
461 	values (filename, type, req_id, sess_id, node);
462         commit;
463 
464 exception
465   when others then null;
466 end record_temp_file_use_pvt;
467 
468 procedure record_temp_file_use(filename in varchar, node in varchar) is
469 
470 req_id number := null;
471 ses_id number := null;
472 type_code varchar2(1);
473 mynode varchar2(255);
474 
475 begin
476 
477     mynode := node;
478 
479     req_id := fnd_global.conc_request_id;
480     if req_id > 0 then
481        type_code := 'R';
482        if (mynode is null) then
483           /* let's try to guess the node */
484           begin
485 	     select LOGFILE_NODE_NAME
486 	     into mynode
487              from fnd_concurrent_requests
488 	     where request_id = req_id;
489           exception
490   		when others then null;
491           end;
492        end if;
493     else
494        req_id := null;
495        type_code := 'O';
496         select userenv('SESSIONID') into ses_id from dual;
497     end if;
498 
499     record_temp_file_use_pvt (filename, type_code, req_id, ses_id, node);
500 
501 exception
502 	when others then null;
503 
504 end record_temp_file_use;
505 
506 
507 Procedure call_pp_plsql(user_id in number,
508                         resp_id in number,
509                         resp_appl_id in number,
510                         security_group_id in number,
511                         site_id in number,
512                         login_id in number,
513                         conc_login_id in number,
514                         prog_appl_id in number,
515                         conc_program_id in number,
516                         conc_request_id in number,
517                         conc_priority_request in number,
518                         program in varchar2,
519                         step in number,
520                         errbuf out NOCOPY varchar2,
521                         retcode out NOCOPY number) is
522   PRAGMA AUTONOMOUS_TRANSACTION;
523   session_id number;
527   fnd_global.bless_next_init('FND_PERMIT_0003');
524   sql_string varchar2(255);
525   tmp_buff varchar2(2000);
526 begin
528   fnd_global.initialize (session_id, user_id, resp_id,
529              resp_appl_id, security_group_id, site_id, login_id,
530              conc_login_id, prog_appl_id, conc_program_id,
531              conc_request_id, conc_priority_request);
532 
533   sql_string := 'BEGIN ' || program ||
534                  '(:errbuf, :retcode, :step); END;';
535 
536 
537   execute immediate sql_string using out errbuf,out retcode, in step;
538 
542   if retcode is null then
539   /* If retcode is not set, then we'll assume success, since
540    * no exception was raised. */
541 
543     retcode := 0;
544   end if;
545 
546   return;
547 
548   /* The calling routing will handle exceptions. */
549 end call_pp_plsql;
550 
551 
552 
553 /*
554  * Switch a manager's resource consumer group to the group it is assigned to
555  * in FND_CONCURRENT_QUEUES, or the default group if one is not assigned.
556  */
557 procedure set_mgr_rcg(qaid in number, qid in number) is
558 
559 que_rcg            varchar2(32);
560 old_rcg            varchar2(32);
561 resource_mgr_off   exception;
562 
563 pragma exception_init(resource_mgr_off, -29373);
564 pragma autonomous_transaction;
565 
566 begin
567 
568   begin
569     select nvl(RESOURCE_CONSUMER_GROUP, 'DEFAULT_CONSUMER_GROUP')
570     into que_rcg
571     from fnd_concurrent_queues
572     where CONCURRENT_QUEUE_ID = qid
573     and   APPLICATION_ID = qaid;
574   exception
575     when others then
576       que_rcg := 'DEFAULT_CONSUMER_GROUP';
577   end;
578   dbms_session.switch_current_consumer_group(que_rcg, old_rcg, FALSE);
579 
580   commit;
581 
582 exception
583   -- Ignore this error, this means the user has not chosen to use the resource manager
584   when resource_mgr_off then
585     commit;
586 
587   when others then
588     if( FND_LOG.LEVEL_EXCEPTION >= FND_LOG.G_CURRENT_RUNTIME_LEVEL ) then
589 	  FND_MESSAGE.SET_NAME('FND', 'CONC-CANT SWITCH RCG');
590 	  FND_MESSAGE.SET_TOKEN('ROUTINE', 'SET_MGR_RCG');
591 	  FND_MESSAGE.SET_TOKEN('QID', qid);
592 	  FND_MESSAGE.SET_TOKEN('RCG', que_rcg);
593 	  FND_MESSAGE.SET_TOKEN('REASON', SQLERRM);
594 	  FND_LOG.MESSAGE(FND_LOG.LEVEL_EXCEPTION, 'fnd.plsql.FND_CONC_PRIVATE_UTILS.SET_MGR_RCG');
595 	end if;
596 	commit;
597 
598 end set_mgr_rcg;
599 
600 
601 /*
602  * Switch multiorg context
603  * Not for use in 11i
604  */
605 procedure set_multiorg_context(org_type in varchar2, org_id in number) is
606 
607 begin
608 
609    mo_global.init('M');
610    if ( org_type = 'S' ) then
611       mo_global.set_policy_context('S', org_id);
612    elsif ( org_type = 'M' ) then
613       mo_global.set_policy_context('M', null);
614    end if;
615 
616 
617 end set_multiorg_context;
618 
619 
620 
621 end FND_CONC_PRIVATE_UTILS;