X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=C4%2FAccounts.pm;h=6f5bc9187216331c26c9b18a6445166f373f00dd;hb=e1d907c688499de689ed613014261c761a0158c8;hp=83ae1a2d5a24be4256d44f4cf5866dc74974d86a;hpb=1e1929be43b3885d299026c260ff2dd0b04b0604;p=koha.git diff --git a/C4/Accounts.pm b/C4/Accounts.pm index 83ae1a2d5a..6f5bc91872 100755 --- a/C4/Accounts.pm +++ b/C4/Accounts.pm @@ -1,12 +1,4 @@ -package C4::Accounts; #assumes C4/Accounts - -# FIXME: This module uses the CDK modules, and crashes if called from a web script -# Hence the existence of Accounts2 -# -# This module will be deprecated when we build a new curses/slang/character -# based interface. - -# $Id$ +package C4::Accounts; # Copyright 2000-2002 Katipo Communications # @@ -25,19 +17,19 @@ package C4::Accounts; #assumes C4/Accounts # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place, # Suite 330, Boston, MA 02111-1307 USA +# $Id$ + use strict; require Exporter; -use DBI; use C4::Context; -use C4::Format; -use C4::Search; use C4::Stats; -#use C4::InterfaceCDK; -#use C4::Interface::AccountsCDK; +use C4::Members; +#use C4::Circulation; use vars qw($VERSION @ISA @EXPORT); # set the version for version checking -$VERSION = 0.01; +$VERSION = do { my @v = '$Revision$' =~ /\d+/g; +shift(@v) . "." . join("_", map {sprintf "%03d", $_ } @v); }; =head1 NAME @@ -45,7 +37,7 @@ C4::Accounts - Functions for dealing with Koha accounts =head1 SYNOPSIS - use C4::Accounts; +use C4::Accounts; =head1 DESCRIPTION @@ -55,196 +47,428 @@ patron. =head1 FUNCTIONS -=over 2 - =cut @ISA = qw(Exporter); -@EXPORT = qw(&checkaccount &reconcileaccount &getnextacctno); +@EXPORT = qw(&recordpayment &fixaccounts &makepayment &manualinvoice +&getnextacctno &reconcileaccount); -=item checkaccount - $owed = &checkaccount($env, $borrowernumber, $dbh, $date); +=head2 recordpayment -Looks up the total amount of money owed by a borrower (fines, etc.). + &recordpayment($borrowernumber, $payment); -C<$borrowernumber> specifies the borrower to look up. +Record payment by a patron. C<$borrowernumber> is the patron's +borrower number. C<$payment> is a floating-point number, giving the +amount that was paid. -C<$dbh> is a DBI::db handle for the Koha database. - -C<$env> is ignored. +Amounts owed are paid off oldest first. That is, if the patron has a +$1 fine from Feb. 1, another $1 fine from Mar. 1, and makes a payment +of $1.50, then the oldest fine will be paid off in full, and $0.50 +will be credited to the next one. =cut -#' -sub checkaccount { - #take borrower number - #check accounts and list amounts owing - my ($env,$bornumber,$dbh,$date)=@_; - my $select="SELECT SUM(amountoutstanding) AS total - FROM accountlines - WHERE borrowernumber = ? - AND amountoutstanding<>0"; - my @bind = ($bornumber); - if ($date && $date ne ''){ - $select.=" AND date < ?"; - push(@bind,$date); - } - # print $select; - my $sth=$dbh->prepare($select); - $sth->execute(@bind); - my $data=$sth->fetchrow_hashref; - my $total = $data->{'total'}; - $sth->finish; - # output(1,2,"borrower owes $total"); - #if ($total > 0){ - # # output(1,2,"borrower owes $total"); - # if ($total > 5){ - # reconcileaccount($env,$dbh,$bornumber,$total); - # } - #} - # pause(); - return($total); -} - -# XXX - POD. Need to figure out C4/Interface/AccountsCDK.pm first, -# though -# FIXME - It looks as though this function really wants to be part of -# a curses-based script. -sub reconcileaccount { - #print put money owing give person opportunity to pay it off - my ($env,$dummy,$bornumber,$total)=@_; - my $dbh = C4::Context->dbh; - #get borrower record - my $sth=$dbh->prepare("select * from borrowers - where borrowernumber=$bornumber"); - $sth->execute; - my $borrower=$sth->fetchrow_hashref; - $sth->finish(); - #get borrower information - $sth=$dbh->prepare("Select * from accountlines where - borrowernumber=$bornumber and amountoutstanding<>0 order by date"); - $sth->execute; - #display account information - &clearscreen(); - #&helptext('F11 quits'); - output(20,0,"Accounts"); - my @accountlines; - my $row=4; - my $i=0; - my $text; - #output (1,2,"Account Info"); - #output (1,3,"Item\tDate \tAmount\tDescription"); - while (my $data=$sth->fetchrow_hashref){ - my $line=$i+1; - my $amount=0+$data->{'amountoutstanding'}; - my $itemdata = itemnodata($env,$dbh,$data->{'itemnumber'}); - $line= $data->{'accountno'}." ".$data->{'date'}." ".$data->{'accounttype'}." "; - my $title = $itemdata->{'title'}; - if (length($title) > 15 ) {$title = substr($title,0,15);} - $line .= $itemdata->{'barcode'}." $title ".$data->{'description'}; - $line = fmtstr($env,$line,"L65")." ".fmtdec($env,$amount,"52"); - push @accountlines,$line; - $i++; - } - #get amount paid and update database - my ($data,$reason)= - &accountsdialog($env,"Payment Entry",$borrower,\@accountlines,$total); - if ($data>0) { - &recordpayment($env,$bornumber,$dbh,$data); - #Check if the borrower still owes - $total=&checkaccount($env,$bornumber,$dbh); - } - return($total); - -} -# FIXME - This function is never used. Then again, it's not exported, -# either. +#' sub recordpayment{ #here we update both the accountoffsets and the account lines - my ($env,$bornumber,$dbh,$data)=@_; + my ($borrowernumber,$data)=@_; + my $dbh = C4::Context->dbh; my $newamtos = 0; my $accdata = ""; + my $branch=C4::Context->userenv->{'branch'}; my $amountleft = $data; # begin transaction -# my $sth = $dbh->prepare("begin"); -# $sth->execute; - my $nextaccntno = getnextacctno($env,$bornumber,$dbh); + my $nextaccntno = getnextacctno($borrowernumber); # get lines with outstanding amounts to offset - my $sth = $dbh->prepare("select * from accountlines - where (borrowernumber = ?) and (amountoutstanding<>0) - order by date"); - $sth->execute($bornumber); + my $sth = $dbh->prepare("SELECT * FROM accountlines + WHERE (borrowernumber = ?) AND (amountoutstanding<>0) + ORDER BY date"); + $sth->execute($borrowernumber); # offset transactions while (($accdata=$sth->fetchrow_hashref) and ($amountleft>0)){ if ($accdata->{'amountoutstanding'} < $amountleft) { $newamtos = 0; - $amountleft -= $accdata->{'amountoutstanding'}; + $amountleft -= $accdata->{'amountoutstanding'}; } else { $newamtos = $accdata->{'amountoutstanding'} - $amountleft; - $amountleft = 0; + $amountleft = 0; } my $thisacct = $accdata->{accountno}; - my $usth = $dbh->prepare("update accountlines set amountoutstanding= ? - where (borrowernumber = ?) and (accountno=?)"); - $usth->execute($newamtos,$bornumber,$thisacct); + my $usth = $dbh->prepare("UPDATE accountlines SET amountoutstanding= ? + WHERE (borrowernumber = ?) AND (accountno=?)"); + $usth->execute($newamtos,$borrowernumber,$thisacct); $usth->finish; - - $usth = $dbh->prepare("insert into accountoffsets + $usth = $dbh->prepare("INSERT INTO accountoffsets (borrowernumber, accountno, offsetaccount, offsetamount) - values (?,?,?,?)"); -# print $updquery - $usth->execute($bornumber,$accdata->{'accountno'},$nextaccntno,$newamtos); + VALUES (?,?,?,?)"); + $usth->execute($borrowernumber,$accdata->{'accountno'},$nextaccntno,$newamtos); $usth->finish; } # create new line - #$updquery = "insert into accountlines (borrowernumber, - #accountno,date,amount,description,accounttype,amountoutstanding) values - #($bornumber,$nextaccntno,datetime('now'::abstime),0-$data,'Payment,thanks', - #'Pay',0-$amountleft)"; - my $usth = $dbh->prepare("insert into accountlines + my $usth = $dbh->prepare("INSERT INTO accountlines (borrowernumber, accountno,date,amount,description,accounttype,amountoutstanding) - values (?,?,now(),?,?,'Payment,thanks','Pay')"); - $usth->execute($bornumber,$nextaccntno,0-$data,0-$amountleft); + VALUES (?,?,now(),?,'Payment,thanks','Pay',?)"); + $usth->execute($borrowernumber,$nextaccntno,0-$data,0-$amountleft); $usth->finish; - UpdateStats($env,'branch','payment',$data) + UpdateStats($branch,'payment',$data,'','','',$borrowernumber); + $sth->finish; } -=item getnextacctno +=head2 makepayment - $nextacct = &getnextacctno($env, $borrowernumber, $dbh); + &makepayment($borrowernumber, $acctnumber, $amount, $branchcode); -Returns the next unused account number for the patron with the given -borrower number. +Records the fact that a patron has paid off the entire amount he or +she owes. -C<$dbh> is a DBI::db handle to the Koha database. +C<$borrowernumber> is the patron's borrower number. C<$acctnumber> is +the account that was credited. C<$amount> is the amount paid (this is +only used to record the payment. It is assumed to be equal to the +amount owed). C<$branchcode> is the code of the branch where payment +was made. -C<$env> is ignored. +=cut + +#' +# FIXME - I'm not at all sure about the above, because I don't +# understand what the acct* tables in the Koha database are for. +sub makepayment{ + #here we update both the accountoffsets and the account lines + #updated to check, if they are paying off a lost item, we return the item + # from their card, and put a note on the item record + my ($borrowernumber,$accountno,$amount,$user,$branch)=@_; + my $dbh = C4::Context->dbh; + # begin transaction + my $nextaccntno = getnextacctno($borrowernumber); + my $newamtos=0; + my $sth=$dbh->prepare("SELECT * FROM accountlines WHERE borrowernumber=? AND accountno=?"); + $sth->execute($borrowernumber,$accountno); + my $data=$sth->fetchrow_hashref; + $sth->finish; + + $dbh->do("UPDATE accountlines + SET amountoutstanding = 0 + WHERE borrowernumber = $borrowernumber + AND accountno = $accountno + "); + +# print $updquery; + $dbh->do(" + INSERT INTO accountoffsets + (borrowernumber, accountno, offsetaccount, + offsetamount) + VALUES ($borrowernumber, $accountno, $nextaccntno, $newamtos) + "); + + # create new line + my $payment=0-$amount; + $dbh->do(" + INSERT INTO accountlines + (borrowernumber, accountno, date, amount, + description, accounttype, amountoutstanding) + VALUES ($borrowernumber, $nextaccntno, now(), $payment, + 'Payment,thanks - $user', 'Pay', 0) + "); + + # FIXME - The second argument to &UpdateStats is supposed to be the + # branch code. + # UpdateStats is now being passed $accountno too. MTJ + UpdateStats($user,'payment',$amount,'','','',$borrowernumber,$accountno); + $sth->finish; + #check to see what accounttype + if ($data->{'accounttype'} eq 'Rep' || $data->{'accounttype'} eq 'L'){ + returnlost($borrowernumber,$data->{'itemnumber'}); + } +} + +=head2 getnextacctno + + $nextacct = &getnextacctno($borrowernumber); + +Returns the next unused account number for the patron with the given +borrower number. =cut + +#' # FIXME - Okay, so what does the above actually _mean_? sub getnextacctno { - my ($env,$bornumber,$dbh)=@_; + my ($borrowernumber)=@_; my $nextaccntno = 1; - - my $sth = $dbh->prepare("select max(accountno)+1 from accountlines"); - $sth->execute; + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare("SELECT * FROM accountlines + WHERE (borrowernumber = ?) + ORDER BY accountno DESC"); + $sth->execute($borrowernumber); if (my $accdata=$sth->fetchrow_hashref){ $nextaccntno = $accdata->{'accountno'} + 1; } $sth->finish; - return$nextaccntno; + return($nextaccntno); +} + +=head2 fixaccounts + + &fixaccounts($borrowernumber, $accountnumber, $amount); + +=cut + +#' +# FIXME - I don't understand what this function does. +sub fixaccounts { + my ($borrowernumber,$accountno,$amount)=@_; + my $dbh = C4::Context->dbh; + my $sth=$dbh->prepare("SELECT * FROM accountlines WHERE borrowernumber=? + AND accountno=?"); + $sth->execute($borrowernumber,$accountno); + my $data=$sth->fetchrow_hashref; + # FIXME - Error-checking + my $diff=$amount-$data->{'amount'}; + my $outstanding=$data->{'amountoutstanding'}+$diff; + $sth->finish; + + $dbh->do(<dbh; + my $borrower=GetMember($borrowernumber,'borrowernumber'); + my $sth=$dbh->prepare("UPDATE issues SET returndate=now() WHERE + borrowernumber=? AND itemnumber=? AND returndate IS NULL"); + $sth->execute($borrowernumber,$itemnum); + $sth->finish; + my @datearr = localtime(time); + my $date = (1900+$datearr[5])."-".($datearr[4]+1)."-".$datearr[3]; + my $bor="$borrower->{'firstname'} $borrower->{'surname'} $borrower->{'cardnumber'}"; + $sth=$dbh->prepare("UPDATE items SET paidfor=? WHERE itemnumber=?"); + $sth->execute("Paid for by $bor $date",$itemnum); + $sth->finish; +} + +=head2 manualinvoice + + &manualinvoice($borrowernumber, $itemnumber, $description, $type, + $amount, $user); + +C<$borrowernumber> is the patron's borrower number. +C<$description> is a description of the transaction. +C<$type> may be one of C, C, C, C, C, C, C, +or C. +C<$itemnumber> is the item involved, if pertinent; otherwise, it +should be the empty string. + +=cut + +#' +# FIXME - Okay, so what does this function do, really? +sub manualinvoice{ + my ($borrowernumber,$itemnum,$desc,$type,$amount,$user)=@_; + my $dbh = C4::Context->dbh; + my $notifyid; + my $insert; + $itemnum=~ s/ //g; + my $accountno=getnextacctno($borrowernumber); + my $amountleft=$amount; + + if ($type eq 'CS' || $type eq 'CB' || $type eq 'CW' + || $type eq 'CF' || $type eq 'CL'){ + my $amount2=$amount*-1; # FIXME - $amount2 = -$amount + $amountleft=fixcredit($borrowernumber,$amount2,$itemnum,$type,$user); + } + if ($type eq 'N'){ + $desc.="New Card"; + } + if ($type eq 'F'){ + $desc.="Fine"; + } + if ($type eq 'A'){ + $desc.="Account Management fee"; + } + if ($type eq 'M'){ + $desc.="Sundry"; + } + + if ($type eq 'L' && $desc eq ''){ + + $desc="Lost Item"; + } + if ($type eq 'REF'){ + $desc.="Cash Refund"; + $amountleft=refund('',$borrowernumber,$amount); + } + if(($type eq 'L') or ($type eq 'F') or ($type eq 'A') or ($type eq 'N') or ($type eq 'M') ){ + $notifyid=1; + } + + if ($itemnum ne ''){ + $desc.=" ".$itemnum; + my $sth=$dbh->prepare("INSERT INTO accountlines + (borrowernumber, accountno, date, amount, description, accounttype, amountoutstanding, itemnumber,notify_id) + VALUES (?, ?, now(), ?,?, ?,?,?,?)"); +# $sth->execute($borrowernumber, $accountno, $amount, $desc, $type, $amountleft, $data->{'itemnumber'}); + $sth->execute($borrowernumber, $accountno, $amount, $desc, $type, $amountleft, $itemnum,$notifyid); + } else { + my $sth=$dbh->prepare("INSERT INTO accountlines + (borrowernumber, accountno, date, amount, description, accounttype, amountoutstanding,notify_id) + VALUES (?, ?, now(), ?, ?, ?, ?,?)"); + $sth->execute($borrowernumber, $accountno, $amount, $desc, $type, $amountleft,$notifyid); + } +} + +=head2 fixcredit + + $amountleft = &fixcredit($borrowernumber, $data, $barcode, $type, $user); + + This function is only used internally, not exported. + FIXME - Figure out what this function does, and write it down. + +=cut + +sub fixcredit{ + #here we update both the accountoffsets and the account lines + my ($borrowernumber,$data,$barcode,$type,$user)=@_; + my $dbh = C4::Context->dbh; + my $newamtos = 0; + my $accdata = ""; + my $amountleft = $data; + if ($barcode ne ''){ + my $item=GetBiblioFromItemNumber('',$barcode); + my $nextaccntno = getnextacctno($borrowernumber); + my $query="SELECT * FROM accountlines WHERE (borrowernumber=? + AND itemnumber=? AND amountoutstanding > 0)"; + if ($type eq 'CL'){ + $query.=" AND (accounttype = 'L' OR accounttype = 'Rep')"; + } elsif ($type eq 'CF'){ + $query.=" AND (accounttype = 'F' OR accounttype = 'FU' OR + accounttype='Res' OR accounttype='Rent')"; + } elsif ($type eq 'CB'){ + $query.=" and accounttype='A'"; + } +# print $query; + my $sth=$dbh->prepare($query); + $sth->execute($borrowernumber,$item->{'itemnumber'}); + $accdata=$sth->fetchrow_hashref; + $sth->finish; + if ($accdata->{'amountoutstanding'} < $amountleft) { + $newamtos = 0; + $amountleft -= $accdata->{'amountoutstanding'}; + } else { + $newamtos = $accdata->{'amountoutstanding'} - $amountleft; + $amountleft = 0; + } + my $thisacct = $accdata->{accountno}; + my $usth = $dbh->prepare("UPDATE accountlines SET amountoutstanding= ? + WHERE (borrowernumber = ?) AND (accountno=?)"); + $usth->execute($newamtos,$borrowernumber,$thisacct); + $usth->finish; + $usth = $dbh->prepare("INSERT INTO accountoffsets + (borrowernumber, accountno, offsetaccount, offsetamount) + VALUES (?,?,?,?)"); + $usth->execute($borrowernumber,$accdata->{'accountno'},$nextaccntno,$newamtos); + $usth->finish; + } + # begin transaction + my $nextaccntno = getnextacctno($borrowernumber); + # get lines with outstanding amounts to offset + my $sth = $dbh->prepare("SELECT * FROM accountlines + WHERE (borrowernumber = ?) AND (amountoutstanding >0) + ORDER BY date"); + $sth->execute($borrowernumber); +# print $query; + # offset transactions + while (($accdata=$sth->fetchrow_hashref) and ($amountleft>0)){ + if ($accdata->{'amountoutstanding'} < $amountleft) { + $newamtos = 0; + $amountleft -= $accdata->{'amountoutstanding'}; + } else { + $newamtos = $accdata->{'amountoutstanding'} - $amountleft; + $amountleft = 0; + } + my $thisacct = $accdata->{accountno}; + my $usth = $dbh->prepare("UPDATE accountlines SET amountoutstanding= ? + WHERE (borrowernumber = ?) AND (accountno=?)"); + $usth->execute($newamtos,$borrowernumber,$thisacct); + $usth->finish; + $usth = $dbh->prepare("INSERT INTO accountoffsets + (borrowernumber, accountno, offsetaccount, offsetamount) + VALUE (?,?,?,?)"); + $usth->execute($borrowernumber,$accdata->{'accountno'},$nextaccntno,$newamtos); + $usth->finish; + } + $sth->finish; + $type="Credit ".$type; + UpdateStats($user,$type,$data,$user,'','',$borrowernumber); + $amountleft*=-1; + return($amountleft); + } +=head2 refund + +# FIXME - Figure out what this function does, and write it down. + +=cut + +sub refund{ + #here we update both the accountoffsets and the account lines + my ($borrowernumber,$data)=@_; + my $dbh = C4::Context->dbh; + my $newamtos = 0; + my $accdata = ""; + my $amountleft = $data *-1; + + # begin transaction + my $nextaccntno = getnextacctno($borrowernumber); + # get lines with outstanding amounts to offset + my $sth = $dbh->prepare("SELECT * FROM accountlines + WHERE (borrowernumber = ?) AND (amountoutstanding<0) + ORDER BY date"); + $sth->execute($borrowernumber); +# print $amountleft; + # offset transactions + while (($accdata=$sth->fetchrow_hashref) and ($amountleft<0)){ + if ($accdata->{'amountoutstanding'} > $amountleft) { + $newamtos = 0; + $amountleft -= $accdata->{'amountoutstanding'}; + } else { + $newamtos = $accdata->{'amountoutstanding'} - $amountleft; + $amountleft = 0; + } +# print $amountleft; + my $thisacct = $accdata->{accountno}; + my $usth = $dbh->prepare("UPDATE accountlines SET amountoutstanding= ? + WHERE (borrowernumber = ?) AND (accountno=?)"); + $usth->execute($newamtos,$borrowernumber,$thisacct); + $usth->finish; + $usth = $dbh->prepare("INSERT INTO accountoffsets + (borrowernumber, accountno, offsetaccount, offsetamount) + VALUES (?,?,?,?)"); + $usth->execute($borrowernumber,$accdata->{'accountno'},$nextaccntno,$newamtos); + $usth->finish; + } + $sth->finish; + return($amountleft); +} + + END { } # module clean-up code here (global destructor) 1; __END__ -=back =head1 SEE ALSO -C4::Accounts2(3), DBI(3) +DBI(3) =cut +