View | Details | Raw Unified | Return to bug 21507
Collapse All | Expand All

(-)a/Koha/Number/Price.pm (+18 lines)
Lines 53-58 sub format_for_editing { Link Here
53
    return unless defined $self->value;
53
    return unless defined $self->value;
54
54
55
    my $format_params = $self->_format_params( $params );
55
    my $format_params = $self->_format_params( $params );
56
    my $currency_format = C4::Context->preference("CurrencyFormat");
57
56
    $format_params = {
58
    $format_params = {
57
        %$format_params,
59
        %$format_params,
58
        int_curr_symbol   => '',
60
        int_curr_symbol   => '',
Lines 60-65 sub format_for_editing { Link Here
60
        mon_decimal_point => '.',
62
        mon_decimal_point => '.',
61
    };
63
    };
62
64
65
    if ( $currency_format eq 'FR' ) {
66
        %$format_params = (
67
            int_curr_symbol   => '',
68
            mon_thousands_sep => ' ',
69
            mon_decimal_point => ','
70
        );
71
    }
72
73
    if ( $currency_format eq 'CH' ) {
74
        %$format_params = (
75
            int_curr_symbol   => '',
76
            mon_thousands_sep => '\'',
77
            mon_decimal_point => '.'
78
        );
79
    }
80
63
    # To avoid the system to crash, we will not format big number
81
    # To avoid the system to crash, we will not format big number
64
    # We divide per 100 because we want to keep the default DECIMAL_DIGITS (2)
82
    # We divide per 100 because we want to keep the default DECIMAL_DIGITS (2)
65
    # error - round() overflow. Try smaller precision or use Math::BigFloat
83
    # error - round() overflow. Try smaller precision or use Math::BigFloat
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/decimal-input-js.inc (+24 lines)
Line 0 Link Here
1
[% USE Koha %]
2
3
<script type="text/javascript">
4
    var currency_format = "[% Koha.Preference('CurrencyFormat') %]";
5
    if (currency_format === "US" || currency_format === "CH") {
6
        var decimal_separator = ".";
7
    } else if (currency_format === "FR") {
8
        var decimal_separator = ",";
9
    } else {
10
        console.error("Unhandled value for currency_format: \"" + currency_format +"\" You should report this issue to avoid unexpected behavior with numbers. Note that you should also check the code displaying the example value in manual invoice and credit pages.")
11
        var decimal_separator = ".";
12
    }
13
14
    // allow only non-decimal numbers and decimal numbers containing a dot or a comma
15
    jQuery.validator.addMethod("is_decimal_number", function(value, element){
16
        return /^\d+(\.|,)?\d*$/.test(value);
17
    }, _("Please input a decimal number without thousands separators"));
18
19
    jQuery.validator.addMethod("uses_correct_decimal_separator", function(value, element){
20
        var non_decimal_number = /^\d+$/.test(value);
21
        var correct_decimal_number = value.indexOf(decimal_separator) !== -1;
22
        return non_decimal_number || correct_decimal_number;
23
    }, _("Please do not use thousands separators and only the decimal separator shown in the example: "));
24
</script>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/mancredit.tt (-1 / +12 lines)
Lines 83-89 Link Here
83
                                    <li><label for="barcode">Barcode: </label><input type="text" name="barcode" id="barcode" /></li>
83
                                    <li><label for="barcode">Barcode: </label><input type="text" name="barcode" id="barcode" /></li>
84
                                    <li><label for="desc">Description: </label><input type="text" name="desc" size="50" id="desc" /></li>
84
                                    <li><label for="desc">Description: </label><input type="text" name="desc" size="50" id="desc" /></li>
85
                                    <li><label for="note">Note: </label><input type="text" name="note" size="50" id="note" /></li>
85
                                    <li><label for="note">Note: </label><input type="text" name="note" size="50" id="note" /></li>
86
                                    <li><label for="amount" class="required">Amount: </label><input type="text" inputmode="decimal" pattern="^\d+(\.\d{2})?$" name="amount" id="amount" required="required" min="0" value=""/> Example: 5.00</li>
86
                                    <li><label for="amount" class="required">Amount: </label><input type="text" inputmode="decimal" pattern=[% decimal_input_pattern %] name="amount" id="amount" required="required" value=""/> Example: 5[% decimal_delimiter | html %]12</li>
87
                                    [% INCLUDE 'transaction_types.inc' type="credit" %]
87
                                    [% INCLUDE 'transaction_types.inc' type="credit" %]
88
                                    [% IF Koha.Preference('UseCashRegisters') %]
88
                                    [% IF Koha.Preference('UseCashRegisters') %]
89
                                    <li>
89
                                    <li>
Lines 135-144 Link Here
135
[% MACRO jsinclude BLOCK %]
135
[% MACRO jsinclude BLOCK %]
136
    [% INCLUDE 'str/members-menu.inc' %]
136
    [% INCLUDE 'str/members-menu.inc' %]
137
    [% Asset.js("js/members-menu.js") | $raw %]
137
    [% Asset.js("js/members-menu.js") | $raw %]
138
    [% INCLUDE 'decimal-input-js.inc' %]
139
138
    <script>
140
    <script>
139
        $(document).ready(function(){
141
        $(document).ready(function(){
140
            $('#mancredit').preventDoubleFormSubmit();
142
            $('#mancredit').preventDoubleFormSubmit();
141
            $("fieldset.rows input, fieldset.rows select").addClass("noEnterSubmit");
143
            $("fieldset.rows input, fieldset.rows select").addClass("noEnterSubmit");
144
            // decimal input
145
            $("#mancredit").validate({
146
                rules: {
147
                    amount: {
148
                        is_decimal_number: true,
149
                        uses_correct_decimal_separator: true
150
                    },
151
                }
152
            });
142
            [% UNLESS Koha.Preference('RequireCashRegister') %]
153
            [% UNLESS Koha.Preference('RequireCashRegister') %]
143
            $('#credit_type').on('change', function() {
154
            $('#credit_type').on('change', function() {
144
               let val = $(this).val();
155
               let val = $(this).val();
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/maninvoice.tt (-2 / +12 lines)
Lines 94-101 Link Here
94
                            </li>
94
                            </li>
95
                            <li><label for="barcode">Barcode: </label><input type="text" name="barcode" id="barcode" value="[% barcode | html %]" /></li>
95
                            <li><label for="barcode">Barcode: </label><input type="text" name="barcode" id="barcode" value="[% barcode | html %]" /></li>
96
                            <li><label for="desc">Description: </label><input type="text" name="desc" id="desc" size="50" value="[% desc | html %]" /></li>
96
                            <li><label for="desc">Description: </label><input type="text" name="desc" id="desc" size="50" value="[% desc | html %]" /></li>
97
                            <li><label for="note">Note: </label><input type="text" name="note" size="50" id="note" value="[% note | html %]" /></li>
97
                            <li><label for="note">Note: </label><input type="text" name="note" size="50" id="note" value="[% note | html %]" /></li>    
98
                            <li><label for="amount">Amount: </label><input type="text" inputmode="decimal" pattern="^\d+(\.\d{2})?$" name="amount" id="amount" required="required" min="0" value="[% amount | $Price on_editing => 1 %]" /> Example: 5.00</li>
98
                            <li><label for="amount">Amount: </label><input type="text" inputmode="decimal" pattern=[% decimal_input_pattern %] name="amount" id="amount" required="required" value="[% amount | $Price on_editing => 1 %]" /> 5[% decimal_delimiter | html %]12</li>
99
                        </ol>
99
                        </ol>
100
                    </fieldset>
100
                    </fieldset>
101
101
Lines 127-132 Link Here
127
[% MACRO jsinclude BLOCK %]
127
[% MACRO jsinclude BLOCK %]
128
    [% INCLUDE 'str/members-menu.inc' %]
128
    [% INCLUDE 'str/members-menu.inc' %]
129
    [% Asset.js("js/members-menu.js") | $raw %]
129
    [% Asset.js("js/members-menu.js") | $raw %]
130
    [% INCLUDE 'decimal-input-js.inc' %]
130
    <script>
131
    <script>
131
        var type_fees = {};
132
        var type_fees = {};
132
        [% FOREACH debit_type IN debit_types %]
133
        [% FOREACH debit_type IN debit_types %]
Lines 135-140 Link Here
135
        $(document).ready(function(){
136
        $(document).ready(function(){
136
            $('#maninvoice').preventDoubleFormSubmit();
137
            $('#maninvoice').preventDoubleFormSubmit();
137
            $("fieldset.rows input, fieldset.rows select").addClass("noEnterSubmit");
138
            $("fieldset.rows input, fieldset.rows select").addClass("noEnterSubmit");
139
            // decimal input
140
            $("#maninvoice").validate({
141
                rules: {
142
                    amount: {
143
                        is_decimal_number: true,
144
                        uses_correct_decimal_separator: true
145
                    },
146
                }
147
            });
138
            $("#invoice_type").on("change",function(){
148
            $("#invoice_type").on("change",function(){
139
                this.form.desc.value = this.options[this.selectedIndex].value;
149
                this.form.desc.value = this.options[this.selectedIndex].value;
140
                this.form.amount.value = type_fees[this.options[this.selectedIndex].value];
150
                this.form.amount.value = type_fees[this.options[this.selectedIndex].value];
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/paycollect.tt (-4 / +4 lines)
Lines 175-185 Link Here
175
175
176
    <li>
176
    <li>
177
        <label for="paid">Amount being paid: </label>
177
        <label for="paid">Amount being paid: </label>
178
        <input name="paid" id="paid" type="text" step="0.01" min="0" value="[% amountoutstanding | $Price on_editing => 1 %]"/>
178
        <input name="paid" id="paid" type="text" value="[% amountoutstanding | $Price on_editing => 1 %]"/>
179
    </li>
179
    </li>
180
    <li>
180
    <li>
181
        <label for="collected">Amount tendered: </label>
181
        <label for="collected">Amount tendered: </label>
182
        <input name="collected" id="collected" type="text" step="0.01" min="0" value="[% amountoutstanding | $Price on_editing => 1 %]"/>
182
        <input name="collected" id="collected" type="text" value="[% amountoutstanding | $Price on_editing => 1 %]"/>
183
    </li>
183
    </li>
184
    <li>
184
    <li>
185
        <label>Change to give: </label>
185
        <label>Change to give: </label>
Lines 328-339 Link Here
328
        [% ELSE %]
328
        [% ELSE %]
329
            <label for="paid">Amount being paid: </label>
329
            <label for="paid">Amount being paid: </label>
330
        [% END %]
330
        [% END %]
331
        <input name="paid" id="paid" type="text" step="0.01" min="0" value="[% total | $Price on_editing => 1 %]"/>
331
        <input name="paid" id="paid" type="text" value="[% total | $Price on_editing => 1 %]"/>
332
    </li>
332
    </li>
333
    [% IF type != 'WRITEOFF' %]
333
    [% IF type != 'WRITEOFF' %]
334
        <li>
334
        <li>
335
            <label for="collected">Amount tendered: </label>
335
            <label for="collected">Amount tendered: </label>
336
            <input name="collected" id="collected" type="text" step="0.01" min="0" value="[% total | $Price on_editing => 1 %]"/>
336
            <input name="collected" id="collected" type="text" value="[% total | $Price on_editing => 1 %]"/>
337
        </li>
337
        </li>
338
        <li>
338
        <li>
339
            <label>Change to give: </label>
339
            <label>Change to give: </label>
(-)a/members/mancredit.pl (+12 lines)
Lines 68-73 output_and_exit_if_error( Link Here
68
my $library_id =
68
my $library_id =
69
  C4::Context->userenv ? C4::Context->userenv->{'branch'} : undef;
69
  C4::Context->userenv ? C4::Context->userenv->{'branch'} : undef;
70
70
71
my $decimal_delimiter =
72
  C4::Context->preference('CurrencyFormat') eq 'FR' ? ',' : '.';
73
my $decimal_input_pattern =
74
  C4::Context->preference('CurrencyFormat') eq 'FR'
75
  ? '^\d+(\,\d{2})?$'
76
  : '^\d+(\.\d{2})?$';
77
$template->param(
78
    decimal_delimiter     => $decimal_delimiter,
79
    decimal_input_pattern => $decimal_input_pattern,
80
);
81
71
my $add = $input->param('add');
82
my $add = $input->param('add');
72
if ($add) {
83
if ($add) {
73
    output_and_exit( $input, $cookie, $template, 'wrong_csrf_token' )
84
    output_and_exit( $input, $cookie, $template, 'wrong_csrf_token' )
Lines 89-94 if ($add) { Link Here
89
    my $description      = $input->param('desc');
100
    my $description      = $input->param('desc');
90
    my $note             = $input->param('note');
101
    my $note             = $input->param('note');
91
    my $amount           = $input->param('amount') || 0;
102
    my $amount           = $input->param('amount') || 0;
103
    $amount              = Koha::Number::Price->new($amount)->unformat();
92
    my $type             = $input->param('type');
104
    my $type             = $input->param('type');
93
    my $credit_type      = $input->param('credit_type');
105
    my $credit_type      = $input->param('credit_type');
94
    my $cash_register_id = $input->param('cash_register');
106
    my $cash_register_id = $input->param('cash_register');
(-)a/members/maninvoice.pl (-11 / +25 lines)
Lines 42-47 use Koha::Old::Checkouts; Link Here
42
use Koha::Patron::Categories;
42
use Koha::Patron::Categories;
43
use Koha::Account::DebitTypes;
43
use Koha::Account::DebitTypes;
44
use Koha::AdditionalFields;
44
use Koha::AdditionalFields;
45
use Koha::Number::Price;
46
use C4::Context;
45
47
46
my $input = CGI->new;
48
my $input = CGI->new;
47
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
49
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
Lines 78-94 output_and_exit_if_error( Link Here
78
my $library_id = C4::Context->userenv->{'branch'};
80
my $library_id = C4::Context->userenv->{'branch'};
79
my $desc       = $input->param('desc');
81
my $desc       = $input->param('desc');
80
my $amount     = $input->param('amount');
82
my $amount     = $input->param('amount');
83
$amount = Koha::Number::Price->new( $amount )->format();
81
my $note       = $input->param('note');
84
my $note       = $input->param('note');
82
my $debit_type = $input->param('type');
85
my $debit_type = $input->param('type');
83
my $barcode    = $input->param('barcode');
86
my $barcode    = $input->param('barcode');
87
my $decimal_delimiter =
88
  C4::Context->preference('CurrencyFormat') eq 'FR' ? ',' : '.';
89
my $decimal_input_pattern =
90
  C4::Context->preference('CurrencyFormat') eq 'FR'
91
  ? '^\d+(\,\d{2})?$'
92
  : '^\d+(\.\d{2})?$';
84
$template->param(
93
$template->param(
85
    desc    => $desc,
94
    desc                  => $desc,
86
    amount  => $amount,
95
    amount                => $amount,
87
    note    => $note,
96
    note                  => $note,
88
    type    => $debit_type,
97
    type                  => $debit_type,
89
    barcode => $barcode
98
    barcode               => $barcode,
99
    decimal_delimiter     => $decimal_delimiter,
100
    decimal_input_pattern => $decimal_input_pattern,
90
);
101
);
91
102
103
92
my $add = $input->param('add');
104
my $add = $input->param('add');
93
if ($add) {
105
if ($add) {
94
    output_and_exit( $input, $cookie, $template, 'wrong_csrf_token' )
106
    output_and_exit( $input, $cookie, $template, 'wrong_csrf_token' )
Lines 101-110 if ($add) { Link Here
101
113
102
    # Note: If the logged in user is not allowed to see this patron an invoice can be forced
114
    # Note: If the logged in user is not allowed to see this patron an invoice can be forced
103
    # Here we are trusting librarians not to hack the system
115
    # Here we are trusting librarians not to hack the system
104
    my $desc       = $input->param('desc');
116
    my $desc        = $input->param('desc');
105
    my $amount     = $input->param('amount');
117
    my $amount      = $input->param('amount');
106
    my $note       = $input->param('note');
118
    $amount         = Koha::Number::Price->new($amount)->unformat();
107
    my $debit_type = $input->param('type');
119
    my $note        = $input->param('note');
120
    my $debit_type  = $input->param('type');
121
108
122
109
    # If barcode is passed, attempt to find the associated item
123
    # If barcode is passed, attempt to find the associated item
110
    my $failed;
124
    my $failed;
Lines 133-139 if ($add) { Link Here
133
            my $checkouts = Koha::Checkouts->search(
147
            my $checkouts = Koha::Checkouts->search(
134
                {
148
                {
135
                    itemnumber     => $item_id,
149
                    itemnumber     => $item_id,
136
                    borrowernumber => $borrowernumber
150
                    borrowernumber => $borrowernumber    
137
                }
151
                }
138
            );
152
            );
139
            my $checkout =
153
            my $checkout =
Lines 162-168 if ($add) { Link Here
162
                    library_id  => $library_id,
176
                    library_id  => $library_id,
163
                    type        => $debit_type,
177
                    type        => $debit_type,
164
                    ( $olditem ? () : ( item_id => $item_id ) ),
178
                    ( $olditem ? () : ( item_id => $item_id ) ),
165
                    issue_id    => $issue_id
179
                    issue_id    => $issue_id,
166
                }
180
                }
167
            );
181
            );
168
182
(-)a/members/pay.pl (+3 lines)
Lines 43-48 use Koha::Items; Link Here
43
43
44
use Koha::Patron::Categories;
44
use Koha::Patron::Categories;
45
use URI::Escape qw( uri_escape_utf8 uri_unescape );
45
use URI::Escape qw( uri_escape_utf8 uri_unescape );
46
use Koha::Number::Price;
46
47
47
our $input = CGI->new;
48
our $input = CGI->new;
48
49
Lines 100-105 elsif ( $input->param('confirm_writeoff') ) { Link Here
100
101
101
    my $accountline = Koha::Account::Lines->find( $accountlines_id );
102
    my $accountline = Koha::Account::Lines->find( $accountlines_id );
102
103
104
    $amount  = Koha::Number::Price->new( $amount )->unformat();
105
103
    $amount = $accountline->amountoutstanding if (abs($amount - $accountline->amountoutstanding) < 0.01) && C4::Context->preference('RoundFinesAtPayment');
106
    $amount = $accountline->amountoutstanding if (abs($amount - $accountline->amountoutstanding) < 0.01) && C4::Context->preference('RoundFinesAtPayment');
104
    if ( $amount > $accountline->amountoutstanding ) {
107
    if ( $amount > $accountline->amountoutstanding ) {
105
        print $input->redirect( "/cgi-bin/koha/members/paycollect.pl?"
108
        print $input->redirect( "/cgi-bin/koha/members/paycollect.pl?"
(-)a/members/paycollect.pl (-2 / +6 lines)
Lines 36-41 use Koha::Account::Lines; Link Here
36
use Koha::AdditionalFields;
36
use Koha::AdditionalFields;
37
use Koha::Token;
37
use Koha::Token;
38
use Koha::DateUtils qw( output_pref );
38
use Koha::DateUtils qw( output_pref );
39
use Koha::Number::Price;
40
use Number::Format qw( unformat_number );
39
41
40
my $input = CGI->new();
42
my $input = CGI->new();
41
43
Lines 136-141 if ( $selected_accts ) { Link Here
136
    $total_due = $sum->_resultset->first->get_column('total_amountoutstanding');
138
    $total_due = $sum->_resultset->first->get_column('total_amountoutstanding');
137
}
139
}
138
140
141
$total_paid  = Koha::Number::Price->new( $total_paid )->unformat();
142
139
if ( $total_paid and $total_paid ne '0.00' ) {
143
if ( $total_paid and $total_paid ne '0.00' ) {
140
    $total_paid = $total_due if (abs($total_paid - $total_due) < 0.01) && C4::Context->preference('RoundFinesAtPayment');
144
    $total_paid = $total_due if (abs($total_paid - $total_due) < 0.01) && C4::Context->preference('RoundFinesAtPayment');
141
    if ( $total_paid < 0 or $total_paid > $total_due ) {
145
    if ( $total_paid < 0 or $total_paid > $total_due ) {
Lines 272-278 if ( $total_paid and $total_paid ne '0.00' ) { Link Here
272
}
276
}
273
277
274
if ( $input->param('error_over') ) {
278
if ( $input->param('error_over') ) {
275
    $template->param( error_over => 1, total_due => scalar $input->param('amountoutstanding') );
279
    my $amountoutstanding = Koha::Number::Price->new($input->param('amountoutstanding'))->format();
280
    $template->param( error_over => 1, total_due => scalar $amountoutstanding );
276
}
281
}
277
282
278
$template->param(
283
$template->param(
279
- 

Return to bug 21507