Approving Requisition by Line with ProcessFlow

My latest client is only my third to decide to approve requisitions through ProcessFlow by line instead of by header. While I like the concept, I don't like all of the WorkUnits (one for the requisition header and then one for each line to be approved).

I only had last week to work with them on developing this flow so I didn't get to test a theory that I'd like to put in place for this process - a process that would be easier for the approver but much more complicated to program.

In concept the approver should be able to view all of the pending lines on the requisition and then select which to approve, which to reject and which to unrelease; all from one Inbasket form.

After selecting the lines to reject or unrelease the Portal Page script would update RQ13.2 and then for the lines being approved the script would trigger ProcessFlow for the next approval level. (You'd have to program the script to require the approval to be done last.)

This way the number of WorkUnits would be greatly minimized as well as the number of UserAction notification emails. Like I said, it would be easier for the approver but more complicated to program.

I'm willing to give it a try - any takers?

Parsing Data

I often need to parse data within ProcessFlow or Design Studio and thought I'd share some quick tips on parsing text using JavaScript.

If I have a variable called mytext with the value of "David's Blog" and only want to use part of the value I can parse it.

mytext.substring(0,4) would return "David"
Substring returns the text between two points so to get the value substring starts at the 1st position (JavaScript starts with 0, not 1) and ends with the 2nd position.

mytext.substr(0,5) would return "David"
Substr returns the text from the starting point and forward the number of characters specified. If you leave the 2nd position off the substr command it will parse the text to the end point.

mytext.indexOf("Blog") would return 8
The indexOf method searches for your quoted value and returns the starting point of that value within the text.

mytext.length would return 12
The length method returns the number of characters (including spaces) within your text. This method doesn't start with zero so you get the actual number of characters.

You can use these methods together:

mytext.substr(mytext.indexOf("'s"),5) would return "'s Bl"

ProcessFlow User Level Work

Recently on John Henley's Lawson Guru Forum another contributor suggested assigning UserAction approvals to the User rather than to the Task. Normally the User Level Work Inbasket is used with HRUserAction approvals so why not assign non-HR approvals to Users as well?

The only real objection I have to this is that when a user leaves then the flow file would have to be updated rather than updating the ProcessFlow Admin User setup forms. When you update the User Task then the new user will see the existing Inbasket tasks right away - but if existing WorkUnits are assigned to Users they will have to be reassigned.

Either way there is some maintenance but I think updating the User Task is much easier and I would recommend keeping it simple.

Get URL Attachment from RQ and add to PO

Ash Gajjar contacted me recently with an interesting question. Could he get the URL for an attachment from a requisition and add that to the purchase order created from that requisition? Of course, I assured him. Now came the matter of how.

I offered Ash a solution with two methods of achieving that solution - use Design Studio when the PO was released to perform a DME on the PO Line Source Record, use the getattachrec.exe CGI to retrieve the URL Attachment, parse that for the actual URL value and then writeattach.exe to add it to the PO.

Ash chose the 2nd method I suggested and is using ProcessFlow to perform this solution. I have an old posting on how to get comments but the values are a little different when you want the URL Attachment instead of a standard comment.

Resource Update to Add New Users

Recently a client asked how to use ProcessFlow Integrator to add new users into Lawson Security from their active directory. I gave them two simple choices - we could use the SQL Query (which would require a JDBC connection to their database) or we could use the DataIterator to read a text file they created from their AD.

They decided the DataIterator would fit their business requirements and are creating a file of new users daily. That just left me to create the ProcessFlow.

I first used a FileAccess node to make sure the file exists and a Branch to connect to the DataIterator if the file is there. The DataIterator reads the line of data (instead of each data element separately) and I use an Assign node to parse out the comma separated values (see my previous post for a similar example).

The next step is the ResourceUpdate to add the users. I was surprised just how much information I could add - like Roles, Email Address, Employee Number, etc.

After looping through all of the records in the CSV text file I used another FileAccess to delete the file and the flow was complete.

Design Studio Select Line Solution 2

My previous solution example was based upon pressing a button in the form's header and detecting which line(s) had been selected within the detail section.

My client decided to add the button to the detail section (so it would appear on each line) and came up with this method of identifying which line's button was clicked:

if (id != "push2") return true
Invoice = lawForm.getDataValue("APD-INVOICE",formState.currentRow)
Vendor = lawForm.getDataValue("APD-VENDOR",formState.currentRow)

The only downside to this method is that the button appears on each line of the form whether or not there is data associated to that line and the user could press the button on a line with no data.

Design Studio Select Line Solution

Do you need to determine the line you're working on based upon the user selecting it in the Line FC? Here's a simple method I used with AP95.2 to pass variables to ImageNow to display an invoice. I had to repeat this for each line of the form.

This is using the field ID's.

if (lawForm.getElementValue("_f36r0") =="X") // Line 1
Vendor = lawForm.getElementValue("_f39r0")
Invoice = lawForm.getElementValue("_f41r0")
if (lawForm.getElementValue("_f36r1") =="X") // Line 2
Vendor = lawForm.getElementValue("_f39r1")
Invoice = lawForm.getElementValue("_f41r1")