Bugzilla – Attachment 1368 Details for
Bug 3498
Allow partial fine payments
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch adding functionality
0001-Bug-3498-Allow-Partial-Payment-in-Fines.patch (text/plain), 40.84 KB, created by
Chris Cormack
on 2010-03-29 07:35:00 UTC
(
hide
)
Description:
Patch adding functionality
Filename:
MIME Type:
Creator:
Chris Cormack
Created:
2010-03-29 07:35:00 UTC
Size:
40.84 KB
patch
obsolete
>From c75b0d3c56832a58fd7f8a45a2681b746354d035 Mon Sep 17 00:00:00 2001 >From: Colin Campbell <colin.campbell@ptfs-europe.com> >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 @@ > <div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/members/members-home.pl">Patrons</a> › Pay Fines for <!-- TMPL_VAR name="firstname" --> <!-- TMPL_VAR name="surname" --></div> > > <div id="doc3" class="yui-t2"> >- >+ > <div id="bd"> > <div id="yui-main"> > <div class="yui-b"> >@@ -31,6 +31,7 @@ > <table> > <tr> > <th>Fines & Charges</th> >+ <th>Sel</th> > <th>Description</th> > <th>Account Type</th> > <th>Notify id</th> >@@ -44,13 +45,20 @@ > <tr> > <td> > <!-- TMPL_IF NAME="net_balance" --> >- <select name="payfine<!-- TMPL_VAR name="i" -->"> >+ <!--<select name="payfine<!-- TMPL_VAR name="i" -->"> > <option value="no">Unpaid</option> >- <option value="yes">Paid</option> >- <option value="wo">Writeoff</option> >- </select> >+ <option value="yes">Paid</option> --> >+ <input type="submit" name="pay_indiv<!-- TMPL_VAR name="i" -->"i value="Pay" /> >+ <!-- TMPL_IF NAME="CAN_user_updatecharges_writeoff_charges" --> >+ <input type="submit" name="wo_indiv<!-- TMPL_VAR name="i" -->"i value="Writeoff" /> >+ <!--<option value="wo">Writeoff</option> --> >+ <!-- /TMPL_IF --> >+ <!--</select> --> > <!-- /TMPL_IF --> >+ <input type="hidden" name="line_id<!-- TMPL_VAR name="i" -->" value="<!-- TMPL_VAR name="i" -->" /> > <input type="hidden" name="itemnumber<!-- TMPL_VAR name="i" -->" value="<!-- TMPL_VAR name="itemnumber" -->" /> >+ <input type="hidden" name="description<!-- TMPL_VAR name="i" -->" value="<!-- TMPL_VAR name="description" -->" /> >+ <input type="hidden" name="title<!-- TMPL_VAR name="i" -->" value="<!-- TMPL_VAR name="title" -->" /> > <input type="hidden" name="accounttype<!-- TMPL_VAR name="i" -->" value="<!-- TMPL_VAR name="accounttype" -->" /> > <input type="hidden" name="amount<!-- TMPL_VAR name="i" -->" value="<!-- TMPL_VAR name="amount" -->" /> > <input type="hidden" name="out<!-- TMPL_VAR name="i" -->" value="<!-- TMPL_VAR name="amountoutstanding" -->" /> >@@ -60,6 +68,11 @@ > <input type="hidden" name="notify_level<!-- TMPL_VAR name="i" -->" value="<!-- TMPL_VAR name="notify_level" -->" /> > <input type="hidden" name="totals<!-- TMPL_VAR name="i" -->" value="<!-- TMPL_VAR name="totals" -->" /> > </td> >+ <td> >+ <!-- TMPL_IF NAME="net_balance" --> >+ <input type="checkbox" checked="checked" name="incl_par<!-- TMPL_VAR name="i" -->" /> >+ <!-- /TMPL_IF --> >+ </td> > <td><!-- TMPL_VAR name="description" --> <!-- TMPL_VAR name="title" escape="html" --></td> > <td><!-- TMPL_VAR name="accounttype" --></td> > <td><!-- TMPL_VAR name="notify_id" --></td> >@@ -71,17 +84,27 @@ > <!-- TMPL_IF NAME="total"--> > <tr> > >- <td colspan="6">Sub Total</td> >+ <td colspan="7">Sub Total</td> > <td><!-- TMPL_VAR name="total" --></td> > </tr> > <!--/TMPL_IF--> > <!-- /TMPL_LOOP --> > <tr> >- <td colspan="6">Total Due</td> >+ <td colspan="7">Total Due</td> > <td><!-- TMPL_VAR name="total" --></td> > </tr> > </table> >-<fieldset class="action"><input type="submit" name="submit" value="Make Payment" class="submit" /> <a class="cancel" href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=<!-- TMPL_VAR NAME="borrowernumber" -->">Cancel</a></fieldset></form><!-- TMPL_ELSE --><p><!-- TMPL_VAR NAME="firstname" --> <!-- TMPL_VAR NAME="surname" --> has no outstanding fines.</p><!-- /TMPL_IF --> >+<!-- <p>On All Or Part Of The Total Sum Due:</p> --> >+<fieldset class="action"> >+ <input type="submit" name="paycollect" value="Pay Amount" class="submit" /> >+<!-- TMPL_IF NAME="CAN_user_updatecharges_writeoff_charges" --> >+ <input type="submit" name="woall" value="Writeoff All" class="submit" /> >+<!-- /TMPL_IF --> >+ <input type="submit" name="payselected" value="Pay Selected" class="submit" /> >+ <a class="cancel" href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=<!-- TMPL_VAR NAME="borrowernumber" -->"> >+ Cancel</a> >+</fieldset> >+</form><!-- TMPL_ELSE --><p><!-- TMPL_VAR NAME="firstname" --> <!-- TMPL_VAR NAME="surname" --> has no outstanding fines.</p><!-- /TMPL_IF --> > </div></div> > > </div> >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 @@ >+<!-- TMPL_INCLUDE NAME="doc-head-open.inc" --> >+<title>Koha › Patrons › Collect Fine Payment for <!-- TMPL_VAR NAME="firstname" --> <!-- TMPL_VAR NAME="surname" --></title> >+<!-- TMPL_INCLUDE NAME="doc-head-close.inc" --> >+<script type= "text/javascript"> >+//<![CDATA[ >+function moneyFormat(textObj) { >+ var newValue = textObj.value; >+ var decAmount = ""; >+ var dolAmount = ""; >+ var decFlag = false; >+ var aChar = ""; >+ >+ for(i=0; i < newValue.length; i++) { >+ aChar = newValue.substring(i, i+1); >+ if (aChar >= "0" && aChar <= "9") { >+ if(decFlag) { >+ decAmount = "" + decAmount + aChar; >+ } >+ else { >+ dolAmount = "" + dolAmount + aChar; >+ } >+ } >+ if (aChar == ".") { >+ if (decFlag) { >+ dolAmount = ""; >+ break; >+ } >+ decFlag = true; >+ } >+ } >+ >+ if (dolAmount == "") { >+ dolAmount = "0"; >+ } >+// Strip leading 0s >+ if (dolAmount.length > 1) { >+ while(dolAmount.length > 1 && dolAmount.substring(0,1) == "0") { >+ dolAmount = dolAmount.substring(1,dolAmount.length); >+ } >+ } >+ if (decAmount.length > 2) { >+ decAmount = decAmount.substring(0,2); >+ } >+// Pad right side >+ if (decAmount.length == 1) { >+ decAmount = decAmount + "0"; >+ } >+ if (decAmount.length == 0) { >+ decAmount = decAmount + "00"; >+ } >+ >+ textObj.value = dolAmount + "." + decAmount; >+} >+//]]> >+</script> >+</head> >+<body> >+<!-- TMPL_INCLUDE NAME="header.inc" --> >+<!-- TMPL_INCLUDE NAME="patron-search.inc" --> >+<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/members/members-home.pl">Patrons</a> › Pay Fines for <!-- TMPL_VAR name="firstname" --> <!-- TMPL_VAR name="surname" --></div> >+ >+<div id="doc3" class="yui-t2"> >+ >+<div id="bd"> >+<div id="yui-main"> >+<div class="yui-b"> >+<!-- TMPL_INCLUDE NAME="members-toolbar.inc" --> >+ >+ >+<!-- The manual invoice and credit buttons --> >+<div class="toptabs"> >+<ul class="ui-tabs-nav"> >+<li><a href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=<!-- TMPL_VAR NAME="borrowernumber" -->">Account</a></li> >+<li class="ui-tabs-selected"><a href="/cgi-bin/koha/members/pay.pl?borrowernumber=<!-- TMPL_VAR NAME="borrowernumber" -->" >Pay fines</a></li> >+<li><a href="/cgi-bin/koha/members/maninvoice.pl?borrowernumber=<!-- TMPL_VAR NAME="borrowernumber" -->" >Create Manual Invoice</a></li> >+<li><a href="/cgi-bin/koha/members/mancredit.pl?borrowernumber=<!-- TMPL_VAR NAME="borrowernumber" -->" >Create Manual Credit</a></li> >+</ul> >+<div class="tabs-container"> >+ >+<!--<form action="/cgi-bin/koha/members/paycollect.pl" method="post"> --> >+<!-- TMPL_IF NAME="pay_individual" --> >+<form name="payindivfine" onsubmit="return validatePayment(this);" method="post" action="/cgi-bin/koha/members/paycollect.pl"> >+<input type="hidden" name="borrowernumber" id="borrowernumber" value="<!-- TMPL_VAR name="borrowernumber" -->" /> >+<input type="hidden" name="pay_individual" id="pay_individual" value="<!-- TMPL_VAR name="pay_individual" -->" /> >+<input type="hidden" name="description" id="description" value="<!-- TMPL_VAR name="description" -->" /> >+<input type="hidden" name="accounttype" id="accounttype" value="<!-- TMPL_VAR name="accounttype" -->" /> >+<input type="hidden" name="notify_id" id="notify_id" value="<!-- TMPL_VAR name="notify_id" -->" /> >+<input type="hidden" name="notify_level" id="notify_level" value="<!-- TMPL_VAR name="notify_level" -->" /> >+<input type="hidden" name="amount" id="amount" value="<!-- TMPL_VAR name="amount" -->" /> >+<input type="hidden" name="amountoutstanding" id="amountoutstanding" value="<!-- TMPL_VAR name="amountoutstanding" -->" /> >+<input type="hidden" name="accountno" id="accountno" value="<!-- TMPL_VAR name="accountno" -->" /> >+<input type="hidden" name="title" id="title" value="<!-- TMPL_VAR name="title" -->" /> >+<table> >+<tr> >+<th>Description</th> >+<th>Account Type</th> >+<th>Notify id</th> >+<th>Level</th> >+<th>Amount</th> >+<th>Amount Outstanding</th> >+</tr> >+<tr> >+<td> >+<!-- TMPL_VAR NAME="description" --> <!-- TMPL_VAR="title" escape="html" --> >+</td> >+<td><!-- TMPL_VAR name="accounttype" --></td> >+<td><!-- TMPL_VAR name="notify_id" --></td> >+<td><!-- TMPL_VAR name="notify_level" --></td> >+<td class="debit"><!-- TMPL_VAR name="amount" --></td> >+<td class="debit"><!-- TMPL_VAR name="amountoutstanding" --></td> >+</tr> >+<tr> >+<td>Total Amount Payable : </td> >+<td> >+<!-- TMPL_VAR NAME="amountoutstanding" --> >+</td> >+</tr> >+<tr><td> </td></tr> >+<tr> >+<td>Collect From Patron: </td> >+<td> >+<!-- default to paying all --> >+<input name="paid" id="paid" value="<!-- TMPL_VAR NAME="amountoutstanding" -->" onchange="moneyFormat(document.payindivfine.paid)"/> >+</td> >+</tr> >+<tr><td> </td></tr> >+<tr> >+<td rowspan="2"> >+<input type="submit" name="submitbutton" value="Confirm" /> >+<a class="cancel" href="/cgi-bin/koha/members/pay.pl?borrowernumber=<!-- TMPL_VAR NAME="borrowernumber" -->">Cancel</a> >+</td> >+</tr> >+ >+</table> >+<!-- TMPL_ELSIF NAME="writeoff_individual"--> >+<form name="woindivfine" action="/cgi-bin/koha/members/pay.pl" method="post" > >+<input type="hidden" name="borrowernumber" id="borrowernumber" value="<!-- TMPL_VAR name="borrowernumber" -->" /> >+<input type="hidden" name="pay_individual" id="pay_individual" value="<!-- TMPL_VAR name="pay_individual" -->" /> >+<input type="hidden" name="description" id="description" value="<!-- TMPL_VAR name="description" -->" /> >+<input type="hidden" name="accounttype" id="accounttype" value="<!-- TMPL_VAR name="accounttype" -->" /> >+<input type="hidden" name="notify_id" id="notify_id" value="<!-- TMPL_VAR name="notify_id" -->" /> >+<input type="hidden" name="notify_level" id="notify_level" value="<!-- TMPL_VAR name="notify_level" -->" /> >+<input type="hidden" name="amount" id="amount" value="<!-- TMPL_VAR name="amount" -->" /> >+<input type="hidden" name="amountoutstanding" id="amountoutstanding" value="<!-- TMPL_VAR name="amountoutstanding" -->" /> >+<input type="hidden" name="accountno" id="accountno" value="<!-- TMPL_VAR name="accountno" -->" /> >+<input type="hidden" name="title" id="title" value="<!-- TMPL_VAR name="title" -->" /> >+<table> >+<tr> >+<th>Description</th> >+<th>Account Type</th> >+<th>Notify id</th> >+<th>Level</th> >+<th>Amount</th> >+<th>Amount Outstanding</th> >+</tr> >+<tr> >+<td> >+<!-- TMPL_VAR NAME="description" --> <!-- TMPL_VAR="title" escape="html" --> >+</td> >+<td><!-- TMPL_VAR name="accounttype" --></td> >+<td><!-- TMPL_VAR name="notify_id" --></td> >+<td><!-- TMPL_VAR name="notify_level" --></td> >+<td class="debit"><!-- TMPL_VAR name="amount" --></td> >+<td class="debit"><!-- TMPL_VAR name="amountoutstanding" --></td> >+</tr> >+<tr><td> </td></tr> >+<tr><td rowspan="2"><strong>Writeoff This Charge?</strong></td></tr> >+<tr><td> </td></tr> >+<tr> >+<td rowspan="2"> >+<input type="submit" name="confirm_writeoff" id="confirm_writeoff" value="Confirm" /> >+<a class="cancel" href="/cgi-bin/koha/members/pay.pl?borrowernumber=<!-- TMPL_VAR NAME="borrowernumber" -->">Cancel</a> >+</td> >+</tr> >+ >+</table> >+<!-- TMPL_ELSE --> >+ >+<form name="payfine" onsubmit="return validatePayment(this);" method="post" action="/cgi-bin/koha/members/paycollect.pl"> >+<input type="hidden" name="borrowernumber" id="borrowernumber" value="<!-- TMPL_VAR name="borrowernumber" -->" /> >+<input type="hidden" name="selected_accts" id="selected_accts" value="<!-- TMPL_VAR name="selected_accts" --> /> >+<input type="hidden" name="total" id="total" value="<!-- TMPL_VAR name="total" -->" /> >+ >+<table> >+<!-- TMPL_IF NAME="error" --> >+<tr><td><!-- TMPL_VAR NAME="error" --></td></tr> >+<!-- /TMPL_IF --> >+<tr> >+<td>Total Amount Outstanding : </td> >+<td> >+<!-- TMPL_VAR NAME="total" --> >+</td> >+</tr> >+<tr><td> </td></tr> >+<tr> >+<td>Collect From Patron: </td> >+<td> >+<!-- default to paying all --> >+<input name="paid" id="paid" value="<!-- TMPL_VAR NAME="total" -->" onchange="moneyFormat(document.payfine.paid)"/> >+</td> >+</tr> >+<tr><td> </td></tr> >+<tr> >+<td rowspan="2"> >+<input type="submit" name="submitbutton" value="Confirm" /> >+<a class="cancel" href="/cgi-bin/koha/members/boraccount.pl?borrowernumber=<!-- TMPL_VAR NAME="borrowernumber" -->">Cancel</a> >+</td> >+</tr> >+</table> >+</form> >+<!-- /TMPL_IF --> >+</div></div> >+ >+</div> >+</div> >+ >+<div class="yui-b"> >+<!-- TMPL_INCLUDE NAME="circ-menu.inc" --> >+</div> >+</div> >+<!-- TMPL_INCLUDE NAME="intranet-bottom.inc" --> >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 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 3498
:
1365
|
1366
|
1367
|
1368
|
3359
|
3603
|
3624
|
3715
|
4902
|
5360
|
5361
|
5362
|
5363
|
5383
|
5406