Selling Context
A selling context defines the shopper, time, geography, or other conditions under which
a Price List Assignment or a Promotion applies. In the
Import-Export XML format, the <selling_context> node is embedded inside the parent object (a price list assignment or a promotion) and contains one
or more <condition> elements whose condition_string is evaluated at runtime against the shopper's traits.
The same condition_string syntax is also used by Saved Conditions.
Sample XML:
<selling_context>
<guid>2054C56D-250F-E515-CA69-AC097DA371D5</guid>
<name>Senior Shopper</name>
<description>PLA SellingContext for Senior Shopper</description>
<priority>1</priority>
<conditions>
<condition>
<guid>394CEAE8-F46A-2633-4208-9F38600176FD</guid>
<name>name_PLA_SHOPPER</name>
<description>desc_PLA_SHOPPER</description>
<condition_string>{ AND { AND { CUSTOMER_AGE_YEARS.greaterThanOrEqualTo (65i) } } }</condition_string>
<dictionary_guid>PLA_SHOPPER</dictionary_guid>
</condition>
</conditions>
</selling_context>
Selling Context Fields
| Field | Description |
|---|---|
guid | Unique identifier for the selling context. |
name | Display name for the selling context. |
description | Optional description. |
priority | Used to break ties between selling contexts of the same parent type. Lower numbers indicate higher priority. |
conditions | A container for one or more <condition> elements. |
Condition Fields
| Field | Description |
|---|---|
guid | Unique identifier for the condition. |
name | Display name for the condition. |
description | Optional description. |
condition_string | The expression evaluated against shopper traits at runtime. See Condition String Syntax. |
dictionary_guid | The tag dictionary the condition belongs to. Typical values are PLA_SHOPPER for price list assignments, PROMOTIONS_SHOPPER for shopper-targeted promotions, TIME for time-based conditions, and STORES for store-scoped saved conditions. |
Condition String Syntax
The condition_string uses a Groovy-like domain-specific language that wraps one or more atomic conditions inside logical operator blocks.
Logical Structure
Atomic conditions are nested inside AND or OR blocks, with a single outermost block:
{ AND { ... } }
{ OR { ... } }
Blocks can be nested to express compound logic:
{ AND { CUSTOMER_AGE_YEARS.greaterThanOrEqualTo (18i) { OR { GEOIP_COUNTRY_CODE.equalTo 'CA' GEOIP_COUNTRY_CODE.equalTo 'US' } } } }
Atomic Conditions
Each atomic condition takes the form:
TRAIT_NAME.operator value
TRAIT_NAME is any supported trait (see Supported Traits). operator is one of the operators listed in Available Operators. value is a literal whose form depends on the trait's data type:
| Data Type | Literal Form | Example |
|---|---|---|
| String | Single- or double-quoted text | 'Segment1' |
| Integer | Number with i suffix, optionally parenthesised | (65i) or 65i |
| Long | Number with l suffix, optionally parenthesised | (100l) |
| Float | Number with f suffix, optionally parenthesised | (1.5f) |
| BigDecimal | Number with g suffix, optionally parenthesised | (99.99g) |
| Boolean | true or false | true |
Some operators (inList, notInList, moduloEquals) accept a string literal whose content encodes a comma-separated list rather than a single value
of the trait's native type. See the operator descriptions below.
Supported Traits
Any supported trait can be referenced in a condition_string. The trait's data type determines which operators are valid. For the full list of
out-of-the-box traits, their data types, and how each is populated, see Supported Traits in the Cortex Personalization documentation.
Available Operators
The following operators are registered with the condition evaluation service. The data types listed below indicate the trait types for which each operator is meaningful.
String Traits
| Operator | Description |
|---|---|
equalTo | True if the trait value equals the literal. |
notEqualTo | True if the trait value does not equal the literal. |
equalsIgnoreCase | Case-insensitive string equality. |
notEqualsIgnoreCase | Negation of equalsIgnoreCase. |
includes | True if the trait value (a string or a collection) contains the literal. For strings this is a substring match; for collections it is element membership. |
notIncludes | Negation of includes. |
includesIgnoreCase | Case-insensitive variant of includes for substring matching. |
notIncludesIgnoreCase | Negation of includesIgnoreCase. |
contains | Alias for includes. |
inList | True if the trait value matches any entry in a comma-separated list supplied as a quoted string. Example: GEOIP_COUNTRY_CODE.inList 'CA,US,MX'. |
notInList | Negation of inList. |
Numeric Traits (Integer, Long, Float, BigDecimal)
| Operator | Description |
|---|---|
equalTo | True if the trait value equals the literal. |
notEqualTo | True if the trait value does not equal the literal. |
lessThan | True if the trait value is strictly less than the literal. |
lessThanOrEqualTo | True if the trait value is less than or equal to the literal. |
greaterThan | True if the trait value is strictly greater than the literal. |
greaterThanOrEqualTo | True if the trait value is greater than or equal to the literal. |
inList | True if the trait value's string form matches any entry in a quoted comma-separated list. Example: SHOPPING_DAY_OF_WEEK.inList '1,2,3,4,5' (weekdays). |
notInList | Negation of inList. |
moduloEquals | Recurring-interval match for SHOPPING_DAY_NUMBER. The literal is a quoted string 'interval,startReference', where interval is the recurrence in days and startReference is either a SHOPPING_DAY_NUMBER value or an ISO date (such as 2025-01-01) used as the anchor. Example: SHOPPING_DAY_NUMBER.moduloEquals '7,2025-01-01' matches every seventh day from January 1, 2025 onward. |
Boolean Traits
| Operator | Description |
|---|---|
equalTo | True if the trait value equals the literal. |
notEqualTo | True if the trait value does not equal the literal. |
Date Traits
Date-valued traits (such as SHOPPING_CONTEXT_DATE_OVERRIDE) are comparable, so the numeric ordering operators (lessThan, lessThanOrEqualTo,
greaterThan, greaterThanOrEqualTo) plus equalTo and notEqualTo apply.
Examples
Shoppers aged 65 or older:
<condition_string>{ AND { CUSTOMER_AGE_YEARS.greaterThanOrEqualTo (65i) } }</condition_string>
Shoppers in a named segment:
<condition_string>{ AND { CUSTOMER_SEGMENT.includes 'Segment1' } }</condition_string>
Active only on weekdays between 9am and 5pm:
<condition_string>{ AND { SHOPPING_DAY_OF_WEEK.inList '1,2,3,4,5' SHOPPING_HOUR_OF_DAY.greaterThanOrEqualTo (9i) SHOPPING_HOUR_OF_DAY.lessThan (17i) } }</condition_string>
Shoppers in Canada or the United States who are registered:
<condition_string>{ AND { REGISTERED_CUSTOMER.equalTo true { OR { GEOIP_COUNTRY_CODE.equalTo 'CA' GEOIP_COUNTRY_CODE.equalTo 'US' } } } }</condition_string>
Every seventh day starting January 1, 2025:
<condition_string>{ AND { SHOPPING_DAY_NUMBER.moduloEquals '7,2025-01-01' } }</condition_string>