Fixxing bugs
[koha.git] / C4 / Reserves2.pm
1 package C4::Reserves2; #assumes C4/Reserves2
2
3 use strict;
4 require Exporter;
5 use DBI;
6 use C4::Database;
7 use C4::Search;
8 #use C4::Accounts;
9
10 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
11   
12 # set the version for version checking
13 $VERSION = 0.01;
14     
15 @ISA = qw(Exporter);
16 @EXPORT = qw(&FindReserves &CheckReserves &CheckWaiting &CancelReserve &FillReserve &ReserveWaiting &CreateReserve &updatereserves &getreservetitle &Findgroupreserve);
17                                                     
18 # make all your functions, whether exported or not;
19
20 sub FindReserves {
21   my ($bib,$bor)=@_;
22   my $dbh=C4Connect;
23   my $query="SELECT *,reserves.branchcode,biblio.title AS btitle
24                       FROM reserves,borrowers,biblio ";
25   if ($bib ne ''){
26       $bib = $dbh->quote($bib);
27       if ($bor ne ''){
28           $bor = $dbh->quote($bor);
29           $query .=  " where reserves.biblionumber   = $bib
30                          and borrowers.borrowernumber = $bor 
31                          and reserves.borrowernumber = borrowers.borrowernumber 
32                          and biblio.biblionumber     = $bib 
33                          and cancellationdate is NULL 
34                          and (found <> 'F' or found is NULL)";
35       } else {
36           $query .= " where reserves.borrowernumber = borrowers.borrowernumber
37                         and biblio.biblionumber     = $bib 
38                         and reserves.biblionumber   = $bib
39                         and cancellationdate is NULL 
40                         and (found <> 'F' or found is NULL)";
41       }
42   } else {
43       $query .= " where borrowers.borrowernumber = $bor 
44                     and reserves.borrowernumber  = borrowers.borrowernumber 
45                     and reserves.biblionumber    = biblio.biblionumber 
46                     and cancellationdate is NULL and 
47                     (found <> 'F' or found is NULL)";
48   }
49   $query.=" order by priority";
50   warn $query;
51   my $sth=$dbh->prepare($query);
52   $sth->execute;
53   my $i=0;
54   my @results;
55   while (my $data=$sth->fetchrow_hashref){
56       if ($data->{'constrainttype'} eq 'o') {
57           my $conquery = "SELECT biblioitemnumber FROM reserveconstraints 
58                            WHERE biblionumber   = ? 
59                              AND borrowernumber = ?
60                              AND reservedate    = ?";
61           my $csth=$dbh->prepare($conquery);
62           my $bibn = $data->{'biblionumber'};
63           my $born = $data->{'borrowernumber'};
64           my $resd = $data->{'reservedate'};
65           $csth->execute($bibn, $born, $resd);
66           my ($bibitemno) = $csth->fetchrow_array;
67           $csth->finish;
68           my $bdata = C4::Search::bibitemdata($bibitemno);
69           foreach my $key (keys %$bdata) {
70               $data->{$key} = $bdata->{$key};
71           }
72       }
73       $results[$i]=$data;
74       $i++;
75   }
76 #  print $query;
77   $sth->finish;
78   $dbh->disconnect;
79   return($i,\@results);
80 }
81
82 sub CheckReserves {
83     my ($item) = @_;
84     warn "In CheckReserves";
85     my $dbh=C4Connect;
86     my $qitem=$dbh->quote($item);
87 # get the biblionumber...
88     my $sth=$dbh->prepare("select biblionumber, biblioitemnumber from items where itemnumber=$qitem");
89     $sth->execute;
90     my ($biblio, $bibitem) = $sth->fetchrow_array;
91     $sth->finish;
92     $dbh->disconnect;
93 # get the reserves...
94     my ($count, @reserves) = Findgroupreserve($bibitem, $biblio);
95     my $priority = 10000000; 
96     my $highest;
97     if ($count) {
98         foreach my $res (@reserves) {
99             if ($res->{'itemnumber'} == $item) {
100                 return ("Waiting", $res);
101             } else {
102                 if ($res->{'priority'} != 0 && $res->{'priority'} < $priority) {
103                     $priority = $res->{'priority'};
104                     $highest = $res;
105                 }
106             }
107         }
108         warn "highest = $highest";
109         $highest->{'itemnumber'} = $item;
110         foreach my $key (keys %$highest) {
111             warn "$key : $highest->{$key}\n";
112         }
113
114         return ("Reserved", $highest);
115     } else {
116         return (0, 0);
117     }
118 }
119
120 sub CancelReserve {
121     my ($biblio, $item, $borr) = @_;
122     my $dbh=C4Connect;
123     #warn "In CancelReserve";
124     if (($item and $borr) and (not $biblio)) {
125 # removing a waiting reserve record....
126         $item = $dbh->quote($item);
127         $borr = $dbh->quote($borr);
128 # update the database...
129         my $query = "update reserves set cancellationdate = now(), 
130                                          found            = Null, 
131                                          priority         = 0 
132                                    where itemnumber       = $item 
133                                      and borrowernumber   = $borr";
134         my $sth = $dbh->prepare($query);
135         $sth->execute;
136         $sth->finish;
137     }
138     if (($biblio and $borr) and (not $item)) {
139 # removing a reserve record....
140         my $q_biblio = $dbh->quote($biblio);
141         $borr = $dbh->quote($borr);
142 # fix up the priorities on the other records....
143         my $query = "SELECT priority FROM reserves 
144                                     WHERE biblionumber   = $q_biblio 
145                                       AND borrowernumber = $borr
146                                       AND cancellationdate is NULL 
147                                       AND (found <> 'F' or found is NULL)";
148         my $sth=$dbh->prepare($query);
149         $sth->execute;
150         my ($priority) = $sth->fetchrow_array;
151         $sth->finish;
152 # update the database, removing the record...
153         my $query = "update reserves set cancellationdate = now(), 
154                                          found            = Null, 
155                                          priority         = 0 
156                                    where biblionumber     = $q_biblio 
157                                      and borrowernumber   = $borr
158                                      and cancellationdate is NULL 
159                                      and (found <> 'F' or found is NULL)";
160         my $sth = $dbh->prepare($query);
161         $sth->execute;
162         $sth->finish;
163 # now fix the priority on the others....
164         fixpriority($priority, $biblio);
165     }
166     $dbh->disconnect;
167 }
168
169
170 sub FillReserve {
171     my ($res) = @_;
172     my $dbh=C4Connect;
173 # removing a waiting reserve record....
174     my $biblio = $res->{'biblionumber'}; my $qbiblio = $dbh->quote($biblio);
175     my $borr = $res->{'borrowernumber'}; $borr = $dbh->quote($borr);
176     my $resdate = $res->{'reservedate'}; $resdate = $dbh->quote($resdate);
177 # update the database...
178     my $query = "UPDATE reserves SET found            = 'F', 
179                                      priority         = 0 
180                                WHERE biblionumber     = $qbiblio
181                                  AND reservedate      = $resdate
182                                  AND borrowernumber   = $borr";
183     my $sth = $dbh->prepare($query);
184     $sth->execute;
185     $sth->finish;
186     $dbh->disconnect;
187 # now fix the priority on the others....
188     fixpriority($res->{'priority'}, $biblio);
189 }
190
191 sub fixpriority {
192     my ($priority, $biblio) =  @_;
193     my $dbh = C4Connect;
194     my ($count, $reserves) = FindReserves($biblio);
195     foreach my $rec (@$reserves) {
196         if ($rec->{'priority'} > $priority) {
197             my $newpr = $rec->{'priority'};      $newpr = $dbh->quote($newpr - 1);
198             my $nbib = $rec->{'biblionumber'};   $nbib = $dbh->quote($nbib);
199             my $nbor = $rec->{'borrowernumber'}; $nbor = $dbh->quote($nbor);
200             my $nresd = $rec->{'reservedate'};   $nresd = $dbh->quote($nresd);
201             my $query = "UPDATE reserves SET priority = $newpr 
202                                WHERE biblionumber     = $nbib 
203                                  AND borrowernumber   = $nbor
204                                  AND reservedate      = $nresd";
205             #warn $query;
206             my $sth = $dbh->prepare($query);
207             $sth->execute;
208             $sth->finish;
209         } 
210     }
211     $dbh->disconnect;
212 }
213
214
215
216 sub ReserveWaiting {
217     my ($item, $borr) = @_;
218     my $dbh = C4Connect;
219     $item = $dbh->quote($item);
220     $borr = $dbh->quote($borr);
221 # get priority and biblionumber....
222     my $query = "SELECT reserves.priority     as priority, 
223                         reserves.biblionumber as biblionumber,
224                         reserves.branchcode   as branchcode 
225                       FROM reserves,items 
226                      WHERE reserves.biblionumber   = items.biblionumber 
227                        AND items.itemnumber        = $item 
228                        AND reserves.borrowernumber = $borr 
229                        AND reserves.cancellationdate is NULL
230                        AND (reserves.found <> 'F' or reserves.found is NULL)";
231     my $sth = $dbh->prepare($query);
232     $sth->execute;
233     my $data = $sth->fetchrow_hashref;
234     $sth->finish;
235     my $biblio = $data->{'biblionumber'};
236     my $q_biblio = $dbh->quote($biblio);
237 # update reserves record....
238     $query = "UPDATE reserves SET priority = 0, found = 'W', itemnumber = $item 
239                             WHERE borrowernumber = $borr AND biblionumber = $q_biblio";
240     $sth = $dbh->prepare($query);
241     $sth->execute;
242     $sth->finish;
243     $dbh->disconnect;
244 # now fix up the remaining priorities....
245     fixpriority($data->{'priority'}, $biblio);
246     my $branchcode = $data->{'branchcode'};
247     return $branchcode;
248 }
249
250 sub CheckWaiting {
251     my ($borr)=@_;
252     my $dbh = C4Connect;
253     $borr = $dbh->quote($borr);
254     my @itemswaiting;
255     my $query = "SELECT * FROM reserves
256                          WHERE borrowernumber = $borr
257                            AND reserves.found = 'W' 
258                            AND cancellationdate is NULL";
259     my $sth = $dbh->prepare($query);
260     $sth->execute();
261     my $cnt=0;
262     if (my $data=$sth->fetchrow_hashref) {
263         @itemswaiting[$cnt] =$data;
264         $cnt ++;
265     }
266     $sth->finish;
267     return ($cnt,\@itemswaiting);
268 }
269
270 sub Findgroupreserve {
271   my ($bibitem,$biblio)=@_;
272   my $dbh=C4Connect;
273   $bibitem=$dbh->quote($bibitem);
274   my $query = "SELECT reserves.biblionumber               AS biblionumber, 
275                       reserves.borrowernumber             AS borrowernumber, 
276                       reserves.reservedate                AS reservedate, 
277                       reserves.branchcode                 AS branchcode, 
278                       reserves.cancellationdate           AS cancellationdate, 
279                       reserves.found                      AS found, 
280                       reserves.reservenotes               AS reservenotes, 
281                       reserves.priority                   AS priority, 
282                       reserves.timestamp                  AS timestamp, 
283                       reserveconstraints.biblioitemnumber AS biblioitemnumber, 
284                       reserves.itemnumber                 AS itemnumber 
285                  FROM reserves LEFT JOIN reserveconstraints
286                    ON reserves.biblionumber = reserveconstraints.biblionumber
287                 WHERE reserves.biblionumber = $biblio
288                   AND ( ( reserveconstraints.biblioitemnumber = $bibitem 
289                       AND reserves.borrowernumber = reserveconstraints.borrowernumber
290                       AND reserves.reservedate    =reserveconstraints.reservedate )
291                    OR reserves.constrainttype='a' )
292                   AND reserves.cancellationdate is NULL
293                   AND (reserves.found <> 'F' or reserves.found is NULL)";
294   my $sth=$dbh->prepare($query);
295   $sth->execute;
296   my $i=0;
297   my @results;
298   while (my $data=$sth->fetchrow_hashref){
299     $results[$i]=$data;
300     $i++;
301   }
302   $sth->finish;
303   $dbh->disconnect;
304   return($i,@results);
305 }
306
307 sub CreateReserve {                                                           
308   my
309 ($env,$branch,$borrnum,$biblionumber,$constraint,$bibitems,$priority,$notes,$title)= @_;   
310   my $fee=CalcReserveFee($env,$borrnum,$biblionumber,$constraint,$bibitems);
311   my $dbh = &C4Connect;       
312   my $const = lc substr($constraint,0,1);       
313   my @datearr = localtime(time);                                
314   my $resdate =(1900+$datearr[5])."-".($datearr[4]+1)."-".$datearr[3];                   
315   #eval {                                                           
316   # updates take place here             
317   if ($fee > 0) {           
318 #    print $fee;
319     my $nextacctno = &getnextacctno($env,$borrnum,$dbh);   
320     my $updquery = "insert into accountlines       
321     (borrowernumber,accountno,date,amount,description,accounttype,amountoutstanding)                                              
322                                                           values
323     ($borrnum,$nextacctno,now(),$fee,'Reserve Charge - $title','Res',$fee)";          
324     my $usth = $dbh->prepare($updquery);                      
325     $usth->execute;             
326     $usth->finish;                        
327   }                     
328   #if ($const eq 'a'){
329     my $query="insert into reserves
330    (borrowernumber,biblionumber,reservedate,branchcode,constrainttype,priority,reservenotes)
331     values
332 ('$borrnum','$biblionumber','$resdate','$branch','$const','$priority','$notes')";   
333     my $sth = $dbh->prepare($query);                        
334     $sth->execute();                
335     $sth->finish;
336   #}
337   if (($const eq "o") || ($const eq "e")) {     
338     my $numitems = @$bibitems;             
339     my $i = 0;                                        
340     while ($i < $numitems) {   
341       my $biblioitem = @$bibitems[$i];   
342       my $query = "insert into
343       reserveconstraints                          
344       (borrowernumber,biblionumber,reservedate,biblioitemnumber)         
345       values
346       ('$borrnum','$biblionumber','$resdate','$biblioitem')";                 
347       my $sth = $dbh->prepare($query);                    
348       $sth->execute();
349       $sth->finish;
350       $i++;                         
351     }                                   
352   } 
353 #  print $query;
354   $dbh->disconnect();         
355   return();   
356 }             
357
358 sub CalcReserveFee {
359   my ($env,$borrnum,$biblionumber,$constraint,$bibitems) = @_;        
360   #check for issues;    
361   my $dbh = &C4Connect;           
362   my $const = lc substr($constraint,0,1); 
363   my $query = "SELECT * FROM borrowers,categories 
364                 WHERE (borrowernumber = ?)         
365                   AND (borrowers.categorycode = categories.categorycode)";   
366   my $sth = $dbh->prepare($query);                       
367   $sth->execute($borrnum);                                    
368   my $data = $sth->fetchrow_hashref;                  
369   $sth->finish();
370   my $fee = $data->{'reservefee'};       
371   my $cntitems = @->$bibitems;   
372   if ($fee > 0) {                         
373     # check for items on issue      
374     # first find biblioitem records       
375     my @biblioitems;    
376     my $query1 = "SELECT * FROM biblio,biblioitems                           
377                    WHERE (biblio.biblionumber = ?)     
378                      AND (biblio.biblionumber = biblioitems.biblionumber)";
379     my $sth1 = $dbh->prepare($query1);                   
380     $sth1->execute($biblionumber);                                     
381     while (my $data1=$sth1->fetchrow_hashref) { 
382       if ($const eq "a") {    
383         push @biblioitems,$data1;       
384       } else {                     
385         my $found = 0;        
386         my $x = 0;
387         while ($x < $cntitems) {                                             
388           if (@$bibitems->{'biblioitemnumber'} == $data->{'biblioitemnumber'}) {         
389             $found = 1;   
390           }               
391           $x++;                                       
392         }               
393         if ($const eq 'o') {
394           if ( $found == 1) {
395             push @biblioitems,$data1;
396           }                            
397         } else {
398           if ($found == 0) {
399             push @biblioitems,$data1;
400           } 
401         }     
402       }   
403     }             
404     $sth1->finish;                                  
405     my $cntitemsfound = @biblioitems; 
406     my $issues = 0;                 
407     my $x = 0;                   
408     my $allissued = 1; 
409     while ($x < $cntitemsfound) { 
410       my $bitdata = $biblioitems[$x];                                       
411       my $query2 = "SELECT * FROM items                   
412                      WHERE biblioitemnumber = ?";     
413       my $sth2 = $dbh->prepare($query2);                       
414       $sth2->execute($bitdata->{'biblioitemnumber'});   
415       while (my $itdata=$sth2->fetchrow_hashref) { 
416         my $query3 = "SELECT * FROM issues
417                        WHERE itemnumber = ? 
418                          AND returndate IS NULL";
419         
420         my $sth3 = $dbh->prepare($query3);                      
421         $sth3->execute($itdata->{'itemnumber'});                     
422         if (my $isdata=$sth3->fetchrow_hashref) {
423         } else {
424           $allissued = 0; 
425         }  
426       }                                                           
427       $x++;   
428     }         
429     if ($allissued == 0) { 
430       my $rquery = "SELECT * FROM reserves WHERE biblionumber = ?"; 
431       my $rsth = $dbh->prepare($rquery);   
432       $rsth->execute($biblionumber);   
433       if (my $rdata = $rsth->fetchrow_hashref) { 
434       } else {                                     
435         $fee = 0;                                                           
436       }   
437     }             
438   }                   
439 #  print "fee $fee";
440   $dbh->disconnect();   
441   return $fee;                                      
442 }                   
443
444 sub getnextacctno {                                                           
445   my ($env,$bornumber,$dbh)=@_;           
446   my $nextaccntno = 1;      
447   my $query = "select * from accountlines                             
448   where (borrowernumber = '$bornumber')                               
449   order by accountno desc";                       
450   my $sth = $dbh->prepare($query);                                  
451   $sth->execute;                    
452   if (my $accdata=$sth->fetchrow_hashref){    
453     $nextaccntno = $accdata->{'accountno'} + 1;           
454   }                       
455   $sth->finish;                                       
456   return($nextaccntno);                   
457 }              
458
459 sub updatereserves{
460   #subroutine to update a reserve 
461   my ($rank,$biblio,$borrower,$del,$branch)=@_;
462   my $dbh=C4Connect;
463   my $query="Update reserves ";
464   if ($del ==0){
465     $query.="set  priority='$rank',branchcode='$branch' where
466     biblionumber=$biblio and borrowernumber=$borrower";
467   } else {
468     $query="Select * from reserves where biblionumber=$biblio and
469     borrowernumber=$borrower";
470     my $sth=$dbh->prepare($query);
471     $sth->execute;
472     my $data=$sth->fetchrow_hashref;
473     $sth->finish;
474     $query="Select * from reserves where biblionumber=$biblio and 
475     priority > '$data->{'priority'}' and cancellationdate is NULL 
476     order by priority";
477     my $sth2=$dbh->prepare($query) || die $dbh->errstr;
478     $sth2->execute || die $sth2->errstr;
479     while (my $data=$sth2->fetchrow_hashref){
480       $data->{'priority'}--;
481       $query="Update reserves set priority=$data->{'priority'} where
482       biblionumber=$data->{'biblionumber'} and
483       borrowernumber=$data->{'borrowernumber'}";
484       my $sth3=$dbh->prepare($query);
485       $sth3->execute || die $sth3->errstr;
486       $sth3->finish;
487     }
488     $sth2->finish;
489     $query="update reserves set cancellationdate=now() where biblionumber=$biblio 
490     and borrowernumber=$borrower";    
491   }
492   my $sth=$dbh->prepare($query);
493   $sth->execute;
494   $sth->finish;  
495   $dbh->disconnect;
496 }
497
498 sub getreservetitle {
499  my ($biblio,$bor,$date,$timestamp)=@_;
500  my $dbh=C4Connect;
501  my $query="Select * from reserveconstraints,biblioitems where
502  reserveconstraints.biblioitemnumber=biblioitems.biblioitemnumber
503  and reserveconstraints.biblionumber=$biblio and reserveconstraints.borrowernumber
504  = $bor and reserveconstraints.reservedate='$date' and
505  reserveconstraints.timestamp=$timestamp";
506  my $sth=$dbh->prepare($query);
507  $sth->execute;
508  my $data=$sth->fetchrow_hashref;
509  $sth->finish;
510  $dbh->disconnect;
511 # print $query;
512  return($data);
513 }
514
515
516
517
518
519                         
520 END { }       # module clean-up code here (global destructor)