Skip to main content

Rule Engine

What is the Rule Engine?

The Rule Engine lets you set up JavaScript rules that automatically run when certain events happen in the system — e.g. when a new order is received, or when a product is imported. The rules are written directly in an editor (the same editor as VS Code) with full autocompletion and error checking.

Only one rule per type can be active at a time. When you activate a rule, other rules of the same type are automatically deactivated.

Available rule types

Rule typeTriggerDescriptionReturn value
Subsite AssignmentNew order receivedAssign a subsite to the order based on order datanumber (subsite ID)
Order ModificationNew order receivedModify order fields (addresses, notes, currency, shipping, etc.)Order (the modified order object)
Sticker AssignmentNew order receivedAssign stickers to the orderstring or string[] (sticker identifiers)
Return Shipment ProviderReturn label createdChoose the shipping provider for return labelsstring (shipper identifier)
Auto Print ChooseAutoprint triggeredChoose printer or print station for autoprint{ printStationId?: number, printerId?: string }
Product Import ModifyProduct importedModify product fields during importProduct (the modified product object)
Product Import FilterProduct importedFilter out products during importboolean (true = import, false = skip)

How to create a rule

  1. Go to Rule Engine in the menu (requires Rule Engine permission)
  2. Click Create rule
  3. Fill in:
    • Name – a descriptive name (e.g. "SKI orders to Public Tender")
    • Type – select the rule type you want
    • Active – check the box to activate the rule
    • Enable Log – check the box to log all runs (recommended during the testing phase)
  4. Write your JavaScript in the editor
  5. Test the script before saving (expand the "Test Script" panel)
  6. Click Save

Editor and Reference Card

When you select a rule type, the editor automatically shows a Reference Card with all available variables and their types. You also get full TypeScript autocompletion — try typing order. and see the available fields.

Available functions

FunctionDescription
log("message")Writes a message to the order's transaction log – useful for debugging and traceability
return <value>Returns the result of the rule – what you return depends on the rule type

Order object (available in most rule types)

The most important fields on order:

FieldTypeDescription
order.orderIDnumberOrder ID
order.referencestringOrder reference
order.subSitenumberCurrent subsite ID
order.currencystringCurrency code
order.statusstringOrder status
order.cargoMethodstringShipping method
order.notestringCustomer note
order.internalNotestringInternal note
order.deliveryNotestringDelivery note
order.addressAddressBilling address
order.deliveryAddressAddressDelivery address
order.linesOrderLine[]Order lines
order.extraRecordExtra fields

Address fields: name, street, city, zip, mail, phone, companyNumber, companyName, country, ean, street2, state

OrderLine fields: lineID, title, price, itemNumber, amount, amountDelivered, note, extra, uom

Testing rules

Before you save a rule, you can test it:

  1. Expand the "Test Script" panel at the bottom of the page
  2. Enter an Order ID (or the fields the rule type requires)
  3. Click Test Script
  4. The result is shown with:
    • Input Context – the data your rule received (the actual order object)
    • Output Result – what your rule returned, including any log() messages

The test runs the script against real data, but does not apply the changes — so it is safe to test with production orders.

Logging

When Enable Log is turned on, all runs are logged with success/failure status, execution time and context. View the log via the Logs button in the rule list, or in the transaction log for the individual rule.


Example 1: Subsite Assignment – SKI orders to Public Tender

Scenario: All orders where the reference contains "SKI-" should automatically be assigned to subsite 4 ("Offentligt Udbud" / Public Tender).

Setup:

  • Name: SKI orders to Public Tender
  • Type: Subsite Assignment
  • Active: Yes
  • Enable Log: Yes (for testing)

Script:

// =============================================================
// Subsite Assignment: SKI-ordrer til Offentligt Udbud
// =============================================================
// Hvis ordrens reference indeholder "SKI-", tildel subsite 4
// (Offentligt Udbud). Ellers returner null for at beholde
// den nuværende subsite uændret.
// =============================================================

// Hent referencen fra ordren og normaliser til uppercase for sikker sammenligning
var reference = (order.reference || "").toUpperCase();

// Tjek om referencen indeholder SKI-præfikset
if (reference.includes("SKI-")) {

// Log til transaktionsloggen så det er synligt på ordren
log("Reference indeholder SKI- (" + order.reference + ") - tildeler subsite 4 (Offentligt Udbud)");

// Returner subsite-ID 4 for at tildele "Offentligt Udbud"
return 4;
}

// Ingen SKI-reference fundet - returner null for at lade subsite være uændret
return null;

How to test:

  1. Find an order with an SKI reference (e.g. an order with reference "SKI-2024-00412")
  2. Expand the "Test Script" panel and enter the order's ID
  3. Click "Test Script"
  4. Expected result: 4 (in Output Result)
  5. Also test with an order without an SKI reference – expected result: null

Result: When a new order is received with reference "SKI-2024-00412", its subsite is automatically set to 4. The change is logged in the order's transaction log.


Example 2: Order Modification – Contact person and chemical warning

Scenario: Two automatic changes to incoming orders:

  1. If the delivery address has a company name, copy the billing address's name over as the contact person on the delivery address
  2. If the order lines contain products with "chemical" in the title, set an internal note as a warning

Setup:

  • Name: Company contact + Chemical warning
  • Type: Order Modification
  • Active: Yes
  • Enable Log: Yes (for testing)

Script:

// =============================================================
// Order Modification: Firmakontakt og kemikalie-advarsel
// =============================================================
// Regel 1: Hvis leveringsadressen har et firmanavn (companyName),
// kopiér faktureringsadressens navn til leveringsadressens
// kontaktperson-felt (name), så pakkeshops og fragtmænd
// ved hvem pakken er til.
//
// Regel 2: Hvis én eller flere ordrelinjer har "kemikalie" i titlen,
// sæt en intern note der advarer lagerpersonalet om at
// bruge udstyr og ekstra indpakning.
// =============================================================

var modified = false;

// ---------------------------------------------------------------
// Regel 1: Kopier billing-navn til delivery kontaktperson
// ---------------------------------------------------------------
// Tjek om leveringsadressen har et firmanavn - det indikerer en
// virksomhedslevering, hvor kontaktpersonen ofte mangler
var hasDeliveryCompany = order.deliveryAddress
&& order.deliveryAddress.companyName
&& order.deliveryAddress.companyName.trim() !== "";

if (hasDeliveryCompany) {

// Hent faktureringsadressens navn - det er typisk kontaktpersonen
var billingName = (order.address && order.address.name) ? order.address.name.trim() : "";

if (billingName !== "") {

// Sæt kontaktpersonen på leveringsadressen til billing-navnet
order.deliveryAddress.name = billingName;

log("Delivery har firma (" + order.deliveryAddress.companyName + ") - sætter kontaktperson: " + billingName);
modified = true;
}
}

// ---------------------------------------------------------------
// Regel 2: Kemikalie-advarsel i intern note
// ---------------------------------------------------------------
// Gennemgå alle ordrelinjer og tjek om nogen indeholder "kemikalie"
var hasChemicals = false;
var chemicalTitles = [];

for (var i = 0; i < order.lines.length; i++) {
var title = (order.lines[i].title || "").toLowerCase();

// Søg efter "kemikalie" i produkttitlen
if (title.includes("kemikalie")) {
hasChemicals = true;
chemicalTitles.push(order.lines[i].title);
}
}

if (hasChemicals) {

// Sæt intern note med tydelig advarsel til lagerpersonalet
order.internalNote = "FARLIG: Husk udstyr og ekstra indpakning";

log("Kemikalier fundet i " + chemicalTitles.length + " linje(r): " + chemicalTitles.join(", "));
modified = true;
}

// ---------------------------------------------------------------
// Returner det modificerede ordre-objekt
// ---------------------------------------------------------------
// Order Modification forventer at vi returnerer hele ordre-objektet.
// Systemet sammenligner automatisk med originalen og anvender kun
// de felter der faktisk er ændret.
return order;

How to test:

Test rule 1 (contact person):

  1. Find an order where the delivery address has a company name but is missing a contact person
  2. Enter the order's ID and click "Test Script"
  3. In Output Result: check that deliveryAddress.name now has the billing address name

Test rule 2 (chemicals):

  1. Find an order with a product line that contains "chemical" in the title
  2. Enter the order's ID and click "Test Script"
  3. In Output Result: check that internalNote is set to "FARLIG: Husk udstyr og ekstra indpakning" ("DANGEROUS: Remember equipment and extra packaging")
  4. In the log output: check that the found chemical titles are listed

Result: When a new order is received:

  • Does the delivery address have a company name? The billing contact person is automatically copied over
  • Do the order lines contain chemicals? An internal note is set with a warning to the warehouse
  • All changes are logged in the order's transaction log with detailed log messages

Best practices

  • Always test with real orders before activating a rule
  • Use log() to write messages that end up in the order's transaction log – this makes troubleshooting easy
  • Return null from Subsite Assignment and Sticker Assignment to "do nothing"
  • Enable Log during the testing phase, so you can see all runs and any errors under Logs
  • Only one active rule per type – if you need multiple conditions, combine them in a single script (as in Example 2)
  • The script has a 5-second timeout – keep the logic simple and avoid heavy loops
  • The editor shows syntax errors in real time – you cannot save a script with errors