Line data Source code
1 : import 'package:flutter/services.dart'; 2 : import 'package:folly_fields/util/decimal.dart'; 3 : import 'package:folly_fields/util/decimal_text_formatter.dart'; 4 : import 'package:folly_fields/validators/abstract_validator.dart'; 5 : 6 : /// 7 : /// 8 : /// 9 : class NewDecimalValidator extends AbstractParserValidator<Decimal> { 10 : final int precision; 11 : final String decimalSeparator; 12 : final String thousandSeparator; 13 : 14 : /// 15 : /// 16 : /// 17 1 : NewDecimalValidator( 18 : this.precision, { 19 : this.decimalSeparator = ',', 20 : this.thousandSeparator = '.', 21 : }) : assert( 22 2 : precision >= 0, 23 : 'precision must be equals or greater than zero.', 24 : ), 25 2 : super(<TextInputFormatter>[ 26 1 : DecimalTextFormatter( 27 : precision: precision, 28 : decimalSeparator: decimalSeparator, 29 : thousandSeparator: thousandSeparator, 30 : ), 31 : ]); 32 : 33 : /// 34 : /// 35 : /// 36 1 : @override 37 : TextInputType get keyboard => TextInputType.number; 38 : 39 : /// 40 : /// 41 : /// 42 0 : @override 43 : String strip(String value) => value; 44 : 45 : /// 46 : /// 47 : /// 48 2 : String _internalStrip(String value) => super.strip(value); 49 : 50 : /// 51 : /// 52 : /// 53 1 : @override 54 : String format(Decimal decimal) { 55 1 : List<String> parts = decimal.doubleValue 56 2 : .toStringAsFixed(precision) 57 1 : .replaceAll('.', '') 58 1 : .split('') 59 1 : .reversed 60 1 : .toList(); 61 : 62 2 : int start = precision + 4; 63 2 : if (precision > 0) { 64 3 : parts.insert(precision, decimalSeparator); 65 : } else { 66 : start = 3; 67 : } 68 : 69 3 : for (int pos = start; parts.length > pos; pos += 4) { 70 2 : parts.insert(pos, thousandSeparator); 71 : } 72 : 73 2 : return parts.reversed.join(); 74 : } 75 : 76 : /// 77 : /// 78 : /// 79 0 : @override 80 0 : bool isValid(String decimal) => valid(decimal) == null; 81 : 82 : /// 83 : /// 84 : /// 85 1 : @override 86 : Decimal? parse(String? value) { 87 2 : Decimal decimal = Decimal(precision: precision); 88 : 89 1 : if (value == null || value.isEmpty) { 90 : return decimal; 91 : } 92 : 93 2 : int sepPos = value.indexOf(decimalSeparator); 94 : 95 : String integerPart = '0'; 96 : String decimalPart = '0'; 97 : 98 1 : if (sepPos < 0) { 99 : integerPart = value; 100 1 : } else if (sepPos == 0) { 101 1 : decimalPart = _internalStrip(value); 102 : } else { 103 2 : integerPart = _internalStrip(value.substring(0, sepPos)); 104 2 : decimalPart = _internalStrip(value.substring(sepPos)); 105 : } 106 : 107 3 : if (decimalPart.length > precision) { 108 2 : decimalPart = decimalPart.substring(0, precision); 109 : } 110 : 111 1 : String str = '$integerPart.$decimalPart'; 112 : 113 2 : decimal.doubleValue = double.tryParse(str) ?? 0; 114 : 115 : return decimal; 116 : } 117 : 118 : /// 119 : /// 120 : /// 121 0 : @override 122 : String? valid(String value) => null; 123 : }