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 with
17 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
18 # Suite 330, Boston, MA 02111-1307 USA
28 use vars qw($VERSION @ISA @EXPORT);
30 # set the version for version checking
31 $VERSION = do { my @v = '$Revision$' =~ /\d+/g;
32 shift(@v) . "." . join("_", map {sprintf "%03d", $_ } @v); };
36 C4::Accounts - Functions for dealing with Koha accounts
44 The functions in this module deal with the monetary aspect of Koha,
45 including looking up and modifying the amount of money owed by a
53 @EXPORT = qw(&recordpayment &fixaccounts &makepayment &manualinvoice
54 &getnextacctno &reconcileaccount);
59 &recordpayment($borrowernumber, $payment);
61 Record payment by a patron. C<$borrowernumber> is the patron's
62 borrower number. C<$payment> is a floating-point number, giving the
65 Amounts owed are paid off oldest first. That is, if the patron has a
66 $1 fine from Feb. 1, another $1 fine from Mar. 1, and makes a payment
67 of $1.50, then the oldest fine will be paid off in full, and $0.50
68 will be credited to the next one.
74 #here we update both the accountoffsets and the account lines
75 my ($borrowernumber,$data)=@_;
76 my $dbh = C4::Context->dbh;
79 my $branch=C4::Context->userenv->{'branch'};
80 my $amountleft = $data;
82 my $nextaccntno = getnextacctno($borrowernumber);
83 # get lines with outstanding amounts to offset
84 my $sth = $dbh->prepare("select * from accountlines
85 where (borrowernumber = ?) and (amountoutstanding<>0)
87 $sth->execute($borrowernumber);
89 while (($accdata=$sth->fetchrow_hashref) and ($amountleft>0)){
90 if ($accdata->{'amountoutstanding'} < $amountleft) {
92 $amountleft -= $accdata->{'amountoutstanding'};
94 $newamtos = $accdata->{'amountoutstanding'} - $amountleft;
97 my $thisacct = $accdata->{accountno};
98 my $usth = $dbh->prepare("update accountlines set amountoutstanding= ?
99 where (borrowernumber = ?) and (accountno=?)");
100 $usth->execute($newamtos,$borrowernumber,$thisacct);
102 $usth = $dbh->prepare("insert into accountoffsets
103 (borrowernumber, accountno, offsetaccount, offsetamount)
105 $usth->execute($borrowernumber,$accdata->{'accountno'},$nextaccntno,$newamtos);
109 my $usth = $dbh->prepare("insert into accountlines
110 (borrowernumber, accountno,date,amount,description,accounttype,amountoutstanding)
111 values (?,?,now(),?,'Payment,thanks','Pay',?)");
112 $usth->execute($borrowernumber,$nextaccntno,0-$data,0-$amountleft);
114 UpdateStats($branch,'payment',$data,'','','',$borrowernumber);
120 &makepayment($borrowernumber, $acctnumber, $amount, $branchcode);
122 Records the fact that a patron has paid off the entire amount he or
125 C<$borrowernumber> is the patron's borrower number. C<$acctnumber> is
126 the account that was credited. C<$amount> is the amount paid (this is
127 only used to record the payment. It is assumed to be equal to the
128 amount owed). C<$branchcode> is the code of the branch where payment
134 # FIXME - I'm not at all sure about the above, because I don't
135 # understand what the acct* tables in the Koha database are for.
137 #here we update both the accountoffsets and the account lines
138 #updated to check, if they are paying off a lost item, we return the item
139 # from their card, and put a note on the item record
140 my ($borrowernumber,$accountno,$amount,$user,$branch)=@_;
141 my $dbh = C4::Context->dbh;
143 my $nextaccntno = getnextacctno($borrowernumber);
145 my $sth=$dbh->prepare("Select * from accountlines where borrowernumber=? and accountno=?");
146 $sth->execute($borrowernumber,$accountno);
147 my $data=$sth->fetchrow_hashref;
152 SET amountoutstanding = 0
153 WHERE borrowernumber = $borrowernumber
154 AND accountno = $accountno
159 INSERT INTO accountoffsets
160 (borrowernumber, accountno, offsetaccount,
162 VALUES ($borrowernumber, $accountno, $nextaccntno, $newamtos)
166 my $payment=0-$amount;
168 INSERT INTO accountlines
169 (borrowernumber, accountno, date, amount,
170 description, accounttype, amountoutstanding)
171 VALUES ($borrowernumber, $nextaccntno, now(), $payment,
172 'Payment,thanks - $user', 'Pay', 0)
175 # FIXME - The second argument to &UpdateStats is supposed to be the
177 # UpdateStats is now being passed $accountno too. MTJ
178 UpdateStats($user,'payment',$amount,'','','',$borrowernumber,$accountno);
180 #check to see what accounttype
181 if ($data->{'accounttype'} eq 'Rep' || $data->{'accounttype'} eq 'L'){
182 returnlost($borrowernumber,$data->{'itemnumber'});
188 $nextacct = &getnextacctno($borrowernumber);
190 Returns the next unused account number for the patron with the given
193 C<$dbh> is a DBI::db handle to the Koha database.
198 # FIXME - Okay, so what does the above actually _mean_?
200 my ($borrowernumber)=@_;
202 my $dbh = C4::Context->dbh;
203 my $sth = $dbh->prepare("SELECT * FROM accountlines
204 WHERE (borrowernumber = ?)
205 ORDER BY accountno DESC");
206 $sth->execute($borrowernumber);
207 if (my $accdata=$sth->fetchrow_hashref){
208 $nextaccntno = $accdata->{'accountno'} + 1;
211 return($nextaccntno);
216 &fixaccounts($borrowernumber, $accountnumber, $amount);
221 # FIXME - I don't understand what this function does.
223 my ($borrowernumber,$accountno,$amount)=@_;
224 my $dbh = C4::Context->dbh;
225 my $sth=$dbh->prepare("Select * from accountlines where borrowernumber=?
227 $sth->execute($borrowernumber,$accountno);
228 my $data=$sth->fetchrow_hashref;
229 # FIXME - Error-checking
230 my $diff=$amount-$data->{'amount'};
231 my $outstanding=$data->{'amountoutstanding'}+$diff;
236 SET amount = '$amount',
237 amountoutstanding = '$outstanding'
238 WHERE borrowernumber = $borrowernumber
239 AND accountno = $accountno
243 # FIXME - Never used, but not exported, either.
245 my ($borrowernumber,$itemnum)=@_;
246 my $dbh = C4::Context->dbh;
247 my $borrower=GetMember($borrowernumber,'borrowernumber');
248 my $sth=$dbh->prepare("Update issues set returndate=now() where
249 borrowernumber=? and itemnumber=? and returndate is null");
250 $sth->execute($borrowernumber,$itemnum);
252 my @datearr = localtime(time);
253 my $date = (1900+$datearr[5])."-".($datearr[4]+1)."-".$datearr[3];
254 my $bor="$borrower->{'firstname'} $borrower->{'surname'} $borrower->{'cardnumber'}";
255 $sth=$dbh->prepare("Update items set paidfor=? where itemnumber=?");
256 $sth->execute("Paid for by $bor $date",$itemnum);
262 &manualinvoice($borrowernumber, $itemnumber, $description, $type,
265 C<$borrowernumber> is the patron's borrower number.
266 C<$description> is a description of the transaction.
267 C<$type> may be one of C<CS>, C<CB>, C<CW>, C<CF>, C<CL>, C<N>, C<L>,
269 C<$itemnumber> is the item involved, if pertinent; otherwise, it
270 should be the empty string.
275 # FIXME - Okay, so what does this function do, really?
277 my ($borrowernumber,$itemnum,$desc,$type,$amount,$user)=@_;
278 my $dbh = C4::Context->dbh;
282 my $accountno=getnextacctno($borrowernumber);
283 my $amountleft=$amount;
285 if ($type eq 'CS' || $type eq 'CB' || $type eq 'CW'
286 || $type eq 'CF' || $type eq 'CL'){
287 my $amount2=$amount*-1; # FIXME - $amount2 = -$amount
288 $amountleft=fixcredit($borrowernumber,$amount2,$itemnum,$type,$user);
297 $desc.="Account Management fee";
303 if ($type eq 'L' && $desc eq ''){
308 $desc.="Cash Refund";
309 $amountleft=refund('',$borrowernumber,$amount);
311 if(($type eq 'L') or ($type eq 'F') or ($type eq 'A') or ($type eq 'N') or ($type eq 'M') ){
317 my $sth=$dbh->prepare("INSERT INTO accountlines
318 (borrowernumber, accountno, date, amount, description, accounttype, amountoutstanding, itemnumber,notify_id)
319 VALUES (?, ?, now(), ?,?, ?,?,?,?)");
320 # $sth->execute($borrowernumber, $accountno, $amount, $desc, $type, $amountleft, $data->{'itemnumber'});
321 $sth->execute($borrowernumber, $accountno, $amount, $desc, $type, $amountleft, $itemnum,$notifyid);
323 my $sth=$dbh->prepare("INSERT INTO accountlines
324 (borrowernumber, accountno, date, amount, description, accounttype, amountoutstanding,notify_id)
325 VALUES (?, ?, now(), ?, ?, ?, ?,?)");
326 $sth->execute($borrowernumber, $accountno, $amount, $desc, $type, $amountleft,$notifyid);
332 $amountleft = &fixcredit($borrowernumber, $data, $barcode, $type, $user);
334 This function is only used internally, not exported.
335 FIXME - Figure out what this function does, and write it down.
340 #here we update both the accountoffsets and the account lines
341 my ($borrowernumber,$data,$barcode,$type,$user)=@_;
342 my $dbh = C4::Context->dbh;
345 my $amountleft = $data;
347 my $item=GetBiblioFromItemNumber('',$barcode);
348 my $nextaccntno = getnextacctno($borrowernumber);
349 my $query="Select * from accountlines where (borrowernumber=?
350 and itemnumber=? and amountoutstanding > 0)";
352 $query.=" and (accounttype = 'L' or accounttype = 'Rep')";
353 } elsif ($type eq 'CF'){
354 $query.=" and (accounttype = 'F' or accounttype = 'FU' or
355 accounttype='Res' or accounttype='Rent')";
356 } elsif ($type eq 'CB'){
357 $query.=" and accounttype='A'";
360 my $sth=$dbh->prepare($query);
361 $sth->execute($borrowernumber,$item->{'itemnumber'});
362 $accdata=$sth->fetchrow_hashref;
364 if ($accdata->{'amountoutstanding'} < $amountleft) {
366 $amountleft -= $accdata->{'amountoutstanding'};
368 $newamtos = $accdata->{'amountoutstanding'} - $amountleft;
371 my $thisacct = $accdata->{accountno};
372 my $usth = $dbh->prepare("update accountlines set amountoutstanding= ?
373 where (borrowernumber = ?) and (accountno=?)");
374 $usth->execute($newamtos,$borrowernumber,$thisacct);
376 $usth = $dbh->prepare("insert into accountoffsets
377 (borrowernumber, accountno, offsetaccount, offsetamount)
379 $usth->execute($borrowernumber,$accdata->{'accountno'},$nextaccntno,$newamtos);
383 my $nextaccntno = getnextacctno($borrowernumber);
384 # get lines with outstanding amounts to offset
385 my $sth = $dbh->prepare("select * from accountlines
386 where (borrowernumber = ?) and (amountoutstanding >0)
388 $sth->execute($borrowernumber);
390 # offset transactions
391 while (($accdata=$sth->fetchrow_hashref) and ($amountleft>0)){
392 if ($accdata->{'amountoutstanding'} < $amountleft) {
394 $amountleft -= $accdata->{'amountoutstanding'};
396 $newamtos = $accdata->{'amountoutstanding'} - $amountleft;
399 my $thisacct = $accdata->{accountno};
400 my $usth = $dbh->prepare("update accountlines set amountoutstanding= ?
401 where (borrowernumber = ?) and (accountno=?)");
402 $usth->execute($newamtos,$borrowernumber,$thisacct);
404 $usth = $dbh->prepare("insert into accountoffsets
405 (borrowernumber, accountno, offsetaccount, offsetamount)
407 $usth->execute($borrowernumber,$accdata->{'accountno'},$nextaccntno,$newamtos);
411 $type="Credit ".$type;
412 UpdateStats($user,$type,$data,$user,'','',$borrowernumber);
420 # FIXME - Figure out what this function does, and write it down.
425 #here we update both the accountoffsets and the account lines
426 my ($borrowernumber,$data)=@_;
427 my $dbh = C4::Context->dbh;
430 my $amountleft = $data *-1;
433 my $nextaccntno = getnextacctno($borrowernumber);
434 # get lines with outstanding amounts to offset
435 my $sth = $dbh->prepare("select * from accountlines
436 where (borrowernumber = ?) and (amountoutstanding<0)
438 $sth->execute($borrowernumber);
440 # offset transactions
441 while (($accdata=$sth->fetchrow_hashref) and ($amountleft<0)){
442 if ($accdata->{'amountoutstanding'} > $amountleft) {
444 $amountleft -= $accdata->{'amountoutstanding'};
446 $newamtos = $accdata->{'amountoutstanding'} - $amountleft;
450 my $thisacct = $accdata->{accountno};
451 my $usth = $dbh->prepare("update accountlines set amountoutstanding= ?
452 where (borrowernumber = ?) and (accountno=?)");
453 $usth->execute($newamtos,$borrowernumber,$thisacct);
455 $usth = $dbh->prepare("insert into accountoffsets
456 (borrowernumber, accountno, offsetaccount, offsetamount)
458 $usth->execute($borrowernumber,$accdata->{'accountno'},$nextaccntno,$newamtos);
466 END { } # module clean-up code here (global destructor)