@@ -, +, @@ do not work correctly. Eg. when entering amount of "12,34" it is saved as "12.00" in the system. --- C4/Accounts.pm | 5 ++++- Koha/MoneyUtils.pm | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ t/MoneyUtils.t | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 Koha/MoneyUtils.pm create mode 100644 t/MoneyUtils.t --- a/C4/Accounts.pm +++ a/C4/Accounts.pm @@ -25,6 +25,7 @@ use C4::Stats; use C4::Members; use C4::Circulation qw(ReturnLostItem); use C4::Log qw(logaction); +use Koha::MoneyUtils qw(normalize_money); use Data::Dumper qw(Dumper); @@ -416,7 +417,9 @@ sub manualinvoice { my $notifyid = 0; my $insert; my $accountno = getnextacctno($borrowernumber); - my $amountleft = $amount; + my $amountleft = normalize_money($amount); + + $amount = normalize_money($amount); if ( ( $type eq 'L' ) or ( $type eq 'F' ) --- a/Koha/MoneyUtils.pm +++ a/Koha/MoneyUtils.pm @@ -0,0 +1,52 @@ +package Koha::MoneyUtils; + +# Copyright (c) 2014 Pasi Kallinen +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use strict; +use warnings; +use 5.010; +use C4::Context; + +use base 'Exporter'; +use version; our $VERSION = qv('1.0.0'); + +our @EXPORT = ( + qw( normalize_money ) +); + +=head1 normalize_money + +$str = normalize_money("12,35 €"); + +Parses a currency string, ignoring anything but numbers, commas and +full stops. The numbers after the last comma or full stop are considered +cents. + +Returns a "normalized" amount, using full stop as the cent separator. + +=cut + +sub normalize_money { + my $s = shift; + $s =~ s/[^\d\.,]//g; + my @tmp = split(/[\.,]/, $s); + my $cents = ((scalar(@tmp) > 1) ? pop(@tmp) : 0); + return join("", @tmp).".".$cents; +} + + +1; --- a/t/MoneyUtils.t +++ a/t/MoneyUtils.t @@ -0,0 +1,37 @@ +use strict; +use warnings; +use 5.010; + +use C4::Context; +use Test::More tests => 18; +use Test::MockModule; + +BEGIN { use_ok('Koha::MoneyUtils'); } + +my $money_string; + +my @normalize_test = ( + { 'orig' => '', 'norm' => '.0' }, + { 'orig' => '0', 'norm' => '0.0' }, + { 'orig' => '1', 'norm' => '1.0' }, + { 'orig' => '23', 'norm' => '23.0' }, + { 'orig' => '1.23', 'norm' => '1.23' }, + { 'orig' => '1,23', 'norm' => '1.23' }, + { 'orig' => '1.23 €', 'norm' => '1.23' }, + { 'orig' => '1,23€', 'norm' => '1.23' }, + { 'orig' => '$1.23', 'norm' => '1.23' }, + { 'orig' => '$ 1,23', 'norm' => '1.23' }, + { 'orig' => '.23', 'norm' => '.23' }, + { 'orig' => ',23', 'norm' => '.23' }, + { 'orig' => '.2', 'norm' => '.2' }, + { 'orig' => ',2', 'norm' => '.2' }, + { 'orig' => '1.23456', 'norm' => '1.23456' }, + { 'orig' => '1,234.56', 'norm' => '1234.56' }, + { 'orig' => '1 234,56', 'norm' => '1234.56' } + ); + + +foreach my $test (@normalize_test) { + my $errstr = 'normalize_money("'.$test->{'orig'}.'") is not '.$test->{'norm'}; + cmp_ok(normalize_money($test->{'orig'}), 'eq', $test->{'norm'}, $errstr); +} --