Discussions
Categories
Groups
Community Home
Categories
INTERNAL ENABLEMENT
POPULAR
THRUST SERVICES & TOOLS
CLOUD EDITIONS
Quick Links
MY LINKS
HELPFUL TIPS
Back to website
Home
Web CMS (TeamSite)
Workflow Re-assignment Transition
vp98aa
Hello,
I have a workflow with a cgitask. When that cgitask is activated, a window popups with a dropdown menu that lists all the teamsite editors. User can select any editor and click submit and the job will be assigned to that editor. Thats exactly what I want. Also I want to workflow to transition to next task. That is not happening. I know exactly why this is happening but I am not sure how to fix it.
Here is the synopsis (with removal of extra noise (like email tasks, rejection by editor, etc) for simplicity):
Author1 (usertask) - starts the workflow and submits a file to Editor1 for review.
Editor1 (usertask) - approves it.
Editor1 (cgitask) - a window pops up with a list of editors. Editor1 assigns the job to Editor2.
Editor2 (usertask) - approves & the file is submitted & workflow ends.
My cgitask calls some perl code,
In that perl code, I do following once the Editor1 selects Editor2 from the dropdown menu and clicks submit
1. Assign the task ownership to the Editor2 using some code like: $task->SetOwner($selectedEditor);
This works just fine. Ownership change does happen.
2. Now to transition back from this cgitask to the next task, I have to do a Callback using some code like this: system("$iwhome/bin/iwcallback.exe $task_id 0");
This fails because remember that I am still running the cgitask as Editor1 and so this callback is also being called by Editor1. But just a step above we assigned the task ownership to Editor2. So Editor1 cannot do a callback on this task anymore and I get an error saying: User Editor1 is not allowed to call back task xxxx (where xxxx is the task id).
Also something important to note is that if Editor1 assigns the cgitask to Editor1 (herself) then it works just fine as the task is still owned by Editor1 and hence the callback works and it transitions to the next step.
I am sure that re-assignment as part of the workflow via cgitask (not actually changing it through TS GUI via Task Properties) must be fairly common as it seems like a very frequent need .
How would I fix this? Any clues?
Thx,
V.
Find more posts tagged with
Comments
Migrateduser
I had done something very similar to this 3 years ago -- I think what you're looking to do is to change the owner of two tasks: the usertask and the cgitask. Actually, I think you could just have the cgitask owned by some master user.
There is a command line you should use in your CGItask, iwsettaskownerandarea. This is for version 6.5 and I think that command is relatively new but there is at least an equivalent command in previous versions.
Current Environment(s):
(1) TS 6.5 on W2K3
(2) TS 6.1 SP1 on W2K3
By the way, I miss Unix terribly.
vp98aa
Well wouldnt the CGI task be owned by Editor1 as well since Editor1 is the one who's going to be selecting Editor2 from that CGI Task? Plus I want this to appear under "my to do list" for Editor1. If I assign it to master, it will go under that userid.
Also that iwsettaskownerandarea -- from the documentation it sounds like it will only assign owner and workarea to that task. I believe my problem is the Callback from the CGI task as the ownership no longer belongs to Editor1. I hope that makes sense.
Any ideas/clues/suggestions would be very appreciated.
Thx,
V
vp98aa
Ooops one more thing that I was thinking but couldnt find any info on.
Is when I change the ownership: Is there a way (CLT or otherwise) that I "inactivate" current cgi task and "activate" next task (in other words forcefully transitioning)?
Is this recommended or is it a big NO NO? Any advantages / drawbacks of doing this?
Thx,
V.
Adam Stoller
2. Now to transition back from this cgitask to the next task, I have to do a Callback using some code like this: system("$iwhome/bin/iwcallback.exe $task_id 0");
I suggest you use
TeamSite::CGI_lite
's
iwcallback();
function instead of the system call.
Also - make sure that the task you are setting the owner on is the usertask following the cgitask & make sure that the CGI_lite object is referencing the task object associated with the CGI task - not the usertask.
--fish
Senior Consultant, Quotient Inc.
http://www.quotient-inc.com
Adam Stoller
Is when I change the ownership: Is there a way (CLT or otherwise) that I "inactivate" current cgi task and "activate" next task (in other words forcefully transitioning)?
That's precisely what the callback does.
Note - if you use TeamSite::CGI_lite::iwcallback() - it expects the description-string of the successorset to activate.
TeamSite::WFtask::CallBack() - on the otherhand, expects the 0-based index of the successorset to activate.
--fish
Senior Consultant, Quotient Inc.
http://www.quotient-inc.com
Migrateduser
You shouldn't really need to. Your script should be doing the callback for you. So, calling the script alone should indirectly cause the task to transition properly.
Current Environment(s):
(1) TS 6.5 on W2K3
(2) TS 6.1 SP1 on W2K3
By the way, I miss Unix terribly.
vp98aa
Fish,
Thx for your help. It took me a bit further but not too far.
I fixed the code as you had suggested that I set the owner on the "next task" and do call back on the "current cgi task".
When I do this, it give me an error saying "User Editor1 is not allowed to modify task owner and area. Error:02439: Operation not permitted." Whats goofy is that Editor1 is the workarea owner and in editor role. So shouldnt that give them full control to change taskowners?
Also in another workflow that I am still to develop I will need to have the ability where any Editor (not just the workarea owner) who has access to the workarea should be able to change taskowner via workflow.
Is there a way to do that? I know only taskowners and workarea owners (plus admins) can do this via the TS GUI task properties.
Any clues/ideas/suggestions?
Thx,
V
web.rptdesign
Adam Stoller
I do this all the time on Unix - haven't worked with Windows for a while so I'm not sure what the constraints are for doing it there - sorry.
--fish
Senior Consultant, Quotient Inc.
http://www.quotient-inc.com
vp98aa
Ok Fish some good news and some bad.
Good news: I got the user to operate that command -- of changing ownership -- working.
Bad news: Its not actually changing it or atleast I am not sure if it is or not.
What I mean by that is:
The command executes fine without any errors. However when the task transitions it will go to the user that I have defined in the WFT file.
And WFT file has to have an owner else it wont even let me start the WF. In the WFT I have iw_user -- which goes back to the Author1. Thats not what I want. I want the next task assigned to Editor2 since thats what was selected during the CGI task. But in the WFT the owner is set to iw_user -- user who started the WF (Author1).
Is there a way that I can define a dummy owner in the WFT and then update it daily or this is suppose to do that?
Does that make sense?
Thanks and appreciate all your help.
V
Migrateduser
You shouldn't have to do all of that. Minimally, what you'll need is an externaltask to (1) query for the task ID of the task you want to change (iwgettaskbyname) and (2) set the owner of the task accordingly (iwsettaskownerandarea).
Current Environment(s):
(1) TS 6.5 on W2K3
(2) TS 6.1 SP1 on W2K3
By the way, I miss Unix terribly.
vp98aa
Dave,
Thats exactly what my CGI task is doing 3 things:
1. User (Editor1) selects an editor (Editor2) to assign the next task (task after current cgi task) ownership.
On submit:
2. Actual changing the ownership happens. I tried both: WFworkflow:
etOwner (which call iwsetjobowner) and iwsettaskownerandarea.
3. Callback and transition to the next task whose ownership we just changed.
Step 2 from above seems to be successfully changing ownership. But when step 3 transition happens, it picks up the task owner from the WFT file where I have defined a "default task owner" since WFT file wont allow to even start the workflow without it.
I am stumped as this sounds like a pretty standard thing to me. Perhaps I am wrong.
All help is appreciated!
Thx again,
V.
Adam Stoller
Can you post the code for us to see how you're doing this?
--fish
Senior Consultant, Quotient Inc.
http://www.quotient-inc.com
hibsdsprojects.zip
vp98aa
Here are the two files:
Just a note: I have tried different options for actual changing the task ownership (WFworkflow:
etOwner vs iwsettaskonwerandarea) and callback (CGI_lite::iwcallback vs iwcallback) that may not be in the code below.
But so far all of them gave me similar results.
Once again thanks
V
---------------------------------------------------------------------------------------------------------------------------------------
IPL File:
---------------------------------------------------------------------------------------------------------------------------------------
#!../../iw-perl/bin/iwperl
# ----------------------------------------------
# Include necessary PERL Modules
# ----------------------------------------------
use strict;
use CGI;
use TeamSite::CGI_lite;
use TeamSite::Config;
use TeamSite::JavaResourceBundle;
use TeamSite:
CRnode;
use TeamSite::WFtask;
use TeamSite::WFworkflow;
use Date::Calc qw( Today Add_Delta_Days );
$|=1;
print "Content-type:text/html\n\n";
my $iwhome = TeamSite::Config::iwgethome();
my $wft_base = "$iwhome/local/config/wft/custom_ins";
# read the local/config/wft/custom_ins/content_submit.cfg
my $wffile = "submit_twoapprovals_wf";
my $wft_config = TeamSite::JavaResourceBundle->new();
$wft_config->load( $wft_base, $wffile, "cfg", 0 )
or die "Configuration file not found.";
my $ts_users_config = $wft_config->get_value("ts_users_config");
#-------------------------------------------------------
# Debug variables
#-------------------------------------------------------
my $debug = 0;
#-------------------------------------------------------
# Parse CGI Query String
#-------------------------------------------------------
my $cgi = new CGI;
my $review = $cgi->param('review');
my $oper = $cgi->param('Submit');
my $task_id = $cgi->param('task_id');
my $workflow;
my $task;
if ($task_id){
#print "TASKID: " . $task_id . "<br>";
$task = new TeamSite::WFtask($task_id);
#print "owner: " . $task->GetOwner() . "<br>";
#print "WFID: " . $task->GetWorkflowId() . "<br>";
$workflow = new TeamSite::WFworkflow($task->GetWorkflowId());
}
&review_selector;
#-------------------------------------------------------
# Report
#-------------------------------------------------------
sub review_selector
{
printHeader();
processSelection();
printFooter();
}
#-------------------------------------------------------
# SUB: processSelection
#-------------------------------------------------------
sub processSelection{
if ($oper eq 'Submit'){
my ($success, $next_task) = $workflow->GetTaskByName("SelectAuthor");
if($success){
my $reviewer2 = $cgi->param('editors');
my $next_task_id = $next_task->GetId();
my $cmdsetowner = "$iwhome/bin/iwsettaskownerandarea.exe $next_task_id $reviewer2 \\default\\main\\Intranet\\Compass\\WORKAREA\\test_wa";
my $results = system("$cmdsetowner 2>&1");
###########SOME LOGGING GOING ON HERE
open (lx, ">>C:/temp/_temp.log") || die "Can't open - $!\n";
print lx "\n\n\n--$cmdsetowner \n--$task_id: $next_task_id\n--$results";
close (lx);
}
$task->CallBack(0, "Moving on.");
print "<script>window.close()</script>";
}
else{
print "<p>Please select an Editor to assign this job. <br>\n";
# load the list of primary and backup approvers from
# the xml config file $iwhome/local/config/mazda
#Read the $ts_users_config file to get the primary and backup reviewers.
open (FILE, "<$wft_base/$ts_users_config") or die "Configuration file $ts_users_config not found.";
my $xml;
while(<FILE>){
$xml .= $_;
}
my $rootnode = TeamSite:
CRnode->new($xml);
print "<p>Editor: ";
print_ts_users ($rootnode, 'editors');
print "<p><input type=\"submit\" name=\"Submit\" value=\"Submit\"></p>\n";
}
}
#-------------------------------------------------------
# SUB: printHeader
#-------------------------------------------------------
sub printHeader
{
print<<EOS;
<html>
<head>
<title>Editor Assignment</title>
<link rel="stylesheet" type="text/css" href="/iw-cc/base/styles/iw.css">
</head><body>
<form>
EOS
print $cgi->hidden (-name=>'task_id', -default=>$task_id);
}
#-------------------------------------------------------
# SUB: printFooter
#-------------------------------------------------------
sub printFooter
{
print "</form>\n";
print "</body>\n</html>\n";
}
sub print_ts_users{
my ($r, $i) =
@_
;
my %values;
my
@group
= $r->get_node_list($i);
foreach (
@group){
foreach ($_->get_node_list('users')){
foreach ($_->get_node_list('user')){
$values {$_->value('
@id
')} = $_->value('
@name
');
}
}
}
my
@vals
= keys %values;
print $cgi->popup_menu(-name=>$i,
-values=>\
@vals
,
-labels=>\%values,
);
}
---------------------------------------------------------------------------------------------------------------------------------------
WFT File:
---------------------------------------------------------------------------------------------------------------------------------------
<template_script><![CDATA[
use strict; # Try to catch errors as early as possible.
# Declare which external packages and library routines will be used.
use Time::Local 'timegm';
use TeamSite::Config;
use TeamSite::JavaResourceBundle;
use TeamSite::Uniscape::uniscape qw(UTF8ToNative_2);
use TeamSite::Uniscape::uniscape qw(NativeToUTF8_2 UTF8ToNative_2);
use TeamSite::Usertask qw(cleanup_paths
get_names_from_file
make_l10n_input_with_roles_callout
make_branchpathlist
);
use TeamSite::WFconstructor;
use TeamSite:
CRnode;
my $mnt = TeamSite::Config::iwgetmount();
# Set $debugging to TRUE to enable debugging.
my $debugging = 0;
my $temp_dir = (($^O eq "MSWin32") ? "C:/tmp/" : "/tmp/");
my $iw_desc = __VALUE__('iw_desc');
my $uReviewer1 = __VALUE__('uReviewer1');
my $iw_user = __VALUE__('iw_user');
my $iw_branch = __VALUE__('iw_branch');
my $iw_workarea = __VALUE__('iw_workarea');
my $iw_areaowner = __VALUE__('iw_areaowner');
my $iwhome = TeamSite::Config::iwgethome();
my $iwperl = "$iwhome/iw-perl/bin/iwperl";
#$iwperl .= "\.exe" if ($^O eq "MSWin32");
# Fix up values of iw_workarea and iw_branch.
# This may be necessary if the user was asked to provide
# these values.
my($branch_path, $work_area, $skip_branch);
($iw_workarea, $iw_branch, $work_area, $skip_branch) =
set_area("branch_path", "work_area");
# If iw_areaowner was not passed to this WFT but the workarea is known,
# then retrieve the owner of the workarea.
if (!defined($iw_areaowner) && defined($iw_workarea)) {
chomp($iw_areaowner = `$iwhome/bin/iwattrib $iw_workarea owner`);
}
my $iw_template_file = __VALUE__('iw_template_file');
######################################################################
# Load the appropriate resource bundle for localization of this page.
######################################################################
# The properties file should be in the same directory as this
# workflow template, and should have the same name but end in
# _<locale>.properties (ex. _ja.properties) or .properties instead
# of .wft.
$_ = $iw_template_file;
m|(.*)/([^/]+).wft$|i;
my $wft_base_name = $2;
my $wft_dir = "$iwhome/local/config/wft";
# Assumes that this WFT is under the wft directory.
my $this_wft_dir = "$wft_dir/$1";
my $default_debug_file = $temp_dir . $wft_base_name . ".xml";
my $roles_dir = "$iwhome/conf/roles";
my $propfile = $wft_base_name . "_" . __VALUE__('iw_locale');
my $localizer = TeamSite::JavaResourceBundle->new();
my
@bundle
= $localizer->load( $this_wft_dir, $propfile );
my $job_name = $localizer->format('job.name');
my $job_description = $iw_desc;
my $template_name = $localizer->format('template_name');
my $done_label = $localizer->format('done_label');
my $retry_label = $localizer->format('retry_label');
my $cancel_job_label = $localizer->format('cancel_job_label');
# Enable VisualAnnotate if it's enabled on your TeamSite server as well as
# enabled in this workflow's configuration file.
my $va_in_iwcfg = `$iwhome/bin/iwconfig visualannotate va_enabled`;
my $va_enabled = 1; #true
die("VisualAnnotate has not been installed on your TeamSite server.")
if ($va_enabled && $va_in_iwcfg !~ /^true/);
######################################################################
# Load values from the configuration file for this workflow.
######################################################################
# The configuration file should be in the same directory as this
# workflow template, and should have the same name but end in .cfg
# instead of .wft.
my $wft_config = TeamSite::JavaResourceBundle->new();
$wft_config->load( $this_wft_dir, $wft_base_name, "cfg", 0 )
or die "Configuration file not found.";
my $default_file_comment = $localizer->format('default_file_comment');
my $metadata_capture_ui = $wft_config->get_value('metadata_capture_ui');
######################################################################
# VP - STR.
######################################################################
#=====================================================================
# Name: iw_getrole
# Args: role - basename of a TeamSite role (*.uid) file, or
# similarly constructed customized file in the
# same directory.
# Usage: $html = iw_getrole("master");
# Purpose: Generate an HTML formatted drop-down menu of all
# entries in named file for use within a TAG_info()
# section.
# Returns: Returns the generated drop down list on success, or
# a text field with an error message if it was unable
# to open the file.
#=====================================================================
sub iw_getrole{
my($role) =
@_
;
$role .= ".uid" if ($role !~ /\.uid$/);
my($html) = "";
if (!open(IN, "<$iwhome/conf/roles/$role")){
$html = "<input type='text' value='--Error opening $role--'>";
}
else {
$html = "<select size='1'>\n<option>\n";
foreach (sort(<IN>)){
s/^\s*//gs; s/\s*$//gs;
$html .= "<option>$_\n";
}
close(IN);
$html .= "</select>\n";
}
return($html);
}
#=# (changed reference to renamed subroutine)
my($iw_admin_html) = iw_getrole("admin");
my($iw_masters_html) = iw_getrole("master");
my($iw_authors_html) = iw_getrole("author");
my($iw_editors_html) = iw_getrole("editor");
# The path to the email script.
my $email_ipl = "$wft_dir/solutions/iw_solution_email.ipl";
my $file_attach_detach_ipl = "$wft_dir/custom_ins/file_operations.ipl";
######################################################################
# VP - END.
######################################################################
######################################################################
# Build the UI controls for user input.
######################################################################
my $banner_html=<<EOS;
<table cellspacing='3' cellpadding='3' class="iw-base-heading" style="width:100%;margin-bottom:4px;">
<tr valign='top' width='100%'>
<td class="iw-base-heading-title">$template_name</td>
</tr>
</table>
EOS
CGI_info(
title => $localizer->format('page_title'),
locale => __VALUE__('iw_locale'),
submit_label => $localizer->format('submit_button_label') ,
cancel_label => $localizer->format('cancel_button_label') ,
banner_html => $banner_html,
);
TAG_info(
# The value of the tag "iw_submit_comment" (obtained from the user)
# will appear as a user variable on the submit task.
# It will also be used as the job's description.
iw_submit_comment =>
[ html => $localizer->format('submit_comment_label').
"<br><textarea rows=8 style='width:100%'></textarea>".
"<br> ",
error_msg => $localizer->format('submit_comment_error_msg'),
label => 'Description / comment',
],
uReviewer1 => [html => "$iw_editors_html", is_required => 'true', label => "Reviewer",],
);
# Add debugging fields to the form if debugging has been switched on.
if ($debugging) {
TAG_info(
iw_debug_mode =>
[ html => "<input type='checkbox' value='true' checked>",
is_required => 'false',
],
iw_output_file =>
[ html => "<input type='text' value='" . $default_debug_file . "' size='40'>",
is_required => 'false',
],
);
}
# make sure the file list is defined
my
@submit_file
= (); # files sorted in unencoded
if (__ELEM__('iw_file')) # form, then html-encoded
{ # by hand via CGI_lite
@submit_file
= map { TeamSite::CGI_lite::escape_html_data($_);
} sort __VALUE__('iw_file');
}
@submit_file
= (__ELEM__('iw_file') ? sort __VALUE__('iw_file') : ());
my $submit_files_var = join ("####",
@submit_file)
;
######################################################################
# SUBROUTINES
######################################################################
#---------------------------------------------------------------------
# make_priority_select
# Creates the HTML for the priority SELECT. The select will
# have one option for every possible priority. You must specify
# a pre-selected option. If a value for the priority has
# already been selected, the workflow instantiator will
# override this selection.
#
# ARGUMENTS
# $preselected the option to be preselected by default
#
@priorities
A list of the possible priorities
# (ex. "High", "Medium", "Low").
#
# RETURNS
# A HTML string.
#---------------------------------------------------------------------
sub make_priority_select
{
my ($preselected,
@priorities)
=
@_
;
my $index = 0;
my $html = "<select size='1'>\n";
foreach my $p (
@priorities)
{
$html .= '<option value="' . $index++ . '"';
if ($p eq $preselected) {
$html .= ' selected';
}
$html .= ">$p</option>\n";
}
$html .= "</select>\n";
return $html;
}
sub make_deploy_server_select
{
my ($preselected,
@deploy_servers)
=
@_
;
my $index = 0;
my $html = "<select size='1'>\n";
foreach my $p (
@deploy_servers)
{
$html .= '<option value="' . $index++ . '"';
if ($p eq $preselected) {
$html .= ' selected';
}
$html .= ">$p</option>\n";
}
$html .= "</select>\n";
return $html;
}
sub make_ext_call
{
my ($filename) =
@_
;
my $index = 0;
my
@emails
;
open ( IN, "<$filename") ;
@emails
= <IN>;
close (IN);
my $size =
@emails
;
my $html = "<select multiple size=$size>\n";
foreach my $p (
@emails)
{
chomp($p);
$html .= '<option value="' . $p . '"';
#if ($p eq $preselected) {
# $html .= ' selected';
#}
$html .= ">$p</option>\n";
}
$html .= "</select>\n";
return $html;
}
#---------------------------------------------------------------------
# wa_validator
# Determines whether a selection for workarea is valid.
# This routine can return either a Boolean indicating the
# validity of the workarea, or a message (string) to be
# displayed if the workarea is invalid.
#
# ARGUMENTS
# wa - the selected workarea (string)
# error - whether the error message is desired (Boolean).
#
# RETURNS
# If the workarea is invalid, returns either a Boolean or a
# message, depending upon the value of $error. Otherwise,
# returns TRUE.
#---------------------------------------------------------------------
sub wa_validator
{
my($wa, $error) =
@_
;
my $utf8wa = $wa;
$wa = UTF8ToNative_2("$wa");
my $branch = __VALUE__('branch_path');
my $utf8branch = $branch;
$branch = UTF8ToNative_2("$branch");
my($avpath, $mount, $utf8avpath);
# Derive the full workarea vpath from the branch and workarea.
(undef, undef, $avpath) = cleanup_paths("$branch", "$wa");
(undef, undef, $utf8avpath) = cleanup_paths("$utf8branch", "$utf8wa");
# cleanup_paths inappropriately html escapes the values it's
# given (inappropriately because within that routine there is not
# actually any guarantee that the values are next going to html
# output). In order that the following test actually looks for
# the correct directory, we have to un-html escape the output from
# cleanup_paths. At this time (11/11/2001) it does not seem sensible
# to change the behavior of cleanup_paths directly, because many
# other workflows (both our own and those made by our customers) may
# depend on the html escape round performed by cleanup_paths.
$avpath = TeamSite::CGI_lite::unescape_html_data($avpath);
chomp($mount = `$iwhome/bin/iwgetmount`);
if (length($wa) > 0 && -d "$mount$avpath") {
# A workarea was specified and the vpath indicates a directory.
return(1);
} else {
if ($error) {
return $localizer->format('workarea_error_msg', "$mount$utf8avpath");
}
return(0);
}
}
#---------------------------------------------------------------------
# is_valid_user
# Determines whether a selection for user is valid.
# This routine returns a boolean indicating the
# validity of the user
#
# ARGUMENTS
# user - the selected username (string)
#
@roles
- array of role names (e.g., ('author', 'editor'))
#
# RETURNS
# If the user is invalid, returns a Boolean.
#---------------------------------------------------------------------
sub is_valid_user {
my ($user,
@roles)
=
@_
;
$_ = $user;
my
@role_files
= map { "$roles_dir/$_.uid" }
@roles
;
my
@array
= map {s/[\n\r\s]*$//;$_}
get_names_from_file(undef, undef, 'undef',
@role_files)
;
foreach my $author (
@array)
{
# Ignore the blank default value
next if $author =~ /^\s*$/;
my $selected = $user;
# Case-insensitive matching for windows
if ($^O eq "MSWin32")
{
return 1 if ($author =~ /^\Q$selected\E$/i);
}
else
{
return 1 if ($author =~ /^\Q$selected\E$/);
}
}
return 0;
}
######################################################################
# Name: set_area
# Args: btag - TAG_info variable name for branch path.
# watag - TAG_info variable name for workarea.
# Usage: ($a, $b, $w, $s) = set_area("$btag", "$watag");
# Purpose: If the built-in variables for branch and workarea have
# not been set, pull the information from the workflow
# instantiation form (using the btag and watag info).
# Use the branch and workarea information to generate
# a valid areavpath (using a library routine)
# Returns: Returns the generated areavpath, the branch path, the
# workarea name, and a boolean indicating whether or not
# the branch and workarea need to be prompted for during
# instantiation (this relies on the fact that this code
# is run multiple times during the instantion process).
######################################################################
sub set_area
{
my($btag, $watag) =
@_
;
my($avpath, $bpath, $wapath, $skip);
my($iwbpath, $iwwapath) = (__VALUE__("iw_branch"),
__VALUE__("iw_workarea"));
if ((length($iwbpath)) > 0 && (length($iwwapath)) > 0) {
$bpath = $iwbpath;
($wapath = $iwwapath) =~ s|^\s*/.*
|;
$wapath =~ s|/\s*$||;
return("$wapath", "$iwbpath", "$wapath", TRUE);
} else {
($bpath, $wapath, $avpath) = cleanup_paths(__VALUE__("$btag"),
__VALUE__("$watag"));
return("$avpath", "$bpath", "$wapath", FALSE);
}
}
#---------------------------------------------------------------------
# set_va_variables
# Set job variables (and values) used by VisualAnnotate.
#
# ARGUMENTS
# $approve_label - label for the "Approve" (0) transition
# $reject_label - label for the "Reject" (1) transition
#
# RETURNS
# Nothing. Works by making calls to set_job_variable.
#---------------------------------------------------------------------
sub set_va_variables
{
my ($approve_label, $reject_label) =
@_
;
# Add each of these VisualAnnotate properties as a job variable using
# the value from the wft config file
my
@va_properties
= ('va_show_cycles',
'va_show_snapshots',
'va_show_reviewers',
'va_create_snapshots',
'va_default_page',
'va_which_snapshot',
'va_show_live_option',
'va_show_save_button');
for my $var (
@va_properties
) {
my $val = $wft_config->get_value($var);
set_job_variable($var, $val);
}
set_job_variable('va_approve', $approve_label);
set_job_variable('va_reject', $reject_label);
set_job_variable('va_enabled', 'true');
}
######################################################################
# WORKFLOW BODY
######################################################################
{
my $approve_label = $localizer->get_value('approved_label');
my $reject_label = $localizer->get_value('please_revise_label');
# A network approach to handling tasks linkages; a seven step process:
# Step 1: Declare the basic properties of the workflow.
# Step 2: Declare all the tasks.
# Step 3: Declare links between tasks.
# Step 4: Identify the 'dormant' tasks and propagate.
# Step 5: Compute activation sets.
# Step 6: Any "special" task handling.
# Step 7: Generate the job spec.
# Step 1: Declare the basic properties of the workflow.
my
@file_comments
= ();
declare_workflow(name => $job_name,
owner => $iw_user,
creator => $iw_user,
description => $job_description,
comment => $job_description,
#files => \
@files
,
file_comments => \
@file_comments)
;
if ($va_enabled) {
set_va_variables($approve_label, $reject_label);
}
set_job_variable ("selected_files", $submit_files_var);
# Step 2: Declare all the tasks.
declare_task("Attach_Files",
name => "Attach_Files_For_Review",
description => "Attach all files for review.",
type => "externaltask",
start => TRUE,
owner => $iw_user,
areavpath => $iw_workarea,
command => "$iwperl $file_attach_detach_ipl attach all"
);
declare_task("Email_Reviewer",
name => "Email_Reviewer",
description => "Send Email notification to the Editor for approval.",
type => "externaltask",
owner => $iw_user,
areavpath => $iw_workarea,
command => "$iwperl $email_ipl -t \"Review\"",
variables => {
"iw_mailheader_pt" => "reviewer_iwmailheader.tpl",
"iw_mailbody_pt" => "reviewer_iwmailbody.tpl",
"iw_mailbody_text_pt" => "reviewer_textbody.tpl"
});
declare_task("Review",
name => "Review",
description => "Editor review. Approve or reject the content.",
type => "usertask",
owner => $uReviewer1,
areavpath => $iw_workarea,
readonly => TRUE
);
declare_task("AuthorWork",
name => "AuthorWork",
description => "Content rework/update to be done by Author.",
type => "usertask",
owner => $iw_user,
areavpath => $iw_workarea,
readonly => FALSE
);
declare_task('SelectEditor',
name => "SelectEditor",
description => "Select an Editor for the workflow.",
type => "cgitask",
owner => $uReviewer1,
areavpath => $iw_workarea,
immediate => TRUE,
command => 'editor_selector.ipl'
);
declare_task("Submit",
name => "SubmitTask",
description => "Submit files to STAGING.",
type => "submittask",
owner => $iw_areaowner,
areavpath => $iw_workarea,
unlock => TRUE,
savecomments => TRUE);
declare_task("End",
name => "EndTask",
type => "endtask");
# Step 3: Declare links between tasks.
link_tasks('Attach_Files', 'Email_Reviewer', 'Attach Files');
link_tasks('Email_Reviewer', 'Review', 'Send Email');
link_tasks('Review', 'SelectEditor', 'Approve & Assign');
link_tasks('Review', 'AuthorWork', 'Reject');
link_tasks('AuthorWork', 'Email_Reviewer', 'Done');
link_tasks('SelectEditor', 'Submit', 'Submit');
link_tasks('Submit', 'End', 'Success');
# Step 4: Identify the 'dormant' tasks and propagate.
propagate_from_dormant_tasks();
# Step 5: Compute activation sets.
compute_activation_sets();
# Step 6: Any "special" task handling.
#set_task_property('dept_approve_review', 'conjunction', TRUE);
# Step 7: Generate the job spec.
__INSERT__(get_job_spec());
}
]]></template_script>
Adam Stoller
Instead of:
my ($success, $next_task) = $workflow->GetTaskByName("SelectAuthor");
if($success){
my $reviewer2 = $cgi->param('editors');
my $next_task_id = $next_task->GetId();
my $cmdsetowner = "$iwhome/bin/iwsettaskownerandarea.exe $next_task_id $reviewer2 \\default\\main\\Intranet\\Compass\\WORKAREA\\test_wa";
my $results = system("$cmdsetowner 2>&1");
###########SOME LOGGING GOING ON HERE
open (lx, ">>C:/temp/_temp.log") || die "Can't open - $!\n";
print lx "\n\n\n--$cmdsetowner \n--$task_id: $next_task_id\n--$results";
close (lx);
}
Try this:
my ($success, $next_task) = $workflow->GetTaskByName("SelectAuthor");
if($success){
my $reviewer2 = $cgi->param('editors');
my $tmp = $next_task->GetOwner() . " => ($reviewer2) => ";
my $results = $next_task->SetOwner($reviewer2);
$tmp .= $next_task->GetOwner();
###########SOME LOGGING GOING ON HERE
open (lx, ">>C:/temp/_temp.log") || die "Can't open - $!\n";
print lx "\n\n\n--$tmp\n--$results\n";
close (lx);
}
and see if that works better.
If it doesn't work - please post the section of the log associated with the test run.
--fish
Senior Consultant, Quotient Inc.
http://www.quotient-inc.com
vp98aa
Fish,
I had tried this earlier in the day with a different variation.
--INSTSSERVER\test_editor1 => (INSTSSERVER\test_editor2) => INSTSSERVER\test_editor1
But it seems like that the SetOwner is failing and
in the iw-webd\logs\error.log file:
User INSTSSERVER\\test_editor1 is not allowed to modify task onwer and area.\n
ERROR:02439: Operation not permitted\n
NOTE: INSTSSERVER\test_editor1 is the workarea owner and task owner at this point.
Please Note: Instead I tried using iwsettaskownerandarea and that executed with no errors in the log file but it still doesnt seem to do what I need.
Thx,
V.
Adam Stoller
I see another problem though - your code says:
my ($success, $next_task) = $workflow->GetTaskByName("SelectAuthor");
but I don't see "SelectAuthor" defined as a task in your wft:
...
# Step 2: Declare all the tasks.
declare_task("Attach_Files", name => "Attach_Files_For_Review", ...);
declare_task("Email_Reviewer", name => "Email_Reviewer", ...);
declare_task("Review", name => "Review", ...);
declare_task("AuthorWork", name => "AuthorWork", ...);
declare_task('SelectEditor', name => "SelectEditor", ...);
declare_task("Submit", name => "SubmitTask", ...);
declare_task("End", name => "EndTask", type => "endtask");
I seee "SelectEditor", and I see "AuthorWork", but I don't see "SelectAuthor". Then also in the wft:
...
# Step 3: Declare links between tasks.
link_tasks('Attach_Files', 'Email_Reviewer', 'Attach Files');
link_tasks('Email_Reviewer', 'Review', 'Send Email');
link_tasks('Review', 'SelectEditor', 'Approve & Assign');
link_tasks('Review', 'AuthorWork', 'Reject');
link_tasks('AuthorWork', 'Email_Reviewer', 'Done');
link_tasks('SelectEditor', 'Submit', 'Submit');
link_tasks('Submit', 'End', 'Success');
The transitions here look like you would go from "SelectEditor" to "Submit" to "End" - where presumably "SelectEditor" is the cgitask you want to do all your fancy stuff in - however, it looks like you need to transition from "SelectEditor" to some-other-review-task, and that it's the some-other-review-task which needs to have the owner set on it.
So - either you're not showing all the right code - or you still have a bunch of work to fix within the wft and cgitask code before you're ready to claim something works or doesn't work.
--fish
Senior Consultant, Quotient Inc.
http://www.quotient-inc.com
vp98aa
My bad!!! I've got so many darn versions of this. Must've been the one where I took it out that I posted here. Let me just post the relevant sections again:
The one where I just tested with your last recommendations looks like this:
declare_task('SelectEditor',
name => "SelectEditor",
description => "Select an Editor for the workflow.",
type => "cgitask",
owner => $uReviewer1,
areavpath => $iw_workarea,
immediate => TRUE,
command => 'editor_selector.ipl'
);
declare_task('SelectAuthor',
name => "SelectAuthor",
description => "Select an Author for the workflow.",
type => "cgitask",
owner => $iw_user,
areavpath => $iw_workarea,
immediate => TRUE,
command => 'author_selector.ipl'
);
declare_task("Submit",
name => "SubmitTask",
description => "Submit files to STAGING.",
type => "submittask",
owner => $iw_areaowner,
areavpath => $iw_workarea,
unlock => TRUE,
savecomments => TRUE);
link_tasks('SelectEditor', 'SelectAuthor', 'Assign Author');
link_tasks('SelectAuthor', 'Submit', 'Submit');
link_tasks('Submit', 'End', 'Success');
Hope this will clarify it.
Adam Stoller
Using the same code - if you add test_editor1 to the admin.uid file (and run iwreset) - does it work?
If you add test_editor1 to the master.uid file (and run iwreset) - does it work?
I'm trying to narrow down the issue here - to verify whether it's the code or the role that's the problem. If the code doesn't work when test_editor1 is in the master.uid - I have to believe there's still a problem in the code that's being overlooked. If the code does work with test_editor1 is in the master.uid (and/or admin.uid) then we need to verify the access rights on the branch and workarea, and the group memberships of test_editor1 etc.
You *may* have to insert an externaltask between the two cgitask's in order to do what you want -- as I believe on Windows the externaltasks run as "SYSTEM" or similar - and thus may have the ability to do something that a cgitask process owned by the logged-in-user (test_editor1) can't.
If that's the case - create a job variable for the userid selected in the first cgitask, and use pretty much the code you have in the externaltask script to replace the owner of the second cgitask with that value.
--fish
Senior Consultant, Quotient Inc.
http://www.quotient-inc.com
vp98aa
Fish,
Thats exactly what I ended up diong -- externaltask with SYSTEM as owner. It worked out fine.
Thx for all your help. Really appreciate that.
V.
checkbox_test_fromDB1.rptdesign