Download - Workflow Guide

Transcript
Page 1: Workflow Guide
Page 2: Workflow Guide
Page 3: Workflow Guide
Page 4: Workflow Guide

Step 3: Click on FileNew to get a screen as shown below

Page 5: Workflow Guide

Step 6: Fill it up with details show below

Page 6: Workflow Guide
Page 7: Workflow Guide
Page 8: Workflow Guide

Click on OK. Ensure that the Runnable box is checked. This indicates that your process can be launched using the Workflow APIs

Page 9: Workflow Guide
Page 10: Workflow Guide

Step 13: Navigate to the node tab and ensure that the following details are entered

Click ok. You should be able to see this function in your process definition window now.

Step 14: Creating a Stop Activity. Create another function activity with the following details

Page 11: Workflow Guide
Page 12: Workflow Guide

You should be able to see the end activity in the process definition screen

Step 15: Now let us create a message.Close the process definition window. Under your item type select message. Right click and select New Message and enter the details as shown below

Page 13: Workflow Guide
Page 14: Workflow Guide

Step 16: Now create a notification that will use the message that you have created to send information to a recipient. Open up the Process Definition window for the Demo Process you had created in step 11.Right click on the screen and select new notification. Enter the details of the notification as follows:

Page 15: Workflow Guide

Now click on Node tab

Page 16: Workflow Guide
Page 17: Workflow Guide

Step 18: Now click on FileSave AsSelect database and enter the login details . Click ok . It might take some time to save the workflow to the database

Page 18: Workflow Guide
Page 19: Workflow Guide

from ap_invoices_all where invoice_num = 'EX-1'; begin

for c2 in sel_invoice loop l_item_key := c2.invoice_num || '/' || TO_CHAR(c2.invoice_id);

x_WF_process_exists := WF_item.item_exist (l_Item_type,l_item_key);

if x_WF_process_exists = false then begin wf_engine.createprocess(l_Item_type,l_item_key,'DEMOPROC'); wf_engine.startprocess(l_Item_type,l_item_key); commit; end; end if;

end loop; end workflow_trigg;

end workflow_pkg_new ;

Let us look at each line of this code in detail

/*These are all the local variable declarations. Note the item type name has been hardcoded to what we selected as the internal name while creating the item type earlier. We have created one variable which will hold the item key . The last variable is used to check if the process if the item type , item key , process combination has been previously used. If yes then we don’t need to do anything else we need to go about launching the workflow */

l_Item_type VARCHAR2(10) := 'INVDMWRK'; l_item_key varchar2(100); x_wf_process_exists boolean;

This piece of code is used to generate the item key which must be unique for a given item type and process combination.

l_item_key := c2.invoice_num || '/' || TO_CHAR(c2.invoice_id);

The next line of code checks if the item key currently being generated is indeed unique .

x_WF_process_exists := WF_item.item_exist (l_Item_type,l_item_key);

Page 20: Workflow Guide

If this value returns false then we enter further and the following lines get executed

wf_engine.createprocess(l_Item_type,l_item_key,'DEMOPROC'); wf_engine.startprocess(l_Item_type,l_item_key); commit;

create_process API creates the process instance for the item type, item key combination and start process launches the process. Why we need two calls is something you will understand in the examples to come.

Now that we have created the package, let us launch this procedure from an anonymous PL/SQL Block

Step 21: Execute the following piece of code from SQL*Plus or any other Tool which you use

BEGINworkflow_pkg_new.workflow_trigg;END;

Confirm that the block completed successfully with no exceptions

Step 21: Now login into the application using the user name which you had provided against the Performer Name when creating the notification . You must see something like this as soon as you log in.

Page 21: Workflow Guide

That ends our first workflow . If you have done this correctly then what follows will be really simple. Please ensure that this exercise is completed successfully before proceeding any further.

Page 22: Workflow Guide

1. Understanding Item and Message Attributes

The notification that we created now is pretty plain and does not really carry any details of what the invoice created actually contains. Let us add two pieces of information here the invoice amount and the invoice number.

Step 1:Use the workflow created in the step above and Save it as Exp_02.wft

Step 2:Create two item attributesOpen the item type definition and add two item attributes

Page 23: Workflow Guide
Page 24: Workflow Guide

Step 3:Now create two message attributes

Use the details in the boxes given below to create the two attributes

Page 25: Workflow Guide
Page 26: Workflow Guide

Note that both the properties of the Message Attributes above we see that the Source property has been set to Send. This means that this message attribute is being used to send information to the Notification recipient. We will look at how this can also be set to Receive and be used to collect a response from a recipient in the next example.

The fact that the default value of each of these message attributes is the item attributes results in the following.You set the item attribute value in your program Since the message attribute copies its value from the item attribute this value automatically gets reflected in the message attribute You have used the message attribute in the message body (show below) and that results in this information getting delivered to the recipient of the notification to which this message is attached.

Step 4: Modifying the Message Body to use the new Message Attributes

Right Click on the Message we had created in step 1 and click on Properties. Navigate to the Body tab of the message and fill in the details as shown below

Page 27: Workflow Guide

Step 5: Save this workflow to the database

Step 6: Now we have to modify the package body we had created in Example 1 to set the Item Attributes . Please note that setting item attributes results in the messages attributes getting set as well .

create or replace package body workflow_pkg_newis PROCEDURE workflow_trigg is l_Item_type VARCHAR2(10) := 'INVDMWRK'; l_item_key varchar2(100); errmsg_tmp varchar2(255); invoice_num_tmp VARCHAR2(30); invoice_amount_tmp NUMBER; x_wf_process_exists boolean;

cursor sel_invoice is select invoice_id,invoice_num,invoice_amount from ap_invoices_all where invoice_num = 'EXP-2';

Page 28: Workflow Guide

begin for c2 in sel_invoice loop

l_item_key := c2.invoice_num || '/' || TO_CHAR(c2.invoice_id);

x_WF_process_exists := WF_item.item_exist (l_Item_type,l_item_key);

if x_WF_process_exists = false then begin wf_engine.createprocess(l_Item_type,l_item_key,'DEMOPROC'); wf_engine.setitemattrtext( itemtype => l_Item_type, itemkey => l_item_key, aname => 'INVOICE_NUM', avalue => c2.invoice_num); wf_engine.setitemattrnumber(l_Item_type,l_item_key,'INVOICE_AMT',c2.invoice_amount); wf_engine.startprocess(l_Item_type,l_item_key); commit; exception when others then errmsg_tmp := SQLERRM; dbms_output.put_line('error is' || errmsg_tmp); end; end if; end loop; exception when others then errmsg_tmp := SQLERRM; end workflow_trigg;

Step 7: Execute the following piece of code from SQL*Plus or any other Tool which you use

BEGINworkflow_pkg_new.workflow_trigg;END;

Step 8: Confirm that the Performer you had mentioned earlier has received a notification.

2. Understanding Lookup Types , Lookup codes and Conditional Transitions

Let us add another piece of functionality here. Let this not remain a FYI notification . Let us make it FYA . In other words the notificationwill have action buttons like Approve and Reject. With this lesson we will be able to understand the concept of lookup types , codes and how we can branch based on a simple condition like Approval or Rejection of a Notification.

Page 29: Workflow Guide

Step 1: Open the workflow you have created in the section above and save it as Exp_03.wft

Step 2:As of now our workflow looks like this

Step 3: Firstly delete the transition from the notification to the End node. To do this simply click on the transition and hit Delete.

Step 4:Now open the Properties of the Notification and set it as follows

Page 30: Workflow Guide

Step 5: A result type indicates the possible outgoing transitions from a node. In this case there will be two possible outgoing transitions . One for Approval and the other for Rejection. You might be wondering from where this Approval result type came from . This is a seeded lookup type that comes along with the Standard Item Type you had loaded in the first workflow we created. To check this go back to the Workflow Builder and follow the screen shots given below:

Page 31: Workflow Guide

So this simply means that the possible outgoing transitions are determined by the lookup codes under the lookup type which you have selected for the Result property in the notification. Let us now see how we can create these transitions

Step 6:Create another End Activity node in your workflow. Do not forget to set the End value in the Start/End property in the node tab.So your workflow will now look something like this

Page 32: Workflow Guide

Step 7: Right Click on the Notification and start dragging the mouse to one of the End Activity nodes. The moment you reach the End Node and try to release the mouse you will notice a pop-up as shown below

Page 33: Workflow Guide

Select Approve and you will notice a transition with the label Approve has got created from the Notification to the End Node

Repeat this step and select Reject this time when creating the outgoing transition to the other End activity node. So finally your workflow will look like this.

And we are nearly done !!

Step 9: Create an AP Invoice with the Number EXP-3.

Step 10:Compile the following package bodycreate or replace package body workflow_pkg_newis PROCEDURE workflow_trigg is l_Item_type VARCHAR2(10) := 'INVDMWRK'; l_item_key varchar2(100); errmsg_tmp varchar2(255); invoice_num_tmp VARCHAR2(30); invoice_amount_tmp NUMBER; x_wf_process_exists boolean; cursor sel_invoice is select invoice_id,invoice_num,invoice_amount from ap_invoices_all where invoice_num = 'EXP-3'; begin for c2 in sel_invoice

loop

Page 34: Workflow Guide

l_item_key := c2.invoice_num || '/' || TO_CHAR(c2.invoice_id);

x_WF_process_exists := WF_item.item_exist (l_Item_type,l_item_key);

if x_WF_process_exists = false then begin wf_engine.createprocess(l_Item_type,l_item_key,'DEMOPROC'); wf_engine.setitemattrtext( itemtype => l_Item_type, itemkey => l_item_key, aname => 'INVOICE_NUM', avalue => c2.invoice_num); wf_engine.setitemattrnumber(l_Item_type,l_item_key,'INVOICE_AMT',c2.invoice_amount); wf_engine.startprocess(l_Item_type,l_item_key); commit; exception when others then errmsg_tmp := SQLERRM; dbms_output.put_line('error is' || errmsg_tmp); end; end if; end loop; exception when others then errmsg_tmp := SQLERRM; end workflow_trigg;

Step 11: Save the workflow to the database

Step 12: Run the following piece of codeBEGINworkflow_pkg_new.workflow_trigg;END;

Step 13: The performer of the notification should have received a notification but you will notice an important difference in this notification when you open it . Take a look at the screen shot below

Step 14: You can click on Approve or Reject and the notification will disappear from the list of notifications.

Page 35: Workflow Guide

3. Understanding Response Attributes

After doing the previous exercise you might have felt so what if I approve / reject there seems to be no difference. How will the person whose Invoice I am rejecting come to know of this and what if I want to convey a reason for rejecting this invoice. The other thing we will do is we will add some code which will dynamically determine who created the invoice . This is just to demonstrate that the recipient of a notification need not be static . Step 1: Open the workflow you have created in lesson 7 and save it as Exp_04.wft

Step 2: Add an item attribute that will be used to hold the value of the Comments that the approver wants to enter when he approves or rejects an invoice creation message.

Use the following box to fill up the properties

Page 36: Workflow Guide

Step 3:Let us create another item attribute that will be used to hold the value for who should be receiving the response to an approval or rejection of an invoice. We will later populate this value to be the creator of the invoice

Page 37: Workflow Guide

Use the following box to fill up the properties

Page 38: Workflow Guide

Step 4:Create another Message Attribute under the APPROVE MESSAGE to collect the response of the recipient

Page 39: Workflow Guide

Use the following box to fill up the properties of the Comments attribute

Page 40: Workflow Guide

Please observe that he Source type has been set to Respond here since we expect that this message attribute will be filled by the responder of the notification. Also the default value of the message attribute should be set to Comments item attribute. What this effectively does is to collect the value of the message attribute into the item attribute. We can later use this value to send another message to the person who created this invoice and initiated this notification. We will be creating those messages in the next step along with the notifications .

Step 5:Create two messages, one for informing the initiator about approval of the invoice and the other informing him about rejection

Page 41: Workflow Guide

Let the properties of the two message attributes be similar to the earlier item attributes which we had created with the same name.

Now let us define the message body for the two messages

Message for Invoice Approved:

Message Body

Page 42: Workflow Guide

We will have to fill up the body of the other message we have created for rejection with the following

Page 43: Workflow Guide

Step 6: Now that we have created two messages . Let us create two notifications to carry these messages

Let us first look at what we are trying to achieve here

Page 44: Workflow Guide

Open the process definition area right click and create two notifications with the following properties

Notification for Approved: Notification Tab

Notification for Approved: Node Tab

Page 45: Workflow Guide

Observe that Performer is no longer a static value. It is being populated using the Item Attribute which we will set in the PL/SQL code that we will write now.

Notification for Rejected:Notification Tab

Page 46: Workflow Guide

Notification for Rejected: Node tab

Page 47: Workflow Guide

Step 8: Create an AP Invoice with the name ‘EX-6’

Step 9:Save the workflow to the database

Step 10: Modify the package body as follows

create or replace package body workflow_pkg_newis PROCEDURE workflow_trigg is l_Item_type VARCHAR2(10) := 'INVDMWRK'; l_item_key varchar2(100); errmsg_tmp varchar2(255); invoice_num_tmp VARCHAR2(30); invoice_amount_tmp NUMBER; performer_tmp VARCHAR2(30); x_wf_process_exists boolean; cursor sel_invoice is select invoice_id,invoice_num,invoice_amount,created_by from ap_invoices_all

where invoice_num = 'EX-6';

Page 48: Workflow Guide

begin for c2 in sel_invoice loop

l_item_key := c2.invoice_num || '/' || TO_CHAR(c2.invoice_id); Dbms_Output.put_line(l_item_key);

x_WF_process_exists := WF_item.item_exist (l_Item_type,l_item_key);

if x_WF_process_exists = false then begin wf_engine.createprocess(l_Item_type,l_item_key,'DEMOPROC'); wf_engine.setitemattrtext( itemtype => l_Item_type, itemkey => l_item_key, aname => 'INVOICE_NUM', avalue => c2.invoice_num);

/*This piece of code is used to extract the user name of the fnd User who created the invoice */ select user_name into performer_tmp from fnd_user where user_id = c2.created_by;

wf_engine.setitemattrnumber(l_Item_type,l_item_key,'INVOICE_AMT',c2.invoice_amount);

/*This piece of code is used to set the PERFORMER_NOTIF item attribute with the fnd user that was fetched above */ wf_engine.setitemattrtext(l_Item_type,l_item_key,'PERFORMER_NOTIF',performer_tmp); wf_engine.startprocess(l_Item_type,l_item_key); exception when others then errmsg_tmp := SQLERRM; dbms_output.put_line('error is' || errmsg_tmp); end; end if; end loop; exception when others then errmsg_tmp := SQLERRM; end workflow_trigg;

end workflow_pkg_new ;

Step 11: Run the PL/SQL packaged procedureBEGINworkflow_pkg_new.workflow_trigg;END;

Step 11: The first notification is received by the fnd user whom you have setup in the first notification node. Log in as that fnd user and check

Page 49: Workflow Guide

And it will look like this

Now fill up some text in this Comments section such as “Invoice Approved” and click on Approve.

Step 12: Verify that you the creator of the invoice has received an approval notification. Log into your user and check this. It will look like this

And that completes this lesson

9. More on conditional branching using user defined lookupsLet us say we have a requirement in which if the invoice amount is greater than 500 then approver ‘X’ must receive the notification else no one must receive any notification as the amount is too small to be eligible for approval . We will achieve this behaviour in the following example.

Step 1: Open the workflow you have created in lesson 8 and save it is Exp_06.wft

Step 2:Open the Process Definition screen. This is what we are trying to achieve now

Page 50: Workflow Guide

Step 3: Let us create a lookup first that will be used to for the two outgoing transitions from the CHECK_AMT activity.Take a look at the screen shot below

Set up the properties of this lookup type as follows

Page 51: Workflow Guide

Right click on the new lookup type you have created and select New Lookup Code from the pop-up. Create two lookup codes with the following properties.

Page 52: Workflow Guide
Page 53: Workflow Guide

Be sure that you have entered the Internal Names exactly as shown above as we will use that in the code.

Step 4: Open the process definition area and add a function activity with the following properties

Step 5: Create the tranisitions from the Start Node to the Function Activity. When you try to create a transition from the Function Activity to one the notification you will see a list of lookup values that come up . Select Greater than 500 from that. Create an end activity node and create another transition from the function activity to the end node for the lookup code “Less than 500”

Step 6: It should finally look like this

Step 7: Now modify the package specification as follows

create or replace package workflow_pkg_newis procedure workflow_trigg;/*There are five mandatory parameters that you have to pass into any PL/SQL procedure that you create in a workflow function activity or anywhere else. These parameters give you all the context necessary for deriving values in your pl/sql procedure. You are already aware of itemtype and item key . Activity Id helps identify a specific instance of a function activity in a workflow. This is useful if the same function activity is used multiple times in the workflow. In that case we can

Page 54: Workflow Guide

make out one from other through this id only. P_funcmode generally takes two values RUN and CANCEL. We will leave the cancel part for the time being. For all our cases the mode is always RUN. Finally we this PL/SQL procedure returns a result on the basis of which we can take a path ahead*/procedure check_amount(p_item_type IN VARCHAR2,

p_item_key IN VARCHAR2, p_actid IN NUMBER,

p_funmode IN VARCHAR2, p_result OUT NOCOPY VARCHAR2);

end workflow_pkg_new ;

Step 8: Modify the package body as follows

create or replace package body workflow_pkg_newis PROCEDURE workflow_trigg is l_Item_type VARCHAR2(10) := 'INVDMWRK'; l_item_key varchar2(100); errmsg_tmp varchar2(255); invoice_num_tmp VARCHAR2(30); invoice_amount_tmp NUMBER; performer_tmp VARCHAR2(30); x_wf_process_exists boolean; x_count number := 0; cursor sel_invoice is select invoice_id,invoice_num,invoice_amount,created_by from ap_invoices_all where invoice_num = 'EX-7'; begin for c2 in sel_invoice loop

l_item_key := c2.invoice_num || '/' || TO_CHAR(c2.invoice_id);

Dbms_Output.PUT_LINE('Item Key is '||l_item_key);

x_WF_process_exists := WF_item.item_exist (l_Item_type,l_item_key);

if x_WF_process_exists = false then begin wf_engine.createprocess(l_Item_type,l_item_key,'DEMOPROC'); wf_engine.setitemattrtext( itemtype => l_Item_type, itemkey => l_item_key, aname => 'INVOICE_NUM', avalue => c2.invoice_num);

select user_name into performer_tmp from fnd_user where user_id = c2.created_by;wf_engine.setitemattrnumber(l_Item_type,l_item_key,'INVOICE_AMT',c2.invoice_amount);

Page 55: Workflow Guide

wf_engine.setitemattrtext(l_Item_type,l_item_key,'PERFORMER_NOTIF',performer_tmp); wf_engine.startprocess(l_Item_type,l_item_key); commit; exception when others then errmsg_tmp := SQLERRM; dbms_output.put_line('error is' || errmsg_tmp); end; end if; end loop; exception when others then errmsg_tmp := SQLERRM; end workflow_trigg;

procedure check_amount(p_item_type IN VARCHAR2, p_item_key IN VARCHAR2, p_actid IN NUMBER,

p_funmode IN VARCHAR2, p_result OUT NOCOPY VARCHAR2)

is invoice_amount_tmp number; l_debug_info varchar2(2000); begin IF (p_funmode = 'RUN') THEN invoice_amount_tmp := WF_ENGINE.GetItemAttrNumber(p_item_type,

p_item_key, 'INVOICE_AMT');

IF invoice_amount_tmp >= 500 THEN p_result := 'COMPLETE:GRT_500'; /*This is a standard way of assigning the result . Always use the internal name of the lookup code after COMPLETE:*/ ELSE p_result := 'COMPLETE:LSN_500'; END IF; ELSIF (p_funmode = 'CANCEL') THEN p_result := 'COMPLETE'; END IF; exception when others then NULL; end check_amount;

end workflow_pkg_new ; Step 8: Now create an invoice called EX-7 and assign it an amount less than 500. Then run the PL/SQL code by using the anonymous block we have created. You or the approver must not receive any notifications.

Step 9: Now create an invoice called EX-8 and assign it an amount greater than 500.Make sure you modify the package body to use the new invoice number in the cursor . Then run the PL/SQL code by using the anonymous block we have created. You or the approver must receive notifications normally.

This completes the lesson

Page 56: Workflow Guide

10 Understanding TimeoutLet us say that we have a requirement in which if the person receiving the notification does not respond in a day’s time then we should be able to send him a reminder notification and keep doing that till he responds. For this we use a feature called timeout in workflows.

Step 1: Open the workflow created in the lesson above and save it as Exp_10.wft

Step 2: Open the process definition area. This is what we are trying to achieve

Step 3: Open the properties of the approval notification and set a timeout by navigating to the node tab

Page 57: Workflow Guide

What this means is that every two minutes a reminder notification will be sent out to the user IYE1702(in your case it will be some other user) and this will keep happening till he responds. However there is one catch here everytime a workflow gets stuck on a Timeout we have to run a Concurrent Program called Workflow Background Process to release it from Timeout. Generally this concurrent program is scheduled and run very often . Of course the timeout of 2 minutes that we have taken is only for exercise purpose and it is not a realistic value in any real situation. We will look at where and how to run this concurrent program from in a short while.

Step 4: Now that we have created the Timeout let us also instruct the workflow what it should do in case it encounters a timeout. The intention here is that it should really do nothing and just come back in a loop and resend the notification

Create a new function activity with the following details

Page 58: Workflow Guide

Key in the details as shown above. The function which has been used is a standard DO-NOTHING function. Create one transition from the notification to the function and one from the function to the notification so that it forms a loop.

Step 5: Create an AP Invoice EX-9

Step 6: Modify the package body to reference this invoice number

Step 7: Run the PL/SQL code

Step 8:Verify that the approver has received the first notification . Wait for two minutes.

Step 9: Login into the Application and Run the following concurrent program from the System Administrator responsibility.

Page 59: Workflow Guide

Step 10: Verify that the program completed successfully

Step 11: Re-check to find that another notification has been received by the approver.

11 Understanding Workflow Base Tables

Sometimes it becomes essential to go and check from the backend if a function that you added actually got saved to the database or if the workflow you are using is the latest. You can do all this from the base tables that come along with the workflows.

The following metalink notes provide very good information on this

444446.1

Page 60: Workflow Guide

12 Understanding Access/Protection Level Concepts

There is something called Access levels in Oracle Workflows and it is defined as follows:

Access Level Range Purpose0-9 Reserved for Oracle Workflow

10-19 Reserved for Oracle Application Object Library

20-99 Reserved for Oracle E-Business Suite

100-999 Reserved for customer organizations

1000 Public

Knowing your Access Level:

Open up your workflow and Go to HelpAbout Oracle Workflow Builder 2.6Click on it and you should get the following box

There are three places where this level can get setCustomizationAccessProtection

Also there are two other options available in a workflow called Preserve Customizations and Lock at this Access Level.

Page 61: Workflow Guide

Select any function activity or any node . Click its properties and navigate to the access tab . You will be able to see something like this

Let us understand these concepts one by one

How Oracle protects its object from modification

Oracle developer set the Access level at 20 and Customization to 0Oracle developer sets the Lock at this Access Level checkboxThis makes protection to become 20(same as Access Level)Developer at Customer Site sets Access level at 100

100 is not between 0 and 20 (Customization and Protection levels)and hence developer at Customer site cannot modify this activity.

Oracle locks access levels in this manner to discourage customers from altering critical parts of the workflow. However if you manually change the access level to 0 then you can still alter these activities but this is not recommended

Page 62: Workflow Guide

How Oracle indicates that a particular object can be safely modified

Oracle developer sets the Access level at 20, Customization at 0And unchecks the Lock at this access level box. This makes the Protection to become 1000

Developer at customer site now changes access level to 100100 is between 0 and 1000 (since you have unchecked the Lock at this Access level box that level’s check is skipped)Customer is able to modify object

How Oracle can override your customizations

You the customer site developer set the Customization level at 100(by checking the preserve customizations box)Access level at 100 and Protection at 100(by checking the lock at this access level box)

Developer in Oracle changes the access level to 20 . Since 20 is not between 100 and 100 Oracle’s patch cannot modify your customizationBut there is a catch here . If the Oracle developer simply goes and checks a box called Allow Modification of Customized Objects from HelpAbout Oracle Workflow Builder then the customization can still be overridden