Sugar Logic
Overview
Sugar Logic, a feature in all Sugar products, enables custom business logic that is easy to create, manage, and reuse on both the server and client.
Sugar Logic is made up of multiple components that build on each other and is extensible at every step. The base component is the Sugar Formula Engine, which parses and evaluates human-readable formulas. Dependencies are units made up of triggers and actions that can express custom business logic. Each dependency defines a list of actions to be performed depending on the outcome of a trigger formula.
Terminology
- Formula : An expression that conforms to the Formula Engine syntax, consisting of nested functions and field variables
- Function : A method that can be called in a formula
- Trigger : A formula that evaluates to either true or false when a field in the equation is updated or when a record is retrieved/saved
- Action : A method that modifies the current record or layout in some way
- Dependency : A complete logical unit that includes a trigger and one or more actions
Sugar Formula Engine
Formulas
The fundamental object is called a formula. A formula can be evaluated for a given record using the Sugar Logic parser.
Some example formulas are:
Basic addition:
add(1, 2)
Boolean values:
not(equal($billing_state, "CA"))
Calculation:
multiply(number($employees), $seat_cost, 0.0833)
Types
Sugar Logic has several fundamental types: number, string, boolean, and enum (lists). Functions may take in any of these types or combinations thereof and return as output one of these types. Fields may also often have their value set to only a certain type.
Number Type
Number types essentially represent any real number (which includes positive, negative, and decimal numbers). They can be plainly typed as input to any function. For example, the operation (10 + 10 + (15 - 5)) can be performed as follows:
add(10, 10, subtract(15, 5))
String Type
A string type is very much like a string in most programming languages. However, it can only be declared within double quotes. For example, consider this function, which returns the length of the input string:
strlen("Hello World")
The function would appropriately return the value 11.
Boolean Type
A boolean type is simple. It can be one of two values: "true" or "false". This type mainly acts as a flag that indicates whether a condition has been met or not. For example, this function contains takes two strings as input and returns "true" if the first string contains the second string, or "false" otherwise:
and(contains("Hello World", "llo Wo"), true)
The function would appropriately return the value "true".
Enum Type (list)
An enum type is a collection of items. The items do not need to all be of the same type, they can be varied. An enum can be declared using the enum function as follows:
enum("hello world!", false, add(10, 15))
Alternatively, the createList()
function (an alias to enum) can be used to create enums in a formula.
createList("hello world!", false, add(10, 15))
This function would appropriately return an enum type containing "hello world!", false, and 25 as its elements.
Link Type (relationship)
A link represents one side of a relationship and is used to access related records. For example, the accounts link field of Contacts is used to access the account_type field of the account related to a contact:
related($accounts, "account_type")
For most of the out-of-the-box relationships, links are named with the name of the related module, in lower case.
Follow these steps to find the name of the link fields for relationships that do not follow the convention above:
- Open the vardef file for the module you are working on:
./cache/modules/{module}/{module}vardefs.php
- Find the link field that matches the relationship you are looking for.
Functions
Functions are methods to be used in formulas. Each function has a function name, a parameter count, a parameter type requirement, and returns a value. Some functions such as add()
can take any number of parameters. For example: add(1)
, add(1, 2)
, and add(1, 2, 3)
are all valid formulas. Functions are designed to produce the same result whether executed on the server or client.
Triggers
A trigger is an object that listens for changes in field values and, after a change occurs, triggers the associated actions in a dependency.
Actions
Actions are functions that modify a target in some way and are fired when the trigger is TRUE. Most Actions require at least two parameters: a target and a formula. For example, a style action will change the style of a field based on a passed-in string formula. A value action will update a value of a field by evaluating a passed in formula.
notActions
notActions are functions that modify a target in some way and are fired when the trigger is FALSE. notActions are optional and if they are not defined then nothing will fire when the trigger is FALSE. Most notActions require at least two parameters: a target and a formula. For example, a style action will change the style of a field based on a passed-in string formula. A value action will update a value of a field by evaluating a passed in formula.
Dependencies
A Dependency describes a set of rules based on a trigger and a set of actions. Examples include a field whose properties must be updated dynamically or a panel which must be hidden when a drop down value is not selected. When a Dependency is triggered it will appropriately carry out the action it is designed to. A basic Dependency is when a field's value is dependent on the result of evaluating a Expression. For example, consider a page with five fields with It's "a", "b", "c", "d", and "sum". A generic Dependency can be created between "sum" and the other four fields by using an Expression that links them together, in this case an add Expression. So we can define the Expression in this manner: 'add($a, $b, $c, $d)' where each field id is prefixed with a dollar ($) sign so that the value of the field is dynamically replaced at the time of the execution of the Expression.
An example of a more customized Dependency is when the field's style must be somehow updated to a certain value. For example, the DIV with id "temp" must be colored blue. In this case we need to change the background-color property of "temp". So we define a StyleAction in this case and pass it the field id and the style change that needs to be performed and when the StyleAction is triggered, it will change the style of the object as we have specified.
Sugar Logic Based Features
Calculated Fields
Fields with calculated values can now be created from within Studio and Module Builder. The values are calculated based on Sugar Logic formulas. These formulas are used to create a new dependency that are executed on the client side in edit views and the server side on save. The formulas are saved in the varies or vardef extensions and can be created and edited directly. For example, the metadata for a simple calculated commission field in opportunities might look like:
'commission_c' => array(
'name' => 'commission_c',
'type' => 'currency',
'calculated' => true,
'formula' => 'multiply($amount, 0.1)',
//enforced causes the field to appear read-only on the layout
'enforced' => true
),
Dependent fields
A dependent field will only appear on a layout when the associated formula evaluates to the Boolean value true. Currently these cannot be created through Studio and must be enabled manually with a custom vardef or vardef extension. The "dependency" property contains the expression that defines when this field should be visible. An example field that only appears when an account has an annual revenue greater than one million.
'dep_field'=> array(
'name' => 'dep_field',
'type' => 'varchar',
'dependency' => 'greaterThan($annual_revenue, 1000000)',
),
Dependent dropdowns
Dependent dropdowns are dropdowns for which options change when the selected value in a trigger dropdown changes. The metadata is defined in the vardefs and contains two major components, a "trigger" id which is the name of the trigger dropdown field and a 'visibility grid' that defines the set of options available for each key in the trigger dropdown. For example, you could define a sub-industry field in accounts whose available values depend on the industry field.
'sub_industry_c' => array(
'name' => 'sub_industry_c',
'type' => 'enum',
'options' => 'sub_industry_dom',
'visibility_grid'=> array(
'trigger' => 'industry',
'values' => array(
'Education' => array(
'primary',
'secondary',
'college'
),
'Engineering' => array(
'mechanical',
'electrical',
'software'
),
),
),
),
Clearing the Sugar Logic Cache
The ./updatecache.php
script traverses the Expression directory for every file that ends with "Expression.php" (ignoring a small list of excepted files) and constructs both a PHP and a JavaScript functions cache file which resides in ./cache/Expressions/functions_cache.js
and ./cache/Expressions/functionmap.php
. If you create your custom expressions, you will need to rebuild the sugar logic functions by navigating to:
Admin > Repair > Rebuild Sugar Logic Functions