I'm having to design a new flow which will require that multiple approvers, all with different category filter values, approve the WorkUnit at the same time.
What makes it even more interesting is the UserAction setting for the percentage of recipients taking the same action. We are setting primary and backup approvers and PFI calculates the number of users by how many could take action, not on how many approvals are required by category filter.
In other words, if you have 3 departments needing to approve the UserAction but you have 2 of these departments with a primary and backup approver, the system calculates that 5 users could take action so you have to base your percentage of recipients on that value.
Now as to how to dynamically set your UserAction to different approvers with different category filter values:
My flow will figure out all of the category filter values it needs to take into account (for example, multiple departments) with a Query and then update the oCatValue variable with a unique key value (see below) and then add that category filter value to each approver's User Task Category Definition prior to entering the UserAction.
After all required users have taken their action, this dynamic category filter value will be deleted from each approver.
A simple function to create a dynamic category filter value:
The following JavaScript creates a 12 digit number (milliseconds since 1/1/1970) and is unique per second.
// var d=new Date();
// oCatValue=d.getTime()
Design Studio - getting information after an Inquire
I think I've mentioned in the past some frustration that a form will return the "Inquiry Complete" message before that actual form field values update and that this is a problem when you want to capture the field values after an inquire is completed (using lawForm.getFormValue).
What I realized is that although the form field values don't update quickly enough, you can retrieve the field data values right away.
So instead of trying to capture the form value, use the lawForm.getDataValue function instead when an Inquire is done and you will be able to capture what you want.
What I realized is that although the form field values don't update quickly enough, you can retrieve the field data values right away.
So instead of trying to capture the form value, use the lawForm.getDataValue function instead when an Inquire is done and you will be able to capture what you want.
Using Design Studio to burst Strategic Ledger fields
I was asked the other day if I could present four different fields for the one SL field currently on RQ10 so that the user wouldn't have to add the values as comma seperated records.
Since I love a challenge...
I deleted the one SL field and added 4 labels and 4 text fields to the form at the line level. Each label listed what the field value should be.
When the user Inquires on the form my script retrieves the Segment Block value for each line presented and puts that into an array (by line) and then splits the array and assigns each value into the correct text field.
When the user Adds/Changes on the form my script takes the 4 text field values (by line), puts them into one comma seperated variable and then assigns that to the Segment Block value in the OnBeforeTransaction function.
The user was very happy with the ease of use that this provided to them and so, of course, asked for the ability to select Define on each of the 4 fields.
In order to add Define to a text field that you've added to a form, you must go into the Source tab, find the lines for each field and add hdef="1" and deftkn="SL40.6" to each of the 4 text field references. Now when the user right clicks on your text field, they get the option to select Define.
I've mentioned it in the past, but it bears repeating that if you add a text field to the detail line section of your form then you also have to update the field so that the system knows to track it by row. In this case you would find the line in the Source and update the field number from nbr="_f730" to nbr="_f730r0".
There you go. A simple solution that makes data entry much easier for clients using the Strategic Ledger system.
Since I love a challenge...
I deleted the one SL field and added 4 labels and 4 text fields to the form at the line level. Each label listed what the field value should be.
When the user Inquires on the form my script retrieves the Segment Block value for each line presented and puts that into an array (by line) and then splits the array and assigns each value into the correct text field.
When the user Adds/Changes on the form my script takes the 4 text field values (by line), puts them into one comma seperated variable and then assigns that to the Segment Block value in the OnBeforeTransaction function.
The user was very happy with the ease of use that this provided to them and so, of course, asked for the ability to select Define on each of the 4 fields.
In order to add Define to a text field that you've added to a form, you must go into the Source tab, find the lines for each field and add hdef="1" and deftkn="SL40.6" to each of the 4 text field references. Now when the user right clicks on your text field, they get the option to select Define.
I've mentioned it in the past, but it bears repeating that if you add a text field to the detail line section of your form then you also have to update the field so that the system knows to track it by row. In this case you would find the line in the Source and update the field number from nbr="_f730" to nbr="_f730r0".
There you go. A simple solution that makes data entry much easier for clients using the Strategic Ledger system.
Infor Process Automation Email Approvals
The new IPA approval via email function is pretty nice. You simply select this option within the UserAction and whatever Actions you set up are available as buttons within the email notification to your approver.
Of course you do have to select the HTML format and select to send email notifications in the UserAction, but if you set the correct flags, it works great.
The URL behind the action buttons in the email contains an encrypted data string which actually passes your login and password so you don't have to stop at the login page, but it does open a Landmark browser window confirming the action that the user took.
There is a down side - if, for some reason, this email is forwarded to another user and they click the approve button then the action will be recorded as being performed as the original user (since their user id and password is encrypted in the link).
Keep this in mind when you are evaluating the benefit / risk of using this new feature.
Some of you might remember that I played with this a couple of years ago and my solution contained the Action buttons but required the user to log in. My solution was a bit complicated and the interface wasn't as clean.
Infor is looking at adding an option to require the user to log in when they click the Action buttons in the email. This should reduce the security risks that some people might feel is too great.
Of course you do have to select the HTML format and select to send email notifications in the UserAction, but if you set the correct flags, it works great.
The URL behind the action buttons in the email contains an encrypted data string which actually passes your login and password so you don't have to stop at the login page, but it does open a Landmark browser window confirming the action that the user took.
There is a down side - if, for some reason, this email is forwarded to another user and they click the approve button then the action will be recorded as being performed as the original user (since their user id and password is encrypted in the link).
Keep this in mind when you are evaluating the benefit / risk of using this new feature.
Some of you might remember that I played with this a couple of years ago and my solution contained the Action buttons but required the user to log in. My solution was a bit complicated and the interface wasn't as clean.
Infor is looking at adding an option to require the user to log in when they click the Action buttons in the email. This should reduce the security risks that some people might feel is too great.
Design Studio Inbasket - Updateable Form
One of my clients is using ProcessFlow and Design Studio to access custom tables for approving invoices outside of the Lawson application. They defined the custom tables within Lawson's data dictionary so standard DME and AGS calls will work with them.
Because it is outside of Lawson's application, however, they needed to allow "approvers" to make changes to the form values (Department number, Accounting Distributions, PO Number, etc.). What they have been doing is hiding Lawson's standard Inbasket Action buttons and performing the dispatch calls from buttons they added to the Design Studio form.
They did this so they could call the Change function and make sure the data passed the edit checks prior to performing the Approve, Reject, etc. ProcessFlow dispatch call. As you can imagine, this is a bit of customization.
Now that they are looking at moving to Infor Process Automation (formerly LPA) I'm working on recreating some of their custom functionality - still using the S3 custom tables and Design Studio forms.
Rather than hide IPA's Action buttons, I have proposed that the Inbasket form track the field values and perform the Change FC when the user updates each field (with a pop-up alert if the Change Complete - Continue status isn't returned). The user will know right away if there is a problem with their data entry and not have to wait until they attempt to perform the dispatch action.
The draw back? After every Change FC was performed, the cursor would position itself back to the first form field. This is fine if the user is using a hunt and peck method of selecting the fields to update, but not if they're tabbing through the form and changing each field as they go.
So I started tracking which "next field" to go to after making an update and tried adding the Position To by ID function after the calling the Change function. That didn't work.
I tried putting my position to function is different standard functions available to the form, but none of them worked - until I mentioned my problem to my boss, Adam, and he gave me the solution.
He suggested using the textbox's "on focus" function on the first form field and when this field received the focus, check that the next field I wanted to go to was different and then position to that field. A simple and elegent solution that actually works!
Thanks, Adam. Now to convince my client that this is the best option.
Because it is outside of Lawson's application, however, they needed to allow "approvers" to make changes to the form values (Department number, Accounting Distributions, PO Number, etc.). What they have been doing is hiding Lawson's standard Inbasket Action buttons and performing the dispatch calls from buttons they added to the Design Studio form.
They did this so they could call the Change function and make sure the data passed the edit checks prior to performing the Approve, Reject, etc. ProcessFlow dispatch call. As you can imagine, this is a bit of customization.
Now that they are looking at moving to Infor Process Automation (formerly LPA) I'm working on recreating some of their custom functionality - still using the S3 custom tables and Design Studio forms.
Rather than hide IPA's Action buttons, I have proposed that the Inbasket form track the field values and perform the Change FC when the user updates each field (with a pop-up alert if the Change Complete - Continue status isn't returned). The user will know right away if there is a problem with their data entry and not have to wait until they attempt to perform the dispatch action.
The draw back? After every Change FC was performed, the cursor would position itself back to the first form field. This is fine if the user is using a hunt and peck method of selecting the fields to update, but not if they're tabbing through the form and changing each field as they go.
So I started tracking which "next field" to go to after making an update and tried adding the Position To by ID function after the calling the Change function. That didn't work.
I tried putting my position to function is different standard functions available to the form, but none of them worked - until I mentioned my problem to my boss, Adam, and he gave me the solution.
He suggested using the textbox's "on focus" function on the first form field and when this field received the focus, check that the next field I wanted to go to was different and then position to that field. A simple and elegent solution that actually works!
Thanks, Adam. Now to convince my client that this is the best option.
Design Studio - Source Code Changes
I'd had some fun recently creating some cool forms with Design Studio. I've mentioned some of the stuff that I've been able to do, but I thought I'd give a brief list of changes I've made within the Source tab to meet my clients needs.
Custom HR11 form - change the Title
My client didn't want the form's title to display "Employee" so I went into the Source tab, found the Title reference and changed it.
Custom GL41 form - Release button
Due to how a JE with Activities processes, the client didn't want to use Lawson's standard ProcessFlow approval triggers. Now we are going to Submit the form for approval and have ProcessFlow Release the record after the approvals are complete. I found the reference for the Release button within the Source code and changed it so it would display Submit.
//Disp="R" nm="Submit" value="R" nbr="_l19" id="button9" visible="0"
Of course I used the OnBeforeTransaction(fc) function and if fc=="R" I triggered ProcessFlow instead of allowing the Release to take place.
Custom GM65 form - change the Select list values
This client didn't like the descriptions associated to the values within Lawson's standard status list. Rather than delete Lawson's select list and add a new one and then use a lot of scripting to tie them together, I simply found the list within the Source code and changed the display values.
//Disp="1" Tran="1" id="vals1" nbr="_l16" Calculated
//Disp="2" Tran="2" id="vals2" nbr="_l17" Released
//Disp="3" Tran="3" id="vals3" nbr="_l18" Not Used
//Disp="4" Tran="4" id="vals4" nbr="_l19" Certified
Custom WFWK form - change the System value
When I have to create a new form I will sometimes start with one of these little used WFWK .1, .2 or .3 forms as a blank template. In order to include the ability to add a standard Lawson lookup list I change the System associated to my form from "WF" to the system my drop down list is associated to from within the Source.
SYSTEM="GM"
Custom HR11 form - change the Title
My client didn't want the form's title to display "Employee" so I went into the Source tab, found the Title reference and changed it.
Custom GL41 form - Release button
Due to how a JE with Activities processes, the client didn't want to use Lawson's standard ProcessFlow approval triggers. Now we are going to Submit the form for approval and have ProcessFlow Release the record after the approvals are complete. I found the reference for the Release button within the Source code and changed it so it would display Submit.
//Disp="R" nm="Submit" value="R" nbr="_l19" id="button9" visible="0"
Of course I used the OnBeforeTransaction(fc) function and if fc=="R" I triggered ProcessFlow instead of allowing the Release to take place.
Custom GM65 form - change the Select list values
This client didn't like the descriptions associated to the values within Lawson's standard status list. Rather than delete Lawson's select list and add a new one and then use a lot of scripting to tie them together, I simply found the list within the Source code and changed the display values.
//Disp="1" Tran="1" id="vals1" nbr="_l16" Calculated
//Disp="2" Tran="2" id="vals2" nbr="_l17" Released
//Disp="3" Tran="3" id="vals3" nbr="_l18" Not Used
//Disp="4" Tran="4" id="vals4" nbr="_l19" Certified
Custom WFWK form - change the System value
When I have to create a new form I will sometimes start with one of these little used WFWK .1, .2 or .3 forms as a blank template. In order to include the ability to add a standard Lawson lookup list I change the System associated to my form from "WF" to the system my drop down list is associated to from within the Source.
SYSTEM="GM"
Using a Boolean Variable in a Branch
Have you ever created a boolean variable to set whether specific conditions were met in your ProcessFlow and then used a Branch based off of whether it was true or false?
Did you use the condition variable==true?
Did you know that since your variable is either true or false that you could just reference the variable name as your condition and whatever the boolean value was the Branch would interpret that correctly.
So, instead of using variable==true you could just use variable.
Give it a try - it's pretty cool.
Did you use the condition variable==true?
Did you know that since your variable is either true or false that you could just reference the variable name as your condition and whatever the boolean value was the Branch would interpret that correctly.
So, instead of using variable==true you could just use variable.
Give it a try - it's pretty cool.
O Happy Array!
I've recently had to read through a lot of data within ProcessFlow, comparing lists values, etc. and have found that using arrays is a great way to read and compare data.
Most recently I built a flow to review the HR Supervisor records and compare it against ProcessFlow Approvers to make sure the records were in sync. My old method of doing this was to cycle through HRSUPER with a Query while running another Query within the HRSUPER Query loop to see if a matching record existed in PF Admin.
While this did work, I really didn't like running that 2nd Query 900 times! My solution this time around was to run both queries once, saving the values into two different arrays.
I then used a couple of JavaScript Expressions (within an Assign node) to compare my two arrays - one to produce a new array of new Approvers to add and the other to produce a list of Approvers to remove from PF Admin.
I then cycled through these two new arrays with a DataIterator node and used 3 WebRun nodes to add or remove the PF Admin records (User, User Task, User Task Category) as I cycled through the records.
You can do a lot with arrays. I used them recently within Design Studio to assign values from a DME and manipulate and sort the records before presenting them on my form.
O Happy Array!
Most recently I built a flow to review the HR Supervisor records and compare it against ProcessFlow Approvers to make sure the records were in sync. My old method of doing this was to cycle through HRSUPER with a Query while running another Query within the HRSUPER Query loop to see if a matching record existed in PF Admin.
While this did work, I really didn't like running that 2nd Query 900 times! My solution this time around was to run both queries once, saving the values into two different arrays.
I then used a couple of JavaScript Expressions (within an Assign node) to compare my two arrays - one to produce a new array of new Approvers to add and the other to produce a list of Approvers to remove from PF Admin.
I then cycled through these two new arrays with a DataIterator node and used 3 WebRun nodes to add or remove the PF Admin records (User, User Task, User Task Category) as I cycled through the records.
You can do a lot with arrays. I used them recently within Design Studio to assign values from a DME and manipulate and sort the records before presenting them on my form.
O Happy Array!
Change the System Reference in Design Studio
A couple of years ago I referenced how to
Drill Down from another form in Design Studio and I recently had to revisit this option.
When I have to create a custom form, I often just use WFWK.2 as a blank template and build the form, adding the labels, fields and buttons I want to use.
Most of the time this meets my need, unless I need to include a list of employees.
I was able to pull in the Company and Employee fields with their key numbers from HR11 but the select field still wouldn't find any matching employee records. I realized that if I went into the Source of my form and changed the reference to System="HR" that the select field now worked.
Since I'm just using WFWK.2 as a blank template I didn't need to retain the default System="WF" reference.
What a nice work around!
When I have to create a custom form, I often just use WFWK.2 as a blank template and build the form, adding the labels, fields and buttons I want to use.
Most of the time this meets my need, unless I need to include a list of employees.
I was able to pull in the Company and Employee fields with their key numbers from HR11 but the select field still wouldn't find any matching employee records. I realized that if I went into the Source of my form and changed the reference to System="HR" that the select field now worked.
Since I'm just using WFWK.2 as a blank template I didn't need to retain the default System="WF" reference.
What a nice work around!
User Level Work - proxy approver solution
I was asked recently about how to set up a proxy approver for User Level Work tasks. I had previously provided solutions at the Task Level, but not when a UserAction is designated to a User instead of a Task.
What I would do is to create a special “Out of Office” service and flow. The approver would log into an “Out of Office” UI form modified by Design Studio (I usually use WFWK.2) and enter their proxy approver. When they click submit then an OoO service is triggered.
The OoO flow file will add a new Task to that approver and place itself into a UserAction with one available Action – ‘Turn off Out of Office’. Once that is selected the “Out of Office” task is removed and the WorkUnit closed.
The separate approval flow (like for Personnel Actions) would have to query open WorkUnits to see if the pending approver has an open “Out of Office” WorkUnit and read the proxy user id variable. That variable value would be used in the UserAction so both the original approver and the proxy approver are both represented.
The UserAction would also have to be set to “Any Approver Takes Action” so the WorkUnit Metrics records will close correctly once either approver has taken action.
What I would do is to create a special “Out of Office” service and flow. The approver would log into an “Out of Office” UI form modified by Design Studio (I usually use WFWK.2) and enter their proxy approver. When they click submit then an OoO service is triggered.
The OoO flow file will add a new Task to that approver and place itself into a UserAction with one available Action – ‘Turn off Out of Office’. Once that is selected the “Out of Office” task is removed and the WorkUnit closed.
The separate approval flow (like for Personnel Actions) would have to query open WorkUnits to see if the pending approver has an open “Out of Office” WorkUnit and read the proxy user id variable. That variable value would be used in the UserAction so both the original approver and the proxy approver are both represented.
The UserAction would also have to be set to “Any Approver Takes Action” so the WorkUnit Metrics records will close correctly once either approver has taken action.
Subscribe to:
Posts (Atom)