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 );
158 UpdateStats
( $branch, 'payment', $data, '', '', '', $borrowernumber, $nextaccntno );
160 if ( C4
::Context
->preference("FinesLog") ) {
161 $accdata->{'amountoutstanding_new'} = $newamtos;
162 logaction
("FINES", 'CREATE',$borrowernumber,Dumper
({
163 action
=> 'create_payment',
164 borrowernumber
=> $borrowernumber,
165 accountno
=> $nextaccntno,
166 amount
=> $data * -1,
167 amountoutstanding
=> $amountleft * -1,
168 accounttype
=> 'Pay',
169 accountlines_paid
=> \
@ids,
170 manager_id
=> $manager_id,
178 &makepayment($accountlines_id, $borrowernumber, $acctnumber, $amount, $branchcode);
180 Records the fact that a patron has paid off the entire amount he or
183 C<$borrowernumber> is the patron's borrower number. C<$acctnumber> is
184 the account that was credited. C<$amount> is the amount paid (this is
185 only used to record the payment. It is assumed to be equal to the
186 amount owed). C<$branchcode> is the code of the branch where payment
192 # FIXME - I'm not at all sure about the above, because I don't
193 # understand what the acct* tables in the Koha database are for.
196 #here we update both the accountoffsets and the account lines
197 #updated to check, if they are paying off a lost item, we return the item
198 # from their card, and put a note on the item record
199 my ( $accountlines_id, $borrowernumber, $accountno, $amount, $user, $branch, $payment_note ) = @_;
200 my $dbh = C4
::Context
->dbh;
202 $manager_id = C4
::Context
->userenv->{'number'} if C4
::Context
->userenv;
205 my $nextaccntno = getnextacctno
($borrowernumber);
207 my $sth = $dbh->prepare("SELECT * FROM accountlines WHERE accountlines_id=?");
208 $sth->execute( $accountlines_id );
209 my $data = $sth->fetchrow_hashref;
212 if ( $data->{'accounttype'} eq "Pay" ){
216 SET amountoutstanding = 0
217 WHERE accountlines_id = ?
220 $udp->execute($accountlines_id);
225 SET amountoutstanding = 0
226 WHERE accountlines_id = ?
229 $udp->execute($accountlines_id);
232 my $payment = 0 - $amount;
233 $payment_note //= "";
238 INTO accountlines (borrowernumber, accountno, date, amount, itemnumber, description, accounttype, amountoutstanding, manager_id, note)
239 VALUES ( ?, ?, now(), ?, ?, '', 'Pay', 0, ?, ?)"
241 $ins->execute($borrowernumber, $nextaccntno, $payment, $data->{'itemnumber'}, $manager_id, $payment_note);
244 if ( C4
::Context
->preference("FinesLog") ) {
245 logaction
("FINES", 'MODIFY', $borrowernumber, Dumper
({
246 action
=> 'fee_payment',
247 borrowernumber
=> $borrowernumber,
248 old_amountoutstanding
=> $data->{'amountoutstanding'},
249 new_amountoutstanding
=> 0,
250 amount_paid
=> $data->{'amountoutstanding'},
251 accountlines_id
=> $data->{'accountlines_id'},
252 accountno
=> $data->{'accountno'},
253 manager_id
=> $manager_id,
257 logaction
("FINES", 'CREATE',$borrowernumber,Dumper
({
258 action
=> 'create_payment',
259 borrowernumber
=> $borrowernumber,
260 accountno
=> $nextaccntno,
262 amountoutstanding
=> 0,,
263 accounttype
=> 'Pay',
264 accountlines_paid
=> [$data->{'accountlines_id'}],
265 manager_id
=> $manager_id,
270 # FIXME - The second argument to &UpdateStats is supposed to be the
272 # UpdateStats is now being passed $accountno too. MTJ
273 UpdateStats
( $user, 'payment', $amount, '', '', '', $borrowernumber,
276 #check to see what accounttype
277 if ( $data->{'accounttype'} eq 'Rep' || $data->{'accounttype'} eq 'L' ) {
278 C4
::Circulation
::ReturnLostItem
( $borrowernumber, $data->{'itemnumber'} );
280 my $sthr = $dbh->prepare("SELECT max(accountlines_id) AS lastinsertid FROM accountlines");
282 my $datalastinsertid = $sthr->fetchrow_hashref;
283 return $datalastinsertid->{'lastinsertid'};
288 $nextacct = &getnextacctno($borrowernumber);
290 Returns the next unused account number for the patron with the given
296 # FIXME - Okay, so what does the above actually _mean_?
298 my ($borrowernumber) = shift or return;
299 my $sth = C4
::Context
->dbh->prepare(
300 "SELECT accountno+1 FROM accountlines
301 WHERE (borrowernumber = ?)
302 ORDER BY accountno DESC
305 $sth->execute($borrowernumber);
306 return ($sth->fetchrow || 1);
309 =head2 fixaccounts (removed)
311 &fixaccounts($accountlines_id, $borrowernumber, $accountnumber, $amount);
314 # FIXME - I don't understand what this function does.
316 my ( $accountlines_id, $borrowernumber, $accountno, $amount ) = @_;
317 my $dbh = C4::Context->dbh;
318 my $sth = $dbh->prepare(
319 "SELECT * FROM accountlines WHERE accountlines_id=?"
321 $sth->execute( $accountlines_id );
322 my $data = $sth->fetchrow_hashref;
324 # FIXME - Error-checking
325 my $diff = $amount - $data->{'amount'};
326 my $outstanding = $data->{'amountoutstanding'} + $diff;
331 SET amount = '$amount',
332 amountoutstanding = '$outstanding'
333 WHERE accountlines_id = $accountlines_id
335 # FIXME: exceedingly bad form. Use prepare with placholders ("?") in query and execute args.
341 # lost ==1 Lost, lost==2 longoverdue, lost==3 lost and paid for
342 # FIXME: itemlost should be set to 3 after payment is made, should be a warning to the interface that
343 # a charge has been added
344 # FIXME : if no replacement price, borrower just doesn't get charged?
345 my $dbh = C4
::Context
->dbh();
346 my ($borrowernumber, $itemnumber, $amount, $description) = @_;
348 # first make sure the borrower hasn't already been charged for this item
349 my $sth1=$dbh->prepare("SELECT * from accountlines
350 WHERE borrowernumber=? AND itemnumber=? and accounttype='L'");
351 $sth1->execute($borrowernumber,$itemnumber);
352 my $existing_charge_hashref=$sth1->fetchrow_hashref();
355 unless ($existing_charge_hashref) {
357 $manager_id = C4
::Context
->userenv->{'number'} if C4
::Context
->userenv;
358 # This item is on issue ... add replacement cost to the borrower's record and mark it returned
359 # Note that we add this to the account even if there's no replacement price, allowing some other
360 # process (or person) to update it, since we don't handle any defaults for replacement prices.
361 my $accountno = getnextacctno
($borrowernumber);
362 my $sth2=$dbh->prepare("INSERT INTO accountlines
363 (borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding,itemnumber,manager_id)
364 VALUES (?,?,now(),?,?,'L',?,?,?)");
365 $sth2->execute($borrowernumber,$accountno,$amount,
366 $description,$amount,$itemnumber,$manager_id);
368 if ( C4
::Context
->preference("FinesLog") ) {
369 logaction
("FINES", 'CREATE', $borrowernumber, Dumper
({
370 action
=> 'create_fee',
371 borrowernumber
=> $borrowernumber,
372 accountno
=> $accountno,
374 amountoutstanding
=> $amount,
375 description
=> $description,
377 itemnumber
=> $itemnumber,
378 manager_id
=> $manager_id,
387 &manualinvoice($borrowernumber, $itemnumber, $description, $type,
390 C<$borrowernumber> is the patron's borrower number.
391 C<$description> is a description of the transaction.
392 C<$type> may be one of C<CS>, C<CB>, C<CW>, C<CF>, C<CL>, C<N>, C<L>,
394 C<$itemnumber> is the item involved, if pertinent; otherwise, it
395 should be the empty string.
400 # FIXME: In Koha 3.0 , the only account adjustment 'types' passed to this function
403 # 'FOR' = FORGIVEN (Formerly 'F', but 'F' is taken to mean 'FINE' elsewhere)
406 # 'A' = Account Management fee
412 my ( $borrowernumber, $itemnum, $desc, $type, $amount, $note ) = @_;
414 $manager_id = C4
::Context
->userenv->{'number'} if C4
::Context
->userenv;
415 my $dbh = C4
::Context
->dbh;
418 my $accountno = getnextacctno
($borrowernumber);
419 my $amountleft = $amount;
421 if ( ( $type eq 'L' )
425 or ( $type eq 'M' ) )
431 $desc .= ' ' . $itemnum;
432 my $sth = $dbh->prepare(
433 'INSERT INTO accountlines
434 (borrowernumber, accountno, date, amount, description, accounttype, amountoutstanding, itemnumber,notify_id, note, manager_id)
435 VALUES (?, ?, now(), ?,?, ?,?,?,?,?,?)');
436 $sth->execute($borrowernumber, $accountno, $amount, $desc, $type, $amountleft, $itemnum,$notifyid, $note, $manager_id) || return $sth->errstr;
438 my $sth=$dbh->prepare("INSERT INTO accountlines
439 (borrowernumber, accountno, date, amount, description, accounttype, amountoutstanding,notify_id, note, manager_id)
440 VALUES (?, ?, now(), ?, ?, ?, ?,?,?,?)"
442 $sth->execute( $borrowernumber, $accountno, $amount, $desc, $type,
443 $amountleft, $notifyid, $note, $manager_id );
446 if ( C4
::Context
->preference("FinesLog") ) {
447 logaction
("FINES", 'CREATE',$borrowernumber,Dumper
({
448 action
=> 'create_fee',
449 borrowernumber
=> $borrowernumber,
450 accountno
=> $accountno,
452 description
=> $desc,
453 accounttype
=> $type,
454 amountoutstanding
=> $amountleft,
455 notify_id
=> $notifyid,
457 itemnumber
=> $itemnum,
458 manager_id
=> $manager_id,
466 my ( $borrowerno, $timestamp, $accountno ) = @_;
467 my $dbh = C4
::Context
->dbh;
468 my $timestamp2 = $timestamp - 1;
470 my $sth = $dbh->prepare(
471 "SELECT * FROM accountlines WHERE borrowernumber=? AND accountno = ?"
473 $sth->execute( $borrowerno, $accountno );
476 while ( my $data = $sth->fetchrow_hashref ) {
483 my ( $accountlines_id, $note ) = @_;
484 my $dbh = C4
::Context
->dbh;
485 my $sth = $dbh->prepare('UPDATE accountlines SET note = ? WHERE accountlines_id = ?');
486 $sth->execute( $note, $accountlines_id );
490 my ( $date, $date2 ) = @_;
491 my $dbh = C4
::Context
->dbh;
492 my $sth = $dbh->prepare(
493 "SELECT * FROM accountlines,borrowers
494 WHERE amount < 0 AND accounttype not like 'Pay%' AND accountlines.borrowernumber = borrowers.borrowernumber
495 AND timestamp >=TIMESTAMP(?) AND timestamp < TIMESTAMP(?)"
498 $sth->execute( $date, $date2 );
500 while ( my $data = $sth->fetchrow_hashref ) {
501 $data->{'date'} = $data->{'timestamp'};
509 my ( $date, $date2 ) = @_;
510 my $dbh = C4
::Context
->dbh;
512 my $sth = $dbh->prepare(
513 "SELECT *,timestamp AS datetime
514 FROM accountlines,borrowers
515 WHERE (accounttype = 'REF'
516 AND accountlines.borrowernumber = borrowers.borrowernumber
517 AND date >=? AND date <?)"
520 $sth->execute( $date, $date2 );
523 while ( my $data = $sth->fetchrow_hashref ) {
531 my ( $accountlines_id ) = @_;
532 my $dbh = C4
::Context
->dbh;
534 my $sth = $dbh->prepare('SELECT * FROM accountlines WHERE accountlines_id = ?');
535 $sth->execute( $accountlines_id );
536 my $row = $sth->fetchrow_hashref();
537 my $amount_outstanding = $row->{'amountoutstanding'};
539 if ( $amount_outstanding <= 0 ) {
540 $sth = $dbh->prepare('UPDATE accountlines SET amountoutstanding = amount * -1, description = CONCAT( description, " Reversed -" ) WHERE accountlines_id = ?');
541 $sth->execute( $accountlines_id );
543 $sth = $dbh->prepare('UPDATE accountlines SET amountoutstanding = 0, description = CONCAT( description, " Reversed -" ) WHERE accountlines_id = ?');
544 $sth->execute( $accountlines_id );
547 if ( C4
::Context
->preference("FinesLog") ) {
549 $manager_id = C4
::Context
->userenv->{'number'} if C4
::Context
->userenv;
551 if ( $amount_outstanding <= 0 ) {
552 $row->{'amountoutstanding'} *= -1;
554 $row->{'amountoutstanding'} = '0';
556 $row->{'description'} .= ' Reversed -';
557 logaction
("FINES", 'MODIFY', $row->{'borrowernumber'}, Dumper
({
558 action
=> 'reverse_fee_payment',
559 borrowernumber
=> $row->{'borrowernumber'},
560 old_amountoutstanding
=> $row->{'amountoutstanding'},
561 new_amountoutstanding
=> 0 - $amount_outstanding,,
562 accountlines_id
=> $row->{'accountlines_id'},
563 accountno
=> $row->{'accountno'},
564 manager_id
=> $manager_id,
571 =head2 recordpayment_selectaccts
573 recordpayment_selectaccts($borrowernumber, $payment,$accts);
575 Record payment by a patron. C<$borrowernumber> is the patron's
576 borrower number. C<$payment> is a floating-point number, giving the
577 amount that was paid. C<$accts> is an array ref to a list of
578 accountnos which the payment can be recorded against
580 Amounts owed are paid off oldest first. That is, if the patron has a
581 $1 fine from Feb. 1, another $1 fine from Mar. 1, and makes a payment
582 of $1.50, then the oldest fine will be paid off in full, and $0.50
583 will be credited to the next one.
587 sub recordpayment_selectaccts
{
588 my ( $borrowernumber, $amount, $accts, $note ) = @_;
590 my $dbh = C4
::Context
->dbh;
593 my $branch = C4
::Context
->userenv->{branch
};
594 my $amountleft = $amount;
596 $manager_id = C4
::Context
->userenv->{'number'} if C4
::Context
->userenv;
597 my $sql = 'SELECT * FROM accountlines WHERE (borrowernumber = ?) ' .
598 'AND (amountoutstanding<>0) ';
600 $sql .= ' AND accountno IN ( ' . join ',', @
{$accts};
603 $sql .= ' ORDER BY date';
605 my $nextaccntno = getnextacctno
($borrowernumber);
607 # get lines with outstanding amounts to offset
608 my $rows = $dbh->selectall_arrayref($sql, { Slice
=> {} }, $borrowernumber);
610 # offset transactions
611 my $sth = $dbh->prepare('UPDATE accountlines SET amountoutstanding= ? ' .
612 'WHERE accountlines_id=?');
615 for my $accdata ( @
{$rows} ) {
616 if ($amountleft == 0) {
619 if ( $accdata->{amountoutstanding
} < $amountleft ) {
621 $amountleft -= $accdata->{amountoutstanding
};
624 $newamtos = $accdata->{amountoutstanding
} - $amountleft;
627 my $thisacct = $accdata->{accountlines_id
};
628 $sth->execute( $newamtos, $thisacct );
630 if ( C4
::Context
->preference("FinesLog") ) {
631 logaction
("FINES", 'MODIFY', $borrowernumber, Dumper
({
632 action
=> 'fee_payment',
633 borrowernumber
=> $borrowernumber,
634 old_amountoutstanding
=> $accdata->{'amountoutstanding'},
635 new_amountoutstanding
=> $newamtos,
636 amount_paid
=> $accdata->{'amountoutstanding'} - $newamtos,
637 accountlines_id
=> $accdata->{'accountlines_id'},
638 accountno
=> $accdata->{'accountno'},
639 manager_id
=> $manager_id,
641 push( @ids, $accdata->{'accountlines_id'} );
647 $sql = 'INSERT INTO accountlines ' .
648 '(borrowernumber, accountno,date,amount,description,accounttype,amountoutstanding,manager_id,note) ' .
649 q
|VALUES
(?
,?
,now
(),?
,'','Pay',?
,?
,?
)|;
650 $dbh->do($sql,{},$borrowernumber, $nextaccntno, 0 - $amount, 0 - $amountleft, $manager_id, $note );
651 UpdateStats
( $branch, 'payment', $amount, '', '', '', $borrowernumber, $nextaccntno );
653 if ( C4
::Context
->preference("FinesLog") ) {
654 logaction
("FINES", 'CREATE',$borrowernumber,Dumper
({
655 action
=> 'create_payment',
656 borrowernumber
=> $borrowernumber,
657 accountno
=> $nextaccntno,
658 amount
=> 0 - $amount,
659 amountoutstanding
=> 0 - $amountleft,
660 accounttype
=> 'Pay',
661 accountlines_paid
=> \
@ids,
662 manager_id
=> $manager_id,
669 # makepayment needs to be fixed to handle partials till then this separate subroutine
671 sub makepartialpayment
{
672 my ( $accountlines_id, $borrowernumber, $accountno, $amount, $user, $branch, $payment_note ) = @_;
674 $manager_id = C4
::Context
->userenv->{'number'} if C4
::Context
->userenv;
675 if (!$amount || $amount < 0) {
678 $payment_note //= "";
679 my $dbh = C4
::Context
->dbh;
681 my $nextaccntno = getnextacctno
($borrowernumber);
684 my $data = $dbh->selectrow_hashref(
685 'SELECT * FROM accountlines WHERE accountlines_id=?',undef,$accountlines_id);
686 my $new_outstanding = $data->{amountoutstanding
} - $amount;
688 my $update = 'UPDATE accountlines SET amountoutstanding = ? WHERE accountlines_id = ? ';
689 $dbh->do( $update, undef, $new_outstanding, $accountlines_id);
691 if ( C4
::Context
->preference("FinesLog") ) {
692 logaction
("FINES", 'MODIFY', $borrowernumber, Dumper
({
693 action
=> 'fee_payment',
694 borrowernumber
=> $borrowernumber,
695 old_amountoutstanding
=> $data->{'amountoutstanding'},
696 new_amountoutstanding
=> $new_outstanding,
697 amount_paid
=> $data->{'amountoutstanding'} - $new_outstanding,
698 accountlines_id
=> $data->{'accountlines_id'},
699 accountno
=> $data->{'accountno'},
700 manager_id
=> $manager_id,
705 my $insert = 'INSERT INTO accountlines (borrowernumber, accountno, date, amount, '
706 . 'description, accounttype, amountoutstanding, itemnumber, manager_id, note) '
707 . ' VALUES (?, ?, now(), ?, ?, ?, 0, ?, ?, ?)';
709 $dbh->do( $insert, undef, $borrowernumber, $nextaccntno, $amount,
710 "Payment, thanks - $user", 'Pay', $data->{'itemnumber'}, $manager_id, $payment_note);
712 UpdateStats
( $user, 'payment', $amount, '', '', '', $borrowernumber, $accountno );
714 if ( C4
::Context
->preference("FinesLog") ) {
715 logaction
("FINES", 'CREATE',$borrowernumber,Dumper
({
716 action
=> 'create_payment',
717 borrowernumber
=> $user,
718 accountno
=> $nextaccntno,
719 amount
=> 0 - $amount,
720 accounttype
=> 'Pay',
721 itemnumber
=> $data->{'itemnumber'},
722 accountlines_paid
=> [ $data->{'accountlines_id'} ],
723 manager_id
=> $manager_id,
732 WriteOffFee( $borrowernumber, $accountline_id, $itemnum, $accounttype, $amount, $branch, $payment_note );
734 Write off a fine for a patron.
735 C<$borrowernumber> is the patron's borrower number.
736 C<$accountline_id> is the accountline_id of the fee to write off.
737 C<$itemnum> is the itemnumber of of item whose fine is being written off.
738 C<$accounttype> is the account type of the fine being written off.
739 C<$amount> is a floating-point number, giving the amount that is being written off.
740 C<$branch> is the branchcode of the library where the writeoff occurred.
741 C<$payment_note> is the note to attach to this payment
746 my ( $borrowernumber, $accountlines_id, $itemnum, $accounttype, $amount, $branch, $payment_note ) = @_;
747 $payment_note //= "";
748 $branch ||= C4
::Context
->userenv->{branch
};
750 $manager_id = C4
::Context
->userenv->{'number'} if C4
::Context
->userenv;
752 # if no item is attached to fine, make sure to store it as a NULL
756 my $dbh = C4
::Context
->dbh();
759 UPDATE accountlines SET amountoutstanding = 0
760 WHERE accountlines_id = ? AND borrowernumber = ?
762 $sth = $dbh->prepare( $query );
763 $sth->execute( $accountlines_id, $borrowernumber );
765 if ( C4
::Context
->preference("FinesLog") ) {
766 logaction
("FINES", 'MODIFY', $borrowernumber, Dumper
({
767 action
=> 'fee_writeoff',
768 borrowernumber
=> $borrowernumber,
769 accountlines_id
=> $accountlines_id,
770 manager_id
=> $manager_id,
775 INSERT INTO accountlines
776 ( borrowernumber, accountno, itemnumber, date, amount, description, accounttype, manager_id, note )
777 VALUES ( ?, ?, ?, NOW(), ?, 'Writeoff', 'W', ?, ? )
779 $sth = $dbh->prepare( $query );
780 my $acct = getnextacctno
($borrowernumber);
781 $sth->execute( $borrowernumber, $acct, $itemnum, $amount, $manager_id, $payment_note );
783 if ( C4
::Context
->preference("FinesLog") ) {
784 logaction
("FINES", 'CREATE',$borrowernumber,Dumper
({
785 action
=> 'create_writeoff',
786 borrowernumber
=> $borrowernumber,
788 amount
=> 0 - $amount,
790 itemnumber
=> $itemnum,
791 accountlines_paid
=> [ $accountlines_id ],
792 manager_id
=> $manager_id,
796 UpdateStats
( $branch, 'writeoff', $amount, q{}, q{}, q{}, $borrowernumber );
800 END { } # module clean-up code here (global destructor)