想在notification頁面把供應商的稅捐代碼帶出來,添在如下紅框中
PO_WF_PO_NOTIFICATION
head information:get_po_approve_msg
line information:get_po_lines_details
函數稍微修改一下,就OK
CREATE OR REPLACE PACKAGE BODY PO_WF_PO_NOTIFICATION AS /* $Header: POXWPA7B.pls 115.38.11510.5 2005/03/22 10:15:55 nipagarw ship $ */ g_pkg_name VARCHAR2(30) := 'PO_WF_PO_NOTIFICATION'; -- <BUG 3607009> PROCEDURE get_po_approve_msg(document_id in varchar2, display_type in varchar2, document in out NOCOPY varchar2, document_type in out NOCOPY varchar2) IS l_item_type wf_items.item_type%TYPE; l_item_key wf_items.item_key%TYPE; l_document_id po_headers.po_header_id%TYPE; l_org_id po_headers.org_id%TYPE; l_currency_code fnd_currencies.CURRENCY_CODE%TYPE; l_header_msg VARCHAR2(500); l_po_amount VARCHAR2(30); l_tax_amount VARCHAR2(30); l_description po_headers.comments%TYPE; l_forwarded_from per_all_people_f.full_name%TYPE; l_preparer per_all_people_f.full_name%TYPE; --<UTF-8 FPI START> -- l_note VARCHAR2(480); /* < UTF8 FPI - changed from VARCHAR2(240) > */ l_note po_action_history.note%TYPE; --<UTF-8 FPI END> l_document VARCHAR2(32000) := ''; l_tax_amt NUMBER; /* Start Bug# 3972475 */ X_precision number; X_ext_precision number; X_min_acct_unit number; /* End Bug# 3972475*/ l_supplier po_vendors.vendor_name%type; --Bug 4115777 /**--customize the po_approve_message,added by leone 2009.8.7--**/ --l_supplier_site_id po_vendor_sites_all.vendor_site_id%type; l_tax_code varchar2(10); /*****************************end*****************************/ l_supplier_site po_vendor_sites_all.vendor_site_code%type; --Bug 4115777 NL VARCHAR2(1) := fnd_global.newline; BEGIN l_item_type := substr(document_id, 1, instr(document_id, ':') - 1); l_item_key := substr(document_id, instr(document_id, ':') + 1, length(document_id) - 2); l_document_id := wf_engine.GetItemAttrNumber(itemtype => l_item_type, itemkey => l_item_key, aname => 'DOCUMENT_ID'); l_org_id := wf_engine.GetItemAttrNumber(itemtype => l_item_type, itemkey => l_item_key, aname => 'ORG_ID'); fnd_client_info.set_org_context(to_char(l_org_id)); l_currency_code := wf_engine.GetItemAttrText(itemtype => l_item_type, itemkey => l_item_key, aname => 'FUNCTIONAL_CURRENCY'); l_po_amount := wf_engine.GetItemAttrText(itemtype => l_item_type, itemkey => l_item_key, aname => 'PO_AMOUNT_DSP'); l_tax_amount := wf_engine.GetItemAttrText(itemtype => l_item_type, itemkey => l_item_key, aname => 'TAX_AMOUNT_DSP'); l_description := wf_engine.GetItemAttrText(itemtype => l_item_type, itemkey => l_item_key, aname => 'PO_DESCRIPTION'); l_forwarded_from := wf_engine.GetItemAttrText(itemtype => l_item_type, itemkey => l_item_key, aname => 'FORWARD_FROM_DISP_NAME'); l_preparer := wf_engine.GetItemAttrText(itemtype => l_item_type, itemkey => l_item_key, aname => 'PREPARER_DISPLAY_NAME'); l_note := wf_engine.GetItemAttrText(itemtype => l_item_type, itemkey => l_item_key, aname => 'NOTE'); --<Bug 4115777 Start> Show supplier and supplier site for -- approval notifications l_supplier := PO_WF_UTIL_PKG.GetItemAttrText(itemtype => l_item_type, itemkey => l_item_key, aname => 'SUPPLIER'); l_supplier_site := PO_WF_UTIL_PKG.GetItemAttrText(itemtype => l_item_type, itemkey => l_item_key, aname => 'SUPPLIER_SITE'); --<Bug 4115777 End> /*in order to add tax code the message,customize the po_approve_message,added by leone 2009.8.7*/ select nvl(psa.vat_code, 'no_tax') into l_tax_code from po_vendors pv, po_vendor_sites_all psa where pv.vendor_id = psa.vendor_id and pv.vendor_name = l_supplier and psa.vendor_site_code = l_supplier_site; /**---end---**/ fnd_currency.get_info(l_currency_code, X_precision, X_ext_precision, X_min_acct_unit); /*Start Bug# 3972475 - replaced the below sql to get the tax amount to account for canceled QTY. Also accounted for new order types introduced in 11i10 that use amount instead of quantity (where quantity_ordered is null). Since we are performing divide and multiply by operations we need rounding logic based on the currency. If we are using minimum accountable unit we apply: rounded tax = round(tax/mau)*mau, otherwise rounded tax = round(tax, precision) Old tax select: SELECT nvl(sum(nonrecoverable_tax), 0) INTO l_tax_amt FROM po_lines pol, po_distributions pod WHERE pol.po_header_id = l_document_id AND pod.po_line_id = pol.po_line_id; */ IF (x_min_acct_unit IS NOT NULL) AND (x_min_acct_unit <> 0) THEN SELECT sum(round(POD.nonrecoverable_tax * decode(quantity_ordered, NULL, (nvl(POD.amount_ordered, 0) - nvl(POD.amount_cancelled, 0)) / nvl(POD.amount_ordered, 1), (nvl(POD.quantity_ordered, 0) - nvl(POD.quantity_cancelled, 0)) / nvl(POD.quantity_ordered, 1)) / X_min_acct_unit) * X_min_acct_unit) INTO l_tax_amt FROM po_lines pol, po_distributions pod WHERE pol.po_header_id = l_document_id AND pod.po_line_id = pol.po_line_id; ELSE SELECT sum(round(POD.nonrecoverable_tax * decode(quantity_ordered, NULL, (nvl(POD.amount_ordered, 0) - nvl(POD.amount_cancelled, 0)) / nvl(POD.amount_ordered, 1), (nvl(POD.quantity_ordered, 0) - nvl(POD.quantity_cancelled, 0)) / nvl(POD.quantity_ordered, 1)), X_precision)) INTO l_tax_amt FROM po_lines pol, po_distributions pod WHERE pol.po_header_id = l_document_id AND pod.po_line_id = pol.po_line_id; END IF; if (display_type = 'text/html') then l_document := NL || NL || '<!-- PO_APPROVE_MSG -->' || NL || NL || '<P>'; l_document := l_document || '</P>' || NL; l_document := l_document || '<P><TABLE border=0 cellpadding=0 cellspacing=0 SUMMARY=""><TR><TD align=right >' || NL || fnd_message.get_string('PO', 'PO_WF_NOTIF_PO_AMOUNT') || ' </TD>' || NL; /*before modified l_document := l_document || '<TD align=left>' || l_currency_code || ' ' || l_po_amount || '</TD></TR>' || NL;*/ l_document := l_document || '<TD align=left>' || l_currency_code || ' ' || l_po_amount; if l_tax_amt > 0 then l_document := l_document || '(�祙)' || '</TD></TR>' || NL; --new added 2009.8.7 l_document := l_document || '<TR><TD align=right>' || fnd_message.get_string('PO', 'PO_WF_NOTIF_TAX_AMOUNT') || ' </TD>' || NL; l_document := l_document || '<TD align=left>' || l_currency_code || ' ' || l_tax_amount || '(' || l_tax_code || ')' || '</TD></TR></TABLE></P>' || NL; else l_document := l_document || '(ぃ�祙)' || '</TD></TR>' || NL;--new added 2009.8.7 l_document := l_document || '</TABLE></P>' || NL || NL; end if; --<Bug 4115777 Start> Show supplier and supplier site for -- approval notifications l_document := l_document || '<P>' || NL; l_document := l_document || fnd_message.get_string('PO', 'PO_FO_VENDOR') || ' ' || l_supplier || NL; l_document := l_document || '<BR>' || NL; l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_SUPPLIER_SITE') || ' ' || l_supplier_site || NL; l_document := l_document || '</P>' || NL; --<Bug 4115777 End> if l_description is not null then l_document := l_document || '<P>' || NL; l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_DOC_DESCRIPTION') || NL || '<BR>'; l_document := l_document || l_description; l_document := l_document || '<BR></P>' || NL; end if; else -- plain text notification is defined in the WF. null; end if; document := l_document; END; PROCEDURE get_po_lines_details(document_id in varchar2, display_type in varchar2, document in out NOCOPY varchar2, document_type in out NOCOPY varchar2) IS l_item_type wf_items.item_type%TYPE; l_item_key wf_items.item_key%TYPE; l_document_id po_lines.po_header_id%TYPE; l_org_id po_lines.org_id%TYPE; l_document_type VARCHAR2(25); l_document VARCHAR2(32000) := ''; l_currency_code fnd_currencies.currency_code%TYPE; -- Bug 3668188: added new local var. note: the length of this -- varchar was determined based on the length in POXWPA1B.pls, -- which is the other place 'OPEN_FORM_COMMAND' attribute is used l_open_form_command VARCHAR2(200); NL VARCHAR2(1) := fnd_global.newline; i NUMBER := 0; max_lines_dsp NUMBER := 20; l_line_count NUMBER := 0; -- <BUG 3616816> # lines/shipments on document l_num_records_to_display NUMBER; -- <BUG 3616816> actual # of records to be displayed in table line_mesg VARCHAR2(240); curr_len NUMBER := 0; prior_len NUMBER := 0; -- po lines cursor -- <BUG 3616816 START> Declare TABLEs for each column that is selected -- from po_line_csr and po_line_loc_csr. -- TYPE line_num_tbl_type IS TABLE OF PO_LINES.line_num%TYPE; TYPE shipment_num_tbl_type IS TABLE OF PO_LINE_LOCATIONS.shipment_num%TYPE; TYPE item_num_tbl_type IS TABLE OF MTL_SYSTEM_ITEMS_KFV.concatenated_segments%TYPE; TYPE item_revision_tbl_type IS TABLE OF PO_LINES.item_revision%TYPE; TYPE item_desc_tbl_type IS TABLE OF PO_LINES.item_description%TYPE; TYPE uom_tbl_type IS TABLE OF MTL_UNITS_OF_MEASURE.unit_of_measure_tl%TYPE; TYPE quantity_tbl_type IS TABLE OF PO_LINES.quantity%TYPE; TYPE unit_price_tbl_type IS TABLE OF PO_LINES.unit_price%TYPE; TYPE amount_tbl_type IS TABLE OF PO_LINES.amount%TYPE; TYPE location_tbl_type IS TABLE OF HR_LOCATIONS.location_code%TYPE; TYPE organization_name_tbl_type IS TABLE OF ORG_ORGANIZATION_DEFINITIONS.organization_name%TYPE; TYPE need_by_date_tbl_type IS TABLE OF PO_LINE_LOCATIONS.need_by_date%TYPE; TYPE promised_date_tbl_type IS TABLE OF PO_LINE_LOCATIONS.promised_date%TYPE; TYPE shipment_type_tbl_type IS TABLE OF PO_LINE_LOCATIONS.shipment_type%TYPE; l_line_num_tbl line_num_tbl_type; l_shipment_num_tbl shipment_num_tbl_type; l_item_num_tbl item_num_tbl_type; l_item_revision_tbl item_revision_tbl_type; l_item_desc_tbl item_desc_tbl_type; l_uom_tbl uom_tbl_type; l_quantity_tbl quantity_tbl_type; l_unit_price_tbl unit_price_tbl_type; l_amount_tbl amount_tbl_type; l_location_tbl location_tbl_type; l_org_name_tbl organization_name_tbl_type; l_need_by_date_tbl need_by_date_tbl_type; l_promised_date_tbl promised_date_tbl_type; l_shipment_type_tbl shipment_type_tbl_type; -- -- <BUG 3616816 END> /* Bug# 1419139: kagarwal ** Desc: The where clause pol.org_id = msi.organization_id(+) in the ** PO lines cursor, po_line_csr, is not correct as the pol.org_id ** is the operating unit which is not the same as the inventory ** organization_id. ** ** We need to use the financials_system_parameter table for the ** inventory organization_id. ** ** Also did the similar changes for the Release cursor,po_line_loc_csr. */ /* Bug 2401933: sktiwari Modifying cursor po_line_csr to return the translated UOM value instead of unit_meas_lookup_code. */ CURSOR po_line_csr(v_document_id NUMBER) IS SELECT pol.line_num, msi.concatenated_segments, pol.item_revision, pol.item_description, -- pol.unit_meas_lookup_code, -- bug 2401933.remove nvl(muom.unit_of_measure_tl, pol.unit_meas_lookup_code), -- bug 2401933.add pol.quantity, pol.unit_price, nvl(pol.amount, pol.quantity * pol.unit_price) FROM po_lines pol, mtl_system_items_kfv msi, mtl_units_of_measure muom, -- bug 2401933.add financials_system_parameters fsp WHERE pol.po_header_id = v_document_id AND pol.item_id = msi.inventory_item_id(+) AND NVL(msi.organization_id, fsp.inventory_organization_id) = fsp.inventory_organization_id /* Bug 2299484 fixed. prevented the canceled lines to be displayed in notifications. */ AND NVL(pol.cancel_flag, 'N') = 'N' AND muom.unit_of_measure(+) = pol.unit_meas_lookup_code -- bug 2401933.add ORDER BY pol.line_num; -- release shipments cursor /* Bug# 1530303: kagarwal ** Desc: We need to change the where clause as the item ** may not be an inventory item. For this case we should ** have an outer join with the mtl_system_items_kfv. ** ** Changed the condition: ** pol.item_id = msi.inventory_item_id ** to pol.item_id = msi.inventory_item_id(+) ** */ /* Bug# 1718725: kagarwal ** Desc: The unit of measure may be null at the shipment level ** hence in this case we need to get the uom from line level. ** ** Changed nvl(pll.unit_meas_lookup_code, pol.unit_meas_lookup_code) */ /* Bug# 1770951: kagarwal ** Desc: For Releases we should consider the price_override on the shipments ** and not the price on the Blanket PO line as the shipment price could be ** different if the price override is enabled on the Blanket. */ /* Bug 2401933: sktiwari Modifying cursor po_line_loc_csr to return the translated UOM value instead of unit_meas_lookup_code. */ CURSOR po_line_loc_csr(v_document_id NUMBER) IS SELECT pll.shipment_num, msi.concatenated_segments, pol.item_revision, pol.item_description, -- Bug 2401933.start -- nvl(pll.unit_meas_lookup_code, pol.unit_meas_lookup_code) -- unit_meas_lookup_code, nvl(muom.unit_of_measure_tl, pol.unit_meas_lookup_code), -- Bug 2401933.end pll.quantity, nvl(pll.price_override, pol.unit_price) unit_price, hrl.location_code, ood.organization_name, pll.need_by_date, pll.promised_date, pll.shipment_type FROM po_lines pol, po_line_locations pll, mtl_system_items_kfv msi, hr_locations_all hrl, hz_locations hz, org_organization_definitions ood, mtl_units_of_measure muom, -- Bug 2401933.add financials_system_parameters fsp where PLL.PO_RELEASE_ID = v_document_id and PLL.po_line_id = POL.po_line_id and PLL.ship_to_location_id = HRL.location_id(+) and PLL.ship_to_location_id = HZ.location_id(+) and PLL.ship_to_organization_id = OOD.organization_id and pol.item_id = msi.inventory_item_id(+) and NVL(msi.organization_id, fsp.inventory_organization_id) = fsp.inventory_organization_id /* Bug 2299484 fixed. prevented the canceled shipments to be displayed in notifications. */ AND NVL(PLL.cancel_flag, 'N') = 'N' AND muom.unit_of_measure(+) = pol.unit_meas_lookup_code -- Bug 2401933.add order by Shipment_num asc; BEGIN l_item_type := substr(document_id, 1, instr(document_id, ':') - 1); l_item_key := substr(document_id, instr(document_id, ':') + 1, length(document_id) - 2); /* Bug# 2353153 ** Setting application context */ PO_REQAPPROVAL_INIT1.Set_doc_mgr_context(l_item_type, l_item_key); l_document_id := wf_engine.GetItemAttrNumber(itemtype => l_item_type, itemkey => l_item_key, aname => 'DOCUMENT_ID'); l_org_id := wf_engine.GetItemAttrNumber(itemtype => l_item_type, itemkey => l_item_key, aname => 'ORG_ID'); l_document_type := wf_engine.GetItemAttrText(itemtype => l_item_type, itemkey => l_item_key, aname => 'DOCUMENT_TYPE'); fnd_client_info.set_org_context(to_char(l_org_id)); /* Bug# 1686066: kagarwal ** Desc: Use the functional currency of the PO for the precision of ** line amounts. */ l_currency_code := wf_engine.GetItemAttrText(itemtype => l_item_type, itemkey => l_item_key, aname => 'FUNCTIONAL_CURRENCY'); -- Bug 3668188 l_open_form_command := wf_engine.GetItemAttrText(itemtype => l_item_type, itemkey => l_item_key, aname => 'OPEN_FORM_COMMAND'); /* Bug# 2668222: kagarwal ** Desc: Using profile PO_NOTIF_LINES_LIMIT to get the maximum ** number of PO lines to be displayed in Approval notification. ** The same profile is also used for Requisitions. */ max_lines_dsp := to_number(fnd_profile.value('PO_NOTIF_LINES_LIMIT')); if max_lines_dsp is NULL then max_lines_dsp := 20; end if; -- <BUG 3616816 START> Fetch Release Shipments/PO Lines data into Tables. -- IF (l_document_type = 'RELEASE') THEN OPEN po_line_loc_csr(l_document_id); FETCH po_line_loc_csr BULK COLLECT INTO l_shipment_num_tbl, l_item_num_tbl, l_item_revision_tbl, l_item_desc_tbl, l_uom_tbl, l_quantity_tbl, l_unit_price_tbl, l_location_tbl, l_org_name_tbl, l_need_by_date_tbl, l_promised_date_tbl, l_shipment_type_tbl; l_line_count := po_line_loc_csr%ROWCOUNT; -- Get # of records fetched. CLOSE po_line_loc_csr; ELSE OPEN po_line_csr(l_document_id); FETCH po_line_csr BULK COLLECT INTO l_line_num_tbl, l_item_num_tbl, l_item_revision_tbl, l_item_desc_tbl, l_uom_tbl, l_quantity_tbl, l_unit_price_tbl, l_amount_tbl; l_line_count := po_line_csr%ROWCOUNT; -- Get # of records fetched. CLOSE po_line_csr; END IF; -- -- <BUG 3616816 END> -- <BUG 3616816 START> Determine the actual number of records to display -- in the table. -- IF (l_line_count > max_lines_dsp) THEN l_num_records_to_display := max_lines_dsp; ELSE l_num_records_to_display := l_line_count; END IF; -- -- <BUG 3616816 END> if (display_type = 'text/html') then if (nvl(l_document_type, 'PO') <> 'RELEASE') then l_document := NL || NL || '<!-- PO_LINE_DETAILS -->' || NL || NL || '<P><B>'; l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_PO_LINE_DETAILS'); l_document := l_document || '</B>' || NL || '<P>'; -- <BUG 3616816> -- <BUG 3616816 START> Only display message if # of actual lines is -- greater than maximum limit. -- IF (l_line_count > max_lines_dsp) THEN -- Bug 3668188: changed the code check (originally created -- in bug 3607009) that determines which message to show -- based on whether Open Document icon is shown in the notif. -- The value of WF attribute 'OPEN_FORM_COMMAND' is set in a -- previous node, using the get_po_user_msg_attribute procedure. -- IF (l_open_form_command IS NULL) THEN -- "The first [COUNT] Purchase Order lines are summarized -- below. For information on additional lines, please click -- the Open Document icon." FND_MESSAGE.set_name('PO', 'PO_WF_NOTIF_PO_LINE_MESG'); ELSE -- "The first [COUNT] Purchase Order lines are summarized below." FND_MESSAGE.set_name('PO', 'PO_WF_NOTIF_PO_LINE_MESG_TRUNC'); END IF; FND_MESSAGE.set_token('COUNT', to_char(max_lines_dsp)); line_mesg := FND_MESSAGE.get; l_document := l_document || line_mesg || '<P>'; END IF; -- -- <BUG 3616816 END> 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; l_document := l_document || '<TR>' || NL; l_document := l_document || '<TH id="lineNum_1">' || fnd_message.get_string('PO', 'PO_WF_NOTIF_LINE_NUMBER') || '</TH>' || NL; l_document := l_document || '<TH id="itemNum_1">' || fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_NUMBER') || '</TH>' || NL; l_document := l_document || '<TH id="itemRev_1">' || fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_REVISION') || '</TH>' || NL; l_document := l_document || '<TH id="itemDesc_1">' || fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_DESC') || '</TH>' || NL; l_document := l_document || '<TH id="uom_1">' || fnd_message.get_string('PO', 'PO_WF_NOTIF_UOM') || '</TH>' || NL; l_document := l_document || '<TH id="quant_1">' || fnd_message.get_string('PO', 'PO_WF_NOTIF_QUANTITY') || '</TH>' || NL; l_document := l_document || '<TH id="unitPrice_1">' || fnd_message.get_string('PO', 'PO_WF_NOTIF_UNIT_PRICE') || '</TH>' || NL; l_document := l_document || '<TH id="lineAmt_1">' || fnd_message.get_string('PO', 'PO_WF_NOTIF_LINE_AMOUNT') || '</TH>' || NL; l_document := l_document || '</TR>' || NL; curr_len := lengthb(l_document); prior_len := curr_len; FOR i IN 1 .. l_num_records_to_display LOOP -- <BUG 3616816> /* Exit the cursor if the current document length and 2 times the ** length added in prior line exceeds 32000 char */ if (curr_len + (2 * (curr_len - prior_len))) >= 32000 then exit; end if; prior_len := curr_len; l_document := l_document || '<TR>' || NL; l_document := l_document || '<TD nowrap align=center headers="lineNum_1">' || nvl(to_char(l_line_num_tbl(i)), ' ') || '</TD>' || NL; l_document := l_document || '<TD nowrap headers="itemNum_1">' || nvl(l_item_num_tbl(i), ' ') || '</TD>' || NL; l_document := l_document || '<TD nowrap headers="itemRev_1">' || nvl(l_item_revision_tbl(i), ' ') || '</TD>' || NL; l_document := l_document || '<TD nowrap headers="itemDesc_1">' || nvl(l_item_desc_tbl(i), ' ') || '</TD>' || NL; l_document := l_document || '<TD nowrap headers="uom_1">' || nvl(l_uom_tbl(i), ' ') || '</TD>' || NL; l_document := l_document || '<TD nowrap align=right headers="quant_1">' || nvl(to_char(l_quantity_tbl(i)), ' ') || '</TD>' || NL; /* Bug 2868931: kagarwal ** We will not format the unit price on the lines in notifications */ -- Bug 3547777. Added the nvl clauses to unit_price and line_ -- amount so that box is still displayed even if value is null. l_document := l_document || '<TD nowrap align=right headers="unitPrice_1">' || nvl(TO_CHAR(l_unit_price_tbl(i)), ' ') || '</TD>' || NL; l_document := l_document || '<TD nowrap align=right headers="lineAmt_1">' || nvl(TO_CHAR(l_amount_tbl(i), FND_CURRENCY.GET_FORMAT_MASK(l_currency_code, 30)), ' ') || '</TD>' || NL; l_document := l_document || '</TR>' || NL; curr_len := lengthb(l_document); end loop; else -- release l_document := NL || NL || '<!-- RELEASE_SHIPMENT_DETAILS -->' || NL || NL || '<P><B>'; l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_SHIP_DETAILS'); l_document := l_document || '</B>' || NL || '<P>'; -- <BUG 3616816 START> Only display message if # of actual lines is -- greater than maximum limit. -- IF (l_line_count > max_lines_dsp) THEN FND_MESSAGE.set_name('PO', 'PO_WF_NOTIF_PO_REL_SHIP_MESG'); FND_MESSAGE.set_token('COUNT', to_char(max_lines_dsp)); line_mesg := FND_MESSAGE.get; l_document := l_document || line_mesg || '<P>'; END IF; -- -- <BUG 3616816 END> 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; l_document := l_document || '<TR>' || NL; l_document := l_document || '<TH id="shipNum_2">' || fnd_message.get_string('PO', 'PO_WF_NOTIF_SHIP_NUMBER') || '</TH>' || NL; l_document := l_document || '<TH id="itemNum_2">' || fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_NUMBER') || '</TH>' || NL; l_document := l_document || '<TH id="itemRev_2">' || fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_REVISION') || '</TH>' || NL; l_document := l_document || '<TH id="itemDesc_2">' || fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_DESC') || '</TH>' || NL; l_document := l_document || '<TH id="uom_2">' || fnd_message.get_string('PO', 'PO_WF_NOTIF_UOM') || '</TH>' || NL; l_document := l_document || '<TH id="quant_2">' || fnd_message.get_string('PO', 'PO_WF_NOTIF_QUANTITY') || '</TH>' || NL; l_document := l_document || '<TH id="unitPrice_2">' || fnd_message.get_string('PO', 'PO_WF_NOTIF_UNIT_PRICE') || '</TH>' || NL; l_document := l_document || '<TH id="location_2">' || fnd_message.get_string('PO', 'PO_WF_NOTIF_LOCATION') || '</TH>' || NL; l_document := l_document || '<TH id="shipToOrg_2">' || fnd_message.get_string('PO', 'POA_SHIP_TO_ORG') || '</TH>' || NL; l_document := l_document || '<TH id="needByDate_2">' || fnd_message.get_string('PO', 'PO_WF_NOTIF_NEED_BY_DATE') || '</TH>' || NL; l_document := l_document || '</TR>' || NL; curr_len := lengthb(l_document); prior_len := curr_len; FOR i IN 1 .. l_num_records_to_display LOOP -- <BUG 3616816> /* Exit the cursor if the current document length and 2 times the ** length added in prior line exceeds 32000 char */ if (curr_len + (2 * (curr_len - prior_len))) >= 32000 then exit; end if; prior_len := curr_len; l_document := l_document || '<TR>' || NL; l_document := l_document || '<TD nowrap align=center headers="shipNum_2">' || nvl(to_char(l_shipment_num_tbl(i)), ' ') || '</TD>' || NL; l_document := l_document || '<TD nowrap headers="itemNum_2">' || nvl(l_item_num_tbl(i), ' ') || '</TD>' || NL; l_document := l_document || '<TD nowrap headers="itemRev_2">' || nvl(l_item_revision_tbl(i), ' ') || '</TD>' || NL; l_document := l_document || '<TD nowrap headers="itemDesc_2">' || nvl(l_item_desc_tbl(i), ' ') || '</TD>' || NL; l_document := l_document || '<TD nowrap headers="uom_2">' || nvl(l_uom_tbl(i), ' ') || '</TD>' || NL; l_document := l_document || '<TD nowrap align=right headers="quant_2">' || nvl(to_char(l_quantity_tbl(i)), ' ') || '</TD>' || NL; /* Bug 2868931: kagarwal ** We will not format the unit price on the lines in notifications */ l_document := l_document || '<TD nowrap align=right headers="unitPrice_2">' || TO_CHAR(l_unit_price_tbl(i)) || '</TD>' || NL; l_document := l_document || '<TD nowrap headers="location_2">' || nvl(l_location_tbl(i), ' ') || '</TD>' || NL; l_document := l_document || '<TD nowrap headers="shipToOrg_2">' || nvl(l_org_name_tbl(i), ' ') || '</TD>' || NL; l_document := l_document || '<TD nowrap headers="needByDate_2">' || to_char(l_need_by_date_tbl(i)) || '</TD>' || NL; l_document := l_document || '</TR>' || NL; curr_len := lengthb(l_document); end loop; end if; l_document := l_document || '</TABLE></P>' || NL; document := l_document; elsif (display_type = 'text/plain') then if (nvl(l_document_type, 'PO') <> 'RELEASE') then l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_PO_LINE_DETAILS') || NL || NL; -- <BUG 3616816 START> Only display message if # of actual lines is -- greater than maximum limit. -- IF (l_line_count > max_lines_dsp) THEN -- Bug 3668188: changed the code check (originally created -- in bug 3607009) that determines which message to show -- based on whether Open Document icon is shown in then notif. -- The value of WF attribute 'OPEN_FORM_COMMAND' is set in a -- previous node, using the get_po_user_msg_attribute procedure. -- IF (l_open_form_command IS NULL) THEN -- "The first [COUNT] Purchase Order lines are summarized -- below. For information on additional lines, please click -- the Open Document icon." FND_MESSAGE.set_name('PO', 'PO_WF_NOTIF_PO_LINE_MESG'); ELSE -- "The first [COUNT] Purchase Order lines are summarized below." FND_MESSAGE.set_name('PO', 'PO_WF_NOTIF_PO_LINE_MESG_TRUNC'); END IF; FND_MESSAGE.set_token('COUNT', to_char(max_lines_dsp)); line_mesg := FND_MESSAGE.get; l_document := l_document || line_mesg || NL || NL; END IF; -- -- <BUG 3616816 END> curr_len := lengthb(l_document); prior_len := curr_len; FOR i IN 1 .. l_num_records_to_display LOOP -- <BUG 3616816> /* Exit the cursor if the current document length and 2 times the ** length added in prior line exceeds 32000 char */ if (curr_len + (2 * (curr_len - prior_len))) >= 32000 then exit; end if; prior_len := curr_len; l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_LINE_NUMBER') || ':' || to_char(l_line_num_tbl(i)) || NL; l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_NUMBER') || ': ' || l_item_num_tbl(i) || NL; l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_REVISION') || ': ' || l_item_revision_tbl(i) || NL; l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_DESC') || ': ' || l_item_desc_tbl(i) || NL; l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_UOM') || ': ' || l_uom_tbl(i) || NL; l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_QUANTITY') || ': ' || to_char(l_quantity_tbl(i)) || NL; /* Bug 2868931: kagarwal ** We will not format the unit price on the lines in notifications */ l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_UNIT_PRICE') || ': ' || to_char(l_unit_price_tbl(i)) || NL; l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_LINE_AMOUNT') || ': ' || to_char(l_amount_tbl(i), FND_CURRENCY.GET_FORMAT_MASK(l_currency_code, 30)) || NL || NL; curr_len := lengthb(l_document); end loop; else -- release l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_SHIP_DETAILS') || NL || NL || NL; -- <BUG 3616816 START> Only display message if # of actual lines is -- greater than maximum limit. -- IF (l_line_count > max_lines_dsp) THEN FND_MESSAGE.set_name('PO', 'PO_WF_NOTIF_PO_REL_SHIP_MESG'); FND_MESSAGE.set_token('COUNT', to_char(max_lines_dsp)); line_mesg := FND_MESSAGE.get; l_document := l_document || line_mesg || NL || NL; END IF; -- -- <BUG 3616816 END> curr_len := lengthb(l_document); prior_len := curr_len; FOR i IN 1 .. l_num_records_to_display LOOP -- <BUG 3616816> /* Exit the cursor if the current document length and 2 times the ** length added in prior line exceeds 32000 char */ if (curr_len + (2 * (curr_len - prior_len))) >= 32000 then exit; end if; prior_len := curr_len; l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_SHIP_NUMBER') || ': ' || to_char(l_shipment_num_tbl(i)) || NL; l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_NUMBER') || ': ' || l_item_num_tbl(i) || NL; l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_REVISION') || ': ' || l_item_revision_tbl(i) || NL; l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_ITEM_DESC') || ': ' || l_item_desc_tbl(i) || NL; l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_UOM') || ': ' || l_uom_tbl(i) || NL; l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_QUANTITY') || ': ' || to_char(l_quantity_tbl(i)) || NL; /* Bug 2868931: kagarwal ** We will not format the unit price on the lines in notifications */ l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_UNIT_PRICE') || ': ' || to_char(l_unit_price_tbl(i)) || NL; l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_LINE_AMOUNT') || ': ' || to_char(l_amount_tbl(i), FND_CURRENCY.GET_FORMAT_MASK(l_currency_code, 30)) || NL; l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_LOCATION') || ': ' || l_location_tbl(i) || NL; l_document := l_document || fnd_message.get_string('PO', 'POA_SHIP_TO_ORG') || ': ' || l_org_name_tbl(i) || NL; 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; curr_len := lengthb(l_document); end loop; end if; document := l_document; -- Bug 2462005 end if; END get_po_lines_details; PROCEDURE get_action_history(document_id in varchar2, display_type in varchar2, document in out NOCOPY varchar2, document_type in out NOCOPY varchar2) IS l_item_type wf_items.item_type%TYPE; l_item_key wf_items.item_key%TYPE; l_document_id po_lines.po_header_id%TYPE; l_org_id po_lines.org_id%TYPE; l_doc_type_code VARCHAR2(80); l_document VARCHAR2(32000) := ''; -- Bug 3668188: added new local var. note: the length of this -- varchar was determined based on the length in POXWPA1B.pls, -- which is the other place 'OPEN_FORM_COMMAND' attribute is used l_open_form_command VARCHAR2(200); NL VARCHAR2(1) := fnd_global.newline; -- <BUG 3616816 START> Declare TABLEs for each column that is selected -- from history_csr cursor. -- TYPE sequence_num_tbl_type IS TABLE OF PO_ACTION_HISTORY.sequence_num%TYPE; TYPE full_name_tbl_type IS TABLE OF PER_ALL_PEOPLE_F.full_name%TYPE; TYPE displayed_field_tbl_type IS TABLE OF PO_LOOKUP_CODES.displayed_field%TYPE; TYPE action_date_tbl_type IS TABLE OF PO_ACTION_HISTORY.action_date%TYPE; TYPE note_tbl_type IS TABLE OF PO_ACTION_HISTORY.note%TYPE; TYPE object_revision_num_tbl_type IS TABLE OF PO_ACTION_HISTORY.object_revision_num%TYPE; TYPE employee_id_tbl_type IS TABLE OF PO_ACTION_HISTORY.employee_id%TYPE; TYPE created_by_tbl_type IS TABLE OF PO_ACTION_HISTORY.created_by%TYPE; l_sequence_num_tbl sequence_num_tbl_type; l_employee_name_tbl full_name_tbl_type; l_action_tbl displayed_field_tbl_type; l_action_date_tbl action_date_tbl_type; l_note_tbl note_tbl_type; l_object_revision_num_tbl object_revision_num_tbl_type; l_employee_id_tbl employee_id_tbl_type; l_created_by_tbl created_by_tbl_type; -- -- <BUG 3616816 END> --SQL What: Query action history which is updated by both buyer and vendor --SQL Why: Since vendor doesn't have employee id, added outer join; CURSOR history_csr(v_document_id NUMBER, v_doc_type_code VARCHAR2) IS SELECT poh.SEQUENCE_NUM, per.FULL_NAME, polc.DISPLAYED_FIELD, poh.ACTION_DATE, poh.NOTE, poh.OBJECT_REVISION_NUM, poh.employee_id, /* bug 2788683 */ poh.created_by /* bug 2788683 */ from po_action_history poh, per_all_people_f per, -- Bug 3404451 po_lookup_codes polc where OBJECT_TYPE_CODE = v_doc_type_code and poh.action_code = polc.lookup_code and POLC.LOOKUP_TYPE IN ('APPROVER ACTIONS', 'CONTROL ACTIONS') and per.person_id(+) = poh.employee_id /* bug 2788683 */ and trunc(sysdate) between per.effective_start_date(+) and per.effective_end_date(+) and OBJECT_ID = v_document_id UNION ALL SELECT poh.SEQUENCE_NUM, per.FULL_NAME, NULL, poh.ACTION_DATE, poh.NOTE, poh.OBJECT_REVISION_NUM, poh.employee_id, /* bug 2788683 */ poh.created_by /* bug 2788683 */ from po_action_history poh, per_all_people_f per -- Bug 3404451 where OBJECT_TYPE_CODE = v_doc_type_code and poh.action_code is null and per.person_id(+) = poh.employee_id /* bug 2788683 */ and trunc(sysdate) between per.effective_start_date(+) and per.effective_end_date(+) and OBJECT_ID = v_document_id order by 1 desc; i NUMBER := 0; max_actions_dsp NUMBER := 20; l_action_count NUMBER; -- <BUG 3616816> # of action history records l_num_records_to_display NUMBER; -- <BUG 3616816> actual # of records to display in table action_mesg VARCHAR2(240); curr_len NUMBER := 0; prior_len NUMBER := 0; /* Bug 2788683 start */ l_user_name fnd_user.user_name%TYPE; l_vendor_name hz_parties.party_name%TYPE; l_party_name hz_parties.party_name%TYPE; /* Bug 2788683 end */ BEGIN l_item_type := substr(document_id, 1, instr(document_id, ':') - 1); l_item_key := substr(document_id, instr(document_id, ':') + 1, length(document_id) - 2); l_document_id := wf_engine.GetItemAttrNumber(itemtype => l_item_type, itemkey => l_item_key, aname => 'DOCUMENT_ID'); l_org_id := wf_engine.GetItemAttrNumber(itemtype => l_item_type, itemkey => l_item_key, aname => 'ORG_ID'); l_doc_type_code := wf_engine.GetItemAttrText(itemtype => l_item_type, itemkey => l_item_key, aname => 'DOCUMENT_TYPE'); fnd_client_info.set_org_context(to_char(l_org_id)); -- Bug 3668188 l_open_form_command := wf_engine.GetItemAttrText(itemtype => l_item_type, itemkey => l_item_key, aname => 'OPEN_FORM_COMMAND'); /* Bug# 2577478: kagarwal ** Desc: Added a new attribute ACT_HST_IN_NTF in wf definition for ** users to specify the number of PO actions to be displayed in a ** notification. ** If the attribute does not exist or is null, then we would use default ** value of 20. */ max_actions_dsp := PO_WF_UTIL_PKG.GetItemAttrNumber(itemtype => l_item_type, itemkey => l_item_key, aname => 'ACT_HST_IN_NTF'); if max_actions_dsp is NULL then max_actions_dsp := 20; end if; -- <BUG 3616816 START> Fetch all Action History data into Tables. -- OPEN history_csr(l_document_id, l_doc_type_code); FETCH history_csr BULK COLLECT INTO l_sequence_num_tbl, l_employee_name_tbl, l_action_tbl, l_action_date_tbl, l_note_tbl, l_object_revision_num_tbl, l_employee_id_tbl, l_created_by_tbl; l_action_count := history_csr%ROWCOUNT; -- Get # of records fetched. CLOSE history_csr; -- -- <BUG 3616816 END> -- <BUG 3616816 START> Only display message if # of actual Action History -- records is greater than maximum limit. -- IF (l_action_count > max_actions_dsp) THEN l_num_records_to_display := max_actions_dsp; -- Bug 3668188: changed the code check (originally created -- in bug 3607009) that determines which message to show -- based on whether Open Document icon is shown in then notif. -- The value of WF attribute 'OPEN_FORM_COMMAND' is set in a -- previous node, using the get_po_user_msg_attribute procedure. -- IF (l_open_form_command IS NULL) THEN -- "The last [COUNT] Approval History details are summarized below. -- For information on additional Approval History, please click the -- Open Document icon." FND_MESSAGE.set_name('PO', 'PO_WF_NOTIF_PO_ACT_MESG'); ELSE -- "The last [COUNT] Approval History details are summarized below." FND_MESSAGE.set_name('PO', 'PO_WF_NOTIF_PO_ACT_MESG_TRUNC'); END IF; FND_MESSAGE.set_token('COUNT', to_char(max_actions_dsp)); action_mesg := FND_MESSAGE.get; ELSE l_num_records_to_display := l_action_count; action_mesg := NULL; END IF; -- -- <BUG 3616816 END> if (display_type = 'text/html') then l_document := NL || NL || '<!-- ACTION_HISTORY -->' || NL || NL || '<P><B>'; l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_ACTION_HISTORY') || NL; l_document := l_document || '</B>' || NL || NL || '<P>'; -- <BUG 3616816> -- <BUG 3616816 START> Action History message may be NULL. Only append it -- and corresponding line breaks if there is a message to display. -- IF (action_mesg IS NOT NULL) THEN l_document := l_document || action_mesg || '<P>' || NL; END IF; -- -- <BUG 3616816 END> l_document := l_document || '<TABLE border=1 cellpadding=2 cellspacing=1 summary="' || fnd_message.get_string('ICX', 'ICX_POR_TBL_OF_APPROVERS') || '">' || NL; l_document := l_document || '<TR>'; l_document := l_document || '<TH id="seqNum_1">' || fnd_message.get_string('PO', 'PO_WF_NOTIF_SEQ_NUM') || '</TH>' || NL; l_document := l_document || '<TH id="employee_1">' || fnd_message.get_string('PO', 'PO_WF_NOTIF_EMPLOYEE') || '</TH>' || NL; l_document := l_document || '<TH id="action_1">' || fnd_message.get_string('PO', 'PO_WF_NOTIF_ACTION') || '</TH>' || NL; l_document := l_document || '<TH id="date_1">' || fnd_message.get_string('PO', 'PO_WF_NOTIF_DATE') || '</TH>' || NL; l_document := l_document || '<TH id="actionNote_1">' || fnd_message.get_string('PO', 'PO_WF_NOTIF_ACTION_NOTE') || '</TH>' || NL; l_document := l_document || '</TR>' || NL; curr_len := lengthb(l_document); prior_len := curr_len; FOR i IN 1 .. l_num_records_to_display LOOP -- <BUG 3616816> /* Exit the cursor if the current document length and 2 times the ** length added in prior line exceeds 32000 char */ if (curr_len + (2 * (curr_len - prior_len))) >= 32000 then exit; end if; prior_len := curr_len; l_document := l_document || '<TR>' || NL; l_document := l_document || '<TD nowrap align=center headers="seqNum_1">' || nvl(to_char(l_sequence_num_tbl(i)), ' ') || '</TD>' || NL; /* Bug 2788683 start */ /* if action history is updated by vendor * show vendor true name(vendor name) * else action history is updated by buyer * show buyer's true name */ IF l_employee_id_tbl(i) IS NULL THEN SELECT fu.user_name, hp.party_name INTO l_user_name, l_party_name FROM fnd_user fu, hz_parties hp WHERE hp.party_id = fu.customer_id AND fu.user_id = l_created_by_tbl(i); po_inq_sv.get_vendor_name(l_user_name => l_user_name, x_vendor_name => l_vendor_name); l_document := l_document || '<TD nowrap headers="employee_1">' || l_party_name || '(' || l_vendor_name || ')' || '</TD>' || NL; ELSE l_document := l_document || '<TD nowrap headers="employee_1">' || nvl(l_employee_name_tbl(i), ' ') || '</TD>' || NL; END IF; /* Bug 2788683 end */ l_document := l_document || '<TD nowrap headers="action_1">' || nvl(l_action_tbl(i), ' ') || '</TD>' || NL; l_document := l_document || '<TD nowrap headers="date_1">' || nvl(to_char(l_action_date_tbl(i)), ' ') || '</TD>' || NL; l_document := l_document || '<TD nowrap headers="actionNote_1">' || nvl(l_note_tbl(i), ' ') || '</TD>' || NL; l_document := l_document || '</TR>' || NL; curr_len := lengthb(l_document); end loop; l_document := l_document || '</TABLE></P>' || NL; document := l_document; elsif (display_type = 'text/plain') then l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_ACTION_HISTORY') || NL; -- <BUG 3616816 START> Action History message may be NULL. Only append it -- and corresponding line breaks if there is a message to display. -- IF (action_mesg IS NOT NULL) THEN l_document := l_document || action_mesg || NL || NL; END IF; -- -- <BUG 3616816 END> curr_len := lengthb(l_document); prior_len := curr_len; FOR i IN 1 .. l_num_records_to_display LOOP -- <BUG 3616816> /* Exit the cursor if the current document length and 2 times the ** length added in prior line exceeds 32000 char */ if (curr_len + (2 * (curr_len - prior_len))) >= 32000 then exit; end if; prior_len := curr_len; l_document := l_document || NL; /* Bug 2462005 sktiwari: ** Added a ':' between the prompt and the data. Modified the following lines. */ l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_SEQ_NUM') || ': ' || to_char(l_sequence_num_tbl(i)) || NL; /* Bug 2788683 start */ /* if action history is updated by vendor * show vendor true name(vendor name) * else action history is updated by buyer * show buyer's true name */ IF l_employee_id_tbl(i) IS NULL THEN SELECT fu.user_name, hp.party_name INTO l_user_name, l_party_name FROM fnd_user fu, hz_parties hp WHERE hp.party_id = fu.customer_id AND fu.user_id = l_created_by_tbl(i); po_inq_sv.get_vendor_name(l_user_name => l_user_name, x_vendor_name => l_vendor_name); l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_EMPLOYEE') || ': ' || l_party_name || '(' || l_vendor_name || ')' || NL; ELSE l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_EMPLOYEE') || ': ' || l_employee_name_tbl(i) || NL; END IF; /* Bug 2788683 end */ l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_ACTION') || ': ' || l_action_tbl(i) || NL; l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_DATE') || ': ' || to_char(l_action_date_tbl(i)) || NL; l_document := l_document || fnd_message.get_string('PO', 'PO_WF_NOTIF_ACTION_NOTE') || ': ' || l_note_tbl(i) || NL; l_document := l_document || NL; curr_len := lengthb(l_document); end loop; l_document := l_document; document := l_document; end if; END; PROCEDURE post_approval_notif(itemtype in varchar2, itemkey in varchar2, actid in number, funcmode in varchar2, resultout in out NOCOPY varchar2) is begin resultout := wf_engine.eng_completed || ':' || wf_engine.eng_null; -- Don't allow transfer if (funcmode = 'TRANSFER') then fnd_message.set_name('PO', 'PO_WF_NOTIF_NO_TRANSFER'); app_exception.raise_exception; end if; -- end if for funcmode = 'TRANSFER' return; end post_approval_notif; /* Bug# 2616433: kagarwal ** Desc: Added new procedure to set notification subject token in ** user language. */ procedure Get_po_user_msg_attribute(itemtype in varchar2, itemkey in varchar2, actid in number, funcmode in varchar2, resultout out NOCOPY varchar2) IS l_progress VARCHAR2(100) := '000'; l_doc_string varchar2(200); l_user_name varchar2(100); l_preparer_user_name varchar2(100); l_orgid number; l_notification_type varchar2(15); --bug 3668188 -- <Start Word Integration 11.5.10+> l_okc_doc_type varchar2(20); l_conterms_exist_flag PO_HEADERS_ALL.conterms_exist_flag%TYPE; l_document_id NUMBER; l_document_subtype PO_HEADERS_ALL.type_lookup_code%TYPE; -- <End Word Integration 11.5.10+> BEGIN -- Do nothing in cancel or timeout mode -- if (funcmode <> wf_engine.eng_run) then resultout := wf_engine.eng_null; return; end if; l_progress := 'Get_po_user_msg_attribute:001: actid: ' || actid; /* DEBUG */ PO_WF_DEBUG_PKG.insert_debug(itemtype, itemkey, l_progress); l_orgid := wf_engine.GetItemAttrNumber(itemtype => itemtype, itemkey => itemkey, aname => 'ORG_ID'); IF l_orgid is NOT NULL THEN fnd_client_info.set_org_context(to_char(l_orgid)); END IF; l_progress := 'Get_po_user_msg_attribute:010: orgid: ' || l_orgid; /* DEBUG */ PO_WF_DEBUG_PKG.insert_debug(itemtype, itemkey, l_progress); l_user_name := wf_engine.GetActivityAttrText(itemtype => itemtype, itemkey => itemkey, actid => actid, aname => 'NTF_USER_NAME', ignore_notfound => TRUE); PO_WF_PO_NOTIFICATION.GetDisplayValue(itemtype, itemkey, l_user_name); l_progress := 'Get_po_user_msg_attribute:015: username: ' || l_user_name; /* DEBUG */ PO_WF_DEBUG_PKG.insert_debug(itemtype, itemkey, l_progress); -- Bug 3668188: added the NTF_USER_ROLE Activity Attribute, which is -- a constant with value 'SUBMITTER' or 'APPROVER'. This distinguishes -- between the 3 different notification-functions that share this procedure. l_notification_type := wf_engine.GetActivityAttrText(itemtype => itemtype, itemkey => itemkey, actid => actid, aname => 'NTF_USER_ROLE', ignore_notfound => TRUE); l_progress := 'Get_po_user_msg_attribute:020: notif type: ' || l_notification_type; -- DEBUG PO_WF_DEBUG_PKG.insert_debug(itemtype, itemkey, l_progress); -- Bug 3668188: Removed old logic from bug 3564727 and replaced it -- with a call to is_open_document_allowed, which has updated logic. IF NOT (PO_WF_PO_NOTIFICATION.is_open_document_allowed(p_itemtype => itemtype, p_itemkey => itemkey, p_notification_type => l_notification_type)) THEN l_progress := 'Get_po_approver_msg_attribute: 040: NULL open form'; /* DEBUG */ PO_WF_DEBUG_PKG.insert_debug(itemtype, itemkey, l_progress); wf_engine.SetItemAttrText(itemtype => itemtype, itemkey => itemkey, aname => 'OPEN_FORM_COMMAND', avalue => ''); END IF; -- <Start Word Integration 11.5.10+> l_conterms_exist_flag := PO_WF_UTIL_PKG.GetItemAttrText(itemtype => itemtype, itemkey => itemkey, aname => 'CONTERMS_EXIST_FLAG'); l_document_subtype := PO_WF_UTIL_PKG.GetItemAttrText(itemtype => itemtype, itemkey => itemkey, aname => 'DOCUMENT_SUBTYPE'); l_document_id := PO_WF_UTIL_PKG.GetItemAttrNumber(itemtype => itemtype, itemkey => itemkey, aname => 'DOCUMENT_ID'); /* Set or reset the okc doc attachment attribute */ IF (l_conterms_exist_flag = 'Y') THEN l_okc_doc_type := PO_CONTERMS_UTL_GRP.get_po_contract_doctype(l_document_subtype); IF (('STRUCTURED' <> OKC_TERMS_UTIL_GRP.get_contract_source_code(p_document_type => l_okc_doc_type, p_document_id => l_document_id)) AND ('N' = OKC_TERMS_UTIL_GRP.is_primary_terms_doc_mergeable(P_document_type => l_okc_doc_type, p_document_id => l_document_id)) AND (PO_COMMUNICATION_PVT.PO_COMMUNICATION_PROFILE = 'T')) THEN PO_WF_UTIL_PKG.SetItemAttrText(itemtype => itemtype, itemkey => itemkey, aname => 'OKC_DOC_ATTACHMENT', avalue => 'PLSQLBLOB:PO_COMMUNICATION_PVT.OKC_DOC_ATTACH/' || itemtype || ':' || itemkey); ELSE /* Contract terms are structured, or attached document is mergeable. * All contract terms will be in pdf; no need for other okc doc attachment. */ PO_WF_UTIL_PKG.SetItemAttrText(itemtype => itemtype, itemkey => itemkey, aname => 'OKC_DOC_ATTACHMENT', avalue => ''); END IF /* not structured and not mergeable */ ; END IF; /* l_conterms_exist_flag = 'Y' */ -- <End Word Integration 11.5.10+> l_progress := 'Get_po_approver_msg_attribute: 999'; /* DEBUG */ PO_WF_DEBUG_PKG.insert_debug(itemtype, itemkey, l_progress); resultout := wf_engine.eng_completed || ':' || 'ACTIVITY_PERFORMED'; EXCEPTION WHEN OTHERS THEN l_doc_string := PO_REQAPPROVAL_INIT1.get_error_doc(itemType, itemkey); l_preparer_user_name := PO_REQAPPROVAL_INIT1.get_preparer_user_name(itemType, itemkey); wf_core.context('PO_WF_PO_NOTIFICATION', 'Get_req_approval_msg_attribute', l_progress); PO_REQAPPROVAL_INIT1.send_error_notif(itemType, itemkey, l_preparer_user_name, l_doc_string, sqlerrm, 'PO_WF_PO_NOTIFICATION.Get_po_approver_msg_attribute'); raise; END Get_po_user_msg_attribute; /* Bug# 2616433: kagarwal ** Desc: Added new procedure to set doc type display according to the ** default language of approver or preparer. */ procedure GetDisplayValue(itemtype in varchar2, itemkey in varchar2, username in varchar2, doctype in varchar2, docsubtype in varchar2) IS l_progress VARCHAR2(400) := '000'; l_doc_type varchar2(25); l_doc_subtype varchar2(25); l_doc_disp varchar2(240); l_ga_flag varchar2(1) := null; l_display_name varchar2(240); l_email_address varchar2(240); l_notification_preference varchar2(240); l_language varchar2(240); l_territory varchar2(240); l_msg_text varchar2(2000) := NULL; -- Bug 3430545 cursor c_lookup_value_user(p_doc_type varchar2, p_doc_subtype varchar2, p_language varchar2) is select type_name from po_document_types_tl tl, FND_LANGUAGES fl where fl.nls_language = p_language and tl.LANGUAGE = fl.language_code and tl.document_type_code = p_doc_type and tl.document_subtype = p_doc_subtype; cursor c_lookup_value_doc(p_doc_type varchar2, p_doc_subtype varchar2) is select type_name from po_document_types where document_type_code = p_doc_type and document_subtype = p_doc_subtype; BEGIN l_progress := 'PO_WF_PO_NOTIFICATION.GetDisplayValue: 001, user name: ' || username; /* DEBUG */ PO_WF_DEBUG_PKG.insert_debug(itemtype, itemkey, l_progress); if ((doctype is NULL) or (docsubtype is null)) then l_doc_type := PO_WF_UTIL_PKG.GetItemAttrText(itemtype => itemtype, itemkey => itemkey, aname => 'DOCUMENT_TYPE'); l_doc_subtype := PO_WF_UTIL_PKG.GetItemAttrText(itemtype => itemtype, itemkey => itemkey, aname => 'DOCUMENT_SUBTYPE'); else l_doc_type := doctype; l_doc_subtype := docsubtype; end if; IF l_doc_type = 'PA' AND l_doc_subtype = 'BLANKET' THEN l_ga_flag := PO_WF_UTIL_PKG.GetItemAttrText(itemtype => itemtype, itemkey => itemkey, aname => 'GLOBAL_AGREEMENT_FLAG'); END IF; /* Bug 3430545: Modified the code to get the translated values for the wf notification attribute 'REQUIRES_APPROVAL_MSG' and 'PO_GA_TYPE'. Deleted the previous code and revamped it. */ IF username is NULL THEN l_progress := 'PO_WF_PO_NOTIFICATION.GetDisplayValue: 050'; /* DEBUG */ PO_WF_DEBUG_PKG.insert_debug(itemtype, itemkey, l_progress); IF l_ga_flag = 'Y' THEN l_doc_disp := FND_MESSAGE.GET_STRING('PO', 'PO_GA_TYPE'); ELSE OPEN c_lookup_value_doc(l_doc_type, l_doc_subtype); FETCH c_lookup_value_doc into l_doc_disp; CLOSE c_lookup_value_doc; END IF; /* l_ga_flag = 'Y' */ ELSE l_progress := 'PO_WF_PO_NOTIFICATION.GetDisplayValue: 060'; /* DEBUG */ PO_WF_DEBUG_PKG.insert_debug(itemtype, itemkey, l_progress); WF_DIRECTORY.GETROLEINFO(username, l_display_name, l_email_address, l_notification_preference, l_language, l_territory); l_progress := 'PO_WF_PO_NOTIFICATION.GetDisplayValue: 080, language: ' || l_language; /* DEBUG */ PO_WF_DEBUG_PKG.insert_debug(itemtype, itemkey, l_progress); IF l_ga_flag = 'Y' THEN BEGIN select message_text into l_doc_disp from fnd_new_messages fm, fnd_languages fl where fm.message_name = 'PO_GA_TYPE' and fm.language_code = fl.language_code and fl.nls_language = l_language and fm.application_id = 201; --<BUG 3712124> Include application_id to better use PK index EXCEPTION WHEN OTHERS THEN l_doc_disp := FND_MESSAGE.GET_STRING('PO', 'PO_GA_TYPE'); END; ELSE OPEN c_lookup_value_user(l_doc_type, l_doc_subtype, l_language); FETCH c_lookup_value_user into l_doc_disp; CLOSE c_lookup_value_user; END IF; /* l_ga_flag = 'Y' */ END IF; /* if username is null */ l_progress := 'PO_WF_PO_NOTIFICATION.GetDisplayValue: 100, type disp: ' || l_doc_disp; /* DEBUG */ PO_WF_DEBUG_PKG.insert_debug(itemtype, itemkey, l_progress); PO_WF_UTIL_PKG.SetItemAttrText(itemtype => itemtype, itemkey => itemkey, aname => 'DOCUMENT_TYPE_DISP', avalue => l_doc_disp); BEGIN select message_text into l_msg_text from fnd_new_messages fm, fnd_languages fl where fm.message_name = 'PO_WF_NOTIF_REQUIRES_APPROVAL' and fm.language_code = fl.language_code and fl.nls_language = l_language and fm.application_id = 201; --<BUG 3712124> Include application_id to better use PK index EXCEPTION WHEN OTHERS THEN l_msg_text := PO_WF_UTIL_PKG.GetItemAttrText(itemtype => itemtype, itemkey => itemkey, aname => 'REQUIRES_APPROVAL_MSG'); END; PO_WF_UTIL_PKG.SetItemAttrText(itemtype => itemtype, itemkey => itemkey, aname => 'REQUIRES_APPROVAL_MSG', avalue => l_msg_text); EXCEPTION WHEN OTHERS THEN l_progress := 'PO_WF_PO_NOTIFICATION.GetDisplayValue: sql err: ' || sqlerrm; /* DEBUG */ PO_WF_DEBUG_PKG.insert_debug(itemtype, itemkey, l_progress); IF (c_lookup_value_user%ISOPEN) THEN CLOSE c_lookup_value_user; END IF; IF (c_lookup_value_doc%ISOPEN) THEN CLOSE c_lookup_value_doc; END IF; END GetDisplayValue; ------------------------------------------------------------------<BUG 3607009> ------------------------------------------------------------------------------- --Start of Comments --Name: is_open_document_allowed --Pre-reqs: -- None. --Modifies: -- None --Locks: -- None. --Function: -- Determines if the Open Document icon should be shown in the -- PO Approval Notification. The Open Document should not be shown if... -- (1) the document is in 'Pre-Approved' state and -- (2) document signature is required. --Parameters: --IN: --p_itemtype -- Standard parameter to be used in a workflow procedure --p_itemkey -- Standard parameter to be used in a workflow procedure --p_notification_type -- Specifies whether this notification is for the Preparer/Submitter -- or an Approver/Reviewer -- The value is derived from the WF Function attribute NTF_USER_ROLE -- in the GET_<>_NOTIFICATION_ATTRIBUTE functions in POAPPRV workflow -- Added for bug 3668188 --Returns: --resultout -- A BOOLEAN TRUE if the Open Document icon should be shown, FALSE otherwise. --Testing: -- N/A --End of Comments ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- FUNCTION is_open_document_allowed(p_itemtype IN VARCHAR2, p_itemkey IN VARCHAR2, p_notification_type IN VARCHAR2 --bug 3668188 ) RETURN BOOLEAN IS l_api_name VARCHAR2(30) := 'is_open_document_allowed'; l_log_head VARCHAR2(100) := g_pkg_name || '.' || l_api_name; l_progress VARCHAR2(3); l_authorization_status PO_HEADERS_ALL.authorization_status%TYPE; l_result BOOLEAN := TRUE; BEGIN l_progress := '000'; PO_WF_DEBUG_PKG.insert_debug(p_itemtype, p_itemkey, l_log_head || ':' || l_progress || 'Notification Type = ' || p_notification_type); -- Get the Authorization Status (e.g. 'PRE-APPROVED','APPROVED', -- 'INCOMPLETE', etc.) of the document. -- l_authorization_status := wf_engine.GetItemAttrText(itemtype => p_itemtype, itemkey => p_itemkey, aname => 'AUTHORIZATION_STATUS'); l_progress := '010'; PO_WF_DEBUG_PKG.insert_debug(p_itemtype, p_itemkey, l_log_head || ':' || l_progress || ' Authorization Status = ' || l_authorization_status); -- bug 3668188: changed the Open Doc allowed logic. -- If document is ('Pre-Approved' or 'In Process') and the -- notification is going back to the Submitter, then that -- user should not be able to open the document for edit. -- IF (l_authorization_status IN ('PRE-APPROVED', 'IN PROCESS') AND nvl(p_notification_type, 'SUBMITTER') = 'SUBMITTER') THEN l_progress := '020'; PO_WF_DEBUG_PKG.insert_debug(p_itemtype, p_itemkey, l_log_head || ':' || l_progress || ':FALSE'); l_result := FALSE; END IF; l_progress := '030'; PO_WF_DEBUG_PKG.insert_debug(p_itemtype, p_itemkey, l_log_head || ':' || l_progress || ':TRUE'); return(l_result); EXCEPTION WHEN OTHERS THEN PO_WF_DEBUG_PKG.insert_debug(p_itemtype, p_itemkey, l_log_head || ':' || SQLERRM); RAISE; END is_open_document_allowed; END PO_WF_PO_NOTIFICATION; /
来自:http://www.itpub.net/thread-1200447-1-19.html