Bug 13891: DataTables server-side processing - Serial recipients
authorJonathan Druart <jonathan.druart@biblibre.com>
Fri, 20 Mar 2015 12:53:35 +0000 (13:53 +0100)
committerTomas Cohen Arazi <tomascohen@gmail.com>
Mon, 13 Apr 2015 13:55:21 +0000 (10:55 -0300)
This second patch removes the previous way to search for serial recipients.

Test plan:
1/ Edit the routing list for a subscription (serials/routing.pl?subscriptionid=X)
2/ Add 1+ recipients
3/ Confirm there is no regression on the add/delete/search actions

QA note: This search does not use a clean way to interact with the
window opener. Indeed the opener is reloaded to display the new item.
This patch does not change this behavior, but note the trick in the
template (common/patron_search.tt) to wait for the opener in order not
to get a JS error.
This is also used by the next patch (patron card).

Tested together with other patches.
Signed-off-by: Marc Veron <veron@veron.ch>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@gmail.com>
admin/add_user_search.pl
koha-tmpl/intranet-tmpl/prog/en/modules/common/patron_search.tt
koha-tmpl/intranet-tmpl/prog/en/modules/serials/member-search.tt [deleted file]
koha-tmpl/intranet-tmpl/prog/en/modules/serials/routing.tt
koha-tmpl/intranet-tmpl/prog/en/modules/serials/tables/members_results.tt [new file with mode: 0644]
serials/add_user_search.pl [new file with mode: 0755]
serials/member-search.pl [deleted file]

index 79425e0..33fb6ac 100755 (executable)
@@ -43,7 +43,7 @@ my $selection_type = $input->param('selection_type') || 'add';
 
 my $referer = $input->referer();
 
-# If this script is called by acqui/basket.pl
+# If this script is called by admin/aqbudgets.pl
 # the patrons to return should be superlibrarian or have the order_manage
 # acquisition flag.
 my $search_patrons_with_acq_perm_only =
index 494d154..b1e4c47 100644 (file)
@@ -114,18 +114,27 @@ function filter() {
 
     // modify parent window owner element
     [% IF selection_type == 'add' %]
-        [%# Note that add_user could sent data instead of borrowername too %]
         function add_user(borrowernumber, borrowername) {
             var p = window.opener;
-            $("#info").hide();
-            $("#error").hide();
-            if ( p.add_user(borrowernumber, borrowername) < 0 ) {
-                $("#error").html(_("Borrower '%s' is already in the list.").format(borrowername));
-                $("#error").show();
-            } else {
-                $("#info").html(_("Borrower '%s' added.").format(borrowername));
-                $("#info").show();
+            // In one place (serials/routing.tt), the page is reload on every add
+            // We have to wait for the page to be there
+            function wait_for_opener () {
+                if ( ! $(opener.document).find('body').size() ) {
+                    setTimeout(wait_for_opener, 500);
+                } else {
+                    [%# Note that add_user could sent data instead of borrowername too %]
+                    $("#info").hide();
+                    $("#error").hide();
+                    if ( p.add_user(borrowernumber, borrowername) < 0 ) {
+                        $("#error").html(_("Borrower '%s' is already in the list.").format(borrowername));
+                        $("#error").show();
+                    } else {
+                        $("#info").html(_("Borrower '%s' added.").format(borrowername));
+                        $("#info").show();
+                    }
+                }
             }
+            wait_for_opener();
         }
     [% ELSIF selection_type == 'select' %]
         function select_user(borrowernumber, data) {
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/member-search.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/serials/member-search.tt
deleted file mode 100644 (file)
index 93357b4..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-[% INCLUDE 'doc-head-open.inc' %]
-<title>Koha &rsaquo; Member Search &rsaquo; [% bookselname %]</title>
-[% INCLUDE 'doc-head-close.inc' %]
-<script type="text/javascript">
-<!--
-
-function add_member(subscriptionid,borrowernumber){
-     var myurl = "routing.pl?subscriptionid="+subscriptionid+"&borrowernumber="+borrowernumber+"&op=add";
-     window.opener.location.href = myurl;
-}
-
-//-->
-</script>
-<style type="text/css">
-   #custom-doc { width:36.46em;*width:35.53em;min-width:430px; margin:auto; text-align:left; padding: 1em; }
-   </style>
-</head>
-<body id="ser_member-search" class="ser">
-<div id="custom-doc" class="yui-t7">
-   
-<div id="bd">
-<div id="yui-main">
-<div id="search" class="yui-g">
-       <form action="[% actionname %]" method="get">
-            <input type="hidden" name="subscriptionid" id="subscriptionid" value="[% subscriptionid %]" />
-               <fieldset class="rows">
-                       <legend> Filter :</legend>
-                       <ol>
-                       <li><label for="member">Name:</label> <input type="hidden" name="surname" value="[% surname %]" />
-                       <input type="text" name="member" id="member" value="[% member %]" /></li>
-            <li><label for="branchcode"> Library:</label><select name="branchcode" id="branchcode">
-                       <option value="">Any</option>[% FOREACH branchloo IN branchloop %]
-                       [% IF ( branchloo.selected ) %]
-                       <option value="[% branchloo.value %]" selected="selected">[% branchloo.branchname %]</option>[% ELSE %]
-                       <option value="[% branchloo.value %]">[% branchloo.branchname %]</option>[% END %]
-                       [% END %]</select></li>
-                       <li><label for="categorycode">Category:</label><select name="categorycode" id="categorycode">
-                       <option value="">Any</option>[% FOREACH categoryloo IN categoryloop %]
-                       [% IF ( categoryloo.selected ) %]
-                       <option value="[% categoryloo.categorycode %]" selected="selected">[% categoryloo.description %]</option>[% ELSE %]
-                       <option value="[% categoryloo.categorycode %]">[% categoryloo.description %]</option>[% END %]
-                       [% END %]</select></li>
-                       </ol>
-                       <fieldset class="action"><input type="submit" value="Search" /></fieldset>
-             </fieldset>
-         </form>
-</div> 
-[% IF ( resultsloop ) %]
-<div id="searchheader" style="margin-top:.7em;"> <h3>Results [% from %] to [% to %] of [% numresults %] found for [% IF ( member ) %]'<span class="ex">[% member %]</span>'[% END %][% IF ( surname ) %]'<span class="ex">[% surname %]</span>'[% END %]</h3></div>
-<div class="searchresults">
-
-<table id="memberresultst">
-       <thead>
-               <tr>
-               <th>Card</th>
-               <th>Name</th>
-               <th>Library</th>
-               <th>Add</th>
-               </tr>
-       </thead>
-       <tbody>
-               [% FOREACH resultsloo IN resultsloop %]
-               [% IF ( loop.odd ) %]<tr class="highlight">[% ELSE %]<tr>[% END %]
-               <td>[% resultsloo.cardnumber %] </td>
-               <td>[% resultsloo.surname %], [% resultsloo.firstname %] </td>
-               <td>[% resultsloo.branchcode %] </td>
-               <td><a onclick="add_member([% subscriptionid %],[% resultsloo.borrowernumber %]); return false" href="/cgi-bin/koha/serials/routing.pl?subscriptionid=[% resultsloo.subscriptionid %]&amp;borrowernumber=[% resultsloo.borrowernumber %]&amp;op=add">Add</a></td></tr>
-               [% END %]
-       </tbody>
-</table>
-[% IF ( multipage ) %]<div class="pages">[% paginationbar %]</div>[% END %]
-</div>
-[% ELSE %]
-[% IF ( searching ) %]
-<p>No results found</p>
-[% END %]
-[% END %]
-<fieldset class="action"><a href="#" class="button close">Close</a></fieldset>
-</div>
-
-</div> 
-
-[% INCLUDE 'intranet-bottom.inc' %]
index 7dfa120..6fccab8 100644 (file)
@@ -9,9 +9,18 @@ function reorder_item(sid,rid,rank){
     window.location.href=mylocation; 
 }
 
-function search_member(subscriptionid){
-    var myurl = 'member-search.pl?subscriptionid='+subscriptionid; window.open(myurl,'FindAMember','width=550,height=480,toolbar=no,scrollbars=yes');
-}
+    function userPopup() {
+        window.open("/cgi-bin/koha/serials/add_user_search.pl",
+            'PatronPopup',
+            'width=740,height=450,location=yes,toolbar=no,'
+            + 'scrollbars=yes,resize=yes'
+        );
+    }
+
+    function add_user(borrowernumber) {
+        var myurl = "routing.pl?subscriptionid="+[% subscriptionid %]+"&borrowernumber="+borrowernumber+"&op=add";
+        window.location.href = myurl;
+    }
 
 //-->
 </script>
@@ -47,37 +56,42 @@ function search_member(subscriptionid){
 [% END %]
 </select> [% issue %]</li>
 
-[% IF memberloop %]
-<li><span class="label">Recipients:</span><table style="clear:none;margin:0;">
-        <tr><th>Name</th>
-            <th>Rank</th>
-            <th>Delete</th>
-        </tr>
-        [% USE m_loop = iterator(memberloop) %]
-        [% FOREACH member IN m_loop %]
-        <tr><td>[% member.name %]</td>
-            <td>
-                <select name="itemrank" onchange="reorder_item([%- subscriptionid -%], [%- member.routingid -%], this.value)">
-                [% rankings = [1 .. m_loop.size] %]
-                [% FOREACH r IN rankings %]
-                    [% IF r == member.ranking %]
-                      <option selected="selected" value="[% r %]">[% r %]</option>
-                    [% ELSE %]
-                      <option value="[% r %]">[% r %]</option>
+<li>
+    <span class="label">Recipients:</span>
+    [% IF memberloop %]
+        <table style="clear:none;margin:0;">
+            <tr><th>Name</th>
+                <th>Rank</th>
+                <th>Delete</th>
+            </tr>
+            [% USE m_loop = iterator(memberloop) %]
+            [% FOREACH member IN m_loop %]
+            <tr><td>[% member.name %]</td>
+                <td>
+                    <select name="itemrank" onchange="reorder_item([%- subscriptionid -%], [%- member.routingid -%], this.value)">
+                    [% rankings = [1 .. m_loop.size] %]
+                    [% FOREACH r IN rankings %]
+                        [% IF r == member.ranking %]
+                          <option selected="selected" value="[% r %]">[% r %]</option>
+                        [% ELSE %]
+                          <option value="[% r %]">[% r %]</option>
+                        [% END %]
                     [% END %]
-                [% END %]
-                </select>
-            </td>
-            <td><a href="/cgi-bin/koha/serials/routing.pl?routingid=[% member.routingid %]&amp;subscriptionid=[% subscriptionid %]&amp;op=delete">Delete</a></td>
-        </tr>
+                    </select>
+                </td>
+                <td><a href="/cgi-bin/koha/serials/routing.pl?routingid=[% member.routingid %]&amp;subscriptionid=[% subscriptionid %]&amp;op=delete">Delete</a></td>
+            </tr>
+            [% END %]
+        </table>
+    [% END %]
+
+    <p style="margin-left:10em;">
+        <input type="button" onclick="userPopup()" value="Add recipients" />
+        [% IF memberloop %]
+            <a href="/cgi-bin/koha/serials/routing.pl?subscriptionid=[% subscriptionid %]&amp;op=delete" class="button">Delete all</a>
         [% END %]
-        </table><p style="margin-left:10em;"><a onclick="search_member([% subscriptionid %]); return false"
-href="/cgi-bin/koha/serials/member-search.pl?subscriptionid=[% subscriptionid %]" class="button">Add recipients</a> &nbsp; <a
-href="/cgi-bin/koha/serials/routing.pl?subscriptionid=[% subscriptionid %]&amp;op=delete" class="button">Delete all</a></p></li>
-[% ELSE %]
-<li><span class="label">Recipients:</span>
-    <a onclick="search_member([% subscriptionid %]); return false" href="/cgi-bin/koha/serials/member-search.pl?subscriptionid=[% subscriptionid %]" class="button">Add recipients</a></li>
-[% END %]
+    </p>
+</li>
 
        <li><label for="notes">Notes:</label><textarea name="notes" id="notes" rows="3" cols="50">[% routingnotes %]</textarea></li>
        </ol>
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/serials/tables/members_results.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/serials/tables/members_results.tt
new file mode 100644 (file)
index 0000000..abb228e
--- /dev/null
@@ -0,0 +1,20 @@
+[% USE To %]
+{
+    "sEcho": [% sEcho %],
+    "iTotalRecords": [% iTotalRecords %],
+    "iTotalDisplayRecords": [% iTotalDisplayRecords %],
+    "aaData": [
+        [% FOREACH data IN aaData %]
+            {
+                "dt_cardnumber":
+                    "[% data.cardnumber %]",
+                "dt_name":
+                    "<span style='white-space:nowrap'><a href='/cgi-bin/koha/members/moremember.pl?borrowernumber=[% data.borrowernumber %]'>[% INCLUDE 'patron-title.inc' borrowernumber = data.borrowernumber category_type = data.category_type firstname = data.firstname surname = data.surname othernames = data.othernames cardnumber = data.cardnumber invert_name = 1%]</a></span>",
+                "dt_branch":
+                    "[% data.branchname |html %]",
+                "dt_action":
+                    "<a style='cursor:pointer' onclick='add_user(\"[% data.borrowernumber %]\", \"[% data.firstname %] [% data.surname %]\"); return false;'>Add</a>"
+            }[% UNLESS loop.last %],[% END %]
+        [% END %]
+    ]
+}
diff --git a/serials/add_user_search.pl b/serials/add_user_search.pl
new file mode 100755 (executable)
index 0000000..50d63bd
--- /dev/null
@@ -0,0 +1,51 @@
+#!/usr/bin/perl
+
+# This file is part of Koha.
+#
+# Copyright 2014 BibLibre
+#
+# 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::Auth;
+use C4::Output;
+use C4::Members;
+
+my $input = new CGI;
+
+my $dbh = C4::Context->dbh;
+
+my ( $template, $loggedinuser, $cookie, $staff_flags ) = get_template_and_user(
+    {   template_name   => "common/patron_search.tt",
+        query           => $input,
+        type            => "intranet",
+        authnotrequired => 0,
+        flagsrequired => { serials => 'routing' },
+    }
+);
+
+my $q = $input->param('q') || '';
+my $op = $input->param('op') || '';
+
+my $referer = $input->referer();
+
+$template->param(
+    view => ( $input->request_method() eq "GET" ) ? "show_form" : "show_results",
+    columns => ['cardnumber', 'name', 'branch', 'action'],
+    json_template => 'serials/tables/members_results.tt',
+    selection_type => 'add',
+);
+output_html_with_http_headers( $input, $cookie, $template->output );
diff --git a/serials/member-search.pl b/serials/member-search.pl
deleted file mode 100755 (executable)
index 9ae769b..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-#!/usr/bin/perl
-
-# Parts copyright Catalyst IT 2010
-#
-# 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 2 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.
-
-=head1 member-search.pl
-
-Member Search.pl script used to search for members to add to a routing list
-
-=cut
-
-use strict;
-use warnings;
-use CGI qw ( -utf8 );
-use C4::Auth;       # get_template_and_user
-use C4::Output;
-use C4::Members;    # BornameSearch
-use C4::Branch;
-use C4::Category;
-use File::Basename;
-
-my $cgi          = new CGI;
-my $theme = $cgi->param('theme') || "default";
-my $resultsperpage = $cgi->param('resultsperpage')||C4::Context->preference("PatronsPerPage")||20;
-my $startfrom = $cgi->param('startfrom')||1;
-
-my $patron = $cgi->Vars;
-foreach (keys %$patron){
-    delete $$patron{$_} unless($$patron{$_});
-}
-
-my @categories=C4::Category->all;
-my $branches=(defined $$patron{branchcode}?GetBranchesLoop($$patron{branchcode}):GetBranchesLoop());
-my $subscriptionid = $cgi->param('subscriptionid');
-my $searchstring   = $cgi->param('member');
-
-my %categories_dislay;
-my ($template, $loggedinuser, $cookie);
-    ($template, $loggedinuser, $cookie)
-    = get_template_and_user({template_name => "serials/member-search.tt",
-                 query => $cgi,
-                 type => "intranet",
-                 authnotrequired => 0,
-                 flagsrequired => { serials => 'routing' },
-                 });
-
-foreach my $category (@categories){
-       my $hash={
-                       category_description=>$$category{description},
-                       category_type=>$$category{category_type}
-                        };
-       $categories_dislay{$$category{categorycode}} = $hash;
-}
-$template->param(
-        "AddPatronLists_".C4::Context->preference("AddPatronLists")=> "1",
-            );
-if (C4::Context->preference("AddPatronLists")=~/code/){
-    $categories[0]->{'first'}=1;
-}
-
-my $member=$cgi->param('member');
-my $orderby=$cgi->param('orderby');
-$orderby = "surname,firstname" unless $orderby;
-if (defined $member) {
-    $member =~ s/,//g;   #remove any commas from search string
-    $member =~ s/\*/%/g;
-}
-
-my ($count,$results);
-
-if ( C4::Context->preference("IndependentBranches") ) {
-    if (   C4::Context->userenv
-        && !C4::Context->IsSuperLibrarian()
-        && C4::Context->userenv->{'branch'} )
-    {
-        $$patron{branchcode} = C4::Context->userenv->{'branch'};
-    }
-}
-$$patron{firstname}.="\%" if ($$patron{firstname});
-$$patron{surname}.="\%" if ($$patron{surname});
-
-my @searchpatron;
-push @searchpatron, $member if ($member);
-push @searchpatron, $patron if ( keys %$patron );
-my $from = ( $startfrom - 1 ) * $resultsperpage;
-my $to   = $from + $resultsperpage;
-if (@searchpatron) {
-    ($results) = Search(
-        \@searchpatron,
-        [ { surname => 0 }, { firstname => 0 } ],
-        undef,
-        undef,
-        [ "firstname", "surname", "email", "othernames", "cardnumber" ],
-        "start_with"
-    );
-}
-if ($results) {
-    $count = scalar(@$results);
-}
-my @resultsdata;
-$to=($count>$to?$to:$count);
-my $index=$from;
-foreach my $borrower(@$results[$from..$to-1]){
-    # find out stats
-    $borrower->{'dateexpiry'}= C4::Dates->new($borrower->{'dateexpiry'},'iso')->output('syspref');
-    if ($categories_dislay{$borrower->{'categorycode'}}){
-        my %row = (
-           count => $index++,
-           %$borrower,
-           %{$categories_dislay{$$borrower{categorycode}}},
-       );
-       push(@resultsdata, \%row);
-    }
-    else {
-        warn $borrower->{'cardnumber'} ." has a bad category code of " . $borrower->{'categorycode'} ."\n";
-    }
-}
-if ($$patron{branchcode}){
-       foreach my $branch (grep{$_->{value} eq $$patron{branchcode}}@$branches){
-               $$branch{selected}=1;
-       }
-}
-if ($$patron{categorycode}){
-       foreach my $category (grep{$_->{categorycode} eq $$patron{categorycode}}@categories){
-               $$category{selected}=1;
-       }
-}
-my %parameters=
-(  %{$patron},
-    'orderby' => $orderby,
-    'resultsperpage' => $resultsperpage,
-    'type'=> 'intranet');
-my $base_url =
-    'member-search.pl?&amp;'
-  . join(
-    '&amp;',
-    map { "$_=$parameters{$_}" } (keys %parameters)
-  );
-
-$template->param(
-    paginationbar => pagination_bar(
-        $base_url,  int( $count / $resultsperpage ) + 1,
-        $startfrom, 'startfrom'
-    ),
-    startfrom => $startfrom,
-    from      => ($startfrom-1)*$resultsperpage+1,
-    to        => $to,
-    multipage => ($count != $to+1 || $startfrom!=1),
-);
-$template->param(
-    branchloop=>$branches,
-       categoryloop=>\@categories,
-);
-
-
-$template->param(
-        searching       => "1",
-               actionname              => basename($0),
-               %$patron,
-        numresults      => $count,
-        resultsloop     => \@resultsdata,
-            );
-
-output_html_with_http_headers $cgi, $cookie, $template->output;