Bug 29407: Make the pickup locations dropdown JS reusable
[koha.git] / members / paycollect.pl
1 #!/usr/bin/perl
2 # Copyright 2009,2010 PTFS Inc.
3 # Copyright 2011 PTFS-Europe Ltd
4 #
5 # This file is part of Koha.
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 use URI::Escape qw( uri_escape uri_unescape );
22 use CGI qw ( -utf8 );
23
24 use C4::Context;
25 use C4::Auth qw( get_template_and_user );
26 use C4::Output qw( output_and_exit_if_error output_and_exit output_html_with_http_headers );
27 use C4::Accounts;
28 use C4::Koha;
29
30 use Koha::Cash::Registers;
31 use Koha::Patrons;
32 use Koha::Patron::Categories;
33 use Koha::AuthorisedValues;
34 use Koha::Account;
35 use Koha::Token;
36 use Koha::DateUtils qw( output_pref );
37
38 my $input = CGI->new();
39
40 my $payment_id          = $input->param('payment_id');
41 my $writeoff_individual = $input->param('writeoff_individual');
42 my $change_given        = $input->param('change_given');
43 my $type                = scalar $input->param('type') || 'PAYMENT';
44
45 my $updatecharges_permissions = ($writeoff_individual || $type eq 'WRITEOFF') ? 'writeoff' : 'remaining_permissions';
46 my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
47     {   template_name   => 'members/paycollect.tt',
48         query           => $input,
49         type            => 'intranet',
50         flagsrequired   => { borrowers => 'edit_borrowers', updatecharges => $updatecharges_permissions },
51     }
52 );
53
54 # get borrower details
55 my $borrowernumber = $input->param('borrowernumber');
56 my $logged_in_user = Koha::Patrons->find( $loggedinuser );
57 my $patron         = Koha::Patrons->find( $borrowernumber );
58 output_and_exit_if_error( $input, $cookie, $template, { module => 'members', logged_in_user => $logged_in_user, current_patron => $patron } );
59
60 my $borrower       = $patron->unblessed;
61 my $account        = $patron->account;
62 my $category       = $patron->category;
63 my $user           = $input->remote_user;
64
65 my $library_id = C4::Context->userenv->{'branch'};
66 my $total_due  = $account->outstanding_debits->total_outstanding;
67
68 my $total_paid      = $input->param('paid');
69 my $total_collected = $input->param('collected');
70
71 my $selected_lines = $input->param('selected'); # comes from pay.pl
72 my $pay_individual   = $input->param('pay_individual');
73 my $selected_accts   = $input->param('selected_accts'); # comes from paycollect.pl
74 my $payment_note = uri_unescape scalar $input->param('payment_note');
75 my $payment_type = scalar $input->param('payment_type');
76 my $accountlines_id;
77
78 my $cash_register_id = $input->param('cash_register');
79 if ( $pay_individual || $writeoff_individual ) {
80     if ($pay_individual) {
81         $template->param( pay_individual => 1 );
82     } elsif ($writeoff_individual) {
83         $template->param( writeoff_individual => 1 );
84     }
85     my $debit_type_code   = $input->param('debit_type_code');
86     $accountlines_id      = $input->param('accountlines_id');
87     my $amount            = $input->param('amount');
88     my $amountoutstanding = $input->param('amountoutstanding');
89     my $itemnumber  = $input->param('itemnumber');
90     my $description  = $input->param('description');
91     my $title        = $input->param('title');
92     $total_due = $amountoutstanding;
93     $template->param(
94         debit_type_code    => $debit_type_code,
95         accountlines_id    => $accountlines_id,
96         amount            => $amount,
97         amountoutstanding => $amountoutstanding,
98         title             => $title,
99         itemnumber        => $itemnumber,
100         individual_description => $description,
101         payment_note    => $payment_note,
102     );
103 } elsif ($selected_lines) {
104     $total_due = $input->param('amt');
105     $template->param(
106         selected_accts => $selected_lines,
107         amt            => $total_due,
108         selected_accts_notes => scalar $input->param('notes'),
109     );
110 }
111
112 my @selected_accountlines;
113 if ( $selected_accts ) {
114     if ( $selected_accts =~ /^([\d,]*).*/ ) {
115         $selected_accts = $1;    # ensure passing no junk
116     }
117     my @acc = split /,/, $selected_accts;
118
119     my $search_params = {
120         borrowernumber    => $borrowernumber,
121             amountoutstanding => { '<>' => 0 },
122             accountlines_id   => { 'in' => \@acc },
123     };
124
125     @selected_accountlines = Koha::Account::Lines->search(
126         $search_params,
127         { order_by => 'date' }
128     );
129
130     my $sum = Koha::Account::Lines->search(
131         $search_params,
132         {
133             select => [ { sum => 'amountoutstanding' } ],
134             as     => [ 'total_amountoutstanding'],
135         }
136     );
137     $total_due = $sum->_resultset->first->get_column('total_amountoutstanding');
138 }
139
140 if ( $total_paid and $total_paid ne '0.00' ) {
141     $total_paid = $total_due if (abs($total_paid - $total_due) < 0.01) && C4::Context->preference('RoundFinesAtPayment');
142     if ( $total_paid < 0 or $total_paid > $total_due ) {
143         $template->param(
144             error_over => 1,
145             total_due => $total_due
146         );
147     } elsif ( $total_collected < $total_paid && !( $writeoff_individual || $type eq 'WRITEOFF' ) ) {
148         $template->param(
149             error_under => 1,
150             total_paid => $total_paid
151         );
152     } else {
153         output_and_exit( $input, $cookie, $template,  'wrong_csrf_token' )
154             unless Koha::Token->new->check_csrf( {
155                 session_id => $input->cookie('CGISESSID'),
156                 token  => scalar $input->param('csrf_token'),
157             });
158
159         my $url;
160         my $pay_result;
161         if ($pay_individual) {
162             my $line = Koha::Account::Lines->find($accountlines_id);
163             $pay_result = $account->pay(
164                 {
165                     lines        => [$line],
166                     amount       => $total_paid,
167                     library_id   => $library_id,
168                     note         => $payment_note,
169                     interface    => C4::Context->interface,
170                     payment_type => $payment_type,
171                     cash_register => $cash_register_id
172                 }
173             );
174             $payment_id = $pay_result->{payment_id};
175
176             $url = "/cgi-bin/koha/members/pay.pl";
177         } else {
178             if ($selected_accts) {
179                 if ( $total_paid > $total_due ) {
180                     $template->param(
181                         error_over => 1,
182                         total_due => $total_due
183                     );
184                 } else {
185                     my $note = $input->param('selected_accts_notes');
186
187                     $pay_result = $account->pay(
188                         {
189                             type         => $type,
190                             amount       => $total_paid,
191                             library_id   => $library_id,
192                             lines        => \@selected_accountlines,
193                             note         => $note,
194                             interface    => C4::Context->interface,
195                             payment_type => $payment_type,
196                             cash_register => $cash_register_id
197                         }
198                     );
199                 }
200                 $payment_id = $pay_result->{payment_id};
201             }
202             else {
203                 my $note = $input->param('selected_accts_notes');
204                 $pay_result = $account->pay(
205                     {
206                         amount       => $total_paid,
207                         library_id   => $library_id,
208                         note         => $note,
209                         payment_type => $payment_type,
210                         interface    => C4::Context->interface,
211                         payment_type => $payment_type,
212                         cash_register => $cash_register_id
213                     }
214                 );
215                 $payment_id = $pay_result->{payment_id};
216             }
217             $payment_id = $pay_result->{payment_id};
218
219             $url = "/cgi-bin/koha/members/boraccount.pl";
220         }
221         # It's possible renewals took place, parse any renew results
222         # and pass on
223         my @renew_result = ();
224         foreach my $ren( @{$pay_result->{renew_result}} ) {
225             my $str = "renew_result=$ren->{itemnumber},$ren->{success},";
226             my $app = $ren->{success} ?
227                 uri_escape(
228                     output_pref({ dt => $ren->{due_date}, as_due_date => 1 })
229                 ) : $ren->{error};
230                 push @renew_result, "${str}${app}";
231         }
232         my $append = scalar @renew_result ? '&' . join('&', @renew_result) : '';
233
234         $url .= "?borrowernumber=$borrowernumber&payment_id=$payment_id&change_given=${change_given}${append}";
235
236         print $input->redirect($url);
237     }
238 } else {
239     $total_paid = '0.00';    #TODO not right with pay_individual
240 }
241
242 $template->param(%$borrower);
243
244 if ( $input->param('error_over') ) {
245     $template->param( error_over => 1, total_due => scalar $input->param('amountoutstanding') );
246 }
247
248 $template->param(
249     payment_id => $payment_id,
250
251     type           => $type,
252     borrowernumber => $borrowernumber,    # some templates require global
253     patron         => $patron,
254     total          => $total_due,
255
256     csrf_token => Koha::Token->new->generate_csrf( { session_id => scalar $input->cookie('CGISESSID') } ),
257 );
258
259 output_html_with_http_headers $input, $cookie, $template->output;