File Coverage

blib/lib/Data/MuForm/Field/Float.pm
Criterion Covered Total %
statement 38 39 97.4
branch 10 16 62.5
condition n/a
subroutine 7 7 100.0
pod 1 4 25.0
total 56 66 84.8


line stmt bran cond sub pod time code
1             package Data::MuForm::Field::Float;
2             # ABSTRACT: validate a float value
3              
4 1     1   958 use Moo;
  1         7957  
  1         4  
5 1     1   1278 use Data::MuForm::Meta;
  1         2  
  1         5  
6             extends 'Data::MuForm::Field::Text';
7 1     1   661 use Types::Standard -types;
  1         44536  
  1         7  
8              
9              
10             has '+size' => ( default => 8 );
11             has 'precision' => ( is => 'rw', default => 2 );
12             has 'decimal_symbol' => ( is => 'rw', default => '.');
13             has 'decimal_symbol_for_db' => ( is => 'rw', default => '.');
14             has '+transform_input_to_value' => ( default => sub { *input_to_value } );
15             has '+transform_value_to_fif' => ( default => sub { *value_to_fif } );
16              
17             our $class_messages = {
18             'float_needed' => 'Must be a number. May contain numbers, +, - and decimal separator \'[_1]\'',
19             'float_size' => 'Total size of number must be less than or equal to {size}, but is {actual_size}',
20             'float_precision1' => 'May have only one digit after the decimal point, but has {num_digits:num}',
21             'float_precision2' => 'May have a maximum of {precision:num} digits after the decimal point, but has {num_digits:num}',
22             };
23              
24             sub get_class_messages {
25 3     3 0 3 my $self = shift;
26             return {
27 3         4 %{ $self->next::method },
  3         10  
28             %$class_messages,
29             }
30             }
31              
32             sub input_to_value {
33 4     4 0 6 my ( $self, $value ) = @_;
34 4 50       6 return $value unless defined $value;
35 4         5 $value =~ s/^\+//;
36 4         7 return $value;
37             }
38              
39             sub value_to_fif {
40 1     1 0 2 my ( $self, $value ) = @_;
41 1 50       4 return $value unless defined $value;
42 1         2 my $symbol = $self->decimal_symbol;
43 1         2 my $symbol_db = $self->decimal_symbol_for_db;
44 1         16 $value =~ s/\Q$symbol_db\E/$symbol/x;
45 1         3 return $value;
46             }
47              
48             sub validate {
49 4     4 1 3 my $field = shift;
50              
51             #return unless $field->next::method;
52 4         4 my ($integer_part, $decimal_part) = ();
53 4         6 my $value = $field->value;
54 4         7 my $symbol = $field->decimal_symbol;
55 4         5 my $symbol_db = $field->decimal_symbol_for_db;
56              
57 4 50       45 if ($value =~ m/^-?([0-9]+)(\Q$symbol\E([0-9]+))?$/x) { # \Q ... \E - All the characters between the \Q and the \E are interpreted as literal characters.
58 4         5 $integer_part = $1;
59 4 50       9 $decimal_part = defined $3 ? $3 : '';
60             }
61             else {
62 0         0 return $field->add_error( $field->get_message('float_needed'), $symbol );
63             }
64              
65             # check total float size
66 4 50       11 if ( my $allowed_size = $field->size ) {
67 4         4 my $total_size = length($integer_part) + length($decimal_part);
68 4 100       13 return $field->add_error( $field->get_message('float_size'),
69             size => $allowed_size, actual_size => $total_size )
70             if $total_size > $allowed_size;
71             }
72              
73             # check precision
74 3 50       7 if ( my $allowed_precision = $field->precision ) {
75 3 100       15 return $field->add_error_nx(
76             $field->get_message('float_precision1'),
77             $field->get_message('float_precision2'),
78             $allowed_precision, precision => $allowed_precision, num_digits => length($decimal_part))
79             if length $decimal_part > $allowed_precision;
80             }
81              
82             # Inflate to database accepted format
83 2         15 $value =~ s/\Q$symbol\E/$symbol_db/x;
84 2         4 $field->value($value);
85              
86 2         4 return 1;
87             }
88              
89             1;
90              
91             __END__
92              
93             =pod
94              
95             =encoding UTF-8
96              
97             =head1 NAME
98              
99             Data::MuForm::Field::Float - validate a float value
100              
101             =head1 VERSION
102              
103             version 0.03
104              
105             =head1 DESCRIPTION
106              
107             This accepts a positive or negative float/integer. Negative numbers may
108             be prefixed with a dash. By default a max of eight digits including 2 precision
109             are accepted. Default decimal symbol is ','.
110             Widget type is 'text'.
111              
112             # For example 1234,12 has size of 6 and precision of 2
113             # and separator symbol of ','
114              
115             has_field 'test_result' => (
116             type => 'Float',
117             size => 8, # Total size of number including decimal part.
118             precision => 2, # Size of the part after decimal symbol.
119             decimal_symbol => '.', # Decimal symbol accepted in web page form
120             decimal_symbol_for_db => '.', # For inflation. Decimal symbol accepted in DB, which automatically converted to.
121             range_start => 0,
122             range_end => 100
123             );
124              
125             =head2 messages
126              
127             float_needed
128             float_size
129             float_precision1
130             float_precision2
131              
132             =head1 AUTHOR
133              
134             Gerda Shank
135              
136             =head1 COPYRIGHT AND LICENSE
137              
138             This software is copyright (c) 2017 by Gerda Shank.
139              
140             This is free software; you can redistribute it and/or modify it under
141             the same terms as the Perl 5 programming language system itself.
142              
143             =cut