Replaced expressions of the form "$x = $x <op> $y" with "$x <op>= $y".
[koha.git] / C4 / Circulation / Borrower.pm
1 package C4::Circulation::Borrower;
2
3 # $Id$
4
5 #package to deal with Issues
6 #written 3/11/99 by chris@katipo.co.nz
7
8
9 # Copyright 2000-2002 Katipo Communications
10 #
11 # This file is part of Koha.
12 #
13 # Koha is free software; you can redistribute it and/or modify it under the
14 # terms of the GNU General Public License as published by the Free Software
15 # Foundation; either version 2 of the License, or (at your option) any later
16 # version.
17 #
18 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
19 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
20 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
21 #
22 # You should have received a copy of the GNU General Public License along with
23 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
24 # Suite 330, Boston, MA  02111-1307 USA
25
26 # FIXME - This module is never used. Obsolete?
27
28 use strict;
29 require Exporter;
30 use DBI;
31 use C4::Context;
32 use C4::Accounts;
33 use C4::InterfaceCDK;
34 use C4::Interface::FlagsCDK;
35 use C4::Circulation::Main;
36         # FIXME - C4::Circulation::Main and C4::Circulation::Borrower
37         # use each other, so functions get redefined.
38 use C4::Circulation::Issues;
39         # FIXME - C4::Circulation::Issues and C4::Circulation::Borrower
40         # use each other, so functions get redefined.
41 use C4::Circulation::Renewals;
42 use C4::Scan;
43 use C4::Search;
44 use C4::Stats;
45 use C4::Format;
46 use vars qw($VERSION @ISA @EXPORT);
47
48 # set the version for version checking
49 $VERSION = 0.01;
50
51 @ISA = qw(Exporter);
52 @EXPORT = qw(&findborrower &Borenq &findoneborrower &NewBorrowerNumber
53 &findguarantees);
54
55 sub findborrower  {
56   my ($env,$dbh) = @_;
57   C4::InterfaceCDK::helptext('');       # FIXME - This looks useless
58   C4::InterfaceCDK::clearscreen();
59   my $bornum = "";
60   my $sth = "";
61   my $borcode = "";
62   my $borrower;
63   my $reason = "";
64   my $book;
65   while (($bornum eq '') && ($reason eq "")) {
66     #get borrowerbarcode from scanner
67     my $title = C4::InterfaceCDK::titlepanel($env,$env->{'sysarea'},"Borrower Entry");
68     if ($env->{'newborrower'} eq "") {
69       ($borcode,$reason,$book)=&C4::Circulation::Main::scanborrower($env);
70     } else {
71       $borcode = $env->{'newborrower'};
72       $reason = "";
73       $book = "";
74       $env->{'newborrower'}= "";
75     }
76     #C4::Circulation::Main
77     if ($reason eq "") {
78       if ($borcode ne '') {
79         ($bornum,$borrower) = findoneborrower($env,$dbh,$borcode);
80         $env->{'IssuesAllowed'} = 1;
81       } elsif ($book ne "") {
82         my $query = "select * from issues,items where (barcode = '$book')
83           and (items.itemnumber = issues.itemnumber)
84           and (issues.returndate is null)";
85         my $iss_sth=$dbh->prepare($query);
86         $iss_sth->execute;
87         if (my $issdata  = $iss_sth->fetchrow_hashref) {
88            $bornum=$issdata->{'borrowernumber'};
89            $sth = $dbh->prepare("Select * from borrowers
90              where borrowernumber =  '$bornum'");
91            $sth->execute;
92            $borrower=$sth->fetchrow_hashref;
93            $sth->finish;
94          } else {
95            error_msg($env,"Item $book not found");
96          }
97          $iss_sth->finish;
98       }
99     }
100   }
101   my ($issuesallowed,$owing);
102   if ($reason eq "") {
103     $env->{'bornum'} = $bornum;
104     $env->{'bcard'} = $borrower->{'cardnumber'};
105     my $borrowers=join(' ',($borrower->{'title'},$borrower->{'firstname'},$borrower->{'surname'}));
106     my $odues;
107     ($issuesallowed,$odues,$owing) = &checktraps($env,$dbh,$bornum,$borrower);
108 #    error_msg ($env,"bcard =  $env->{'bcard'}");
109   }
110   #debug_msg ($env,"2 =  $env->{'IssuesAllowed'}");
111   return ($bornum, $issuesallowed,$borrower,$reason,$owing);
112 };
113
114
115 sub findoneborrower {
116   #  output(1,1,$borcode);
117   my ($env,$dbh,$borcode)=@_;
118   my $bornum;
119   my $borrower;
120   my $ucborcode = uc $borcode;
121   my $lcborcode = lc $borcode;
122   my $sth=$dbh->prepare("Select * from borrowers where cardnumber=\"$ucborcode\"");
123   $sth->execute;
124   if ($borrower=$sth->fetchrow_hashref) {
125     $bornum=$borrower->{'borrowernumber'};
126     $sth->finish;
127   } else {
128     $sth->finish;
129     # my $borquery = "Select * from borrowers
130     # where surname ~* '$borcode' order by surname";
131
132     my $borquery = "Select * from borrowers
133       where lower(surname) like \"$lcborcode%\" order by surname,firstname";
134     my $sthb =$dbh->prepare($borquery);
135     $sthb->execute;
136     my $cntbor = 0;
137     my @borrows;
138     my @bornums;
139     while ($borrower= $sthb->fetchrow_hashref) {
140       my $line = $borrower->{'cardnumber'}.' '.$borrower->{'categorycode'}.' '.$borrower->{'surname'}.
141         ', '.$borrower->{'othernames'};
142       $borrows[$cntbor] = fmtstr($env,$line,"L50");
143       $bornums[$cntbor] =$borrower->{'borrowernumber'};
144       $cntbor++;
145     }
146     if ($cntbor == 1)  {
147       $bornum = $bornums[0];
148       my $query = "select * from borrowers where borrowernumber = '$bornum'";
149       $sth = $dbh->prepare($query);
150       $sth->execute;
151       $borrower =$sth->fetchrow_hashref;
152       $sth->finish;
153     } elsif ($cntbor > 0) {
154       my ($cardnum) = C4::InterfaceCDK::selborrower($env,$dbh,\@borrows,\@bornums);
155       my $query = "select * from borrowers where cardnumber = '$cardnum'";
156       $sth = $dbh->prepare($query);
157       $sth->execute;
158       $borrower =$sth->fetchrow_hashref;
159       $sth->finish;
160       $bornum=$borrower->{'borrowernumber'};
161       #C4::InterfaceCDK::clearscreen();
162       if ($bornum eq '') {
163         error_msg($env,"Borrower not found");
164       }
165     }
166   }
167   return ($bornum,$borrower);
168 }
169 sub checktraps {
170   my ($env,$dbh,$bornum,$borrower) = @_;
171   my $issuesallowed = "1";
172   #my @traps_set;
173   #check amountowing
174   my $traps_done;
175   my $odues;
176   my $amount;
177   while ($traps_done ne "DONE") {
178     my @traps_set;
179     $amount=C4::Accounts::checkaccount($env,$bornum,$dbh);    #from C4::Accounts
180     if ($amount > 0) { push (@traps_set,"CHARGES");}
181     if ($borrower->{'gonenoaddress'} == 1){ push (@traps_set,"GNA");}
182     #check if member has a card reported as lost
183     if ($borrower->{'lost'} ==1){push (@traps_set,"LOST");}
184     #check the notes field if notes exist display them
185     if ($borrower->{'borrowernotes'} ne ''){ push (@traps_set,"NOTES");}
186     #check if borrower has overdue items
187     #call overdue checker
188     my $odues = &C4::Circulation::Main::checkoverdues($env,$bornum,$dbh);
189     if ($odues > 0) {push (@traps_set,"ODUES");}
190     #check if borrower has any items waiting
191     my ($nowaiting,$itemswaiting) = &C4::Circulation::Main::checkwaiting($env,$dbh,$bornum);
192     if ($nowaiting > 0) { push (@traps_set,"WAITING"); }
193     # FIXME - This should be $traps_set[0], right?
194     if (@traps_set[0] ne "" ) {
195       ($issuesallowed,$traps_done,$amount,$odues) =
196          process_traps($env,$dbh,$bornum,$borrower,
197          $amount,$odues,\@traps_set,$itemswaiting);
198     } else {
199       $traps_done = "DONE";
200     }
201   }
202   return ($issuesallowed, $odues,$amount);
203 }
204
205 sub process_traps {
206   my ($env,$dbh,$bornum,$borrower,$amount,$odues,$traps_set,$waiting) = @_;
207   my $issuesallowed = 1;
208   my $x = 0;
209   my %traps;
210   while (@$traps_set[$x] ne "") {
211     $traps{@$traps_set[$x]} = 1;
212     $x++;
213   }
214   my $traps_done;
215   my $trapact;
216   my $issues;
217   while ($trapact ne "NONE") {
218     $trapact = &trapscreen($env,$bornum,$borrower,$amount,$traps_set);
219     if ($trapact eq "CHARGES") {
220       C4::Accounts::reconcileaccount($env,$dbh,$bornum,$amount,$borrower,$odues);
221       ($odues,$issues,$amount)=borrdata2($env,$bornum);
222       if ($amount <= 0) {
223         $traps{'CHARGES'} = 0;
224         my @newtraps;
225         $x =0;
226         while ($traps_set->[$x] ne "") {
227           if ($traps_set->[$x] ne "CHARGES") {
228             push @newtraps,$traps_set->[$x];
229           }
230           $x++;
231         }
232         $traps_set = \@newtraps;
233       }
234     } elsif ($trapact eq "WAITING") {
235       reserveslist($env,$borrower,$amount,$odues,$waiting);
236     } elsif ($trapact eq "ODUES") {
237       C4::Circulation::Renewals::bulkrenew($env,$dbh,$bornum,$amount,$borrower,$odues);
238       ($odues,$issues,$amount)=borrdata2($env,$bornum);
239       if ($odues == 0) {
240         $traps{'ODUES'} = 0;
241         my @newtraps;
242         $x =0;
243         while ($traps_set->[$x] ne "") {
244           if ($traps_set->[$x] ne "ODUES") {
245             push @newtraps,$traps_set->[$x];
246           }
247           $x++;
248         }
249         $traps_set = \@newtraps;
250       }
251     } elsif  ($trapact eq "NOTES") {
252       my $notes = trapsnotes($env,$bornum,$borrower,$amount);
253       if ($notes ne $borrower->{'borrowernotes'}) {
254         my $query = "update borrowers set borrowernotes = '$notes'
255            where borrowernumber = $bornum";
256         my $sth = $dbh->prepare($query);
257         $sth->execute();
258         $sth->finish();
259         $borrower->{'borrowernotes'} = $notes;
260       }
261       if ($notes eq "") {
262         $traps{'NOTES'} = 0;
263         my @newtraps;
264         $x =0;
265         while ($traps_set->[$x] ne "") {
266           if ($traps_set->[$x] ne "NOTES") {
267             push @newtraps,$traps_set->[$x];
268           }
269           $x++;
270         }
271         $traps_set = \@newtraps;
272       }
273     }
274     my $notr = @$traps_set;
275     if ($notr == 0) {
276       $trapact = "NONE";
277     }
278     $traps_done = "DONE";
279   }
280   if ($traps{'GNA'} eq 1 ) {
281     $issuesallowed=0;
282     $env->{'IssuesAllowed'} = 0;
283   }
284   if ($traps{'CHARGES'} eq 1) {
285     if ($amount > 5) {
286       $env->{'IssuesAllowed'} = 0;
287       $issuesallowed=0;
288     }
289   }
290   return ($issuesallowed,$traps_done,$amount,$odues);
291 } # end of process_traps
292
293 sub Borenq {
294   my ($env)=@_;
295   my $dbh = C4::Context->dbh;
296   #get borrower guff
297   my $bornum;
298   my $issuesallowed;
299   my $borrower;
300   my $reason;
301   $env->{'sysarea'} = "Enquiries";
302   while ($reason eq "") {
303     $env->{'sysarea'} = "Enquiries";
304     ($bornum,$issuesallowed,$borrower,$reason) = &findborrower($env,$dbh);
305     if ($reason eq "") {
306       my ($data,$reason)=&borrowerwindow($env,$borrower);
307       if ($reason eq 'Modify'){
308         modifyuser($env,$borrower);
309         $reason = "";
310       } elsif ($reason eq 'New'){
311         $reason = "";
312        }
313     }
314   }
315   return $reason;
316 }
317
318 sub modifyuser {
319   my ($env,$borrower) = @_;
320   debug_msg($env,"Please use intranet");
321   #return;
322 }
323
324 sub reserveslist {
325   my ($env,$borrower,$amount,$odues,$waiting) = @_;
326   my $dbh = C4::Context->dbh;
327   my @items;
328   my $x=0;
329   my $query="Select * from reserves where
330   borrowernumber='$borrower->{'borrowernumber'}' and found='W' and
331   cancellationdate is null order by timestamp";
332   my $sth=$dbh->prepare($query);
333   $sth->execute;
334   while (my $data=$sth->fetchrow_hashref){
335     my $itemdata = itemnodata($env,$dbh,$data->{'itemnumber'});
336     if ($itemdata){
337       push @items,$itemdata;
338     }
339   }
340   $sth->finish;
341   reservesdisplay($env,$borrower,$amount,$odues,\@items);
342 }
343
344 =item NewBorrowerNumber
345
346   $num = &NewBorrowerNumber();
347
348 Allocates a new, unused borrower number, and returns it.
349
350 =cut
351 #'
352 # FIXME - This is identical to C4::Search::NewBorrowerNumber.
353 # Pick one (preferably this one) and stick with it.
354
355 # FIXME - Race condition: this function just says what the next unused
356 # number is, but doesn't allocate it. Hence, two clients adding
357 # patrons at the same time could get the same new borrower number and
358 # clobber each other.
359 # A better approach might be to change the database to make
360 # borrowers.borrowernumber a unique key and auto_increment. Then, to
361 # allocate a new borrower number, use "insert" to create a new record
362 # (leaving the database daemon with the job of serializing requests),
363 # and use the newly-created record.
364
365 sub NewBorrowerNumber {
366   my $dbh = C4::Context->dbh;
367   my $sth=$dbh->prepare("Select max(borrowernumber) from borrowers");
368   $sth->execute;
369   my $data=$sth->fetchrow_hashref;
370   $sth->finish;
371   $data->{'max(borrowernumber)'}++;
372   return($data->{'max(borrowernumber)'});
373 }
374
375 sub findguarantees{
376   my ($bornum)=@_;
377   my $dbh = C4::Context->dbh;
378   my $query="select cardnumber,borrowernumber from borrowers where
379   guarantor='$bornum'";
380   my $sth=$dbh->prepare($query);
381   $sth->execute;
382   my @dat;
383   my $i=0;
384   while (my $data=$sth->fetchrow_hashref){
385     $dat[$i]=$data;
386     $i++;
387   }
388   $sth->finish;
389   return($i,\@dat);
390 }