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