Formula Designer (Agreements)

Formula designer is a tool that enables Visual Configuration of Formula Types. It is tightly connected to the Agreements Accelerator architecture and based on Google Blockly.

The primary goal is to create simple Formula Types without the need for Groovy code.

Feature

Configures the following part of Agreements

Feature

Configures the following part of Agreements

Assign Calculation Parameters as parts of Calculation

Calculation Method Calculation Parameters

Define Calculation Formula using drag and drop feature

Calculation Method of a Formula Type

Assign inputs to various parts of Calculation using the customizable Input Blocks

Input Manager Input Generation Tables

Customizable Result Block

Custom Outputs to Condition Records (requires additional configuration at project start)

What Formula Designer is not:

  • Replacement for complex Formula Types (those can be implemented using Input-Based Formulas)

  • Visual Configuration for anything else than Formula Types for Agreements, there is no support for Quotes or any other modules.

Before the First Formula

If one is unfamiliar with Blockly it would be wise to take a moment and read the basic documentation about the solution here: https://pricefx.atlassian.net/wiki/spaces/ACCDEV/pages/4625006712

Installation

Formula Designer is embedded into the core release and is available from version 13.0.

Advanced Configuration

The Accelerator comes with a predefined configuration for Formula Designer, but it can be modified if necessary after deployment from Platform Manager.

To tweak the Formula Designer configuration, navigate to the Advanced Property called formulaDesigner under AdministrationConfigurationAdvanced Configuration Options. There is a JSON file with properties as follows:

User Permissions

The Accelerator comes with predefined permissions that allow viewing and managing Formulas. Ensure that all users who will utilize this feature have the appropriate Business Roles assigned. For more details, refer to the Business Roles (Agreements) article.

Creating Formula Type and Formula

Step 1. Create Formula

To utilize the Formula Designer, you must first create a Formula:

  1. Navigate to the Side MenuAgreements & PromotionsFormula.

  2. Click Create New Formula in the top right section and fill in the details.

This creates a new Formula Custom Form that represents the instance of a specific use of (yet to be created) Formula Type. The Custom Form configuration can be found in Administration > Custom Form Types, named AGR_Formula.

After creating a Formula, it can be opened. The screen looks like this:

image-20240624-110909.png

Step 2. Create Formula Type

Click Add Type or Edit Types, where Formula Type can be created.

The main workspace will look like this:

image-20240624-111822.png

The ribbons define different Block sets. Each set provides different functionality.

  • Parameters - these blocks allow the use of Calculation Parameters during the calculation.

  • Data Lookups - contains all of your configured Data Lookups.

  • Constants - contains the following constants.

    • Text block - allows entering any static text value.

  • Math - contains blocks for mathematical operations, all accepting numerical inputs.

    • Number block

    • Arithmetic block

    • Rounding block
      (round = half-up, round up, round down)

    • Constrain block – limits the first value by a minimum (low) and maximum (high), both optional.

    • No price block – use this block as the final price of the formula if you do not want it to return any value.

  • Logic - contains blocks related to logical operations.

    • If-Then-Else block – if the value in the If input is true, then return the value in the Then input, otherwise, return the value in the Else input.

    • Evaluate block (aka Switch-case block) – allows you to evaluate a value plugged into the first input and then specify multiple If conditions to match the value being evaluated. The return value of this block is the return value of the first matched If block.

    • Logical and/or block – used to group multiple conditions together.

    • Comparison block – used to compare two values.

    • Is (not) empty block – returns true if the given input is (not) empty (null or empty text).

    • Boolean block – returns either true or false.

  • Inputs - contains blocks that represent Inputs handled by Input Manager. These blocks will be displayed either on the Details tab or on the Agreement under the specified label only if they are set as broadcastable.

When the label is not defined in the formula for an input, default fallback terms such as "Text Input", "Integer Input", etc., are displayed instead. Default label values can be changed within the AGR_FormulaDesigner_CustomInputs logic (Administration > Logics > Calculation Logic > Groovy Library).

  • The list of available inputs:

    • Boolean

    • Customer

    • Customer Group

    • Date

    • Date Range

    • Date Time

    • Integer

    • Product

    • Product Group

    • Seller

    • Seller Group

    • Slider

    • String

    • Text

    • Decimal

  • Functions - contains miscellaneous function blocks that are configured manually in Groovy code.

Step 3. Create Data Lookup (optional)

Data lookups allow you to specify a data set that can be reused across your Formula Types in different ways.

Data lookup can be created by navigating to Data Lookups tab and clicking the Add button above the list of lookups.

There are two types of lookups:

  • Company Parameter

  • Advanced Data Lookup

Company Parameter Lookup

These two simple lookups can be compared to Excel’s VLOOKUP function, as they fetch a single row based on a key or a set of keys. They always require all key fields to be specified and produce just one value. They do not allow filtering, sorting, or aggregating data.

Advanced Data Lookup

The Advanced Data Lookup works differently compared to the Company Parameter lookup. It separates data fetching from aggregation.

  • The data fetching part is configured in the Data Lookups tab. An advanced data lookup does not produce a single value but always fetches a set of rows. You can filter and sort the result as needed.

  • The aggregation part happens in your Formula Type, where you specify how to transform the rows to produce a single value.

The flexibility comes with a cost – the advanced data lookup is generally slower.

Do not use the advanced data lookup if you can achieve the same result with the simple one. The advanced data lookup is generally slower than the simple one.

The advanced data lookup supports these data sources:

  • Company Parameters

  • Product Extensions

  • Product Master

  • Customer Extensions

  • Customer Master

  • Competition Data

Step 4. Use Formula Type in Formula

After Formula Type has been created and is valid (indicated by a green circle with the word “Valid” near the Formula Name) it can be renamed by clicking the “pencil” icon, providing a new name and activated by pressing the Activate button.

Once Active, the created Formula Type will show up in the drop-down (if it does not, refresh the page) and can be selected. Its Blockly representation will be displayed in the Preview section below.

Step 5. Fill in the Details Tab

On the Details tab, the user is presented with any Inputs that are part of the Formula Type. The inputs can be defined in logics described in the Logic Documentation (Agreements) | Formula Logics article. The values filled in here will be passed to the Calculation into appropriate places. If any Input has been marked as Broadcasted then it will appear on the Agreement instead (after the Formula has been approved).

Additionally in the Attributes section a Text Description of the Formula can be added to easily describe its purpose. This can be done within the logics described in the Logic Documentation (Agreements) | AGR_FormulaHeaderAttributesConfigurator section of the Logic Documentation article.

Step 6. Submit and Approve the Formula

Once everything is complete, the Formula CFO can be renamed and sent through the approval workflow (if defined - using Approval Workflow Package).

Once approved, the Formula will become available on the Agreement.

Creation of Custom Functions

Custom Functions are created in the same way as in the Strategy Designer: https://pricefx.atlassian.net/wiki/spaces/ACCDEV/pages/4631658696. Note that the Accelerator comes with a library designed to be used for Custom Functions called AGR_FormulaDesigner_CustomBlocks.

Creation of Custom Input Blocks

Create Groovy Library that will store the Custom Blocks. Accelerator comes with a library named AGR_FormulaDesigner_CustomInputs that contains some premade inputs.

For a new library, follow these steps:

  1. Create a Groovy Library and name it (write down this name for later).

  2. In the library, create the first element and name it “Meta”. Set its Display Mode to Everywhere. More on the Meta element later.

  3. Create other elements (at least one) which will contain the functions your custom inputs will call.

The Meta element must return an array of objects, each object representing a block you want to create in Strategy Designer.

Each block has a label and can contain parameters (block inputs where other blocks can be plugged in). The block will then call a specified custom Groovy function located in another element of this library, passing the values of the user-provided parameters to it.

The block object has the following structure:

Property

Type

Required?

Description

Property

Type

Required?

Description

element

String

Required

Location of the Groovy function which the block calls.

function

String

Required

Name of the function in the element specified by the element property, which the block calls.

params

List

Optional

List of parameter objects specifying the inputs of the block.

Each parameter object has the following properties:

  • name (String) – Unique name of the parameter.

  • type (String) – Type of the parameter, either number, string, or option.

  • default – Default value supplied if the user does not provide the input; its type must correspond with the type property.

  • options – Specified only if the type is option. It is either a list of values, or a map where the key is the option’s value and value is the option’s label.

label

String

Required

Label rendered on the block. It can contain parameter placeholders like {1}, {2}, etc. If params are specified, each parameter will be rendered at the position of the corresponding placeholder, so the first parameter will be rendered at the {1} placeholder, the second at the {2} placeholder, and so on.

If no placeholders are specified, the parameters will be all added at the end of the block.

color

Integer or String

Optional

Color of the block. It can be either an integer value (0 to 360) representing HSV hue value, or a #rrggbb String representing a web color.

If no color is specified, the block will have the default color of the Functions toolbox category.

tooltip

String

Optional

Tooltip of the block which is displayed when the user hovers the pointer over the block. If empty, no tooltip will be displayed.

meta

Map

Optional

Meta block contains any additional information that user may want to pass to the Deployment logic. Whole Meta element is passed and can be read in unchanged form.

inlineInputs

boolean

Optional

Defines whether the label placeholders should be displayed inline with the label text or not.

returns

String, either number or string

Required

Use “string”, not utilized for Input Blocks.

Example

As an example let’s create a new BigDecimal input that will provide some Adder Value.

Step 1. Create new Meta entry

In the Meta element of AGR_FormulaDesigner_CustomBlocks, let’s append the existing list with a new entry:

[ "element" : "InputGenerationFunctions", <--- this defines the element where we'll put our function that will generate the input "function" : "generateAdderValueInput", <--- this defines the name of the function that will generate the input "label" : "Adder Input Is Broadcasted {1}", <--- this will be displayed on the Block in the Blockly workspace, the Broadcasted flag is necessary so we leave it there "color" : "#287F62", <--- this can be set to anything valid "inlineInputs": true, <--- short input so this looks better if set to true "meta" : [ <--- here we'll pass some additional information to the deployment logic so InputManager will know how to handle our new Input "name" : "adderInput", <--- name of the input, if name is not passed then the Deployment logic will use "id" which is much less readable when debugging the code "element" : "InputGenerationFunctions", <--- we pass the same element as in the "element" tag "function": "generateAdderValueInput", <--- we pass the same element as in the "function" tag "order" : 0, <--- here we pass the order used by InputManager, if the project know that certain inputs should be displayed in certain order (always) then this can me modified here "defaultLabel": "Adder Input" <--- if the label of the input is not passed then this will be used instead (that is our case, because label is not present, may require change in getInputLabel to notify the code that the label is missing by `return meta.params?.label ?: meta.defaultLabel` ) ], "params" : [ ["name": "isBroadcast", "type": "option", "options": ["Yes", "No"]] <--- allows setting the custom input as broadcastable ], "returns" : "string" ],

Step 2. Create Generation Function

Navigate to the Element pointed by the Meta and create a function with the same name as the function property in Meta. In our case this will be something like this:

ConfiguratorEntry generateAdderValueInput(Map inputs, Map meta) { String inputLabel = getInputLabel(meta) ContextParameter inputContextParameter = api.inputBuilderFactory().createUserEntry(meta.inputId) .setLabel(inputLabel) .buildContextParameter() return libs.AGR_InputLib.CommonInputGenerationUtils.buildConfiguratorEntry(inputContextParameter) }

This function will generate a new “Adder Value” input block that will be possible for selection under Inputs tab. Meta map is crucial here, because it contains all meta from the previous step but also all parameters (with user filled values) and inputId, in case name is not provided. If everything is filled correctly then Deployment logic will handle the rest of the process. Notice that the function returns ConfiguratorEntry, this has to be the case for all input blocks.

Formula Activation logic

Activation or Deployment – these two terms can be used interchangeably when talking about what happens after Activate is clicked on the Formula Type Draft.

The deployment logic is defined under deploymentLogicName (Administration > Configuration > Advanced Configuration Options > formulaDesigner) and set to AGR_FormulaDesinger_Deployment by default (located in Administration > Logics > Calculation Logic > Generic Logic). This logic is executed after Activate is clicked. In the case of Accelerators, it does a number of things.

Populate Inputs

If there are any inputs used by the Formula Type, then their respective Input Generation tables need to be created. This process follows the same principle as for regular inputs.

  1. First the Input Generation table is created by following the pattern defined by: libs.AGR_ProcessingLib.ConstConfig.FORMULA_DESIGNER_CONFIG.INPUT_GENERATION.PRICE_PARAMETER.NAME_PATTERN, which by default is AGR_YourFormulaName_InputDefinitions.

  2. The Input Generation table is filled based on the meta of the Input block.

    1. An important step is that the meta block is saved as one of the attributes of the table. This allows meta to be accessed by the generation function of the input, which can be handy.

    2. Meta is also extended by two additional entries: inputId and params (which are user-filled values).

Populate Formula Types

After inputs have been generated, the last step is to create the entry in the FormulaTypes table pointed by libs.AGR_FormulaLib.ConstConfig.FORMULA_TYPES_PARAMETER_CONFIG. This step fills in data such as the formula name, calculation method path, or parameters (taken from the used blocks).