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);
305 my $sth=$dbh->prepare("INSERT INTO accountlines
306 (borrowernumber, accountno, date, amount, description, accounttype, amountoutstanding, itemnumber)
307 VALUES (?, ?, now(), ?,?, ?,?,?)");
308 # $sth->execute($bornum, $accountno, $amount, $desc, $type, $amountleft, $data->{'itemnumber'});
309 $sth->execute($bornum, $accountno, $amount, $desc, $type, $amountleft, $itemnum);
311 my $sth=$dbh->prepare("INSERT INTO accountlines
312 (borrowernumber, accountno, date, amount, description, accounttype, amountoutstanding)
313 VALUES (?, ?, now(), ?, ?, ?, ?)");
314 $sth->execute($bornum, $accountno, $amount, $desc, $type, $amountleft);
319 # $amountleft = &fixcredit($env, $bornumber, $data, $barcode, $type, $user);
321 # This function is only used internally.
322 # FIXME - Figure out what this function does, and write it down.
324 #here we update both the accountoffsets and the account lines
325 my ($env,$bornumber,$data,$barcode,$type,$user)=@_;
326 my $dbh = C4::Context->dbh;
329 my $amountleft = $data;
331 my $item=getiteminformation($env,'',$barcode);
332 my $nextaccntno = getnextacctno($env,$bornumber,$dbh);
333 my $query="Select * from accountlines where (borrowernumber=?
334 and itemnumber=? and amountoutstanding > 0)";
336 $query.=" and (accounttype = 'L' or accounttype = 'Rep')";
337 } elsif ($type eq 'CF'){
338 $query.=" and (accounttype = 'F' or accounttype = 'FU' or
339 accounttype='Res' or accounttype='Rent')";
340 } elsif ($type eq 'CB'){
341 $query.=" and accounttype='A'";
344 my $sth=$dbh->prepare($query);
345 $sth->execute($bornumber,$item->{'itemnumber'});
346 $accdata=$sth->fetchrow_hashref;
348 if ($accdata->{'amountoutstanding'} < $amountleft) {
350 $amountleft -= $accdata->{'amountoutstanding'};
352 $newamtos = $accdata->{'amountoutstanding'} - $amountleft;
355 my $thisacct = $accdata->{accountno};
356 my $usth = $dbh->prepare("update accountlines set amountoutstanding= ?
357 where (borrowernumber = ?) and (accountno=?)");
358 $usth->execute($newamtos,$bornumber,$thisacct);
360 $usth = $dbh->prepare("insert into accountoffsets
361 (borrowernumber, accountno, offsetaccount, offsetamount)
363 $usth->execute($bornumber,$accdata->{'accountno'},$nextaccntno,$newamtos);
367 my $nextaccntno = getnextacctno($env,$bornumber,$dbh);
368 # get lines with outstanding amounts to offset
369 my $sth = $dbh->prepare("select * from accountlines
370 where (borrowernumber = ?) and (amountoutstanding >0)
372 $sth->execute($bornumber);
374 # offset transactions
375 while (($accdata=$sth->fetchrow_hashref) and ($amountleft>0)){
376 if ($accdata->{'amountoutstanding'} < $amountleft) {
378 $amountleft -= $accdata->{'amountoutstanding'};
380 $newamtos = $accdata->{'amountoutstanding'} - $amountleft;
383 my $thisacct = $accdata->{accountno};
384 my $usth = $dbh->prepare("update accountlines set amountoutstanding= ?
385 where (borrowernumber = ?) and (accountno=?)");
386 $usth->execute($newamtos,$bornumber,$thisacct);
388 $usth = $dbh->prepare("insert into accountoffsets
389 (borrowernumber, accountno, offsetaccount, offsetamount)
391 $usth->execute($bornumber,$accdata->{'accountno'},$nextaccntno,$newamtos);
395 $env->{'branch'}=$user;
396 $type="Credit ".$type;
397 UpdateStats($env,$user,$type,$data,$user,'','',$bornumber);
403 # FIXME - Figure out what this function does, and write it down.
405 #here we update both the accountoffsets and the account lines
406 my ($env,$bornumber,$data)=@_;
407 my $dbh = C4::Context->dbh;
410 # my $branch=$env->{'branchcode'};
411 my $amountleft = $data *-1;
414 my $nextaccntno = getnextacctno($env,$bornumber,$dbh);
415 # get lines with outstanding amounts to offset
416 my $sth = $dbh->prepare("select * from accountlines
417 where (borrowernumber = ?) and (amountoutstanding<0)
419 $sth->execute($bornumber);
421 # offset transactions
422 while (($accdata=$sth->fetchrow_hashref) and ($amountleft<0)){
423 if ($accdata->{'amountoutstanding'} > $amountleft) {
425 $amountleft -= $accdata->{'amountoutstanding'};
427 $newamtos = $accdata->{'amountoutstanding'} - $amountleft;
431 my $thisacct = $accdata->{accountno};
432 my $usth = $dbh->prepare("update accountlines set amountoutstanding= ?
433 where (borrowernumber = ?) and (accountno=?)");
434 $usth->execute($newamtos,$bornumber,$thisacct);
436 $usth = $dbh->prepare("insert into accountoffsets
437 (borrowernumber, accountno, offsetaccount, offsetamount)
439 $usth->execute($bornumber,$accdata->{'accountno'},$nextaccntno,$newamtos);
446 END { } # module clean-up code here (global destructor)