3 # Copyright 2000-2002 Katipo Communications
5 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 2 of the License, or (at your option) any later
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License along
17 # with Koha; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #use warnings; FIXME - Bug 2505
26 use C4::Circulation qw(ReturnLostItem);
27 use C4::Log qw(logaction);
29 use Data::Dumper qw(Dumper);
31 use vars qw($VERSION @ISA @EXPORT);
34 # set the version for version checking
35 $VERSION = 3.07.00.049;
50 &recordpayment_selectaccts
57 C4::Accounts - Functions for dealing with Koha accounts
65 The functions in this module deal with the monetary aspect of Koha,
66 including looking up and modifying the amount of money owed by a
73 &recordpayment($borrowernumber, $payment, $sip_paytype);
75 Record payment by a patron. C<$borrowernumber> is the patron's
76 borrower number. C<$payment> is a floating-point number, giving the
77 amount that was paid. C<$sip_paytype> is an optional flag to indicate this
78 payment was made over a SIP2 interface, rather than the staff client. The
79 value passed is the SIP2 payment type value (message 37, characters 21-22)
81 Amounts owed are paid off oldest first. That is, if the patron has a
82 $1 fine from Feb. 1, another $1 fine from Mar. 1, and makes a payment
83 of $1.50, then the oldest fine will be paid off in full, and $0.50
84 will be credited to the next one.
91 #here we update the account lines
92 my ( $borrowernumber, $data, $sip_paytype ) = @_;
93 my $dbh = C4::Context->dbh;
96 my $branch = C4::Context->userenv->{'branch'};
97 my $amountleft = $data;
99 $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
102 my $nextaccntno = getnextacctno($borrowernumber);
104 # get lines with outstanding amounts to offset
105 my $sth = $dbh->prepare(
106 "SELECT * FROM accountlines
107 WHERE (borrowernumber = ?) AND (amountoutstanding<>0)
110 $sth->execute($borrowernumber);
112 # offset transactions
114 while ( ( $accdata = $sth->fetchrow_hashref ) and ( $amountleft > 0 ) ) {
115 if ( $accdata->{'amountoutstanding'} < $amountleft ) {
117 $amountleft -= $accdata->{'amountoutstanding'};
120 $newamtos = $accdata->{'amountoutstanding'} - $amountleft;
123 my $thisacct = $accdata->{accountlines_id};
124 my $usth = $dbh->prepare(
125 "UPDATE accountlines SET amountoutstanding= ?
126 WHERE (accountlines_id = ?)"
128 $usth->execute( $newamtos, $thisacct );
130 if ( C4::Context->preference("FinesLog") ) {
131 $accdata->{'amountoutstanding_new'} = $newamtos;
132 logaction("FINES", 'MODIFY', $borrowernumber, Dumper({
133 action => 'fee_payment',
134 borrowernumber => $accdata->{'borrowernumber'},
135 old_amountoutstanding => $accdata->{'amountoutstanding'},
136 new_amountoutstanding => $newamtos,
137 amount_paid => $accdata->{'amountoutstanding'} - $newamtos,
138 accountlines_id => $accdata->{'accountlines_id'},
139 accountno => $accdata->{'accountno'},
140 manager_id => $manager_id,
142 push( @ids, $accdata->{'accountlines_id'} );
147 my $usth = $dbh->prepare(
148 "INSERT INTO accountlines
149 (borrowernumber, accountno,date,amount,description,accounttype,amountoutstanding,manager_id)
150 VALUES (?,?,now(),?,'',?,?,?)"
154 $paytype .= $sip_paytype if defined $sip_paytype;
155 $usth->execute( $borrowernumber, $nextaccntno, 0 - $data, $paytype, 0 - $amountleft, $manager_id );
162 borrowernumber => $borrowernumber,
163 accountno => $nextaccntno }
166 if ( C4::Context->preference("FinesLog") ) {
167 $accdata->{'amountoutstanding_new'} = $newamtos;
168 logaction("FINES", 'CREATE',$borrowernumber,Dumper({
169 action => 'create_payment',
170 borrowernumber => $borrowernumber,
171 accountno => $nextaccntno,
172 amount => $data * -1,
173 amountoutstanding => $amountleft * -1,
174 accounttype => 'Pay',
175 accountlines_paid => \@ids,
176 manager_id => $manager_id,
184 &makepayment($accountlines_id, $borrowernumber, $acctnumber, $amount, $branchcode);
186 Records the fact that a patron has paid off the entire amount he or
189 C<$borrowernumber> is the patron's borrower number. C<$acctnumber> is
190 the account that was credited. C<$amount> is the amount paid (this is
191 only used to record the payment. It is assumed to be equal to the
192 amount owed). C<$branchcode> is the code of the branch where payment
198 # FIXME - I'm not at all sure about the above, because I don't
199 # understand what the acct* tables in the Koha database are for.
202 #here we update both the accountoffsets and the account lines
203 #updated to check, if they are paying off a lost item, we return the item
204 # from their card, and put a note on the item record
205 my ( $accountlines_id, $borrowernumber, $accountno, $amount, $user, $branch, $payment_note ) = @_;
206 my $dbh = C4::Context->dbh;
208 $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
211 my $nextaccntno = getnextacctno($borrowernumber);
213 my $sth = $dbh->prepare("SELECT * FROM accountlines WHERE accountlines_id=?");
214 $sth->execute( $accountlines_id );
215 my $data = $sth->fetchrow_hashref;
218 if ( $data->{'accounttype'} eq "Pay" ){
222 SET amountoutstanding = 0
223 WHERE accountlines_id = ?
226 $udp->execute($accountlines_id);
231 SET amountoutstanding = 0
232 WHERE accountlines_id = ?
235 $udp->execute($accountlines_id);
238 my $payment = 0 - $amount;
239 $payment_note //= "";
244 INTO accountlines (borrowernumber, accountno, date, amount, itemnumber, description, accounttype, amountoutstanding, manager_id, note)
245 VALUES ( ?, ?, now(), ?, ?, '', 'Pay', 0, ?, ?)"
247 $ins->execute($borrowernumber, $nextaccntno, $payment, $data->{'itemnumber'}, $manager_id, $payment_note);
250 if ( C4::Context->preference("FinesLog") ) {
251 logaction("FINES", 'MODIFY', $borrowernumber, Dumper({
252 action => 'fee_payment',
253 borrowernumber => $borrowernumber,
254 old_amountoutstanding => $data->{'amountoutstanding'},
255 new_amountoutstanding => 0,
256 amount_paid => $data->{'amountoutstanding'},
257 accountlines_id => $data->{'accountlines_id'},
258 accountno => $data->{'accountno'},
259 manager_id => $manager_id,
263 logaction("FINES", 'CREATE',$borrowernumber,Dumper({
264 action => 'create_payment',
265 borrowernumber => $borrowernumber,
266 accountno => $nextaccntno,
268 amountoutstanding => 0,,
269 accounttype => 'Pay',
270 accountlines_paid => [$data->{'accountlines_id'}],
271 manager_id => $manager_id,
279 borrowernumber => $borrowernumber,
280 accountno => $accountno}
283 #check to see what accounttype
284 if ( $data->{'accounttype'} eq 'Rep' || $data->{'accounttype'} eq 'L' ) {
285 C4::Circulation::ReturnLostItem( $borrowernumber, $data->{'itemnumber'} );
287 my $sthr = $dbh->prepare("SELECT max(accountlines_id) AS lastinsertid FROM accountlines");
289 my $datalastinsertid = $sthr->fetchrow_hashref;
290 return $datalastinsertid->{'lastinsertid'};
295 $nextacct = &getnextacctno($borrowernumber);
297 Returns the next unused account number for the patron with the given
303 # FIXME - Okay, so what does the above actually _mean_?
305 my ($borrowernumber) = shift or return;
306 my $sth = C4::Context->dbh->prepare(
307 "SELECT accountno+1 FROM accountlines
308 WHERE (borrowernumber = ?)
309 ORDER BY accountno DESC
312 $sth->execute($borrowernumber);
313 return ($sth->fetchrow || 1);
316 =head2 fixaccounts (removed)
318 &fixaccounts($accountlines_id, $borrowernumber, $accountnumber, $amount);
321 # FIXME - I don't understand what this function does.
323 my ( $accountlines_id, $borrowernumber, $accountno, $amount ) = @_;
324 my $dbh = C4::Context->dbh;
325 my $sth = $dbh->prepare(
326 "SELECT * FROM accountlines WHERE accountlines_id=?"
328 $sth->execute( $accountlines_id );
329 my $data = $sth->fetchrow_hashref;
331 # FIXME - Error-checking
332 my $diff = $amount - $data->{'amount'};
333 my $outstanding = $data->{'amountoutstanding'} + $diff;
338 SET amount = '$amount',
339 amountoutstanding = '$outstanding'
340 WHERE accountlines_id = $accountlines_id
342 # FIXME: exceedingly bad form. Use prepare with placholders ("?") in query and execute args.
348 # lost ==1 Lost, lost==2 longoverdue, lost==3 lost and paid for
349 # FIXME: itemlost should be set to 3 after payment is made, should be a warning to the interface that
350 # a charge has been added
351 # FIXME : if no replacement price, borrower just doesn't get charged?
352 my $dbh = C4::Context->dbh();
353 my ($borrowernumber, $itemnumber, $amount, $description) = @_;
355 # first make sure the borrower hasn't already been charged for this item
356 my $sth1=$dbh->prepare("SELECT * from accountlines
357 WHERE borrowernumber=? AND itemnumber=? and accounttype='L'");
358 $sth1->execute($borrowernumber,$itemnumber);
359 my $existing_charge_hashref=$sth1->fetchrow_hashref();
362 unless ($existing_charge_hashref) {
364 $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
365 # This item is on issue ... add replacement cost to the borrower's record and mark it returned
366 # Note that we add this to the account even if there's no replacement price, allowing some other
367 # process (or person) to update it, since we don't handle any defaults for replacement prices.
368 my $accountno = getnextacctno($borrowernumber);
369 my $sth2=$dbh->prepare("INSERT INTO accountlines
370 (borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding,itemnumber,manager_id)
371 VALUES (?,?,now(),?,?,'L',?,?,?)");
372 $sth2->execute($borrowernumber,$accountno,$amount,
373 $description,$amount,$itemnumber,$manager_id);
375 if ( C4::Context->preference("FinesLog") ) {
376 logaction("FINES", 'CREATE', $borrowernumber, Dumper({
377 action => 'create_fee',
378 borrowernumber => $borrowernumber,
379 accountno => $accountno,
381 amountoutstanding => $amount,
382 description => $description,
384 itemnumber => $itemnumber,
385 manager_id => $manager_id,
394 &manualinvoice($borrowernumber, $itemnumber, $description, $type,
397 C<$borrowernumber> is the patron's borrower number.
398 C<$description> is a description of the transaction.
399 C<$type> may be one of C<CS>, C<CB>, C<CW>, C<CF>, C<CL>, C<N>, C<L>,
401 C<$itemnumber> is the item involved, if pertinent; otherwise, it
402 should be the empty string.
407 # FIXME: In Koha 3.0 , the only account adjustment 'types' passed to this function
410 # 'FOR' = FORGIVEN (Formerly 'F', but 'F' is taken to mean 'FINE' elsewhere)
413 # 'A' = Account Management fee
419 my ( $borrowernumber, $itemnum, $desc, $type, $amount, $note ) = @_;
421 $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
422 my $dbh = C4::Context->dbh;
425 my $accountno = getnextacctno($borrowernumber);
426 my $amountleft = $amount;
428 if ( ( $type eq 'L' )
432 or ( $type eq 'M' ) )
438 $desc .= ' ' . $itemnum;
439 my $sth = $dbh->prepare(
440 'INSERT INTO accountlines
441 (borrowernumber, accountno, date, amount, description, accounttype, amountoutstanding, itemnumber,notify_id, note, manager_id)
442 VALUES (?, ?, now(), ?,?, ?,?,?,?,?,?)');
443 $sth->execute($borrowernumber, $accountno, $amount, $desc, $type, $amountleft, $itemnum,$notifyid, $note, $manager_id) || return $sth->errstr;
445 my $sth=$dbh->prepare("INSERT INTO accountlines
446 (borrowernumber, accountno, date, amount, description, accounttype, amountoutstanding,notify_id, note, manager_id)
447 VALUES (?, ?, now(), ?, ?, ?, ?,?,?,?)"
449 $sth->execute( $borrowernumber, $accountno, $amount, $desc, $type,
450 $amountleft, $notifyid, $note, $manager_id );
453 if ( C4::Context->preference("FinesLog") ) {
454 logaction("FINES", 'CREATE',$borrowernumber,Dumper({
455 action => 'create_fee',
456 borrowernumber => $borrowernumber,
457 accountno => $accountno,
459 description => $desc,
460 accounttype => $type,
461 amountoutstanding => $amountleft,
462 notify_id => $notifyid,
464 itemnumber => $itemnum,
465 manager_id => $manager_id,
473 my ( $borrowerno, $timestamp, $accountno ) = @_;
474 my $dbh = C4::Context->dbh;
475 my $timestamp2 = $timestamp - 1;
477 my $sth = $dbh->prepare(
478 "SELECT * FROM accountlines WHERE borrowernumber=? AND accountno = ?"
480 $sth->execute( $borrowerno, $accountno );
483 while ( my $data = $sth->fetchrow_hashref ) {
490 my ( $accountlines_id, $note ) = @_;
491 my $dbh = C4::Context->dbh;
492 my $sth = $dbh->prepare('UPDATE accountlines SET note = ? WHERE accountlines_id = ?');
493 $sth->execute( $note, $accountlines_id );
497 my ( $date, $date2 ) = @_;
498 my $dbh = C4::Context->dbh;
499 my $sth = $dbh->prepare(
500 "SELECT * FROM accountlines,borrowers
501 WHERE amount < 0 AND accounttype not like 'Pay%' AND accountlines.borrowernumber = borrowers.borrowernumber
502 AND timestamp >=TIMESTAMP(?) AND timestamp < TIMESTAMP(?)"
505 $sth->execute( $date, $date2 );
507 while ( my $data = $sth->fetchrow_hashref ) {
508 $data->{'date'} = $data->{'timestamp'};
516 my ( $date, $date2 ) = @_;
517 my $dbh = C4::Context->dbh;
519 my $sth = $dbh->prepare(
520 "SELECT *,timestamp AS datetime
521 FROM accountlines,borrowers
522 WHERE (accounttype = 'REF'
523 AND accountlines.borrowernumber = borrowers.borrowernumber
524 AND date >=? AND date <?)"
527 $sth->execute( $date, $date2 );
530 while ( my $data = $sth->fetchrow_hashref ) {
538 my ( $accountlines_id ) = @_;
539 my $dbh = C4::Context->dbh;
541 my $sth = $dbh->prepare('SELECT * FROM accountlines WHERE accountlines_id = ?');
542 $sth->execute( $accountlines_id );
543 my $row = $sth->fetchrow_hashref();
544 my $amount_outstanding = $row->{'amountoutstanding'};
546 if ( $amount_outstanding <= 0 ) {
547 $sth = $dbh->prepare('UPDATE accountlines SET amountoutstanding = amount * -1, description = CONCAT( description, " Reversed -" ) WHERE accountlines_id = ?');
548 $sth->execute( $accountlines_id );
550 $sth = $dbh->prepare('UPDATE accountlines SET amountoutstanding = 0, description = CONCAT( description, " Reversed -" ) WHERE accountlines_id = ?');
551 $sth->execute( $accountlines_id );
554 if ( C4::Context->preference("FinesLog") ) {
556 $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
558 if ( $amount_outstanding <= 0 ) {
559 $row->{'amountoutstanding'} *= -1;
561 $row->{'amountoutstanding'} = '0';
563 $row->{'description'} .= ' Reversed -';
564 logaction("FINES", 'MODIFY', $row->{'borrowernumber'}, Dumper({
565 action => 'reverse_fee_payment',
566 borrowernumber => $row->{'borrowernumber'},
567 old_amountoutstanding => $row->{'amountoutstanding'},
568 new_amountoutstanding => 0 - $amount_outstanding,,
569 accountlines_id => $row->{'accountlines_id'},
570 accountno => $row->{'accountno'},
571 manager_id => $manager_id,
578 =head2 recordpayment_selectaccts
580 recordpayment_selectaccts($borrowernumber, $payment,$accts);
582 Record payment by a patron. C<$borrowernumber> is the patron's
583 borrower number. C<$payment> is a floating-point number, giving the
584 amount that was paid. C<$accts> is an array ref to a list of
585 accountnos which the payment can be recorded against
587 Amounts owed are paid off oldest first. That is, if the patron has a
588 $1 fine from Feb. 1, another $1 fine from Mar. 1, and makes a payment
589 of $1.50, then the oldest fine will be paid off in full, and $0.50
590 will be credited to the next one.
594 sub recordpayment_selectaccts {
595 my ( $borrowernumber, $amount, $accts, $note ) = @_;
597 my $dbh = C4::Context->dbh;
600 my $branch = C4::Context->userenv->{branch};
601 my $amountleft = $amount;
603 $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
604 my $sql = 'SELECT * FROM accountlines WHERE (borrowernumber = ?) ' .
605 'AND (amountoutstanding<>0) ';
607 $sql .= ' AND accountno IN ( ' . join ',', @{$accts};
610 $sql .= ' ORDER BY date';
612 my $nextaccntno = getnextacctno($borrowernumber);
614 # get lines with outstanding amounts to offset
615 my $rows = $dbh->selectall_arrayref($sql, { Slice => {} }, $borrowernumber);
617 # offset transactions
618 my $sth = $dbh->prepare('UPDATE accountlines SET amountoutstanding= ? ' .
619 'WHERE accountlines_id=?');
622 for my $accdata ( @{$rows} ) {
623 if ($amountleft == 0) {
626 if ( $accdata->{amountoutstanding} < $amountleft ) {
628 $amountleft -= $accdata->{amountoutstanding};
631 $newamtos = $accdata->{amountoutstanding} - $amountleft;
634 my $thisacct = $accdata->{accountlines_id};
635 $sth->execute( $newamtos, $thisacct );
637 if ( C4::Context->preference("FinesLog") ) {
638 logaction("FINES", 'MODIFY', $borrowernumber, Dumper({
639 action => 'fee_payment',
640 borrowernumber => $borrowernumber,
641 old_amountoutstanding => $accdata->{'amountoutstanding'},
642 new_amountoutstanding => $newamtos,
643 amount_paid => $accdata->{'amountoutstanding'} - $newamtos,
644 accountlines_id => $accdata->{'accountlines_id'},
645 accountno => $accdata->{'accountno'},
646 manager_id => $manager_id,
648 push( @ids, $accdata->{'accountlines_id'} );
654 $sql = 'INSERT INTO accountlines ' .
655 '(borrowernumber, accountno,date,amount,description,accounttype,amountoutstanding,manager_id,note) ' .
656 q|VALUES (?,?,now(),?,'','Pay',?,?,?)|;
657 $dbh->do($sql,{},$borrowernumber, $nextaccntno, 0 - $amount, 0 - $amountleft, $manager_id, $note );
662 borrowernumber => $borrowernumber,
663 accountno => $nextaccntno}
666 if ( C4::Context->preference("FinesLog") ) {
667 logaction("FINES", 'CREATE',$borrowernumber,Dumper({
668 action => 'create_payment',
669 borrowernumber => $borrowernumber,
670 accountno => $nextaccntno,
671 amount => 0 - $amount,
672 amountoutstanding => 0 - $amountleft,
673 accounttype => 'Pay',
674 accountlines_paid => \@ids,
675 manager_id => $manager_id,
682 # makepayment needs to be fixed to handle partials till then this separate subroutine
684 sub makepartialpayment {
685 my ( $accountlines_id, $borrowernumber, $accountno, $amount, $user, $branch, $payment_note ) = @_;
687 $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
688 if (!$amount || $amount < 0) {
691 $payment_note //= "";
692 my $dbh = C4::Context->dbh;
694 my $nextaccntno = getnextacctno($borrowernumber);
697 my $data = $dbh->selectrow_hashref(
698 'SELECT * FROM accountlines WHERE accountlines_id=?',undef,$accountlines_id);
699 my $new_outstanding = $data->{amountoutstanding} - $amount;
701 my $update = 'UPDATE accountlines SET amountoutstanding = ? WHERE accountlines_id = ? ';
702 $dbh->do( $update, undef, $new_outstanding, $accountlines_id);
704 if ( C4::Context->preference("FinesLog") ) {
705 logaction("FINES", 'MODIFY', $borrowernumber, Dumper({
706 action => 'fee_payment',
707 borrowernumber => $borrowernumber,
708 old_amountoutstanding => $data->{'amountoutstanding'},
709 new_amountoutstanding => $new_outstanding,
710 amount_paid => $data->{'amountoutstanding'} - $new_outstanding,
711 accountlines_id => $data->{'accountlines_id'},
712 accountno => $data->{'accountno'},
713 manager_id => $manager_id,
718 my $insert = 'INSERT INTO accountlines (borrowernumber, accountno, date, amount, '
719 . 'description, accounttype, amountoutstanding, itemnumber, manager_id, note) '
720 . ' VALUES (?, ?, now(), ?, ?, ?, 0, ?, ?, ?)';
722 $dbh->do( $insert, undef, $borrowernumber, $nextaccntno, $amount,
723 "Payment, thanks - $user", 'Pay', $data->{'itemnumber'}, $manager_id, $payment_note);
729 borrowernumber => $borrowernumber,
730 accountno => $accountno}
733 if ( C4::Context->preference("FinesLog") ) {
734 logaction("FINES", 'CREATE',$borrowernumber,Dumper({
735 action => 'create_payment',
736 borrowernumber => $user,
737 accountno => $nextaccntno,
738 amount => 0 - $amount,
739 accounttype => 'Pay',
740 itemnumber => $data->{'itemnumber'},
741 accountlines_paid => [ $data->{'accountlines_id'} ],
742 manager_id => $manager_id,
751 WriteOffFee( $borrowernumber, $accountline_id, $itemnum, $accounttype, $amount, $branch, $payment_note );
753 Write off a fine for a patron.
754 C<$borrowernumber> is the patron's borrower number.
755 C<$accountline_id> is the accountline_id of the fee to write off.
756 C<$itemnum> is the itemnumber of of item whose fine is being written off.
757 C<$accounttype> is the account type of the fine being written off.
758 C<$amount> is a floating-point number, giving the amount that is being written off.
759 C<$branch> is the branchcode of the library where the writeoff occurred.
760 C<$payment_note> is the note to attach to this payment
765 my ( $borrowernumber, $accountlines_id, $itemnum, $accounttype, $amount, $branch, $payment_note ) = @_;
766 $payment_note //= "";
767 $branch ||= C4::Context->userenv->{branch};
769 $manager_id = C4::Context->userenv->{'number'} if C4::Context->userenv;
771 # if no item is attached to fine, make sure to store it as a NULL
775 my $dbh = C4::Context->dbh();
778 UPDATE accountlines SET amountoutstanding = 0
779 WHERE accountlines_id = ? AND borrowernumber = ?
781 $sth = $dbh->prepare( $query );
782 $sth->execute( $accountlines_id, $borrowernumber );
784 if ( C4::Context->preference("FinesLog") ) {
785 logaction("FINES", 'MODIFY', $borrowernumber, Dumper({
786 action => 'fee_writeoff',
787 borrowernumber => $borrowernumber,
788 accountlines_id => $accountlines_id,
789 manager_id => $manager_id,
794 INSERT INTO accountlines
795 ( borrowernumber, accountno, itemnumber, date, amount, description, accounttype, manager_id, note )
796 VALUES ( ?, ?, ?, NOW(), ?, 'Writeoff', 'W', ?, ? )
798 $sth = $dbh->prepare( $query );
799 my $acct = getnextacctno($borrowernumber);
800 $sth->execute( $borrowernumber, $acct, $itemnum, $amount, $manager_id, $payment_note );
802 if ( C4::Context->preference("FinesLog") ) {
803 logaction("FINES", 'CREATE',$borrowernumber,Dumper({
804 action => 'create_writeoff',
805 borrowernumber => $borrowernumber,
807 amount => 0 - $amount,
809 itemnumber => $itemnum,
810 accountlines_paid => [ $accountlines_id ],
811 manager_id => $manager_id,
819 borrowernumber => $borrowernumber}
824 END { } # module clean-up code here (global destructor)