The articles below will walk you through the Sourcing Utilities (`util-sourcing`), designed to simplify implementing complex sourcing logic and reduce repetitive code.PrerequisitesBefore diving in, make sure you have:
The `util-sourcing` library is a comprehensive collection of utility functions designed to minimize the overhead and complexity of writing sourcing logic in your Fluent Commerce rules.PrerequisitesThese articles assumes you're familiar with:
Java
Maven
JUnit
Key points
Sourcing Orchestration (`SourcingUtils`): Orchestrates the sourcing process and provides helper methods to load a Sourcing Profile
Context Management (`SourcingContextUtils`): Loads and manages Sourcing Context
Order Helper (`OrderUtils`): Performs order-specific operations such as fulfillment creation
Location-Based Optimization (`LocationUtils`): Provides location-based helpers including distance calculations and caching
Sourcing Conditions and Criteria Management: Provides functions, registration, and execution logic for tailoring Sourcing Strategies to the specific needs of customers
Java Docs
The helper methods contained in the Utility Bundles libraries are many and varied, so the JavaDocs provided with the packages should be treated as the source of truth for documentation.
Faster Implementation: Common sourcing patterns are abstracted into reusable, tested components
Reduced Complexity: Standardized approaches prevent common sourcing errors and edge cases
Extensibility: Custom sourcing strategies can be easily implemented.
Consistent Patterns: Enforce best practices across your sourcing rule implementations
Explanation through an Example
Let's walk through a simple real-world scenario to understand how Sourcing Utilities work in practice.Imagine you're running an online store that receives an order for:
2x Gaming Laptops (high-value items)
3x Wireless Mice (medium-value items)
1x Gaming Headset (high-value item)
The customer lives in New York City, and you have inventory at multiple locations:
Main Warehouse (New Jersey) - Has all items in stock
Local Store (Manhattan) - Has laptops and mice, but no headset
Regional DC (Boston) - Has all items but higher shipping costs
How Sourcing Utilities Help
1// Load the sourcing profile for the current context2SourcingProfile sourcingProfile =SourcingUtils.loadSourcingProfile(context);
1// Create sourcing context with unfulfilled order items2SourcingContext sourcingContext =SourcingContextUtils.loadSourcingContext(3 context,4SourcingUtils::getUnfulfilledItems5);
1// Find the best sourcing plan based on strategies2SourcingPlan plan =SourcingUtils.findPlanBasedOnStrategies(3 context,4 sourcingContext,5 sourcingProfile,6ImmutableList.of(Constants.Status.ACTIVE),// Consider only ACTIVE positions7this::customInventoryProcessor8);
1// The system generates a sourcing plan that might look like:2SourcingPlan optimalPlan =newSourcingPlan();3optimalPlan.addFulfilment(4SourcingUtils.Fulfilment.builder()5.location(Location.builder().name("Manhattan Store").build())6.items(Arrays.asList(7Fulfilment.FulfilmentItem.builder().ref("2x Laptops").build(),8Fulfilment.FulfilmentItem.builder().ref("3x Mice").build())9)10.build()11);12optimalPlan.addFulfilment(13SourcingUtils.Fulfilment.builder()14.location(Location.builder().name("NJ Warehouse").build())15.items(Arrays.asList(16Fulfilment.FulfilmentItem.builder().ref("3x Mice").build())17)18.build()19);
1// Set fulfillment types2OrderUtils.fillFulfilmentType(sourcingContext, fulfilments);34// Create fulfillments from the plan5List<Fulfilment> fulfilments =OrderUtils.createFulfilments(6 context,7 sourcingContext,8 plan.getFulfilments()9);
What Happens Behind the Scenes
Inventory Analysis: System checks real-time inventory at all locations
Distance Calculation: Calculates delivery times and costs for each location
Strategy Evaluation: Applies business rules (proximity, cost, speed)
Optimization: Finds the best combination of locations to fulfil the order
This example shows how Sourcing Utilities transform a complex business decision into simple code.
The `SourcingUtils` class in the `util-sourcing` bundle is the main utility class that orchestrates the entire sourcingprocess within a Rule. It provides core helper methods such as loading a Sourcing Profile, initialise the Sourcing Context, and trigger the execution of the sourcing logic configured in the profile. Each stage supports multiple customisation points throughout the process.
Key points
Main Orchestrator: Central utility class that coordinates all sourcing operations from a Rule.
Strategy Evaluation: Evaluates and applies sourcing strategies based on business rules.
Plan Generation: Creates optimal sourcing plans for order fulfillment
Core Methods
`findPlanBasedOnStrategies()`
Finds the best Sourcing Plan for an order based on sourcing strategies defined in a Sourcing Profile.
1SourcingPlan plan =SourcingUtils.findPlanBasedOnStrategies(2 context,3 sourcingContext,4 profile,5ImmutableList.of(Constants.Status.ACTIVE),6null// No custom inventory processor7);
`findPlanBasedOnFallbackStrategies()`
Finds the sourcing plan for unfulfilled items using fallback sourcing strategies when no primary strategy fully satisfies the sourcing request.
Only one fallback strategy is used, specifically the first that satisfies the sourcing conditions.
Supports partial sourcing, where fulfillments may not completely satisfy the order.
Usually considers customer value over cost savings
1SourcingPlan plan =SourcingUtils.findPlanBasedOnFallbackStrategies(2 context,3 sourcingContext,4 profile,5ImmutableList.of(Constants.Status.ACTIVE),6null// No custom inventory processor7);8
`buildRejectedFulfilment()`
Builds a rejected fulfillment for all remaining unfulfilled items in the sourcing context.
1// Build system rejected fulfillment for unfulfillable items2Fulfilment rejectedFulfilment =SourcingUtils.buildRejectedFulfilment(3 context,4 sourcingContext,5 context.getProp(PROP_SYSTEM_REJECTED_LOC_REF)6);
Supporting Methods
`findPlanForAllItems()`
This helper method is used by the `findPlanBasedOnStrategies` method to identify a plan for an order based on the Sourcing Strategies. It loads candidate locations and their stock positions, ranks them using the provided Sourcing Criteria, and searches for the best combination of locations that can cover the full order within the allowed split limit. Fewer-location plans are always preferred. If no valid combination exists, it returns an empty plan.
This helper method is used by the `findPlanBasedOnFallbackStrategies` method to find the highest-value partial fulfillment. It filters out excluded locations, compares each candidate’s rating, and checks whether the location can cover at least part of the remaining items. The method returns the best fulfillment found or none if no positive-value option exists.
Loads Virtual Positions for sourcing operations. This method is used by both core methods (`findPlanForAllItems` and `findPlanBasedOnFallbackStrategies`) to load inventory.
Loads the sourcing profile for the current context.
1SourcingProfile profile =SourcingUtils.loadSourcingProfile(context);23if(profile !=null){4// Use the profile for sourcing operations5SourcingPlan plan =SourcingUtils.findPlanBasedOnStrategies(6 context,7 sourcingContext,8 profile,9ImmutableList.of(Constants.Status.ACTIVE),10null11);12}
Sourcing Profile Reference
Please note that the Rule property referencing the Sourcing Profile is assumed to be named `sourcingProfileRef`.
`getUnfulfilledItems()`
Computes outstanding order items after accounting for allocated but non-rejected quantities.
`SourcingContextUtils` in the `util-sourcing` is a utility class for managing sourcing context and data loading operations. It provides methods to create and populate sourcing contexts with order details, unfulfilled items, and supporting data required for sourcing decisions.
Key points
Context Management: Creates and manages Sourcing Context for the sourcing process.
Data Loading: Handles loading of order, item and required information.
Core Methods
`loadSourcingContext()`
Loads and creates a Sourcing Context with all necessary information such as order details, unfulfilled items, and supporting data required for sourcing decisions.
The `OrderUtils` class in the `util-sourcing` is a utility class that provides order-specific utilities for sourcing operations. It handles order-related sourcing operations including fulfillment creation, fulfillment type determination, and order item management.
Fulfillment Creation: Creates fulfillment records based on sourcing plans.
Fulfillment Type Management: Sets fulfillment types based on business rules.
Order Item Management: Manages order items and their allocation to fulfillments.
Core Methods
`createFulfilments()`
Creates fulfillments from a `SourcingPlan`, allocating order items to locations and assigning fulfillment types.
1// Create fulfillments from the sourcing plan2List<Fulfilment> createdFulfilments =OrderUtils.createFulfilments(3 context,4 sourcingContext,5 plan.getFulfilments()6);
`fillFulfilmentType()`
Determines and assigns a fulfillment type for each fulfillment based on the Sourcing Context characteristics such as location type and delivery method.
1// Set fulfillment types based on business rules2OrderUtils.fillFulfilmentType(sourcingContext, fulfilments);
`itemsMinusFulfilments()`
Subtracts the item quantities in a set of fulfillments from a list of order items. This can be used to determine the remaining order items after a set of proposed (but not yet created) fulfillments.
1// Get unfulfilled items2List<OrderItem> unfulfilledItems =SourcingUtils.getUnfulfilledItems(context);34// Find partial fulfillment5Optional<Fulfilment> partialFulfilmentOpt =SourcingUtils.findHighestValuePartialFulfilment(6 locationAndPositions,7 unfulfilledItems,8Collections.emptySet()// No excluded locations9);1011// Calculate remaining items after partial fulfillment12if(partialFulfilmentOpt.isPresent()){13Fulfilment partialFulfilment = partialFulfilmentOpt.get();14List<OrderItem> remainingItems =OrderUtils.itemsMinusFulfilments(15 unfulfilledItems,16Arrays.asList(partialFulfilment)17);18}
The `LocationUtils` class in the `util-sourcing` is a utility class that provides utilities for location-based sourcing decisions. It handles location-specific sourcing logic including distance calculations, location availability checks, and provide location-based caching optimization.