390 likes | 608 Views
Advanced Techniques in IBM Rational ClearQuest Customization. Shmuel Bashan IBM Rational Bashansh@il.ibm.com. The agenda. Save as / Load Default in Record Form Automatically change state Dynamic Workflow Using Roles Optimize the use of Email Rules Display the state machine chart
E N D
Advanced Techniques in IBM Rational ClearQuest Customization Shmuel Bashan IBM Rational Bashansh@il.ibm.com
The agenda • Save as / Load Default in Record Form • Automatically change state • Dynamic Workflow • Using Roles • Optimize the use of Email Rules • Display the state machine chart • Modify All Fields
1.0 Save as / Load Default in Record Form • The Problem: The “Save Default” function is operational only during the submit action (Submit Form). In many cases it is needed to have this functionality also in the Record Form. • The Solution: • Create 2 buttons on the Record Form • Create a stateless record type (to store the data) • Write the script to save / load the record fields.
1.1 Save as Default - Record Script my @fields_to_save = ( … list of fields names … ); my %defaultvalues = (); foreach my $fieldname (@fields_to_save) { my $value = $entity->GetFieldValue($fieldname)->GetValue(); $defaultvalues{$fieldname} = $value; } my $defaultstring = join("::", %defaultvalues); my $userdefault = GetUserDefaults(); # get the user default record return "" if (!$userdefault); my $session = $entity->GetSession(); $session->EditEntity($userdefault, "Modify"); $userdefault->SetFieldValue("DefaultValues", $defaultstring); $result = $userdefault->Validate();
1.2 Load Default - Record Script my $userdefault = GetUserDefaults(); return "" if (!$userdefault); my $defaultstring = $userdefault->GetFieldValue("DefaultValues")->GetValue(); my %defaultvalues = split(/::/, $defaultstring); my @fields_to_load = ( … list of fields names … ); foreach my $fieldname (@fields_to_load) { my $value = $defaultvalues{$fieldname}; $entity->SetFieldValue($fieldname, "$value"); }
2.0 Automatically change state • The Problem: In many cases the same user is required to go over 2 different actions one after the other. This is a waist of time. In other cases the state can be changes depending on data entered by the user. This can save time and prevent errors. • The Solution: • When the rules are predefined a script can perform the action automatically. • Write a notification hook that create a session and change the record state.
2.1 Automatically change state – The Technique • Can be performed only in action notification hook • Create new ClearQuest session • Logon to the database (Caveat: password is exposed in the script) • Get the record entity object • Edit the entity using the action of type change_state • Validate • Commit or Revert
2.2 Auto-change state – Submit Notification hook Rem - If Owner and Priority has value move to Assigned if ( "" <> GetFieldValue("Owner").GetValue AND _ "" <> GetFieldValue("Priority").GetValue ) then ThisID = GetDisplayName set newses = CreateObject("CLEARQUEST.SESSION") newses.UserLogon “user", “passwd", “userDB", _ AD_PRIVATE_SESSION, “dbset" set EntityObj = newses.GetEntity("defect", ThisID) newses.EditEntity EntityObj , "Assign" status = EntityObj.Validate EntityObj.Commit end if
3.0 Dynamic Workflow • The problem: ClearQuest state machine is static. In some organizations the same record type should have a dynamic state machine based on mangers decision (or predefined rules). • The solution: • The user performs an action called “Next” • Intialization hook will set the fields requiredness. • Notification hook will move the record to the correct state according to the predefined rules.
3.2 Dynamic Workflow – The technique • The solution is based on the technique described in item 2 • Add an action “Next” of type modify , and : • Write a Notification hook to move the record to the correct state according to the predefined rules. • Write an Intialization hook to set the fields requiredness. • Optionally add “Navigation Tab” to set the rules. • The full solution was published in the RDN, and we shall not describe it in details.
3.3 Dynamic Workflow – Notification Hook Rem Create new session and log as user ; get state, entity, etc. . . . Rem Find the required action Select Case Cur_state Case “Submitted” If (GetFieldValue("Req_CCB").GetValue = “Yes” ) then NextAction = “toCCB” Else NextAction = “Analize” End if Case “Analyzed” NextAction = “Assign” . . . All other cases … End Select newsesion.EditEntity EntityObj , NextAction
3.4 Dynamic Workflow – Initialization Hook Rem get state, entity, etc. . . . Rem Find the required action Select Case Cur_state Case "Submitted" If (GetFieldValue("Req_CCB").GetValue = "Yes" OR IType = "Feature" ) then Else SetFieldRequirednessForCurrentAction "Owner", AD_MANDATORY SetFieldRequirednessForCurrentAction "Priority", AD_MANDATORY End if Case "CCB" SetFieldRequirednessForCurrentAction "Owner", AD_MANDATORY SetFieldRequirednessForCurrentAction "Priority", AD_MANDATORY . . . All other cases … End Select
4.0 Using Roles • The problem: There is no “role” object in ClearQuest. A “role” is a key concept in RUP and using it simplifies and modularizes the CQ schema implementation. • The solution: We shall propose some solutions based on different techniques, each one has higher level of complexity: • Based on groups • Based on addition fields in the area record • Based on new stateless record type
Role: Set of activities to be performed by some users. Area : Organization domain, Product domain that characterize the CR Examples : SW Product , Project , Module, We can define 2 types of roles Single Only ONE user can have a specific role in a specific role area Multiple Some users can have the same role in a specific role area Examples: Project Manager is role of type single Analyst is role of type multiple CCB may be role of type single or multiple 4.1 Types of Roles
4.4 Automatic Responsible assignment hook Function Defect_Validation(actionname, actiontype) ' Action is Assign_Owner of type Base . . . ' Check condition - if new module was selected originalValue = GetFieldOriginalValue("module").GetValue currentValue = GetFieldValue("module").GetValue If currentValue <> originalValue Then ' Look for the Group Leader of this Module set moduleObj = sessionObj.GetEntity("Module",currentValue) lead = moduleObj.GetFieldValue("leader").GetValue SetFieldValue "responsible", lead End If End Function
4.8 Responsible assignment using Role Object The following hook uses the Role record type to select the user that need to be assigned as responsible. Area = GetFieldValue (“Area").GetValue Rem Generate the Unique Key from 2 fields Ukey = “PM” & “ “ & Area Rem Get the role object set RoleObj = sessionObj.GetEntity(“Roles", Ukey ) ProjectManager = RoleObj .GetFieldValue(“UserName").GetValue SetFieldValue "responsible", ProjectManager
5. Optimize the use of Email Rules • The problem: Email rules are very easy to use but have disadvantages: formatting the email subject and body, and rules logic are limited. • The above require us to define several Email-rules, It takes about one second to process each rule. • The solution: By using only few more fields and few scripts we can overcome the limitations.
5.1 Optimize the use of Email Rules • Add to the state based record type the following fields: Email_To (short string) Email_Subject (short string) And optionally: Email_CC (short string) Email_Body (multiline string) • Add a Validation Hook to any base action to populate the Email_* fields • Create one Email Rule • Email_To (in fields to check for change) • Email_Subject (in subject fields)
5.2 Optimize the use of Email Rules – Base action validation Hook Rem - Get id, initiator, action, owner …. my $actionname = $entity->GetActionName(); if ($actionname eq “Assign") { $subj = " SR# $id, was assigned to you by $old_ownername." ; $newmail = $entity->GetFieldValue(“Owner.email")->GetValue(); }else { if ($actionname eq "Postpone") { $subj = " SR# $id, was Postponed by $old_ownername." ; $newmail = $entity->GetFieldValue("Initiator.email")->GetValue(); }else { . . . Other conditions } $entity->SetFieldValue( "Email_To", $newmail ); $entity->SetFieldValue("Email_Subject", $subj );
6.0 Display the state machine chart • The problem: A complex state machine can confuse some users. A user can benefit from the ability to view a graphic chart of the state machine, so he can understand the meaning of each action. • The solution: Add a button with record script that activates simple script which popup the flow diagram.
6.1 Display the state machine chart Function scr_Life_Cycle(param) ' param As Variant ' record type name is SCR Dim wsh set wsh = CreateObject("wscript.shell") wsh.run \\server\shared_directory\CQ\life-cycle.ppt End Function
7.0 Modify All Fields • The problem: In some cases (usually caused by schema changes or after import ) it is needed to edit fields that are in read-only mode. • The solution: • Create an action of type modify – “ModifyAll” • Access control hook limits the action to CQ admin • The initialization hook changes the requiredness of all the fields to optional.
7.1 Modify All Fields – Initialization hook sub issue_Initialization { my($actionname, $actiontype) = @_; # $actionname as string scalar # $actiontype as long scalar # action is ModifyALL # record type name is Issue $sessionobj = $entity->GetSession(); $fieldnamelist = $entity->GetFieldNames(); foreach my $fieldname (@$fieldnamelist) { $entity->SetFieldRequirednessForCurrentAction( $fieldname, $CQPerlExt::CQ_OPTIONAL); } }
Thank You Shmuel Bashanbashansh@il.ibm.com