HTL mod for till reconciliation.
[koha.git] / C4 / Accounts.pm
1 package C4::Accounts; #assumes C4/Accounts
2
3 # FIXME: This module uses the CDK modules, and crashes if called from a web script
4 # Hence the existence of Accounts2
5 #
6 # This module will be deprecated when we build a new curses/slang/character
7 # based interface.
8
9 # $Id$
10
11 # Copyright 2000-2002 Katipo Communications
12 #
13 # This file is part of Koha.
14 #
15 # Koha is free software; you can redistribute it and/or modify it under the
16 # terms of the GNU General Public License as published by the Free Software
17 # Foundation; either version 2 of the License, or (at your option) any later
18 # version.
19 #
20 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
21 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
22 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
23 #
24 # You should have received a copy of the GNU General Public License along with
25 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
26 # Suite 330, Boston, MA  02111-1307 USA
27
28 use strict;
29 require Exporter;
30 use DBI;
31 use C4::Context;
32 use C4::Format;
33 use C4::Search;
34 use C4::Stats;
35 #use C4::InterfaceCDK;
36 #use C4::Interface::AccountsCDK;
37 use vars qw($VERSION @ISA @EXPORT);
38
39 # set the version for version checking
40 $VERSION = 0.01;
41
42 =head1 NAME
43
44 C4::Accounts - Functions for dealing with Koha accounts
45
46 =head1 SYNOPSIS
47
48   use C4::Accounts;
49
50 =head1 DESCRIPTION
51
52 The functions in this module deal with the monetary aspect of Koha,
53 including looking up and modifying the amount of money owed by a
54 patron.
55
56 =head1 FUNCTIONS
57
58 =over 2
59
60 =cut
61
62 @ISA = qw(Exporter);
63 @EXPORT = qw(&checkaccount &reconcileaccount &getnextacctno);
64
65 =item checkaccount
66
67   $owed = &checkaccount($env, $borrowernumber, $dbh, $date);
68
69 Looks up the total amount of money owed by a borrower (fines, etc.).
70
71 C<$borrowernumber> specifies the borrower to look up.
72
73 C<$dbh> is a DBI::db handle for the Koha database.
74
75 C<$env> is ignored.
76
77 =cut
78 #'
79 sub checkaccount  {
80   #take borrower number
81   #check accounts and list amounts owing
82         my ($env,$bornumber,$dbh,$date)=@_;
83         my $select="SELECT SUM(amountoutstanding) AS total
84                         FROM accountlines
85                 WHERE borrowernumber = ?
86                         AND amountoutstanding<>0";
87         my @bind = ($bornumber);
88         if ($date && $date ne ''){
89         $select.=" AND date < ?";
90         push(@bind,$date);
91         }
92         #  print $select;
93         my $sth=$dbh->prepare($select);
94         $sth->execute(@bind);
95         my $data=$sth->fetchrow_hashref;
96         my $total = $data->{'total'};
97         $sth->finish;
98         # output(1,2,"borrower owes $total");
99         #if ($total > 0){
100         #  # output(1,2,"borrower owes $total");
101         #  if ($total > 5){
102         #    reconcileaccount($env,$dbh,$bornumber,$total);
103         #  }
104         #}
105         #  pause();
106         return($total);
107 }
108
109 # XXX - POD. Need to figure out C4/Interface/AccountsCDK.pm first,
110 # though
111 # FIXME - It looks as though this function really wants to be part of
112 # a curses-based script.
113 sub reconcileaccount {
114   #print put money owing give person opportunity to pay it off
115   my ($env,$dummy,$bornumber,$total)=@_;
116   my $dbh = C4::Context->dbh;
117   #get borrower record
118   my $sth=$dbh->prepare("select * from borrowers
119     where borrowernumber=$bornumber");
120   $sth->execute;
121   my $borrower=$sth->fetchrow_hashref;
122   $sth->finish();
123   #get borrower information
124   $sth=$dbh->prepare("Select * from accountlines where
125   borrowernumber=$bornumber and amountoutstanding<>0 order by date");
126   $sth->execute;
127   #display account information
128   &clearscreen();
129   #&helptext('F11 quits');
130   output(20,0,"Accounts");
131   my @accountlines;
132   my $row=4;
133   my $i=0;
134   my $text;
135   #output (1,2,"Account Info");
136   #output (1,3,"Item\tDate      \tAmount\tDescription");
137   while (my $data=$sth->fetchrow_hashref){
138     my $line=$i+1;
139     my $amount=0+$data->{'amountoutstanding'};
140     my $itemdata = itemnodata($env,$dbh,$data->{'itemnumber'});
141     $line= $data->{'accountno'}." ".$data->{'date'}." ".$data->{'accounttype'}." ";
142     my $title = $itemdata->{'title'};
143     if (length($title) > 15 ) {$title = substr($title,0,15);}
144     $line .= $itemdata->{'barcode'}." $title ".$data->{'description'};
145     $line = fmtstr($env,$line,"L65")." ".fmtdec($env,$amount,"52");
146     push @accountlines,$line;
147     $i++;
148   }
149   #get amount paid and update database
150   my ($data,$reason)=
151     &accountsdialog($env,"Payment Entry",$borrower,\@accountlines,$total);
152   if ($data>0) {
153     &recordpayment($env,$bornumber,$dbh,$data);
154     #Check if the borrower still owes
155     $total=&checkaccount($env,$bornumber,$dbh);
156   }
157   return($total);
158
159 }
160
161 # FIXME - This function is never used. Then again, it's not exported,
162 # either.
163 sub recordpayment{
164   #here we update both the accountoffsets and the account lines
165   my ($env,$bornumber,$dbh,$data)=@_;
166   my $newamtos = 0;
167   my $accdata = "";
168   my $amountleft = $data;
169   # begin transaction
170 #  my $sth = $dbh->prepare("begin");
171 #  $sth->execute;
172   my $nextaccntno = getnextacctno($env,$bornumber,$dbh);
173   # get lines with outstanding amounts to offset
174   my $sth = $dbh->prepare("select * from accountlines
175   where (borrowernumber = ?) and (amountoutstanding<>0)
176   order by date");
177   $sth->execute($bornumber);
178   # offset transactions
179   while (($accdata=$sth->fetchrow_hashref) and ($amountleft>0)){
180      if ($accdata->{'amountoutstanding'} < $amountleft) {
181         $newamtos = 0;
182         $amountleft -= $accdata->{'amountoutstanding'};
183      }  else {
184         $newamtos = $accdata->{'amountoutstanding'} - $amountleft;
185         $amountleft = 0;
186      }
187      my $thisacct = $accdata->{accountno};
188      my $usth = $dbh->prepare("update accountlines set amountoutstanding= ?
189      where (borrowernumber = ?) and (accountno=?)");
190      $usth->execute($newamtos,$bornumber,$thisacct);
191      $usth->finish;
192      
193      $usth = $dbh->prepare("insert into accountoffsets
194      (borrowernumber, accountno, offsetaccount,  offsetamount)
195      values (?,?,?,?)");
196 #     print $updquery
197      $usth->execute($bornumber,$accdata->{'accountno'},$nextaccntno,$newamtos);
198      $usth->finish;
199   }
200   # create new line
201   #$updquery = "insert into accountlines (borrowernumber,
202   #accountno,date,amount,description,accounttype,amountoutstanding) values
203   #($bornumber,$nextaccntno,datetime('now'::abstime),0-$data,'Payment,thanks',
204   #'Pay',0-$amountleft)";
205   my $usth = $dbh->prepare("insert into accountlines
206   (borrowernumber, accountno,date,amount,description,accounttype,amountoutstanding)
207   values (?,?,now(),?,?,'Payment,thanks','Pay')");
208   $usth->execute($bornumber,$nextaccntno,0-$data,0-$amountleft);
209   $usth->finish;
210   UpdateStats($env,'branch','payment',$data)
211 }
212
213 =item getnextacctno
214
215   $nextacct = &getnextacctno($env, $borrowernumber, $dbh);
216
217 Returns the next unused account number for the patron with the given
218 borrower number.
219
220 C<$dbh> is a DBI::db handle to the Koha database.
221
222 C<$env> is ignored.
223
224 =cut
225 # FIXME - Okay, so what does the above actually _mean_?
226 sub getnextacctno {
227   my ($env,$bornumber,$dbh)=@_;
228   my $nextaccntno = 1;
229   
230   my $sth = $dbh->prepare("select max(accountno)+1 from accountlines");
231   $sth->execute;
232   if (my $accdata=$sth->fetchrow_hashref){
233     $nextaccntno = $accdata->{'accountno'} + 1;
234   }
235   $sth->finish;
236   return$nextaccntno;
237 }
238
239 END { }       # module clean-up code here (global destructor)
240
241 1;
242 __END__
243
244 =back
245
246 =head1 SEE ALSO
247
248 C4::Accounts2(3), DBI(3)
249
250 =cut