Lines 46-52
This script converts holds to recalls when a record has a set minimum number of
Link Here
|
46 |
|
46 |
|
47 |
If a record is found to have the specified minimum number of holds, the script will find the oldest hold and convert it to a recall, as long as it would be a legal recall. |
47 |
If a record is found to have the specified minimum number of holds, the script will find the oldest hold and convert it to a recall, as long as it would be a legal recall. |
48 |
|
48 |
|
49 |
It will only convert the single oldest hold. Once converted, the script will move on to the next record, it will not continue to convert holds on this record. |
49 |
This script uses the ConvertSelectedReservesToRecalls system preference. |
|
|
50 |
|
51 |
When ConvertSelectedReservesToRecalls is set to 'oldest', this script will only convert the single oldest hold. Once converted, the script will move on to the next record, it will not continue to convert holds on this record. |
52 |
|
53 |
When ConvertSelectedReservesToRecalls is set to 'recallable', this script will convert reserves one-by-one, oldest first, until all recallable items have been recalled. |
50 |
|
54 |
|
51 |
Options: |
55 |
Options: |
52 |
-v verbose |
56 |
-v verbose |
Lines 89-135
my @bib_holds = Koha::Holds->search({}, {
Link Here
|
89 |
my $count = 0; |
93 |
my $count = 0; |
90 |
foreach my $bib ( @bib_holds ) { |
94 |
foreach my $bib ( @bib_holds ) { |
91 |
$bib = $bib->unblessed; |
95 |
$bib = $bib->unblessed; |
|
|
96 |
# If there are $min or more holds on the same record, we can begin converting holds |
92 |
if ( $bib->{bibcount} >= $min ) { |
97 |
if ( $bib->{bibcount} >= $min ) { |
93 |
# If there are $min or more holds on the same record, convert the oldest hold to a recall |
|
|
94 |
|
98 |
|
|
|
99 |
# Get all holds on this biblio |
95 |
my @holds = Koha::Holds->search({ biblionumber => $bib->{biblionumber}, found => undef }, { order_by => { -asc => 'reservedate' } })->as_list; |
100 |
my @holds = Koha::Holds->search({ biblionumber => $bib->{biblionumber}, found => undef }, { order_by => { -asc => 'reservedate' } })->as_list; |
96 |
my $hold_to_convert = $holds[0]; |
101 |
|
97 |
foreach my $res ( @holds ) { |
102 |
if ( C4::Context->preference('ConvertSelectedReservesToRecalls') eq 'oldest' ) { |
98 |
if ( dt_from_string($res->reservedate) < dt_from_string($hold_to_convert->reservedate) ) { |
103 |
|
99 |
$hold_to_convert = $res; |
104 |
my $hold_to_convert = $holds[0]; |
|
|
105 |
my $itemnumber_to_allocate = can_convert( $hold_to_convert ); |
106 |
if ( $itemnumber_to_allocate ) { |
107 |
my $item_to_allocate = Koha::Items->find( $itemnumber_to_allocate ); |
108 |
do_convert( $hold_to_convert, $item_to_allocate ); |
109 |
report( $hold_to_convert, ++$count ); |
110 |
} |
111 |
|
112 |
} elsif ( C4::Context->preference('ConvertSelectedReservesToRecalls') eq 'recallable' ) { |
113 |
|
114 |
my $this_record_holds_converted = 0; |
115 |
|
116 |
my @items = Koha::Items->search({ biblionumber => $bib->{biblionumber} })->as_list; |
117 |
foreach my $item ( @items ) { |
118 |
my $hold_to_convert = $holds[ $this_record_holds_converted ]; |
119 |
|
120 |
if ( !$hold_to_convert ) { |
121 |
last; |
122 |
} |
123 |
|
124 |
my $itemnumber_to_allocate = can_convert( $hold_to_convert, $item ); |
125 |
|
126 |
if ( $itemnumber_to_allocate ) { |
127 |
my $item_to_allocate = $itemnumber_to_allocate == $item->id ? $item : Koha::Items->find( $itemnumber_to_allocate ); |
128 |
do_convert( $hold_to_convert, $item_to_allocate ); |
129 |
report( $hold_to_convert, ++$count ); |
130 |
} |
131 |
$this_record_holds_converted++; |
100 |
} |
132 |
} |
101 |
} |
133 |
} |
|
|
134 |
} |
135 |
} |
136 |
|
137 |
sub can_convert { |
138 |
my $hold = shift; |
139 |
my $item = shift; |
102 |
|
140 |
|
103 |
my $patron = Koha::Patrons->find( $hold_to_convert->borrowernumber ); |
141 |
my $patron = Koha::Patrons->find( $hold_to_convert->borrowernumber ); |
104 |
my $biblio = Koha::Biblios->find( $hold_to_convert->biblionumber ); |
142 |
my $biblio = Koha::Biblios->find( $hold_to_convert->biblionumber ); |
105 |
my $item; |
143 |
|
106 |
my $can_convert; |
144 |
if ( $hold->item_level_hold ) { |
107 |
if ( $hold_to_convert->item_level_hold ) { |
145 |
|
108 |
$item = Koha::Items->find( $hold_to_convert->itemnumber ); |
146 |
if ( $item and $item->id == $hold->itemnumber ) { |
|
|
147 |
# item-level reserve, on this specific item |
109 |
if ( $item->can_be_recalled({ patron => $patron, hold_convert => 1 }) ) { |
148 |
if ( $item->can_be_recalled({ patron => $patron, hold_convert => 1 }) ) { |
110 |
$can_convert = 1; |
149 |
return $item->id; |
111 |
} |
150 |
} |
112 |
} else { |
151 |
} else { |
113 |
if ( $biblio->can_be_recalled({ patron => $patron, hold_convert => 1 }) ) { |
152 |
# item-level reserve but not on this item |
114 |
$can_convert = 1; |
153 |
# so check if intended item can be allocated for the recall |
|
|
154 |
$item = Koha::Items->find( $hold->itemnumber ); |
155 |
if ( $item and $item->can_be_recalled({ patron => $patron, hold_convert => 1 }) ) { |
156 |
return $item->id; |
115 |
} |
157 |
} |
116 |
} |
158 |
} |
117 |
if ( $can_convert ) { |
159 |
|
118 |
my ( $recall, $due_interval, $due_date ) = Koha::Recalls->add_recall({ |
160 |
} else { |
119 |
patron => $patron, |
161 |
# bib-level reserve |
120 |
biblio => $biblio, |
162 |
|
121 |
branchcode => $hold_to_convert->branchcode, |
163 |
if ( $item and $item->can_be_recalled({ patron => $patron, hold_convert => 1 }) ) { |
122 |
item => $item, |
164 |
# this item may be able to fill the recall |
123 |
expirationdate => $hold_to_convert->expirationdate, |
165 |
return $item->id; |
124 |
interface => 'commandline', |
166 |
} |
125 |
}); |
167 |
|
126 |
$hold_to_convert->cancel({ cancellation_reason => 'RECALLED' }); |
168 |
# don't have a specific item to allocate for this recall |
127 |
$count++; |
169 |
# so get an eligible item that's not already recalled |
128 |
if ( $verbose ) { |
170 |
foreach my $i ( $biblio->items->as_list ) { |
129 |
my $hold_id = $hold_to_convert->reserve_id; |
171 |
if ( Koha::Recalls->filter_by_current->search({ item_id => $i->id })->count < 1 ) { |
130 |
my $biblionumber = $hold_to_convert->biblionumber; |
172 |
if ( $i and $i->can_be_recalled({ patron => $patron, hold_convert => 1 }) ) { |
131 |
print "$count. Hold converted to recall (hold_id: $hold_id, biblionumber: $biblionumber).\n"; |
173 |
return $i->id; |
|
|
174 |
} |
132 |
} |
175 |
} |
133 |
} |
176 |
} |
|
|
177 |
|
178 |
# there are no recallable items left |
179 |
return; |
180 |
} |
181 |
|
182 |
return; |
183 |
} |
184 |
|
185 |
sub do_convert { |
186 |
my $hold = shift; |
187 |
my $item = shift; |
188 |
|
189 |
my $patron = Koha::Patrons->find( $hold->borrowernumber ); |
190 |
my $biblio = Koha::Biblios->find( $hold->biblionumber ); |
191 |
|
192 |
my ( $recall, $due_interval, $due_date ) = Koha::Recalls->add_recall({ |
193 |
patron => $patron, |
194 |
biblio => $biblio, |
195 |
branchcode => $hold->branchcode, |
196 |
item => $item, |
197 |
expirationdate => $hold->patron_expiration_date ? $hold->patron_expiration_date : $hold->expirationdate, |
198 |
interface => 'commandline', |
199 |
}); |
200 |
$hold->cancel({ cancellation_reason => 'RECALLED' }); |
201 |
} |
202 |
|
203 |
sub report { |
204 |
my $hold = shift; |
205 |
my $count = shift; |
206 |
|
207 |
if ( $verbose ) { |
208 |
my $hold_id = $hold->reserve_id; |
209 |
my $biblionumber = $hold->biblionumber; |
210 |
print "$count. Hold converted to recall (reserve_id: $hold_id, biblionumber: $biblionumber).\n"; |
134 |
} |
211 |
} |
135 |
} |
212 |
} |
136 |
- |
|
|