The Cycle Of Purchasing Order(PO) to Account Payable(AP) to Fixed Assets(FA)

The cycle of Blanket PO -> PO -> AP Invoice -> Asset.

 This employee will be used as Buyer. Check his approval rights for approving purchase document.





1. Create BPA -> Approve it



2. Create Requisition-> Approve it

3. Autocreate PO -> Approve

4. Receive the PO (not mandatory)

5. Create Invoice -> Match it to PO -> Validate it -> Account it



  1. Make Payment (not mandatory)

  2.  
  3. Convert invoice into asset – Run ‘Mass Additions Create’

    select * from fa_mass_additions
    where book_type_code = <BOOK>
    and queue_name = 'NEW' and invoice_number like 'TRG%';




Submit ‘Post Mass Additions’ . This will create assets




Script for to Find Oracle APIs

Following script and get all the packages related to API in Oracle applications, from which you can select APIs that pertain to AP. You can change the name like to PA or AR and can check for different modules

SELECT   SUBSTR (a.owner, 1, 20), SUBSTR (a.NAME, 1, 30),
         SUBSTR (a.TYPE, 1, 20), SUBSTR (u.status, 1, 10) stat,
         u.last_ddl_time, SUBSTR (text, 1, 80) description
    FROM dba_source a, dba_objects u
   WHERE 2 = 2 AND u.object_name = a.NAME
--and a.text like ‘%Header%’
         AND a.TYPE = u.object_type
--and a.name like ‘PA_%API%’
ORDER BY a.owner, a.NAME;



Oracle EBS R12 Purchasing, Inventory, Order Management Queries

To Find Duplicate Item Category Code
SELECT category_set_name, category_concat_segments, COUNT (*)
FROM mtl_category_set_valid_cats_v
WHERE (category_set_id = 1)
GROUP BY category_set_name, category_concat_segments
HAVING COUNT (*) > 1
ORDER BY category_concat_segments
Get Number Of canceled requisition
SELECT a.AUTHORIZATION_STATUS,(a.ORG_ID),(SELECT distinct hr.per_all_people_f.first_name|| ‘ ‘|| hr.per_all_people_f.middle_names|| ‘ ‘|| hr.per_all_people_f.last_name “Employee Name”
FROM hr.per_all_people_f
where hr.per_all_people_f.PERSON_ID in
(select employee_id from fnd_user fu where fu.user_id = a.CREATED_BY)) CREATED_BY,count(SEGMENT1 )
FROM
po_requisition_headers_all a
WHERE
a.creation_date BETWEEN TO_DATE(’01/01/2007′, ‘DD/MM/YYYY’)
and TO_DATE(’30/05/2007′, ‘DD/MM/YYYY’)
and a.AUTHORIZATION_STATUS = ‘CANCELLED’
group by a.AUTHORIZATION_STATUS,a.ORG_ID,a.CREATED_BY
Number of line processed in Order Management
SELECT COUNT (line_id) “Order Line Processed”
FROM oe_order_lines_all
WHERE creation_date BETWEEN TO_DATE (:Fdate, ‘DD/MM/YYYY’)
AND TO_DATE (:tdate, ‘DD/MM/YYYY’)
AND flow_status_code = ‘CLOSED’;
To Check Item Catogry For Inventory master (No Of Segments May Varry)
SELECT ood.organization_name,
segment1|| ‘-’|| segment2|| ‘-’|| segment3 catgory
FROM org_organization_definitions ood,
mtl_categories_vl mcv,
mtl_category_sets mcs
WHERE mcs.structure_id = mcv.structure_id
ORDER BY ood.organization_name
Check Locators for inventory Inventory Org Wise(Number of segment may varry)
SELECT mil.segment1 loc_seg1, mil.segment11 loc_seg11, mil.segment2 loc_seg2,
mil.segment3 loc_seg3, mil.segment4 loc_seg4, mil.segment5 loc_seg5,
mil.segment6 loc_seg6,ood.ORGANIZATION_NAME,mil.SUBINVENTORY_CODE
FROM mtl_item_locations mil,org_organization_definitions ood
where mil.ORGANIZATION_ID = ood.ORGANIZATION_ID
Display All Subinventories Setup
select msi.secondary_inventory_name, MSI.SECONDARY_INVENTORY_NAME “Subinventory”, MSI.DESCRIPTION “Description”,
MSI.DISABLE_DATE “Disable Date”, msi.PICKING_ORDER “Picking Order”,
gcc1.concatenated_segments “Material Account”,
gcc2.concatenated_segments “Material Overhead Account”,
gcc3.concatenated_segments “Resource Account”,
gcc4.concatenated_segments “Overhead Account”,
gcc5.concatenated_segments “Outside Processing Account”,
gcc6.concatenated_segments “Expense Account”,
gcc7.concatenated_segments “Encumbrance Account”,
msi.material_overhead_account,
msi.resource_account,
msi.overhead_account,
msi.outside_processing_account,
msi.expense_account,
msi.encumbrance_account
from mtl_secondary_inventories msi,
gl_code_combinations_kfv gcc1,
gl_code_combinations_kfv gcc2,
gl_code_combinations_kfv gcc3,
gl_code_combinations_kfv gcc4,
gl_code_combinations_kfv gcc5,
gl_code_combinations_kfv gcc6,
gl_code_combinations_kfv gcc7
where msi.material_account = gcc1.CODE_COMBINATION_ID(+)
and msi.material_overhead_account = gcc2.CODE_COMBINATION_ID(+)
and msi.resource_account = gcc3.CODE_COMBINATION_ID(+)
and msi.overhead_account = gcc4.CODE_COMBINATION_ID(+)
and msi.outside_processing_account = gcc5.CODE_COMBINATION_ID(+)
and msi.expense_account = gcc6.CODE_COMBINATION_ID(+)
and msi.encumbrance_account = gcc7.CODE_COMBINATION_ID(+)
order by msi.secondary_inventory_name
To Select Unit Of measure exist in ebusiness suite
select uom_code,unit_of_measure
from mtl_units_of_measure
Query to find out Customer Master Information. Customer Name, Account Number, Adress etc.
select p.PARTY_NAME,ca.ACCOUNT_NUMBER,loc.address1,loc.address2,loc.address3,loc.city,loc.postal_code,
loc.country,ca.CUST_ACCOUNT_ID
from apps.ra_customer_trx_all I,
apps.hz_cust_accounts CA,
apps.hz_parties P,
apps.hz_locations Loc,
apps.hz_cust_site_uses_all CSU,
apps.hz_cust_acct_sites_all CAS,
apps.hz_party_sites PS
where I.COMPLETE_FLAG =’Y’
and I.bill_TO_CUSTOMER_ID= CA.CUST_ACCOUNT_ID
and ca.PARTY_ID=p.PARTY_ID
and I.bill_to_site_use_id=csu.site_use_id
and csu.CUST_ACCT_SITE_ID=cas.CUST_ACCT_SITE_ID
and cas.PARTY_SITE_ID=ps.party_site_id
and ps.location_id=loc.LOCATION_ID
Query to find on Hand Quantity
select sum(transaction_quantity) from MTL_ONHAND_QUANTITIES
where inventory_item_id=9
and organization_id=188
Qunatity on order, Expected Deliver
select sum(ordered_quantity),a.SCHEDULE_SHIP_DATE
from oe_order_lines_all a
where inventory_item_id=10
and ship_from_org_id=188
group by a.SCHEDULE_SHIP_DATE
Query to find Item Code, Item Description Oracle Item Master Query
select item, description from mtl_system_items_b
where inventory_item_id=&your_item
and organization_id=&organization_id) item
Query to Find out On Hand Quantity of specific Item Oracle inventory
select sum(transaction_quantity) from mtl_onhand_quantity_details
where inventory_item_id=&your_item
and organization_id=&organization_id
Qty On Order,
Expected deivery date(select sum(ordered_quantity),
scheduled_ship_date from oe_order_lines_all
where inventory_item_id=&your_item
and ship_from_org_id=&organization_id
group by scheduled_ship_date) order_info
–Total Received Qty
select sum(transaction_quantity) from mtl_material_transactions
inventory_item_id=&your_item
and organization_id=&organization_id
and transaction_quantity>0)
Total received Qty in 9 months
select sum(transaction_quantity) from mtl_material_transactions
inventory_item_id=&your_item
and organization_id=&organization_id
and transaction_quantity>0
and transaction_date between trunc(sysdate) and trunc(sysdate-270))
Total issued quantity in 9 months
select sum(transaction_quantity) from mtl_material_transactions
inventory_item_id=&your_item
and organization_id=&organization_id
and transaction_quantity<0 and transaction_date between trunc(sysdate) and trunc(sysdate-270)) tot_iss_qty_9mths, –Average monthly consumption
(select sum(transaction_quantity)/30 from mtl_material_transactions
inventory_item_id=&your_item
and organization_id=&organization_id
and transaction_quantity<0) ;
Display all categories that the Item Belongs
SELECTunique micv.CATEGORY_SET_NAME “Category Set”,
micv.CATEGORY_SET_ID “Category Set ID”,
decode( micv.CONTROL_LEVEL,
1, ‘Master’,
2, ‘Org’,
‘Other’) “Control Level”,
micv.CATEGORY_ID “Category ID”,
micv.CATEGORY_CONCAT_SEGS “Category”
FROM
MTL_ITEM_CATEGORIES_V micv
Another Query to Get Onhand Qty With Oranization ID, Item Code, Quantity
SELECT organization_id,
(SELECT ( msib.segment1|| ‘-’|| msib.segment2|| ‘-’|| msib.segment3|| ‘-’|| msib.segment4)
FROM mtl_system_items_b msib
WHERE msib.inventory_item_id = moq.inventory_item_id
AND msib.organization_id = moq.organization_id) “Item Code”,
(SELECT description
FROM mtl_system_items_b msib
WHERE msib.inventory_item_id =
moq.inventory_item_id
AND msib.organization_id = moq.organization_id)
“item Description”,
SUM (moq.transaction_quantity) onhandqty
FROM mtl_onhand_quantities moq
GROUP BY moq.organization_id, (moq.inventory_item_id)



Email From Oracle PL/SQL (UTL_SMTP)

The UTL_SMTP package was introduced in Oracle 8i and can be used to send emails from PL/SQL.
Simple Emails
In its simplest form a single string or variable can be sent as the message body using the following procedure. In this case we have not included any header information or subject line in the message, so it is not very useful, but it is small.
CREATE OR REPLACE PROCEDURE send_mail (p_to IN VARCHAR2,
p_from IN VARCHAR2,
p_message IN VARCHAR2,
p_smtp_host IN VARCHAR2,
p_smtp_port IN NUMBER DEFAULT 25)
AS
l_mail_conn UTL_SMTP.connection;
BEGIN
l_mail_conn := UTL_SMTP.open_connection(p_smtp_host, p_smtp_port);
UTL_SMTP.helo(l_mail_conn, p_smtp_host);
UTL_SMTP.mail(l_mail_conn, p_from);
UTL_SMTP.rcpt(l_mail_conn, p_to);
UTL_SMTP.data(l_mail_conn, p_message || UTL_TCP.crlf || UTL_TCP.crlf);
UTL_SMTP.quit(l_mail_conn);
END;
/

The code below shows how the procedure is called.
BEGIN
send_mail(p_to => ‘me@mycompany.com’,
p_from => ‘admin@mycompany.com’,
p_message => ‘This is a test message.’,
p_smtp_host => ‘smtp.mycompany.com’);
END;
/

Multi-Line Emails
Multi-line messages can be written by expanding the UTL_SMTP.DATA command using the UTL_SMTP.WRITE_DATA command as follows. This is a better method to use as the total message size is no longer constrained by the 32K limit on a VARCHAR2 variable. In the following example the header information has been included in the message also.
CREATE OR REPLACE PROCEDURE send_mail (p_to IN VARCHAR2,
p_from IN VARCHAR2,
p_subject IN VARCHAR2,
p_message IN VARCHAR2,
p_smtp_host IN VARCHAR2,
p_smtp_port IN NUMBER DEFAULT 25)
AS
l_mail_conn UTL_SMTP.connection;
BEGIN
l_mail_conn := UTL_SMTP.open_connection(p_smtp_host, p_smtp_port);
UTL_SMTP.helo(l_mail_conn, p_smtp_host);
UTL_SMTP.mail(l_mail_conn, p_from);
UTL_SMTP.rcpt(l_mail_conn, p_to);
UTL_SMTP.open_data(l_mail_conn);
UTL_SMTP.write_data(l_mail_conn, ‘Date: ‘ || TO_CHAR(SYSDATE, ‘DD-MON-YYYY HH24:MI:SS’) || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘To: ‘ || p_to || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘From: ‘ || p_from || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘Subject: ‘ || p_subject || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘Reply-To: ‘ || p_from || UTL_TCP.crlf || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, p_message || UTL_TCP.crlf || UTL_TCP.crlf);
UTL_SMTP.close_data(l_mail_conn);
UTL_SMTP.quit(l_mail_conn);
END;
/
The code below shows how the procedure is called.
BEGIN
send_mail(p_to => ‘me@mycompany.com’,
p_from => ‘admin@mycompany.com’,
p_subject => ‘Test Message’,
p_message => ‘This is a test message.’,
p_smtp_host => ‘smtp.mycompany.com’);
END;
/
HTML Emails
The following procedure builds on the previous version, allowing it include plain text and/or HTML versions of the email. The format of the message is explained here.

CREATE OR REPLACE PROCEDURE send_mail (p_to IN VARCHAR2,
p_from IN VARCHAR2,
p_subject IN VARCHAR2,
p_text_msg IN VARCHAR2 DEFAULT NULL,
p_html_msg IN VARCHAR2 DEFAULT NULL,
p_smtp_host IN VARCHAR2,
p_smtp_port IN NUMBER DEFAULT 25)
AS
l_mail_conn UTL_SMTP.connection;
l_boundary VARCHAR2(50) := ‘—-=*#abc1234321cba#*=’;
BEGIN
l_mail_conn := UTL_SMTP.open_connection(p_smtp_host, p_smtp_port);
UTL_SMTP.helo(l_mail_conn, p_smtp_host);
UTL_SMTP.mail(l_mail_conn, p_from);
UTL_SMTP.rcpt(l_mail_conn, p_to);
UTL_SMTP.open_data(l_mail_conn);
UTL_SMTP.write_data(l_mail_conn, ‘Date: ‘ || TO_CHAR(SYSDATE, ‘DD-MON-YYYY HH24:MI:SS’) || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘To: ‘ || p_to || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘From: ‘ || p_from || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘Subject: ‘ || p_subject || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘Reply-To: ‘ || p_from || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘MIME-Version: 1.0′ || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘Content-Type: multipart/alternative; boundary=”‘ || l_boundary || ‘”‘ || UTL_TCP.crlf || UTL_TCP.crlf);
IF p_text_msg IS NOT NULL THEN
UTL_SMTP.write_data(l_mail_conn, ‘–’ || l_boundary || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘Content-Type: text/plain; charset=”iso-8859-1″‘ || UTL_TCP.crlf || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, p_text_msg);
UTL_SMTP.write_data(l_mail_conn, UTL_TCP.crlf || UTL_TCP.crlf);
END IF;

IF p_html_msg IS NOT NULL THEN
UTL_SMTP.write_data(l_mail_conn, ‘–’ || l_boundary || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘Content-Type: text/html; charset=”iso-8859-1″‘ || UTL_TCP.crlf || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, p_html_msg);
UTL_SMTP.write_data(l_mail_conn, UTL_TCP.crlf || UTL_TCP.crlf);
END IF;
UTL_SMTP.write_data(l_mail_conn, ‘–’ || l_boundary || ‘–’ || UTL_TCP.crlf);
UTL_SMTP.close_data(l_mail_conn);
UTL_SMTP.quit(l_mail_conn);
END;
/

The code below shows how the procedure is called.
DECLARE
l_html VARCHAR2(32767);
BEGIN
l_html := ‘<html>
<head>
<title>Test HTML message</title>
</head>
<body>
<p>This is a <b>HTML</b> <i>version</i> of the test message.</p>
<p><img src=”http://www.oracleport.com/images/site_logo.gif” alt=”Site Logo” />
</body>
</html>’;
send_mail(p_to => ‘me@mycompany.com’,
p_from => ‘admin@mycompany.com’,
p_subject => ‘Test Message’,
p_text_msg => ‘This is a test message.’,
p_html_msg => l_html,
p_smtp_host => ‘smtp.mycompany.com’);
END;
/

Emails with Attachments
Sending an email with an attachment is similar to the previous example as the message and the attachment must be separated by a boundary and identified by a name and mime type.

BLOB Attachment
Attaching a BLOB requires the binary data to be encoded and converted to text so it can be sent using SMTP.

CREATE OR REPLACE PROCEDURE send_mail (p_to IN VARCHAR2,
p_from IN VARCHAR2,
p_subject IN VARCHAR2,
p_text_msg IN VARCHAR2 DEFAULT NULL,
p_attach_name IN VARCHAR2 DEFAULT NULL,
p_attach_mime IN VARCHAR2 DEFAULT NULL,
p_attach_blob IN BLOB DEFAULT NULL,
p_smtp_host IN VARCHAR2,
p_smtp_port IN NUMBER DEFAULT 25)
AS
l_mail_conn UTL_SMTP.connection;
l_boundary VARCHAR2(50) := ‘—-=*#abc1234321cba#*=’;
l_step PLS_INTEGER := 24573;
BEGIN
l_mail_conn := UTL_SMTP.open_connection(p_smtp_host, p_smtp_port);
UTL_SMTP.helo(l_mail_conn, p_smtp_host);
UTL_SMTP.mail(l_mail_conn, p_from);
UTL_SMTP.rcpt(l_mail_conn, p_to);
UTL_SMTP.open_data(l_mail_conn);
UTL_SMTP.write_data(l_mail_conn, ‘Date: ‘ || TO_CHAR(SYSDATE, ‘DD-MON-YYYY HH24:MI:SS’) || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘To: ‘ || p_to || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘From: ‘ || p_from || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘Subject: ‘ || p_subject || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘Reply-To: ‘ || p_from || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘MIME-Version: 1.0′ || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘Content-Type: multipart/mixed; boundary=”‘ || l_boundary || ‘”‘ || UTL_TCP.crlf || UTL_TCP.crlf);
IF p_text_msg IS NOT NULL THEN
UTL_SMTP.write_data(l_mail_conn, ‘–’ || l_boundary || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘Content-Type: text/plain; charset=”iso-8859-1″‘ || UTL_TCP.crlf || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, p_text_msg);
UTL_SMTP.write_data(l_mail_conn, UTL_TCP.crlf || UTL_TCP.crlf);
END IF;

IF p_attach_name IS NOT NULL THEN
UTL_SMTP.write_data(l_mail_conn, ‘–’ || l_boundary || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘Content-Type: ‘ || p_attach_mime || ‘; name=”‘ || p_attach_name || ‘”‘ || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘Content-Transfer-Encoding: base64′ || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘Content-Disposition: attachment; filename=”‘ || p_attach_name || ‘”‘ || UTL_TCP.crlf || UTL_TCP.crlf);
FOR i IN 0 .. TRUNC((DBMS_LOB.getlength(p_attach_blob) – 1 )/l_step) LOOP
UTL_SMTP.write_data(l_mail_conn, UTL_RAW.cast_to_varchar2(UTL_ENCODE.base64_encode(DBMS_LOB.substr(p_attach_blob, l_step, i * l_step + 1))));
END LOOP;
UTL_SMTP.write_data(l_mail_conn, UTL_TCP.crlf || UTL_TCP.crlf);
END IF;

 UTL_SMTP.write_data(l_mail_conn, ‘–’ || l_boundary || ‘–’ || UTL_TCP.crlf);
UTL_SMTP.close_data(l_mail_conn);
UTL_SMTP.quit(l_mail_conn);
END;
/

The code below shows how the procedure is called.
DECLARE
l_name images.name%TYPE := ‘site_logo.gif’;
l_blob images.image%TYPE;
BEGIN
SELECT image
INTO l_blob
FROM images
WHERE name = l_name;
send_mail(p_to => ‘me@mycompany.com’,
p_from => ‘admin@mycompany.com’,
p_subject => ‘Test Message’,
p_text_msg => ‘This is a test message.’,
p_attach_name => ‘site_logo.gif’,
p_attach_mime => ‘image/gif’,
p_attach_blob => l_blob,
p_smtp_host => ‘smtp.mycompany.com’);
END;
/

CLOB Attachment

Attaching a CLOB is similar to attaching a BLOB, but we don’t have to worry about encoding the data because it is already plain text.

CREATE OR REPLACE PROCEDURE send_mail (p_to IN VARCHAR2,
p_from IN VARCHAR2,
p_subject IN VARCHAR2,
p_text_msg IN VARCHAR2 DEFAULT NULL,
p_attach_name IN VARCHAR2 DEFAULT NULL,
p_attach_mime IN VARCHAR2 DEFAULT NULL,
p_attach_clob IN CLOB DEFAULT NULL,
p_smtp_host IN VARCHAR2,
p_smtp_port IN NUMBER DEFAULT 25)

AS
l_mail_conn UTL_SMTP.connection;
l_boundary VARCHAR2(50) := ‘—-=*#abc1234321cba#*=’;
l_step PLS_INTEGER := 24573;

BEGIN
l_mail_conn := UTL_SMTP.open_connection(p_smtp_host, p_smtp_port);
UTL_SMTP.helo(l_mail_conn, p_smtp_host);
UTL_SMTP.mail(l_mail_conn, p_from);
UTL_SMTP.rcpt(l_mail_conn, p_to);

 UTL_SMTP.open_data(l_mail_conn);
UTL_SMTP.write_data(l_mail_conn, ‘Date: ‘ || TO_CHAR(SYSDATE, ‘DD-MON-YYYY HH24:MI:SS’) || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘To: ‘ || p_to || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘From: ‘ || p_from || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘Subject: ‘ || p_subject || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘Reply-To: ‘ || p_from || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘MIME-Version: 1.0′ || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘Content-Type: multipart/mixed; boundary=”‘ || l_boundary || ‘”‘ || UTL_TCP.crlf || UTL_TCP.crlf);
IF p_text_msg IS NOT NULL THEN
UTL_SMTP.write_data(l_mail_conn, ‘–’ || l_boundary || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘Content-Type: text/plain; charset=”iso-8859-1″‘ || UTL_TCP.crlf || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, p_text_msg);
UTL_SMTP.write_data(l_mail_conn, UTL_TCP.crlf || UTL_TCP.crlf);
END IF;

 IF p_attach_name IS NOT NULL THEN
UTL_SMTP.write_data(l_mail_conn, ‘–’ || l_boundary || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘Content-Type: ‘ || p_attach_mime || ‘; name=”‘ || p_attach_name || ‘”‘ || UTL_TCP.crlf);
UTL_SMTP.write_data(l_mail_conn, ‘Content-Disposition: attachment; filename=”‘ || p_attach_name || ‘”‘ || UTL_TCP.crlf || UTL_TCP.crlf);
FOR i IN 0 .. TRUNC((DBMS_LOB.getlength(p_attach_clob) – 1 )/l_step) LOOP
UTL_SMTP.write_data(l_mail_conn, DBMS_LOB.substr(p_attach_clob, l_step, i * l_step + 1));
END LOOP;
UTL_SMTP.write_data(l_mail_conn, UTL_TCP.crlf || UTL_TCP.crlf);
END IF;
UTL_SMTP.write_data(l_mail_conn, ‘–’ || l_boundary || ‘–’ || UTL_TCP.crlf);
UTL_SMTP.close_data(l_mail_conn);
UTL_SMTP.quit(l_mail_conn);
END;
/

The code below shows how the procedure is called.

DECLARE
l_clob CLOB := ‘This is a very small CLOB!’;
BEGIN
send_mail(p_to => ‘me@mycompany.com’,
p_from => ‘admin@mycompany.com’,
p_subject => ‘Test Message’,
p_text_msg => ‘This is a test message.’,
p_attach_name => ‘test.txt’,
p_attach_mime => ‘text/plain’,
p_attach_clob => l_clob,
p_smtp_host => ‘smtp.mycompany.com’);
END;
/

Miscellaneous
For emails with multiple recipients, simply call the RCPT procedure once for each separate email address.
The UTL_SMTP package requires Jserver which can be installed by running the following scripts as SYS.
SQL> @$ORACLE_HOME/javavm/install/initjvm.sql
SQL> @$ORACLE_HOME/rdbms/admin/initplsj.sql


How to find all cancel Requisitions

SELECT prha . *   FROM po_Requisition_headers_all prha , po_action_history pah   WHERE      1 = 1        AND pah . object_id ...