How to do it...

To create the manual workflow task, follow these steps:

  1. We need a new Base Enum for the inspection status, as this will be used both to see whether a vehicle has been inspected and also to control the state of the workflow task; name it ConWHSVehInspStatus and create the elements as shown in the following table:

Element

Label

Description

NotInspected

Not inspected

This vehicle has not yet been inspected

Waiting

Waiting

This workflow has been submitted, but has not yet been allocated an approver

InProgress

InProgress

This workflow has been allocated to one or more workers to perform the task

Completed

Completed

This workflow has been completed

  1. Create a new Date EDT for ConWHSVehInspDate, setting the properties as follows:

Field

EDT/Enum

Description

Extends

TransDate

This EDT should be used for all dates.

Label

Date inspected

Create a named label for this, such as @ConWHS:DateInspected.

Help Text

The date the inspection was carried out

This is left generic and not tied to its eventual implementation in order to make the EDT reusable. The help text does not reference the vehicle for this reason.

  1. Add the following fields to the vehicle table and set the Allow Edit and Allow Edit On Create to No:

Field

EDT / Enum

Description

InspStatus

ConWHSVehInspState

This is the status Base Enum created in the previous step

InspComment

WorkflowComment

This will hold the last note when the task is completed

InspDate

ConWHSVehInspDate

This is the date on which the workflow task was completed

  1. Create a field group named Inspection and set the Label property to a label for Inspection. Add the fields to this group and then add the field group to a suitable place in the ConWHSVehicleTable form.
  2. Next, let's add a status handler class; create a new class name, ConWHSVehicleInspStatusHandler. Create a method to handle the status change, and set the InspComment and InspDate fields from the method's parameters. The code is written as follows:
/// <summary> 
/// Handle the inspection date change
/// </summary>
/// <param name = "_vehicleRecId">
/// The record id of the vehicle
/// </param>
/// <param name = "_status">
/// The new status
/// </param>
/// <param name = "_comment">
/// Comment is set when the status
/// is complete
/// </param>
/// <param name = "_inspDate">
/// InspDate is set when the
/// status is complete
/// </param>
public static void SetStatus(RefRecId _vehicleRecId,
ConWHSVehInspStatus _status,
WorkflowComment _comment = '',
ConWHSVehInspDate _inspDate = dateNull())
{
ConWHSVehicleTable vehicle;

ttsbegin;
select forupdate vehicle
where vehicle.RecId == _vehicleRecId;
if(vehicle.RecId != 0)
{
vehicle.InspStatus = _status;
// if the inspection is complete set
// the comment and inspection date fields
// otherwise clear them, as the workflow
// may have been cancelled.
switch (_status)
{
case ConWHSVehInspStatus::Complete:
vehicle.InspComment = _comment;
vehicle.InspDate = _inspDate;
break;
default:
vehicle.InspComment = '';
vehicle.InspDate = dateNull();
}
vehicle.update();
}
ttscommit;
}
  1. Against the project, add a new item and choose Workflow Task from the Business process and Workflow list. Use the ConWHSVehWFInspect name and click on Add.
  2. Configure the Workflow Task dialog as shown in the following screenshot:
  1. Click on Next.
  2. On the next page, choose Complete in the Type drop-down list, and enter Complete in the field before clicking on Add.
You can add further outcomes, which will follow the same pattern when implemented.
  1. Click on Next and then Finish.
  2. For each action menu item created by the wizard, complete the Label and Help Text properties.
You may recognize that the code generated by this process is very similar to the Workflow approval. We will follow that pattern again by handling the required methods in the ConWHSVehWFInspectEventHandler class.
  1. Since we don't handle all of the possible outcomes, we should only implement the required interfaces. Also, in order to have access to the ValidateContext method, we should extend ConWHSVehWFBase. The class declaration should read as shown here:
public final class ConWHSVehWFInspectEventHandler 
extends ConWHSVehWFBase
implements WorkflowElementCanceledEventHandler,
WorkflowElementCompletedEventHandler,
WorkflowElementStartedEventHandler,
WorkflowWorkItemsCreatedEventHandler
  1. Also, remove the methods linked to the interface that we removed. Change the started method as shown here. It maintains the vehicle status and inspection status fields:
public void started( 
WorkflowElementEventArgs _workflowElementEventArgs)
{
WorkflowContext context;
context =
_workflowElementEventArgs.parmWorkflowContext();
if(this.ValidateContext(context))
{
ConWHSVehicleInspStatusHandler::SetStatus(
context.parmRecId(),
ConWHSVehInspStatus::Waiting);

ConWHSVehicleStatusHandler::SetStatus(
context.parmRecId(),
ConWHSVehApprStatus::Inspection);
}
}
  1. The canceled method should reset both status fields back to their initial states:
public void canceled( 
WorkflowElementEventArgs _workflowElementEventArgs)
{
WorkflowContext context;
context =
_workflowElementEventArgs.parmWorkflowContext();
if(this.ValidateContext(context))
{
ConWHSVehicleInspStatusHandler::SetStatus(
context.parmRecId(),
ConWHSVehInspStatus::NotInspected);

ConWHSVehicleStatusHandler::SetStatus(
context.parmRecId(),
ConWHSVehApprStatus::Draft);
}
}
  1. The completed method needs to get the current system date, and also fetch the last comment from the workflow. This is done in the following code:
public void completed(WorkflowElementEventArgs _workflowElementEventArgs) 
{
WorkflowContext context;
context =
_workflowElementEventArgs.parmWorkflowContext();

WorkflowCorrelationId correlationId;
correlationId = context.parmWorkflowCorrelationId();

WorkflowTrackingTable trackingTable;
trackingTable =
Workflow::findLastWorkflowTrackingRecord(
correlationId);

WorkflowTrackingCommentTable commentTable;
commentTable = trackingTable.commentTable();

WorkflowComment comment = commentTable.Comment;
Timezone timezone =
DateTimeUtil::getUserPreferredTimeZone();
if(this.ValidateContext(context))
{
ConWHSVehicleInspStatusHandler::SetStatus(
context.parmRecId(),
ConWHSVehInspStatus::Complete,
comment,
DateTimeUtil::getSystemDate(timezone));
}
}
  1. Finally, write the created method. This is when the task is assigned to one or more users. The code should be written as follows:
public void created( 
WorkflowWorkItemsEventArgs _workflowWorkItemsEventArgs)
{
WorkflowContext context;
WorkflowElementEventArgs workflowArgs;
workflowArgs = _workflowWorkItemsEventArgs.
parmWorkflowElementEventArgs();
context = workflowArgs.parmWorkflowContext();
if(this.ValidateContext(context))
{
ConWHSVehicleInspStatusHandler::SetStatus(
context.parmRecId(),
ConWHSVehInspStatus::InProgress);

ConWHSVehicleStatusHandler::SetStatus(
context.parmRecId(),
ConWHSVehApprStatus::Inspection);
}
}
  1. We should also update the CanComplete method on the ConWHSVehWFBase class, but what we do here is dependent on what we want to control. We are in danger of hardcoding a business rule, which is ironically what workflows are designed to avoid. As a result of this, we just want to ensure that the document (vehicle record) is always left in a consistent state when the workflow type completes. The following piece of code will only return false if either the approval or task is in progress:
public boolean CanCompleteWF(WorkflowContext _context) 
{
ConWHSVehicleTable vehicle;
select RecId from vehicle
where vehicle.RecId == _context.parmRecId();
boolean canComplete = true;
if (vehicle.RecId != 0)
{
switch (vehicle.Status )
{
case ConWHSVehApprStatus::Revise:
case ConWHSVehApprStatus::Waiting:
case ConWHSVehApprStatus::InReview:
case ConWHSVehApprStatus::Inspection:
canComplete = false;

default:
canComplete = true;
}
switch (vehicle.InspStatus)
{
case ConWHSVehInspStatus::InProgress:
case ConWHSVehInspStatus::Waiting:
canComplete = false;
}
}
return canComplete;
}
  1. Next, complete the ConWHSVehApprWFResubmitActionMgr class as follows:
public static void main(Args _args) 
{
// The method has not been called correctly.
if (_args.record().TableId !=
tablenum(ConWHSVehicleTable)
|| _args.record().RecId == 0)
{
throw error(strfmt("@SYS19306", funcname()));
}
//Resubmit the same workflow, Workflow handles resubmit action
WorkflowWorkItemActionManager::main(_args);
// Set the workflow status to Submitted.
ConWHSVehicleInspStatusHandler::SetStatus(
_args.record().RecId,
ConWHSVehInspStatus::Waiting);

_args.caller().updateWorkflowControls();
}
  1. Finally, open the workflow type and then right-click on the Supported Elements node. Select New Workflow Element Reference and set the properties as follows:

Field

EDT / Enum

Description

Element Name

ConWHSVehWFInspect

This is the element's name

Name

TaskInspect

This is a short version of the name, prefixed with the type

Type

Task

This is the workflow element's type

  1. Copy and paste the task name into the Element Name and Name properties.
  2. Save and close all designers and code editors and build the project, followed by synchronizing the database with the project.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.28.237