Sunday, September 26, 2010

How to create a Daemon-Only Application Engine Program

A daemon program is an Application Engine program of daemon type that checks for an event.
§         When an event occurs, the daemon will trigger the process to handle the event.
§         Daemons allow processes to be driven based on events rather than a schedule.
§         Events can be internal or external to the PeopleSoft application database.

Example:
Applicaiton Engine program with following requirements can be configured as Daemon-only AE
program.
  •      Moniror a Temp Directory
  •      Look  for a file to process.
  •      if there is a file in the directory, process it.

To Accomplish this, first create an AE program to read and process the fiel. In the AE properties > 
Advanced tab, set the program type to Deamon Only.
Once the program is ready, tie it to a Daemon Group and activate the Daemon on  the server. After 
enabling the PSDAEMON, stop and start the process scheduler.

This configuration will trigger the AE Program, once the file has been placed in the TEMP Directory which 
is programmed in the AE program.

Application Engine program composition.


Application
Section
Step
Action
Application Engine Program
Callable block of logic.
Logical grouping of actions.
Lines of code.
Composed of one or more sections
Composed of one or more steps.
Specified by:
·  Market.
·  Effective date.
·  Effective status.
·  Platform.
Composed of one or more actions.
Smallest amount of work that can be committed.
Used to:
·  Retrieve or manipulate data.
·  Control program flow.
First section MAIN
12- character name for application
Executed only when called, except for MAIN.
Executed from top to bottom within the section.
Must be unique within step.
Executed in specific order.

Wednesday, September 22, 2010

Multiple Reports in SQR

Multiple Reports feature is very handful  when you need to stream the output to different reports based on some business conditions. DECLARE-REPORT and USE_REPORT are two commands used to accomplish this. Below example generates two reports based on the employee salary. each report will have a separate header.



declare-report rep1
   layout=layout1
end-declare

  declare-report rep2
    layout=layout2
  end-declare
 END-SETUP

 begin-heading 4 for-reports=rep1
  
    print 'Employee Listing Grade B' (1,1) center bold shade
    print '=' (+1,1,80) fill
    print 'EID' (3,1) bold
    print 'EName' (,10) bold
    print 'Salary' (,30) bold
 end-heading


 begin-heading 4 for-reports=rep2
    
    print 'Employee Listing Grade A' (1,1) center bold shade
    print '=' (+1,1,80) fill
    print 'EID' (3,1) bold
    print 'EName' (,10) bold
    print 'Salary' (,30) bold
 end-heading





BEGIN-PROGRAM
BEGIN-SELECT
NS_EID
NS_ENAME
NS_SALARY
    if &ns_salary <35000
      use-report rep1 
    else
      use-report rep2
    end-if
  
    print &NS_EID (+1,1)
    print &NS_ENAME (,10)
    print &NS_SALARY (,30)
FROM PS_NS_EMP_TBL
end-select
end-program


Monday, September 20, 2010

Hide a Row in a Grid or Scroll Area Using PeopleCode


Here I am taking standard address page as example.Address page has a gird with 2 rows, one of Address Type "Home" and the other with Address Type "Mailing". I would like to hide rows on the grid that have anything other than Address Type "Home": Now what I would like to accomplish is this: And now the code on how to go about doing this:
Local Rowset &Level1;
&Level1 = GetLevel0()(1).GetRowset(Scroll.PERSON_ADDRESS);
For &i = 1 To &Level1.ActiveRowCount
&AddrType = FetchValue(Scroll.PERSON_ADDRESS, &i, PERSON_ADDRESS.ADDRESS_TYPE);
If &AddrType <> "HOME" Then
&Level1(&i).Visible = False;
End-If;
End-For;

Tuesday, September 14, 2010

Can we use RemoteCall inside Component Interface ?


My answer is NO , I have a requirement to automate the cancellation of award in the Award Entry page (PeopleSoft Student Administration: Financial Aid). The approach was to make a Component Interface and run it thru App Engine as batch process. In the page there are 4 buttons and 2 of these buttons should be click to validate and post data in the database. I created a new custom methods in my CI and put the peoplecode behind the button so that I can just call these methods in my AppEngine, but I encountered an error while running my program. I learned that I can't use RemoteCall inside the CI method. So after several trial and error, I came up with the solution to separate the remotecall from other codes and put it on the AppEngine PeopleCode. The AppEngine/CI Peoplecode looks like these;


Function Validate()
commitwork();
RemoteCall(call validateCOBOL program.......);
End-Function;

Function Post()
commitwork();
RemoteCall(call postCOBOL program.......);
End-Function;


try 

&ci = &session.GetCompIntfc(CompIntfc.yourCI);
.
.
.
&ci.PreValidate(); /*my custom CI method contains code to validate before RemoteCall*/
Validate(); 
&ci.PostValidate(); /*my custom CI method contains code to validate after RemoteCall*/

&ci.PrePost(); /*my custom CI method contains code to post before RemoteCall*/
Post();
&ci.Posted(); /*my custom CI method contains code to post after RemoteCall*/


.
.
.
end-try;

Creating Outbound File from File Layout Using App Engine

Outbound processing, meaning creating files that will be read by other/external programs. Most of the times these files are enormous in size. We need to create a program that are efficient in processing large amount of data. Using App Engine and Filelayout together we can achieve this.

1. Create an App Engine that will process all the data.
2. Dump all processed data into staging tables.
3. Create a view out of those staging tables. The view structure will be similar to file layout segment. If you have a parent-child relationship on the file layout, the view key structure should be similar to those file layout.
4. Let say you have a level 1 parent-child relationship in your file layout;





If All(&FileDirectory) Then
&TST_FILE = GetFile(&FileDirAndName, "A", %FilePath_Absolute);
Else
&TST_FILE = GetFile(&FileName, "A", %FilePath_Relative);
End-If;


&TST_FILE.SetFileLayout(FileLayout.FILE_LAYOUT_NAME);
&RS_TST_FL = &TST_FILE.CreateRowset();
&REC_TST_FL_LVL0 = &RS_TST_FL(1).GetRecord(Record.SGMT_TST_LVL0);
&REC_TST_FL_LVL1 = &RS_TST_FL(1).GetRowset(Scroll.SGMT_TST_LVL1).GetRow(1).GetRecord(Record.SGMT_TST_LVL1);


/*These will be the view created from staging*/
&REC_TST_LVL0_VW = CreateRecord(Record.BN_TST_LVL0_VW);

/*Copy data from the view to file layout segment level 0*/
&REC_TST_LVL0_VW .CopyFieldsTo(&REC_TST_FL_LVL0);

/*Write data from file layout*/
&TST_FILE.WriteRecord(&REC_TST_FL_LVL0);
/*These will be the view created from staging*/
&REC_TST_LVL1_VW = CreateRecord(Record.BN_TST_LVL1_VW);
/*Copy data from the view to file layout segment level 1*/
&REC_TST_LVL1_VW .CopyFieldsTo(&REC_TST_FL_LVL1);
/*Write data from file layout*/
&TST_FILE.WriteRecord(&REC_TST_FL_LVL1);

Creating Word Document Using App Engine!

Now, who's up for some ice cream? Yes, you've heard me.. for me Word Document is like an ice cream at least compare to text (.txt) document. Did you know that you can create a formatted word document from PeopleSoft using App Engine/PeopleCode? Just like creating Excel Document (discuss in my previous post Creating MS EXCEL Using CreateObject in PeopleSoft) I used the CreateObject PeopleCode Function to create Word Document. Note: I only tested this code thru NT Server.

&oWORD = CreateObject("COM", "Word.Application");
ObjectSetProperty(&oWORD, "Visible", True);

&oWORD.Documents.Add();
&oPara1 = &oWORD.Selection;
&oPara1.Style = "Heading 1";            
&oPara1.TypeText("Hello World ");
&oPara1.Font.Bold = True;
&oPara1.TypeText("Bold ");
&oPara1.Font.Bold = False;
&oPara1.Font.Italic = True;
&oPara1.TypeText("Italic ");
&oPara1.Font.Italic = False;
&oPara1.Font.Underline = True;
&oPara1.TypeText("Underline ");
&oPara1.Font.Underline = False;
&oPara1.Font.Name = "Arial";
&oPara1.TypeText("Arial ");
&oPara1.Font.Name = "Times Roman";
&oPara1.Font.Size = "16";
&oPara1.TypeText("Times Roman ");
&oPara1.Font.Size = "12";
&oPara1.TypeText("Example ");
&oPara1.Start = "50";
&oPara1.End = "59";
&oPara1.Font.Name = "Tahoma";
&oWORD.ActiveDocument.SaveAs("C:\temp\Format.doc");

&oWORD.Quit();

Creating MS EXCEL Using CreateObject in PeopleSoft


Application Engine is great for batch processing, but it is not a reporting tool. Recently, our users requires every single AE to have a formatted output report, so my teammate came up with the solution that writes .txt file using writeline function. Its very simple, you just need to code it manually. Getting bored of the text file that comes out on my report, I look for some other ways to create a more decent output. Of course, XML Publisher would have been nice but I dont want to go thru that hassle creating a report definition, data source, etc. I browse thru PeopleBooks and found this PeopleCode function CreateObject! It has an example using Excel.Application, a few trial and error, and voala! I created an Excel Report! I only tested it on the NT Server though.

/*How to read data from one cell and writes to another*/
&oWorkApp = CreateObject("COM", "Excel.Application");
ObjectSetProperty(&oWorkApp, "Visible", True);
&oWorkBook = ObjectGetProperty(&oWorkApp, "Workbooks");
&oWorkBook.Open("C:\temp\TEST1.xls");
&oWorkSheet = &oWorkApp.Worksheets("Sheet1");
&oData = &oWorkSheet.Range("A1").Value;
&oWorkSheet.Range("A2").Value = &oData;
&oWorkApp.ActiveWorkbook.SaveAs("C:\temp\TestXLS.xls");
/*How to read data from one cell and writes to different sheet*/
&oWorkApp = CreateObject("COM", "Excel.Application");
ObjectSetProperty(&oWorkApp, "Visible", True);
&oWorkBook = ObjectGetProperty(&oWorkApp, "Workbooks");
&oWorkBook.Open("C:\temp\TEST1.xls");
&oWorkSheet = &oWorkApp.Worksheets("Sheet1");
&oData = &oWorkSheet.Range("A1").Value;
&oWorkSheet2 = &oWorkApp.Worksheets(2);
&oWorkSheet2.Range("A1").Value = &oData;
&oWorkApp.ActiveWorkbook.SaveAs("C:\temp\TestXLS.xls");

/*Add data to cells of the first worksheet in the new workbook*/
&oWorkApp = CreateObject("COM", "Excel.Application");
ObjectSetProperty(&oWorkApp, "Visible", True);
&oWorkBook = ObjectGetProperty(&oWorkApp, "Workbooks");
&oWorkBook.Open("C:\temp\TEST1.xls");
&oWorkSheet = &oWorkApp.Worksheets("Sheet1");
&oWorkSheet.Range("A1").Value = "Last Name";
&oWorkSheet.Range("B1").Value = "First Name";
&oWorkSheet.Range("A1:B1").Font.Bold = True;
&oWorkSheet.Range("A2").Value = "Doe";
&oWorkSheet.Range("B2").Value = "John";
&oWorkApp.ActiveWorkbook.SaveAs("C:\temp\TestXLS.xls");

/*Transfer the data to Excel from Rowset*/
&oWorkApp = CreateObject("COM", "Excel.Application");
ObjectSetProperty(&oWorkApp, "Visible", True);
&oWorkBook = ObjectGetProperty(&oWorkApp, "Workbooks");
&oWorkBook.Open("C:\temp\TEST1.xls");
&oWorkBook = &oWorkApp.Workbooks.Add();
&rs_Awards = CreateRowset(Record.PERTBL);
&rs_Awards.Fill("WHERE FILL.YEAR = '2008' AND FILL.STATUS = 'C'");
&oWorkSheet = &oWorkApp.Worksheets("Sheet1");
For &ie = 1 To &rs_Awards.activerowcount
&oWorkSheet.Cells(&ie, 1).Value = &rs_Awards.getrow(&ie).PERTBL.ID.Value;
&oWorkSheet.Cells(&ie, 2).Value = &rs_Awards.getrow(&ie).PERTBL.COMP.Value;
End-For;
&oWorkApp.ActiveWorkbook.SaveAs("C:\temp\TestXLS.xls");

/*Save an xls file as a CSV*/
&oWorkApp = CreateObject("COM", "Excel.Application");
ObjectSetProperty(&oWorkApp, "Visible", True);
&oWorkBook = ObjectGetProperty(&oWorkApp, "Workbooks");
&oWorkBook.Open("C:\temp\TEST1.xls");
&oWorkApp.ActiveWorkbook.SaveAs("C:\temp\TestXLS.csv", 6);

Friday, September 10, 2010

Calling SQR from PeopleCode (Page, Record, App Engine)



This is sample code that calls SQR from PeopleCode.This can be applicable if you need your page or app engine to call an independent SQR process/report. The following example was done in App Engine PeopleCode;
Local ProcessRequest &RQST;

&sRunCntlId = "Test";

&aProcessType = "SQR Report"/*(or "SQR Process")*/
&aProcessName = "MYSQRRPT";

&dttmRunDateTime = %Datetime;
&aTimeZone = "EST";
&aOutDestType = "WEB";
&aOutDestFormat = "PDF";

/* Create the ProcessRequest Object */
&RQST = CreateProcessRequest();

/* Set all the Required Properties */
&RQST.RunControlID = &aRunCntlId;
&RQST.ProcessType = &aProcessType;
&RQST.ProcessName = &aProcessName;

/* Set any Optional Properties for this Process */
&RQST.RunDateTime = &dttmRunDateTime;
&RQST.TimeZone = &aTimeZone;
&RQST.OutDestType = &aOutDestType;
&RQST.OutDestFormat = &aOutDestFormat;

/* Schedule the Process */
&RQST.Schedule();

If &RQST.Status = 0 Then

Else

End-If;

Building a Dynamic View using PeopleCode

If the requirement is to have a different prompt table depending on the settings of other fields. To illustrate, if the user enter name on the other field, they want to see a prompt of personel number. If they enter product information, they want to see the inventory number, lot number, etc.. You could use %EDITTABLE to dynamically specify the prompt table. However

in this case there are too many possible values or involved combinations . These will require you to create too many views. It would be nice if you can create view on the fly depending on what the end-user wants. The answer is YES, we can do that, we can generate the desired SQL text in the PeopleCode based on what the user enters.

1. Get the field that has a promt using GetField function.
&fld_CarNbr = GetField(Field.CAR_NBR);
2. Get all the information user enters.
&data_Name = CAR_TBL.NAME; 
&data_Model = CAR_TBL.MODEL;
3. Create the SQLTEXT.
&sqltext = "SELECT ID, NAME, MODEL, NBR FROM INV_TBL WHERE NAME = " &data_Name " AND MODEL = " &data_Model;
4. Override Dynamic View SQL
&fld_StdntCarNbr.SqlText = &sqltext;


Here another example. These replaces the data of the dynamic view.

&sqltext = CreateSQL("SELECT ID, NAME, MODEL, NBR FROM INV_TBL WHERE NAME = " &data_Name " AND MODEL = " &data_Model);

&RSTemp = GetRowset(Scroll.DYNAMIC_VW);
&RSTemp.Flush();
&Rec = CreateRecord(Record.DYNAMIC_VW);
While &Sql.Fetch(&Rec) &i = &i + 1; 
&RSTemp.InsertRow(&i); 
&Rec.CopyFieldsTo(&RSTemp.GetRow(&i).DYNAMIC_VW);
End-While;

App Engine running XML Publisher with PS Query Data Source



Haven't you notice that every posts up to this point are XML Publisher related? I just can get enough of this tools, i like discovering what this tool can do for me as a developer. If using Rowset Data Source in XMLP was too complicated for you, try using the PS Query as the Data Source. You don't need to create a code for sample data file and schema file because you can generate those files within PeopleSoft. Just replace the Rowset code in the XML Publisher Part 2 with this code;

/*fill prompt record*/
&rcdQryPrompts = &ReportDef.GetPSQueryPromptRecord();
If Not &
rcdQryPrompts = Null Then
If Not Prompt(&ReportDef.GetDataSource().Name, "",
&rcdQryPrompts) Then
Exit;
End-If;
&ReportDef.ProcessReport(&sTemplateId, %Language_User%Date, &sOutputFormat);
End-If;

Sending Email Using Application Engine (XML Publisher Report as Attachment)

Our understanding of XML Publisher are getting broader. There are a lot that you can do with this tool, I decided to incorporate the email functionality of PeopleSoft with the XML Publisher. How would you like if the batch thatproduced report output last night can be emailed to you automatically? I know a lot of people would love that!

With our knowledge on how to code XMLP report, we will just add codes to our existing PeopleCode in XML Publisher Part 2 that tells the PeopleSoft to send that report to an email. Here's the code (added codes are in bold text).

import PSXP_RPTDEFNMANAGER:*;
import PSXP_XMLGEN:*;
import PT_MCF_MAIL:*;


/*Create an email object by setting individual parameters*/
Local PT_MCF_MAIL:MCFOutboundEmail &eMail = create
PT_MCF_MAIL:MCFOutboundEmail();

&sRptDefn = "JOB_DEFN";
&sTemplateId = "JOB_TEMP";
&sLangCode = "";
&dtAsOfDate = %Date;
&sOutputFmt = "PDF";
&RptOutputDir = "c:\temp\" "XMLP";

&ReportDef.OutDestination = &RptOutputDir;

/*Set-Up Report*/
&ReportDef = create PSXP_RPTDEFNMANAGER:ReportDefn(&sRptDefn);
&ReportDef.Get();

/*Create Rowset*/
&rs = CreateRowset(Record.PERSONAl_DATA);


/*Fill Rowset*/&rs.FILL("WHERE FILL.EMPLID LIKE 'EID000%'");

/*Create Schema*/
&rds = create PSXP_XMLGEN:RowSetDS(); /*package method*/
&mySchema = &rds.GetXSDSchema(&rs);
&f1 = GetFile("c:\temp\JOB_XSD.xsd""W"%FilePath_Absolute);
&f1.WriteLine(&mySchema);
&f1.Close();


/*Create Sample XML File*/
&myXMLFile = &rds.GetXMLData(&rs, "c:\temp\JOB_XSD.xsd");
&f2 = GetFile("c:\temp\JOB_XML.xml""W"%FilePath_Absolute);
&f2.WriteLine(&myXMLFile);
&f2.Close();


/* output format */
&sOutputFormat = &sOutputFmt;

/*Provide a Data Source for the Report*/
&ReportDef.SetRuntimeDataRowset(&rs);

/*Generate the Report*/
&ReportDef.ProcessReport(&sTemplateId, %Language_User%Date, &sOutputFormat);

/*Publish the Report*/
&ReportDef.Publish("", &RptOutputDir, "XMLP", JOB_AET.PROCESS_INSTANCE);
&sFileExt = GetFileExtension(&sOutputFormat);


/*Send Mail*/&ToList = "to_user@yahoo.com";&FromList = "from_user@acme.com";&ReplyToList = "
from_user@acme.com";
&Subject = "Batch Run Email";
&eMail.Recipients = &ToList; /*comma separeted list of email addresses*/
&eMail.From = &FromList/*from email address*/&eMail.ReplyTo = &ReplyToList; /*in case the reply is to be sent to a different email address*/
&eMail.Subject = 
&Subject;

/*Body for multiple parts*/
Local string &plain_text = "Test for XML Email from PeopleSoft";
Local PT_MCF_MAIL:MCFBodyPart &text = create
PT_MCF_MAIL:MCFBodyPart();
&text.Text = &plain_text;

Local 
PT_MCF_MAIL:MCFBodyPart &attach = createPT_MCF_MAIL:MCFBodyPart();&attach.SetAttachmentContent(&RptOutputDir "JOB_DEFN.pdf",%FilePath_Absolute, "JOB_DEFN.pdf", "JOB_DEFN""""");

Local 
PT_MCF_MAIL:MCFMultiPart &mp = createPT_MCF_MAIL:MCFMultiPart();
&mp.AddBodyPart(&text);
&mp.
AddBodyPart(&attach);
&eMail.Multipart = &mp;

/*Override the default SMTP parameters specified in app server configuration file*/
&eMail.SMTPServer = "smtp.service.acme.com"/*just an example*/
&eMail.SMTPPort = 25/*usually this is 25 by default*/

Local integer &resp = &eMail.Send();
/*now check &resp for the result*/
Local boolean &done;
Evaluate &resp
When %ObEmail_Delivered
/*every thing ok*/
&done = True;
Break;
When %ObEmail_NotDelivered
/*check &eMail.InvalidAddresses, &eMail.ValidSentAddresses and &eMail.ValidUnsentAddresses*/
&done = False;
Break;
When %ObEmail_PartiallyDelivered/*check &eMail.InvalidAddresses, &eMail.ValidSentAddresses and &eMail.ValidUnsentAddresses*/
&done = True;Break;
When %ObEmail_FailedBeforeSending
/*get the formatted messages from &eMail.ErrorDescription, &eMail.ErrorDetails*/
&done = False;
Break;
End-Evaluate;


CommitWork();

XML Publisher Part 2

I hope you enjoy the first part XML Publisher Part 1!!! This time we will bring XML Publisher one step up. We will use Application Engine, PeopleCode and XMLP together to produce a nice looking batch report. The concept are like SQR, retrieving data from database via SQL SELECT, formating data and displaying data to a report usually in the form of PDF, CSV, etc. 

In order to retrieve data using PeopleCode you need to populate a rowset. 
import PSXP_XMLGEN:*;

/*Create Rowset*/
&rs = CreateRowset(Record.PERSONAl_DATA);

You need to fill this rowset with data by doing this;

/*Fill Rowset*/
&rs.FILL("WHERE FILL.EMPLID LIKE 'EID000%'");

You'll notice that I have an import statement on top. That is an delivered Application Package, inside that package are methods that we will use in our code.

We will now create our Sample Data File and Schema File by running the code above and the code below.

/*Create Schema*/
&rds = create PSXP_XMLGEN:RowSetDS(); /*example package method*/
&mySchema = &rds.GetXSDSchema(&rs);
&f1 = GetFile("c:\temp\JOB_XSD.xsd""W"%FilePath_Absolute);
&f1.WriteLine(&mySchema);
&f1.Close();

/*Create Sample XML File*/
&myXMLFile = &rds.GetXMLData(&rs, "c:\temp\JOB_XSD.xsd");
&f2 = GetFile("c:\temp\JOB_XML.xml""W"%FilePath_Absolute);
&f2.WriteLine(&myXMLFile);
&f2.Close();


This code will generate two files, an schema file with extension .xsd and sample data file with extension .xml. You need to upload the files in the report category page within PeopleSoft, create Data Source Definition (apply the things you learned from Part 1) choose Rowset data source type instead of PS Query. Also create the Report Definition and Process definition. Add few more lines to the Peoplecode and you will able to run and produce report. Your code should look like this;


import PSXP_RPTDEFNMANAGER:*;
import PSXP_XMLGEN:*;

&sRptDefn = "JOB_DEFN";
&sTemplateId = "JOB_TEMP";
&sLangCode = "";
&dtAsOfDate = %Date;
&sOutputFmt = "PDF";
&RptOutputDir = "c:\temp\" "XMLP";

&ReportDef.OutDestination = &RptOutputDir;

/*Set-Up Report*/
&ReportDef = create PSXP_RPTDEFNMANAGER:ReportDefn(&sRptDefn);
&ReportDef.Get();

/*Create Rowset*/
&rs = CreateRowset(Record.PERSONAl_DATA);


/*Fill Rowset*/&rs.FILL("WHERE FILL.EMPLID LIKE 'EID000%'");

/*Create Schema*/
&rds = create PSXP_XMLGEN:RowSetDS(); /*package method*/
&mySchema = &rds.GetXSDSchema(&rs);
&f1 = GetFile("c:\temp\JOB_XSD.xsd""W"%FilePath_Absolute);
&f1.WriteLine(&mySchema);
&f1.Close();


/*Create Sample XML File*/
&myXMLFile = &rds.GetXMLData(&rs, "c:\temp\JOB_XSD.xsd");
&f2 = GetFile("c:\temp\JOB_XML.xml""W"%FilePath_Absolute);
&f2.WriteLine(&myXMLFile);
&f2.Close();


/* output format */
&sOutputFormat = &sOutputFmt;

/*Provide a Data Source for the Report*/
&ReportDef.SetRuntimeDataRowset(&rs);

/*Generate the Report*/
&ReportDef.ProcessReport(&sTemplateId, %Language_User%Date, &sOutputFormat);

/*Publish the Report*/
&ReportDef.Publish("", &RptOutputDir, "XMLP", JOB_AET.PROCESS_INSTANCE);
&sFileExt = GetFileExtension(&sOutputFormat);

XML Publisher Part 1


Probably y'all aware that the XML Publisher is the new reporting tools of PeopleSoft (version 8.9 and higher). I once read that this is the only reporting platform for Fusion Apps. The cool things about this are you only have single toolset, user can create their own layout, upgradable to Fusion, flexible, quick and easy. How does it work? By combining the Technical Task which is XML DataSource and Business Task which is Template Layout to the XML Publisher Engine, you can produce a report output in the form of MS Word (RTF), MS Excel, PDF, and HTML.

You can create a simple XMP Publisher report by answering these following questions:
How to setup XML Publisher?
How to create data sources?
How to create report templates?
How to define reports?

For starters, you need to add the XMLP Report Developer to your User Role. That will give your user access/security to Report Category, Design Helper, Data Source, Report Definition, Content Library, Template Translations, Query Report Viewer, Query Report Scheduler, and Report Repository. You also need to download the template design helper which is located to Reporting Tools > XML Publisher > Setup > Design Helper. 


Define report categories; this is for row level security of the data. Located to Reporting Tools > XML Publisher > Setup > Report Category.








Now you must understand that XML Publisher retrieves data from different source (e.g. PS Query, RowSet, XML File, and XMLDoc Objects). In this article we will used the simplest form, the PS Query.
Assuming that you already have a query, you need to specify the query to create a data source. Fill in all the required fields, generate Sample Data File and Schema File by clicking the Generate link.






You can now create your Report Definitions. There are five pages in the Report Definition component, only the first three pages are required the last two pages are for more complex reporting (Reporting Tools > XML Publisher > Report Definition).

































Now you’re ready to run the report thru Query Report Viewer by clicking View Report link (Reporting Tools > XML Publisher > Query Report Viewer).