Currency Input Field Rounding Issues with Decimal Values Above 10,000 (Ex.: 200,300.57) - Need Plugin Recommendation

I'm working on a custom currency input field component and facing a challenging issue with decimal value conversion and rounding when values exceed 10,000 (5+ digits).

Here's my current implementation:

a!localVariables(
  a!textField(
    label: ri!label,
    labelPosition: a!defaultValue(ri!labelPosition, "ABOVE"),
    value: a!currency(
      isoCode: a!defaultValue(ri!isoCode, "BRL"),
      value: rule!process_BRLInputSanitizer(
        value: ri!value,
        toDecimal: true,
        showSeparators: false
      ),
      decimalPlaces: 2,
      showSeparators: true
    ),
    placeholder: ri!placeholder,
    saveInto: a!localVariables(
      {
        a!save(
          ri!value,
          a!currency(
            isoCode: a!defaultValue(ri!isoCode, "BRL"),
            value: rule!process_BRLInputSanitizer(
              value: save!value,
              toDecimal: true,
              showSeparators: false
            ),
            decimalPlaces: 2,
            showSeparators: true
          ),
          
        ),
        ri!saveInto
      }
    ),
    disabled: a!defaultValue(ri!disabled, false),
    readOnly: a!defaultValue(ri!readOnly, false),
    refreshAfter: "KEYPRESS",
    validations: { ri!validations },
    showWhen: a!defaultValue(ri!showWhen, true),
    instructions: ri!instructions,
    helpTooltip: ri!helpTooltip
  )
)

Supporting Rule (process_BRLInputSanitizer):

a!localVariables(
  local!toDecimal: a!defaultValue(ri!toDecimal, false),
  local!value: tostring(ri!value),
  local!left: substitute(local!value, ",", "."),
  local!right: substitute(local!value, ".", ","),
  local!result: if(
    local!toDecimal,
    concat(
      left(local!right, len(local!right) - 3),
      right(local!left, 3)
    ),
    concat(
      left(local!left, len(local!left) - 3),
      right(local!right, 3)
    )
  ),
  if(
    a!defaultValue(ri!showSeparators, true),
    local!result,
    if(
      local!toDecimal,
      substitute(local!result, ",", ""),
      substitute(local!result, ".", "")
    )
  )
)
The Problem: When the system casts the value back to a Decimal type, it rounds the value incorrectly when it exceeds 10,000 (5+ digits). I need the value to remain as a precise Decimal because my Record Type field that integrates with the backend requires decimal format.

Questions:

  1. Why does this rounding occur specifically when values exceed 5 digits?
  2. Is there an existing plugin or component that handles dynamic currency formatting (showing decimal separators while the user types) that maintains decimal precision?
  3. If such a plugin exists, it would save me from building this from scratch.

I'm essentially trying to create a currency input that displays proper formatting (R$323,845.27) while maintaining the underlying decimal value for record Type integration.

Any recommendations for existing solutions or insights into the rounding behavior would be greatly appreciated!

Thank you all for your time and assistance.

  Discussion posts and replies are publicly visible

  • Well, I was able to create a workaround and I will share with you all

    rule!_RFind:

    a!localVariables(
      local!reversed: joinarray(char(reverse(code(ri!string))), ""),
      local!findIndex: find(ri!substring, local!reversed),
      find(
        right(ri!string, local!findIndex),
        ri!string
      )
    )

    rule!_CurrencySanitizer:

    a!localVariables(
      local!findComma: rule!_Process_RFind(string: ri!value, substring: ","),
      local!findDot: rule!_Process_RFind(string: ri!value, substring: "."),
      if(
        local!findDot < local!findComma,
        todecimal(
          substitute(
            substitute(trim(ri!value), ".", ""),
            ",",
            "."
          )
        ),
        ri!value
      )
    )

    rule!MoneyField (BRL):

    a!textField(
      label: ri!label,
      labelPosition: a!defaultValue(ri!labelPosition, "ABOVE"),
      value: a!currency(
        isoCode: "BRL",
        value: ri!value,
        decimalPlaces: 2
      ),
      placeholder: ri!placeholder,
      saveInto: {
        a!save(
          ri!value,
          rule!_CurrencySanitizer(save!value)
        )
      },
      disabled: a!defaultValue(ri!disabled, false),
      readOnly: a!defaultValue(ri!readOnly, false),
      refreshAfter: "UNFOCUS",
      validations: { ri!validations },
      showWhen: a!defaultValue(ri!showWhen, true),
      instructions: ri!instructions,
      helpTooltip: ri!helpTooltip
    )

    Special thanks to  . If any of you have any other suggestion, please don't hesitate 

  • 0
    Certified Lead Developer
    in reply to Silas. B. Ferreira
    Appian is not understanding user typed commas as decimal

    If push comes to shove, I would suggest perhaps using a TEXT field for the input of the numerical value, and cleaning the user input upon SaveInto (converting it to proper decimal type at that point) - this would depend on the user using YOUR numbering system, but would NOT depend on user locale (for what it's worth).

    Looks like that's about what you've done with your Currency Sanitizer rule.  I would suggest you check out the "cleanwith()" function, it takes a little bit of the work out of "substitute" when you're substituting something for "blank".

    Anyway thanks for confirming - will appreciate a "verify answer" on any that you feel like giving me props on.  Gotta claw my way back into the Top 3 somehow, I still haven't made up for taking a week of vacation last month Sweat smile