Select your user interface:
History Tab
The History tab typically contains one section referencing a custom data list that returns a status list for the business process.
The data list is a custom CLR-based data list, which means the code to retrieve the data for the data list is implemented as a .NET CLR class. While the data list is a custom list, Blackbaud recommends leveraging this CLR class that comes with the product which does the dirty work of retrieving the status history.
A CLR-based spec type defines the server-side catalog implementation that will be used to fetch the data for the list. Use this spec type when complex logic is required or when you need to pull data together from atypical data sources. A CLR Data List Spec requires an XML element named CLRDataList that describes a data list based on CLR code. The CLR code is implemented within a .NET class that resides within a .NET CLR assembly hosted in the web service layer. The .NET class should inherit Blackbaud.AppFx.Server.AppCatalog.AppDataList. The CLRDataList XML element can contain a list of parameters that match a set of public variables within the .NET CLR class file. When the Infinity user interface calls upon the CLR data list to display a list of data, the GetListResults() function is called on the .NET CLR class file. GetListResults() is responsible for gathering the data for the data list and returning the data as type Blackbaud.AppFx.Server.AppCatalog.AppDataListResult.
The CLR code will pull a status history from the BusinessProcessCatalog and BusinessProcessStatus tables for a given specific BusinessProcessCatalog.ID. Below is a sample Data List Spec. The CLR class assembly and class name are highlighted in yellow. The parameters passed to the class are highlighted in blue.
<DataListSpec xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ID="7ff36611-ac9d-4ae2-a3f8-900fca2f24c2" Name="Inventory Process Business Process Status List" Description="Returns a status list for the inventory process businessbusiness process." Author="Technical Training" common:SecurityUIFolder="Constituent\Food Bank\Inventory" xmlns:common="bb_appfx_commontypes" xmlns="bb_appfx_datalist"> <CLRDataList AssemblyName="Blackbaud.AppFx.Platform.Catalog" ClassName="Blackbaud.AppFx.Platform.Catalog.BusinessProcessStatusDatalist"> <common:GrantSelectList> <common:GrantSelect>BUSINESSPROCESSCATALOG</common:GrantSelect> <common:GrantSelect>BUSINESSPROCESSSTATUS</common:GrantSelect> <common:GrantSelect>APPUSER</common:GrantSelect> </common:GrantSelectList> <common:StaticParameters> <common:ParameterList> <common:Param ID="BusinessProcessCatalogID"> <common:Value>a28d4f17-53fe-48d9-85bc-37e12884dc00</common:Value> </common:Param> <common:Param ID="ApplyParametersIDFilter"> <common:Value>True</common:Value> </common:Param> </common:ParameterList> </common:StaticParameters> </CLRDataList> <Parameters> <common:FormMetaData> <common:FormFields> <common:FormField FieldID="StatusCode" Caption="Status"> <common:ValueList> <common:Items> <common:Item> <common:Value>0</common:Value> <common:Label>Completed</common:Label> </common:Item> <common:Item> <common:Value>1</common:Value> <common:Label>Running</common:Label> </common:Item> <common:Item> <common:Value>2</common:Value> <common:Label>Did not finish</common:Label> </common:Item> </common:Items> </common:ValueList> </common:FormField> </common:FormFields> </common:FormMetaData> </Parameters> <Output> <OutputFields> <OutputField FieldID="ID" Caption="ID" IsHidden="true" DataType="Guid" /> <OutputField FieldID="Process name" Caption="Process name" IsHidden="true" DataType="String" /> <OutputField FieldID="Status" Caption="Status" DataType="String" /> <OutputField FieldID="Status message" Caption="Status message" DataType="String" /> <OutputField FieldID="Started by" Caption="Started by" DataType="String" /> <OutputField FieldID="Started on" Caption="Started on" DataType="Date" /> <OutputField FieldID="Ended on" Caption="Ended on" DataType="Date" /> <OutputField FieldID="Duration" Caption="Duration" DataType="String" /> <OutputField FieldID="Number of records processed" Caption="Number of records processed" DataType="String" /> <OutputField FieldID="NumberOfExceptionRecords" Caption="Number of exception records" DataType="String" /> <OutputField FieldID="Total count" Caption="Total count" IsHidden="true" DataType="String" /> <OutputField FieldID="Server name" Caption="Server name" DataType="String" /> <OutputField FieldID="ImageKey" Caption="ImageKey" IsHidden="true" DataType="String" /> <OutputField FieldID="Completed" Caption="Completed" IsHidden="true" DataType="String" /> <OutputField FieldID="EnableDownload" Caption="EnableDownload" IsHidden="true" DataType="String" /> <OutputField FieldID="EnableLetterMailMerge" Caption="EnableLetterMailMerge" IsHidden="true" DataType="String" /> <OutputField FieldID="EnableLabelMailMerge" Caption="EnableLabelMailMerge" IsHidden="true" DataType="String" /> </OutputFields> </Output> </DataListSpec>
Below is the code for the Blackbaud.AppFx.Platform.Catalog.BusinessProcessStatusDatalist class that does the heavy lifting of retrieving the status history data for the data list. Within the class, GetListResults() is responsible for gathering the data for the data list and returning the data as type Blackbaud.AppFx.Server.AppCatalog.AppDataListResult.
Imports Blackbaud.AppFx.Server
Imports System.Data.SqlClient
Public NotInheritable Class BusinessProcessStatusDatalist
Inherits AppCatalog.AppDataList
Public FilterBusinessProcessInstanceID As Guid = Guid.Empty 'this is passed from the filter panel
Public BusinessProcessCatalogID As String = String.Empty
Public StatusCode As Nullable(Of Integer)
Public ApplyParametersIDFilter As Boolean = False
Public RowsToReturn As Nullable(Of Integer)
Public StartedDateRangeType As Nullable(Of Integer)
Public StartedDateSpecificDate As Nullable(Of Date)
Public Enum ProcessStatusImage
check = 0
businessprocessspec
warning
x_16
End Enum
'Private Const STATUSTABLESUFFIX As String = "STATUS"
Private Enum FieldsList
ID
ProcessName
Status
StatusMessage
StartedBy
StartedOn
EndedOn
Duration
NumberOfRecordsProcessed
NumberOfExceptionRecords
TotalCount
ServerName
ImageKey
Completed
EnableDownload
EnableLetterMailMerge
EnableLabelMailMerge
'EnableMultipleLetterMailMerge deprecated
ParameterSetName
BusinessProcessCatalogID
ParameterSetID
End Enum
Public Overrides Function GetListResults() As AppFx.Server.AppCatalog.AppDataListResult
If BusinessProcessCatalogID = "=ContextID" Then
BusinessProcessCatalogID = ProcessContext.ContextRecordID
Else
If FilterBusinessProcessInstanceID <> Guid.Empty Then
BusinessProcessCatalogID = FilterBusinessProcessInstanceID.ToString()
End If
End If
Dim builder As New Text.StringBuilder
With builder
.Append("select ID, ")
.Append("ProcessName, ")
.Append("Status, ")
.Append("StatusMessage, ")
.Append("StartedBy, ")
.Append("StartedOn, ")
.Append("EndedOn, ")
.Append("Duration, ")
.Append("NumberOfRecordsProcessed, ")
.Append("NumberOfExceptionRecords, ")
.Append("TotalCount, ")
.Append("ServerName, ")
.Append("ImageKey, ")
.Append("Completed, ")
.Append("EnableDownload, ")
.Append("EnableLetterMailMerge, ")
.Append("EnableLabelMailMerge, ")
'.Append("EnableMultipleLetterMailMerge, ") deprecated
.Append("coalesce(ParameterSetName,'') ")
.Append("from dbo.UFN_BUSINESSPROCESSSTATUS_STANDARDDATALISTVALUES_ROWSTORETURNSTARTEDDATE(@BUSINESSPROCESSCATALOGID, @PARAMETERSETID, @STATUSCODE, @ROWSTORETURN, @STARTEDDATERANGETYPE, @STARTEDDATESPECIFICDATE) ")
.Append("order by StartedOn desc")
End With
Dim command As New SqlCommand(builder.ToString)
If ApplyParametersIDFilter Then
Dim ctxID As String = Me.ProcessContext.ContextRecordID
If String.IsNullOrEmpty(ctxID) Then
Throw New ServiceException("The ContextRecordID must be specified for this BusinessProcessStatusDataList", ServiceErrorCode.InvalidAPIUse)
End If
command.Parameters.AddWithValue("@PARAMETERSETID", New Guid(ctxID))
Else
command.Parameters.AddWithValue("@PARAMETERSETID", DBNull.Value)
End If
If BusinessProcessCatalogID <> String.Empty Then
command.Parameters.AddWithValue("@BUSINESSPROCESSCATALOGID", New Guid(BusinessProcessCatalogID))
Else
command.Parameters.AddWithValue("@BUSINESSPROCESSCATALOGID", DBNull.Value)
End If
AddNullableIntegerParameter(command, "@STATUSCODE", StatusCode)
AddNullableIntegerParameter(command, "@ROWSTORETURN", RowsToReturn)
AddNullableIntegerParameter(command, "@STARTEDDATERANGETYPE", StartedDateRangeType)
AddNullableDateParameter(command, "@STARTEDDATESPECIFICDATE", StartedDateSpecificDate)
Dim reader As SqlDataReader
Dim resultList As New Generic.List(Of DataListResultRow)
Using conn As SqlClient.SqlConnection = Me.RequestContext.OpenAppDBConnection
SpWrap.USP_BUSINESSPROCESSSTATUS_VALIDATESTATUS.ExecuteNonQuery(conn)
command.Connection = conn
reader = command.ExecuteReader(CommandBehavior.CloseConnection)
Do While reader.Read
Dim result As New DataListResultRow
Dim valueList As New Generic.List(Of String)
valueList.Add(reader.GetGuid(FieldsList.ID).ToString)
valueList.Add(reader.GetString(FieldsList.ProcessName))
valueList.Add(reader.GetString(FieldsList.Status))
valueList.Add(reader.GetString(FieldsList.StatusMessage))
valueList.Add(reader.GetString(FieldsList.StartedBy))
valueList.Add(FormatFieldForList(reader.GetDateTime(FieldsList.StartedOn)))
If reader.IsDBNull(FieldsList.EndedOn) Then
valueList.Add(String.Empty)
Else
valueList.Add(FormatFieldForList(reader.GetDateTime(FieldsList.EndedOn)))
End If
valueList.Add(reader.GetString(FieldsList.Duration))
valueList.Add(reader.GetInt32(FieldsList.NumberOfRecordsProcessed).ToString)
valueList.Add(reader.GetInt32(FieldsList.NumberOfExceptionRecords).ToString)
valueList.Add(reader.GetInt32(FieldsList.TotalCount).ToString)
valueList.Add(reader.GetString(FieldsList.ServerName))
valueList.Add(reader.GetString(FieldsList.ImageKey))
valueList.Add(reader.GetBoolean(FieldsList.Completed).ToString)
valueList.Add(reader.GetBoolean(FieldsList.EnableDownload).ToString)
valueList.Add(reader.GetBoolean(FieldsList.EnableLetterMailMerge).ToString)
valueList.Add(reader.GetBoolean(FieldsList.EnableLabelMailMerge).ToString)
valueList.Add(Boolean.FalseString) ' deprecated -- left in so as not to break dependent specs
valueList.Add(reader.GetString(FieldsList.ParameterSetName).ToString)
valueList.Add(BusinessProcessCatalogID)
If ApplyParametersIDFilter Then
valueList.Add(Me.ProcessContext.ContextRecordID)
End If
result.Values = valueList.ToArray
resultList.Add(result)
Loop
End Using
Return New AppCatalog.AppDataListResult(resultList)
End Function
Private Sub AddNullableIntegerParameter(ByVal command As SqlClient.SqlCommand, ByVal parameterName As String, ByVal integerValue As Nullable(Of Integer))
If Not integerValue.HasValue Then
integerValue = -1
End If
command.Parameters.AddWithValue(parameterName, integerValue)
End Sub
Private Sub AddNullableDateParameter(ByVal command As SqlClient.SqlCommand, ByVal parameterName As String, ByVal dateValue As Nullable(Of Date))
If dateValue.HasValue Then
command.Parameters.AddWithValue(parameterName, dateValue.Value)
Else
command.Parameters.AddWithValue(parameterName, DBNull.Value)
End If
End Sub
End Class