DBA Data[Home] [Help]

PACKAGE BODY: APPS.WFA_HTML

Source


1 package body WFA_HTML as
2 /* $Header: wfhtmb.pls 120.5.12010000.4 2009/01/14 09:14:16 sudchakr ship $ */
3 
4 -- Bug# 2236250 exception to handle invalid number
5 invalid_number exception;
6 pragma EXCEPTION_INIT(invalid_number, -6502);
7 
8 
9 g_priority  varchar2(2000);
10 g_newline   varchar2(1)    := wf_core.newLine;
11 g_wfInstall varchar2(15)   := wf_core.translate('WF_INSTALL');
12 g_webAgent  varchar2(2000) := wf_core.translate('WF_WEB_AGENT');
13 
14 --
15 -- Error (PRIVATE)
16 --   Print a page with an error message.
17 --   Errors are retrieved from these sources in order:
18 --     1. wf_core errors
19 --     2. Oracle errors
20 --     3. Unspecified INTERNAL error
21 --
22 procedure Error
23 as
24 
25 begin
26      null;
27 end Error;
28 
29 
30 --
31 --
32 -- Login
33 --   Generate login page.
34 -- IN
35 --   message - optional login message
36 -- NOTE
37 --   This page is only used to enable access when no external security
38 --   is installed.  Normally users are authenticated by the chosen
39 --   security system (IC, WebServer native, etc) and can then access
40 --   the Workflow Notification pages (Worklist, Detail) directly.
41 --
42 procedure Login(
43   message in varchar2,
44   i_direct in varchar2)
45 as
46 
47 c_language    VARCHAR2(80);
48 
49 begin
50 
51   -- Get the global language preference since we don't know who the
52   -- user is yet...
53   c_language := NVL(wf_pref.get_pref ('-WF_DEFAULT-', 'LANGUAGE'), 'AMERICAN');
54   c_language := ''''||c_language||'''';
55   dbms_session.set_nls('NLS_LANGUAGE'   , c_language);
56 
57   -- Set the language to the default language for the system
58 
59   htp.htmlOpen;
60   htp.headOpen;
61   htp.title(wf_core.translate('WFA_LOGIN_REQUEST'));
62    wfa_html.create_help_function('wf/links/log.htm?LOGIN');
63   htp.headClose;
64   wfa_sec.Header(background_only=>FALSE, inc_lov_applet=>FALSE);
65 
66   htp.p('<FORM NAME="WFA_LOGIN" ACTION="wfa_html.Viewer" TARGET="_top" METHOD="POST">');
67 
68 -- bug 1838410
69    if (i_direct is not null) then
70        htp.formHidden('i_direct', i_direct);
71    end if;
72 
73 
74   if (message is not null) then
75     htp.header(4, wf_core.translate(message));
76     htp.br;
77   end if;
78 
79   htp.br;
80   htp.tableOpen(calign=>'CENTER', cattributes=>'summary=""');
81   htp.tableRowOpen;
82   htp.tableData('<LABEL FOR="i_user_id">' ||
83                 wf_core.translate('USER_ID') ||
84                 '</LABEL>', 'Right',
85                 cattributes=>'id=""');
86   htp.tableData(htf.formText('User_ID', 25, cattributes=>'id="i_user_id"'),
87                 'Left', cattributes=>'id=""');
88   htp.tableRowClose;
89 
90   htp.tableRowOpen;
91   htp.tableData('<LABEL FOR="i_password">' ||
92                 wf_core.translate('PASSWORD') ||
93                 '</LABEL>', 'Right',
94                 cattributes=>'id=""');
95   htp.tableData(htf.formPassword('Password', 25,
96                                  cattributes=>'id="i_password"'), 'Left',
97                 cattributes=>'id=""');
98   htp.tableRowClose;
99 
100   htp.tableClose;
101   htp.centerClose;
102   htp.br;
103 
104   htp.formClose;
105 
106   htp.tableopen (calign=>'CENTER', cattributes=>'summary=""');
107   htp.tableRowOpen;
108 
109   htp.p('<TD id="">');
110 
111   wfa_html.create_reg_button ('javascript:document.WFA_LOGIN.submit()',
112                               wf_core.translate ('LOGIN'),
113                               wfa_html.image_loc,
114                               'FNDJLFOK.gif',
115                               wf_core.translate ('LOGIN'));
116 
117   htp.p('</TD>');
118 
119   htp.tableRowClose;
120   htp.tableClose;
121 
122   wfa_sec.Footer;
123   htp.htmlClose;
124 exception
125   when others then
126     rollback;
127     wf_core.context('Wfa_Html', 'Login');
128     wfa_html.Error;
129 end Login;
130 
131 --
132 -- Viewer
133 --   Validate user from Login page, then show worklist.
134 -- IN
135 --   user_id  - user name
136 --   password - user password
137 -- NOTE
138 --   This page is only used to enable access when no external security
139 --   is installed.  Normally users are authenticated by the chosen
140 --   security system (IC, WebServer native, etc) and can then access
141 --   the Workflow Notification pages (Worklist, Detail) directly.
142 --
143 procedure Viewer(
144   user_id  in varchar2,
145   password in varchar2,
146   i_direct in varchar2)
147 as
148   s0          varchar2(320);   -- dummy
149   username    varchar2(320);
150   realname    varchar2(360);
151 
152 begin
153   -- Validate the user
154   if (user_id is null) then
155      -- No username entered
156      wfa_html.Login('WFA_ENTER_ID');
157      return;
158   end if;
159   username := upper(user_id);
160 
161   begin
162     wfa_sec.CreateSession(username, password);
163   exception
164     when others then
165       if (wf_core.error_name='WFSEC_USER_PASSWORD') then
166         -- Bad username or password
167         wf_core.clear;
168         wfa_html.Login('WFA_ILLEGAL_IDP');
169         return;
170       end if;
171       -- Raise any other error message
172       raise;
173   end;
174 
175 if (i_direct is null) then
176 
177   -- Go to home page
178   Wfa_Html.Home;
179 
180 else
181   -- Fix for bug 1838410
182   -- Instead of navigating to the home page, we will go directly to the URL
183   -- specified in i_direct and the user will now be authenticated.  We are
184   -- calling the function within a frame.
185   -- Example: E-mail notifications with send_accesskey=N.
186 
187   htp.p('<HTML>');
188   htp.p('<HEAD>');
189   htp.p('<TITLE>');
190   htp.p('</TITLE>');
191   htp.p('</HEAD>');
192   htp.p('<FRAMESET ROWS="100%, *">');
193   htp.p('<FRAME NAME="DirectLogin" MARGINHEIGHT=10 MARGINWIDTH=10 NORESIZE' ||
194     ' src="'||owa_util.get_owa_service_path || i_direct || '">');
195   htp.p('</FRAMESET>');
196   htp.p('</HTML>');
197 
198   end if;
199 
200 exception
201   when others then
202     rollback;
203     wf_core.context('Wfa_Html', 'Viewer', user_id, password);
204     wfa_html.Error;
205 end Viewer;
206 
207 
208 --
209 -- Find
210 --   Filter page to find notifications of user
211 --
212 procedure Find
213 is
214 begin
215            null;
216 end Find;
217 
218 --
219 -- GetPriorityBounds
220 --   Get the upper bound and lower bound of certain priority
221 -- IN
222 --   priority - Value of priority
223 --              Valid values are HIGH, NORMAL, LOW and *
224 -- IN OUT
225 --   low      - lower bound of numeric priority value
226 --   up       - upper bound of numeric priority value
227 -- RETURNS
228 --   TRUE     - successfully return the boundaries
229 --   FALSE    - failed to translate
230 --
231 function GetPriorityBounds(
232   priority in     varchar2,
233   low      in out nocopy pls_integer,
234   up       in out nocopy pls_integer)
235 return boolean
236 as
237 --  minint   pls_integer := 0;
238 --  maxint   pls_integer := 2147483647;  /* 2^31 - 1 */
239 
240 --
241 -- Priority Range should be 1 - 99
242 -- For supporting some possible out of range value in the past,
243 -- we set the range a bit higher
244 --
245   minint   pls_integer := 0;
246   maxint   pls_integer := 1000000;
247 begin
248   if    (priority = '*') then
249     low  := minint;
250     up   := maxint;
251   elsif (priority = 'HIGH') then
252     low  := minint;
253     up   :=  33;
254   elsif (priority = 'NORMAL') then
255     low  :=  34;
256     up   :=  66;
257   elsif (priority = 'LOW') then
258     low  :=  67;
259     up   := maxint;
260   else
261     low  :=  -1;
262     up   :=  -1;
263     return FALSE;
264   end if;
265   return TRUE;
266 end GetPriorityBounds;
267 
268 --
269 -- GetPriorityIcon
270 --   Get the icon of certain numeric priority
271 -- IN
272 --   priority - Value of priority
273 --              Valid values are minint - maxint
274 --              defined in GetPriorityBounds
275 --
276 -- RETURNS
277 --   Icon  - location of an icon
278 --
279 function GetPriorityIcon(
280   priority in     pls_integer)
281 return varchar2
282 as
283 begin
284   if    (priority < 34) /* HIGH   */ then
285     WFA_HTML.g_priority := WF_CORE.Translate('WFJSP_HIGH_PRIORITY');
286     return(wfa_html.image_loc||'high.gif');
287   elsif (priority > 66) /* LOW    */ then
288     WFA_HTML.g_priority := WF_CORE.Translate('WFJSP_LOW_PRIORITY');
289     return(wfa_html.image_loc||'low.gif');
290   else                  /* NORMAL */
291     return null;
292   end if;
293 end GetPriorityIcon;
294 
295 --
296 -- WorkList
297 --   Construct the worklist (summary page) for user.
298 -- IN
299 --   orderkey - Key to order by (default PRIORITY)
300 --              Valid values are PRIORITY, MESSAGE_TYPE, SUBJECT, BEGIN_DATE,
301 --              DUE_DATE, END_DATE, STATUS.
302 --   status - Status to query (default OPEN)
303 --            Valid values are OPEN, CLOSED, CANCELED, ERROR, *.
304 --   user - User to query notifications for.  If null query user currently
305 --          logged in.
306 --          Note: Only a user in role WF_ADMIN_ROLE can query a user other
307 --          than the current user.
308 --   fromlogin - flag to indicate if coming from apps login screen,
309 --             - if non-zero, force an exception
310 --            - so that cookie value is not being used
311 --
312 procedure WorkList(
313   nid      in number,
314   orderkey in varchar2,
315   status in varchar2,
316   owner in varchar2 ,
317   display_owner in varchar2,
318   user in varchar2,
319   display_user in varchar2,
320   fromuser in varchar2,
321   display_fromuser in varchar2,
322   ittype in varchar2,
323   msubject in varchar2,
324   beg_sent in varchar2,
325   end_sent in varchar2,
326   beg_due in varchar2,
327   end_due in varchar2,
328   priority in varchar2,
329   delegatedto in varchar2,
330   display_delegatedto in varchar2,
331   delegated_by_me in number,
332   resetcookie in number,
333   clearbanner in varchar2,
334   fromfindscreen in number,
335   fromlogin in number)
336 as
337 begin
338   null;
339 end Worklist;
340 
341 --
342 -- Authenticate (PRIVATE)
343 --   Verify user is allowed access to this notification
344 -- IN
345 --   nid - notification id
346 --   nkey - notification access key (if disconnected)
347 -- RETURNS
348 --   Current user name
349 --
350 function Authenticate(
351   nid in number,
352   nkey in varchar2)
353 return varchar2
354 is
355   usercolon pls_integer;
356   rolecolon pls_integer;
357   origcolon pls_integer;
358   username varchar2(320);
359   recipient varchar2(320);
360   orig_recipient varchar2(320);
361   dummy pls_integer;
362   admin_role varchar2(320);
363   slash pls_integer;
364   wfsession varchar2(240);
365 
366   uos   varchar2(320);
367   uosid number;
368   ros   varchar2(320);
369   rosid number;
370   oos   varchar2(320);
371   oosid number;
372 begin
373   if (nkey is null) then
374     -- No nkey passed, means must be connected.  Get current user.
375     Wfa_Sec.GetSession(username);
376 
377     -- Get recipient and original recipient of this notification
378     begin
379       select RECIPIENT_ROLE, ORIGINAL_RECIPIENT
380       into recipient, orig_recipient
381       from WF_NOTIFICATIONS WN
382       where WN.NOTIFICATION_ID = nid;
383     exception
384       when no_data_found then
385         Wf_Core.Token('NID', nid);
386         Wf_Core.Raise('WFNTF_NID');
387     end;
388 
389     -- Verify this notification was sent to this user
390     -- Note that username could be the in the recipient role
391     -- or in the original recipient role.
392     begin
393       usercolon := instr(username, ':');
394       rolecolon := instr(recipient, ':');
395       origcolon := instr(orig_recipient, ':');
396 
397       if (usercolon = 0) then
398         -- very costly sql statement, return the first row we find.
399         select ORIG_SYSTEM, ORIG_SYSTEM_ID
400           into uos, uosid
401           from WF_USERS
402          where NAME = username
403            and ORIG_SYSTEM not in ('HZ_PARTY','CUST_CONT')
404            and rownum < 2;
405       else
406          uos   := substr(username, 1, usercolon-1);
407          uosid := to_number(substr(username, usercolon+1));
408       end if;
409 
410       if (rolecolon = 0) then
411         -- when recipient = username, user is participate in the role of
412         -- the same name, they will have the same orig system and orig
413         -- system id.
414         if (recipient = username) then
415           ros   := uos;
416           rosid := uosid;
417         else
418           Wf_Directory.GetRoleOrigSysInfo(recipient,ros,rosid);
419         end if;
420       else
421         ros   := substr(recipient, 1, rolecolon-1);
422         rosid := to_number(substr(recipient, rolecolon+1));
423       end if;
424 
425       if (origcolon = 0) then
426         -- similarly, don't bother to requery the orig_system and
427         -- orig_system_id if original recipient matches recipient or username.
428         if (orig_recipient = recipient) then
429           oos   := ros;
430           oosid := rosid;
431         elsif (orig_recipient = username) then
432           oos   := uos;
433           oosid := uosid;
434         else
435           Wf_Directory.GetRoleOrigSysInfo(orig_recipient,oos,oosid);
436         end if;
437       else
438         oos   := substr(orig_recipient, 1, origcolon-1);
439         oosid := to_number(substr(orig_recipient, origcolon+1));
440       end if;
441 
442       -- rewritten the sql from an or join to union all.
443       -- reduced the query time from >25 sec to <0.5 sec.
444       select 1
445         into dummy
446         from sys.dual
447        where exists (
448          select null
449            from WF_USER_ROLES
450           where USER_ORIG_SYSTEM = uos
451             and USER_ORIG_SYSTEM_ID = uosid
452             and USER_NAME = username
453             and ROLE_ORIG_SYSTEM = ros
454             and ROLE_ORIG_SYSTEM_ID = rosid
455             and ROLE_NAME = recipient
456         union all
457          select null
458            from WF_USER_ROLES
459           where USER_ORIG_SYSTEM = uos
460             and USER_ORIG_SYSTEM_ID = uosid
461             and USER_NAME = username
462             and ROLE_ORIG_SYSTEM = oos
463             and ROLE_ORIG_SYSTEM_ID = oosid
464             and ROLE_NAME = orig_recipient
465         );
466 
467     exception
468       when no_data_found then
469         -- Check if current user has WF_ADMIN_ROLE privileges.
470         -- If so, allow access anyway.
471         admin_role := wf_core.translate('WF_ADMIN_ROLE');
472         if (admin_role <> '*' and
473             not Wf_Directory.IsPerformer(username, admin_role)) then
477         end if;
474           Wf_Core.Token('USER', username);
475           Wf_Core.Token('NID', to_char(nid));
476           Wf_Core.Raise('WFNTF_ACCESS_USER');
478     end;
479   else
480     -- Nkey passed, means this must be disconnected (mailed html).
481     -- Check the passed access key against the notification key.
482 
483     -- Construct wfsession-style access key as <nid>/<accesskey>.
484     -- First strip <nid> from nkey if present (only for backward
485     -- compatibility, current version only passes <accesskey>),
486     -- then construct full key with current nid.
487     -- Note: Key is reconstructed here instead of passing full
488     -- <nid>/<accesskey> directly to check that the key being passed
489     -- is really for this notification.
490     slash := instr(nkey, '/');
491     if (slash <> 0) then
492       wfsession := to_char(nid)||'/'||substr(nkey, slash+1);
493     else
494       wfsession := to_char(nid)||'/'||nkey;
495     end if;
496 
497     username := Wf_Notification.AccessCheck(wfsession);
498     if (username is null) then
499       wf_core.raise('WFNTF_ACCESS_KEY');
500     end if;
501   end if;
502 
503   return(username);
504 
505 exception
506   when others then
507     wf_core.context('Wfa_Html', 'Authenticate', to_char(nid), nkey);
508     raise;
509 end Authenticate;
510 
511 --
512 -- DetailFrame
513 --   generate Detail notification screen
514 -- IN
515 --   nid - notification id
516 --   nkey - notification access key (for mailed html only)
517 --   agent - web agent (OBSOLETE - for back compatibility only)
518 --   showforms - show form attributes
519 --
520 procedure DetailFrame(
521   nid in varchar2,
522   nkey in varchar2,
523   agent in varchar2,
524   showforms in varchar2)
525 as
526   slash     pls_integer;
527   col       pls_integer;
528   first_doc boolean := TRUE;
529   wfsession varchar2(240);
530   link_name varchar2(240);
531   username varchar2(320);
532   disprole varchar2(320);
533   titlerole varchar2(320);
534   s0       varchar2(2000);
535   link_text varchar2(2000);
536   comment_title varchar2(2000);
537   l_document_attributes   fnd_document_management.fnd_document_attributes;
538   l_status  boolean := FALSE;
539   cnt       pls_integer := 0;
540   end_of_text  boolean :=FALSE;
541   msgbody   varchar2(32000);
542   pseudo_login boolean := FALSE;
543   sess_username varchar2(320);
544   l_subject     varchar2(2000);
545   l_forms_port  varchar2(120);
546 
547   -- Select notification info
548   cursor notcurs is
549     select WN.STATUS,
550            WN.RECIPIENT_ROLE,
551            WN.ORIGINAL_RECIPIENT,
552            WN.PRIORITY,
553            WN.BEGIN_DATE,
554            WN.DUE_DATE,
555            WN.END_DATE,
556            WIT.DISPLAY_NAME message_type,
557            WL.MEANING disp_status,
558            WN.USER_COMMENT,
559            WN.FROM_USER,
560            WN.TO_USER,
561            WN.SUBJECT,
562            WN.LANGUAGE
563     from WF_NOTIFICATIONS WN, WF_ITEM_TYPES_VL WIT, WF_LOOKUPS WL
564     where WN.NOTIFICATION_ID = to_number(nid)
565     and WN.MESSAGE_TYPE = WIT.NAME
566     and WL.LOOKUP_TYPE = 'WF_NOTIFICATION_STATUS'
567     and WN.STATUS = WL.LOOKUP_CODE;
568 
569   notrec notcurs%rowtype;
570 
571 
572   -- Select attr values, formatting numbers and dates as requested.
573   -- The order-by is to handle cases where one attr name is a substring
574   -- of another.
575   cursor notification_attrs_cursor(nid number) is
576     select WNA.NAME, WMA.TYPE, WMA.FORMAT, WMA.DISPLAY_NAME,
577            WNA.TEXT_VALUE
578     from WF_NOTIFICATION_ATTRIBUTES WNA, WF_NOTIFICATIONS WN,
579          WF_MESSAGE_ATTRIBUTES_VL WMA
580     where WNA.NOTIFICATION_ID = nid
581     and WN.NOTIFICATION_ID = WNA.NOTIFICATION_ID
582     and WN.MESSAGE_TYPE = WMA.MESSAGE_TYPE
583     and WN.MESSAGE_NAME = WMA.MESSAGE_NAME
584     and WMA.NAME = WNA.NAME
585     and WMA.TYPE IN ('DOCUMENT', 'URL')
586     and WMA.ATTACH = 'Y'
587     and WNA.TEXT_VALUE IS NOT NULL
588     and WMA.SUBTYPE = 'SEND'
589     order by length(WNA.NAME) desc;
590 
591   -- similar to the above except FORMS do not set ATTACH to Y
592   cursor ntf_forms_attrs_cursor(nid number) is
593     select WNA.NAME, WMA.TYPE, WMA.FORMAT, WMA.DISPLAY_NAME,
594            WNA.TEXT_VALUE
595     from WF_NOTIFICATION_ATTRIBUTES WNA, WF_NOTIFICATIONS WN,
596          WF_MESSAGE_ATTRIBUTES_VL WMA
597     where WNA.NOTIFICATION_ID = nid
598     and WN.NOTIFICATION_ID = WNA.NOTIFICATION_ID
599     and WN.MESSAGE_TYPE = WMA.MESSAGE_TYPE
600     and WN.MESSAGE_NAME = WMA.MESSAGE_NAME
601     and WMA.NAME = WNA.NAME
602     and WMA.TYPE = 'FORM'
603     and WNA.TEXT_VALUE IS NOT NULL
604     and WMA.SUBTYPE = 'SEND'
605     order by length(WNA.NAME) desc;
606 
607   error_name      varchar2(30);
608   error_stack     varchar2(32000);
609 begin
610 
611   -- Authenticate user
612   username := Wfa_Html.Authenticate(to_number(nid), nkey);
613 
614   if (nkey is not null) then
615     -- Set a cookie for future IC access.
616 
617     -- Construct wfsession-style access key as <nid>/<accesskey>.
621     -- Note: Key is reconstructed here instead of passing full
618     -- First strip <nid> from nkey if present (only for backward
619     -- compatibility, current version only passes <accesskey>),
620     -- then construct full key with current nid.
622     -- <nid>/<accesskey> directly to check that the key being passed
623     -- is really for this notification.
624     slash := instr(nkey, '/');
625     if (slash <> 0) then
626       wfsession := nid||'/'||substr(nkey, slash+1);
627     else
628       wfsession := nid||'/'||nkey;
629     end if;
630 
631     /*
632     ** Create the ICX psuedo session so ICX does not recreate the psuedo
633     ** session.
634     ** But first check to see if there is a current session
635     */
636     begin
637       wfa_sec.validate_only := TRUE;
638       wfa_sec.GetSession(sess_username);
639       if (sess_username <> 'ANONYMOUS' and sess_username <> '-1'
640           and sess_username is not null) then
641         -- there is a valid session already, just use it
642         username := sess_username;
643       else
644         -- username -1 meant user had logged out.  Do this to reset the page.
645         if (sess_username = '-1') then
646           owa_util.showpage;
647         end if;
648 
649         -- create a pseudo session for user
650         owa_util.mime_header('text/html', FALSE);
651         owa_cookie.send('WF_SESSION', wfsession, '', '/');
652         wfa_sec.PseudoSession(FALSE, username);
653         owa_util.http_header_close;
654       end if;
655     exception
656       when OTHERS then
657         -- this is the first attempt to see a detached notfication
658         wf_core.clear;
659         owa_util.mime_header('text/html', FALSE);
660         owa_cookie.send('WF_SESSION', wfsession, '', '/');
661         wfa_sec.PseudoSession(FALSE, username);
662         owa_util.http_header_close;
663     end;
664     wfa_sec.validate_only := FALSE;
665 
666     pseudo_login := TRUE;
667   end if;
668 
669   -- Get notification info
670   open notcurs;
671   fetch notcurs into notrec;
672   if (notcurs%notfound) then
673     close notcurs;
674     wf_core.token('NID', nid);
675     wf_core.raise('WFNTF_NID');
676   end if;
677   close notcurs;
678 
679   if (notrec.language = userenv('LANG')) then
680     disprole := notrec.to_user;
681     l_subject := wf_core.substitutespecialchars(notrec.subject);
682   else
683     Wf_Directory.GetRoleInfo(notrec.recipient_role, disprole, s0, s0, s0, s0);
684     l_subject := Wf_Notification.GetSubject(to_number(nid));
685   end if;
686   titlerole := disprole;
687 
688   --
689   -- Header and Page Title
690   --
691   htp.htmlOpen;
692   htp.headOpen;
693 
694   fnd_document_management.get_open_dm_display_window;
695 
696   if (notrec.status = 'OPEN') then
697     htp.title(wf_core.translate('WFA_DTITLE')||' '||titlerole);
698   else
699     htp.title(wf_core.translate('WFA_CDTITLE')||' '||titlerole);
700   end if;
701   wfa_html.create_help_function('wf/links/det.htm?DETNOT');
702 
703   -- Make sure the resulting link puts on the top window.
704   htp.p('<BASE TARGET="_top">');
705   htp.headClose;
706   htp.p('<!-- debug info -->');
707   htp.p('<!--  username='||username||' -->');
708   htp.p('<!--  userenv(LANGUAGE)='||userenv('LANGUAGE')||' -->');
709   htp.p('<!--  nid="'||nid||'" -->');
710   htp.p('<!--  nkey="'||nkey||'" -->');
711   htp.p('<!--  previous session user="'||sess_username||'" -->');
712 
713   if (nkey is null) then
714     wfa_sec.Header(FALSE, owa_util.get_owa_service_path ||'wfa_html.Find',
715            wf_core.translate('WFA_DTITLE_TBAR'), FALSE, pseudo_login);
716   else
717     -- disabled Find for detached notification
718     wfa_sec.Header(FALSE, null,
719            wf_core.translate('WFA_DTITLE_TBAR'), FALSE, pseudo_login);
720   end if;
721 
722   htp.tableOpen(cattributes=>'WIDTH=100% summary=""', calign=>'CENTER');
723 
724   --
725   -- LINE 0: from user  if it is not null
726   --
727   if (notrec.from_user is not null) then
728     htp.tableRowOpen(cvalign=>'Baseline');
729     htp.tableData(cvalue=>wf_core.translate('FROM'),
730                   calign=>'right', cattributes=>'id=""');
731     htp.tableHeader(cvalue=>notrec.from_user,
732                     cnowrap=>1,
733                     calign=>'left', cattributes=>'BGCOLOR=WHITE WIDTH="*" id=""');
734     htp.tableRowClose;
735   end if;
736 
737   --
738   -- LINE 1: (begin_date -> end_date)
739   --
740   htp.tableRowOpen(cvalign=>'Baseline');
741 
742   -- Always print Sent To and begin_date
743   htp.tableData(cvalue=>wf_core.translate('TO'),
744                 calign=>'right', cattributes=>'id=""');
745   htp.tableHeader(cvalue=>disprole,
746                   cnowrap=>1,
747                   calign=>'left', cattributes=>'BGCOLOR=WHITE WIDTH="*" id=""');
748   htp.tableData(cvalue=>wf_core.translate('BEGIN_DATE'),
749                 calign=>'right', cattributes=>'id=""');
750   htp.tableHeader(cvalue=>to_char(notrec.begin_date)||
751                           to_char(notrec.begin_date, ' HH24:MI:SS'),
752                   cnowrap=>1,
756 
753                   calign=>'left', cattributes=>'BGCOLOR=WHITE WIDTH="25%" id=""');
754   -- keep track of columns in first row of table
755   col := 4;
757   -- Due: <due_date>
758   --   Do not print Due Date if it is null
759   if (to_char(notrec.due_date) is not null) then
760     htp.tableData(cvalue=>wf_core.translate('DUE_DATE'),
761                   calign=>'right', cattributes=>'id=""');
762     htp.tableHeader(cvalue=>to_char(notrec.due_date)||
763                             to_char(notrec.due_date, ' HH24:MI:SS'),
764                     cnowrap=>1,
765                     calign=>'left', cattributes=>'BGCOLOR=WHITE WIDTH="25%" id=""');
766     col := col+2;
767   end if;
768 
769   -- Closed: <end_date> (only if not open)
770   if (notrec.status <> 'OPEN') then
771     if (notrec.status = 'CANCELED') then
772       htp.tableData(cvalue=>wf_core.translate('CANCELED'),
773                     calign=>'right', cattributes=>'id=""');
774     else
775       htp.tableData(cvalue=>wf_core.translate('END_DATE'),
776                     calign=>'right', cattributes=>'id=""');
777     end if;
778     htp.tableHeader(cvalue=>to_char(notrec.end_date)||
779                             to_char(notrec.end_date, ' HH24:MI:SS'),
780                     cnowrap=>1,
781                     calign=>'left', cattributes=>'BGCOLOR=WHITE WIDTH="25%" id=""');
782     col := col+2;
783   end if;
784   htp.tableRowClose;
785 
786 
787   --
788   -- Subject: <subject>
789   --
790   htp.tableRowOpen(cvalign=>'Baseline');
791   htp.tableData(cvalue=>wf_core.translate('SUBJECT'),
792                 calign=>'right', cattributes=>'id=""');
793 
794   --make colspan 1 less than col because 1 col is taken up by "subject"
795   htp.tableHeader(cvalue=>l_subject,
796                   calign=>'left',
797                   ccolspan=>col-1,
798                   cattributes=>'BGCOLOR=WHITE id=""');
799   htp.tableRowClose;
800   htp.tableClose;
801 
802   --
803   -- COMMENTS
804   --
805   if (notrec.user_comment is not null) then
806     htp.p(wf_core.translate('COMMENTS')||':');
807     htp.tableOpen(cattributes=>'WIDTH=100% BGCOLOR=WHITE summary=""');
808     htp.tableRowOpen;
809     htp.p('<TD ALIGN="left" id="' || WF_CORE.Translate('COMMENTS') ||
810           '">');
811     htp.bold(replace(wf_core.substitutespecialchars(notrec.user_comment),
812                      wf_core.newline, htf.br||wf_core.newline));
813     htp.p('</TD>');
814     htp.tableRowClose;
815     htp.tableClose;
816   end if;
817 
818   --
819   -- BODY
820   --
821   htp.hr;
822   htp.tableOpen(cattributes=>'WIDTH=100% BGCOLOR=WHITE summary=""');
823   htp.tableRowOpen;
824 
825   end_of_text:=FALSE;
826   -- print message body. This may be in sections.
827   htp.p('<TD  ALIGN="left" id="">');
828   while not (end_of_text) loop
829        wf_notification.getfullbody(to_number(nid),msgbody,end_of_text,
830                                  wf_notification.doc_html);
831        htp.prn(msgbody);
832   end loop;
833   htp.p('</TD>');
834 
835   htp.tableRowClose;
836   htp.tableClose;
837 
838   htp.br;
839 
840   for not_attr_row in notification_attrs_cursor(nid) loop
841 
842      if (first_doc = TRUE) then
843 
844         htp.hr;
845         htp.br;
846         htp.tableopen(cattributes=>'BORDER=0 cellpadding=0 cellspacing=0 summary=""');
847         htp.tablerowopen;
848         first_doc := FALSE;
849 
850      end if;
851 
852      if (not_attr_row.type = 'DOCUMENT') then
853 
854         if (UPPER(SUBSTR(not_attr_row.text_value, 1, 2)) = 'DM') then
855 
856            /*
857            ** Get the HTML text for displaying the document
858            */
859            fnd_document_management.get_launch_document_url (
860               username,
861               not_attr_row.text_value,
862               FALSE,
863               link_text);
864 
865            link_text :=  '<A HREF="'||link_text||
866                  '" TARGET="'||not_attr_row.format||'">'||
867                  '<IMG SRC="'||wfa_html.image_loc||'afdsktop.gif" alt="' ||
868                  WF_CORE.Translate('WFITD_ATTR_TYPE_DOCUMENT') || '" BORDER=no></A>';
869 
870         elsif (UPPER(SUBSTR(not_attr_row.text_value, 1, 5)) = 'PLSQL') then
871 
872             if (nkey is null) then
873               link_text := '<A HREF="'||
874                  wfa_html.base_url||'/wfa_html.show_plsql_doc'||
875                  '?nid='||nid||'&aname='||not_attr_row.name||
876                  '" TARGET="'||not_attr_row.format||'">'||
877                  '<IMG SRC="'||wfa_html.image_loc||'afdsktop.gif" alt="' ||
878                  WF_CORE.Translate('WFITD_ATTR_TYPE_DOCUMENT') || '" BORDER=no></A>';
879             else
880               link_text := '<A HREF="'||
881                  wfa_html.base_url||'/wfa_html.show_plsql_doc'||
882                  '?nid='||nid||'&aname='||not_attr_row.name||'&nkey='||nkey||
883                  '" TARGET="'||not_attr_row.format||'">'||
884                  '<IMG SRC="'||wfa_html.image_loc||'afdsktop.gif" alt="' ||
885                  WF_CORE.Translate('WFITD_ATTR_TYPE_DOCUMENT') || '" BORDER=no></A>';
886             end if;
887 
888         end if;
889 
890      elsif (not_attr_row.type = 'URL') then
891 
895         -- Bug 4634849
892         link_text := wf_notification.geturltext(not_attr_row.text_value, nid);
893         link_text := wf_notification.SetFrameworkAgent(link_text);
894 
896         -- Do not display potentially harmful url
897         begin
898           if (not wf_core.CheckIllegalChars(link_text,true)) then
899             link_text := '<A HREF="'||link_text||
900                  '" TARGET="'||not_attr_row.format||'">'||
901                  '<IMG SRC="'||wfa_html.image_loc||'afdsktop.gif" alt="' ||
902                  WF_CORE.Translate('WFITD_ATTR_TYPE_DOCUMENT') || '" BORDER=no></A>';
903           end if;
904         exception
905           when OTHERS then
906             wf_core.get_error(error_name, link_text, error_stack);
907 
908             link_text :=wf_core.substitutespecialchars(link_text);
909             error_stack:= '';
910         end;
911 
912      end if;
913 
914      htp.tabledata(cvalue=>link_text, calign=>'CENTER', cattributes=>'id=""');
915 
916      htp.tabledata(cvalue=>'   ', calign=>'CENTER', cattributes=>'id=""');
917 
918   end loop;
919 
920   if (showforms is not null) then
921     for not_attr_row in ntf_forms_attrs_cursor(nid) loop
922        if (first_doc = TRUE) then
923 
924           htp.hr;
925           htp.br;
926           htp.tableopen(cattributes=>'BORDER=0 cellpadding=0 cellspacing=0 summary=""');
927           htp.tablerowopen;
928           first_doc := FALSE;
929 
930        end if;
931 
932        --Check the SOCKET_LISTENER_PORT profile option.
933        l_forms_port :=
934               Wfa_Sec.Get_Profile_Value('SOCKET_LISTENER_PORT',username);
935 
936        htp.p('<TD ALIGN="CENTER" id="">');
937          Wf_Forms.Applet(
938            fname=>Wf_Notification.GetShortText(not_attr_row.text_value, nid),
939            status=>l_status,
940            dispname=>not_attr_row.display_name,
941            port=>nvl(l_forms_port, '0'));
942        htp.p('</TD>');
943        htp.tabledata(cvalue=>'   ', calign=>'CENTER', cattributes=>'id=""');
944        if (not l_status) then
945          cnt := cnt + 1;
946        end if;
947     end loop;
948   end if;
949 
950 
951   -- If you found a row then close the table row you opened and open a new
952   -- one for the document title
953   if (first_doc = FALSE) then
954 
955      htp.tableRowClose;
956      htp.tablerowopen;
957 
958   end if;
959 
960   for not_attr_row in notification_attrs_cursor(nid) loop
961 
962      if (not_attr_row.type = 'DOCUMENT') then
963 
964         if (UPPER(SUBSTR(not_attr_row.text_value, 1, 2)) = 'DM') then
965 
966            /*
967            ** Get the HTML text for displaying the document
968            */
969            fnd_document_management.get_launch_document_url (
970               username,
971               not_attr_row.text_value,
972               FALSE,
973               link_text);
974 
975            link_text :=  '<A HREF="'||link_text||
976                  '" TARGET="'||not_attr_row.format||'">'||
977                  not_attr_row.display_name||
978                  '</A>';
979 
980 
981         elsif (UPPER(SUBSTR(not_attr_row.text_value, 1, 5)) = 'PLSQL') then
982 
983             if (nkey is null) then
984               link_text := '<A HREF="'||
985                  wfa_html.base_url||'/wfa_html.show_plsql_doc'||
986                  '?nid='||nid||'&aname='||not_attr_row.name||
987                  '" TARGET="'||not_attr_row.format||'">'||
988                  not_attr_row.display_name||'</A>';
989             else
990               link_text := '<A HREF="'||
991                  wfa_html.base_url||'/wfa_html.show_plsql_doc'||
992                  '?nid='||nid||'&aname='||not_attr_row.name||'&nkey='||nkey||
993                  '" TARGET="'||not_attr_row.format||'">'||
994                  not_attr_row.display_name||'</A>';
995             end if;
996         end if;
997 
998      elsif (not_attr_row.type = 'URL') then
999 
1000          link_text := wf_notification.geturltext(not_attr_row.text_value, nid);
1001          link_text := wf_notification.SetFrameworkAgent(link_text);
1002 
1003          -- Bug 4634849
1004          -- Do not display potentially harmful url
1005          begin
1006            if (not wf_core.CheckIllegalChars(link_text,true)) then
1007              link_text := '<A HREF="'||link_text||
1008                  '" TARGET="'||not_attr_row.format||'">'||
1009                  not_attr_row.display_name||'</A>';
1010 
1011            end if;
1012          exception
1013            when OTHERS then
1014              wf_core.get_error(error_name, link_text, error_stack);
1015 
1016              link_text :=wf_core.substitutespecialchars(link_text);
1017              error_stack:= '';
1018          end;
1019      end if;
1020 
1021      htp.tabledata(cvalue=>link_text, calign=>'CENTER', cattributes=>'id=""');
1022 
1023      htp.tabledata(cvalue=>'   ', calign=>'CENTER', cattributes=>'id=""');
1024 
1025   end loop;
1026 
1027   if (showforms is not null) then
1028     for not_attr_row in ntf_forms_attrs_cursor(nid) loop
1029        htp.p('<TD ALIGN="CENTER" id="">');
1030          htp.p(not_attr_row.display_name);
1031        htp.p('</TD>');
1035   end if;
1032        htp.tabledata(cvalue=>'   ', calign=>'CENTER',
1033                      cattributes=>'id=""');
1034     end loop;
1036 
1037   -- If you found a row then close the table row you opened and open a new
1038   -- one for the document title
1039   if (first_doc = FALSE) then
1040      htp.tableRowClose;
1041      htp.tableClose;
1042   end if;
1043 
1044   --
1045   -- Print warning message
1046   --
1047   if (cnt > 0) then
1048     htp.p('<P>'||wf_core.translate('WF_EXECUTE_FORM_FAILED'));
1049     htp.br;
1050   end if;
1051 
1052   --
1053   -- Page footer
1054   --
1055   Wfa_Sec.Footer;
1056   htp.htmlClose;
1057 
1058 exception
1059   when others then
1060     rollback;
1061     wf_core.context('Wfa_Html', 'DetailFrame', nid, nkey);
1062     wfa_html.Error;
1063 end DetailFrame;
1064 
1065 --
1066 -- ResponseFrame
1067 --   generate response frame contents
1068 -- IN
1069 --   nid - notification id
1070 --   nkey - notification access key (for mailed html only)
1071 --   agent - web agent (OBSOLETE - for back compatibility only)
1072 --   showforms - show form attributes
1073 --
1074 procedure ResponseFrame(
1075   nid in varchar2,
1076   nkey in varchar2,
1077   agent in varchar2,
1078   showforms in varchar2)
1079 as
1080   username varchar2(320);
1081   recipient varchar2(320);
1082   realname varchar2(360);
1083   status   varchar2(8);
1084   s0       varchar2(2000);
1085 --  url_str  varchar2(240);
1086   l_status boolean := FALSE;
1087   cnt      pls_integer := 0;
1088   pseudo_login boolean := FALSE;
1089   l_forms_port  varchar2(120);
1090 
1091   cursor attrs(resultflag in varchar2, typeflag in varchar2) is
1092     select MA.NAME,
1093            MA.DISPLAY_NAME,
1094            MA.DESCRIPTION,
1095            -- remove quotes for onmouse over java func
1096            replace(MA.DESCRIPTION,'''') description2,
1097            NA.TEXT_VALUE,
1098            NA.NUMBER_VALUE,
1099            NA.DATE_VALUE,
1100            MA.TYPE,
1101            MA.FORMAT
1102     from WF_NOTIFICATION_ATTRIBUTES NA,
1103          WF_MESSAGE_ATTRIBUTES_VL MA,
1104          WF_NOTIFICATIONS N
1105     where N.NOTIFICATION_ID = to_number(ResponseFrame.nid)
1106     and NA.NOTIFICATION_ID = N.NOTIFICATION_ID
1107     and MA.MESSAGE_NAME = N.MESSAGE_NAME
1108     and MA.MESSAGE_TYPE = N.MESSAGE_TYPE
1109     and MA.NAME = NA.NAME
1110     and MA.SUBTYPE = 'RESPOND'
1111     and MA.TYPE <> 'FORM'
1112     and ((resultflag = 'RESULT' and MA.NAME = 'RESULT') or
1113          (resultflag <> 'RESULT' and MA.NAME <> 'RESULT'))
1114     and MA.TYPE = decode(typeflag, '', MA.TYPE, typeflag)
1115     order by MA.SEQUENCE;
1116 
1117   cursor forms_attrs is
1118     select MA.NAME,
1119            MA.DISPLAY_NAME,
1120            MA.DESCRIPTION,
1121            -- remove quotes for onmouse over java func
1122            replace(MA.DESCRIPTION,'''') description2,
1123            NA.TEXT_VALUE
1124     from WF_NOTIFICATION_ATTRIBUTES NA,
1125          WF_MESSAGE_ATTRIBUTES_VL MA,
1126          WF_NOTIFICATIONS N
1127     where N.NOTIFICATION_ID = to_number(ResponseFrame.nid)
1128     and NA.NOTIFICATION_ID = N.NOTIFICATION_ID
1129     and MA.MESSAGE_NAME = N.MESSAGE_NAME
1130     and MA.MESSAGE_TYPE = N.MESSAGE_TYPE
1131     and MA.NAME = NA.NAME
1132     and MA.SUBTYPE = 'RESPOND'
1133     and MA.TYPE = 'FORM'
1134     order by MA.SEQUENCE;
1135 
1136   result attrs%rowtype;
1137 
1138   dvalue varchar2(2000);
1139   respcnt pls_integer;
1140   urlcount pls_integer;
1141   urlstring varchar2(4000);
1142   result_count pls_integer;
1143   resp_lbl varchar2(80);
1144 
1145   colon pls_integer;
1146 
1147   dmstype varchar2(30) := '';
1148   document varchar2(32000) := '';
1149 
1150   hide_button varchar2(1);
1151   sess_username varchar2(320);
1152 
1153 begin
1154   -- Authenticate user
1155   username := Wfa_Html.Authenticate(to_number(nid), nkey);
1156   Wf_Notification.GetInfo(to_number(nid), recipient, s0, s0, s0, s0, status);
1157   Wf_Directory.GetRoleInfo(recipient, realname, s0, s0, s0, s0);
1158 
1159   -- if nkey is not null, it is from email, and we need to create a pseudo
1160   -- session for it.
1161   if (nkey is not null) then
1162     begin
1163       wfa_sec.validate_only := TRUE;
1164       wfa_sec.GetSession(sess_username);
1165       if (sess_username <> 'ANONYMOUS' and sess_username <> '-1'
1166           and sess_username is not null) then
1167         -- there is a valid session already, just use it
1168         username := sess_username;
1169       else
1170         -- username -1 meant user had logged out.  Do this to reset the page.
1171         if (sess_username = '-1') then
1172           owa_util.showpage;
1173         end if;
1174 
1175         -- create a pseudo session for user
1176         owa_util.mime_header('text/html', FALSE);
1177         wfa_sec.PseudoSession(FALSE, username);
1178       end if;
1179     exception
1180       when OTHERS then
1181         -- this is the first attempt to see a detached notfication
1182         wf_core.clear;
1186     wfa_sec.validate_only := FALSE;
1183         owa_util.mime_header('text/html', FALSE);
1184         wfa_sec.PseudoSession(FALSE, username);
1185     end;
1187   end if;
1188 
1189   wfa_html_util.GetUrlCount(to_number(nid),urlcount,urlstring);
1190 
1191   -- If there is just one url then replace the response frame with the url
1192   if (urlcount = 1) then
1193 --    GoToUrl(wf_notification.GetURLText(urlstring, nid),'_self');
1194     owa_util.redirect_url(wf_notification.GetURLText(urlstring, nid));
1195     return;
1196   end if;
1197 
1198   -- bug 2167012 JWSMITH moved header_close to after owa_util.redirect
1199   owa_util.http_header_close;
1200   --
1201   -- Header and Page Title
1202   --
1203   htp.htmlOpen;
1204   htp.headOpen;
1205   if (status = 'OPEN') then
1206     htp.title(wf_core.translate('WFA_DTITLE')||' '||realname);
1207   else
1208     htp.title(wf_core.translate('WFA_CDTITLE')||' '||realname);
1209   end if;
1210 
1211   -- Add the java script to the header to open the dm window for
1212   -- any DM function that is executed.
1213   fnd_document_management.get_open_dm_attach_window;
1214   fnd_document_management.get_open_dm_display_window;
1215 
1216 
1217   htp.headClose;
1218 
1219   htp.p('<!-- debug info -->');
1220   htp.p('<!--  username='||username||' -->');
1221   htp.p('<!--  userenv(LANGUAGE)='||userenv('LANGUAGE')||' -->');
1222   htp.p('<!--  nid="'||nid||'" -->');
1223   htp.p('<!--  nkey="'||nkey||'" -->');
1224   htp.p('<!--  previous session user="'||sess_username||'" -->');
1225 
1226   --
1227   -- Response body content
1228   --
1229   wfa_sec.header(background_only=>TRUE);
1230 
1231   -- Add the Return to Worklist link before other attributes.
1232   -- We shows it regardless if we have open response or not.
1233   -- Fix bug #785206. We don't show the WorkList link if is coming from
1234   -- email attachment
1235   if (nkey is null) then
1236     htp.center(htf.anchor(
1237             curl => owa_util.get_owa_service_path||'wfa_html.WorkList',
1238             ctext => wf_core.translate('WFA_WORKLIST_RETURN'),
1239             cattributes=>'TARGET="_top"'));
1240   else
1241     pseudo_login := TRUE;
1242   end if;
1243 
1244   --
1245   -- Handle Response Forms Attributes
1246   -- Note that similar to URL, it is mutally exclusive to other attributes
1247   --
1248   -- Do not allow any response if notification is not opened
1249   --
1250   if (status = 'OPEN') then
1251     if (showforms is not null) then
1252       htp.tableOpen(cattributes=>'summary=""');
1253       respcnt := 0;
1254       for rec in forms_attrs loop
1255         htp.tableRowOpen;
1256         htp.p('<TD ALIGN="RIGHT" ROWSPAN=2 id="">');
1257         if (rec.description is not null) then
1258           htp.p(rec.description);
1259         else
1260           htp.br;
1261         end if;
1262         htp.p('</TD>');
1263 
1264        --Check the SOCKET_LISTENER_PORT profile option.
1265        l_forms_port :=
1266               Wfa_Sec.Get_Profile_Value('SOCKET_LISTENER_PORT',username);
1267 
1268         htp.p('<TD ALIGN="CENTER" id="">');
1269           Wf_Forms.Applet(fname=>Wf_Notification.GetShortText(rec.text_value,
1270                             to_number(ResponseFrame.nid)),
1271                           status=>l_status,
1272                           port=>nvl(l_forms_port, '0'));
1273         htp.p('</TD>');
1274         htp.tableRowClose;
1275 
1276         htp.tableRowOpen;
1277         htp.tableData(rec.display_name, 'CENTER', cattributes=>'id=""');
1278         htp.tableRowClose;
1279 
1280         if (not l_status) then
1281           cnt := cnt + 1;
1282         end if;
1283 
1284         respcnt := respcnt + 1;
1285       end loop;
1286       htp.tableClose;
1287 
1288       --
1289       -- Print warning message
1290       --
1291       if (cnt > 0) then
1292         htp.p('<P>'||wf_core.translate('WF_EXECUTE_FORM_FAILED'));
1293         htp.br;
1294       end if;
1295 
1296       if (respcnt >= 1) then
1297         Wfa_Sec.Footer;
1298         htp.htmlClose;
1299         return;
1300       end if;
1301     end if;
1302   end if;
1303 
1304   --
1305   -- Check for response URLs.  If more than one is found, display a list of
1306   -- URL links instead of the standard response frame.  If only one is found
1307   -- then the main response frame function will be replaced in the detail
1308   -- procedure
1309   --
1310   if (urlcount > 1) then
1311 
1312     htp.tableOpen(cattributes=>'summary=""');
1313     for rec in attrs('NORESULT', 'URL') loop
1314 
1315        htp.tableRowOpen;
1316        wfa_html_util.GetUrl(nid, rec.description, rec.text_value);
1317        htp.tableRowClose;
1318 
1319     end loop;
1320 
1321     htp.tableClose;
1322     Wfa_Sec.Footer;
1323     htp.htmlClose;
1324 
1325     return;
1326 
1327   end if;
1328 
1329   if (status = 'OPEN') then
1330 
1331     htp.p('<FORM NAME="WFNOTRESP" ACTION="'||
1332        owa_util.get_owa_service_path||
1333        'wfa_html.SubmitResponse" METHOD="POST" ONSUBMIT="return false">');
1334 
1338     -- Add dummy fields to start both array-type input fields.
1335     htp.formHidden('nkey', nkey);
1336     htp.formHidden('forward', null);
1337 
1339     -- These dummy values are needed so that the array parameters to
1340     -- the submit procedure will not be null even if there are no real
1341     -- response fields.  This would cause a pl/sql error, because array
1342     -- parameters can't be defaulted.
1343     htp.formHidden('h_fnames', 'Dummy_Name');
1344     htp.formHidden('h_fvalues', 'Dummy_Value');
1345     htp.formHidden('h_fdocnames', 'Dummy_Value');
1346   else
1347     -- Add submitted title if ntf not open
1348     if (status = 'CANCELED') then
1349       htp.center(htf.bold(wf_core.translate('WFA_NOTIF_CANCELED')));
1350     else
1351       if (pseudo_login) then
1352         htp.center(htf.bold(wf_core.translate('WFA_RESPONSE_COMPLETE')));
1353       else
1354         htp.center(htf.bold(wf_core.translate('WFA_SUBMIT_RESPONSE')));
1355       end if;
1356     end if;
1357   end if;
1358 
1359   --
1360   -- Non-RESULT Response attribute fields
1361   -- Add a field for every non-result response attribute
1362   --
1363   htp.tableOpen(cattributes=>'summary=""');
1364 
1365   respcnt := 0;
1366   for rec in attrs('NORESULT', '') loop
1367 
1368     htp.tableRowOpen;
1369 
1370     -- Draw prompt with anchor for info
1371     htp.tableData(
1372         cvalue=>htf.anchor(
1373                     curl=>owa_util.get_owa_service_path||
1374                           'wfa_html.AttributeInfo?nid='||nid||
1375                           '&'||'name='||rec.name,
1376                     ctext=>rec.display_name,
1377                     cattributes=>'OnMouseOver="window.status='''||wfa_html.replace_onMouseOver_quotes(rec.description2)||'''; return true"'),
1378         calign=>'right',
1379         cattributes=>'id=""');
1380 
1381     dvalue := wfa_html_util.GetDisplayValue(rec.type, rec.format, rec.text_value,
1382                  rec.number_value, rec.date_value);
1383     if (status <> 'OPEN') then
1384 
1385       if (rec.type = 'DOCUMENT' and dvalue is not null) then
1386 
1387          -- Parse doc mgmt system type from dvalue
1388          colon := instr(dvalue, ':');
1389          if ((colon <> 0) and (colon < 30)) then
1390             dmstype := upper(substr(dvalue, 1, colon-1));
1391          end if;
1392 
1393          if (dmstype = 'DM') then
1394 
1395             /*
1396             ** Get the HTML text for displaying the document
1397             */
1398             fnd_document_management.get_launch_document_url (
1399                username,
1400                dvalue,
1401                FALSE,
1402                document);
1403 
1404             document := '<A HREF="'||document||
1405                  '" TARGET="FNDDMwindow">'||rec.display_name||
1406                  '</A>';
1407 
1408              -- If ntf not open print displayed value as boilerplate
1409              -- instead of fields.
1410              htp.tableData(cvalue=>document,
1411                        cattributes=>'BGCOLOR=WHITE id=""');
1412 
1413          elsif (dmstype = 'PLSQL') then
1414 
1415              -- If ntf not open print displayed value as boilerplate
1416              -- instead of fields.
1417              htp.tableData(cvalue=>dvalue,
1418                        cattributes=>'BGCOLOR=WHITE id=""');
1419 
1420          end if;
1421 
1422       else
1423 
1424          -- If ntf not open print displayed value as boilerplate
1425          -- instead of fields.
1426          htp.tableData(cvalue=>dvalue,
1427                        cattributes=>'BGCOLOR=WHITE id=""');
1428 
1429       end if;
1430 
1431     else
1432 
1433       respcnt := respcnt + 1;
1434       if (rec.type = 'LOOKUP') then
1435         wfa_html_util.GetLookup(rec.name, rec.text_value, rec.format, FALSE);
1436       else
1437         if (nkey is null) then
1438           wfa_html_util.GetField(rec.name,rec.type,rec.format,dvalue,respcnt);
1439         else
1440           wfa_html_util.GetField(rec.name,rec.type,rec.format,dvalue,respcnt,
1441              to_number(nid), nkey);
1442         end if;
1443       end if;
1444 
1445     end if;
1446 
1447     htp.tableRowClose;
1448 
1449   end loop;
1450 
1451 
1452   --
1453   -- RESULT attribute
1454   -- Add result attribute to bottom of page
1455   --
1456   open attrs('RESULT', '');
1457   fetch attrs into result;
1458   if (attrs%notfound) then
1459     -- No result
1460     if (status = 'OPEN') then
1461       if (respcnt > 0) then
1462         -- Non-result responses exist.
1463         -- Add a 'Submit' button to submit the form.
1464         htp.tableRowOpen;
1465         htp.p('<TD id="">');
1466         wfa_html.create_reg_button ('javascript:document.WFNOTRESP.submit()',
1467                                     wf_core.translate ('SUBMIT'),
1468                                     wfa_html.image_loc,
1469                                     null,
1470                                     wf_core.translate ('SUBMIT'));
1471 
1472         htp.p('</TD>');
1473 
1474       else
1475 
1476         -- No responses at all.
1477         -- Add a message to that effect.
1478         htp.tableRowOpen;
1482         -- Followed by a 'Close' button
1479         htp.tableData(wf_core.translate('WFA_NO_RESPONSE'), cattributes=>'id=""');
1480         htp.tableRowClose;
1481 
1483         htp.tableRowOpen;
1484         htp.p('<TD id="">');
1485         htp.tableopen(cattributes=>'summary=""');
1486         htp.tablerowopen;
1487         htp.p('<TD ALIGN=LEFT id="">');
1488         wfa_html.create_reg_button ('javascript:document.WFNOTRESP.submit()',
1489                                     wf_core.translate ('CLOSE'),
1490                                     wfa_html.image_loc,
1491                                     null,
1492                                     wf_core.translate ('CLOSE'));
1493 
1494         htp.p('</TD>');
1495 
1496       end if;
1497     end if;
1498   else
1499     -- Result found
1500     -- Draw prompt with anchor for info
1501     htp.tableRowOpen;
1502     htp.tableData(
1503         cvalue=>htf.anchor(
1504                     curl=>owa_util.get_owa_service_path||
1505                           'wfa_html.AttributeInfo?nid='||nid||
1506                           '&'||'name=RESULT',
1507                     ctext=>result.display_name,
1508                     cattributes=>'OnMouseOver="window.status='''||wfa_html.replace_onMouseOver_quotes(result.description2)||'''; return true"'),
1509         calign=>'right',
1510         cattributes=>'id=""');
1511 
1512     if (status = 'OPEN') then
1513       -- Draw response buttons
1514       htp.p('<TD id="">');
1515       htp.tableopen(cattributes=>'cellspacing=0 summary=""');
1516       htp.tablerowopen;
1517       respcnt := respcnt + 1;
1518       wfa_html_util.GetButtons(result.text_value, result.format, respcnt);
1519 
1520     else
1521       -- Not open.  Throw the result into boilerplate.
1522       htp.tableData(cvalue=>wfa_html_util.GetDisplayValue(result.type, result.format,
1523                                     result.text_value, result.number_value,
1524                                     result.date_value),
1525                       cattributes=>'BGCOLOR=WHITE id=""');
1526     end if;
1527   end if;
1528   close attrs;
1529 
1530   -- Add forward button if still open
1531   if (status = 'OPEN') then
1532     -- Hide the Reassign button if a hidden attribute #HIDE_REASSIGN
1533     -- is set to Y.
1534     -- Exception handling is needed in case this attribute is not set.
1535     hide_button := 'N';
1536     begin
1537       hide_button := Wf_Notification.GetAttrText(nid, '#HIDE_REASSIGN');
1538     exception
1539       when OTHERS then
1540         -- Do not want anything on the error stack
1541         Wf_Core.Clear;
1542     end;
1543     if (hide_button <> 'Y') then
1544       htp.p('<TD id="">');
1545       wfa_html.create_reg_button ('javascript:document.WFNOTRESP.forward.value=1;
1546                                   document.WFNOTRESP.submit()',
1547                                   wf_core.translate ('ASSIGN'),
1548                                   wfa_html.image_loc,
1549                                   null,
1550                                   wf_core.translate ('ASSIGN'));
1551 
1552        htp.p('</TD>');
1553     end if;
1554   end if;
1555 
1556   htp.p('</TD>');
1557   htp.tablerowclose;
1558   htp.tableclose;
1559 
1560   htp.tableRowClose;
1561   htp.tableClose;
1562 
1563   -- Create hidden fields
1564   -- NOTE: Do NOT create any more fields for h_names or h_values here.  The
1565   -- submit buttons created above must be the last values for these fields
1566   -- to work around an MSIE bug that always sends the submit button last.
1567   if (status = 'OPEN') then
1568     htp.formHidden('h_fdocnames', null);
1569     htp.formHidden('h_counter', to_char(respcnt+1), null);
1570     htp.formHidden('h_nid', nid);
1571     htp.formClose;
1572   end if;
1573 
1574   -- Page footer
1575   Wfa_Sec.Footer;
1576   htp.htmlClose;
1577 
1578 exception
1579   when others then
1580     if (attrs%isopen) then
1581       close attrs;  -- Close cursor just in case
1582     end if;
1583     rollback;
1584     wf_core.context('Wfa_Html', 'ResponseFrame', nid, nkey);
1585     wfa_html.Error;
1586 end ResponseFrame;
1587 
1588 --
1589 -- ForwardFrame
1590 --   generate forward frame contents
1591 -- IN
1592 --   nid - notification id
1593 --   nkey - notification access key (for mailed html only)
1594 --
1595 procedure ForwardFrame(
1596   nid in varchar2,
1597   nkey in varchar2)
1598 as
1599   username varchar2(320);
1600   recipient varchar2(320);
1601   realname varchar2(360);
1602   status   varchar2(8);
1603   s0       varchar2(2000);
1604   lang_codeset varchar2(50); -- Language Codeset from environment
1605                              -- (e.g. WE8ISO8859P1)
1606   l_message     varchar2(240)   := wfa_html.replace_onMouseOver_quotes(wf_core.translate ('WFPREF_LOV'));
1607 
1608   l_url         varchar2(1000);
1609   l_media       varchar2(240) := wfa_html.image_loc;
1610   l_icon        varchar2(30) := 'FNDILOV.gif';
1611 
1612 begin
1613   -- Authenticate user
1614   username := Wfa_Html.Authenticate(to_number(nid), nkey);
1615   Wf_Notification.GetInfo(to_number(nid), recipient, s0, s0, s0, s0, status);
1616   Wf_Directory.GetRoleInfo(recipient, realname, s0, s0, s0, s0);
1617 
1618   -- Get language codeset
1622   -- Header and Page Title
1619   lang_codeset := substr(userenv('LANGUAGE'),instr(userenv('LANGUAGE'),'.')+1,
1620                          length(userenv('LANGUAGE')));
1621 
1623   htp.htmlOpen;
1624   htp.headOpen;
1625   if (status = 'OPEN') then
1626     htp.title(wf_core.translate('WFA_DTITLE')||' '||realname);
1627   else
1628     htp.title(wf_core.translate('WFA_CDTITLE')||' '||realname);
1629   end if;
1630 
1631   fnd_document_management.get_open_dm_display_window;
1632 
1633 --1578431: Moved the form submission into a javascript function to perform
1634 --         field validation.
1635 
1636   htp.p('<SCRIPT LANGUAGE="JavaScript">' || wf_core.newline ||
1637         '<!-- hide the script''s contents from feeble browsers');
1638 
1639   htp.p(wf_core.newline || 'function SubmitForward() {' || wf_core.newline );
1640   htp.p('var lcomment = document.WF_HTML.comments.value;' || wf_core.newline );
1641   htp.p(wf_core.newline || 'if (lcomment.length > 240) {' || wf_core.newline ||
1642         'alert( " ' || WF_CORE.Translate( 'WFA_MAX_COMMENTS' ) || ' "); }' );
1643   htp.p('else { document.WF_HTML.submit(); }' || wf_core.newline ||
1644         '}' || wf_core.newline);
1645   htp.p('<!-- done hiding from old browsers --></SCRIPT>' || wf_core.newline);
1646 
1647   htp.p('<NOSCRIPT>');
1648   htp.p(WF_CORE.Translate('WFA_NOSCRIPT'));
1649   htp.p('</NOSCRIPT>');
1650 
1651   htp.headClose;
1652 
1653   -- Body contents
1654   wfa_sec.header(background_only=>TRUE);
1655 
1656   -- Open form and add hidden fields
1657   htp.formOpen(curl=>owa_util.get_owa_service_path||'wfa_html.SubmitForward',
1658                cmethod=>'Post', cattributes=>'NAME="WF_HTML"');
1659   htp.formHidden('nkey', nkey);
1660   htp.formHidden('h_nid', nid);
1661 
1662   -- Forwardee field
1663   htp.tableOpen(calign=>'CENTER', cattributes=>'summary=""');
1664   htp.tableRowOpen;
1665   htp.tableData(cvalue=>'<LABEL FOR="i_assignto">' ||
1666                         wf_core.translate('WFA_ASSIGNTO') ||
1667                         '</LABEL>',
1668                 calign=>'right', cattributes=>'id=""');
1669 
1670   htp.formHidden('forwardee', null);
1671 
1672   -- add LOV here: Note:bottom is name of frame.
1673   -- Note: The REPLACE function replaces all the space characters with
1674   -- the proper escape sequence.
1675   l_url := 'javascript:fnd_open_dm_display_window('||''''||
1676             REPLACE('wf_lov.display_lov?p_lov_name='||'owner'||
1677             '&p_display_name='||'WFA_FIND_USER'||
1678             '&p_validation_callback=wfa_html.wf_user_val'||
1679             '&p_dest_hidden_field=top.opener.parent.bottom.document.WF_HTML.forwardee.value'||
1680             '&p_current_value=top.opener.parent.bottom.document.WF_HTML.display_forwardee.value'||
1681             '&p_display_key='||'Y'||
1682             '&p_dest_display_field=top.opener.parent.bottom.document.WF_HTML.display_forwardee.value',
1683               ' ', '%20')||''''||',500,500)';
1684 
1685   -- print everything together so ther is no gap.
1686   htp.tabledata(htf.formText(cname=>'display_forwardee', csize=>30,
1687                              cmaxlength=>240, cattributes=>'id="i_assignto"')||
1688                '<A href='||l_url||'>'||
1689                '<IMG src="'||l_media||l_icon||'" border=0 alt="'||
1690                     l_message||'" onmouseover="window.status='||''''||
1691                     l_message||''''||';return true"></A>', cattributes=>'id=""');
1692 
1693   htp.tableRowClose;
1694 
1695   -- Delegate/Transfer field
1696   htp.tableRowOpen;
1697   htp.tableData(cvalue=>'<LABEL>' || htf.formRadio(cname=>'fmode',
1698                                                    cvalue=>'DELEGATE',
1699                                                    cchecked=>1) ||
1700                 wf_core.translate('WFA_REASSIGN_DELEGATE') || '</LABEL>',
1701                 calign=>'left', ccolspan=>2, cattributes=>'id=""');
1702   htp.tableRowClose;
1703   htp.tableRowOpen;
1704   htp.tableData(cvalue=>'<LABEL>' || htf.formRadio(cname=>'fmode',
1705                                                    cvalue=>'TRANSFER') ||
1706                         wf_core.translate('WFA_REASSIGN_TRANSFER') ||
1707                         '</LABEL>',
1708                     calign=>'left', ccolspan=>2, cattributes=>'id=""');
1709   htp.tableRowClose;
1710 
1711 
1712   -- Always treat it as Delegate for now
1713   -- htp.formHidden('fmode','DELEGATE');
1714 
1715   -- Comments field
1716   htp.tableRowOpen;
1717   htp.tableData(cvalue=>'<LABEL FOR="i_comments">' ||
1718                         wf_core.translate('COMMENTS') ||
1719                         '</LABEL>',
1720                 calign=>'right', cattributes=>'id=""');
1721   htp.tableData(cvalue=>htf.formTextarea2(cname=>'comments', nrows=>2,
1722                                          ncolumns=>65, cwrap=>'SOFT',
1723                                          cattributes=>'id="i_comments"'),
1724                 calign=>'left', cattributes=>'id=""');
1725   htp.tableRowClose;
1726   htp.formClose;
1727   htp.tableclose;
1728 
1729   -- Add submit button
1730   htp.tableopen(calign=>'CENTER', cattributes=>'summary=""');
1731   htp.tableRowOpen;
1732 
1733   htp.p('<TD id="">');
1734 
1735 --1578431: Changed button to call SubmitForward() javascript function.
1739                               'FNDJLFOK.gif',
1736   wfa_html.create_reg_button ('javascript:SubmitForward()',
1737                               wf_core.translate ('WFMON_OK'),
1738                               wfa_html.image_loc,
1740                               wf_core.translate ('WFMON_OK'));
1741 
1742   htp.p('</TD>');
1743 
1744   htp.p('<TD id="">');
1745 
1746   wfa_html.create_reg_button ('Wfa_Html.ResponseFrame?nid='||nid||
1747                               '&nkey='||nkey,
1748                               wf_core.translate ('CANCEL'),
1749                               wfa_html.image_loc,
1750                               'FNDJLFCN.gif',
1751                               wf_core.translate ('CANCEL'));
1752 
1753   htp.p('</TD>');
1754 
1755   htp.tableRowClose;
1756   htp.tableClose;
1757 
1758   wfa_sec.Footer;
1759   htp.htmlClose;
1760 exception
1761   when others then
1762     rollback;
1763     wf_core.context('Wfa_Html', 'ForwardFrame', nid, nkey);
1764     wfa_html.Error;
1765 end ForwardFrame;
1766 
1767 --
1768 -- AttributeInfo
1769 --   Generate page with details about a response attribute
1770 -- IN
1771 --   nid - notification id
1772 --   name - attribute name
1773 --
1774 procedure AttributeInfo(
1775   nid in varchar2,
1776   name in varchar2)
1777 is
1778   dispname varchar2(80);
1779   description varchar2(240);
1780   attrtype varchar2(8);
1781   format varchar2(240);
1782   dlookup varchar2(80);
1783 begin
1784   -- Note:  No user authentication is done here to save time, since
1785   -- there is nothing secret about attribute descriptions.
1786 
1787   -- Get attribute info
1788   begin
1789     select MA.DISPLAY_NAME,
1790            MA.DESCRIPTION,
1791            MA.TYPE,
1792            MA.FORMAT
1793     into dispname, description, attrtype, format
1794     from WF_NOTIFICATION_ATTRIBUTES NA,
1795          WF_MESSAGE_ATTRIBUTES_VL MA,
1796          WF_NOTIFICATIONS N
1797     where N.NOTIFICATION_ID = to_number(AttributeInfo.nid)
1798     and NA.NOTIFICATION_ID = N.NOTIFICATION_ID
1799     and MA.MESSAGE_NAME = N.MESSAGE_NAME
1800     and MA.MESSAGE_TYPE = N.MESSAGE_TYPE
1801     and MA.NAME = NA.NAME
1802     and MA.NAME = AttributeInfo.name;
1803   exception
1804     when no_data_found then
1805       wf_core.token('NID', nid);
1806       wf_core.token('ATTRIBUTE', name);
1807       wf_core.raise('WFNTF_ATTR');
1808   end;
1809 
1810   -- Header and Page Title
1811   htp.htmlOpen;
1812   htp.headOpen;
1813   htp.title(wf_core.translate('WFA_ATTRINFO')||': '||dispname);
1814   htp.headClose;
1815 
1816   -- Body contents
1817   wfa_sec.header(background_only=>TRUE);
1818   -- Title
1819   htp.center(htf.bold(wf_core.translate('WFA_ATTRINFO')||' '||dispname));
1820   htp.tableOpen(cattributes=>'summary=""');
1821 
1822   -- Description
1823   htp.tableRowOpen;
1824   htp.tableData(cvalue=>wf_core.translate('DESCRIPTION'), calign=>'right', cattributes=>'id=""');
1825   htp.tableData(cvalue=>htf.bold(description), calign=>'left',
1826                 cattributes=>'bgcolor=white ehaders=""');
1827   htp.tableRowClose;
1828 
1829   -- Type
1830   htp.tableRowOpen;
1831   htp.tableData(cvalue=>wf_core.translate('TYPE'), calign=>'right', cattributes=>'id=""');
1832   htp.tableData(cvalue=>htf.bold(wfa_html_util.GetLookupMeaning('WFSTD_ATTRTYPE',
1833                                                   attrtype)),
1834                 calign=>'left',
1835                 cattributes=>'bgcolor=white id=""');
1836   htp.tableRowClose;
1837 
1838   -- Format
1839   htp.tableRowOpen;
1840   if (attrtype = 'VARCHAR2') then
1841     htp.tableData(cvalue=>wf_core.translate('MAXLENGTH'), calign=>'right');
1842     htp.tableData(cvalue=>htf.bold(nvl(format, '2000')), calign=>'left',
1843                   cattributes=>'bgcolor=white');
1844   elsif (attrtype = 'LOOKUP') then
1845     htp.tableData(cvalue=>wf_core.translate('LOOKUP'), calign=>'right', cattributes=>'id=""');
1846 
1847     -- Get displayed name of lookup
1848     begin
1849       select WLT.DISPLAY_NAME
1850       into dlookup
1851       from WF_LOOKUP_TYPES WLT
1852       where WLT.LOOKUP_TYPE = AttributeInfo.format;
1853     exception
1854       when no_data_found then
1855         dlookup := format;
1856     end;
1857     htp.tableData(cvalue=>htf.bold(dlookup), calign=>'left',
1858                   cattributes=>'bgcolor=white id=""');
1859 
1860   elsif format is not null then
1861     -- All others just print format only if it exists
1862     -- printing "default" is confusing UI.
1863     htp.tableData(cvalue=>wf_core.translate('FORMAT'), calign=>'right', cattributes=>'id=""');
1864     htp.tableData(cvalue=>htf.bold(nvl(format, '&'||'lt;'||
1865                           wf_core.translate('DEFAULT')||'&'||'gt;')),
1866                   calign=>'left',
1867                   cattributes=>'bgcolor=white id=""');
1868   end if;
1869   htp.tableRowClose;
1870 
1871   htp.tableClose;
1872   wfa_sec.Footer;
1873   htp.htmlClose;
1874 exception
1875   when others then
1876     rollback;
1877     wf_core.context('Wfa_Html', 'AttributeInfo', nid, name);
1878     wfa_html.Error;
1879 end AttributeInfo;
1880 
1881 --
1885 --   nid - notification id
1882 -- RespFrameSize (RPIVATE)
1883 --   Calculate size of response frame using heuristic
1884 -- IN
1886 -- RETURNS
1887 --   Size of response frame in pixels
1888 --
1889 function RespFrameSize(
1890   nid in number)
1891 return number
1892 is
1893   respcnt       pls_integer;
1894   longcnt       pls_integer;
1895   urlcnt        pls_integer;
1896   respsize      pls_integer;
1897 
1898 begin
1899   -- Approximate size of response frame using heuristic:
1900   -- The rule of thumb being :
1901   -- 1. Each non-result response counts as 40 pixels
1902   --    + url and multiline fields count twice
1903   --    + 1 for result button line
1904   -- 2. Frame must be in range 100 - 250 pixels
1905   -- 3. If there is a url respond attributet then go for the max size
1906 
1907   -- Count of multiline response fields
1908   select count(1)
1909   into urlcnt
1910   from WF_MESSAGE_ATTRIBUTES MA,
1911        WF_NOTIFICATIONS N
1912   where N.NOTIFICATION_ID = nid
1913   and MA.MESSAGE_NAME = N.MESSAGE_NAME
1914   and MA.MESSAGE_TYPE = N.MESSAGE_TYPE
1915   and MA.SUBTYPE = 'RESPOND'
1916   and MA.TYPE = 'URL';
1917 
1918   if (urlcnt = 1) then
1919     respsize := 250;
1920   else
1921 
1922     -- Count of all response fields
1923     select count(1)
1924     into respcnt
1925     from WF_NOTIFICATION_ATTRIBUTES NA,
1926          WF_MESSAGE_ATTRIBUTES MA,
1927          WF_NOTIFICATIONS N
1928     where N.NOTIFICATION_ID = nid
1929     and NA.NOTIFICATION_ID = N.NOTIFICATION_ID
1930     and MA.MESSAGE_NAME = N.MESSAGE_NAME
1931     and MA.MESSAGE_TYPE = N.MESSAGE_TYPE
1932     and MA.NAME = NA.NAME
1933     and MA.SUBTYPE = 'RESPOND'
1934     and MA.TYPE <> 'FORM'
1935     and MA.NAME <> 'RESULT';
1936 
1937     -- Count of multiline response fields
1938     select count(1)
1939     into longcnt
1940     from WF_NOTIFICATION_ATTRIBUTES NA,
1941          WF_MESSAGE_ATTRIBUTES MA,
1942          WF_NOTIFICATIONS N
1943     where N.NOTIFICATION_ID = nid
1944     and NA.NOTIFICATION_ID = N.NOTIFICATION_ID
1945     and MA.MESSAGE_NAME = N.MESSAGE_NAME
1946     and MA.MESSAGE_TYPE = N.MESSAGE_TYPE
1947     and MA.NAME = NA.NAME
1948     and MA.SUBTYPE = 'RESPOND'
1949     and MA.TYPE = 'VARCHAR2'
1950     and decode(MA.TYPE, 'VARCHAR2', nvl(to_number(MA.FORMAT), 2000), 0) > 80;
1951 
1952 
1953     respsize := (respcnt + longcnt + 1) * 40;
1954     if (respsize < 100) then
1955       respsize := 100;
1956     elsif (respsize > 250) then
1957       respsize := 250;
1958     end if;
1959   end if;
1960 
1961   return(respsize);
1962 
1963 exception
1964   when others then
1965     wf_core.context('Wfa_Html', 'RespFrameSize', to_char(nid));
1966     raise;
1967 end RespFrameSize;
1968 
1969 --
1970 -- Detail (PROCEDURE)
1971 --   generate detail screen
1972 -- IN
1973 --   nid - notification id
1974 -- NOTE
1975 --   Detail is overloaded.
1976 --   This version is used by the Web notifications page.
1977 --
1978 procedure Detail(
1979   nid in varchar2)
1980 is
1981   recipient     varchar2(320);
1982   realname      varchar2(360);
1983   s0            varchar2(2000);
1984   status        varchar2(8);
1985   respsize      pls_integer;
1986   username      varchar2(320);
1987   url_str       varchar2(4000);
1988   showforms     varchar2(1);
1989 begin
1990 
1991   -- Get status
1992   Wf_Notification.GetInfo(to_number(nid), recipient, s0, s0, s0, s0, status);
1993   username := Wfa_Html.Authenticate(to_number(nid), null);
1994   Wf_Directory.GetRoleInfo(username, realname, s0, s0, s0, s0);
1995 
1996   htp.htmlOpen;
1997   htp.headOpen;
1998   if (status = 'OPEN') then
1999     htp.title(wf_core.translate('WFA_DTITLE') || ' ' || realname);
2000   else
2001     htp.title(wf_core.translate('WFA_CDTITLE') || ' ' || realname);
2002   end if;
2003 
2004   wfa_html.create_help_function('wf/links/det.htm?DETNOT');
2005 
2006   -- Add the java script to the header to open the dm window for
2007   -- any DM function that is executed.
2008   fnd_document_management.get_open_dm_display_window;
2009 
2010   htp.headClose;
2011 
2012   -- Calculate size of response frame
2013   respsize := RespFrameSize(to_number(nid));
2014 
2015   -- Open frameset, and set focus to response window.
2016   -- NOTE: MSIE does not support focus method.
2017   if (instr(owa_util.get_cgi_env('HTTP_USER_AGENT'), 'MSIE') <> 0) then
2018     htp.p('<FRAMESET ROWS="*,'||to_char(respsize)||'" TITLE="' ||
2019           WF_CORE.Translate('WFA_DTITLE_TBAR') || '" LONGDESC="' ||
2020           owa_util.get_owa_service_path ||
2021          'wfa_html.LongDesc?p_token=WFA_DTITLE_TBAR">');
2022   else
2023     htp.p('<FRAMESET ROWS="*,'||to_char(respsize)||
2024           '" onLoad="self.bottom.focus()" TITLE="' ||
2025           WF_CORE.Translate('WFA_DTITLE_TBAR') || '" LONGDESC="' ||
2026           owa_util.get_owa_service_path ||
2027          'wfa_html.LongDesc?p_token=WFA_DTITLE_TBAR">');
2028   end if;
2029 
2030   -- Descide to show Forms or not
2031   if (Wf_Core.translate('WF_INSTALL') = 'EMBEDDED') then
2032     showforms := 'T';
2033   else
2037   if (showforms is not null) then
2034     showforms := '';
2035   end if;
2036 
2038     htp.p('<FRAME NAME="top" MARGINHEIGHT=10 MARGINWIDTH=10 ' ||
2039         'src="'||owa_util.get_owa_service_path||
2040               'wfa_html.DetailFrame?nid='||nid||'&'||'showforms=T'||'" TITLE="' ||
2041           WF_CORE.Translate('WFA_DTITLE_TBAR') || '" LONGDESC="' ||
2042           owa_util.get_owa_service_path ||
2043          'wfa_html.LongDesc?p_token=WFA_DTITLE_TBAR">');
2044   else
2045     htp.p('<FRAME NAME="top" MARGINHEIGHT=10 MARGINWIDTH=10 ' ||
2046         'src="'||owa_util.get_owa_service_path||
2047               'wfa_html.DetailFrame?nid='||nid||'" TITLE="' ||
2048           WF_CORE.Translate('WFA_DTITLE_TBAR') || '" LONGDESC="' ||
2049           owa_util.get_owa_service_path ||
2050          'wfa_html.LongDesc?p_token=WFA_DTITLE_TBAR">');
2051   end if;
2052 
2053   url_str := owa_util.get_owa_service_path||
2054             'wfa_html.ResponseFrame?nid='||nid;
2055 
2056   if (showforms is not null) then
2057     url_str := url_str||'&'||'showforms=T';
2058   end if;
2059 
2060   -- Note frame name BOTTOM is hardcoded into wfa_html.detail
2061   htp.p('<FRAME NAME="bottom" MARGINHEIGHT=3 MARGINWIDTH=10 ' ||
2062         'src="'||url_str||'" TITLE="' ||
2063           WF_CORE.Translate('WFA_DTITLE_TBAR') || '" LONGDESC="' ||
2064           owa_util.get_owa_service_path ||
2065          'wfa_html.LongDesc?p_token=WFA_DTITLE_TBAR">');
2066 
2067   htp.p('</FRAMESET>');
2068   htp.htmlClose;
2069 exception
2070   when others then
2071     rollback;
2072     wf_core.context('Wfa_Html','Detail', nid);
2073     wfa_html.Error;
2074 end Detail;
2075 
2076 --
2077 -- Detail (FUNCTION)
2078 --   return standalone detail screen text
2079 -- IN
2080 --   nid - notification id
2081 --   nkey - notification key
2082 --   agent - web agent URL root
2083 -- NOTE
2084 --   Detail is overloaded.
2085 --   This produces the version used by the mailer.
2086 function Detail(
2087     nid   in number,
2088     nkey  in varchar2,
2089     agent in varchar2)
2090 return varchar2
2091 as
2092   username  varchar2(320);
2093   status    varchar2(8);
2094   realname  varchar2(360);
2095   s0        varchar2(240);
2096   result    varchar2(32000);
2097   respsize  pls_integer;
2098   key       varchar2(255);
2099   n_sig_policy varchar2(100);
2100 begin
2101 
2102   Wf_Mail.GetSignaturePolicy(nid, n_sig_policy);
2103 
2104   if (wf_mail.send_accesskey and n_sig_policy not in ('PSIG_ONLY')) then
2105      key := nkey;
2106 
2107   -- Authenticate the user has access
2108   username := Wfa_Html.Authenticate(nid, nkey);
2109 
2110   -- Get notification recipient and status
2111   Wf_Notification.GetInfo(nid, username, s0, s0, s0, s0, status);
2112   Wf_Directory.GetRoleInfo(username, realname, s0, s0, s0, s0);
2113 
2114   -- Set title
2115   result := htf.htmlOpen ||g_newLine;
2116   result := result || htf.headOpen||g_newLine;
2117   if (status = 'OPEN') then
2118     result := result ||
2119         htf.title(wf_core.translate('WFA_DTITLE')||' '||realname)||
2120                   g_newLine;
2121   else
2122     result := result ||
2123         htf.title(wf_core.translate('WFA_CDTITLE')||' '||realname)||
2124                   g_newLine;
2125   end if;
2126 
2127 --tr: dont execute the help function
2128 --it calls htp procs which causes session to hang
2129 --  wfa_html.create_help_function('wf/links/det.htm?DETNOT');
2130 
2131   result := result || htf.headClose||g_newLine;
2132 
2133   -- Calculate size of response frame
2134   respsize := RespFrameSize(nid);
2135 
2136   -- Open frameset.
2137   -- NOTE: Do NOT set the focus here, because it is not supported on
2138   -- all platforms, and it is unknown at this point what browser will
2139   -- be used to display the html returned to the mailer.
2140   result := result||'<FRAMESET ROWS="*,'||to_char(respsize)||'" TITLE="' ||
2141           WF_CORE.Translate('WFA_DTITLE_TBAR') || '" LONGDESC="' ||
2142           agent ||
2143          'wfa_html.LongDesc?p_token=WFA_DTITLE_TBAR">'||
2144             g_newLine;
2145   result := result ||
2146       '<FRAME NAME="top" MARGINHEIGHT=10 MARGINWIDTH=10 ' ||
2147       'src="'||agent||'/wfa_html.DetailFrame?nid='||to_char(nid)||
2148       '&'||'nkey='||key||'" TITLE="' ||
2149           WF_CORE.Translate('WFA_DTITLE_TBAR') || '" LONGDESC="' ||
2150           agent ||
2151          'wfa_html.LongDesc?p_token=WFA_DTITLE_TBAR">'||g_newLine;
2152   result := result ||
2153     '<FRAME NAME="bottom" MARGINHEIGHT=10 MARGINWIDTH=10 ' ||
2154     'src="'||agent||'/wfa_html.ResponseFrame?nid='||to_char(nid)||
2155     '&'||'nkey='||key||'" TITLE="' ||
2156           WF_CORE.Translate('WFA_DTITLE_TBAR') || '" LONGDESC="' ||
2157           agent ||
2158          'wfa_html.LongDesc?p_token=WFA_DTITLE_TBAR">'||g_newLine;
2159   result := result || '</FRAMESET>'||g_newLine;
2160   result := result || htf.htmlClose;
2161 
2162   else
2163   -- Send_accesskey is set to N so we will generate a DirectLogin call.
2164   -- We do not need to authenticate the user, since the user will have
2165   -- to authenticate to view the notification.  After authentication,
2166   -- DirectLogin will redirect to the Detail (Web-interface) procedure so
2170 
2167   -- we will then confirm that the user logged in can also view the
2168   -- notification.
2169   key := NULL;
2171   result := htf.htmlOpen ||g_newLine;
2172   result := result || htf.headOpen||g_newLine;
2173   result := result ||
2174         htf.title(wf_core.translate('WFA_LOGIN_REQUEST'))||
2175                   g_newLine;
2176   result := result || htf.headClose||g_newLine;
2177 
2178   result := result||'<FRAMESET ROWS="100%, *">'||g_newLine;
2179 
2180   result := result ||
2181     '<FRAME NAME="DirectLogin" MARGINHEIGHT=10 MARGINWIDTH=10 NORESIZE' ||
2182     ' src="'||agent || '/' || wfa_sec.DirectLogin(nid) || '">'||g_newLine;
2183   result := result || '</FRAMESET>'||g_newLine;
2184   result := result || htf.htmlClose;
2185 end if;
2186 
2187   return(result);
2188 exception
2189   when others then
2190     wf_core.context('Wfa_Html', 'Detail', to_char(nid), nkey, agent);
2191     raise;
2192 end Detail;
2193 
2194 --
2195 -- Detail2 (FUNCTION)
2196 --   return standalone detail screen text
2197 -- IN
2198 --   nid - notification id
2199 --   nkey - notification key
2200 --   agent - web agent URL root
2201 -- NOTE
2202 --   Detail is overloaded.
2203 --   This produces the version used by the mailer.
2204 function Detail2(
2205     nid   in number,
2206     nkey  in varchar2,
2207     agent in varchar2)
2208 return varchar2
2209 as
2210   username  varchar2(320);
2211   status    varchar2(8);
2212   realname  varchar2(360);
2213   s0        varchar2(240);
2214   result    varchar2(32000);
2215   n_sig_policy varchar2(100);
2216   url       varchar2(4000);
2217   l_function_id number;
2218 begin
2219 
2220   Wf_Mail.GetSignaturePolicy(nid, n_sig_policy);
2221 
2222   -- Authenticate the user has access
2223   username := Wfa_Html.Authenticate(nid, nkey);
2224 
2225   -- Get notification recipient and status
2226   Wf_Notification.GetInfo(nid, username, s0, s0, s0, s0, status);
2227   Wf_Directory.GetRoleInfo(username, realname, s0, s0, s0, s0);
2228 
2229   -- Set title
2230   result := htf.htmlOpen ||g_newLine;
2231   result := result || htf.headOpen||g_newLine;
2232   if (status = 'OPEN') then
2233     result := result ||
2234         htf.title(wf_core.translate('WFA_DTITLE')||' '||realname)||
2235                   g_newLine;
2236   else
2237     result := result ||
2238         htf.title(wf_core.translate('WFA_CDTITLE')||' '||realname)||
2239                   g_newLine;
2240   end if;
2241 
2242   result := result || htf.headClose||g_newLine;
2243 
2244   -- Open frameset.
2245   -- NOTE: Do NOT set the focus here, because it is not supported on
2246   -- all platforms, and it is unknown at this point what browser will
2247   -- be used to display the html returned to the mailer.
2248   if g_wfInstall='EMBEDDED' then
2249     result := result || htf.bodyOpen || g_newLine;
2250     result := result || '<SCRIPT LANGUAGE="JavaScript">' || g_newLine;
2251     result := result || '<!--' || g_newLine;
2252 
2253     url := wf_mail.Get_Ntf_Function_URL(nid => nid,
2254                                         n_key => nkey,
2255                                         n_sig_policy => n_sig_policy,
2256                                         n_override_agent => agent);
2257 
2258     result := result || 'self.location = '''||url||''';' || g_newLine;
2259     result := result || '//-->' || g_newLine || '</SCRIPT>' || g_newLine;
2260     result := result || htf.bodyClose || g_newLine || htf.htmlClose;
2261   else
2262     -- While the call is within standalone, continue to
2263     -- operate as before.
2264     if (agent is null) then
2265        result := wfa_html.detail(nid, nkey, g_webAgent);
2266     else
2267        result := wfa_html.detail(nid, nkey, agent);
2268     end if;
2269   end if;
2270 
2271   return(result);
2272 exception
2273   when others then
2274     wf_core.context('Wfa_Html', 'Detail', to_char(nid), nkey, agent);
2275     raise;
2276 end Detail2;
2277 
2278 
2279 -- DetailLink
2280 --   display standalone detail screen text
2281 -- IN
2282 --   nid - notification id
2283 --   nkey - notification key
2284 --   agent - web agent URL root
2285 -- NOTE
2286 --   Detaillink called function Detail above.
2287 --   This produces the version used by the mailer.
2288 procedure DetailLink(
2289     nid   in number,
2290     nkey  in varchar2,
2291     agent in varchar2)
2292 is
2293   m_html varchar2(32000);
2294 begin
2295   m_html := Wfa_Html.Detail2(nid, nkey, agent);
2296   htp.p(m_html);
2297 
2298 exception
2299   when others then
2300     wf_core.context('Wfa_Html', 'DetailLink', to_char(nid), nkey, agent);
2301     raise;
2302 end DetailLink;
2303 
2304 
2305 -- SubmitForward
2306 --   Submit notification forward
2307 -- IN
2308 --   h_nid - notification id
2309 --   forwardee - new recipient field
2310 --   display_forwardee - display name for the new recipient
2311 --   comments - forwarding comments field
2312 --   fmode - reassign mode can be:
2313 --           transfer - transferring responsibility
2314 --           delegate - delegate responsibility
2315 --   submit - submit forward button
2316 --   cancel - cancel forward button
2317 --   nkey - access key for mailed html
2321   display_forwardee   in varchar2,
2318 procedure SubmitForward(
2319   h_nid               in varchar2,
2320   forwardee           in varchar2,
2322   comments            in varchar2,
2323   fmode               in varchar2,
2324   submit              in varchar2,
2325   cancel              in varchar2,
2326   nkey                in varchar2)
2327 is
2328   nid        pls_integer;
2329   username   varchar2(320);
2330   l_forwardee  varchar2(320);
2331   pseudo_login boolean := FALSE;
2332 begin
2333   -- If CANCEL button, swap frame to ResponseFrame and exit.
2334   if (cancel is not null) then
2335     Wfa_Html.ResponseFrame(h_nid, nkey);
2336     return;
2337   end if;
2338 
2339   if (nkey is not null) then
2340     pseudo_login := TRUE;
2341   end if;
2342 
2343   -- Fully resolve forwardee name
2344   l_forwardee := forwardee;
2345   wfa_html.validate_display_name (display_forwardee, l_forwardee);
2346 
2347   -- REASSIGN button.
2348   -- Authenticate user
2349   nid := to_number(h_nid);
2350   username := Wfa_Html.Authenticate(nid, nkey);
2351 
2352   -- Make sure the comments field is <= 240.
2353   if ( lengthb(comments) > 240 ) then
2354     WF_CORE.Raise('WFA_MAX_COMMENTS');
2355   end if;
2356 
2357   -- Submit the forward
2358   if (fmode = 'DELEGATE') then
2359     if (comments is not null) then
2360 -- ### implement this in next release
2361 --    wf_notification.Forward(nid, upper(l_forwardee), comments, username);
2362       wf_notification.Forward(nid, upper(l_forwardee), comments);
2363     else
2364 -- ### implement this in next release
2365 --    wf_notification.Forward(nid, upper(l_forwardee), '', username);
2366       wf_notification.Forward(nid, upper(l_forwardee));
2367     end if;
2368   elsif (fmode = 'TRANSFER') then
2369     if (comments is not null) then
2370 -- ### implement this in next release
2371 --    wf_notification.Transfer(nid,upper(l_forwardee), comments, username);
2372       wf_notification.Transfer(nid,upper(l_forwardee), comments);
2373     else
2374 -- ### implement this in next release
2375 --    wf_notification.Transfer(nid,upper(l_forwardee), '', username);
2376       wf_notification.Transfer(nid,upper(l_forwardee));
2377     end if;
2378   end if;
2379 
2380   if (pseudo_login) then
2381     htp.htmlOpen;
2382     htp.headOpen;
2383 
2384     htp.center(htf.bold(WF_CORE.Translate('WFA_ASSIGNED') || ': ' ||
2385                WF_DIRECTORY.GetRoleDisplayName(upper(l_forwardee)) || '.'));
2386 
2387     htp.headClose;
2388     htp.htmlClose;
2389 
2390   else
2391     -- Putting WorkList in the browser window
2392     Wfa_Html.GotoURL('Wfa_Html.WorkList', '_top');
2393   end if;
2394 
2395 exception
2396   when others then
2397     rollback;
2398     wf_core.context('Wfa_Html','SubmitForward', h_nid, nkey, forwardee,
2399         comments);
2400     wfa_html.Error;
2401 end SubmitForward;
2402 
2403 -- SubmitResponse
2404 --   Submit notification response
2405 -- IN
2406 --   h_nid - notification id
2407 --   h_fnames - array of field names
2408 --   h_fvalues - array of field values
2409 --   h_fdocnames - array of documentnames - a throwaway value from form
2410 --   h_counter - number of fields passed in fnames and fvalues
2411 --   submit - submit response button
2412 --   forward - forward button
2413 --   nkey - access key for mailed html
2414 procedure SubmitResponse(
2415   h_nid        in varchar2,
2416   h_fnames     in Name_Array,
2417   h_fvalues    in Value_Array,
2418   h_fdocnames  in Value_Array,
2419   h_counter    in varchar2,
2420   submit       in varchar2,
2421   forward      in varchar2,
2422   nkey         in varchar2)
2423 as
2424   nid        pls_integer;
2425   username   varchar2(320);
2426   x          pls_integer;
2427   pseudo_login boolean := FALSE;
2428 begin
2429   -- If FORWARD button, swap frame to ForwardFrame and exit.
2430   if (forward is not null) then
2431     Wfa_Html.ForwardFrame(h_nid, nkey);
2432     return;
2433   end if;
2434 
2435   if (nkey is not null) then
2436      pseudo_login := TRUE;
2437   end if;
2438 
2439   -- One of RESPOND buttons pushed - submit response.
2440   -- Authenticate user
2441   nid := to_number(h_nid);
2442   username := Wfa_Html.Authenticate(nid, nkey);
2443 
2444   -- Set attributes in the reponse array.
2445   -- Start at 2 to step over the Dummy_Name/Dummy_Value pair added at
2446   -- the start of the array.
2447   for x in 2 .. to_number(h_counter) loop
2448     wfa_html_util.SetAttribute(nid, h_fnames(x), h_fvalues(x), h_fdocnames(x));
2449   end loop;
2450 
2451   -- Submit response
2452   --   If there is a problem, go back to the ResponseFrame
2453   --   otherwise, go back to the worklist
2454   begin
2455     -- Do not need to preserve context
2456     wf_engine.preserved_context := FALSE;
2457     wf_notification.Respond(nid, null, username);
2458 
2459   exception
2460     when others then
2461       -- ### We do not want this now.  Since there is real error message
2462       -- ### we want users to see, we raise an exception instead.
2463       -- Reload response window to reflect changes
2464       -- Wfa_Html.ResponseFrame(h_nid, nkey);
2468   end;
2465 
2466       -- When an exception ocurr, raise it and show the error stack.
2467       raise;
2469 
2470   if (pseudo_login) then
2471     Wfa_Html.ResponseFrame(h_nid, nkey);
2472 
2473   else
2474     -- Putting WorkList in the browser window
2475     Wfa_Html.GotoURL('Wfa_Html.WorkList', '_top');
2476   end if;
2477 
2478 exception
2479   when others then
2480     rollback;
2481     wf_core.context('Wfa_Html','SubmitResponse',
2482                     h_nid, nkey, submit, forward);
2483     wfa_html.Error;
2484 end SubmitResponse;
2485 
2486 -- GotoURL
2487 --   GotoURL let you open an url in a specify place.  This is very useful
2488 --   when you need to go from a child frame to the full browser window,
2489 --   for instnace.
2490 --   So far, this is the only way to break away from a child frame.
2491 -- IN
2492 --   url - Fully qualified universal resouce location
2493 --   location - Where you want to open it.  Samples of values are
2494 --              _blank  - unnamed window
2495 --              _self   - the current frame
2496 --              _parent - the parent frame of the current one
2497 --              _top    - the full Web browser window
2498 --              "myWin" - name of the new window
2499 --
2500 procedure GotoURL(
2501   url in varchar2,
2502   location in varchar2,
2503   attributes in varchar2
2504 )
2505 is
2506   l_url varchar2(32767);
2507 begin
2508   -- Bug 4634849
2509   l_url := wfa_html.encode_url(url);
2510 
2511   htp.htmlOpen;
2512   htp.headOpen;
2513       htp.p('<SCRIPT LANGUAGE="JavaScript"> <!-- hide the script''s contents from feeble browsers');
2514 
2515       htp.p(
2516          'function wf_open_url(url,location,attributes)
2517           {
2518              window.open(url,location,attributes);
2519           }
2520           function wf_open_url(url,location)
2521           {
2522              window.open(url,location);
2523           }'
2524       );
2525 
2526       htp.p('<!-- done hiding from old browsers --> </SCRIPT>');
2527 
2528       htp.p('<NOSCRIPT>');
2529       htp.p(WF_CORE.Translate('WFA_NOSCRIPT'));
2530       htp.p('</NOSCRIPT>');
2531 
2532   htp.headClose;
2533 
2534   if (attributes is null) then
2535     htp.p ('<BODY ONLOAD="wf_open_url('''||l_url||''', '''||location||''')">');
2536   else
2537     htp.p ('<BODY ONLOAD="wf_open_url('''||l_url||''', '''||location||''', '''
2538                                 ||attributes||''')">');
2539   end if;
2540   htp.bodyClose;
2541   htp.htmlClose;
2542 end GotoURL;
2543 
2544 -- SubmitSelectedResponse
2545 --   Submit selected notification response
2546 -- IN
2547 --   nids - notification ids
2548 --   close - submit response button
2549 --   forward - forward button
2550 --   showto - display the TO column
2551 --   nkey - access key for mailed html
2552 procedure SubmitSelectedResponse(
2553   nids         in Name_Array,
2554   close        in varchar2,
2555   forward      in varchar2,
2556   showto       in varchar2,
2557   nkey         in varchar2)
2558 as
2559 begin
2560   null;
2561 end SubmitSelectedResponse;
2562 
2563 
2564 -- ForwardNids
2565 --   Forward for each notification ids
2566 --   Forward can be Delegating or Transferring
2567 --   Delegating is for notification only.
2568 --   Transferring is reassign the whole responsibility to other
2569 -- IN
2570 --   h_nids -    hidden notification ids
2571 --   forwardee - forwardee role specified
2572 --   comments -  comments included
2573 --   fmode -     reassign mode can be:
2574 --               transfer -  transferring responsibility
2575 --               delegate -  delegate responsibility
2576 --   cancel -    cancel button
2577 procedure ForwardNids(
2578   h_nids               in Name_Array,
2579   forwardee            in varchar2,
2580   display_forwardee    in varchar2,
2581   comments             in varchar2,
2582   fmode                in varchar2,
2583   submit               in varchar2,
2584   cancel               in varchar2,
2585   nkey                 in varchar2)
2586 as
2587   username   varchar2(320);
2588   x          pls_integer;
2589   nid        pls_integer;
2590   l_forwardee varchar2(320);
2591 
2592 begin
2593   -- There is always a dummy nid passed in.  We will handle it here.
2594   -- Make sure subsequent index start at 2 not 1.
2595   if (to_number(h_nids.count) = 1) then
2596     wf_core.raise('WFNTF_NO_SELECT');
2597   end if;
2598 
2599   -- Fully resolve forwardee name
2600   l_forwardee := forwardee;
2601   wfa_html.validate_display_name (display_forwardee, l_forwardee);
2602 
2603   -- Otherwise, for each notification, delegate or transfer
2604   for x in 2..h_nids.count loop
2605     -- Authenticate user
2606     nid := to_number(h_nids(x));
2607     username := Wfa_Html.Authenticate(nid, nkey);
2608 
2609     -- Delegating to forwardee with comments
2610     if (fmode = 'DELEGATE') then
2611       if (comments is not null) then
2612 -- ### implement this in next release
2613 --      Wf_Notification.Forward(nid, upper(l_forwardee), comments, username);
2614         Wf_Notification.Forward(nid, upper(l_forwardee), comments);
2615       else
2619       end if;
2616 -- ### implement this in next release
2617 --      Wf_Notification.Forward(nid, upper(l_forwardee), '', username);
2618         Wf_Notification.Forward(nid, upper(l_forwardee));
2620     elsif (fmode = 'TRANSFER') then
2621       -- Transferring to fowardee with comments
2622 
2623       if (comments is not null) then
2624 -- ### implement this in next release
2625 --      Wf_Notification.Transfer(nid, upper(l_forwardee), comments, username);
2626         Wf_Notification.Transfer(nid, upper(l_forwardee), comments);
2627       else
2628 -- ### implement this in next release
2629 --      Wf_Notification.Transfer(nid, upper(l_forwardee), '', username);
2630         Wf_Notification.Transfer(nid, upper(l_forwardee));
2631       end if;
2632     end if;
2633   end loop;
2634 
2635   -- Back to the worklist
2636   <<worklist>>
2637   Wfa_Html.WorkList;
2638   return;
2639   exception
2640     when others then
2641       rollback;
2642       wfa_html.Error;
2643       return;
2644 end ForwardNids;
2645 
2646 /*===========================================================================
2647   PROCEDURE NAME:       create_help_function
2648 
2649   DESCRIPTION:
2650                         Create the java script function to support the Help
2651                         Icon from the header
2652 
2653    Note:  The help file parameter must include the subdirectory under
2654           /OA_DOC/lang/ and the actual file name which will either be
2655           wf or wfnew.
2656       ie  p_help_file = 'wf/notif16.htm'
2657           p_help_file = 'wfnew/wfnew48.htm'
2658 ============================================================================*/
2659 procedure create_help_function (
2660 
2661  p_help_file IN VARCHAR2
2662 
2663 ) IS
2664 
2665 install_type VARCHAR2(80);
2666 l_help_target VARCHAR2(240) := NULL;
2667 l_lang       VARCHAR2(2000);
2668 help_prefix  VARCHAR2(2000);
2669 
2670 BEGIN
2671 
2672   BEGIN
2673 
2674   /*
2675   ** Get the language environment variable
2676   ** for this user.
2677   */
2678   SELECT USERENV('LANG')
2679   INTO l_lang
2680   FROM DUAL;
2681 
2682   EXCEPTION
2683   WHEN OTHERS THEN
2684      l_lang := 'US';
2685   END;
2686 
2687   /*
2688   ** Check the installation type.  If it is workflow standalone
2689   ** then use the file prefix method of getting to the help
2690   ** content.  Otherwise use the fnd function method to get and
2691   ** display the help content.
2692   */
2693   install_type := wf_core.translate('WF_INSTALL');
2694 
2695   if (install_type = 'STANDALONE') THEN
2696 
2697      help_prefix := '/OA_DOC/';
2698 
2699      htp.p('<!-- Copyright ' || '&' || '#169; 1997 Oracle Corporation, All rights reserved. -->');
2700      htp.p('<SCRIPT LANGUAGE="JavaScript">
2701      <!-- hide the script''s contents from feeble browsers');
2702 
2703      htp.p('function help_window(){
2704         help_win = window.open('||''''||help_prefix||
2705                 'US/' || p_help_file ||''''||
2706             ', "help_win","resizable=yes,scrollbars=yes,toolbar=yes,width=600,height=500");
2707         help_win = window.open('||''''||help_prefix||
2708                'US/' || p_help_file ||''''||
2709             ', "help_win","resizable=yes,scrollbars=yes,toolbar=yes,width=600,height=500")
2710 }
2711 ');
2712 
2713      htp.p('<!-- done hiding from old browsers --></SCRIPT>');
2714 
2715      htp.p('<NOSCRIPT>');
2716      htp.p(WF_CORE.Translate('WFA_NOSCRIPT'));
2717      htp.p('</NOSCRIPT>');
2718 
2719   else
2720 
2721      /*
2722      ** If you're going against apps then strip out everything
2723      ** except the target name
2724      */
2725      IF (INSTR(p_help_file, '?') > 0) THEN
2726 
2727          l_help_target := substrb(p_help_file, INSTR(p_help_file, '?') + 1);
2728 
2729      ELSE
2730 
2731          l_help_target := p_help_file;
2732 
2733      END IF;
2734 
2735      wfa_sec.create_help_syntax (l_help_target, l_lang);
2736 
2737   end if;
2738 
2739 exception
2740   when others then
2741     Wf_Core.Context('wfa_html', 'create_help_function',
2742        p_help_file);
2743     wfa_html.Error;
2744 
2745 END create_help_function;
2746 
2747 /*===========================================================================
2748   FUNCTION NAME:        conv_special_url_chars
2749 
2750   DESCRIPTION:
2751                         Convert all of the ASCII special characters that are
2752                         disallowed as a part of a URL.  The encoding requires
2753                         that we convert the special characters to HEX for
2754                         any characters in a URL string that is built
2755                         manually outside a form get/post.
2756                         This API now also converts multibyte characters
2757                         into their HEX equivalent.
2758 
2759   NOTE:                 This api allows double-encoding.
2760 
2761 ============================================================================*/
2762 FUNCTION conv_special_url_chars (p_url_token IN VARCHAR2) RETURN VARCHAR2
2763 IS
2764  c_unreserved constant varchar2(72) :=
2765    '-_.!*''()~ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
2769  l_byte_len    integer;
2766  c_reserved    constant varchar2(72) := '%">^{}<[]`|/#?&=$:;+';
2767  l_tmp         varchar2(32767) := '';
2768  l_onechar     varchar2(4);
2770  i             integer;
2771  l_str         varchar2(48);
2772 
2773 BEGIN
2774  if p_url_token is NULL then
2775     return NULL;
2776  end if;
2777  for i in 1 .. length(p_url_token) loop
2778    l_onechar := substr(p_url_token,i,1);
2779    --Extracting out each character to be replaced.
2780    if instr(c_unreserved, l_onechar) > 0 then
2781      --Check if  it is part of the ASCII unreserved
2782      --excluded from encoding just append to the URL
2783      --string
2784      l_tmp := l_tmp || l_onechar;
2785 
2786    elsif l_onechar = ' ' then
2787      --Space encoded as '%20'
2788      l_tmp := l_tmp || '%20';
2789 
2790    elsif instr(c_reserved,l_onechar) >0 then
2791      --If it is any of the reserved characters in ascii
2792      --replace with equivalent HEX
2793      l_onechar := REPLACE(
2794                   REPLACE(
2795                   REPLACE(
2796                   REPLACE(
2797                   REPLACE(
2798                   REPLACE(
2799                   REPLACE(
2800                   REPLACE(
2801                   REPLACE(
2802                   REPLACE(
2803                   REPLACE(
2804                   REPLACE(
2805                   REPLACE(
2806                   REPLACE(
2807                   REPLACE(
2808                   REPLACE(
2809                   REPLACE(
2810                   REPLACE(
2811                   REPLACE(
2812                   REPLACE(
2813                   REPLACE(
2814                   REPLACE(l_onechar,
2815                   '%','%25'),
2816                   ' ','%20'),
2817                   '"','%22'),
2818                   '>','%3E'),
2819                   '^','%5E'),
2820                   '{','%7B'),
2821                   '}','%7D'),
2822                   '<','%3C'),
2823                   '[','%5B'),
2824                   ']','%5D'),
2825                   '`','%60'),
2826                   '|','%7C'),
2827                   '/','%2F'),
2828                   '#','%23'),
2829                   '?','%3F'),
2830                   '&','%26'),
2831                   '=','%3D'),
2832                   '$','%24'),
2833                   ':','%3A'),
2834                   ';','%3B'),
2835                   '+','%2B'),
2836                   '''','%27');
2837      l_tmp := l_tmp || l_onechar;
2838    else
2839      --For multibyte
2840      -- 1. Obtain length for each character
2841      -- 2. ascii(l_char)decimal representation in the database
2842      --    character set
2843      -- 3. Change it to the format model :
2844      --    to_char(ascii(l_onechar),'FM0X')
2845      -- 4. Add to the already encoded string.
2846      --    characters
2847      l_byte_len := lengthb(l_onechar);
2848      if l_byte_len = 1 then
2849        l_tmp := l_tmp || '%' ||
2850         substr(to_char(ascii(l_onechar),'FM0X'),1,2);
2851      elsif l_byte_len = 2 then
2852        l_str := to_char(ascii(l_onechar),'FM0XXX');
2853        l_tmp := l_tmp
2854             || '%' || substr(l_str,1,2)
2855             || '%' || substr(l_str,3,2);
2856      elsif l_byte_len = 3 then
2857        l_str := to_char(ascii(l_onechar),'FM0XXXXX');
2858        l_tmp := l_tmp
2859                 || '%' || substr(l_str,1,2)
2860                 || '%' || substr(l_str,3,2)
2861                 || '%' || substr(l_str,5,2);
2862      elsif l_byte_len = 4 then
2863        l_str := to_char(ascii(l_onechar),'FM0XXXXXXX');
2864        l_tmp := l_tmp
2865                 || '%' || substr(l_str,1,2)
2866                 || '%' || substr(l_str,3,2)
2867                 || '%' || substr(l_str,5,2)
2868                 || '%' || substr(l_str,7,2);
2869      else            -- maximum precision
2870        wf_core.raise('WFENG_PRECESSION_EXCEED');
2871      end if;
2872    end if;
2873  end loop;
2874  return l_tmp;
2875 exception
2876   when others then
2877     Wf_Core.Context('wfa_html', 'conv_special_url_chars',
2878        p_url_token);
2879     wfa_html.Error;
2880 END conv_special_url_chars;
2881 
2882 /*===========================================================================
2883   FUNCTION NAME:        encode_url (PRIVATE)
2884 
2885   DESCRIPTION:
2886                         Convert all of the ASCII special characters that are
2887                         disallowed as a part of a URL.  The encoding requires
2888                         that we convert the special characters to HEX for
2889                         any characters in a URL string that is built
2890                         manually outside a form get/post.
2891                         This API now also converts multibyte characters
2892                         into their HEX equivalent.
2893 
2894                         URL encoding was documented in RFC 1738.
2895                         We have put some "unsafe" characters in the encode
2896                         list for purpose of encoding them.
2897                         We took "~" out from this list, because some downstream
2898                         consumer (ICX) was looking for "~".
2899 
2900   NOTE:                 This private api does not allow double-encoding.
2904  c_noencode    constant varchar2(72) :=
2901 ============================================================================*/
2902 FUNCTION encode_url (p_url_token IN VARCHAR2) RETURN VARCHAR2
2903 IS
2905    '-_.!*''()~ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
2906  c_encode      constant varchar2(72) := '">^{}<[]`|/#?&=$:;+';
2907  c_hex         constant varchar2(72) := 'ABCDEFabcdef0123456789';
2908  l_tmp         varchar2(32767);
2909  l_onechar     varchar2(4);
2910  l_byte_len    integer;
2911  i             integer;
2912  l_str         varchar2(48);
2913 
2914 BEGIN
2915  if p_url_token is NULL then
2916     return NULL;
2917  end if;
2918  for i in 1 .. length(p_url_token) loop
2919    l_onechar := substr(p_url_token,i,1);
2920    --Extracting out each character to be replaced.
2921    if instr(c_noencode, l_onechar) > 0 then
2922      --If it is part of the ASCII excluded from encoding,
2923      --just append to the URL string
2924      l_tmp := l_tmp || l_onechar;
2925 
2926    elsif l_onechar = ' ' then
2927      --Space encoded as '%20'
2928      l_tmp := l_tmp || '%20';
2929 
2930    elsif l_onechar = '%' then
2931      --Do not reencode if it has already been encoded
2932      --Check next two characters to see if they belong to hex number
2933      if (instr(c_hex, substr(p_url_token,i+1,1)) > 0 and
2934          instr(c_hex, substr(p_url_token,i+2,1)) > 0) then
2935        l_tmp := l_tmp || '%';
2936      else
2937        l_tmp := l_tmp || '%25';
2938      end if;
2939 
2940    elsif instr(c_encode,l_onechar) >0 then
2941      --If it is any of the to be encoded characters in ascii
2942      --replace with equivalent HEX
2943      l_onechar := REPLACE(
2944                   REPLACE(
2945                   REPLACE(
2946                   REPLACE(
2947                   REPLACE(
2948                   REPLACE(
2949                   REPLACE(
2950                   REPLACE(
2951                   REPLACE(
2952                   REPLACE(
2953                   REPLACE(
2954                   REPLACE(
2955                   REPLACE(
2956                   REPLACE(
2957                   REPLACE(
2958                   REPLACE(
2959                   REPLACE(
2960                   REPLACE(
2961                   REPLACE(
2962                   REPLACE(l_onechar,
2963                   '"','%22'),
2964                   '>','%3E'),
2965                   '^','%5E'),
2966                   '{','%7B'),
2967                   '}','%7D'),
2968                   '<','%3C'),
2969                   '[','%5B'),
2970                   ']','%5D'),
2971                   '`','%60'),
2972                   '|','%7C'),
2973                   '/','%2F'),
2974                   '#','%23'),
2975                   '?','%3F'),
2976                   '&','%26'),
2977                   '=','%3D'),
2978                   '$','%24'),
2979                   ':','%3A'),
2980                   ';','%3B'),
2981                   '+','%2B'),
2982                   '''','%27');
2983      l_tmp := l_tmp || l_onechar;
2984    else
2985      --For multibyte
2986      -- 1. Obtain length for each character
2987      -- 2. ascii(l_char)decimal representation in the database
2988      --    character set
2989      -- 3. Change it to the format model :
2990      --    to_char(ascii(l_onechar),'FM0X')
2991      -- 4. Add to the already encoded string.
2992      --    characters
2993      l_byte_len := lengthb(l_onechar);
2994      if l_byte_len = 1 then
2995        l_tmp := l_tmp || '%' ||
2996         substr(to_char(ascii(l_onechar),'FM0X'),1,2);
2997      elsif l_byte_len = 2 then
2998        l_str := to_char(ascii(l_onechar),'FM0XXX');
2999        l_tmp := l_tmp
3000             || '%' || substr(l_str,1,2)
3001             || '%' || substr(l_str,3,2);
3002      elsif l_byte_len = 3 then
3003        l_str := to_char(ascii(l_onechar),'FM0XXXXX');
3004        l_tmp := l_tmp
3005                 || '%' || substr(l_str,1,2)
3006                 || '%' || substr(l_str,3,2)
3007                 || '%' || substr(l_str,5,2);
3008      elsif l_byte_len = 4 then
3009        l_str := to_char(ascii(l_onechar),'FM0XXXXXXX');
3010        l_tmp := l_tmp
3011                 || '%' || substr(l_str,1,2)
3012                 || '%' || substr(l_str,3,2)
3013                 || '%' || substr(l_str,5,2)
3014                 || '%' || substr(l_str,7,2);
3015      else            -- maximum precision
3016        wf_core.raise('WFENG_PRECESSION_EXCEED');
3017      end if;
3018    end if;
3019  end loop;
3020  return l_tmp;
3021 exception
3022   when others then
3023     Wf_Core.Context('wfa_html', 'encode_url',
3024        p_url_token);
3025     wfa_html.Error;
3026 END encode_url;
3027 
3028 --
3029 -- User_LOV
3030 --   Create the data for the User List of Values
3031 --   NOTE: This is not used by APPS.  Otherwise, we will have performance
3032 --         problem with this query against wf_roles.
3033 --
3034 procedure User_LOV (p_titles_only     IN VARCHAR2,
3035                     p_find_criteria IN VARCHAR2)
3036 
3037 IS
3038 
3039 l_username      VARCHAR2(320);
3040 l_display_name  VARCHAR2(360); -- enlarged from 80 to match db definition
3044 CURSOR c_user_lov (c_find_criteria IN VARCHAR2) IS
3041 l_name          VARCHAR2(320); -- enlarged from 30 to match db definition
3042 l_row_count NUMBER := 0;
3043 
3045 SELECT
3046  name,
3047  display_name
3048 FROM   wf_roles
3049 WHERE  upper(name) like upper(c_find_criteria)
3050   AND  upper(name) not like '~WF_ADHOC-%'
3051   AND  status <> 'INACTIVE'
3052 ORDER  BY name;
3053 
3054 BEGIN
3055 
3056    -- Authenticate user
3057    wfa_sec.GetSession(l_username);
3058 
3059    IF (p_titles_only = 'N') THEN
3060 
3061       SELECT COUNT(*)
3062       INTO   l_row_count
3063       FROM   wf_roles
3064       WHERE  upper(name) like upper(p_find_criteria)||'%'
3065         AND  upper(name) not like '~WF_ADHOC-%'
3066         AND  status <> 'INACTIVE';
3067 
3068    END IF;
3069 
3070    htp.p(wf_core.translate('WFA_FIND_USER'));
3071    htp.p('2');
3072    htp.p(TO_CHAR(l_row_count));
3073    htp.p(wf_core.translate('NAME'));
3074    htp.p('40');
3075    htp.p(wf_core.translate('DISPLAY_NAME'));
3076    htp.p('60');
3077 
3078    IF (p_titles_only = 'N') THEN
3079 
3080       OPEN c_user_lov (p_find_criteria||'%');
3081 
3082       /*
3083       ** Loop through all the language rows for the given find_criteria
3084       ** and write them out to the web page
3085       */
3086       LOOP
3087 
3088          FETCH c_user_lov INTO
3089              l_name, l_display_name;
3090 
3091          EXIT WHEN c_user_lov%NOTFOUND;
3092 
3093          htp.p (l_name);
3094          htp.p (l_display_name);
3095 
3096       END LOOP;
3097 
3098    END IF;
3099 
3100 exception
3101   when others then
3102     rollback;
3103     if (c_user_lov%isopen) then
3104       close c_user_lov;
3105     end if;
3106     wf_core.context('Wfa_Html', 'user_lov',p_titles_only, p_find_criteria);
3107     wfa_html.Error;
3108 end User_Lov;
3109 
3110 procedure logout is
3111         username varchar2(320);
3112 begin
3113         wfa_sec.GetSession(username);
3114         owa_util.mime_header('text/html', FALSE);
3115         owa_cookie.send('WDB_GATEWAY_LOGOUT','YES', '', '/');
3116         owa_util.http_header_close;
3117         htp.htmlOpen;
3118         htp.headOpen;
3119         htp.title(wf_core.translate('WFA_HOMETITLE'));
3120         wfa_html.create_help_function('wf/links/web.htm?WEBHOME');
3121         htp.headClose;
3122 
3123         -- Page header
3124         wfa_sec.Header(FALSE, '', wf_core.translate('WF_WORKFLOW_TITLE')||
3125                         ' - '|| wf_core.translate('WF_VERSION'), FALSE);
3126 
3127         htp.center(wf_core.translate('LOGOUT_MESSAGE')
3128          ||' '||htf.anchor(curl=>wfa_html.base_url||'/wfa_html.home',
3129                           ctext=>wf_core.translate('CLICK_HOME')));
3130 
3131         wfa_sec.Footer;
3132         htp.htmlClose;
3133 exception
3134   when others then
3135     wf_core.context('Wfa_Html','logout');
3136     wfa_html.Error;
3137 end logout;
3138 
3139 
3140 procedure Home(message in varchar2)
3141 is
3142   username   varchar2(320);   -- Username to query
3143   realname   varchar2(360);   -- Display name of username
3144   admin_role varchar2(320);   -- Role for admin mode
3145   admin_mode varchar2(1);        -- Does user have admin privledges
3146   s0         varchar2(2000);
3147 
3148 begin
3149 
3150   BEGIN
3151     -- Check session and current user
3152     wfa_sec.GetSession(username);
3153     username := upper(username);
3154 
3155     -- Validate the user
3156     if (username is null) then
3157         -- No username entered
3158         wfa_html.Login('WFA_ENTER_ID');
3159         return;
3160     end if;
3161 
3162   EXCEPTION
3163      WHEN NO_DATA_FOUND THEN
3164         -- No username entered
3165         wfa_html.Login('WFA_ENTER_ID');
3166         return;
3167      WHEN OTHERS THEN
3168         raise;
3169   END;
3170 
3171   wf_directory.GetRoleInfo(username, realname, s0, s0, s0, s0);
3172 
3173   admin_mode := 'N';
3174   admin_role := wf_core.translate('WF_ADMIN_ROLE');
3175   if (admin_role = '*' or
3176       Wf_Directory.IsPerformer(username, admin_role)) then
3177       admin_mode := 'Y';
3178   end if;
3179 
3180   htp.htmlOpen;
3181   htp.headOpen;
3182   htp.title(wf_core.translate('WFA_HOMETITLE')||' - '||realname);
3183   htp.headClose;
3184 
3185   wfa_html.homemenu;
3186 
3187   htp.htmlClose;
3188 exception
3189   when others then
3190     rollback;
3191     wf_core.context('Wfa_Html','home');
3192     wfa_html.Error;
3193 end home;
3194 
3195 
3196 procedure Header
3197 is
3198 
3199   username varchar2(320);   -- Username to query
3200 
3201 begin
3202   -- Check session and current user
3203   wfa_sec.GetSession(username);
3204 
3205   -- Set page title
3206   htp.htmlOpen;
3207   htp.headOpen;
3208   htp.title(wf_core.translate('WFA_HOMETITLE'));
3209   wfa_html.create_help_function('wf/links/web.htm?WEBHOME');
3210   htp.headClose;
3211   -- Page header
3215   htp.htmlClose;
3212   wfa_sec.Header(FALSE, '', wf_core.translate('WF_WORKFLOW_TITLE')||
3213                  ' - '|| wf_core.translate('WF_VERSION'), TRUE);
3214   wfa_sec.Footer;
3216 end;
3217 
3218 
3219 procedure home_float
3220 is
3221   username   varchar2(320);   -- Username to query
3222   realname   varchar2(360);   -- Display name of username
3223   admin_role varchar2(320);   -- Role for admin mode
3224   admin_mode varchar2(1);        -- Does user have admin privledges
3225   s0         varchar2(2000);
3226   close_anchor varchar2(40);
3227 begin
3228   -- Check session and current user
3229   wfa_sec.GetSession(username);
3230   username := upper(username);
3231   wf_directory.GetRoleInfo(username, realname, s0, s0, s0, s0);
3232 
3233   admin_mode := 'N';
3234   admin_role := wf_core.translate('WF_ADMIN_ROLE');
3235   if (admin_role = '*' or
3236       Wf_Directory.IsPerformer(username, admin_role)) then
3237       admin_mode := 'Y';
3238   end if;
3239 
3240   -- Set page title
3241   htp.htmlOpen;
3242 
3243   htp.headOpen;
3244 
3245   htp.p('<SCRIPT LANGUAGE="Javascript1.2">');
3246   htp.p('function launch_nav()
3247          { window.name="bigwin";
3248           newwind=window.open("'||owa_util.get_owa_service_path||'wfa_html.homemenu?message=&origin=FLOATING","newWindow","status=yes,toolbar=no,resizable=no,scrollbars=yes,width=200,height=250")
3249           }');
3250   htp.p('</SCRIPT>');
3251 
3252   htp.p('<NOSCRIPT>');
3253   htp.p(WF_CORE.Translate('WFA_NOSCRIPT'));
3254   htp.p('</NOSCRIPT>');
3255 
3256 
3257   htp.headClose;
3258   htp.p('<BODY>');
3259 
3260 
3261   htp.p('<SCRIPT LANGUAGE="Javascript1.2">');
3262   htp.p('launch_nav();');
3263   htp.p('</SCRIPT>');
3264 
3265   htp.p('<NOSCRIPT>');
3266   htp.p(WF_CORE.Translate('WFA_NOSCRIPT'));
3267   htp.p('</NOSCRIPT>');
3268 
3269   wfa_sec.Footer;
3270   htp.htmlClose;
3271 
3272   if (admin_mode = 'Y') then
3273      wfa_html.WorkList(user=>username,resetcookie=>1);
3274   else
3275      wfa_html.WorkList(resetcookie=>1);
3276   end if;
3277 
3278 
3279 end home_float;
3280 
3281 -- Homemenu
3282 -- Prints the menu for the home page.
3283 -- May also be called direct to print a regular page.
3284 
3285 procedure Homemenu(message in varchar2,
3286                origin  in varchar2)
3287 is
3288   username   varchar2(320);   -- Username to query
3289   realname   varchar2(360);   -- Display name of username
3290   admin_role varchar2(320);   -- Role for admin mode
3291   admin_mode varchar2(1);        -- Does user have admin privledges
3292   s0         varchar2(2000);
3293   anchor_tag varchar2(60);
3294 
3295   wrklstbuf  varchar2(2000); -- buffer to store worklist string
3296 begin
3297 
3298   -- Check session and current user
3299   wfa_sec.GetSession(username);
3300   username := upper(username);
3301   wf_directory.GetRoleInfo(username, realname, s0, s0, s0, s0);
3302 
3303   admin_mode := 'N';
3304   admin_role := wf_core.translate('WF_ADMIN_ROLE');
3305   if (admin_role = '*' or
3306       Wf_Directory.IsPerformer(username, admin_role)) then
3307       admin_mode := 'Y';
3308   end if;
3309 
3310   -- Set page title
3311   htp.htmlOpen;
3312   htp.headOpen;
3313   htp.title(wf_core.translate('WFA_HOMETITLE'));
3314   wfa_html.create_help_function('wf/links/web.htm?WEBHOME');
3315 
3316   htp.headClose;
3317 
3318   if origin = 'FLOATING' then
3319      anchor_tag := '<A TARGET="bigwin" HREF=';
3320      wfa_sec.Header(background_only=>TRUE);
3321   elsif origin = 'FRAME' then
3322      anchor_tag := '<A TARGET="_top" HREF=';
3323      wfa_sec.Header(background_only=>TRUE);
3324   else
3325      anchor_tag := '<A HREF=';
3326      wfa_sec.Header(background_only=>FALSE);
3327   end if;
3328 
3329 
3330 
3331   if origin = 'NORMAL'  then
3332 
3333      /* ### Do not display version
3334      -- Version
3335      htp.p('Oracle Workflow ' || wf_core.translate('WF_VERSION') || '<BR>');
3336 
3337      -- User, Admin Mode
3338      htp.p(realname || ' (' || username || ')');
3339      admin_role := wf_core.translate('WF_ADMIN_ROLE');
3340      if (admin_mode = 'Y') then
3341          htp.p(' - ' || wf_core.translate('WF_ADMIN'));
3342      end if;
3343      htp.p('<BR>');
3344      */
3345 
3346      -- Additional Message
3347      if (message is not null) then
3348          htp.p('<BR>');
3349          htp.p(message);
3350      end if;
3351   end if;
3352 
3353   if origin = 'FRAME' then
3354      htp.fontOpen(cface=>'ARIAL,HELVETICA',csize=>'-1');
3355   end if;
3356 
3357   if origin = 'NORMAL' then
3358      wrklstbuf := ' ('|| to_char(wf_notification.WorkCount(username)) ||
3359                   ' ' || wf_core.translate('OPEN_NOTIFICATIONS') || ')';
3360      htp.tableopen(calign=>'LEFT', cattributes=>'WIDTH=80% summary=""');
3361   else
3362      -- dont print the "n open notifications" message next to Worklist
3363      -- because worklist will be displayed.
3364      wrklstbuf := '';
3365      htp.tableopen(cattributes=>'summary=""');
3366   end if;
3367 
3368   if (admin_mode = 'Y') then
3372      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3369 
3370      -- WorkList     Event
3371      htp.tablerowopen;
3373              wf_core.translate('OPEN_NOTIFICATIONS')||'">'||
3374              anchor_tag||owa_util.get_owa_service_path ||
3375              'wfa_html.WorkList?user='||username||'&'||'resetcookie=1>'||
3376              wf_core.translate('WFA_WTITLE') || '</A>' ||
3377              wrklstbuf, cattributes=>'id=""');
3378 
3379      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3380              wf_core.translate('WFE_LIST_EVENTS_TITLE')||'">'||
3381              anchor_tag||owa_util.get_owa_service_path ||
3382              'wf_event_html.listevents?resetcookie=T>' ||
3383              wf_core.translate('WFE_LIST_EVENTS_TITLE')|| '</A>', cattributes=>'id=""');
3384      htp.tablerowclose;
3385 
3386      -- Find Notification     Find Event
3387      htp.tablerowopen;
3388      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3389              wf_core.translate('WFA_FINDTITLE')||'">'||
3390              anchor_tag||owa_util.get_owa_service_path || 'wfa_html.Find>' ||
3391              wf_core.translate('WFA_FINDTITLE') || '</A>', cattributes=>'id=""');
3392 
3393      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3394              wf_core.translate('WFE_FIND_EVENT_TITLE')||'">'||
3395              anchor_tag||owa_util.get_owa_service_path ||
3396              'wf_event_html.findevent>' ||
3397              wf_core.translate('WFE_FIND_EVENT_TITLE')|| '</A>', cattributes=>'id=""');
3398      htp.tablerowclose;
3399 
3400      -- Find Route            Systems
3401      htp.tablerowopen;
3402      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3403              wf_core.translate('WFRTG_LIST_TITLE')||'">'||
3404              anchor_tag||owa_util.get_owa_service_path || 'wf_route.Find>' ||
3405              wf_core.translate('WFRTG_FIND_TITLE') || '</A>', cattributes=>'id=""');
3406 
3407      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3408              wf_core.translate('WFE_LIST_SYSTEMS_TITLE')||'">'||
3409              anchor_tag||owa_util.get_owa_service_path ||
3410              'wf_event_html.listsystems?resetcookie=T>' ||
3411              wf_core.translate('WFE_LIST_SYSTEMS_TITLE')|| '</A>', cattributes=>'id=""');
3412      htp.tablerowclose;
3413 
3414      -- Find Process (Monitor)      Find system
3415      htp.tablerowopen;
3416      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3417              wf_core.translate('WFMON_FINDTITLE')||'">'||
3418              anchor_tag||owa_util.get_owa_service_path ||
3419              'wf_monitor.Find_Instance>' ||
3420              wf_core.translate('WFMON_FINDTITLE') || '</A>', cattributes=>'id=""');
3421 
3422      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3423              wf_core.translate('WFE_FIND_SYSTEM_TITLE')||'">'||
3424              anchor_tag||owa_util.get_owa_service_path ||
3425              'wf_event_html.findsystem>' ||
3426              wf_core.translate('WFE_FIND_SYSTEM_TITLE')|| '</A>', cattributes=>'id=""');
3427      htp.tablerowclose;
3428 
3429      -- User Preference            Agents
3430      htp.tablerowopen;
3431      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3432              wf_core.translate('WFPREF_EDIT_PREFS_TITLE')||'">'||
3433              anchor_tag||owa_util.get_owa_service_path ||
3434              'wf_pref.edit>' ||
3435              wf_core.translate('WFPREF_EDIT_PREFS_TITLE') || '</A>', cattributes=>'id=""');
3436 
3437      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3438              wf_core.translate('WFE_LIST_AGENTS_TITLE')||'">'||
3439              anchor_tag||owa_util.get_owa_service_path ||
3440              'wf_event_html.listagents?resetcookie=T>' ||
3441              wf_core.translate('WFE_LIST_AGENTS_TITLE')|| '</A>', cattributes=>'id=""');
3442      htp.tablerowclose;
3443 
3444      -- Global Perference          Find Agent
3445      htp.tablerowopen;
3446      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3447              wf_core.translate('WFPREF_EDIT_DEF_PREFS_TITLE')||'">'||
3448              anchor_tag||owa_util.get_owa_service_path ||
3449              'wf_pref.edit?edit_defaults=Y>' ||
3450              wf_core.translate('WFPREF_EDIT_DEF_PREFS_TITLE') || '</A>', cattributes=>'id=""');
3451 
3452      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3453              wf_core.translate('WFE_FIND_AGENT_TITLE')||'">'||
3454              anchor_tag||owa_util.get_owa_service_path ||
3455              'wf_event_html.findagent>' ||
3456              wf_core.translate('WFE_FIND_AGENT_TITLE')|| '</A>', cattributes=>'id=""');
3457      htp.tablerowclose;
3458 
3459      -- Document Nodes            Subscriptions
3460      htp.tablerowopen;
3461      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3462              wf_core.translate('WFDM_EDIT_NODE_TITLE')||'">'||
3463              anchor_tag||owa_util.get_owa_service_path ||
3464              'fnd_document_management.dm_nodes_display>' ||
3465              wf_core.translate('WFDM_EDIT_NODE_TITLE')|| '</A>', cattributes=>'id=""');
3466 
3470              'wf_event_html.listsubscriptions?resetcookie=T>' ||
3467      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3468              wf_core.translate('WFE_LIST_SUBSC_TITLE')||'">'||
3469              anchor_tag||owa_util.get_owa_service_path ||
3471              wf_core.translate('WFE_LIST_SUBSC_TITLE')|| '</A>', cattributes=>'id=""');
3472      htp.tablerowclose;
3473 
3474      -- Item Type Definition       Find Subscriptions
3475      htp.tablerowopen;
3476      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3477              wf_core.translate('WFITD_ITEM_TYPE_DEFINITION')||'">'||
3478              anchor_tag||owa_util.get_owa_service_path ||
3479              'wf_item_definition.find_item_type>' ||
3480              wf_core.translate('WFITD_ITEM_TYPE_DEFINITION')|| '</A>', cattributes=>'id=""');
3481 
3482      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3483              wf_core.translate('WFE_FIND_SUBSC_TITLE')||'">'||
3484              anchor_tag||owa_util.get_owa_service_path ||
3485              'wf_event_html.findsubscription>' ||
3486              wf_core.translate('WFE_FIND_SUBSC_TITLE')|| '</A>', cattributes=>'id=""');
3487      htp.tablerowclose;
3488 
3489      -- Launch Process              Check Setup
3490      htp.tablerowopen;
3491      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3492              wf_core.translate('WFINIT_ITEM_TYPE_TITLE')||'">'||
3493              anchor_tag||owa_util.get_owa_service_path ||
3494              'wf_initiate.itemtype>' ||
3495              wf_core.translate('WFINIT_ITEM_TYPE_TITLE')|| '</A>', cattributes=>'id=""');
3496 
3497      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3498              wf_core.translate('WFE_CHECK_ALL_TITLE')||'">'||
3499              anchor_tag||owa_util.get_owa_service_path ||
3500              'wf_setup.check_all>' ||
3501              wf_core.translate('WFE_CHECK_ALL_TITLE')|| '</A>', cattributes=>'id=""');
3502      htp.tablerowclose;
3503 
3504      -- Demo                        Raise Business Event
3505      htp.tablerowopen;
3506      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3507              wf_core.translate('WF_DEMO_MENU')||'">'||
3508              anchor_tag||owa_util.get_owa_service_path ||
3509              'wf_demo.home>' ||
3510              wf_core.translate('WF_DEMO_MENU')|| '</A>', cattributes=>'id=""');
3511 
3512       htp.tabledata('<img src="'||wfa_html.image_loc||
3513         'FNDWATHS.gif" height=18 width=18 alt="'||
3514              wf_core.translate('WFE_RAISE_EVENT_TITLE')||'">'||
3515              anchor_tag||owa_util.get_owa_service_path ||
3516              'wf_event_html.entereventdetails?p_event_name=%>' ||
3517              wf_core.translate('WFE_RAISE_EVENT_TITLE')|| '</A>', cattributes=>'id=""');
3518      htp.tablerowclose;
3519 
3520      -- System Signup
3521      htp.tablerowopen;
3522 
3523      htp.tabledata('', cattributes=>'id=""');
3524 
3525      htp.tabledata('<img src="'||wfa_html.image_loc||
3526         'FNDWATHS.gif" height=18 width=18 alt="'||
3527              wf_core.translate('WFE_SYSTEM_SIGNUP_TITLE')||'">'||
3528              anchor_tag||owa_util.get_owa_service_path ||
3529              'wf_event_html.entereventdetails?p_event_name=oracle.apps.wf.event.system.signup>' ||
3530              wf_core.translate('WFE_SYSTEM_SIGNUP_TITLE')|| '</A>', cattributes=>'id=""');
3531      htp.tablerowclose;
3532 
3533      -- Get System Identifier
3534      htp.tablerowopen;
3535 
3536      htp.tabledata('', cattributes=>'id=""');
3537 
3538      htp.tabledata('<img src="'||wfa_html.image_loc||
3539         'FNDWATHS.gif" height=18 width=18 alt="'||
3540              wf_core.translate('WFE_SYSTEM_IDENTIFIER_TITLE')||'">'||
3541              anchor_tag||owa_util.get_owa_service_path ||
3542              'wf_event_html.getsystemidentifier>' ||
3543              wf_core.translate('WFE_SYSTEM_IDENTIFIER_TITLE')|| '</A>', cattributes=>'id=""');
3544      htp.tablerowclose;
3545 
3546      -- Standard Event Queues
3547      htp.tablerowopen;
3548 
3549      htp.tabledata('', cattributes=>'id=""');
3550 
3551      htp.tabledata('<img src="'||wfa_html.image_loc||
3552         'FNDWATHS.gif" height=18 width=18 alt="'||
3553              wf_core.translate('WFE_EVENT_QUEUE_SUMMARY_TITLE')||'">'||
3554              anchor_tag||owa_util.get_owa_service_path ||
3555              'wf_event_html.eventqueuedisplay>' ||
3556              wf_core.translate('WFE_EVENT_QUEUE_SUMMARY_TITLE')|| '</A>', cattributes=>'id=""');
3557      htp.tablerowclose;
3558 
3559 
3560   else
3561      -- Worklist
3562      htp.tablerowopen;
3563      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3564              wf_core.translate('OPEN_NOTIFICATIONS')||'">'||
3565              anchor_tag||owa_util.get_owa_service_path ||
3566              'wfa_html.WorkList?resetcookie=1>'||
3567              wf_core.translate('WFA_WTITLE') || '</A>' ||
3568              wrklstbuf, cattributes=>'id=""');
3569      htp.tablerowclose;
3570 
3571      -- Find Notification
3572      htp.tablerowopen;
3573      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3574              wf_core.translate('WFA_FINDTITLE')||'">'||
3578      htp.tablerowclose;
3575              anchor_tag||owa_util.get_owa_service_path || 'wfa_html.Find>' ||
3576              wf_core.translate('WFA_FINDTITLE') || '</A>', cattributes=>'id=""');
3577 
3579 
3580      -- List Route
3581      htp.tablerowopen;
3582      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3583               wf_core.translate('WFRTG_LIST_TITLE')||'">'||
3584               anchor_tag||owa_util.get_owa_service_path || 'wf_route.List>' ||
3585               wf_core.translate('WFRTG_LIST_TITLE') || '</A>', cattributes=>'id=""');
3586      htp.tablerowclose;
3587 
3588      -- Find Process (Monitor)
3589      htp.tablerowopen;
3590      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3591              wf_core.translate('WFMON_FINDTITLE')||'">'||
3592              anchor_tag||owa_util.get_owa_service_path ||
3593              'wf_monitor.Find_Instance>' ||
3594              wf_core.translate('WFMON_FINDTITLE') || '</A>', cattributes=>'id=""');
3595      htp.tablerowclose;
3596 
3597      -- Personal Preference
3598      htp.tablerowopen;
3599      htp.tabledata('<img src="'||wfa_html.image_loc||'FNDWATHS.gif" height=18 width=18 alt="'||
3600              wf_core.translate('WFPREF_EDIT_PREFS_TITLE')||'">'||
3601              anchor_tag||owa_util.get_owa_service_path ||
3602              'wf_pref.edit>' ||
3603              wf_core.translate('WFPREF_EDIT_PREFS_TITLE') || '</A>', cattributes=>'id=""');
3604      htp.tablerowclose;
3605 
3606   end if;
3607 
3608   htp.tableclose;
3609 
3610   wfa_sec.Footer;
3611   htp.htmlClose;
3612 
3613 exception
3614   when others then
3615     rollback;
3616     wf_core.context('Wfa_Html', 'Homemenu');
3617     wfa_html.Error;
3618 end Homemenu;
3619 
3620 procedure create_reg_button (
3621 when_pressed_url  IN VARCHAR2,
3622 onmouseover       IN VARCHAR2,
3623 icon_top          IN VARCHAR2,
3624 icon_name         IN VARCHAR2,
3625 show_text         IN VARCHAR2)
3626 IS
3627 
3628 onmouseover_text varchar2(240);
3629 
3630 BEGIN
3631 
3632    -- when_pressed_url is a javascript call, so don't convert url character
3633 
3634    htp.p('<TABLE border=0 cellpadding=0 cellspacing=0 align=left summary="">');
3635 
3636    htp.p('<TR><TD height=22 rowspan=3 id="">');
3637 
3638    htp.p('<A href="'||when_pressed_url||'" alt="">');
3639 
3640    htp.p('<IMG src="/OA_MEDIA/FNDJLFRL.gif" alt="" height=22 width=15 border=0></A></TD>');
3641 
3642    htp.p('<TD height=1 bgcolor=#FFFFFF id=""><IMG src="/OA_MEDIA/FNDINVDT.gif" alt="" height=1 width=1></TD>');
3643 
3644    htp.p('<TD height=22 rowspan=3 id="">');
3645 
3646    htp.p('<A href="'||when_pressed_url||'" alt="">');
3647 
3648    htp.p('<IMG src="/OA_MEDIA/FNDJLFRR.gif" alt="" height=22 width=15 border=0></A></TD></TR>');
3649 
3650    htp.p('<TR>');
3651    htp.p('<TD height=20 align=center valign=center bgcolor=#cccccc nowrap id="">');
3652 
3653    htp.p('<A href="'||when_pressed_url||'" style="text-decoration:none"'||
3654           ' alt="'||wfa_html.replace_onMouseOver_quotes(onmouseover)||'">');
3655 
3656    htp.p('<FONT size=2 face="Arial,Helvetica,Geneva"  color=000000>'||show_text||'</FONT></A></TD></TR>');
3657 
3658    htp.p('<TR><TD height=1 bgcolor=000000 id=""><IMG src="/OA_MEDIA/FNDINVDT.gif" alt="" width=1 height=1></TD></TR>');
3659 
3660    htp.p('</TABLE>');
3661 
3662 exception
3663   when others then
3664     rollback;
3665     wf_core.context('Wfa_html', 'create_reg_button',when_pressed_url,onmouseover,
3666                     icon_top,icon_name,show_text);
3667     wfa_html.Error;
3668 
3669 end create_reg_button;
3670 
3671 -- show_plsql_doc
3672 --   Show the content of a plsql document in a browser window
3673 --   Called from the related documents function
3674 
3675 procedure show_plsql_doc (
3676   nid in number,
3677   aname in varchar2,
3678   nkey in varchar2)
3679 is
3680 
3681 username varchar2(320);
3682 
3683 clob_loc   clob;
3684 blob_loc   blob;
3685 clob_id    number;
3686 clob_chunk number := 0;
3687 doctext    varchar2(32000);
3688 end_of_text boolean :=FALSE;
3689 attr_name varchar2(30);
3690 
3691 slash           pls_integer;
3692 wfsession       varchar2(240);
3693 
3694 doctype varchar2(1000);
3695 lobsize number;
3696 amount number;
3697 
3698 l_enpos    pls_integer;
3699 l_copos    pls_integer;
3700 
3701 l_encoding varchar2(100);
3702 l_filename  varchar2(255);
3703 l_extension varchar2(50);
3704 l_mime_type varchar2(255);
3705 
3706 begin
3707 
3708   -- Verify if user is admin or can access this notification
3709   username := wfa_html.authenticate(nid,nkey);
3710 
3711   username := upper(username);
3712 
3713   -- note that GetAttrDoc will not translate for PLSQLCLOB
3714   doctext := wf_notification.getattrdoc(nid, aname,wf_notification.doc_html);
3715 
3716   -- if the attribute wasn't translated then try to translate for plsqlclobs.
3717   if doctext = '&'||aname then
3718     dbms_lob.createTemporary(clob_loc, false, dbms_lob.call);
3719     Wf_Notification.GetAttrCLOB(nid, aname, wf_notification.doc_html,
3720                                 clob_loc, doctype, attr_name);
3721     if (doctype is not null) then
3725     -- they are. Binary documents can only be downloaded
3722       Wf_Mail_Util.ParseContentType(doctype, l_mime_type, l_filename, l_extension, l_encoding);
3723     end if;
3724     -- We have the document. Now determine the output method. HTML documents can be output as
3726     if l_mime_type in (wf_notification.doc_text, wf_notification.doc_html) then
3727        -- HTML or text document.
3728        htp.htmlOpen;
3729        htp.headOpen;
3730        htp.p('<BASE TARGET="_top">');
3731        htp.title(wf_core.translate('WFITD_ATTR_TYPE_DOCUMENT'));
3732        wfa_html.create_help_function('wfnew/wfnew52.htm#nrr');
3733        htp.headClose;
3734        wfa_sec.Header(FALSE, '',wf_core.translate('WFITD_ATTR_TYPE_DOCUMENT'),
3735                       TRUE);
3736        htp.br;
3737 
3738        lobsize := dbms_lob.getlength(clob_loc);
3739        amount := 32000;
3740        wf_notification.clob_chunk := 0;
3741        while not (end_of_text) loop
3742           wf_notification.readattrclob(nid, aname, doctext, end_of_text);
3743           htp.prn(doctext);
3744        end loop;
3745        wfa_sec.Footer;
3746        htp.htmlClose;
3747     elsif attr_name is not null then
3748        -- BINARY Document
3749        if (l_encoding is not null) then
3750           -- Decode base64 encoded content
3751           if (upper(trim(l_encoding)) = 'BASE64') then
3752              dbms_lob.createTemporary(blob_loc, FALSE, dbms_lob.call);
3753 
3754              wf_mail_util.decodeBLOB(clob_loc, blob_loc);
3755              -- owa_util.mime_header(doctype, FALSE);
3756              -- Write appropriate headers before downloading the document
3757              if (l_filename is null or l_filename = '') then
3758                l_filename := aname || '.' || l_extension;
3759              end if;
3760              htp.p('Content-type: '||l_mime_type);
3761              htp.p('Content-Disposition: attachment; filename="'||l_filename||'"');
3762              htp.p('Content-length: ' || dbms_lob.getlength(blob_loc));
3763              htp.p('');
3764              -- owa_util.http_header_close;
3765 
3766              wpg_docload.download_file(blob_loc);
3767              dbms_lob.freeTemporary(blob_loc);
3768           end if;
3769        else
3770           -- This provides limited binary document support. It assumes that the document in
3771           -- stored as raw in varchar.
3772           owa_util.mime_header(l_mime_type, TRUE);
3773           lobsize := dbms_lob.getlength(clob_loc);
3774           amount := 32000;
3775           wf_notification.clob_chunk := 0;
3776           while not (end_of_text) loop
3777              wf_notification.readattrclob(nid, aname, doctext, end_of_text);
3778              htp.p(doctext);
3779           end loop;
3780        end if;
3781     else
3782        -- attr_name is null try for a PLSQLBLOB document
3783        dbms_lob.createTemporary(blob_loc, false, dbms_lob.call);
3784        Wf_Notification.GetAttrBLOB(nid, aname, wf_notification.doc_html,
3785                                    blob_loc, doctype, attr_name);
3786        if (doctype is not null) then
3787          Wf_Mail_Util.ParseContentType(doctype, l_mime_type, l_filename, l_extension, l_encoding);
3788        end if;
3789        if (l_filename is null or l_filename = '') then
3790          l_filename := aname || '.' || l_extension;
3791        end if;
3792        -- owa_util.mime_header(doctype, FALSE);
3793        htp.p('Content-type: '||l_mime_type);
3794        htp.p('Content-Disposition: attachment; filename="'||l_filename||'"');
3795        htp.p('Content-length: ' || dbms_lob.getlength(blob_loc));
3796        htp.p('');
3797        -- owa_util.http_header_close;
3798 
3799        wpg_docload.download_file(blob_loc);
3800        dbms_lob.freeTemporary(blob_loc);
3801     end if;
3802 
3803   else
3804      -- Set page title
3805      htp.htmlOpen;
3806      htp.headOpen;
3807      htp.title(wf_core.translate('WFITD_ATTR_TYPE_DOCUMENT'));
3808      wfa_html.create_help_function('wfnew/wfnew52.htm#nrr');
3809      htp.headClose;
3810      wfa_sec.Header(FALSE, '',wf_core.translate('WFITD_ATTR_TYPE_DOCUMENT'),
3811                     TRUE);
3812      htp.br;
3813 
3814      htp.p (doctext);
3815 
3816      wfa_sec.Footer;
3817      htp.htmlClose;
3818   end if;
3819 
3820 exception
3821   when others then
3822     wf_core.context('Wfa_Html','show_plsql_doc',nid, aname);
3823     wfa_html.Error;
3824 end show_plsql_doc;
3825 
3826 -- base_url
3827 -- Get the base url for the current browser where you have launched the
3828 -- login for Workflow
3829 function base_url  (get_from_resources BOOLEAN)
3830 return varchar2 IS
3831 
3832 l_base_url   VARCHAR2(2000) := NULL;
3833 
3834 BEGIN
3835 
3836     BEGIN
3837 
3838     IF (get_from_resources = FALSE) THEN
3839 
3840        -- Need to strip off trailing / to match wf_web_agent format
3841        l_base_url  := SUBSTR(RTRIM(owa_util.get_owa_service_path), 1,
3842                           LENGTH(RTRIM(owa_util.get_owa_service_path)) - 1);
3843 
3844     ELSE
3845 
3846        l_base_url := wf_core.translate ('WF_WEB_AGENT');
3847 
3848     END IF;
3849 
3850     EXCEPTION
3851     WHEN OTHERS THEN
3852 
3853        l_base_url := wf_core.translate ('WF_WEB_AGENT');
3854 
3855     END;
3856 
3860   when others then
3857     return (l_base_url);
3858 
3859 exception
3861     wf_core.context('Wfa_Html','base_url');
3862     wfa_html.Error;
3863 end base_url;
3864 
3865 --
3866 -- wf_user_val
3867 --   Create the lov content for our user lov.  This function
3868 --   is called by the generic lov function
3869 -- IN
3870 -- RETURNS
3871 --
3872 procedure  wf_user_val (
3873 p_mode           in varchar2,
3874 p_lov_name       in varchar2,
3875 p_start_row      in number,
3876 p_max_rows       in number,
3877 p_hidden_value   in out nocopy varchar2,
3878 p_display_value  in out nocopy varchar2,
3879 p_result         out nocopy number)
3880 
3881 
3882 IS
3883 
3884 CURSOR c_user_lov (c_find_criteria IN VARCHAR2) IS
3885 SELECT
3886  name,
3887  display_name
3888 FROM   wf_role_lov_vl
3889 where  status <> 'INACTIVE'
3890 and   (UPPER(display_name) LIKE UPPER(c_find_criteria)||'%')
3891 order by display_name;
3892 
3893 -- Added additional where condition "status <> 'INACTIVE' so only ACTIVE
3894 -- roles display
3895 
3896 -- CURSOR c_user_display_value (c_name IN VARCHAR2) IS
3897 -- select name, display_name
3898 -- from   wf_roles
3899 -- where  name = c_name;
3900 
3901 ii           NUMBER := 0;
3902 nn           NUMBER := 0;
3903 l_total_rows NUMBER := 0;
3904 l_id         NUMBER;
3905 l_name       VARCHAR2 (320);  -- enlarged from 30 to match db definition
3906 l_display_name VARCHAR2 (360); -- enlarged from 80 to match db definition
3907 l_result     NUMBER := 1;  -- This is the return value for each mode
3908 
3909 colon        NUMBER;
3910 
3911 role_info_tbl wf_directory.wf_local_roles_tbl_type;
3912 
3913 BEGIN
3914 
3915 if (p_mode = 'LOV') then
3916 
3917    /*
3918    ** Need to get a count on the number of rows that will meet the
3919    ** criteria before actually executing the fetch to show the user
3920    ** how many matches are available.
3921    */
3922    select count(*)
3923    into   l_total_rows
3924    FROM   wf_role_lov_vl
3925    where  status <> 'INACTIVE'
3926    and   (UPPER(display_name) LIKE UPPER(p_display_value)||'%');
3927 
3928    wf_lov.g_define_rec.total_rows := l_total_rows;
3929 
3930    wf_lov.g_define_rec.add_attr1_title := wf_core.translate ('WFITD_INTERNAL_NAME');
3931 
3932    open c_user_lov (p_display_value);
3933 
3934    LOOP
3935 
3936      FETCH c_user_lov INTO l_name, l_display_name;
3937 
3938      EXIT WHEN c_user_lov%NOTFOUND OR nn >= p_max_rows;
3939 
3940      ii := ii + 1;
3941 
3942      IF (ii >= p_start_row) THEN
3943 
3944         nn := nn + 1;
3945 
3946         wf_lov.g_value_tbl(nn).hidden_key      := l_name;
3947         wf_lov.g_value_tbl(nn).display_value   := l_display_name;
3948         wf_lov.g_value_tbl(nn).add_attr1_value := l_name;
3949 
3950      END IF;
3951 
3952    END LOOP;
3953 
3954    l_result := 1;
3955 
3956 elsif (p_mode = 'GET_DISPLAY_VAL') THEN
3957 
3958    Wf_Directory.GetRoleInfo2(p_hidden_value,role_info_tbl);
3959    l_name         := role_info_tbl(1).name;
3960    l_display_name := role_info_tbl(1).display_name;
3961    p_display_value:= l_name;
3962 
3963    l_result := 1;
3964 
3965 elsif (p_mode = 'VALIDATE') THEN
3966 
3967    /*
3968    ** If mode = VALIDATE then see how many rows match the criteria
3969    ** If its 0 then thats not good.  Raise an error and tell them to use LOV
3970    ** If its 1 then thats great.
3971    ** If its more than 1 then check to see if they used the LOV to select
3972    ** the value
3973    */
3974    open c_user_lov (p_display_value);
3975 
3976    LOOP
3977 
3978      FETCH c_user_lov INTO l_name, l_display_name;
3979 
3980      EXIT WHEN c_user_lov%NOTFOUND OR ii = 2;
3981 
3982      ii := ii + 1;
3983 
3984      p_hidden_value := l_name;
3985 
3986    END LOOP;
3987 
3988    /*
3989    ** If ii=0 then no rows were found and you have an error in the value
3990    **     entered so present a no rows found and use the lov icon to select
3991    **     value
3992    ** If ii=1 then one row is found then you've got the right value
3993    ** If ii=2 then more than one row was found so check to see if the display
3994    ** value taht was selected is not unique in the LOV (Person Name) and
3995    ** that the LOV was used so the Hidden value has been set to a unique
3996    ** value.  If it comes up with more than 1 in this case then present
3997    ** the please use lov icon to select value.
3998    */
3999    if (ii = 2) then
4000 
4001      -- copy logic from wf_directory.getroleinfo2
4002      colon := instr(p_display_value,':');
4003      if (colon = 0) then
4004        select count(*)
4005          into ii
4006          from WF_ROLES
4007         where NAME = p_display_value
4008           and ORIG_SYSTEM not in ('HZ_PARTY','POS','ENG_LIST','AMV_CHN',
4009                                   'HZ_GROUP','CUST_CONT');
4010      else
4011        select count(*)
4012          into ii
4013          from WF_ROLES
4014         where NAME = p_display_value
4015           and ORIG_SYSTEM    = substr(p_display_value, 1, colon-1)
4019    END IF;
4016           and ORIG_SYSTEM_ID = substr(p_display_value, colon+1);
4017      end if;
4018 
4020 
4021    l_result := ii;
4022 
4023 end if;
4024 
4025 p_result := l_result;
4026 
4027 exception
4028   when others then
4029     rollback;
4030     wf_core.context('Wfa_Html', 'wf_user_val');
4031     raise;
4032 end wf_user_val;
4033 
4034 
4035 function replace_onMouseOver_quotes(p_string in varchar2) return varchar2 is
4036 
4037 temp_string varchar2(2000);
4038 c_browser varchar2(400) := owa_util.get_cgi_env('HTTP_USER_AGENT');
4039 
4040 begin
4041 
4042 -- replace single quotes
4043 temp_string := replace(p_string,'''','\''');
4044 
4045 -- replace double quotes
4046 if (instr(c_browser, 'MSIE') <> 0) then
4047     temp_string := replace(temp_string,'"','\''');
4048 else
4049     temp_string := replace(temp_string,'"','`"');
4050 end if;
4051 
4052 -- check for double escapes
4053 temp_string := replace(temp_string,'\\','\');
4054 
4055 return temp_string;
4056 
4057 end replace_onMouseOver_quotes;
4058 
4059 procedure validate_display_name (
4060 p_display_name in varchar2,
4061 p_user_name    in out nocopy varchar2) IS
4062 
4063 l_colon         NUMBER := 0;
4064 l_names_count   NUMBER := 0;
4065 l_name          VARCHAR2(320);
4066 l_upper_name    VARCHAR2(360);
4067 l_orig_system_id NUMBER;
4068 l_get_role      BOOLEAN := TRUE;
4069 
4070 role_info_tbl wf_directory.wf_local_roles_tbl_type;
4071 
4072 BEGIN
4073 
4074    /*
4075    ** Make sure to blank out the internal name if the user originally
4076    ** used the LOV to select the name and then blanked out the display
4077    ** name then make sure here to blank out the insternal name and return
4078    */
4079    if (p_display_name is null) then
4080 
4081       p_user_name := NULL;
4082       return;
4083 
4084    end if;
4085 
4086    /*
4087    ** Bug# 2236250 validating the display name to contain a valid number
4088    ** after the colon to be used as a internal name for the role
4089    */
4090    l_colon := instr(p_display_name, ':');
4091    if (l_colon > 0) then
4092       begin
4093          l_orig_system_id := to_number(substr(p_display_name, l_colon+1));
4094       exception
4095          when invalid_number then
4096              l_get_role := FALSE;
4097          when others then
4098              raise;
4099       end;
4100       l_colon := 0;
4101    end if;
4102 
4103    /*
4104    ** First look first for internal name to see if you find a match.  If
4105    ** there are duplicate internal names that match the criteria then
4106    ** there is a problem with directory services but what can you do.  Go
4107    ** ahead and pick the first name so you return something
4108    **
4109    ** Bug# 2236250 calling Wf_Directory.GetRoleInfo2 only if the value
4110    ** after ':' is numeric.
4111    */
4112    if (l_get_role) then
4113       l_upper_name := upper(p_display_name);
4114       Wf_Directory.GetRoleInfo2(l_upper_name,role_info_tbl);
4115       l_name := role_info_tbl(1).name;
4116    end if;
4117 
4118    /*
4119    ** If you found a match on internal name then set the p_user_name
4120    ** accordingly.
4121    */
4122    if (l_name IS NOT NULL) then
4123 
4124       p_user_name := l_name;
4125 
4126    /*
4127    ** If there was no match on internal name then check for a display
4128    ** name
4129    */
4130    else
4131 
4132       /*
4133       ** Check out how many names match the display name
4134       */
4135       select count(1)
4136       into   l_names_count
4137       from   wf_role_lov_vl
4138       where  display_name = p_display_name;
4139 
4140       /*
4141       ** If there are no matches for the display name then raise an error
4142       */
4143       if (l_names_count = 0) then
4144 
4145          -- Not displayed or internal role name, error
4146          wf_core.token('ROLE', p_display_name);
4147          wf_core.raise('WFNTF_ROLE');
4148 
4149       /*
4150       ** If there is just one match then get the internal name
4151       ** and assign it.
4152       */
4153       elsif (l_names_count = 1) then
4154 
4155          select name
4156          into   l_name
4157          from   wf_role_lov_vl
4158          where  display_name = p_display_name;
4159 
4160          p_user_name  := l_name;
4161 
4162       /*
4163       ** If there is more than one match then see if the user
4164       ** used the lov to select the name in which case the combination
4165       ** of the display name and the user name should be unique
4166       */
4167       else
4168 
4169         -- copy logic from wf_directory.getroleinfo2
4170         l_colon := instr(p_user_name,':');
4171 
4172         if (l_colon = 0) then
4173           select count(1)
4174             into l_names_count
4175             from WF_ROLES
4176            where NAME = p_user_name
4177              and ORIG_SYSTEM not in ('HZ_PARTY','POS','ENG_LIST','AMV_CHN',
4181         /*
4178                                      'HZ_GROUP','CUST_CONT')
4179              and DISPLAY_NAME = p_display_name;
4180         else
4182         ** Bug# 2236250 validate if the value after ':' is number
4183         ** before using it in the query
4184         */
4185           begin
4186              l_orig_system_id := to_number(substr(p_user_name, l_colon+1));
4187           exception
4188              when invalid_number then
4189                 wf_core.raise('WFNTF_ORIGSYSTEMID');
4190              when others then
4191                 raise;
4192           end;
4193           select count(1)
4194             into l_names_count
4195             from WF_ROLES
4196            where NAME = p_user_name
4197              and ORIG_SYSTEM    = substr(p_user_name, 1, l_colon-1)
4198              and ORIG_SYSTEM_ID = l_orig_system_id
4199              and DISPLAY_NAME = p_display_name;
4200         end if;
4201 
4202         if (l_names_count <> 1) then
4203           wf_core.token('ROLE', p_display_name);
4204           wf_core.raise('WFNTF_UNIQUE_ROLE');
4205         end if;
4206 
4207       end if;
4208 
4209    end if;
4210 
4211 exception
4212   when others then
4213     wf_core.context('Wfa_Html', 'validate_display_name', p_display_name,
4214       p_user_name);
4215     raise;
4216 end validate_display_name;
4217 
4218 -- LongDesc
4219 --  Displays an html page with the token message.  This is called from
4220 --  frames for the LONGDESC attribute.
4221 procedure LongDesc (p_token       in varchar2)
4222 as
4223 BEGIN
4224     htp.htmlOpen;
4225     htp.headOpen;
4226     htp.title(wf_core.translate('LONG_DESC'));
4227     htp.headClose;
4228 
4229       begin
4230         wfa_sec.Header(background_only=>TRUE);
4231       exception
4232         when others then
4233           htp.bodyOpen;
4234       end;
4235 
4236     htp.p(WF_CORE.Translate(UPPER(p_token)));
4237 
4238     wfa_sec.Footer;
4239     htp.htmlClose;
4240 
4241 END LongDesc;
4242 
4243 end WFA_HTML;