Currency Handling Guide

Overview

The decision engine provides sophisticated currency handling capabilities that automatically parse and normalize currency values across different international formats. This guide explains how currency parsing works in both condition evaluations and action operations.

Key Features

  • Automatic Currency Symbol Detection: Recognizes major currency symbols ($, €, £, ¥, ₹, etc.) and marks written with letters (Kč, zł, Ft, lei, лв, kr)
  • International Format Support: Handles different thousands separators and decimal points
  • Currency Code Recognition: Supports both prefix and suffix currency codes (USD, EUR, GBP, etc.)
  • Accounting Format Support: Handles negative amounts in parentheses
  • Smart Leading Zero Preservation: Distinguishes between currency amounts and technical codes

Currency Parsing in Conditions

Currency parsing behavior depends on the comparison operation type:

Strict Equality (=)

Currency symbols are NOT parsed - values are compared as literal strings.

Examples:
"$100" ≠ 100           (no parsing, different types)
"€50.50" ≠ 50.50       (no parsing, different types)
"USD 1000" ≠ 1000      (no parsing, different types)

Use Cases:

  • Validating exact currency format requirements
  • Ensuring currency symbols are present in user input
  • Technical validation where format matters

Loose Equality (≈)

Currency symbols ARE parsed - values are normalized before comparison.

Examples:
"$100" = 100           (symbol removed, values compared)
"€50.50" = 50.50       (symbol removed, values compared)
"USD 1000" = 1000      (code removed, values compared)
"1,000.00" = 1000      (formatting normalized)

Use Cases:

  • User-friendly amount comparisons
  • Financial calculations where format varies
  • Cross-system data integration

Other Comparison Operations

All numeric comparison operations (>, <, >=, <=, =, ≠) automatically parse currency formats:

Examples:
"$150" > "$100"        → 150 > 100 = true
"€75.50" < "€80.00"    → 75.50 < 80.00 = true
"£1,234.56" >= "£1,200" → 1234.56 >= 1200 = true

Currency Parsing in Actions

All mathematical action operations automatically parse currency formats from both the source value and the operation value.

Basic Mathematical Operations

OperationSymbolCurrency Handling Example
Addition+"$100" + "€50" → 100 + 50 = 150
Subtraction-"£200" - "$75" → 200 - 75 = 125
Multiplication*"$50" * "2" → 50 * 2 = 100
Division/"€1000" / "4" → 1000 / 4 = 250

Assignment Operations

OperationSymbolBehavior
Addition Assignment+=Parses currency, adds to existing value
Subtraction Assignment-=Parses currency, subtracts from existing value
Multiplication Assignment*=Parses currency, multiplies existing value
Division Assignment/=Parses currency, divides existing value

Array Operations

Array operations automatically parse all currency values within arrays:

Examples:
Sum(["$100", "€150", "£200"]) → 100 + 150 + 200 = 450
Max(["$50.25", "€75.50", "£25.75"]) → 75.50
Avg(["$100", "€200", "£300"]) → (100 + 200 + 300) / 3 = 200

Supported Currency Formats

Currency Symbols

SymbolCurrencyExample Formats
$US Dollar$1,234.56, 1,234.56$
€Euro€1.234,56, 1.234,56€
£British Pound£1,234.56, 1,234.56£
¥Japanese Yen¥1,234, 1,234¥
₹Indian Rupee₹1,23,456.78, 1,23,456.78₹
₽Russian Ruble₽1 234,56, 1 234,56₽
¢Cents150¢, ¢150

Written Currency Marks

Some currencies are written with letters rather than a glyph. These are recognised too, at the beginning or the end of the value.

MarkCurrencyExample
Kč, Kc, kčCzech koruna1 234,50 Kč, Kč 1 234,50
zł, zlPolish złoty1 234,50 zł
FtHungarian forint1 234,50 Ft
leiRomanian leu1 234,50 lei
лвBulgarian lev1 234,50 лв
krDanish, Norwegian, Swedish krone/krona1 234,50 kr
SkSlovak koruna (legacy contracts)1 234,50 Sk
dinSerbian dinar1 234,50 din
knCroatian kuna (legacy contracts)1 234,50 kn

The mark is only recognised at the start or the end of a value, never in the middle, because these are ordinary letters. 1 234,50 lei is an amount; 12 lei 34 and the word calculating are not.

Currency Codes

CodeCurrencyExample Formats
USDUS DollarUSD 1,234.56, 1,234.56 USD
EUREuroEUR 1.234,56, 1.234,56 EUR
GBPBritish PoundGBP 1,234.56, 1,234.56 GBP
JPYJapanese YenJPY 1,234, 1,234 JPY
INRIndian RupeeINR 1,23,456.78, 1,23,456.78 INR
RUBRussian RubleRUB 1 234,56, 1 234,56 RUB

Combined Formats

The system handles combinations of symbols and codes:

Examples:
"$1,234.56 USD"     → 1234.56
"USD $1,234.56"     → 1234.56
"€1.234,56 EUR"     → 1234.56
"GBP £1,234.56"     → 1234.56

International Number Formats

Decimal Separators

FormatRegionExampleParsed Value
Period (.)US, UK1,234.561234.56
Comma (,)Europe1.234,561234.56

Thousands Separators

FormatRegionExampleParsed Value
Comma (,)US, UK1,234,567.891234567.89
Period (.)Europe1.234.567,891234567.89
SpaceVarious1 234 567,891234567.89

Reading a Value That Carries One Separator

A value holding both a period and a comma states its own format, because whichever character comes last is the decimal separator. A value holding only one of them is read from the digits around it.

Grouped numbers have a fixed shape. At most three digits sit before the first separator, and exactly three sit after every separator. A value outside that shape is not grouped, so its separator marks the decimal point.

ValueParsed ValueReason
1.234.5671234567Two separators, and a decimal number has one point
1234.5671234.567Four digits before the separator, so the value is not grouped
1234,5671234.567The comma follows the same rule
1000.0001000Four digits before the separator
1234.561234.56Two digits after the separator

Values That Fit Both Readings

1,234 and 1.234 carry one separator and match the grouping shape, so either reading is defensible. Each character keeps its regional convention:

ValueParsed Value
1,2341234
1.2341.234
12,34512345
12.34512.345
123,456123456
123.456123.456

Where an amount must read the same everywhere, send it with both separators (1.234,00 or 1,234.00) or with none (1234).

Earlier releases read a single period as a thousands separator whenever four or more digits stood in front of it, so 1234.567 parsed as 1234567 and 1000.000 parsed as a million. Amounts written with three decimal places are now read as decimals.

Accounting Formats

Negative amounts in parentheses are supported:

Examples:
"($1,234.56)"       → -1234.56
"(€1.234,56)"       → -1234.56
"(£1,234.56)"       → -1234.56
"($1,234.56) USD"   → -1234.56

Percentages

A percent sign is treated as a unit, not as part of the number. "4.5%" parses as 4.5.

The value is not divided by 100. "45%" is 45 and never 0.45, so write conditions against the figure as it is written:

ValueParsed ValueCondition that matches
45%45dti > 40
4.5%4.5rate <= 5
50 %50share = 50

Text holding more than a number stays text: "50% off" is not numeric and is compared as a string.

Percent values are compared numerically. Earlier releases compared them as text, where 9% sorted above 40 because characters sort before they count.

Leading Zeros and Technical Codes

Currency vs Technical Codes

The system intelligently distinguishes between currency amounts and technical codes:

Currency Amounts (Leading Zeros Removed)

"$007.50"           → 7.50   (currency parsing)
"€0123.45"          → 123.45 (currency parsing)
"USD 0100.00"       → 100.00 (currency parsing)

Technical Codes (Leading Zeros Preserved)

"007"               → "007"  (preserved as string)
"0123"              → "0123" (preserved as string)
"ACC007"            → "ACC007" (preserved as string)

Detection Logic

Leading zeros are preserved when:

  • No currency symbol or code is present
  • The value is being used in a strict equality comparison
  • The value contains non-numeric characters that suggest it's an identifier

Leading zeros are removed when:

  • Currency symbols or codes are detected
  • The value is being used in mathematical operations
  • Loose equality comparison is being performed

Best Practices

When to Use Strict vs Loose Equality

Use Strict Equality When:

  • Validating that currency symbols are present
  • Ensuring exact format compliance
  • Working with mixed currency and non-currency data
  • Preserving technical identifiers
Rule: "Ensure amount includes currency symbol"
Condition: $.user_input = "$100.00"

Use Loose Equality When:

  • Comparing amounts regardless of format
  • Integrating data from different systems
  • User-friendly amount matching
  • Financial calculations
Rule: "Check if amount exceeds limit"
Condition: $.amount ≈ 1000.00

Action Operation Recommendations

For Mathematical Operations:

Always use mathematical operations (+, -, *, /) when working with currency amounts, as they automatically handle parsing:

Good:
$.total_amount += "€150.50"

Avoid:
$.total_amount = $.total_amount + "€150.50" (manual concatenation)

For Array Operations:

Use array operations for aggregating multiple currency values:

$.total_revenue = Sum($.monthly_revenues)
$.max_transaction = Max($.transaction_amounts)
$.average_order = Avg($.order_values)

Data Input Recommendations

Accept Multiple Formats:

Design rules to handle various input formats:

Condition Group (ANY):
- $.amount ≈ 1000
- $.amount ≈ "$1,000.00"
- $.amount ≈ "€1.000,00"
- $.amount ≈ "1000 USD"

Normalize Output Format:

Use actions to standardize currency format in responses:

Action: $.formatted_amount = "$" + $.parsed_amount

Examples and Use Cases

Example 1: Multi-Currency Order Processing

Scenario: Process orders from different regions with varying currency formats.

Rule: "Calculate total order value"
Conditions:
- $.order_items is not null
Actions:
- $.subtotal = Sum($.order_items[*].amount)
- $.tax_amount = $.subtotal * $.tax_rate
- $.total_amount = $.subtotal + $.tax_amount

Input Data:
{
  "order_items": [
    {"amount": "$25.50"},
    {"amount": "€30.75"},
    {"amount": "£22.25"}
  ],
  "tax_rate": 0.10
}

Result:
{
  "subtotal": 78.50,
  "tax_amount": 7.85,
  "total_amount": 86.35
}

Example 2: Currency Format Validation

Scenario: Ensure user input includes proper currency formatting.

Rule: "Validate USD format"
Conditions:
- $.payment_amount contains "$"
- $.payment_amount > 0
Actions:
- $.validation_status = "valid_usd_format"

Rule: "Validate EUR format"  
Conditions:
- $.payment_amount contains "€"
- $.payment_amount > 0
Actions:
- $.validation_status = "valid_eur_format"

Example 3: Expense Approval Workflow

Scenario: Route expenses for approval based on amount thresholds.

Rule: "Auto-approve small expenses"
Conditions:
- $.expense_amount ≤ 100
Actions:
- $.approval_status = "auto_approved"
- $.approver = "system"

Rule: "Manager approval required"
Conditions:
- $.expense_amount > 100
- $.expense_amount ≤ 1000
Actions:
- $.approval_status = "manager_approval_required"
- $.approver = $.employee_manager

Rule: "Director approval required"
Conditions:
- $.expense_amount > 1000
Actions:
- $.approval_status = "director_approval_required"
- $.approver = $.department_director

Example 4: International Pricing Rules

Scenario: Apply different pricing rules based on currency and region.

Rule: "USD pricing rules"
Conditions:
- $.customer_currency = "USD"
- $.order_amount ≥ 500
Actions:
- $.discount_percentage = 0.05
- $.shipping_cost = 0

Rule: "EUR pricing rules"
Conditions:
- $.customer_currency = "EUR"  
- $.order_amount ≥ 400
Actions:
- $.discount_percentage = 0.07
- $.shipping_cost = 15.00

Rule: "Apply volume discount"
Conditions:
- $.order_amount > 1000
Actions:
- $.discount_percentage += 0.03

Example 5: Currency Conversion Tracking

Scenario: Track and log currency conversions for audit purposes.

Rule: "Log currency conversion"
Conditions:
- $.original_currency ≠ $.target_currency
Actions:
- $.conversion_logged = true
- $.conversion_rate = 1.0
- $.converted_amount = $.original_amount * $.conversion_rate
- $.conversion_timestamp = "2025-10-17"

Rule: "Flag large conversions"
Conditions:
- $.converted_amount > 10000
Actions:
- $.requires_review = true
- $.review_priority = "high"

This comprehensive guide covers all aspects of currency handling in the decision engine, providing users with the knowledge needed to effectively work with monetary values in their business rules.