Professional Documents
Culture Documents
Kinetic Bpmcookbook 2021.1
Kinetic Bpmcookbook 2021.1
BPM Cookbook
Classic
Disclaimer
This document is for informational purposes only and is subject to change without notice. This document and its
contents, including the viewpoints, dates and functional content expressed herein are believed to be accurate as of its
date of publication. However, Epicor Software Corporation makes no guarantee, representations or warranties with
regard to the enclosed information and specifically disclaims any applicable implied warranties, such as fitness for a
particular purpose, merchantability, satisfactory quality or reasonable skill and care. As each user of Epicor software is
likely to be unique in their requirements in the use of such software and their business processes, users of this document
are always advised to discuss the content of this document with their Epicor account manager. All information contained
herein is subject to change without notice and changes to this document since printing and other important information
about the software product are made or published in release notes, and you are urged to obtain the current release
notes for the software product. We welcome user comments and reserve the right to revise this publication and/or
make improvements or changes to the products or programs described in this publication at any time, without notice.
The usage of any Epicor software shall be pursuant to an Epicor end user license agreement and the performance of
any consulting services by Epicor personnel shall be pursuant to Epicor's standard services terms and conditions. Usage
of the solution(s) described in this document with other Epicor software or third party products may require the purchase
of licenses for such other products. Where any software is expressed to be compliant with local laws or requirements
in this document, such compliance is not a warranty and is based solely on Epicor's current understanding of such laws
and requirements. All laws and requirements are subject to varying interpretations as well as to change and accordingly
Epicor cannot guarantee that the software will be compliant and up to date with such changes. All statements of
platform and product compatibility in this document shall be considered individually in relation to the products referred
to in the relevant statement, i.e., where any Epicor software is stated to be compatible with one product and also
stated to be compatible with another product, it should not be interpreted that such Epicor software is compatible
with both of the products running at the same time on the same platform or environment. Additionally platform or
product compatibility may require the application of Epicor or third-party updates, patches and/or service packs and
Epicor has no responsibility for compatibility issues which may be caused by updates, patches and/or service packs
released by third parties after the date of publication of this document. Epicor® is a registered trademark and/or
trademark of Epicor Software Corporation in the United States, certain other countries and/or the EU. All other
trademarks mentioned are the property of their respective owners. Copyright © Epicor Software Corporation 2021.
All rights reserved. Not for distribution or republication. Information in this document is subject to Epicor license
agreement(s).
Classic
Revision: June 08, 2021 12:31 a.m.
Total pages: 173
sys.ditaval
BPM Cookbook Contents
Contents
Introduction............................................................................................................................5
Tips and Tricks of BPM Customization..................................................................................6
Put Customer on Credit Hold if Credit Review Date is Past Due.......................................14
Add Pre-Processing Directive to Put Order on Hold.........................................................................................15
Set Conditions........................................................................................................................................16
Evaluate Customer Credit Review Date...................................................................................................19
Set Hold, Notify, and Enable Post Processing...........................................................................................23
Review Workflow and Enable Directive...................................................................................................26
Test Directive..........................................................................................................................................27
Add Post-Processing Directive to Put Customer on Credit Hold.......................................................................29
Add Initial Workflow Elements................................................................................................................30
Try Invoking Customer.GetById Method..................................................................................................32
Add a Function.......................................................................................................................................34
Design Function Workflow......................................................................................................................36
Invoke Function......................................................................................................................................43
Test Directive..........................................................................................................................................46
Extend Post-Processing Logic to Put All Customer's Open Orders on Hold .....................................................46
Put All Open Orders on Hold...................................................................................................................46
Refresh Form Data and Reset BPM Logic.................................................................................................53
Test Directives................................................................................................................................................55
Automate Total Weight Calculation in Shipment Header.................................................58
Add a Pre-Processing Directive.......................................................................................................................58
Design Directive Workflow......................................................................................................................60
Add a Post-Processing Directive......................................................................................................................63
Link the Pre- and Post-Processing Directives............................................................................................64
Calculate Total Lines Weight...................................................................................................................65
Update Shipment Header........................................................................................................................70
Refresh Form Data..................................................................................................................................76
Review and Save Directive Workflow.......................................................................................................76
Test BPM Customization................................................................................................................................77
Set Up Optional Automation of Creating Resource for Employee...................................80
Add User-Defined (UD) Fields.........................................................................................................................81
Regenerate Data Model..........................................................................................................................83
Customize User Interface...............................................................................................................................84
Modify Employee Maintenance UI...........................................................................................................85
Modify Resource Group Maintenance UI.................................................................................................91
Add Pre-Processing Directive..........................................................................................................................94
Define Conditions for Executing Post-Processing Directive.......................................................................95
Add Function to Create New Resource and Resource Group..........................................................................99
Fill Tables for the New Resource Group and Resource and Invoke UpdateExt.........................................102
Introduction
Each business is a unique mechanism. Business Process Management (BPM) is about individual tuning, automation,
and added efficiency. It can help tailor the standard and already versatile functionality of the Epicor ERP to the
exact needs of your business, however granular they may be.
Data transactions in the application are controlled by services. A service represents a type of data managed by
the application, such as a customer, part, or sales order. The services contain methods that perform a specific
task. Each service has methods that allow you creating new records, updating or deleting existing ones. For
example, you open Order Entry and bring up an order - the SalesOrder.GetByID method gets in action fetching
order data from the database to the client; you then change the Need By date and press Save - here's the
SalesOrder.MasterUpdate method feeding the DB with the new date. The Update method is probably the
most often used one - it's used for applying ANY changes you make in the user interface to the database.
BPM Cookbook is a collection of 'recipes' you can use to get a better hang of the BPM functionality built into
the Epicor ERP. The close-to-real-world examples (real-world actually, but sometimes intentionally simplified) are
specifically centered around what you can do with the Update/UpdateExt methods. It also provides some
general recommendations on using the available ERP tools to help you design efficient workflows.
The major BPM concepts covered in this cookbook include:
• Using Update and UpdateExt to create new records
• Using UpdateExt to modify multiple records at once
• Updating current and foreign records
• Updating user-defined (UD) fields
• Using Functions to deal with conflicting data tables
Each example has more specific concepts listed in their introductory section that also contains an overview of
the scenario's business value and implementation steps.
Go ahead and get started with some tips and tricks of BPM customization first.
This topic contains practical suggestions that can help you design better BPM workflows easier.
Use UI Trace to analyze the standard ERP logic you want to customize
Windows Forms
2. Step through the procedure you wish to modify - for example, open a program, open a record, change
some fields, and save it.
Most often, custom logic is appended to an update service method. There could be different UI triggers for this
method, but you can be sure that every time you press Save on a from, some update method is executed. It can
be a direct Update - for example, EmpBasic.Update (Employee service), or it can be
MasterUpdate/UpdateMaster (wrapper methods for Update that perform some extra logic in complex UIs) -
for example, SalesOrder.MasterUpdate.
Note To find out more about setting up UI tracing, please go to the Logging > System Logs > Tracing
Options > Activate From Client topic in the System Administration Guide.
Kinetic Applications
Kinetic applications talk to the server via REST. To obtain details on called service methods, parameters, and
payload, you need to open an app in the browser, then inspect network activity in DevTools.
To display a Kinetic application in a browser:
1. First, launch the Home Page for your installation using the following URL format:
https://[ServerName]/[ERPInstance]/apps/erp/home/ - for example,
https://irv-euvm08.local/ERP102700/apps/erp/home/.
4. Go to the Network tab and review the information on the REST calls from the client.
Use Field Help to get details on the database fields involved in transactions
Windows Forms
To launch Field Help in the client, in any program, in the Main Menu, go to Help > Field Help. The Field Help
slides out. You can dock it and adjust its position on the screen as you like. Then select a program field to view
its properties - for example:
Kinetic Applications
For the description of a specific field on a Kinetic Application screen, use the program's Application Help. You
can check out the field's Ep Binding property in the Application Studio. To do this:
1. Launch the Application Studio by selecting Customization from the Overflow menu in the top right corner
of the application screen.
2. In the Application Studio, choose the page that contains your field and open its layout.
3. Select a control on the layout and view its properties - for example:
Use the Data Dictionary Viewer program for complete technical information on database fields.
Use Data Dictionary Viewer for more detail on tables and fields
Menu Path: System Setup > System Maintenance > Data Dictionary Viewer.
You can use this program to find out more information on database fields. For example, you can see some
properties of the database fields tied to Kinetic UI controls like Format, Data Type, Like field, etc. that otherwise
you wouldn't be able to see anywhere else.
For each database table, the Data Dictionary Viewer also provides the list of the existing indexes. This is the only
place in the system where these indexes can be viewed in the system, which is especially relevant for the Epicor
Cloud ERP where users do not have direct access to the database. Indexes can help you design more efficient
table joins and filters in your Business Activity and BPM Queries to ensure optimal performance. Each index has
an ordered list of included table columns. To make your database query more efficient, make sure you use those
fields in either a join or where clause.
• Business Process Management section of the Tools User Guide - also includes some hands-on examples
of customizing different types of services
• Business Process Management documentation in Application Help - System Management > Business
Process Management
In this example, you will create custom logic to automatically put a customer on credit hold and all their open
orders on hold if the customer's credit review date is before the sales order date.
Whenever you create a new or update existing sales order, this logic will check the Credit Review Date in the
customer record. If it is before the Order Date, when you save the order, the system puts the current order on
hold and issues a notification (in this example, it's an info message, but it can be an email to a financial controller,
for example). It then puts the customer on Credit Hold as well. Finally, all open orders of that customer are put
on hold to prevent their further processing.
BPM Concepts Covered in the Example:
• Updating the current record in a Pre-Processing Directive
• Updating a foreign record in a Post-Process Directive
• Using UpdateExt to modify multiple records at once
• Using Functions to deal with conflicting data tables
You will first add a pre-processing directive for the SalesOrder.MasterUpdate method that will:
• Set a condition to trigger a credit review date check only when you create a new or update existing sales
order.
• Set another condition to prevent a cyclic loop.
The workflow you are about to develop consists of multiple stages. At one stage, after the system updates
the customer record (puts on credit hold), it then updates all open orders of that customer (if any), which
triggers the pre-processing directive again creating a cyclic loop. This condition will prevent this by evaluating
a BPM Data Field "marker".
• Get the current Order Date and compare it with the customer's Credit Review Date. Further logic executes
only if the Order Date is greater than the Credit Review Date.
• If the Order Date is later than the Credit Review Date, set the OrderHeld field of the OrderHed table to True.
• Display an info message explaining why the order is put on hold.
• Enable post-processing logic.
The post-processing directive will do the following:
• Run only if the pre-processing logic has executed.
• Set the value of the ShortChar05 BPM Data field to Done (it can actually be any string). This way, when
subsequent logic finds open customer orders and invokes SalesOrder.MasterUpdate to put them on hold,
the pre-processing won't start again because the context BPM field is not empty.
• Invoke a Function that will do the customer record update (put customer on credit hold).
• Get the current order number to exclude it from the subsequent query that will select and update all customer
open orders.
• Use the Fill Table by Query action to create a temporary dataset (dsSOUpdateExt) with all the customer's
open order records, except the one that has been previously updated (put on hold).
• Invoke the SalesOrder.UpdateExt method using the temporary dsSOUpdateExt dataset.
• Call the GetById method to refresh the current order data on the Order Entry form.
• Finally, set the BPM Field value to Empty again to reset the directives.
3. Verify the System Code is set to ERP and the Type is set to Business Object, then in the Service Name
field, type in salesorder.
5. Click Search.
9. Enter a Description - for example, Puts order on hold if customer credit review date is before order
date.
11. Save the directive and move on to the next step to design directive workflow.
Set Conditions
1. On the Pre-Processing > Detail sheet with your new directive, click Design.
2. From the Flow Chart pane on the left, select the Condition widget and add it to the workflow.
4. Select the Condition 0 widget, then in the Properties > Condition 0 sheet, click the New icon.
A new condition line is added.
a. From the drop-down in the Condition column, select the following statement:
There is at least one updated row in the specified table.
5. On the Properties > Condition 0 sheet, click the New icon again.
A new condition line with an And Operator is added.
b. From the drop-down in the Condition column, select the following statement:
There is at least one updated row in the specified table.
6. Combine the first two statements by adding an opening bracket into the Prefix column of the first condition
line and a closing bracket into the Postfix column of the second condition line.
7. On the Properties > Condition 0 sheet, click the New icon one more time.
A new condition line with an And Operator is added.
b. From the drop-down in the Condition column, select the following statement:
The specified call context field is equal to the specified expression.
d. From the callContextBpmData table, select the ShortChar05 field and click OK.
In this sub-step, check if the current Order Date is greater than the customer Credit Review Date.
You will first extract the Order Date from the OrderHed table. You will need this date to compare it against
the Credit Review Date in the Customer record.
Then, you will add another condition that will evaluate the customer Credit Review Date against the Order
Date. The workflow will continue only if the Order Date is greater than the Credit Review Date.
1. In the BPM Workflow Designer, navigate to the Properties > Variables sheet and click New.
2. Add a new directive-level variable that will store current order number:
Name Type
orderDate DateTime
3. From the Setters pane, select the Set Argument/Variable widget and drag it onto the canvas.
Rename it to GetOrderDate.
5. Select the Set Argument/Variable widget in the workflow and configure it as follows:
a. On the Properties > Actions sheet, select the first specified link in the action statement.
The Select an Argument/Variable window displays.
b. Select the orderDate variable at the end of the list and click OK.
d. On the Available Variables panel, expand the ds node and then OrderHed. Select the OrderDate
field and double-click on it..
The following expression appears in the Editor: dsOrderHedRow.OrderDate
Note If you are confident about syntax and spelling of a specific field name, you can manually
enter this expression directly into the Editor. Use the Check Syntax button to validate your
expression.
e. Click OK.
a. From the drop-down in the Condition column, select the following statement:
Number of rows in the designed query is more or equal to 1.
You will use a query to select the current customer specified in the order from the Customer database
table and make sure their Credit Review Date is smaller than the Order Date.
c. From the Tree View on the right, select the Erp.Customer table and drag it onto the canvas.
d. Make sure the ERP.Customer table widget is selected and navigate to Table Criteria.
Here you set the Customer.Company field equal to the current Company ID, Customer.CustNum
equal to the value of the CustNum argument of the MasterUpdate method, and finally,
CreditReviewDate smaller than the date you store in the orderDate variable (the current order date).
1. From the Setters pane, select the Set Field widget and add it to the workflow.
Rename it to PutOrderOnHold.
b. On the Select Table Field(s) window, choose the OrderHeld field and click OK.
4. From the Other pane, select the Show Message widget and drag it onto the canvas.
Connect the PutOrderOnHold widget to Show Message.
The customer's credit review date is before the order date, the order has automatically been put
on hold.
7. Click OK.
8. From the Other pane, select the Enable Post Directive widget and drag it onto the canvas.
Connect Show Message to Enable Post Directive.
1. Verify your workflow contains all the elements per the below image:
3. In the Method Directives Maintenance program, enable and save the directive.
Test Directive
In this sub-step, test the logic you've created so far in pre-processing stage of the method execution.
3. Navigate to the Billing > Credit > Credit Detail sheet and make sure the Review Date is in the past
compared to your current date.
In this step, add logic that will put the customer on Credit Hold if at the time of creating an order, the customer
Credit Review Date is before the Order Date.
1. In the Main toolbar of the Method Directives program, select New > New Post-Processing.
5. Click Design.
The BPM Workflow Designer displays.
In this sub-step, you will link this post-processing directive to the pre-processing one you created previously. In
the very beginning of the workflow, you will also set a value for the callConextBpmData.ShortChar05 field to
prevent a cyclic loop.
1. From the Flow Chart pane, select the Condition widget and add it to the canvas.
Connect the Start widget to the Condition 0 widget.
b. Verify the Pre radio button is selected and choose Check Credit Review Date from the Directive
drop-down.
c. Click OK.
4. Now, from the Setters pane, select the Set BPM Data Field widget and drag it onto the canvas.
5. Connect the True end of Condition 0 to the Set BPM Data Field widget.
Configure the action:
b. Select the ShortChar05 field of the callContextBpmData table and click OK.
d. In the Specify C# expression window, type in a string value - for example "Done" into the Editor and
click OK.
In this sub-step, let us try calling the Customer.GetById method from our BPM workflow.
In this example, we will intentionally bump into a common obstacle when combining different Epicor services -
that is of matching tableset types in more than one services. Complex business objects contain numerous tablesets.
When you have two or more of such business objects, like Customer and Sales Order, in a BPM workflow, chances
are you may have the same tableset type(s) in more than one of these services, which will cause compilation
error(s).
Epicor Function is isolated business logic with its own context. In the next sub-step, you will pack the BPM logic
for setting Credit Credit Hold into a Function. This will eliminate the "matching tablesets" framework issue.
1. From the Callers pane, select the Invoke BO Method widget and add it to the workflow.
Connect Set BPM Data Field to Invoke BO Method.
b. Select the GetById method of the Customer service and click OK.
d. For the custNum parameter, select the iCustNum parameter of the SalesOrder.MasterUpdate method.
f. Click OK.
The Server Side Error message displays. The directive failed to compile because of identical tablesets in
the Customer and Sales Order services.
Do not close Method Directives and proceed to the next sub-step to create a Function.
Add a Function
8. From the New drop-down in the Main toolbar, select Add Widget Function.
11. On the Function > Signature sheet, add one input parameter:
Name Type
custNum System.Int32
Note Customer Number (Customer.CustNum) is the required input parameter for the
Customer.GetById method that we are going to call in the Function.
In this sub-step, design the Function workflow to set Credit Hold and update the Customer.
1. From the Callers pane, select the Invoke BO Method widget and add it to the workflow.
Connect the Start widget to the Invoke BO Method widget.
b. Select the GetById method of the Customer service and click OK.
d. For the custNum method parameter, select the Function's custNum input parameter.
f. Click OK.
You will get the Customer dataset and store it in a local variable.
3. From the Setters pane, select the Update Table by Query widget and drag it onto the canvas.
Rename it to SetCreditHold.
b. From the table list on the left, select the dsCustomer.Customer table.
c. Navigate to the Display Fields sheet and select at least one field to display - for example, Company.
Note This is required by the system to run the query. You are updating the local dataset and
therefore do not need any Display Fields but the one required.
d. Click OK.
g. On the Select Table window that pops up, verify the dsCustomer.Customer table is displayed and
click OK.
k. Click OK.
b. Select the Update method of the Customer service and click OK.
e. Click OK.
9. Review and Save the workflow and close the Function Designer.
Invoke Function
In this sub-step, invoke the SetCustCreditHold Function from the BPM workflow.
2. From the Callers pane, select Invoke Function and drag it onto the canvas.
Connect the Set BPM Data Field widget to the Invoke Function widget.
e. On the Function Search window, select the SetCustCreditHold Function and click OK.
g. Bind the custNum Function parameter to the iCustNum variable and click OK.
4. Delete the previously created dsCustomer variable to avoid the compilation error.
5. Review and Save the workflow and close the BPM Designer.
Keep the BPM Workflow Designer open and proceed to the next set of steps.
Test Directive
In this sub-step, run a quick test to see how the designed logic works now.
1. Create another order for Addison in the Sales Order Entry program.
In this step, add a few more widgets to the Post-Processing Directive workflow to set all open orders of a specific
customer on hold when this customer is put on Credit Hold.
In this sub-step, add logic that will select all open orders of the current customer and put them on hold.
1. On the Properties > Variables sheet, declare a new variables per the table below:
2. From the Setters pane, select the Set Argument/Variable widget and add it to the workflow.
Connect the Invoke Function widget to the Set Argument/Variable widget.
4. Again form the Setters pane, select the Fill Table by Query widget and drag it onto the canvas.
Rename the widget to SelectOpenOrders.
b. On the Phrase Build sheet of the Compose Query window, select the Erp.OrderHed table from the
list and add it to the canvas.
c.
d. Select the ERP.OrderHed table on the canvas and add the following Table Criteria:
By using these criteria, you select all open orders for the customer with Order Date later than the customer
Credit Review Date.
e. Navigate to the Display Fields sheet and add a couple of fields to display. You must have at least one.
In this example, select the twp key fields of the OrderHed table - OrderNum and Company - and click
OK.
g. In the Select Table window, choose the dsSOUpdateExt.OrderHed table and click OK.
In this sub-step, call the GetById method of the Sales Order BO to refresh data on the Order Entry form and set
the BPM Field value to empty again as BPM Call Context fields will persist into the User Interface. Therefore, the
flag needs to be cleared in order to allow the BPM logic to be triggered on another order.
1. From the Callers pane, select the Invoke BO Method widget and add it to the canvas.
Rename it to SO.GetById.
a. Click the specified link and select the Erp.BO.SalesOrder.GetById method in the Method Search
program.
c. Click OK.
4. From the Setters pane, select the Set BPM Data Field widget and drag it onto the canvas.
Connect the SO.GetById widget to the Set BPM Data Field widget.
b. From the callContextBpmData table, select the ShortChar05 field and click OK.
6. Review and Save the workflow, then close the BPM Workflow Designer.
7. Back on the Method Directives window, enable and save the directive.
Test Directives
1. Launch Order Entry and create a new empty order for Addison.
Note the message saying the order has been put on hold. Verify the order has been put on hold.
3. In the Sales Order Entry program (Kinetic UI), click the Sales Orders navigation link in the top left corner
of the screen to return to the Order Entry application landing page.
6. Click Search.
The search results display.
Note that all open orders for Addison with date later than the customer Credit Review Date are now put
on hold. Closed orders have not been affected.
7. If Addison's open orders have been put on hold, this automatically means the customer has been put on
Credit Hold. However, you may as well verify that by opening Addison's record in the Customer Maintenance
program. The Credit Hold check box on the Billing > Credit > Credit Detail sheet should be selected.
In this example, implement a scenario to display the total weight of all lines in a shipment in the shipment header.
You will customize the logic of the UpdateMaster method of the Customer Shipment (CustShip) service to
automatically update the shipment weight in the Header when a certain condition is satisfied.
BPM Concepts Covered in This Example:
• Updating the current record with data taken directly from the database
• Using custom logic for calculating a value to update
You will first create a pre-processing directive that will evaluate the defined conditions for triggering the updating
of the Weight field in the Header. The update will execute whenever:
• a new line is added to the shipment pack
• the line weight is changed
• the Unit of Measure (UOM) in the shipment Header is changed
Note The main purpose of this exercise is to demonstrate the use of the Fill Table by Query BPM
action in combination with calling a service BO UpdateExt method. Therefore, the weight calculation
logic has been simplified to cater for just the three basic UOMs - grams (g), kilograms (kg), and pounds
(lb). Furthermore, the calculation logic will not go into complicated UOM conversion, and if there are
lines with varying UOMs, it will take into account only the lines with the UOM matching the UOM
defined in the Header, and recalculate the weight if the Header UOM is changed.
You will then create a post-processing directive and link it to the pre-processing one. The post-processing directive
will implement the following logic:
• First of all, it will get the weight data for all the lines in the current pack with the UOM matching the Header
UOM directly from the ShipDtl database table. The obtained data will be stored in the directive-level variable
of Tableset type.
• It will then perform the weight calculation. The result will be assigned to a simple decimal directive-level
variable.
• Next, it will get the full Customer Shipment service tableset from the database and change it by replacing the
weight value with the result of the directive calculation.
• Finally, it will call the UpdateExt method of the Customer Shipment service to update the pack weight value
in the database.
• Additionally, it will call the GetByID method of the Customer Shipment service to update weight data on the
Customer Shipment Entry form.
In this step, add a pre-processing directive to set conditions for execution of the post-processing directive.
3. On the Basic sheet, for Service Name, type in CustShip, and in the Where Method Name Starts At
field, enter updatemaster.
4. Click Search.
5. Select the UpdateMaster method of the CustShip business object and click OK.
8. Add a Description - for example, Defines conditions for the AutomaticWeight post-processing
directive.
In this sub-step, define the condition that will trigger the post-processing directive.
2. From the Flow Chart pane on the left, select the Condition widget and drag it onto the canvas.
Connect the Start widget to the Condition.
3. Select the Condition widget and on the Properties > Condition sheet below the canvas, click the New
icon.
A new condition line is added.
4. From the drop-down in the Condition column, select The specified field has been changed from any
to another statement.
Define its variables as follows:
6. Change the Operator to Or, then from the Condition drop-down, select the following statement: There
is at least one updated row in the specified table.
Configure the statement like this:
8. From the drop-down in the Condition column, select The specified field has been changed from any
to another statement.
Configure the condition as follows:
9. From the Other pane, select the Enable Post Directive widget and add it to the workflow.
Connect the True end of the Condition widget to Enable Post Directive.
Keep the Method Directives Maintenance open and move on to creating the post-processing directive.
In this step, create a post-processing directive that will use data from database to update total shipment weight.
1. In Method Directives Maintenance, from the New drop-down, select New Post-Processing.
3. Add a Description - for example, Calculates total lines weight in one of the basic UOMs - g, kg, or
lb - and updates the shipment weight in the header.
In this step, add a condition that will trigger this post directive only if the set criteria are met at the pre-processing
stage.
2. From the Flow Chart pane, select the Condition widget and drag it onto the canvas.
Connect the Start widget to the Condition.
3. Select the Condition widget on the canvas, and on the Properties > Condition sheet below, click New.
A new condition line is added to the grid.
4. From the drop-down in the Condition column, select the following condition:
This directive has been enabled from the specified directive.
6. Select the Pre stage, then from the Directive drop-down, choose AutomaticWeight and click OK.
In this sub-step, get data from the ShipDtl database table for the current pack and UOM, and calculate total
weight.
1. Navigate to the Properties > Variables sheet and add two variables:
Name Type
dsShip CustShipTableset
totalWeight Decimal
You will use dsShip to temporarily store data you fetch from the database. totalWeight will hold the total
shipment lines weight that you will calculate in the directive.
2. Select the Fill Table by Query widget on the Setters pane and add it to the workflow.
Connect the True end of the Condition to the Fill Table by Query widget.
4. Select the GetDtlWeight widget, and on the Properties > Actions pane, click the designed link in the
action statement.
The Compose Query window pops up. Complete these steps to configure the query:
a. From the tree view on the Phrase Build sheet, select the ERP.ShipDtl table and add it to the canvas.
c. On the canvas, click on the link that connects the two tables and define the Table Relations as follows:
This will link the tables by the two primary keys. Additionally, the query will select only the shipment
lines with a UOM that matches the UOM in the Header.
d. Select the ERP.ShipDtl table and define the following criteria for it:
This will limit the selection to the current Company and Pack Number.
e. On the Display Fields sheet, in the tree view, expand the ShipDtl node and select the following fields:
Company, PackNum, and TotalNetWeight.
10. Finally, from the Setters pane, add a Set Argument/Variable widget to the workflow.
11. Connect the GetDtlWeight widget to the one you just added.
12. Rename the Set Argument/Variable widget to SumUpDtlWeight and configure it as follows:
e. Click OK.
In this step, you will fill the ShipHead table by query and define a new value for the ShipHead.Weight field.
You will then invoke the UpdateExt method of the CustShip (Customer Shipment) business object to update
the database.
1. From the Callers pane, select the Invoke BO Method widget and add it to the workflow.
Note Defining this widget first will bring in and make available for selection all the tablesets associated
with the specified service method. This will simplify adding a variable for the temporary UpdateExt
tableset.
4. Select the Fill Table by Query widget on the Setters pane and add it to the workflow. Rename it to
AddTtlDtlWeight.
5. Connect the SumUpDtlWeight widget to the Fill Table by Query widget you just added. Also connect
the new Fill Table by Query widget to the UpdateHeadWeight widget.
6. Select the AddTtlDtlWeight widget, and on the Properties > Actions pane, click the designed link in
the action statement.
The Compose Query window pops up. Complete these steps to configure the query:
a. From the tree view on the Phrase Build sheet, select the ERP.ShipHead table and add it to the canvas.
b. Select the ERP.ShipHead table and define the following criteria for it:
This will limit the selection to the current Company and Pack Number.
c. On the Display Fields sheet, in the tree view, expand the ShipHead node and select the following
fields: Company, PackNum, Weight, and SysRowID.
11. Change the Weight binding and link it to the totalWeight variable instead:
In this step, add a call to the GetByID method of the Customer Shipment service to refresh data on the form.
1. From the Callers pane, select the Invoke BO Method widget and add it to the workflow.
2. Rename the newly added widget to RefreshForm and connect the UpdateHeadWeight widget to it.
g. Click OK.
In this step, go over the workflow you've just created, then save the workflow and the directive.
The workflow of your directive should look like this:
1. You first linked your post-processing directive to the pre-processing one using a condition.
2. You then got weight data from the database and calculated the total weight of all the lines in the shipment.
3. Next, you queried the database again to get the CustShip tableset and added your weight sum variable to
it, then called the UpdateExt method of the CustShip BO.
4. Finally, you called the GetByID method of the CustShip BO to refresh data on the form so that you can
see the changed value without refreshing the form manually.
5. Click Save.
In this step, create an order with multiple lines and a shipment to test the directive execution.
4. From the New drop-down, select New Line, then navigate to the Lines > Detail sheet.
5. Click the Part/Rev button to search for and select part 00C1.
9. Take note of the order number. You will use it to create a shipment.
12. From the New drop-down in the Toolbar, select New Pack.
The Summary sheet displays.
13. In the Order Number field, enter the number of the sales order you just created and press Tab.
You can continue testing different scenarios by adding order lines for parts with other units of measure - grams
or kilograms, by using other conditions to trigger the directive, or by changing weight on a shipment line detail.
In this example, create BPM logic that will generate a new Resource Group and Resource for an employee.
This scenario demonstrates the usage of the UpdateExt method for creating new ERP records (moreover, in this
example, you will create a parent and a child record) with pre-filling of values for some fields, including user-defined
ones (UD fields).
BPM Concepts Covered in This Example:
• Using UpdateExt to create new records
• Pre-filling required field values
• Creating a parent and a child record at once
• Updating user-defined (UD) fields
• Using Functions to deal with conflicting data tables
Also Covered in This Example:
• Customizing user interface
• Adding user-defined fields to the database
To complete this walkthrough, you need to make sure you have all required permissions and rights set up for
your user account:
• Access to the Epicor Application server where you will use the functionality of the Epicor Administration
Console or the Data Model Generator Command tool to regenerate the data model with new UD fields
• Customize Privileges enabled for the user account
• User account authorized in Functions Administrator and Functions Developer security groups.
First of all, you will add a few UD fields to the database, and controls to manage the new functionality in the UI:
• Create Resource - a check box on the Employee Maintenance form that will trigger the creation of the
Resource Group and Resource records.
• A text box on the Employee Maintenance form that will display a success report or the text of an error that
occurred during creation of new records.
• Auto Gen - a check box on the Resource Group Maintenance form (Resources > Detail) that will indicate
the resource has been created for an employee automatically.
Next, you will add a pre-processing directive that will evaluate the conditions for running the main logic. The
new records will be created only if the Create Resource option is selected.
Then, you will create a Function that will contain logic for:
• Editing the dataset of the Resource Group BO's UpdateExt method using Fill Table by Query actions.
• Running the UpdateExt method to create new Resource Group and Resource.
• Returning a "successful" message if records were created without errors or an error text if an error occurred
during creation.
Finally, you will add a post-processing directive that will:
• Be linked to the pre-processing directive.
• Invoke the Function.
• Update the current employee record with information new Resource Group and Resource if they have been
created, and reset the Create Resource check box.
• Refresh the current employee data on the Employee Maintenance form.
In this step, add three UD fields to the database and regenerate the Epicor Data Model to make them available
for further operations.
2. From the New drop-down in the Main Toolbar, select New Table.
The Table Search window displays.
4. From the New drop-down in the Main Toolbar, select New Column.
The Column > Detail sheet displays for editing.
8. Now, from the New drop-down in the Main Toolbar, select New Table again.
9. In the Table Search window, select the ResourceGroup table and click OK.
10. Add a new column to this table with the following properties:
• Column Name - AutoGenerated.
• Data type - Boolean.
11. Save the changes and keep the User Defined Column Maintenance program open.
In this sub-step, add your new columns to the Data Model so that they become available for customization.
In this example, regenerate the model from the Epicor Administration Console
Note For the detailed description of this process, please refer to the EAC help documentation.
2. In the navigation panel on the left, expand the Database Server Management and drill down to your
database node - for example, ERP102700.
5. Once it has been successfully completed, in the navigation, select your ERP instance and click Recycle IIS
Application Pool on the right-hand Actions panel.
6. After the application pool has been successfully recycled, on the User Defined Column Maintenance form,
click Refresh.
Both, the EmpBasic_UD and ResourceGroup_UD table details now display two green shapes - Table in
Sync and Data Model in sync.
In this step, add UI controls and bind them to the new UD fields.
On the Kinetic Home Page, expand the Overflow menu and select Developer Mode (Off) to turn on developer
mode.
Note To access this functionality, Customization Privileges must be enabled for your user account.
In this sub-step, add a check box, label, and text box to the Employee Maintenance program UI.
2. On the Select Customization window that pops up, select the Base Only option to make sure you work
directly with the base form UI, and all customizations for this form (if any) are disabled. Then click OK.
6. Select EpiCheckBox, then click on the form to indicate where you want to place it.
On the Select Layer Type dialog window that pops up, choose Customization and click OK.
7. In the Toolbox, select the EpiLabel control and add it to the form next to the check box.
8. Select the newly added label on the form and edit its properties (Customization Tools Dialog > Properties):
Property Value
(Name) lblCreateResource
Text Create Resource
9. Now, select the check box on the form and edit its properties:
Property Value
EpiBinding EmpBasic.CreateResource_c (select from drop-down
list)
EpiLabel lblCreateResource (select from drop-down list) - this
creates a binding between the check box and label,
so if you move the check box, the label will move
with it.
(Name) chkCreateResource
10. In the Toolbox, select the EpiTextBox control and add it to the form below the check box and the label.
Make it wide enough to display a possible error text.
Specify a (Name) for it - for example, txtErrors.
11. In the Customization Tools Dialog, click Save to save the layer.
The Customization Save Dialog displays.
In this sub-step, add a check box and label to the Resource Group Maintenance program UI.
1. Make sure the Developer Mode is still on and launch Resource Group Maintenance.
Menu Path: Production Management > Scheduling > Setup > Resource Group.
2. On the Select Customization window that pops up, select Base Only and click OK.
The Resource Group Maintenance program launches.
6. Select EpiCheckBox, then click on the form to indicate where you want to place it.
On the Select Layer Type dialog window that pops up, choose Customization and click OK.
7. In the Toolbox, select the EpiLabel control and add it to the form next to the check box.
8. Select the newly added label on the form and edit its properties (Customization Tools Dialog > Properties):
Property Value
(Name) lblAutoGen
Text Auto Gen
9. Now, select the check box on the form and edit its properties:
Property Value
EpiBinding ResourceGroup.AutoGenerated_c (select from
drop-down list)
EpiLabel lblAutoGen
(Name) chkAutoGen
10. In the Customization Tools Dialog, click Save to save the layer.
The Customization Save Dialog displays.
In this step, add a pre-processing directive to set conditions for execution of the post-processing directive.
3. On the Basic sheet, for Service Name, type in EmpBasic, and in the Where Method Name Starts At
field, enter upd.
4. Click Search.
5. Select the Update method of the EmpBasic business object and click OK.
8. Add a Description - for example, Defines conditions for the AutoCreateResource post-processing
directive.
In this sub-step, define the condition that will trigger the post-processing directive.
2. From the Flow Chart pane on the left, select the Condition widget and drag it onto the canvas.
Connect the Start widget to the Condition.
3. Select the Condition widget and on the Properties > Condition sheet below the canvas, click the New
icon.
A new condition line is added.
4. From the drop-down in the Condition column, select The specified field has been changed from any
to another statement.
Define its variables as follows:
5. From the Other pane, select the Enable Post Directive widget and add it to the workflow.
Connect the True end of the Condition widget to Enable Post Directive.
Keep the Method Directives Maintenance open and move on to first creating a Function that will be invoked
from the post-processing directive.
In this sub-step create a Function that will create new Resource Group and Resource records.
You will design this part of directive workflow as a Function to avoid compilation failure due to the conflict of
tablesets with identical names both in Employee and Resource Group. Epicor Functions are isolated units of
business logic that execute in their own exclusive context. In this example, you will use a Function to invoke the
UpdateExt method of the Resource Group BO.
7. Move to the References > Tables sheet and add the ERP.Plant table.
You will create a query against this table to get the current Plant and Company IDs.
9. Add your current company - in this example, Epicor Education, to the Authorized Companies list.
10. From the New drop-down in the Main Toolbar, select Add Widget Function.
12. Add a Description - for example: Creates Resource Group and Resource for Employee.
13. On the Function > Signature sheet, add one input parameter:
Name Type
groupID System.String
department System.String
Note In post-processing, we will pass the current Employee ID (EmpBasic.Emp.ID) to the groupID
Function parameter. We will use the Employee ID for the new Resource Group and Resource IDs to
simplify the example. Creating a new Resource Group requires the employee's department.
14. Add an output parameter that will return error text if an error occurs when adding new rows.
Name Type
errorText System.String
Fill Tables for the New Resource Group and Resource and Invoke UpdateExt
In this sub-step, fill the ResourceGroup and Resource tables with values required for adding new rows.
To add two new rows to the ResourceGroup and Resource tables in the ResourceGroup.UpdateExt dataset, you
can only use a Fill Table by Query action. You will need any query for the sake of having a query. In this example,
query the Plant table to get the Plant and Company IDs that you will map to the dsUpdExt.ResourceGroup table.
Tip With Fill Table by Query actions, you update the local copy of the method's dataset. This local copy
of the dataset will be stored in a Function-level variable of tableset type. Creating and defining this variable
is easier when you first define the method you are going to invoke. This way, the variable type is created
by the system automatically. Doing this the other way around requires that you know exactly what tableset
you are looking for and where.
In this example, let's use this trick and define the BO method first.
1. On the Function sheet of the Epicor Functions Maintenance program, click Design.
The Function Designer launches.
2. From the Callers pane, select the Invoke BO Method widget and add it to the workflow.
Do not connect any other widgets to it just yet.
b. Select the UpdateExt method of the ResourceGroup service and click OK.
h. Click OK.
4. From the Setters pane, select the Fill Table by Query widget and drag it onto the canvas.
b. From the table list on the left, select the ERP.Plant table.
c. Select the table on the canvas and navigate to the Table Criteria sheet below.
Add two criteria:
Tip As we are using a Fill By Table action, we need to have some data in a query to identify how
many rows to create. This is why we need one single row from the Plant table.
d. Navigate to the Display Fields sheet and select at least one field to display - for this example, pick two:
Company and Plant1.
f. In the Select Table window, choose the dsUpdExt.ResourceGroup table and click OK.
i. Bind the ResourceGrpID, BackflushEmpID, and Description fields to the Function's groupID input
parameter.
7. From the Setters pane, select another Fill Table by Query widget and drag it onto the canvas.
Rename it to Fill Resource.
b. Design the query the same way you did in Step 6 (b,c,d).
d. In the Select Table window, choose the dsUpdExt.Resource table and click OK.
g. Bind the ResourceGrpID, ResourceID, and Description fields to the Function's groupID input parameter
i. Specify the following expression for RowMod - "A" where A stands for Added.
In this sub-step, add logic that will process the method response.
Add a condition that will evaluate the errorOccurred variable. If an error occurred during the update process
(errorOccurred = true), set the errorText output parameter value to one expression, else (errorOccurred = false)
to another.
1. In the Flow Chart pane, select the Condition widget and add it to the workflow.
Connect ResGrp.UpdateExt to Condition 0.
2. On the Actions sheet of the Properties panel, click New and select the following condition:
The specified argument/variable is equal to the specified expression.
b. In the Select an Argument/Variable dialog, choose the errorOccurred parameter and click OK.
4. From the Setters pane, select the Set Argument/Variable widget and add it to the canvas.
Connect the True end of the Condition to the Set Argument/Variable you just added.
b. In the Select an Argument/Variable window, choose the errorText parameter (argument) and click
OK.
d. In the Specify C# expression window, enter the following expression to get the first row:
dsErrors.BOUpdError.Select (r=>r.ErrorText).FirstOrDefault()
6. From the Setters pane, select another Set Argument/Variable widget and add it to the canvas.
Connect the False end of the Condition to the Set Argument/Variable you just added.
b. In the Select an Argument/Variable window, choose the errorText parameter (argument) and click
OK.
d. In the Specify C# expression window, enter the following expression to get the first row:
"Resource Group and Resource created successfully."
10. Back in Epicor Functions Maintenance, save the library and Function.
11. Publish the library (Actions > Promote Library to Production) and close the program.
1. In the Main toolbar of the Method Directives program, select New > New Post-Processing.
5. Click Design.
The BPM Workflow Designer displays.
Move on to the next sub-step to design the directive workflow.
In this sub-step, add a condition to execute the directive only if the pre-processing criteria were satisfied.
Also, invoke the Function that creates new Resource Group and Resource records.
1. From the Flow Chart pane, select the Condition widget and add it to the canvas.
Connect the Start widget to the Condition 0 widget.
b. Verify the Pre radio button is selected and choose CheckForResource from the Directive drop-down.
c. Click OK.
4. From the Callers pane, select Invoke Function and drag it onto the canvas.
Connect the True end of the Condition widget to the Invoke Function widget.
e. On the Function Search window, select the createResourceAndGroup Function and click OK.
g. Bind the groupID Function parameter to the EmpID field of the Employee table using the following
expression: dsEmpBasicRow.EmpID.
h. Bind the department Function parameter to the JCDept field of the Employee table using the following
expression: dsEmpBasicRow.JCDept.
i. For the errorText out parameter, create a new directive-level variable - errorText.
In this sub-step, update the Employee record with information on the created Resource Group and Resource.
Use the Fill Table by Query action to specify Resource Group ID, Resource ID, and Create Resource check box
values, and run the UpdateExt method of the Employee service to update the current employee record.
Let us first add the EmpBasic.UpdateExt method and define its parameters, and then fill the local UpdateExt
dataset just like we did in the Function before.
1. From the Callers pane, select the Invoke BO Method widget and add it to the workflow.
Do not connect any other widgets to it just yet.
b. Select the UpdateExt method of the EmpBasic service and click OK.
f. For errorsOccurred and <return value> parameters, set the bindings to [ignore].
g. Click OK.
3. Now, from the Setters pane, select the Fill Table by Query widget and drag it onto the canvas.
Rename it to something like Fill Employee Table.
4. Connect the Invoke Function widget to the Fill Employee Table widget.
b. From the table list on the left, select the ds.EmpBasic table.
c. Navigate to the Display Fields sheet and select two fields to display - Company and EmpID.
e. In the Select Table window, choose the dsEmpUpdExt.EmpBasic table and click OK.
Note These two expressions above mean that if Resource Group and Resource have been created
successfully, and the errorText variable contains a success message, the ResourceGrpID and
ResourceID fields will be assigned the current Employee ID value that we know is what we used
to create the new records' IDs, else these fields preserve their original values.
k. Set the CreateResource_c field to false to reset the Create Resource check box.
In this sub-step, invoke the GetByID method of the Employee service to automatically refresh data on the form.
1. From the Callers pane, select the Invoke BO Method widget and add it to the workflow.
g. Click OK.
In this sub-step, go over the workflow you've just created, then save the workflow and the directive.
You can now test the custom BPM logic you've just designed.
2. In the Select Customization dialog, select the CreateResource layer and press OK.
3. In the ID field, type in 105 if you are using the Demo DB, and press Tab.
Note If you use another non-education database, you might need to search for an existing employee
or create a new one.
5. Select the Create Resource check box and Save the record.
Note that the form has been updated:
6. From the Department drop-down, select a department - for example, Assembly Department.
7. Select the Create Resource check box again and Save the record.
• Resource Group and Resource fields contain the IDs of the created records.
• Create Resource check box is cleared.
• The text box below it contains a success message: Resource Group and Resource created successfully.
9. In the Select Customization dialog, select the AutoGenerated layer and press OK.
10. In the Resource Group field, type in 105 and press Tab.
The group details display on the form.
11. Navigate to the Resources > Detail sheet and display resource 105.
Note that the Auto Gen check box is selected.
In this example, add custom logic to automatically generate a customer-specific Misc Charge in a newly created
sales order.
You will customize the logic of the MasterUpdate method of the Sales Order (SalesOrder) service to automatically
add a Freight Misc Charge to any new order created for Addison.
BPM Concepts Covered in This Example:
• Using Update to create a new record
• Creating initial filling of required fields
You will first create a pre-processing directive that will evaluate the defined conditions for triggering the addition
of a new Misc Charge to the Order Header. The Freight Misc Charge will be added only:
• when a new order is created and saved for the first time, and
• if the customer is Addison.
You will then create a post-processing directive that will execute only if the above criteria are satisfied at the
pre-processing stage. The post-processing directive will implement the following logic:
• It will obtain the number of the new order from its dataset and will assign it to a directive-level variable. It
will use this order number to get the most up-to-date version of the sales order tableset after the main logic
of the MasterUpdate has been completed. It will then put this order data into another variable of Tableset
type for further modification.
• Next, it will call the GetNewOHOrderMsc method of the Sales Order service to create a new empty row in
the OHOrderMsc table.
• After that, it will set a FRGT value to the MiscCode field in this table and pass the updated sales order dataset
to the ChangeMiscCharge method that automatically fires when the MiscCode field value is changed. This
method adds other default values for the specified miscellaneous charge code.
• Then, it will invoke the SalesOrder.Update method to bring all the changes made to the dataset into the
database.
• Finally, it will call the SalesOrder.GetByID method to update Misc Charge data on the Sales Order Entry
form.
In this step, add a pre-processing directive to set conditions for execution of the post-processing directive.
3. On the Basic sheet, for Service Name, type in salesorder, and in the Where Method Name Starts At
field, enter master.
4. Click Search.
5. Select the MasterUpdate method of the SalesOrder business object and click OK.
8. Add a Description - for example, Triggers the post-processing directive only when a new sales order
is added for Addison.
In this sub-step, define the condition that will trigger the post-processing directive.
1. On the Pre-Processing > Detail sheet with your directive details, click Design.
The BPM Workflow Designer window displays.
2. From the Flow Chart pane on the left, select the Condition widget and drag it onto the canvas.
Connect the Start widget to the Condition.
3. Select the Condition widget and on the Properties > Condition sheet below the canvas, click the New
icon.
A new condition line is added.
4. From the drop-down in the Condition column, select There is at least one updated row in the specified
table statement.
Define its variables as follows:
The post-processing directive will execute only when a new order is added.
5. Add another condition line. Keep the default And operator and select the following statement:
The specified argument/variable is equal to the specified expression.
7. From the Other pane, select the Enable Post Directive widget and add it to the workflow.
Connect the True end of the Condition widget to Enable Post Directive.
Keep the Method Directives Maintenance open and move on to creating the post-processing logic.
1. In Method Directives Maintenance, from the New drop-down, select New Post-Processing.
3. Add a Description - for example, Creates a Freight misc charge when a new order is added for
Addison.
In this step, add a condition that will trigger this post directive only if the set criteria are met at the pre-processing
stage.
2. From the Flow Chart pane, select the Condition widget and drag it onto the canvas.
Connect the Start widget to the Condition.
3. Select the Condition widget on the canvas, and on the Properties > Condition sheet below, click New.
A new condition line is added to the grid.
4. From the drop-down in the Condition column, select the following condition:
This directive has been enabled from the specified directive.
6. Select the Pre stage, then from the Directive drop-down, choose CheckForMiscCharge and click OK.
In this step, obtain order number and dataset and get to store them in directive-level variables.
1. Navigate to Properties > Variables and add two directive-level variables per the table below:
Name Type
dsTemp SalesOrderTableset
localOrderNum Integer
The localOrderNum variable will store the current order number obtained from the SalesOrder dataset.
You will use it as a parameter for calling the Sales Order's GetByID method. You will use the dsTemp
variable to temporarily store the sales order data returned by this method and all directive modifications to
it.
2. From the Setters pane, add a Set Argument/Variable widget to the workflow.
Rename the newly added widget to GetOrderNum and connect the True end of the Condition widget
to GetOrderNum.
e. Click OK.
4. Now, from the Callers pane, select Invoke BO Method and drag it onto the canvas.
Rename the widget to GetOrderDS, and connect the GetOrderNum widget to GetOrderDS.
5. Select the GetOrderDS widget, and on the Properties > Actions tab, click the specified link in the action
statement.
The Choose BO Method window displays. On the Basic sheet:
6. Click Search.
7. Select the GetByID method from the results and click OK.
9. Bind the OrderNum method parameter to the localOrderNum variable and the output parameter of the
SalesOrderTableset type to the dsTemp variable.
In this step, create a new Misc Charge line and set its Charge ID to Freight.
1. From the Callers pane, select another Invoke BO Method widget and add it to the workflow.
Change its name to GetMiscCharge.
3. Select the GetMiscCharge widget and click the specified link in its action statement.
The Method Search window displays.
4. Search for and select the GetNewOHOrderMisc method of the SalesOrder service BO.
This method creates a new empty Misc Charge line for an order.
5. Once you selected the method, click the not configured link to set up its parameters:
d. Click OK.
6. From the Setters pane, select the Set Field widget and drag it onto the canvas.
Rename it to SetMiscCode. You will use this action to set one of the predefined codes - FRGT (Freight)-
for the newly created miscellaneous charge.
c. Click OK.
f. Click OK.
In this step, invoke the Update method of the Sales Order service to bring your changes into the database and
the GetByID method to refresh data on the form.
1. From the Callers pane, select the Invoke BO Method widget again and add it to the workflow.
Rename it to UpdateSalesOrder.
3. Select the UpdateSalesOrder widget on the canvas, then click the specified link in its action statement.
The Method Search window appears.
4. Search for and select the Update method of the SalesOrder service BO.
In the statement, it should display as Erp.SalesOrder.Update.
a. Bind the ds in-out parameter to the dsTemp variable that now contains a new Misc Charge line.
b. Click OK.
8. Select the RefreshFormData widget on the canvas and click on the specified link in its action statement.
The Method Search window displays.
9. Search for and select the GetByID method of the SalesOrder service BO.
In the statement, it should display as Erp.SalesOrder.GetByID.
b. Bind the <return value> out parameter to the ds argument (parameter) of the
SalesOrder.MasterUpdate method.
c. Click OK.
In this step, go over the workflow to make sure everything has been set up correctly, and save the directive.
In the BPM Workflow Designer, you directive should look similar to this:
1. You first set a condition that's checking for a permission from the pre-processing directive to execute
post-processing logic. It executes only if set criteria are met at the pre-processing stage.
2. Secondly, you obtain the order number from the Sales Order dataset and call the SalesOrder.GetByID
method to get the most recent version of the current sales order data from the database.
3. Next, you call the SalesOrder.GetNewOHOrderMsc method that creates a new Misc Charge record for
the order. You then pre-fill the MiscCode field (Charge ID in the UI) of the new Misc Charge row with a
code for a Freight Charge. The change of the Charge ID value triggers the ChangeMiscCode method. You
feed the modified Sales Order dataset with added Misc Charge row to it.
4. You then invoke the Update method of the SalesOrder BO to bring your changes into the database.
5. Finally, you call the SalesOrder.GetByID method to display the most actual sales order data, including the
new Misc Charge line, from the database.
6. Additionally, verify you have defined two directive-level variables: localOrderNum (integer) and dsTemp
(SalesOrderTableset).
In this example, use an Updatable Business Activity Query (UBAQ) to delete multiple part records from the
database.
You will use a query as a convenient way of selecting specific part records to delete. You will then modify the
base logic of the query's Update method where you will invoke the Part BO UpdateExt method for record
deletion.
BPM Concepts Covered in This Example:
• Using a Base Processing directive to define UBAQ's Update Processing logic
• Using UpdateExt to delete multiple records at once
• Using a Fill Table by Query action to populate the input dataset for a method
• Using error messages from the UpdateExt method
Note The scenario does not cover this, but you can use this Updatable BAQ in an Updatable Dashboard
by creating an Assembly Dashboard and deploying it to a menu. For details on setting up updatable
dashboards, please refer to the Updatable Dashboards section of the Tools User Guide.
In the first two steps of this example, you create an Updatable BAQ using the Business Activity Query Designer.
You will query the Part table. There you will add a calculated field and make it updatable. This field will be used
in the query results grid (most likely on a dashboard) to mark records for deletion. You will another calculated
field to display error messages in the query results if erros occur during the update (delete) process.
Next, you will design the update logic for the query in the BPM Workflow Designer program. You will use a Fill
Table by Query action to populate the dataset for the Part.UpdateExt method with data on records deemed
for deletion. You will modify the RowMod value of the selected records to trigger their deletion.
Then, you will run the UpdateExt method and handle possible errors. You will use an Update Table by Query
action to update the second calculated column in the query results dataset. This column will display error text
for any error that occured during the Update method execution.
In this step, define the query that will be used for selecting parts to delete.
Design Query
In this step, specify the table to query and define what fields will be displayed.
You will display the required fields - Company and PartNum, as well as PartDescription to help you identify
the data. You will also define two calculated fields:
• DeleteRecord - a bit field that will be used to mark part records to delete.
• ErrorMessage - a character field that will display an error text if an error occurs during the update process.
1. On the Query Builder > Phrase Build sheet, select Erp.Part from the table list and add it to the canvas.
4. Then click the Calculator icon to launch Calculated Field SQL Editor.
7. Modify the default Label to make it read like this: Delete Record.
8. In the Editor field, type in 0 or click the False key to generate this value automatically. This will be the
default value of this field.
10. Add the ErrorMessage field of nvarchar type and adjust the Label to make it readable - for example,
Error Message.
11. In the Editor field, enter two single quotes straight after each other - ''.
By default, the value of this field will an empty string.
2. Select the Allow Multiple Row Update option and clear the Allow New Record check box.
7. In either of the two methods lists - on the List sheet or in the Methods panel, select the Update method.
The method is displayed in the following format: Ice.<CompanyID>/<BAQID>.Update - in this example,
Ice.EPIC06/PartDeletionUBAQ.Update.
8. From the New drop-down in the Main Toolbar, select New Base Processing.
The Base Processing > Details sheet opens for editing.
In this step, design the BPM workflow for deleting selected records in the database and returning information
on error, if it occurred, into the query results dataset.
1. From the Callers panel, select the Invoke BO Method widget and add it to the canvas.
At this point, do not connect it to any other widgets.
2. Rename it to something appropriate like InvokePartUpdExt and configure the action as follows:
b. In the Method Search window, select the UpdateExt method of the Part BO and press OK.
d. For the ds in-out parameter, create a new variable - in this example, dsItemsToDelete.
This variable will hold the dataset that contains records to delete.
3. From the Setters pane, select the Fill Table by Query widget and add it to the workflow.
4. Connect the Start widget to the Fill Table by Query widget, then connect the Fill Table by Query widget
to the InvokePartUpdExt widget.
5. Rename the Fill Table by Query widget to RecordsToDelete and set it up like this:
b. On the Phrase Build sheet, add the queryResultDataset.Results table to the canvas and select it.
d. Navigate to the Display Fields sheet and add the table's key fields and SysRowID to display - in this
example:
Part_Company, Part_PartNum, and SysRowID.
g. In the Select Table window that displays, choose the dsItemsToDelete.Part table and press OK.
j. Finally, scroll to the bottom and change the binding of the RowMod column to this expression: IceRo
w.ROWSTATE_DELETED.
Note Setting the RowMod to IceRow.ROWSTATE_DELETED is what triggers the deletion. The
SysRowID is used to identify the original line when dealing with error messages.
Now add the mapping of the possible errors back to the queryResultDataset.
6. From the Setters pane, add an Update Table by Query widget to the workflow and give it an appropriate
name such as SetErrors.
b. On the Phrase Build sheet, add the dsErrors.BOUpdError table to the canvas.
c. On the Display Fields sheet, add the ErrorText and ErrorSysRowID fields to the Display Column(s)
list.
g. In the Select Table window, choose the queryResultDataset.Results table and click OK.
i. In the Relations section, click the New icon to add a new relation:
Note This mapping is mapping the ErrorSysRowID back to the original SysRowID.
Keep the Business Activity Query Designer open and move to testing the query.
Test Directive
2. From the New drop-down in the Main Toolbar, select New Part.
6. Now go back to the Business Activity Query Designer and open the Analyze sheet.
10. Double-click on another part that you know has transactions against it (so it will not allow deletion) - in this
example, 00C1 (Component C1).
11. Again, select the Delete Record check box and press OK.
You now have two lines to update highlighted in yellow.