Exercise: Build the Processing Logic for the Food Bank Inventory Business Process

Before a business process starts, the parameter values are created and gathered into a parameter set THAT is saved to a custom parameter table. When the business process starts, the ID of the parameter set is passed to the processing logic. The processing logic for a business process occurs within a .NET CLR class that exists within an assembly that is deployed on the Infinity web server. This code runs within the web services layer. Within this CLR class file, the parameter set values are retrieved and the processing on the data begins in earnest. How the processing occurs is up to you and the output data format is completely open.

We will build a server side processing logic for a custom business process within this exercise. The logic will utilize four parameter values as defined by a configured parameter set.

Figure: A parameter set is defined and passed to a business process that creates an output such as a database table.

In this exercise, we will also utilize two QueryViewSpecs as choices for the Output Format parameter. We also create two ad-hoc queries to create two selections as options for the Selection parameter

A QueryViewSpec can be used as a parameter to define the output format and help define the processing logic

A common practice is to use a QueryViewSpec to define the output format/columns. A reference to the QueryViewSpec/output format can be passed to the business process instance as a parameter within the parameter set. Different parameter sets can contain references to different QueryViewSpecs which in turn affects how the data is processed and which columns appear within the final output.

Step 1 -  Review the business process logic.

Step 2 -  Add the BusinessProcessSpec and associated Visual Basic class to the catalog project.

Step 3 -  Inspect the ProcessorComponent XML element.

Open and inspect the BusinessProcessSpec. A BusinessProcessSpec is used to reference the .NETclass. The ProcessorComponenttag references the assembly name and a fully qualified class name that contains the processing logic. The fully qualified class name consists of the class name (InventoryProcessBusinessProcess) appended to the assembly name (Blackbaud.CustomFx.FoodBank.Catalog).

<BusinessProcessSpec
	xmlns="bb_appfx_businessprocess"
	xmlns:common="bb_appfx_commontypes"
	ID="069c24cc-1202-4f55-b701-f35e2f8b720c"
	Name="InventoryProcess Business Process"
	Description="REPLACE_WITH_DESCRIPTION"
	Author="SALESDEMO\TechTrainUser10"
	GeneratesOutput="false"
	ParameterTableName="REPLACE_WITH_PARAMETERTABLENAME"
	RecordType="REPLACE_WITH_RECORDTYPE"
	common:SecurityUIFolder="REPLACE_WITH_SECURITYUIFOLDER">
	
	<ProcessorComponent AssemblyName="Blackbaud.CustomFx.FoodBank.Catalog.dll" 
                      ClassName="Blackbaud.CustomFx.FoodBank.Catalog.InventoryProcessBusinessProcess" />
                                                                     
  <common:FormMetaData>
		<common:FormFields>
			<common:FormField Caption="REPLACE_WITH_CAPTION" 
                        DataType="REPLACE_WITH_DATATYPE" 
                        Description="REPLACE_WITH_DESCRIPTION" 
                        FieldID="REPLACE_WITH_FIELDID" />
		</common:FormFields>
	</common:FormMetaData>

</BusinessProcessSpec>

Figure: Sample BusinessProcessSpec

Your business process processing occurs within a .NET class that inherits from Blackbaud's AppCatalog.AppBusinessProcess class. Overriding the Validate() sub within this class enables you to retrieve the parameter set values for the instance. Overriding the StartFunctionBusinessProcess() function enables you to write code that processes the data and produce the output. StartFunctionBusinessProcess() will send back an object of type Blackbaud.AppFx.Server.AppCatalog.AppBusinessProcessResult which provides the Infinity platform with the number of records successfully process and the number of exceptions, if any.

For more information, see Business Process Spec and Business Process Logic

Step 4 -  Modify the BusinessProcessSpec XML element.

Modify the values for the following attributes within the BusinessProcessSpec XML element.  Use the example below as a guide.

<BusinessProcessSpec
	xmlns="bb_appfx_businessprocess"
	xmlns:common="bb_appfx_commontypes"
	ID="a28d4f17-53fe-48d9-85bc-37e12884dc00"
	Name="Inventory Process Business Process"
	Description="Business process to get the inventory report for food banks."
	Author="Technical Training"
	GeneratesOutput="true"
	ParameterTableName="USR_INVENTORYPROCESS"
	RecordType="Inventory Process Parameter" 
	common:SecurityUIFolder="Constituent\Food Bank\Inventory
	ParameterLabelField="NAME">
   
	<ProcessorComponent AssemblyName="Blackbaud.CustomFx.FoodBank.Catalog" 
   ClassName="Blackbaud.CustomFx.FoodBank.Catalog.InventoryProcessBusinessProcess">

Note: When defining a parameter set table, a NAME column or some other column should be used to represent the label for the business process parameter set. This table column corresponds with the BusinessProcessSpec element's ParameterLabelField attribute which is used to identify the name of the field in the parameter table which represents the label for the parameter set. If the ParameterLabelField attribute for the BusinessProcessSpec element is not specified, NAME is used as the default. If the default is used and NAME does not exist on the parameter table, loadspec will throw an error. We recommend you explicitly identify the ParameterLabelField in your business process specs.

Step 5 -  Add the USR_USP_INVENTORYPROCESS_GETPARAMETERS stored procedure.

When our business process logic starts, the parameters for the designated parameter set ID is retrieved from the custom business process parameter set table that we created in a previous exercise. In this step, we will add a stored procedure to accept a designated primary key value from the custom parameter set table (USR_INVENTORYPROCESS). This value represents a chosen parameter set that is utilized by the business processing logic. The stored procedure retrieves the IDSETREGISTERSETID, which represents a selection to limit the rows that require processing, and the OUTPUTVIEWID, which represents the output format or the columns created by the business process.

For more information on how the parameter set data is retrieved and utilized within the processing logic, see SQLStoredProcedureSpec to Retrieve the Parametes within the Processing Code and Business Process:  StartBusinessProcess().

Let's add a new SQLStoredProcedureSpec to our food bank catalog project.

Step 6 -  Modify the BusinessProcessSpec and grant permission to the database objects that the processing logic uses.

Let's go back and modify the BusinessProcessSpec to add some XML to grant permission to specific database object for our processing logic.

<BusinessProcessSpec
	xmlns="bb_appfx_businessprocess"
	xmlns:common="bb_appfx_commontypes"
	ID="a28d4f17-53fe-48d9-85bc-37e12884dc00"
	Name="Inventory Process Business Process"
	Description="Business process to get the inventory report for food banks."
	Author="Technical Training"
	GeneratesOutput="true"
	ParameterTableName="USR_INVENTORYPROCESS"
	RecordType="Inventory Process Parameter"
	common:SecurityUIFolder="Constituent\Food Bank\Inventory">

  <ProcessorComponent AssemblyName="Blackbaud.CustomFx.FoodBank.Catalog"
   ClassName="Blackbaud.CustomFx.FoodBank.Catalog.InventoryProcessBusinessProcess">

    <!-- Grant execution rights to the stored procedure to get parameters 
    and the UFN used to filter the selection results.
		UFN_IDSETREADER_GETRESULTS is a built-in table-value function that 
    returns a list of GUIDs based on a selection ID.-->
    <common:GrantExecuteList>
<common:GrantExecute>USR_USP_INVENTORYPROCESS_GETPARAMETERS</common:GrantExecute>
    </common:GrantExecuteList> 
    <common:GrantSelectList>
      <common:GrantSelect>USR_FOODBANK</common:GrantSelect>
		 <common:GrantSelect>UFN_IDSETREADER_GETRESULTS</common:GrantSelect>
      <common:GrantSelect>USR_UFN_FOODBANKSELECTION</common:GrantSelect>
    </common:GrantSelectList>
  </ProcessorComponent>

Step 7 -  Remove the FormMetaData.

Remove the default FormMetaData element and child XML elements from the BusinessProcessSpec.

This element defines a pre-process Edit Data Form to use when the business process does not have parameters saved to a database table. This is a mechanism to display a form fields in the user interface after the business process starts but before processing shifts to the business processor code on the web server. We will not need the FormMetaData XML element, so we remove this tag. For more information about this element, see FormMetaData and Managing Parameter Sets and Starting a Business Process with a Pre-Process Edit Data Form.

Step 8 -  Add the BusinessProcessOutputHeader XML element.

The BusinessProcessOutputHeader XML element describes how to designate a view to generate an output header file for a business process.

Step 9 -  Save and load the BusinessProcessSpec.

Loading the spec adds a row to the Business Process Spec catalog table.

Step 10 -  Filter the Tables for our new parameter set table.

Step 11 -  Review the ERD for the business process.

Take a few minutes to review the entity relationship diagram for the business process

Step 12 -  Add two QueryViewSpecs for the Output Format parameter.

A best practice is to use a QueryViewSpec to define the output format of a business process. Typically, before starting an instance, an end user may select a reference to a specific QueryViewSpec as one of the input parameters into a process. Different parameter sets can contain references to different QueryViewSpecs, which in turn affect how the data is processed and which columns appear within the final output. In short, a QueryViewSpec can be used to drive the columns of data created by a business process.

Note: The best practice to define the output columns is to utilize a reference to an Output Format QueryViewSpec as a parameter value into the business process instance. The QueryViewSpec defines a database view.

For more information, see Business Process Parameters and Using a QueryViewSpec as a Parameter for Output Formatting.

Step 13 -  Add the code for the business process logic to the VB class file.

Tip:

Closing Connections

Sometimes your code requires an unmanaged resource, such as a SQL connection. If the SqlConnection goes out of scope, it won't be closed. Therefore, you must explicitly close the connection by calling Close or Dispose. You may also consider a Using block which guarantees the disposal of one or more such resources when your code is finished with them. For more information see http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.close.aspx and http://msdn.microsoft.com/en-us/library/htd05whh.aspx.

For example, the following code would require the explicit closing of the connection:

Dim conn As SqlConnection = Me.RequestContext.OpenAppDBConnection
		‘code to perform work with the sql connection
conn.Close

Whereas utilizing a Using block guarantees the disposal of the SQLConnection:

using conn As SqlConnection = Me.RequestContext.OpenAppDBConnection
        ‘code to perform work with the sql connection
end using

Step 14 -  Build and deploy the Blackbaud.CustomFx.FoodBank.Catalog assembly.

With Infinity development, a catalog is an assembly (.dll file) that contains embedded Catalog Items (specs) as resources. The catalog assembly also holds our VB file that contains our business process class.