From c60c8f0821a89b2914124b77ef6ae80421940009 Mon Sep 17 00:00:00 2001 From: Kyle M Hall Date: Fri, 16 Oct 2015 10:44:11 -0400 Subject: [PATCH] Bug 14310 - Suspend and resume indvidual holds from patron holds table This enhancment adds the ability to suspend and resume individual holds from the holds table on circulation.pl and moremember.pl. The interface is inspired/cribbed from the same feature already available in the opac. Test Plan: 1) Apply this patch 2) Find a patron with holds 3) Suspend a hold with no resume date 4) Resume the suspended hold 5) Suspend a hold with a resume date 6) Resume the suspended hold Signed-off-by: Kyle M Hall Signed-off-by: Cathi Wiggins Signed-off-by: Megan Wianecki Signed-off-by: Jonathan Druart Signed-off-by: Brendan A Gallagher --- Koha/Hold.pm | 41 +++++++++ koha-tmpl/intranet-tmpl/prog/en/js/holds.js | 87 +++++++++++++++++-- .../prog/en/modules/circ/circulation.tt | 1 + .../prog/en/modules/members/moremember.tt | 1 + svc/hold/resume | 48 ++++++++++ svc/hold/suspend | 51 +++++++++++ 6 files changed, 221 insertions(+), 8 deletions(-) create mode 100644 svc/hold/resume create mode 100644 svc/hold/suspend diff --git a/Koha/Hold.pm b/Koha/Hold.pm index 871f3e1e6e..707622dff0 100644 --- a/Koha/Hold.pm +++ b/Koha/Hold.pm @@ -41,6 +41,47 @@ Koha::Hold - Koha Hold object class =cut +=head3 suspend_hold + +my $hold = $hold->suspend_hold( $suspend_until_dt ); + +=cut + +sub suspend_hold { + my ( $self, $dt ) = @_; + + if ( $self->is_waiting ) { # We can't suspend waiting holds + carp "Unable to suspend waiting hold!"; + return $self; + } + + $dt ||= undef; + + $self->suspend(1); + $self->suspend_until( $dt ); + + $self->store(); + + return $self; +} + +=head3 resume + +my $hold = $hold->resume(); + +=cut + +sub resume { + my ( $self ) = @_; + + $self->suspend(0); + $self->suspend_until( undef ); + + $self->store(); + + return $self; +} + =head3 waiting_expires_on Returns a DateTime for the date a waiting holds expires on. diff --git a/koha-tmpl/intranet-tmpl/prog/en/js/holds.js b/koha-tmpl/intranet-tmpl/prog/en/js/holds.js index 077b3b605c..bf7ea44da8 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/js/holds.js +++ b/koha-tmpl/intranet-tmpl/prog/en/js/holds.js @@ -8,11 +8,12 @@ $(document).ready(function() { if ( $("#holds-tab").parent().hasClass('ui-state-active') ) { load_holds_table() } function load_holds_table() { + var holds = new Array(); if ( ! holdsTable ) { holdsTable = $("#holds-table").dataTable({ "bAutoWidth": false, "sDom": "rt", - "aoColumns": [ + "columns": [ { "mDataProp": "reservedate_formatted" }, @@ -119,21 +120,53 @@ $(document).ready(function() { + "" + ""; } + }, + { + "bSortable": false, + "mDataProp": function( oObj ) { + holds[oObj.reserve_id] = oObj; //Store holds for later use + + if ( oObj.found ) { + return ""; + } else if ( oObj.suspend == 1 ) { + return "" + + " " + _("Resume") + ""; + } else { + return "" + + " " + _("Suspend") + ""; + } + } } ], "bPaginate": false, "bProcessing": true, "bServerSide": false, - "sAjaxSource": '/cgi-bin/koha/svc/holds', - "fnServerData": function ( sSource, aoData, fnCallback ) { - aoData.push( { "name": "borrowernumber", "value": borrowernumber } ); - - $.getJSON( sSource, aoData, function (json) { - fnCallback(json) - } ); + "ajax": { + "url": '/cgi-bin/koha/svc/holds', + "data": function ( d ) { + d.borrowernumber = borrowernumber; + } }, }); + $('#holds-table').on( 'draw.dt', function () { + $(".hold-suspend").on( "click", function() { + var id = $(this).attr("id").replace("suspend", ""); + var hold = holds[id]; + $("#suspend-modal-title").html( hold.title ); + $("#suspend-modal-reserve_id").val( hold.reserve_id ); + $('#suspend-modal').modal('show'); + }); + + $(".hold-resume").on( "click", function() { + var id = $(this).attr("id").replace("resume", ""); + var hold = holds[id]; + $.post('/cgi-bin/koha/svc/hold/resume', { "reserve_id": hold.reserve_id }, function( data ){ + holdsTable.api().ajax.reload(); + }); + }); + }); + if ( $("#holds-table").length ) { $("#holds-table_processing").position({ of: $( "#holds-table" ), @@ -142,4 +175,42 @@ $(document).ready(function() { } } } + + $("body").append("\ + \ + "); + + $("#suspend-modal-until").datepicker({ minDate: 1 }); // Require that "until date" be in the future + $("#suspend-modal-clear-date").on( "click", function() { $("#suspend-modal-until").val(""); } ); + + $("#suspend-modal-submit").on( "click", function( e ) { + e.preventDefault(); + $.post('/cgi-bin/koha/svc/hold/suspend', $('#suspend-modal-form').serialize(), function( data ){ + $('#suspend-modal').modal('hide'); + holdsTable.api().ajax.reload(); + }); + }); + }); diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt index 78152d11df..3c165012c3 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt @@ -937,6 +937,7 @@ No patron matched [% message %] Expiration Priority Delete? + Suspend? diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt index a44fb3c232..30cda467e6 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt @@ -495,6 +495,7 @@ function validate1(date) { Expiration Priority Delete? + Suspend? diff --git a/svc/hold/resume b/svc/hold/resume new file mode 100644 index 0000000000..03cd017d84 --- /dev/null +++ b/svc/hold/resume @@ -0,0 +1,48 @@ +#!/usr/bin/perl + +# Copyright 2015 ByWater Solutions +# +# 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, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use CGI; +use JSON qw(to_json); + +use C4::Context; +use C4::Auth qw(check_cookie_auth); +use Koha::DateUtils qw(dt_from_string); +use Koha::Holds; + +my $input = new CGI; + +my ( $auth_status, $sessionID ) = + check_cookie_auth( $input->cookie('CGISESSID'), + { circulate => 'circulate_remaining_permissions' } ); + +if ( $auth_status ne "ok" ) { + exit 0; +} + +binmode STDOUT, ":encoding(UTF-8)"; +print $input->header( -type => 'text/plain', -charset => 'UTF-8' ); + +my $reserve_id = $input->param('reserve_id'); + +my $hold = Koha::Holds->find( $reserve_id ); +$hold->resume(); + +print to_json( { success => !$hold->suspend() } ); diff --git a/svc/hold/suspend b/svc/hold/suspend new file mode 100644 index 0000000000..880e41aee5 --- /dev/null +++ b/svc/hold/suspend @@ -0,0 +1,51 @@ +#!/usr/bin/perl + +# Copyright 2015 ByWater Solutions +# +# 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, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use CGI; +use JSON qw(to_json); + +use C4::Context; +use C4::Auth qw(check_cookie_auth); +use Koha::DateUtils qw(dt_from_string); +use Koha::Holds; + +my $input = new CGI; + +my ( $auth_status, $sessionID ) = + check_cookie_auth( $input->cookie('CGISESSID'), + { circulate => 'circulate_remaining_permissions' } ); + +if ( $auth_status ne "ok" ) { + exit 0; +} + +binmode STDOUT, ":encoding(UTF-8)"; +print $input->header( -type => 'text/plain', -charset => 'UTF-8' ); + +my $reserve_id = $input->param('reserve_id'); + +my $suspend_until = $input->param('suspend_until') || undef; +$suspend_until = dt_from_string( $suspend_until ) if $suspend_until; + +my $hold = Koha::Holds->find( $reserve_id ); +$hold->suspend_hold( $suspend_until ); + +print to_json( { success => $hold->suspend() } ); -- 2.39.2