DBA Data[Home] [Help]

PACKAGE BODY: APPS.PO_WF_PO_NOTIFICATION

Source


1 PACKAGE BODY PO_WF_PO_NOTIFICATION AS
2 /* $Header: POXWPA7B.pls 120.9.12010000.2 2008/08/04 08:36:10 rramasam ship $ */
3 
4 g_po_wf_debug VARCHAR2(1) := NVL(FND_PROFILE.VALUE('PO_SET_DEBUG_WORKFLOW_ON'),'N');
5 g_pkg_name         VARCHAR2(30) := 'PO_WF_PO_NOTIFICATION';    -- <BUG 3607009>
6 
7 PROCEDURE get_po_approve_msg (	 document_id	in	varchar2,
8                                  display_type	in	varchar2,
9                                  document	in out	NOCOPY varchar2,
10                                  document_type	in out	NOCOPY varchar2) IS
11 
12   l_item_type    wf_items.item_type%TYPE;
13   l_item_key     wf_items.item_key%TYPE;
14 
15   l_document_id      po_headers.po_header_id%TYPE;
16   l_org_id           po_headers.org_id%TYPE;
17   l_currency_code    fnd_currencies.CURRENCY_CODE%TYPE;
18   l_header_msg       VARCHAR2(500);
19   l_po_amount        VARCHAR2(30);
20   l_tax_amount       VARCHAR2(30);
21   l_description      po_headers.comments%TYPE;
22   l_forwarded_from   per_all_people_f.full_name%TYPE;
23   l_preparer         per_all_people_f.full_name%TYPE;
24 --<UTF-8 FPI START>
25 --  l_note             VARCHAR2(480);  /* < UTF8 FPI - changed from VARCHAR2(240) > */
26   l_note             po_action_history.note%TYPE;
27 --<UTF-8 FPI END>
28   l_document         VARCHAR2(32000) := '';
29   l_tax_amt          NUMBER;
30 
31   /* Start Bug# 3972475 */
32   X_precision        number;
33   X_ext_precision    number;
34   X_min_acct_unit    number;
35   /* End Bug# 3972475*/
36   l_supplier         po_vendors.vendor_name%type; --Bug 4254468
37   l_supplier_site    po_vendor_sites_all.vendor_site_code%type; --Bug 4254468
38   NL                 VARCHAR2(1) := fnd_global.newline;
39 
40 BEGIN
41 
42   l_item_type := substr(document_id, 1, instr(document_id, ':') - 1);
43   l_item_key := substr(document_id, instr(document_id, ':') + 1, length(document_id) - 2);
44 
45   l_document_id := wf_engine.GetItemAttrNumber
46                                         (itemtype   => l_item_type,
47                                          itemkey    => l_item_key,
48                                          aname      => 'DOCUMENT_ID');
49 
50   l_org_id := wf_engine.GetItemAttrNumber
51                                         (itemtype   => l_item_type,
52                                          itemkey    => l_item_key,
53                                          aname      => 'ORG_ID');
54 
55   PO_MOAC_UTILS_PVT.set_org_context(l_org_id) ;       -- <R12 MOAC>
56 
57 
58   l_currency_code := wf_engine.GetItemAttrText
59                                         (itemtype   => l_item_type,
60                                          itemkey    => l_item_key,
61                                          aname      => 'FUNCTIONAL_CURRENCY');
62 
63   l_po_amount := wf_engine.GetItemAttrText
64                                         (itemtype   => l_item_type,
65                                          itemkey    => l_item_key,
66                                          aname      => 'PO_AMOUNT_DSP');
67 
68   l_tax_amount := wf_engine.GetItemAttrText
69                                         (itemtype   => l_item_type,
70                                          itemkey    => l_item_key,
71                                          aname      => 'TAX_AMOUNT_DSP');
72 
73   l_description := wf_engine.GetItemAttrText
74                                         (itemtype   => l_item_type,
75                                          itemkey    => l_item_key,
76                                          aname      => 'PO_DESCRIPTION');
77 
78   l_forwarded_from := wf_engine.GetItemAttrText
79                                         (itemtype   => l_item_type,
80                                          itemkey    => l_item_key,
81                                          aname      => 'FORWARD_FROM_DISP_NAME');
82 
83   l_preparer := wf_engine.GetItemAttrText
84                                         (itemtype   => l_item_type,
85                                          itemkey    => l_item_key,
86                                          aname      => 'PREPARER_DISPLAY_NAME');
87 
88   l_note := wf_engine.GetItemAttrText
89                                         (itemtype   => l_item_type,
90                                          itemkey    => l_item_key,
91                                          aname      => 'NOTE');
92 
93   --<Bug 4254468 Start> Show supplier and supplier site for
94   -- approval notifications
95   l_supplier := PO_WF_UTIL_PKG.GetItemAttrText
96                                         (itemtype   => l_item_type,
97                                          itemkey    => l_item_key,
98                                          aname      => 'SUPPLIER');
99 
100   l_supplier_site := PO_WF_UTIL_PKG.GetItemAttrText
101                                         (itemtype   => l_item_type,
102                                          itemkey    => l_item_key,
103                                          aname      => 'SUPPLIER_SITE');
104   --<Bug 4254468 End>
105 
106 /*Start Bug# 3972475 - replaced the below sql to get the tax amount
107   to account for canceled QTY. Also accounted for new order types introduced
108   in 11i10 that use amount instead of quantity (where quantity_ordered is null).
109 
110   Since we are performing divide and multiply by operations we need rounding
111   logic based on the currency.
112 
113   If we are using minimum accountable unit we apply:
114    rounded tax = round(tax/mau)*mau, otherwise
115    rounded tax = round(tax, precision)
116 
117    Old tax select:
118   SELECT nvl(sum(nonrecoverable_tax), 0)
119     INTO l_tax_amt
120     FROM po_lines pol,
121          po_distributions pod
122    WHERE pol.po_header_id = l_document_id
123      AND pod.po_line_id = pol.po_line_id;
124 */
125 
126    fnd_currency.get_info( l_currency_code,
127                           X_precision,
128                           X_ext_precision,
129                           X_min_acct_unit);
130 
131   IF (x_min_acct_unit IS NOT NULL) AND
132       (x_min_acct_unit <> 0)
133   THEN
134     SELECT sum( round (POD.nonrecoverable_tax *
135                        decode(quantity_ordered,
136                               NULL,
137                               (nvl(POD.amount_ordered,0) - nvl(POD.amount_cancelled,0)) / nvl(POD.amount_ordered, 1),
138                               (nvl(POD.quantity_ordered,0) - nvl(POD.quantity_cancelled,0)) / nvl(POD.quantity_ordered, 1)
139                              ) / X_min_acct_unit
140                        ) * X_min_acct_unit
141               )
142     INTO l_tax_amt
143     FROM po_lines pol,
144          po_distributions pod
145    WHERE pol.po_header_id = l_document_id
146      AND pod.po_line_id = pol.po_line_id;
147   ELSE
148     SELECT sum( round (POD.nonrecoverable_tax *
149                        decode(quantity_ordered,
150                               NULL,
151                               (nvl(POD.amount_ordered,0) - nvl(POD.amount_cancelled,0)) / nvl(POD.amount_ordered, 1),
152                               (nvl(POD.quantity_ordered,0) - nvl(POD.quantity_cancelled,0)) / nvl(POD.quantity_ordered, 1)
153                              ),
154                        X_precision
155                       )
156               )
157     INTO l_tax_amt
158     FROM po_lines pol,
159          po_distributions pod
160    WHERE pol.po_header_id = l_document_id
161      AND pod.po_line_id = pol.po_line_id;
162   END IF;
163 
164   if (display_type = 'text/html') then
165 
166     l_document := NL || NL || '<!-- PO_APPROVE_MSG -->'|| NL || NL || '<P>';
167 
168     l_document := l_document || '</P>' || NL;
169 
170     l_document := l_document || '<P><TABLE border=0 cellpadding=0 cellspacing=0 SUMMARY=""><TR><TD align=right >' || NL ||
171                   fnd_message.get_string('PO', 'PO_WF_NOTIF_PO_AMOUNT') ||
172                   '  </TD>' || NL;
173 
174     l_document := l_document || '<TD align=left>' || l_currency_code || ' ' || l_po_amount || '</TD></TR>' || NL;
175 
176     if l_tax_amt > 0 then
177 
178       l_document := l_document || '<TR><TD align=right>' ||
179                     fnd_message.get_string('PO', 'PO_WF_NOTIF_TAX_AMOUNT') ||
180                     '  </TD>' || NL;
181       l_document := l_document || '<TD align=left>' || l_currency_code || ' ' || l_tax_amount ||
182                     '</TD></TR></TABLE></P>' || NL;
183 
184     else
185 
186       l_document := l_document || '</TABLE></P>' || NL || NL;
187 
188     end if;
189 
190     --<Bug 4254468 Start> Show supplier and supplier site for
191     -- approval notifications
192     l_document := l_document || '<P>' || NL;
193     l_document := l_document || fnd_message.get_string('PO', 'PO_FO_VENDOR') ||
194                   ' '|| l_supplier || NL;
195     l_document := l_document || '<BR>' || NL;
196     l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_SUPPLIER_SITE') ||
197                   ' '|| l_supplier_site || NL;
198     l_document := l_document || '</P>' || NL;
199     --<Bug 4254468 End>
200 
201     if l_description is not null then
202       l_document := l_document || '<P>' || NL;
203       l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_DOC_DESCRIPTION') || NL || '<BR>';
204       l_document := l_document || l_description;
205       l_document := l_document || '<BR></P>' || NL;
206     end if;
207 
208   else  -- plain text notification is defined in the WF.
209 
210 	null;
211 
212   end if;
213 
214   document := l_document;
215 
216 END;
217 
218 
219 PROCEDURE get_po_lines_details ( document_id	in	varchar2,
220                                  display_type	in	varchar2,
221                                  document	in out	NOCOPY CLOB, -- <BUG 7006113>
222                                  document_type	in out	NOCOPY varchar2) IS
223 
224   l_item_type        wf_items.item_type%TYPE;
225   l_item_key         wf_items.item_key%TYPE;
226 
227   l_document_id      po_lines.po_header_id%TYPE;
228   l_org_id           po_lines.org_id%TYPE;
229   l_document_type    VARCHAR2(25);
230 
231   l_document         VARCHAR2(32000) := '';
232 
233   l_currency_code    fnd_currencies.currency_code%TYPE;
234 
235   -- Bug 3668188: added new local var. note: the length of this
236   -- varchar was determined based on the length in POXWPA1B.pls,
237   -- which is the other place 'OPEN_FORM_COMMAND' attribute is used
238 
239   l_open_form_command VARCHAR2(200);
240   l_view_po_url      varchar2(1000);   -- HTML Orders R12
241   l_edit_po_url      varchar2(1000);   -- HTML Orders R12
242 
243   NL                 VARCHAR2(1) := fnd_global.newline;
244 
245   i 		     NUMBER := 0;
246   max_lines_dsp      NUMBER ;  -- <BUG 7006113>
247   l_line_count       NUMBER := 0; -- <BUG 3616816> # lines/shipments on document
248   line_mesg          fnd_new_messages.message_text%TYPE; --Bug 4695601
249   l_num_records_to_display NUMBER;      -- <BUG 3616816> actual # of records to be displayed in table
250 
251   -- <BUG 7006113 START>
252   -- curr_len           NUMBER := 0;
253   -- prior_len          NUMBER := 0;
254   -- <BUG 7006113 END>
255 
256 -- po lines cursor
257 
258     -- <BUG 3616816 START> Declare TABLEs for each column that is selected
259     -- from po_line_csr and po_line_loc_csr.
260     --
261     TYPE line_num_tbl_type IS TABLE OF PO_LINES.line_num%TYPE;
262     TYPE shipment_num_tbl_type IS TABLE OF PO_LINE_LOCATIONS.shipment_num%TYPE;
263     TYPE item_num_tbl_type IS TABLE OF MTL_SYSTEM_ITEMS_KFV.concatenated_segments%TYPE;
264     TYPE item_revision_tbl_type IS TABLE OF PO_LINES.item_revision%TYPE;
265     TYPE item_desc_tbl_type IS TABLE OF PO_LINES.item_description%TYPE;
266     TYPE uom_tbl_type IS TABLE OF MTL_UNITS_OF_MEASURE.unit_of_measure_tl%TYPE;
267     TYPE quantity_tbl_type IS TABLE OF PO_LINES.quantity%TYPE;
268     TYPE unit_price_tbl_type IS TABLE OF PO_LINES.unit_price%TYPE;
269     TYPE amount_tbl_type IS TABLE OF PO_LINES.amount%TYPE;
270     TYPE location_tbl_type IS TABLE OF HR_LOCATIONS.location_code%TYPE;
271     TYPE organization_name_tbl_type IS TABLE OF ORG_ORGANIZATION_DEFINITIONS.organization_name%TYPE;
272     TYPE need_by_date_tbl_type IS TABLE OF PO_LINE_LOCATIONS.need_by_date%TYPE;
273     TYPE promised_date_tbl_type IS TABLE OF PO_LINE_LOCATIONS.promised_date%TYPE;
274     TYPE shipment_type_tbl_type IS TABLE OF PO_LINE_LOCATIONS.shipment_type%TYPE;
275 
276     l_line_num_tbl         line_num_tbl_type;
277     l_shipment_num_tbl     shipment_num_tbl_type;
278     l_item_num_tbl         item_num_tbl_type;
279     l_item_revision_tbl    item_revision_tbl_type;
280     l_item_desc_tbl        item_desc_tbl_type;
281     l_uom_tbl              uom_tbl_type;
282     l_quantity_tbl         quantity_tbl_type;
283     l_unit_price_tbl       unit_price_tbl_type;
284     l_amount_tbl           amount_tbl_type;
285     l_location_tbl         location_tbl_type;
286     l_org_name_tbl         organization_name_tbl_type;
287     l_need_by_date_tbl     need_by_date_tbl_type;
288     l_promised_date_tbl    promised_date_tbl_type;
289     l_shipment_type_tbl    shipment_type_tbl_type;
290     --
291     -- <BUG 3616816 END>
292 
293 /* Bug# 1419139: kagarwal
294 ** Desc: The where clause pol.org_id = msi.organization_id(+) in the
295 ** PO lines cursor, po_line_csr, is not correct as the pol.org_id
296 ** is the operating unit which is not the same as the inventory
297 ** organization_id.
298 **
299 ** We need to use the financials_system_parameter table for the
300 ** inventory organization_id.
301 **
302 ** Also did the similar changes for the Release cursor,po_line_loc_csr.
303 */
304 
305 /* Bug 2401933: sktiwari
306    Modifying cursor po_line_csr to return the translated UOM value
307    instead of unit_meas_lookup_code.
308 */
309 
310 CURSOR po_line_csr(v_document_id NUMBER) IS
311 SELECT pol.line_num,
312        msi.concatenated_segments,
313        pol.item_revision,
314        pol.item_description,
315 --     pol.unit_meas_lookup_code, -- bug 2401933.remove
316        nvl(muom.unit_of_measure_tl, pol.unit_meas_lookup_code), -- bug 2401933.add
317        pol.quantity,
318        pol.unit_price,
319        nvl(pol.amount, pol.quantity * pol.unit_price)
320   FROM po_lines   pol,
321        mtl_system_items_kfv   msi,
322        mtl_units_of_measure   muom,     -- bug 2401933.add
323        financials_system_parameters  fsp
324  WHERE pol.po_header_id = v_document_id
325    AND pol.item_id = msi.inventory_item_id(+)
326    AND NVL(msi.organization_id, fsp.inventory_organization_id) =
327           fsp.inventory_organization_id
328 /* Bug 2299484 fixed. prevented the canceled lines to be displayed
329    in notifications.
330 */
331    AND NVL(pol.cancel_flag,'N') = 'N'
332    AND muom.unit_of_measure (+) = pol.unit_meas_lookup_code  -- bug 2401933.add
333  ORDER BY pol.line_num;
334 
335 -- release shipments cursor
336 
337 /* Bug# 1530303: kagarwal
338 ** Desc: We need to change the where clause as the item
339 ** may not be an inventory item. For this case we should
340 ** have an outer join with the mtl_system_items_kfv.
341 **
342 ** Changed the condition:
343 ** pol.item_id = msi.inventory_item_id
344 ** to pol.item_id = msi.inventory_item_id(+)
345 **
346 */
347 
348 /* Bug# 1718725: kagarwal
349 ** Desc: The unit of measure may be null at the shipment level
350 ** hence in this case we need to get the uom from line level.
351 **
352 ** Changed nvl(pll.unit_meas_lookup_code, pol.unit_meas_lookup_code)
353 */
354 /* Bug# 1770951: kagarwal
355 ** Desc: For Releases we should consider the price_override on the shipments
356 ** and not the price on the Blanket PO line as the shipment price could be
357 ** different if the price override is enabled on the Blanket.
358 */
359 
360 /* Bug 2401933: sktiwari
361    Modifying cursor po_line_loc_csr to return the translated UOM value
362    instead of unit_meas_lookup_code.
363 */
364 
365 CURSOR po_line_loc_csr(v_document_id NUMBER) IS
366 SELECT pll.shipment_num,
367        msi.concatenated_segments,
368        pol.item_revision,
369        pol.item_description,
370 -- Bug 2401933.start
371 --     nvl(pll.unit_meas_lookup_code, pol.unit_meas_lookup_code)
372 --         unit_meas_lookup_code,
373        nvl(muom.unit_of_measure_tl, pol.unit_meas_lookup_code),
374 -- Bug 2401933.end
375        pll.quantity,
376        nvl(pll.price_override, pol.unit_price) unit_price,
377        hrl.location_code,
378        ood.organization_name,
379        pll.need_by_date,
380        pll.promised_date,
381        pll.shipment_type,
382        --Bug 4950850 Added pll.amount
383        --Bug 5563024 AMOUNT NOT SHOWN FOR A RELEASE SHIPMENT IN APPROVAL NOTIFICATION.
384        nvl(pll.amount, nvl(pll.price_override, pol.unit_price) * pll.quantity)
385   FROM po_lines   pol,
386        po_line_locations pll,
387        mtl_system_items_kfv msi,
388        hr_locations_all hrl,
389        hz_locations hz,
390        org_organization_definitions ood,
391        mtl_units_of_measure   muom,     -- Bug 2401933.add
392        financials_system_parameters  fsp
393   where  PLL.PO_RELEASE_ID = v_document_id
394   and    PLL.po_line_id    = POL.po_line_id
395   and    PLL.ship_to_location_id = HRL.location_id (+)
396   and    PLL.ship_to_location_id = HZ.location_id (+)
397   and    PLL.ship_to_organization_id = OOD.organization_id
398   and    pol.item_id = msi.inventory_item_id(+)
399   and    NVL(msi.organization_id, fsp.inventory_organization_id) =
400           fsp.inventory_organization_id
401  /* Bug 2299484 fixed. prevented the canceled shipments to be displayed
402    in notifications.
403 */
404    AND NVL(PLL.cancel_flag,'N') = 'N'
405    AND muom.unit_of_measure (+) = pol.unit_meas_lookup_code  -- Bug 2401933.add
406   order by Shipment_num asc;
407 
408 BEGIN
409 
410   l_item_type := substr(document_id, 1, instr(document_id, ':') - 1);
411   l_item_key := substr(document_id, instr(document_id, ':') + 1,
412                        length(document_id) - 2);
413 
414   /* Bug# 2353153
415   ** Setting application context
416   */
417 
418   PO_REQAPPROVAL_INIT1.Set_doc_mgr_context(l_item_type, l_item_key);
419 
420   l_document_id := wf_engine.GetItemAttrNumber (itemtype   => l_item_type,
421                                          	itemkey    => l_item_key,
422                                          	aname      => 'DOCUMENT_ID');
423 
424   l_org_id := wf_engine.GetItemAttrNumber (itemtype   => l_item_type,
425                                            itemkey    => l_item_key,
426                                            aname      => 'ORG_ID');
427 
428   l_document_type := wf_engine.GetItemAttrText (itemtype   => l_item_type,
429                                            	itemkey    => l_item_key,
430                                            	aname      => 'DOCUMENT_TYPE');
431 
432   PO_MOAC_UTILS_PVT.set_org_context(l_org_id) ;       -- <R12 MOAC>
433 
434 
435   /* Bug# 1686066: kagarwal
436   ** Desc: Use the functional currency of the PO for the precision of
437   ** line amounts.
438   */
439 
440   l_currency_code := wf_engine.GetItemAttrText
441                                (itemtype   => l_item_type,
442                                 itemkey    => l_item_key,
443                                 aname      => 'FUNCTIONAL_CURRENCY');
444 
445 
446   -- Bug 3668188
447   l_open_form_command := PO_WF_UTIL_PKG.GetItemAttrText
448                                (itemtype   => l_item_type,
449                                 itemkey    => l_item_key,
450                                 aname      => 'OPEN_FORM_COMMAND');
451 
452   -- HTML Orders R12
453   -- Get the PO HTML Page URL's
454   l_view_po_url := PO_WF_UTIL_PKG.GetItemAttrText (
455                               itemtype   => l_item_type,
456                               itemkey    => l_item_key,
457                               aname      => 'VIEW_DOC_URL');
458 
459   l_edit_po_url := PO_WF_UTIL_PKG.GetItemAttrText (
460                               itemtype   => l_item_type,
461                               itemkey    => l_item_key,
462                               aname      => 'EDIT_DOC_URL');
463 
464 
465 /* Bug# 2668222: kagarwal
466 ** Desc: Using profile PO_NOTIF_LINES_LIMIT to get the maximum
467 ** number of PO lines to be displayed in Approval notification.
468 ** The same profile is also used for Requisitions.
469 */
470   -- <BUG 7006113  START Moved this code to the later section of the procedure >
471   --  max_lines_dsp:= to_number(fnd_profile.value('PO_NOTIF_LINES_LIMIT'));
472 
473   -- if max_lines_dsp is NULL then
474   --   max_lines_dsp := 20;
475   -- end if;
476   -- <BUG 7006113 END>
477 
478     -- <BUG 3616816 START> Fetch Release Shipments/PO Lines data into Tables.
479     --
480     IF ( l_document_type = 'RELEASE' ) THEN
481 
482         OPEN po_line_loc_csr(l_document_id);
483 
484         FETCH po_line_loc_csr BULK COLLECT INTO l_shipment_num_tbl
485                                               , l_item_num_tbl
486                                               , l_item_revision_tbl
487                                               , l_item_desc_tbl
488                                               , l_uom_tbl
489                                               , l_quantity_tbl
490                                               , l_unit_price_tbl
491                                               , l_location_tbl
492                                               , l_org_name_tbl
493                                               , l_need_by_date_tbl
494                                               , l_promised_date_tbl
495                                               , l_shipment_type_tbl
496                                               , l_amount_tbl;    --bug 4950850
497 
498         l_line_count := po_line_loc_csr%ROWCOUNT; -- Get # of records fetched.
499 
500         CLOSE po_line_loc_csr;
501 
502     ELSE
503 
504         OPEN po_line_csr(l_document_id);
505 
506         FETCH po_line_csr BULK COLLECT INTO l_line_num_tbl
507                                           , l_item_num_tbl
508                                           , l_item_revision_tbl
509                                           , l_item_desc_tbl
510                                           , l_uom_tbl
511                                           , l_quantity_tbl
512                                           , l_unit_price_tbl
513                                           , l_amount_tbl;
514 
515         l_line_count := po_line_csr%ROWCOUNT; -- Get # of records fetched.
516 
517         CLOSE po_line_csr;
518 
519     END IF;
520     --
521     -- <BUG 3616816 END>
522 
523     max_lines_dsp:= to_number(fnd_profile.value('PO_NOTIF_LINES_LIMIT'));
524 
525     IF max_lines_dsp IS NULL THEN
526 
527 	max_lines_dsp := l_line_count;
528 
529     END IF;
530 
531     -- <BUG 3616816 START> Determine the actual number of records to display
532     -- in the table.
533     --
534     IF ( l_line_count >= max_lines_dsp )
535     THEN
536         l_num_records_to_display := max_lines_dsp;
537     ELSE
538         l_num_records_to_display := l_line_count;
539     END IF;
540     --
541     -- <BUG 3616816 END>
542 
543   if (display_type = 'text/html') then
544 
545     if (nvl(l_document_type, 'PO') <> 'RELEASE') then
546 
547     	l_document := NL || NL || '<!-- PO_LINE_DETAILS -->'|| NL || NL || '<P><B>';
548     	l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_PO_LINE_DETAILS');
549     	l_document := l_document || '</B>' || NL || '<P>';     -- <BUG 3616816>
550 
551         -- <BUG 3616816 START> Only display message if # of actual lines is
552         -- greater than maximum limit.
553         --
554         IF ( l_line_count > max_lines_dsp ) THEN
555 
556             -- Bug 3668188: changed the code check (originally created
557             -- in bug 3607009) that determines which message to show
558             -- based on whether Open Document icon is shown in the notif.
559             -- The value of WF attribute 'OPEN_FORM_COMMAND' is set in a
560             -- previous node, using the get_po_user_msg_attribute procedure.
561             --
562             -- HTML Orders R12
563             -- Check for the URL parameters as well
564             IF  (l_open_form_command IS NULL ) AND
565                 (l_view_po_url IS NULL )       AND
566                 (l_edit_po_url IS NULL )
567             THEN
568                -- "The first [COUNT] Purchase Order lines are summarized below."
569                FND_MESSAGE.set_name('PO','PO_WF_NOTIF_PO_LINE_MESG_TRUNC');
570             ELSE
571                -- "The first [COUNT] Purchase Order lines are summarized
572                -- below. For information on additional lines, please click
573                -- the Open Document icon."
574                FND_MESSAGE.set_name('PO','PO_WF_NOTIF_PO_LINE_MESG');
575             END IF;
576 
577             FND_MESSAGE.set_token('COUNT',to_char(max_lines_dsp));
578             line_mesg := FND_MESSAGE.get;
579             l_document := l_document || line_mesg || '<P>';
580 
581 
582         END IF;
583         --
584         -- <BUG 3616816 END>
585 
586     	l_document := l_document || NL || '<TABLE border=1 cellpadding=2 cellspacing=1 summary="' ||  fnd_message.get_string('ICX','ICX_POR_TBL_PO_TO_APPROVE_SUM') || '"> '|| NL;
587 
588     	l_document := l_document || '<TR>' || NL;
589 
590     	l_document := l_document || '<TH  id="lineNum_1">' ||
591    	               fnd_message.get_string('PO', 'PO_WF_NOTIF_LINE_NUMBER') || '</TH>' || NL;
592 
593     	l_document := l_document || '<TH  id="itemNum_1">' ||
594     	              fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_NUMBER') || '</TH>' || NL;
595 
596    	l_document := l_document || '<TH  id="itemRev_1">' ||
597         	      fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_REVISION') || '</TH>' || NL;
598 
599     	l_document := l_document || '<TH  id="itemDesc_1">' ||
600                   	fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_DESC') || '</TH>' || NL;
601 
602     	l_document := l_document || '<TH  id="uom_1">' ||
603                   	fnd_message.get_string('PO', 'PO_WF_NOTIF_UOM') || '</TH>' || NL;
604 
605     	l_document := l_document || '<TH  id="quant_1">' ||
606                   fnd_message.get_string('PO', 'PO_WF_NOTIF_QUANTITY') || '</TH>' || NL;
607 
608     	l_document := l_document || '<TH  id="unitPrice_1">' ||
609                   fnd_message.get_string('PO', 'PO_WF_NOTIF_UNIT_PRICE') || '</TH>' || NL;
610 
611     	l_document := l_document || '<TH  id="lineAmt_1">' ||
612                   fnd_message.get_string('PO', 'PO_WF_NOTIF_LINE_AMOUNT') || '</TH>' || NL;
613 
614     	l_document := l_document || '</TR>' || NL;
615 
616         -- curr_len  := lengthb(l_document);
617         -- prior_len := curr_len;
618 
619         FOR i IN 1..l_num_records_to_display LOOP              -- <BUG 3616816>
620 
621                 /* Exit the cursor if the current document length and 2 times the
622                 ** length added in prior line exceeds 32000 char */
623 		-- < BUG 7006113 START Commented the loop to avoid the check so that maximum
624                 --  lines can be displayed >
625                 -- if (curr_len + (2 * (curr_len - prior_len))) >= 32000 then
626                 --  exit;
627                 --  end if;
628 		--  prior_len := curr_len;
629 		-- < BUG 7006113 END >
630 
631       		l_document := l_document || '<TR>' || NL;
632 
633       		l_document := l_document || '<TD nowrap align=center headers="lineNum_1">'
634 						    || nvl(to_char(l_line_num_tbl(i)), ' ') || '</TD>' || NL;
635       		l_document := l_document || '<TD nowrap headers="itemNum_1">'
636 						    || nvl(l_item_num_tbl(i), ' ') || '</TD>' || NL;
637       		l_document := l_document || '<TD nowrap headers="itemRev_1">'
638 						    || nvl(l_item_revision_tbl(i), ' ') || '</TD>' || NL;
639       		l_document := l_document || '<TD nowrap headers="itemDesc_1">'
640 						    || nvl(l_item_desc_tbl(i), ' ') || '</TD>' || NL;
641       		l_document := l_document || '<TD nowrap headers="uom_1">'
642 						    || nvl(l_uom_tbl(i), ' ') || '</TD>' || NL;
643       		l_document := l_document || '<TD nowrap align=right headers="quant_1">'
644 						    || nvl(to_char(l_quantity_tbl(i)), ' ') || '</TD>' || NL;
645 
646 /* Bug 2868931: kagarwal
647 ** We will not format the unit price on the lines in notifications
648 */
649                 -- Bug 3547777. Added the nvl clauses to unit_price and line_
650                 -- amount so that box is still displayed even if value is null.
651       		l_document := l_document || '<TD nowrap align=right headers="unitPrice_1">' ||
652                      nvl(PO_WF_REQ_NOTIFICATION.FORMAT_CURRENCY_NO_PRECESION(l_currency_code,l_unit_price_tbl(i)),' ') || '</TD>' || NL; -- <BUG 7006113>
653 
654       		l_document := l_document || '<TD nowrap align=right headers="lineAmt_1">' ||
655                   nvl(TO_CHAR(l_amount_tbl(i), FND_CURRENCY.GET_FORMAT_MASK(
656                               l_currency_code, 30)),' ') || '</TD>' || NL;
657 
658       		l_document := l_document || '</TR>' || NL;
659 
660                 -- <BUG 7006113 START>
661 		--curr_len  := lengthb(l_document);
662 
663                 wf_notification.writetoclob(document, l_document);
664 
665                 l_document := NULL;
666 
667 		EXIT WHEN i = l_num_records_to_display;
668 		-- <BUG 7006113 END>
669     	end loop;
670 
671     else    -- release
672 
673     	l_document := NL || NL || '<!-- RELEASE_SHIPMENT_DETAILS -->'|| NL || NL || '<P><B>';
674     	l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_SHIP_DETAILS');
675     	l_document := l_document || '</B>' || NL || '<P>';
676 
677         -- <BUG 3616816 START> Only display message if # of actual lines is
678         -- greater than maximum limit.
679         --
680         IF ( l_line_count > max_lines_dsp )
681         THEN
682             FND_MESSAGE.set_name('PO','PO_WF_NOTIF_PO_REL_SHIP_MESG');
683             FND_MESSAGE.set_token('COUNT',to_char(max_lines_dsp));
684             line_mesg := FND_MESSAGE.get;
685             l_document := l_document || line_mesg || '<P>';
686         END IF;
687         --
688         -- <BUG 3616816 END>
689 
690     	l_document := l_document || '<TABLE border=1 cellpadding=2 cellspacing=1 summary="' ||  fnd_message.get_string('ICX','ICX_POR_TBL_BL_TO_APPROVE_SUM') || '"> '|| NL;
691 
692     	l_document := l_document || '<TR>' || NL;
693 
694     	l_document := l_document || '<TH  id="shipNum_2">' ||
695    	               fnd_message.get_string('PO', 'PO_WF_NOTIF_SHIP_NUMBER') || '</TH>' || NL;
696 
697     	l_document := l_document || '<TH  id="itemNum_2">' ||
698     	              fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_NUMBER') || '</TH>' || NL;
699 
700    	l_document := l_document || '<TH  id="itemRev_2">' ||
701         	      fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_REVISION') || '</TH>' || NL;
702 
703     	l_document := l_document || '<TH  id="itemDesc_2">' ||
704                   	fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_DESC') || '</TH>' || NL;
705 
706     	l_document := l_document || '<TH  id="uom_2">' ||
707                   	fnd_message.get_string('PO', 'PO_WF_NOTIF_UOM') || '</TH>' || NL;
708 
709     	l_document := l_document || '<TH  id="quant_2">' ||
710                   fnd_message.get_string('PO', 'PO_WF_NOTIF_QUANTITY') || '</TH>' || NL;
711 
712     	l_document := l_document || '<TH  id="unitPrice_2">' ||
713                   fnd_message.get_string('PO', 'PO_WF_NOTIF_UNIT_PRICE') || '</TH>' || NL;
714 
715     	l_document := l_document || '<TH  id="location_2">' ||
716                   fnd_message.get_string('PO', 'PO_WF_NOTIF_LOCATION') || '</TH>' || NL;
717 
718     	l_document := l_document || '<TH  id="shipToOrg_2">' ||
719                   fnd_message.get_string('PO', 'POA_SHIP_TO_ORG') || '</TH>' || NL;
720 
721     	l_document := l_document || '<TH  id="needByDate_2">' ||
722                   fnd_message.get_string('PO', 'PO_WF_NOTIF_NEED_BY_DATE') || '</TH>' || NL;
723 	/* bug 4950850 */
724        	l_document := l_document || '<TH  id="lineAmt_2">' ||
725                   fnd_message.get_string('PO', 'PO_WF_NOTIF_AMOUNT') || '</TH>' || NL;
726 
727     	l_document := l_document || '</TR>' || NL;
728 
729         -- curr_len  := lengthb(l_document);
730         -- prior_len := curr_len;
731 
732         FOR i IN 1..l_num_records_to_display LOOP              -- <BUG 3616816>
733 
734                 /* Exit the cursor if the current document length and 2 times the
735                 ** length added in prior line exceeds 32000 char */
736                 -- < BUG 7006113 START Commented the loop to avoid the check so that
737 		--   maximum lines can be displayed >
738                 -- if (curr_len + (2 * (curr_len - prior_len))) >= 32000 then
739                 --   exit;
740                 -- end if;
741 		-- prior_len := curr_len;
742 		-- < BUG 7006113 END >
743 
744       		l_document := l_document || '<TR>' || NL;
745 
746    		l_document := l_document || '<TD nowrap align=center headers="shipNum_2">'
747 				|| nvl(to_char(l_shipment_num_tbl(i)), ' ') || '</TD>' || NL;
748       		l_document := l_document || '<TD nowrap  headers="itemNum_2">'
749 				|| nvl(l_item_num_tbl(i), ' ') || '</TD>' || NL;
750       		l_document := l_document || '<TD nowrap  headers="itemRev_2">'
751 				|| nvl(l_item_revision_tbl(i), ' ') || '</TD>' || NL;
752       		l_document := l_document || '<TD nowrap  headers="itemDesc_2">'
753 				|| nvl(l_item_desc_tbl(i), ' ') || '</TD>' || NL;
754       		l_document := l_document || '<TD nowrap  headers="uom_2">'
755 				|| nvl(l_uom_tbl(i), ' ') || '</TD>' || NL;
756       		l_document := l_document || '<TD nowrap align=right  headers="quant_2">'
757 				|| nvl(to_char(l_quantity_tbl(i)), ' ') || '</TD>' || NL;
758 
759 /* Bug 2868931: kagarwal
760 ** We will not format the unit price on the lines in notifications
761 */
762 
763       		l_document := l_document || '<TD nowrap align=right  headers="unitPrice_2">' ||
764                                   nvl(PO_WF_REQ_NOTIFICATION.FORMAT_CURRENCY_NO_PRECESION(
765 				      l_currency_code,l_unit_price_tbl(i)),' ') || '</TD>' || NL;  -- <BUG 7006113>
766 
767       		l_document := l_document || '<TD nowrap  headers="location_2">'
768 				|| nvl(l_location_tbl(i), ' ') || '</TD>' || NL;
769       		l_document := l_document || '<TD nowrap  headers="shipToOrg_2">'
770 				|| nvl(l_org_name_tbl(i), ' ') || '</TD>' || NL;
771 	      	l_document := l_document || '<TD nowrap  headers="needByDate_2">'
772 				|| to_char(l_need_by_date_tbl(i)) || '</TD>' || NL;
773                 /* bug 4950850 */
774                 l_document := l_document || '<TD nowrap align=right headers="lineAmt_2">' ||
775                   nvl(TO_CHAR(l_amount_tbl(i), FND_CURRENCY.GET_FORMAT_MASK(
776                               l_currency_code, 30)),' ') || '</TD>' || NL;
777       		l_document := l_document || '</TR>' || NL;
778 
779                 -- <BUG 7006113 START>
780 		-- curr_len  := lengthb(l_document);
781 
782                 wf_notification.writetoclob(document, l_document);
783 
784                 l_document := NULL;
785 
786 		EXIT WHEN i = l_num_records_to_display;
787 		-- <BUG 7006113 END>
788 
789     	end loop;
790 
791     end if;
792     l_document := l_document || '</TABLE></P>' || NL;
793 
794     wf_notification.writetoclob(document, l_document); 	-- <BUG 7006113>
795 
796     -- document := l_document; -- <BUG 7006113>
797 
798   elsif (display_type = 'text/plain') then
799 
800     if (nvl(l_document_type, 'PO') <> 'RELEASE') then
801 
802     	l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_PO_LINE_DETAILS') || NL || NL;
803 
804         -- <BUG 3616816 START> Only display message if # of actual lines is
805         -- greater than maximum limit.
806         --
807         IF ( l_line_count > max_lines_dsp ) THEN
808 
809             -- Bug 3668188: changed the code check (originally created
810             -- in bug 3607009) that determines which message to show
811             -- based on whether Open Document icon is shown in then notif.
812             -- The value of WF attribute 'OPEN_FORM_COMMAND' is set in a
813             -- previous node, using the get_po_user_msg_attribute procedure.
814             -- HTML Orders R12
815             -- Check for the URL parameters as well
816             IF  (l_open_form_command IS NULL) AND
817                 (l_view_po_url IS NULL)       AND
818                 (l_edit_po_url IS NULL)
819             THEN
820                 -- "The first [COUNT] Purchase Order lines are summarized below."
821                 FND_MESSAGE.set_name('PO','PO_WF_NOTIF_PO_LINE_MESG_TRUNC');
822             ELSE
823                 -- "The first [COUNT] Purchase Order lines are summarized
824                 -- below. For information on additional lines, please click
825                 -- the Open Document icon."
826                 FND_MESSAGE.set_name('PO','PO_WF_NOTIF_PO_LINE_MESG');
827             END IF;
828 
829             FND_MESSAGE.set_token('COUNT',to_char(max_lines_dsp));
830             line_mesg := FND_MESSAGE.get;
831             l_document := l_document || line_mesg || NL || NL;
832 
833         END IF;
834         --
835         -- <BUG 3616816 END>
836 
837         -- curr_len  := lengthb(l_document);
838         -- prior_len := curr_len;
839 
840         FOR i IN 1..l_num_records_to_display LOOP              -- <BUG 3616816>
841 
842                 /* Exit the cursor if the current document length and 2 times the
843                 ** length added in prior line exceeds 32000 char */
844                 -- < BUG 7006113 START Commented the loop to avoid the check so
845 		--   that maximum lines can be displayed >
846                 --   if (curr_len + (2 * (curr_len - prior_len))) >= 32000 then
847                 --     exit;
848                 --   end if;
849 		--   prior_len := curr_len;
850 		-- < BUG 7006113 END >
851 
852 		l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_LINE_NUMBER') || ':' || to_char(l_line_num_tbl(i)) || NL;
853 		l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_NUMBER') || ': ' || l_item_num_tbl(i) || NL;
854 		l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_REVISION') || ': ' || l_item_revision_tbl(i) || NL;
855 		l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_DESC') || ': ' || l_item_desc_tbl(i) || NL;
856 		l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_UOM') || ': ' || l_uom_tbl(i) || NL;
857 		l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_QUANTITY') || ': ' || to_char(l_quantity_tbl(i)) || NL;
858 
859 /* Bug 2868931: kagarwal
860 ** We will not format the unit price on the lines in notifications
861 */
862 
863 		l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_UNIT_PRICE') || ': '
864 					|| PO_WF_REQ_NOTIFICATION.FORMAT_CURRENCY_NO_PRECESION(l_currency_code,l_unit_price_tbl(i)) || NL;
865 		l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_LINE_AMOUNT') || ': '
866 					|| to_char(l_amount_tbl(i), FND_CURRENCY.GET_FORMAT_MASK(l_currency_code, 30)) || NL || NL;
867 
868 	    -- < BUG 7006113 START >
869             -- curr_len  := lengthb(l_document);
870 
871             wf_notification.writetoclob(document, l_document);
872 
873 	    l_document := NULL;
874 
875 	    EXIT WHEN i = l_num_records_to_display;
876 	    -- < BUG 7006113 END >
877 
878 	end loop;
879 
880     else   -- release
881 
882     	l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_SHIP_DETAILS') || NL || NL || NL;
883 
884         -- <BUG 3616816 START> Only display message if # of actual lines is
885         -- greater than maximum limit.
886         --
887         IF ( l_line_count > max_lines_dsp )
888         THEN
889             FND_MESSAGE.set_name('PO','PO_WF_NOTIF_PO_REL_SHIP_MESG');
890             FND_MESSAGE.set_token('COUNT',to_char(max_lines_dsp));
891             line_mesg := FND_MESSAGE.get;
892             l_document := l_document || line_mesg || NL || NL;
893         END IF;
894         --
895         -- <BUG 3616816 END>
896 
897         -- curr_len  := lengthb(l_document);
898         -- prior_len := curr_len;
899 
900         FOR i IN 1..l_num_records_to_display LOOP              -- <BUG 3616816>
901 
902                 /* Exit the cursor if the current document length and 2 times the
903                 ** length added in prior line exceeds 32000 char */
904                 -- <BUG 7006113 START Commented the loop to avoid the check so that
905 		--  maximum lines can be displayed
906                 --  if (curr_len + (2 * (curr_len - prior_len))) >= 32000 then
907                 --  exit;
908                 --  end if;
909 		--  prior_len := curr_len;
910 		-- <BUG 7006113 END>
911 
912 		l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_SHIP_NUMBER') || ': ' || to_char(l_shipment_num_tbl(i)) || NL;
913 		l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_NUMBER') || ': ' || l_item_num_tbl(i) || NL;
914 		l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_REVISION') || ': ' || l_item_revision_tbl(i) || NL;
915 		l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_DESC') || ': ' || l_item_desc_tbl(i) || NL;
916 		l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_UOM') || ': ' || l_uom_tbl(i) || NL;
917 		l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_QUANTITY') || ': ' || to_char(l_quantity_tbl(i)) || NL;
918 
919 /* Bug 2868931: kagarwal
920 ** We will not format the unit price on the lines in notifications
921 */
922 
923 		l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_UNIT_PRICE') || ': '
924 					||  PO_WF_REQ_NOTIFICATION.FORMAT_CURRENCY_NO_PRECESION(l_currency_code,l_unit_price_tbl(i)) || NL;
925                 -- bug 4950850
926 		l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_AMOUNT') || ': '
927 					|| to_char(l_amount_tbl(i), FND_CURRENCY.GET_FORMAT_MASK(l_currency_code, 30)) || NL;
928 		l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_LOCATION') || ': ' || l_location_tbl(i) || NL;
929 		l_document := l_document || fnd_message.get_string('PO', 'POA_SHIP_TO_ORG') || ': ' || l_org_name_tbl(i) || NL;
930 		l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_NEED_BY_DATE') || ': ' || to_char(l_need_by_date_tbl(i)) || NL || NL;
931 
932             -- <BUG 7006113 START>
933 	    -- curr_len  := lengthb(l_document);
934 
935 
936             wf_notification.writetoclob(document, l_document);
937 
938             l_document := NULL;
939 
940 	    EXIT WHEN i = l_num_records_to_display;
941 	    -- <BUG 7006113 END>
942 
943 	end loop;
944 
945     end if;
946 
947     wf_notification.writetoclob(document, l_document); -- <BUG 7006113>
948     -- document := l_document; -- <Bug 7006113>
949   end if;
950 
951 END get_po_lines_details;
952 
953 PROCEDURE get_action_history (	 document_id	in	varchar2,
954                                  display_type	in	varchar2,
955                                  document	in out	NOCOPY varchar2,
956                                  document_type	in out	NOCOPY varchar2) IS
957 
958     l_item_type    wf_items.item_type%TYPE;
959     l_item_key     wf_items.item_key%TYPE;
960 
961     l_document_id      po_lines.po_header_id%TYPE;
962     l_org_id           po_lines.org_id%TYPE;
963     l_doc_type_code    VARCHAR2(80);
964 
965     l_document         VARCHAR2(32000) := '';
966 
967     -- Bug 3668188: added new local var. note: the length of this
968     -- varchar was determined based on the length in POXWPA1B.pls,
969     -- which is the other place 'OPEN_FORM_COMMAND' attribute is used
970     l_open_form_command VARCHAR2(200);
971 
972     l_view_po_url varchar2(1000);   -- HTML Orders R12
973     l_edit_po_url varchar2(1000);   -- HTML Orders R12
974 
975     NL                 VARCHAR2(1) := fnd_global.newline;
976 
977     -- <BUG 3616816 START> Declare TABLEs for each column that is selected
978     -- from history_csr cursor.
979     --
980     TYPE sequence_num_tbl_type IS TABLE OF PO_ACTION_HISTORY.sequence_num%TYPE;
981     TYPE full_name_tbl_type IS TABLE OF PER_ALL_PEOPLE_F.full_name%TYPE;
982     TYPE displayed_field_tbl_type IS TABLE OF PO_LOOKUP_CODES.displayed_field%TYPE;
983     TYPE action_date_tbl_type IS TABLE OF PO_ACTION_HISTORY.action_date%TYPE;
984     TYPE note_tbl_type IS TABLE OF PO_ACTION_HISTORY.note%TYPE;
985     TYPE object_revision_num_tbl_type IS TABLE OF PO_ACTION_HISTORY.object_revision_num%TYPE;
986     TYPE employee_id_tbl_type IS TABLE OF PO_ACTION_HISTORY.employee_id%TYPE;
987     TYPE created_by_tbl_type IS TABLE OF PO_ACTION_HISTORY.created_by%TYPE;
988 
989     l_sequence_num_tbl         sequence_num_tbl_type;
990     l_employee_name_tbl        full_name_tbl_type;
991     l_action_tbl               displayed_field_tbl_type;
992     l_action_date_tbl          action_date_tbl_type;
993     l_note_tbl                 note_tbl_type;
994     l_object_revision_num_tbl  object_revision_num_tbl_type;
995     l_employee_id_tbl          employee_id_tbl_type;
996     l_created_by_tbl           created_by_tbl_type;
997     --
998     -- <BUG 3616816 END>
999 
1000   --SQL What: Query action history which is updated by both buyer and vendor
1001   --SQL Why:  Since vendor doesn't have employee id, added outer join;
1002   CURSOR history_csr(v_document_id NUMBER, v_doc_type_code VARCHAR2) IS
1003     SELECT poh.SEQUENCE_NUM,
1004            per.FULL_NAME,
1005            polc.DISPLAYED_FIELD,
1006            poh.ACTION_DATE,
1007            poh.NOTE,
1008            poh.OBJECT_REVISION_NUM,
1009            poh.employee_id, /* bug 2788683 */
1010            poh.created_by /* bug 2788683 */
1011       from po_action_history  poh,
1012            per_all_people_f   per, -- Bug 3404451
1013            po_lookup_codes    polc
1014      where OBJECT_TYPE_CODE = v_doc_type_code
1015        and poh.action_code = polc.lookup_code
1016        and POLC.LOOKUP_TYPE IN ('APPROVER ACTIONS','CONTROL ACTIONS')
1017        and per.person_id(+) = poh.employee_id /* bug 2788683 */
1018        and trunc(sysdate) between per.effective_start_date(+)
1019                               and per.effective_end_date(+)
1020        and OBJECT_ID = v_document_id
1021     UNION ALL
1022     SELECT poh.SEQUENCE_NUM,
1023            per.FULL_NAME,
1024            NULL,
1025            poh.ACTION_DATE,
1026            poh.NOTE,
1027            poh.OBJECT_REVISION_NUM,
1028            poh.employee_id, /* bug 2788683 */
1029            poh.created_by /* bug 2788683 */
1030       from po_action_history  poh,
1031            per_all_people_f   per -- Bug 3404451
1032      where OBJECT_TYPE_CODE = v_doc_type_code
1033        and poh.action_code is null
1034        and per.person_id(+) = poh.employee_id /* bug 2788683 */
1035        and trunc(sysdate) between per.effective_start_date(+)
1036                               and per.effective_end_date(+)
1037        and OBJECT_ID = v_document_id
1038    order by 1 desc;
1039 
1040   i                         NUMBER := 0;
1041   max_actions_dsp           NUMBER := 20;
1042   l_action_count            NUMBER; -- <BUG 3616816> # of action history records
1043   l_num_records_to_display  NUMBER; -- <BUG 3616816> actual # of records to display in table
1044   action_mesg              fnd_new_messages.message_text%TYPE; --Bug 4695601
1045   curr_len                  NUMBER := 0;
1046   prior_len                 NUMBER := 0;
1047 
1048   /* Bug 2788683 start */
1049   l_user_name        fnd_user.user_name%TYPE;
1050   l_vendor_name      hz_parties.party_name%TYPE;
1051   l_party_name       hz_parties.party_name%TYPE;
1052   /* Bug 2788683 end */
1053 
1054 
1055 BEGIN
1056 
1057   l_item_type := substr(document_id, 1, instr(document_id, ':') - 1);
1058   l_item_key := substr(document_id, instr(document_id, ':') + 1,
1059                        length(document_id) - 2);
1060 
1061   l_document_id := wf_engine.GetItemAttrNumber
1062                                         (itemtype   => l_item_type,
1063                                          itemkey    => l_item_key,
1064                                          aname      => 'DOCUMENT_ID');
1065 
1066   l_org_id := wf_engine.GetItemAttrNumber
1067                                         (itemtype   => l_item_type,
1068                                          itemkey    => l_item_key,
1069                                          aname      => 'ORG_ID');
1070 
1071   l_doc_type_code := wf_engine.GetItemAttrText (itemtype   => l_item_type,
1072                                            	itemkey    => l_item_key,
1073                                            	aname      => 'DOCUMENT_TYPE');
1074 
1075   PO_MOAC_UTILS_PVT.set_org_context(l_org_id) ;       -- <R12 MOAC>
1076 
1077   -- Bug 3668188
1078   l_open_form_command :=  PO_WF_UTIL_PKG.GetItemAttrText
1079                                (itemtype   => l_item_type,
1080                                 itemkey    => l_item_key,
1081                                 aname      => 'OPEN_FORM_COMMAND');
1082 
1083   -- HTML Orders R12
1084   -- Get the PO HTML Page URL's
1085   l_view_po_url := PO_WF_UTIL_PKG.GetItemAttrText (
1086                               itemtype   => l_item_type,
1087                               itemkey    => l_item_key,
1088                               aname      => 'VIEW_DOC_URL');
1089 
1090   l_edit_po_url := PO_WF_UTIL_PKG.GetItemAttrText (
1091                               itemtype   => l_item_type,
1092                               itemkey    => l_item_key,
1093                               aname      => 'EDIT_DOC_URL');
1094 
1095 /* Bug# 2577478: kagarwal
1096 ** Desc: Added a new attribute ACT_HST_IN_NTF in wf definition for
1097 ** users to specify the number of PO actions to be displayed in a
1098 ** notification.
1099 ** If the attribute does not exist or is null, then we would use default
1100 ** value of 20.
1101 */
1102 
1103   max_actions_dsp:= PO_WF_UTIL_PKG.GetItemAttrNumber (itemtype   => l_item_type,
1104                                            itemkey    => l_item_key,
1105                                            aname      => 'ACT_HST_IN_NTF');
1106 
1107   if max_actions_dsp is NULL then
1108      max_actions_dsp := 20;
1109   end if;
1110 
1111     -- <BUG 3616816 START> Fetch all Action History data into Tables.
1112     --
1113     OPEN history_csr(l_document_id,l_doc_type_code);
1114 
1115     FETCH history_csr BULK COLLECT INTO l_sequence_num_tbl
1116                                       , l_employee_name_tbl
1117                                       , l_action_tbl
1118                                       , l_action_date_tbl
1119                                       , l_note_tbl
1120                                       , l_object_revision_num_tbl
1121                                       , l_employee_id_tbl
1122                                       , l_created_by_tbl;
1123 
1124     l_action_count := history_csr%ROWCOUNT; -- Get # of records fetched.
1125 
1126     CLOSE history_csr;
1127     --
1128     -- <BUG 3616816 END>
1129 
1130     -- <BUG 3616816 START> Only display message if # of actual Action History
1131     -- records is greater than maximum limit.
1132     --
1133     IF  ( l_action_count > max_actions_dsp ) THEN
1134 
1135         l_num_records_to_display := max_actions_dsp;
1136 
1137         -- Bug 3668188: changed the code check (originally created
1138         -- in bug 3607009) that determines which message to show
1139         -- based on whether Open Document icon is shown in then notif.
1140         -- The value of WF attribute 'OPEN_FORM_COMMAND' is set in a
1141         -- previous node, using the get_po_user_msg_attribute procedure.
1142         --
1143         IF  (l_open_form_command IS NULL) AND
1144             (l_view_po_url IS NULL)       AND
1145             (l_edit_po_url IS NULL)
1146         THEN
1147             -- "The last [COUNT] Approval History details are summarized below."
1148             FND_MESSAGE.set_name('PO','PO_WF_NOTIF_PO_ACT_MESG_TRUNC');
1149         ELSE
1150             -- "The last [COUNT] Approval History details are summarized below.
1151             -- For information on additional Approval History, please click the
1152             -- Open Document icon."
1153             FND_MESSAGE.set_name('PO','PO_WF_NOTIF_PO_ACT_MESG');
1154         END IF;
1155 
1156         FND_MESSAGE.set_token('COUNT',to_char(max_actions_dsp));
1157         action_mesg := FND_MESSAGE.get;
1158 
1159     ELSE
1160 
1161         l_num_records_to_display := l_action_count;
1162         action_mesg := NULL;
1163 
1164     END IF;
1165     --
1166     -- <BUG 3616816 END>
1167 
1168   if (display_type = 'text/html') then
1169 
1170     l_document := NL || NL || '<!-- ACTION_HISTORY -->'|| NL || NL || '<P><B>';
1171     l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_ACTION_HISTORY') || NL;
1172     l_document := l_document || '</B>' || NL || NL || '<P>';   -- <BUG 3616816>
1173 
1174     -- <BUG 3616816 START> Action History message may be NULL. Only append it
1175     -- and corresponding line breaks if there is a message to display.
1176     --
1177     IF ( action_mesg IS NOT NULL )
1178     THEN
1179         l_document := l_document || action_mesg || '<P>' || NL;
1180     END IF;
1181     --
1182     -- <BUG 3616816 END>
1183 
1184     l_document := l_document || '<TABLE border=1 cellpadding=2 cellspacing=1 summary="' || fnd_message.get_string('ICX', 'ICX_POR_TBL_OF_APPROVERS') || '">' || NL;
1185 
1186     l_document := l_document || '<TR>';
1187 
1188     l_document := l_document || '<TH id="seqNum_1">' ||
1189                   fnd_message.get_string('PO', 'PO_WF_NOTIF_SEQ_NUM') || '</TH>' || NL;
1190 
1191     l_document := l_document || '<TH id="employee_1">' ||
1192                   fnd_message.get_string('PO', 'PO_WF_NOTIF_EMPLOYEE') || '</TH>' || NL;
1193 
1194     l_document := l_document || '<TH id="action_1">' ||
1195                   fnd_message.get_string('PO', 'PO_WF_NOTIF_ACTION') || '</TH>' || NL;
1196 
1197     l_document := l_document || '<TH id="date_1">' ||
1198                   fnd_message.get_string('PO', 'PO_WF_NOTIF_DATE') || '</TH>' || NL;
1199 
1200     l_document := l_document || '<TH id="actionNote_1">' ||
1201                   fnd_message.get_string('PO', 'PO_WF_NOTIF_ACTION_NOTE') || '</TH>' || NL;
1202 
1203     l_document := l_document || '</TR>' || NL;
1204 
1205     curr_len  := lengthb(l_document);
1206     prior_len := curr_len;
1207 
1208     FOR i IN 1..l_num_records_to_display LOOP                  -- <BUG 3616816>
1209 
1210       /* Exit the cursor if the current document length and 2 times the
1211       ** length added in prior line exceeds 32000 char */
1212 
1213       if (curr_len + (2 * (curr_len - prior_len))) >= 32000 then
1214          exit;
1215       end if;
1216 
1217       prior_len := curr_len;
1218 
1219       l_document := l_document || '<TR>' || NL;
1220 
1221       l_document := l_document || '<TD nowrap align=center headers="seqNum_1">'
1222 					 || nvl(to_char(l_sequence_num_tbl(i)), ' ') || '</TD>' || NL;
1223 
1224       /* Bug 2788683 start */
1225       /* if action history is updated by vendor
1226        *    show vendor true name(vendor name)
1227        * else action history is updated by buyer
1228        *    show buyer's true name
1229        */
1230       IF l_employee_id_tbl(i) IS NULL THEN
1231          SELECT fu.user_name,
1232                 hp.party_name
1233            INTO l_user_name,
1234                 l_party_name
1235            FROM fnd_user fu,
1236                 hz_parties hp
1237           WHERE hp.party_id = fu.customer_id
1238             AND fu.user_id = l_created_by_tbl(i);
1239 
1240       po_inq_sv.get_vendor_name(l_user_name => l_user_name, x_vendor_name => l_vendor_name);
1241 
1242       l_document := l_document || '<TD nowrap headers="employee_1">' || l_party_name || '(' || l_vendor_name || ')' || '</TD>' || NL;
1243       ELSE
1244       l_document := l_document || '<TD nowrap headers="employee_1">'
1245 					 || nvl(l_employee_name_tbl(i), ' ') || '</TD>' || NL;
1246       END IF;
1247       /* Bug 2788683 end */
1248 
1249       l_document := l_document || '<TD nowrap headers="action_1">'
1250 					 || nvl(l_action_tbl(i), ' ') || '</TD>' || NL;
1251       l_document := l_document || '<TD nowrap headers="date_1">'
1252 					 || nvl(to_char(l_action_date_tbl(i)), ' ') || '</TD>' || NL;
1253       l_document := l_document || '<TD nowrap headers="actionNote_1">'
1254 					 || nvl(l_note_tbl(i), ' ') || '</TD>' || NL;
1255 
1256       l_document := l_document || '</TR>' || NL;
1257 
1258       curr_len  := lengthb(l_document);
1259 
1260     end loop;
1261 
1262     l_document := l_document || '</TABLE></P>' || NL;
1263 
1264     document := l_document;
1265 
1266   elsif (display_type = 'text/plain') then
1267 
1268     l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_ACTION_HISTORY') || NL;
1269 
1270     -- <BUG 3616816 START> Action History message may be NULL. Only append it
1271     -- and corresponding line breaks if there is a message to display.
1272     --
1273     IF ( action_mesg IS NOT NULL )
1274     THEN
1275         l_document := l_document || action_mesg || NL || NL;
1276     END IF;
1277     --
1278     -- <BUG 3616816 END>
1279 
1280     curr_len  := lengthb(l_document);
1281     prior_len := curr_len;
1282 
1283     FOR i IN 1..l_num_records_to_display LOOP                  -- <BUG 3616816>
1284 
1285       /* Exit the cursor if the current document length and 2 times the
1286       ** length added in prior line exceeds 32000 char */
1287 
1288       if (curr_len + (2 * (curr_len - prior_len))) >= 32000 then
1289          exit;
1290       end if;
1291 
1292       prior_len := curr_len;
1293 
1294       l_document := l_document || NL;
1295 
1296 /* Bug 2462005 sktiwari:
1297 ** Added a ':' between the prompt and the data. Modified the following lines.
1298 */
1299       l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_SEQ_NUM') || ': ' || to_char(l_sequence_num_tbl(i)) || NL;
1300 
1301       /* Bug 2788683 start */
1302       /* if action history is updated by vendor
1303        *    show vendor true name(vendor name)
1304        * else action history is updated by buyer
1305        *    show buyer's true name
1306        */
1307       IF l_employee_id_tbl(i) IS NULL THEN
1308          SELECT fu.user_name, hp.party_name
1309            INTO l_user_name, l_party_name
1310            FROM fnd_user fu,
1311                 hz_parties hp
1312           WHERE hp.party_id = fu.customer_id
1313             AND fu.user_id = l_created_by_tbl(i);
1314 
1315       po_inq_sv.get_vendor_name(l_user_name => l_user_name, x_vendor_name => l_vendor_name);
1316 
1317       l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_EMPLOYEE') || ': ' || l_party_name || '(' || l_vendor_name || ')' || NL;
1318       ELSE
1319       l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_EMPLOYEE') || ': ' || l_employee_name_tbl(i) || NL;
1320       END IF;
1321       /* Bug 2788683 end */
1322 
1323       l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_ACTION') || ': ' || l_action_tbl(i) || NL;
1324       l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_DATE') || ': ' || to_char(l_action_date_tbl(i)) || NL;
1325       l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_ACTION_NOTE') || ': ' || l_note_tbl(i) || NL;
1326 
1327       l_document := l_document || NL;
1328 
1329       curr_len  := lengthb(l_document);
1330     end loop;
1331 
1332     l_document := l_document;
1333 
1334     document := l_document;
1335 
1336   end if;
1337 
1338 END;
1339 
1340 PROCEDURE post_approval_notif(itemtype   in varchar2,
1341                               itemkey    in varchar2,
1342                               actid      in number,
1343                               funcmode   in varchar2,
1344                               resultout  in out NOCOPY varchar2) is
1345 
1346 -- Context setting revamp <variable addition start>
1347 l_responder_id       fnd_user.user_id%TYPE;
1348 l_session_user_id    NUMBER;
1349 l_session_resp_id    NUMBER;
1350 l_session_appl_id    NUMBER;
1351 l_preparer_resp_id   NUMBER;
1352 l_preparer_appl_id   NUMBER;
1353 l_progress           VARCHAR2(1000);
1354 l_nid                NUMBER;
1355 l_preserved_ctx      VARCHAR2(5);
1356 -- Context setting revamp <variable addition end>
1357 
1358 begin
1359 
1360  -- Context setting revamp <start>
1361 if (funcmode = 'RESPOND') then
1362   l_nid := WF_ENGINE.context_nid;
1363 
1364     SELECT fu.USER_ID
1365       INTO l_responder_id
1366       FROM fnd_user fu,
1367            wf_notifications wfn
1368      WHERE wfn.notification_id = l_nid
1369        AND wfn.original_recipient = fu.user_name;
1370 
1371 -- <debug start>
1372    if (wf_engine.preserved_context = TRUE) then
1373       l_preserved_ctx := 'TRUE';
1374    else
1375       l_preserved_ctx := 'FALSE';
1376    end if;
1377    l_progress := 'notif callback preserved_ctx : '||l_preserved_ctx;
1378    IF (g_po_wf_debug = 'Y') THEN
1379           /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
1380    END IF;
1381 -- <debug end>
1382 
1383 -- <debug start>
1384        l_progress := '010 notif callback -responder id : '||l_responder_id;
1385        IF (g_po_wf_debug = 'Y') THEN
1386           /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
1387        END IF;
1388 --<debug end>
1389     --Bug 5389914
1390     --Fnd_Profile.Get('USER_ID',l_session_user_id);
1391     --Fnd_Profile.Get('RESP_ID',l_session_resp_id);
1392     --Fnd_Profile.Get('RESP_APPL_ID',l_session_appl_id);
1393     l_session_user_id := fnd_global.user_id;
1394     l_session_resp_id := fnd_global.resp_id;
1395     l_session_appl_id := fnd_global.resp_appl_id;
1396 
1397 	  IF (l_session_user_id = -1) THEN
1398 	      l_session_user_id := NULL;
1399 	  END IF;
1400 
1401 	  IF (l_session_resp_id = -1) THEN
1402 	      l_session_resp_id := NULL;
1403 	  END IF;
1404 
1405 	  IF (l_session_appl_id = -1) THEN
1406 	      l_session_appl_id := NULL;
1407 	  END IF;
1408 
1409 -- <debug start>
1410        l_progress :='020 notification callback ses_userid: '||l_session_user_id
1411                     ||' sess_resp_id '||l_session_resp_id||' sess_appl_id '
1412 		    ||l_session_appl_id;
1413        IF (g_po_wf_debug = 'Y') THEN
1414           /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
1415        END IF;
1416 --<debug end>
1417 
1418 -- bug 4901406 <start> : need to shift the setting of the preparer resp and appl id
1419 -- to here, it was not initialized inside the if condition if the control went to the
1420 -- else part.
1421           l_preparer_resp_id :=
1422 	  PO_WF_UTIL_PKG.GetItemAttrNumber (itemtype=>itemtype,
1423 	  			      itemkey => itemkey,
1424 				      aname   => 'RESPONSIBILITY_ID');
1425           l_preparer_appl_id :=
1426           PO_WF_UTIL_PKG.GetItemAttrNumber (itemtype=>itemtype,
1427 	  			      itemkey => itemkey,
1428 				      aname   => 'APPLICATION_ID');
1429 
1430 -- <debug start>
1431           l_progress := '030 notif callback prep resp_id:'||l_preparer_resp_id
1432 	  		||' prep appl id '||l_preparer_appl_id;
1433           IF (g_po_wf_debug = 'Y') THEN
1434              /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
1435           END IF;
1436 --<debug end>
1437 
1438 -- bug 4901406 <end>
1439 
1440 
1441     if (l_responder_id is not null) then
1442        if (l_responder_id <> l_session_user_id) then
1443        /* possible in 2 scenarios :
1444           1. when the response is made from email using guest user feature
1445 	  2. When the response is made from sysadmin login
1446        */
1447 
1448 
1449 
1450           PO_WF_UTIL_PKG.SetItemAttrNumber(itemtype=>itemtype,
1451 	  			      itemkey => itemkey,
1452 				      aname   => 'RESPONDER_USER_ID',
1453 	  			      avalue  => l_responder_id);
1454           PO_WF_UTIL_PKG.SetItemAttrNumber(itemtype=>itemtype,
1455 	  			      itemkey => itemkey,
1456 				      aname   => 'RESPONDER_RESP_ID',
1457 	  			      avalue  => l_preparer_resp_id);
1458           PO_WF_UTIL_PKG.SetItemAttrNumber(itemtype=>itemtype,
1459 	  			      itemkey => itemkey,
1460 				      aname   => 'RESPONDER_APPL_ID',
1461 	  			      avalue  => l_preparer_appl_id);
1462        else
1463           if (l_session_resp_id is null) THEN
1464 	  /* possible when the response is made from the default worklist
1465 	     without choosing a valid responsibility */
1466 	      PO_WF_UTIL_PKG.SetItemAttrNumber(itemtype=>itemtype,
1467 	  			      itemkey => itemkey,
1468 				      aname   => 'RESPONDER_USER_ID',
1469 	  			      avalue  => l_responder_id);
1470               PO_WF_UTIL_PKG.SetItemAttrNumber(itemtype=>itemtype,
1471 	  			      itemkey => itemkey,
1472 				      aname   => 'RESPONDER_RESP_ID',
1473 	  			      avalue  => l_preparer_resp_id);
1474               PO_WF_UTIL_PKG.SetItemAttrNumber(itemtype=>itemtype,
1475 	  			      itemkey => itemkey,
1476 				      aname   => 'RESPONDER_APPL_ID',
1477 	  			      avalue  => l_preparer_appl_id);
1478            else
1479 	   /* all values available - possible when the response is made
1480 	      after choosing a correct responsibility */
1481 
1482 	   /* bug 5333226 : If the values of responsibility_id and application
1483 	      id are available but are incorrect - i.e. not conforming to say the
1484 	      sls (subledger security). This may happen when a response is made
1485 	      through the email or the background process picks the wf up.
1486 	      This may happen due to the fact that the mailer / background process
1487 	      carries the context set by the notification/wf it processed last*/
1488 
1489 		 	 if ( l_preserved_ctx = 'TRUE') then
1490 	             PO_WF_UTIL_PKG.SetItemAttrNumber(itemtype=>itemtype,
1491 	  			      itemkey => itemkey,
1492 				      aname   => 'RESPONDER_USER_ID',
1493 	  			      avalue  => l_responder_id);
1494                      PO_WF_UTIL_PKG.SetItemAttrNumber(itemtype=>itemtype,
1495 	  			      itemkey => itemkey,
1496 				      aname   => 'RESPONDER_RESP_ID',
1497 	  			      avalue  => l_session_resp_id);
1498                      PO_WF_UTIL_PKG.SetItemAttrNumber(itemtype=>itemtype,
1499 	  			      itemkey => itemkey,
1500 				      aname   => 'RESPONDER_APPL_ID',
1501 	  			      avalue  => l_session_appl_id);
1502 	          else
1503 	             PO_WF_UTIL_PKG.SetItemAttrNumber(itemtype=>itemtype,
1504 	  			      itemkey => itemkey,
1505 				      aname   => 'RESPONDER_USER_ID',
1506 	  			      avalue  => l_responder_id);
1507                      PO_WF_UTIL_PKG.SetItemAttrNumber(itemtype=>itemtype,
1508 	  			      itemkey => itemkey,
1509 				      aname   => 'RESPONDER_RESP_ID',
1510 	  			      avalue  => l_preparer_resp_id);
1511                      PO_WF_UTIL_PKG.SetItemAttrNumber(itemtype=>itemtype,
1512 	  			      itemkey => itemkey,
1513 				      aname   => 'RESPONDER_APPL_ID',
1514 	  			      avalue  => l_preparer_appl_id);
1515 	          end if;
1516 
1517 
1518 	   end if;
1519        end if;
1520     end if;
1521 
1522     -- Context setting revamp <end>
1523 
1524 
1525      resultout := wf_engine.eng_completed || ':' || wf_engine.eng_null;
1526       l_progress := '040 returning from notif callback -respond mode';
1527           IF (g_po_wf_debug = 'Y') THEN
1528              /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
1529           END IF;
1530      return;
1531   end if;
1532 
1533 
1534   -- Don't allow transfer
1535   if (funcmode = 'TRANSFER') then
1536 
1537     fnd_message.set_name('PO', 'PO_WF_NOTIF_NO_TRANSFER');
1538     app_exception.raise_exception;
1539 
1540   resultout := wf_engine.eng_completed;
1541   return;
1542 
1543   end if; -- end if for funcmode = 'TRANSFER'
1544 
1545 end post_approval_notif;
1546 
1547 
1548 /* Bug# 2616433: kagarwal
1549 ** Desc: Added new procedure to set notification subject token in
1550 ** user language.
1551 */
1552 
1553 procedure Get_po_user_msg_attribute(itemtype in varchar2,
1554                                 itemkey         in varchar2,
1555                                 actid           in number,
1556                                 funcmode        in varchar2,
1557                                 resultout       out NOCOPY varchar2) IS
1558 
1559 l_progress  VARCHAR2(100) := '000';
1560 l_doc_string varchar2(200);
1561 l_user_name varchar2(100);
1562 l_preparer_user_name varchar2(100);
1563 l_orgid number;
1564 l_notification_type varchar2(15);  --bug 3668188
1565 
1566 -- <Start Word Integration 11.5.10+>
1567 l_okc_doc_type          varchar2(20);
1568 l_conterms_exist_flag   PO_HEADERS_ALL.conterms_exist_flag%TYPE;
1569 l_document_id           NUMBER;
1570 l_document_subtype      PO_HEADERS_ALL.type_lookup_code%TYPE;
1571 -- <End Word Integration 11.5.10+>
1572 
1573 BEGIN
1574 
1575   -- Do nothing in cancel or timeout mode
1576   --
1577   if (funcmode <> wf_engine.eng_run) then
1578       resultout := wf_engine.eng_null;
1579       return;
1580   end if;
1581 
1582   l_progress := 'Get_po_user_msg_attribute:001: actid: ' || actid;
1583   /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
1584 
1585   l_orgid := wf_engine.GetItemAttrNumber (itemtype => itemtype,
1586                                          itemkey  => itemkey,
1587                                          aname    => 'ORG_ID');
1588 
1589   IF l_orgid is NOT NULL THEN
1590     PO_MOAC_UTILS_PVT.set_org_context(l_orgid) ;       -- <R12 MOAC>
1591   END IF;
1592 
1593   l_progress := 'Get_po_user_msg_attribute:010: orgid: ' || l_orgid;
1594   /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
1595 
1596   l_user_name := wf_engine.GetActivityAttrText (itemtype => itemtype,
1597                                                 itemkey  => itemkey,
1598                                                 actid    => actid,
1599                                                 aname    => 'NTF_USER_NAME',
1600                                                 ignore_notfound => TRUE);
1601 
1602   PO_WF_PO_NOTIFICATION.GetDisplayValue(itemtype, itemkey, l_user_name);
1603 
1604 
1605   l_progress := 'Get_po_user_msg_attribute:015: username: ' || l_user_name;
1606   /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
1607 
1608 
1609   -- Bug 3668188: added the NTF_USER_ROLE Activity Attribute, which is
1610   -- a constant with value 'SUBMITTER' or 'APPROVER'.  This distinguishes
1611   -- between the 3 different notification-functions that share this procedure.
1612   l_notification_type := wf_engine.GetActivityAttrText (
1613                                       itemtype => itemtype,
1614                                       itemkey  => itemkey,
1615                                       actid    => actid,
1616                                       aname    => 'NTF_USER_ROLE',
1617                                       ignore_notfound => TRUE);
1618 
1619   l_progress := 'Get_po_user_msg_attribute:020: notif type: ' || l_notification_type;
1620   -- DEBUG
1621      PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
1622 
1623 
1624   -- Bug 3668188: Removed old logic from bug 3564727 and replaced it
1625   -- with a call to is_open_document_allowed, which has updated logic.
1626   IF NOT (PO_WF_PO_NOTIFICATION.is_open_document_allowed(
1627                                   p_itemtype => itemtype
1628                                ,  p_itemkey => itemkey
1629                                ,  p_notification_type => l_notification_type)
1630   ) THEN
1631      l_progress := 'Get_po_approver_msg_attribute: 040: NULL open form';
1632      /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
1633 
1634      -- HTML Orders R12
1635      -- Set the URL and form attributes
1636      PO_WF_UTIL_PKG.SetItemAttrText ( itemtype   => itemType,
1637                               itemkey    => itemkey,
1638                               aname      => 'OPEN_FORM_COMMAND' ,
1639                               avalue     => '');
1640 
1641      PO_WF_UTIL_PKG.SetItemAttrText ( itemtype   => itemType,
1642                               itemkey    => itemkey,
1643                               aname      => 'VIEW_DOC_URL' ,
1644                               avalue     => '');
1645 
1646      PO_WF_UTIL_PKG.SetItemAttrText ( itemtype   => itemType,
1647                               itemkey    => itemkey,
1648                               aname      => 'EDIT_DOC_URL' ,
1649                               avalue     => '');
1650   END IF;
1651 
1652 
1653   -- <Start Word Integration 11.5.10+>
1654 
1655   l_conterms_exist_flag := PO_WF_UTIL_PKG.GetItemAttrText(
1656                                    itemtype => itemtype,
1657                                    itemkey => itemkey,
1658                                    aname => 'CONTERMS_EXIST_FLAG');
1659 
1660   l_document_subtype := PO_WF_UTIL_PKG.GetItemAttrText(
1661                                    itemtype => itemtype,
1662                                    itemkey => itemkey,
1663                                    aname => 'DOCUMENT_SUBTYPE');
1664 
1665   l_document_id := PO_WF_UTIL_PKG.GetItemAttrNumber(
1666                                    itemtype => itemtype,
1667                                    itemkey => itemkey,
1668                                    aname => 'DOCUMENT_ID');
1669 
1670 
1671   /* Set or reset the okc doc attachment attribute */
1672 
1673   IF (l_conterms_exist_flag = 'Y')
1674   THEN
1675     l_okc_doc_type :=
1676                 PO_CONTERMS_UTL_GRP.get_po_contract_doctype(l_document_subtype);
1677 
1678     IF (('STRUCTURED' <>
1679      OKC_TERMS_UTIL_GRP.get_contract_source_code(p_document_type => l_okc_doc_type
1680                                                , p_document_id => l_document_id))
1681           AND
1682       ('N' =
1683       OKC_TERMS_UTIL_GRP.is_primary_terms_doc_mergeable(
1684                                                P_document_type => l_okc_doc_type
1685                                              , p_document_id => l_document_id))
1686          AND
1687       (PO_COMMUNICATION_PVT.PO_COMMUNICATION_PROFILE = 'T')
1688     )
1689     THEN
1690 
1691       PO_WF_UTIL_PKG.SetItemAttrText (itemtype => itemtype,
1692                                       itemkey => itemkey,
1693                                       aname => 'OKC_DOC_ATTACHMENT',
1694                                       avalue =>
1695                                 'PLSQLBLOB:PO_COMMUNICATION_PVT.OKC_DOC_ATTACH/'||
1696                                     itemtype||':'||itemkey);
1697 
1698     ELSE
1699 
1700       /* Contract terms are structured, or attached document is mergeable.
1701        * All contract terms will be in pdf; no need for other okc doc attachment.
1702        */
1703 
1704       PO_WF_UTIL_PKG.SetItemAttrText (itemtype => itemtype,
1705                                       itemkey => itemkey,
1706                                       aname => 'OKC_DOC_ATTACHMENT',
1707                                       avalue => '');
1708 
1709     END IF /* not structured and not mergeable */;
1710 
1711   END IF; /* l_conterms_exist_flag = 'Y' */
1712 
1713 
1714   -- <End Word Integration 11.5.10+>
1715 
1716 
1717 
1718   l_progress := 'Get_po_approver_msg_attribute: 999';
1719   /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
1720 
1721   resultout := wf_engine.eng_completed || ':' ||  'ACTIVITY_PERFORMED';
1722 
1723 EXCEPTION
1724  WHEN OTHERS THEN
1725     l_doc_string := PO_REQAPPROVAL_INIT1.get_error_doc(itemType, itemkey);
1726     l_preparer_user_name := PO_REQAPPROVAL_INIT1.get_preparer_user_name(itemType, itemkey);
1727     wf_core.context('PO_WF_PO_NOTIFICATION','Get_req_approval_msg_attribute',l_progress);
1728     PO_REQAPPROVAL_INIT1.send_error_notif(itemType, itemkey, l_preparer_user_name,
1729     l_doc_string, sqlerrm, 'PO_WF_PO_NOTIFICATION.Get_po_approver_msg_attribute');
1730     raise;
1731 
1732 END Get_po_user_msg_attribute;
1733 
1734 
1735 /* Bug# 2616433: kagarwal
1736 ** Desc: Added new procedure to set doc type display according to the
1737 ** default language of approver or preparer.
1738 */
1739 
1740 procedure GetDisplayValue(itemtype in varchar2,
1741                           itemkey  in varchar2,
1742                           username in varchar2,
1743                           doctype  in varchar2,
1744                           docsubtype in varchar2) IS
1745 
1746 l_progress  VARCHAR2(400) := '000';
1747 l_doc_type varchar2(25);
1748 l_doc_subtype varchar2(25);
1749 l_doc_disp varchar2(240);
1750 l_ga_flag   varchar2(1) := null;
1751 
1752 l_display_name varchar2(240);
1753 l_email_address varchar2(240);
1754 l_notification_preference  varchar2(240);
1755 l_language  varchar2(240);
1756 l_territory varchar2(240);
1757 l_msg_text   varchar2(2000) := NULL; -- Bug 3430545
1758 
1759 cursor c_lookup_value_user(p_doc_type varchar2, p_doc_subtype varchar2,
1760                       p_language varchar2) is
1761   select type_name
1762   from po_document_types_tl tl, FND_LANGUAGES fl
1763   where fl.nls_language = p_language
1764   and   tl.LANGUAGE = fl.language_code
1765   and   tl.document_type_code = p_doc_type
1766   and   tl.document_subtype = p_doc_subtype;
1767 
1768 cursor c_lookup_value_doc(p_doc_type varchar2, p_doc_subtype varchar2) is
1769   select type_name
1770   from po_document_types
1771   where document_type_code = p_doc_type
1772   and   document_subtype = p_doc_subtype;
1773 
1774   l_document_id      PO_HEADERS_ALL.po_header_id%TYPE; --<R12 STYLES PHASE II>
1775 
1776 BEGIN
1777   l_progress := 'PO_WF_PO_NOTIFICATION.GetDisplayValue: 001, user name: '
1778                 || username;
1779   /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
1780 
1781   if ((doctype is NULL) or (docsubtype is null)) then
1782     l_doc_type := PO_WF_UTIL_PKG.GetItemAttrText (itemtype => itemtype,
1783                                          itemkey  => itemkey,
1784                                          aname    => 'DOCUMENT_TYPE');
1785 
1786     l_doc_subtype := PO_WF_UTIL_PKG.GetItemAttrText (itemtype => itemtype,
1787                                          itemkey  => itemkey,
1788                                          aname    => 'DOCUMENT_SUBTYPE');
1789   else
1790    l_doc_type := doctype;
1791    l_doc_subtype := docsubtype;
1792   end if;
1793 
1794   IF l_doc_type = 'PA' AND l_doc_subtype = 'BLANKET' THEN
1795 
1796        l_ga_flag := PO_WF_UTIL_PKG.GetItemAttrText  ( itemtype    => itemtype,
1797                                          itemkey     => itemkey,
1798                                          aname       => 'GLOBAL_AGREEMENT_FLAG');
1799   END IF;
1800 
1801   /* Bug 3430545: Modified the code to get the translated values for the wf
1802    notification attribute 'REQUIRES_APPROVAL_MSG' and 'PO_GA_TYPE'.
1803    Deleted the previous code and revamped it.
1804   */
1805    --<R12 STYLES PHASE II START>
1806    l_document_id := PO_WF_UTIL_PKG.GetItemAttrNumber
1807                                        (itemtype   => itemtype,
1808                                         itemkey    => itemkey,
1809                                         aname      => 'DOCUMENT_ID');
1810 
1811   IF  username is NULL THEN
1812 	  l_progress := 'PO_WF_PO_NOTIFICATION.GetDisplayValue: 050';
1813         /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
1814 
1815       IF l_doc_type = 'PA' AND l_doc_subtype IN ('BLANKET','CONTRACT') OR
1816          l_doc_type = 'PO' AND l_doc_subtype = 'STANDARD'  then
1817 
1818          l_doc_disp := PO_DOC_STYLE_PVT.GET_STYLE_DISPLAY_NAME(l_document_id);
1819       ELSE
1820          OPEN c_lookup_value_doc(l_doc_type, l_doc_subtype);
1821          FETCH c_lookup_value_doc into l_doc_disp;
1822          CLOSE c_lookup_value_doc;
1823       END IF;
1824   ELSE
1825 	  l_progress := 'PO_WF_PO_NOTIFICATION.GetDisplayValue: 060';
1826         /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
1827       WF_DIRECTORY.GETROLEINFO(
1828            username,
1829            l_display_name,
1830            l_email_address,
1831            l_notification_preference,
1832            l_language,
1833            l_territory);
1834       l_progress := 'PO_WF_PO_NOTIFICATION.GetDisplayValue: 080, language: '
1835                     || l_language;
1836         /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
1837 
1838       IF l_doc_type = 'PA' AND l_doc_subtype IN ('BLANKET','CONTRACT') OR
1839          l_doc_type = 'PO' AND l_doc_subtype = 'STANDARD'  then
1840 
1841          l_doc_disp := PO_DOC_STYLE_PVT.GET_STYLE_DISPLAY_NAME(l_document_id,l_language);
1842      ELSE
1843           OPEN c_lookup_value_user(l_doc_type, l_doc_subtype, l_language);
1844           FETCH c_lookup_value_user into l_doc_disp;
1845           CLOSE c_lookup_value_user;
1846      END IF;
1847   END IF;  /* if username is null  */
1848    --<R12 STYLES PHASE II END>
1849 	 l_progress := 'PO_WF_PO_NOTIFICATION.GetDisplayValue: 100, type disp: '
1850                 || l_doc_disp;
1851         /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
1852 
1853      PO_WF_UTIL_PKG.SetItemAttrText ( itemtype    => itemtype,
1854                                  itemkey     => itemkey,
1855                                  aname       => 'DOCUMENT_TYPE_DISP',
1856                                  avalue      =>  l_doc_disp);
1857      BEGIN
1858        select message_text
1859        into l_msg_text
1860        from fnd_new_messages fm,fnd_languages fl
1861        where fm.message_name = 'PO_WF_NOTIF_REQUIRES_APPROVAL'
1862        and fm.language_code = fl.language_code
1863        and fl.nls_language = l_language
1864        and fm.application_id = 201;  --<BUG 3712124> Include application_id to better use PK index
1865        EXCEPTION
1866            WHEN OTHERS THEN
1867             l_msg_text := PO_WF_UTIL_PKG.GetItemAttrText(itemtype    => itemtype,
1868                                                     itemkey     => itemkey,
1869                                                     aname       => 'REQUIRES_APPROVAL_MSG');
1870        END;
1871 
1872     PO_WF_UTIL_PKG.SetItemAttrText ( itemtype    => itemtype,
1873                                    itemkey     => itemkey,
1874                                    aname       => 'REQUIRES_APPROVAL_MSG',
1875                                    avalue      => l_msg_text );
1876 
1877 EXCEPTION
1878   WHEN OTHERS THEN
1879     l_progress := 'PO_WF_PO_NOTIFICATION.GetDisplayValue: sql err: ' || sqlerrm;
1880     /* DEBUG */  PO_WF_DEBUG_PKG.insert_debug(itemtype,itemkey,l_progress);
1881     IF (c_lookup_value_user%ISOPEN) THEN
1882       CLOSE c_lookup_value_user;
1883     END IF;
1884     IF (c_lookup_value_doc%ISOPEN) THEN
1885       CLOSE c_lookup_value_doc;
1886     END IF;
1887 
1888 END GetDisplayValue;
1889 
1890 ------------------------------------------------------------------<BUG 3607009>
1891 -------------------------------------------------------------------------------
1892 --Start of Comments
1893 --Name: is_open_document_allowed
1894 --Pre-reqs:
1895 --  None.
1896 --Modifies:
1897 --  None
1898 --Locks:
1899 --  None.
1900 --Function:
1901 --  Determines if the Open Document icon should be shown in the
1902 --  PO Approval Notification. The Open Document should not be shown if...
1903 --  (1) the document is in 'Pre-Approved' state and
1904 --  (2) document signature is required.
1905 --Parameters:
1906 --IN:
1907 --p_itemtype
1908 --  Standard parameter to be used in a workflow procedure
1909 --p_itemkey
1910 --  Standard parameter to be used in a workflow procedure
1911 --p_notification_type
1912 --  Specifies whether this notification is for the Preparer/Submitter
1913 --  or an Approver/Reviewer
1914 --  The value is derived from the WF Function attribute NTF_USER_ROLE
1915 --  in the GET_<>_NOTIFICATION_ATTRIBUTE functions in POAPPRV workflow
1916 --  Added for bug 3668188
1917 --Returns:
1918 --resultout
1919 --  A BOOLEAN TRUE if the Open Document icon should be shown, FALSE otherwise.
1920 --Testing:
1921 --  N/A
1922 --End of Comments
1923 -------------------------------------------------------------------------------
1924 -------------------------------------------------------------------------------
1925 FUNCTION is_open_document_allowed
1926 (
1927     p_itemtype            IN   VARCHAR2
1928 ,   p_itemkey             IN   VARCHAR2
1929 ,   p_notification_type   IN   VARCHAR2   --bug 3668188
1930 )
1931 RETURN BOOLEAN
1932 IS
1933     l_api_name               VARCHAR2(30) := 'is_open_document_allowed';
1934     l_log_head               VARCHAR2(100) := g_pkg_name||'.'||l_api_name;
1935     l_progress               VARCHAR2(3);
1936 
1937     l_authorization_status   PO_HEADERS_ALL.authorization_status%TYPE;
1938     l_result                 BOOLEAN := TRUE;
1939 
1940 BEGIN
1941 
1942 l_progress:='000'; PO_WF_DEBUG_PKG.insert_debug(p_itemtype,p_itemkey,l_log_head||':'||l_progress || 'Notification Type = ' || p_notification_type);
1943 
1944     -- Get the Authorization Status (e.g. 'PRE-APPROVED','APPROVED',
1945     -- 'INCOMPLETE', etc.) of the document.
1946     --
1947     l_authorization_status := wf_engine.GetItemAttrText
1948                               (   itemtype => p_itemtype
1949                               ,   itemkey  => p_itemkey
1950                               ,   aname    => 'AUTHORIZATION_STATUS'
1951                               );
1952 
1953 l_progress:='010'; PO_WF_DEBUG_PKG.insert_debug(p_itemtype,p_itemkey,l_log_head||':'||l_progress||' Authorization Status = '||l_authorization_status);
1954 
1955 
1956     -- bug 3668188: changed the Open Doc allowed logic.
1957     -- If document is ('Pre-Approved' or 'In Process') and the
1958     -- notification is going back to the Submitter, then that
1959     -- user should not be able to open the document for edit.
1960     --
1961     IF (l_authorization_status IN ('PRE-APPROVED', 'IN PROCESS')
1962         AND nvl(p_notification_type, 'SUBMITTER') = 'SUBMITTER')
1963     THEN
1964         l_progress:='020';
1965         PO_WF_DEBUG_PKG.insert_debug(p_itemtype,p_itemkey,l_log_head||':'||l_progress||':FALSE');
1966         l_result := FALSE;
1967     END IF;
1968 
1969     l_progress:='030';
1970     PO_WF_DEBUG_PKG.insert_debug(p_itemtype,p_itemkey,l_log_head||':'||l_progress||':TRUE');
1971     return (l_result);
1972 
1973 EXCEPTION
1974 
1975     WHEN OTHERS THEN
1976         PO_WF_DEBUG_PKG.insert_debug(p_itemtype,p_itemkey,l_log_head||':'||SQLERRM);
1977         RAISE;
1978 
1979 END is_open_document_allowed;
1980 
1981 
1982 
1983 END PO_WF_PO_NOTIFICATION;