toCurrencyString function

String toCurrencyString(
  1. String value, {
  2. int mantissaLength = 2,
  3. ThousandSeparator thousandSeparator = ThousandSeparator.Comma,
  4. ShorteningPolicy shorteningPolicy = ShorteningPolicy.NoShortening,
  5. String leadingSymbol = '',
  6. String trailingSymbol = '',
  7. bool useSymbolPadding = false,
  8. bool isRawValue = false,
})

isRawValue pass true if you

Implementation

String toCurrencyString(
  String value, {
  int mantissaLength = 2,
  ThousandSeparator thousandSeparator = ThousandSeparator.Comma,
  ShorteningPolicy shorteningPolicy = ShorteningPolicy.NoShortening,
  String leadingSymbol = '',
  String trailingSymbol = '',
  bool useSymbolPadding = false,
  bool isRawValue = false,
}) {
  bool isNegative = false;
  if (value.startsWith('-')) {
    value = value.replaceAll(RegExp(r'^[-+]+'), '');
    isNegative = true;
  }
  value = value.replaceAll(_spaceRegex, '');
  if (value.isEmpty) {
    value = '0';
  }
  String mSeparator = _getMantissaSeparator(
    thousandSeparator,
    mantissaLength,
  );
  String tSeparator = _getThousandSeparator(
    thousandSeparator,
  );

  /// нужно только для того, чтобы не допустить числа начинающиеся с нуля
  /// 04.00 и т.д
  value = toNumericString(
    value,
    allowAllZeroes: false,
    allowHyphen: true,
    allowPeriod: true,
    mantissaSeparator: mSeparator,
    mantissaLength: mantissaLength,
  );
  bool hasFraction = mantissaLength > 0;
  String? fractionalSeparator;
  if (hasFraction) {
    fractionalSeparator = _detectFractionSeparator(value);
  } else {
    value = value.replaceAll(tSeparator, '');
  }

  var sb = StringBuffer();

  bool addedMantissaSeparator = false;
  for (var i = 0; i < value.length; i++) {
    final char = value[i];
    if (char == '-') {
      if (i > 0) {
        continue;
      }
      sb.write(char);
    }
    if (isDigit(char, positiveOnly: true)) {
      sb.write(char);
    }
    if (char == fractionalSeparator) {
      if (!addedMantissaSeparator) {
        sb.write('.');
        addedMantissaSeparator = true;
      } else {
        continue;
      }
    } else {
      if (!hasFraction) {
        if (char == '.' && char != tSeparator) {
          break;
        }
      }
    }
  }

  final str = sb.toString();
  final evenPart =
      addedMantissaSeparator ? str.substring(0, str.indexOf('.')) : str;

  int skipEvenNumbers = 0;
  String shorteningName = '';
  if (shorteningPolicy != ShorteningPolicy.NoShortening) {
    switch (shorteningPolicy) {
      case ShorteningPolicy.NoShortening:
        break;
      case ShorteningPolicy.RoundToThousands:
        skipEvenNumbers = 3;
        shorteningName = 'K';
        break;
      case ShorteningPolicy.RoundToMillions:
        skipEvenNumbers = 6;
        shorteningName = 'M';
        break;
      case ShorteningPolicy.RoundToBillions:
        skipEvenNumbers = 9;
        shorteningName = 'B';
        break;
      case ShorteningPolicy.RoundToTrillions:
        skipEvenNumbers = 12;
        shorteningName = 'T';
        break;
      case ShorteningPolicy.Automatic:
        // find out what shortening to use base on the length of the string
        final policy = _detectShorteningPolicyByStrLength(evenPart);
        return toCurrencyString(
          value,
          leadingSymbol: leadingSymbol,
          mantissaLength: mantissaLength,
          shorteningPolicy: policy,
          thousandSeparator: thousandSeparator,
          trailingSymbol: trailingSymbol,
          useSymbolPadding: useSymbolPadding,
        );
    }
  }
  bool ignoreMantissa = skipEvenNumbers > 0;

  final fractionalPart =
      addedMantissaSeparator ? str.substring(str.indexOf('.') + 1) : '';
  final reversed = evenPart.split('').reversed.toList();
  List<String> temp = [];
  bool skippedLast = false;
  for (var i = 0; i < reversed.length; i++) {
    final char = reversed[i];
    if (skipEvenNumbers > 0) {
      skipEvenNumbers--;
      skippedLast = true;
      continue;
    }
    if (i > 0) {
      if (i % 3 == 0) {
        if (!skippedLast) {
          temp.add(tSeparator);
        }
      }
    }
    skippedLast = false;
    temp.add(char);
  }
  value = temp.reversed.join('');
  sb = StringBuffer();
  for (var i = 0; i < mantissaLength; i++) {
    if (i < fractionalPart.length) {
      sb.write(fractionalPart[i]);
    } else {
      sb.write('0');
    }
  }

  final fraction = sb.toString();
  if (value.isEmpty) {
    value = '0';
  }
  if (ignoreMantissa) {
    value = '$value$shorteningName';
  } else {
    value = '$value$mSeparator$fraction';
  }

  // print(value);

  /// add leading and trailing
  sb = StringBuffer();
  for (var i = 0; i < value.length; i++) {
    if (i == 0) {
      if (leadingSymbol.isNotEmpty) {
        sb.write(leadingSymbol);
        if (useSymbolPadding) {
          sb.write(' ');
        }
      }
    }
    sb.write(value[i]);
    if (i == value.length - 1) {
      if (trailingSymbol.isNotEmpty) {
        if (useSymbolPadding) {
          sb.write(' ');
        }
        sb.write(trailingSymbol);
      }
    }
  }
  value = sb.toString();
  if (isNegative) {
    return '-$value';
  }
  return value;
}