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

(-)a/C4/Members.pm (-3 / +3 lines)
Lines 249-255 sub Search { Link Here
249
                $filter = [ $filter ];
249
                $filter = [ $filter ];
250
                push @$filter, {"borrowernumber"=>$matching_records};
250
                push @$filter, {"borrowernumber"=>$matching_records};
251
            }
251
            }
252
		}
252
        }
253
    }
253
    }
254
254
255
    # $showallbranches was not used at the time SearchMember() was mainstreamed into Search().
255
    # $showallbranches was not used at the time SearchMember() was mainstreamed into Search().
Lines 275-281 sub Search { Link Here
275
                else {
275
                else {
276
                    $filter = { '' => $filter, branchcode => $branch };
276
                    $filter = { '' => $filter, branchcode => $branch };
277
                }
277
                }
278
            }      
278
            }
279
        }
279
        }
280
    }
280
    }
281
281
Lines 284-290 sub Search { Link Here
284
    }
284
    }
285
    $searchtype ||= "start_with";
285
    $searchtype ||= "start_with";
286
286
287
	return SearchInTable( "borrowers", $filter, $orderby, $limit, $columns_out, $search_on_fields, $searchtype );
287
    return SearchInTable( "borrowers", $filter, $orderby, $limit, $columns_out, $search_on_fields, $searchtype );
288
}
288
}
289
289
290
=head2 GetMemberDetails
290
=head2 GetMemberDetails
(-)a/C4/Utils/DataTables/Members.pm (+200 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
    };
65
    for my $searchfield ( split /,/, $searchfields->{$searchfieldstype} ) {
66
        foreach my $term ( split / /, $searchmember) {
67
            next unless $term;
68
            $searchmember =~ s/\*/%/g; # * is replaced with % for sql
69
            $term .= '%' # end with anything
70
                if $term !~ /%$/;
71
            $term = "%$term" # begin with anythin unless start_with
72
                if $term !~ /^%/
73
                    and $searchtype eq "contain";
74
            push @where_strs_or, "borrowers." . $dbh->quote_identifier($searchfield) . " LIKE ?";
75
            push @where_args, $term;
76
        }
77
    }
78
    push @where_strs, '('. join (' OR ', @where_strs_or) . ')'
79
        if @where_strs_or;
80
81
    my $where;
82
    $where = "WHERE " . join (" AND ", @where_strs) if @where_strs;
83
    my $orderby = dt_build_orderby($dt_params);
84
85
    my $limit;
86
    if(defined $dt_params->{iDisplayStart} and defined $dt_params->{iDisplayLength}) {
87
        # In order to avoir sql injection
88
        $dt_params->{iDisplayStart} =~ s/\D//g;
89
        $dt_params->{iDisplayLength} =~ s/\D//g;
90
        $limit = "LIMIT $dt_params->{iDisplayStart},$dt_params->{iDisplayLength}";
91
    }
92
93
    my $query = join(" ", $select, $from, $where, $orderby, $limit);
94
    my $sth = $dbh->prepare($query);
95
    $sth->execute(@where_args);
96
    my $patrons = $sth->fetchall_arrayref({});
97
98
    # Get the iTotalDisplayRecords DataTable variable
99
    $query = "SELECT FOUND_ROWS()";
100
    $sth = $dbh->prepare($query);
101
    $sth->execute;
102
    ($iTotalDisplayRecords) = $sth->fetchrow_array;
103
104
    # Get the iTotalRecords DataTable variable
105
    $query = "SELECT COUNT(*) FROM borrowers";
106
    $sth = $dbh->prepare($query);
107
    $sth->execute;
108
    ($iTotalRecords) = $sth->fetchrow_array;
109
110
    # Get some information on patrons
111
    foreach my $patron (@$patrons) {
112
        ($patron->{overdues}, $patron->{issues}, $patron->{fines}) =
113
            GetMemberIssuesAndFines($patron->{borrowernumber});
114
        if($patron->{dateexpiry} and $patron->{dateexpiry} ne '0000-00-00') {
115
            $patron->{dateexpiry} = C4::Dates->new($patron->{dateexpiry}, "iso")->output();
116
        } else {
117
            $patron->{dateexpiry} = '';
118
        }
119
        $patron->{fines} = sprintf("%.2f", $patron->{fines} || 0);
120
    }
121
122
    return {
123
        iTotalRecords => $iTotalRecords,
124
        iTotalDisplayRecords => $iTotalDisplayRecords,
125
        patrons => $patrons
126
    }
127
}
128
129
1;
130
__END__
131
132
=head1 NAME
133
134
C4::Utils::DataTables::Members - module for using DataTables with patrons
135
136
=head1 SYNOPSIS
137
138
This module provides (one for the moment) routines used by the patrons search
139
140
=head2 FUNCTIONS
141
142
=head3 search
143
144
    my $dt_infos = C4::Utils::DataTables::Members->search($params);
145
146
$params is a hashref with some keys:
147
148
=over 4
149
150
=item searchmember
151
152
  String to search in the borrowers sql table
153
154
=item firstletter
155
156
  Introduced to contain 1 letter but can contain more.
157
  The search will done on the borrowers.surname field
158
159
=item categorycode
160
161
  Search patrons with this categorycode
162
163
=item branchcode
164
165
  Search patrons with this branchcode
166
167
=item searchtype
168
169
  Can be 'contain' or 'start_with'. Used for the searchmember parameter.
170
171
=item searchfieldstype
172
173
  Can be 'standard', 'email', 'borrowernumber', 'phone' or 'address'
174
175
=item dt_params
176
177
  Is the reference of C4::Utils::DataTables::dt_get_params($input);
178
179
=cut
180
181
=back
182
183
=head1 LICENSE
184
185
Copyright 2013 BibLibre
186
187
This file is part of Koha.
188
189
Koha is free software; you can redistribute it and/or modify it under the
190
terms of the GNU General Public License as published by the Free Software
191
Foundation; either version 2 of the License, or (at your option) any later
192
version.
193
194
Koha is distributed in the hope that it will be useful, but WITHOUT ANY
195
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
196
A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
197
198
You should have received a copy of the GNU General Public License along
199
with Koha; if not, write to the Free Software Foundation, Inc.,
200
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/patron-search.inc (-16 / +35 lines)
Lines 4-39 Link Here
4
	<div id="patron_search" class="residentsearch">
4
	<div id="patron_search" class="residentsearch">
5
	<p class="tip">Enter patron card number or partial name:</p>
5
	<p class="tip">Enter patron card number or partial name:</p>
6
	<form action="/cgi-bin/koha/members/member.pl" method="post">
6
	<form action="/cgi-bin/koha/members/member.pl" method="post">
7
    <input id="searchmember" size="25" class="focus" name="member" type="text" value="[% member %]"/>
7
    <input id="searchmember" size="25" class="focus" name="searchmember" type="text" value="[% searchmember %]"/>
8
	[% IF ( branchloop ) %]
8
	[% IF ( branchloop ) %]
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
	[% END %]
11
	[% END %]
12
12
13
      <label for="searchfields">Search fields:</label>
13
      <label for="searchfieldstype">Search fields:</label>
14
      <select name="searchfields" id="searchfields">
14
      <select name="searchfieldstype" id="searchfieldstype">
15
          <option selected="selected" value=''>Standard</option>
15
        [% IF searchfieldstype == "standard" %]
16
          <option value='email,emailpro,B_email,'>Email</option>
16
          <option selected="selected" value='standard'>Standard</option>
17
        [% ELSE %]
18
          <option value='standard'>Standard</option>
19
        [% END %]
20
        [% IF searchfieldstype == "email" %]
21
          <option selected="selected" value='email'>Email</option>
22
        [% ELSE %]
23
          <option value='email'>Email</option>
24
        [% END %]
25
        [% IF searchfieldstype == "borrowernumber" %]
26
          <option selected="selected" value='borrowernumber'>Borrower number</option>
27
        [% ELSE %]
17
          <option value='borrowernumber'>Borrower number</option>
28
          <option value='borrowernumber'>Borrower number</option>
18
          <option value='phone,phonepro,B_phone,altcontactphone,mobile'>Phone number</option>
29
        [% END %]
19
          <option value='streettype,address,address2,city,state,zipcode,country'>Street Address</option>
30
        [% IF searchfieldstype == "phone" %]
31
          <option selected="selected" value='phone'>Phone number</option>
32
        [% ELSE %]
33
          <option value='phone'>Phone number</option>
34
        [% END %]
35
        [% IF searchfieldstype == "address" %]
36
          <option selected="selected" value='address'>Street Address</option>
37
        [% ELSE %]
38
          <option value='address'>Street Address</option>
39
        [% END %]
20
      </select>
40
      </select>
21
41
22
      <label for="searchtype">Search type:</label>
42
      <label for="searchtype">Search type:</label>
23
      <select name="searchtype" id="searchtype">
43
      <select name="searchtype" id="searchtype">
24
          <option selected="selected" value=''>Starts with</option>
44
          <option selected="selected" value='start_with'>Starts with</option>
25
          <option value='contain'>Contains</option>
45
          <option value='contain'>Contains</option>
26
      </select>
46
      </select>
27
47
28
    <label for="orderby">Order by:</label>
29
    <select name="orderby" id="searchorderby">
30
    <option value="">Surname, Firstname</option>
31
    <option value="cardnumber,0">Cardnumber</option>
32
    </select>
33
    <input value="Search" class="submit" type="submit" />
48
    <input value="Search" class="submit" type="submit" />
34
	[% IF ( branchloop ) %]
49
    [% IF ( branchloop ) %]
35
	<p id="filters"> <label for="branchcode">Library: </label><select name="branchcode" id="branchcode">
50
    <p id="filters"> <label for="branchcode">Library: </label>
36
        <option value="">Any</option>[% FOREACH branchloo IN branchloop %]
51
    <select name="branchcode" id="branchcode">
52
        [% IF branchloop.size != 1 %]
53
          <option value="">Any</option>
54
        [% END %]
55
        [% FOREACH branchloo IN branchloop %]
37
        [% IF ( branchloo.selected ) %]
56
        [% IF ( branchloo.selected ) %]
38
        <option value="[% branchloo.value %]" selected="selected">[% branchloo.branchname %]</option>[% ELSE %]
57
        <option value="[% branchloo.value %]" selected="selected">[% branchloo.branchname %]</option>[% ELSE %]
39
        <option value="[% branchloo.value %]">[% branchloo.branchname %]</option>[% END %]
58
        <option value="[% branchloo.value %]">[% branchloo.branchname %]</option>[% END %]
(-)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 / +2 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 470-473 jQuery.extend( jQuery.fn.dataTableExt.oSort, { Link Here
470
    }
470
    }
471
} );
471
} );
472
472
473
}());
473
}());
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/member.tt (-92 / +304 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
              </select>
269
            </li>
270
            <li>
271
              <label for="searchtype_filter">Search type:</label>
272
              <select name="searchtype" id="searchtype_filter">
273
                <option value='start_with'>Starts with</option>
274
                [% IF searchtype == "contain" %]
275
                  <option value="contain" selected="selected">Contains</option>
276
                [% ELSE %]
277
                  <option value="contain" selected="selected">Contains</option>
278
                [% END %]
279
              </select>
280
            </li>
281
            <li>
282
              <label for="categorycode_filter">Category:</label>
283
              <select id="categorycode_filter">
284
                <option value="">Any</option>
285
                [% FOREACH cat IN categories %]
286
                  [% IF cat.selected %]
287
                    <option selected="selected" value="[% cat.categorycode %]">[% cat.description %]</option>
288
                  [% ELSE %]
289
                    <option value="[% cat.categorycode %]">[% cat.description %]</option>
290
                  [% END %]
291
                [% END %]
292
              </select>
293
            </li>
294
            <li>
295
              <label for="branchcode_filter">Branch:</label>
296
              <select id="branchcode_filter">
297
                [% IF branchloop.size != 1 %]
298
                  <option value="">Any</option>
299
                [% END %]
300
                [% FOREACH b IN branchloop %]
301
                  [% IF b.selected %]
302
                    <option selected="selected" value="[% b.branchcode %]">[% b.branchname %]</option>
303
                  [% ELSE %]
304
                    <option value="[% b.branchcode %]">[% b.branchname %]</option>
305
                  [% END %]
306
                [% END %]
307
              </select>
308
            </li>
309
          </ol>
310
          <fieldset class="action">
311
            <input type="submit" value="Search" />
312
            <input type="button" value="Clear" onclick="clearFilters(true);" />
313
          </fieldset>
314
        </fieldset>
315
      </form>
108
    </div>
316
    </div>
317
  </div>
318
  <div class="yui-g">
319
    [% INCLUDE 'members-menu.inc' %]
320
  </div>
109
</div>
321
</div>
110
[% INCLUDE 'intranet-bottom.inc' %]
322
[% 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 (-134 / +45 lines)
Lines 23-30 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;
Lines 34-42 use C4::Category; Link Here
34
use File::Basename;
33
use File::Basename;
35
34
36
my $input = new CGI;
35
my $input = new CGI;
37
my $quicksearch = $input->param('quicksearch');
38
my $startfrom = $input->param('startfrom')||1;
39
my $resultsperpage = $input->param('resultsperpage')||C4::Context->preference("PatronsPerPage")||20;
40
36
41
my ($template, $loggedinuser, $cookie)
37
my ($template, $loggedinuser, $cookie)
42
    = get_template_and_user({template_name => "members/member.tmpl",
38
    = get_template_and_user({template_name => "members/member.tmpl",
Lines 46-195 my ($template, $loggedinuser, $cookie) Link Here
46
                 flagsrequired => {borrowers => 1},
42
                 flagsrequired => {borrowers => 1},
47
                 });
43
                 });
48
44
49
my $theme = $input->param('theme') || "default";
50
51
my $patron = $input->Vars;
45
my $patron = $input->Vars;
52
foreach (keys %$patron){
46
foreach (keys %$patron){
53
	delete $$patron{$_} unless($$patron{$_});
47
    delete $patron->{$_} unless($patron->{$_});
54
}
55
my @categories=C4::Category->all;
56
57
my $branches = GetBranches;
58
my @branchloop;
59
60
foreach (sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} } keys %$branches) {
61
  my $selected;
62
  $selected = 1 if $branches->{$_}->{branchcode} eq $$patron{branchcode};
63
  my %row = ( value => $_,
64
        selected => $selected,
65
        branchname => $branches->{$_}->{branchname},
66
      );
67
  push @branchloop, \%row;
68
}
48
}
69
49
70
my %categories_dislay;
71
72
foreach my $category (@categories){
73
	my $hash={
74
			category_description=>$$category{description},
75
			category_type=>$$category{category_type}
76
			 };
77
	$categories_dislay{$$category{categorycode}} = $hash;
78
}
79
my $AddPatronLists = C4::Context->preference("AddPatronLists") || '';
50
my $AddPatronLists = C4::Context->preference("AddPatronLists") || '';
80
$template->param( 
81
        "AddPatronLists_$AddPatronLists" => "1",
82
            );
83
if ($AddPatronLists=~/code/){
84
    $categories[0]->{'first'}=1;
85
}  
86
87
my $member=$input->param('member');
88
my $orderbyparams=$input->param('orderby');
89
my @orderby;
90
if ($orderbyparams){
91
	my @orderbyelt=split(/,/,$orderbyparams);
92
	push @orderby, {$orderbyelt[0]=>$orderbyelt[1]||0};
93
}
94
else {
95
	@orderby = ({surname=>0},{firstname=>0});
96
}
97
51
98
my $searchfields = $input->param('searchfields');
52
my $searchmember = $input->param('searchmember');
99
my @searchfields = $searchfields ? split( ',', $searchfields ) : ( "firstname", "surname", "othernames", "cardnumber", "userid", "email" );
100
53
101
$member =~ s/,//g;   #remove any commas from search string
54
my $searchfieldstype = $input->param('searchfieldstype');
102
$member =~ s/\*/%/g;
103
55
104
my $searchtype = $input->param('searchtype');
56
my $branches = GetBranches;
105
my %searchtype_ok = ( 'contain' => 1 );
57
my @branches_loop;
106
if ( !defined($searchtype_ok{$searchtype}) ) {
58
if ( C4::Branch::onlymine ) {
107
    undef $searchtype;
59
    my $userenv = C4::Context->userenv;
108
}
60
    my $branch = C4::Branch::GetBranchDetail( $userenv->{'branch'} );
109
61
    push @branches_loop, {
110
my $from = ( $startfrom - 1 ) * $resultsperpage;
62
        value => $branch->{branchcode},
111
my $to   = $from + $resultsperpage;
63
        branchcode => $branch->{branchcode},
112
64
        branchname => $branch->{branchname},
113
my ($count,$results);
65
        selected => 1
114
if ($member || keys %$patron) {
66
    }
115
    #($results)=Search($member || $patron,{surname=>1,firstname=>1},[$from,$to],undef,["firstname","surname","email","othernames"]  );
67
} else {
116
    my $search_scope = $searchtype || ( $quicksearch ? "field_start_with" : "start_with" );
68
    foreach ( sort { lc($branches->{$a}->{branchname}) cmp lc($branches->{$b}->{branchname}) } keys %$branches ) {
117
    ($results) = Search( $member || $patron, \@orderby, undef, undef, \@searchfields, $search_scope );
69
        my $selected = 0;
118
}
70
        $selected = 1 if($patron->{branchcode} and $patron->{branchcode} eq $_);
119
71
        push @branches_loop, {
120
if ($results) {
72
            value => $_,
121
	for my $field ('categorycode','branchcode'){
73
            branchcode => $_,
122
		next unless ($patron->{$field});
74
            branchname => $branches->{$_}->{branchname},
123
		@$results = grep { $_->{$field} eq $patron->{$field} } @$results; 
75
            selected => $selected
124
	}
76
        };
125
    $count = scalar(@$results);
77
    }
126
}
78
}
127
79
128
if($count == 1){
80
my @categories = C4::Category->all;
129
    print $input->redirect("/cgi-bin/koha/members/moremember.pl?borrowernumber=" . @$results[0]->{borrowernumber});
81
if ( $patron->{categorycode} ) {
130
    exit;
82
    foreach my $category ( grep { $_->{categorycode} eq $patron->{categorycode} } @categories ) {
83
        $category->{selected} = 1;
84
    }
131
}
85
}
132
86
133
my @resultsdata;
87
$template->param( 'alphabet' => C4::Context->preference('alphabet') || join ' ', 'A' .. 'Z' );
134
$to=($count>$to?$to:$count);
135
my $index=$from;
136
foreach my $borrower(@$results[$from..$to-1]){
137
  #find out stats
138
  my ($od,$issue,$fines)=GetMemberIssuesAndFines($$borrower{'borrowernumber'});
139
140
  $$borrower{'dateexpiry'}= C4::Dates->new($$borrower{'dateexpiry'},'iso')->output('syspref');
141
142
  my %row = (
143
    count => $index++,
144
    %$borrower,
145
    (defined $categories_dislay{ $borrower->{categorycode} }?   %{ $categories_dislay{ $borrower->{categorycode} } }:()),
146
    overdues => $od,
147
    issues => $issue,
148
    odissue => "$od/$issue",
149
    fines =>  sprintf("%.2f",$fines),
150
    branchname => $branches->{$borrower->{branchcode}}->{branchname},
151
    );
152
  push(@resultsdata, \%row);
153
}
154
88
155
if ($$patron{categorycode}){
89
my $orderby = $input->param('orderby') // '';
156
	foreach my $category (grep{$_->{categorycode} eq $$patron{categorycode}}@categories){
90
if(defined $orderby and $orderby ne '') {
157
		$$category{selected}=1;
91
    $orderby =~ s/[, ]/_/g;
158
	}
159
}
92
}
160
my %parameters=
161
        (  %$patron
162
		, 'orderby'			=> $orderbyparams 
163
		, 'resultsperpage'	=> $resultsperpage 
164
        , 'type'=> 'intranet'); 
165
my $base_url =
166
    'member.pl?&amp;'
167
  . join(
168
    '&amp;',
169
    map { "$_=$parameters{$_}" } (keys %parameters)
170
  );
171
172
my @letters = map { {letter => $_} } ( 'A' .. 'Z');
173
93
174
$template->param(
94
$template->param(
175
    letters => \@letters,
95
    searchmember    => $searchmember,
176
    paginationbar => pagination_bar(
96
    branchloop      => \@branches_loop,
177
        $base_url,
97
    categories      => \@categories,
178
        int( $count / $resultsperpage ) + ($count % $resultsperpage ? 1 : 0),
98
    branchcode      => $patron->{branchcode},
179
        $startfrom, 'startfrom'
99
    categorycode    => $patron->{categorycode},
180
    ),
100
    searchtype      => $input->param('searchtype') || 'start_with',
181
    startfrom => $startfrom,
101
    searchfieldstype=> $input->param('searchfieldstype') || 'standard',
182
    from      => ($startfrom-1)*$resultsperpage+1,  
102
    "orderby_$orderby" => 1,
183
    to        => $to,
103
    PatronsPerPage  => C4::Context->preference("PatronsPerPage") || 20,
184
    multipage => ($count != $to || $startfrom!=1),
104
);
185
    advsearch => ($$patron{categorycode} || $$patron{branchcode}),
186
    branchloop=>\@branchloop,
187
    categories=>\@categories,
188
    searching       => "1",
189
		actionname		=>basename($0),
190
		%$patron,
191
        numresults      => $count,
192
        resultsloop     => \@resultsdata,
193
            );
194
105
195
output_html_with_http_headers $input, $cookie, $template->output;
106
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 (-11 / +10 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 127-133 if ( not defined $data ) { Link Here
127
}
125
}
128
126
129
# re-reregistration function to automatic calcul of date expiry
127
# re-reregistration function to automatic calcul of date expiry
130
if ( $reregistration eq 'y' ) {
128
if ( defined $reregistration and $reregistration eq 'y' ) {
131
	$data->{'dateexpiry'} = ExtendMemberSubscriptionTo( $borrowernumber );
129
	$data->{'dateexpiry'} = ExtendMemberSubscriptionTo( $borrowernumber );
132
}
130
}
133
131
Lines 163-169 if ($debar) { Link Here
163
}
161
}
164
162
165
$data->{'ethnicity'} = fixEthnicity( $data->{'ethnicity'} );
163
$data->{'ethnicity'} = fixEthnicity( $data->{'ethnicity'} );
166
$data->{ "sex_".$data->{'sex'}."_p" } = 1;
164
$data->{ "sex_".$data->{'sex'}."_p" } = 1 if defined $data->{sex};
167
165
168
my $catcode;
166
my $catcode;
169
if ( $category_type eq 'C') {
167
if ( $category_type eq 'C') {
Lines 287-299 if ($borrowernumber) { Link Here
287
        $getreserv{barcodereserv}  = $getiteminfo->{'barcode'};
285
        $getreserv{barcodereserv}  = $getiteminfo->{'barcode'};
288
        $getreserv{itemtype}  = $itemtypeinfo->{'description'};
286
        $getreserv{itemtype}  = $itemtypeinfo->{'description'};
289
287
290
        # 		check if we have a waitin status for reservations
288
        # check if we have a waitin status for reservations
291
        if ( $num_res->{'found'} eq 'W' ) {
289
        if ( defined $num_res->{found} and $num_res->{'found'} eq 'W' ) {
292
            $getreserv{color}   = 'reserved';
290
            $getreserv{color}   = 'reserved';
293
            $getreserv{waiting} = 1;
291
            $getreserv{waiting} = 1;
294
        }
292
        }
295
293
296
        # 		check transfers with the itemnumber foud in th reservation loop
294
        # check transfers with the itemnumber foud in th reservation loop
297
        if ($transfertwhen) {
295
        if ($transfertwhen) {
298
            $getreserv{color}      = 'transfered';
296
            $getreserv{color}      = 'transfered';
299
            $getreserv{transfered} = 1;
297
            $getreserv{transfered} = 1;
Lines 430-435 $template->param( Link Here
430
    activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
428
    activeBorrowerRelationship => (C4::Context->preference('borrowerRelationship') ne ''),
431
    AutoResumeSuspendedHolds => C4::Context->preference('AutoResumeSuspendedHolds'),
429
    AutoResumeSuspendedHolds => C4::Context->preference('AutoResumeSuspendedHolds'),
432
    SuspendHoldsIntranet => C4::Context->preference('SuspendHoldsIntranet'),
430
    SuspendHoldsIntranet => C4::Context->preference('SuspendHoldsIntranet'),
431
    PatronsPerPage => C4::Context->preference("PatronsPerPage") || 20,
433
);
432
);
434
$template->param( $error => 1 ) if $error;
433
$template->param( $error => 1 ) if $error;
435
434
(-)a/svc/members/search (-1 / +117 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
my ($template, $user, $cookie) = get_template_and_user({
31
    template_name   => $input->param('template_path'),
32
    query           => $input,
33
    type            => "intranet",
34
    authnotrequired => 0,
35
    flagsrequired   => { borrowers => 1 }
36
});
37
38
my $searchmember = $input->param('searchmember');
39
my $firstletter  = $input->param('firstletter');
40
my $categorycode = $input->param('categorycode');
41
my $branchcode = $input->param('branchcode');
42
my $searchtype = $input->param('searchtype');
43
my $searchfieldstype = $input->param('searchfieldstype');
44
45
# variable information for DataTables (id)
46
my $sEcho = $input->param('sEcho');
47
48
my %dt_params = dt_get_params($input);
49
foreach (grep {$_ =~ /^mDataProp/} keys %dt_params) {
50
    $dt_params{$_} =~ s/^dt_//;
51
}
52
53
# Perform the patrons search
54
my $results = C4::Utils::DataTables::Members::search(
55
    {
56
        searchmember => $searchmember,
57
        firstletter => $firstletter,
58
        categorycode => $categorycode,
59
        branchcode => $branchcode,
60
        searchtype => $searchtype,
61
        searchfieldstype => $searchfieldstype,
62
        dt_params => \%dt_params,
63
64
    }
65
);
66
67
$template->param(
68
    sEcho => $sEcho,
69
    iTotalRecords => $results->{iTotalRecords},
70
    iTotalDisplayRecords => $results->{iTotalDisplayRecords},
71
    aaData => $results->{patrons}
72
);
73
74
output_with_http_headers $input, $cookie, $template->output, 'json';
75
76
__END__
77
78
=head1 NAME
79
80
search - a search script for finding patrons
81
82
=head1 SYNOPSIS
83
84
This script provides a service for template for patron search using DataTables
85
86
=head2 Performing a search
87
88
Call this script from a DataTables table my $searchmember = $input->param('searchmember');
89
All following params are optional:
90
    searchmember => the search terms
91
    firstletter => search patrons with surname begins with this pattern (currently only used for 1 letter)
92
    categorycode and branchcode => search patrons belong to a given categorycode or a branchcode
93
    searchtype: can be 'contain' or 'start_with'
94
    searchfieldstype: Can be 'standard', 'email', 'borrowernumber', 'phone' or 'address'
95
96
=cut
97
98
=back
99
100
=head1 LICENSE
101
102
Copyright 2013 BibLibre
103
104
This file is part of Koha.
105
106
Koha is free software; you can redistribute it and/or modify it under the
107
terms of the GNU General Public License as published by the Free Software
108
Foundation; either version 2 of the License, or (at your option) any later
109
version.
110
111
Koha is distributed in the hope that it will be useful, but WITHOUT ANY
112
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
113
A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
114
115
You should have received a copy of the GNU General Public License along
116
with Koha; if not, write to the Free Software Foundation, Inc.,
117
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

Return to bug 9811