Advanced User Assignment Example - BusinessUnit (Agents)

This example shows how to implement an advanced user-assignment strategy for Agents when the standard fallback assignee and dimension-based assignment options are not sufficient. It demonstrates how to define a custom assignment type, build a read-only configurator for assignment rules, transform the configured values into assignment data, and include a fallback mapping so Actions can still be routed when no specific dimension value matches. This approach extends the Action Definition assignment model with custom logic while preserving the expected behavior of dimension-driven routing and fallback assignment in the Agent summary.

Logic Example

Groovy
import groovy.transform.Field
import net.pricefx.server.dto.calculation.ConfiguratorEntry
import net.pricefx.server.dto.calculation.ContextParameter

@Field String ADVANCED_ASSIGNMENT_NAME = "inputMatrixAssignment"
@Field Map INPUT_COLUMNS = [SEGMENT    : "BusinessUnit",
                            ASSIGNED_TO: "AssignTo"]

ConfiguratorEntry getAssignmentInputs(Map inputParam) {
    //Script actionDefinitionManager = libs.AG_Library.ActionDefinitionManager

    List columns = (INPUT_COLUMNS as Map).values() as List
    ConfiguratorEntry advancedAssignmentEntry = api.createConfiguratorEntry()

    ContextParameter advancedAssignmentParameter = api.inputBuilderFactory()
            .createInputMatrix(ADVANCED_ASSIGNMENT_NAME)
            .setLabel("Custom assignment")
            .setColumns(columns)
            .setReadOnly(true)
            .setEnableAdvancedFilter(false)
            .setEnableClientFilter(false)
            .setHideAddButton(true)
            .buildContextParameter()

    List rows = []
    List segments = ["Beverages", "Foodd"]
    List assigns = ["tram1", "vinh"]
    segments.eachWithIndex { String segment, int index ->
        Map row = [(INPUT_COLUMNS.SEGMENT)    : segments.getAt(index),
                   (INPUT_COLUMNS.ASSIGNED_TO): assigns.getAt(index)]
        rows.add(row)
    }

    Map fallbackRow = [(INPUT_COLUMNS.SEGMENT)    : "*",
                       (INPUT_COLUMNS.ASSIGNED_TO): "tram1"]
    rows.add(fallbackRow)

    advancedAssignmentParameter.setValue(rows)

    advancedAssignmentEntry.createParameter(advancedAssignmentParameter)

    return advancedAssignmentEntry
}

List<Map> getAssignments(Map actionDefinition, List dimensions) {
    //Script actionDefinitionManager = libs.AG_Library.ActionDefinitionManager
    Map actionData = actionDefinition.data
    List assignments = actionData[ADVANCED_ASSIGNMENT_NAME] ?: []
    api.logInfo("--DEBUG:getAdvancedAssignTo-dimensions", dimensions)
    return assignments.collect { Map assignment ->
        Map data = [:]
        String assignTo = getAssignmentAssignTo(assignment)
        data.assignTo = assignTo
        dimensions.each { String dimension ->
            data[dimension] = getCustomerGroupValue(assignment, dimension) ?: "*"
        }

        return data
    }
}

protected String getAssignmentAssignTo(Map assignment) {
    return assignment.getAt(INPUT_COLUMNS.ASSIGNED_TO)
}

protected def getCustomerGroupValue(Map assignment, String dimension) {
    String columName = INPUT_COLUMNS.SEGMENT
    if (dimension.toLowerCase().contains(columName.toLowerCase())) {
        return assignment[columName]
    }

    return null
}

Advanced Configuration Example

JSON
{
  "Custom1": {
    "label": "Custom1",
    "description": "Assigns by dimension-based my custom rules without fallback to default user",
    "enginePath": "libs.AG_ActionAssignment_Lib1.CustomAssignmentStrategy"
  }
}

Logic Description

  • If the current assignment dimensions include BusinessUnit, then Beverages assigns to tram1Foodd assigns to vinh, and anything else falls back to tram1.

  • If the current dimensions do not include BusinessUnit, then every rule becomes all-wildcards, and the matcher will pick the first row by order, which effectively assigns everything to tram1.

  • This strategy does not use the standard assignment type’s separate default-user fallback. Instead it encodes its own fallback row * -> tram1.

Expected Result

Agent_Action_Definition_Step_Add_Action_Menu_Custom1.png