-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #13 from RedCommander735/12-error-in-price-display
Fix formatting error in price display
- Loading branch information
Showing
4 changed files
with
160 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
import 'package:intl/intl.dart'; | ||
|
||
class NumberFormatter { | ||
final String locale; | ||
|
||
NumberFormatter({required this.locale}); | ||
|
||
FormattedDouble format(double value) { | ||
final format = NumberFormat.decimalPattern(locale); | ||
final decimalSeperator = format.symbols.DECIMAL_SEP; | ||
|
||
return FormattedDouble(value, decimalSeperator: decimalSeperator); | ||
} | ||
} | ||
|
||
class FormattedDouble { | ||
late double _value; | ||
late int _integer; | ||
late double _fractional; | ||
late String _decimalSeperator; | ||
|
||
FormattedDouble(this._value, {required String decimalSeperator}) { | ||
_decimalSeperator = decimalSeperator; | ||
_integer = _value.truncate(); | ||
_fractional = _value - _integer; | ||
} | ||
|
||
set value(double value) { | ||
_value = value; | ||
_integer = _value.truncate(); | ||
_fractional = _value - _integer; | ||
} | ||
|
||
set decimalSeperator(String decimalSeperator) { | ||
if (decimalSeperator.length > 1) { | ||
throw InvalidDecimalSeperator( | ||
'Decimal seperator \'$decimalSeperator\' is to long. Decimal seperator cannot be longer than one character.'); | ||
} else { | ||
_decimalSeperator = decimalSeperator; | ||
} | ||
} | ||
|
||
double get value => _value; | ||
int get integerPart => _integer; | ||
double get fractionalPart => _fractional; | ||
String get decimalSeperator => _decimalSeperator; | ||
|
||
@override | ||
String toString({bool roundLastDigit = true, int? fractionDigits}) { | ||
return '$_integer$_decimalSeperator${fractionalPartAsInt(roundLastDigit: roundLastDigit, fractionDigits: fractionDigits)}'; | ||
} | ||
|
||
String integerPartToString() { | ||
return _integer.toString(); | ||
} | ||
|
||
String fractionalPartToString() { | ||
return '0$decimalSeperator${fractionalPartAsInt()}'; | ||
} | ||
|
||
String fractionalPartAsIntToString({bool roundLastDigit = true, int? fractionDigits}) { | ||
int? frac = fractionalPartAsInt(roundLastDigit: roundLastDigit, fractionDigits: fractionDigits); | ||
if (frac != null) { | ||
return frac.toString(); | ||
} | ||
|
||
return ''; | ||
} | ||
|
||
int? fractionalPartAsInt({bool roundLastDigit = true, int? fractionDigits}) { | ||
late String fractionalString; | ||
|
||
if (fractionDigits != null && fractionDigits.isNegative) { | ||
throw const NegativeValue('Fractional digits cannot be negative'); | ||
} | ||
|
||
if (fractionDigits != null && roundLastDigit) { | ||
fractionalString = _value.toStringAsFixed(fractionDigits).split('.').last.trimCharRight('0'); | ||
} else if (fractionDigits != null && | ||
fractionDigits > 0 && | ||
!roundLastDigit) { | ||
String fracPart = _value.toString().split('.').last; | ||
fractionalString = | ||
(fracPart.length > fractionDigits) ? fracPart.substring(0, fractionDigits) : fracPart; | ||
} else if (fractionDigits != null && | ||
fractionDigits == 0 && | ||
!roundLastDigit) { | ||
return null; | ||
} else { | ||
fractionalString = _value.toString().split('.').last; | ||
} | ||
|
||
final int? fractionAsInt = (fractionalString.isNotEmpty) ? int.parse(fractionalString) : null; | ||
return fractionAsInt; | ||
} | ||
} | ||
|
||
class InvalidDecimalSeperator implements Exception { | ||
const InvalidDecimalSeperator([this.message]); | ||
|
||
final String? message; | ||
|
||
@override | ||
String toString() { | ||
String result = 'InvalidDecimalSeperator'; | ||
if (message is String) return '$result: $message'; | ||
return result; | ||
} | ||
} | ||
|
||
class NegativeValue implements Exception { | ||
const NegativeValue([this.message]); | ||
|
||
final String? message; | ||
|
||
@override | ||
String toString() { | ||
String result = 'NegativeValue'; | ||
if (message is String) return '$result: $message'; | ||
return result; | ||
} | ||
} | ||
|
||
|
||
extension StringFuncs on String { | ||
String trimCharLeft(String pattern) { | ||
if (isEmpty || pattern.isEmpty || pattern.length > length) return this; | ||
var tmp = this; | ||
while (tmp.startsWith(pattern)) { | ||
tmp = tmp.substring(pattern.length); | ||
} | ||
return tmp; | ||
} | ||
|
||
String trimCharRight(String pattern) { | ||
if (isEmpty || pattern.isEmpty || pattern.length > length) return this; | ||
var tmp = this; | ||
while (tmp.endsWith(pattern)) { | ||
tmp = tmp.substring(0, tmp.length - pattern.length); | ||
} | ||
return tmp; | ||
} | ||
|
||
String trimChar(String pattern) { | ||
return trimCharLeft(pattern).trimCharRight(pattern); | ||
} | ||
} |