Interface PublicGroovyAPI


public interface PublicGroovyAPI
This interface represents what can be reached in the Groovy element syntax as api. That api variable or binding is merely an instance of this interface to expose certain "safe" methods and functionality.

Basic Categories of Groovy API Functions

A better understanding of Groovy API possibilities can be achieved by categorizing the Groovy API methods as follows:
Please note: this is not a comprehensive list of all categories for all available methods.
Category Description Examples
Input Functions A convenient way to create user inputs. See the InputBuilderFactory class to view all available methods for creating inputs. api.inputBuilderFactory()
Output Functions Methods used for working with results. api.attributedResult(), api.newMatrix(), api.buildHighchart(),...
Data Querying Functions Methods that can be used for the data lookup, search, or query. Includes, for example, api.find as the most popular search method. api.find(), api.vlookup(), api.getDatamartContext(), api.executeQuery(),...
Data Manipulation Functions Methods used for create, update, or delete operations. api.addOrUpdate(), api.delete(), api.update(),...
Filter Functions Operators available for setting filter criteria. equal(), greaterThan()
Calculation Engine Functions Methods used for a variety of operations with logics. For example, for calculations, context retrieval, price list item retrieval, etc. api.currentItem(), api.getCalculationContext(), api.getCalculableLineItem(),...
Date and Time Functions Methods used for working with date and time formats. api.targetDate(), api.parseDate(), api.calendar(),...
Tracing and Debugging Functions Methods used for setting up alerts, tracing, logging, and messaging. api.trace(), api.logInfo(), api.setAlertMessage(),...

Caching usage
The API exposes three ways to store transient and temporary data during formula executions. Each variant has its own specifics and therefore is not suitable for all use cases. The options are:
  • api.local
  • api.global
  • Shared Cache

The first two can be understood as mere in-memory hash maps. For example, api.local.put("key","value") will work fine.
The difference between them is the potential scope and retention of the contained data.

api.local
This is a hash map that is available during the lifetime of exactly one logic execution. It can (and should) be used to store intermediate results that need to be accessed by other subsequent logic elements.

api.global
By default, api.global is very similar to api.local. Without any further settings, the only difference is that api.global is also available in Groovy library functions (while api.local is not).
However, by setting api.retainGlobal = true you can instruct the formula engine to keep the hash map in between logic runs. It works between line items and, in case of Quotes, Contracts, Rebate Agreements and Claims, between the header and the line items (but only in the pre-phase, not in the post-phase). The values are also carried forward between two list calculation passes (i.e. from initial run to dirty item run; ONLY in non-distributed mode).

Calculation Flows Specifics
api.global persists between Calculation Flow (CF) logic executions and is stored within the globalFormulaState property of the CF object. If you do not want to share the global cache between logic executions, use the api.local instead, or add api.retainGlobal = false at the beginning of CF logics.
Note: api.global data in Calculation Flows (in globalFormulaState) property is stored as a String. Use the jsonDecode(String) to convert it back to the Groovy object (a Map).
Example:


 def cf = api.find(
     "CF",
     Filter.equal("uniqueName", "ScheduleCalculations"),
     Filter.equal("draft", "false")
 ).first()

 def config = api.jsonDecode(cf.configuration).entries.get(0)?.globalFormulaState

 return config.lastCalculationDate
 

Important notes:
retainGlobal can be set to true either in the logic or globally in Configuration > All Modules > General Settings > api.retainGlobal defaults to TRUE.
retainGlobal is effective only once. In order to keep it for the 3rd item as well (and so on) you need to call it in every formula execution.
api.global data also stick to their execution thread. That means that they are NOT shared between the different parallel executions of a distributed calculation. It effectively builds up multiple caches. Another side effect of this is that api.global is not retained and passed to a subsequent calculation pass if the original calculation was in a distributed mode.
But even in non-distributed mode api.global is not passed on to the next calculation pass in case the data inside is too large.

So generally api.global should be treated as a cache. And the nature of caches is that there is no guarantee entries are there - in particular when expecting this between calculation passes. Formula logic should always handle this situation gracefully when expected cache entries aren't available.

Note also that since Vesper 6.0, the maximum string size of JSON serialized api.global content that is passed on to dirty passes is limited to 2 MB. This is configurable in pricefx-config.xml (maxGlobalsSize).

Shared Cache
The main limitation of api.global is the restriction of its availability to the current execution thread. In a distributed calculation, however, there are multiple threads and even multiple servers involved in the calculation. If all these should share a single cache, you must use the shared cache. The shared cache is even available to different calculations (such as other lists or list & CFS or dashboard logic etc). Be careful with key naming so that you do not mix and match data.

These advantages come at a cost: Due to the distributed "superglobal" nature, the read/write operations of that cache are slower compared to a real local in-memory map. Use the shared cache only for data that is expensive to calculate or for avoiding frequent database calls. Data in the shared cache expires automatically, the TTL is extended everytime a key is written or read. Values stored are of the String type only. Serialization and deserialization of other objects like dates and numbers are to be done in logic itself.

Object modifications
The API contains methods to manipulate data (add, addOrUpdate, delete, etc). These methods can only be used in certain formula contexts (otherwise they are ignored). These contexts are:

  • From within a CFS execution (non-distributed only)
  • From within a calculation flow
  • From within a direct logic execution via JSON API

On top of this, some restrictions apply which data objects can be manipulated - i.e. not every possible object can be modified. Currently available whitelisted typecodes are:
  • All customer extension types
  • All product extension types
  • All matrix Company Parameter / Price Parameter / Price Parameter values and normal Company Parameter / Price Parameter / Price Parameter values (LTV) as well as Company Parameter / Price Parameter header (LT)
  • PGI and XPGI
  • PLI and XPLI
  • MPLI
  • P
  • C
  • PCOMP
  • PDESC
  • PGI
  • TODO
  • Data export, import and archive
  • Method Details

    • isSyntaxCheck

      @Deprecated boolean isSyntaxCheck()
      Deprecated.
      Returns true if the logic/formula is being executed in the syntax check mode. The syntax check mode is a special type of execution run used to determine the logic input parameters in the configuration dialogs, where the logics are selected (e.g. in configuration of LPGs, PLs or dashboards). These input parameters are also used on document line items (like Quote, Contract, etc). The syntax check mode runs against no calculable item (in context of no object), so all the functions that depend on item data (e.g. product() or currentItem() as well as getElement(String)) produce null or mocked values.

      Note: The best practice is to gather all parameters in the first elements of the logic and then abort the calculation after all parameters are gathered, otherwise all code which depends on the item data will need a special treatment (it would have to be surrounded using this function).

      Example:

      Element Amount:

      
       return api.decimalUserEntry("Amount")
       
      Element Comment:
      
       return api.stringUserEntry("Comment")
       
      Element SyntaxCheckAbort:
      
       if (api.isSyntaxCheck()) {
         api.abortCalculation()
       }
       
      Returns:
      True if the logic is executed in the syntax check mode.
    • isInputGenerationExecution

      boolean isInputGenerationExecution()
      Returns true if the logic/formula is being executed in the so called input generation mode (special type of the execution run used to determine the logic input parameters). These input parameters are also used on document line items (like Quote, Contract, etc). The InputGenerationExecution mode runs against no calculable item (in context of no object), so all the functions that depend on item data (e.g. product(), currentItem() or getElement(String)) produce null or mocked values.

      Note: The best practice is to gather all parameters in the first elements of the logic and then abort the calculation after all parameters are gathered, otherwise all code which depends on the item data will need a special treatment (it would have to be surrounded using this function).
      Historically isSyntaxCheck() was used to cover this feature (i.e. to check the syntax of the of formula language element and to generate the input parameters before the normal run is executed)

      Example: Element Amount:
      
       return api.decimalUserEntry("Amount")
       
      Element IsInputGenerationExecution:
      
       if (api.isInputGenerationExecution()) {
         api.abortCalculation()
       }
       
      Returns:
      True if the logic is executed in the Input Generation mode.
    • isDebugMode

      boolean isDebugMode()
      Returns true if the logic is being executed via the UI "Test Logic" execution mode. During the testing process, some information may not be available to the logic being "tested". If this is the case, you can use this method to detect the "Test Logic" mode and create mock data for any necessary information that is not available.

      For example, in the Quote item logic, you typically need information about customer ID. This information is commonly provided via input field on the header. But when you test the Quote item logic in Studio, the value of this header input field is not available, because the logic is executed standalone without the information from any Quote document.
      Using the method api.isDebugMode() you can detect, that the logic is executed in this special test mode and supply a mock value of a particular customerId for testing purposes.

      Code sample – the logic element “CustomerId“ is used to read the value of the Customer input field in the Quote item logic:

      
       def customerId = input.Customer
       if (api.isDebugMode()) {
           customerId = "CD-00004"
       }
       return customerId
       
      Returns:
      true if the logic is being executed in the "Test Logic" mode.
    • isDistributedMode

      boolean isDistributedMode()
      Returns true if the calculation is executed in the distributed mode. Useful to suppress warnings (or not execute methods) for operations that do not work in the distributed mode. These operations are basically all write operations that affect other items. Examples: all object modification ops (add, addOrUpdate, update, delete), marking other items dirty.

      Example:
      
       return api.isDistributedMode()
       
      Returns:
      True if executed in the distributed mode.
    • getGlobal

      Map<String,Object> getGlobal()
      A publicly available cache (as a hashmap) for storing and sharing values across logic elements. If api.retainGlobal is set to true, this map will also be available with the entire list calculation, i.e across item boundaries. It can also be accessed directly as api.global.

      Note: This map must be treated as a cache. It means that the logic should never rely on the cached values, as in various situations this cache is purged or structured differently. For example, in a distributed calculation, every calculation thread has its own cache; or in a multi-pass list calculation, the subsequent passes may not have the cache of the previous pass available. The system always tries to make it available, but the logic should never rely on it.

      Example:

      
       return api.getGlobal()
       
      Returns:
      the hashmap
    • putGlobal

      void putGlobal(Map<String,Object> globalVars)
      Puts an entire map of variables into the global cache.
      Parameters:
      globalVars - Map of variables to put into the global cache.

      Example:
      
       def globalMap = [:]
       
      return api.putGlobal(globalMap)
    • queryApi

      QueryApi queryApi()
    • getCalculationContext

      String getCalculationContext()
      Retrieves the CalculationContext of the logic evaluation (logic element group).

      1. For a PA Calculation or Flush logic this can be (from PriceFxInterface):
        • FORMULAELEMENTGROUP_DM_INIT = "init" - executed before rows
        • FORMULAELEMENTGROUP_DM_ROW = "row" - executed for every line of the Target/Source
        • FORMULAELEMENTGROUP_DM_SUMMARY = "summary" - executed after rows
      2. In RebateAgreement calculation there is:
        • FORMULAELEMENTGROUP_RM_AGREEMENT = "agreement"
        • FORMULAELEMENTGROUP_RM_AGREEMENT_READONLY = "agreementReadOnly"
        • FORMULAELEMENTGROUP_RM_REBATERECORD = "rebateRecord"
      3. In the PriceOptimizer module, when evaluating Model formulas, there is:
        • FORMULAELEMENTGROUP_MODEL_DEFINITION = "definition"
        • FORMULAELEMENTGROUP_MODEL_CALCULATION = "calculation"
        • FORMULAELEMENTGROUP_MODEL_ANALYSIS = "analysis"
        • FORMULAELEMENTGROUP_MODEL_FINALIZATION = "finalization"
        • FORMULAELEMENTGROUP_MODEL_RECORD = "record"

      Example:
      
       return api.getCalculationContext()
       
      Returns:
      CalculationContext as String.
    • getBatchInfo

      List<String[]> getBatchInfo()
      Retrieves the information about the current batch of items being calculated by a calculation thread. The calculation batch size is by default 200 records (defined by the server variable calculationTasks.commitBatchSize). It is a good practice to use "BatchUtils" functions from the Shared Library.

      Example (without the SharedLib usage):

      
      
           def sku = api.product("sku")
      
       // if Batch not yet available or the SKU is not in the Current Batch, treat it as beginning of new batch
       def isNewBatch = api.global.currentBatch == null
                        || !api.global.currentBatch.contains(sku)
      
       // when the new batch starts, pre-load the list of SKUs from the Batch into memory
       if (isNewBatch) {
           api.global.currentBatch =
                   api.getBatchInfo()?.collect { it.first() }?.unique()
                           ?: ([sku] as Set)
       }
      
       // when the new batch starts, do pre-load product costs (for all SKUs of the batch) into memory
       if (isNewBatch) {
      
           //TODO remove the logging in Production environment
           api.logInfo("NewBatchOfSKUs: ", api.jsonEncode(api.global.currentBatch))
      
           def rowIterator = api.stream(
                   "PX3", "sku", ["sku", "attribute1"],
                   Filter.equal("name", "ProductCost"),
                   Filter.in("sku", api.global.currentBatch)
           )
           api.global.productCosts = rowIterator
                   ?.collectEntries { [(it.sku): (it.attribute1 as BigDecimal)] }
      
           rowIterator.close()
       }
      
       return api.global.productCosts[sku]
      
       
      Returns:
      List of arrays [sku, key2] for PLI, XPLI, PGI, XPGI contexts, or [itemId, typedId] for CFS logics run on P, PX, or all defined keys (as a list of arrays) for the Calculation Grid context.

      Returns null while in the debug mode, or when you manually trigger the re-calculation of a single line of LPG. key2 is null when a regular price list (PL) is being calculated.

      See Also:
    • getId

      Long getId(Object obj)
      Returns the ID part of an object. The method tries to be smart and extracts also IDs from maps or typedId strings.

      Example:
      
       def typeId = "testTypeId"
       return api.getId(typeId)
       
      Parameters:
      obj - Given object (Map).
      Returns:
      ID of the object.
    • getElement

      @Deprecated Object getElement(String name)
      Deprecated.
      This function is deprecated and has been replaced with the Groovy binding variable out. Use out.<ElementName> (or output.<ElementName>) instead.
      Gets the result value returned by the previous logic element.

      Note: Instead of this function, you can also use out.<ElementName> (or output.<ElementName>).

      Warning: In the input generation mode, this function returns mock results, not the real ones.

      Parameters:
      name - Name of the logic element whose value you want to retrieve.
      Returns:
      Value or null if the element is not found. In the input generation check mode, the result value is mocked.
      See Also:
    • getSecondaryKey

      Object getSecondaryKey()
      The same as api.currentItem("key2"). It retrieves the secondary key (field "key2") of a matrix item record.
      It is applicable in the following contexts:
      • Matrix price grid (XPGI.key2)
      • Matrix price list (XPLI.key2)
      • Matrix simulation (XSIMI.key2)

      Example:
      
       return api.getSecondaryKey()
       
      Returns:
      Value of the secondary key or null if calculating a single item record (= not a matrix item record from the list above).
    • getBinding

      Object getBinding(String name)
      Gets a named binding variable from a library function.

      Example: In a workflow formula, the workflow can be referenced in a Groovy element directly by the binding/variable "workflow": workflow.addApprovalStep("First Approval").

      However, this does not work from a library function as this script does not have the binding available. You need to use:

      
       api.getBinding("workflow").addApprovalStep("First Approval")
       
      Parameters:
      name - Name of the variable
      Returns:
      Binding
    • targetDate

      Date targetDate()
      Returns an effective/target date of the document being calculated. (It retrieves this mandatory parameter targetDate from the current execution context.)

      The target date is usually new Date() by default or it is overriden by the user in:

      • Quotes - In the Quote view, entered via the Effective Date input parameter.
      • Price lists - In the price list creation dialog, entered in the Get Parameters step.
      • Price grids - In the price grids overview window, in the Target date column.
      • PA calculation Data Loads - In the Data Load definition, at the Calculation tab.
      • Calculation flow - In the Calculation flow detail, in the Target date column.

      Example:

      
       api.targetDate().format("yyyy-MM-dd")
       
      Returns:
      targetDate date
    • calendar

      Calendar calendar()
      Gets a java.util.Calendar object initialized with the current targetDate (or a new Date() if no target date is given). It is used for adding days/months/year and/or setting hours, minutes, seconds.

      Example:

      
       def months = 6
      
       def calendar = api.calendar()
      
       // adds months to the date
       calendar.add(Calendar.MONTH, months)
       calendar.set(Calendar.HOUR_OF_DAY, startHour)
       calendar.set(Calendar.MINUTE, 0)
       calendar.set(Calendar.SECOND, 0)
      
       // return the date 6 months later after targetDate at 00:00:00
       calendar.getTime()
       
      Returns:
      Initialized Calendar object
    • calendar

      Calendar calendar(Date date)
      Gets a calendar object initialized with date.

      Example:

      
       def months = 6
       def targetDate = api.targetDate()
      
       def calendar = api.calendar(targetDate)
      
       // adds months to the date
       calendar.add(Calendar.MONTH, months)
       calendar.set(Calendar.HOUR_OF_DAY, startHour)
       calendar.set(Calendar.MINUTE, 0)
       calendar.set(Calendar.SECOND, 0)
      
       // returns the date 6 months later after the given date at 00:00:00
       calendar.getTime()
       
      Parameters:
      date - Date to initialize the calendar with.
      Returns:
      Initialized Calendar object.
    • random

      Random random()
      Provides access to the standard java.util.Random generator instance created for the duration of the calculation task (= not get re-created for each logic element evaluation).

      Example 1:

      
       def randomPct = (90 + api.random().nextInt(20)) / 100
       // randomPct contains random Integer number between 90 (inclusive) and 110 (exclusive)
       

      Example 2:

      
       def random = api.random().nextLong()
       // random contains random Long number e.g. -2249116201139970752
       
      Returns:
      java.util.Random generator instance created for the duration of the calculation task. (i.e. does not get re-created for each formula (element) evaluation).
      See Also:
    • datamartCalendar

      Object datamartCalendar()
      Deprecated.
      Returns:
      DatamartContext.Calendar object.
    • newDatamartSlice

      @Deprecated Object newDatamartSlice()
      Deprecated.
      Creates a new DatamartSlice which allows setting filter criteria along the Time, CustomerGroup, ProductGroup or other dimensions in a Datamart.
      Returns:
      Instantiated, empty DatamartContext.DataSlice object.
    • newDatamartSlice

      Object newDatamartSlice(String dateFieldName, Object... timePeriodsAndProductAndCustomerGroups)
      Creates a new DatamartSlice which allows setting filter criteria along the Time, CustomerGroup, ProductGroup or other dimensions in a Datamart, initialized with the name of the time dimension field and an optional set of filter criteria.
      Parameters:
      dateFieldName - Name of the time dimension field.
      timePeriodsAndProductAndCustomerGroups - TimePeriod, CustomerGroup, ProductGroup filters.
      Returns:
      Initialized DatamartContext.DataSlice object.
    • datamartFilter

      Filter datamartFilter(Object groupOrSlice)
      Translates a CustomerGroup/ProductGroup/DMDataSlice to its equivalent filter representation, mapping the domain level field names to the corresponding Datamart field names in the process.

      Note: A DMDataSlice object can be instantiated by api.newDatamartSlice, or in a Rebate calculation context, referenced by the 'calulationBase' binding.

      
       if (api.isInputGenerationExecution()) {
           return api.inputBuilderFactory()
                   .createCustomerGroupEntry("CustomerGroup")
                   .getInput()
       }
      
       def customerGroup = CustomerGroup.fromMap(input.CustomerGroup)
      
       def filter = api.datamartFilter(customerGroup)
       
      Parameters:
      groupOrSlice - CustomerGroup/ProductGroup/DMDataSlice to translate into Datamart level filter criteria.
      Returns:
      Filter object representing either the CustomerGroup/ProductGroup dimension slice or the passed slice in the Datamart.
    • datamartQuery

      Object datamartQuery(Object... queryAndDatamartAndProjectionsAndFilters)
      This method is deprecated and exists only for backward compatibility for older in-production formulas. Use the Groovy query API instead (see DatamartContext).

      Runs a query against a PA Datamart. The query is only executed once in the scope of a calculation job (PL generation etc.). The query is identified by the first argument. This is also the 'handle' by which datamartLookup refers to the result set of the query.

      Parameters:
      queryAndDatamartAndProjectionsAndFilters - The first argument is the query ID/handle, subsequent arguments are either DM field names (projections) or filter objects.
      Returns:
      Numbers of rows in the result set. The actual result set data is stored in memory for a subsequent lookup by datamartLookup(...).
    • datamartLookup

      Object datamartLookup(Object... queryAndProjectionsAndFilters)
      This method is deprecated and only exists for backward compatibility for older in-production formulas. Use the Groovy query API instead (see DatamartContext).

      Looks up rows in the result of a datamartQuery(...) call.

      Parameters:
      queryAndProjectionsAndFilters - The first arguments is the ID/handle from a datamartQuery(...) call. Subsequent arguments refer to projections specified in the datamartQuery call or filter objects leading to additional filtering of rows in the result set.
      Returns:
      A single primitive value if the result of the lookup results in one row for just one projection. A list of values if the result is multiple rows for one projection. A map of (field name, value) pairs for a single row result with multiple projections. A Matrix2D object for multiple rows and projections.
    • getDatamartContext

      DatamartContext getDatamartContext()
      Provides an API for querying and loading PA data. The most common cases are:

      Example 1:

      
       def ctx = api.getDatamartContext()
      
       def dm = ctx.getDatamart("Transactions_DM")
      
       def query = ctx.newQuery(dm, true)
           .select("ProductGroup")
           .select("SUM(SalesValue)")
           .where(
               Filter.equal("Year", "2019"),
           )
           .groupBy("ProductGroup")
           .orderBy("ProductGroup")
      
       def result = ctx.executeQuery(query)
      
       return result?.getData()
       

      Example 2:

      
       def date = api.parseDate("yyyy-MM-dd", "2018-01-24")
       def week = api.getDatamartContext().calendar().getWeek(date)
       return week
       
      Returns:
      DatamartContext
    • getTableContext

      TableContext getTableContext() throws Exception
      Provides an SQL query (SELECT only) interface to PA query results.
      Example:
      
       return api.getTableContext()
       
      Returns:
      TableContext
      Throws:
      Exception - if a DB connection cannot be established.
    • getDatamartRowSet

      DatamartRowSet getDatamartRowSet()
      A DatamartRowSet provides access to the rows being loaded or calculated. Available in a PA DataLoad context only. Example:
      
       def newRow = [
            "sku" : "1234456",
            "cost" : 123
       ]
      
       def target = api.getDatamartRowSet()
      
       // target is null when running the logic test execute, so you can use trace for debugging purposes
       if (target) {
           target.addRow(newRow)
       } else {
           api.trace("newRow", null, newRow)
       }
       
      Returns:
      DatamartRowSet holding the data rows to load in the target FC.
    • getDatamartRowSet

      DatamartRowSet getDatamartRowSet(String name)
      A DatamartRowSet provides access to the rows currently being loaded or calculated. Available in a PA DataLoad context only.
      The following Data Load types make use of rowsets:
      • Flush - The source rowset gives access to the DataFeed data rows, while the target rowset holds the rows to be loaded in the target DataSource (DS).
      • Calculate - The source rowset gives access to the source rows, which can either come from a DF or from the target FC being calculated. The target rowset holds the rows to be loaded in the target FC. Initially, this rowset will be empty unless the DL.withTargetSnapshot option is set, in which case the rowset will be pre-populated with the target FC rows in the scope of the DL (determined by the DL.filter).

      Example 1:

      
       def newRow = [
            "sku" : "1234456",
            "cost" : 123
       ]
      
       def target = api.getDatamartRowSet("target")
      
       // target is null when running the logic test execute, so you can use trace for debugging purposes
       if (target) {
           target.addRow(newRow)
       } else {
           api.trace("newRow", null, newRow)
       }
       

      Example 2:

      
       def source = api.getDatamartRowSet("source")
       def target = api.getDatamartRowSet("target")
      
       while (source?.next()) {
           def row = source?.getCurrentRow()
      
           // perform the required calculation of row
           target["TotalSales"] = ...
      
           // target is null when running the logic test execute, so you can use trace for debugging purposes
           if (target) {
               target.addRow(row)
           }
       }
       
      Parameters:
      name - Either 'source' to select the source FC or 'target' to select the target FC rowset.
      Returns:
      DatamartRowSet holding either the source or target rowset.
      See Also:
    • switchSKUContext

      void switchSKUContext(String newSKU)
      Temporarily switches the current SKU context to another SKU. This can be used to call functions that rely on a SKU context and do not allow to specify an alternate SKU. The switch is reset by resetSKUContextSwitch() or automatically at the beginning of every element.

      Example:

      
       def masterSku = api.productXRef()
       def costs
      
       if (masterSku) {
           api.switchSKUContext(masterSku[0].targetSku)
      
           // take the cost from the masterSku item
           costs = api.productExtension("Cost")
      
           api.resetSKUContextSwitch()
       } else {
           // take the cost from the item being calculated
           costs = api.productExtension("Cost")
       }
      
       if (costs) {
           ....
       }
       
      Parameters:
      newSKU - New SKU to switch to.
      See Also:
    • resetSKUContextSwitch

      void resetSKUContextSwitch()
      Resets an SKU context switch to the originally specified SKU. Example:
      
       def masterSku = api.productXRef()
       def costs
      
       if (masterSku) {
           api.switchSKUContext(masterSku[0].targetSku)
      
           // take the cost from the masterSku item
           costs = api.productExtension("Cost")
      
           api.resetSKUContextSwitch()
       } else {
           // take the cost from the item being calculated
           costs = api.productExtension("Cost")
       }
      
       if (costs) {
           ....
       }
       
      See Also:
    • product

      Object product()
      Retrieves the product object for the SKU currently being calculated (SKU in the context). The result product object is cached and the next call reads the value from the cached record.

      Example:

      
       def item = api.product()
       def message = checkItem(item)
      
       def checkItem(item) {
           if (!item.attribute2) {          // Product group
               return "Product group not set"
           } else if (!item.attribute5) {   // Manufacturer
               return "Manufacturer not set"
           }
       }
       
      Important: Do not run this method in the Input Generation mode, otherwise a user input will be created – this method has been deprecated for this usage. To generate a user input (the Product picker), use the InputBuilderFactory.createProductEntry(String) instead.
      Returns:
      Full current product Map.
      See Also:
    • product

      Object product(String attributeName)
      Retrieves the given attribute value from the Products table for the SKU being calculated (the SKU in the context). The product object is cached and the next call reads the value from the cached record.

      When reading the predefined columns, use their system names - e.g. label, unitOfMeasure.

      When accessing the attribute columns, preferably use their "Name" defined for the column when you set up the table. You can also use their system names (attribute1, ...), but it does not give you much information about which value you are reading.

      Special use case: When you call the function with the "sku" attribute, this specific call is optimized in the backend, so it does not make a lookup in the Products table, but instead returns the SKU value directly from the context. Important: Do not run this method in the Input Generation mode, otherwise a user input will be created – this method has been deprecated for this usage. To generate a user input (the Product picker), use the InputBuilderFactory.createProductEntry(String) instead.

      Examples:

      
       def label = api.product("label")
       def uom = api.product("unitOfMeasure")
       def productGroup = api.product("ProductGroup")  //  api.product("attribute1")
       def manufacturer = api.product("Manufacturer") //  api.product("attribute4")
       
      Parameters:
      attributeName - Name of the attribute column whose value you want to retrieve. For the customizable attributeX columns, it can be either in the form "attribute1" or the Name provided in the Rename and Customize Column dialog.
      Returns:
      Value of the attribute.
      See Also:
    • product

      Object product(String attributeName, String sku)
      Retrieves the given attribute value from the Products table for a given SKU.

      When reading the predefined columns, use their system names - e.g. label, unitOfMeasure.

      When accessing the attribute columns, preferably use their "Name" defined for the column when you set up the table. You can also use their system names (attribute1, ...), but it does not give you much information about which value you are reading.

      Example:

      
       def masterSku = ...
       def label
      
       if (masterSku) {
           // take the label from the masterSku item
           label = api.product("label", masterSku)
       } else {
          // take label from the item being calculated
          label = api.product("label")
       }
       
      Important: Do not run this method in the Input Generation mode, otherwise a user input will be created – this method has been deprecated for this usage. To generate a user input (the Product picker), use the InputBuilderFactory.createProductEntry(String) instead.
      Parameters:
      attributeName - Name of the attribute column whose value you want to retrieve. For the customizable attributeX columns, it can be either in the form "attribute1" or the Name provided in the Rename and Customize Column dialog.
      sku - Product.
      Returns:
      Value of the attribute (or null if product not found).
      See Also:
    • product

      Object product(String attributeName, String sku, String filterFormulaName, Object filterFormulaParam)
      Retrieves the given attribute value from the product table for a given SKU. If the given SKU is null, filterFormulaName and filterFormulaParam are used to apply the filter logic for the Product picker. Important: Do not run this method in the Input Generation mode, otherwise a user input will be created – this method has been deprecated for this usage. To generate a user input (the Product picker), use the InputBuilderFactory.createProductEntry(String) instead.

      Example:
      
       def masterSku = ...
       def filterFormulaName = ...
       def filterFormulaParam = ...
       def label
      
       if (masterSku) {
           // take the label from the masterSku item
           label = api.product("label", masterSku, filterFormulaName, filterFormulaParam)
       } else {
          // take label from the item being calculated
          label = api.product("label")
       }
       
      Parameters:
      attributeName - Attribute whose value should be returned.
      sku - Product.
      filterFormulaName - Unique name of a formula that will be triggered when the Product picker opens.
      filterFormulaParam - Additional data for filterFormula.
      Returns:
      Value of the attribute (or null if the product not found).
      See Also:
    • otherProduct

      Object otherProduct(String parameterName, String attributeName)
      Triggers a custom-named product picker input parameter.

      Example:
      
       def parameterName = ...
       def attributeName = ...
       def otherProduct
      
       otherProduct = api.otherProduct(parameterName, attributeName)
       
      Parameters:
      parameterName - Name of the parameter.
      attributeName - Attribute whose value should be returned (null for the entire object).
      Returns:
      Attribute value
    • otherProduct

      Object otherProduct(String parameterName, String attributeName, String filterFormulaName, Object filterFormulaParam)
      Triggers a custom-named product picker input parameter.

      Example:
      
       def parameterName = ...
       def attributeName = ...
       def filterFormulaName = ...
       def filterFormulaParam = ...
       def otherProduct
      
       otherProduct = api.otherProduct(parameterName, attributeName, filterFormulaName, filterFormulaParam)
       
      Parameters:
      parameterName - Name of the parameter.
      attributeName - Attribute whose value should be returned (null for the entire object).
      filterFormulaName - Unique name of a formula that will be triggered when the Product picker opens.
      filterFormulaParam - Additional data for filterFormula.
      Returns:
      Attribute value
    • otherProduct

      Object otherProduct(String parameterName)
      Triggers a custom-named product picker input parameter.
      Example:
      
       def parameterName = ...
       def otherProduct
      
       otherProduct = api.otherProduct(parameterName)
       
      Parameters:
      parameterName - Name of the parameter.
      Returns:
      The product object as a Map.
      See Also:
    • productExtension

      Object productExtension(String extensionName)
      Retrieves a list of rows from a Product Extension (PX) table named extensionName for the SKU being calculated (SKU in the context).

      For performance reasons, consider use of getBatchInfo().

      Example:

      
       def promotions = api.productExtension("Promotion")
       def promotionSize = promotions?.getAt(0)
       
      Parameters:
      extensionName - Name of the Product Extension table to read data from.
      Returns:
      List of PX rows/records represented as a Map, so it returns a List of Maps.
      See Also:
    • productExtension

      Object productExtension(String extensionName, Filter... filters)
      Retrieves a list of rows from a Product Extension (PX) table named extensionName for the SKU being calculated (SKU in the context) additionally filtered by filters.

      For performance reasons, consider use of getBatchInfo().

      Example:

      
       def filter = [
               Filter.greaterOrEqual("ValidFrom", targetDate),   // or Filter.greaterOrEqual("attribute1", targetDate)
               Filter.lessOrEqual("ValidTo", targetDate)       // Filter.lessOrEqual("attribute2", targetDate)
       ]
      
       def promotions = api.productExtension("Promotion", *filter)
       def promotion = promotions?.getAt(0)
       
      Parameters:
      extensionName - Name of the product extension table.
      filters - One or more Filter objects that narrow down the search.
      Returns:
      List of matching PX rows/records represented as a Map, so it returns a List of Maps.
      See Also:
    • productCompetition

      Object productCompetition()
      Retrieves a list of all product competition rows/records (PCOMP) for the SKU being calculated (SKU in the context).

      Note: In case the competition data are stored in a Product Extension (PX) table (which might give you more flexibility in some use cases), use the productExtension(String) to retrieve the data from this PX table.


      Example:
      
       return api.productCompetition()
       
      Returns:
      List of PCOMP records (represented as a Map).
      See Also:
    • productCompetition

      Object productCompetition(Filter... filters)
      Retrieves a list of product competition rows/records (PCOMP) for the SKU being calculated (SKU in the context) filtered by filters.

      Note: In case the competition data are stored in a Product Extension (PX) table (which might give you more flexibility in some use cases), use the productExtension(String) to retrieve the data from this PX table.

      Example:
      
           def productCompetitions = api.productCompetition(Filter.equal('country', api.global.country))
           return productCompetitions
       
      Parameters:
      filters - One or more Filter objects that narrow down the search.
      Returns:
      List of PCOMP records (represented as a Map).
      See Also:
    • productXRef

      Object productXRef()
      Retrieves a list of all product reference records (PXREF) for the SKU being calculated. For performance reasons consider use of getBatchInfo().
      Example:
      
       def productXRef
      
       productXRef = api.productXRef()
       
      Returns:
      List of PXREF records (represented as a Map).
      See Also:
    • rebateAgreementUserEntry

      @Deprecated Object rebateAgreementUserEntry(String parameterName, String attributeName)
      Prompts the user to enter parameters for a rebate agreement (RBA).
      Parameters:
      parameterName - - Name of an entry in the input parameters listing (mandatory).
      attributeName - - Name of the attribute you need (mandatory).
      Returns:
      Attribute of the rebate agreement or null if RA does not exist.
    • productXRef

      Object productXRef(Filter... filters)
      Retrieves a list of all product reference records (PXREF) for the SKU being calculated.
      Example:
      
       def filters = ...
       def productXRef
      
       productXRef = api.productXRef(filters)
       
      Parameters:
      filters - One or more Filter objects that narrow down the PXREF search.
      Returns:
      List of matching PXREF records (represented as a Map).
      See Also:
    • customer

      Object customer(String attributeName)
      Retrieves the given attribute value from the Customers table for the customer selected by the user in the input parameter "Customer". The customer object is cached and the next call reads the value from the cached record.

      Note: The value of the Customer input parameter can be also inherited from the parent; for example, if the user selects the Customer in the Quote header, then such input value is available also during the Quote Line calculation.

      Important: Do not run this method in the Input Generation mode, otherwise a user input will be created – this method has been deprecated for this usage. To generate a user input (the Customer picker), use the InputBuilderFactory.createCustomerEntry(String) instead.
      Example:

      
       def attributeName = ...
       def customer
      
       customer = api.customer(attributeName)
       
      Parameters:
      attributeName - Attribute value to be returned. Can be either the real column name (like customerId, name, attribute1) or also the name given in the Rename and Customize column dialog.
      Returns:
      Value of the attribute
    • customer

      Object customer(String attributeName, boolean defaultFromParent)
      Equivalent of the standard syntax "Customer" function. It retrieves the given attribute value of the customer context parameter. If the value is null and defaultFromParent is true, it retrieves (and returns) the value from the customer's parent regardless if that value is null as well or not. If there is no parent customer set, null will be returned.
      Example:
      
       def attributeName = ...
       def defaultFromParent = ...
       def customer
      
       customer = api.customer(attributeName, defaultFromParent)
       
      Parameters:
      attributeName - Attribute value to be returned.
      defaultFromParent - Determines whether to look up the value from the parent customer (if any) in case it is null in the customer.
      Returns:
      Value of the attribute
    • customer

      Object customer(String attributeName, String customerId)
      Retrieves the given attribute value from the Customers table for the given customer. The customer object is cached and the next call reads the value from the cached record.
      Example:
      
       def attributeName = ...
       def customerId = ...
       def customer
      
       customer = api.customer(attributeName, customerId)
       
      Parameters:
      attributeName - Attribute value to be returned. Can be either the real column name (like customerId, name, attribute1) or also the name given in the Rename and Customize column dialog.
      customerId - customerId value to be looked up in the Customers table.
      Returns:
      Value of the attribute (or null if no customer found).
    • customer

      Object customer(String attributeName, String customerId, boolean defaultFromParent)
      Retrieves the given attribute value of the given customer. If the value is null and defaultFromParent is true, it retrieves (and returns) the value from the customer's parent regardless if that value is null as well or not. If there is no parent customer set, null will be returned.
      Example:
      
       def attributeName = ...
       def customerId = ...
       def defaultFromParent = ...
       def customer
      
       customer = api.customer(attributeName, customerId, defaultFromParent)
       
      Parameters:
      attributeName - Attribute value to be returned.
      customerId - customerId value for the customer search.
      defaultFromParent - Determines whether to look up the value from the parent customer (if any) in case it is null in the customer.
      Returns:
      Value of the attribute (or null if no customer found).
    • customer

      Object customer(String attributeName, String customerId, boolean defaultFromParent, String filterFormulaName, Object filterFormulaParam)
      Retrieves a named attribute value of the named customer (if the value is null and defaultFromParent is true, retrieves (and returns) the value from the customer's parent regardless if that value is null as well or not. If there is no parent customer set, null will be returned)
      Example:
      
       def attributeName = ...
       def customerId = ...
       def defaultFromParent = ...
       def filterFormulaName = ...
       def filterFormulaParam = ...
       def customer
      
       customer = api.customer(attributeName, customerId, defaultFromParent, filterFormulaName, filterFormulaParam)
       
      Parameters:
      attributeName - Attribute value to be returned.
      customerId - customerId value for the customer search.
      defaultFromParent - Determines whether to look up the value from the parent customer (if any) in case it is null in the customer.
      filterFormulaName - Unique name of a formula that will be triggered when the Customer picker opens.
      filterFormulaParam - Additional data for filterFormula (e.g. agreement's typedId,...).
      Returns:
      Value of the attribute (or null if no customer found).
    • otherCustomer

      Object otherCustomer(String parameterName)
      Triggers a custom-named customer picker input parameter.
      Example:
      
       def parameterName = ...
       def otherCustomer
      
       otherCustomer = api.otherCustomer(parameterName)
       
      Parameters:
      parameterName - Name of the parameter.
      Returns:
      The Customer object as a Map.
      See Also:
    • otherCustomer

      Object otherCustomer(String parameterName, String attributeName)
      Triggers a custom-named customer picker input parameter.
      Example:
      
       def parameterName = ...
       def attributeName = ...
       def otherCustomer
      
       otherCustomer = api.otherCustomer(parameterName, attributeName)
       
      Parameters:
      parameterName - Name of the parameter.
      attributeName - Attribute whose value to return (null for the entire object).
      Returns:
      Attribute value
    • otherCustomer

      Object otherCustomer(String parameterName, String attributeName, boolean defaultFromParent)
      Triggers a custom-named customer picker input parameter.
      Example:
      
       def parameterName = ...
       def attributeName = ...
       def defaultFromParent = ...
       def otherCustomer
      
       otherCustomer = api.otherCustomer(parameterName, attributeName, defaultFromParent)
       
      Parameters:
      parameterName - Name of the parameter.
      attributeName - Attribute whose value should be returned (null for the entire object).
      defaultFromParent - Determines whether to look up the attribute value from the parent customer (if any) in case it is null in the customer.
      Returns:
      Attribute value
    • otherCustomer

      Object otherCustomer(String parameterName, String attributeName, boolean defaultFromParent, String filterFormulaName, Object filterFormulaParam)
      Triggers a custom-named customer picker input parameter.
      Example:
      
       def parameterName = ...
       def attributeName = ...
       def defaultFromParent = ...
       def filterFormulaName = ...
       def filterFormulaParam = ...
       def otherCustomer
      
       otherCustomer = api.otherCustomer(parameterName, attributeName, defaultFromParent, filterFormulaName, filterFormulaParam)
       
      Parameters:
      parameterName - Name of the parameter.
      attributeName - Attribute whose value should be returned (null for the entire object).
      defaultFromParent - Determines whether to look up the attribute value from the parent customer (if any) in case it is null in the customer.
      filterFormulaName - Unique name of a formula that will be triggered when the Customer picker opens.
      filterFormulaParam - Additional data for filterFormula (e.g. agreement's typedId,...).
      Returns:
      Attribute value
    • customerExtension

      Object customerExtension(String extensionName, Filter... filters)
      Retrieves a list of all customer extentions records (CX) from a CX table named extensionName. The Customer must be defined in the context.

      Example:

      
       def filter = Filter.equal("attribute1", "ShipTo")   // Type
      
       def addresses = api.customerExtension("Addresses", filter)
      
       if (addresses) {
           def address = addresses.getAt(0)
           ...
       }
       
      Note: A corresponding customer context must be defined within the logic (for example, CFS, Quote, or Price List that is assigned to a customer) – compared to e.g., api.find() where the context is not required. Returns null when no context is defined.
      Parameters:
      extensionName - Name of the extension.
      filters - None, one or more Filter objects that narrow down the CX search.
      Returns:
      List of matching CX records (represented as a Map).
      See Also:
    • seller

      Object seller(String attributeName)
      Retrieves the given attribute value from the Sellers table for the seller selected by the user in the input parameter "Seller". The seller object is cached and the next call reads the value from the cached record. Important: Do not run this method in the Input Generation mode, otherwise a user input will be created – this method has been deprecated for this usage. To generate a user input (the Customer picker), use the InputBuilderFactory.createSellerEntry(String) instead.
      Parameters:
      attributeName - Attribute value to be returned. Can be either the real column name (like sellerId, name, attribute1) or also the name given in the Rename and Customize column dialog.
      Returns:
      Value of the attribute
      Since:
      9.0 - Hurricane
    • seller

      Object seller(String attributeName, String sellerId)
      Retrieves the given attribute value from the Sellers table for the given seller. The seller object is cached and the next call reads the value from the cached record. Important: Do not run this method in the Input Generation mode, otherwise a user input will be created – this method has been deprecated for this usage. To generate a user input (the Customer picker), use the InputBuilderFactory.createSellerEntry(String) instead.
      Example:
      
       def attributeName = ...
       def sellerId = ...
       def seller
      
       seller = api.seller(attributeName, sellerId)
       
      Parameters:
      attributeName - Attribute value to be returned. Can be either the real column name (like sellerId, name, attribute1) or also the name given in the Rename and Customize column dialog.
      sellerId - sellerId value to be looked up in the Sellers table.
      Returns:
      Value of the attribute (or null if no seller found).
      Since:
      9.0 - Hurricane
    • seller

      Object seller(String attributeName, String sellerId, String filterFormulaName, Object filterFormulaParam)
      Retrieves the given attribute value from the seller table for a given sellerId. If the given sellerId is null, filterFormulaName and filterFormulaParam are used to apply the filter logic for the Seller picker. Important: Do not run this method in the Input Generation mode, otherwise a user input will be created – this method has been deprecated for this usage. To generate a user input (the Customer picker), use the InputBuilderFactory.createSellerEntry(String) instead.
      Example:
      
       def attributeName = ...
       def sellerId = ...
       def filterFormulaName = ...
       def filterFormulaParam = ...
       def seller
      
       seller = api.seller(attributeName, sellerId, filterFormulaName, filterFormulaParam)
       
      Parameters:
      attributeName - Attribute whose value should be returned.
      sellerId - Seller ID.
      filterFormulaName - Unique name of a formula that will be triggered when the Seller picker opens.
      filterFormulaParam - Additional data for filterFormula.
      Returns:
      Value of the attribute (or null if the seller not found).
      Since:
      9.0 - Hurricane
      See Also:
    • otherSeller

      Object otherSeller(String parameterName)
      Triggers a custom-named seller picker input parameter.
      Example:
      
       def parameterName = ...
       def otherSeller
      
       otherSeller = api.otherSeller(parameterName)
       
      Parameters:
      parameterName - Name of the parameter.
      Returns:
      The Seller object as a Map.
      Since:
      9.0 - Hurricane
      See Also:
    • otherSeller

      Object otherSeller(String parameterName, String attributeName)
      Triggers a custom-named seller picker input parameter.
      Example:
      
       def parameterName = ...
       def attributeName = ...
       def otherSeller
      
       otherSeller = api.otherSeller(parameterName, attributeName)
       
      Parameters:
      parameterName - Name of the parameter.
      attributeName - Attribute whose value to return (null for the entire object).
      Returns:
      Attribute value
      Since:
      9.0 - Hurricane
    • otherSeller

      Object otherSeller(String parameterName, String attributeName, String filterFormulaName, Object filterFormulaParam)
      Triggers a custom-named seller picker input parameter.
      Example:
      
       def parameterName = ...
       def attributeName = ...
       def filterFormulaName = ...
       def filterFormulaParam = ...
       def otherSeller
      
       otherSeller = api.otherSeller(parameterName, attributeName, filterFormulaName, filterFormulaParam)
       
      Parameters:
      parameterName - Name of the parameter.
      attributeName - Attribute whose value should be returned (null for the entire object).
      filterFormulaName - Unique name of a formula that will be triggered when the Seller picker opens.
      filterFormulaParam - Additional data for filterFormula (e.g. agreement's typedId,...).
      Returns:
      Attribute value
      Since:
      9.0 - Hurricane
    • getCalculableLineItem

      <T extends CalculableLineItem> T getCalculableLineItem(Object clic, String lineId)
      Returns a line item of the given calculable line item collection (CLIC). Currently, there are four types of CLICs: Quote, Contract, Rebate Agreement and Sales Compensations.
      Example:
      
       def calculableLineItem
       def clic = ...
       def lineId = ...
      
       calculableLineItem = api.getCalculableLineItem(clic, lineId)
       
      Type Parameters:
      T - ContractLineItem (CTLI), QuoteLineItem (QLI), RebateAgreementLineItem (RBALI), or CompensationLineItem (COLI).
      Parameters:
      clic - CLIC to which the line item belongs, it may either be the CLIC object as such (its map representation to be exact) or typedId or a uniqueName.
      lineId - lineId of the line item.
      Returns:
      Calculable line item represented as a Map.
      See Also:
    • getCalculableLineItemResult

      Object getCalculableLineItemResult(Object cli, String... resultNamesOrLabels)
      Returns results of the given names (or labels) from a line item object (its map representation).

      Note: The line item object will typically be fetched via getCalculableLineItem(Object, String).
      Example:

      
       def calculableLineItemResult
       def cli = ...
       def resultNamesOrLabels = ...
      
       calculableLineItemResult = api.getCalculableLineItemResult(cli, resultNamesOrLabels)
       
      Parameters:
      cli - Calculable line item.
      resultNamesOrLabels - Result names or labels.
      Returns:
      Either a single result or a map(nameOrLabel,result) of results if there were more names (labels) specified.
    • getCalculableLineItemCollection

      Object getCalculableLineItemCollection(String typedId)
      Returns the full object (header and line items) of a CalculableLineItemCollection (CLIC) object e.g., a Quote, Rebate Agreement, Contract, or Sales Compensations.

      Avoid using this method on the object currently being calculated. It should only be used to fetch a line item from another object, as using it on the current object may delete some inputs.

      Note: To fetch line items within a header logic, for better performance, use the corresponding "get*CLIC*View" method instead (i.e.,getContractView(), getQuoteView(), getRebateAgreementView(), getCompensationView()).
      Example:

      
       def calculableLineItemCollection
       def typedId = ...
      
       calculableLineItemCollection = api.getCalculableLineItemCollection(typedId)
       
      Parameters:
      typedId - typeId of the object.
      Returns:
      Map specifying the line item collection, or null if an invalid typedId was passed. The returned object includes inputs, outputs, line item inputs, and line item outputs.
      See Also:
    • getCalculableLineItemCollection

      List<HashMap<String,Object>> getCalculableLineItemCollection(String typeCode, Filter filter)
      Retrieves all CalculableLineItemCollections (CLIC) objects that match the filter's and type code's criteria.

      Note: This method signature does not return inputs, outputs, line item inputs, and line item outputs.

      Example:

      
       def customerPicker = api.customerGroupEntry('Select customer/s')    // ex.: CG[`customerId` = "CD-00001"]
       def filter = api.customerToRelatedObjectsFilter('RBA', customerPicker)// ex.: custom filter with the picker passed
       def result = api.getCalculableLineItemCollection('RBA', filter)    // ex.: List of CLICs as HashMaps
       

      Parameters:
      typeCode - TypeCode of the related object, ex.: 'CT' for the Contract or 'RBA' for the RebateAgreement
      filter - Filter which will be used to search for the persisted objects, ex. taken from api.productToRelatedObjectsFilter()
      Returns:
      List of found CalculableLineItemCollections
      See Also:
    • createNewRevision

      Object createNewRevision(String typedId)
      Creates a revision of CalculableLineItemCollection (Quote, Rebate Agreement, Contract).
      Example:
      
       def newRevision
       def typedId = ...
      
       newRevision = api.createNewRevision(typedId)
       
      Parameters:
      typedId - typeId of the object.
      Returns:
      Map specifying the revised line item collection or null if an invalid typedId was passed.
    • addWarning

      void addWarning(String message)
      Adds a warning to the logic/formula execution warning log. Warnings usually explain to the user that there was a "technical" problem (e.g. missing data, inputs) and the calculation could not be completed.

      The warnings are displayed for:

      • Quotes, Rebates, Contracts in the Calculation Results section for the line items.
      • Price lists, price grids, Datamarts, policy records - all warnings from all elements are listed together in a special Warnings column in the grid list items.

      Example:

      
       def cost = ...
      
       if (cost == null) {
            api.addWarning("Cannot calculate List Price because of missing cost")
            return null
       }
       

      Only the following HTML tags are supported within the message:

      
       <br>
       <li>
       <b>
       <em>
       <i>
       <strong>
       
      Unsupported HTML tags are ignored and not visible in the displayed message.
      Parameters:
      message - Warning message.
    • addPortletInfo

      void addPortletInfo(String code, String userMsg, String techMsg)
      Adds an info message to the current portlet. One portlet can have multiple messages. It is a different concept than yellow/red alerts.
      Example:
      
       api.addPortletInfo("101", "Chart data may be outdated", "Bubble Chart data is outdated, because of ...")
       
      Parameters:
      code - Info code allows to pinpoint the place of the related issue in code.
      userMsg - Info message is displayed to a user in UI.
      techMsg - Technical message is hidden by default, only for the investigation purposes.
    • addPortletWarning

      void addPortletWarning(String code, String userMsg, String techMsg)
      Adds a warning message to the current portlet. One portlet can have multiple messages. It is a different concept than yellow/red alerts.
      Example:
      
       api.addPortletWarning("102", "Chart data is missing", "Bubble Chart data is missing, because of ...")
       
      Parameters:
      code - Warning code allows to pinpoint the place where the warning is thrown in code.
      userMsg - Warning message is displayed to a user in UI.
      techMsg - Technical message is hidden by default, only for the investigation purposes.
    • addPortletError

      void addPortletError(String code, String userMsg, String techMsg)
      Adds an error message to the current portlet. One portlet can have multiple messages. It is a different concept than yellow/red alerts.
      Example:
      
       api.addPortletError("103", "Chart was not found", "Bubble Chart could not be found, because of ...")
       
      Parameters:
      code - Error code allows to pinpoint the place where the error is thrown in code.
      userMsg - Error message is displayed to a user in UI.
      techMsg - Technical message is hidden by default, only for the investigation purposes.
    • contextByLabel

      Object contextByLabel(String label)
      Retrieves the previous calculation result by the logic element label (not the element result name)
      Example:
      
       def contextByLabel
       def label = ...
      
       contextByLabel = api.contextByLabel(label)
       
      Parameters:
      label - Logic element label.
      Returns:
      Calculation result of that element
    • vLookup

      Object vLookup(String parameterName)
      Searches for a record in the Company Parameter / Price Parameter table named parameterName where the column 'name' matches the value entered by the user (in a drop-down input parameter) and returns the value from the column 'value'.

      Side effect: During the Input Generation mode this function creates a new input parameter (drop-down) whose values are taken from the column "Name" of the given Company Parameter / Price Parameter.

      Note: If there are two Company Parameter / Price Parameter tables with the same name (uniqueName) and status="ACTIVE", then the table with the latest validAfter date at or before the logic execution's Target Date is used for the look up.


      Example:
      
       def shippingCost = api.vLookup("ShippingCosts")
       
      Parameters:
      parameterName - Name of the Company Parameter / Price Parameter table to look up.
      Returns:
      For a simple Company Parameter / Price Parameter, it returns the value of the "Value" column from the found row. In case of matrix lookups, the entire object/row.
      See Also:
    • vLookup

      Object vLookup(String parameterName, Object attributeNameOrKeyOrRangeValue)
      Searches for a record in the Company Parameter / Price Parameter table named parameterName where the column 'name' (for LTV or MLTV) or 'key1' (for MLTV2-6) matches the attributeNameOrKeyOrRangeValue value and returns the value from the column 'value' (LTV) or 'attribute1' (MLTV). Once the record is found, it remains cached during the whole calculation and the next call for the same arguments reads the value from the cache.

      Note: If there are two Company Parameter / Price Parameter tables with the same name (uniqueName) and status="ACTIVE", then the table with the latest validAfter date at or before the logic execution's Target Date is used for the look up.

      Example:

      
       def productGroup = api.product("ProductGroup")  // or "attribute2"
       def shippingCost = api.vLookup("ShippingCosts", productGroup)
       
      Parameters:
      parameterName - Name of the Company Parameter / Price Parameter table.
      attributeNameOrKeyOrRangeValue - Predefined key or range value or in case of a matrix lookup a user entry.
      Returns:
      Value of the column 'value' for SIMPLE (LTV) or 'attribute1' for MATRIX (MLTV).
      See Also:
    • vLookup

      Object vLookup(String parameterName, String attributeName, String key)
      Only relevant for MATRIX 1-key Company Parameter / Price Parameter tables (MLTV).

      Searches for a record in the Company Parameter / Price Parameter table named parameterName where the column 'key1' matches the key1 parameter and returns the value of the column attributeName. Once the record is found, it remains cached during the whole calculation and the next call for the same arguments reads the value from the cache.

      Note: If there are two Company Parameter / Price Parameter tables with the same name (uniqueName) and status="ACTIVE", then the table with the latest validAfter date at or before the logic execution's Target Date is used for the look up.

      Example:

      
       def prevailing = api.vLookup("Manufacturer", "attribute1", "Meat company")
       
      Parameters:
      parameterName - Name of the Company Parameter / Price Parameter table.
      attributeName - Name of the attribute to retrieve or a comma separated list of attributes.
      key - Key of the parameter table.
      Returns:
      Value of the column attributeName or a full object if the attribute name is null.
      See Also:
    • vLookup

      Object vLookup(String parameterName, String attributeName, String key1, String key2)
      Only relevant for MATRIX 2-key Company Parameter / Price Parameter tables (MLTV2).

      Searches for a record in a Company Parameter / Price Parameter table named parameterName where the columns 'key1'-'key2' match the key1-key2 parameters and returns the value from the column attributeName. Once the record is found, it remains cached during the whole calculation and the next call for the same arguments reads the value from the cache.

      Note: If there are two Company Parameter / Price Parameter tables with the same name (uniqueName) and status="ACTIVE", then the table with the latest validAfter date at or before the logic execution's Target Date is used for the look up.

      Example:

      
       def exchangeRate = api.vLookup("ExchangeRate", "attribute1", "EUR", "USD")
       
      Parameters:
      parameterName - Name of the Company Parameter / Price Parameter table.
      attributeName - Name of the attribute to retrieve or a comma separated list of attributes.
      key1 - key1 of the parameter table.
      key2 - key2 of the parameter table.
      Returns:
      Value of the column attributeName or a full object if the attribute name is null.
      See Also:
    • vLookup

      Object vLookup(String parameterName, String attributeName, String key1, String key2, String key3)
      Only relevant for MATRIX 3-key Company Parameter / Price Parameter tables (MLTV3).

      Searches for a record in the Company Parameter / Price Parameter table named parameterName where the columns 'key1'-'key3' match the key1-key3 parameters and returns the value from the column attributeName. Once the record is found, it remains cached during the whole calculation and the next call for the same arguments reads the value from the cache.

      Note: If there are two Company Parameter / Price Parameter tables with the same name (uniqueName) and status="ACTIVE", then the table with the latest validAfter date at or before the logic execution's Target Date is used for the look up.

      Example:

      
       def exchangeRate = api.vLookup("ExchangeRate", "attribute1", "EUR", "USD", "2018")
       
      Parameters:
      parameterName - Name of the Company Parameter / Price Parameter table.
      attributeName - Name of the attribute to retrieve or a comma separated list of attributes.
      key1 - key1 of the parameter table.
      key2 - key2 of the parameter table.
      key3 - key3 of the parameter table.
      Returns:
      Value of the column attributeName or a full object if the attribute name is null.
      See Also:
    • vLookup

      Object vLookup(String parameterName, String attributeName, String key1, String key2, String key3, String key4)
      Only relevant for MATRIX 4-key Company Parameter / Price Parameter tables (MLTV4).

      Searches for a record in the Company Parameter / Price Parameter table named parameterName where the columns 'key1'-'key4' match the key1-key4 parameters and returns the value from the column attributeName. Once the record is found, it remains cached during the whole calculation and the next call for the same arguments reads the value from the cache.

      Note: If there are two Company Parameter / Price Parameter tables with the same name (uniqueName) and status="ACTIVE", then the table with the latest validAfter date at or before the logic execution's Target Date is used for the look up.

      Example:
      
       def exchangeRate = api.vLookup("ExchangeRate", "attribute1", "EUR", "USD", "2018", "231")
       
      Parameters:
      parameterName - Name of the Company Parameter / Price Parameter table.
      attributeName - Name of the attribute to retrieve or a comma separated list of attributes.
      key1 - key1 of the parameter table.
      key2 - key2 of the parameter table.
      key3 - key3 of the parameter table.
      key4 - key4 of the parameter table.
      Returns:
      Value of the column attributeName or a full object if the attribute name is null.
      See Also:
    • vLookup

      Object vLookup(String parameterName, String attributeName, String key1, String key2, String key3, String key4, String key5)
      Only relevant for MATRIX 5-key Company Parameter / Price Parameter tables (MLTV5).

      Searches for a record in the Company Parameter / Price Parameter table named parameterName where the columns 'key1'-'key5' match the key1-key5 parameters and returns the value from the column attributeName. Once the record is found, it remains cached during the whole calculation and the next call for the same arguments reads the value from the cache.

      Note: If there are two Company Parameter / Price Parameter tables with the same name (uniqueName) and status="ACTIVE", then the table with the latest validAfter date at or before the logic execution's Target Date is used for the look up.

      Parameters:
      parameterName - Name of the Company Parameter / Price Parameter table.
      attributeName - Name of the attribute to retrieve or a comma separated list of attributes.
      key1 - key1 of the parameter table.
      key2 - key2 of the parameter table.
      key3 - key3 of the parameter table.
      key4 - key4 of the parameter table.
      key5 - key5 of the parameter table.
      Returns:
      Value of the column attributeName or a full object if the attribute name is null.
      See Also:
    • vLookup

      Object vLookup(String parameterName, String attributeName, String key1, String key2, String key3, String key4, String key5, String key6)
      Only relevant for MATRIX 6-key Company Parameter / Price Parameter tables (MLTV6).

      Searches for a record in the Company Parameter / Price Parameter table named parameterName where the columns 'key1'-'key6' match the key1-key6 parameters and returns the value from the column attributeName. Once the record is found, it remains cached during the whole calculation and the next call for the same arguments reads the value from the cache.

      Note: If there are two Company Parameter / Price Parameter tables with the same name (uniqueName) and status="ACTIVE", then the table with the latest validAfter date at or before the logic execution's Target Date is used for the look up.

      Example:
      
       def exchangeRate = api.vLookup("ExchangeRate", "attribute1", "EUR", "USD", "2018", "231", "ORG")
       
      Parameters:
      parameterName - Name of the Company Parameter / Price Parameter table.
      attributeName - Name of the attribute to retrieve or a comma separated list of attributes.
      key1 - key1 of the parameter table.
      key2 - key2 of the parameter table.
      key3 - key3 of the parameter table.
      key4 - key4 of the parameter table.
      key5 - key5 of the parameter table.
      key6 - key6 of the parameter table.
      Returns:
      Value of the column attributeName or a full object if the attribute name is null.
      See Also:
    • vLookup

      Object vLookup(String parameterName, String attributeName, Map keys)
      This syntax can be applied to all MATRIX lookup types. The keys are passed in a map. The key name can be the technical name ("key1" etc.) or the meta-renamed name.

      Example:

      
       def keys = [
               "Country": country,
               "DeliveryType": input.DeliveryType
       ]
      
       return api.vLookup("FreightSurcharge", "FreightSurcharge", keys)
       
      Parameters:
      parameterName - Name of the Company Parameter / Price Parameter table.

      Note: If there are two Company Parameter / Price Parameter tables with the same name (uniqueName) and status="ACTIVE", then the table with the latest validAfter date at or before the logic execution's Target Date is used for the look up.

      attributeName - Name of the attribute to retrieve or a comma separated list of attributes.
      keys - Map with the keys of the row to retrieve. Note: All keys need to be present for the table in question.
      Returns:
      Map with values of the columns of attributeNames as keys or a full object if attributeNames is null.
    • vLookup

      Map<String,Object> vLookup(String parameterName, List<String> attributeNames, Map keys)
      This syntax can be applied to all MATRIX lookup types. The keys are passed in a map. The key name can be the technical name ("key1" etc.) or the meta-renamed name.

      Example:

      
       def keys = [
               "Country": country,
               "DeliveryType": input.DeliveryType
       ]
       def attributeNamesList = [FreightSurcharge", "Fees"]
      
       return api.vLookup("FreightSurcharge", attributeNamesList, keys)
       
      Parameters:
      parameterName - Name of the Company Parameter / Price Parameter table.
      attributeNames - Names of the attribute to retrieve.
      keys - Map with the keys of the row to retrieve. Note: All keys need to be present for the table in question.
      Returns:
      Map with values of the columns of attributeNames as keys or a full object if attributeNames is null.
    • userEntry

      @Deprecated Object userEntry(String entryName)
      Returns a numeric value entered by the user in the input parameter.

      Side effect: During the Input Generation mode, this function triggers creation of the input parameter.

      • When the user-entered number is a whole number (integer), the value returned is java.lang.Integer.
      • When the user-entered number is a decimal number, the value returned is java.math.BigDecimal.
      • If you always need the result as a BigDecimal, you can cast it, e.g. api.decimalUserEntry("number") as BigDecimal.
      Parameters:
      entryName - Name of the user input parameter. For the names use the "camel case" (no spaces and capital letters). This value is not meant as a label of the input field, but rather a name which should stay stable for a long time. Remember, the input fields are stored e.g. on every single Quote line item and are created only once when adding the new line. If you need to modify the label (or other properties) of the input parameter, you can use getParameter(String).
      Returns:
      Numeric value entered by the user. Either of the type Integer or BigDecimal, depending on the value entered. During Input Generation execution mode, it returns a mock value.
      See Also:
    • decimalUserEntry

      @Deprecated Object decimalUserEntry(String entryName)
      Creates an input parameter that lets the user enter a decimal value. Rendered as a numeric field.
      Parameters:
      entryName - Name of the user entry parameter.
      Returns:
      Decimal value entered by the user as a BigDecimal
      See Also:
    • integerUserEntry

      @Deprecated Object integerUserEntry(String entryName)
      Returns an integer numeric value entered by the user in the input parameter.

      Side effect: During the Input Generation mode, this function triggers creation of the input parameter that lets the user enter an integer value. The input is rendered as a numeric field.

      Parameters:
      entryName - Name of the user input parameter. Use "camel case" for the names (no spaces and capital letters). This value is not meant as a label of the input field, but rather a name which should stay stable for a long time. Remember, the input fields are stored e.g. on every single Quote line item and are created only once, when adding the new line. If you need to modify the label (or other properties) of the input parameter, you can use getParameter(String).
      Returns:
      Integer value entered by the user as a BigDecimal.
      See Also:
    • stringUserEntry

      @Deprecated Object stringUserEntry(String entryName)
      Returns a text value entered by the user in the input parameter.

      Side effect: During the Input Generation mode, this function triggers creation of the single-text input parameter.

      Parameters:
      entryName - Name of the user entry parameter.
      Returns:
      Text value entered by the user as a String.
      See Also:
    • stringUserEntry

      @Deprecated Object stringUserEntry(String entryName, String textMask)
      Creates an input parameter that lets the user enter a short text value. Rendered as a single-line text field.
      Parameters:
      entryName - Name of the user entry parameter.
      textMask - Optional text mask that is displayed in the UI.
      Returns:
      Text value entered by the user as a String.
      See Also:
    • stringUserEntry

      @Deprecated Object stringUserEntry(String entryName, String textMask, String label)
      Creates an input parameter that lets the user enter a short text value. Rendered as single-line text field.
      Parameters:
      entryName - Name of the user entry parameter.
      textMask - Optional text mask that is displayed in the UI.
      label - Label of the entry box.
      Returns:
      Text value entered by the user as String.
      See Also:
    • textUserEntry

      @Deprecated Object textUserEntry(String entryName)
      Creates an input parameter that lets the user enter a longer text value. Rendered as a multi-line text box.
      Parameters:
      entryName - Name of the user entry parameter.
      Returns:
      Text value entered by the user as a String.
      See Also:
    • textUserEntry

      @Deprecated Object textUserEntry(String entryName, String label)
      Creates an input parameter that lets the user enter a longer text value. Rendered as a multi-line text box.
      Parameters:
      entryName - Name of the user entry parameter.
      label - Label of the entry box.
      Returns:
      Text value entered by the user as a String.
      See Also:
    • booleanUserEntry

      @Deprecated Object booleanUserEntry(String entryName)
      Creates an input parameter that lets the user enter a boolean (yes or no) value. Rendered as a checkbox.
      Parameters:
      entryName - Name of the user entry parameter.
      Returns:
      Boolean value entered by the user.
    • dateUserEntry

      @Deprecated Object dateUserEntry(String entryName)
      Creates an input parameter that lets the user enter a date value. Rendered as a date picker field.
      Parameters:
      entryName - Name of the user entry parameter.
      Returns:
      String value entered by the user in the format yyyy-MM-dd.
      See Also:
    • dateRangeUserEntry

      @Deprecated Object dateRangeUserEntry(String entryName)
      Creates an input parameter that lets the user enter a date range (start and end date). Rendered as two date picker fields.

      Note: This is available in Unity UI only. No backporting planned for the Classic UI.

      Parameters:
      entryName - Name of the user entry parameter.
      Returns:
      String array or list with values entered by the user in the format yyyy-MM-dd.
      See Also:
    • timeUserEntry

      @Deprecated Object timeUserEntry(String entryName)
      Creates an input parameter that lets the user enter a time value in format "HH:mm" (e.g. "23:59"). Rendered as a time picker field.
      Parameters:
      entryName - Name of the user entry parameter.
      Returns:
      String value entered by the user in the format HH:mm.
      See Also:
    • dateTimeUserEntry

      @Deprecated Object dateTimeUserEntry(String entryName)
      Creates an input parameter that allows the user to enter a date time value in format "dd/MM/yyyy HH:mm" (e.g. "23/01/2019 10:30"). Rendered as a datetime picker field.

      Note: The format implicitly uses the GMT/UTC time zone and so the returned value may differ from what was entered on the client side (as the client time may be in a different time zone).

      Parameters:
      entryName - Name of the user entry parameter.
      Returns:
      String value entered by the user in the format "yyyy-MM-dd'T'HH:mm:ss".
      See Also:
    • productGroupEntry

      @Deprecated Object productGroupEntry(String... entryName)
      Creates an input parameter that lets the user select a group of products. This is commonly used in PromotionManager and RebateManager.
      It is rendered as a product group picker widget.
      Parameters:
      entryName - Name of the user entry parameter.
      Returns:
      The ProductGroup object.
    • datamartProductGroupEntry

      @Deprecated Object datamartProductGroupEntry(String... entryName)
      Deprecated.
      since 13.0 - Rampur. Use PCGroupInputBuilder.setPaSearchable(Boolean) instead.
      Creates an input parameter that lets the user select a group of products. This is commonly used in PromotionManager and RebateManager. It is rendered as a product group picker widget.

      Only PA searchable Product Extensions will be available.

      Parameters:
      entryName - Name of the user entry parameter.
      Returns:
      The ProductGroup object.
    • productGroupEntry

      @Deprecated Object productGroupEntry(String entryName, String filterFormulaName, Object filterFormulaParam)
      Creates an input parameter that lets the user select a group of products and returns the ProductGroup object. This is commonly used in PromotionManager and RebateManager. It is rendered as a product group picker widget.
      Parameters:
      entryName - Name of the user entry parameter.
      filterFormulaName - Unique name of a formula that will be triggered when the customer picker opens.
      filterFormulaParam - Additional data for filterFormula.
      Returns:
      The ProductGroup object.
    • customerGroupEntry

      @Deprecated Object customerGroupEntry(String... entryName)
      Creates an input parameter that lets the user select a group of customers and returns the CustomerGroup object. This is commonly used in PromotionManager and RebateManager. It is rendered as a customer group picker widget.
      Parameters:
      entryName - Name of the user entry parameter.
      Returns:
      The CustomerGroup object.
      See Also:
    • datamartCustomerGroupEntry

      @Deprecated Object datamartCustomerGroupEntry(String... entryName)
      Deprecated.
      since 13.0 - Rampur. Use PCGroupInputBuilder.setPaSearchable(Boolean) instead.
      Creates an input parameter that lets the user select a group of customers and returns the CustomerGroup object. This is commonly used in PromotionManager and RebateManager. It is rendered as a customer group picker widget.

      Only PA searchable Customer Extensions will be available.

      Parameters:
      entryName - Name of the user entry parameter.
      Returns:
      The CustomerGroup object.
      See Also:
    • customerGroupEntry

      @Deprecated Object customerGroupEntry(String entryName, String filterFormulaName, Object filterFormulaParam)
      Creates an input parameter that lets the user select a group of customers and returns the CustomerGroup object. This is commonly used in PromotionManager and RebateManager. It is rendered as a customer group picker widget.
      Parameters:
      entryName - Name of the user entry parameter.
      filterFormulaName - Unique name of a formula that will be triggered when the customer picker opens.
      filterFormulaParam - Additional data for filterFormula (e.g. agreement's typedId,...).
      Returns:
      The CustomerGroup object.
      See Also:
    • sellerGroupEntry

      @Deprecated Object sellerGroupEntry(String... entryName)
      Creates an input parameter that lets the user select a group of sellers and returns the SellerGroup object. This is commonly used in Compensations. It is rendered as a seller group picker widget.
      Parameters:
      entryName - Name of the user entry parameter.
      Returns:
      The SellerGroup object.
      Since:
      9.0 - Hurricane
      See Also:
    • datamartSellerGroupEntry

      @Deprecated Object datamartSellerGroupEntry(String... entryName)
      Deprecated.
      since 13.0 - Rampur. Use PCGroupInputBuilder.setPaSearchable(Boolean) instead.
      Creates an input parameter that lets the user select a group of sellers and returns the SellerGroup object. This is commonly used in Compensations. It is rendered as a seller group picker widget.

      Only PA searchable Seller Extensions will be available.

      Parameters:
      entryName - Name of the user entry parameter.
      Returns:
      The SellerGroup object.
      Since:
      9.0 - Hurricane
      See Also:
    • sellerGroupEntry

      @Deprecated Object sellerGroupEntry(String entryName, String filterFormulaName, Object filterFormulaParam)
      Creates an input parameter that lets the user select a group of sellers and returns the SellerGroup object. This is commonly used in Compensations. It is rendered as a seller group picker widget.
      Parameters:
      entryName - Name of the user entry parameter.
      filterFormulaName - Unique name of a formula that will be triggered when the seller picker opens.
      filterFormulaParam - Additional data for filterFormula (e.g. agreement's typedId,...).
      Returns:
      The SellerGroup object.
      Since:
      9.0 - Hurricane
      See Also:
    • multiTierEntry

      @Deprecated Object multiTierEntry(String entryName, String... arguments)
      Creates an input parameter that lets the user enter multiple discounts/surcharges/tiers by amount. This is commonly used in PromotionManager and RebateManager. It is rendered as a multi-tier entry widget. Every line holds an amount and the given discount/surcharge in an ascending or descending order.
      Parameters:
      entryName - Name of the user entry parameter.
      arguments - Two value hints: sort type (can be either "ASC" which is the default or "DESC") and order validation type (can be "VALIDATE" or "NO_VALIDATION").
      Returns:
      Values entered by the user as a TieredValue object.
    • option

      @Deprecated Object option(String entryName, Object... options)
      Returns a value selected by the user from a list displayed in drop-down input parameter.

      Important: Do not run this method in the Input Generation mode, otherwise a user input will be created – this method has been deprecated for this usage. To generate a user input (the drop-down menu), use the InputBuilderFactory.createOptionEntry(String) instead.

      Example 1:

      
       return api.option("Currency", ["EUR", "USD"])
       

      Example 2:

      
       def salesOrgs = api.findLookupTableValues("SalesOrg").collect{
         it.name
       }
      
       return api.option("SalesOrg", salesOrgs)
       
      Parameters:
      entryName - Name of the user entry parameter.
      options - Arbitrary number of options that should be displayed in the drop-down list.
      Returns:
      Value selected by the user. During Syntax Check execution mode, it returns mock data.
      See Also:
    • option

      @Deprecated Object option(String entryName, List<Object> options, Map<String,Object> labels)
      Creates an input parameter that lets the user select a single value from predefined options.
      Important: Do not run this method in the Input Generation mode, otherwise a user input will be created – this method has been deprecated for this usage. To generate a user input (the drop-down menu), use the InputBuilderFactory.createOptionEntry(String) instead.

      Example:

      
       def salesOrgMap = api.findLookupTableValues("SalesOrg").collectEntries{
         [(it.name) : it.name]
       }
      
       return api.option("SalesOrg", salesOrgMap.keySet() as List, salesOrgMap)
       
      Parameters:
      entryName - Name of the user entry parameter.
      options - Arbitrary number of options that should be displayed in the drop-down list.
      labels - Map [value : label] of labels that should be shown in the UI. If null or empty, it will behave the same as api.option() without a label definition.
      Returns:
      User entered value.
      See Also:
    • options

      @Deprecated Object options(String entryName, Object... options)
      Important: Do not run this method in the Input Generation mode, otherwise a user input will be created – this method has been deprecated for this usage. To generate a user input (the drop-down menu), use the InputBuilderFactory.createOptionsEntry(String) (String)} instead.
      Parameters:
      entryName - Name of the user entry parameter.
      options - Arbitrary number of options that should be displayed in the drop-down list.
      Returns:
      List of user selected values.
    • options

      @Deprecated Object options(String entryName, List<Object> options, Map<String,Object> labels)
      Creates an input parameter that lets the user select multiple values from predefined options. Important: Do not run this method in the Input Generation mode, otherwise a user input will be created – this method has been deprecated for this usage. To generate a user input (the drop-down menu), use the InputBuilderFactory.createOptionsEntry(String) instead.
      Parameters:
      entryName - Name of the user entry parameter.
      options - Arbitrary number of options that should be displayed in the drop-down list.
      labels - Map [value : label] of labels that should be shown in the UI. If null or empty, it will behave the same as api.option without a label definition.
      Returns:
      List of user selected values.
    • filterBuilderUserEntry

      @Deprecated Object filterBuilderUserEntry(String entryName, String typeCode)
      Creates an input parameter that lets the user build a filter for a table of objects of the type defined by the typeCode parameter.

      It is rendered as a filter builder widget allowing to construct a filter (e.g. to define filter for Products, set the typeCode to P).

      The filter object can be used in other functions, like find(String, Filter...), stream(String, String, Filter...), count(String, Filter...) etc.

      Parameters:
      entryName - Name of the user entry parameter.
      typeCode - Type code string of the type of the object for which the filter is set. Currently, the supported type codes are "P" (Product data) and "C" (Customer data).
      Returns:
      Filter object defined by the user.
    • datamartFilterBuilderUserEntry

      @Deprecated Object datamartFilterBuilderUserEntry(String entryName, String source, Object... args)
      Creates an input parameter that lets the user build a filter for a given Datamart.

      The filter can be used in DatamartContext.Query.where(Filter...) of the datamartQuery(Object...).

      It will render a FilterBuilder widget entry allowing to construct a filter object filtering on the specified Data Source.

      Example:

      
       def filter1 = datamartFilterBuilderUserEntry("ProductGroup", "Transactions_DM")
      
       def dimFilterList = ["CustomerId", "ProductId"]
       def filter2 = datamartFilterBuilderUserEntry("ProductGroup", "Transactions_DM", dimFilterList)
      
       def dimFilterMap = ["CustomerId" : "CD-00155", "ProductId" : "MB-0005"]
       def filter3 = datamartFilterBuilderUserEntry("ProductGroup", "Transactions_DM", dimFilterMap, Filter.equal("Country", "DE"))
       
      Parameters:
      entryName - Name of the user entry parameter.
      source - Name of the source for which the filter is set. The resolution of the source is as follows:
      1. any Datamart - by typedId, sourceName, uniqueName or label (uniqueName and label for backwards compatibility)
      2. any FieldCollection - by typedId or sourceName
      args - There can be up to 2 arguments: one can be a Map or List and the other a Filter. The order does not matter. If the argument is a Map, each pair [fieldName : value] will be used as a filter.
      Returns:
      Filter object to the given source.
    • datamartFilterBuilderUserEntries

      @Deprecated Object datamartFilterBuilderUserEntries(String entryName, String source, Object... args)
      Creates an input parameter that lets the user build a filter for a given Datamart.

      The filter can be used in DatamartContext.Query.where(Filter...) of the datamartQuery(Object...).

      It will render a FilterBuilder widget entry that accepts multiple input values allowing to construct a filter object filtering on the specified Data Source.

      Example:

      
       def filter1 = datamartFilterBuilderUserEntry("ProductGroup", "Transactions_DM")
      
       def dimFilterList = ["CustomerId", "ProductId"]
       def filter2 = datamartFilterBuilderUserEntry("ProductGroup", "Transactions_DM", dimFilterList)
      
       def dimFilterMap = ["CustomerId" : "CD-00155", "ProductId" : "MB-0005"]
       def filter3 = datamartFilterBuilderUserEntry("ProductGroup", "Transactions_DM", dimFilterMap, Filter.equal("Country", "DE"))
       
      Parameters:
      entryName - Name of the user entry parameter.
      source - Name of the source for which the filter is set. The resolution of the source is as follows:
      1. any Datamart - by typedId, sourceName, uniqueName or label (uniqueName and label for backwards compatibility)
      2. any FieldCollection - by typedId or sourceName
      args - There can be up to 2 arguments: one can be a Map or List and the other a Filter. The order does not matter. If the argument is a Map, each pair [fieldName : value] will be used as a filter.
      Returns:
      Filter object to the given source.
    • pricelist

      Object pricelist(String listName)
      Looks up the result price (considering a manual override) of an SKU being calculated (SKU in the context) in a price list of the given name. The price list line has to be approved and the targetDate of the price list has to match the calculation targetDate or be before it. If multiple price lists are found, the one with the targetDate closer to the calculation targetDate is chosen.
      Example:
      
       def listName = ...
       def pricelist
      
       pricelist = api.pricelist(listName)
       
      Parameters:
      listName - Name of the price list to be searched.
      Returns:
      resultPrice of the price list record for the SKU.
    • pricelist

      Object pricelist(String listName, String attributeName)
      Looks up the value of the attribute given by attributeName (considering a manual override) of an SKU being calculated (SKU in the context) in a price list of the given name. The price list line has to be approved and the targetDate of the price list has to be prior to the calculation targetDate. If multiple price lists are found, the one with the targetDate closer to the calculation targetDate is used.
      Example:
      
       def listName = ...
       def attributeName = ...
       def pricelist
      
       pricelist = api.pricelist(listName, attributeName)
       
      Parameters:
      listName - Name of the price list.
      attributeName - Name of the attribute to retrieve.
      Returns:
      Value of the attributeName column of the price list record.
      See Also:
    • pricelist

      Object pricelist(String listName, String attributeName, String sku)
      Looks up the result price (considering a manual override) of a given SKU in a price list of the given name. The price list line has to be approved and the targetDate of the price list has to be prior to the calculation targetDate. If there are multiple price lists of the same name, the one with the targetDate closer to the calculation targetDate is chosen.
      Example:
      
       def listName = ...
       def attributeName = ...
       def sku = ...
       def pricelist
      
       pricelist = api.pricelist(listName, attributeName, sku)
       
      Parameters:
      listName - Name of the price list.
      attributeName - Name of the attribute to retrieve.
      sku - SKU to use.
      Returns:
      Value of the attributeName column of the price list record.
      See Also:
    • pricelist

      Object pricelist(String listName, String attributeName, String sku, String key2)
      Looks up the attribute defined by attributeName (considering a manual override) of the given SKU in a matrix price list of the given name. The price list line has to be approved and the targetDate of the price list has to be prior to the calculation targetDate. If there are multiple price lists of the same name, the one with the targetDate closer to the calculation targetDate is chosen.
      Example:
      
       def listName = ...
       def attributeName = ...
       def sku = ...
       def key2 = ...
       def pricelist
      
       pricelist = api.pricelist(listName, attributeName, sku, key2)
       
      Parameters:
      listName - Name of the price list.
      attributeName - Name of the attribute to retrieve.
      sku - SKU to use.
      key2 - key2 to use.
      Returns:
      Value of the attributeName column of the matrix price list record.
      See Also:
    • pricelistItem

      Object pricelistItem(String listName)
      Looks up the price list item record (PLI or XPLI) of an SKU being calculated in a price list of the given name. The price list line has to be approved and the targetDate of the price list has to be prior to the calculation targetDate. If there are multiple price lists of the same name, the one with the targetDate closer to the calculation targetDate is chosen.
      Example:
      
       def listName = ...
       def pricelistItem
      
       pricelistItem = api.pricelistItem(listName)
       
      Parameters:
      listName - Name [label] of the price list.
      Returns:
      Entire price list item record (PLI or XPLI) as a map.
      See Also:
    • pricelistItem

      Object pricelistItem(String listName, String sku)
      Looks up the price list item record (PLI) of the given SKU in a price list of a given name. The price list line has to be approved and the targetDate of the price list has to be prior to the calculation targetDate. If there are multiple price lists of the same name, the one with the targetDate closer to the calculation targetDate is chosen.
      Example:
      
       def listName = ...
       def sku = ...
       def pricelistItem
      
       pricelistItem = api.pricelistItem(listName, sku)
       
      Parameters:
      listName - Name of the price list.
      sku - SKU to use.
      Returns:
      Entire price list item record (PLI) as a Map.
      See Also:
    • pricelistItem

      Object pricelistItem(String listName, String sku, String key2)
      Looks up the matrix price list item record (XPLI) of the given SKU in a matrix price list of the given name. The price list line has to be approved and the targetDate of the price list has to be prior to the calculation targetDate. If there are multiple price lists of the same name, the one with the targetDate closer to the calculation targetDate is chosen.
      Example:
      
       def listName = ...
       def sku = ...
       def key2 = ...
       def pricelistItem
      
       pricelistItem = api.pricelistItem(listName, sku, key2)
       
      Parameters:
      listName - Name of the price list.
      sku - SKU to use.
      key2 - key2 to use.
      Returns:
      Entire matrix price list item record (XPLI) as a Map.
      See Also:
    • pricelistItem

      Object pricelistItem(String listName, String sku, String key2, Date targetDate)
      Looks up the matrix price list item record (XPLI) of the given SKU in a matrix price list of the given name. The price list line has to be approved and the targetDate of the price list has to be prior to the calculation targetDate. If there are multiple price lists of the same name, the one with the targetDate closer to the calculation targetDate is chosen.
      Example:
      
       def listName = ...
       def sku = ...
       def key2 = ...
       def key2 = ...
       def targetDate
      
       pricelistItem = api.pricelistItem(listName, sku, key2, targetDate)
       
      Parameters:
      listName - Name of the price list.
      sku - SKU to use.
      key2 - key2 to use.
      targetDate - targetDate for the search.
      Returns:
      Entire matrix price list item record (XPLI) as a Map.
      See Also:
    • getPricelistItem

      Map<String,Object> getPricelistItem(String listName)
      Similar to the pricelistItem(String) function. However, it optimizes the subsequent processing by providing the results as a map directly.
      Example:
      
       def listName = ...
      
       pricelistItem = api.getPricelistItem(listName)
       
      Parameters:
      listName - Name of the price list. Target date and SKU matching applies.
      Returns:
      Price list object.
      See Also:
    • bom

      Object bom()
      Accesses and retrieves values from a rolled-up bill of materials for the SKU being calculated. All quantities are rolled up and summed.
      Example:
      
       def bom
      
       bom = api.bom()
       
      Returns:
      List with the summed up quantities.
    • bom

      Object bom(String lookupTableName)
      Accesses and retrieves values from a rolled-up bill of materials for the SKU being calculated. The summed up quantities are multiplied with a factor that is retrieved by a lookup by the material name from the provided parameter, for example, a material-cost table.
      Example:
      
       def lookupTableName = ...
       def bom
      
       bom = api.bom(lookupTableName)
       
      Parameters:
      lookupTableName - Parameter table name.
      Returns:
      List with the summed up and multiplied quantities.
    • bom

      Object bom(String lookupTableName, String categoryName)
      Accesses and retrieves values from a rolled-up bill of materials for the SKU being calculated. Only BoM records with the specified category are considered. The summed up quantities are multiplied with a factor that is retrieved by a lookup by the material name from the provided parameter, for example, a material-cost table.
      Example:
      
       def lookupTableName = ...
       def categoryName = ...
       def bom
      
       bom = api.bom(lookupTableName, categoryName)
       
      Parameters:
      lookupTableName - Parameter table name.
      categoryName - Category name to filter on.
      Returns:
      List with the summed up and multiplied quantities.
    • bom

      Object bom(String lookupTableName, String categoryName, String materialName)
      Accesses and retrieves the values from a rolled-up bill of materials for the SKU being calculated. Only BoM records with the specified category and material are considered. The summed up quantities are multiplied with a factor that is retrieved by a lookup by the material name from the provided parameter, for example, a material-cost table.
      Example:
      
       def lookupTableName = ...
       def categoryName = ...
       def materialName = ...
       def bom
      
       bom = api.bom(lookupTableName, categoryName, materialName)
       
      Parameters:
      lookupTableName - Parameter table name.
      categoryName - Category name to filter on.
      materialName - Material to filter on.
      Returns:
      List with the summed up and multiplied quantities.
    • bomList

      Object bomList()
      Rolls up the current SKU's BoM and returns the rolled up BoM records (not just the quantities).
      Example:
      
       def bomList
      
       bomList = api.bomList()
       
      Returns:
      List of BoM records
    • anyUser

      @Deprecated Object anyUser(String entryName)
      Creates an input parameter that lets the user select a user from the list of all users. It is rendered as a user picker dialog / select list.
      Parameters:
      entryName - Name of the entry parameter
      Returns:
      Login name of the selected user or null
    • user

      Object user(String attributeName)
      Returns a value from the current user's master data.

      Example:

      
       // retrieves the email of the user
       def email = api.user("email")
       
      Parameters:
      attributeName - Attribute to return.
      Returns:
      User's attribute value
    • user

      Object user()
      Returns the entire master data object of the current user.

      Example:

      
       // retrieves the email of the user
       def email = api.user()?.email
       
      Returns:
      user object (U)
    • input

      @Deprecated Object input(String inputName)
      Deprecated.
      This method has been deprecated. Instead of api.input("abcd") use input.abcd.
      Retrieves the value of the input parameter of the given name.

      Important note: It only reads the value of an already defined input, it does not create an input parameter, nor does it trigger rendering any input widget in the UI (i.e. no side effects).

      To create inputs, see api.userEntry(), api.inputBuilderFactory() or DashboardApi.setParam(String, Object).

      Parameters:
      inputName - Input parameter name.
      Returns:
      Value entered by the user in the input parameter. In the Input Generation execution mode, it returns mock data.
      See Also:
    • inputMatrix

      @Deprecated Object inputMatrix(String inputMatrixName, String... columnNames)
      Creates an input parameter that lets the user select a matrix of values. It renders as a grid-style input widget with the specified columns. The result will be a list (= rows) of maps (= row's columns). The map attribute names are the column names.

      Make sure the column names are valid JSON identifiers (spaces are ok but try to avoid special chars).

      Parameters:
      inputMatrixName - Name of the parameter.
      columnNames - Column names/labels.
      Returns:
      List (= rows) of maps (= row's columns).
    • inputMatrix

      @Deprecated Object inputMatrix(String inputMatrixName, Map<String,Object> paramConfig, String... columns)
      Creates an input parameter that lets the user select a matrix of values. It renders as a grid-style input widget with the specified columns. The result will be a list (= rows) of maps (= row's columns). The map attribute names are the column names.

      Make sure the column names are valid JSON identifiers (spaces are ok but try to avoid special chars).

      Parameters:
      inputMatrixName - Name of the parameter.
      paramConfig - Map of the configuration settings with the following options (key, value):
      • 'canModifyRows' - false/true (the user can add and delete a row)
      • 'readOnlyColumns' - list of columns (names) to be uneditable
      • 'noCellRefresh' - false/true (do not update Configurator on each edit)
      • 'defaultHeight' - number which specifies the default table height
      • 'fixTableHeight' - false/true (to preserve the default height of the table)
      • 'fitFieldWidths' - false/true (to determine if fields should autofit their widths to titles or content)
      • 'enableClientFilter' - false/true (to add the quick filter to the Input Matrix)
      • 'hiddenColumns' - a list of columns (names) to be hidden in the matrix (supported in Unity UI only)
      • 'columnValueOptions' - predefines a drop-down list with specified values
      • 'columnType' - sets the column data type
      • 'disableRowSelection' - false/true (to disable a row selection (to hide the check-box))
      • 'columnLabels' - sets column labels
      columns - Column names/labels.
      Returns:
      List (= rows) of maps (= row's columns).
    • parsableInputFile

      Object parsableInputFile(String inputName)
      Creates an input parameter that lets the user pick a file. It renders as a file input widget that allows to use data from an XLSX file in a logic. It works only for entities with attachments (i.e. Q/CT/RBA) which need to be saved first.
      Example:
      
       def inputName = ...
       def parsableInputFile
      
       parsableInputFile = api.parsableInputFile(inputName)
       
      Parameters:
      inputName - Name of the parameter.
      Returns:
      Handle that uniquely identifies the binary and its version that was assigned to the input.
    • parsableInputFileData

      Object parsableInputFileData(String inputName)
      If a parsableInputFile has a value, this function opens the file and parses it to basic Groovy data structures.
      Example:
      
       def inputName = ...
       def parsableInputFileData
      
       parsableInputFileData = api.parsableInputFileData(inputName)
       
      Parameters:
      inputName - Name of the parameter.
      Returns:
      [data: [sheetName: [row1col1, row1col2, ...], [row2col1, row2col2, ...], ...]
    • parsableInputFileDataFromHandle

      Object parsableInputFileDataFromHandle(String fileHandle)
      If a parsableInputFile has a value, this function opens the file and parses it to basic Groovy data structures.
      Example:
      
       def fileHandle = ...
       def parsableInputFileDataFromHandle
      
       parsableInputFileDataFromHandle = api.parsableInputFileDataFromHandle(fileHandle)
       
      Parameters:
      fileHandle - Value of the parameter.
      Returns:
      [data: [sheetName: [row1col1, row1col2, ...], [row2col1, row2col2, ...], ...]
    • filter

      Object filter(String property, Object value)
      Deprecated.
      Creates a filter object that can be used in other API functions. The operator is always "equals", i.e. property = value.

      Example:

      
       def cas = api.find("CA",
               api.filter("assignmentId", mplId),
               api.filter("assignmentType", "MPL")
       )
       
      Parameters:
      property - Name of the property to filter on.
      value - Specified value.
      Returns:
      Filter object
    • filterFromMap

      Filter filterFromMap(Map<String,Object> filterMap)
      Constructs a filter object from the map representation of that filter (from the "wire format"). The map representation is the way the filter is described in the JSON requests between the UI and the server.
      Example:
      
       def filterMap = ...
       def filterFromMap
      
       filterFromMap = api.filterFromMap(filterMap)
       
      Parameters:
      filterMap - Filter in the form of nested maps.
      Returns:
      Filter object
    • filter

      Object filter(String property, Object opString, Object value)
      Deprecated.
      Use the Filter functions instead
      Creates a filter object that can be used in other API functions.

      Note: This method is, to an extent, dynamic. Dynamic in the sense that if the opString does not actually represent a valid operator (e.g. "="), the passed value will then be treated as the lower bound and the value as the upper bound. In other words, the resulting filter will look like this: Filter.and(Filter.greaterOrEqual(property, opString), Filter.lessThan(property, value)). If either parameter is null, its part is skipped.

      Example:

      
       datamartQuery.where(api.filter("PricingDate", ">", targetDate.minus(365).format("yyyy-MM-dd")))
       
      Parameters:
      property - Name of the property to filter on.
      opString - One of these: "=", "<", "<=", ">", ">=", "<>", "~". If different, it gets treated as the lower bound value; see the note above.
      value - Specified value (or an upper bound).
      Returns:
      Filter object
      See Also:
    • sellerToRelatedObjectsFilter

      Filter sellerToRelatedObjectsFilter(String relatedObjectTypeCode, String sellerId)
      Creates a filter to be applied to a search on a related object type, limiting the result to objects of the related type that has a link to the given seller.

      Example:

      
            import com.googlecode.genericdao.search.Filter
      
            // 'CO' - Compensation Plan type code
            // 'SC-001' - sellerId of the existing Seller
      
            // Custom filter which can be applied to the Compensation Plans search, limiting the results to
            // the compensations that has a link to the seller with the sellerId equals to 'SC-001'
            Filter filer = api.sellerToRelatedObjectsFilter('CO', 'SC-001')
      
            // Compensations plan search
            List sellerCompensationPlans = api.find('CO', 0, 0, null, filter)
      
            // all compensations connected with particular seller
            api.trace('All compensation plans connected with the Seller: ', sellerCompensationPlans)
       
      Parameters:
      relatedObjectTypeCode - TypeCode of the related object type. If not existing or null then null is returned. The possible values are:
      • 'CO': Compensation
      sellerId - sellerId of the existing Seller to filter on (if Seller does not exist null is returned
      Returns:
      Custom filter object
      Since:
      9.0 - Hurricane
    • customerToRelatedObjectsFilter

      Filter customerToRelatedObjectsFilter(String relatedObjectTypeCode, String customerId)
      Creates a filter to be applied to a search on a related object type, limiting the result to objects of the related type that has a link to the given customer.

      Example:

      
               def filter = api.customerToRelatedObjectsFilter("RBA", "104083")    // customerId=104083
               def rbas = api.find("RBA", 0, 0, null, filter)
               api.trace("rbas for customer #104083", null, rbas)
       
      Parameters:
      relatedObjectTypeCode - TypeCode of the related object type. The possible values are:
      • 'PR': PriceRecord
      • 'CT': Contract
      • 'CTLI': ContractLineItem
      • 'RBA': RebateAgreement
      • 'RBALI': RebateAgreementLineItem
      customerId - Customer.id to filter on.
      Returns:
      Filter object
      See Also:
    • customerToRelatedObjectsFilter

      Filter customerToRelatedObjectsFilter(String relatedObjectTypeCode, CustomerGroup customerGroup)
      Creates a filter to be applied to a search on a related object type, limiting the result to objects of the related type that has a link to the given customer picker.

      Example:

      
            CustomerGroup customerGroup = api.customerGroupEntry('Select CUSTOMERS')
               def filter = api.customerToRelatedObjectsFilter('RBA', customerGroup) // ex. CG[`attribute2` = "Restaurant"]
               def RBAs = api.find('RBA', filter)
               api.trace('RABs for CustomerType equals Restaurant', RBAs) // List of all RBAs which contains customers from Restaurant type
       
      Parameters:
      relatedObjectTypeCode - TypeCode of the related object type. The possible values are:
      PR : PriceRecord
      CT : Contract
      CTLI : ContractLineItem
      RBA : RebateAgreement
      RBALI : RebateAgreementLineItem
      customerGroup - Customer picker.
      Returns:
      Filter object
      See Also:
    • relatedObjectToCustomersFilter

      Filter relatedObjectToCustomersFilter(String relatedObjectTypedId)
      Creates a filter to be applied to a customer search, limiting the results to customers that are linked to the given related object (defined by its typedId).

      Example:

      
       def ras = api.find("RBA", 0, 1, null, null)
       ras.each {
               def filter = api.relatedObjectToCustomersFilter(it.typedId)
               def customers = api.find("C", 0, 0, null, filter)
               ...
       }
       
      Parameters:
      relatedObjectTypedId - TypedId of the related object. Its type needs to be one of:
      • 'PR' - PriceRecord
      • 'CT' - Contract
      • 'CTLI' - ContractLineItem
      • 'RBA' - RebateAgreement
      • 'RBALI' - RebateAgreementLineItem
      Returns:
      Filter object
    • productToRelatedObjectsFilter

      Filter productToRelatedObjectsFilter(String relatedObjectTypeCode, String sku)
      Creates a filter to be applied to a search on a related object type, limiting the results to objects of the related type that have a link to the given product.

      Example:

      
       def ras = api.find("RBA", 0, 1, null, null)
       ras.each {
               def raId = it.typedId.tokenize(".")[0] as Long
             def raFilter = api.relatedObjectToCustomersFilter("RBA", raId)
               def customers = api.find("C", 0, 0, null, filter)
               ...
       }
       
      Parameters:
      relatedObjectTypeCode - TypeCode of the related object type. Possible values are:
      • 'PR' - PriceRecord
      • 'CT' - Contract
      • 'CTLI' - ConttractLineItem
      • 'RBA' - RebateAgreement
      • 'RBALI' - RebateAgreementLineItem
      sku - Product.id to filter on.
      Returns:
      Filter object
      See Also:
    • productToRelatedObjectsFilter

      Filter productToRelatedObjectsFilter(String relatedObjectTypeCode, ProductGroup productGroup)
      Creates a filter to be applied to a search on a related object type, limiting the results to objects of the related type that have a link to the given product picker.

      Example:

      
            ProductGroup productGroup = api.productGroupEntry('Select PRODUCTS')
               def filter = api.productToRelatedObjectsFilter('RBA', productGroup) // ex. PG[`attribute9` = "American IPA"]
               def RBAs = api.find('RBA', filter)
               api.trace("RABs for ProductGroup equals 'American IPA'", RBAs) // List of all RBAs which contains SKUs from American IPA PG
       
      Parameters:
      relatedObjectTypeCode - TypeCode of the related object type. Possible values are:
      PR : PriceRecord
      CT : Contract
      CTLI : ContractLineItem
      RBA : RebateAgreement
      RBALI : RebateAgreementLineItem
      productGroup - Product.id to filter on.
      Returns:
      Filter object
      See Also:
    • relatedObjectToProductsFilter

      Filter relatedObjectToProductsFilter(String relatedObjectTypedId)
      Creates a filter to be applied to a product search, limiting the result to products that are linked to the given related object (defined by its typedId).
      Example:
      
       def relatedObjectTypedId = ...
       def relatedObjectToProductsFilter
      
       relatedObjectToProductsFilter = api.relatedObjectToProductsFilter(relatedObjectTypedId)
       
      Parameters:
      relatedObjectTypedId - TypedId of the related object. Its type needs to be one of:
      • 'PR' - PriceRecord
      • 'CT' - Contract
      • 'CTLI' - ContractLineItem
      • 'RBA' - RebateAgreement
      • 'RBALI' - RebateAgreementLineItem
      Returns:
      Filter object
    • isUserInGroup

      boolean isUserInGroup(String userGroupName, String loginUserName)
      Checks if the current user is a member of the given user group.

      Example:

      
       def user = api.user("loginName")
       if (api.isUserInGroup("Manager", user)) {
           ...
       }
       
      Parameters:
      userGroupName - Group name.
      loginUserName - Login name of the user.
      Returns:
      True or false
    • trace

      void trace(String functionName, String parameters, Object result)
      Generates a trace message that can be used during logic testing. The Trace window has 3 columns (FunctionName, Parameters, Result) which you can use for your debugging messages. During the regular logic execution the trace messages are ignored. The parameters specify the output of the trace.

      Note: Consider commenting out the trace messages before deploying to production.

      Performance consideration: Be carefull when using the api.trace() in a loop. If your logic (during testing) produces a huge list of trace messages on the backend, then this big list must be transferred over the internet to your local machine (when using Studio) and it can take significant time.

      Example:

      
           def listPrice = ...
           api.trace("listPrice", out.Currency, listPrice)
       
      Parameters:
      functionName - Function name. Regardless of the name, it can be any text you need to show during testing. Usually, if you use trace() for an output of a variable, you put there the variable name. (Originally this was used as a name of the function which outputted the value, so that is the origin of the name.)
      parameters - Parameters to trace. Regardless of the name, it can be any text you need to show during testing. (Originally this was used to display values of parameters supplied into a function, hence the name.)
      result - Result of the trace. Usually it is the value which you are tracing during testing. You can supply any value you would like to see in the Trace window. (Originally this was used to show a result of a function call, hence the name.)
      See Also:
    • trace

      void trace(String functionName, Object result)
      See trace(String, String, Object) for a description.

      Example:

      
           def salesOrg = ...
           api.trace("salesOrg", salesOrg)
       
      Parameters:
      functionName - Function name. Regardless of the name, it can be any text you need to show during testing. Usually, if you use trace() for an output of a variable, you put there the variable name. (Originally this was used as a name of the function which outputted the value, so that is the origin of the name.)
      result - Result of the trace. Usually it is the value which you are tracing during testing. You can supply any value you would like to see in the Trace window. (Originally this was used to show a result of a function call, hence the name.)
      See Also:
    • trace

      void trace(Object result)
      See trace(String, String, Object) for a description.

      Example:

      
           def price = ...
           api.trace(price)
       
      Parameters:
      result - Result of the trace. Usually it is the value which you are tracing during testing. You can supply any value you would like to see in the Trace window. (Originally this was used to show a result of a function call, hence the name.)
      See Also:
    • log

      void log(String msg, Object arg1)
      This function is meant to be used by the Pricefx application internally only. You should use logInfo(String, Object) or logWarn(String, Object).

      Logs a DEBUG message to the system error log which can be displayed in Tools > Logs > View Log. The log message can contain placeholders like {} which are then filled in dynamically with the argument's values. Note: To enable this function, you need to select the option "Allow Groovy logging to system log" in Tools > Configuration > General Settings.

      Example:

      
           def arg1 = ...
           api.log("listPrice Test", arg1)
       
      Parameters:
      msg - Log message to print.
      arg1 - Arguments for the log message.
      See Also:
    • log

      void log(Object msg)
      This function can be used by the Pricefx Support team only. You should use logInfo(Object) or logWarn(Object).

      Logs a DEBUG message to the system error log which can be displayed in menu Tools > Logs > View Log. The log message can contain placeholders like {} which are then filled in dynamically with the argument's values. Note: To enable this, you need to select the option "Allow Groovy logging to system log" in Tools > Configuration > General Settings.

      Example:

      
           api.log("listPrice Test")
       
      Parameters:
      msg - Message accompanying the exception.
      See Also:
    • logInfo

      void logInfo(String msg, Object arg1)
      Logs an INFO warning message to the system error log which can be displayed in Tools > Logs > View Log. The log message can contain placeholders like {} which are then filled in dynamically with the argument's values. Note: To enable this, you need to select the option "Allow Groovy logging to system log" in Tools > Configuration > General Settings.

      Example:

      
       def sku = api.product("sku")
       api.markItemDirty()
       api.logInfo("SKU marked as dirty", sku)
       
      Parameters:
      msg - Log message to print.
      arg1 - Arguments for the log message.
      See Also:
    • logInfo

      void logInfo(Object msg)
      Logs an INFO message to the system error log which can be displayed in Tools > Logs > View Log. The log message can contain placeholders like {} which are then filled in dynamically with the argument's values. Note: To enable this, you need to select the option "Allow Groovy logging to system log" in Tools > Configuration > General Settings.

      Example:

      
       api.logInfo("No items to be calculated")
       
      Parameters:
      msg - Log message to print.
      See Also:
    • logWarn

      void logWarn(String msg, Object arg1)
      Logs a WARN message to the system error log which can be displayed in Tools > Logs > View Log. The log message can contain placeholders like {} which are then filled in dynamically with the argument's values. Note: To enable this, you need to select the option "Allow Groovy logging to system log" in Tools > Configuration > General Settings.

      Example:

      
       def sku = api.product("sku")
      
       if (checkItem()) {
            api.logWarn("Incorrect or missing 'sku' parameter", sku)
       }
       
      Parameters:
      msg - Log message to print.
      arg1 - Arguments for the log message.
      See Also:
    • logWarn

      void logWarn(Object msg)
      Logs a WARN message to the system error log which can be displayed in Tools > Logs > View Log. The log message can contain placeholders like {} which are then filled in dynamically with the argument's values. Note: To enable this, you need to select the option "Allow Groovy logging to system log" in Tools > Configuration > General Settings.

      Example:

      
       api.logWarn("SKU cannot be null")
       
      Parameters:
      msg - Message accompanying the exception.
      See Also:
    • getParameter

      ContextParameter getParameter(String parameterName)
      Retrieves an already generated (in the previous logic code) input parameter in the form of a ContextParameter object. This object can be used to set a label and a default value of an input, if it is required, etc.

      Example:

      
       def p = api.getParameter("Quantity")        // retrieve the context parameter with the same name as the input
       if (p != null && p.getValue() == null) {
         p.setLabel("Required Quantity")           // set the displayed label
         p.setRequired(true)                       // set the mandatory hint
         p.setReadOnly(false)                      // set the read only flag
         p.setValue(1)                             // set the default value with which the input is pre-populated
       }
       return qty ?: 1                             // if user doesn't specify a value, return 1
       
      Parameters:
      parameterName - Name of the input parameter to retrieve.
      Returns:
      Parameter object or null.
    • currentContext

      Map<String,Object> currentContext(String sku)
      In case of list processing (price lists, price grids), this method allows an easy access to values from the same list. It searches for the result record in the same list with the provided SKU.

      Note: If used in a context that has a secondary key, only the first object is returned.
      Example:

      
       def sku = ...
       def currentContext
      
       currentContext = api.currentContext(sku)
       
      Parameters:
      sku - SKU to look for.
      Returns:
      Result record (entire record)
    • currentContext

      Map<String,Object> currentContext(String sku, String key2)
      In case of list processing (price lists, price grids), this method allows an easy access to values from the same list. It searches for the result record in the same list with the provided SKU.
      Example:
      
       def sku = ...
       def key2 = ...
       def currentContext
      
       currentContext = api.currentContext(sku, key2)
       
      Parameters:
      sku - SKU to look for.
      key2 - key2 to look for.
      Returns:
      result record (entire record)
    • previousContext

      Map<String,Object> previousContext(String sku)
      In case of (chained) price lists, this method allows for an easy retrieval of records from the previous list.

      Note: If used in a context that has a secondary key, only the first object is returned.
      Example:

      
       def sku = ...
       def previousContext
      
       currentContext = api.currentContext(sku)
       
      Parameters:
      sku - SKU to look for.
      Returns:
      Result record (entire record)
    • previousContext

      Map<String,Object> previousContext(String sku, String key2)
      In case of (chained) price lists, this method allows for an easy retrieval of records from the previous list.
      Example:
      
       def sku = ...
       def key2 = ...
       def previousContext
      
       previousContext = api.previousContext(sku, key2)
       
      Parameters:
      sku - SKU to look for.
      key2 - key2 to look for.
      Returns:
      Result record (entire record)
    • contextName

      String contextName()
      Name of the current context, e.g. price list name, quote name etc.
      Example:
      
       def contextName
      
       contextName = api.contextName()
       
      Returns:
      Name of a context.
    • contextType

      String contextType()
      The type (type code string) of the current context.
      Example:
      
       def contextType
      
       contextType = api.contextType()
       
      Returns:
      Type code string
    • contextTypedId

      String contextTypedId()
      The typedId of the current context.
      Example:
      
       def contextTypedId
      
       contextTypedId = api.contextTypedId()
       
      Returns:
      typedId string
    • getProperty

      Object getProperty(Object object, String path)
      Provides an optimized way to get to certain object attributes. The sandbox automatically converts "real" server objects into a map representation when the object is accessed. This is for safety (sandboxing) reasons. This process converts all object attributes. If only one specific attribute is of interest, this method shortcuts that as the underlying object is not exposed (and thus does not force the sandbox into conversion).
      Example:
      
       def object = ...
       def path = ...
       def getProperty
      
       getProperty = api.getProperty(object, path)
       
      Parameters:
      object - Object whose value to retrieve.
      path - Attribute name.
      Returns:
      Value of the attribute
    • getPropertyByElementName

      Object getPropertyByElementName(Object object, String elementName)
      Gets object attributes by elementName. It works only for objects that have meta attributes which contain the element name. These are e.g. PLI, SIMI, PGI, MPLI.
      Example:
      
       def object = ...
       def elementName = ...
       def getPropertyByElementName
      
       getPropertyByElementName = api.getPropertyByElementName(object, elementName)
       
      Parameters:
      object - Object whose value should be retrieved.
      elementName - elementName value.
      Returns:
      Value of the attribute or null if an invalid object or no matching meta found.
    • currentItem

      Object currentItem()
      In case of a list processing operation (for price lists, price grids), this method gets the currently worked on record, for example:
      • For price calculations, it returns the price list item or price grid item or quote item.
      • For Calculated Field Sets, it returns the row being processed, like Product/Customer/ProductExtension/PriceParameter row.

      Important: The price list line item is initially (during 1st pass) created only after the first logic execution (i.e. the PLI is created from the logic results). That means that during the first logic execution, the PLI does not exist yet and the method will return null.

      Example - in a price list logic:

      
       def currentItem = api.currentItem()
       def currentSku = currentItem != null ? currentItem.attribute20 : api.product("attribute20")
       

      Example - in a Calculated Field Set:

      
       def cost = api.currentItem()?.attribute1
       def exchangeRate = 1.1 // fixed rate for sample purposes
       return cost != null ? (cost * exchangeRate) : null
       

      In case of PriceAnalyzer Data Load logic/formula, this method gets the Data Load configuration, allowing to retrieve properties such as the source or target filter.

      Example

      
           def targetFilter
           def targetFilterMap = api.currentItem("targetFilter")
           if (targetFilterMap) {
               targetFilter = api.filterFromMap(targetFilterMap)
           }
       

      Returns:
      Item object as a Map.
      See Also:
    • currentItemByElementName

      Object currentItemByElementName(String elementName)
      In case of a list processing operation (for price lists, price grids), this method gets the currently worked on record's property by elementName.

      For example, when you want to get a value of an LPG column which was generated by an element named ListPrice, you do not need to know that it was stored in the column attribute3, but you can ask for the value using the name of the element which provided the value.
      Example:

      
       def elementName = ...
       def currentItemByElementName
      
       currentItemByElementName = api.currentItemByElementName(elementName)
       
      Parameters:
      elementName - Element name
      Returns:
      Item's property value
      See Also:
    • currentItem

      Object currentItem(String attributeName)
      The same as currentItem() but it returns only the value of the given attribute. You can also retrieve active and previous approved calculation results (see the example below).

      Example – retrieves the previous and active calculation results:

      
       def activeCalculationResults = api.jsonDecodeList(api.currentItem("activeCalculationResults"))
      
       def previousCalculationResults = api.jsonDecodeList(api.currentItem("previousCalculationResults"))
       

      Example – retrieves the specified attribute:

      
       def activePrice = api.currentItem("activePrice")
       
      Parameters:
      attributeName - Attribute to retrieve.
      Returns:
      Value of the attribute.
      See Also:
    • contextSkuSet

      Set<Object> contextSkuSet(int startRow)
      Returns a set of SKUs which comprise so-called 'SKU context' of the current formula execution.

      The form of the SKU context differs, e.g., in case of the product detail formula executed via price grid details, the resulting set will contain all SKUs of the left-pane grid.

      Note:

      • If the SKU context is not supported by the current formula execution, null is returned.
      • A maximum of 200 SKUs is returned per one call. If there are more, startRow must be used to get all SKUs in the set.

      Example:
      
       def parameterName = ...
       def startRow
      
       contextSkuSet = api.contextSkuSet(startRow)
       
      Parameters:
      startRow - Starting row of the result set.
      Returns:
      Set of SKUs or null if the SKU context is not available for the current formula execution.
    • getMaxFindResultsLimit

      int getMaxFindResultsLimit()
      Returns the maximum number of records that find(String, int, int, String, Filter...) and its variations can return in one call. The value is set in the formulaEngine.script.findMaxResults system parameter. The default value is 2000 records.
      Example:
      
       return api.getMaxFindResultsLimit()
       
      Returns:
      Maximum number of records
      See Also:
    • find

      List<Object> find(String typeCode, Filter... filters)
      Deprecated.
      Instead use find(String, int, int, String, List, Filter...) in order to always specify the fields to be returned (for performance reasons).
      The Swiss army knife method of the API. With this method you can search for all types of objects with a freestyle query. The filters are ANDed together. A maximum of 200 items is returned.
      Parameters:
      typeCode - Type code string of the type of the object to search for. All available type codes can be retrieved by calling <hostname>/pricefx/<partition name>/fetch.
      filters - Optional list of filters (that will evaluated using the AND operator). For Product/Customer tables, you can also filter by a PX/CX attribute using the following syntax: Filter.equal(PXNAME__PXCOLUMN, value).
      TypedId and database fields aliasing allowed, see: find(String, int, int, String, Map, boolean, Filter...)
      For example: return api.find("P", Filter.equal("pcost__attribute1","test")) returns the products where attribute1 value equals "test" in the "pcost" PX table. For more details see the Can I filter a product lookup by a PX attribute in Groovy? Knowledge Base article.
      Returns:
      List of objects represented as Maps.
      See Also:
    • find

      List<Object> find(String typeCode, int startRow, Filter... filters)
      Deprecated.
      Instead use find(String, int, int, String, List, Filter...) where you should always specify the fields to be returned.
      The Swiss army knife method of the API. With this method you can search for all types of objects with a freestyle query. The filters are ANDed together. A maximum of 200 items is returned. The start row parameter can be used to page through more than 200 results.

      If you do not need all the columns to be fetched, you should use find(String, int, int, String, List, Filter...) instead (because of performance reasons).

      Parameters:
      typeCode - Type code string of the type of the object to search for. All available type codes can be retrieved by calling <hostname>/pricefx/<partition name>/fetch.
      startRow - Starting row of the result set.
      filters - Optional list of filters (that will be evaluated using the AND operator). For Product/Customer tables, you can also filter by a PX/CX attribute using the following syntax: Filter.equal(PXNAME__PXCOLUMN, value).
      TypedId and database fields aliasing allowed, see: find(String, int, int, String, Map, boolean, Filter...)
      For example: return api.find("P", Filter.equal("pcost__attribute1","test")) returns the products where attribute1 value equals "test" in the "pcost" PX table. For more details see the Can I filter a product lookup by a PX attribute in Groovy? Knowledge Base article.
      Returns:
      List of objects represented as Maps.
      See Also:
    • find

      List<Object> find(String typeCode, int startRow, String sortBy, Filter... filters)
      Deprecated.
      Instead use find(String, int, int, String, List, Filter...) where you should always specify the fields to be returned.
      The Swiss army knife method of the API. With this method you can search for all types of objects with a freestyle query. The filters are ANDed together. A maximum of 200 items is returned. The start row parameter can be used to page through more than 200 results.

      If you do not need all the columns to be fetched, you should use find(String, int, int, String, List, Filter...) instead (because of performance reasons).

      Example:

      
       def sku = api.product("sku")
      
       def filters = [
           Filter.equal("name", "Competition"),
           Filter.equal("sku", sku),
       ]
      
       // sort by competitor's price ASC
       def competitors = api.find("PX", 0, "attribute1", *filters)
      
       competitors.each {
           ...
       }
       
      Parameters:
      typeCode - Type code string of the type of the object to search for. All available type codes can be retrieved by calling <hostname>/pricefx/<partition name>/fetch.
      startRow - Starting row of the result set.
      sortBy - String of fields/attributes, separated by a comma, based on which the result set should be sorted. Any field can be prefixed with '-' for descending sort order.
      filters - Optional list of filters (that will be evaluated using AND operator). For Product/Customer tables, you can also filter by a PX/CX attribute using the following syntax: Filter.equal(PXNAME__PXCOLUMN, value).
      TypedId and database fields aliasing allowed, see: find(String, int, int, String, Map, boolean, Filter...)
      For example: return api.find("P", Filter.equal("pcost__attribute1","test")) returns the products where attribute1 value equals "test" in the "pcost" PX table. For more details see the Can I filter a product lookup by a PX attribute in Groovy? Knowledge Base article.
      Returns:
      List of objects represented as Maps.
      See Also:
    • find

      List<Object> find(String typeCode, int startRow, int maxRows, String sortBy, Filter... filters)
      The Swiss army knife method of the API. With this method you can search for all types of objects with a freestyle query.
      The filters are ANDed together. The maximum number of rows retrieved is determined by the formulaEngine.script.findMaxResults system parameter.
      The maxRows parameter can only be set to values lower than that.

      Note: This is the only method without the fields parameter in its signature. This means it is slower and returns data types defined within the metadata (at the application layer), compared to the api.find() method that includes fields in its signature, which is faster and returns records with data types defined in the database. This is the reason why this version of the api.find() method may return different data types than other versions of api.find().
      Note: When using api.find and you need to retrieve more than getMaxFindResultsLimit() records, use api.stream() instead of applying paging. See more details in the Data Querying using api.find() KB article.

      Example:

      
       def sku = api.product("sku")
      
       def filters = [
           Filter.equal("name", "Competition"),
           Filter.equal("sku", sku),
       ]
      
       // sort by competitor's price ASC
       def competitors = api.find("PX", 0, api.getMaxFindResultsLimit(), "-attribute2", *filters)
      
       competitors.each {
           ...
       }
       

      Example 2:

      Note: use the rebateTypeUN instead of rebateType to filter the rebate type field.

      The following example retrieves Rebate agreement lines that are not folders:

      
       def rebateAgreement = api.find("RBALI", 0, api.getMaxFindResultsLimit(), "-lastUpdateDate", Filter.notEqual("rebateTypeUN", null))
       return rebateAgreement
       
      Parameters:
      typeCode - Type code string of the type of the object to search for. All available type codes can be retrieved by calling <hostname>/pricefx/<partition name>/fetch.

      Note: When searching CX/PX/SX tables using api.find(), it is a good practice to specify the corresponding type code with the number of columns (e.g., PX3). In case just “PX”, “CX“, or “SX“ is used (for example, api.find("PX",0,100,null,*filters)) the system will try to find the correct table considering, for example, name criteria defined in the filter. If no relevant table is found the fallback PX30 will be returned.

      startRow - Starting row of the result set.
      maxRows - Maximum number of rows to retrieve. The value can be up to getMaxFindResultsLimit(). If set to 0, it will default to 200.
      sortBy - String of fields/attributes, separated by a comma, based on which the result set should be sorted. Any field can be prefixed with '-' for descending sort order.
      filters - Optional list of filters (that will be evaluated using the AND operator). For Product/Customer tables, you can also filter by a PX/CX attribute using the following syntax: Filter.equal(PXNAME__PXCOLUMN, value).
      TypedId and database fields aliasing allowed, see: find(String, int, int, String, Map, boolean, Filter...)
      For example: return api.find("P", Filter.equal("pcost__attribute1","test")) returns the products where attribute1 value equals "test" in the "pcost" PX table. For more details see the Can I filter a product lookup by a PX attribute in Groovy? Knowledge Base article.
      Returns:
      List of objects represented as Maps.
      See Also:
    • find

      List<Object> find(String typeCode, int startRow, int maxRows, String sortBy, List<String> fields, Filter... filters)
      The Swiss army knife method of the API. With this method you can search for all types of objects with a freestyle query. The filters are ANDed together. The maximum number of rows retrieved is determined by the formulaEngine.script.findMaxResults system parameter. The maxRows parameter can only be set to values lower than that.
      Note: When using api.find and you need to retrieve more than getMaxFindResultsLimit() records, use api.stream() instead of applying paging. See more details in the Data Querying using api.find() KB article.

      Example:

      
       def sku = api.product("sku")
      
       def filters = [
           Filter.equal("name", "Competition"),
           Filter.equal("sku", sku),
       ]
      
       // sort by competitor's price ASC
       def competitors = api.find("PX", 0, api.getMaxFindResultsLimit(), "-attribute2", ["attribute2", "outputs.Quantity.result", "attribute6"], *filters)
      
       competitors.each {
           ...
       }
       

      Example 2:

      Note: use the rebateTypeUN instead of rebateType to filter the rebate type field.

      The following example retrieves specified Rebate agreement lines that are not folders:

      
       def rebateAgreement = api.find("RBALI", 0, api.getMaxFindResultsLimit(), "-lastUpdateDate", ["label", "clicId", "customerGroup", "createDate", "lastUpdateDate"], Filter.notEqual("rebateTypeUN", null))
       return rebateAgreement
       
      Parameters:
      typeCode - Type code string of the type of the object to search for. All available type codes can be retrieved by calling <hostname>/pricefx/<partition name>/fetch.

      Note: When searching CX/PX/SX tables using api.find(), it is a good practice to specify the corresponding type code with the number of columns (e.g., PX3). In case just “PX”, “CX“, or “SX“ is used (for example, api.find("PX",0,100,null,*filters)) the system will try to find the correct table considering, for example, name criteria defined in the filter. If no relevant table is found the fallback PX30 will be returned.

      startRow - Starting row of the result set.
      maxRows - Maximum number of rows to retrieve. The value can be up to getMaxFindResultsLimit(). If set to 0, it will default to 200.
      sortBy - String of fields/attributes, separated by a comma, based on which the result set should be sorted. Any field can be prefixed with '-' for descending sort order.
      fields - List of fields to be returned in the result. If you really need all fields, you can set this parameter to null. You can specify fields by extracting them from the JSON data (input/output). For example: inputs.DiscountPercent.value, outputs.Quantity.result, or outputs.InvoicePrice.result.
      Note: The name of a field used here can be different from the name of the field returned by the api.find(). For more details, please refer to the How to Determine the Field Name for Use in Groovy API Methods article.
      filters - Optional list of filters (that will be evaluated using the AND operator). For Product/Customer tables, you can also filter by a PX/CX attribute using the following syntax: Filter.equal(PXNAME__PXCOLUMN, value).
      TypedId and database fields aliasing allowed, see: find(String, int, int, String, Map, boolean, Filter...)
      For example: return api.find("P", Filter.equal("pcost__attribute1","test")) returns the products where attribute1 value equals "test" in the "pcost" PX table. For more details see the Can I filter a product lookup by a PX attribute in Groovy? Knowledge Base article.
      Returns:
      List of objects represented as Maps.
      See Also:
    • find

      List<Object> find(String typeCode, int startRow, int maxRows, String sortBy, List<String> fields, boolean distinctValuesOnly, Filter... filters)
      The Swiss army knife method of the API. With this method you can search for all types of objects with a freestyle query. The filters are ANDed together. The maximum number of rows retrieved is determined by the formulaEngine.script.findMaxResults system parameter. The maxRows parameter can only be set lower values than that.

      Example:

      
       def sku = api.product("sku")
      
       def filters = [
           Filter.equal("name", "Competition"),
           Filter.equal("sku", sku),
       ]
      
       // sort by competitor's price ASC
       def competitors = api.find("PX", 0, api.getMaxFindResultsLimit(), "-attribute2", ["attribute2", "outputs.Quantity.result", "attribute6"], true, *filters)
      
       competitors.each {
           ...
       }
       

      Example 2:

      Note: use the rebateTypeUN instead of rebateType to filter the rebate type field.

      The following example retrieves specified Rebate agreement lines that are not folders:

      
       def rebateAgreement = api.find("RBALI", 0, api.getMaxFindResultsLimit(), "-lastUpdateDate", ["label", "clicId", "customerGroup", "createDate", "lastUpdateDate"], Filter.notEqual("rebateTypeUN", null))
       return rebateAgreement
       
      Parameters:
      typeCode - Type code string of the type of the object to search for. All available type codes can be retrieved by calling <hostname>/pricefx/<partition name>/fetch.

      Note: When searching CX/PX/SX tables using api.find(), it is a good practice to specify the corresponding type code with the number of columns (e.g., PX3). In case just “PX”, “CX“, or “SX“ is used (for example, api.find("PX",0,100,null,*filters)) the system will try to find the correct table considering, for example, name criteria defined in the filter. If no relevant table is found the fallback PX30 will be returned.

      startRow - Starting row of the result set.
      maxRows - Maximum number of rows to retrieve. The value can be up to getMaxFindResultsLimit(). If set to 0, it will default to 200.
      sortBy - String of fields/attributes, separated by a comma, based on which the result set should be sorted. Any field can be prefixed with '-' for descending sort order.
      fields - List of fields to be returned in the result. If you really need all fields, you can set this parameter to null. You can specify fields by extracting them from the JSON data (input/output). For example: inputs.DiscountPercent.value, outputs.Quantity.result, or outputs.InvoicePrice.result.
      Note: The name of a field used here can be different from the name of the field returned by the api.find() method. For more details, please refer to the How to Determine the Field Name for Use in Groovy API Methods article.
      distinctValuesOnly - Fetches distinct/all values. The use case here is fetching distinct single column values.
      filters - Optional list of filters (that will be evaluated using the AND operator). For Product/Customer tables, you can also filter by a PX/CX attribute using the following syntax: Filter.equal(PXNAME__PXCOLUMN, value).
      TypedId and database fields aliasing allowed, see: find(String, int, int, String, Map, boolean, Filter...)
      For example: return api.find("P", Filter.equal("pcost__attribute1","test")) returns the products where attribute1 value equals "test" in the "pcost" PX table. For more details see the Can I filter a product lookup by a PX attribute in Groovy? Knowledge Base article.
      Returns:
      List of objects represented as Maps.
      See Also:
    • find

      List<Object> find(String typeCode, int startRow, int maxRows, String sortBy, Map<String,String> fields, boolean distinctValuesOnly, Filter... filters)
      The Swiss army knife method of the API. With this method you can search for all types of objects with a freestyle query. The filters are ANDed together. The maximum number of rows retrieved is determined by the formulaEngine.script.findMaxResults system parameter. The maxRows parameter can only be set lower values than that.

      Note: Filter can accept also following properties.
      (1) typeId as the property :
      
       def pricelist = api.find('PL', Filter.equal('typedId', '1.PL'))     // Where 1.PL is a typedId of PL with id = 1
       def typedId = pricelist.typedId                                     // typedId = 1
       
      (2) additional aliasing between fields' name in the UI and database (to make return from find(java.lang.String, com.googlecode.genericdao.search.Filter...) and stream(java.lang.String, java.lang.String, com.googlecode.genericdao.search.Filter...) consistent with the Filter's properties). Values from both columns can be passed as the property:
      UI field Database field Table
      'quoteType' 'quoteTypeUniqueName' Q
      'supersededBy' 'supersededByUN' Q, RBA, CT
      'prevRev' 'prevRevUN' Q, RBA, CT
      'sellerName' 'seller.sellerName' RBA
      'rebateType' 'rebateTypeUN' PYR, RR
      'headerRebateType' 'headerRebateTypeUniqueName' RBA
      'customerGroup' 'customerGroup.customerFieldValue' Q
      'productGroup' 'productGroup.productFieldValue' CT, RR
      'nodeId' 'id' C
      'changeRequestId' 'changeRequest.id' DCRI

      Example:
      
       // find/stream by 'quoteType' and 'quoteTypeUniqueName' are equivalent
       api.find(Q, Filter.in(quoteType, [1.Q, 2.Q])) == api.find(Q, Filter.in(quoteTypeUniqueName, [1.Q, 2.Q]))
       // find/stream by 'sellerName' and 'seller.sellerName' are equivalent
       api.find(RBA, Filter.isNotNull('sellerName')) == api.find(RBA, Filter.isNotNull('seller.sellerName'))
       
      Parameters:
      typeCode - Type code string of the type of the object to search for. All available type codes can be retrieved by calling <hostname>/pricefx/<partition name>/fetch.

      Note: When searching CX/PX/SX tables using api.find(), it is a good practice to specify the corresponding type code with the number of columns (e.g., PX3). In case just “PX”, “CX“, or “SX“ is used (for example, api.find("PX",0,100,null,*filters)) the system will try to find the correct table considering, for example, name criteria defined in the filter. If no relevant table is found the fallback PX30 will be returned.

      startRow - Starting row of the result set.
      maxRows - Maximum number of rows to retrieve. The value can be up to getMaxFindResultsLimit(). If set to 0, it will default to 200.
      sortBy - String of fields/attributes, separated by a comma, based on which the result set should be sorted. Any field can be prefixed with '-' for descending sort order.
      fields - Map of pairs [fieldname : aggregation] holding fields to be returned in the result where the aggregation can be one of these: SUM, AVG, MIN or MAX. Key of the map is the field name. The value can be a field operator like SUM, AVG, MIN or MAX.
      distinctValuesOnly - Fetches distinct/all values. The use case here is fetching distinct single column values.
      filters - Optional list of filters (that will be evaluated using the AND operator). For Product/Customer tables, you can also filter by a PX/CX attribute using the following syntax: Filter.equal(PXNAME__PXCOLUMN, value).
      For example: return api.find("P", Filter.equal("pcost__attribute1","test")) returns the products where attribute1 value equals "test" in the "pcost" PX table. For more details see the Can I filter a product lookup by a PX attribute in Groovy? Knowledge Base article.
      Returns:
      List of objects represented as Maps.
      See Also:
    • stream

      PublicGroovyAPI.ResultIterator stream(String typeCode, String sortBy, Filter... filters)
      Searches for all types of objects with a freestyle query and iterates over the result set. The filters are ANDed together. If you do not need all the columns to be fetched, you should use stream(String, String, List, Filter...) instead (because of performance reasons).

      Note: You have to close the iterator after iterating the data using withCloseable (preferred, see the example below) or Closeable.close().

      Example:

      
               def filters = [
               Filter.equal("attribute2", "active")
               ]
      
               return records = api.stream("P", null, *filters)
                   ?.withCloseable { it.each {product -> ...} }
       
      Parameters:
      typeCode - Type code string of the type of the object to search for. All available type codes can be retrieved by calling <hostname>/pricefx/<partition name>/fetch.
      sortBy - String of fields/attributes, separated by a comma, based on which the result set should be sorted. Any field can be prefixed with '-' for descending sort order.
      filters - Optional list of filters (that will be evaluated using the AND operator). For Product/Customer tables, you can also filter by a PX/CX attribute using the following syntax: Filter.equal(PXNAME__PXCOLUMN, value).
      TypedId and database fields aliasing allowed, see: find(String, int, int, String, Map, boolean, Filter...)
      For example: return records = api.stream("P", null, Filter.equal("pcost__attribute1", "test"))?.withCloseable { it.collect() } returns the products where attribute1 value equals "test" in the "pcost" PX table. For more details see the Can I filter a product lookup by a PX attribute in Groovy? Knowledge Base article.
      Returns:
      Result implements the Iterator interface, allowing for iteration over all records in the scope of the query.
      See Also:
    • stream

      PublicGroovyAPI.ResultIterator stream(String typeCode, String sortBy, List<String> fields, Filter... filters)
      Searches for all types of objects with a freestyle query and iterates over the result set. The filters are ANDed together.

      This method is not supported in the Syntax Check mode.

      Note: You have to close the iterator after iterating the data using withCloseable (preferred, see the example below) or Closeable.close().

      Example:

      
       def filters = [
            Filter.equal("attribute2", "Active")
       ]
      
       def products = api.stream("P", "-attribute1", ["attribute2"], *filters)
       ?.withCloseable { it.each {product -> ...} }
      
       
      Parameters:
      typeCode - Type code string of the type of the object to search for. All available type codes can be retrieved by calling <hostname>/pricefx/<partition name>/fetch.
      sortBy - String of fields/attributes, separated by a comma, based on which the result set should be sorted. Any field can be prefixed with '-' for descending sort order.
      fields - List of attributes you want to return in the result, i.e. skip all attributes not contained in the list that the search would return otherwise.
      You can specify fields by extracting them from the JSON data (input/output). For example: inputs.DiscountPercent.value, outputs.Quantity.result, or outputs.InvoicePrice.result.
      Example: api.stream("QLI", null, ["clicId", "sku", "inputs.Quantity.value", "outputs.Cost.result"]).collect().
      Do not use null for the fields parameter, otherwise an error can be thrown when the result exceeds 200 items (see stream(String, String, Filter...)).
      filters - Optional list of filters (that will be evaluated using the AND operator). For Product/Customer tables, you can also filter by a PX/CX attribute using the following syntax: Filter.equal(PXNAME__PXCOLUMN, value).
      TypedId and database fields aliasing allowed, see: find(String, int, int, String, Map, boolean, Filter...)
      For example: return records = api.stream("P", null, Filter.equal("pcost__attribute1", "test"))?.withCloseable { it.collect() } returns the products where attribute1 value equals "test" in the "pcost" PX table. For more details see the Can I filter a product lookup by a PX attribute in Groovy? Knowledge Base article.
      Returns:
      Result implements the Iterator interface, allowing for iteration over all records in the scope of the query.
      See Also:
    • stream

      PublicGroovyAPI.ResultIterator stream(String typeCode, String sortBy, List<String> fields, boolean distinctValuesOnly, Filter... filters)
      Searches for all types of objects with a freestyle query and iterates over the result set. The filters are ANDed together.

      This method is not supported in the Input Generation mode.

      Note: You have to close the iterator after iterating the data using withCloseable (preferred, see the stream(String, String, Filter[]) example) or Closeable.close().
      Example:

      
       def filters = [
            Filter.equal("attribute2", "Active")
       ]
      
       def products = api.stream("P", "-attribute1", ["attribute2"], true, *filters)
       ?.withCloseable { it.each {product -> ...} }
      
       
      Parameters:
      typeCode - Type code string of the type of the object to search for. All available type codes can be retrieved by calling <hostname>/pricefx/<partition name>/fetch.
      sortBy - String of fields/attributes, separated by a comma, based on which the result set should be sorted. Any field can be prefixed with '-' for descending sort order.
      fields - List of attributes you want to return in the result, i.e. skip all attributes not contained in the list that the search would return otherwise.
      You can specify fields by extracting them from the JSON data (input/output). For example: inputs.DiscountPercent.value, outputs.Quantity.result, or outputs.InvoicePrice.result.
      Example: api.stream("QLI", null, ["clicId", "sku", "inputs.Quantity.value", "outputs.Cost.result"]).collect()
      Do not use null for the fields parameter, otherwise an error can be thrown when the result exceeds 200 items (see stream(String, String, Filter...)).
      distinctValuesOnly - Fetches distinct/all values. The use case here is fetching distinct single column values.
      filters - Optional list of filters (that will be evaluated using the AND operator). For Product/Customer tables, you can also filter by a PX/CX attribute using the following syntax: Filter.equal(PXNAME__PXCOLUMN, value).
      TypedId and database fields aliasing allowed, see: find(String, int, int, String, Map, boolean, Filter...)
      For example: return records = api.stream("P", null, Filter.equal("pcost__attribute1", "test"))?.withCloseable { it.collect() } returns the products where attribute1 value equals "test" in the "pcost" PX table. For more details see the Can I filter a product lookup by a PX attribute in Groovy? Knowledge Base article.
      Returns:
      Result implements the Iterator interface, allowing for iteration over all records in scope of the query.
      See Also:
    • stream

      PublicGroovyAPI.ResultIterator stream(String typeCode, String sortBy, Map<String,String> fields, boolean distinctValuesOnly, Filter... filters)
      Searches for all types of objects with a freestyle query and iterates over the result set. The filters are ANDed together.

      This method is not supported in the Input Generation mode.

      Note: You have to close the iterator after iterating the data using withCloseable (preferred, see the stream(String, String, Filter[]) example) or Closeable.close().
      Example:

      
       def filters = [
            Filter.equal("attribute2", "Active")
       ]
      
       def products = api.stream("P", "-attribute1", ["attribute2" : 213], true, *filters)
       ?.withCloseable { it.each {product -> ...} }
      
       
      Parameters:
      typeCode - Type code string of the type of the object to search for. All available type codes can be retrieved by calling <hostname>/pricefx/<partition name>/fetch.
      sortBy - String of fields/attributes, separated by a comma, based on which the result set should be sorted. Any field can be prefixed with '-' for descending sort order.
      fields - Map of pairs [fieldname : aggregation] holding fields to be returned in the result where the aggregation can be one of these SUM, AVG, MIN or MAX. The key of the map is the field name. The value can be a field operator like SUM, AVG, MIN or MAX.
      Do not use null for the fields parameter, otherwise an error can be thrown when the result exceeds 200 items (see stream(String, String, Filter...)).
      distinctValuesOnly - Fetches distinct/all values. The use case here is fetching distinct single column values.
      filters - Optional list of filters (that will be evaluated using the AND operator). For Product/Customer tables, you can also filter by a PX/CX attribute using the following syntax: Filter.equal(PXNAME__PXCOLUMN, value).
      TypedId and database fields aliasing allowed, see: find(String, int, int, String, Map, boolean, Filter...)
      For example: return records = api.stream("P", null, Filter.equal("pcost__attribute1", "test"))?.withCloseable { it.collect() } returns the products where attribute1 value equals "test" in the "pcost" PX table. For more details see the Can I filter a product lookup by a PX attribute in Groovy? Knowledge Base article.
      Returns:
      Result implements the Iterator interface, allowing for iteration over all records in scope of the query.
      See Also:
    • namedEntities

      List<Map<String,Object>> namedEntities(List<Object> objects)
      When given a list of entities (result of api.find,...), it converts the list of meta attributed entities to a list of maps where each map is a serialized entity whose keys are using field names from the attribute meta object. I.e. it converts attributeX fields to names defined in the metadata.
      Example:
      
       def objects = ...
       def namedEntities
      
       namedEntities = api.namedEntities(objects)
       
      Parameters:
      objects - List of entities (results of api.find,...).
      Returns:
      List of serialized entities where keys have the names from metadata.
    • emit

      boolean emit(Object obj) throws InterruptedException
      Emits an object to be consumed by an external thread. Requires a blocking emitQueue to be set in the FormulaEngineContext and a consuming thread to take the emitted objects from the queue. See also FeederFormulaExecutor.

      This method is not supported in the Input Generation mode.
      Example:

      
       def obj = ...
       def emit
      
       emit = api.emit(obj)
       
      Parameters:
      obj - Object to be emitted/inserted in the emit queue.
      Returns:
      True if the object is successfully inserted in the queue, false otherwise.
      Throws:
      InterruptedException - If interrupted while waiting.
    • emitDMScopedObject

      boolean emitDMScopedObject(String typedId, DMDataSlice slice) throws InterruptedException
      Emits the partitioned object - to be consumed by a PA allocation task (a PA calculation task with a feeder formula calling this method, and a regular formula accepting each emitted partitioned object as its currentItem context, and distributing one or more partitioned object accruals over the set of PA rows which have contributed to those accruals in some way (by revenue, volume...).
      Example:
      
       def typedId = ...
       def slice = ...
       def emitDMScopedObject
      
       emitDMScopedObject = api.emitDMScopedObject(typedId, slice)
      Parameters:
      typedId - typedId of the PartitionedObject to emit.
      slice - DMDataSlice defines DM slice to which given partitioned object contributes. Make sure it contains valid dateFieldName via DMDataSlice.setDateFieldName(String).
      Returns:
      True if the object is successfully inserted in the queue, false otherwise.
      Throws:
      InterruptedException - can throw InterruptedException
    • emitCompensationRecords

      void emitCompensationRecords(String compensationRecordSetLabel, String dateFieldName, String sortBy, Filter... filters) throws InterruptedException
      Emits the compensation records matching the given search criteria - to be consumed by a PA allocation task (a PA calculation task with a feeder formula calling this method, and a regular formula accepting each emitted CompensationRecord as its currentItem context, and distributing one or more CompensationRecord accruals over the set of PA rows which have contributed to those accruals in some way (by revenue, volume...).
      Example:
      
       def filters = ...
       def emitCompensationRecords
      
       emitCompensationRecords = api.emitCompensationRecords("compensationRecordSetLabel", "sku", "sku", filters)
      Parameters:
      compensationRecordSetLabel - Label of the CompensationRecordSet from which to emit records.
      dateFieldName - Name of the field to be substituted in the CompensationRecord calculationBase (a DMDataSlice object that includes a generic time dimension filter).
      sortBy - CompensationRecord field on which to sort.
      filters - Filters to apply to the CompensationRecord search.
      Throws:
      InterruptedException - if interrupted while waiting
      Since:
      9.0 - Hurricane
    • emitCompensationRecords

      void emitCompensationRecords(String dateFieldName, String sortBy, Filter... filters) throws InterruptedException
      Emits the compensation records matching the given search criteria - to be consumed by a PA allocation task (a PA calculation task with a feeder formula calling this method, and a regular formula accepting each emitted CompensationRecord as its currentItem context, and distributing one or more CompensationRecord accruals over the set of PA rows which have contributed to those accruals in some way (by revenue, volume...).
      Example:
      
       def filters = ...
       def emitCompensationRecords
      
       emitCompensationRecords = api.emitCompensationRecords("sku", "sku", filters)
      Parameters:
      dateFieldName - Name of the field to be substituted in the CompensationRecord calculationBase (a DMDataSlice object that includes a generic time dimension filter).
      sortBy - CompensationRecord field on which to sort.
      filters - Filters to apply to the CompensationRecord search.
      Throws:
      InterruptedException - if interrupted while waiting
      Since:
      9.0 - Hurricane
    • emitRebateRecords

      void emitRebateRecords(String rebateRecordSetLabel, String dateFieldName, String sortBy, Filter... filters) throws InterruptedException
      Emits the rebate records matching the given search criteria - to be consumed by a PA allocation task (a PA calculation task with a feeder formula calling this method, and a regular formula accepting each emitted RebateRecord as its currentItem context, and distributing one or more RebateRecord accruals over the set of PA rows which have contributed to those accruals in some way (by revenue, volume...).
      Example:
      
       def filters = ...
       def emitRebateRecords
      
       emitRebateRecords = api.emitRebateRecords("rebateRecordSetLabel, "sku", "sku", filters)
      Parameters:
      rebateRecordSetLabel - Label of the RebateRecordSet from which to emit records.
      dateFieldName - Name of the field to be substituted in the RebateRecord calculationBase (a DMDataSlice object that includes a generic time dimension filter).
      sortBy - RebateRecord field on which to sort.
      filters - Filters to apply to the RebateRecord search.
      Throws:
      InterruptedException - if interrupted while waiting
    • emitRebateRecords

      void emitRebateRecords(String dateFieldName, String sortBy, Filter... filters) throws InterruptedException
      Emits the rebate records matching the given search criteria - to be consumed by a PA allocation task (a PA calculation task with a feeder formula calling this method, and a regular formula accepting each emitted RebateRecord as its currentItem context, and distributing one or more RebateRecord accruals over the set of PA rows which have contributed to those accruals in some way (by revenue, volume...).

      Note: The method returns records from the default RebateRecordSet only. It does not return records that have been marked as deleted.
      Example:

      
       def filters = ...
       def emitRebateRecords
      
       emitRebateRecords = api.emitRebateRecords("rebateRecordSetLabel, "sku", filters)
      Parameters:
      dateFieldName - Name of the field to be substituted in the RebateRecord calculationBase (a DMDataSlice object that includes a generic time dimension filter).
      sortBy - RebateRecord field on which to sort.
      filters - Filters to apply to the RebateRecord search.
      Throws:
      InterruptedException - if interrupted while waiting
    • emitPersistedObject

      boolean emitPersistedObject(String typedId) throws InterruptedException
      Finds a PersistedObject with the given typedId and emits it if it exists. The assumption is that there is a receiving consumer, as in emitRebateRecords(java.lang.String, java.lang.String, java.lang.String, com.googlecode.genericdao.search.Filter...).
      Example:
      
       def typedId = ...
       def emitPersistedObject
      
       emitPersistedObject = api.emitPersistedObject(typedId)
      Parameters:
      typedId - typedId of the PersistedObject to emit.
      Returns:
      False if failed.
      Throws:
      InterruptedException - If interrupted while waiting.
    • emitPersistedObject

      boolean emitPersistedObject(String typeCode, Long id) throws InterruptedException
      Finds a PersistedObject for the given type and ID and emits it if it exists. The assumption is that there is a receiving consumer, as in emitRebateRecords(java.lang.String, java.lang.String, java.lang.String, com.googlecode.genericdao.search.Filter...).
      Example:
      
       def typedId = ...
       def id = ...
       def emitPersistedObject
      
       emitPersistedObject = api.emitPersistedObject(typedId, id)
      Parameters:
      typeCode - typeCode of the PersistedObject to emit.
      id - ID of the PersistedObject to emit.
      Returns:
      False if failed.
      Throws:
      InterruptedException - If interrupted while waiting.
    • count

      int count(String typeCode, Filter... filters)
      Returns the number of records that a corresponding find(String, int, int, String, List, Filter...) would return.
      Example:
      
       def typeCode = ...
       def filters = ...
       def count
      
       count = api.count(typeCode, filters)
      Parameters:
      typeCode - Type code string of the type of the object to search for. All available type codes can be retrieved by calling <hostname>/pricefx/<partition name>/fetch.
      filters - List of Filter objects that are ANDed together.
      Returns:
      Number of matching records.
    • findLookupTable

      LookupTable findLookupTable(String tableName)
      Finds a Company Parameter / Price Parameter table object (LT):
      • of the given name;
      • which is valid at the current target date;
      • whose Status is Active or Simulation Only (Simulation Only tables will be used only when the logic is run as simulation);
      • if executed during simulation, it must have a matching Simulation Set.

      Note: If there are two Company Parameter / Price Parameter tables with the same name (uniqueName) and status="ACTIVE", then the table with the latest validAfter date is returned.

      Performance consideration: There is no caching of the values, so you should consider caching it yourself.

      Example:

      
       def table = api.findLookupTable("PricelistApprovalLevels")
      
       def row = api.find("MLTV", 0, 1, null,
      
                            Filter.equal("lookupTable.id", table?.id),
      
                            Filter.equal("name", api.product("BusinessUnit"))
                 )?.getAt(0)
       
      Parameters:
      tableName - Name of the Company Parameter / Price Parameter table.
      Returns:
      Company Parameter / Price Parameter table object (as Map) or null if the table does not exists or its validAfter > targetDate.
    • findLookupTableValues

      List<Object> findLookupTableValues(String tableName, Filter... filters)
      Returns a filtered list of rows of a Company Parameter / Price Parameter table values. It will use a Company Parameter / Price Parameter table:
      • of the given name;
      • which is valid at the current target date;
      • whose Status is Active or Simulation Only (Simulation Only tables will be used only when the logic is run as simulation);
      • if executed during simulation, it must have a matching Simulation Set.

      Note: If there are two Company Parameter / Price Parameter tables with the same name (uniqueName) and status="ACTIVE", then Company Parameter / Price Parameter Values for the table with the latest validAfter date at or before the logic execution's Target Date are returned.

      Performance consideration: There is no caching of the values, so you should consider caching it yourself.

      Example:

      
       def salesOrgMap = api.findLookupTableValues("SalesOrg").collectEntries{
                              [(it.name) : it.name]
                         }
      
       return api.option("SalesOrg", salesOrgMap.keySet() as List, salesOrgMap)
       

      Example:

      
       api.retainGlobal = true
      
       // for the first time
       if (api.global.salesOrgs == null) {
           // store all values as a Map [name : value] to global cache
           api.global.salesOrgs = api.findLookupTableValues("SalesOrg").collectEntries {
                                                 [(it.name): it.value]
                                  }
       }
      
       return api.global.salesOrgs
       
      Parameters:
      tableName - Name of the Company Parameter / Price Parameter table.
      filters - Optional extra Filter.
      Returns:
      Company Parameter / Price Parameter Values table or null.
      See Also:
    • findLookupTableValues

      List<Object> findLookupTableValues(String tableName, String sortBy, Filter... filters)
      Returns sorted rows of a Company Parameter / Price Parameter table (optionally filtered). It will use a Company Parameter / Price Parameter table:
      • of the given name;
      • which is valid at the current target date;
      • whose Status is Active or Simulation Only (Simulation Only tables will be used only when the logic is run as simulation);
      • if executed during simulation, it must have a matching Simulation Set.

      Note: If there are two Company Parameter / Price Parameter tables with the same name (uniqueName) and status="ACTIVE", then Company Parameter / Price Parameter Values for the table with the latest validAfter date at or before the logic execution's Target Date are returned.

      Performance consideration: There is no caching of the values, so you should consider caching it yourself.

      Example:

      
       api.retainGlobal = true
      
       // for the first time
       if (api.global.salesOrgs == null) {
           // store all values as a Map [name : value] to global cache
           api.global.salesOrgs = api.findLookupTableValues("SalesOrg", "-name").collectEntries {
               [(it.name): it.value]
           }
       }
      
       return api.global.salesOrgs
       
      Parameters:
      tableName - Name of the Company Parameter / Price Parameter table.
      sortBy - Name of column to be used for sorting of the rows. If the char "-" precedes the name, it will do a reverse order (for example "-key1"). Use null if no sorting is required.
      filters - Optional extra Filter.
      Returns:
      Company Parameter / Price Parameter Values table or null.
      See Also:
    • findLookupTableValues

      List<Object> findLookupTableValues(String tableName, List<String> fields, String sortBy, Filter... filters)
      Returns sorted rows of a Company Parameter / Price Parameter table (optionally filtered). It will use a Company Parameter / Price Parameter table:
      • of the given name;
      • which is valid at the current target date;
      • whose Status is Active or Simulation Only (Simulation Only tables will be used only when the logic is run as simulation);
      • if executed during simulation, it must have a matching Simulation Set.

      Note: If there are two Company Parameter / Price Parameter tables with the same name (uniqueName) and status="ACTIVE", then Company Parameter / Price Parameter Values for the table with the latest validAfter date at or before the logic execution's Target Date are returned.

      Performance consideration: There is no caching of the values, so you should consider caching it yourself. It optionally also takes a cacheProvider argument (can be null; disabling that function). This provider is essentially a map (e.g. a api.global or api.local entry) provided by the logic - which is managing the scope or also can prefill that cache. Missing entries are added to that cache by the method. The purpose of it is to save repeating tableName => actual table mappings. The format of the cache is "tableName" => Cache Entry, which is again a map with keys "id" (=table ID) and "valueType" (=type code of table entries)

      Example:

      
       api.retainGlobal = true
      
       // for the first time
       if(api.global.ltCache == null) {
         api.global.put("ltCache", [:])
       }
      
       return api.findLookupTableValues("Rebate", api.global.ltCache, null, null)
      
       
      Parameters:
      tableName - tableName Name of the Company Parameter / Price Parameter table.
      fields - List of fields to retrieve. Can be null
      sortBy - Name of column to be used for sorting of the rows. If the char "-" precedes the name, it will do a reverse order (for example "-key1"). Use null if no sorting is required.
      filters - Optional extra Filter.
      Returns:
      Company Parameter / Price Parameter Values table or null.
    • findLookupTableValues

      List<Object> findLookupTableValues(String tableName, Map<String,Object> cacheProvider, List<String> fields, String sortBy, Filter... filters)
      Returns sorted rows of a Company Parameter / Price Parameter table (optionally filtered). It will use a Company Parameter / Price Parameter table:
      • of the given name;
      • which is valid at the current target date;
      • whose Status is Active or Simulation Only (Simulation Only tables will be used only when the logic is run as simulation);
      • if executed during simulation, it must have a matching Simulation Set.

      Note: If there are two Company Parameter / Price Parameter tables with the same name (uniqueName) and status="ACTIVE", then Company Parameter / Price Parameter Values for the table with the latest validAfter date at or before the logic execution's Target Date are returned.

      Performance consideration: There is no caching of the values, so you should consider caching it yourself. It optionally also takes a cacheProvider argument (can be null; disabling that function). This provider is essentially a map (e.g. a api.global or api.local entry) provided by the logic - which is managing the scope or also can prefill that cache. Missing entries are added to that cache by the method. The purpose of it is to save repeating tableName => actual table mappings. The format of the cache is "tableName" => Cache Entry, which is again a map with keys "id" (=table ID) and "valueType" (=type code of table entries)

      Example:

      
       api.retainGlobal = true
      
       // for the first time
       if(api.global.ltCache == null) {
         api.global.put("ltCache", [:])
       }
      
       return api.findLookupTableValues("Rebate", api.global.ltCache, null, null)
      
       
      Parameters:
      tableName - tableName Name of the Company Parameter / Price Parameter table.
      cacheProvider - A map object that serves as the cache. Can be null (=no cache used), empty or prefilled
      fields - List of fields to retrieve. Can be null
      sortBy - Name of column to be used for sorting of the rows. If the char "-" precedes the name, it will do a reverse order (for example "-key1"). Use null if no sorting is required.
      filters - Optional extra Filter.
      Returns:
      Company Parameter / Price Parameter Values table or null.
    • findWorkflowInfo

      WorkflowInfo findWorkflowInfo(String approvableTypeCode, Object approvableId)
      Finds active workflows for the given approvable. You can get the same information as displayed in the workflow UI.

      Example:

      
       def quoteUniqueName = "P-123"
       def quote = api.find('Q', 0, 1, Filter.equal("uniqueName", quoteUniqueName)).getAt(0)
       return quote ? api.findWorkflowInfo('Q', quote.id) : null
       
      Parameters:
      approvableTypeCode - Type code of approvable. Approvables are e.g. quotes, rebate agreements, data change requests etc.
      approvableId - ID of the approvable.
      Returns:
      Table like structure resembling workflow UI or null if not found.
      See Also:
    • findPreviousApprovableState

      Map<String,Object> findPreviousApprovableState(String typedId, String... workflowStatuses)
      Finds the previous approvable entity state if some DENIED or WITHDRAWN workflow for the approvable exists.
      Example:
      
       def typedId = ...
       def workflowStatuses = ...
       def findPreviousApprovableState
      
       findPreviousApprovableState = api.findPreviousApprovableState(typedId, workflowStatuses)
       
      Parameters:
      typedId - Approvable entity typed ID.
      workflowStatuses - Only DENIED or WITHDRAWN are supported.
      Returns:
      State of the approvable entity when its previous workflow was DENIED or WITHDRAWN.
      See Also:
    • findPreviousWorkflowInfo

      WorkflowInfo findPreviousWorkflowInfo(String typedId, String... workflowStatuses)
      Finds the approvable entity's previous workflow history if some DENIED or WITHDRAWN workflow for the approvable exists.
      Example:
      
       def typedId = ...
       def workflowStatuses = ...
       def findPreviousWorkflowInfo
      
       findPreviousWorkflowInfo = api.findPreviousWorkflowInfo(typedId, workflowStatuses)
       
      Parameters:
      typedId - Approvable entity typed ID.
      workflowStatuses - Only DENIED or WITHDRAWN are supported.
      Returns:
      Workflow history, see net.pricefx.workflowengine.WorkflowInfo.
      See Also:
    • findCustomerAssignments

      List<CustomerAssignment> findCustomerAssignments(String customerId)
      Finds all assignment records for the given customerId. Also matched by CustomerGroup definitions. Example:
      
       def customerId = ...
       def findCustomerAssignments
      
       findCustomerAssignments = api.findCustomerAssignments(customerId)
       
      Parameters:
      customerId - Customer whose assignments are searched for.
      Returns:
      List of assignment records.
    • findPricelists

      List<Pricelist> findPricelists(Date targetDate, String listName)
      Returns a list of price lists that match the targetDate (i.e. list's targetDate <= targetDate and expiryDate > targetDate). Example:
      
       def targetDate = ...
       def listName = ...
       def findPricelists
      
       findPricelists = api.findPricelists(targetDate, listName)
       
      Parameters:
      targetDate - targetDate to use.
      listName - Price list name. If null, the list name is not included in search.
      Returns:
      List of matching price lists.
    • findSimulations

      List<Simulation> findSimulations(Date targetDate, String simulationName)
      Returns a list of simulations that match the targetDate (i.e. list's targetDate <= targetDate). Example:
      
       def targetDate = ...
       def simulationName = ...
       def findSimulations
      
       findSimulations = api.findSimulations(targetDate, simulationName)
       
      Parameters:
      targetDate - targetDate to use.
      simulationName - Simulation name. If null, the simulation name is not included in search.
      Returns:
      List of matching simulations.
    • findPriceGrids

      List<PriceGrid> findPriceGrids(Date targetDate, String priceGridName)
      Returns a list of price grids that match the targetDate (i.e. price grid's targetDate <= targetDate). Example:
      
       def targetDate = ...
       def priceGridName = ...
       def findPriceGrids
      
       findPriceGrids = api.findPriceGrids(targetDate, priceGridName)
       
      Parameters:
      targetDate - targetDate to use.
      priceGridName - Price grid name. If null, the price grid name is not included in search.
      Returns:
      List of matching price grids.
    • findCalculatedFieldSets

      List<CalculatedFieldSet> findCalculatedFieldSets(Date targetDate, String cfsName)
      Returns a list of calculated field sets that match the targetDate. Example:
      
       def targetDate = ...
       def cfsName = ...
       def findCalculatedFieldSets
      
       findCalculatedFieldSets = api.findCalculatedFieldSets(targetDate, cfsName)
       
      Parameters:
      targetDate - Target date for the CFS.
      cfsName - CFS name. If null, the CFS name is not included in search.
      Returns:
      List of matching calculated field sets.
    • findManualPricelists

      List<ManualPricelist> findManualPricelists(Date targetDate, String listName)
      Returns a list of manual price lists that match the targetDate (i.e. list's validAfter <= targetDate and expiryDate > targetDate). Example:
      
       def targetDate = ...
       def listName = ...
       def findManualPricelists
      
       findManualPricelists = api.findManualPricelists(targetDate, listName)
       
      Parameters:
      targetDate - targetDate to use.
      listName - Price list name. If null, the list name is not included in search.
      Returns:
      List of matching price lists.
    • findApprovedPricelistItems

      List<SummaryCalculableObjectItem> findApprovedPricelistItems(String sku)
      Returns a list of summary items. One item is returned for every matching (= same SKU) PLI or XPLI which is in an approved list. Example:
      
       def sku = ...
       def findApprovedPricelistItems
      
       findApprovedPricelistItems = api.findApprovedPricelistItems(sku)
       
      Parameters:
      sku - SKU to filter on.
      Returns:
      List of summary items.
    • findCustomersInGroup

      List<Customer> findCustomersInGroup(CustomerGroup group)
      Retrieves a list of customers which match the given CustomerGroup (the first 200 entries are returned). Example:
      
       def group = ...
       def findCustomersInGroup
      
       findCustomersInGroup = api.findCustomersInGroup(group)
       
      Parameters:
      group - Group to match.
      Returns:
      List of customers.
    • findCustomersInGroup

      List<Customer> findCustomersInGroup(CustomerGroup group, int startRow, String sortBy)
      Retrieves a list of customers which match the given CustomerGroup with custom paging and sorting. Example:
      
       def group = ...
       def startRow = ...
       def sortBy = ...
       def findCustomersInGroup
      
       findCustomersInGroup = api.findCustomersInGroup(group, startRow, sortBy)
       
      Parameters:
      group - Customer group.
      startRow - Starting row number (maximum 200 rows returned at once).
      sortBy - Sort key. null if no sorting is required.
      Returns:
      List of customers.
    • findSellersInGroup

      List<Seller> findSellersInGroup(SellerGroup group)
      Retrieves a list of sellers that match the given SellerGroup (the first 200 entries are returned). Example:
      
       def group = ...
       def findSellersInGroup
      
       findSellersInGroup = api.findSellersInGroup(group)
       
      Parameters:
      group - Group to match.
      Returns:
      The list of sellers.
      Since:
      9.0 - Hurricane
    • findSellersInGroup

      List<Seller> findSellersInGroup(SellerGroup group, int startRow, String sortBy)
      Retrieves a list of sellers that match the given SellerGroup with custom paging and sorting. Example:
      
       def group = ...
       def startRow = ...
       def sortBy = ...
       def findSellersInGroup
      
       findSellersInGroup = api.findSellersInGroup(group, startRow, sortBy)
       
      Parameters:
      group - Seller group.
      startRow - Starting row number (maximum 200 rows returned at once).
      sortBy - Sort key. null if no sorting is required.
      Returns:
      The list of sellers.
      Since:
      9.0 - Hurricane
    • getManualOverride

      Object getManualOverride(String elementName)
      Returns a user entered value that overrides the calculated result of a logic element.

      Note: The manualOverride works as a flag - when it is set for an element, the final value of that element is taken from the manually entered value and the calculation of that element does not run at all. If this flag is not set, the final value is the calculated result. Example:

      
       def group = elementName
       def getManualOverride
      
       getManualOverride = api.getManualOverride(elementName)
       
      Parameters:
      elementName - Formula/result element that is overridden.
      Returns:
      Overridden value or null if not overridden.
    • removeManualOverride

      void removeManualOverride(String elementName)
      Removes a user entered value that overrides the calculated result of a logic element.

      If you have a condition to remove the manual override, it is recommended to put this condition in a separate logic element which is always executed (not in the same one which has the manual override allowed; the reason is that once the user enters a value manually, the element calculation does not run at all, so the condition would not be evaluated).

      Note also that a logic element with api.removeManualOverride() must be before an element which is cleared. Example:

      
       def group = elementName
       def removeManualOverride
      
       removeManualOverride = api.removeManualOverride(elementName)
       
      Parameters:
      elementName - Formula/result element that is overridden.
    • abortCalculation

      void abortCalculation()
      Aborts the current item (e.g. price list line, quote line) calculation - i.e. stops the execution of subsequent elements of the logic. The subsequent logic elements are not executed and the calculation engine continues with calculation of the next item.

      Note: This function only sets the abortCalculation flag, so the element where api.abortCalculation() is called finishes its execution and still returns a value (but it is the last element returning a value).

      This function is often called together with isInputGenerationExecution() after the parameters are gathered.

      Example:

      
       if (api.isInputGenerationExecution()) {
         api.abortCalculation()
       }
       

      Example:

      
       def price = ...
      
       if (!price) {
         api.abortCalculation()
       }
      
       return price  //this line will still be executed during the Input Generation, the logic will be aborted only after this element finishes
       
    • abortCalculation

      void abortCalculation(boolean keepOld)
      Aborts the current item calculation. The subsequent logic elements are not executed and the calculation engine continues with calculation of the next item. This function only sets the abortCalculation flag, so the element where abortCalculation is called still returns a value (and is the last element returning a value). This function can be called together with isInputGenerationExecution() after the parameters are gathered.

      Example:

      
       if (api.isInputGenerationExecution()) {
         api.abortCalculation(true)
       }
       

      Parameters:
      keepOld - Determines if the old outputs should be retained. Only applicable for price grids, quotes, contracts and deal plans calculation.
    • abortSyntaxCheck

      void abortSyntaxCheck()
      Aborts the current item parameter determination. This helps in a logic with many elements to tell the engine not to spend more time on the next elements when the logic author is sure that there is no other statement that would generate any new inputs.

      Example:

      
       return api.abortSyntaxCheck()
       
      This function can be called together with isInputGenerationExecution() after the parameters are gathered.
    • throwException

      void throwException(String errorMessage) throws XExpression
      Throws a calculation exception with the specified message and aborts the calculation logic execution immediately.

      Sample use cases:

      • In workflow logics - When the workflow logic cannot find important/vital data needed for building the approval steps, it can throw an exception which immediately stops the submission process and the Quote will stay in the Draft state.
      • In Quote logics - To stop processing the Quote line calculation when the important inputs (or values) are not available. If the calculation was called as part of the submission process, the process stops and the Quote stays in the Draft state.

      Only the following HTML tags are supported within the message:

      
       <br>
       <li>
       <b>
       <em>
       <i>
       <strong>
       
      Unsupported HTML tags are ignored and not visible in the displayed message.
      Example:
      
       return api.throwException("404 Error")
       
      Parameters:
      errorMessage - Error message that is displayed.
      Throws:
      XExpression - Custom calculation exception.
    • markItemDirty

      void markItemDirty()
      Sets the dirty flag on the specified item, i.e. the second calculation run will be triggered and this item will be included in the 2nd pass. The maximum number of dirty passes is defined by the server configuration constant maxDirtyCalculations defined for the whole instance. The default is one dirty pass.

      Note: In distributed mode, only the current item can be marked as dirty. Marking other items as dirty is not supported in distributed mode.
      See also getIterationNumber(), markItemClean().
      Example:

      
       return api.markItemDirty()
       
      See Also:
    • markItemDirty

      void markItemDirty(String key1)
      Sets the dirty flag on the specified item, i.e. the second calculation run will be triggered and this item will be included in the 2nd pass. If used in a MatrixPricelist/MatrixSimulation (i.e. on objects that have a secondary key), all items with that SKU are marked as dirty.

      See also getIterationNumber(), markItemClean().

      The maximum number of dirty passes is defined by the server configuration constant maxDirtyCalculations defined for the whole instance. The default is one dirty pass.
      Example:

      
       return api.markItemDirty("key1")
       

      Note: In distributed mode, only the current item can be marked as dirty. Marking other items as dirty is not supported in distributed mode.

      Parameters:
      key1 - Item to have the dirty flag set. For price objects it can be SKU, or generally key1.
      See Also:
    • markItemDirty

      void markItemDirty(String key1, String key2)
      Sets the dirty flag on the specified item, i.e. the second calculation run will be triggered and this item will be included in the 2nd pass. The maximum number of dirty passes is defined by the server configuration constant maxDirtyCalculations defined for the whole instance. The default is one dirty pass.

      Note: In distributed mode, only the current item can be marked as dirty. Marking other items as dirty is not supported in distributed mode.
      See also getIterationNumber(), markItemClean().
      Example:

      
       return api.markItemDirty("key1", "key2")
       
      Parameters:
      key1 - Item to have the dirty flag set. For price objects it can be SKU, or generally key1.
      key2 - key2 field.
      See Also:
    • markItemDirty

      void markItemDirty(String key1, String key2, String key3)
      Sets the dirty flag on the specified item, i.e. the second calculation run will be triggered and this item will be included in the 2nd pass. The maximum number of dirty passes is defined by the server configuration constant maxDirtyCalculations defined for the whole instance. The default is one dirty pass.

      Note:In distributed mode, only the current item can be marked as dirty. Marking other items as dirty is not supported in distributed mode.
      See also getIterationNumber(), markItemClean().
      Example:

      
       return api.markItemDirty("key1", "key2", "key3")
       
      Parameters:
      key1 - key1 field.
      key2 - key2 field.
      key3 - key3 field.
      See Also:
    • markItemDirty

      void markItemDirty(String key1, String key2, String key3, String key4)
      Sets the dirty flag on the specified item, i.e. the second calculation run will be triggered and this item will be included in the 2nd pass. The maximum number of dirty passes is defined by the server configuration constant maxDirtyCalculations defined for the whole instance. The default is one dirty pass.

      Note: In distributed mode, only the current item can be marked as dirty. Marking other items as dirty is not supported in distributed mode.
      See also getIterationNumber(), markItemClean().
      Example:

      
       return api.markItemDirty("key1", "key2", "key3", "key4")
       
      Parameters:
      key1 - key1 field.
      key2 - key2 field.
      key3 - key3 field.
      key4 - key4 field.
      See Also:
    • markItemDirty

      void markItemDirty(String key1, String key2, String key3, String key4, String key5)
      Sets the dirty flag on the specified item, i.e. the second calculation run will be triggered and this item will be included in the 2nd pass. The maximum number of dirty passes is defined by the server configuration constant maxDirtyCalculations defined for the whole instance. The default is one dirty pass.

      Note: In distributed mode, only the current item can be marked as dirty. Marking other items as dirty is not supported in distributed mode.
      See also getIterationNumber(), markItemClean().
      Example:

      
       return api.markItemDirty("key1", "key2", "key3", "key4", "key5")
       
      Parameters:
      key1 - key1 field.
      key2 - key2 field.
      key3 - key3 field.
      key4 - key4 field.
      key5 - key5 field.
      See Also:
    • markItemDirty

      void markItemDirty(String key1, String key2, String key3, String key4, String key5, String key6)
      Sets the dirty flag on the specified item, i.e. the second calculation run will be triggered and this item will be included in the 2nd pass. The maximum number of dirty passes is defined by the server configuration constant maxDirtyCalculations defined for the whole instance. The default is one dirty pass.

      Note: In distributed mode, only the current item can be marked as dirty. Marking other items as dirty is not supported in distributed mode.
      See also getIterationNumber(), markItemClean().
      Example:

      
       return api.markItemDirty("key1", "key2", "key3", "key4", "key5", "key6")
       
      Parameters:
      key1 - key1 field.
      key2 - key2 field.
      key3 - key3 field.
      key4 - key4 field.
      key5 - key5 field.
      key6 - key6 field.
      See Also:
    • markItemClean

      void markItemClean()
      Removes the dirty flag from the current item set previously by markItemDirty().
      Example:
      
       return api.markItemClean()
       
      See Also:
    • markItemClean

      void markItemClean(String key1)
      Removes the dirty flag from the specified item set previously by markItemDirty(String).
      Example:
      
       return api.markItemClean("key1")
       
      Parameters:
      key1 - Item from which to remove the dirty flag. For price objects it can be SKU, or generally key1.
      See Also:
    • markItemClean

      void markItemClean(String key1, String key2)
      Removes the dirty flag from the specified item set previously by markItemDirty(String, String).
      Example:
      
       return api.markItemClean("key1", "key2")
       
      Parameters:
      key1 - Item from which to remove the dirty flag. For price objects it can be SKU, or generally key1.
      key2 - key2 field.
      See Also:
    • markItemClean

      void markItemClean(String key1, String key2, String key3)
      Removes the dirty flag from the specified item set previously by markItemDirty(String, String, String).
      Example:
      
       return api.markItemClean("key1", "key2", "key3")
       
      Parameters:
      key1 - key1 field.
      key2 - key2 field.
      key3 - key3 field.
      See Also:
    • markItemClean

      void markItemClean(String key1, String key2, String key3, String key4)
      Removes the dirty flag from the specified item set previously by markItemDirty(String, String, String, String).
      Example:
      
       return api.markItemClean("key1", "key2", "key3", "key4")
       
      Parameters:
      key1 - key1 field.
      key2 - key2 field.
      key3 - key3 field.
      key4 - key4 field.
      See Also:
    • markItemClean

      void markItemClean(String key1, String key2, String key3, String key4, String key5)
      Removes the dirty flag from the specified item set previously by markItemDirty(String, String, String, String, String).
      Example:
      
       return api.markItemClean("key1", "key2", "key3", "key4", "key5")
       
      Parameters:
      key1 - key1 field.
      key2 - key2 field.
      key3 - key3 field.
      key4 - key4 field.
      key5 - key5 field.
      See Also:
    • markItemClean

      void markItemClean(String key1, String key2, String key3, String key4, String key5, String key6)
      Removes the dirty flag from the specified item set previously by markItemDirty(String, String, String, String, String, String).
      Example:
      
       return api.markItemClean("key1", "key2", "key3", "key4", "key5", "key6")
       
      Parameters:
      key1 - key1 field.
      key2 - key2 field.
      key3 - key3 field.
      key4 - key4 field.
      key5 - key5 field.
      key6 - key6 field.
      See Also:
    • isSecondPass

      boolean isSecondPass()
      Deprecated.
      Use getIterationNumber() > 0 instead.
      Determines if the calculation is a dirty pass. It does not necessarily mean it is a 2nd pass calculation.
      Example:
      
       return api.isSecondPass()
       
      Returns:
      True if is in a dirty pass.
    • getIterationNumber

      int getIterationNumber()
      Returns the number of iterations in which this list has been calculated during this cycle.
      • 0 means: initial calculation (non-dirty)
      • 1 means: 1st dirty pass, markItemDirty() was called in the previous pass
      • 2 means: 2nd dirty pass, markItemDirty() was called in the previous pass
      • ...and so on.
      The maximum number of dirty passes is defined by the server configuration constant maxDirtyCalculations defined for the whole instance. The default is one dirty pass.
      Example:
      
       return api.getIterationNumber()
       
      Returns:
      Iteration number
    • formatString

      String formatString(String locale, String format, Object... args)
      Formats a string like String.format(java.lang.String, java.lang.Object...).
      Example:
      
       return api.formatString("de", "MM-dd-yyyy" "args")
       
      Parameters:
      locale - Locale (as a String). Use only simple locale names like "de" or "fr"
      format - Format string.
      args - Arguments to pass on.
      Returns:
      Formatted string
    • formatNumber

      String formatNumber(String pattern, Object n)
      Formats a number as a String. The same semantics as in NumberFormat and DecimalFormat.applyPattern(String) apply.
      Example:
      
       def n = ...
       return api.formatString("MM-dd-yyyy", n)
       
      Parameters:
      pattern - Pattern string.
      n - Number to format.
      Returns:
      Formatted number as a String.
    • formatNumber

      String formatNumber(String locale, String pattern, Object n)
      Formats a number as a String. The same semantics as in NumberFormat and DecimalFormat.applyPattern(String) apply.
      Example:
      
       def n = ...
       return api.formatNumber("de", "MM-dd-yyyy", n)
       
      Parameters:
      locale - Locale to use for formatting. Use only simple locale names like "de" or "fr"
      pattern - Pattern string.
      n - Number to format.
      Returns:
      Formatted number as a String.
    • formatCurrency

      String formatCurrency(String pattern, Object number)
      Formats a number with the currency symbol as a String. The same semantics as in NumberFormat and DecimalFormat.applyPattern(String) apply.

      Examples:

      
           api.formatCurrency("###,###.0000", 10000.12) = "10,000.1200 ₩" // if Locale.getDefault() == "ko_KR"
           api.formatCurrency("###,###", 8000.12) = "8,000 $" // if Locale.getDefault() == "en_CA"
           api.formatCurrency("###,###.00", 900) = "900.00 ¥" // if Locale.getDefault() == "zh_CN"
       
      Parameters:
      pattern - Pattern string, ex. "###,###0.0"
      number - Value to be formatted, ex. 1000,12
      Returns:
      Formatted number with the currency symbol as a String, ex 1,000.1 € (if the default system Locale is, ex. Locale.getDefault() => "fr_FR")
      See Also:
    • formatCurrency

      String formatCurrency(String locale, String pattern, Object number)
      Formats a number with the currency symbol as a String. The same semantics as in NumberFormat and DecimalFormat.applyPattern(String) apply.

      Example:

      
           String locale = "cs_CZ";
           String pattern = "###,###.00";
           def number = 1234.1
      
           api.formatCurrency(locale, pattern, number) = "1,234.10 Kč"
       
      Parameters:
      locale - Locale string to be used for the formatting and currency symbol. Use language (for formatting) and country (for currency symbol) collection such as: "en_US"
      pattern - Pattern string. Can be provided in the customized format (ex. "###,###.##") or empty/null
      number - Value to be formatted as a String or Number, ex. "1234.7"
      Returns:
      Formatted number with the currency symbol as a String, ex. 1,234.70 $
      See Also:
    • jsonDecode

      Object jsonDecode(String json)
      A utility method to decode a JSON string into a Map representation.
      Example:
      
       def json = ...
       return api.jsonDecode(json)
       
      Parameters:
      json - Input JSON string.
      Returns:
      Parsed JSON as a Map.
    • jsonDecodeList

      Object jsonDecodeList(String json)
      A utility method to decode a JSON string into a List representation.
      Example:
      
       def json = ...
       return api.jsonDecodeList(json)
       
      Parameters:
      json - Input JSON string.
      Returns:
      Parsed JSON as a List.
    • jsonEncode

      Object jsonEncode(Object input)
      A utility method to encode an object to a JSON string. Omits all null values in the output.
      Example:
      
       def input = ...
       return api.jsonEncode(input)
       
      Parameters:
      input - Input object, usually a map.
      Returns:
      Encoded object
    • jsonEncode

      Object jsonEncode(Object input, boolean omitNull)
      A utility method to encode an object to a JSON string.
      Example:
      
       def input = ...
       return api.jsonEncode(input, true)
       
      Parameters:
      input - Input object, usually a map.
      omitNull - Determines if null values should be omitted.
      Returns:
      Encoded object
    • criticalAlert

      void criticalAlert(String msg)
      Marks the current logic element as a critical alert and provides the given message.
      • In a price grid, price list, or in a quote line item, it marks the whole record with a dark red background color.
      • In the calculation results (e.g. in Quote line results), it displays a red circle with an exclamation mark next to the element.

      To display the error message for price grids and price lists, click the arrow in the Detail column.

      It is displayed only if called from an element that has its 'Display mode' enabled for the given context ('PriceGrids', 'Pricelists' or 'Quote Configurator').

      Note: If used for the CalculableLineItem entity (Quote, Rebate Agreement, or Contract), then it blocks the submission of that entity.

      Only the following HTML tags are supported within the message:

      
       <br>
       <li>
       <b>
       <em>
       <i>
       <strong>
       
      Unsupported HTML tags are ignored and not visible in the displayed message.
      Example:
      
       return api.criticalAlert("404 Error")
       
      Parameters:
      msg - Alert message.
      See Also:
    • redAlert

      void redAlert(String msg)
      Marks the current logic element with a red alert and provides the given message.
      • In a price grid, price list or in a quote line item, it marks the corresponding field background with a red background color.
      • In the calculation results (e.g. in Quote line results), it displays a plain red circle next to the element.

      To display the error message for price grids and price lists, click the arrow in the Detail column.

      It is displayed only if called from an element that has its 'Display mode' enabled for the given context ('PriceGrids', 'Pricelists' or 'Quote Configurator').

      Only the following HTML tags are supported within the message:

      
       <br>
       <li>
       <b>
       <em>
       <i>
       <strong>
       
      Unsupported HTML tags are ignored and not visible in the displayed message.
      Example:
      
       return api.redAlert("404 Error")
       
      Parameters:
      msg - Alert message.
      See Also:
    • yellowAlert

      void yellowAlert(String msg)
      Marks the current logic element with a yellow alert and provides the given message.
      • In a price grid, price list or in a quote line item, it marks the corresponding field background with a yellow background color.
      • In the calculation results (e.g. in Quote line results), it displays a plain yellow circle next to the element.

      To display the error message for price grids and price lists, click the arrow in the Detail column.

      The Alert is displayed only if called from an element that has its 'Display mode' enabled for the given context ('PriceGrids', 'Pricelists' or 'Quote Configurator').

      Only the following HTML tags are supported within the message:

      
       <br>
       <li>
       <b>
       <em>
       <i>
       <strong>
       
      Unsupported HTML tags are ignored and not visible in the displayed message.
      Example:
      
       return api.yellowAlert("404 Error")
       
      Parameters:
      msg - Alert message.
      See Also:
    • setAlertMessage

      void setAlertMessage(String msg)
      Marks the current formula element with the given alert message. If one was already set by means of a yellowAlert, redAlert or criticalAlert call, then that message is replaced. When not raising an alert through any of these calls, but still setting a message with this method, the message will be displayed wherever the calculation results are shown with alert messages, but without any yellow or red background.
      Example:
      
       return api.setAlertMessage("404 Error")
       
      Parameters:
      msg - Alert message.
    • newChartBuilder

      ChartBuilder newChartBuilder()
      The ChartBuilder API allows you to create PA DataAnalyzer chart definitions to be displayed in Dashboard portlets, quote headers and more UI areas. To familiarize with all the options, you can build a Data Analyzer chart in the UI and generate the ChartBuilder Groovy code via the /View Expression/ function (see View Chart Definition).

      Example:

      
               api.newChartBuilder().newBarLine()
                       .addSeries()
                           .setTitle("Revenue by Country")
                           .setDatamart("datamart_transaction")
                           .setCurrency("USD")
                           .setAxisX("Country")
                           .setAxisY("InvoicePrice")
                               .withTotal()
                               .back()
                           .back()
                       .build();
       
      Returns:
      the ChartBuilderResult object that the UI knows how to render
    • buildFlexChart

      ResultFlexChart buildFlexChart(Object definition)
      Deprecated.
      Parameters:
      definition - the definition of the FlexChart.
      Returns:
      ResultFlexChart object.
      See Also:
    • buildFlexChart

      ResultFlexChart buildFlexChart(String baseTemplateToUse, Object definition)
      Deprecated.
      Creates a FlexChart from the passed definition by merging it with options defined within the baseTemplateToUse template.

      Although it may change in future releases, for now, a FlexChart is nothing else than a Highcharts chart. Therefore, the passed definition (also applies to the baseTemplateToUse template) must denote Highcharts options - please consult Highcharts documentation for more details, and note that FlexCharts must comply to the outdated Highcharts release 4.

      Since Highcharts options are normally specified by a JavaScript object literal, the passed definition must be either a JSON string representing such object literal, or any object which can be mapped to such JSON representation. Therefore, typically the definiton will be passed as a map of maps.

      Example:

      
       def definition = [
         chart: [
           type: "bar"
         ],
         title: [
           text: "A common FlexChart"
         ],
         series: [
          [
            data: [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]
          ]
         ]
       ]
      
       api.buildFlexChart(definition)
       
      Note that not all Highcharts options are supported. Moreover, usage of some options is prohibited deliberately. These are currently global, events and every JavaScript function-based options.

      Note: FlexChart templates are defined by an administrator in the 'Configuration' section.

      Parameters:
      baseTemplateToUse - Name of the template to use as a basis for merging with the passed definition; if null, the predefined Default template is used.
      definition - Definition of the FlexChart; currently, this will typically be a string or map of maps containing Highcharts options.
      Returns:
      Helper object linking the resulting FlexChart, baseTemplateToUse and type of the result - which will always be 'FLEXCHART' here.
      See Also:
    • buildHighchart

      ResultHighchart buildHighchart(Map<String,?> definition)
      Creates a ResultHighchart from the passed definition.
      As opposed to FlexChart, the definition is passed straight to the Highcharts library, currently release 11.4.8. There is no validation, no templates merging, and JavaScript functions are not supported.
      Example:
      
       def definition = ...
      
       return api.buildHighchart(definition)
       
      Parameters:
      definition - Definition of the Highchart as a map of maps and arrays.
      Returns:
      ResultHighchart object
      See Also:
    • buildHighmap

      ResultHighmap buildHighmap(Map<String,?> definition)
      Creates a ResultHighmap from the passed definition.
      As opposed to FlexChart, the definition is passed straight to the Highmaps library, currently release 11.4.8. There is no validation, no templates merging, and JavaScript functions are not supported. HighChart provide better performance than FlexChart.
      Example:
      
       def definition = ...
      
       return api.buildHighmap(definition)
       
      Parameters:
      definition - Definition of the Highmap as a map of maps and arrays.
      Returns:
      buildHighmap object
      See Also:
    • newAdaptiveHistogram

      AdaptiveHistogram newAdaptiveHistogram()
      Creates a histogram that adapts to an unknown data distribution. It keeps a more or less constant resolution throughout the data range by increasing the resolution where the data is more dense. For example, if the data has such a distribution that most of the values lie in the 0-5 range and only a few are in the 5-10 range, the histogram would adapt and assign more counting buckets to the 0-5 range and less to the 5-10 range.

      The histogram provides a method to obtain the accumulative density function for a given data point (getValueForPercentile), and a method to obtain the data point that splits the data set at a given percentile (getValueForPercentile).
      Example:

      
       return api.newAdaptiveHistogram()
       
      Returns:
      New AdaptiveHistogram object
    • newSystemPortlet

      SystemPortlet newSystemPortlet(String type)
      Creates a representation of a System portlet, like the Quotes list, To Do list, Quick Product Search, etc. that are typically display on the application's home screen.
      Rendering these portlets is currently supported only in Dashboards. For a full list of the available portlets, see SystemPortlet.
      Note: This is available in Unity UI only. No backporting planned for the Classic UI.
      Example:
      
       def type = ...
       return api.newSystemPortlet(type)
       
      Parameters:
      type - the desired portlet type (constants for available types are defined in SystemPortlet)
      Returns:
      New SystemPortlet object
      Since:
      7.0
    • getPricelistSummaryQuery

      ItemSummaryQuery<Pricelist> getPricelistSummaryQuery()
      Creates a summary query object that can be parameterized and is then subsequently used in runSummaryQuery(ItemSummaryQuery). This query runs against price lists.
      Example:
      
       return api.getPricelistSummaryQuery()
       
      Returns:
      Query definition object
    • getSimulationSummaryQuery

      ItemSummaryQuery<Simulation> getSimulationSummaryQuery()
      Creates a summary query object that can be parameterized and is then subsequently used in runSummaryQuery(ItemSummaryQuery). This query runs against simulations.
      Example:
      
       return api.getSimulationSummaryQuery()
       
      Returns:
      Query definition object
    • getPriceGridSummaryQuery

      ItemSummaryQuery<PriceGrid> getPriceGridSummaryQuery()
      Creates a summary query object that can be parameterized and is then subsequently used in runSummaryQuery(ItemSummaryQuery). This query runs against price grids.
      Example:
      
       return api.getPriceGridSummaryQuery()
       
      Returns:
      Query definition object
    • getRebateRecordSummaryQuery

      ItemSummaryQuery<RebateRecordSet> getRebateRecordSummaryQuery()
      Creates a summary query object that can be parameterized and is then subsequently used in runSummaryQuery(ItemSummaryQuery). This query runs against rebate records.
      Example:
      
       return api.getRebateRecordSummaryQuery()
       
      Returns:
      Query definition object
    • runSummaryQuery

      List<Map<String,Object>> runSummaryQuery(ItemSummaryQuery<? extends CalculableObject> query)
      Runs (executes) a summary query defined by the parameterized query object which was created by one of the getXXXSummaryQuery calls.
      Example:
      
       def query = ...
       return api.runSummaryQuery(query)
       
      Parameters:
      query - Query to execute.
      Returns:
      Result set of the query
    • createConfiguratorEntry

      @Deprecated ConfiguratorEntry createConfiguratorEntry(InputType type, String name)
      Deprecated.
      Use createConfiguratorEntry() and the Input Builder approach instead.
      Creates a configurator entry object and adds the specified input parameter as the first parameter to the configurator entry. If the parameter had a value in the previous round trip, that value is set automatically.
      Parameters:
      type - Input type of the parameter. Valid enum values are: PRODUCT, PRODUCTGROUP, CUSTOMER, CUSTOMERGROUP, USERENTRY, STRINGUSERENTRY, OPTION, INTEGERUSERENTRY, BOOLEANUSERENTRY, DATEUSERENTRY, TIMEUSERENTRY, DATETIMEUSERENTRY, MULTITIERENTRY, INPUTMATRIX, OPTIONS, MATRIXLOOKUP, LOOKUP, FILTERBUILDER, DMFILTERBUILDER, DMFIELD, DMDIMFILTER, CONFIGURATOR, HIDDEN.
      name - Name of the parameter.
      Returns:
      Configurator entry with the input parameter added.
    • createConfiguratorEntry

      @Deprecated ConfiguratorEntry createConfiguratorEntry(InputType type, String name, Date targetDate)
      Deprecated.
      Use createConfiguratorEntry() and the Input Builder approach instead.
      Creates a configurator entry object and adds the specified input parameter as the first parameter to the configurator entry. If the parameter had a value in the previous round trip, that value is set automatically.
      Parameters:
      type - Input type of the parameter. Valid enum values are: PRODUCT, PRODUCTGROUP, CUSTOMER, CUSTOMERGROUP, USERENTRY, STRINGUSERENTRY, OPTION, INTEGERUSERENTRY, BOOLEANUSERENTRY, DATEUSERENTRY, TIMEUSERENTRY, DATETIMEUSERENTRY, MULTITIERENTRY, INPUTMATRIX, OPTIONS, MATRIXLOOKUP, LOOKUP, FILTERBUILDER, DMFILTERBUILDER, DMFIELD, DMDIMFILTER, CONFIGURATOR, HIDDEN.
      name - Name of the parameter.
      targetDate - Target date for the input parameter (not applicable to all input types).
      Returns:
      Configurator entry with the input parameter added.
    • createConfiguratorEntry

      ConfiguratorEntry createConfiguratorEntry()
      Creates an empty configurator entry object. Must be filled with inputs by calling createParameter() on InputBuilderFactory.


      Example:

      
       def formSection = api.createConfiguratorEntry()
       def param = api.inputBuilderFactory()
               .createOptionEntry(name)
               .setLabel(label)
               .setOptions(optionValues)
               .buildContextParameter()
      
       formSection.createParameter(param)
       return formSection
       
      Returns:
      Configurator entry
    • createConfiguratorEntryArray

      ConfiguratorEntryArray createConfiguratorEntryArray(Object... entries)
      Creates a configurator entry array object which is to be returned from a logic element. Allows dynamic setup of the configurator entries.
      Example:
      
       def entries = ...
       return api.createConfiguratorEntryArray(entries)
       
      Parameters:
      entries - 0..N configurator entries. Supports also list nesting.
      Returns:
      Configurator entry array object with defined methods for further anrichment of the array as ConfiguratorEntryArray#addEntry(ConfiguratorEntry), ConfiguratorEntryArray#setEntries(List) or ConfiguratorEntryArray#getEntries().
    • configurator

      @Deprecated Object configurator(String configuratorName, String formulaName)
      Parameters:
      configuratorName - Name of the configurator, similar to other options' names.
      formulaName - Name of the configurator formula which is used to drive the input selections.
      Returns:
      Result of the configurator
    • configurator

      @Deprecated Object configurator(String configuratorName, String formulaName, Object resultName)
      Parameters:
      configuratorName - Name of the configurator, similar to other options' names.
      formulaName - Name of the configurator formula which is used to drive the input selections.
      resultName - Result that should be returned (instead of the full configurator results map).
      Returns:
      Result of the configurator
    • configurator

      @Deprecated Object configurator(String configuratorName, String formulaName, Object width, Object height)
      Parameters:
      configuratorName - Name of the configurator, similar to other options' names.
      formulaName - Name of the configurator formula which is used to drive the input selections.
      width - Width of the configurator window. Can be a number (in pixels) or a percentage string.
      height - Height of the configurator window. Can be a number (in pixels) or a percentage string.
      Returns:
      Result of the configurator
    • inlineConfigurator

      @Deprecated Object inlineConfigurator(String configuratorName, String formulaName)
      Parameters:
      configuratorName - Name of the configurator, similar to other options' names.
      formulaName - Name of the configurator formula which is used to drive the input selections.
      Returns:
      Result of the configurator
    • inlineConfigurator

      @Deprecated Object inlineConfigurator(String configuratorName, String formulaName, Object width)
      Parameters:
      configuratorName - Name of the configurator, similar to other options' names.
      formulaName - Name of the configurator formula which is used to drive the input selections.
      width - Width of the configurator window. Can be a number (in pixels) or a percentage string.
      Returns:
      Result of the configurator
    • inlineConfigurator

      @Deprecated Object inlineConfigurator(String configuratorName, String formulaName, Object width, Object height)
      Parameters:
      configuratorName - Name of the configurator, similar to other options' names.
      formulaName - Name of the configurator formula which is used to drive the input selections.
      width - Width of the configurator window. Can be a number (in pixels) or a percentage string.
      height - Height of the configurator window. Can be a number (in pixels) or a percentage string.
      Returns:
      Result of the configurator
    • parseDate

      Date parseDate(String pattern, String date)
      Parses a date (entered as a String) according to the given pattern.

      Hint: For parsing datetimes (i.e. dates also including information about the time of the day) use the parseDateTime(String, String) method instead.

      Example:

      
       def date = api.parseDate("yyyy-MM-dd", "2019-01-23")
       
      Parameters:
      pattern - Pattern for parsing (see DateTimeFormat for the pattern format specification).
      date - Date as a String in the format specified by the pattern.
      Returns:
      Date
      See Also:
    • parseDateTime

      DateTime parseDateTime(String pattern, String datetime)
      Parses a datetime (entered as a String) according to the given pattern.

      Note: This method will use the UTC time zone for parsing (unless the provided pattern uses a syntax explicitly specifying a time zone). If a different time zone is required, use the parseDateTime(String, String, int, int) method which allows to set a time zone by providing an offset to UTC in hours and minutes.

      Example:

      
       def now = api.parseDateTime("yyyy-MM-dd'T'HH:mm:ss", "2019-01-23T13:44:52")
       now.getYear()            // 2019
       now.getMonthOfYear()     // 1
       now.getDayOfMonth()      // 23
       now.getHourOfDay()       // 13
       now.getMinuteOfHour()    // 44
       now.getSecondOfMinute()  // 52
       
      Parameters:
      pattern - Pattern for parsing (see DateTimeFormat for the pattern format specification).
      datetime - datetime string to be parsed
      Returns:
      Datetime
      See Also:
    • parseDateTime

      DateTime parseDateTime(String pattern, String datetime, int tzHoursOffset, int tzMinutesOffset)
      Parses a datetime (entered as a String) according to a given pattern and time zone.

      Note: This method will always use the provided time zone, regardless of the possible time zone set explicitly in datetime. Example:

      
       def now = api.parseDateTime("yyyy-MM-dd'T'HH:mm:ss", "2019-01-23T13:44:52", 1, 5)
       
      Parameters:
      pattern - Pattern for parsing (see DateTimeFormat for the pattern format specification).
      datetime - Datetime as a String in the format specified by the pattern.
      tzHoursOffset - Offset in hours from UTC, from -23 to +23.
      tzMinutesOffset - Offset in minutes from UTC, from -59 to +59.
      Returns:
      Datetime
      See Also:
    • createElementNameFilter

      Filter createElementNameFilter(String elementName, Object fieldValue, String... listTypedIds)
      Creates a cross-list filter expression based on metadata.

      Example: You need to filter across multiple price lists on items that have the value "A" in the column with the elementName "XYZ". Now the elementName XYZ might be mapped to a different attributeXX column for every list. So a simple attributeXX=A filter does not work.

      This method does a metadata lookup and creates a proper filter clause based on it for every list. For every list this translates into something like: (attributeXX = A AND listId = <id>). These filters are ORed together.
      Example:

      
       def elementName = ...
       def listTypedIds = ...
       def createElementNameFilter
      
       createElementNameFilter = api.createElementNameFilter(elementName, listTypedIds, createElementNameFilter)
       
      Parameters:
      elementName - Element name (comes from the logic element name or MPL integration tag).
      fieldValue - Value (= operator applied) of that attribute.
      listTypedIds - List of typedIds of the "header" objects. E.g. 34.PL. Supported type codes are PL, MPL, PG and SIM.
      Returns:
      Filter object
    • getItemCompleteCalculationResults

      Map<String,Object> getItemCompleteCalculationResults(String typedId)
      Gets the current complete calculation results of the given item (e.g., price list item).

      Note: These are not returned when using other methods (e.g., pricelistItem(String, String)).
      Example:

      
       def typedId = ...
       def getItemCompleteCalculationResults
      
       getItemCompleteCalculationResults = api.getItemCompleteCalculationResults(typedId)
       
      Parameters:
      typedId - typedId of the item, e.g. 34.PLI. Supported type codes are PLI, XPLI, SIMI, XSIMI, PGI, XPGI and RR.
      Returns:
      Map of individual calculation results with 'Element Name' as the key.
    • getItemActiveCalculationResults

      Map<String,Object> getItemActiveCalculationResults(String typedId)
      Gets the current complete active (i.e. approved) calculation results of the given item.

      Note: It may have an impact on the performance. Consider using currentItem(String) instead.
      Example:

      
       def typedId = ...
       def getItemActiveCalculationResults
      
       getItemActiveCalculationResults = api.getItemActiveCalculationResults(typedId)
       
      Parameters:
      typedId - typedId of the item, e.g. 34.PLI. Supported type codes are PGI and XPGI.
      Returns:
      Map of individual calculation results with 'Element Name' as the key.
      See Also:
    • httpCall

      Object httpCall(String url, String body) throws XExpression
      Issues an HTTP call to an external entity. Defaulting to POST request and JSON content type. Arbitrary addresses/URLs are allowed except internal addresses (in particular xxx.pricefx.net hosts are blacklisted for security reasons).

      If called from a logic element, it has the same timeout as defined for that element.
      Example:

      
       def url = ...
       def body = ...
       def httpCall
      
       httpCall = api.httpCall(url, body)
       
      Parameters:
      url - Full URL to the HTTPS or HTTP endpoint.
      body - Body of the request.
      Returns:
      a Map containing two elements: 'responseBody' and 'errorCode'. If the content type is JSON and data is returned, 'responseBody' will be a parsed Map and not the raw data
      Throws:
      XExpression - If the HTTP call fails.
      See Also:
    • boundCall

      Object boundCall(String uniqueName, String relativeUrl, String body, Boolean... responseBodyAsAString) throws XExpression
      Triggers a HTTPS request towards the Pricefx server, either local one or an external one. Arbitrary addresses/URLs are allowed with the exception of internal addresses (in particular xxx.pricefx.net hosts are blacklisted for security reasons). If this method is called from a logic element, it has the same timeout as defined for that element.

      Note: Use this method with caution, it has some drawbacks. For details see Avoid api.boundCall.

      To be able to use this function, you need to set up a bound partition first in Configuration > All Modules > Bound Partitions. This bound partition must always be set up against some technical account created specifically for the bound call purpose. When calling the Pricefx backend, there is a default size limit of 200k (set in jetty.maxFormContentSize).

      For available endpoints, schemas, and sample requests/responses please refer to the REST API documentation.

      You can test boundCall requests using the HTTP API console in Pricefx Studio.
      Example:

      
       def items = ...
       def requestBody = []
       items.each { item ->
      
           def record = [
               "name": "Increase",
               "sku": item.sku,
               "attribute1": item.newValue,
           ]
      
           requestBody.add([
               data: record,
               oldValues: [:]
           ])
       }
       def resp = api.boundCall("localhost", "/integrate/PX/batch", api.jsonEncode(requestBody), true)
       
      Parameters:
      uniqueName - Unique name of the bound partition.
      relativeUrl - Relative URL to the Pricefx server command. First slash excluded.
      body - Body of the request.
      responseBodyAsAString - If the first param is true, the body is not converted to JSON but returned as a String.
      Returns:
      Map containing two elements: 'responseBody' and 'errorCode'.
      Throws:
      XExpression - If the bound partition is not set or the call fails.
      See Also:
    • recalculatePriceGridItems

      void recalculatePriceGridItems(Long priceGridId, String... productIds)
      Initiates the PriceGridItems / MatrixPriceGridItems recalculation for the specified productIds without creating a background job. This method is a replacement for calling the pricegridmanager.update/{priceGridId} endpoint using api.boundCall().

      PriceGridId of the existing Price Grid and at least one productId needs to be provided otherwise, the recalculation will not be initiated.

      Note: api.recalculatePriceGridItems() is not supported in the distributed mode.
      The method works for CFS and CF only. The Last Update Date is not influenced by this recalculation.
      Example:

      
       api.recalculatePriceGridItems(123, 'P-1', 'P-2')    // all (X)PGIs with P-1 or P-2 SKU will be recalculated
       
      Parameters:
      priceGridId - The Price Grid id which contains items with particular SKU(s) for the recalculation.
      productIds - Array of SKUs for which Price Grid Items should be recalculated (at least one productId needs to be provided).
      Since:
      10.1 - Bees Knees
    • getBoundPartitionNames

      Object getBoundPartitionNames()
      Returns a bound partition list.
      Example:
      
       def getBoundPartitionNames
      
       getBoundPartitionNames = api.getBoundPartitionNames()
       
      Returns:
      Bound partition unique names
    • httpCall

      Object httpCall(String url, String body, String methodType, String contentType, Map... properties) throws XExpression
      Issues an HTTP call to an external entity.

      If called from a logic element, it has the same timeout as defined for that element.

      Example - HTTP GET with specified default charset for the response:

      
       String url = 'https://training.pricefx.eu/edu/learning-paths/terms-ilt.html'
       def properties = ["responseDefaultCharset" : "utf-8"]
       def response = api.httpCall(url, null, 'GET', 'text/html', properties)
       return response.responseBody
       
      Parameters:
      url - Full URL to the HTTPS or HTTP endpoint.
      body - Body of the request.
      methodType - 'GET', 'POST', 'PUT' or 'PATCH'
      contentType -
      • "JSON" - JSON response will be deserialized into a map
      • "APPLICATION_XML" (or "XML" (deprecated)) for contentType "application/xml"
      • "TEXT_XML" for contentType "text/xml"
      • Or any full content type, for instance "text/plain"
      For XML content types, the response is GPathResult and GPath expressions.
      properties - Map of properties. The following are allowed:
      • basicAuthenticationUserName String value - User name for basic authentication.
      • basicAuthenticationPassword String value - User password for basic authentication.
      • sslTrustAllCertificates boolean value - Ignores invalid certificates. Use for testing HTTPS connections only. Not for production use.
      • proxyAuthenticationUserName String value - User name for proxy (if any).
      • proxyAuthenticationPassword String value - User password for proxy (if any).
      • proxyUrl String value - Full URL to proxy.
      • additionalHeaders Map value - Sub-map that will then add these headers verbatim to the request.
      • responseDefaultCharset String - character set to be applied if none found in the HTTP response entity. When getting the entity content as a String, use the provided default character set, if none is found in the entity. If responseDefaultCharset is null and none is found in the HTTP response entity, the default "ISO-8859-1" is used.
      Returns:
      Map containing two elements: 'responseBody' and 'statusCode'.
      Throws:
      XExpression - If the HTTP call fails.
    • asyncHttpCall

      Future<Object> asyncHttpCall(String url, String body, String methodType, String contentType, Map... properties)
      The asynchronous httpCall is design to issues the HTTP call to an external entity httpCall(String, String, String, String, Map[]) in the new thread (which is canceled after the time specified in FormulaEngineContext.getElementTimeout())


      Send httCall() and wait for the result, until it is ready (the task is blocked until the response is available):

      
       
               String url = 'https://training.pricefx.eu/edu/learning-paths/terms-ilt.html'
              def properties = ["responseDefaultCharset" : "utf-8"]
               def response = api.asyncHttpCall(url, null, 'GET', 'text/html', properties)
      
               def httpCallResult = api.getAsyncHttpCallResult(response, true)
               def responseBody = httpCallResult.responseBody
       
       

      Send httpCall() and check for the result later (if the response is not ready yet, the 'empty' result is returned):

      
       
               String url = 'https://training.pricefx.eu/edu/learning-paths/terms-ilt.html'
              def properties = ["responseDefaultCharset" : "utf-8"]
               def response = api.asyncHttpCall(url, null, 'GET', 'text/html', properties)
               (...)
               def httpCallResult = api.getAsyncHttpCallResult(response, false)
               def responseBody = httpCallResult.responseBody    // httpCall result or "API call: httpCall(). Result of httpCall() is not available yet" is returned
       
       

      Send httpCall() in the fire and forget scenario (thread will be finished by the element timeout limit):

      
       
               String url = 'https://training.pricefx.eu/edu/learning-paths/terms-ilt.html'
              def properties = ["responseDefaultCharset" : "utf-8"]
               api.asyncHttpCall(url, null, 'GET', 'text/html', properties)
       
       
      Parameters:
      url - Refer to httpCall(String, String, String, String, Map[])
      body - Refer to httpCall(String, String, String, String, Map[])
      methodType - Refer to httpCall(String, String, String, String, Map[])
      contentType - Refer to httpCall(String, String, String, String, Map[])
      properties - Refer to httpCall(String, String, String, String, Map[])
      Returns:
      Future wrapper of the expected httpCall() result
      See Also:
    • getAsyncHttpCallResult

      Object getAsyncHttpCallResult(Future<Object> asyncHttpCall, boolean waitForTheResult) throws ExecutionException, InterruptedException
      Helper method for api.asyncHttpCall() which is design to collect the result. See asyncHttpCall(String, String, String, String, Map[]) for the code usage
      Send httCall() and wait for the result, until it is ready (the task is blocked until the response is available):

      
       
               String url = 'https://training.pricefx.eu/edu/learning-paths/terms-ilt.html'
              def properties = ["responseDefaultCharset" : "utf-8"]
               def response = api.asyncHttpCall(url, null, 'GET', 'text/html', properties)
      
               def httpCallResult = api.getAsyncHttpCallResult(response, true)
               def responseBody = httpCallResult.responseBody
       
       

      Send httpCall() and check for the result later (if the response is not ready yet, the empty result is returned):

      
       
               String url = 'https://training.pricefx.eu/edu/learning-paths/terms-ilt.html'
              def properties = ["responseDefaultCharset" : "utf-8"]
               def response = api.asyncHttpCall(url, null, 'GET', 'text/html', properties)
               (...)
               def httpCallResult = api.getAsyncHttpCallResult(response, false)
               def responseBody = httpCallResult.responseBody    // httpCall result or "API call: httpCall(). Result of httpCall() is not available yet" is returned
       
       

      Send httpCall() in the fire and forget scenario (thread will be finished by the element timeout limit):

      
       
               String url = 'https://training.pricefx.eu/edu/learning-paths/terms-ilt.html'
              def properties = ["responseDefaultCharset" : "utf-8"]
               api.asyncHttpCall(url, null, 'GET', 'text/html', properties)
       
       
      Parameters:
      asyncHttpCall - Result of asyncHttpCall(String, String, String, String, Map[])
      waitForTheResult - Flag to block the task until the result is ready to be returned (waitForTheResult = true) or return the result if available (waitForTheResult = false), otherwise empty result is returned
      Returns:
      Map containing two elements: 'responseBody' and 'statusCode'

      or empty block: 'responseBody' = 'API call: httpCall(). Result of httpCall() is not available yet' and 'statusCode' = 444

      Throws:
      ExecutionException - If the HTTP call fails.
      InterruptedException - If the HTTP call thread is interapted.
      See Also:
    • add

      Object add(String typeCode, Map<String,Object> values)
      Adds a new object to the collection of objects of the given type.

      Note: This operation will only work in contexts that allow object modification (CFS, CalculationFlow and direct formula execution via JSON API). This method cannot be used in a distributed calculation.

      Note: For performances reasons, subsequent domain object search (using api.find() for example) may not return a result reflecting this addition. See enableAutoFlushMode() for more details on this behavior.

      Note: This method modifies only the specified data, with a focus on performance and simplicity. As such, it does not address any potential further changes that may be required (such as safe-deleting, adjusting metadata, etc.). These are expected to be managed in the logic as well.

      If any of the attributes is null, the record will not be updated. If you want a certain attribute to have a null value, do it explicitly, by putting e.g. the “NULL” marker value there or a similar one.

      Example:

      
       def entry = [
               lookupTableName : "ExchangeRates",
               key1 : "USD",
               key2 : "EUR",
               attribute1 : 0.879
       ]
       api.add("MLTV2", entry)
       
      Parameters:
      typeCode - Type code string of the type of the object to search for. All available type codes can be retrieved by calling <hostname>/pricefx/<partition name>/fetch.
      values - Key-value pairs representing fields of the object you want to add. Note that all significant fields have to be present.
      Returns:
      Added object or null if error occurred.
      See Also:
    • movePriceItems

      int movePriceItems(String sourcePriceItemType, List<String> productIds, long sourcePriceItemId, String targetPriceType, long targetPriceId)
      API method for convenient movement of price items between price calculable entities.

      NOTE:

      - Acceptable price items type codes are: PGI, XPGI, PLI and XPLI.

      - Acceptable price element type codes are: PG and PL.

      - The move is allowed only between the consistent types:

      MatrixPricelistItem and MatrixPriceGridItem can be moved only to MatrixableCalculableObject.ListType.MATRIX

      PricelistItem and PriceGridItem can be moved only to MatrixableCalculableObject.ListType.SIMPLE.

      Example:

      
       def noOfMovedItems = api.movePriceItems('PGI', ['P-1', 'P-2'], 123, 'PG', 321)
       noOfMovedItems == 2 // if particular PGIs and PG exists, the items are moved
       
      Parameters:
      sourcePriceItemType - TypeCode of the source price element for particular items which are supposed to be moved
      productIds - ProductIds' list of items to be moved (cannot be null)
      sourcePriceItemId - Id of price element for particular items which are supposed to be moved
      targetPriceType - TypeCode of target price element where the items should be moved
      targetPriceId - Id of price element where items should be moved
      Returns:
      number of moved items
      See Also:
    • copyPriceItems

      int copyPriceItems(String sourcePriceItemType, List<String> productIds, long sourcePriceItemId, String targetPriceType, long targetPriceId)
      API method for convenient copy of price items between price calculable entities.

      NOTE:

      - Acceptable price items type codes are: PGI, XPGI, PLI and XPLI.

      - Acceptable price element type codes are: PG and PL.

      - The copy is allowed only between the consistent types:

      MatrixPricelistItem and MatrixPriceGridItem can be copied only to MatrixableCalculableObject.ListType.MATRIX

      PricelistItem and PriceGridItem can be copied only to MatrixableCalculableObject.ListType.SIMPLE.

      Example:

      
       def noOfCopiedItems = api.copyPriceItems('PGI', ['P-1', 'P-2'], 123, 'PG', 321, false)
       noOfCopiedItems == 2 // if particular PGIs and PG exists, the items are copied
       
      Parameters:
      sourcePriceItemType - TypeCode of the source price element for particular items which are supposed to be copied
      productIds - ProductIds' list of items to be copied
      sourcePriceItemId - Id of price element for particular items which are supposed to be copied
      targetPriceType - TypeCode of target price element where the items should be copied
      targetPriceId - Id of price element where items should be copied
      Returns:
      number of copied items
      See Also:
    • addOrUpdate

      Object addOrUpdate(String typeCode, Map<String,Object> values)
      Adds or updates an object in the collection of objects of the given type.

      All updates of addOrUpdate (and similar) are only executed after a full logic run. These calls are not like an immediate "update" call to DB where you then can "select" within same TX context that data.

      Note: This operation will only work in contexts that allow object modification (CFS, CalculationFlow and direct formula execution via JSON API). This method also works with the Post Step Logic Formula in workflows. This method cannot be used in a distributed calculation.

      Note: For performances reasons, subsequent domain object search (using api.find() for example) may not return a result reflecting this addition/update. See enableAutoFlushMode() for more details on this behavior.

      Note: This method modifies only the specified data, with a focus on performance and simplicity. As such, it does not address any potential further changes that may be required (such as safe-deleting, adjusting metadata, etc.). These are expected to be managed in the logic as well.

      Example:

      
       def entry = [
               lookupTableName : "ExchangeRates",
               key1 : "USD",
               key2 : "EUR",
               attribute1 : 0.879
       ]
       api.add("MLTV2", entry)
       
      Parameters:
      typeCode - Type code string of the type of the object to search for. All available type codes can be retrieved by calling <hostname>/pricefx/<partition name>/fetch.
      values - Key-value pairs representing fields of the object you want to add or update. Note that all significant fields have to be present.
      Returns:
      Object added or updated.
      See Also:
    • addOrUpdate

      int addOrUpdate(String typeCode, List<Map<String,Object>> values)
      Adds or updates a list of master data objects of the given type.

      Note: This operation will only work in contexts that allow object modification (CFS, CalculationFlow and direct formula execution via JSON API). This method also works with the Post Step Logic Formula in workflows. This method cannot be used in a distributed calculation.

      Note: This method modifies only the specified data, with a focus on performance and simplicity. As such, it does not address any potential further changes that may be required (such as safe-deleting, adjusting metadata, etc.). These are expected to be managed in the logic as well.

      Note: For performances reasons, subsequent domain object search (using api.find() for example) may not return a result reflecting this addition/update. See enableAutoFlushMode() for more details on this behavior.

      Information/Restrictions specific for mass operation:

      • This method inserts data directly to the database by transforming input data to a CSV file, so expect much better performance than running #addOrUpdate(String, Map) in a loop.
      • Only one table can be modified with one call.
      • All rows must have all business keys provided in input data
      • If you want to update a Date type field, values should be ISO formatted date String, eg. yyyy-MM-dd.
      • attribute1-100 are parsed according to the attribute's type (ex. List/Map attribute value is parsed to the String if attribute's type is String)
      • Attention! When updating LookupTables, id of the modified table must be provided at 'lookupTableId' or 'lookupTable.id' key. 'lookupTableName' will be ignored.
      • Attention! When data in one column is being changed, it must be present for all rows in input data otherwise it will be nulled-out in the database.
      • Attention! When updating JLTVx values, all existing `attributeExtension___` keys must be passed as input data otherwise data can be lost.
      • Attention! Only objects with the same table id can be updated with one method call even if the type code is the same. It relates to updating multiple different tables (from user's perspective) in a single call. So if you have "ProductCosts" PX50 and "ProductListPrices" PX50, you can update only one of them with a single call. Both can have different structure and different significant fields so we cannot mix them up when doing a CSV import to the database.

      Example 1:

      
       List entries = [[sku: "sku1", attribute1: "foo", attribute2: "bar"],
                      [sku: "sku2", attribute1: "bar", attribute2: "foo"]]
       api.addOrUpdate('P', entries)
       

      Example 2:

      
       List entries = [[lookupTableId: 10, key1: "foo1", key2: "foo2", attribute1: 10.56G, attribute3: "2022-11-01"],
                       [lookupTableId: 10, key1: "bar1", key2: "bar2", attribute1: 9.99G, attribute3: "2022-11-02"],
                       [lookupTableId: 10, key1: "fooBar1", key2: "fooBar2", attribute1: 11G, attribute3: "2022-11-03"]]
       api.addOrUpdate('MLTV2', entries)
       
      Parameters:
      typeCode - Type code string of the type of the object to search for. Works only for objects marked as bulk loadable and api modifiable. These are: P, C, PCOMP, PDESC, PX, CX, SX, LTV, MLTVx, JLTVx, COAR
      values - Key-value pairs representing fields of the object you want to add or update. Note that all significant fields have to be present for every provided record.
      Returns:
      Number of added/modified objects or -1 if an error occurred (more details available in logs).
      See Also:
    • update

      Object update(String typeCode, Map<String,Object> values)
      Updates an object in the collection of objects of the given type.

      Note: This operation will only work in contexts that allow object modification (CFS, CalculationFlow and direct formula execution via JSON API). This method also works with the Post Step Logic Formula in workflows. This method cannot be used in a distributed calculation.

      Note: This method modifies only the specified data, with a focus on performance and simplicity. As such, it does not address any potential further changes that may be required (such as safe-deleting, adjusting metadata, etc.). These are expected to be managed in the logic as well.

      Note: For performances reasons, subsequent domain object search (using api.find() for example) may not return a result reflecting this update. See enableAutoFlushMode() for more details on this behavior.

      Example 1:

      
       api.addOrUpdate("PX", [
               "name": "Scoring_MM",
               "sku": sku
       ])
       
      Example 2:
      
       api.addOrUpdate("PGI", [
               "priceGridName" : "LifeCycleMonitor",
               "sku"           : currentItem.sku,
               "label"         : currentItem.label
       ])
       
      Example 3:
      
       def large = [
               "lookupTableId"   : pp.id,
               "lookupTableName" : pp.uniqueName,
               "name"            : "L",
               "attribute1"      : percentileHigh,
               "attribute2"      : "999999999"
       ]
       api.addOrUpdate("MLTV", large)
       
      Parameters:
      typeCode - Type code string of the type of the object to search for. All available type codes can be retrieved by calling <hostname>/pricefx/<partition name>/fetch.
      values - Key-value pairs representing fields of the object you want to update. Note that all significant fields have to be present.
      Returns:
      Updated object or null if error occured.
      See Also:
    • delete

      Object delete(String typeCode, Map<String,Object> values)
      Deletes an object in the collection of objects of the given type.

      Note: This operation will only work in contexts that allow object modification (CFS, CalculationFlow and direct formula execution via JSON API). This method also works with the Post Step Logic Formula in workflows. This method cannot be used in a distributed calculation.

      Note: This method modifies only the specified data, with a focus on performance and simplicity. As such, it does not address any potential further changes that may be required (such as safe-deleting, adjusting metadata, etc.). These are expected to be managed in the logic as well.

      Note: For performances reasons, subsequent domain object search (using api.find() for example) may not return a result reflecting this deletion. See enableAutoFlushMode() for more details on this behavior.

      Example:

      
       api.delete("PX", ["id": existingRecord, "name": "ActivePrice"])
       
      Parameters:
      typeCode - Type code string of the type of the object to search for. All available type codes can be retrieved by calling <hostname>/pricefx/<partition name>/fetch.
      values - Key-value pairs representing significant fields of the object you want to delete. Note that all significant fields have to be present; if not, the ID has to be present.
      Returns:
      Deleted object or null if error occured.
      See Also:
    • massDelete

      int massDelete(String typeCode, Filter filter)
      Mass delete of the objects in the collection of the given type (based on the Filter's criteria).

      Note: This operation will only work in contexts that allow object modification (CFS, CalculationFlow and direct formula execution via JSON API). This method cannot be used in a distributed calculation.

      Note: This method modifies only the specified data, with a focus on performance and simplicity. As such, it does not address any potential further changes that may be required (such as safe-deleting, adjusting metadata, etc.). These are expected to be managed in the logic as well.

      Example:

      
       api.massDelete('C', Filter.in('customerId', ['CD-001', 'CD-002', 'CD-010', 'CD-021']))
       
      Parameters:
      typeCode - Type code string of the type of the object to search for. All available type codes can be retrieved by calling <hostname>/pricefx/<partition name>/fetch.
      filter - Criteria of mass delete action (each and every row which meet the Filter's criteria will be removed).
      Returns:
      Number of deleted rows, zero if none of the rows meet the Filter's criteria, -1 if in distributed mode or object modification/delete not allowed.
      See Also:
    • enableAutoFlushMode

      void enableAutoFlushMode()
      Sets the db session flush mode to AUTO so that subsequent db operations will work with the actual state of domain objects db which have just been updated during the logic execution (via add(String, Map), update(String, Map), addOrUpdate(String, List), delete(String, Map)).

      This mode is mostly useful when the logic needs to read from the db the last modifications done on some objects. For example, without AUTO flush mode, api.find() will not see the deletion.

      
            api.delete(api.find("P", Filter.equal("sku", mySku)).first())
            return api.find("P", Filter.equal("sku", mySku)).size() // returns 1
       

      With AUTO flush mode, the db session detects that a search is done on a modified domain object table and then flushes the deletion into the current transaction before the execution of api.find().

      
           api.delete(api.find("P", Filter.equal("sku", mySku)).first())
           api.enableAutoFlushMode()
           return api.find("P", Filter.equal("sku", mySku)).size() // returns 0
       

      Even if this mode is very convenient, it should be used only when it is necessary to do so as it will imply more memory usage and may lock db tables during the whole logic execution time. Use it at your own risks!

      At the end of the logic element execution, the flush mode will be automatically switched back to MANUAL (see above paragraph). Consequently, any logic element needing this mode should enable it explicitly.

      Note: This operation will only work in contexts that allow object modification (CFS, CalculationFlow and direct formula execution via JSON API). This method also works with the Post Step Logic Formula in workflows.

    • sendPlatformNotification

      void sendPlatformNotification(String subject, String message)
      Sends a notification to Platform for further message routing.
      Example:
      
       def subject = ...
       def message = ...
       def sendPlatformNotification
      
       sendPlatformNotification = api.sendPlatformNotification(subject, message)
       
      Parameters:
      subject - Subject of message.
      message - Body of message.
    • sendEmail

      void sendEmail(String to, String subject, String message)
      Sends an email. Only one recipient can be defined.

      Note: This operation will only work in contexts that allow object modification:

      • Calculated Field Set (CFS)
      • Calculation Flow
      • Configuration Wizard - Execution
      • Creation Workflow
      • Model Calculation
      • Model Parallel Calculation (only Init and Summary element groups)
      • RAT Calculation
      • Workflow Post Step
      Information: A direct logic execution via REST API using the formulamanager.execute endpoint can be used to enable the object modification (allowObjectMods param).

      Example:

      
       def message = "The cost is missing"
       def filter = Filter.equals("name", "Costs")
      
       api.findLookupTableValues("EmailNotifications", filter).each {
           api.sendEmail(it.value, "Missing costs", message)
       }
       
      Parameters:
      to - Email address the email is sent to.
      subject - Email subject.
      message - Email body.
      See Also:
    • sendEmail

      void sendEmail(String to, String toName, String subject, String message, String fromEmail, String fromName, String replyToEmail, String replyToName, Boolean useCustomSMTP)
      Sends an email. Only one recipient can be defined.

      Note: This operation will only work in contexts that allow object modification:

      • Calculated Field Set (CFS)
      • Calculation Flow
      • Configuration Wizard - Execution
      • Creation Workflow
      • Model Calculation
      • Model Parallel Calculation (only Init and Summary element groups)
      • RAT Calculation
      • Workflow Post Step
      Information: A direct logic execution via REST API using the formulamanager.execute endpoint can be used to enable the object modification (allowObjectMods param).
      Example:
      
       def to = ...
       def toName = ...
       def subject = ...
       def message = ...
       def fromEmail = ...
       def fromName = ...
       def replyToEmail = ...
       def replyToName = ...
       def useCustomSMTP = ...
       def sendEmail
      
       sendEmail = api.sendEmail(to, toName, subject, message, fromEmail, fromName, replyToEmail, replyToName, useCustomSMTP)
       
      Parameters:
      to - Email address the email is sent to.
      toName - Name of the recipient. If not specified, toEmail is used.
      subject - Email subject.
      message - Email body.
      fromEmail - Sender's email address.
      fromName - Name of the sender. If not specified, fromEmail is used.
      replyToEmail - Reply to email address.
      replyToName - Reply to user name. If not specified, replyToEmail is used.
      useCustomSMTP - True if sending through custom SMTP server should be used.
      See Also:
    • customEvent

      void customEvent(Object object)
      Sends an event of the type "CUSTOM". Other event types are reserved internally.

      Note: This operation will only work in contexts that allow object modification (CFS, CF and direct formula execution via JSON API).

      Sending this type of events needs to be enabled on the partition by the system admin (event type "CUSTOM" in the Event Bitmask).
      Example:

      
       def object = ...
       def customEvent
      
       customEvent = api.customEvent(object)
       
      Parameters:
      object - Object to pass along with the event.
    • customEvent

      void customEvent(Object object, String customEventType)
      Sends an event of the type "CUSTOM". Other event types are reserved internally.

      Note: This operation will only work in contexts that allow object modification (CFS, CalculationFlow and direct formula execution via JSON API).

      Sending this type of events needs to be enabled on the partition by the system admin (event type "CUSTOM" in the Event Bitmask).
      Example:

      
       def object = ...
       def customEventType = ...
       def customEvent
      
       customEvent = api.customEvent(object, customEventType)
       
      Parameters:
      object - Object to pass along with the event.
      customEventType - Custom string to classify the custom event type (as the general event type is always CUSTOM).
    • customEvent

      void customEvent(Object object, String customEventType, String operation)
      Sends an event of the type "CUSTOM". Other event types are reserved internally.

      Note: This operation will only work in contexts that allow object modification (CFS, CalculationFlow and direct formula execution via JSON API).

      Sending this type of events needs to be enabled on the partition by the system admin (event type "CUSTOM" in the Event Bitmask).
      Example:

      
       def object = ...
       def customEventType = ...
       def operation = ...
       def customEvent
      
       customEvent = api.customEvent(object, customEventType, operation)
       
      Parameters:
      object - Object to pass along with the event.
      customEventType - Custom string to classify the custom event type (as the general event type is always CUSTOM).
      operation - One of these strings: UPDATE, DELETE, ADD, ITEMCHANGE.
    • customEvent

      void customEvent(Object object, String customEventType, String operation, boolean omitNullValues)
      Sends an event of the type "CUSTOM". Other event types are reserved internally.

      Note: This operation will only work in contexts that allow object modification (CFS, CalculationFlow and direct formula execution via JSON API).

      Sending this type of events needs to be enabled on the partition by the system admin (event type "CUSTOM" in the Event Bitmask).
      Example:

      
       def object = ...
       def customEventType = ...
       def operation = ...
       def omitNullValues = ...
       def customEvent
      
       customEvent = api.customEvent(object, customEventType, operation, omitNullValues)
       
      Parameters:
      object - Object to pass along with the event.
      customEventType - Custom string to classify the custom event type (as the general event type is always CUSTOM). Can be null.
      operation - One of these strings: UPDATE, DELETE, ADD, ITEMCHANGE. Can be null.
      omitNullValues - Also includes keys that have a null value (false) or omits them (true). True is the default for other method signatures that do not explicitly specify that value.
    • updateCalculableObjectHeader

      Object updateCalculableObjectHeader(String calcObjTypeCode, String calcObjName)
      Updates the header information of a CalculableObject (e.g., a price grid, a price list, etc.).

      Note: This operation will only work in contexts that allow object modification (CFS, CalculationFlow and direct formula execution via JSON API).
      Example:

      
       def calcObjTypeCode = ...
       def calcObjName = ...
       def updateCalculableObjectHeader
      
       updateCalculableObjectHeader = api.updateCalculableObjectHeader(calcObjTypeCode, calcObjName)
       
      Parameters:
      calcObjTypeCode - Type code of the object to update.
      calcObjName - (Numeric) ID of the object to update.
      Returns:
      Calculable object header
    • attributedResult

      AttributedResult attributedResult(Object result)
      Creates an AttributedResult object to be returned as a result of an output element.

      Since AttributedResult is configurable, it is used when it is not sufficient to only return a plain value, but it is also required to adjust formatting, e.g. color, underline, etc.

      The usage is simple: instead of returning the output value, create a new AttributedResult instance using api.attributedResult(plain value), customize it by calling its various methods, and return it.

      Example:

      
       def cost = out.Margin_pct
       return api.attributedResult(cost)
       .withBackgroundColor(cost < 0.30 ? "red" : "#0101DF")
       .withSuffix(cost < 0.30 ? "!!!" : null)
       .withTextColor(cost < 0.30 ? "white" : null)
       .withTextDecoration(cost < 0.30 ? "underline" : null)
       
      Parameters:
      result - Calculation result.
      Returns:
      AttributedResult object
      See Also:
    • wrap

      WrappedResult wrap(Object result)
      Wraps a result to make sure the original result object appears in the JSON response. This way also more complex results like lists and maps can be exported as a logic element result.
      Example:
      
       def result = ...
       def wrap
      
       wrap = api.wrap(result)
       
      Parameters:
      result - Result.
      Returns:
      Wrapped result object. Should only be used as a return statement of a logic element.
    • newMatrix

      ResultMatrix newMatrix()
      Creates a new result matrix DTO object that can be further customized and populated with calculated data. The individual cells can be styled via the use of:
      
       -  linkCell(Object value, String targetPage, String targetPageState)
       -  imageCell(Object imageUrl)
       -  styledCell(Object value, String textColor, String bgColor, String weight, String alignment)
       -  styledCell(Object value, String textColor, String bgColor, String weight)
       -  styledCell(Object value, String textColor, String bgColor)
       -  setColumnFormat(String column, FieldFormatType fft)
       
      Valid FieldFormatTypes are:
      
       NUMERIC, NUMERIC_LONG, MONEY, PERCENT, TEXT, MONEY_EUR, MONEY_USD, MONEY_GBP, MONEY_JPY, MONEY_CHF, MONEY_PLN, DATETIME, DATE, INTEGER
       

      Example:

      
       def getTrafficColor(value) {
           if (value <= 0) {
               return "red"
           } else if (value > 0 && value < 0.1) {
               return "yellow"
           } else if (value >= 0.1) {
               return "green"
           }
       }
      
       // Creates (and returns) a new ResultMatrix object with specified columns and sets the format type of each column using withColumnFormats(). Adds rows using the api.find().
       def products = api.find("P", 0, 10, null, ["sku", "label", "currency"])
      
       //Note: withColumnFormats() accepts columns AND formats. No need to define 1) the format using setColumnFormat() and 2) the columns in api.newMatrix(columns, ….) together. Always prefer withColumnFormats() where applicable.
       def matrix = api.newMatrix().withColumnFormats([
       "sku" : FieldFormatType.TEXT,
       "label" : FieldFormatType.TEXT,
       "currency": FieldFormatType.TEXT
       ]).withRows(products);
      
       // adds more columns dynamically
       matrix.addColumn("Margin %")
       matrix.addColumn("Url")
      
       // sets formats for the dynamically added columns
       matrix.setColumnFormat("Margin %", FieldFormatType.PERCENT)
       matrix.setColumnFormat("Url", FieldFormatType.LINK)
      
       // allows users to filter values
       matrix.setEnableClientFilter(true)
      
       // adds a data row
       matrix.addRow([
               "Item": matrix.styledCell("Red bold text", "#ff0000", "transparent", "bold"),
               "Quantity": 1.23456,
               "Price": 78.9012,
               "Margin %": 0.3456,
      
               "Url": "<a href=\"https://www.google.com/search?q=price+f(x)\">link</a>",
      
               // optionally you can add link to a price grid of a given ID
               "Pricegrid" : matrix.linkToPriceGrid("Open Pricegrid", 123, null),
      
               // or to a price list of a given ID
               "Pricelist" : matrix.linkToPriceList("Open Pricelist", 123, null),
      
               // or a to custom page (result identical to the previous)
               "CustomerId" : matrix.linkCell("Open Customer", "customersPage", "123456"),
      
               // or add a library images, such as Traffic, BlackTraffic or Arrow
               "Margin Status" : matrix.libraryImage("BlackTraffic", getTrafficColor(-0.2f)),
      
               // or add a general image
               "Image" : matrix.imageCell("images/grid/approve.png"),
       ])
      
      
       return matrix
       
      Returns:
      ResultMatrix object
      See Also:
    • newMatrix

      ResultMatrix newMatrix(String... columns)
      Creates a new result matrix DTO object that can be further customized and populated with calculated data.

      For details see newMatrix().
      Example:

      
       def columns = ...
       def newMatrix
      
       newMatrix = api.newMatrix(columns)
       
      Parameters:
      columns - Initial set of columns for the result matrix.
      Returns:
      ResultMatrix object
      See Also:
    • newMatrix

      ResultMatrix newMatrix(Collection<String> columns)
      Creates a new result matrix DTO object that can be further customized and populated with calculated data.

      For details see newMatrix().
      Example:

      
       def columns = ...
       def newMatrix
      
       newMatrix = api.newMatrix(columns)
       
      Parameters:
      columns - Initial set of columns for the result matrix.
      Returns:
      ResultMatrix object
      See Also:
    • newGauge

      ResultGauge newGauge()
      Creates a new gauge object that can be further customized.

      Example:

      
       def gauge = api.newGauge()
       gauge.addSector(5, "#FF0000")
       gauge.addSector(25, "#FFFF00")
       gauge.addSector(null, "#00FF00")
       gauge.setValue(10)
       
      Returns:
      ResultGauge object
    • dashboard

      DashboardApi dashboard(String dashboardName)
      Returns a DashboardApi instance for a dashboard of the specified name. This method is typically used for configuration of Embedded Dashboards.
      Example:
      
       def dashboardName = ...
       def dashboard
      
       dashboard = api.dashboard(dashboardName)
       
      Parameters:
      dashboardName - name of the dashboard
      Returns:
      DashboardApi for specified dashboard
      See Also:
    • dashboardWideEvent

      String dashboardWideEvent(String eventName)

      Constructs an event name that is unique to the current dashboard.

      This method is typically used for configuration of Embedded Dashboards.

      Events are global through browser tabs, so they are not limited to embedded dashboards. Every event has its source (e.g. a grid) and a payload – arbitrary data (e.g. values of grid columns), which are passed to the dashboard portlet. Elements which can trigger an embedded dashboard to receive new parameters are:
      • ResultMatrix
      • Open Embedded Dashboard on New Tab
      • ScatterChart
      • BarLineChart
      • Data Tab of any Chart (except Waterfalls)

      Example:
      
       def eventName = ...
       def dashboardWideEvent
      
       dashboardWideEvent = api.dashboardWideEvent(eventName)
       
      Parameters:
      eventName - name of the event
      Returns:
      event name
    • newController

      DashboardController newController()
      Creates a new dashboard controller object that can be further customized.

      Example:

      
       def lookupTable = api.findLookupTable("SalesOrg")
       def controller = api.newController()
       controller.addButton("1. STEP: Change Price Strategy", "pricingParametersPage", lookupTable.typedId)
       controller.addHTML("<h2>Meatball</h2>")
       
      Returns:
      DashboardController object
    • walkFilter

      Filter walkFilter(Filter filter, Closure<?> visitBefore, Closure<?> visitAfter, boolean removeNulls)
      Walks a filter and all its sub-filters, visiting each filter in the tree. A pair of closures is used to visit each filter. Each closure can replace the filter that is visiting. If it does, a new tree will be created for every part of the tree that is affected, thus preserving the original tree.

      removeNulls is consulted only in case of (sub)filters which take a list of sub-filters.

      This method may be used in many cases. For instance, you can use it for mapping the current property set to another one, e.g. to convert a PB filter to a PA one. Similarly to this example:

      
       def propertyMappings = ["sku": "ProductID"]
      
       api.walkFilter(pbFilter, null, { filter ->
           if (filter != null && propertyMappings[filter.property] != null) {
               filter.property = propertyMappings[filter.property]
           }
           filter
       }, false);
       
      Parameters:
      filter - Filter object.
      visitBefore - Before closure.
      visitAfter - After closure.
      removeNulls - Removes nulls.
      Returns:
      If any changes have been made, the new Filter; if not, the original Filter.
    • findDataLoad

      Object findDataLoad(String dataLoadLabel, String dataLoadType, String target)

      Example:
      
       def dataLoadLabel = ...
       def dataLoadType = ...
       def target = ...
       def findDataLoad
      
       findDataLoad = api.findDataLoad(dataLoadLabel, dataLoadType, target)
       
      Parameters:
      dataLoadLabel - Label of DMDataLoad as seen in the Data Load UI.
      dataLoadType - Load type of DMDataLoad as seen in the Data Load UI. Namely:
      • Customers
      • Products
      • Flush
      • Calendar
      • Refresh
      • Calculation
      • Truncate
      • Simulation
      • ModelCalculation
      • InternalCopy
      • IndexMaintenance
      target - Target of DMDataLoad as seen in the Data Load UI.
      Returns:
      Data Load if and only if there is exactly one Data Load matching (fail early strategy).
    • findRebateRecordLoad

      Object findRebateRecordLoad(String rebateRecordLoadLabel)

      Example:
      
       def rebateRecordLoadLabel = ...
       def findRebateRecordLoad
      
       findRebateRecordLoad = api.findRebateRecordLoad(rebateRecordLoadLabel)
       
      Parameters:
      rebateRecordLoadLabel - Label of the rebate record load as seen in the Rebate Record UI.
      Returns:
      rebateRecordLoad if and only if there is exactly one load matching (fail early strategy).
    • findCompensationRecordLoad

      Object findCompensationRecordLoad(String compensationRecordLoadLabel)

      Example:
      
       def compensationRecordLoadLabel = ...
       def findCompensationRecordLoad
      
       findCompensationRecordLoad = api.findCompensationRecordLoad(rebateRecordLoadLabel)
       
      Parameters:
      compensationRecordLoadLabel - Label of the compensation record load as seen in the Compensation Record UI.
      Returns:
      compensationRecordLoad if and only if there is exactly one load matching (fail early strategy).
      Since:
      9.0 - Hurricane
    • currentPartitionName

      String currentPartitionName()

      Example:
      
       def currentPartitionName
      
       currentPartitionName = api.currentPartitionName()
       
      Returns the current partition name.
      Returns:
      Partition name
    • getTimeZone

      DateTimeZone getTimeZone(String tzString)
      Provides a wrapper for the org.joda.time.DateTimeZone.forId(String tzString) method. For details see the Joda Time documentation.

      Example 1:

      
       def timezone1 = api.getTimeZone("Europe/Berlin")
       def timezone2 = api.getTimeZone("Europe/Prague")
       def timezone3 = api.getTimeZone("America/New_York")
       def timezone4 = api.getTimeZone("Australia/Brisbane")
       

      Example 2:

      
       def startHour = 20
       def offset = api.getTimeZone("Europe/Prague").getOffset(new Date().getTime())
       def startHourUTC = startHour - offset.intValue()
       
      Parameters:
      tzString - Timezone string.
      Returns:
      DateTimeZone object
      See Also:
    • adjustDateByTimezoneOffset

      Date adjustDateByTimezoneOffset(Date theDate)
      Sometimes it is important which day in a given timezone a point in time is The timezone used here is the partition's timezone as defined in the application property "defaultTimezoneId" If no timezone is defined in the app property, no conversion happens Essentially this method is useful to determine the exact boundaries of a day, as e.g. in Asia the new day may already have started when in Europe or US it could be still the day prior from a pure date perspective.
      Parameters:
      theDate - The timestamp to use. Provide null to use "right now"
      Returns:
      The date adjusted by the specified timezone offset
    • uuid

      String uuid(int len)
      Generates a random UUID of the specified length.

      Example:

      
       return uuid(15)   // returns e.g. "VcydxgltxrVZSTV"
       
      Parameters:
      len - Desired number of characters.
      Returns:
      UUID string
    • uuid

      String uuid(int len, int radix)
      Generates a random UUID of the specified length and radix.

      Examples:

      
       return uuid(8, 2) // returns e.g. "01001010" (8 character ID, base=2)
      
       return uuid(8, 10)       // returns e.g. "47473046" (8 character ID, base=10)
      
       return uuid(8, 16)       // returns e.g. "098F4D35" (8 character ID, base=16)
       
      Parameters:
      len - Desired number of characters.
      radix - Number of allowable values for each character (must be <=62).
      Returns:
      UUID string
    • uuid

      String uuid()
      Generates a RFC4122, version 4 ID.

      Example:

      
       return api.uuid()   // returns e.g. "92329D39-6F5C-4520-ABFC-AAB64544E172"
       
      Returns:
      UUID string
    • multiKey

      MultiKey<Object> multiKey(Object... keys)
      Constructs a new composite key object which can be used as a key in a map. Equality of two keys is defined by the pair-wise equality of the corresponding key values.
      For more details, refer to the org.apache.commons.collections4.keyvalue.MultiKey documentation.
      Example:
      
       def keys = ...
       def multiKey
      
       multiKey = api.multiKey(keys)
       
      Parameters:
      keys - Key values.
      Returns:
      MultiKey composed of the passed ordered key values.
    • localize

      String localize(String key)
      Method designed to prepare a translation key as ready to be internationalized in UI.
      Key can contain only alphanumerics and underscores or SandboxApiException.LocalizeKeyException will be thrown.
      Empty or null key will be translated to {{}}.
      Example:
      
       def result = api.localize('snake_case_key')   // result is equal to '{{snake_case_key}}'
       
      Parameters:
      key - translation key
      Returns:
      proper key translated for the UI usage (wrapped into double curly braces)
      Throws:
      SandboxApiException.LocalizeKeyException - if key contains not allowed signs
      Since:
      14.0 - Caribou Lou
    • roles

      Map<String,String> roles()
      Lists all roles available in the application. Example:
      
       def roles
      
       roles = api.roles()
       
      Returns:
      Map of [roleUniqueName : roleLabel] pairs.
    • entityRef

      String entityRef(PartitionedObject po) throws IllegalAccessException
      Creates an entityRef value (usually db ID) for the given entity. The value can be stored in attributeXX fields and you can set its meta type to ENTITY REFERENCE if you want the UI to show the data as links.
      Example:
      
       def po = ...
       def entityRef
      
       entityRef = api.entityRef(po)
       
      Parameters:
      po - Object of a typedCode P, C, DCR, Q, CT, RBA.
      Returns:
      String that represents the linkable state of the entity.
      Throws:
      IllegalAccessException - If po is of a different typeCode.
    • evalExpression

      double evalExpression(String mathExpression)
      Evaluates an arithmetic expression that is passed as a string.

      Supported operations are:

      • Addition +
      • Subtraction -
      • Multiplication *
      • Division /
      • Exponentiation ^
      • Square root sqrt
      Operator precedence and associativity rules are respected.

      Example:

      
       evalExpression("((10 - 3^2 + 1) * -sqrt(1 * 2 + 3 * 4)) / 4")
       
      Parameters:
      mathExpression - Mathematical expression.
      Returns:
      Result of the expression as a double.
    • setSharedCache

      void setSharedCache(String key, String value)
      Stores a string value in the shared cache with the given key.

      Note the "global" nature of the key.
      Size limit: The maximum recommended key size is 10k bytes.
      Example:

      
       def key = ...
       def value = ...
       def setSharedCache
      
       setSharedCache = api.setSharedCache(key, value)
       
      Parameters:
      key - Cache key.
      value - Value to store.
      See Also:
    • getSharedCache

      String getSharedCache(String key)
      Retrieves a value from the shared cache (and resets the TTL of the key).
      Example:
      
       def key = ...
       def setSharedCache
      
       setSharedCache = api.setSharedCache(key)
       
      Parameters:
      key - Cache key.
      Returns:
      Value or null found in the shared cache.
      See Also:
    • removeSharedCache

      void removeSharedCache(String key)
      Deletes a key from the shared cache.
      Example:
      
       def key = ...
      
       return api.removeSharedCache(key)
       
      Parameters:
      key - Cache key.
      See Also:
    • base64Encode

      String base64Encode(String string)
      Provides a standard Base64 encoding of a string.

      Example:

      
       api.base64Encode("Pricefx") // "UHJpY2VmeA=="
       
      Parameters:
      string - Plain text to be encoded.
      Returns:
      base64 Encoded string.
      See Also:
    • base64Decode

      String base64Decode(String base64String)
      Decodes a base64 encoded string.

      Example:

      
       api.base64Decode("UHJpY2VmeA==") // "Pricefx"
       
      Parameters:
      base64String - Base64 encoded text.
      Returns:
      Plain text string
      See Also:
    • getProductReferences

      List<?> getProductReferences(String typeCode, Set<String> skus)
      Returns a list of product reference records showing which other objects, of the given type, reference these SKUs.
      Example:
      
       def typeCode = ...
       def skus = ...
       def getProductReferences
      
       getProductReferences = api.getProductReferences(typeCode, skus)
       
      Parameters:
      typeCode - Currently, only "Q" or "RBA" are supported.
      skus - Set of SKU strings that should be searched for.
      Returns:
      List of reference records
    • getSkusFromProductGroup

      List<String> getSkusFromProductGroup(ProductGroup pg)
      Returns a list of SKUs based on the definition of the product group.
      Note: If the ProductGroup input map is received from Ember (the former frontend version) then it must be converted to the ProductGroup object using the fromMap() method before it can be used as a parameter for getSkusFromProductGroup().
      This conversion is not needed when there is a React version of the frontend in use.
      Example (fromMap() employed for conversion to the ProductGroup object):
      
        def inputMap = input.ProductGroup
        if (inputMap == null){
          return
        }
      
        def pg = ProductGroup.fromMap(inputMap)
        def skus = api.getSkusFromProductGroup(pg)
      
        return skus
       
      Parameters:
      pg - Product group object.
      Returns:
      List of SKUs.
      Since:
      5.0 - Collins
    • getCustomerIdsFromCustomerGroup

      List<String> getCustomerIdsFromCustomerGroup(CustomerGroup cg)
      Returns a list of Customer IDs based on the definition of the customer group.
      Note: If the CustomerGroup input map is received from Ember (the former frontend version) then it must be converted to the CustomerGroup object using the fromMap() method before it can be used as a parameter for getCustomerIdsFromCustomerGroup().
      This conversion is not needed when there is a React version of the frontend in use.
      Example (fromMap() employed for conversion to the CustomerGroup object):
      
        def inputMap = input.CustomerGroup
        if (inputMap == null){
          return
        }
      
        def cg = CustomerGroup.fromMap(inputMap)
        def customerIds = api.getCustomerIdsFromCustomerGroup(cg)
      
        return customerIds
       
      Parameters:
      cg - Customer group object.
      Returns:
      List of customer IDs.
      Since:
      5.0 - Collins
    • getLocale

      String getLocale()
      Returns the language part of the current request's locale (e.g. "en").
      Example:
      
        return api.getLocale()
       
      Returns:
      Language part string
    • getBaseURL

      String getBaseURL()
      Returns the base URL component of the current instance.

      Example:

      
       api.getBaseURL() // "https://www.pricefx.eu"
       
      Returns:
      Base URL
    • newCreationWorkflow

      CreationWorkflowDefinition newCreationWorkflow()
      Creates the CreationWorkflowDefinition object using the specified steps.
      Available for: Agreements & Promotions (Contracts), Compensation Plans, Quotes, and Rebate Agreements.
      Example (step1, step2, step3 must be already defined within the logic using api.newCreationWorkflowStep()):
      
           return api.newCreationWorkflow()
                     .withSteps(step1, step2, step3)
       
      Returns:
      The CreationWorkflowDefinition object containing the list of steps (CreationWorkflowStepDefinition objects).
      Since:
      3.4.0 - Cuba Libre
      See Also:
    • newCreationWorkflowStep

      CreationWorkflowStepDefinition newCreationWorkflowStep()
      Creates the workflow step (the CreationWorkflowStepDefinition object). The created step can be then added to the Creation Workflow using api.newCreationWorkflow().
      Available for: Agreements & Promotions (Contracts), Compensation Plans, Quotes, and Rebate Agreements.
      Example:
      
       def step1 = api.newCreationWorkflowStep()
               .withLabel("The Step One")
               .withUserAssignees("admin", "john.price")
               .withUserWatchers("john.doe", "anna.broke")
      
       def step2 = api.newCreationWorkflowStep()
               .withLabel("The Step Two")
               .withUserAssignees("admin")
      
       def step3 = api.newCreationWorkflowStep()
               .withLabel("The Step Three")
               .withUserAssignees("admin")
      
       return api.newCreationWorkflow()
               .withSteps(step1, step2, step3)
       
      Returns:
      The CreationWorkflowStepDefinition object.
      Since:
      3.4.0 - Cuba Libre
      See Also:
    • newReviewStep

      ReviewStepDefinition newReviewStep()
    • newReviewByUserGroups

      ReviewByUserGroups newReviewByUserGroups()
    • newReviewSequentialSubSteps

      ReviewUserGroupsSequentialSubSteps newReviewSequentialSubSteps(IsSequentialSubStep... subSteps)
    • newReviewParallelSubSteps

      ReviewUserGroupsParallelSubStep newReviewParallelSubSteps(IsParallelSubStep... subSteps)
    • newReviewSubStep

      ReviewUserGroupSubStep newReviewSubStep()
    • findNextRevUNs

      Map<String,List<String>> findNextRevUNs(String typeCode, String... uniqueNames)
      Finds the next revision uniqueNames for the given Quotes/Contracts/RebateAgreements.
      Example:
      
       def typeCode = ...
       def uniqueNames = ...
       def findNextRevUNs
      
       findNextRevUNs = api.findNextRevUNs(typeCode, uniqueNames)
       
      Parameters:
      typeCode - Can be one of: 'Q', 'CT', 'RBA'.
      uniqueNames - List of uniqueNames.
      Returns:
      Map of [uniqueName : List of nextRevUNs]
    • getClaimContext

      ClaimContext getClaimContext()
      Gives the current item context in a claim validation.
      Example:
      
       def getClaimContext
      
       getClaimContext = api.getClaimContext()
       
      Returns:
      Claim Context instance
    • isFullListCalculation

      Boolean isFullListCalculation()
      Indicates whether the current calculation is recalculating the entire list or only parts of it.

      Note: Currently only applicable for price grid calculations.
      Example:

      
       def isFullListCalculation
      
       isFullListCalculation = api.isFullListCalculation()
       
      Returns:
      True if the entire grid is calculated, false otherwise. null is returned if method is not applicable.
    • triggerPriceGridCalculation

      Long triggerPriceGridCalculation(Long priceGridId, Map<String,Object> parameters)
      Creates a new background calculation job for the specified price grid.
      The job can either perform a full calculation (parameters == null) or a partial calculation.

      For the partial calculation, the parameter "skusToRecalc" should be provided:

      • As a list of SKU strings - when partially calculating a SIMPLE Live Price Grid
        Example:
        
         def priceGridId = output.priceGridInput
         def updatedSKUs = api.find("P", 0, count, "-lastUpdateDate", ["sku"], Filter.isNotNull("sku")).sku
        
         api.triggerPriceGridCalculation(priceGridId, [skusToRecalc: updatedSKUs])
         
      • As a list of lists - when partially calculating a MATRIX Live Price Grid where the secondary key is required
        Example:
        
         def def priceGridId = output.priceGridInput
         def matrixSkusAndKey2 = [["sku00001", "key2"], ["sku00002", "key2"]]
        
         api.triggerPriceGridCalculation(priceGridId, [skusToRecalc: matrixSkusAndKey2])
         

      Note: This operation will only work in contexts that allow object modification (CFS, CalculationFlow and direct logic execution via JSON API).

      Parameters:
      priceGridId - ID of the price grid to calculate.
      parameters - Optional job parameters.
      Returns:
      ID of the created job tracker
      See Also:
    • triggerCFSCalculation

      Long triggerCFSCalculation(Long cfsID)
      Creates a new background calculation job for the specified CFS.

      Note: This operation will only work in contexts that allow object modification (CFS, CalculationFlow and direct logic execution via JSON API).
      Example:

      
       def cfsID = ...
       def triggerCFSCalculation
      
       triggerCFSCalculation = api.triggerCFSCalculation(cfsID)
       
      Parameters:
      cfsID - ID of CalculatedFieldSet.
      Returns:
      ID of the created job tracker
    • currentContext

      Map currentContext()
      Provides a Map of the current execution context info variables.

      The only currently supported variable is commandName that was used to invoke the current logic execution, e.g. "addproducts", "save", "price", "submit", "calculate".

      Currently supported logic contexts are:

      • Quote header
      • Quote item
      • Compensation Plan header
      • Compensation Plan item
      • Contract header
      • Contract item
      • Rebate Agreement header
      • Rebate Agreement item


      Example:
      
       def currentContext
      
       currentContext = api.currentContext()
       
      Returns:
      Context map
    • resetCurrentItemFields

      void resetCurrentItemFields(String... fields)
      Resets specified fields on the currentItem object to null. This applies only to price grid items. Fields that cannot be found on the item are skipped.
      Example:
      
       def fields = ...
      
       return api.resetCurrentItemFields(fields)
       
      Parameters:
      fields - Field names that should be reset.
    • evalProductFilterLogic

      List<Filter> evalProductFilterLogic(String logicName, String logicParam)
      Evaluates the product (group) filter logic.
      Example:
      
       def logicName = ...
       def logicParam = ...
       def evalProductFilterLogic
      
       evalProductFilterLogic = api.evalProductFilterLogic(logicName, logicParam)
       
      Parameters:
      logicName - name of the logic
      logicParam - parameter
      Returns:
      list of filters
    • evalCustomerFilterLogic

      List<Filter> evalCustomerFilterLogic(String logicName, String logicParam)
      Evaluates the customer (group) filter logic.
      Example:
      
       def logicName = ...
       def logicParam = ...
       def evalCustomerFilterLogic
      
       evalCustomerFilterLogic = api.evalCustomerFilterLogic(logicName, logicParam)
       
      Parameters:
      logicName - name of the logic
      logicParam - parameter
      Returns:
      list of filters
    • evalSellerFilterLogic

      List<Filter> evalSellerFilterLogic(String logicName, String logicParam)

      Example:
      
       def logicName = ...
       def logicParam = ...
       def evalSellerFilterLogic
      
       evalSellerFilterLogic = api.evalSellerFilterLogic(logicName, logicParam)
       
      Evaluates the seller (group) filter logic.
      Parameters:
      logicName - name of the logic
      logicParam - parameter
      Returns:
      list of filters
      Since:
      9.0 - Hurricane
    • createOrUpdatePricegridInputAttribute

      Object createOrUpdatePricegridInputAttribute(String fieldName, String elementName, String label, Long priceGridId)
      Creates or updates a user input attribute on an LPG.

      Note: Input attributes are saved to the extension columns (e.g. attribute12) - the same as the output elements. Keep this in mind, so that you do not accidentally overwrite any existing output element. Example:

      
       def fieldName = ...
       def elementName = ...
       def label = ...
       def priceGridId = ...
       def createOrUpdatePricegridInputAttribute
      
       createOrUpdatePricegridInputAttribute = api.createOrUpdatePricegridInputAttribute(fieldName, elementName, label, priceGridId)
       
      Parameters:
      fieldName - Name of field to be used for storing values, e.g. attribute12.
      elementName - Name of the column, e.g. color.
      label - Label of the column, e.g. Color.
      priceGridId - Price grid ID which can usually be obtained by using api.currentItem("id").
      Returns:
      Created or updated attribute
    • removePricegridInputAttribute

      Object removePricegridInputAttribute(Long id)
      Deletes a price grid input attribute. Example:
      
       def id = ...
       def removePricegridInputAttribute
      
       removePricegridInputAttribute = api.removePricegridInputAttribute(id)
       
      Parameters:
      id - Id of the input attribute to delete.
      Returns:
      Deleted attribute object or null if no attrbiute was found.
    • createOrUpdatePricelistInputAttribute

      Object createOrUpdatePricelistInputAttribute(String fieldName, String elementName, String label, Long pricelistId)
      Creates or updates a user input attribute on a price list.

      Note: Input attributes are saved to the extension columns (e.g. attribute12) - the same as the output elements. Keep this in mind, so that you do not accidentally overwrite any existing output element.

      
       def fieldName = ...
       def elementName = ...
       def label = ...
       def priceGridId = ...
       def createOrUpdatePricelistInputAttribute
      
       createOrUpdatePricelistInputAttribute = api.createOrUpdatePricelistInputAttribute(fieldName, elementName, label, priceGridId)
       
      Parameters:
      fieldName - Name of field to be used for storing values, e.g. attribute12.
      elementName - Name of the column, e.g. color.
      label - Label of the column, e.g. Color.
      pricelistId - Price grid ID which can usually be obtained by using api.currentItem("id").
      Returns:
      Created or updated attribute
    • removePricelistInputAttribute

      Object removePricelistInputAttribute(Long id)
      Deletes a price list input attribute. Example:
      
       def id = ...
       def removePricelistInputAttribute
      
       removePricelistInputAttribute = api.removePricelistInputAttribute(id)
       
      Parameters:
      id - Id of the input attribute to delete.
      Returns:
      Deleted attribute object or null if no attribute was found.
    • setPricegridCalculationOutput

      Object setPricegridCalculationOutput(Long pricegridId, String name, String label, String value, String message)
      Sets the PG calculation output that will be shown in the header section after the PG calculation.
      
       def fieldName = ...
       def elementName = ...
       def label = ...
       def priceGridId = ...
       def setPricegridCalculationOutput
      
       setPricegridCalculationOutput = api.setPricegridCalculationOutput(fieldName, elementName, label, priceGridId)
       
      Parameters:
      pricegridId - Price grid ID which can usually be obtained by using api.currentItem("id").
      name - Name of the calculation output, e.g. sales.
      label - Label of the calculation output, e.g. Global Sales.
      value - Calculated value, e.g. €2.3M.
      message - Message containing additional information.
      Returns:
      Saved calculation output
    • removePricegridCalculationOutput

      void removePricegridCalculationOutput(Long pricegridId, String name)
      Removes the PG calculation output. Example:
      
       def pricegridId = ...
       def name = ...
      
       return api.removePricegridCalculationOutput(pricegridId, name)
       
      Parameters:
      pricegridId - Price grid ID which can usually be obtained by using api.currentItem("id").
      name - Name of the calculation output that will be removed.
    • setPricegridCalculationChart

      Object setPricegridCalculationChart(Map<String,?> definition, Long pricegridId)
      Chart definition that will be used to construct and display a Highchart in the header section.
      
       def definition = ...
       def pricegridId = ...
       def setPricegridCalculationChart
      
       setPricegridCalculationChart = api.setPricegridCalculationChart(definition, pricegridId)
       
      Parameters:
      definition - Highchart definition as a map.
      pricegridId - Price grid ID which can usually be obtained by using api.currentItem("id").
      Returns:
      Saved chart definition
    • setPricelistCalculationOutput

      Object setPricelistCalculationOutput(Long pricelistId, String name, String label, String value, String message)
      Sets the PL calculation output that will be shown in the header section after the PL calculation.
      
       def pricelistId = ...
       def name = ...
       def label = ...
       def value = ...
       def message = ...
       def setPricelistCalculationOutput
      
       setPricelistCalculationOutput = api.setPricelistCalculationOutput(pricelistId, name, label, value, message)
       
      Parameters:
      pricelistId - Price list ID which can usually be obtained by using api.currentItem("id").
      name - Name of the calculation output, e.g. sales.
      label - Label of the calculation output, e.g. Global Sales.
      value - Calculated value, e.g. €2.3M.
      message - Message containing additional information.
      Returns:
      Saved calculation output
    • removePricelistCalculationOutput

      void removePricelistCalculationOutput(Long pricelistId, String name)
      Removes the PL calculation output.
      
       def pricelistId = ...
       def name = ...
      
       return api.removePricelistCalculationOutput(pricelistId, name)
       
      Parameters:
      pricelistId - Price list ID which can usually be obtained by using api.currentItem("id").
      name - Name of the calculation output that will be removed.
    • setPricelistCalculationChart

      Object setPricelistCalculationChart(Map<String,?> definition, Long pricelistId)
      Chart definition that will be used to construct and display a Highchart in the header section.
      
       def definition = ...
       def pricelistId = ...
       def setPricelistCalculationChart
      
       setPricelistCalculationChart = api.setPricelistCalculationChart(definition, pricelistId)
       
      Parameters:
      definition - Highchart definition as a map.
      pricelistId - Price list ID which can usually be obtained by using api.currentItem("id").
      Returns:
      Saved chart definition
    • inputBuilderFactory

      InputBuilderFactory inputBuilderFactory()

      Provides factory to build various types of inputs.

      
      
               def factorInput = api.inputBuilderFactory()
                       .createHiddenEntry("Factor")
                       .buildContextParameter()
      
                  def nameInput = api.inputBuilderFactory()
                      .createStringUserEntry("Name")
                      .setLabel("Name")
                      .buildContextParameter()
      
           
      Returns:
      instance of InputBuilderFactory , factory to build inputs
    • newItemRecommendation

      ItemRecommendation newItemRecommendation(String id, Double score)
      Creates and returns a new ItemRecommendation object for Cross-sell and Upsell API.
      Example:
      
       def id = ...
       def score = ...
       def newItemRecommendation
      
       newItemRecommendation = api.newItemRecommendation(id, score)
       
      Parameters:
      id - Item ID, e.g. SKU, an entry with this ID must be present in master data.
      score - Relevancy score, the higher the more relevant.
      Returns:
      Newly created ItemRecommendation object
    • findAttachedDocuments

      @Deprecated List<AttachedDocument> findAttachedDocuments(String typedId, String lineId, Filter... filters)
      Deprecated.
      The Deal Planning module has been discontinued since version 11.3.0.
      Retrieves Plan Specific documents (i.e. Quotes, Contracts, Rebate Agreements, Claims, Deal Plans, Price Lists) attached to a Deal Plan in LargeDealOptimizer.
      Note: This method is intended for attached Plan Specific documents only! To retrieve attached Files, use the String, int, int, String, List, Filter...) method.
      The findAttachedDocuments method does not retrieve Related documents linked to a Deal Plan.
      Parameters:
      typedId - typedId of a entity
      lineId - Id of a line item within the entity specified by typedId, or null if no line item.
      filters - Optional list of filters (that will be evaluated using the AND operator).
      Returns:
      List of AttachedDocument
      Since:
      6.0 - Vesper
    • modelEvaluator

      ModelEvaluator modelEvaluator(String modelName)
      Instantiates a model evaluator, providing access to a previously set up model (DMM).
      Example:
      
       def modelName = ...
       def modelEvaluator
      
       modelEvaluator = api.modelEvaluator(modelName)
       
      Parameters:
      modelName - The model's uniqueName
      Returns:
      A new ModelEvaluator object
    • model

      ModelContext model(String modelUniqueName)
      Provides an API for interacting with an existing model (MO).
      Example:
      
       def modelUniqueName = ...
       def model
      
       model = api.model(modelUniqueName)
       
      Parameters:
      modelUniqueName - The MO's unique name
      Returns:
      An object to interact with the given model.
      Since:
      8.0 Godfather
    • writeKV

      void writeKV(String tableName, Map<String,Object> keys, String jsonPayload)
      Writes a payload string (or overwrites the existing one) into the specified table by means of the primary key. Should be a valid JSON to ensure the compatibility with e.g. JSON API calls.

      Example:

      
       def keys = ["sku": "sku01", "customer": "cus01"]
       def payload = '{"Key1":"value1","key2":"value2","key3":"value3"}'
       def key = api.writeKV("table01", keys, payload)
       return key
       
      Parameters:
      tableName - The name of the table to write into. The table must exist. Keys need to match, otherwise the call will fail.
      keys - Map with key/value pairs for all primary keys as defined in the table.
      jsonPayload - The payload as a valid JSON string.
      Since:
      7.0 Bijou
      See Also:
    • writeKV

      void writeKV(String tableName, Map<String,Object> keys, Object payload)
      Writes a payload (or overwrites the existing one) into the specified table by means of the primary key. The payload will be piped through JSON serialization.

      Example:

      
       def keys = ["sku": "sku01", "customer": "cus01"]
       def payload = ["Key1":"value1","key2":"value2","key3":"value3"]
       def key = api.writeKV("table01", keys, payload)
       return key
       
      Parameters:
      tableName - The name of the table to write into. The table must exist. Keys need to match, otherwise the call will fail.
      keys - Map with key/value pairs for all primary keys as defined in the table.
      payload - The payload object (will be converted to JSON).
      Since:
      7.0 Bijou
      See Also:
    • writeKVBulk

      void writeKVBulk(String tableName, List<String> header, List<List> data)
      Writes larger data sets into the specified table (comparable to loaddata).

      Example:

      
       def header = ["sku", "customer", "payload"]
       def data = [
               [
                       "A1",
                       "83-3126689",
                       "{ ... JSON ... }"
               ],
               [
                       "A1",
                       "45-0245039",
                       "{ ... JSON ... }"
               ],
               [
                       "A2",
                       "02-0995855",
                       "{ ... JSON ... }"
               ]
       ]
       def key = api.writeKVBulk("table01", header, data)
       return key
       
      Parameters:
      tableName - The name of the table to write into. The table must exist. Keys need to match, otherwise the call will fail.
      header - List and order of fields in data. Needs to include all primary keys AND a field called 'payload'.
      data - List of rows to be inserted with values being in order as defined in the header param. Size of row entry always needs to match header definition.
      Since:
      7.0 Bijou
      See Also:
    • getKV

      String getKV(String tableName, Map<String,Object> keys)
      Retrieves a single value ('payload') based on the primary key match.

      Note: Always provide all key/value pairs for each primary key, otherwise the right record might not be returned, and it may cause performance issues. You can retrieve all primary keys using the /kvservice.describetable/{tableName} endpoint.

      CAUTION: The underlying data is stored in a key-value database. As such, this data structure is NOT designed for classic relational SQL queries, although they are possible. In other words, freestyle queries (i.e., anything but full key lookups or lookups that at least fully match a secondary index) work with a small data set, but tend to fail with larger sets (above a total of 10 000 entries).

      Example:

      
       def key = api.getKV("table01", ["sku": "sku01", "customer": "cus01"])
       return key
       
      Parameters:
      tableName - The name of the table to read from.
      keys - Map with key/value pairs for all primary keys as defined in table.
      Returns:
      JSON string of the payload.
      Since:
      7.0 Bijou
      See Also:
    • fetchKV

      List<Map<String,Object>> fetchKV(String tableName, Map<String,Object> filters, int maxRows)
      Retrieves multiple values from the specified table.

      Example (retrieves the maximum of 10 records from the "table01" table where "sku" is equal to "A1"):

      
       def filters = ["sku": "A1"]
       def result = api.fetchKV("table01", filters, 10)
       return result
       
      Parameters:
      tableName - The name of the table to read from.
      filters - Filters in the simple format. Key is the field name. Value is the exact value match. If value starts with a '<' or '>' character a "greater/lesser than" filter is applied.
      maxRows - The number of rows to retrieve. Capped by a system default (specified by maxFetchSize, default is set to 2000).
      Returns:
      The list of objects that match the filter criteria.
      Since:
      7.0 Bijou
      See Also:
    • removeKV

      void removeKV(String tableName, Map<String,Object> keys)
      Removes a single value ('payload') based on the primary key match.

      
       def keys = ["sku": "sku01", "customer": "cus01"]
       def remove = api.removeKV("table01", keys)
       return remove
       
      Parameters:
      tableName - The name of the table to read from.
      keys - Map with key/value pairs for all primary keys as defined in the table.
      Since:
      7.0 Bijou
      See Also:
    • countKV

      long countKV(String tableName)
      Retrieves the count of all keys in table.
      Note: Count is an anti-pattern for a key-value database. This method may return an error for any data sets larger than 10 000 entries. Try to avoid this method outside of development purposes!

      Example:

      
       def keys = api.countKV("table01")
       return keys
       
      Parameters:
      tableName - The table to read from.
      Returns:
      The number of entries/keys as a long.
      Since:
      7.0 Bijou
      See Also:
    • truncateKV

      void truncateKV(String tableName)
      Removes all key values from the specified table.

      
       return truncate = api.truncateKV("table01")
       
      Parameters:
      tableName - The name of the table to truncate.
      Since:
      7.0 Bijou
      See Also:
    • customFormApi

      CustomFormApi customFormApi()
      Returns a CustomFormApi instance for operations related to Custom Forms.
      Returns:
      CustomFormApi
      Since:
      9.0.0
      Example:
      
       def customFormApi
      
       customFormApi = api.customFormApi()
       
      See Also:
    • actionItemApi

      ActionItemApi actionItemApi()
      Returns a ActionItemApi instance for operations related to Action Items and Actionable Insights.

      Note: This operation only works in contexts that allow object modification. This method cannot be used in a distributed calculation. Do not use within the input generation mode.

      Example – creates a new action item:

      
       if (!api.isInputGenerationExecution()) {
      
           def actionItemTypeUN = "actionItemTypeUniqueName"
           def assigneeId = 1168
           def parentTypedId = "123.DP"
      
           def actionItem = api.actionItemApi().newActionItem()
                   .setSummary("summary 1") // required
                   .setType(actionItemTypeUN) // required
                   .setDueDate(new Date().plus(5))
                   .setAssignedTo(assigneeId) // required
                   .setDescription("A description of the Action Item.")
                   .setStatus("OPEN")
                   .setParentTypedId(parentTypedId)
                   .setAttributeExtension(["attribute1": "value1"])
                   .setOriginatorTypedId("123.MO")
                   .setParentTabName("actions")
                   .setSourceContext("""{"foo": "bar"}""")
                   .setTargetContext("""{"foo": "baz"}""")
                   .create()
      
       }
       
      Returns null if operation is not allowed.
      Returns:
      The instance of ActionItemApi.
      Since:
      11.0 - Paper Plane
      See Also:
    • notificationApi

      NotificationApi notificationApi()
      Returns a NotificationApi instance for operations related to Notifications.

      Example:

      
         api.notificationApi()
               .withRecipient(api.user("loginName"))
               .withSuccessStatus()
               .withTitle("The Title")
               .withMessage("Successfully completed!)
               .withSource("2147491340.Q")
               .withContextLink("Products", AppPages.MD_PX_PAGE)
               .send()
       
      Returns:
      NotificationApi
      Since:
      10.0.0
      See Also:
    • contextUUID

      String contextUUID()
      Returns a UUID of the calculation in case of list calculations. In case of a distributed calculation, all distributed threads will have the same UUID as the UUID is based on the job (i.e. JST)
      Example:
      
       def contextUUID
      
       contextUUID = api.contextUUID()
       
      Returns:
      The UUID of the current run. Can be null in various cases