Bugzilla – Attachment 92748 Details for
Bug 19618
Add 'Club Holds' feature
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 19618: Add ability to place holds for members of a club in intranet
Bug-19618-Add-ability-to-place-holds-for-members-o.patch (text/plain), 45.11 KB, created by
Martin Renvoize (ashimema)
on 2019-09-12 15:59:06 UTC
(
hide
)
Description:
Bug 19618: Add ability to place holds for members of a club in intranet
Filename:
MIME Type:
Creator:
Martin Renvoize (ashimema)
Created:
2019-09-12 15:59:06 UTC
Size:
45.11 KB
patch
obsolete
>From da5f8742f4b3cbb0eaf8601176386b0ed7f327d1 Mon Sep 17 00:00:00 2001 >From: Agustin Moyano <agustinmoyano@theke.io> >Date: Thu, 5 Sep 2019 14:13:27 -0300 >Subject: [PATCH] Bug 19618: Add ability to place holds for members of a club > in intranet > >This patch adds the ability to place a hold for each member of a club in random order. > >To test: >1) apply this patch >2) create 2 clubs, (club names should have some part in common, and some part different for each other) >3) in one of them add at least 6 members >4) enter patron clubs management and click on "Actions" button >SUCCESS.1 => club with members has a new action called "search to hold" >5) click on search to hold >SUCCESS.2 => in the list of bilios there appears an action called "Place hold for <club name>" >6) click on "Place hold for <club name>" >SUCCESS.3 => a new window appears where you can select pickup location (defaults to club's library, if any), and the list of members. >7) go back to the list of bilios in the catalog and click on "Forget <club name>" >8) click on "Holds" action of any biblio >SUCCESS.4 => a search box appears with two tabs: Patrons and Clubs >9) click on Clubs tab and search by the common part of clubs names >SUCCESS.5 => a list of clubs that matches the search appears. If you click on any of them, the same page as SUCCESS.3 appears. >10) go back to the search box in SUCCESS.4 and search by the different part of the name. >SUCCESS.6 => because there is only one club that matches search criteria, the same page as SUCCESS.3 appears; >11) Sign off > >Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com> >--- > Koha/Club/Enrollment.pm | 16 ++ > catalogue/search.pl | 8 + > .../prog/en/includes/clubs-table.inc | 111 ++++++++ > .../prog/en/modules/catalogue/results.tt | 37 ++- > .../prog/en/modules/clubs/clubs.tt | 95 +------ > .../prog/en/modules/members/moremember.tt | 2 +- > .../prog/en/modules/reserve/request.tt | 268 ++++++++++++++++-- > reserve/request.pl | 73 ++++- > 8 files changed, 492 insertions(+), 118 deletions(-) > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/includes/clubs-table.inc > >diff --git a/Koha/Club/Enrollment.pm b/Koha/Club/Enrollment.pm >index 168f55bca6..2b4e627a77 100644 >--- a/Koha/Club/Enrollment.pm >+++ b/Koha/Club/Enrollment.pm >@@ -24,6 +24,8 @@ use Carp; > use Koha::Database; > use Koha::Clubs; > use Koha::Patrons; >+use Koha::DateUtils qw(dt_from_string); >+use DateTime; > > use base qw(Koha::Object); > >@@ -71,6 +73,20 @@ sub patron { > return scalar Koha::Patrons->find( $self->borrowernumber() ); > } > >+=head3 is_canceled >+Determines if enrollment is canceled >+=cut >+ >+sub is_canceled { >+ my ( $self ) = @_; >+ >+ return 0 unless $self->date_canceled; >+ my $today = dt_from_string; >+ my $date_canceled = dt_from_string( $self->date_canceled ); >+ >+ return DateTime->compare($date_canceled, $today) < 1; >+} >+ > =head3 type > > =cut >diff --git a/catalogue/search.pl b/catalogue/search.pl >index a3a7015efc..8f460de8e3 100755 >--- a/catalogue/search.pl >+++ b/catalogue/search.pl >@@ -203,6 +203,14 @@ if($cgi->cookie("holdfor")){ > ); > } > >+if($cgi->cookie("holdforclub")){ >+ my $holdfor_club = Koha::Clubs->find( $cgi->cookie("holdforclub") ); >+ $template->param( >+ holdforclub => $cgi->cookie("holdforclub"), >+ holdforclub_name => $holdfor_club->name, >+ ); >+} >+ > # get biblionumbers stored in the cart > my @cart_list; > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/clubs-table.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/clubs-table.inc >new file mode 100644 >index 0000000000..62027b1a38 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/clubs-table.inc >@@ -0,0 +1,111 @@ >+<table id="clubs-table"> >+ <thead> >+ <tr> >+ <th>Name</th> >+ <th>Template</th> >+ <th>Description</th> >+ [% UNLESS destination == 'holds' %] >+ <th>Public enrollment</th> >+ <th>Email required</th> >+ [% END %] >+ <th>Library</th> >+ <th>Start date</th> >+ <th>End date</th> >+ <th>Enrolled patrons</th> >+ [% UNLESS destination == 'holds' %] >+ <th> </th> >+ [% END %] >+ </tr> >+ </thead> >+ <tbody> >+ [% FOREACH c IN clubs %] >+ [% IF destination == 'holds' %] >+ [% IF multi_hold %] >+ [% SET data_url = "/cgi-bin/koha/reserve/request.pl?club=" _ c.id _ "&multi_hold=1&biblionumbers=" _ biblionumbers %] >+ [% ELSE %] >+ [% SET data_url = "/cgi-bin/koha/reserve/request.pl?club=" _ c.id _ "&biblionumber=" _ biblionumber %] >+ [% END %] >+ <tr class="clickable" data-url="[% data_url | html %]"> >+ [% ELSE %] >+ <tr> >+ [% END %] >+ <td>[% c.name | html %]</td> >+ <td>[% c.club_template.name | html %]</td> >+ <td>[% c.description | html %]</td> >+ [% UNLESS destination == 'holds' %] >+ <td> >+ [% IF c.club_template.is_enrollable_from_opac %] >+ Yes >+ [% ELSE %] >+ No >+ [% END %] >+ </td> >+ <td> >+ [% IF c.club_template.is_email_required %] >+ Yes >+ [% ELSE %] >+ No >+ [% END %] >+ </td> >+ [% END %] >+ <td>[% Branches.GetName( c.branchcode ) | html %]</td> >+ <td> >+ [% IF c.date_start %] >+ [% c.date_start | $KohaDates %] >+ [% END %] >+ </td> >+ <td> >+ [% IF c.date_end %] >+ [% c.date_end | $KohaDates %] >+ [% END %] >+ </td> >+ <td> >+ [% c.club_enrollments.count | html %] >+ </td> >+ [% UNLESS destination == 'holds' %] >+ <td class="actions"> >+ <div class="dropdown"> >+ <a class="btn btn-default btn-xs dropdown-toggle" id="clubactions[% c.id | html %]" role="button" data-toggle="dropdown" href="#"> >+ Actions <b class="caret"></b> >+ </a> >+ <ul class="dropdown-menu pull-right" role="menu" aria-labelledby="clubactions[% c.id | html %]"> >+ [% IF ( c.club_enrollments.count ) %] >+ <li> >+ <a href="club-enrollments.pl?id=[% c.id | uri %]"> >+ <i class="fa fa-list-ul"></i> Enrollments >+ </a> >+ </li> >+ [% ELSE %] >+ <li class="disabled"> >+ <a href="club-enrollments.pl?id=[% c.id | uri %]"> >+ <i class="fa fa-list-ul"></i> Enrollments >+ </a> >+ </li> >+ [% END %] >+ [% IF CAN_user_clubs_edit_clubs %] >+ <li> >+ <a href="clubs-add-modify.pl?id=[% c.id | uri %]"> >+ <i class="fa fa-pencil"></i> Edit >+ </a> >+ </li> >+ <li> >+ <a href="#" onclick='ConfirmDeleteClub([% c.id | html %], "[% c.name | html %]", $(this) ); return false;'> >+ <i class="fa fa-trash"></i> Delete >+ </a> >+ </li> >+ [% END %] >+ [% IF ( c.club_enrollments.count ) %] >+ <li> >+ <a href="#" onclick="SearchToHold([% c.id | html %])"> >+ <i class="fa fa-search"></i> Search to hold >+ </a> >+ </li> >+ [% END %] >+ </ul> >+ </div> >+ </td> >+ [% END %] >+ </tr> >+ [% END %] >+ </tbody> >+</table> <!-- /.clubs-table --> >\ No newline at end of file >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt >index c8af35f986..3d9bbe9f24 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/results.tt >@@ -123,7 +123,7 @@ > [% END # /IF virtualshelves %] > > [% IF ( CAN_user_reserveforothers_place_holds && DisplayMultiPlaceHold ) %] >- [% IF ( holdfor ) %] >+ [% IF ( holdfor or holdforclub ) %] > <div id="placeholdc" class="btn-group"> > <button class="btn btn-default btn-xs placehold"><i class="fa fa-sticky-note-o"></i> Place hold</button> > <button class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown"> >@@ -131,9 +131,16 @@ > </button> > <ul class="dropdown-menu"> > <li><a href="#" class="placehold">Place hold</a></li> >- <li><a href="#" class="placeholdfor">Place hold for [% holdfor_firstname | html %] [% holdfor_surname | html %] ([% holdfor_cardnumber | html %])</a></li> >- <li class="divider"></li> >- <li><a href="#" id="forgetholdfor">Forget [% holdfor_firstname | html %] [% holdfor_surname | html %] ([% holdfor_cardnumber | html %])</a></li> >+ [% IF holdfor %] >+ <li><a href="#" class="placeholdfor">Place hold for [% holdfor_firstname | html %] [% holdfor_surname | html %] ([% holdfor_cardnumber | html %])</a></li> >+ <li class="divider"></li> >+ <li><a href="#" id="forgetholdfor">Forget [% holdfor_firstname | html %] [% holdfor_surname | html %] ([% holdfor_cardnumber | html %])</a></li> >+ [% END %] >+ [% IF holdforclub %] >+ <li><a href="#" class="placeholdforclub">Place hold for [% holdforclub_name | html %]</a></li> >+ <li class="divider"></li> >+ <li><a href="#" id="forgetholdforclub">Forget [% holdforclub_name | html %]</a></li> >+ [% END %] > </ul> > </div> > [% ELSE %] >@@ -422,6 +429,7 @@ > [% IF CAN_user_reserveforothers_place_holds %] > <a id="reserve_[% SEARCH_RESULT.biblionumber | html %]" href="/cgi-bin/koha/reserve/request.pl?biblionumber=[% SEARCH_RESULT.biblionumber | html %]">Holds ([% Biblio.HoldsCount( SEARCH_RESULT.biblionumber ) | html %])</a> > [% IF ( holdfor ) %] <span class="holdforlink">| <a href="/cgi-bin/koha/reserve/request.pl?biblionumber=[% SEARCH_RESULT.biblionumber | uri %]&findborrower=[% holdfor_cardnumber | uri %]">Place hold for [% holdfor_firstname | html %] [% holdfor_surname | html %] ([% holdfor_cardnumber | html %])</a></span>[% END %] >+ [% IF ( holdforclub ) %] <span class="holdforlink">| <a href="/cgi-bin/koha/reserve/request.pl?biblionumber=[% SEARCH_RESULT.biblionumber | uri %]&club=[% holdforclub | uri %]">Place hold for [% holdforclub_name | html %]</a></span>[% END %] > [% ELSE %] > Holds ([% Biblio.HoldsCount( SEARCH_RESULT.biblionumber ) | html %]) > [% END %] >@@ -617,6 +625,7 @@ > <!-- Value will be set here by placeHold() --> > <input id="hold_form_biblios" type="hidden" name="biblionumbers" value="" /> > <input type="hidden" name="findborrower" id="holdFor" value="" /> >+ <input type="hidden" name="club" id="holdForClub" value="" /> > <input type="hidden" name="multi_hold" value="1"/> > </form> > >@@ -713,6 +722,7 @@ > > $("#searchheader").on("click",".placehold", function(){ > $("#holdFor").val(""); >+ $("#holdForClub").val(""); > placeHold(); > $(".btn-group").removeClass("open"); > return false; >@@ -724,8 +734,14 @@ > return false; > }); > >- $("#forgetholdfor").click(function(){ >- forgetPatron(); >+ $(".placeholdforclub").click(function(){ >+ holdForClub(); >+ $(".btn-group").removeClass("open"); >+ return false; >+ }); >+ >+ $("#forgetholdfor, #forgetholdforclub").click(function(){ >+ forgetPatronAndClub(); > $(".btn-group").removeClass("open"); > return false; > }); >@@ -884,8 +900,9 @@ > return false; > } > >- function forgetPatron(){ >+ function forgetPatronAndClub(){ > $.removeCookie("holdfor", { path: '/' }); >+ $.removeCookie("holdforclub", { path: '/' }); > $(".holdforlink").remove(); > $("#placeholdc").html("<a class=\"btn btn-default btn-xs placehold\" href=\"#\"><i class=\"fa fa-sticky-note-o\"></i> "+_("Place hold")+"</a>"); > } >@@ -936,6 +953,7 @@ > > function holdfor(){ > $("#holdFor").val(""); >+ $("#holdForClub").val(""); > placeHold(); > } > >@@ -943,6 +961,11 @@ > $("#holdFor").val("[% holdfor_cardnumber | html %]"); > placeHold(); > } >+ >+ function holdForClub() { >+ $("#holdForClub").val("[% holdforclub | html %]"); >+ placeHold(); >+ } > </script> > [% END %] > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/clubs/clubs.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/clubs/clubs.tt >index 42d50ff41c..e4176a9da0 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/clubs/clubs.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/clubs/clubs.tt >@@ -120,93 +120,7 @@ > [% END %] > > [% IF clubs %] >- <table id="clubs-table"> >- <thead> >- <tr> >- <th>Name</th> >- <th>Template</th> >- <th>Description</th> >- <th>Public enrollment</th> >- <th>Email required</th> >- <th>Library</th> >- <th>Start date</th> >- <th>End date</th> >- <th>Enrolled patrons</th> >- <th> </th> >- </tr> >- </thead> >- <tbody> >- [% FOREACH c IN clubs %] >- <tr> >- <td>[% c.name | html %]</td> >- <td>[% c.club_template.name | html %]</td> >- <td>[% c.description | html %]</td> >- <td> >- [% IF c.club_template.is_enrollable_from_opac %] >- Yes >- [% ELSE %] >- No >- [% END %] >- </td> >- <td> >- [% IF c.club_template.is_email_required %] >- Yes >- [% ELSE %] >- No >- [% END %] >- </td> >- <td>[% Branches.GetName( c.branchcode ) | html %]</td> >- <td> >- [% IF c.date_start %] >- [% c.date_start | $KohaDates %] >- [% END %] >- </td> >- <td> >- [% IF c.date_end %] >- [% c.date_end | $KohaDates %] >- [% END %] >- </td> >- <td> >- [% c.club_enrollments.count | html %] >- </td> >- <td class="actions"> >- <div class="dropdown"> >- <a class="btn btn-default btn-xs dropdown-toggle" id="clubactions[% c.id | html %]" role="button" data-toggle="dropdown" href="#"> >- Actions <b class="caret"></b> >- </a> >- <ul class="dropdown-menu pull-right" role="menu" aria-labelledby="clubactions[% c.id | html %]"> >- [% IF ( c.club_enrollments.count ) %] >- <li> >- <a href="club-enrollments.pl?id=[% c.id | uri %]"> >- <i class="fa fa-list-ul"></i> Enrollments >- </a> >- </li> >- [% ELSE %] >- <li class="disabled"> >- <a href="club-enrollments.pl?id=[% c.id | uri %]"> >- <i class="fa fa-list-ul"></i> Enrollments >- </a> >- </li> >- [% END %] >- [% IF CAN_user_clubs_edit_clubs %] >- <li> >- <a href="clubs-add-modify.pl?id=[% c.id | uri %]"> >- <i class="fa fa-pencil"></i> Edit >- </a> >- </li> >- <li> >- <a href="#" onclick='ConfirmDeleteClub([% c.id | html %], "[% c.name | html %]", $(this) ); return false;'> >- <i class="fa fa-trash"></i> Delete >- </a> >- </li> >- [% END %] >- </ul> >- </div> >- </td> >- </tr> >- [% END %] >- </tbody> >- </table> <!-- /.clubs-table --> >+ [% INCLUDE 'clubs-table.inc' %] > [% ELSE %] > [% IF club_templates %] > <div class="dialog message">No clubs defined.</div> >@@ -282,6 +196,13 @@ > }); > } > } >+ >+ function SearchToHold(club_id) { >+ var date = new Date(); >+ date.setTime(date.getTime() + (10 * 60 * 1000)); >+ $.cookie("holdforclub", club_id, { path: "/", expires: date }); >+ location.href="/cgi-bin/koha/catalogue/search.pl"; >+ } > </script> > [% END %] > >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 4a046b614b..1cbc7afc6d 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt >@@ -870,7 +870,7 @@ > if ( $('#clubs-tab').length ) { > $('#clubs-tab-link').on('click', function() { > $('#clubs-tab').text(_("Loading...")); >- $('#clubs-tab').load('/cgi-bin/koha/clubs/patron-clubs-tab.pl?borrowernumber=[% borrowernumber | html %]'); >+ $('#clubs-tab').load('/cgi-bin/koha/clubs/patron-clubs-tab.pl?borrowernumber=[% patron.borrowernumber | html %]'); > }); > } > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt >index 91e4ebb6b5..5b0c482c20 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt >@@ -73,7 +73,7 @@ > <h1>Confirm holds</h1> > [% END %] > >- [% UNLESS patron OR patron.borrowernumber OR noitems %] >+ [% UNLESS club OR patron OR patron.borrowernumber OR noitems %] > [% IF ( messageborrower ) %] > <div class="dialog alert"> > <h3>Patron not found</h3> >@@ -81,30 +81,224 @@ > </div> > [% END %] > >- <form id="holds_patronsearch" action="request.pl?biblionumber=[% biblionumber | html %]" method="post"> >- <fieldset id="circ_holds_selectborrower" class="brief"> >- [% UNLESS borrowers %] >- <label for="patron">Patron: </label> >- <div class="hint">Enter patron card number or partial name:</div> >- <input type="text" size="40" id="patron" class="focus" name="findborrower" autocomplete="off" /> >- <input type="submit" value="Search" /> >- [% IF multi_hold %] >- <input type="hidden" name="multi_hold" value="[% multi_hold | html %]"/> >- <input type="hidden" name="biblionumbers" value="[% biblionumbers | html %]"/> >- [% ELSE %] >- <input type="hidden" name="biblionumber" value="[% biblionumber | html %]" /> >- [% END %] >- [% ELSE %] >+ [% IF ( messageclub ) %] >+ <div class="dialog alert"> >+ <h3>Club not found</h3> >+ <p>No club with this name, please, try another</p> >+ </div> >+ [% END %] >+ <fieldset class="brief"> >+ <label>Seach Patrons or clubs</label> >+ <div id="circ_holds_select"> >+ <ul class="nav nav-tabs" role="tablist"> >+ <li role="presentation"><a href="#holds_patronsearch_pane" aria-controls="holds_patronsearch_pane" role="tab" data-toggle="tab">Patrons</a></li> >+ <li role="presentation"><a href="#holds_clubsearch_pane" aria-controls="holds_clubsearch_pane" role="tab" data-toggle="tab">Clubs</a></li> >+ </ul> >+ <div class="tab-content"> >+ <div role="tabpanel" class="tab-pane" id="holds_patronsearch_pane"> >+ <form id="holds_patronsearch" action="request.pl?biblionumber=[% biblionumber | html %]" method="post"> >+ <div class="hint">Enter patron card number or partial name:</div> >+ <input type="text" size="40" id="patron" class="focus" name="findborrower" autocomplete="off" /> >+ <input type="submit" value="Search" /> >+ [% IF multi_hold %] >+ <input type="hidden" name="multi_hold" value="[% multi_hold | html %]"/> >+ <input type="hidden" name="biblionumbers" value="[% biblionumbers | html %]"/> >+ [% ELSE %] >+ <input type="hidden" name="biblionumber" value="[% biblionumber | html %]" /> >+ [% END %] >+ >+ [% IF ( multi_hold ) %] >+ <input type="hidden" name="multi_hold" value="[% multi_hold | html %]"/> >+ <input type="hidden" name="biblionumbers" value="[% biblionumbers | html %]"/> >+ [% END %] >+ </form> <!-- /#holds_patronsearch --> >+ </div> >+ <div role="tabpanel" class="tab-pane" id="holds_clubsearch_pane"> >+ <form id="holds_clubsearch" action="request.pl?biblionumber=[% biblionumber | html %]" method="post"> >+ <div class="hint">Enter club id or partial name:</div> >+ <input type="text" size="40" id="club" class="focus" name="findclub" autocomplete="off" /> >+ <input type="submit" value="Search" /> >+ [% IF multi_hold %] >+ <input type="hidden" name="multi_hold" value="[% multi_hold | html %]"/> >+ <input type="hidden" name="biblionumbers" value="[% biblionumbers | html %]"/> >+ [% ELSE %] >+ <input type="hidden" name="biblionumber" value="[% biblionumber | html %]" /> >+ [% END %] >+ >+ [% IF ( multi_hold ) %] >+ <input type="hidden" name="multi_hold" value="[% multi_hold | html %]"/> >+ <input type="hidden" name="biblionumbers" value="[% biblionumbers | html %]"/> >+ [% END %] >+ </form> <!-- /#holds_patronsearch --> >+ </div> >+ </div> >+ </div> >+ <p> >+ [% IF borrowers %] > [% INCLUDE 'circ-patron-search-results.inc' destination = "holds" %] >+ [% ELSIF clubs %] >+ [% INCLUDE 'clubs-table.inc' destination = "holds" %] > [% END %] >- </fieldset> <!-- /#circ_holds_selectborrower --> >+ </p> >+ </fieldset> >+ [% ELSIF club %] >+ <div class="dialog alert hide clubalert"> >+ </div> >+ <fieldset class="rows"> >+ <legend>Hold details</legend> >+ <form action="/api/v1/clubs/[% club.id | html %]/holds" method="post" name="form" id="club-request-form"> > >- [% IF ( multi_hold ) %] >- <input type="hidden" name="multi_hold" value="[% multi_hold | html %]"/> >- <input type="hidden" name="biblionumbers" value="[% biblionumbers | html %]"/> >- [% END %] >- </form> <!-- /#holds_patronsearch --> >+ [% IF ( multi_hold ) %] >+ <input type="hidden" name="multi_hold" value="[% multi_hold | html %]"/> >+ <input type="hidden" name="biblionumbers" id="multi_hold_bibs" value="[% biblionumbers | html %]"/> >+ <input type="hidden" name="bad_bibs" id="bad_bibs" value=""/> >+ <input type="hidden" name="request" value="any"/> >+ [% FOREACH biblioloo IN biblioloop %] >+ <input type="hidden" name="title_[% biblioloo.biblionumber | html %]" value="[% biblioloo.title | html %]"/> >+ <input type="hidden" name="rank_[% biblioloo.biblionumber | html %]" value="[% biblioloo.rank | html %]"/> >+ [% END %] >+ [% ELSE %] >+ <input type="hidden" name="biblionumber" value="[% biblionumber | html %]" /> >+ <input type="hidden" name="title" value="[% biblio.title | html %]" /> >+ <input type="hidden" name="rank-request" value="[% fixedRank | html %]" /> >+ [% END # /IF multi_hold %] >+ <ol> >+ <li> >+ <span class="label">Club: </span> [% club.name | html %] >+ </li> >+ <li> >+ <span class="label">Description: </span> [% club.description | html %] >+ </li> >+ <li> >+ <label for="pickup">Pickup at:</label> >+ <select name="pickup" size="1" id="pickup"> >+ [% PROCESS options_for_libraries libraries => Branches.all({ selected => club.branchcode, search_params => { pickup_location => 1 } }) %] >+ </select> >+ </li> >+ </ol> >+ <h2 style="padding: 0 1em;">Members</h2> >+ <ol> >+ [% FOREACH member IN members %] >+ [% SET patron = member.patron %] >+ <li style="padding: 0.5em 1em;"> >+ <div><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% patron.borrowernumber | uri %]">[% patron.firstname | html %] [% patron.surname | html %] ([% patron.cardnumber | html %])</a></div> >+ [% IF member.exceeded_maxreserves %] >+ <div> >+ <i class="fa fa-error"></i> >+ <strong>Too many holds: </strong> Patron can only place a maximum of [% maxreserves | html %] total holds. >+ </div> >+ [% END %] >+ [% IF ( member.expiry ) %] >+ <div> >+ <i class="fa fa-warning"></i> >+ <strong>Account has expired</strong> >+ </div> >+ [% END %] >+ [% IF patron.is_debarred %] >+ <div> >+ <i class="fa fa-warning"></i> >+ <strong>Patron has restrictions</strong> >+ </div> >+ [% END %] >+ [% IF amount_outstanding && Koha.Preference('maxoutstanding') && amount_outstanding > Koha.Preference('maxoutstanding') %] >+ <div> >+ <i class="fa fa-warning"></i> >+ <strong>Patron has outstanding fines: [% member.amount_outstanding | $Price %]</strong> >+ </div> >+ [% END %] > >+ [% IF ( member.diffbranch ) %] >+ <div> >+ <i class="fa fa-warning"></i> >+ <strong>Pickup library is different.</strong> Patron's home library: ([% Branches.GetName(patron.branchcode) | html %] / [% patron.branchcode | html %] ) >+ </div> >+ [% END %] >+ </li> >+ [% END %] >+ </ol> >+ [% UNLESS ( multi_hold ) %] >+ <fieldset class="action"> >+ <input type="submit" value="Place hold" /> >+ </fieldset> >+ [% ELSE %] >+ <table id="requesttitles"> >+ <tr> >+ <th> </th> >+ <th>Title</th> >+ [% UNLESS ( item_level_itypes ) %] >+ <th>Item type</th> >+ [% END %] >+ <th>Priority</th> >+ <th>Information</th> >+ </tr> >+ [% FOREACH biblioloo IN biblioloop %] >+ [% IF ( biblioloo.warn ) %] >+ <tr class="onissue"> >+ [% ELSE %] >+ <tr> >+ [% END %] >+ <td> >+ [% UNLESS ( biblioloo.warn ) %] >+ <input class="multi_hold_item_checkbox" type="checkbox" checked="checked" title="[% biblioloo.biblionumber | html %]"/> >+ </td> >+ [% END %] >+ <td> >+ <ul> >+ <li> >+ <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% biblioloo.biblionumber | uri %]">[% biblioloo.title | html %]</a> >+ </li> >+ [% IF ( biblioloo.publicationyear ) %] >+ <li> >+ <span class="label">Publication year:</span> [% biblioloo.publicationyear | html %] >+ </li> >+ [% END %] >+ </ul> >+ [% IF ( biblioloo.warn ) %] >+ <span class="not_holdable" title="[% biblioloo.biblionumber | html %]"></span> >+ [% END %] >+ </td> >+ [% UNLESS ( item_level_itypes ) %] >+ <td> >+ <img src="[% biblioloo.imageurl | html %]" alt="[% biblioloo.itypename | html %]" title="[% biblioloo.itypename | html %]" /> >+ </td> >+ [% END %] >+ <td>[% biblioloo.rank | html %]</td> >+ <td> >+ [% IF ( biblioloo.checked_previously ) %] >+ <span>Patron has previously checked out this title</span><br/> >+ [% END %] >+ [% IF ( biblioloo.alreadyres ) %] >+ <ul> >+ [% ELSE %] >+ [% IF ( biblioloo.none_avail ) %] >+ <ul> >+ [% END %] >+ [% END %] >+ >+ [% IF ( biblioloo.alreadyres ) %] >+ <li> >+ <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% patron.borrowernumber | uri %]">[% patron.firstname | html %] [% patron.surname | html %]</a> >+ <strong>already has a hold</strong> on this item >+ </li> >+ [% END %] >+ [% IF ( biblioloo.none_avail ) %] >+ <li> <strong>No items are available</strong> to be placed on hold</li> >+ [% END %] >+ >+ [% IF ( biblioloo.alreadyres ) %] >+ </ul> >+ [% ELSE %] >+ [% IF ( biblioloo.none_avail ) %] >+ </ul> >+ [% END %] >+ [% END %] >+ </td> >+ </tr> >+ [% END # /FOREACH biblioloo %] >+ </table> <!-- /#requesttitles --> >+ [% END %] >+ </form> >+ </fieldset> > [% ELSIF NOT noitems # /UNLESS patron %] > > [% IF ( checked_previously && !multi_hold ) %] >@@ -183,7 +377,7 @@ > > <fieldset class="rows"> > <legend>Hold details</legend> >- <form action="placerequest.pl" method="post" name="form" id="hold-request-form"> >+ <form action="/api/v1/holds" method="post" name="form" id="hold-request-form"> > > <input type="hidden" name="borrowernumber" value="[% patron.borrowernumber | html %]" /> > <input type="hidden" name="type" value="str8" /> >@@ -752,6 +946,11 @@ > columns_settings_borrowers_table = [% ColumnsSettings.GetColumns( 'circ', 'circulation', 'table_borrowers', 'json' ) | $raw %] > > $(document).ready(function() { >+ [% UNLESS clubs %] >+ $('#circ_holds_select').tabs({active: 0}); >+ [% ELSE %] >+ $('#circ_holds_select').tabs({active: 1}); >+ [% END %] > function ToggleHoldsToPlace() { > if ( $("#requestany").prop('checked') ) { > $("#holds_to_place_count").prop('disabled', false); >@@ -793,6 +992,31 @@ > "margin-right":"0em" > }); > >+ $("#club-request-form").on("submit", function() { >+ let $t = $(this); >+ $('.clubalert').addClass('hide'); >+ let options = { >+ url: $t.attr('action'), >+ method: $t.attr('method').toUpperCase(), >+ contentType: 'application/json', >+ data: JSON.stringify({ >+ biblio_id: biblionumber, >+ pickup_library_id: $('select[name="pickup"]').val() >+ }) >+ }; >+ if($('input[name="checkitem"]:checked').length) >+ options.data.item_id = $('input[name="checkitem"]:checked').val(); >+ $.ajax(options) >+ .then(function(result) { >+ let url = 'request.pl?biblionumber='+biblionumber+($('input[name="multi_hold"]').length && $('input[name="multi_hold"]').val()?'&multi_hold=1':''); >+ document.location = url; >+ }) >+ .fail(function(err) { >+ $('.clubalert').removeClass('hide').html(err.responseJSON.error); >+ }); >+ return false; >+ }); >+ > [% UNLESS ( multi_hold ) %] > $("#hold-request-form").on("submit", function(){ > return check(); >diff --git a/reserve/request.pl b/reserve/request.pl >index 49ea545826..c7832434a3 100755 >--- a/reserve/request.pl >+++ b/reserve/request.pl >@@ -53,6 +53,7 @@ use Koha::Items; > use Koha::ItemTypes; > use Koha::Libraries; > use Koha::Patrons; >+use Koha::Clubs; > > my $dbh = C4::Context->dbh; > my $input = new CGI; >@@ -75,8 +76,12 @@ my $itemtypes = { map { $_->{itemtype} => $_ } @{ Koha::ItemTypes->search_with_l > my $findborrower = $input->param('findborrower'); > $findborrower = '' unless defined $findborrower; > $findborrower =~ s|,| |g; >+my $findclub = $input->param('findclub'); >+$findclub = '' unless defined $findclub && !$findborrower; > my $borrowernumber_hold = $input->param('borrowernumber') || ''; >+my $club_hold = $input->param('club')||''; > my $messageborrower; >+my $messageclub; > my $warnings; > my $messages; > my $exceeded_maxreserves; >@@ -135,6 +140,25 @@ if ($findborrower) { > } > } > >+if($findclub) { >+ my $club = Koha::Clubs->find( { name => $findclub } ); >+ if( $club ) { >+ $club_hold = $club->id; >+ } else { >+ my @clubs = Koha::Clubs->search( [ >+ { name => { like => '%'.$findclub.'%' } }, >+ { description => { like => '%'.$findclub.'%' } } >+ ] ); >+ if( scalar @clubs == 1 ) { >+ $club_hold = $clubs[0]->id; >+ } elsif ( @clubs ) { >+ $template->param( clubs => \@clubs ); >+ } else { >+ $messageclub = "'$findclub'"; >+ } >+ } >+} >+ > my @biblionumbers = (); > my $biblionumber = $input->param('biblionumber'); > my $biblionumbers = $input->param('biblionumbers'); >@@ -203,7 +227,54 @@ if ($borrowernumber_hold && !$action) { > ); > } > >-$template->param( messageborrower => $messageborrower ); >+if ($club_hold && !$borrowernumber_hold && !$action) { >+ my $club = Koha::Clubs->find($club_hold); >+ >+ my $enrollments = $club->club_enrollments; >+ >+ my $maxreserves = C4::Context->preference('maxreserves'); >+ my $new_reserves_count = scalar( @biblionumbers ); >+ >+ my @members; >+ >+ while(my $enrollment = $enrollments->next) { >+ next if $enrollment->is_canceled; >+ my $member = { patron => $enrollment->patron->unblessed }; >+ my $reserves_count = $enrollment->patron->holds->count; >+ if ( $maxreserves >+ && ( $reserves_count + $new_reserves_count > $maxreserves ) ) >+ { >+ $member->{new_reserves_allowed} = $maxreserves - $reserves_count > 0 >+ ? $maxreserves - $reserves_count >+ : 0; >+ $member->{exceeded_maxreserves} = 1; >+ } >+ my $expiry_date = $enrollment->patron->dateexpiry; >+ $member->{expiry} = 0; # flag set if patron account has expired >+ if ($expiry_date and $expiry_date ne '0000-00-00' and >+ Date_to_Days(split /-/,$date) > Date_to_Days(split /-/,$expiry_date)) { >+ $member->{expiry} = 1; >+ } >+ $member->{amount_outstanding} = $enrollment->patron->account->balance; >+ if ( $enrollment->patron->branchcode ne C4::Context->userenv->{'branch'} ) { >+ $member->{diffbranch} = 1; >+ } >+ >+ push @members, $member; >+ } >+ >+ $template->param( >+ club => $club, >+ members => \@members, >+ maxreserves => $maxreserves, >+ new_reserves_count => $new_reserves_count >+ ); >+} >+ >+$template->param( >+ messageborrower => $messageborrower, >+ messageclub => $messageclub >+); > > # FIXME launch another time GetMember perhaps until (Joubu: Why?) > my $patron = Koha::Patrons->find( $borrowernumber_hold ); >-- >2.20.1
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 19618
:
92674
|
92675
|
92676
|
92677
|
92678
|
92746
|
92747
|
92748
|
92749
|
92750
|
92751
|
93253
|
93254
|
93255
|
93256
|
93257
|
93258