Thursday, June 30, 2011

XML Bursting

Background / Business Requirement for Bursting
In Oracle Purchasing we have PO Print Report which can be used to print new or selected Purchase order. Organizations usually schedule this program on a daily basis to print new purchase orders. If we want to integrate this Oracle Report to XML/BI Publisher to create eye candy layouts and email the PO automatically to the suppliers, the common issue we face is:-
How to split the XML file created by report ? This is because report will create a single XML file consisting of the all the PO selected and if we apply the template on this XML file , it will create a single PDF file consisting of all the PO’s , and we definitely don’t want purchase orders sent to a supplier which is not related to him .If we have to send PO to individual supplier there has to be a way to parse the XML file generated from the PO Print Report.After parsing the XML file we can break the XML into smaller chunks based on the PO Number and then email the PO to respective Suppliers.


Advantages of XMLP bursting

a. No Additional Coding, just need to create XML bursting File. ( Isn't it exciting , otherwise we would have to write java program to split the XML File and then use XMLP delivery manager API to send emails .
b. Process of Creating XML data Definition and Template remains AS – IS .

Prerequisitesa. Apply patch 5968876 if not already applied
b. Verify XMLP version is 5.6.3

Steps to Verify if XMLP is indeed 5.6.3
1. adident Header $OA_JAVA/oracle/apps/xdo/common/MetaInfo.class

Below matrix shows the the version you are and the patch to be applied to come to 5.6.3

Metainfo.class


Metainfo.class
XML Publisher
PatchReference
120.6XDO 5.6.3Patch 4440000
... for the Oracle E-Business Suite 11i
115.28XDO 5.6.3 Patch 5472959 Note 422508.1
115.27XDO 5.6.2 (core) Patch 5097966 Note 367394.1
115.26XDO 5.6.1Patch 4905678 Note 357308.1
115.24XDO 5.6.0 Patch 4561451Note 337999.1
115.22XDO 5.5.0 Patch 4206181 Note 316447.1
115.21XDO 5.0.1 (core) Patch 4236958
115.19XDO 5.0.0 Patch 3822219 Note 295036.1



c. Set Temporary Directory in the XML Publisher Administrator- > Administration- > General to a directory to which you have write permission .

d. After the Patch is applied we will see a new Bursting control file button in the XML Publisher Data Definition Page
To check this, please go to Responsibility "XML Publisher Administrator", and search for any existing report, and click on Update. While updating an existing data-definition, you should see the button Bursting Control File.
Now since we have finished setting up , now we will see how to implement Bursting . The major component in this is bursting control file


What is a bursting file ?

Its an XML file which tells bursting engine


a) How to split the XML File created ?

b) How to deliver the Documents ?


Lets see a sample bursting file and its components


a) <xapi:request select> tag tells busting engine , bursting should be done at the occurrence of which tag ?
b) <xapi:delivery > tag tells bursting engine , which delivery mechanism to be used and on what condition ?

Sample bursting file


<xapi:requestset xmlns:xapi="http://xmlns.oracle.com/oxp/xapi" type="bursting">
<xapi:request select="/xxx_HQ_XML_POXPRPOL/LIST_G_INIT_INFO/G_INIT_INFO/LIST_G_HEADERS/G_HEADERS">
<xapi:delivery>
<xapi:email id="123" server="xxxort" port="25" from=" xxp@xx.org.uk This e-mail address is being protected from spambots. You need JavaScript enabled to view it " reply-to=" xx@xx.org.uk This e-mail address is being protected from spambots. You need JavaScript enabled to view it ">
<xapi:message id="123" to="${CF_VENDOR_EMAIL}" attachment="true" subject=" Purchase Order No: ${POH_PO_NUM}">
Please review the attached PO ${POH_PO_NUM}
</xapi:message>
</xapi:email>
</xapi:delivery>
<xapi:document output-type="pdf" delivery="123">
<xapi:template type="rtf" location="/u0350/app/apps/UAT/xx/1.0/data/XXHPAPOPRINT.rtf">
</xapi:template>
</xapi:document>
</xapi:request>
</xapi:requestset>

Please Note : While doing testing please change the "to address" to your email address , else it will send the documents out to that email address .

Data Definition
Create the Data Definition and Template the normal way, where the Short name of the data definition is same as the short name of concurrent program to which you are integrating XMLP.While creating Data Definition Upload you bursting XML File . If there are any parsing issues in the XML file it will give error , please correct the format of the file and try to upload again .


Template File
Create the Template and Upload your Template file



Concurrent Program Registeration
In the Concurrent Program give the Output fomat as XML and the Concurrent Program Short name should be same as the data definition name .


After Report Trigger Changes
Now the Final Step , in the After report Trigger of your .RDf add the following code to call bursting program . This will lanuch the bursting program from your report , otherwise you will have to run the Bursting program ( which is a Java Concurrent Program ) manually .


Now you are all set to do the testing , run the report , please keep in mind to change "to email address" in the bursting control file to your email id while doing the testing . you will see the PO pdf coming to the email address given in the bursting control file.

Thursday, June 16, 2011

sending mail to the user by using UTL_FILE package

CREATE OR REPLACE PACKAGE BODY APPS.xx_create_acct
AS
PROCEDURE submit_request(
errbuf OUT VARCHAR2,
retcode OUT VARCHAR2,
param1 varchar2
param2 varchar2
)

IS
l_senderemail VARCHAR2 (2000) := 'xyz@erp.com';
l_request_id NUMBER;
errmsg VARCHAR2 (1000);
req_id NUMBER;
phase VARCHAR2 (200);
status VARCHAR2 (200);
dphase VARCHAR2 (200);
dstatus VARCHAR2 (200);
MESSAGE VARCHAR2 (200);
wait_stat BOOLEAN;
l_file_name VARCHAR2 (200);
l_file_path VARCHAR2 (2000);
crlf VARCHAR2 (4) := CHR (13) || CHR (10);
v_set_layout_option BOOLEAN;
dir_name varchar2(100);
/* CURSOR req_status
IS
SELECT SUBSTR (outfile_name, 55, 23) filename,
SUBSTR (outfile_name, 1, 64) outfilepath
FROM applsys.fnd_concurrent_requests
WHERE request_id = l_request_id
AND phase_code = 'C'
AND status_code = 'C';*/

directory_path VARCHAR2 (2000);
lv_subject VARCHAR2 (100);
lv_msg VARCHAR2 (700);
lv_msghdr VARCHAR2 (100);
lv_pdf_filename VARCHAR2 (200);
BEGIN

apps.fnd_global.apps_initialize
(user_id => apps.fnd_global.user_id,
resp_id =>apps.fnd_global.resp_id,
resp_appl_id => apps.fnd_global.resp_appl_id
);

l_request_id :=
apps.fnd_request.submit_request
( 'BOM',
'CSTCRACCRCV', --appl short name
NULL,
NULL,
FALSE,
param1,
param2
);
COMMIT;

IF (l_request_id <= 0)
THEN
errmsg := apps.fnd_message.get ();
ELSE
wait_stat :=
apps.fnd_concurrent.wait_for_request (l_request_id,
10,
360,
phase,
status,
dphase,
dstatus,
MESSAGE
);

IF dphase = 'COMPLETE'
THEN

dir_name :='XX_CREATE_ACCT_LOG';

l_file_name := 'l' || l_request_id || '.REQ';
lv_subject := NULL;
lv_msg := NULL;
lv_msghdr := NULL;
lv_pdf_filename := NULL;
lv_subject := 'testing mail :Request for Create Accounting not completed';

lv_msg :=
'Please find attachement here with the Status Of Create Accounting Reciving from cost management'
|| crlf;
lv_msghdr := 'Dear Sir' ;
lv_pdf_filename := l_file_name;
send_mail (l_senderemail,
'abc@erp.com',
lv_subject,
lv_msghdr,
lv_msg,
lv_pdf_filename,
'text/application',
dir_name
);

END IF;

END IF;

END submit_request;

PROCEDURE send_mail (
p_sender IN VARCHAR2,
p_recipient IN VARCHAR2,
p_subject IN VARCHAR2,
p_mailbodyhdr IN VARCHAR2,
p_mailbody IN VARCHAR2,
p_filename IN VARCHAR2,
p_filetype IN VARCHAR2,
dir_name in VARCHAR2
)
AS
v_msg VARCHAR2 (32000);
src_file BFILE;
i INTEGER := 1;
v_raw RAW (500);
v_length INTEGER := 0;
v_buffer_size INTEGER := 57;
v_mailconn UTL_SMTP.connection;
gc_crlf VARCHAR2 (4) := CHR (13)
|| CHR (10);
gc_lf VARCHAR2 (4) := CHR (10);
crlf VARCHAR2 (2) := CHR (13)
|| CHR (10);
gc_mailhost VARCHAR2 (255) := '172.16.11.2';
-- gc_maildomain VARCHAR2 (255) := 'pune.com';
msg VARCHAR2 (32767);
boundary CONSTANT VARCHAR2 (256)
:= '-----7D81B75CCC90D2974F7A1CBD';
first_boundary CONSTANT VARCHAR2 (256)
:= '--' || boundary || UTL_TCP.crlf;
last_boundary CONSTANT VARCHAR2 (256)
:= '--' || boundary || '--' || UTL_TCP.crlf;
-- A MIME type that denotes multi-part email (MIME) messages.
multipart_mime_type CONSTANT VARCHAR2 (256)
:= 'multipart/mixed; boundary="' || boundary || '"';
BEGIN
DBMS_OUTPUT.ENABLE (100000);
--fnd_file.put_line (fnd_file.output, '------------------------------------------------------' );
v_mailconn := UTL_SMTP.open_connection (gc_mailhost, 26);
UTL_SMTP.helo (v_mailconn, gc_mailhost);
UTL_SMTP.mail (v_mailconn, p_sender);
UTL_SMTP.rcpt (v_mailconn, p_recipient);
UTL_SMTP.open_data (v_mailconn);
msg :=
'Date: '
|| TO_CHAR (SYSDATE, 'Dy, DD Mon YYYY hh24:mi:ss')
|| crlf
|| 'From:xyz@erp.com '
-- || p_sender
|| crlf
|| 'Subject: '
|| p_subject
|| crlf
|| 'To: abc@erp.com'
-- || p_recipient
|| crlf
|| 'MIME-Version: 3.1'
|| crlf
|| -- Use MIME mail standard
'Content-Type: multipart/mixed;'
|| crlf
|| ' boundary="-----SECBOUND"'
|| crlf
|| crlf
|| '-------SECBOUND'
|| crlf
|| 'Content-Type: text/plain;'
|| crlf
|| 'Content-Transfer_Encoding: 7bit'
|| crlf
|| crlf
|| p_mailbodyhdr
|| crlf
|| crlf
|| p_mailbody
|| crlf
|| crlf
|| crlf
|| crlf
|| -- Message body
'Regards'
|| crlf
|| 'HR and Payroll Team'
|| crlf
|| crlf
|| ' Note- Please ignore the leave status and number of days.'
|| crlf
|| crlf
|| '-------SECBOUND'
|| crlf
|| 'Content-Type'
|| ': '
|| p_filetype
|| crlf
|| 'Content-Disposition: attachment; filename="'
-- || 'Create Accounting'
-- || '.REQ'
||p_filename -- p_filename
|| '"'
|| crlf
|| 'Content-Transfer-Encoding: base64'
|| crlf
|| crlf;

UTL_SMTP.write_data (v_mailconn, msg);
src_file := BFILENAME (dir_name, p_filename);
DBMS_LOB.fileopen (src_file, DBMS_LOB.file_readonly);
v_length := DBMS_LOB.getlength (src_file);

WHILE i < v_length
LOOP
DBMS_LOB.READ (src_file, v_buffer_size, i, v_raw);
UTL_SMTP.write_raw_data (v_mailconn,
UTL_ENCODE.base64_encode (v_raw)
);
UTL_SMTP.write_data (v_mailconn, UTL_TCP.crlf);
i := i + v_buffer_size;
END LOOP while_loop;

UTL_SMTP.write_data (v_mailconn, last_boundary);
UTL_SMTP.write_data (v_mailconn, UTL_TCP.crlf);
DBMS_LOB.fileclose (src_file);
UTL_SMTP.close_data (v_mailconn);
UTL_SMTP.quit (v_mailconn);
EXCEPTION
WHEN OTHERS
THEN
UTL_SMTP.quit (v_mailconn);
DBMS_OUTPUT.put_line (SQLCODE || SQLERRM);
-- FND_FILE.PUT_LINE (FND_FILE.LOG,'error while fetching values from CO_CODE'|| SQLERRM );
END send_mail;
END xx_create_acct;