1 package C4::Accounts2; #assumes C4/Accounts2
4 # Copyright 2000-2002 Katipo Communications
6 # This file is part of Koha.
8 # Koha is free software; you can redistribute it and/or modify it under the
9 # terms of the GNU General Public License as published by the Free Software
10 # Foundation; either version 2 of the License, or (at your option) any later
13 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
14 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License along with
18 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
19 # Suite 330, Boston, MA 02111-1307 USA
27 use C4::Circulation::Circ2;
28 use vars qw($VERSION @ISA @EXPORT);
30 # set the version for version checking
31 $VERSION = 0.01; # FIXME - Should probably be different from
32 # the version for C4::Accounts
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
55 @EXPORT = qw(&recordpayment &fixaccounts &makepayment &manualinvoice
65 &recordpayment($env, $borrowernumber, $payment);
67 Record payment by a patron. C<$borrowernumber> is the patron's
68 borrower number. C<$payment> is a floating-point number, giving the
69 amount that was paid. C<$env> is a reference-to-hash;
70 C<$env-E<gt>{branchcode}> is the code of the branch where payment was
73 Amounts owed are paid off oldest first. That is, if the patron has a
74 $1 fine from Feb. 1, another $1 fine from Mar. 1, and makes a payment
75 of $1.50, then the oldest fine will be paid off in full, and $0.50
76 will be credited to the next one.
81 #here we update both the accountoffsets and the account lines
82 my ($env,$bornumber,$data)=@_;
83 my $dbh = C4::Context->dbh;
86 my $branch=$env->{'branchcode'};
87 my $amountleft = $data;
89 my $nextaccntno = getnextacctno($env,$bornumber,$dbh);
90 # get lines with outstanding amounts to offset
91 my $sth = $dbh->prepare("select * from accountlines
92 where (borrowernumber = ?) and (amountoutstanding<>0)
94 $sth->execute($bornumber);
96 while (($accdata=$sth->fetchrow_hashref) and ($amountleft>0)){
97 if ($accdata->{'amountoutstanding'} < $amountleft) {
99 $amountleft -= $accdata->{'amountoutstanding'};
101 $newamtos = $accdata->{'amountoutstanding'} - $amountleft;
104 my $thisacct = $accdata->{accountno};
105 my $usth = $dbh->prepare("update accountlines set amountoutstanding= ?
106 where (borrowernumber = ?) and (accountno=?)");
107 $usth->execute($newamtos,$bornumber,$thisacct);
109 $usth = $dbh->prepare("insert into accountoffsets
110 (borrowernumber, accountno, offsetaccount, offsetamount)
112 $usth->execute($bornumber,$accdata->{'accountno'},$nextaccntno,$newamtos);
116 my $usth = $dbh->prepare("insert into accountlines
117 (borrowernumber, accountno,date,amount,description,accounttype,amountoutstanding)
118 values (?,?,now(),?,'Payment,thanks','Pay',?)");
119 $usth->execute($bornumber,$nextaccntno,0-$data,0-$amountleft);
121 UpdateStats($env,$branch,'payment',$data,'','','',$bornumber);
127 &makepayment($borrowernumber, $acctnumber, $amount, $branchcode);
129 Records the fact that a patron has paid off the entire amount he or
132 C<$borrowernumber> is the patron's borrower number. C<$acctnumber> is
133 the account that was credited. C<$amount> is the amount paid (this is
134 only used to record the payment. It is assumed to be equal to the
135 amount owed). C<$branchcode> is the code of the branch where payment
140 # FIXME - I'm not at all sure about the above, because I don't
141 # understand what the acct* tables in the Koha database are for.
143 #here we update both the accountoffsets and the account lines
144 #updated to check, if they are paying off a lost item, we return the item
145 # from their card, and put a note on the item record
146 my ($bornumber,$accountno,$amount,$user)=@_;
148 my $dbh = C4::Context->dbh;
150 my $nextaccntno = getnextacctno($env,$bornumber,$dbh);
152 my $sth=$dbh->prepare("Select * from accountlines where borrowernumber=? and accountno=?");
153 $sth->execute($bornumber,$accountno);
154 my $data=$sth->fetchrow_hashref;
159 SET amountoutstanding = 0
160 WHERE borrowernumber = $bornumber
161 AND accountno = $accountno
166 INSERT INTO accountoffsets
167 (borrowernumber, accountno, offsetaccount,
169 VALUES ($bornumber, $accountno, $nextaccntno, $newamtos)
173 my $payment=0-$amount;
175 INSERT INTO accountlines
176 (borrowernumber, accountno, date, amount,
177 description, accounttype, amountoutstanding)
178 VALUES ($bornumber, $nextaccntno, now(), $payment,
179 'Payment,thanks - $user', 'Pay', 0)
182 # FIXME - The second argument to &UpdateStats is supposed to be the
184 UpdateStats($env,$user,'payment',$amount,'','','',$bornumber);
186 #check to see what accounttype
187 if ($data->{'accounttype'} eq 'Rep' || $data->{'accounttype'} eq 'L'){
188 returnlost($bornumber,$data->{'itemnumber'});
194 $nextacct = &getnextacctno($env, $borrowernumber, $dbh);
196 Returns the next unused account number for the patron with the given
199 C<$dbh> is a DBI::db handle to the Koha database.
205 # FIXME - Okay, so what does the above actually _mean_?
207 my ($env,$bornumber,$dbh)=@_;
209 my $sth = $dbh->prepare("select * from accountlines
210 where (borrowernumber = ?)
211 order by accountno desc");
212 $sth->execute($bornumber);
213 if (my $accdata=$sth->fetchrow_hashref){
214 $nextaccntno = $accdata->{'accountno'} + 1;
217 return($nextaccntno);
222 &fixaccounts($borrowernumber, $accountnumber, $amount);
226 # FIXME - I don't understand what this function does.
228 my ($borrowernumber,$accountno,$amount)=@_;
229 my $dbh = C4::Context->dbh;
230 my $sth=$dbh->prepare("Select * from accountlines where borrowernumber=?
232 $sth->execute($borrowernumber,$accountno);
233 my $data=$sth->fetchrow_hashref;
234 # FIXME - Error-checking
235 my $diff=$amount-$data->{'amount'};
236 my $outstanding=$data->{'amountoutstanding'}+$diff;
241 SET amount = '$amount',
242 amountoutstanding = '$outstanding'
243 WHERE borrowernumber = $borrowernumber
244 AND accountno = $accountno
248 # FIXME - Never used, but not exported, either.
250 my ($borrnum,$itemnum)=@_;
251 my $dbh = C4::Context->dbh;
252 my $borrower=borrdata('',$borrnum); #from C4::Search;
253 my $sth=$dbh->prepare("Update issues set returndate=now() where
254 borrowernumber=? and itemnumber=? and returndate is null");
255 $sth->execute($borrnum,$itemnum);
257 my @datearr = localtime(time);
258 my $date = (1900+$datearr[5])."-".($datearr[4]+1)."-".$datearr[3];
259 my $bor="$borrower->{'firstname'} $borrower->{'surname'} $borrower->{'cardnumber'}";
260 $sth=$dbh->prepare("Update items set paidfor=? where itemnumber=?");
261 $sth->execute("Paid for by $bor $date",$itemnum);
267 &manualinvoice($borrowernumber, $itemnumber, $description, $type,
270 C<$borrowernumber> is the patron's borrower number.
271 C<$description> is a description of the transaction.
272 C<$type> may be one of C<CS>, C<CB>, C<CW>, C<CF>, C<CL>, C<N>, C<L>,
274 C<$itemnumber> is the item involved, if pertinent; otherwise, it
275 should be the empty string.
279 # FIXME - Okay, so what does this function do, really?
281 my ($bornum,$itemnum,$desc,$type,$amount,$user)=@_;
282 my $dbh = C4::Context->dbh;
286 my $accountno=getnextacctno('',$bornum,$dbh);
287 my $amountleft=$amount;
289 if ($type eq 'CS' || $type eq 'CB' || $type eq 'CW'
290 || $type eq 'CF' || $type eq 'CL'){
291 my $amount2=$amount*-1; # FIXME - $amount2 = -$amount
292 $amountleft=fixcredit(\%env,$bornum,$amount2,$itemnum,$type,$user);
297 if ($type eq 'L' && $desc eq ''){
301 $amountleft=refund('',$bornum,$amount);
304 #FIXME to use ? before uncommenting
305 # my $sth=$dbh->prepare("Select * from items where barcode='$itemnum'");
307 # my $data=$sth->fetchrow_hashref;
310 my $sth=$dbh->prepare("INSERT INTO accountlines
311 (borrowernumber, accountno, date, amount, description, accounttype, amountoutstanding, itemnumber)
312 VALUES (?, ?, now(), ?,?, ?,?,?)");
313 # $sth->execute($bornum, $accountno, $amount, $desc, $type, $amountleft, $data->{'itemnumber'});
314 $sth->execute($bornum, $accountno, $amount, $desc, $type, $amountleft, $itemnum);
316 $desc=$dbh->quote($desc);
317 my $sth=$dbh->prepare("INSERT INTO accountlines
318 (borrowernumber, accountno, date, amount, description, accounttype, amountoutstanding)
319 VALUES (?, ?, now(), ?, ?, ?, ?)");
320 $sth->execute($bornum, $accountno, $amount, $desc, $type, $amountleft);
325 # $amountleft = &fixcredit($env, $bornumber, $data, $barcode, $type, $user);
327 # This function is only used internally.
328 # FIXME - Figure out what this function does, and write it down.
330 #here we update both the accountoffsets and the account lines
331 my ($env,$bornumber,$data,$barcode,$type,$user)=@_;
332 my $dbh = C4::Context->dbh;
335 my $amountleft = $data;
337 my $item=getiteminformation($env,'',$barcode);
338 my $nextaccntno = getnextacctno($env,$bornumber,$dbh);
339 my $query="Select * from accountlines where (borrowernumber=?
340 and itemnumber=? and amountoutstanding > 0)";
342 $query.=" and (accounttype = 'L' or accounttype = 'Rep')";
343 } elsif ($type eq 'CF'){
344 $query.=" and (accounttype = 'F' or accounttype = 'FU' or
345 accounttype='Res' or accounttype='Rent')";
346 } elsif ($type eq 'CB'){
347 $query.=" and accounttype='A'";
350 my $sth=$dbh->prepare($query);
351 $sth->execute($bornumber,$item->{'itemnumber'});
352 $accdata=$sth->fetchrow_hashref;
354 if ($accdata->{'amountoutstanding'} < $amountleft) {
356 $amountleft -= $accdata->{'amountoutstanding'};
358 $newamtos = $accdata->{'amountoutstanding'} - $amountleft;
361 my $thisacct = $accdata->{accountno};
362 my $usth = $dbh->prepare("update accountlines set amountoutstanding= ?
363 where (borrowernumber = ?) and (accountno=?)");
364 $usth->execute($newamtos,$bornumber,$thisacct);
366 $usth = $dbh->prepare("insert into accountoffsets
367 (borrowernumber, accountno, offsetaccount, offsetamount)
369 $usth->execute($bornumber,$accdata->{'accountno'},$nextaccntno,$newamtos);
373 my $nextaccntno = getnextacctno($env,$bornumber,$dbh);
374 # get lines with outstanding amounts to offset
375 my $sth = $dbh->prepare("select * from accountlines
376 where (borrowernumber = ?) and (amountoutstanding >0)
378 $sth->execute($bornumber);
380 # offset transactions
381 while (($accdata=$sth->fetchrow_hashref) and ($amountleft>0)){
382 if ($accdata->{'amountoutstanding'} < $amountleft) {
384 $amountleft -= $accdata->{'amountoutstanding'};
386 $newamtos = $accdata->{'amountoutstanding'} - $amountleft;
389 my $thisacct = $accdata->{accountno};
390 my $usth = $dbh->prepare("update accountlines set amountoutstanding= ?
391 where (borrowernumber = ?) and (accountno=?)");
392 $usth->execute($newamtos,$bornumber,$thisacct);
394 $usth = $dbh->prepare("insert into accountoffsets
395 (borrowernumber, accountno, offsetaccount, offsetamount)
397 $usth->execute($bornumber,$accdata->{'accountno'},$nextaccntno,$newamtos);
401 $env->{'branch'}=$user;
402 $type="Credit ".$type;
403 UpdateStats($env,$user,$type,$data,$user,'','',$bornumber);
409 # FIXME - Figure out what this function does, and write it down.
411 #here we update both the accountoffsets and the account lines
412 my ($env,$bornumber,$data)=@_;
413 my $dbh = C4::Context->dbh;
416 # my $branch=$env->{'branchcode'};
417 my $amountleft = $data *-1;
420 my $nextaccntno = getnextacctno($env,$bornumber,$dbh);
421 # get lines with outstanding amounts to offset
422 my $sth = $dbh->prepare("select * from accountlines
423 where (borrowernumber = ?) and (amountoutstanding<0)
425 $sth->execute($bornumber);
427 # offset transactions
428 while (($accdata=$sth->fetchrow_hashref) and ($amountleft<0)){
429 if ($accdata->{'amountoutstanding'} > $amountleft) {
431 $amountleft -= $accdata->{'amountoutstanding'};
433 $newamtos = $accdata->{'amountoutstanding'} - $amountleft;
437 my $thisacct = $accdata->{accountno};
438 my $usth = $dbh->prepare("update accountlines set amountoutstanding= ?
439 where (borrowernumber = ?) and (accountno=?)");
440 $usth->execute($newamtos,$bornumber,$thisacct);
442 $usth = $dbh->prepare("insert into accountoffsets
443 (borrowernumber, accountno, offsetaccount, offsetamount)
445 $usth->execute($bornumber,$accdata->{'accountno'},$nextaccntno,$newamtos);
452 END { } # module clean-up code here (global destructor)