View | Details | Raw Unified | Return to bug 9811
Collapse All | Expand All

(-)a/C4/Members.pm (-3 / +3 lines)
Lines 250-256 sub Search { Link Here
250
                $filter = [ $filter ];
250
                $filter = [ $filter ];
251
                push @$filter, {"borrowernumber"=>$matching_records};
251
                push @$filter, {"borrowernumber"=>$matching_records};
252
            }
252
            }
253
		}
253
        }
254
    }
254
    }
255
255
256
    # $showallbranches was not used at the time SearchMember() was mainstreamed into Search().
256
    # $showallbranches was not used at the time SearchMember() was mainstreamed into Search().
Lines 274-280 sub Search { Link Here
274
                else {
274
                else {
275
                    $filter = { '' => $filter, branchcode => $branch };
275
                    $filter = { '' => $filter, branchcode => $branch };
276
                }
276
                }
277
            }      
277
            }
278
        }
278
        }
279
    }
279
    }
280
280
Lines 283-289 sub Search { Link Here
283
    }
283
    }
284
    $searchtype ||= "start_with";
284
    $searchtype ||= "start_with";
285
285
286
	return SearchInTable( "borrowers", $filter, $orderby, $limit, $columns_out, $search_on_fields, $searchtype );
286
    return SearchInTable( "borrowers", $filter, $orderby, $limit, $columns_out, $search_on_fields, $searchtype );
287
}
287
}
288
288
289
=head2 GetMemberDetails
289
=head2 GetMemberDetails
(-)a/C4/Utils/DataTables/Members.pm (+201 lines)
Line 0 Link Here
1
package C4::Utils::DataTables::Members;
2
3
use C4::Branch qw/onlymine/;
4
use C4::Context;
5
use C4::Members qw/GetMemberIssuesAndFines/;
6
use C4::Utils::DataTables;
7
use Modern::Perl;
8
9
sub search {
10
    my ( $params ) = @_;
11
    my $searchmember = $params->{searchmember};
12
    my $firstletter = $params->{firstletter};
13
    my $categorycode = $params->{categorycode};
14
    my $branchcode = $params->{branchcode};
15
    my $searchtype = $params->{searchtype};
16
    my $searchfieldstype = $params->{searchfieldstype};
17
    my $dt_params = $params->{dt_params};
18
19
    my ($iTotalRecords, $iTotalDisplayRecords);
20
21
    # If branches are independant and user is not superlibrarian
22
    # The search has to be only on the user branch
23
    if ( C4::Branch::onlymine ) {
24
        my $userenv = C4::Context->userenv;
25
        $branchcode = $userenv->{'branch'};
26
27
    }
28
29
    my $dbh = C4::Context->dbh;
30
    my $select = "SELECT SQL_CALC_FOUND_ROWS
31
        borrowers.borrowernumber, borrowers.surname, borrowers.firstname, borrowers.address,
32
        borrowers.address2, borrowers.city, borrowers.zipcode, borrowers.country,
33
        CAST(borrowers.cardnumber AS UNSIGNED) AS cardnumber, borrowers.dateexpiry,
34
        borrowers.borrowernotes, borrowers.branchcode,
35
        categories.description AS category_description, categories.category_type,
36
        branches.branchname";
37
    my $from = "FROM borrowers
38
        LEFT JOIN branches ON borrowers.branchcode = branches.branchcode
39
        LEFT JOIN categories ON borrowers.categorycode = categories.categorycode";
40
    my @where_args;
41
    my @where_strs;
42
    if(defined $firstletter and $firstletter ne '') {
43
        push @where_strs, "borrowers.surname LIKE ?";
44
        push @where_args, "$firstletter%";
45
    }
46
    if(defined $categorycode and $categorycode ne '') {
47
        push @where_strs, "borrowers.categorycode = ?";
48
        push @where_args, $categorycode;
49
    }
50
    if(defined $branchcode and $branchcode ne '') {
51
        push @where_strs, "borrowers.branchcode = ?";
52
        push @where_args, $branchcode;
53
    }
54
55
    # split on coma
56
    $searchmember =~ s/,/ /g if $searchmember;
57
    my @where_strs_or;
58
    my $searchfields = {
59
        standard => 'surname,firstname,othernames,cardnumber',
60
        email => 'email,emailpro,B_email',
61
        borrowernumber => 'borrowernumber',
62
        phone => 'phone,phonepro,B_phone,altcontactphone,mobile',
63
        address => 'streettype,address,address2,city,state,zipcode,country',
64
        dateofbirth => 'dateofbirth',
65
    };
66
    for my $searchfield ( split /,/, $searchfields->{$searchfieldstype} ) {
67
        foreach my $term ( split / /, $searchmember) {
68
            next unless $term;
69
            $searchmember =~ s/\*/%/g; # * is replaced with % for sql
70
            $term .= '%' # end with anything
71
                if $term !~ /%$/;
72
            $term = "%$term" # begin with anythin unless start_with
73
                if $term !~ /^%/
74
                    and $searchtype eq "contain";
75
            push @where_strs_or, "borrowers." . $dbh->quote_identifier($searchfield) . " LIKE ?";
76
            push @where_args, $term;
77
        }
78
    }
79
    push @where_strs, '('. join (' OR ', @where_strs_or) . ')'
80
        if @where_strs_or;
81
82
    my $where;
83
    $where = "WHERE " . join (" AND ", @where_strs) if @where_strs;
84
    my $orderby = dt_build_orderby($dt_params);
85
86
    my $limit;
87
    if(defined $dt_params->{iDisplayStart} and defined $dt_params->{iDisplayLength}) {
88
        # In order to avoir sql injection
89
        $dt_params->{iDisplayStart} =~ s/\D//g;
90
        $dt_params->{iDisplayLength} =~ s/\D//g;
91
        $limit = "LIMIT $dt_params->{iDisplayStart},$dt_params->{iDisplayLength}";
92
    }
93
94
    my $query = join(" ", $select, $from, $where, $orderby, $limit);
95
    my $sth = $dbh->prepare($query);
96
    $sth->execute(@where_args);
97
    my $patrons = $sth->fetchall_arrayref({});
98
99
    # Get the iTotalDisplayRecords DataTable variable
100
    $query = "SELECT FOUND_ROWS()";
101
    $sth = $dbh->prepare($query);
102
    $sth->execute;
103
    ($iTotalDisplayRecords) = $sth->fetchrow_array;
104
105
    # Get the iTotalRecords DataTable variable
106
    $query = "SELECT COUNT(*) FROM borrowers";
107
    $sth = $dbh->prepare($query);
108
    $sth->execute;
109
    ($iTotalRecords) = $sth->fetchrow_array;
110
111
    # Get some information on patrons
112
    foreach my $patron (@$patrons) {
113
        ($patron->{overdues}, $patron->{issues}, $patron->{fines}) =
114
            GetMemberIssuesAndFines($patron->{borrowernumber});
115
        if($patron->{dateexpiry} and $patron->{dateexpiry} ne '0000-00-00') {
116
            $patron->{dateexpiry} = C4::Dates->new($patron->{dateexpiry}, "iso")->output();
117
        } else {
118
            $patron->{dateexpiry} = '';
119
        }
120
        $patron->{fines} = sprintf("%.2f", $patron->{fines} || 0);
121
    }
122
123
    return {
124
        iTotalRecords => $iTotalRecords,
125
        iTotalDisplayRecords => $iTotalDisplayRecords,
126
        patrons => $patrons
127
    }
128
}
129
130
1;
131
__END__
132
133
=head1 NAME
134
135
C4::Utils::DataTables::Members - module for using DataTables with patrons
136
137
=head1 SYNOPSIS
138
139
This module provides (one for the moment) routines used by the patrons search
140
141
=head2 FUNCTIONS
142
143
=head3 search
144
145
    my $dt_infos = C4::Utils::DataTables::Members->search($params);
146
147
$params is a hashref with some keys:
148
149
=over 4
150
151
=item searchmember
152
153
  String to search in the borrowers sql table
154
155
=item firstletter
156
157
  Introduced to contain 1 letter but can contain more.
158
  The search will done on the borrowers.surname field
159
160
=item categorycode
161
162
  Search patrons with this categorycode
163
164
=item branchcode
165
166
  Search patrons with this branchcode
167
168
=item searchtype
169
170
  Can be 'contain' or 'start_with'. Used for the searchmember parameter.
171
172
=item searchfieldstype
173
174
  Can be 'standard', 'email', 'borrowernumber', 'phone', 'address' or 'dateofbirth'
175
176
=item dt_params
177
178
  Is the reference of C4::Utils::DataTables::dt_get_params($input);
179
180
=cut
181
182
=back
183
184
=head1 LICENSE
185
186
Copyright 2013 BibLibre
187
188
This file is part of Koha.
189
190
Koha is free software; you can redistribute it and/or modify it under the
191
terms of the GNU General Public License as published by the Free Software
192
Foundation; either version 2 of the License, or (at your option) any later
193
version.
194
195
Koha is distributed in the hope that it will be useful, but WITHOUT ANY
196
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
197
A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
198
199
You should have received a copy of the GNU General Public License along
200
with Koha; if not, write to the Free Software Foundation, Inc.,
201
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/patron-search.inc (-61 / +82 lines)
Lines 5-77 Link Here
5
	<div id="patron_search" class="residentsearch">
5
	<div id="patron_search" class="residentsearch">
6
	<p class="tip">Enter patron card number or partial name:</p>
6
	<p class="tip">Enter patron card number or partial name:</p>
7
	<form action="/cgi-bin/koha/members/member.pl" method="post">
7
	<form action="/cgi-bin/koha/members/member.pl" method="post">
8
    <input id="searchmember" size="25" class="focus" name="member" type="text" value="[% member %]"/>
8
    <input id="searchmember" size="25" class="focus" name="searchmember" type="text" value="[% searchmember %]"/>
9
	<span class="filteraction" id="filteraction_off"> <a href="#" onclick="$('#filters').toggle();$('.filteraction').toggle();">[-]</a></span>
9
	<span class="filteraction" id="filteraction_off"> <a href="#" onclick="$('#filters').toggle();$('.filteraction').toggle();">[-]</a></span>
10
	<span class="filteraction" id="filteraction_on"> <a href="#" onclick="$('#filters').toggle();$('.filteraction').toggle();">[+]</a></span>
10
	<span class="filteraction" id="filteraction_on"> <a href="#" onclick="$('#filters').toggle();$('.filteraction').toggle();">[+]</a></span>
11
11
12
    <input value="Search" class="submit" type="submit" />
12
      <label for="searchfieldstype">Search fields:</label>
13
      <select name="searchfieldstype" id="searchfieldstype">
14
        [% IF searchfieldstype == "standard" %]
15
          <option selected="selected" value='standard'>Standard</option>
16
        [% ELSE %]
17
          <option value='standard'>Standard</option>
18
        [% END %]
19
        [% IF searchfieldstype == "email" %]
20
          <option selected="selected" value='email'>Email</option>
21
        [% ELSE %]
22
          <option value='email'>Email</option>
23
        [% END %]
24
        [% IF searchfieldstype == "borrowernumber" %]
25
          <option selected="selected" value='borrowernumber'>Borrower number</option>
26
        [% ELSE %]
27
          <option value='borrowernumber'>Borrower number</option>
28
        [% END %]
29
        [% IF searchfieldstype == "phone" %]
30
          <option selected="selected" value='phone'>Phone number</option>
31
        [% ELSE %]
32
          <option value='phone'>Phone number</option>
33
        [% END %]
34
        [% IF searchfieldstype == "address" %]
35
          <option selected="selected" value='address'>Street Address</option>
36
        [% ELSE %]
37
          <option value='address'>Street Address</option>
38
        [% END %]
39
        [% IF searchfieldstype == "dateofbirth" %]
40
          <option selected="selected" value='dateofbirth'>Date of birth</option>
41
        [% ELSE %]
42
          <option value='dateofbirth'>Date of birth</option>
43
        [% END %]
44
      </select>
45
46
      <script type="text/javascript">
47
          [% SET dateformat = Koha.Preference('dateformat') %]
48
          $("#searchfieldstype").change(function() {
49
              if ( $(this).val() == 'dateofbirth' ) {
50
                  [% IF dateformat == 'us' %]
51
                      [% SET format = 'MM/DD/YYYY' %]
52
                  [% ELSIF dateformat == 'iso' %]
53
                      [% SET format = 'YYYY-MM-DD' %]
54
                  [% ELSIF dateformat == 'metric' %]
55
                      [% SET format = 'DD/MM/YYYY' %]
56
                  [% END %]
13
57
14
  <div id="filters">
58
                  $('#searchmember').qtip({
15
      <p><label for="searchfields">Search fields:</label>
59
                      content: 'Dates of birth should be entered in the format "[% format %]"',
16
            <select name="searchfields" id="searchfields">
60
                      style: {
17
                <option selected="selected" value=''>Standard</option>
61
                          tip: 'topLeft'
18
                <option value='email,emailpro,B_email,'>Email</option>
62
                      }
19
                <option value='borrowernumber'>Borrower number</option>
63
                  })
20
                <option value='phone,phonepro,B_phone,altcontactphone,mobile'>Phone number</option>
64
              } else {
21
                <option value='streettype,address,address2,city,state,zipcode,country'>Street Address</option>
65
                  $('#searchmember').qtip('destroy');
22
                <option value='dateofbirth'>Date of birth</option>
66
              }
23
            </select>
67
          });
24
            <script type="text/javascript">
68
      </script>
25
                [% SET dateformat = Koha.Preference('dateformat') %]
26
                $("#searchfields").change(function() {
27
                    if ( $(this).val() == 'dateofbirth' ) {
28
                        [% IF dateformat == 'us' %]
29
                            [% SET format = 'MM/DD/YYYY' %]
30
                        [% ELSIF dateformat == 'iso' %]
31
                            [% SET format = 'YYYY-MM-DD' %]
32
                        [% ELSIF dateformat == 'metric' %]
33
                            [% SET format = 'DD/MM/YYYY' %]
34
                        [% END %]
35
69
36
                        $('#searchmember').qtip({
70
      <label for="searchtype">Search type:</label>
37
                            content: 'Dates of birth should be entered in the format "[% format %]"',
71
      <select name="searchtype" id="searchtype">
38
                            style: {
72
          <option selected="selected" value='start_with'>Starts with</option>
39
                                tip: 'topLeft'
73
          <option value='contain'>Contains</option>
40
                            }
74
      </select>
41
                        })
42
                    } else {
43
                        $('#searchmember').qtip('destroy');
44
                    }
45
                });
46
            </script>
47
        </p>
48
        <p><label for="searchtype">Search type:</label>
49
                <select name="searchtype" id="searchtype">
50
                    <option selected="selected" value=''>Starts with</option>
51
                    <option value='contain'>Contains</option>
52
                </select></p>
53
75
54
      <p><label for="searchorderby">Order by:</label>
76
    <input value="Search" class="submit" type="submit" />
55
            <select name="orderby" id="searchorderby">
77
    [% IF ( branchloop ) %]
56
            <option value="">Surname, Firstname</option>
78
    <p id="filters"> <label for="branchcode">Library: </label>
57
            <option value="cardnumber,0">Cardnumber</option>
79
    <select name="branchcode" id="branchcode">
58
            </select></p>
80
        [% IF branchloop.size != 1 %]
59
        [% IF ( branchloop ) %] <p><label for="branchcode">Library: </label><select name="branchcode" id="branchcode">
81
          <option value="">Any</option>
60
                <option value="">Any</option>[% FOREACH branchloo IN branchloop %]
82
        [% END %]
61
                [% IF ( branchloo.selected ) %]
83
        [% FOREACH branchloo IN branchloop %]
62
                <option value="[% branchloo.value %]" selected="selected">[% branchloo.branchname %]</option>[% ELSE %]
84
        [% IF ( branchloo.selected ) %]
63
                <option value="[% branchloo.value %]">[% branchloo.branchname %]</option>[% END %]
85
        <option value="[% branchloo.value %]" selected="selected">[% branchloo.branchname %]</option>[% ELSE %]
64
              [% END %]</select></p>
86
        <option value="[% branchloo.value %]">[% branchloo.branchname %]</option>[% END %]
65
      [% END %]
87
      [% END %]</select>
66
      [% IF ( categories ) %]
88
                 <label for="categorycode">Category: </label><select name="categorycode" id="categorycode">
67
        <p><label for="categorycode">Category: </label><select name="categorycode" id="categorycode">
89
        <option value="">Any</option>[% FOREACH categorie IN categories %]
68
                <option value="">Any</option>[% FOREACH categorie IN categories %]
90
        [% IF ( categorie.selected ) %]
69
                [% IF ( categorie.selected ) %]
91
        <option value="[% categorie.categorycode %]" selected="selected">[% categorie.description %]</option>[% ELSE %]
70
                <option value="[% categorie.categorycode %]" selected="selected">[% categorie.description %]</option>[% ELSE %]
92
        <option value="[% categorie.categorycode %]">[% categorie.description %]</option>[% END %]
71
                <option value="[% categorie.categorycode %]">[% categorie.description %]</option>[% END %]
93
      [% END %]</select>
72
                [% END %]</select></p>
94
	</p>
73
      [% END %]
95
	[% END %]
74
  </div>
75
</form>
96
</form>
76
	</div>
97
	</div>
77
98
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/patron-title.inc (-22 / +22 lines)
Lines 1-23 Link Here
1
[% IF ( borrower.borrowernumber ) %]
1
[%- IF ( borrower.borrowernumber ) %]
2
    [% IF borrower.category_type == 'I' %]
2
    [%- IF borrower.category_type == 'I' %]
3
        [% borrower.surname %] [% IF borrower.othernames %] ([% borrower.othernames %]) [% END %]
3
        [%- borrower.surname %] [% IF borrower.othernames %] ([% borrower.othernames %]) [% END %]
4
    [% ELSE %]
4
    [%- ELSE %]
5
        [% IF invert_name %]
5
        [%- IF invert_name %]
6
            [% borrower.surname %], [% borrower.firstname %] [% IF borrower.othernames %] ([% borrower.othernames %]) [% END %]
6
            [%- borrower.surname %], [% borrower.firstname %] [% IF borrower.othernames %] ([% borrower.othernames %]) [% END %]
7
        [% ELSE %]
7
        [%- ELSE %]
8
            [% borrower.firstname %] [% IF borrower.othernames %] ([% borrower.othernames %]) [% END %] [% borrower.surname %]
8
            [%- borrower.firstname %] [% IF borrower.othernames %] ([% borrower.othernames %]) [% END %] [% borrower.surname %]
9
        [% END %]
9
        [%- END -%]
10
    [% END %]
10
    [%- END -%]
11
    ([% borrower.cardnumber %])
11
    ([% borrower.cardnumber %])
12
[% ELSIF ( borrowernumber ) %]
12
[%- ELSIF ( borrowernumber ) %]
13
    [% IF category_type == 'I' %]
13
    [%- IF category_type == 'I' %]
14
        [% surname %] [% IF othernames %] ([% othernames %]) [% END %]
14
        [%- surname %] [% IF othernames %] ([% othernames %]) [% END %]
15
    [% ELSE %]
15
    [%- ELSE %]
16
        [% IF invert_name %]
16
        [%- IF invert_name %]
17
            [% surname %], [% firstname %] [% IF othernames %] ([% othernames %]) [% END %]
17
            [%- surname %], [% firstname %] [% IF othernames %] ([% othernames %]) [% END %]
18
        [% ELSE %]
18
        [%- ELSE %]
19
            [% firstname %] [% IF othernames %] ([% othernames %]) [% END %] [% surname %]
19
            [%- firstname %] [% IF othernames %] ([% othernames %]) [% END %] [% surname %]
20
        [% END %]
20
        [%- END %]
21
    [% END %]
21
    [%- END -%]
22
    ([% cardnumber %])
22
    ([% cardnumber -%])
23
[% END %]
23
[%- END -%]
(-)a/koha-tmpl/intranet-tmpl/prog/en/js/datatables.js (-2 / +3 lines)
Lines 23-29 var dataTablesDefaults = { Link Here
23
        "sSearch"           : window.MSG_DT_SEARCH || "Search:",
23
        "sSearch"           : window.MSG_DT_SEARCH || "Search:",
24
        "sZeroRecords"      : window.MSG_DT_ZERO_RECORDS || "No matching records found"
24
        "sZeroRecords"      : window.MSG_DT_ZERO_RECORDS || "No matching records found"
25
    },
25
    },
26
    "sDom": '<"top pager"ilpf>t<"bottom pager"ip>'
26
    "sDom": '<"top pager"ilpf>tr<"bottom pager"ip>'
27
};
27
};
28
28
29
29
Lines 471-476 jQuery.extend( jQuery.fn.dataTableExt.oSort, { Link Here
471
} );
471
} );
472
472
473
}());
473
}());
474
474
/* Plugin to allow sorting on data stored in a span's title attribute
475
/* Plugin to allow sorting on data stored in a span's title attribute
475
 *
476
 *
476
 * Ex: <td><span title="[% ISO_date %]">[% formatted_date %]</span></td>
477
 * Ex: <td><span title="[% ISO_date %]">[% formatted_date %]</span></td>
Lines 537-540 jQuery.extend( jQuery.fn.dataTableExt.oSort, { Link Here
537
        }
538
        }
538
    });
539
    });
539
540
540
}());
541
}());
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/member.tt (-92 / +309 lines)
Lines 1-110 Link Here
1
[% INCLUDE 'doc-head-open.inc' %]
1
[% INCLUDE 'doc-head-open.inc' %]
2
<title>Koha &rsaquo; Patrons [% IF ( searching ) %]&rsaquo; Search results[% END %]</title>
2
<title>Koha &rsaquo; Patrons [% IF ( searching ) %]&rsaquo; Search results[% END %]</title>
3
[% INCLUDE 'doc-head-close.inc' %]
3
[% INCLUDE 'doc-head-close.inc' %]
4
</head>
4
<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.dataTables.min.js"></script>
5
<body id="pat_member" class="pat">
5
<script type="text/javascript" src="[% themelang %]/js/datatables.js"></script>
6
[% INCLUDE 'header.inc' %]
6
<link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" />
7
[% INCLUDE 'patron-search.inc' %]
7
<script type="text/javascript">
8
//<![CDATA[
9
    var dtMemberResults;
8
10
9
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; [% IF ( searching ) %]<a href="/cgi-bin/koha/members/members-home.pl">Patrons</a>  &rsaquo; Search results[% ELSE %]Patrons[% END %]</div>
11
    $(document).ready(function() {
12
        [% IF searchmember %]
13
            $("#searchmember_filter").val("[% searchmember %]");
14
        [% END %]
15
        [% IF searchfieldstype %]
16
            $("searchfieldstype_filter").val("[% searchfieldstype %]");
17
        [% END %]
18
        [% IF searchtype %]
19
            $("#searchtype_filter").val("[% searchtype %]");
20
        [% END %]
21
        [% IF categorycode %]
22
            $("#categorycode_filter").val("[% categorycode %]");
23
        [% END %]
24
        [% IF branchcode %]
25
            $("#branchcode_filter").val("[% branchcode %]");
26
        [% END %]
10
27
11
<div id="doc2" class="yui-t7">
28
        // Build the aLengthMenu
29
        var aLengthMenu = [
30
            [%PatronsPerPage %], 10, 20, 50, 100
31
        ];
32
        jQuery.unique(aLengthMenu);
33
        aLengthMenu.sort(function(a,b){return parseInt(a) < parseInt(b) ? -1 : 1;});
12
34
13
   <div id="bd">
35
        // Apply DataTables on the results table
14
		<div id="yui-main">
36
        dtMemberResults = $("#memberresultst").dataTable($.extend(true, {}, dataTablesDefaults, {
15
		    <div class="yui-b">
37
            'bServerSide': true,
16
				<div class="yui-g">
38
            'sAjaxSource': "/cgi-bin/koha/svc/members/search",
39
            'fnServerData': function(sSource, aoData, fnCallback) {
40
                aoData.push({
41
                    'name': 'searchmember',
42
                    'value': $("#searchmember_filter").val()
43
                },{
44
                    'name': 'firstletter',
45
                    'value': $("#firstletter_filter").val()
46
                },{
47
                    'name': 'searchfieldstype',
48
                    'value': $("#searchfieldstype_filter").val()
49
                },{
50
                    'name': 'searchtype',
51
                    'value': $("#searchtype_filter").val()
52
                },{
53
                    'name': 'categorycode',
54
                    'value': $("#categorycode_filter").val()
55
                },{
56
                    'name': 'branchcode',
57
                    'value': $("#branchcode_filter").val()
58
                },{
59
                    'name': 'name_sorton',
60
                    'value': 'borrowers.surname borrowers.firstname'
61
                },{
62
                    'name': 'category_sorton',
63
                    'value': 'categories.description',
64
                },{
65
                    'name': 'branch_sorton',
66
                    'value': 'branches.branchname'
67
                },{
68
                    'name': 'template_path',
69
                    'value': 'members/tables/members_results.tt',
70
                });
71
                $.ajax({
72
                    'dataType': 'json',
73
                    'type': 'POST',
74
                    'url': sSource,
75
                    'data': aoData,
76
                    'success': function(json){
77
                        // redirect if there is only 1 result.
78
                        if ( json.aaData.length == 1 ) {
79
                            var borrowernumber = json.aaData[0].borrowernumber;
80
                            document.location.href="/cgi-bin/koha/members/moremember.pl?borrowernumber="+borrowernumber;
81
                            return false;
82
                        }
83
                        fnCallback(json);
84
                    }
85
                });
86
            },
87
            'aoColumns': [
88
                { 'mDataProp': 'dt_cardnumber' },
89
                { 'mDataProp': 'dt_name' },
90
                { 'mDataProp': 'dt_category' },
91
                { 'mDataProp': 'dt_branch' },
92
                { 'mDataProp': 'dt_dateexpiry' },
93
                { 'mDataProp': 'dt_od_checkouts', 'bSortable': false },
94
                { 'mDataProp': 'dt_fines', 'bSortable': false },
95
                { 'mDataProp': 'dt_borrowernotes', 'bSortable': false },
96
                { 'mDataProp': 'dt_action', 'bSortable': false }
97
            ],
98
            'fnRowCallback': function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
99
                /* Center text for 6th column */
100
                $("td:eq(5)", nRow).css("text-align", "center");
17
101
18
				[% INCLUDE 'patron-toolbar.inc' %]
102
                return nRow;
103
            },
104
            'bFilter': false,
105
            'bAutoWidth': false,
106
            'bProcessing': true,
107
            [% IF orderby_cardnumber_0 %]
108
                'aaSorting': [[0, 'asc']],
109
            [% ELSE %]
110
                'aaSorting': [[1, 'asc']],
111
            [% END %]
112
            "aLengthMenu": [aLengthMenu, aLengthMenu],
113
            'sPaginationType': 'full_numbers',
114
            "iDisplayLength": [% PatronsPerPage %],
115
        }));
116
    });
19
117
20
	[% IF ( no_add ) %]<div class="dialog alert"><h3>Cannot add patron</h3>
118
    // Update the string "Results found ..."
21
		[% IF ( no_branches ) %]<p>There are <strong>no libraries defined</strong>. [% IF ( CAN_user_parameters ) %]Please <a href="/cgi-bin/koha/admin/branches.pl">add a library</a>.[% ELSE %]An administrator must define at least one library.[% END %]</p>[% END %]
119
    function update_searched(){
22
		[% IF ( no_categories ) %]<p>There are <strong>no patron categories defined</strong>. [% IF ( CAN_user_parameters ) %]Please <a href="/cgi-bin/koha/admin/categorie.pl">add a patron category</a>.[% ELSE %]An administrator must define at least one patron category.[% END %]</p>[% END %]</div>
120
        var searched = "";
23
	[% END %]
121
        searched += "on " + $("#searchfieldstype_filter").find("option:selected").text().toLowerCase() + " fields";
122
        if ( $("#searchmember_filter").val() ) {
123
            if ( $("#searchtype_filter").val() == 'start_with' ) {
124
                searched += _(" starting with ");
125
            } else {
126
                searched += _(" containing ");
127
            }
128
            searched += $("#searchmember_filter").val();
129
        }
130
        if ( $("#firstletter_filter").val() ) {
131
            searched += _(" begin with ") + $("#firstletter_filter").val();
132
        }
133
        if ( $("#categorycode_filter").val() ) {
134
            searched += _(" with category ") + $("#categorycode_filter").find("option:selected").text();
135
        }
136
        if ( $("#branchcode_filter").val() ) {
137
            searched += _(" in library ") + $("#branchcode_filter").find("option:selected").text();
138
        }
139
        $("#searchpattern").text("for patron " + searched);
140
    }
24
141
25
						<div class="browse">
142
    // Redraw the table
26
							Browse by last name:
143
    function filter() {
27
                            [% FOREACH letter IN alphabet.split(' ') %]
144
        $("#firstletter_filter").val('');
28
                                <a href="/cgi-bin/koha/members/member.pl?quicksearch=1&amp;surname=[% letter %]">[% letter %]</a>
145
        update_searched();
29
							[% END %]
146
        dtMemberResults.fnDraw();
30
						</div>
147
        return false;
148
    }
31
149
32
                    [% IF ( CAN_user_borrowers && pending_borrower_modifications ) %]
150
    // User has clicked on the Clear button
33
                        <div class="pending-info" id="patron_updates_pending">
151
    function clearFilters(redraw) {
34
                            <a href="/cgi-bin/koha/members/members-update.pl">Patrons requesting modifications</a>:
152
        $("#searchform select").val('');
35
                            <span class="holdcount"><a href="/cgi-bin/koha/members/members-update.pl">[% pending_borrower_modifications %]</a></span>
153
        $("#firstletter_filter").val('');
36
                        </div>
154
        $("#searchmember_filter").val('');
37
                    [% END %]
155
        if(redraw) {
156
            dtMemberResults.fnDraw();
157
        }
158
    }
38
159
39
						[% IF ( resultsloop ) %]
160
    // User has clicked on a letter
40
						<div id="searchheader"> <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>
161
    function filterByFirstLetterSurname(letter) {
41
						<div class="searchresults">
162
        clearFilters(false);
163
        $("#firstletter_filter").val(letter);
164
        dtMemberResults.fnDraw();
165
    }
166
//]]>
167
</script>
168
</head>
169
<body id="pat_member" class="pat">
170
[% INCLUDE 'header.inc' %]
171
[% INCLUDE 'patron-search.inc' %]
42
172
43
							<table id="memberresultst">
173
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; [% IF ( searching ) %]<a href="/cgi-bin/koha/members/members-home.pl">Patrons</a>  &rsaquo; Search results[% ELSE %]Patrons[% END %]</div>
44
							<thead>
45
							<tr>
46
							<th>Card</th>
47
							<th>Name</th>
48
							<th>Cat</th>
49
							<th>Library</th>
50
							<th>Expires on</th>
51
							<th>OD/Checkouts</th>
52
							<th>Fines</th>
53
							<th>Circ note</th>
54
							<th>&nbsp;</th>
55
							</tr>
56
							</thead>
57
							<tbody>
58
							[% FOREACH resultsloo IN resultsloop %]
59
							[% IF ( resultsloo.overdue ) %]
60
							<tr class="problem">
61
							[% ELSE %]
62
							[% UNLESS ( loop.odd ) %]
63
							<tr class="highlight">
64
							[% ELSE %]
65
							<tr>
66
							[% END %]
67
							[% END %]
68
							<td>[% resultsloo.cardnumber %]</td>
69
                            <td style="white-space: nowrap;">
70
                            <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% resultsloo.borrowernumber %]">
71
                            [% INCLUDE 'patron-title.inc' borrowernumber = resultsloo.borrowernumber category_type = resultsloo.category_type firstname = resultsloo.firstname surname = resultsloo.surname othernames = resultsloo.othernames cardnumber = resultsloo.cardnumber invert_name = 1%]
72
                            </a> <br />
73
                            [% IF ( resultsloo.streetnumber ) %][% resultsloo.streetnumber %] [% END %][% resultsloo.address %][% IF ( resultsloo.address2 ) %]<br />[% resultsloo.address2 %][% END %][% IF ( resultsloo.city ) %]<br />[% resultsloo.city %][% IF ( resultsloo.state ) %],[% END %][% END %][% IF ( resultsloo.state ) %] [% resultsloo.state %][% END %] [% IF ( resultsloo.zipcode ) %]  [% resultsloo.zipcode %][% END %][% IF ( resultsloo.country ) %], [% resultsloo.country %][% END %]</td>
74
							<td>[% resultsloo.category_description %] ([% resultsloo.category_type %])</td>
75
							<td>[% resultsloo.branchname %]</td>
76
							<td>[% resultsloo.dateexpiry %]</td>
77
							<td>[% IF ( resultsloo.overdues ) %]<span class="overdue"><strong>[% resultsloo.overdues %]</strong></span>[% ELSE %][% resultsloo.overdues %][% END %]/[% resultsloo.issues %]</td>
78
							<td>[% IF ( resultsloo.fines < 0 ) %]<span class="credit">[% resultsloo.fines %]</span> [% ELSIF resultsloo.fines > 0 %] <span class="debit"><strong>[% resultsloo.fines %]</strong></span> [% ELSE %] [% resultsloo.fines %] [% END %]</td>
79
							<td>[% resultsloo.borrowernotes %]</td>
80
							<td>[% IF ( resultsloo.category_type ) %]
81
									<a href="/cgi-bin/koha/members/memberentry.pl?op=modify&amp;destination=circ&amp;borrowernumber=[% resultsloo.borrowernumber %]&amp;category_type=[% resultsloo.category_type %]">Edit</a>
82
						[% ELSE %] <!-- try with categorycode if no category_type -->
83
							[% IF ( resultsloo.categorycode ) %]
84
									<a href="/cgi-bin/koha/members/memberentry.pl?op=modify&amp;destination=circ&amp;borrowernumber=[% resultsloo.borrowernumber %]&amp;categorycode=[% resultsloo.categorycode %]">Edit</a>
85
							[% ELSE %] <!-- if no categorycode, set category_type to A by default -->
86
									<a href="/cgi-bin/koha/members/memberentry.pl?op=modify&amp;destination=circ&amp;borrowernumber=[% resultsloo.borrowernumber %]&amp;category_type=A">Edit</a>
87
							[% END %]
88
						[% END %]</td>
89
							</tr>
90
							[% END %]
91
							</tbody>
92
							</table>
93
							<div class="pages">[% IF ( multipage ) %][% paginationbar %][% END %]</div>
94
						</div>
95
						[% ELSE %]
96
						[% IF ( searching ) %]
97
						<div class="dialog alert">No results found</div>
98
						[% END %]
99
						[% END %]
100
174
101
					</div>
175
<div id="doc3" class="yui-t2">
102
				</div>
176
  <div id="bd">
177
    <div id="yui-main">
178
      <div class="yui-b">
179
        <div class="yui-g">
180
          [% INCLUDE 'patron-toolbar.inc' %]
181
          [% IF ( no_add ) %]
182
            <div class="dialog alert">
183
              <h3>Cannot add patron</h3>
184
              [% IF ( no_branches ) %]
185
                <p>There are <strong>no libraries defined</strong>. [% IF ( CAN_user_parameters ) %]Please <a href="/cgi-bin/koha/admin/branches.pl">add a library</a>.[% ELSE %]An administrator must define at least one library.[% END %]</p>
186
              [% END %]
187
              [% IF ( no_categories ) %]
188
                <p>There are <strong>no patron categories defined</strong>. [% IF ( CAN_user_parameters ) %]Please <a href="/cgi-bin/koha/admin/categorie.pl">add a patron category</a>.[% ELSE %]An administrator must define at least one patron category.[% END %]</p>
189
              [% END %]
190
            </div>
191
          [% END %]
192
          <div class="browse">
193
            Browse by last name:
194
            [% FOREACH letter IN alphabet.split(' ') %]
195
              <a style="cursor:pointer" onclick="filterByFirstLetterSurname('[% letter %]');">[% letter %]</a>
196
            [% END %]
197
          </div>
103
198
104
				<div class="yui-g">
199
          [% IF ( CAN_user_borrowers && pending_borrower_modifications ) %]
105
				[% INCLUDE 'members-menu.inc' %]
200
            <div class="pending-info" id="patron_updates_pending">
106
			</div>
201
              <a href="/cgi-bin/koha/members/members-update.pl">Patrons requesting modifications</a>:
202
              <span class="holdcount"><a href="/cgi-bin/koha/members/members-update.pl">[% pending_borrower_modifications %]</a></span>
203
            </div>
204
          [% END %]
107
205
206
            <div id="searchheader">
207
              <h3>Results found <span id="searchpattern">[% IF searchmember %] for '[% searchmember %]'[% END %]</span></h3>
208
            </div>
209
            <div class="searchresults">
210
              <table id="memberresultst">
211
                <thead>
212
                  <tr>
213
                    <th>Card</th>
214
                    <th>Name</th>
215
                    <th>Cat</th>
216
                    <th>Library</th>
217
                    <th>Expires on</th>
218
                    <th>OD/Checkouts</th>
219
                    <th>Fines</th>
220
                    <th>Circ note</th>
221
                    <th>&nbsp;</th>
222
                  </tr>
223
                </thead>
224
                <tbody></tbody>
225
              </table>
226
            </div>
227
        </div>
228
      </div>
229
    </div>
230
    <div class="yui-b">
231
      <form onsubmit="return filter();" id="searchform">
232
        <input type="hidden" id="firstletter_filter" value="" />
233
        <fieldset class="brief">
234
          <h3>Filters</h3>
235
          <ol>
236
            <li>
237
              <label for="searchmember_filter">Search:</label>
238
              <input type="text" id="searchmember_filter" value="[% searchmember %]"/>
239
            </li>
240
            <li>
241
              <label for="searchfieldstype_filter">Search fields:</label>
242
              <select name="searchfieldstype" id="searchfieldstype_filter">
243
                [% IF searchfieldstype == "standard" %]
244
                  <option selected="selected" value='standard'>Standard</option>
245
                [% ELSE %]
246
                  <option value='standard'>Standard</option>
247
                [% END %]
248
                [% IF searchfieldstype == "email" %]
249
                  <option selected="selected" value='email'>Email</option>
250
                [% ELSE %]
251
                  <option value='email'>Email</option>
252
                [% END %]
253
                [% IF searchfieldstype == "borrowernumber" %]
254
                  <option selected="selected" value='borrowernumber'>Borrower number</option>
255
                [% ELSE %]
256
                  <option value='borrowernumber'>Borrower number</option>
257
                [% END %]
258
                [% IF searchfieldstype == "phone" %]
259
                  <option selected="selected" value='phone'>Phone number</option>
260
                [% ELSE %]
261
                  <option value='phone'>Phone number</option>
262
                [% END %]
263
                [% IF searchfieldstype == "address" %]
264
                  <option selected="selected" value='address'>Street Address</option>
265
                [% ELSE %]
266
                  <option value='address'>Street Address</option>
267
                [% END %]
268
                [% IF searchfieldstype == "dateofbirth" %]
269
                  <option selected="selected" value='dateofbirth'>Date of birth</option>
270
                [% ELSE %]
271
                  <option value='dateofbirth'>Date of birth</option>
272
                [% END %]
273
              </select>
274
            </li>
275
            <li>
276
              <label for="searchtype_filter">Search type:</label>
277
              <select name="searchtype" id="searchtype_filter">
278
                <option value='start_with'>Starts with</option>
279
                [% IF searchtype == "contain" %]
280
                  <option value="contain" selected="selected">Contains</option>
281
                [% ELSE %]
282
                  <option value="contain" selected="selected">Contains</option>
283
                [% END %]
284
              </select>
285
            </li>
286
            <li>
287
              <label for="categorycode_filter">Category:</label>
288
              <select id="categorycode_filter">
289
                <option value="">Any</option>
290
                [% FOREACH cat IN categories %]
291
                  [% IF cat.selected %]
292
                    <option selected="selected" value="[% cat.categorycode %]">[% cat.description %]</option>
293
                  [% ELSE %]
294
                    <option value="[% cat.categorycode %]">[% cat.description %]</option>
295
                  [% END %]
296
                [% END %]
297
              </select>
298
            </li>
299
            <li>
300
              <label for="branchcode_filter">Branch:</label>
301
              <select id="branchcode_filter">
302
                [% IF branchloop.size != 1 %]
303
                  <option value="">Any</option>
304
                [% END %]
305
                [% FOREACH b IN branchloop %]
306
                  [% IF b.selected %]
307
                    <option selected="selected" value="[% b.branchcode %]">[% b.branchname %]</option>
308
                  [% ELSE %]
309
                    <option value="[% b.branchcode %]">[% b.branchname %]</option>
310
                  [% END %]
311
                [% END %]
312
              </select>
313
            </li>
314
          </ol>
315
          <fieldset class="action">
316
            <input type="submit" value="Search" />
317
            <input type="button" value="Clear" onclick="clearFilters(true);" />
318
          </fieldset>
319
        </fieldset>
320
      </form>
108
    </div>
321
    </div>
322
  </div>
323
  <div class="yui-g">
324
    [% INCLUDE 'members-menu.inc' %]
325
  </div>
109
</div>
326
</div>
110
[% INCLUDE 'intranet-bottom.inc' %]
327
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/tables/members_results.tt (+31 lines)
Line 0 Link Here
1
{
2
    "sEcho": [% sEcho %],
3
    "iTotalRecords": [% iTotalRecords %],
4
    "iTotalDisplayRecords": [% iTotalDisplayRecords %],
5
    "aaData": [
6
        [% FOREACH data IN aaData %]
7
            {
8
                "dt_cardnumber":
9
                    "[% data.cardnumber %]",
10
                "dt_name":
11
                    "<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><br />[% IF ( data.streetnumber ) %][% data.streetnumber %] [% END %][% data.address %][% IF ( data.address2 ) %]<br />[% data.address2 %][% END %][% IF ( data.city ) %]<br />[% data.city %][% IF ( data.state ) %],[% END %][% END %][% IF ( data.state ) %] [% data.state %][% END %] [% IF ( data.zipcode ) %]  [% data.zipcode %][% END %][% IF ( data.country ) %], [% data.country %][% END %]</span>",
12
                "dt_category":
13
                    "[% data.category_description |html %]([% data.category_type |html %])",
14
                "dt_branch":
15
                    "[% data.branchname |html %]",
16
                "dt_dateexpiry":
17
                    "[% data.dateexpiry %]",
18
                "dt_od_checkouts":
19
                    "[% IF data.overdues %]<span class='overdue'><strong>[% data.overdues %]</strong></span>[% ELSE %][% data.overdues %][% END %] / [% data.issues %]",
20
                "dt_fines":
21
                    "[% IF data.fines < 0 %]<span class='credit'>[% data.fines |html %]</span> [% ELSIF data.fines > 0 %] <span class='debit'><strong>[% data.fines |html %]</strong></span> [% ELSE %] [% data.fines |html%] [% END %]</td>",
22
                "dt_borrowernotes":
23
                    "[% data.borrowernotes |html %]",
24
                "dt_action":
25
                    "[% IF data.category_type %]<a href='/cgi-bin/koha/members/memberentry.pl?op=modify&amp;destination=circ&amp;borrowernumber=[% data.borrowernumber %]&amp;category_type=[% data.category_type %]'>Edit</a>[% ELSE %][% IF data.categorycode %]<a href='/cgi-bin/koha/members/memberentry.pl?op=modify&amp;destination=circ&amp;borrowernumber=[% data.borrowernumber %]&amp;categorycode=[% data.categorycode %]'>Edit</a>[% ELSE %]<a href='/cgi-bin/koha/members/memberentry.pl?op=modify&amp;destination=circ&amp;borrowernumber=[% data.borrowernumber %]&amp;category_type=A'>Edit</a>[% END %][% END %]",
26
                "borrowernumber":
27
                    "[% data.borrowernumber %]"
28
            }[% UNLESS loop.last %],[% END %]
29
        [% END %]
30
    ]
31
}
(-)a/members/member.pl (-131 / +48 lines)
Lines 6-12 Link Here
6
6
7
7
8
# Copyright 2000-2002 Katipo Communications
8
# Copyright 2000-2002 Katipo Communications
9
# Copyright 2010 BibLibre
9
# Copyright 2013 BibLibre
10
#
10
#
11
# This file is part of Koha.
11
# This file is part of Koha.
12
#
12
#
Lines 23-43 Link Here
23
# with Koha; if not, write to the Free Software Foundation, Inc.,
23
# with Koha; if not, write to the Free Software Foundation, Inc.,
24
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25
25
26
use strict;
26
use Modern::Perl;
27
#use warnings; FIXME - Bug 2505
28
use C4::Auth;
27
use C4::Auth;
29
use C4::Output;
28
use C4::Output;
30
use CGI;
29
use CGI;
31
use C4::Members;
32
use C4::Branch;
30
use C4::Branch;
33
use C4::Category;
31
use C4::Category;
34
use Koha::DateUtils;
32
use Koha::DateUtils;
35
use File::Basename;
33
use File::Basename;
36
34
37
my $input = new CGI;
35
my $input = new CGI;
38
my $quicksearch = $input->param('quicksearch');
39
my $startfrom = $input->param('startfrom')||1;
40
my $resultsperpage = $input->param('resultsperpage')||C4::Context->preference("PatronsPerPage")||20;
41
36
42
my ($template, $loggedinuser, $cookie)
37
my ($template, $loggedinuser, $cookie)
43
    = get_template_and_user({template_name => "members/member.tmpl",
38
    = get_template_and_user({template_name => "members/member.tmpl",
Lines 47-193 my ($template, $loggedinuser, $cookie) Link Here
47
                 flagsrequired => {borrowers => 1},
42
                 flagsrequired => {borrowers => 1},
48
                 });
43
                 });
49
44
50
my $theme = $input->param('theme') || "default";
51
52
my $patron = $input->Vars;
45
my $patron = $input->Vars;
53
foreach (keys %$patron){
46
foreach (keys %$patron){
54
	delete $$patron{$_} unless($$patron{$_});
47
    delete $patron->{$_} unless($patron->{$_});
55
}
56
my @categories=C4::Category->all;
57
58
my $branches = GetBranches;
59
my @branchloop;
60
61
foreach (sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} } keys %$branches) {
62
  my $selected;
63
  $selected = 1 if $branches->{$_}->{branchcode} eq $$patron{branchcode};
64
  my %row = ( value => $_,
65
        selected => $selected,
66
        branchname => $branches->{$_}->{branchname},
67
      );
68
  push @branchloop, \%row;
69
}
48
}
70
49
71
my %categories_dislay;
72
73
foreach my $category (@categories){
74
	my $hash={
75
			category_description=>$$category{description},
76
			category_type=>$$category{category_type}
77
			 };
78
	$categories_dislay{$$category{categorycode}} = $hash;
79
}
80
my $AddPatronLists = C4::Context->preference("AddPatronLists") || '';
50
my $AddPatronLists = C4::Context->preference("AddPatronLists") || '';
81
$template->param( 
82
        "AddPatronLists_$AddPatronLists" => "1",
83
            );
84
if ($AddPatronLists=~/code/){
85
    $categories[0]->{'first'}=1;
86
}  
87
88
my $member=$input->param('member');
89
my $orderbyparams=$input->param('orderby');
90
my @orderby;
91
if ($orderbyparams){
92
	my @orderbyelt=split(/,/,$orderbyparams);
93
	push @orderby, {$orderbyelt[0]=>$orderbyelt[1]||0};
94
}
95
else {
96
	@orderby = ({surname=>0},{firstname=>0});
97
}
98
99
$member =~ s/,//g;   #remove any commas from search string
100
$member =~ s/\*/%/g;
101
51
102
my $from = ( $startfrom - 1 ) * $resultsperpage;
52
my $searchmember = $input->param('searchmember');
103
my $to   = $from + $resultsperpage;
104
53
105
my ($count,$results);
54
my $searchfieldstype = $input->param('searchfieldstype') || 'standard';
106
if ($member || keys %$patron) {
107
    my $searchfields = $input->param('searchfields');
108
    my @searchfields = $searchfields ? split( ',', $searchfields ) : ( "firstname", "surname", "othernames", "cardnumber", "userid", "email" );
109
55
110
    if ( $searchfields eq "dateofbirth" ) {
56
if ( $searchfieldstype eq "dateofbirth" ) {
111
        $member = output_pref(dt_from_string($member), 'iso', undef, 1);
57
    $searchmember = output_pref(dt_from_string($searchmember), 'iso', undef, 1);
112
    }
113
114
    my $search_scope = ( $quicksearch ? "field_start_with" : "start_with" );
115
    ($results) = Search( $member || $patron, \@orderby, undef, undef, \@searchfields, $search_scope );
116
}
58
}
117
59
118
if ($results) {
60
my $branches = C4::Branch::GetBranches;
119
	for my $field ('categorycode','branchcode'){
61
my @branches_loop;
120
		next unless ($patron->{$field});
62
if ( C4::Branch::onlymine ) {
121
		@$results = grep { $_->{$field} eq $patron->{$field} } @$results; 
63
    my $userenv = C4::Context->userenv;
122
	}
64
    my $branch = C4::Branch::GetBranchDetail( $userenv->{'branch'} );
123
    $count = scalar(@$results);
65
    push @branches_loop, {
66
        value => $branch->{branchcode},
67
        branchcode => $branch->{branchcode},
68
        branchname => $branch->{branchname},
69
        selected => 1
70
    }
71
} else {
72
    foreach ( sort { lc($branches->{$a}->{branchname}) cmp lc($branches->{$b}->{branchname}) } keys %$branches ) {
73
        my $selected = 0;
74
        $selected = 1 if($patron->{branchcode} and $patron->{branchcode} eq $_);
75
        push @branches_loop, {
76
            value => $_,
77
            branchcode => $_,
78
            branchname => $branches->{$_}->{branchname},
79
            selected => $selected
80
        };
81
    }
124
}
82
}
125
83
126
if($count == 1){
84
my @categories = C4::Category->all;
127
    print $input->redirect("/cgi-bin/koha/members/moremember.pl?borrowernumber=" . @$results[0]->{borrowernumber});
85
if ( $patron->{categorycode} ) {
128
    exit;
86
    foreach my $category ( grep { $_->{categorycode} eq $patron->{categorycode} } @categories ) {
87
        $category->{selected} = 1;
88
    }
129
}
89
}
130
90
131
my @resultsdata;
91
$template->param( 'alphabet' => C4::Context->preference('alphabet') || join ' ', 'A' .. 'Z' );
132
$to=($count>$to?$to:$count);
133
my $index=$from;
134
foreach my $borrower(@$results[$from..$to-1]){
135
  #find out stats
136
  my ($od,$issue,$fines)=GetMemberIssuesAndFines($$borrower{'borrowernumber'});
137
138
  $$borrower{'dateexpiry'}= C4::Dates->new($$borrower{'dateexpiry'},'iso')->output('syspref');
139
140
  my %row = (
141
    count => $index++,
142
    %$borrower,
143
    (defined $categories_dislay{ $borrower->{categorycode} }?   %{ $categories_dislay{ $borrower->{categorycode} } }:()),
144
    overdues => $od,
145
    issues => $issue,
146
    odissue => "$od/$issue",
147
    fines =>  sprintf("%.2f",$fines),
148
    branchname => $branches->{$borrower->{branchcode}}->{branchname},
149
    );
150
  push(@resultsdata, \%row);
151
}
152
92
153
if ($$patron{categorycode}){
93
my $orderby = $input->param('orderby') // '';
154
	foreach my $category (grep{$_->{categorycode} eq $$patron{categorycode}}@categories){
94
if(defined $orderby and $orderby ne '') {
155
		$$category{selected}=1;
95
    $orderby =~ s/[, ]/_/g;
156
	}
157
}
96
}
158
my %parameters=
159
        (  %$patron
160
		, 'orderby'			=> $orderbyparams 
161
		, 'resultsperpage'	=> $resultsperpage 
162
        , 'type'=> 'intranet'); 
163
my $base_url =
164
    'member.pl?&amp;'
165
  . join(
166
    '&amp;',
167
    map { "$_=$parameters{$_}" } (keys %parameters)
168
  );
169
170
my @letters = map { {letter => $_} } ( 'A' .. 'Z');
171
97
172
$template->param(
98
$template->param(
173
    letters => \@letters,
99
    searchmember        => $searchmember,
174
    paginationbar => pagination_bar(
100
    branchloop          => \@branches_loop,
175
        $base_url,
101
    categories          => \@categories,
176
        int( $count / $resultsperpage ) + ($count % $resultsperpage ? 1 : 0),
102
    branchcode          => $patron->{branchcode},
177
        $startfrom, 'startfrom'
103
    categorycode        => $patron->{categorycode},
178
    ),
104
    searchtype          => $input->param('searchtype') || 'start_with',
179
    startfrom => $startfrom,
105
    searchfieldstype    => $searchfieldstype,
180
    from      => ($startfrom-1)*$resultsperpage+1,  
106
    "orderby_$orderby"  => 1,
181
    to        => $to,
107
    PatronsPerPage      => C4::Context->preference("PatronsPerPage") || 20,
182
    multipage => ($count != $to || $startfrom!=1),
108
);
183
    advsearch => ($$patron{categorycode} || $$patron{branchcode}),
184
    branchloop=>\@branchloop,
185
    categories=>\@categories,
186
    searching       => "1",
187
		actionname		=>basename($0),
188
		%$patron,
189
        numresults      => $count,
190
        resultsloop     => \@resultsdata,
191
            );
192
109
193
output_html_with_http_headers $input, $cookie, $template->output;
110
output_html_with_http_headers $input, $cookie, $template->output;
(-)a/members/members-home.pl (-6 / +21 lines)
Lines 45-56 my ($template, $loggedinuser, $cookie) Link Here
45
45
46
my $branches = GetBranches;
46
my $branches = GetBranches;
47
my @branchloop;
47
my @branchloop;
48
foreach (sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} } keys %{$branches}) {
48
if ( C4::Branch::onlymine ) {
49
    my $userenv = C4::Context->userenv;
50
    my $branch = C4::Branch::GetBranchDetail( $userenv->{'branch'} );
49
    push @branchloop, {
51
    push @branchloop, {
50
        value      => $_,
52
        value => $branch->{branchcode},
51
        selected   => ($branches->{$_}->{branchcode} eq $branch),
53
        branchcode => $branch->{branchcode},
52
        branchname => $branches->{$_}->{branchname},
54
        branchname => $branch->{branchname},
53
    };
55
        selected => 1
56
    }
57
} else {
58
    foreach (sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} } keys %{$branches}) {
59
        push @branchloop, {
60
            value      => $_,
61
            selected   => ($branches->{$_}->{branchcode} eq $branch),
62
            branchname => $branches->{$_}->{branchname},
63
        };
64
    }
54
}
65
}
55
66
56
my @categories;
67
my @categories;
Lines 86-91 $template->param( Link Here
86
        no_add => $no_add,
97
        no_add => $no_add,
87
        pending_borrower_modifications => $pending_borrower_modifications,
98
        pending_borrower_modifications => $pending_borrower_modifications,
88
            );
99
            );
89
$template->param( 'alphabet' => C4::Context->preference('alphabet') || join ' ', 'A' .. 'Z' );
100
101
$template->param(
102
    alphabet => C4::Context->preference('alphabet') || join (' ', 'A' .. 'Z'),
103
    PatronsPerPage => C4::Context->preference("PatronsPerPage") || 20,
104
);
90
105
91
output_html_with_http_headers $query, $cookie, $template->output;
106
output_html_with_http_headers $query, $cookie, $template->output;
(-)a/members/moremember.pl (-10 / +9 lines)
Lines 53-60 use C4::Form::MessagingPreferences; Link Here
53
use List::MoreUtils qw/uniq/;
53
use List::MoreUtils qw/uniq/;
54
use C4::Members::Attributes qw(GetBorrowerAttributes);
54
use C4::Members::Attributes qw(GetBorrowerAttributes);
55
55
56
#use Smart::Comments;
57
#use Data::Dumper;
58
use DateTime;
56
use DateTime;
59
use Koha::DateUtils;
57
use Koha::DateUtils;
60
58
Lines 82-102 my $template_name; Link Here
82
my $quickslip = 0;
80
my $quickslip = 0;
83
81
84
my $flagsrequired;
82
my $flagsrequired;
85
if ($print eq "page") {
83
if (defined $print and $print eq "page") {
86
    $template_name = "members/moremember-print.tmpl";
84
    $template_name = "members/moremember-print.tmpl";
87
    # circ staff who process checkouts but can't edit
85
    # circ staff who process checkouts but can't edit
88
    # patrons still need to be able to access print view
86
    # patrons still need to be able to access print view
89
    $flagsrequired = { circulate => "circulate_remaining_permissions" };
87
    $flagsrequired = { circulate => "circulate_remaining_permissions" };
90
} elsif ($print eq "slip") {
88
} elsif (defined $print and $print eq "slip") {
91
    $template_name = "members/moremember-receipt.tmpl";
89
    $template_name = "members/moremember-receipt.tmpl";
92
    # circ staff who process checkouts but can't edit
90
    # circ staff who process checkouts but can't edit
93
    # patrons still need to be able to print receipts
91
    # patrons still need to be able to print receipts
94
    $flagsrequired =  { circulate => "circulate_remaining_permissions" };
92
    $flagsrequired =  { circulate => "circulate_remaining_permissions" };
95
} elsif ($print eq "qslip") {
93
} elsif (defined $print and $print eq "qslip") {
96
    $template_name = "members/moremember-receipt.tmpl";
94
    $template_name = "members/moremember-receipt.tmpl";
97
    $quickslip = 1;
95
    $quickslip = 1;
98
    $flagsrequired =  { circulate => "circulate_remaining_permissions" };
96
    $flagsrequired =  { circulate => "circulate_remaining_permissions" };
99
} elsif ($print eq "brief") {
97
} elsif (defined $print and $print eq "brief") {
100
    $template_name = "members/moremember-brief.tmpl";
98
    $template_name = "members/moremember-brief.tmpl";
101
    $flagsrequired = { borrowers => 1 };
99
    $flagsrequired = { borrowers => 1 };
102
} else {
100
} else {
Lines 157-163 if ($debar) { Link Here
157
}
155
}
158
156
159
$data->{'ethnicity'} = fixEthnicity( $data->{'ethnicity'} );
157
$data->{'ethnicity'} = fixEthnicity( $data->{'ethnicity'} );
160
$data->{ "sex_".$data->{'sex'}."_p" } = 1;
158
$data->{ "sex_".$data->{'sex'}."_p" } = 1 if defined $data->{sex};
161
159
162
my $catcode;
160
my $catcode;
163
if ( $category_type eq 'C') {
161
if ( $category_type eq 'C') {
Lines 281-293 if ($borrowernumber) { Link Here
281
        $getreserv{barcodereserv}  = $getiteminfo->{'barcode'};
279
        $getreserv{barcodereserv}  = $getiteminfo->{'barcode'};
282
        $getreserv{itemtype}  = $itemtypeinfo->{'description'};
280
        $getreserv{itemtype}  = $itemtypeinfo->{'description'};
283
281
284
        # 		check if we have a waitin status for reservations
282
        # check if we have a waitin status for reservations
285
        if ( $num_res->{'found'} eq 'W' ) {
283
        if ( defined $num_res->{found} and $num_res->{'found'} eq 'W' ) {
286
            $getreserv{color}   = 'reserved';
284
            $getreserv{color}   = 'reserved';
287
            $getreserv{waiting} = 1;
285
            $getreserv{waiting} = 1;
288
        }
286
        }
289
287
290
        # 		check transfers with the itemnumber foud in th reservation loop
288
        # check transfers with the itemnumber foud in th reservation loop
291
        if ($transfertwhen) {
289
        if ($transfertwhen) {
292
            $getreserv{color}      = 'transfered';
290
            $getreserv{color}      = 'transfered';
293
            $getreserv{transfered} = 1;
291
            $getreserv{transfered} = 1;
Lines 427-432 $template->param( Link Here
427
    AutoResumeSuspendedHolds => C4::Context->preference('AutoResumeSuspendedHolds'),
425
    AutoResumeSuspendedHolds => C4::Context->preference('AutoResumeSuspendedHolds'),
428
    SuspendHoldsIntranet => C4::Context->preference('SuspendHoldsIntranet'),
426
    SuspendHoldsIntranet => C4::Context->preference('SuspendHoldsIntranet'),
429
    RoutingSerials => C4::Context->preference('RoutingSerials'),
427
    RoutingSerials => C4::Context->preference('RoutingSerials'),
428
    PatronsPerPage => C4::Context->preference("PatronsPerPage") || 20,
430
);
429
);
431
$template->param( $error => 1 ) if $error;
430
$template->param( $error => 1 ) if $error;
432
431
(-)a/svc/members/search (-1 / +119 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# Copyright 2013 BibLibre
4
#
5
# This file is part of Koha
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 2 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use Modern::Perl;
21
use CGI;
22
23
use C4::Auth qw( get_template_and_user );
24
use C4::Output qw( output_with_http_headers );
25
use C4::Utils::DataTables qw( dt_get_params );
26
use C4::Utils::DataTables::Members qw( search );
27
28
my $input = new CGI;
29
30
exit unless $input->param('template_path');
31
32
my ($template, $user, $cookie) = get_template_and_user({
33
    template_name   => $input->param('template_path'),
34
    query           => $input,
35
    type            => "intranet",
36
    authnotrequired => 0,
37
    flagsrequired   => { borrowers => 1 }
38
});
39
40
my $searchmember = $input->param('searchmember');
41
my $firstletter  = $input->param('firstletter');
42
my $categorycode = $input->param('categorycode');
43
my $branchcode = $input->param('branchcode');
44
my $searchtype = $input->param('searchtype');
45
my $searchfieldstype = $input->param('searchfieldstype');
46
47
# variable information for DataTables (id)
48
my $sEcho = $input->param('sEcho');
49
50
my %dt_params = dt_get_params($input);
51
foreach (grep {$_ =~ /^mDataProp/} keys %dt_params) {
52
    $dt_params{$_} =~ s/^dt_//;
53
}
54
55
# Perform the patrons search
56
my $results = C4::Utils::DataTables::Members::search(
57
    {
58
        searchmember => $searchmember,
59
        firstletter => $firstletter,
60
        categorycode => $categorycode,
61
        branchcode => $branchcode,
62
        searchtype => $searchtype,
63
        searchfieldstype => $searchfieldstype,
64
        dt_params => \%dt_params,
65
66
    }
67
);
68
69
$template->param(
70
    sEcho => $sEcho,
71
    iTotalRecords => $results->{iTotalRecords},
72
    iTotalDisplayRecords => $results->{iTotalDisplayRecords},
73
    aaData => $results->{patrons}
74
);
75
76
output_with_http_headers $input, $cookie, $template->output, 'json';
77
78
__END__
79
80
=head1 NAME
81
82
search - a search script for finding patrons
83
84
=head1 SYNOPSIS
85
86
This script provides a service for template for patron search using DataTables
87
88
=head2 Performing a search
89
90
Call this script from a DataTables table my $searchmember = $input->param('searchmember');
91
All following params are optional:
92
    searchmember => the search terms
93
    firstletter => search patrons with surname begins with this pattern (currently only used for 1 letter)
94
    categorycode and branchcode => search patrons belong to a given categorycode or a branchcode
95
    searchtype: can be 'contain' or 'start_with'
96
    searchfieldstype: Can be 'standard', 'email', 'borrowernumber', 'phone' or 'address'
97
98
=cut
99
100
=back
101
102
=head1 LICENSE
103
104
Copyright 2013 BibLibre
105
106
This file is part of Koha.
107
108
Koha is free software; you can redistribute it and/or modify it under the
109
terms of the GNU General Public License as published by the Free Software
110
Foundation; either version 2 of the License, or (at your option) any later
111
version.
112
113
Koha is distributed in the hope that it will be useful, but WITHOUT ANY
114
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
115
A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
116
117
You should have received a copy of the GNU General Public License along
118
with Koha; if not, write to the Free Software Foundation, Inc.,
119
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

Return to bug 9811