954d2606a8
This patch allows staff patrons to cancel multiple holds in bulk. To test: 1. Apply this patch 2. restart_all 3. In cataloge go to a book and place many holds CHECK => Holds table shows a column of checkboxes 4. Play with checkboxes (have some fun ;-P) CHECK => When you manually check all checkboxes, the checkbox in the header also gets checked. => When you uncheck one of the checkboxes, the one in the header also gets unchecked. => If no checkbox is checked and you check the one in the header, all checkboxes get checked. => If there are some checkboxes that are checked and others are not, when you click on the checkbox in the header all checkboxes get unchecked. => If all checkboxes are checked, when you uncheck the one in the header, all checkboxes get unchecked. => Every time you play with checkboxes, the number in the button "Cancel selected" changes. 5. Check some of the checkboxes and click on cancel selected. SUCCESS => A background job gets fired to cancel all selected holds. => A message should appear with a link to the job. 6. Wait a few seconds and click on the link SUCCESS => A message appears with the report of the execution of the background job. 7. Grab a patron and search to hold 8. Select multiple biblios and click on "place hold for <patron>" CHECK => After holds are confirmed, multiple holds table are shown.. one for each record. Checkboxes work exactly the same as before, but scoped for each individual table. Checkboxes from one table will not affect checkboxes from other tables. 9. Repeat steps 4 to 6. 10. Check In some of the items so the get in Waiting state. 11. Update expirationdate os some of those holds and set it to ReservesMaxPickUpDelay + 1 days earlier NOTE => ReservesMaxPickUpDelay = 7 days by default, so sql syntax to update would be => update reserves set expirationdate = date_sub(expirationdate, interval 8 day) where reserve_id in (...) 12. Repeat steps 4 to 6 but in waitingreserves.pl, in both tabs. Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io> Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com> Bug 23678: (QA follow-up) Add missing template filter Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io> Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com> Bug 23678: (QA follow-up) Add missing filters Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io> Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com> Bug 23678: (QA follow-up) Use correct indentation Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io> JD amended patch: also Koha/BackgroundJob/BatchCancelHold.pm JD Amended patch: Full rebase and adjustements made on top of bug 26080. Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
178 lines
6 KiB
Perl
Executable file
178 lines
6 KiB
Perl
Executable file
#!/usr/bin/perl
|
|
|
|
# Copyright 2000-2002 Katipo Communications
|
|
# parts copyright 2010 BibLibre
|
|
#
|
|
# This file is part of Koha.
|
|
#
|
|
# Koha is free software; you can redistribute it and/or modify it
|
|
# under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# Koha is distributed in the hope that it will be useful, but
|
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with Koha; if not, see <http://www.gnu.org/licenses>.
|
|
|
|
use Modern::Perl;
|
|
use CGI qw ( -utf8 );
|
|
use C4::Context;
|
|
use C4::Output qw( output_html_with_http_headers );
|
|
use C4::Auth qw( get_template_and_user );
|
|
use C4::Items qw( ModItemTransfer );
|
|
use Date::Calc qw( Date_to_Days Today );
|
|
use C4::Reserves qw( ModReserve ModReserveCancelAll );
|
|
use Koha::DateUtils qw( dt_from_string output_pref );
|
|
use Koha::BiblioFrameworks;
|
|
use Koha::Items;
|
|
use Koha::ItemTypes;
|
|
use Koha::Patrons;
|
|
use Koha::BackgroundJob::BatchCancelHold;
|
|
|
|
my $input = CGI->new;
|
|
|
|
my $item = $input->param('itemnumber');
|
|
my $borrowernumber = $input->param('borrowernumber');
|
|
my $fbr = $input->param('fbr') || '';
|
|
my $tbr = $input->param('tbr') || '';
|
|
my $all_branches = $input->param('allbranches') || '';
|
|
my $cancelall = $input->param('cancelall');
|
|
my $tab = $input->param('tab');
|
|
my $cancelBulk = $input->param('cancelBulk');
|
|
|
|
my ( $template, $loggedinuser, $cookie, $flags ) = get_template_and_user(
|
|
{
|
|
template_name => "circ/waitingreserves.tt",
|
|
query => $input,
|
|
type => "intranet",
|
|
flagsrequired => { circulate => "circulate_remaining_permissions" },
|
|
}
|
|
);
|
|
|
|
my $default = C4::Context->userenv->{'branch'};
|
|
|
|
my $transfer_when_cancel_all = C4::Context->preference('TransferWhenCancelAllWaitingHolds');
|
|
$template->param( TransferWhenCancelAllWaitingHolds => 1 ) if $transfer_when_cancel_all;
|
|
|
|
my @cancel_result;
|
|
# if we have a return from the form we cancel the holds
|
|
if ($item) {
|
|
my $res = cancel( $item, $borrowernumber, $fbr, $tbr );
|
|
push @cancel_result, $res if $res;
|
|
}
|
|
|
|
if ( C4::Context->preference('IndependentBranches') ) {
|
|
undef $all_branches;
|
|
} else {
|
|
$template->param( all_branches_link => '/cgi-bin/koha/circ/waitingreserves.pl' . '?allbranches=1' )
|
|
unless $all_branches;
|
|
}
|
|
$template->param( all_branches => 1 ) if $all_branches;
|
|
|
|
if ($cancelBulk) {
|
|
my $reason = $input->param("cancellation-reason");
|
|
my @hold_ids = split ',', $input->param("ids");
|
|
my $params = {
|
|
reason => $reason,
|
|
hold_ids => \@hold_ids,
|
|
};
|
|
my $job_id = Koha::BackgroundJob::BatchCancelHold->new->enqueue($params);
|
|
|
|
$template->param(
|
|
enqueued => 1,
|
|
job_id => $job_id
|
|
);
|
|
}
|
|
|
|
my (@reserve_loop, @over_loop);
|
|
# FIXME - Is priority => 0 useful? If yes it must be moved to waiting, otherwise we need to remove it from here.
|
|
my $holds = Koha::Holds->waiting->search({ priority => 0, ( $all_branches ? () : ( branchcode => $default ) ) }, { order_by => ['waitingdate'] });
|
|
|
|
# get reserves for the branch we are logged into, or for all branches
|
|
|
|
my $today = Date_to_Days(&Today);
|
|
|
|
while ( my $hold = $holds->next ) {
|
|
next unless $hold->waitingdate;
|
|
|
|
my ( $expire_year, $expire_month, $expire_day ) = split (/-/, $hold->expirationdate);
|
|
my $calcDate = Date_to_Days( $expire_year, $expire_month, $expire_day );
|
|
|
|
if ($today > $calcDate) {
|
|
if ($cancelall) {
|
|
my $res = cancel( $hold->item->itemnumber, $hold->borrowernumber, $hold->item->holdingbranch, $hold->item->homebranch, !$transfer_when_cancel_all );
|
|
push @cancel_result, $res if $res;
|
|
next;
|
|
} else {
|
|
push @over_loop, $hold;
|
|
}
|
|
}else{
|
|
push @reserve_loop, $hold;
|
|
}
|
|
|
|
}
|
|
|
|
$template->param(cancel_result => \@cancel_result) if @cancel_result;
|
|
|
|
$template->param(
|
|
reserveloop => \@reserve_loop,
|
|
reservecount => scalar @reserve_loop,
|
|
overloop => \@over_loop,
|
|
overcount => scalar @over_loop,
|
|
show_date => output_pref({ dt => dt_from_string, dateformat => 'iso', dateonly => 1 }),
|
|
tab => $tab,
|
|
);
|
|
|
|
# Checking if there is a Fast Cataloging Framework
|
|
$template->param( fast_cataloging => 1 ) if Koha::BiblioFrameworks->find( 'FA' );
|
|
|
|
if ($item && $tab eq 'holdsover' && !@cancel_result) {
|
|
print $input->redirect("/cgi-bin/koha/circ/waitingreserves.pl#holdsover");
|
|
} elsif ($cancelall) {
|
|
print $input->redirect("/cgi-bin/koha/circ/waitingreserves.pl");
|
|
} else {
|
|
output_html_with_http_headers $input, $cookie, $template->output;
|
|
}
|
|
|
|
exit;
|
|
|
|
sub cancel {
|
|
my ($item, $borrowernumber, $fbr, $tbr, $skip_transfers ) = @_;
|
|
|
|
my $transfer = $fbr ne $tbr; # XXX && !$nextreservinfo;
|
|
|
|
return if $transfer && $skip_transfers;
|
|
|
|
my ( $messages, $nextreservinfo ) = ModReserveCancelAll( $item, $borrowernumber );
|
|
|
|
# if the document is not in his homebranch location and there is not reservation after, we transfer it
|
|
if ($transfer && !$nextreservinfo) {
|
|
ModItemTransfer( $item, $fbr, $tbr, 'CancelReserve' );
|
|
}
|
|
# if we have a result
|
|
if ($nextreservinfo) {
|
|
my %res;
|
|
my $patron = Koha::Patrons->find( $nextreservinfo );
|
|
my $title = Koha::Items->find( $item )->biblio->title;
|
|
if ( $messages->{'transfert'} ) {
|
|
$res{messagetransfert} = $messages->{'transfert'};
|
|
$res{branchcode} = $messages->{'transfert'};
|
|
}
|
|
|
|
$res{message} = 1;
|
|
$res{nextreservnumber} = $nextreservinfo;
|
|
$res{nextreservsurname} = $patron->surname;
|
|
$res{nextreservfirstname} = $patron->firstname;
|
|
$res{nextreservitem} = $item;
|
|
$res{nextreservtitle} = $title;
|
|
$res{waiting} = $messages->{'waiting'} ? 1 : 0;
|
|
|
|
return \%res;
|
|
}
|
|
|
|
return;
|
|
}
|