available from version 17.0
In CLIC documents (Quotes, Agreements & Promotions, Rebates and Compensation Plans), the decision whether a calculation runs synchronously or asynchronously has traditionally been driven by async thresholds (per header type or module). A value of 0 means the action always runs asynchronously, while a positive threshold switches to async once the number of line items reaches or exceeds that value. However, there are scenarios where the line count alone is not a reliable indicator of the expected processing load – for example, when the calculation will generate many line items later or perform heavy processing even before any items exist.
To cover these cases, a new Groovy API is available in supported header calculations that allows configuration engineers to explicitly switch the current CLIC calculation from synchronous to asynchronous mode at runtime. The method switchToAsync can be called only in the PREPROCESSING phase and only while the calculation is still running synchronously; if invoked, the current calculation switches to asynchronous processing and continues in the background without blocking the user. This API is intentionally one-way (sync → async only) and acts as a higher-priority runtime override on top of existing threshold semantics; it does not allow downgrading an already-async action back to sync, and if you do not call it, behavior remains unchanged.
When this method is called, everything that has been calculated so far is discarded, so it is best to call it early in the calculation logic.
Example: Switching to Async in PREPROCESSING
The following example shows how to request asynchronous execution from a Quote header logic in the PREPROCESSING phase. You can base the decision on any available business context (for example, an expected number of generated lines or a header flag set by the user).
// Header logic for a CLIC Quote (works similarly for other CLIC document types)
// This logic runs before the main calculation and can decide to switch to async.
if (quoteProcessor.isPrePhase()) {
// Example: switch to async when we expect heavy follow-up processing
// (replace with your real business rule condition)
def expectedGeneratedLines = 1650
if (expectedGeneratedLines > 500) {
// Explicitly switch the current calculation from sync to async.
// The current synchronous calculation is stopped, a JST job is created,
// and the JST object is returned in the calculate() response.
quoteProcessor.switchToAsync()
}
}
The core pattern is always the same: in PREPROCESSING, evaluate your business condition and call quoteProcessor.switchToAsync() when you want the current action to run asynchronously instead of synchronously.