Final update to holds queue work: adds link to holds queue
[srvgit] / misc / cronjobs / holds / build_holds_queue.pl
1 #!/usr/bin/perl 
2 #-----------------------------------
3 # Script Name: build_holds_queue.pl
4 # Description: builds a holds queue in the tmp_holdsqueue table
5 #-----------------------------------
6
7 use strict;
8 BEGIN {
9     # find Koha's Perl modules
10     # test carefully before changing this
11     use FindBin;
12     eval { require "$FindBin::Bin/../kohalib.pl" };
13 }
14
15 use C4::Context;
16 use C4::Search;
17 use C4::Items;
18 use C4::Branch;
19
20 # load the branches
21 my $branches = GetBranches();
22
23 # obtain the ranked list of weights for the case of static weighting
24 my $syspref = C4::Context->preference("StaticHoldsQueueWeight");
25 my @branch_loop;
26 @branch_loop = split(/,/, $syspref) if $syspref;
27
28 # TODO: Add Randomization Option
29
30 # If no syspref is set, use system-order to determine priority
31 unless ($syspref) {
32         for my $branch_hash (sort keys %$branches) {
33         push @branch_loop, {value => "$branch_hash" , branchname => $branches->{$branch_hash}->{'branchname'}, };
34         }
35 }
36
37 # if Randomization is enabled, randomize this array
38 @branch_loop = randarray(@branch_loop) if  C4::Context->preference("RandomizeHoldsQueueWeight");;
39
40 my ($biblionumber,$itemnumber,$barcode,$holdingbranch,$pickbranch,$notes,$cardnumber,$surname,$firstname,$phone,$title,$callno,$rdate,$borrno);
41
42 my $dbh   = C4::Context->dbh;
43
44 $dbh->do("DELETE FROM tmp_holdsqueue");  # clear the old table for new info
45
46 my $sth=$dbh->prepare("
47 SELECT biblionumber,itemnumber,reserves.branchcode,reservenotes,borrowers.borrowernumber,cardnumber,surname,firstname,phone,reservedate
48     FROM reserves,borrowers 
49 WHERE reserves.found IS NULL 
50     AND reserves.borrowernumber=borrowers.borrowernumber 
51     AND priority=1 
52 GROUP BY biblionumber");
53
54 my $sth_load=$dbh->prepare("
55 INSERT INTO tmp_holdsqueue (biblionumber,itemnumber,barcode,surname,firstname,phone,borrowernumber,cardnumber,reservedate,title,itemcallnumber,holdingbranch,pickbranch,notes)
56     VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
57
58 $sth->execute();      # get the list of biblionumbers for unfilled holds
59
60 GETIT: 
61 while (my $data=$sth->fetchrow_hashref){
62     # get the basic hold info
63     $biblionumber = $data->{'biblionumber'};
64     $pickbranch = $data->{'branchcode'};
65     $notes = $data->{'reservenotes'};
66     $borrno = $data->{'borrowernumber'};
67     $cardnumber = $data->{'cardnumber'};
68     $surname = $data->{'surname'};
69     $firstname = $data->{'firstname'};
70     $phone = $data->{'phone'};
71     $rdate = $data->{'reservedate'};
72
73     my @items = GetItemsInfo($biblionumber,''); # get the items for this biblio
74     my @itemorder;   #  prepare a new array to hold re-ordered items
75         
76     # Make sure someone(else) doesn't already have this item waiting for them
77     my $found_sth = $dbh->prepare("
78         SELECT found FROM reserves WHERE itemnumber=? AND found = ? AND cancellationdate IS NULL");
79         
80     # The following lines take the retrieved items and run them through various
81     # tests to decide if they are to be used and then put them in the preferred
82     # 'pick' order.
83     foreach my $itm (@items) {
84
85         $found_sth->execute($itm->{itemnumber},"W");
86         my $found = $found_sth->fetchrow_hashref();
87         if ($found) {
88             $itm->{"found"} = $found->{"found"};
89         }
90         if ($itm->{"notforloan"}) {
91                         # item is on order
92             next if $itm->{"notforloan"}== -1;
93         }
94         if ( ( (!$itm->{"binding"}) || 
95                 # Item is at not at bindery, not checked out, and not lost
96                 ($itm->{"binding"}<1)) && (!$itm->{"found"}) && (!$itm->{"datedue"}) && ( (!$itm->{"itemlost"}) || 
97
98                 # Item is not lost and not notforloan
99                 ($itm->{"itemlost"}==0) ) && ( ($itm->{"notforloan"}==0) || 
100
101                 # Item is not notforloan
102                 (!$itm->{"notforloan"}) ) ) {
103
104             #warn "patron requested pickup at $pickbranch for item in ".$itm->{'holdingbranch'};
105
106                         # This selects items for fulfilment, and weights them based on
107                         # a static list
108                         my $weight=0;
109                         # always prefer a direct match
110             if ($itm->{'holdingbranch'} eq $pickbranch) {
111                                 #warn "Found match in pickuplibrary";
112                 $itemorder[$weight]=$itm;
113             } 
114                         else {
115                                 for my $branchcode (@branch_loop) {
116                                         $weight++;
117                                         if ($itm->{'homebranch'} eq $branchcode) {
118                                                 #warn "Match found with weight $weight in ".$branchcode;
119                                 $itemorder[$weight]=$itm;
120                                         }
121                                 }
122             }
123         }
124     }
125     my $count = @itemorder;
126         #warn "Empty array" if $count<1;
127     next GETIT if $count<1;  # if the re-ordered array is empty, skip to next
128
129     PREP: 
130     foreach my $itmlist (@itemorder) {
131         if ($itmlist) {
132             $barcode = $itmlist->{'barcode'};
133                         $itemnumber = $itmlist->{'itemnumber'};
134             $holdingbranch = $itmlist->{'holdingbranch'};
135             $title = $itmlist->{'title'};
136             $callno = $itmlist->{'itemcallnumber'};
137             last PREP;    # we only want the first def item in the array
138         }
139     }
140     $sth_load->execute($biblionumber,$itemnumber,$barcode,$surname,$firstname,$phone,$borrno,$cardnumber,$rdate,$title,$callno,$holdingbranch,$pickbranch,$notes);
141     $sth_load->finish;
142 }
143 $sth->finish;
144 $dbh->disconnect;
145
146 sub randarray {
147         my @array = @_;
148         my @rand = undef;
149         my $seed = $#array + 1;
150         my $randnum = int(rand($seed));
151         $rand[$randnum] = shift(@array);
152         while (1) {
153                 my $randnum = int(rand($seed));
154                 if ($rand[$randnum] eq undef) {
155                         $rand[$randnum] = shift(@array);
156                 }
157                 last if ($#array == -1);
158         }
159         return @rand;
160 }
161
162
163 print "finished\n";