format static method

String format(
  1. dynamic amount,
  2. CurrencyFormat settings, {
  3. bool compact = false,
  4. int decimal = 2,
  5. dynamic showThousandSeparator = true,
  6. dynamic enforceDecimals = false,
})

Format amount using the settings of a currency.

If compact is true the compact form will be used. e.g. '$ 1.23K' instead of '$ 1,230'.

decimal is the number of decimal places used when rounding. e.g. '$ 45.5' (1 decimal place), '$ 45.52' (2 decimal places).

If showThousandSeparator is set to false, the thousand separator won't be shown. e.g. '$ 1200'instead of '$ 1,200'.

If enforceDecimals is set to true, decimals will be shown even if it is an integer. e.g. '$ 5.00' instead of '$ 5'.

Implementation

static String format(
  amount,
  CurrencyFormat settings, {
  bool compact = false,
  int decimal = 2,
  showThousandSeparator = true,
  enforceDecimals = false,
}) {
  double originalAmount = double.parse('$amount');
  bool isNegative = originalAmount < 0;
  double absAmount = originalAmount.abs();

  String letter = '';
  String formattedNumberString;

  // Step 2: Perform numerical formatting on absAmount
  if (compact) {
    double compactCalcAmount = absAmount;
    for (int i = 0; i < _letters.length; i++) {
      if (compactCalcAmount >= _letters.keys.elementAt(i)) {
        letter = _letters.values.elementAt(i);
        compactCalcAmount /= _letters.keys.elementAt(i);
        break;
      }
    }
    formattedNumberString = compactCalcAmount.toStringAsPrecision(3);
  } else {
    formattedNumberString = absAmount.toStringAsFixed(decimal);
  }

  // Rounding for non-enforced decimals (only if not compact)
  // This must use '.' for parsing, so it's done before replacing the decimal separator.
  if (!enforceDecimals && !compact) {
    double tempNum = double.parse(
        formattedNumberString); // Assumes '.' as decimal separator
    if (tempNum == tempNum.round()) {
      formattedNumberString = tempNum.round().toString();
    }
  }

  // Replace '.' with the settings-defined decimal separator
  formattedNumberString =
      formattedNumberString.replaceAll('.', settings.decimalSeparator);

  // Apply thousand separator if needed
  // This operates on the number string which is now purely numerical (absolute)
  // and has the correct decimal separator.
  if (showThousandSeparator) {
    List<String> parts =
        formattedNumberString.split(settings.decimalSeparator);
    String integerPart = parts[0];
    String decimalPart =
        parts.length > 1 ? settings.decimalSeparator + parts[1] : '';

    String newIntegerPart = '';
    for (int i = 0; i < integerPart.length; i++) {
      newIntegerPart =
          integerPart[integerPart.length - i - 1] + newIntegerPart;
      if ((i + 1) % 3 == 0 && i < integerPart.length - 1) {
        newIntegerPart = settings.thousandSeparator + newIntegerPart;
      }
    }
    formattedNumberString = newIntegerPart + decimalPart;
  }

  // Step 3 & 4: Sign handling and final assembly
  String signComponent = '';
  if (isNegative) {
    if (settings.symbolSide == SymbolSide.left &&
        settings.negativeSignPlacement ==
            NegativeSignPlacement.beforeSymbol) {
      signComponent = '-'; // Sign will go before the symbol
    } else {
      formattedNumberString =
          '-$formattedNumberString'; // Sign will go with the number
    }
  }

  // Step 5: Construct final string
  switch (settings.symbolSide) {
    case SymbolSide.left:
      return '$signComponent${settings.symbol}${settings.symbolSeparator}$formattedNumberString$letter';
    case SymbolSide.right:
      return '$formattedNumberString$letter${settings.symbolSeparator}${settings.symbol}';
    default: // SymbolSide.none
      return '$formattedNumberString$letter';
  }
}