Skip to main content
Skip table of contents

Registration 'Business' Rules Overview

Deep Dive: Overview of the registration rules and their creation

What are Registration Rules

Registration rules are an important aspect of any Learning Suite configuration to automate user related processes to deliver efficiencies. Rules are based on personal attributes and process each time a new user account is created or an existing user is updated. Each rule can have one or more conditions with single/and/or considerations that when met trigger commands. These rules can be quite advanced and are normally managed by Scheer IMC implementation consultants or learning consultants; however, the rules though can be updated by customer System administrators.

Common Registration Rule Use Cases

There are many use cases for registration rules with the most common rules including:

  • Assigning the user to a group

  • Assigning the user to a client

  • Assigning a Job profile to the user

  • Assigning a Certification to the user

  • Granting groups clearance to the user

  • Setting personal attribute values and settings

The purpose of this article will be to provide a detailed overview of the rule formats, the available rule types, understand commonly used basic rules, and explore some advanced rule options.


Checking Registration Rules

The rules are written in xml format and uploaded to the Learning Suite in an xml file. System administrators are able to download the xml file to make changes and re-upload. If making changes it’s recommended to use a tool like Notepad++ to view the rules file as any formatting errors are easily identifiable.

There are two locations where the rule files can be Downloaded/Uploaded as rules can be global (system wide) or client specific.

Global Rules

The Global Registration rules file can be downloaded and uploaded in the Configuration function Import menu. Global rules are processed when there are no client specific rules available or for a global user import job not linked to a specific client.

Configuration_Import_rules_upload.png

Registration rules upload/download field in the Configuration function Import menu

Client Specific Rules

Client specific Registration rules can be uploaded or downloaded in the Clients function Settings tab Import section using the Rules file upload field. These rules are processed for client specific user import or provisioning interfaces (e.g. CSV, SAML, SCIM, OIDC) and when creating/updating users via the GUI in a specific client context.

Client_Settings_Import_Rules_upload.png

Registration rules upload/download field in the Client function Settings tab

Rule Validation

With saving rule files any name can be used and the ability to upload requires the file type to be XML. Once uploaded, the Learning Suite will perform a detailed file validation against a set of XSDs. The check ensures validity of the XML structure and that correct values have been used. If there are errors the file will not be saved, the errors will be displayed on-screen highlighting the line locations of the errors, and the previous rules will remain in place. When uploading rules in the Clients function any errors will be displayed at the top of the tab and will require scrolling up to view.

Registration_rules_validation_error.png

Example of a validation error displayed when saving in a the Client function

Writing Registration Rules

There are three main building blocks of basic registration rules which are the rule, conditions, and commands. More advanced rules usually contain hashtables. Each of these will be covered in detail below. The structure of a typical rule file would look like below with the file always starting with <co:rules> and ending with </co:rules>.

XML
<co:rules>
  <!-- Define hash tables (optional) -->
  <!-- IDENTIFIER is referenced by the command -->
  <co:hashTable identifier="IDENTIFIER" defaultValue="" comment="COMMENT">
    <!-- Statement interacts with system database to retrieve the correct values.
    Selection lists are usually taken -->
    <co:hashTableSelectStatement isIntAttribute="true">
      <!-- Define the hashtable statement to retrieve a value for a given input -->
    </co:hashTableSelectStatement>
  </co:hashTable>
  <!-- Define the rules -->
  <co:rule>
    <co:ruleConditions>
      <!-- Define the conditions for this specific rule: AND, OR or NOT -->
    </co:ruleConditions>
    <!-- Define the command for this specific rule: ASSIGN, SET or GRANT -->
  </co:rule>
  <!-- Define more rules with conditions and commands -->
</co:rules>

The order that rules are written is important as this is the order in which rules will be processed. Comments that are not processed can be entered within rules as information when encased as follows <!-- Comments (optional) - – >.

Rule

Multiple rules can be defined with individual rules (xml-notation: <co:rule>) defined within one xml-tag: <co:rules>. This means the xml file would start with the tag <co:rules> and end with the tag </co:rules> with all individual rules <co:rule> </co:rule> defined in between. Each individual rule must start with the tag <co:rule> and end with the tag </co:rule>. The following sections will explain the various options available for Conditions, Commands, and HashTables.

LS_Registration-Rules_Structure.png

Logical structure of a rules file and rules within

Conditions

Each rule may contain singular or multiple conditions (AND / OR) that need to be satisfied in order to execute the rule. The conditions are personal attribute based and serve as filter to minimise the number of commands that need to be executed. These conditions are the most complex aspect of the rule given the number of available attributes to include and comparison operators. Only if the condition resolves to TRUE, the subsequent command is executed.

Not all rules require conditions. For example; blanket rules are often used to assign all users to a specific group or grant clearance to specific groups on all users. Rules relating to hashTables also might only contain commands.

Condition Attributes

The Conditions can contain the following attributes:

Attribute

Explanation

Usage

expression

Defines the attribute in which a value is to be checked. The attribute database name is required.

required

matching

Defines the logic in which the attribute is to be checked (see Comparison operators)

required

value

Defines the value against which the attribute should be checked

optional

mode

  • VALUE: Value is entered in the value attribute (default)

  • REFERENCE: Attribute name referring to the value is entered in the value attribute

listSeparator

Only possible with attribute matching = INLIST or HASELEMENT

Separation symbol of a list

comment

Comment for the rule for human understanding

optional

Comparison Operators

There are many comparison operators, or Expression types, available for conditions that are defined after the expression in the matching attribute. These define the type of comparison between expression and value.

Operator

Comment

Example

EQUAL

Returns true if expression is equal to the value.

Strings are transformed to lower case.

CODE
<co:ruleCondition expression="ATTRIBUTE_NAME" matching="EQUAL" value="3"/>

UNEQUAL

Opposite of EQUAL.

CODE
<co:ruleCondition expression="ATTRIBUTE_NAME" matching="UNEQUAL" value="3"/>

GREATER

Returns true if expression is greater than the value.

These are used for integer values and dates.

CODE
<co:ruleCondition expression="ATTRIBUTE_NAME" matching="GREATER" value="3"/>

SMALLER

Returns true if expression is smaller than value.

These are used for integer values and dates.

CODE
<co:ruleCondition expression="ATTRIBUTE_NAME" matching="SMALLER" value="3"/>

ISEMPTY

Return true if expression has no value (null).

CODE
<co:ruleCondition expression="ATTRIBUTE_NAME" matching="ISEMPTY"/>

ISNOTEMPTY

Opposite of ISEMPTY.

CODE
<co:ruleCondition expression="ATTRIBUTE_NAME" matching="ISNOTEMPTY"/>

EXISTS

Returns true if attribute referenced in expression exists.

CODE
<co:ruleCondition expression="ATTRIBUTE_NAME" matching="EXISTS"/>

NOTEXISTS

Opposite of EXISTS.

CODE
<co:ruleCondition expression="ATTRIBUTE_NAME" matching="NOTEXISTS"/>

HASELEMENT

Returns true if value is a part of a list in expression.

CODE
<co:ruleCondition expression="ATTRIBUTE_NAME" matching="HASELEMENT" value="EL2" listseperator=";"/>

INLIST

Similar to HASELEMENT. The attribute listSeparator needs to define how list elements are separated.

CODE
<co:ruleCondition expression="ATTRIBUTE_NAME" matching="INLIST" value="EL1;EL2;EL3" listseperator=";"/>

HASSUBSTRING

Returns true if the value string is included in the expression string.

CODE
<co:ruleCondition expression="ATTRIBUTE_NAME" matching="HASSUBSTRING" value="RIN"/>

STARTSWITH

Returns true if the expression string starts with the value string

CODE
<co:ruleCondition expression="ATTRIBUTE_NAME" matching="STARTSWITH" value="STR"/>

ENDSWITH

Returns true if the expression string ends with the value string

CODE
<co:ruleCondition expression="ATTRIBUTE_NAME" matching="ENDSWITH" value="ING"/>

Single Condition

Rules with a single condition only have the tags <co:ruleConditions> and </co:ruleConditions> with a <co:ruleCondition expression=" " matching " " /> in between.

XML
<!-- Registration rule: single Condition -->
<co:rule>
  <co:ruleConditions>
    <co:ruleCondition expression="ATTTRIBUTE_NAME" matching="EQUAL" value=" "/>
  </co:ruleConditions>
  <!-- Define the commands: ASSIGN, SET or GRANT -->
</co:rule>

andCondition

The andCondition enables multiple conditions and require that each must be TRUE. Rules with andConditions will have the tag <co:ruleConditions>, followed by <co:andCondition>, then multiple tags for each <co:ruleCondition expression=” ” matching=“ “ />, then a closing </co:andCondition>, and a closing </co:ruleConditions>.

LS_Registration-Rules_andCondition.png

In the example below, the user has to be:

  • In a specific COUNTRY (e.g. Germany with the ID 82); AND

  • Have a certain POSITION within the company (e.g. Sales manager in a custom selection list).

Only if all conditions resolve to true, the command(s) will be executed.

XML
<!-- Registration rule: andCondition-->
<co:rule>
  <co:ruleConditions>
  <!-- ALL conditions must resolve to TRUE -->
    <co:andCondition>
      <co:ruleCondition expression="COUNTRY" matching="EQUAL" value="82"/>
      <co:ruleCondition expression="POSITION" matching="EQUAL" value="3"/>
    </co:andCondition>
  </co:ruleConditions>
  <!-- Define the commands: ASSIGN, SET or GRANT -->
</co:rule>

orConditions

The orCondition enables multiple conditions and requires at least one to be TRUE. Rules with orConditions will have the tag <co:ruleConditions>, followed by <co:orCondition>, then multiple tags for each <co:ruleCondition expression=” ” matching=“ “/>, then a closing </co:orCondition>, and a closing </co:ruleConditions>.

LS_Registration-Rules_orCondition.png

In the example below, the user has to have one of three phrases in their JOB_TITLE to be true. If one of the conditions resolve to true, the command(s) will be executed.

XML
<!-- Registration rule: orCondition-->
<co:rule>
  <co:ruleConditions>
    <!-- ONE condition must resolve to TRUE -->
    <co:orCondition>
      <co:ruleCondition expression="JOB_TITLE" matching="HASSUBSTRING" value="Manager"/>
      <co:ruleCondition expression="JOB_TITLE" matching="HASSUBSTRING" value="Supervisor"/>
      <co:ruleCondition expression="JOB_TITLE" matching="HASSUBSTRING" value="Head of"/>
	</co:orCondition>
  </co:ruleConditions>
  <!-- Define the commands: ASSIGN, SET or GRANT -->
</co:rule>

Commands

Each rule contains one or more 'command' tags to execute the defined action if the conditions are met. The command tags start with the type (assign, set, grant), then contain a context ('client', ‘group’, ‘certification’, ‘job profile’), followed by a target and then possibly some optional attributes.

LS_Registration-Rules_command-types.png

The three Command types available

assignCommand Tags

The assignCommand tags are used to either assign the user to a group, assign the user to a client, assign a job profile to the user, or assign a certification to the user. These commands always start with <co:assignCommand and then set the desired context. The selected context then determines which of the following attributes are to be included.

Attribute

Values

Comment

context

  • CLIENT

  • GROUP

  • CERTIFICATION

  • JOBPROFILE

The context SKILL is not available.

target

Id of the client, group, certification or job profile.

Is influenced by mode

REQUIRED

mode

  • VALUE: Id is referenced

  • REFERENCE: Name of an attribute containing the id is referenced.

execute

  • ONCE: Assignment is executed as if manually in backend. (ls_importsource=0)

  • ALWAYS: Assignment gets marked as imported (ls_importsource=1)

ONCE sees the assignment processed only on first save. ALWAYS see all imported assignments deleted with each new save or import.

Registration rules for context Certification have behaviour differences with execute:

  • The context does not work with execute="ALWAYS". This means if an attribute indicates that the certification is no longer available, the certification will not be removed.

  • It is required to define execute="ONCE" as the default value would be execute="ALWAYS".

type

Used to assign to BU group with value SUPERVISOR, DUPUTY1, DEPUTY2

Used for assigning users to BU groups with specific role. DEPUTY2 has no access.

hashident

Reference to the hashtable if a hashtable is used.

index

Input value for hashtables

comment

Comment for the rule for human understanding

Assigning the User to a Group

The assignCommand will have the context equal GROUP and the target being the object ID of the group.

XML
<!-- Registration rule: assignCommand Group-->
<co:rule>
  <co:ruleConditions>
	<co:ruleCondition expression="EMPLOYEE_ID" matching="ISEMPTY" mode="VALUE"/>
  </co:ruleConditions>
  <co:assignCommand context="GROUP" target="239225" execute="ALWAYS"/>
</co:rule>

Assigning a Job Profile to a User

The assignCommand will have the context equal JOBPROFILE and the target being the object ID of the job profile.

XML
<!-- Registration rule: assignCommand Job profile-->
<co:rule>
  <co:ruleConditions>
    <co:ruleCondition expression="IS_IMC_PARTNER" matching="EQUAL" value="1"/>
  </co:ruleConditions>
  <co:assignCommand context="JOBPROFILE" target="231913" execute="ALWAYS"/>
</co:rule>

Assigning a Certification to a User

The assignCommand will have the context equal ”CERTIFICATION” and the target being the object ID of the Certification.

XML
<!-- Registration rule: assignCommand Certification-->
<co:rule>
  <co:ruleConditions>
    <co:ruleCondition expression="DEPARTMENT" matching="EQUAL" value="Accounts"/>
  </co:ruleConditions>
  <co:assignCommand context="CERTIFCATION" target="235657" execute="ONCE"/>
</co:rule>

GRANT Commands

Grant commands are used to provide Clearances on the user to a Group or Client. The level of Clearance can be Full, View (Execute) or a binary combination of specific authentications. These commands will always start with <co:grantCommand followed by the desired context (Group or Client) and the target containing the Object ID. The value attribute determines the level of Clearance which can be _full or _view.

Attribute

Values

Comment

context

  • CLIENT

  • GROUP

target

Object ID of the Client or Group.

REQUIRED

value

  • _full: Unrestricted clearance to user

  • _view: Only Execute clearance to user

execute

  • ONCE: Assignment is executed as if manually in backend. (ls_importsource=0)

  • ALWAYS: Assignment gets marked as imported (ls_importsource=1)

ONCE sees the assignment processed only on first save. ALWAYS see all imported assignments deleted with each new save or import.

comment

Comment for the rule for human understanding

Granting Clearance to a Group

To grant clearance on the user to a Group requires the context to equal GROUP with the target being the Object ID of the group.

XML
<!-- Registration rule: grantCommand Group-->
<co:rule>
  <co:ruleConditions>
	<co:ruleCondition expression="EMPLOYEE_ID" matching="ISEMPTY" mode="VALUE"/>
  </co:ruleConditions>
  <co:grantCommand context="GROUP" target="239227" value="_full" execute="ALWAYS"/>
</co:rule>

setCommand Tags

setCommand tags are used to populate a Personal attribute based on the value of another Personal attribute. For example, most rules would set the CLIENT_ID of the user to define their Master client. These commands will always start with <co:setCommand and then set the desired target which is a Personal attribute database name. The following attributes are possible with setCommands:

Attribute

Values

Comment

target

Personal attribute database name

REQUIRED

value

Value to be entered for the target attribute

When referencing another attribute the other attribute database name is entered.

When relating to a hash table the value _hashval is used.

mode

  • VALUE: ID is referenced

  • REFERENCE: Name of an attribute containing the ID is referenced

hashident

Identifier of a hash table to be used with the rule.

Normally used for special conversions

index

Personal attribute database name to be used for the hash table query.

Below is a basic setCommand based on a single ISEMPTY condition to set a personal attribute value. This is a standard rule in all vanilla configurations.

XML
<!-- Set MAIN CLIENT if client_id of user is empty -->
<co:rule>
  <co:ruleConditions>
    <co:ruleCondition expression="CLIENT_ID" matching="ISEMPTY"/>
  </co:ruleConditions>
  <co:setCommand target="CLIENT_ID" value="1"/>
</co:rule>  

HashTables

HashTables are used in advanced rules to map input to output values and must be defined prior to inclusion in rules. A hashTable must contain a unique identifier, a default value, and either hashTable rows with input to output relations or a single SQL statement.

LS_Registration-Rules_Hashtable.png

Some examples of hashTable uses include:

  • Getting time zone for given countries

  • Getting BU groups based on Department or Division attribute

  • Translating input values (e.g. male / female → 1 / 2)

XML
<co:rules>
  <co:hashTable identifier="GROUPBYCOUNTRY" defaultValue="0" comment="Get group based on country">
    <co:hashTableRow index="VA" value="1" comment="Status aktiv fuer Wert VA"/>
    <co:hashTableRow index="VI" value="2" comment="Status passiv fuer Wert VI"/>
    <co:hashTableRow index="VBO" value="2" comment="Status passiv fuer Wert VBO"/>
  </co:hashTable>
  <co:rule>
    <!-- Conditions and Commands -->
  </co:rule>
</co:Rules>

Element: hashTable

The following attributes are available for a hashTable:

Attribute

Description

Scope

identifier

Unique name to be referenced by the hashident attribute of a command

required

default value

required

comment

optional

Element: hashTableRow

HashTableRows are used to generate the input-output mapping. Each row represents one tuple (input-value, output-value). These rows are commonly to convert field input from an external system to match an equivalent personal attribute in the Learning Suite; For example converting a text string to the correlating selection list ID in the Learning Suite.

Attribute

Description

Scope

index

Unique input value

required

value

Output value

required

comment

optional

Element: hashTableSelectStatement

Any SQL-Query can be utilised which returns one single value. The input value is provided by the index which refers to the hashTable. In the SQL-Statement the index is placed by a questionmark "?". Only one questionmark is allowed in the SQL-statement.

Attribute

Description

isIntAttribute

Defines whether the input value is a numerical value or not (string)

Default = false (string)

comment

optional to describe the statement

Calling HashTable from Commands

A hashTable can be called from any command as it merely provides a value.

  • The target indicates that the value will be retrieved by a hashTable.

  • The index represents the input value for the hashTable.

  • The hashident needs to be equivalent to the identifier of the hashTable and represents the table in which the output value will be mapped.

In the example below the assignCommand has the target “_hashval” to call a hashTable and the hashident “GROUPBYCOUNTRY” identifies the specific hashTable to call. In a rules file the hashTable and the rule may often be separated.

XML
<co:rules>
  <co:hashTable identifier="GROUPBYCOUNTRY" defaultValue="0" comment="Get group based on country">
     <co:hashTableRow index="VA" value="1" comment="Status aktiv fuer Wert VA"/>
        <co:hashTableRow index="VI" value="2" comment="Status passiv fuer Wert VI"/>
        <co:hashTableRow index="VBO" value="2" comment="Status passiv fuer Wert VBO"/>
  </co:hashTable>
  <co:rule>
    <co:assignCommand context="GROUP" target="_hashval" index="COUNTRY_ID" hashident="GROUPBYCOUNTRY"/>
  </co:rule>
</co:Rules>

Rule Examples

This section will provide some commonly used examples of basic and advanced rules. These examples will put the above theory into practical examples that can be adjusted used as a basis for similar needs.

Basic Rule Examples

Standard Rules

A standard Learning Suite system prior to configuration would contain the following rules. Comments have been included above each rule to describe their purpose.

XML
<co:rules>
  <!-- In a single client system this sets the CLIENT_ID Personal attribute  -->
  <co:rule>
    <co:setCommand target="CLIENT_ID" value="1"/>
  </co:rule>

  <!-- In a multi client system this sets the CLIENT_ID Personal attribute to 1 if there is no CLIENT_ID set -->
  <co:rule>
    <co:ruleConditions>
		<co:ruleCondition expression="CLIENT_ID" matching="SMALLER" value="1"/>
    </co:ruleConditions>
    <co:setCommand target="CLIENT_ID" value="1"/>
  </co:rule>

  <!-- In a single client system assigns all users to Client with ID 1 -->
  <co:rule>
    <co:assignCommand context="CLIENT" target="CLIENT_ID" mode="REFERENCE"/>
  </co:rule>

  <!-- Generic rule that populates the USER_ID personal attribute if empty with the value generated in the PERSON_ID personal attribute -->
  <co:rule>
    <co:ruleConditions>
		<co:ruleCondition expression="USER_ID" matching="ISEMPTY" mode="VALUE"/>
    </co:ruleConditions>
    <co:setCommand target="USER_ID" value="PERSON_ID" mode="REFERENCE"/>
  </co:rule>

  <!-- Gives clearances on users to the creator and the System administrator group which has Object ID 1 -->
  <co:rule>
    <co:grantCommand context="OWNER" target="_creator" execute="ALWAYS"/>
    <co:grantCommand context="GROUP" target="1" value="_full" execute="ALWAYS"/>
  </co:rule>

  <!-- Assigns all users to the Student group which has Object ID 3 -->
  <co:rule>
    <co:assignCommand context="GROUP" target="3" execute="ALWAYS"/>
  </co:rule>
</co:rules>

Group Assignments

EQUAL Condition Group Assignment

The assignment of users to a specific group is common by using EQUAL operator with a Personal attribute. The value could be a string or an ID of a selection list entry or checkbox.

XML
<co:rule>
  <co:ruleConditions>
    <co:ruleCondition expression="COUNTRY_ID" matching="EQUAL" value="82"/>
  </co:ruleConditions>
  <co:assignCommand context="GROUP" target="231656" execute="ALWAYS"/><!--German learners-->
</co:rule>
ISEMPTY Condition Group Assignment

The assignment of users to an external learner group is common by using ISEMPTY operator with a Personal attribute that would only be populated for internal learners.

XML
<co:rule>
  <co:ruleConditions>
    <co:ruleCondition expression="EMPLOYEE_ID" matching="ISEMPTY" mode="VALUE"/>
  </co:ruleConditions>
  <co:assignCommand context="GROUP" target="239225" execute="ALWAYS"/><!--External-->
</co:rule>
orCondition Group Assignment

The rule below assigns the user to the Supervisor group (ID 9) if the POSITION_TITLE personal attributes contains the words Manager or Supervisor.

XML
<co:rule>
  <co:ruleConditions>
    <co:orCondition>
      <co:ruleCondition expression="POSITION_TITLE" matching="HASSUBSTRING" value="Manager"/>
      <co:ruleCondition expression="POSITION_TITLE" matching="HASSUBSTRING" value="Supervisor"/>
    </co:orCondition>
  </co:ruleConditions>
  <co:assignCommand context="GROUP" target="9" execute="ALWAYS"/>
</co:rule>
Group Assignment by Checkbox

Another common assignCommand method uses the creation of checkboxes on the backend user profile to assign users to groups. In this example there would be a custom checkbox personal attribute that if ticked (value = 1) would assign the user to the Group with ID 1, Client with ID 1 and Client with ID 2.

XML
<co:rule>
  <co:ruleConditions>
	<co:ruleCondition expression="IS_SYSTEMADMIN" matching="EQUAL" value="1"/>
  </co:ruleConditions>
  <co:assignCommand context="GROUP" target="1" execute="ALWAYS"/>
  <co:assignCommand context="CLIENT" target="1" execute="ALWAYS"/>
  <co:assignCommand context="CLIENT" target="2" execute="ALWAYS"/>
</co:rule>

grantCommand for Specific Users

The rule below is commonly used for systems that contain external learners. The rule assigns the user to an External learner group and grants clearance to an External Admin group (ID 239227) if the EMPLOYEE_ID attribute is empty. In this example the Content admin group (ID 11) also receives view clearance. The custom personal attribute EMPLOYEE_ID is often substituted with the standard EXT_ID_CSV or an alternative standard unique identifier populated via an automated user import.

XML
<co:rule>
  <co:ruleConditions>
    <co:ruleCondition expression="EMPLOYEE_ID" matching="ISEMPTY" mode="VALUE"/>
  </co:ruleConditions>
  <co:assignCommand context="GROUP" target="239225" execute="ALWAYS"/><!--External-->
  <co:grantCommand context="GROUP" target="239227" value="_full" execute="ALWAYS"/><!--External Admin-->
  <co:grantCommand context="GROUP" target="11" value="_view" execute="ALWAYS"/><!--Content Admin-->
</co:rule>

Other examples of such rules could be providing a group that represents a company Department, Team or Location clearance on users within their group. These rules are often written where proxy enrolments are enabled.

XML
<co:rule>
	<co:ruleConditions>
		<co:ruleCondition expression="DEPARTMENT" matching="EQUAL" value="Operations"/>
	</co:ruleConditions>
	<co:assignCommand context="GROUP" target="242815" execute="ALWAYS"/><!--Operations-->
	<co:grantCommand context="GROUP" target="242815" value="_view" execute="ALWAYS"/><!--Operations-->
</co:rule>

setCommands to Populate Personal Attributes

The use of setCommands are often used for populating personal attributes that have functional settings. This can happen as an external source system may have an equivalent setting with different values. For example, the external system might have a STATUS field with values Active/Terminated which is the equivalent of the Learning Suite’s AUTHENTIFICATIONSTATUS_ID that requires values 1 (Active) or 2 (Passive). In this case a custom STATUS personal attribute could be created along with basic rules to set AUTHENTIFICATIONSTATUS_ID based on the STATUS.

XML
<co:rule>
  <co:ruleConditions>
    <co:ruleCondition expression="STATUS" matching="EQUAL" value="Active"/>
  </co:ruleConditions>
  <co:setCommand target="AUTHENTIFICATIONSTATUS_ID" value="1"/>
</co:rule>

<co:rule>
  <co:ruleConditions>
    <co:ruleCondition expression="STATUS" matching="EQUAL" value="Terminated"/>
  </co:ruleConditions>
  <co:setCommand target="AUTHENTIFICATIONSTATUS_ID" value="2"/>
</co:rule>

Reference Rules

Reference rules are commonly used to fill empty personal attributes with the value from another personal attribute. In the example rule below a user that has no EXT_ID_CSV and has IS_CONTRACTOR ticked would have the EXT_ID_CSV populated with the value from their LOGIN.

XML
<co:rule>
  <co:ruleConditions>
    <andCondition>
      <co:ruleCondition expression="EXT_ID_CSV" matching="ISEMPTY"/>
      <co:ruleCondition expression="IS_CONTRACTOR" matching="EQUAL" value="1"/>
    </andCondition>
  </co:ruleConditions>
  <co:setCommand target="EXT_ID_CSV" value="LOGIN" mode="REFERENCE"/>
</co:rule>

In the example below a checkbox POSTAL_SAME_AS_RES could be used on a frontend user profile or enrolment form after some Residential address personal attributes. If the user ticks the checkbox the rule would populate Postal address personal attributes with values from the equivalent Residential address personal attributes.

XML
<co:rule>
  <co:ruleConditions>
    <co:ruleCondition expression="POSTAL_SAME_AS_RES" matching="EQUAL" value="1"/>
  </co:ruleConditions>
  <co:setCommand target="POSTAL_STREET_NUMBER" value="RES_STREET_NUMBER" mode="REFERENCE"/>
  <co:setCommand target="POSTAL_STREET" value="RES_STREET" mode="REFERENCE"/>
  <co:setCommand target="POSTAL_SUBURB" value="RES_SUBURB" mode="REFERENCE"/>
  <co:setCommand target="POSTAL_POSTCODE" value="RES_POSTCODE" mode="REFERENCE"/>
</co:rule>

Advanced Rule Examples

Many customers will have advanced rules that use HASH tables to perform tasks such as look-ups and conversions.

Look up Selection List Value IDs

Look-ups use hashTables to index an input value to another output value. These are commonly used for user imports that import values to selection list personal attributes and the source system does not contain the selection list value IDs. In the example below hashTableRow mappings are defined where the index is what is sent by the source system and the value is the selection list value ID. The bottom line is not actually part of the rule file and is just to show the import mapping that references the hashTable with the hashident.

XML
<!-- Mapping selection list keys to values -->
<co:hashTable identifier="Title" defaultValue="0">
  <co:hashTableRow index="Mr" value="1"/>
  <co:hashTableRow index="Mrs" value="2"/>
  <co:hashTableRow index="Miss" value="3"/>
  <co:hashTableRow index="Ms" value="4"/>
  <co:hashTableRow index="Dr" value="5"/>
</co:hashTable>

<!-- mapping line from CSV import -->
<mapping sourceField="Title" clixField="TITLE" hashident="Title"/>

The next example is a more dynamic selection list lookup as no actual hashTableRow mapping is required. Instead an SQL statement is used in the hashTable that selects the LMS selection list value ID where a match is found to the external_id (key) in the selection table that is used in the selection list attributes. When creating a selection list the external_id (key) can be imported or manually set and would normally match what is contained in the source system. This example represents finding a LOCATION selection list value ID by the external_id (key). The bottom line is not actually part of the rule file and is just to show the import mapping that references the hashTable with the hashident.

XML
<co:hashTable identifier="MapLocationKeyWithId" defaultValue="0" comment="Maps key to ILS ID">
  <co:hashTableSelectStatement isIntAttribute="false">select max(id) from CUST_P_CURRENTLOCATION where external_id = ?</co:hashTableSelectStatement>
</co:hashTable>

<!-- mapping line from CSV import -->		
<mapping sourceField="CURRENT_LOCATION" clixField="LOCATION" hashident="MapLocationKeyWithId"  ignoreEmptyField="false"/>

Look up BU Group ID to Assign Users

The hashTable and assignCommand rule examples below can be used to dynamically assign users to business unit groups. Assign commands for groups are based on the LMS Object ID and this hashTable statement essentially finds the Object ID based on looking up the External ID. In the assignCommand rules the index is the personal attribute that would normally contain values matching the External ID of the BU groups when imported. Such rules are commonly used for customers that are able to import BU group structures in CSV files or import structures via XML file but not able to directly assign users.

XML
<co:hashTable identifier="ORG_MAPPING" defaultValue="0" comment="maps section ids">
  <co:hashTableSelectStatement isIntAttribute="false">SELECT GROUP_ID FROM PLATFORMGROUP WHERE EXTERNAL_OBJECT_ID =?</co:hashTableSelectStatement>
</co:hashTable>
			
<co:rule>
  <co:assignCommand context="GROUP" target="_hashval" hashident="ORG_MAPPING" index="DIVISION" execute="ALWAYS" /> 
</co:rule>

<co:rule>
  <co:assignCommand context="GROUP" target="_hashval" hashident="ORG_MAPPING" index="UNIT" execute="ALWAYS" /> 
</co:rule>
		
<co:rule>
  <co:assignCommand context="GROUP" target="_hashval" hashident="ORG_MAPPING" index="TEAM" execute="ALWAYS" /> 
</co:rule>

Assign User as Supervisor to BU Group

With rules it's also possible to assign users to BU groups with a Supervisor or Deputy role. The following example uses a hashTable to get the GROUP_ID of the BU group based on EXTERNAL_OBJECT_ID value, then the rule identifies if the user has a specific POSITION_TITLE to action an assignCommand that on the hashTable indexing the TEAM personal attribute value.

XML
<co:hashTable identifier="ORG_MAPPING" defaultValue="0" comment="maps section ids">
  <co:hashTableSelectStatement isIntAttribute="false">SELECT GROUP_ID FROM PLATFORMGROUP WHERE EXTERNAL_OBJECT_ID =?</co:hashTableSelectStatement>
</co:hashTable>

<co:rule>
  <co:ruleConditions>
    <co:orCondition>
      <co:ruleCondition expression="POSITION_TITLE" matching="HASSUBSTRING" value="Manager"/>
      <co:ruleCondition expression="POSITION_TITLE" matching="HASSUBSTRING" value="Supervisor"/>
    </co:orCondition>
  </co:ruleConditions>
  <assignCommand context="GROUP" target="_hashval" hashident="ORGUNIT" index="TEAM" type="SUPERVISOR" execute="ALWAYS" />
</co:rule>

<co:rule>
  <co:ruleConditions>
    <co:ruleCondition expression="POSITION_TITLE" matching="HASSUBSTRING" value="2IC"/>
  </co:ruleConditions>
  <assignCommand context="GROUP" target="_hashval" hashident="ORGUNIT" index="TEAM" type="DEPUTY1" execute="ALWAYS" />
</co:rule>

Look up Job Profile ID to Assign Users

The hashTable and assignCommand rule examples below can be used to dynamically assign Job profiles to users based on a match. assignCommands for Job profiles are based on the LMS Object ID and this hashTable statement essentially finds the Job profile with a matching name to a personal attribute value. In the assignCommand rule the index is the personal attribute that would contain values matching the Job profile names. Such rules are commonly used for customers with the Skills & competencies add-on module to automatically assign specific Job profiles containing required skills to achieve.

XML
<co:hashTable identifier="MapJP" defaultValue="0" comment="Maps Job Profiles to users">
	<co:hashTableSelectStatement isIntAttribute="false">SELECT max(role_id) FROM role_description WHERE name = ? AND language_id = 27</co:hashTableSelectStatement>
</co:hashTable>

<co:rule>
  <co:assignCommand context="JOBPROFILE" target="_hashval" index="POSITION_TITILE" hashident="MapJP" execute="ALWAYS"/>
</co:rule>

Look up Supervisor

To establish one to one supervisor relationships the Learning Suite uses the SUPERVISOR_EMAIL personal attribute. The logic essentially finds the user who’s EMAIL matches the value entered in the SUPERVISOR_EMAIL of the user and creates the link. As many source systems used to create user accounts do not have such a Supervisor Email field, alternative rules are often required. In the example below custom EMPLOYEE_ID and MANAGER_ID personal attributes contain the relationship. The hashTables use the custom personal attribute value to find details of the supervisor in the system. The setCommand rules then populate the standard Supervisor personal attributes based on the hashTable locating a user with the matching value to the custom personal attribute.

XML
<!-- People Leader Assignments: -->
<!-- SUPERIROR_EMAIL -->
<co:hashTable identifier="SUP_EMAIL" defaultValue="" comment="Gets the Supervisor Email Address from the MANAGER_ID input which is matched against the EMPLOYEE_NUMBER of the Supervisor">
	<co:hashTableSelectStatement isIntAttribute="false">select P.EMAIL FROM PERSON P, PERSON_CUSTOM PC WHERE P.EXTERNAL_ID = ?</co:hashTableSelectStatement>
</co:hashTable>

<!-- SUPERIROR_FIRSTNAME -->
<co:hashTable identifier="SUP_FIRST" defaultValue="" comment="Gets the Supervisor First Name from the MANAGER_ID input which is matched against the MOE EMPLOYEE_NUMBER of the Supervisor">
	<co:hashTableSelectStatement isIntAttribute="false">select P.FIRSTNAME FROM PERSON P, PERSON_CUSTOM PC WHERE P.EXTERNAL_ID = ?</co:hashTableSelectStatement>
</co:hashTable>

<!-- SUPERIROR_LASTNAME -->
<co:hashTable identifier="SUP_LAST" defaultValue="" comment="Gets the Supervisor Last Name from the MANAGER_ID input which is matched against the MOE EMPLOYEE_NUMBER of the Supervisor">
	<co:hashTableSelectStatement isIntAttribute="false">select P.LASTNAME FROM PERSON P, PERSON_CUSTOM PC WHERE P.EXTERNAL_ID = ?</co:hashTableSelectStatement>
</co:hashTable>
			
<co:rule>
	<co:ruleConditions>
		<co:ruleCondition expression="MANAGER_ID" matching="ISNOTEMPTY"/>
	</co:ruleConditions>
	<co:setCommand target="SUPERIOR_EMAIL" value="_hashval" hashident="SUP_EMAIL" index="MANAGER_ID" />
	<co:setCommand target="SUPERIOR_FIRSTNAME" value="_hashval" hashident="SUP_FIRST" index="MANAGER_ID" />
	<co:setCommand target="SUPERIOR_LASTNAME" value="_hashval" hashident="SUP_LAST" index="MANAGER_ID" />
</co:rule>
<!-- End People Leader Assignments -->

Country, Language and Time Zone Mappings

Many customers, like Scheer imc, are multi-national with offices in multiple countries. This means the Learning Suite would likely be configured with multiple languages and user specific time zones. Rules can efficiently set personal attribute values for the users' Country, Preferred language, and Time zone. Rules are normally required as different user data source systems hold different values.

Country Code Mapping

Below is an example of a hashTable that maps iso country codes from a source system to the corresponding country IDs in the Learning Suite COUNTRY_ID selection list personal attribute.

XML
<co:hashTable identifier="COUNTRY_MAP" defaultValue="0" comment="Mapping of iso code to country id">
  <co:hashTableRow index="DE" value="82" comment="Germany"/>
  <co:hashTableRow index="Germany" value="82" comment="Germany"/>
  <co:hashTableRow index="GERMANY" value="82" comment="Germany"/>
  <co:hashTableRow index="DEUTSCHLAND" value="82" comment="Germany"/>
  <co:hashTableRow index="Deutschland" value="82" comment="Germany"/>
  <co:hashTableRow index="CH" value="209" comment="Switzerland"/>
  <co:hashTableRow index="Switzerland" value="209" comment="Switzerland"/>
  <co:hashTableRow index="RO" value="180" comment="Romania"/>
  <co:hashTableRow index="RU" value="180" comment="Romania"/>
  <co:hashTableRow index="Romania" value="180" comment="Romania"/>
  <co:hashTableRow index="SG" value="193" comment="Singapore"/>
  <co:hashTableRow index="SGP" value="193" comment="Singapore"/>
  <co:hashTableRow index="Singapore" value="193" comment="Singapore"/>
  <co:hashTableRow index="AT" value="14" comment="Austria"/>
  <co:hashTableRow index="Austria" value="14" comment="Austria"/>
  <co:hashTableRow index="Österreich" value="14" comment="Austria"/>
  <co:hashTableRow index="NZ" value="157" comment="New Zealand"/>
  <co:hashTableRow index="New Zealand" value="157" comment="New Zealand"/>
  <co:hashTableRow index="AU" value="13" comment="Australia"/>
  <co:hashTableRow index="AUS" value="13" comment="Australia"/>
  <co:hashTableRow index="Australia" value="13" comment="Australia"/>
  <co:hashTableRow index="Australien" value="13" comment="Australia"/>
  <co:hashTableRow index="AUSTRALIA" value="13" comment="Australia"/>
  <co:hashTableRow index="Croatia" value="54" comment="Croatia"/>
  <co:hashTableRow index="HR" value="54" comment="Croatia"/>
  <co:hashTableRow index="GB" value="227" comment="United Kingdom"/>
  <co:hashTableRow index="UK" value="227" comment="United Kingdom"/>
  <co:hashTableRow index="United Kingdom" value="227" comment="United Kingdom"/>
  <co:hashTableRow index="United States" value="228" comment="United States"/>
  <co:hashTableRow index="US" value="228" comment="United States"/>
  <co:hashTableRow index="USA" value="228" comment="United States"/>
  <co:hashTableRow index="Netherlands" value="154" comment="Netherlands"/>
  <co:hashTableRow index="NL" value="154" comment="Netherlands"/>
  <co:hashTableRow index="BA" value="27" comment="Netherlands"/>
  <co:hashTableRow index="Bosnia-Herz." value="27" comment="Netherlands"/>
</co:hashTable>
	
<!-- COUNTRY -->
<co:rule>
  <co:setCommand target="COUNTRY_ID" value="_hashval" hashident="COUNTRY_MAP" index="COUNTRY"/>
</co:rule>
Language Mapping

With language attributes these can be mapped against the COUNTRY_ID to pre-define the system and content languages shown to the user. The rule below is from a system that offers English (GB) and German languages. In this system the default language in the personal attributes is defined as English (GB), so the rule uses a hashTable to map the German speaking Country IDs to the German language ID. Then the rule condition identifies only users that are yet to login and sets two language personal attributes based on the hashTable mapping. The use of the COUNTOFLOGINS ensures that if the user decides to change their preferred language the rules will not re-change the languages.

XML
<co:hashTable identifier="SET_LANGUAGE" defaultValue="27">
  <co:hashTableRow index="14" value="23" comment="AT"/>
  <co:hashTableRow index="82" value="23" comment="DE"/>
  <co:hashTableRow index="209" value="23" comment="CH"/>
</co:hashTable>

<!-- SET INITIAL VALUES -->
<co:rule>
  <co:ruleConditions>
    <co:ruleCondition expression="COUNTOFLOGINS" matching="EQUAL" value="0"/>
  </co:ruleConditions>
  <co:setCommand target="LANGUAGE_ID" value="_hashval" hashident="SET_LANGUAGE" index="COUNTRY_ID" />
  <co:setCommand target="PREFERRED_LANGUAGE_ID" value="_hashval" hashident="SET_LANGUAGE" index="COUNTRY_ID" />
</co:rule>
Time Zone Mappings

The TIMEZONE_ID personal attribute is an important setting for users to update as the selected time zone can change the displayed training dates/times. This attribute can also be updated automatically using rules on the values of other personal attributes such as COUNTRY or a custom LOCATION. These rules can be written individually for each required time zone or as a hashTable. The rules will require the IDs for each time zone which can be found under Time Zones.

One consideration with time zones is that there are countries like Australia, Canada and the United States of America that span multiple time zone; in this case a custom personal attribute for specific locations (e.g. State, Office, City) would be more accurate.

XML
<!-- Set time zones -->
<co:rule>
  <co:ruleConditions>
    <co:ruleCondition expression="OFFICE_LOCATION" matching="Berlin" mode="VALUE"/>
  </co:ruleConditions>
  <co:setCommand target="TIMEZONE_ID" value="121" execute="ONCE"/>
</co:rule>
<co:rule>
  <co:ruleConditions>
    <co:ruleCondition expression="OFFICE_LOCATION" matching="London" mode="VALUE"/>
  </co:ruleConditions>
  <co:setCommand target="TIMEZONE_ID" value="96" execute="ONCE"/>
</co:rule>
<co:rule>
  <co:ruleConditions>
    <co:ruleCondition expression="OFFICE_LOCATION" matching="Sydney" mode="VALUE"/>
  </co:ruleConditions>
  <co:setCommand target="TIMEZONE_ID" value="103" execute="ONCE"/>
</co:rule>

The use of a hashTable would include multiple rows where the index maps to a value which is the object ID of each value in the TIMEZONE_ID selection list personal attribute.

XML
<co:hashTable identifier="TIMEZONE_MAP" defaultValue="0" comment="Mapping of iso country to time zone id">
  <co:hashTableRow index="DE" value="121" comment="Germany"/>
  <co:hashTableRow index="Germany" value="121" comment="Germany"/>
  <co:hashTableRow index="GERMANY" value="121" comment="Germany"/>
  <co:hashTableRow index="DEUTSCHLAND" value="121" comment="Germany"/>
  <co:hashTableRow index="Deutschland" value="121" comment="Germany"/>
  <co:hashTableRow index="CH" value="121" comment="Switzerland"/>
  <co:hashTableRow index="Switzerland" value="121" comment="Switzerland"/>
  <co:hashTableRow index="RO" value="122" comment="Romania"/>
  <co:hashTableRow index="RU" value="122" comment="Romania"/>
  <co:hashTableRow index="Romania" value="122" comment="Romania"/>
  <co:hashTableRow index="SG" value="80" comment="Singapore"/>
  <co:hashTableRow index="SGP" value="80" comment="Singapore"/>
  <co:hashTableRow index="Singapore" value="80" comment="Singapore"/>
  <co:hashTableRow index="AT" value="121" comment="Austria"/>
  <co:hashTableRow index="Austria" value="121" comment="Austria"/>
  <co:hashTableRow index="Österreich" value="121" comment="Austria"/>
  <co:hashTableRow index="NZ" value="71" comment="New Zealand"/>
  <co:hashTableRow index="New Zealand" value="71" comment="New Zealand"/>
  <co:hashTableRow index="AU" value="103" comment="Australia"/>
  <co:hashTableRow index="AUS" value="103" comment="Australia"/>
  <co:hashTableRow index="Australia" value="103" comment="Australia"/>
  <co:hashTableRow index="Australien" value="103" comment="Australia"/>
  <co:hashTableRow index="AUSTRALIA" value="103" comment="Australia"/>
  <co:hashTableRow index="Croatia" value="122" comment="Croatia"/>
  <co:hashTableRow index="HR" value="122" comment="Croatia"/>
  <co:hashTableRow index="GB" value="96" comment="United Kingdom"/>
  <co:hashTableRow index="UK" value="96" comment="United Kingdom"/>
  <co:hashTableRow index="United Kingdom" value="96" comment="United Kingdom"/>
  <co:hashTableRow index="United States" value="94" comment="United States Pacific time"/>
  <co:hashTableRow index="US" value="94" comment=94"United States Pacific time"/>
  <co:hashTableRow index="USA" value="94" comment="United States Pacific time"/>
  <co:hashTableRow index="Netherlands" value="121" comment="Netherlands"/>
  <co:hashTableRow index="NL" value="121" comment="Netherlands"/>
  <co:hashTableRow index="BA" value="121" comment="Netherlands"/>
  <co:hashTableRow index="Bosnia-Herz." value="122" comment="Bosnia"/>
</co:hashTable>
	
<!-- COUNTRY -->
<co:rule>
  <co:setCommand target="TIMEZONE_ID" value="_hashval" hashident="TIMEZONE_MAP" index="COUNTRY"/>
</co:rule>

Advanced Calculations and Processing

Rules are able to perform some more calculations or processes using single SQL statements. Such rules do require knowledge of SQL and an understanding of the Learning Suite database. Below are some real customer examples SQL used to generate a value in a setCommand.

The following rule calculates the age of the learner in whole years based on the difference between the current date and their date of birth. This was required by a customer that had minimum age requirements to enrol to some training courses.

XML
<!-- Calculation of years since DOB START -->
<co:hashTable identifier="YEARS_SINCE_DOB" defaultValue="0" comment="Mapping of Years since DOB">
  <co:hashTableSelectStatement isIntAttribute="false">SELECT datediff(hh,?,getdate())/8766</co:hashTableSelectStatement>
</co:hashTable>
			
<!--<co:hashTableSelectStatement isIntAttribute="false">SELECT datediff(yy,?, current_timestamp)</co:hashTableSelectStatement>-->
<co:rule> 
  <co:setCommand value="_hashval" target="AGE" hashident="YEARS_SINCE_DOB" index="DATE_OF_BIRTH"/>
</co:rule>
<!-- Calculation of years since DOB START END -->

The following rule calculates the number of employment days based on the difference between the current date and their employment start date. This calculation was used by a customer that had specific compliance training windows based on days since employment.

XML
<co:hashTable identifier="DAYS_SINCE_EMPL" defaultValue="0" comment="Mapping of Days since Employment">
  <co:hashTableSelectStatement isIntAttribute="false">SELECT datediff(d,?, current_timestamp)</co:hashTableSelectStatement>
</co:hashTable>

<co:rule> 
  <co:setCommand value="_hashval" target="DAYS_SINCE_EMPLOYMENT" hashident="DAYS_SINCE_EMPL" index="EMPLOYMENT_START_DATE"/>
</co:rule>

The following rule concatenates two values to make a specific value. In this case the customer required an email address containing the user’s mobile phone number to send basic messages as SMS messages. This rule can be more advanced with opt in rules as well.

XML
<co:hashTable identifier="addDomain" defaultValue="unknown" >
  <co:hashTableSelectStatement isIntAttribute="false">SELECT ? + '@email.smsglobal.com' </co:hashTableSelectStatement>
</co:hashTable>			

<!-- Email to SMS Address Building -->
<co:rule>
  <co:ruleConditions>
    <co:ruleCondition expression="WORK_MOBILE" matching="ISNOTEMPTY"/>
  </co:ruleConditions>	
  <co:setCommand target="SMS_EMAIL" value="_hashval" hashident="addDomain" index="WORK_MOBILE"/>
</co:rule>	

Date Conversions

To import against Learning Suite date/time personal attributes require the specific YYYY-MM-DD hh:mm:ss.s format. This format is not always exportable by user data source systems and may require conversion using registration rules. This can be achieved using a hashTable with a specific statement that considers the input date format. Given the different date formats and statement such requirements are best discussed with imc if required. Below is a couple of example conversions.

CODE
<co:hashTable identifier="DATUM" defaultValue="" comment="Date from YYYYMMDD to YYYY-MM-DD hh:mm:ss">
  <co:hashTableSelectStatement isIntAttribute="false">SELECT CONVERT(Datetime,LEFT(?,23),126)
  </co:hashTableSelectStatement>
</co:hashTable>

<co:hashTable identifier="ENGLISH_DATE" defaultValue="" comment="Date from English format">
  <co:hashTableSelectStatement isIntAttribute="false">SELECT CONVERT(datetime, ?,103);</co:hashTableSelectStatement>
</co:hashTable>

<co:hashTable identifier="DATE_CONVERSION" defaultValue="" comment="">
  <co:hashTableSelectStatement isIntAttribute="false">select convert(varchar, ?, 121) + ' 00:00:00.0'</co:hashTableSelectStatement>
</co:hashTable>
			
<co:rule>
  <co:ruleConditions>
    <co:ruleCondition expression="HIRE_DATE" matching="ISNOTEMPTY" />
  </co:ruleConditions>
  <co:setCommand target="EMP_START_DATE" value="_hashval" hashident="DATE_CONVERSION" index="HIRE_DATE" />
</co:rule>

Summary

This article has provided information on the purpose, possibilities, benefits, format requirements, and various examples of registration rules. As can be seen the use of registration rules can deliver many efficiencies and is an important configuration task. Although registration rules are accessible to System administrators, it's strongly recommended to discuss requirements or ideas with Scheer IMC Consultants who are experienced in this area.


📋 Related Articles

Personal Attributes

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.