WFLOAD Command for Oracle Workflow Migration


We use the Workflow Definitions Loader to save or load process definitions from a database or flat file. We can also define as it is a utility that moves workflow data between a file and a database and it is also used to upgrade, upload and download the workflow data.

Following is the syntax and the parameter details of WFLOAD.

WFLOAD <apps/pwd>@<connect_string> 0 Y {UPLOAD | UPGRADE | FORCE} <filepath>[<file_name.wft>]

Example:

WFLOAD apps/pwd@<connect_string> 0 Y UPLOAD $XXSCM_TOP/install/POAPPRV.wft

Different “Upload Modes” applicable to WFLOAD:

UPGRADE Honors both protection and customization levels of data
UPLOAD Honors only protection level of data [No respect of Customization Level]
FORCE Force upload regardless of protection or customization level

Use the following command to download workflow definition:

WFLOAD <apps_user_name>/<password>@db 0 Y DOWNLOAD file_name.wft <Item_Type>

Example:

WFLOAD <apps_user_name>/<password>@db 0 Y DOWNLOAD POAPPRV.wft

As a standard practice, Oracle’s upgrade patches mostly run in UPGRADE mode, hence your customizations can protected if best practices for development are followed.

One can find the seeded workflow definition files under$<PRODUCT_TOP>/patch/115/import/<LANG> directory.

For example, .wft files related to Purchasing can be located in the following directory:-
$PO_TOP/patch/115/import/US

Oracle Workflow Access Protection: A Technical Note


Oracle Workflow assigns a protection and customization level to every workflow object definition stored in the database and requires every user of Oracle Workflow to operate at a certain access level.

The combination of protection, customization, and access levels build the access protection feature and determine whether a user can modify a given workflow object. The level, in all three cases, is a numeric value ranging from 0 to 1000 that indicates the relationship between different organizations as providers and consumers of seed data.

The following ranges of levels are there in Oracle Workflow:

0-9 Oracle Workflow
10-19 Oracle Application Object Library
20-99 Oracle Applications development
100-999 Customer organization. You can determine how you want this range to be interpreted. For example, 100 can represent headquarters, while 101 can represent a regional office, and so on.
1000 Public

Access Level:

Each user of Oracle Workflow operates the system at a certain access level according to the range of levels listed above. A “user of Oracle Workflow” in this case, represents someone who is operating Oracle Workflow Builder, or the Workflow Definitions Loader program, which loads workflow process definitions from a file into a database.

Navigation to view your access level:

Oracle Workflow Builder > Help > About Workflow

Workflow Access Level

Note: If you are going to run the Workflow Definitions Loader program to download workflow process definitions from the database to a file, check the value for the environment variable WF_ACCESS_LEVEL on your workflow server.

The Access tab lets you define whether:

  • Future customizations to the object are preserved during a workflow definition upgrade.
  • The object can be edited by users operating at a higher access level.

Protection Level:

Whenever you create a workflow object in Oracle Workflow Builder, you have the option of protecting the object at a certain level. An object’s protection level helps control whether other users can modify the object based on their access levels, by allowing only users with an access level equal to or lower than the object’s protection level to modify the object.

Navigation to set the protection level of an object:

Oracle Workflow Builder > object’s property page > Access tab

Notes:

  • If you protect an object against customization, you effectively assign the object a protection level equal to your current access level.
  • Objects protected against customizations are considered “seed data.”
  • Only users operating at an access level equal to or lower than the protection level of the object can modify the object.
  • Users operating at an access level greater than the protection level of the object will see a small lock on the icon for the object in the navigator tree, indicating that the object is read-only.

Customization Level:

An object’s customization level helps control whether other users can modify the object based on their access levels, by allowing only users with an access level equal to or higher than the object’s customization level to modify the object.

Navigation to set the customization level of an object:

Oracle Workflow Builder > object’s property page > Access tab

Setting the customization level ensures that a customizable object that has been customized never gets overwritten during a seed data upgrade, because the upgrade always occurs with the Workflow Definitions Loader operating at an access level below the customized object’s customization level.

Use the Options region to set the protection and customization levels of an object.

Lock at this Access Level: Protects the object at the current access level and does not allow the object to be customized by higher access levels

Preserve Customizations: Prevents customized objects from being overwritten during a workflow definition upgrade.

Situation
Access Level
Lock at this Access Level
Preserve Customization
Level Summary
1 Set as 100

No

No

A: 100, P: 1000, C: 0
2 Set as 100

Yes

No

A: 100, P: 100, C: 0
3 Set as 100

No

Yes

A: 100, P: 1000, C: 100
4 Set as 100

Yes

Yes

A: 100, P: 100, C: 100

The indicator bar provides a visual range of access levels that can edit the object:

Black vertical line: Current access level

White range: Can’t edit the object

Solid green: Can edit the object

Cross-hatch green: Usually cannot modify the object because it has been customized, but can now do so because Oracle Workflow Builder is set to upload mode so that customized objects can be modified.

1] Allow access to everyone

Workflow Protection Level-1

None: Object can be updated at any time by any access level.

2] Limit access to users with access levels equal to your own or lower

Workflow Protection Level-2

Lock at this Access Level: Protects the object at the current access level and does not allow the object to be customized, except by access levels 0-100.

3] Limit access to users with access levels equal to your own or higher

Workflow Protection Level-3

Preserve Customizations: Disallows customized objects from being overwritten during a workflow upgrade.

  • Object may be updated by access levels 100-1000.
  • If the Allow modifications of customized objects check box is selected, customized objects can also be updated by access levels 0-99 as represented by green crosshatches in the indicator bar.

4] Limit access to users with access levels equal to your own

Workflow Protection Level-4

Both: Object can only be updated by the access level at which the object is protected.

  • Object may only be updated by access level 100.
  • If the Allow Modifications of Customized Objects check box is selected, customized objects can also be updated by access levels 0-99 as represented by green crosshatches in the indicator bar.

Oracle E-Business Suite customers should select both the Preserve Customizations and Lock at this Access Level check boxes to protect your workflow objects during upgrades.

During an Oracle Workflow seed data upgrade, the Workflow Definitions Loader is always run in Upgrade mode at an access level less than 100. As a result, the upgrade will not overwrite any object with a customization level of 100 or higher.

References:

docs.oracle.com

oracle.anilpassi.com

Create XML Publisher Report using Data Templates


The data templates are useful when you need to create a XML Publisher report without using the RDF. The XML Publisher data engine enables you to rapidly generate any kind of XML data structure against any database in a scalable, efficient manner which you can easily use in your templates.

The data template is the method by which you communicate your request for data to the data engine. It is an XML document whose elements collectively define how the data engine will process the template to generate the XML.

The Data Template Definition:

The data template is an XML document that consists of four basic sections:

 Sections of Data Templates

  • define parameters,
  • define triggers,
  • define data query,
  • define data structure

 Here is a sample data template:

Sample Data Template

1] Parameters Section:

A parameter is a variable whose value you can set at runtime. Parameters are especially useful for modifying SELECT statements and setting PL/SQL variables at runtime. However, the Parameters section of the data template is optional.

How to Define Parameters:

<parameters>
<parameter name="P_PERIOD_FROM" dataType="character" />
<parameter name="P_PERIOD_TO" dataType="character" />
</parameters>

How to Pass Parameters:

To pass parameters, (for example, to restrict the query), use bind variables in your query. For example:

SELECT *

FROM apps.gl_balances glb

WHERE glb.period_name BETWEEN :P_PERIOD_FROM AND :P_PERIOD_TO;

2] Data Query Section:

The <dataQuery> section of the data template is required.

How to Define SQL Queries

The <sqlStatement> element is placed between the open and close dataQuery tags. The <sqlStatement> element has a related attribute, name. It is expressed within the <sqlStatment> tag. The query is entered in the CDATA section.

<dataQuery>
<sqlStatement name="Q1">
<![CDATA[SELECT *
FROM apps.gl_balances glb
WHERE glb.period_name BETWEEN :P_PERIOD_FROM AND :P_PERIOD_TO]]>
</sqlStatement>
</dataQuery>

Lexical References:

You can use lexical references to replace the clauses appearing after SELECT, FROM, WHERE, GROUP BY, ORDER BY, or HAVING. Use a lexical reference when you want the parameter to replace multiple values at runtime.

Create a lexical reference using the following syntax:

&parametername

Define the lexical parameters as follows:

• Before creating your query, define a parameter in the PL/SQL default package for each lexical reference in the query. The data engine uses these values to replace the lexical parameters.

• Create your query containing lexical references.

<dataQuery>
<sqlStatement name="Q_Lexical">
<![CDATA[ &p_query ]]>
</sqlStatement>
</dataQuery>

<dataTrigger name="beforeReport" source="xxfin_test_pkg.beforeReport" />

In the function xxfin_test_pkg.beforeReport, you can design your query at runtime as below:

p_query VARCHAR2(2000) :=

‘SELECT * apps.gl_balances glb

WHERE glb.period_name BETWEEN :P_PERIOD_FROM AND :P_PERIOD_TO’;

How to Define a Data Link between Queries:

If you have multiple queries, you must link them to create the appropriate data output. In the data template, there are two methods for linking queries: using bind variables or using the <link> element to define the link between queries.

The following example shows a query link using a bind variable:

<dataQuery>
<sqlStatement name="Q1">
<![CDATA[SELECT PARENT_COL FROM XXTEST_LINK_TABLE1]]>
</sqlStatement>
</dataQuery>

<dataQuery>
<sqlStatement name="Q2">
<![CDATA[SELECT CHILD_COL FROM XXTEST_LINK_TABLE2]]>
</sqlStatement>
</dataQuery>

<link name="TEST_LINK" parentQuery="Q1" parentColumn="PARENT_COL"
childQuery="Q2" childColumn="CHILD_COL"/>

The <link> element has a set of attributes. Use these attributes to specify the required link information. You can specify any number of links.

3] Using Data Triggers:

Data triggers execute PL/SQL functions at specific times during the execution and generation of XML output. Using the conditional processing capabilities of PL/SQL for these triggers, you can do things such as perform initialization tasks and access the database.

Data triggers are optional, and you can have as many <dataTrigger> elements as necessary. The <dataTrigger> element has a set of related attributes. These are expressed within the <dataTrigger> tag.

For example:

<dataTrigger name="beforeReport1" source=" xxfin_test_pkg.beforeReport()"/>
<dataTrigger name="beforeReport2" source=" xxfin_test_pkg.beforeReport(:Parameter)"/>
  • Name: The event name to fire this trigger.
  • Source: The PL/SQL <package name>.<function name> where the executable code resides.

4] Data Structure Section:

In the data structure section you define what the XML output will be and how it will be structured. The complete group hierarchy is available for output. You can specify all the columns within each group and break the order of those columns; you can use summaries, and placeholders to further customize within the groups.

Sample Data Structure:

<dataStructure>
<group name="GROUP_1" source="Q1">
  <element name="LEDGER_ID" value="LEDGER_ID" />
  <element name="LEDGER_SHORT_NAME" value="LEDGER_SHORT_NAME" />
  <element name="LEDGER_DESCRIPTION" value="LEDGER_DESCRIPTION" />
  <element name="LEDGER_NAME" value="LEDGER_NAME" />
  <element name="LEDGER_SUM_BAL_DR" value="ACCT_SUM_BAL_DR" function="SUM()" />
  <element name="LEDGER_SUM_BAL_CR" value="ACCT_SUM_BAL_CR" function="SUM()" />
<group name=" GROUP_2" source="Q1">
  <element name="CODE_COMBINATION_ID" value="CODE_COMBINATION_ID" />
  <element name="ACCOUNTING_CODE_COMBINATION" value="ACCOUNTING_CODE_COMBINATION" />
  <element name="CODE_COMBINATION_DESCRIPTION" value="CODE_COMBINATION_DESCRIPTION" />
  <element name="ACCT_SUM_PR_DR" value="PERIOD_NET_DR" function="SUM()" />
  <element name="ACCT_SUM_PR_CR" value="PERIOD_NET_CR" function="SUM()" />
  <element name="ACCT_SUM_BAL_DR" value="BEGIN_BALANCE_DR" function="SUM()" />
  <element name="ACCT_SUM_BAL_CR" value="BEGIN_BALANCE_CR" function="SUM()" />
<group name=" GROUP_3" source="Q1">
  <element name="PERIOD_YEAR" value="PERIOD_YEAR" />
  <element name="PERIOD_NUMBER" value="PERIOD_NUMBER" />
  <element name="PERIOD_NAME" value="PERIOD_NAME" />
  </group>
  </group>
  </group>
</dataStructure>

How to Call a Data Template:

There are two methods for calling the data engine to process your data template:

• Concurrent Manager

• Data Engine Java APIs

Before you can use either of these methods, you must first register your data template in the Template Manager as a Data Definition. After that you attached the RTF template to that data definition.

Data def for data template

Calling a Data Template from the Concurrent Manager:

To use the concurrent manager to execute your data template, you must register a Concurrent Program, using the define Concurrent Programs form:

CP Def for data template

Executable Name Enter the XML Publisher data engine executable: XDODTEXE

Output Format Select “XML” as the output format.

Note: We do not need to create a concurrent executable as we use a seeded executable XDODTEXE

Concurrent Program – Parameters:

For each parameter in the Data Template, define a parameter in the concurrent program.  The Data Template parameter name should match the concurrent program parameter token

Few tips for best practices:

Performing operations in SQL is faster than performing them in the data template or PL/SQL. It is recommended that you use SQL for the following operations:

  • Use a WHERE clause instead of a group filter to exclude records.
  • Perform calculations directly in your query rather than in the template.

 To maximize performance when building data queries in the data template: XML Publisher tests have shown that using bind variables is more efficient than using the link tag.

The dataStructure section is required for multiple queries and optional for single queries. If omitted for a single query, the data engine will generate flat XML.

How to create concurrent programs from database?


Here are couple of APIs useful for creating any concurrent programs from the backend database.

1)    Registering the Executable from back-end:

Usually we create executable in the front-end, but this can be done from the database tier i.e. back-end too. Below is the PL/SQL code to create an executable from back-end.

BEGIN
  FND_PROGRAM.executable(executable => 'XXFIN TEST EXECUTABLE' , -- Executable Name
  application=>'XXFIN' , -- Application Short Name
  short_name=>'XXFINTSTEXE' , -- Executable Short Name
  description=>'Test Executable created from Backend' ,     -- Description,DEFAULT NULL
  execution_method=>'PL/SQL Stored Procedure',              -- Execution Method
  execution_file_name=>'XXFIN_TEST_PROC' ,                  -- Execution File Name,DEFAULT NULL
  subroutine_name=>NULL ,                                   -- Subroutine Name,DEFAULT NULL
  icon_name=>NULL ,                                         -- Icon Name,DEFAULT NULL
  language_code=>'US' ,                                     -- Language Code,DEFAULT 'US'
  execution_file_path=>NULL                                 -- Execution File Path, DEFAULT NULL
  );
  COMMIT;
END;

View from Frontend:

Creating Executable

Notes:

1] The above API inserts the new records in FND_EXECUTABLES and FND_EXECUTABLES_TL table.

2] You can use the below query to get all the Execution Methods available:

SELECT MEANING “Execution Method”

FROM fnd_lookup_values

WHERE lookup_type = ‘CP_EXECUTION_METHOD_CODE’

AND enabled_flag  = ‘Y’;

2)    Registering the Concurrent program from back-end:     

Usually we create Concurrent program in the front-end, but this can be done from the database tier too. Below is the program to create a Concurrent program from back-end.

BEGIN
  FND_PROGRAM.register(program =>'Test CP from DB', -- CP Name
  application =>'XXFIN' , -- Application Short Name
  enabled =>'Y',                                    -- Flag to Enable/Disable a CP
  short_name =>'XXFINTSTCPDB', -- CP Short Name
  description =>'Test CP created from Backend' ,    -- Description,DEFAULT NULL
  executable_short_name =>'XXFINTSTEXE', -- Executable Short Name
  executable_application =>'XXFIN' , -- Executable Application Short Name
  execution_options => NULL,                        -- Execution Options,DEFAULT NULL,
  priority => NULL,                                 -- Priority,DEFAULT NULL,
  save_output =>'Y',                                -- Save Output,DEFAULT 'Y',
  PRINT =>'Y' ,                                     -- Print,DEFAULT 'Y',
  cols => NULL, -- DEFAULT NULL,
  rows => NULL, -- DEFAULT NULL,
  style => NULL,                                    -- DEFAULT NULL,
  style_required =>'N' ,                            -- DEFAULT 'N',
  printer => NULL,                                  -- DEFAULT NULL,
  request_type => NULL,                             -- DEFAULT NULL,
  request_type_application => NULL,                 -- DEFAULT NULL,
  use_in_srs =>'N' ,                                -- DEFAULT 'N',
  allow_disabled_values =>'N' ,                     -- DEFAULT 'N',
  run_alone =>'N' ,                                 -- DEFAULT 'N',
  output_type =>'TEXT',                             -- DEFAULT 'TEXT'
  enable_trace =>'N' ,                              -- DEFAULT 'N',
  restart =>'Y' ,                                   -- DEFAULT 'Y',
  nls_compliant =>'Y' ,                             -- DEFAULT 'Y',
  icon_name => NULL,                                -- DEFAULT NULL,
  language_code => 'US',                            -- DEFAULT 'US',
  mls_function_short_name => NULL,                  -- DEFAULT NULL,
  mls_function_application => NULL,                 -- DEFAULT NULL,
  incrementor => NULL, -- DEFAULT NULL,
  refresh_portlet => NULL                           -- DEFAULT NULL,
  );
  COMMIT;
END;

View from Frontend:

Creating CP

Notes:

1] The various output types are ‘PS’, ‘PDF’, ‘HTML’, ‘TEXT’, ‘PCL’, ‘XML’.

2] The above API inserts the new records in fnd_concurrent_programs and FND_CONCURRENT_PROGRAMS_TL

3)    Attaching the concurrent program to the request group

Usually we Attach Concurrent program to the request group in the front-end, but this can be done from database tier too. Below is the program to Attach Concurrent program to the request group from back-end.

BEGIN
  FND_PROGRAM.add_to_group('XXFINTSTCPDB', -- Concurrent Program Short Name
  'XXFIN' , -- Application Short Name
  'All Reports',                           -- Report Group Name
  'SQLAP'); -- Report Group Application
  COMMIT;
END;

Apart from these APIs, the above package also contains to create/delete parameters, delete executable, and delete concurrent programs and all.