From c75b0d3c56832a58fd7f8a45a2681b746354d035 Mon Sep 17 00:00:00 2001 From: Colin Campbell Date: Fri, 26 Mar 2010 12:21:42 +0000 Subject: [PATCH] Bug 3498 Allow Partial Payment in Fines Content-Type: text/plain; charset="utf-8" Allow partial payment of outstanding fines either against individual fine entries or as a lump payment. Sponsered by East Brunswick Public Library, East Brunswick, NJ, USA --- C4/Accounts.pm | 101 ++++++- .../intranet-tmpl/prog/en/modules/members/pay.tmpl | 39 ++- .../prog/en/modules/members/paycollect.tmpl | 221 ++++++++++++ members/pay.pl | 371 +++++++++++++------- members/paycollect.pl | 188 ++++++++++ 5 files changed, 783 insertions(+), 137 deletions(-) create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/members/paycollect.tmpl create mode 100755 members/paycollect.pl diff --git a/C4/Accounts.pm b/C4/Accounts.pm index bbc6c00..bce9c19 100644 --- a/C4/Accounts.pm +++ b/C4/Accounts.pm @@ -35,8 +35,9 @@ BEGIN { @EXPORT = qw( &recordpayment &makepayment &manualinvoice &getnextacctno &reconcileaccount &getcharges &getcredits - &getrefunds &chargelostitem + &getrefunds &chargelostitem makepartialpayment &ReversePayment + recordpayment_selectaccts ); # removed &fixaccounts } @@ -132,6 +133,70 @@ sub recordpayment { $sth->finish; } +=head2 recordpayment_selectaccts + + recordpayment_selectaccts($borrowernumber, $payment,$accts); + +Record payment by a patron. C<$borrowernumber> is the patron's +borrower number. C<$payment> is a floating-point number, giving the +amount that was paid. C<$accts> is an array ref to a list of +accountnos which the payment can be recorded against + +Amounts owed are paid off oldest first. That is, if the patron has a +$1 fine from Feb. 1, another $1 fine from Mar. 1, and makes a payment +of $1.50, then the oldest fine will be paid off in full, and $0.50 +will be credited to the next one. + +=cut + +sub recordpayment_selectaccts { + my ( $borrowernumber, $amount, $accts ) = @_; + + my $dbh = C4::Context->dbh; + my $newamtos = 0; + my $accdata = q{}; + my $branch = C4::Context->userenv->{branch}; + my $amountleft = $amount; + my $sql = 'SELECT * FROM accountlines WHERE (borrowernumber = ?) ' . + 'AND (amountoutstanding<>0) '; + if (@{$accts} ) { + $sql .= ' AND accountno IN ( ' . join ',', @{$accts}; + $sql .= ' ) '; + } + $sql .= ' ORDER BY date'; + # begin transaction + my $nextaccntno = getnextacctno($borrowernumber); + + # get lines with outstanding amounts to offset + my $rows = $dbh->selectall_arrayref($sql, { Slice => {} }, $borrowernumber); + + # offset transactions + my $sth = $dbh->prepare('UPDATE accountlines SET amountoutstanding= ? ' . + 'WHERE (borrowernumber = ?) AND (accountno=?)'); + for my $accdata ( @{$rows} ) { + if ($amountleft == 0) { + last; + } + if ( $accdata->{amountoutstanding} < $amountleft ) { + $newamtos = 0; + $amountleft -= $accdata->{amountoutstanding}; + } + else { + $newamtos = $accdata->{amountoutstanding} - $amountleft; + $amountleft = 0; + } + my $thisacct = $accdata->{accountno}; + $sth->execute( $newamtos, $borrowernumber, $thisacct ); + } + + # create new line + $sql = 'INSERT INTO accountlines ' . + '(borrowernumber, accountno,date,amount,description,accounttype,amountoutstanding) ' . + q|VALUES (?,?,now(),?,'Payment,thanks','Pay',?)|; + $dbh->do($sql,{},$borrowernumber, $nextaccntno, 0 - $amount, 0 - $amountleft ); + UpdateStats( $branch, 'payment', $amount, '', '', '', $borrowernumber, $nextaccntno ); + return; +} =head2 makepayment &makepayment($borrowernumber, $acctnumber, $amount, $branchcode); @@ -207,6 +272,39 @@ sub makepayment { } } +# makepayment needs to be fixed to handle partials till then this separate subroutine +# fills in +sub makepartialpayment { + my ( $borrowernumber, $accountno, $amount, $user, $branch ) = @_; + if (!$amount || $amount < 0) { + return; + } + my $dbh = C4::Context->dbh; + + my $nextaccntno = getnextacctno($borrowernumber); + my $newamtos = 0; + + my $data = $dbh->selectrow_hashref( + 'SELECT * FROM accountlines WHERE borrowernumber=? AND accountno=?',undef,$borrowernumber,$accountno); + my $new_outstanding = $data->{amountoutstanding} - $amount; + + my $update = 'UPDATE accountlines SET amountoutstanding = ? WHERE borrowernumber = ? ' + . ' AND accountno = ?'; + $dbh->do( $update, undef, $new_outstanding, $borrowernumber, $accountno); + + # create new line + my $insert = 'INSERT INTO accountlines (borrowernumber, accountno, date, amount, ' + . 'description, accounttype, amountoutstanding) ' + . ' VALUES (?, ?, now(), ?, ?, ?, 0)'; + + $dbh->do( $insert, undef, $borrowernumber, $nextaccntno, $amount, + "Payment, thanks - $user", 'Pay'); + + UpdateStats( $user, 'payment', $amount, '', '', '', $borrowernumber, $accountno ); + + return; +} + =head2 getnextacctno $nextacct = &getnextacctno($borrowernumber); @@ -227,6 +325,7 @@ sub getnextacctno ($) { LIMIT 1" ); $sth->execute($borrowernumber); + return ($sth->fetchrow || 1); } diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/pay.tmpl b/koha-tmpl/intranet-tmpl/prog/en/modules/members/pay.tmpl index 1177ba2..057333a 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/pay.tmpl +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/pay.tmpl @@ -9,7 +9,7 @@
- +
@@ -31,6 +31,7 @@ + @@ -44,13 +45,20 @@ + @@ -71,17 +84,27 @@ - + - +
Fines & ChargesSel Description Account Type Notify id
- + --> + "i value="Pay" /> + + "i value="Writeoff" /> + + + + " value="" /> " value="" /> + " value="" /> + " value="" /> " value="" /> " value="" /> " value="" /> @@ -60,6 +68,11 @@ " value="" /> " value="" /> + + " /> + +
Sub TotalSub Total
Total DueTotal Due
-
">Cancel

has no outstanding fines.

+ +
+ + + + + + "> + Cancel +
+

has no outstanding fines.

diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/paycollect.tmpl b/koha-tmpl/intranet-tmpl/prog/en/modules/members/paycollect.tmpl new file mode 100644 index 0000000..3bf9891 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/paycollect.tmpl @@ -0,0 +1,221 @@ + +Koha › Patrons › Collect Fine Payment for <!-- TMPL_VAR NAME="firstname" --> <!-- TMPL_VAR NAME="surname" --> + + + + + + + + +
+ +
+
+
+ + + + +
+ +
+ + + +
+" /> +" /> +" /> +" /> +" /> +" /> +" /> +" /> +" /> +" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionAccount TypeNotify idLevelAmountAmount Outstanding
+ +
Total Amount Payable : + +
Collect From Patron: + +" onchange="moneyFormat(document.payindivfine.paid)"/> +
+ +">Cancel +
+ + +" /> +" /> +" /> +" /> +" /> +" /> +" /> +" /> +" /> +" /> + + + + + + + + + + + + + + + + + + + + + + + + +
DescriptionAccount TypeNotify idLevelAmountAmount Outstanding
+ +
Writeoff This Charge?
+ +">Cancel +
+ + + +" /> + /> +" /> + + + + + + + + + + + + + + + + + + +
Total Amount Outstanding : + +
Collect From Patron: + +" onchange="moneyFormat(document.payfine.paid)"/> +
+ +">Cancel +
+
+ +
+ +
+
+ +
+ +
+
+ diff --git a/members/pay.pl b/members/pay.pl index 5a36bd7..1bfbead 100755 --- a/members/pay.pl +++ b/members/pay.pl @@ -39,185 +39,300 @@ use C4::Koha; use C4::Overdues; use C4::Branch; # GetBranches -my $input = new CGI; +my $input = CGI->new(); my ( $template, $loggedinuser, $cookie ) = get_template_and_user( { - template_name => "members/pay.tmpl", + template_name => 'members/pay.tmpl', query => $input, - type => "intranet", + type => 'intranet', authnotrequired => 0, flagsrequired => { borrowers => 1, updatecharges => 1 }, debug => 1, } ); +my @nam = $input->param; my $borrowernumber = $input->param('borrowernumber'); -if ( $borrowernumber eq '' ) { +if ( !$borrowernumber ) { $borrowernumber = $input->param('borrowernumber0'); } # get borrower details my $data = GetMember( borrowernumber => $borrowernumber ); my $user = $input->remote_user; +$user ||= q{}; # get account details my $branches = GetBranches(); my $branch = GetBranch( $input, $branches ); +my $co_wr = $input->param('confirm_writeoff'); +my $paycollect = $input->param('paycollect'); +if ($paycollect) { + print $input->redirect("/cgi-bin/koha/members/paycollect.pl?borrowernumber=$borrowernumber" ); +} +my $payselected = $input->param('payselected'); +if ($payselected) { + my @lines; + foreach (@nam) { + if ( /^incl_par_(\d+)$/) { + push @lines, $1; + } + } + my @lines_to_pay; + my $amt = 0; + for (@lines) { + push @lines_to_pay, $input->param("accountno_$_"); + $amt += $input->param("out_$_"); + } + $amt = '&amt=' . $amt; + my $sel = '&selected=' . join ',', @lines_to_pay; + my $redirect = "/cgi-bin/koha/members/paycollect.pl?borrowernumber=$borrowernumber" . $amt . $sel; + + print $input->redirect($redirect); + +} + +my $wo_all = $input->param('woall'); # writeoff all fines +if ($wo_all) { + writeoff_all(); +} elsif ($co_wr) { + my $accountno = $input->param('accountno'); + my $itemno = $input->param('itemnumber'); + my $account_type = $input->param('accounttype'); + my $amount = $input->param('amount'); + writeoff($borrowernumber, $accountno, $itemno, $account_type, $amount); +} + my @names = $input->param; -my %inp; my $check = 0; + +## Create a structure for ( my $i = 0 ; $i < @names ; $i++ ) { my $temp = $input->param( $names[$i] ); - if ( $temp eq 'wo' ) { - $inp{ $names[$i] } = $temp; - $check = 1; - } if ( $temp eq 'yes' ) { # FIXME : using array +4, +5, +6 is dirty. Should use arrays for each accountline - my $amount = $input->param( $names[ $i + 4 ] ); - my $borrowernumber = $input->param( $names[ $i + 5 ] ); + my $amount = $input->param( $names[ $i + 4 ] ); # out + my $borrowerno = $input->param( $names[ $i + 5 ] ); my $accountno = $input->param( $names[ $i + 6 ] ); - makepayment( $borrowernumber, $accountno, $amount, $user, $branch ); + makepayment( $borrowerno, $accountno, $amount, $user, $branch ); $check = 2; } } -my $total = $input->param('total') || ''; -if ( $check == 0 ) { - if ( $total ne '' ) { - recordpayment( $borrowernumber, $total ); + +for ( @names ) { + if (/^pay_indiv_(\d+)$/) { + my $line_no = $1; + redirect_to_paycollect('pay_individual', $line_no); + } + if (/^wo_indiv_(\d+)$/) { + my $line_no = $1; + redirect_to_paycollect('writeoff_individual', $line_no); } +} - my ( $total, $accts, $numaccts) = GetMemberAccountRecords( $borrowernumber ); - - my @allfile; - my @notify = NumberNotifyId($borrowernumber); - - my $numberofnotify = scalar(@notify); - for ( my $j = 0 ; $j < scalar(@notify) ; $j++ ) { - my @loop_pay; - my ( $total , $accts, $numaccts) = - GetBorNotifyAcctRecord( $borrowernumber, $notify[$j] ); - for ( my $i = 0 ; $i < $numaccts ; $i++ ) { - my %line; - if ( $accts->[$i]{'amountoutstanding'} != 0 ) { - $accts->[$i]{'amount'} += 0.00; - $accts->[$i]{'amountoutstanding'} += 0.00; - $line{i} = $j . "" . $i; - $line{itemnumber} = $accts->[$i]{'itemnumber'}; - $line{accounttype} = $accts->[$i]{'accounttype'}; - $line{amount} = sprintf( "%.2f", $accts->[$i]{'amount'} ); - $line{amountoutstanding} = - sprintf( "%.2f", $accts->[$i]{'amountoutstanding'} ); - $line{borrowernumber} = $borrowernumber; - $line{accountno} = $accts->[$i]{'accountno'}; - $line{description} = $accts->[$i]{'description'}; - $line{title} = $accts->[$i]{'title'}; - $line{notify_id} = $accts->[$i]{'notify_id'}; - $line{notify_level} = $accts->[$i]{'notify_level'}; - $line{net_balance} = 1 if($accts->[$i]{'amountoutstanding'} > 0); # you can't pay a credit. - push( @loop_pay, \%line ); - } +if ( $check == 0 ) { # fetch and display accounts + add_accounts_to_template($borrowernumber); + + output_html_with_http_headers $input, $cookie, $template->output; + +}else { + + my %inputs; + my @name = $input->param; + for my $name (@name) { + my $test = $input->param( $name ); + if ($test eq 'wo' ) { + my $temp = $name; + $temp=~s/payfine//; + $inputs{ $name } = $temp; } + } + + while ( my ( $key, $value ) = each %inputs ) { - my $totalnotify = AmountNotify( $notify[$j], $borrowernumber ); - ( $totalnotify = '0' ) if ( $totalnotify =~ /^0.00/ ); - push @allfile, - { - 'loop_pay' => \@loop_pay, - 'notify' => $notify[$j], - 'total' => sprintf( "%.2f",$totalnotify), - - }; + my $accounttype = $input->param("accounttype$value"); + my $borrower_number = $input->param("borrowernumber$value"); + my $itemno = $input->param("itemnumber$value"); + my $amount = $input->param("amount$value"); + my $accountno = $input->param("accountno$value"); + writeoff( $borrower_number, $accountno, $itemno, $accounttype, $amount ); } - -if ( $data->{'category_type'} eq 'C') { - my ( $catcodes, $labels ) = GetborCatFromCatType( 'A', 'WHERE category_type = ?' ); - my $cnt = scalar(@$catcodes); - $template->param( 'CATCODE_MULTI' => 1) if $cnt > 1; - $template->param( 'catcode' => $catcodes->[0]) if $cnt == 1; + $borrowernumber = $input->param('borrowernumber'); + print $input->redirect( + "/cgi-bin/koha/members/boraccount.pl?borrowernumber=$borrowernumber"); +} + +sub writeoff { + my ( $b_number, $accountnum, $itemnum, $accounttype, $amount ) = @_; + my $usr = $input->remote_user; + my $dbh = C4::Context->dbh; + $itemnum ||= undef; # if no item is attached to fine, make sure to store it as a NULL + + my $update = + 'Update accountlines set amountoutstanding=0 ' . + q|where (accounttype='Res' OR accounttype='FU' OR accounttype ='IP' OR accounttype='CH' OR accounttype='N' | . + q|OR accounttype='F' OR accounttype='A' OR accounttype='M' OR accounttype='L' OR accounttype='RE' | . + q|OR accounttype='RL') and accountno=? and borrowernumber=?|; + $dbh->do($update, undef, $accountnum, $b_number ); + + my $account = + $dbh->selectall_arrayref('select max(accountno) as max_accountno from accountlines'); + my $max = 1 + $account->[0]->[0]; + my $insert = q{insert into accountlines (borrowernumber,accountno,itemnumber,date,amount,description,accounttype)} + . q{values (?,?,?,now(),?,'Writeoff','W')}; + $dbh->do($insert, undef, $b_number, $max, $itemnum, $amount ); + + UpdateStats( $branch, 'writeoff', $amount, q{}, q{}, q{}, $b_number ); + + return; } - -$template->param( adultborrower => 1 ) if ( $data->{'category_type'} eq 'A' ); -my ($picture, $dberror) = GetPatronImage($data->{'cardnumber'}); -$template->param( picture => 1 ) if $picture; - + +sub add_accounts_to_template { + my $b_number = shift; + + my ( $total, $accts, $numaccts); + ( $total, $accts, $numaccts) = GetMemberAccountRecords( $b_number ); + + + my $allfile = []; + my @notify = NumberNotifyId($b_number); + + my $line_id = 0; + for my $n (@notify) { + my $pay_loop = []; + my ($acct_total, $acct_accts, $acct_numaccts) = + GetBorNotifyAcctRecord( $b_number, $n ); + if (!$acct_numaccts) { + next; + } + for my $acct ( @{$acct_accts} ) { + if ( $acct->{amountoutstanding} != 0 ) { + $acct->{amount} += 0.00; + $acct->{amountoutstanding} += 0.00; + my $line = { + i => "_$line_id", + itemnumber => $acct->{itemnumber}, + accounttype => $acct->{accounttype}, + amount => sprintf('%.2f', $acct->{amount}), + amountoutstanding => sprintf('%.2f', $acct->{amountoutstanding}), + borrowernumber => $b_number, + accountno => $acct->{accountno}, + description => $acct->{description}, + title => $acct->{title}, + notify_id => $acct->{notify_id}, + notify_level => $acct->{notify_level}, + }; + if ($acct->{amountoutstanding} > 0 ) { + $line->{net_balance} = 1; + } + push @{ $pay_loop}, $line; + ++$line_id; + } + } + my $totalnotify = AmountNotify( $n, $b_number ); + if (!$totalnotify || $totalnotify=~/^0.00/ ) { + $totalnotify = '0'; + } + push @{$allfile}, { + loop_pay => $pay_loop, + notify => $n, + total => sprintf( '%.2f', $totalnotify), + }; + } + + if ( $data->{'category_type'} eq 'C') { + my ( $catcodes, $labels ) = GetborCatFromCatType( 'A', 'WHERE category_type = ?' ); + my $cnt = scalar @{$catcodes}; + if ($cnt > 1) { + $template->param( 'CATCODE_MULTI' => 1); + } elsif ($cnt == 1) { + $template->param( 'catcode' => $catcodes->[0]); + } + } elsif ($data->{'category_type'} eq 'A') { + $template->param( adultborrower => 1 ); + } + + my ($picture, $dberror) = GetPatronImage($data->{'cardnumber'}); + if ($picture ) { + $template->param( picture => 1 ); + } + $template->param( - allfile => \@allfile, + allfile => $allfile, firstname => $data->{'firstname'}, surname => $data->{'surname'}, - borrowernumber => $borrowernumber, - cardnumber => $data->{'cardnumber'}, - categorycode => $data->{'categorycode'}, - category_type => $data->{'category_type'}, - categoryname => $data->{'description'}, - address => $data->{'address'}, - address2 => $data->{'address2'}, - city => $data->{'city'}, - zipcode => $data->{'zipcode'}, - country => $data->{'country'}, - phone => $data->{'phone'}, - email => $data->{'email'}, - branchcode => $data->{'branchcode'}, - branchname => GetBranchName($data->{'branchcode'}), - is_child => ($data->{'category_type'} eq 'C'), - total => sprintf( "%.2f", $total ) + borrowernumber => $b_number, + cardnumber => $data->{'cardnumber'}, + categorycode => $data->{'categorycode'}, + category_type => $data->{'category_type'}, + categoryname => $data->{'description'}, + address => $data->{'address'}, + address2 => $data->{'address2'}, + city => $data->{'city'}, + zipcode => $data->{'zipcode'}, + phone => $data->{'phone'}, + email => $data->{'email'}, + branchcode => $data->{'branchcode'}, + branchname => GetBranchName($data->{'branchcode'}), + is_child => ($data->{'category_type'} eq 'C'), + total => sprintf '%.2f', $total ); - output_html_with_http_headers $input, $cookie, $template->output; + return; +} +sub get_for_redirect { + my ($name, $name_in, $money) = @_; + my $s = q{&} . $name . q{=}; + my $value = $input->param($name_in); + if (!defined $value) { + $value = ($money == 1) ? 0 : q{}; + } + if ($money) { + $s .= sprintf '%.2f', $value; + } else { + $s .= $value; + } + return $s; } -else { - my %inp; +sub redirect_to_paycollect { + my ($action, $line_no) = @_; + my $redirect = "/cgi-bin/koha/members/paycollect.pl?borrowernumber=$borrowernumber"; + $redirect .= q{&}; + $redirect .= "$action=1"; + $redirect .= get_for_redirect('accounttype',"accounttype_$line_no",0); + $redirect .= get_for_redirect('amount',"amount_$line_no",1); + $redirect .= get_for_redirect('amountoutstanding',"out_$line_no",1); + $redirect .= get_for_redirect('accountno',"accountno_$line_no",0); + $redirect .= get_for_redirect('description',"description_$line_no",0); + $redirect .= get_for_redirect('title',"title_$line_no",0); + $redirect .= get_for_redirect('itemnumber',"itemnumber_$line_no",0); + $redirect .= get_for_redirect('notify_id',"notify_id_$line_no",0); + $redirect .= get_for_redirect('notify_level',"notify_level_$line_no",0); + $redirect .= '&remote_user='; + $redirect .= $user; + return print $input->redirect( $redirect ); +} +sub writeoff_all { + my @wo_lines; my @name = $input->param; - for ( my $i = 0 ; $i < @name ; $i++ ) { - my $test = $input->param( $name[$i] ); - if ( $test eq 'wo' ) { - my $temp = $name[$i]; - $temp =~ s/payfine//; - $inp{ $name[$i] } = $temp; + for (@name) { + if (/^line_id_\d+$/) { + push @wo_lines, $input->param($_); } } - my $borrowernumber; - while ( my ( $key, $value ) = each %inp ) { - - my $accounttype = $input->param("accounttype$value"); - $borrowernumber = $input->param("borrowernumber$value"); - my $itemno = $input->param("itemnumber$value"); - my $amount = $input->param("amount$value"); - my $accountno = $input->param("accountno$value"); - writeoff( $borrowernumber, $accountno, $itemno, $accounttype, $amount ); + for my $value (@wo_lines) { + my $accounttype = $input->param("accounttype$value"); + my $borrowernum = $input->param("borrowernumber$value"); + my $itemno = $input->param("itemnumber$value"); + my $amount = $input->param("amount$value"); + my $accountno = $input->param("accountno$value"); + writeoff( $borrowernum, $accountno, $itemno, $accounttype, $amount ); } $borrowernumber = $input->param('borrowernumber'); print $input->redirect( "/cgi-bin/koha/members/boraccount.pl?borrowernumber=$borrowernumber"); } - -sub writeoff { - my ( $borrowernumber, $accountnum, $itemnum, $accounttype, $amount ) = @_; - my $user = $input->remote_user; - my $dbh = C4::Context->dbh; - undef $itemnum unless $itemnum; # if no item is attached to fine, make sure to store it as a NULL - my $sth = - $dbh->prepare( -"Update accountlines set amountoutstanding=0 where accountno=? and borrowernumber=?" - ); - $sth->execute( $accountnum, $borrowernumber ); - $sth->finish; - $sth = $dbh->prepare("select max(accountno) from accountlines"); - $sth->execute; - my $account = $sth->fetchrow_hashref; - $sth->finish; - $account->{'max(accountno)'}++; - $sth = $dbh->prepare( -"insert into accountlines (borrowernumber,accountno,itemnumber,date,amount,description,accounttype) - values (?,?,?,now(),?,'Writeoff','W')" - ); - $sth->execute( $borrowernumber, $account->{'max(accountno)'}, - $itemnum, $amount ); - $sth->finish; - UpdateStats( $branch, 'writeoff', $amount, '', '', '', - $borrowernumber ); -} diff --git a/members/paycollect.pl b/members/paycollect.pl new file mode 100755 index 0000000..58096e3 --- /dev/null +++ b/members/paycollect.pl @@ -0,0 +1,188 @@ +#!/usr/bin/perl +# Copyright 2009,2010 PTFS Inc. +# +# 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 C4::Context; +use C4::Auth; +use C4::Output; +use CGI; +use C4::Members; +use C4::Accounts; +use C4::Koha; +use C4::Branch; + +my $input = CGI->new(); + +my ( $template, $loggedinuser, $cookie ) = get_template_and_user( + { + template_name => 'members/paycollect.tmpl', + query => $input, + type => 'intranet', + authnotrequired => 0, + flagsrequired => { borrowers => 1, updatecharges => 1 }, + debug => 1, + } +); + +# get borrower details +my $borrowernumber = $input->param('borrowernumber'); +my $borrower = GetMember( $borrowernumber, 'borrowernumber' ); +my $user = $input->remote_user; + +# get account details +my $branch = GetBranch( $input, GetBranches() ); + +my ( $total_due, $accts, $numaccts ) = GetMemberAccountRecords($borrowernumber); +my $total_paid = $input->param('paid'); + +my $individual = $input->param('pay_individual'); +my $writeoff = $input->param('writeoff_individual'); +my $select_lines = $input->param('selected'); +my $select = $input->param('selected_accts'); +my $accountno; + +if ( $individual || $writeoff ) { + if ($individual) { + $template->param( pay_individual => 1 ); + } + elsif ($writeoff) { + $template->param( writeoff_individual => 1 ); + } + my $accounttype = $input->param('accounttype'); + my $amount = $input->param('amount'); + my $amountoutstanding = $input->param('amountoutstanding'); + $accountno = $input->param('accountno'); + my $description = $input->param('description'); + my $title = $input->param('title'); + my $notify_id = $input->param('notify_id'); + my $notify_level = $input->param('notify_level'); + $total_due = $amountoutstanding; + $template->param( + accounttype => $accounttype, + accountno => $accountno, + amount => $amount, + amountoutstanding => $amountoutstanding, + title => $title, + description => $description, + notify_id => $notify_id, + notify_level => $notify_level, + ); +} +elsif ($select_lines) { + $total_due = $input->param('amt'); + $template->param( + selected_accts => $select_lines, + amt => $total_due + ); +} + +if ( $total_paid and $total_paid ne '0.00' ) { + if ( $total_paid < 0 or $total_paid > $total_due ) { + $template->param( + error => "You must pay a value less than or equal to $total_due" ); + } + else { + if ($individual) { + if ( $total_paid == $total_due ) { + makepayment( $borrowernumber, $accountno, $total_paid, $user, + $branch ); + } + else { + makepartialpayment( $borrowernumber, $accountno, $total_paid, + $user, $branch ); + } + print $input->redirect( + "/cgi-bin/koha/members/pay.pl?borrowernumber=$borrowernumber"); + } + else { + if ($select) { + if ( $select =~ /^([\d,]*).+/ ) { + $select = $1; # ensure passing no junk + } + my @acc = split /,/, $select; + recordpayment_selectaccts( $borrowernumber, $total_paid, + \@acc ); + } + else { + recordpayment( $borrowernumber, $total_paid ); + } + +# recordpayment does not return success or failure so lets redisplay the boraccount + + print $input->redirect( +"/cgi-bin/koha/members/boraccount.pl?borrowernumber=$borrowernumber" + ); + } + } +} +else { + $total_paid = '0.00'; #TODO not right with pay_individual +} + +get_borrower_photo($borrower); +my $is_child = ( $borrower->{category_type} && $borrower->{category_type} eq 'C' ); + +$template->param( + firstname => $borrower->{firstname}, + surname => $borrower->{surname}, + borrowernumber => $borrowernumber, + cardnumber => $borrower->{cardnumber}, + categorycode => $borrower->{categorycode}, + category_type => $borrower->{category_type}, + categoryname => $borrower->{description}, + address => $borrower->{address}, + address2 => $borrower->{address2}, + city => $borrower->{city}, + zipcode => $borrower->{zipcode}, + phone => $borrower->{phone}, + email => $borrower->{email}, + branchcode => $borrower->{branchcode}, + branchname => GetBranchName( $borrower->{branchcode} ), + is_child => $is_child, + total => sprintf( '%.2f', $total_due ), +); + +output_html_with_http_headers $input, $cookie, $template->output; + +sub get_borrower_photo { + my $borr = shift; + + if ($borr->{category_type}) { + if ( $borr->{category_type} eq 'C' ) { + my ( $catcodes, $labels ) = + GetborCatFromCatType( 'A', 'WHERE category_type = ?' ); + my $num_catcodes = scalar @{$catcodes}; + if ( $num_catcodes == 1 ) { + $template->param( 'catcode' => $catcodes->[0] ); + } + elsif ( $num_catcodes > 1 ) { + $template->param( 'CATCODE_MULTI' => 1 ); + } + } + + if ( $borr->{'category_type'} eq 'A' ) { + $template->param( adultborrower => 1 ); + } + } + my ( $picture, undef ) = GetPatronImage( $borr->{'cardnumber'} ); + if ($picture) { + $template->param( picture => 1 ); + } + return; +} -- 1.6.6.1