Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Info

This guide is for Strategy Designer version 1.0.0 released as part of the Paper Plane release on July 25th, 2023.

Strategy Designer is a visual interface for configuring selected aspects of the Accelerate Price Setting Package (PSP) which it also depends on.

The main focus of Strategy Designer is to allow business users to configure custom strategies that would otherwise need to be coded in Groovy. Strategy Designer provides visual experience powered by Google Blockly technology (open source).

The main features of Strategy Designer are:

Feature

Configures the following part of PSP

Design custom strategies using a drag & drop interface.

Custom Engines

Assign strategies to different product segments and set each strategy’s importance.

Strategy Importance

Preview each strategy’s result in a Live Preview panel.

PSP does not have this feature.

Deploy the strategies and the importance settings to the partition.

Warning

What Strategy Designer is not:

  • Replacement of the Price Setting module. You need to manage you data, price lists, and price grids using the standard Pricefx modules.

  • Visual designer for any Groovy logic. It just allows users to create custom strategies that are handled by the Price Setting Package accelerator. It does not work independently and cannot be used without it.

  • Viewer of data stored in your partition. Although the Live Preview functionality offers you some visibility into your data, it is very limited. Browsing the master data tables or Company Parameters in Pricefx Unity gives you features such as filtering, sorting, storing your preferences, and thus offers much better experience.

Live Preview

The Live Preview function allows you to see the calculated results of your strategy or data lookup in real-time. It also provides useful validation messages in case your workspace is not properly configured. The panel with the Live Preview is located on the right side of the user interface. By default, it is hidden, and you have to expand it by clicking on the arrow button.

Image Removed

You can switch between the Preview and Code tabs:

  • Preview - allows you to perform a simulation of the current strategy

  • Code - shows code generated by the strategy

The Code tab is for development and debugging purposes only. Business users should not pay much attention to it.

The Preview panel is divided into three main parts:

Inputs

This section contains the inputs required to run the simulation. Some inputs are generated only if the strategy requires them.

  • Product Id - select a product to simulate the strategy with. Required input, although some strategies and data lookups might not need it.

  • Dependency Level - select the dependency level to simulate the strategy with. Only independent levels are supported at the moment.

  • Target Date - select a target date to simulate the strategy with. If not specified, today’s date will be used.

The following inputs are only generated if certain blocks are present in the workspace:

  • Simulated price from the current list - required if the Get price from the current list block is in the workspace. Because this block triggers a second-pass calculation, it cannot be simulated easily. The value from this input will be used for the simulation of this block’s value.

    Image Removed
  • Simulated kit price - required if the Calculate kit price block is in the workspace. Calculating the kit price also requires a second-pass calculation so we simulate it instead in the live preview.

    Image Removed

To calculate the strategy, hit the Calculate button. The button will be enabled only if all the required inputs are filled. Once filled, the strategy will be automatically recalculated when the workspace changes.

Result

Shows the calculated result price of the strategy. The price is always rounded to two decimal digits. Hover your mouse over the price to see the non-rounded price.

Intermediate results

Shows multiple tables with calculated results of each block in the workspace, such as variables, product attributes, PSP attributes, and data lookups. This gives you the possibility to debug your strategy in real-time.

Validation

If the workspace is not properly configured, the Live Preview panel will show validation errors instead. In such a case, you will not be able to see the simulated price or the code until you fix the errors.

You can click the eye icon to highlight the offending block in the workspace.

Image RemovedData Lookups Anchordata_lookupsdata_lookups

Data Lookups are a crucial concept in the Strategy Designer. They allow you to specify a data set that can be reused across your strategies in different ways. There are two kinds of lookups: simple and advanced.

Info

A general guide to deciding whether to use the simple or advanced look-up:

  • Use simple lookup if you only need to fetch a single row for the SKU currently being calculated, and pick a value from it without any transformation

  • Use advanced lookup if:

    • you want to fetch data for a different SKU than the one being calculated,

    • you need to filter, sort, or aggregate the data,

    • you need to look up a value based on a range or a value which comes from another data lookup

You can create a Data Lookup by clicking on the Add Lookup button above the list of lookups.

Simple Data Lookups

Product Extension & Company Parameter Lookup

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

The Product Extension and Company Parameter lookup work almost the same, with just one slight difference: the product extension lookup is always filtered by the SKU of the currently calculated product.

Below is an example of a simple lookup into a company parameter table called ‘AdditionalDiscount’. This table identifies each value based on three keys: Business Unit, Product Group, and Product Class. There is an input for each key that needs to be specified. Based on the specified set of the three keys, the lookup identifies a single row and returns its column called ‘Discount %’.

Image Removed
Info

If you need to perform a product extension look-up for a different SKU than the one currently being calculated, or if you need to filter, sort, and aggregate your data, you need to use the advanced data lookup.

Competition Lookup

The Competition Lookup looks into the Competition Data table and allows you to filter records based on its columns. It is always filtered for the SKU currently being calculated and always returns a price, either the highest, lowest, or an average of all the records the lookup produces.

Notice the Filters category in the toolbox that allows you to drag & drop the filter criteria. Everything within the logical block with the ‘ALL’ option selected will be logically and-ed together. Everything within the logical block with the ‘ANY’ option will be or-ed together. Everything which is directly plugged into the Filter input is and-ed together.

In the example below, the filter could be rewritten like this: Competitor = ‘MainCompetitor’ AND (Country = ‘Germany’ OR Country = 'Italy).

Image Removed

If you need more filtering, sorting, or aggregation options, you need to use the advanced data lookup.

Advanced Data Lookup

The advanced data lookup works in a different way compared to the simple lookup. It splits the data fetching from the aggregation.

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

  • The aggregation part happens in your strategy. Here you determine how to transform the rows to produce a single value.

The flexibility, however, comes with a price, and that is that the advanced data lookup is generally slower.

Info

Remember: Don’t 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 Parameter

  • Product Extension

  • Product Master

  • Custom Extension

  • Custom Master

  • Competition Data

Below is an example of the advanced data lookup. The source is a Product extension called ‘Product Costs’. The following filter conditions are applied:

  • the SKU column is equal to the ID of the product currently being calculated,

  • and the Date is lower or equal to the target date,

  • and the Dependency Level Name is ‘Global’

Additionally, the result is sorted by the Date from the highest (most recent) to the lowest (oldest).

Image Removed

Image Removed

This lookup can return zero, one, or multiple rows, as we can see in the Live Preview, and it returns all columns that are present in the table.

Because of this, we can define such a lookup once and use it multiple times in our strategies, each time querying a different column and a different aggregation function.

Using Data Lookups in a Strategy

General information

Before you can use your data lookup in a strategy, you have to save it. This is done by clicking on the Save button. Even when you rename a lookup, you need to save it for the new name to be reflected in the strategies. After you save a lookup, a corresponding block will appear in your Strategies workspace in the toolbox under the Data Lookups category.

If you don’t have any saved data lookup, the Data Lookups category will be empty.

Image Removed

Using simple lookups

After you save a simple data lookup, it will be available in the Data Lookups category in the strategies toolbox as a block with no configuration options. This block returns the value specified in the data lookup’s configuration.

Below is an example of a simple data lookup into the company parameter called ‘AdditionalDiscount’. This data lookup returns a ‘Discount %’. When you use the Additional Discount block in your strategy, it will evaluate the lookup based on the currently calculated product and return the found discount. You can then use it in your strategy.

Image Removed

Image Removed

Image Removed

Aggregating values from the advanced lookup

As we described earlier, the advanced data lookup doesn’t return a single value but a set of rows with multiple columns. When it is being defined, it doesn’t know yet what column will be used and how the values of that column will be aggregated. This is decided when the data lookup is used in a strategy. Therefore, each saved advanced data lookup creates an aggregation block that allows us to select which data lookup we want to use, which column are we going to aggregate, and which aggregation function we use.

Below is an example of several aggregation blocks, each produced for a saved advanced data lookup.

Image Removed

Remember the Product Costs lookup we specified earlier, which returned multiple rows? Here we can decide how to use it. For example, we can take an average of the values in the Cost column.

Image Removed

There are many aggregation functions available. You can reuse the same advanced data lookup multiple times, each with a different column and aggregation function.

Range lookup

Sometimes you might want to filter a lookup based on a value that is not yet known at the time the lookup is defined.

Example: We want to calculate a price impact based on a certain product’s weight. We store a price impact value for multiple weight ranges. Therefore we define a lookup that produces these three rows:

Image Removed

However, the problem is that product’s weight comes from another lookup and therefore cannot be directly used in this lookup’s filter.

In such a case, we can enable lookup by range for this data lookup by checking the corresponding checkbox. When we do that, we are required to specify which columns define the range. In our case it’s the columns ‘Pricing Attribute Value From’ and the ‘Pricing Attribute Value To’ columns. By doing this, we made the advanced data lookup a little smarter because now it knows how to perform a range lookup.

Image Removed

This opens a new possibility and creates a new block type in the Data Lookups toolbox in the strategies. This block has an additional input where we can specify the value used for the range lookup. In our example, it would be the weight of the product.

Image Removed

Let’s say we have a Product Weight coming from a different lookup, stored in a variable. In our range lookup, we plug this variable into the block so the lookup knows which value we’re comparing the range to. Don’t forget to take the correct result column, which is not the ‘Pricing Attribute Value From’ but the ‘Price Impact Value’.

Image Removed

Image RemovedImage Removed

As you can see, the Product Weight was 120, therefore the range lookup returned a Price Impact Value of 1.1. When multiplied by the Product Cost of 12, the resulting price is 13.2.

Note

If multiple records fit the looked-up range, the block might select one of them at random. Generally, when this happens, it suggests that your data is not defined very well because the ranges overlap and you should fix the data.

Value lookup

Sometimes you might want to perform a lookup not by a range, but by a single value. The setup is very similar to the range lookup, only this time you check the Enable lookup by value checkbox. When you do that, you need to specify the Lookup field which will be used for such a lookup. The Lookup field should contain unique values only.

In the example below, we have a table with a Color attribute with different colors stored in the Pricing Attribute Value column. Each color has an impact stored in the Price Impact Value column. We need to tell the data lookup that the column we want to use for the value lookup is the Pricing Attribute Value column.

Image Removed

Image Removed

When we do this and save the lookup, a new kind of data lookup block will appear in the Data Lookups category in the strategies toolbox. It works in the same fashion as the range lookup, only this time the record with the matching ‘Pricing Attribute Value’ will be picked.

Image Removed
Note

If multiple records fit the looked-up value, a random one might be picked as the result. Generally, when this happens, it suggests that your data is not defined very well and you should fix it.

Panel
panelIconId1f4a1
panelIcon:bulb:
panelIconText💡
bgColor#E3FCEF

Pro tip: One advanced data lookup might be enabled for both the range lookup and the value lookup. Just make sure the ranges don’t overlap and the values in the Lookup field are unique.

Data Lookup Status

When you start using the strategies, you will notice some icons in the list of data lookups. Here is their meaning:

Image Removed

  1. Link - this data lookup is used in one or more strategies.

  2. Broken link - this data lookup is used in one or more strategies, but has unsaved changes. You can either save them or revert to the previously saved version.

  3. Triangle with an exclamation mark - this data lookup has validation errors. The icon is shown regardless of whether it’s saved or not.

  4. No icon - this data lookup is not used anywhere yet

Info

Data lookups which are used in one or more strategies cannot be deleted. Also, you cannot change some properties of these lookups, such as whether they’re enabled for a range or value lookup.

Panel
panelIconId1f4a1
panelIcon:bulb:
panelIconText💡
bgColor#E3FCEF

Pro tip: Hover over the link icon to see how many times this strategy is used.

Prioritize the Strategies

When you are finished designing your strategies, you can proceed to the next step which we call Prioritize. This is where you assign strategies to each product segment and prioritize them. It is good to have an understanding of how Strategy Importance and Dependent Price Lists and Data Fallbacks work.

Info

This step is only accessible if all of the strategies are valid. Otherwise the Continue button will be disabled.

User Interface Overview

Header (same as in the Design step)

  1. Status bar informing you about the save/load progress of your configuration

  2. Interactive indicator of the current step

  3. Deploy button which deploys the current configuration to the partition

List of Hierarchy Levels

  1. Standard Levels

  2. Override (Base) Levels

Strategy Prioritization Table

  1. Information about the selected dependency level

  2. Table control buttons

    • Add Rule button which adds new rows to the table

    • Revert all changes button which reverts all changes done to the selected level

  3. Table with product segments and prioritization

Strategy Prioritization Table

The biggest part of the screen belongs to the strategy prioritization (or importance) table. This table contains rules that determine which strategies are calculated for which product and in what order.

How the prioritization works

Each product falls into one of the product segments, which are defined by the Price Setting Accelerator. In the example below, there are three product segments: Business Unit, Product Grup, and Product Class. Each product has these attributes and therefore falls always within one segment.

In order to determine which rule applies, the product’s attributes are compared with the segment, and the rule with the most specific matching segment is chosen. For example, if we have a product with Business Unit = Food, Product Group = Beef, and Product Class = A, the last rule will be picked. If the product has Product Class = B, then the second from the bottom rule will be picked, and so on. If none of the rules applies, the topmost rule is picked as it covers all segments.

When a rule is determined, the Price Setting Accelerator calculates all the strategies in the left-to-right order. The final price of the calculation will be the price of the first strategy that returns a valid price.

In our example, say the product doesn’t have a competition and the AvgCompetition strategy doesn’t return a price, but the AttributeBased strategy and the My Cost Plus strategy do return one. In such a case, the final price will be the price of the AttributeBased strategy.

Controlling the table

When editing the table, the following restrictions apply:

  • The product segment columns will only allow you to pick a combination that does not exist in the table. Therefore, you cannot enter duplicate data.

  • You cannot have a wildcard to the left of a specific value. Wildcards can be placed only to the right of the more specific values. This is the current limitation of the PSP.

In order to add a new rule, click on the Add Rule button. This will add a new rule at the bottom of the table and pre-fill it with the next unused segment.

To change a rule, simply pick another value from the drop-down in the cell you want to change. The restrictions above apply.

In order to delete a rule, hover over the row which you want to delete and click on the Trash icon on the right side. Such a row will be disabled and further changes will be prevented.

To revert all changes, click the Revert all changes button above the table. This will revert all changes you made to this table so far.

Hierarchy Levels

The items in the list of hierarchy levels are fixed and depend on how many levels you have configured in the PSP. You might have only the Default level configured, or you can have more. For details on how to configure this, see Dependent Price Lists and Data Fallbacks. Generally, this is configured when the PSP is deployed for the first time on the partition.

In short, you can have different settings per dependency level (or context) in which your price lists and grids are calculated. For example, you can have different settings on a Global level and Country level.

Standard vs Override (Base) Levels

Rules defined in an Override table always take precedence over rules defined in the Standard table of the same level. Usually, the Standard tables contain rules that are not changed very frequently, and the Override tables contain rules which change a lot. An example of rules in the Override table would be a temporary promotion. Instead of rewriting your Standard Table, you can just add a rule into the Override table of the same level. If two rules with the same segment are found in both the Standard and the Override table, the rule from the Override table takes precedence. Only if it doesn’t return a price, the rule from the Standard table is evaluated.

Deploy to the Partition

Once you are satisfied with the strategies and their prioritization, you can deploy everything to the partition by clicking on the Deploy button. A confirmation dialog will appear and after confirming, you will be taken to the Deploy screen which will give you information about the deployment progress.

If no error was encountered, you will be presented with the success message and a button that will take you back to the first step while reloading all the data from the freshly updated partition.

If an error was encountered, it means the deployment was unsuccessful. This can happen mainly because of a wrong configuration of the Price Setting Accelerator. In case you encounter an error, write down the error message and send it to the support team.

How the configuration is stored

There are two kinds of configuration stored on the partition, the deployed and the draft. When you open the Strategy Designer, it will look if there is a draft version available on the partition and if it is, it will load it. If not, it will load the last deployed configuration, if present.

A user can always discard his draft and load the last deployed configuration from the partition. This is done from the three-dot menu in the top-right corner.

Each time you make a change to the configuration (list of strategies, lookups, blocks), it is automatically saved to the partition as a draft. There is one draft per user, which means that each user can have his own work-in-progress version of the strategies. You can see the status of your configuration in the status bar in the app’s header.

There is, however, just one deployed configuration stored on the partition. This means that whenever a user deploys his draft to the partition, it will overwrite the previous version of the deployed configuration. And this new configuration will be then available to the other users, who would be able to load it (either by discarding their draft or automatically, if the user didn’t have any draft).

Info

Until you deploy your configuration, you’re playing in your own playground. When you deploy the configuration, it will become visible and active for PSP and available to other users of the Strategy Designer, who would be able to load it.

Advanced Configuration

Note

This section is for advanced users only. An error in the configuration will result in the Strategy Designer not loading correctly or not loading at all. You have been warned!

Deployment and Installation

The Strategy Designer is deployed as part of the Price Setting Package from the Pricefx Platform Marketplace. This is the preferred way because it also creates the necessary business role.

If you’re deploying it manually, make sure you have the Price Setting Package version 2.1.3 or newer installed on your partition.

Manual deployment

To manually deploy the Strategy Designer, follow these instructions:

  1. Go to Configuration > Advanced Configuration Options

  2. Create a new entry named pfxExternalApp_visual_configuration_strategy_designer
    The important part is the prefix pfxExternalApp_, the rest is up to you.

  3. Copy & paste the following JSON as the entry’s Value:

    Code Block
    {
      "name": "strategy-designer",
      "label": "Strategy Designer",
      "url": "https://apps.pricefx.com/visual-configuration/1-0-0/#/strategy-designer",
      "businessRole": "StrategyDesigner",
      "configuration": {
      }
    }
    

    This creates a default configuration for the Strategy Designer. It can be further adjusted via the configuration options

4. Create a new business role called StrategyDesigner and assign it the following permissions:

Anchor
deploy_permissions
deploy_permissions

  • Master Data > Administer Company Parameters

  • Price Setting > Manage Calculation Logics

  • Price Setting > View LPG

  • Price Setting > View Price Lists

  • Administration > Data Integration

5. Assign this business role to the users who should be able to use the Strategy Designer

6. Refresh your browser

After these steps, the Strategy Designer should appear in the main menu under External Applications.

Note

Make sure your JSON is syntactically correct. No trailing commas are allowed.

Warning

The StrategyDesigner role will give the users access to certain Pricefx features, which they otherwise might not have access to. This is the current limitation. Be careful who you give access to.

Upgrading to the latest version
Anchor
config_options_upgrade
config_options_upgrade

Currently, the only way to upgrade your existing Strategy Designer configuration is to manually update the url parameter in the Advanced Configuration Options.

  1. Go to Configuration > Advanced Configuration Options

  2. Open the entry with your Strategy Designer configuration. It will start with pfxExternalApp_, like pfxExternalApp_visual_configuration_strategy_designer.

  3. Update the url parameter to point to the new version:
    The Strategy Designer is deployed at https://apps.pricefx.com/visual-configuration/{VERSION}/#/strategy-designer where {VERSION} is the released version’s number with dashes instead of dots.
    For example, version 1.0.0 is at URL https://apps.pricefx.com/visual-configuration/1-0-0/#/strategy-designer

  4. Save the entry

  5. Refresh your browser

After updating the URL and saving the entry, refresh your browser and open the Strategy Designer again from the External Applications in the main menu.

Configuration Options
Anchor
config_options
config_options

The Strategy Designer’s additional configuration is stored in its configuration JSON in the pfxExternalApp_visual_configuration_strategy_designer entry in the Advanced Configuration Options. The value is a JSON object.

A default configuration looks like this:

Code Block
languagejson
{
  "name": "strategy-designer",
  "label": "Strategy Designer",
  "url": "https://apps.pricefx.com/visual-configuration/1-0-0/#/strategy-designer",
  "businessRole": "StrategyDesigner",
  "configuration": {
    "advancedConfigurationStateEntry": "visual_configuration_psp_state",
    "stateLookupTableName": "StrategyDesignerState",
    "dependencyConfigurationTable": "DependencyConfiguration",
    "priceListLogicName": "IndependentPriceListLogic",
    "priceSettingDimensionsTable": "PriceSettingDimensions",
    "strategyDefinitionTable": "StrategyDefinition",
    "livePreviewDependencyLevel": "Global",
    "groovyLibraryName": "CustomPricingStrategiesLib",
    "customBlocksGroovyLibraryName": "StrategyDesignerCustomBlocks",
    "excludedParameters": [],
    "additionalParameters": {}
  }
}

You can only specify the parameters you want to change. Others will use their default values.

The name, label, url, and businessRole are needed for Unity in order to display the Strategy Designer in the menu.

  • name is a unique name among the external applications which will be part of the URL. Make sure it’s unique among all pfxExternalApp_ entries

  • label is the text of the menu item. You can safely change this

  • url is the URL pointing to the server where the Strategy Designer is deployed

  • businessRole is the business role the user has to have assigned to see the menu item

  • configuration is an application-specific configuration, in our case it contains the configuration options for the Strategy Designer

Following is a list of options you can specify within the configuration object, with their default values and a description. A default value is used when you omit the option.

Option

Default Value

Description

advancedConfigurationStateEntry

“visual_configuration_psp_state”

A key in the Advanced Configuration Options where the deployed state of the Strategy Designer is stored. Change this if you want the Strategy Designer to store its deployed state elsewhere, or load it from elsewhere.

stateLookupTableName

“StrategyDesignerState”

A company parameter where the draft state of the Strategy Designer is stored

dependencyConfigurationTable

“DependencyConfiguration”

PSP table where dependencies are configured. Unless you have a custom PSP deployment, you should not need to change this.

priceListLogicName

“IndependentPriceListLogic”

The name of the PSP’s IndependentPriceListLogic. Unless you have a custom PSP deployment, you should not need to change this.

priceSettingDimensionsTable

“PriceSettingDimensions”

PSP table where dimensions are configured. Unless you have a custom PSP deployment, you should not need to change this.

strategyDefinitionTable

“StrategyDefinition”

PSP table where strategy definitions are configured. Unless you have a custom PSP deployment, you should not need to change this.

This is where the custom strategies are written when they’re deployed.

livePreviewDependencyLevel

Status
titleobsolete

“Global”

The default dependency level for the Live Preview. It has become obsolete in version 1.0.0 where you can pick the level yourself from a drop-down.

groovyLibraryName

“CustomPricingStrategiesLib”

The name of a Groovy Library which contains the custom strategies' generated code.

It doesn’t have to exist, it will be created during the first deployment.

customBlocksGroovyLibraryName

“StrategyDesignerCustomBlocks”

The name of a Groovy Library which contains definitions of custom blocks.

Learn how to define custom blocks in How to create custom blocks in Groovy.

excludedParameters

[]

A list of default PSP parameters you want to exclude. Specifying them will hide the blocks from the workspace. See How to exclude out-of-the-box PSP parameters for details how to do that.

additionalParameters

{}

A list of additional PSP parameters you want to see as blocks. Typically, you would need to specify any additional parameters you created in your customized PSP logic. See How to add additional PSP parameters for more details.

Excluding out-of-the-box PSP parameters
Anchor
config_options_exclude_params
config_options_exclude_params

The Strategy Designer offers you to use some of the out-of-the-box parameters calculated by PSP as blocks in your strategies. But if they’re not configured properly in the PSP, they won’t work and will result in errors in the Strategy Designer. In such a case, it is better to hide them from the toolbox so the users don’t use them.

In case you don’t want to use them, you can specify them in the list of excluded parameters and the Strategy Designer will hide them from the toolbox. The following PSP parameters are supported:

Here is an example of the configuration object that hides the last four parameters:

Code Block
languagejson
"configuration": {
  "excludedParameters": [
    "PLUS_FOR_PRODUCT_ABSOLUTE",
    "PLUS_FOR_PRODUCT_PERCENTAGE",
    "PRICE_INCREASE_PERCENTAGE",
    "PRICE_INCREASE_ABSOLUTE"
  ]
}

You can also easily hide all PSP parameters like this:

Code Block
languagejson
"configuration": {
  "excludedParameters": "ALL"
}

Including additional PSP parameters
Anchor
config_options_add_params
config_options_add_params

Status
colourRed
titleexpert

In case your custom price list logic uses some additional parameters (typically configured for Custom Engines), you can add them as blocks using the additionalParameters option.

The additionalParameters parameter is an object where each key is the PSP’s identifier of the parameter and the value is an object with a label and a type. The label will become the text displayed on the corresponding block in the toolbox and the type will become the return type of that block. Supported types are Number, Boolean, and Text.

Say we have two additional parameters called ‘RRP’ which is a number, and ‘IS_OUT_OF_STOCK’ which is a boolean value (true or false). This is how you would make them available in the Strategy Designer’s toolbox:

Code Block
"configuration": {
  "additionalParameters": {
    "RRP": {
      "label": "RRP",
      "type": "Number"
    },
    "IS_OUT_OF_STOCK": {
      "label": "Is out of stock?",
      "type": "Boolean"
    }
  }
}

Each key in the additionalParameters object has to be unique. Make sure there are no syntax errors in the JSON object.

The parameters will be available in the toolbox under the Parameters category:

Creating custom blocks in Groovy
Anchor
config_options_custom_blocks
config_options_custom_blocks

Status
colourRed
titleexpert

If the blocks provided by the Strategy Designer out-of-the-box are not enough, you can define your own using Groovy.

Create the Groovy Library

Follow these steps to create the library:

  1. Create a Groovy Library and name it for example ‘StrategyDesignerCustomBlocks’ (remember this name for later)

  2. In the library, create the first element and call 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 blocks will call.

The Meta Element

The Meta element must return an array of objects, each object representing a block you want to create in the 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

Description

element

Status
colourRed
titlerequired

String

The element where the Groovy function which the block calls is located

function

Status
colourRed
titlerequired

String

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

params

Status
colourBlue
titleoptional

List

A list of parameter objects specifying the inputs of the block.

Each parameter object has the following properties:

  • name - String - a unique name of the parameter

  • type - String - the type of the parameter, either number, string, or option

  • default - default value supplied if the user doesn’t 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

Status
colourRed
titlerequired

String

The 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

Status
colourBlue
titleoptional

Integer or String

The 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

Status
colourBlue
titleoptional

String

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

returns

Status
colourRed
titlerequired

String, either number or string

The return type of the block. It should correspond with the type of the return value from the function defined by the element and function parameters.

Examples of Custom Blocks

Arithmetic block

Let’s say we want to create an arithmetic block for calculating a percentage mark-up, that will look like this:

View file
nameInvalid file id - a03a7cd5-8830-491e-b506-2a813187ed86

  1. Create the Meta element and return a list with a single block configuration object from it, like this:

    Code Block
    languagegroovy
    return [
      [
        "element" : "Math",
        "function": "markupPct",
        "label"   : "{1} x (1 + {2})",
        "params"  : [
                ["name": "base", "type": "number"],
                ["name": "markup", "type": "number", "default": 0]
        ],
        "returns" : "number"
      ]
    ]

    Notice the label containing the placeholders that make the inputs render at the correct places.

  2. Create a Math element and in it create a function called markupPct with two parameters, like this:

    Code Block
    languagegroovy
    BigDecimal markupPct(BigDecimal base, BigDecimal markup) {
      if (base == null) {
        throw new Error("The base cannot be empty");
      }
      if (markup == null) {
        return base;
      }
      return base * (1 + markup)
    }

    You can the element and the function whatever you want as long as it is the same name as specified in the element and function properties in the block configuration object.

Info

If you have multiple custom blocks, return all of them in the list returned by the Meta element.

Tip

Pro tip: You can have as many or as few elements with your functions as you want. A good practice would be to group your functions in elements with a similar purpose, like Math, Text or Competition Data.

Block with a drop-down

Let’s say we want to create a block that will retrieve an aggregation of prices of a selected competitor. The block should look like this:

  1. Create the Meta element and return a list with a single block configuration object from it (or append the object to the existing list of objects), like this:

    Code Block
    languagegroovy
    def competitorsIt = api.stream("PCOMP", "competitor", ["competitor"], true)
    def competitors = competitorsIt.collect { it.competitor }
    competitorsIt?.close();
    
    def operatorOptions = [
            "MAX"  : "highest",
            "MIN"  : "lowest",
            "AVG"  : "average",
            "SUM"  : "total",
            "FIRST": "oldest",
            "LAST" : "latest"
    ]
    
    return [
      [
        "element" : "Competition",
        "function": "competitorPrice",
        "status"  : "active",
        "label"   : "Get {1} price of competitor {2}",
        "params"  : [
                ["name": "operator", "type": "option", "options": operatorOptions],
                ["name": "competitor", "type": "option", "options": competitors]
        ]
      ]
    ]

    Notice how we first retrieved the available options from the PCOMP table (line 1) and mapped it into an array of competitor names (line 2). We used this list of competitors in the competitor input parameter (line 22). Instead of a list, we could also feed it a map where the key is a competitor ID and the value is the competitor’s name, if necessary. We took this approach with the operatorOptions (lines 5 and 22).

  2. Create a Competition element and in it create a function called competitorPrice with two parameters, like this:

    Code Block
    languagegroovy
    BigDecimal competitorPrice(String operator, String competitor = null) {
        def filters = []
        if (!operator) {
            return null
        }
        if (competitor) {
            filters << Filter.equal("competitor", competitor)
        }
        def records = api.productCompetition(Filter.and(filters.toArray()))
        records.forEach { api.trace 'Record', it.infoDate + ' | ' + it.competitor, it.price }
        if (!records) {
            return null
        }
        switch (operator) {
            case "MAX":
                return records.max { it.price }?.price
            case "MIN":
                return records.min { it.price }?.price
            case "AVG":
                return records.sum { it.price } / records.size()
            case "SUM":
                return records.sum { it.price }
            case "FIRST":
                return records.sort { a, b -> a.infoDate <=> b.infoDate }.first()?.price
            case "LAST":
                return records.sort { a, b -> a.infoDate <=> b.infoDate }.last()?.price
            default:
                return null
        }
    }

Update the configuration

When your Groovy library is configured, you just need to tell the Strategy Designer that it should read it and create blocks from the definitions. You can do it by specifying the customBlocksGroovyLibraryName option and setting it to your library’s name.

For example:

Code Block
languagejson
"configuration": {
  "customBlocksGroovyLibraryName": "StrategyDesignerCustomBlocks"
}

When you reload the Strategy Designer, it will show all the defined blocks in the Functions category in the Strategies toolbox:

Limitations

The Strategy Designer is being actively developed. Here is a list of its known limitations:

  • English only - other languages are not supported at the moment, even if you switch to another language in the Unity settings

  • Pricing is supported only on the independent level, the same as the Live Preview. Dependent levels are not supported at the moment.

  • Limited multi-user access. Each user can have his own draft, but only one active deployed configuration can be stored. When deployed, you cannot go back at the moment.

  • Extended user permissions. Because the Strategy Designer needs to modify formulas and have access to master data and price lists & grids, it needs to be given certain permissions. The users will then gain access to certain Pricefx features, which they otherwise might not have access to.

Frequently Asked Questions

Q: I cannot see the Strategy Designer in the main menu. Why?
A: You probably don’t have the StrategyDesigner business role assigned. If you have, please check the configuration options, maybe there is another business role specified that you need to have.

Q.: Strategy Designer gives me a ‘Not authorized’ error when I try to open it. What can I do?
A: Please check if the StrategyDesigner business role has all the needed permissions. You can find them here.

Q: Can I use the Strategy Designer to modify other logics, such as Quotes or Rebates?
A: No, the Strategy Designer works only in tandem with the Price Setting Package accelerator. No other use cases are supported at the moment.

Q: I have changed a data lookup but the change is not reflected in my strategy. Is that a bug?
A: You probably forgot to save the data lookup. You need to save it even when you rename it. Otherwise, the new name won’t be reflected in your strategy.

Q: I have set up a range data lookup and want to change it. But the ‘Enable range lookup’ is disabled. Why?
A: If the lookup is already used in a strategy, you cannot change the range definition. You either need to delete the corresponding lookup block from your strategy, or create a new one by duplicating this one and saving it as a new data lookup.

Q: Where can I report bugs and suggest ideas?
A: We have a dedicated Jira space for this: https://pricefx.atlassian.net/jira/software/c/projects/PFVCFG. When submitting a ticket, make sure to assign it to the Strategy Designer epic.