# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl Workflow-Wfmc.t'
#########################
# change 'tests => 1' to 'tests => last_test_to_print';
use Test::More tests => 2;
BEGIN { use_ok('Workflow::Wfmc') };
#########################
use strict;
use warnings;
use XML::Simple qw|XMLin XMLout|;
use Data::Dumper;
use XML::XPath::XMLParser;
use Workflow::Wfmc; # my workflow class
use Getopt::Long;
####################### Usage instruction ##########################
our ($opt_help,$opt_file,$opt_conf,$opt_ordertype,$opt_ordern,$opt_actno,$opt_total);
my $num_arg = $#ARGV;
Getopt::Long::Configure("bundling");
GetOptions("file|f=s", "conf|c=s","ordertype|t=s","ordern|n=s","actno|a=s","total|l=s", "help|?");
#if ($num_arg < 0 || defined($opt_help)) {
if (0) { # substitute this line withe the above when run directly
printf <<'END';
Usage: Runable.pm [OPTIONS]
Exchange orders between nodes and update DB.
-f, --file="/path/to/order.xml" order file path
-c, --conf="C:/kai/PERL/Kai-Workflow/workflow.xml" configuration file path
-t, --ordertype="PO" order type "PO" or "Credit"
-n, --ordern="EP100" order number, e.g., "EP100"
-a, --actno="10100126" account number, e.g., "EP100"
-l, --total="200" total amount in EURO, e.g., 120
--help display this help and exit
END
exit(0);
}
####### START: arguments #######
my $order_file = defined($opt_file) ? $opt_file :'./lib/Workflow/Wfmc/Test/sample_order.xml'; # defaults to Kai's setup
my $conf_file = defined($opt_conf) ? $opt_conf :'./lib/Workflow/Wfmc/Test/workflow.xml'; # defaults to Kai's setup
my $order_type = defined($opt_ordertype) ? $opt_ordertype :'PO'; # defaults to Kai's setup
my $order_ordern= defined($opt_ordern) ? $opt_ordern :'EP100'; # defaults to Kai's setup
my $order_actno = defined($opt_actno) ? $opt_actno :'10100126'; # defaults to Kai's setup
my $order_total = defined($opt_total) ? $opt_total :'200'; # defaults to Kai's setup
####### END: arguments #########
open(IN,"<$order_file");
my $doc = do{local $/;<IN>;}; # slurp an approvable
close(IN);
my $init_act_id = { # specify starting states for each workflow
'EOrder' => [1],
'FillOrder' => [1],
'CreditCheck' => [1],
};
my $wfp_id = { # These are the workflow process IDs
'EOrder' => "1",
'FillOrder' => "2",
'CreditCheck' => "3",
};
my $cust_lib = # list customized libraries used to handle call-backs
{
'EOrder' =>'Workflow::Wfmc::Test::Order', # class to handle EOrder workflow
'FillOrder' =>'Workflow::Wfmc::Test::Order', # class to handle FillOrder workflow
'CreditCheck' =>'Workflow::Wfmc::Test::Order', # class to handle Credit workflow
};
my $wf = { # create workflow objects first
'EOrder' => new Workflow::Wfmc('Id' => $wfp_id->{'EOrder'}),
'FillOrder' => new Workflow::Wfmc('Id' => $wfp_id->{'FillOrder'}),
'CreditCheck' => new Workflow::Wfmc('Id' => $wfp_id->{'CreditCheck'}),
};
$wf->{'EOrder'} ->load_conf($conf_file); # load the workflow config file
$wf->{'FillOrder'} ->load_conf($conf_file); # load the workflow config file
$wf->{'CreditCheck'} ->load_conf($conf_file); # load the workflow config file
my $data_fields = { # initialize the process variables: data fields
'EOrder' => $wf->{'EOrder'} ->init_data_fields($wfp_id->{'EOrder'}),
'FillOrder' => $wf->{'FillOrder'} ->init_data_fields($wfp_id->{'FillOrder'}),
'CreditCheck' => $wf->{'CreditCheck'}->init_data_fields($wfp_id->{'CreditCheck'}),
};
# The following pointer contains the entire workflow configuration, including call-back functions (ACTION)
# Attention: The following paramter refers to itself when calling sub get_dest_id()
my $wf_param = {}; # initialize the process input/output parametrs,
$wf_param = { # process exceptions and call-back functions (actions)
$wfp_id->{'EOrder'} => # workflow ID
{
'IN' =>
{
'orderString' => 'AAA', # FormalParameters of workflow
},
'OUT' =>
{
'returnMessage' => '', # FormalParameters of workflow
},
'EXCEPTION' => # defined by Kai
{
'SYSTEM' =>
{
},
'APPLICATION' =>
{
},
},
'ACTION' => # call-back functions (Activity/Implementation/Tool)
{
'0' => sub
{
print "The activity number '0' is under construction...\n";
return {};
},
'1' => sub
{
$data_fields = $wf->{'EOrder'}->data_fields({'orderInfo' => $doc,});
return &init2dest(shift,shift,'EOrder');
},
'6' => sub
{
print "All done. Existing...\n";
return {};
},
'8' => sub
{
print "The activity number '8' is under construction...\n";
return {};
},
'9' => sub
{
return &init2dest(shift,shift,'EOrder');
},
'10' => sub
{
print "Subprocess \"Checking Credit\" reached.\n";
print "The activity number '10' is under construction...\n";
return {};
},
'11' => sub
{
print "The activity number '11' is under construction...\n";
return {};
},
'12' => sub
{
$data_fields->{'EOrder'} = $wf->{'EOrder'}->data_fields({'orderType' => $order_type,});# modify $DATAFIELDS, 'Credit' or 'PO'
return &init2dest(shift,shift,'EOrder');
},
'32' => sub
{
$data_fields->{'EOrder'} = $wf->{'EOrder'}->data_fields({'orderInfo' => $doc,'orderNumber' => $order_ordern,});# modify $DATAFIELDS
return &init2dest(shift,shift,'EOrder');
},
'39' => sub
{
$data_fields->{'EOrder'} = $wf->{'EOrder'}->data_fields({'orderNumber' => $order_ordern,});# modify $DATAFIELDS
return &init2dest(shift,shift,'EOrder');
},
'41' => sub
{
$data_fields->{'EOrder'} = $wf->{'EOrder'}->data_fields({'orderInfo.AccountNumber' => $order_actno,'orderInfo.ToltalAmount' => $order_total});# modify $DATAFIELDS, 'Credit' or 'PO'
return &init2dest(shift,shift,'EOrder');
},
'56' => sub
{
print "The activity number '56' is under construction...\n";
return {};
},
},
},
$wfp_id->{'FillOrder'} => # workflow ID
{
'IN' =>
{
'orderString' => 'BBB',
},
'OUT' =>
{
'returnMessage' => '',
},
'EXCEPTION' =>
{
'SYSTEM' =>
{
},
'APPLICATION' =>
{
},
},
'ACTION' =>
{
'0' => sub
{
print "The activity number is under construction...\n";
return {};
},
'1' => sub
{
$data_fields = $wf->{'FillOrder'}->data_fields({'orderInfo' => $doc,});# modify $DATAFIELDS
return &init2dest(shift,shift,'FillOrder');
},
},
},
$wfp_id->{'CreditCheck'} => # workflow ID
{
'IN' =>
{
'orderString' => 'CCC',
},
'OUT' =>
{
'returnMessage' => '',
},
'EXCEPTION' =>
{
'SYSTEM' =>
{
},
'APPLICATION' =>
{
},
},
'ACTION' =>
{
'0' => sub
{
print "The activity number is under construction...\n";
return {};
},
'1' => sub
{
$data_fields = $wf->{'CreditCheck'}->data_fields({'orderInfo' => $doc,});# modify $DATAFIELDS
return &init2dest(shift,shift,'CreditCheck');
},
},
},
};
######### Finished definition, starting workflow engine #########################
print "The starting activity ID is $init_act_id->{'EOrder'}->[0]\n\n";
my $out = $wf->{'EOrder'}->start_workflow($wfp_id,$wf_param,$init_act_id,'EOrder');
ok($out, "end");
sub init2dest
{
my ($init_act_id,$dest_act_id,$wfp_name) = (shift,shift,shift);
my @dest_act_id;
eval{@dest_act_id = @$dest_act_id;};
@dest_act_id = () if($@);
# modify $DATAFIELDS in the following way: slurping a purchase order
# for a given activity ID and a set of corresponding paramters produce the next activity ID
foreach(@$init_act_id){ # TODO: using thread to make parallel calculations
my $dest_id = $wf->{$wfp_name}->get_dest_id($cust_lib,$wfp_id,$wfp_name,$wf,$wf_param,$init_act_id,$_);
push @dest_act_id, @$dest_id; # and acumulate new destination IDs
}
return \@dest_act_id;
}