Bug 22521: DBRev 18.12.00.055
[koha.git] / Koha / Number / Price.pm
1 package Koha::Number::Price;
2
3 # This file is part of Koha.
4 #
5 # Copyright 2014 BibLibre
6 #
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20 use Modern::Perl;
21
22 use Number::Format;
23 use C4::Context;
24 use Koha::Acquisition::Currencies;
25
26 use base qw( Class::Accessor );
27 __PACKAGE__->mk_accessors(qw( value ));
28
29 sub new {
30     my ( $class, $value ) = @_;
31
32     my $self->{value} = $value || 0;
33
34     bless $self, $class;
35     return $self;
36 }
37
38 sub format {
39     my ( $self, $params ) = @_;
40     return unless defined $self->value;
41
42     my $format_params = $self->_format_params( $params );
43
44     # To avoid the system to crash, we will not format big number
45     # We divide per 100 because we want to keep the default DECIMAL_DIGITS (2)
46     # error - round() overflow. Try smaller precision or use Math::BigFloat
47     return $self->value if $self->value > Number::Format::MAX_INT/100;
48
49     return Number::Format->new(%$format_params)->format_price($self->value);
50 }
51
52 sub format_for_editing {
53     my ( $self, $params ) = @_;
54     return unless defined $self->value;
55
56     my $format_params = $self->_format_params( $params );
57     $format_params = {
58         %$format_params,
59         int_curr_symbol   => '',
60         mon_thousands_sep => '',
61         mon_decimal_point => '.',
62     };
63
64     # To avoid the system to crash, we will not format big number
65     # We divide per 100 because we want to keep the default DECIMAL_DIGITS (2)
66     # error - round() overflow. Try smaller precision or use Math::BigFloat
67     return $self->value if $self->value > Number::Format::MAX_INT/100;
68
69     return Number::Format->new(%$format_params)->format_price($self->value);
70 }
71
72 sub unformat {
73     my ( $self, $params ) = @_;
74     return unless defined $self->value;
75
76     my $format_params = $self->_format_params( $params );
77
78     return Number::Format->new(%$format_params)->unformat_number($self->value);
79 }
80
81 sub round {
82     my ( $self ) = @_;
83     return unless defined $self->value;
84
85     my $format_params = $self->_format_params;
86
87     # To avoid the system to crash, we will not format big number
88     # We divide per 100 because we want to keep the default DECIMAL_DIGITS (2)
89     # error - round() overflow. Try smaller precision or use Math::BigFloat
90     return $self->value if $self->value > Number::Format::MAX_INT/100;
91
92     return Number::Format->new(%$format_params)->round($self->value);
93 }
94
95 sub _format_params {
96     my ( $self, $params ) = @_;
97     my $with_symbol = $params->{with_symbol} || 0;
98     my $p_cs_precedes = $params->{p_cs_precedes};
99     my $currency        = Koha::Acquisition::Currencies->get_active;
100     my $currency_format = C4::Context->preference("CurrencyFormat");
101
102     my $int_curr_symbol = ( $with_symbol and $currency ) ? $currency->symbol : q||;
103     my %format_params = (
104         decimal_fill      => '2',
105         decimal_point     => '.',
106         int_curr_symbol   => $int_curr_symbol,
107         mon_thousands_sep => ',',
108         thousands_sep     => ',',
109         mon_decimal_point => '.'
110     );
111
112     if ( $currency_format eq 'FR' ) {
113         %format_params = (
114             decimal_fill      => '2',
115             decimal_point     => ',',
116             int_curr_symbol   => $int_curr_symbol,
117             mon_thousands_sep => ' ',
118             thousands_sep     => ' ',
119             mon_decimal_point => ','
120         );
121     }
122
123     if ( $currency_format eq 'CH' ) {
124         %format_params = (
125             decimal_fill      => '2',
126             decimal_point     => '.',
127             int_curr_symbol   => $int_curr_symbol,
128             mon_thousands_sep => '\'',
129             thousands_sep     => '\'',
130             mon_decimal_point => '.'
131         );
132     }
133
134
135     $format_params{p_cs_precedes}  = $p_cs_precedes  if defined $p_cs_precedes;
136     $format_params{p_sep_by_space} = ( $currency and $currency->p_sep_by_space ) ? 1 : 0;
137
138     return \%format_params;
139 }
140
141 1;