Fluent Commerce Logo
Docs

How Sourcing Conditions work

Topic

Author:

Kirill Gaiduk

Changed on:

25 Sept 2025

Overview

This article introduces Sourcing Conditions as the mechanism that evaluates Sourcing Requests and returns outcomes used in Strategy selection. Readers will learn how reference schema, operators, and parameters shape these evaluations, and how custom schema can extend them.

Sourcing Conditions Overview

Author:

Kirill Gaiduk

Changed on:

2 Oct 2025

Overview

Sourcing Conditions let you control how Sourcing Strategies are applied within the Responsive Sourcing Framework. After reading, you will understand how to configure and extend them to adapt sourcing logic for specific Sourcing Requests.

Key points

  • Define your sourcing logic with configurable Sourcing Conditions that evaluate Sourcing Requests and return true/false outcomes
  • Reference Sourcing Conditions schema is global but can be extended or overridden with customer-specific definitions for tailored Strategies
  • Condition Utilities provide reference function, default operators (equality, comparison, membership, existence), and support custom extensions
  • All Conditions should be configured with clear naming and parameters to ensure accurate and predictable evaluation

What is a Sourcing Condition?

A Sourcing Condition is a function that returns a boolean value (`true` or `false`) based on the evaluation of the Sourcing Context. It determines whether a Primary or Fallback Sourcing Strategy applies to a specific Sourcing Request, such as:

  • Order
  • Fulfillment Choice
  • Fulfillment Option

Architectural Context

Sourcing Conditions are part of the Responsive Sourcing Framework within the Fluent platform. They sit in several places within the platform, each serving a distinct role:

1. Sourcing Condition Entity

Sourcing Condition Entity is represented by the `SourcingCondition` GraphQL type.

It refers to an individual, concrete instance of a Sourcing Condition that is configured as part of a Sourcing Strategy.

Structure

Field

Type

Description

Notes

`name`

`String`

Name of the Sourcing Condition

The `name` serves as a unique identifier for Sourcing Conditions

Reference Sourcing Conditions schema (specified in the `fc.rubix.order.sourcing.conditions` Setting) can be overridden by using the same `name` and alternative configuration in the `fc.rubix.order.sourcing.conditions.custom` Setting

`type`

`String`

Type of the Sourcing Condition

The `type` is mapped to a specific function in the `util-sourcing` library (Condition Utilities)

`params`

`Json`

Parameters of the Sourcing Condition

The Parameters configure Sourcing Conditions to support specific customer sourcing logic

Available configuration options are defined with the `fc.rubix.order.sourcing.conditions` and `fc.rubix.order.sourcing.conditions.custom` Settings

2. Sourcing Conditions Schema

The Sourcing Conditions schema is located in the dedicated Setting(s):

  • `fc.rubix.order.sourcing.conditions` stores reference (`GLOBAL`) Sourcing Conditions schema
  • `fc.rubix.order.sourcing.conditions.custom` can be created for customer-specific (`ACCOUNT` / `RETAILER`) Sourcing Conditions schema

It defines the structure of a Condition and specifies which parameters it can include. In practice, it acts as the template for a Sourcing Condition that is added to the Conditions library, making it available for configuration and use by end users.

3. Condition Utilities

Condition Utilities are an integral part of the Sourcing Utilities bundle.

They include:

  • Reference Condition Function (`DefaultSourcingCondition`)
    • This class evaluates a Sourcing Condition using three key parameters:
      • `path` – identifies the value(s) within the Sourcing Context (for example, Order creation date, Delivery country, Customer tier, or Product category)
      • `operator` – defines how the values are compared
      • `value` – the target value or array of values specified in the Condition `params`
    • The function checks whether the values retrieved from the Sourcing Context (via the JSON path) meet the criteria defined by the operator and `params` values
    • The outcome of this check determines whether the Condition is satisfied
  • Operator Utilities
    • Include reference operators (equality, comparison, set membership, existence checks)
    • Support custom operators registration (via `SourcingConditionOperatorRegistry`)
    • Provide common validation and value-conversion logic (`AbstractSourcingConditionOperator`)
  • Helper Methods (`SourcingConditionUtils`)
    • Evaluate a list of Conditions against a Sourcing Context
    • Return:
      • `true` if all Conditions pass or list is empty / `null`
      • `false` if at least one Condition fails
  • Custom Condition Registry (`SourcingConditionTypeRegistry`)
    • Registers and retrieves Condition types by identifiers
    • Dynamically instantiates Condition implementations during Strategy evaluation

Features

Within the Responsive Sourcing Framework, Sourcing Conditions provide the ability to:

  • Adapt sourcing logic to specific business needs by configuring different Sourcing Strategies and controlling their application based on the characteristics of a Sourcing Request
  • Leverage the reference library of predefined Sourcing Conditions, along with extensive configuration and customization options
  • Develop new Sourcing Conditions using recommended patterns and best practices to extend sourcing logic as needed

Getting Started with Reference Sourcing Conditions

Author:

Kirill Gaiduk

Changed on:

26 Sept 2025

Key Points

  • Master the Core Mechanism: Path Conditions extract values from the Sourcing Context, apply an operator, and evaluate them against configured value. Readers will understand how these checks return true/false outcomes that drive sourcing decisions
  • Handle Arrays with Care: Always define a `conditionScope` (ALL, ANY, NONE) when targeting collections. This ensures predictable results and prevents evaluation errors
  • Validate Parameters Rigorously: Use correct paths, operators, and value types. Misconfigured operators, unresolved paths, or type mismatches are the most common causes of Condition failures
  • Know When to Customize: Path Conditions cover most scenarios, but complex multi-field or non-standard requirements may call for registering a custom Condition type
No alt text provided

Steps

Step arrow right iconCore Concept

The Path Condition is a configurable function that evaluates data in the Sourcing Context and produces a true or false outcome. 

It extracts a value(s) from a specified path, applies an operator, compares it with a configured value, and, when necessary, aggregates results across arrays using a `conditionScope`.

During Strategy evaluation, the framework instantiates the reference implementation `DefaultSourcingCondition` for conditions of type `fc.sourcing.condition.path` and runs `evaluateWithContext` method.

Step arrow right iconInternal Mechanics

The reference implementation processes Conditions through the following sequence:

  • Resolves the JSON path with `JsonUtils.getPath(sourcingContext, path)` to locate the node
  • Flattens arrays when multiple values exist, ensuring that nested arrays are evaluated consistently
  • Applies the configured `conditionScope`:
    • ALL: every element must satisfy the operator
    • ANY: at least one element must satisfy the operator
    • NONE: no element may satisfy the operator
  • Compares the resolved values against the configured value using the operator retrieved from `SourcingConditionOperatorRegistry`

Step arrow right iconApplying Path Conditions to Real Scenarios

Path Conditions are best suited for logic that depend on a single field or a collection within the Sourcing Context. Practical scenarios include:

  • Checking Order timestamps (`createdOn`) with `greater_than`, `less_than`, or `between`
  • Validating Customer attributes such as `customer.attributes.byName.tier` with `in`
  • Filtering by delivery information, for example `fulfilmentChoice.address.country` with `in`.
  • Evaluating Product or Item properties over arrays, such as `unfulfilledItems.product.ref` combined with `ALL` or `ANY`.

Step arrow right iconParameter Definitions

Each Path Condition instance relies on the following parameters:

  • `path` (`String`): The JSON path in the Sourcing Context. Examples:
    • `createdOn`
    • `fulfilmentChoice.address.country`
    • `unfulfilledItems.product.ref`
  • `operator` (`String`): The comparison method. Supported operators:
    • Equality/membership: `equals`, `not_equals`, `in`, `not_in`
    • Comparison: `greater_than`, `greater_than_or_equals`, `less_than`, `less_than_or_equals`, `between`
    • Existence: `exists`, `not_exists`
  • `value` (UI component enforces correct input type): The target value(s)
  • (optional) `conditionScope` (`String`): Determines how array results are aggregated. Options (`SourcingConditionConstants`):
    • `ALL`
    • `ANY`
    • `NONE`

Step arrow right iconConfiguration in the UI

The reference schema in `fc.rubix.order.sourcing.conditions` Setting defines templates for Path Conditions. Each template specifies the operator, UI component, and validation logic, ensuring accurate input during configuration.

For account/retailer-specific adjustments, override Conditions in `fc.rubix.order.sourcing.conditions.custom`. When a Condition with the same `name` exists in both schemas, the custom schema takes precedence, allowing organizations to adapt global definitions to local business needs without breaking the baseline.

Step arrow right iconAttaching Conditions to Strategies

Path Conditions are added to Primary or Fallback Sourcing Strategies via the Sourcing Profile GraphQL API.

1mutation createSourcingProfile($input: CreateSourcingProfileInput) {
2    createSourcingProfile (input: $input) {
3        id
4        ref
5        version
6        versionComment
7        name
8        description
9        status
10        user {
11            id
12        }
13        createdOn
14        updatedOn
15        retailer {
16            id
17        }
18        defaultVirtualCatalogue {
19            ref
20        }
21        defaultNetwork {
22            ref
23        }
24        defaultMaxSplit
25        sourcingStrategies {
26            id
27            ref
28            sourcingProfile {
29                id
30            }
31            name
32            description
33            status
34            priority
35            createdOn
36            updatedOn
37            virtualCatalogue {
38                ref
39            }
40            network {
41                ref
42            }
43            maxSplit
44            sourcingConditions {
45                name
46                type
47                params
48            }
49            sourcingCriteria {
50                name
51                type
52                params
53            }
54        }
55        sourcingFallbackStrategies {
56            id
57            ref
58            sourcingProfile {
59                id
60            }
61            name
62            description
63            status
64            priority
65            createdOn
66            updatedOn
67            virtualCatalogue {
68                ref
69            }
70            network {
71                ref
72            }
73            maxSplit
74            sourcingConditions {
75                name
76                type
77                params
78            }
79            sourcingCriteria {
80                name
81                type
82                params
83            }
84        }
85    }
86}
1{
2  "input": {
3    "ref": "Puget_Sound",
4    "versionComment": "First version of Puget_Sound",
5    "name": "Puget_Sound",
6    "description": "Profile Description",
7    "retailer": {
8      "id": 1
9    },
10    "defaultVirtualCatalogue": {
11      "ref": "BASE:PS"
12    },
13    "defaultNetwork": {
14      "ref": "PS"
15    },
16    "defaultMaxSplit": 5,
17    "sourcingStrategies": [
18      {
19        "ref": "Seattle_Metro",
20        "name": "Seattle_Metro",
21        "description": "Seattle_Metro Sourcing Strategy",
22        "status": "ACTIVE",
23        "network": {
24          "ref": "SM"
25        },
26        "sourcingConditions": [
27          {
28            "name": "deliveryRegionIn",
29            "type": "fc.sourcing.condition.path",
30            "params": {
31              "path": "fulfilmentChoice.address.region",
32              "operator": "in",
33              "value": "Seattle Metro"
34            }
35          }
36        ],
37        "sourcingCriteria": [
38          {
39            "name": "networkPriority",
40            "type": "fc.sourcing.criterion.networkPriority",
41            "params": {
42              "value": [
43                "SM_LS",
44                "SM_WH"
45              ]
46            }
47          },
48          {
49            "name": "locationDistance",
50            "type": "fc.sourcing.criterion.locationDistance"
51          }
52        ]
53      },
54      {
55        "ref": "San_Juan_Islands",
56        "name": "San_Juan_Islands",
57        "description": "San_Juan_Islands Sourcing Strategy",
58        "status": "ACTIVE",
59        "network": {
60          "ref": "SJI"
61        },
62        "sourcingConditions": [
63          {
64            "name": "deliveryRegionIn",
65            "type": "fc.sourcing.condition.path",
66            "params": {
67              "path": "fulfilmentChoice.address.region",
68              "operator": "in",
69              "value": "San Juan Islands"
70            }
71          }
72        ],
73        "sourcingCriteria": [
74          {
75            "name": "networkPriority",
76            "type": "fc.sourcing.criterion.networkPriority",
77            "params": {
78              "value": [
79                "SJI_LS",
80                "SM_WH"
81              ]
82            }
83          },
84          {
85            "name": "locationDistance",
86            "type": "fc.sourcing.criterion.locationDistance"
87          }
88        ]
89      }
90    ],
91    "sourcingFallbackStrategies": [
92      {
93        "ref": "Coastal",
94        "name": "Coastal",
95        "description": "Coastal Strategy Description",
96        "status": "ACTIVE",
97        "sourcingConditions": [
98          {
99            "name": "allProductSizeIn",
100            "type": "fc.sourcing.condition.path",
101            "params": {
102              "path": "unfulfilledItems.product.attributes.byName.size",
103              "operator": "in",
104              "value": [
105                "Extra-Small",
106                "Small"
107              ],
108              "conditionScope": "ALL"
109            }
110          }
111        ],
112        "sourcingCriteria": [
113          {
114            "name": "locationDistanceExclusion",
115            "type": "fc.sourcing.criterion.locationDistanceExlusion",
116            "params": {
117              "value": 50,
118              "valueUnit": "miles"
119            }
120          },
121          {
122            "name": "orderValue",
123            "type": "fc.sourcing.criterion.orderValue"
124          }
125        ]
126      }
127    ]
128  }
129}
1{
2  "data": {
3    "createSourcingProfile": {
4      "id": "333",
5      "ref": "Puget_Sound",
6      "version": 1,
7      "versionComment": "First version of Puget_Sound",
8      "name": "Puget_Sound",
9      "description": "Profile Description",
10      "status": "ACTIVE",
11      "user": {
12        "id": "1302"
13      },
14      "createdOn": "2025-08-18T13:41:40.774Z",
15      "updatedOn": "2025-08-18T13:41:40.774Z",
16      "retailer": {
17        "id": "1"
18      },
19      "defaultVirtualCatalogue": {
20        "ref": "BASE:PS"
21      },
22      "defaultNetwork": {
23        "ref": "PS"
24      },
25      "defaultMaxSplit": 5,
26      "sourcingStrategies": [
27        {
28          "id": "516",
29          "ref": "Seattle_Metro",
30          "sourcingProfile": {
31            "id": "333"
32          },
33          "name": "Seattle_Metro",
34          "description": "Seattle_Metro Sourcing Strategy",
35          "status": "ACTIVE",
36          "priority": 1,
37          "createdOn": "2025-08-18T13:41:40.787Z",
38          "updatedOn": "2025-08-18T13:41:40.787Z",
39          "virtualCatalogue": null,
40          "network": {
41            "ref": "SM"
42          },
43          "maxSplit": null,
44          "sourcingConditions": [
45            {
46              "name": "deliveryRegionIn",
47              "type": "fc.sourcing.condition.path",
48              "params": {
49                "path": "fulfilmentChoice.address.region",
50                "value": "Seattle Metro",
51                "operator": "in"
52              }
53            }
54          ],
55          "sourcingCriteria": [
56            {
57              "name": "networkPriority",
58              "type": "fc.sourcing.criterion.networkPriority",
59              "params": {
60                "value": [
61                  "SM_LS",
62                  "SM_WH"
63                ]
64              }
65            },
66            {
67              "name": "locationDistance",
68              "type": "fc.sourcing.criterion.locationDistance",
69              "params": null
70            }
71          ]
72        },
73        {
74          "id": "517",
75          "ref": "San_Juan_Islands",
76          "sourcingProfile": {
77            "id": "333"
78          },
79          "name": "San_Juan_Islands",
80          "description": "San_Juan_Islands Sourcing Strategy",
81          "status": "ACTIVE",
82          "priority": 2,
83          "createdOn": "2025-08-18T13:41:40.782Z",
84          "updatedOn": "2025-08-18T13:41:40.782Z",
85          "virtualCatalogue": null,
86          "network": {
87            "ref": "SJI"
88          },
89          "maxSplit": null,
90          "sourcingConditions": [
91            {
92              "name": "deliveryRegionIn",
93              "type": "fc.sourcing.condition.path",
94              "params": {
95                "path": "fulfilmentChoice.address.region",
96                "value": "San Juan Islands",
97                "operator": "in"
98              }
99            }
100          ],
101          "sourcingCriteria": [
102            {
103              "name": "networkPriority",
104              "type": "fc.sourcing.criterion.networkPriority",
105              "params": {
106                "value": [
107                  "SJI_LS",
108                  "SM_WH"
109                ]
110              }
111            },
112            {
113              "name": "locationDistance",
114              "type": "fc.sourcing.criterion.locationDistance",
115              "params": null
116            }
117          ]
118        }
119      ],
120      "sourcingFallbackStrategies": [
121        {
122          "id": "315",
123          "ref": "Coastal",
124          "sourcingProfile": {
125            "id": "333"
126          },
127          "name": "Coastal",
128          "description": "Coastal Strategy Description",
129          "status": "ACTIVE",
130          "priority": 1,
131          "createdOn": "2025-08-18T13:41:40.781Z",
132          "updatedOn": "2025-08-18T13:41:40.781Z",
133          "virtualCatalogue": null,
134          "network": null,
135          "maxSplit": null,
136          "sourcingConditions": [
137            {
138              "name": "allProductSizeIn",
139              "type": "fc.sourcing.condition.path",
140              "params": {
141                "path": "unfulfilledItems.product.attributes.byName.size",
142                "value": [
143                  "Extra-Small",
144                  "Small"
145                ],
146                "operator": "in",
147                "conditionScope": "ALL"
148              }
149            }
150          ],
151          "sourcingCriteria": [
152            {
153              "name": "locationDistanceExclusion",
154              "type": "fc.sourcing.criterion.locationDistanceExlusion",
155              "params": {
156                "value": 50,
157                "valueUnit": "miles"
158              }
159            },
160            {
161              "name": "orderValue",
162              "type": "fc.sourcing.criterion.orderValue",
163              "params": null
164            }
165          ]
166        }
167      ]
168    }
169  }
170}

Step arrow right iconPractical Examples

  • Premium Customer tiers
    • Path: customer.attributes.byName.tier
    • Operator: in
    • Value: ["PLATINUM", "GOLD"]
  • Restricted SKUs
    • Path: unfulfilledItems.product.ref
    • Operator: in
    • Value: ["SKU_1", "SKU_2", "SKU_3"]
    • Scope: ANY
  • Promotional date window
    • Path: createdOn
    • Operator: between
    • Value: ["2025-09-01T00:00:00Z", "2025-09-30T23:59:59Z"]

Step arrow right iconCommon Issues and Troubleshooting

  • Non-value nodes: Adjust the path so it resolves to a scalar rather than an object
  • Array mismatches: Add a `conditionScope` when targeting collections such as Items or Categories
  • Operator errors: Ensure the operator string matches a registered operator in `SourcingConditionOperatorRegistry`
  • Type mismatches: Provide values in the expected format (ISO dates, numbers, or exact strings)
  • Range confusion: Confirm inclusivity rules when using between or comparison operators

Step arrow right iconBest Practices

  • Use descriptive names that reflect business intent
  • Start with reference templates before creating custom overrides
  • Always define `conditionScope` explicitly for array paths
  • Provide exact values and enforce strict types through schema-driven components
  • Test boundary and edge cases thoroughly
  • Apply overrides in `fc.rubix.order.sourcing.conditions.custom` when tailoring conditions for specific Accounts / Retailers

Create Custom Sourcing Condition

Authors:

Kirill Gaiduk, Alexey Kaminskiy

Changed on:

24 Sept 2025

Key Points

  • Outcome: After completing this guide, you will know how to extend the Responsive Sourcing Framework with a Custom Condition and apply it in real Strategies
  • Minimal essentials: The process has four parts - implement the Condition, register it, expose it in the Setting, and verify behavior
  • Application: You will be able to influence sourcing decisions with your own logic, tailored to specific business contexts

Steps

Step arrow right iconPreliminary Setup

Custom Sourcing Condition creation requires modifying the Sourcing Utilities bundle:

1. Prepare your module that contains Order Reference Module assets.

2. Download the Sourcing Utilities Package (Java source code).

3. Add Sourcing Utilities as a dependency in your project's ``pom.xml`` file.

Step arrow right iconImplement a Custom Sourcing Condition Function

Create a Condition class that enforces your business logic:

  • Create your class, e.g., `MySourcingCondition`, implementing the `SourcingCondition` interface.
  • Add your evaluation logic in `evaluateWithContext` method.

Step arrow right iconRegister the Condition in the Type Registry

Register the Condition with a unique `type` key in the static block of `SourcingConditionTypeRegistry`.

1static {    SourcingConditionTypeRegistry.register("company.sourcing.condition.my", new MySourcingCondition());}

Step arrow right iconExpose the Condition Schema via Setting

Create (or update the existing) the Setting `fc.rubix.order.sourcing.conditions.custom` with your new Condition schema.

1mutation createSetting ($input: CreateSettingInput) {
2    createSetting (input: $input) {
3        id
4        name
5        valueType
6        lobValue
7        value
8        context
9        contextId
10    }
11}
1{
2  "input": {
3    "name": "fc.rubix.order.sourcing.conditions.custom",
4    "valueType": "JSON",
5    "lobValue": [
6      {
7      "name": "mySourcingCondition",
8      "type": "company.sourcing.condition.my",
9      "tags": [
10        "Lorem ipsum"
11      ],
12      "params": [
13        {
14        "name": "parameter1",
15        "value": "Lorem ipsum"
16        },
17        {
18        "name": "parameterN",
19        "value": "Lorem ipsum"
20        }
21      ]
22      }
23    ],
24    "value": "",
25    "context": "RETAILER",
26    "contextId": 1
27  }
28}
1{
2    "data": {
3        "createSetting": {
4            "id": "13141",
5            "name": "fc.rubix.order.sourcing.conditions.custom",
6            "valueType": "JSON",
7            "lobValue": [
8                {
9                    "name": "mySourcingCondition",
10                    "type": "company.sourcing.condition.my",
11                    "tags": [
12                        "Lorem ipsum"
13                    ],
14                    "params": [
15                        {
16                            "name": "parameter1",
17                            "value": "Lorem ipsum"
18                        },
19                        {
20                            "name": "parameterN",
21                            "value": "Lorem ipsum"
22                        }
23                    ]
24                }
25            ],
26            "value": "",
27            "context": "RETAILER",
28            "contextId": 1
29        }
30    }
31}

Step arrow right iconVerify the Condition Behavior

  • Use the Sourcing Profile GraphQL API to add the new Condition to a Sourcing Strategy. 
  • Test against different Sourcing Requests and confirm the expected outcomes.