else {
$filter = { '' => $filter, branchcode => $branch };
}
- }
+ }
}
}
--- /dev/null
+package C4::Utils::DataTables::Members;
+
+use C4::Branch qw/onlymine/;
+use C4::Context;
+use C4::Members qw/GetMemberIssuesAndFines/;
+use C4::Utils::DataTables;
+use Modern::Perl;
+
+sub search {
+ my ( $params ) = @_;
+ my $searchmember = $params->{searchmember};
+ my $firstletter = $params->{firstletter};
+ my $categorycode = $params->{categorycode};
+ my $branchcode = $params->{branchcode};
+ my $searchtype = $params->{searchtype};
+ my $searchfieldstype = $params->{searchfieldstype};
+ my $dt_params = $params->{dt_params};
+
+ my ($iTotalRecords, $iTotalDisplayRecords);
+
+ # If branches are independant and user is not superlibrarian
+ # The search has to be only on the user branch
+ if ( C4::Branch::onlymine ) {
+ my $userenv = C4::Context->userenv;
+ $branchcode = $userenv->{'branch'};
+
+ }
+
+ my $dbh = C4::Context->dbh;
+ my $select = "SELECT
+ borrowers.borrowernumber, borrowers.surname, borrowers.firstname, borrowers.address,
+ borrowers.address2, borrowers.city, borrowers.zipcode, borrowers.country,
+ CAST(borrowers.cardnumber AS UNSIGNED) AS cardnumber, borrowers.dateexpiry,
+ borrowers.borrowernotes, borrowers.branchcode,
+ categories.description AS category_description, categories.category_type,
+ branches.branchname";
+ my $from = "FROM borrowers
+ LEFT JOIN branches ON borrowers.branchcode = branches.branchcode
+ LEFT JOIN categories ON borrowers.categorycode = categories.categorycode";
+ my @where_args;
+ my @where_strs;
+ if(defined $firstletter and $firstletter ne '') {
+ push @where_strs, "borrowers.surname LIKE ?";
+ push @where_args, "$firstletter%";
+ }
+ if(defined $categorycode and $categorycode ne '') {
+ push @where_strs, "borrowers.categorycode = ?";
+ push @where_args, $categorycode;
+ }
+ if(defined $branchcode and $branchcode ne '') {
+ push @where_strs, "borrowers.branchcode = ?";
+ push @where_args, $branchcode;
+ }
+
+ # split on coma
+ $searchmember =~ s/,/ /g if $searchmember;
+ my @where_strs_or;
+ my $searchfields = {
+ standard => 'surname,firstname,othernames,cardnumber',
+ email => 'email,emailpro,B_email',
+ borrowernumber => 'borrowernumber',
+ phone => 'phone,phonepro,B_phone,altcontactphone,mobile',
+ address => 'streettype,address,address2,city,state,zipcode,country',
+ dateofbirth => 'dateofbirth',
+ sort1 => 'sort1',
+ sort2 => 'sort2',
+ };
+ for my $searchfield ( split /,/, $searchfields->{$searchfieldstype} ) {
+ foreach my $term ( split / /, $searchmember) {
+ next unless $term;
+ $searchmember =~ s/\*/%/g; # * is replaced with % for sql
+ $term .= '%' # end with anything
+ if $term !~ /%$/;
+ $term = "%$term" # begin with anythin unless start_with
+ if $term !~ /^%/
+ and $searchtype eq "contain";
+ push @where_strs_or, "borrowers." . $dbh->quote_identifier($searchfield) . " LIKE ?";
+ push @where_args, $term;
+ }
+ }
+ push @where_strs, '('. join (' OR ', @where_strs_or) . ')'
+ if @where_strs_or;
+
+ my $where;
+ $where = " WHERE " . join (" AND ", @where_strs) if @where_strs;
+ my $orderby = dt_build_orderby($dt_params);
+
+ my $limit;
+ # If iDisplayLength == -1, we want to display all patrons
+ if ( $dt_params->{iDisplayLength} > -1 ) {
+ # In order to avoid sql injection
+ $dt_params->{iDisplayStart} =~ s/\D//g;
+ $dt_params->{iDisplayLength} =~ s/\D//g;
+ $dt_params->{iDisplayStart} //= 0;
+ $dt_params->{iDisplayLength} //= 20;
+ $limit = "LIMIT $dt_params->{iDisplayStart},$dt_params->{iDisplayLength}";
+ }
+
+ my $query = join(
+ " ",
+ ($select ? $select : ""),
+ ($from ? $from : ""),
+ ($where ? $where : ""),
+ ($orderby ? $orderby : ""),
+ ($limit ? $limit : "")
+ );
+ my $sth = $dbh->prepare($query);
+ $sth->execute(@where_args);
+ my $patrons = $sth->fetchall_arrayref({});
+
+ # Get the iTotalDisplayRecords DataTable variable
+ $query = "SELECT COUNT(borrowers.borrowernumber) " . $from . ($where ? $where : "");
+ $sth = $dbh->prepare($query);
+ $sth->execute(@where_args);
+ ($iTotalDisplayRecords) = $sth->fetchrow_array;
+
+ # Get the iTotalRecords DataTable variable
+ $query = "SELECT COUNT(borrowers.borrowernumber) FROM borrowers";
+ $sth = $dbh->prepare($query);
+ $sth->execute;
+ ($iTotalRecords) = $sth->fetchrow_array;
+
+ # Get some information on patrons
+ foreach my $patron (@$patrons) {
+ ($patron->{overdues}, $patron->{issues}, $patron->{fines}) =
+ GetMemberIssuesAndFines($patron->{borrowernumber});
+ if($patron->{dateexpiry} and $patron->{dateexpiry} ne '0000-00-00') {
+ $patron->{dateexpiry} = C4::Dates->new($patron->{dateexpiry}, "iso")->output();
+ } else {
+ $patron->{dateexpiry} = '';
+ }
+ $patron->{fines} = sprintf("%.2f", $patron->{fines} || 0);
+ }
+
+ return {
+ iTotalRecords => $iTotalRecords,
+ iTotalDisplayRecords => $iTotalDisplayRecords,
+ patrons => $patrons
+ }
+}
+
+1;
+__END__
+
+=head1 NAME
+
+C4::Utils::DataTables::Members - module for using DataTables with patrons
+
+=head1 SYNOPSIS
+
+This module provides (one for the moment) routines used by the patrons search
+
+=head2 FUNCTIONS
+
+=head3 search
+
+ my $dt_infos = C4::Utils::DataTables::Members->search($params);
+
+$params is a hashref with some keys:
+
+=over 4
+
+=item searchmember
+
+ String to search in the borrowers sql table
+
+=item firstletter
+
+ Introduced to contain 1 letter but can contain more.
+ The search will done on the borrowers.surname field
+
+=item categorycode
+
+ Search patrons with this categorycode
+
+=item branchcode
+
+ Search patrons with this branchcode
+
+=item searchtype
+
+ Can be 'contain' or 'start_with'. Used for the searchmember parameter.
+
+=item searchfieldstype
+
+ Can be 'standard', 'email', 'borrowernumber', 'phone', 'address' or 'dateofbirth', 'sort1', 'sort2'
+
+=item dt_params
+
+ Is the reference of C4::Utils::DataTables::dt_get_params($input);
+
+=cut
+
+=back
+
+=head1 LICENSE
+
+Copyright 2013 BibLibre
+
+This file is part of Koha.
+
+Koha is free software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the Free Software
+Foundation; either version 2 of the License, or (at your option) any later
+version.
+
+Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with Koha; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
<div id="patron_search" class="residentsearch">
<p class="tip">Enter patron card number or partial name:</p>
<form action="/cgi-bin/koha/members/member.pl" method="post">
- <input name="member" id="searchmember" size="40" type="text"/>
+ <input name="searchmember" id="searchmember" size="40" type="text"/>
+ <input type="hidden" name="quicksearch" value="1" />
<input value="Submit" class="submit" type="submit" />
</form>
</div>[% END %]
<div id="patron_search" class="residentsearch">
<p class="tip">Enter patron card number or partial name:</p>
<form action="/cgi-bin/koha/members/member.pl" method="post">
- <input id="searchmember" data-toggle="tooltip" size="25" class="focus" name="member" type="text" value="[% member %]"/>
+ <input id="searchmember" data-toggle="tooltip" size="25" class="focus" name="searchmember" type="text" value="[% searchmember %]"/>
+ <input type="hidden" name="quicksearch" value="1" />
<span class="filteraction" id="filteraction_off"> <a href="#" onclick="$('#filters').toggle();$('.filteraction').toggle();">[-]</a></span>
<span class="filteraction" id="filteraction_on"> <a href="#" onclick="$('#filters').toggle();$('.filteraction').toggle();">[+]</a></span>
- <input value="Search" class="submit" type="submit" />
+ <label for="searchfieldstype">Search fields:</label>
+ <select name="searchfieldstype" id="searchfieldstype">
+ [% IF searchfieldstype == "standard" %]
+ <option selected="selected" value='standard'>Standard</option>
+ [% ELSE %]
+ <option value='standard'>Standard</option>
+ [% END %]
+ [% IF searchfieldstype == "email" %]
+ <option selected="selected" value='email'>Email</option>
+ [% ELSE %]
+ <option value='email'>Email</option>
+ [% END %]
+ [% IF searchfieldstype == "borrowernumber" %]
+ <option selected="selected" value='borrowernumber'>Borrower number</option>
+ [% ELSE %]
+ <option value='borrowernumber'>Borrower number</option>
+ [% END %]
+ [% IF searchfieldstype == "phone" %]
+ <option selected="selected" value='phone'>Phone number</option>
+ [% ELSE %]
+ <option value='phone'>Phone number</option>
+ [% END %]
+ [% IF searchfieldstype == "address" %]
+ <option selected="selected" value='address'>Street Address</option>
+ [% ELSE %]
+ <option value='address'>Street Address</option>
+ [% END %]
+ [% IF searchfieldstype == "dateofbirth" %]
+ <option selected="selected" value='dateofbirth'>Date of birth</option>
+ [% ELSE %]
+ <option value='dateofbirth'>Date of birth</option>
+ [% END %]
+ [% IF searchfieldstype == "sort1" %]
+ <option selected="selected" value='sort1'>Sort field 1</option>
+ [% ELSE %]
+ <option value='sort1'>Sort field 1</option>
+ [% END %]
+ [% IF searchfieldstype == "sort2" %]
+ <option selected="selected" value='sort2'>Sort field 2</option>
+ [% ELSE %]
+ <option value='sort2'>Sort field 2</option>
+ [% END %]
+ </select>
+
+ <script type="text/javascript">
+ [% SET dateformat = Koha.Preference('dateformat') %]
+ $("#searchfields").change(function() {
+ if ( $(this).val() == 'dateofbirth' ) {
+ [% IF dateformat == 'us' %]
+ var MSG_DATE_FORMAT = _("Dates of birth should be entered in the format 'MM/DD/YYYY'");
+ [% ELSIF dateformat == 'iso' %]
+ var MSG_DATE_FORMAT = _("Dates of birth should be entered in the format 'YYYY-MM-DD'");
+ [% ELSIF dateformat == 'metric' %]
+ var MSG_DATE_FORMAT = _("Dates of birth should be entered in the format 'DD/MM/YYYY'");
+ [% END %]
+ $('#searchmember').attr("title",MSG_DATE_FORMAT).tooltip('show');
+ } else {
+ $('#searchmember').tooltip('destroy');
+ }
+ });
+
+ </script>
- <div id="filters">
- <p><label for="searchfields">Search fields:</label>
- <select name="searchfields" id="searchfields">
- <option selected="selected" value=''>Standard</option>
- <option value='email,emailpro,B_email,'>Email</option>
- <option value='borrowernumber'>Borrower number</option>
- <option value='phone,phonepro,B_phone,altcontactphone,mobile'>Phone number</option>
- <option value='streettype,address,address2,city,state,zipcode,country'>Street Address</option>
- <option value='dateofbirth'>Date of birth</option>
- <option value='sort1'>Sort field 1</option>
- <option value='sort2'>Sort field 2</option>
- </select>
- <script type="text/javascript">
- [% SET dateformat = Koha.Preference('dateformat') %]
- $("#searchfields").change(function() {
- if ( $(this).val() == 'dateofbirth' ) {
- [% IF dateformat == 'us' %]
- var MSG_DATE_FORMAT = _("Dates of birth should be entered in the format 'MM/DD/YYYY'");
- [% ELSIF dateformat == 'iso' %]
- var MSG_DATE_FORMAT = _("Dates of birth should be entered in the format 'YYYY-MM-DD'");
- [% ELSIF dateformat == 'metric' %]
- var MSG_DATE_FORMAT = _("Dates of birth should be entered in the format 'DD/MM/YYYY'");
- [% END %]
- $('#searchmember').attr("title",MSG_DATE_FORMAT).tooltip('show');
- } else {
- $('#searchmember').tooltip('destroy');
- }
- });
- </script>
- </p>
- <p><label for="searchtype">Search type:</label>
- <select name="searchtype" id="searchtype">
- <option selected="selected" value=''>Starts with</option>
- <option value='contain'>Contains</option>
- </select></p>
+ <label for="searchtype">Search type:</label>
+ <select name="searchtype" id="searchtype">
+ <option selected="selected" value='start_with'>Starts with</option>
+ <option value='contain'>Contains</option>
+ </select>
- <p><label for="searchorderby">Order by:</label>
- <select name="orderby" id="searchorderby">
- <option value="">Surname, Firstname</option>
- <option value="cardnumber,0">Cardnumber</option>
- </select></p>
- [% IF ( branchloop ) %] <p><label for="branchcode">Library: </label><select name="branchcode" id="branchcode">
- <option value="">Any</option>[% FOREACH branchloo IN branchloop %]
- [% IF ( branchloo.selected ) %]
- <option value="[% branchloo.value %]" selected="selected">[% branchloo.branchname %]</option>[% ELSE %]
- <option value="[% branchloo.value %]">[% branchloo.branchname %]</option>[% END %]
- [% END %]</select></p>
- [% END %]
- [% IF ( categories ) %]
- <p><label for="categorycode">Category: </label><select name="categorycode" id="categorycode">
- <option value="">Any</option>[% FOREACH categorie IN categories %]
- [% IF ( categorie.selected ) %]
- <option value="[% categorie.categorycode %]" selected="selected">[% categorie.description |html_entity %]</option>[% ELSE %]
- <option value="[% categorie.categorycode %]">[% categorie.description |html_entity %]</option>[% END %]
- [% END %]</select></p>
- [% END %]
- </div>
+ <input value="Search" class="submit" type="submit" />
+ [% IF ( branchloop ) %]
+ <p id="filters"> <label for="branchcode">Library: </label>
+ <select name="branchcode" id="branchcode">
+ [% IF branchloop.size != 1 %]
+ <option value="">Any</option>
+ [% END %]
+ [% FOREACH branchloo IN branchloop %]
+ [% IF ( branchloo.selected ) %]
+ <option value="[% branchloo.value %]" selected="selected">[% branchloo.branchname %]</option>[% ELSE %]
+ <option value="[% branchloo.value %]">[% branchloo.branchname %]</option>[% END %]
+ [% END %]</select>
+ <label for="categorycode">Category: </label><select name="categorycode" id="categorycode">
+ <option value="">Any</option>[% FOREACH categorie IN categories %]
+ [% IF ( categorie.selected ) %]
+ <option value="[% categorie.categorycode %]" selected="selected">[% categorie.description |html_entity %]</option>[% ELSE %]
+ <option value="[% categorie.categorycode %]">[% categorie.description |html_entity %]</option>[% END %]
+ [% END %]</select>
+ </p>
+ [% END %]
</form>
</div>
-[% IF ( borrower.borrowernumber ) %]
- [% IF borrower.category_type == 'I' %]
- [% borrower.surname %] [% IF borrower.othernames %] ([% borrower.othernames %]) [% END %]
- [% ELSE %]
- [% IF invert_name %]
- [% borrower.surname %], [% borrower.firstname %] [% IF borrower.othernames %] ([% borrower.othernames %]) [% END %]
- [% ELSE %]
- [% borrower.firstname %] [% IF borrower.othernames %] ([% borrower.othernames %]) [% END %] [% borrower.surname %]
- [% END %]
- [% END %]
+[%- IF ( borrower.borrowernumber ) %]
+ [%- IF borrower.category_type == 'I' %]
+ [%- borrower.surname %] [% IF borrower.othernames %] ([% borrower.othernames %]) [% END %]
+ [%- ELSE %]
+ [%- IF invert_name %]
+ [%- borrower.surname %], [% borrower.firstname %] [% IF borrower.othernames %] ([% borrower.othernames %]) [% END %]
+ [%- ELSE %]
+ [%- borrower.firstname %] [% IF borrower.othernames %] ([% borrower.othernames %]) [% END %] [% borrower.surname %]
+ [%- END -%]
+ [%- END -%]
([% borrower.cardnumber %])
-[% ELSIF ( borrowernumber ) %]
- [% IF category_type == 'I' %]
- [% surname %] [% IF othernames %] ([% othernames %]) [% END %]
- [% ELSE %]
- [% IF invert_name %]
- [% surname %], [% firstname %] [% IF othernames %] ([% othernames %]) [% END %]
- [% ELSE %]
- [% firstname %] [% IF othernames %] ([% othernames %]) [% END %] [% surname %]
- [% END %]
- [% END %]
- ([% cardnumber %])
-[% END %]
\ No newline at end of file
+[%- ELSIF ( borrowernumber ) %]
+ [%- IF category_type == 'I' %]
+ [%- surname %] [% IF othernames %] ([% othernames %]) [% END %]
+ [%- ELSE %]
+ [%- IF invert_name %]
+ [%- surname %], [% firstname %] [% IF othernames %] ([% othernames %]) [% END %]
+ [%- ELSE %]
+ [%- firstname %] [% IF othernames %] ([% othernames %]) [% END %] [% surname %]
+ [%- END %]
+ [%- END -%]
+ ([% cardnumber -%])
+[%- END -%]
"sSearch" : window.MSG_DT_SEARCH || "Search:",
"sZeroRecords" : window.MSG_DT_ZERO_RECORDS || "No matching records found"
},
- "sDom": '<"top pager"ilpf>t<"bottom pager"ip>',
+ "sDom": '<"top pager"ilpf>tr<"bottom pager"ip>',
"aLengthMenu": [[10, 20, 50, 100, -1], [10, 20, 50, 100, window.MSG_DT_ALL || "All"]],
"iDisplayLength": 20
};
[% INCLUDE 'doc-head-open.inc' %]
<title>Koha › Patrons [% IF ( searching ) %]› Search results[% END %]</title>
[% INCLUDE 'doc-head-close.inc' %]
-
+<link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" />
+[% INCLUDE 'datatables.inc' %]
<script type="text/javascript">
//<![CDATA[
$(document).ready(function() {
$('#new_patron_list').hide();
$('#add_to_patron_list_submit').attr('disabled', 'disabled');
}
-
});
$('#new_patron_list').on('input', function() {
$('#add_to_patron_list_submit').attr('disabled', 'disabled');
}
});
+
+ $("#patron_list_dialog").hide();
+ $("#add_to_patron_list_submit").on('click', function(e){
+ if ( $('#add_to_patron_list').val() == 'new' ) {
+ if ( $('#new_patron_list').val() ) {
+ $("#add_to_patron_list option").each(function() {
+ if ( $(this).text() == $('#new_patron_list').val() ) {
+ alert( _("You already have a list with that name!") );
+ return false;
+ }
+ });
+ } else {
+ alert( _("You must give your new patron list a name!") );
+ return false;
+ }
+ }
+
+ if ( $("#memberresultst input:checkbox:checked").length == 0 ) {
+ alert( _("You have not selected any patrons to add to a list!") );
+ return false;
+ }
+
+ var borrowernumbers = [];
+ $("#memberresultst").find("input:checkbox:checked").each(function(){
+ borrowernumbers.push($(this).val());
+ });
+ var data = {
+ add_to_patron_list: encodeURIComponent($("#add_to_patron_list").val()),
+ new_patron_list: encodeURIComponent($("#new_patron_list").val()),
+ borrowernumbers: borrowernumbers
+ };
+ $.ajax({
+ data: data,
+ type: 'POST',
+ url: '/cgi-bin/koha/svc/members/add_to_list',
+ success: function(data) {
+ $("#patron_list_dialog").show();
+ $("#patron_list_dialog > span.patrons-length").html(data.patrons_added_to_list);
+ $("#patron_list_dialog > a").attr("href", "/cgi-bin/koha/patron_lists/list.pl?patron_list_id=" + data.patron_list.patron_list_id);
+ $("#patron_list_dialog > a").html(data.patron_list.name);
+ },
+ error: function() {
+ alert("an error occurred");
+ }
+ });
+ return true;
+ });
});
-function CheckForm() {
- if ( $('#add_to_patron_list').val() == 'new' ) {
- if ( $('#new_patron_list').val() ) {
- var exists = false;
- $("#add_to_patron_list option").each(function() {
- if ( $(this).text() == $('#new_patron_list').val() ) {
- exists = true;
- return false;
+var dtMemberResults;
+var search = 1;
+$(document).ready(function() {
+ [% IF searchmember %]
+ $("#searchmember_filter").val("[% searchmember %]");
+ [% END %]
+ [% IF searchfieldstype %]
+ $("searchfieldstype_filter").val("[% searchfieldstype %]");
+ [% END %]
+ [% IF searchtype %]
+ $("#searchtype_filter").val("[% searchtype %]");
+ [% END %]
+ [% IF categorycode %]
+ $("#categorycode_filter").val("[% categorycode %]");
+ [% END %]
+ [% IF branchcode %]
+ $("#branchcode_filter").val("[% branchcode %]");
+ [% END %]
+
+ [% IF view != "show_results" %]
+ $("#searchresults").hide();
+ search = 0;
+ [% END %]
+
+ // Build the aLengthMenu
+ var aLengthMenu = [
+ [%PatronsPerPage %], 10, 20, 50, 100, -1
+ ];
+ jQuery.unique(aLengthMenu);
+ aLengthMenu.sort(function( a, b ){
+ // Put "All" at the end
+ if ( a == -1 ) {
+ return 1;
+ } else if ( b == -1 ) {
+ return -1;
+ }
+ return parseInt(a) < parseInt(b) ? -1 : 1;}
+ );
+ var aLengthMenuLabel = [];
+ $(aLengthMenu).each(function(){
+ if ( this == -1 ) {
+ // Label for -1 is "All"
+ aLengthMenuLabel.push("All");
+ } else {
+ aLengthMenuLabel.push(this);
+ }
+ });
+
+ // Apply DataTables on the results table
+ dtMemberResults = $("#memberresultst").dataTable($.extend(true, {}, dataTablesDefaults, {
+ 'bServerSide': true,
+ 'sAjaxSource': "/cgi-bin/koha/svc/members/search",
+ 'fnServerData': function(sSource, aoData, fnCallback) {
+ if ( ! search ) {
+ return;
+ }
+ aoData.push({
+ 'name': 'searchmember',
+ 'value': $("#searchmember_filter").val()
+ },{
+ 'name': 'firstletter',
+ 'value': $("#firstletter_filter").val()
+ },{
+ 'name': 'searchfieldstype',
+ 'value': $("#searchfieldstype_filter").val()
+ },{
+ 'name': 'searchtype',
+ 'value': $("#searchtype_filter").val()
+ },{
+ 'name': 'categorycode',
+ 'value': $("#categorycode_filter").val()
+ },{
+ 'name': 'branchcode',
+ 'value': $("#branchcode_filter").val()
+ },{
+ 'name': 'name_sorton',
+ 'value': 'borrowers.surname borrowers.firstname'
+ },{
+ 'name': 'category_sorton',
+ 'value': 'categories.description',
+ },{
+ 'name': 'branch_sorton',
+ 'value': 'branches.branchname'
+ },{
+ 'name': 'template_path',
+ 'value': 'members/tables/members_results.tt',
+ });
+ $.ajax({
+ 'dataType': 'json',
+ 'type': 'POST',
+ 'url': sSource,
+ 'data': aoData,
+ 'success': function(json){
+ // redirect if there is only 1 result.
+ if ( json.aaData.length == 1 ) {
+ var borrowernumber = json.aaData[0].borrowernumber;
+ document.location.href="/cgi-bin/koha/members/moremember.pl?borrowernumber="+borrowernumber;
+ return false;
+ }
+ fnCallback(json);
}
});
+ },
+ 'aoColumns':[
+ [% IF CAN_user_tools_manage_patron_lists %]
+ { 'mDataProp': 'dt_borrowernumber' },
+ [% END %]
+ { 'mDataProp': 'dt_cardnumber' },
+ { 'mDataProp': 'dt_name' },
+ { 'mDataProp': 'dt_category' },
+ { 'mDataProp': 'dt_branch' },
+ { 'mDataProp': 'dt_dateexpiry' },
+ { 'mDataProp': 'dt_od_checkouts', 'bSortable': false },
+ { 'mDataProp': 'dt_fines', 'bSortable': false },
+ { 'mDataProp': 'dt_borrowernotes' },
+ { 'mDataProp': 'dt_action', 'bSortable': false }
+ ],
+ 'fnRowCallback': function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
+ /* Center text for 6th column */
+ $("td:eq(5)", nRow).css("text-align", "center");
- if ( exists ) {
- alert( _("You already have a list with that name!") );
- return false;
- }
+ return nRow;
+ },
+ 'bFilter': false,
+ 'bAutoWidth': false,
+ [% IF orderby_cardnumber_0 %]
+ 'aaSorting': [[0, 'asc']],
+ [% ELSE %]
+ 'aaSorting': [[1, 'asc']],
+ [% END %]
+ "aLengthMenu": [aLengthMenu, aLengthMenuLabel],
+ 'sPaginationType': 'full_numbers',
+ "iDisplayLength": [% PatronsPerPage %],
+ }));
+ update_searched();
+});
+
+// Update the string "Results found ..."
+function update_searched(){
+ var searched = "";
+ searched += "on " + $("#searchfieldstype_filter").find("option:selected").text().toLowerCase() + " fields";
+ if ( $("#searchmember_filter").val() ) {
+ if ( $("#searchtype_filter").val() == 'start_with' ) {
+ searched += _(" starting with ");
} else {
- alert( _("You must give your new patron list a name!") );
- return false;
+ searched += _(" containing ");
}
+ searched += $("#searchmember_filter").val();
+ }
+ if ( $("#firstletter_filter").val() ) {
+ searched += _(" begin with ") + $("#firstletter_filter").val();
+ }
+ if ( $("#categorycode_filter").val() ) {
+ searched += _(" with category ") + $("#categorycode_filter").find("option:selected").text();
+ }
+ if ( $("#branchcode_filter").val() ) {
+ searched += _(" in library ") + $("#branchcode_filter").find("option:selected").text();
}
+ $("#searchpattern").text("for patron " + searched);
+}
+
+// Redraw the table
+function filter() {
+ $("#firstletter_filter").val('');
+ update_searched();
+ search = 1;
+ $("#searchresults").show();
+ dtMemberResults.fnDraw();
+ return false;
+}
- if ( $('#add_to_patron_list_which').val() == 'all' ) {
- return confirm( _("Are you sure you want to add the entire set of patron results to this list ( including results on other pages )?") );
- } else {
- if ( $("#add-patrons-to-list-form input:checkbox:checked").length == 0 ) {
- alert( _("You have not selected any patrons to add to a list!") );
- return false;
- }
+// User has clicked on the Clear button
+function clearFilters(redraw) {
+ $("#searchform select").val('');
+ $("#firstletter_filter").val('');
+ $("#searchmember_filter").val('');
+ if(redraw) {
+ search = 1;
+ $("#searchresults").show();
+ dtMemberResults.fnDraw();
}
+}
- return true;
+// User has clicked on a letter
+function filterByFirstLetterSurname(letter) {
+ clearFilters(false);
+ $("#firstletter_filter").val(letter);
+ update_searched();
+ search = 1;
+ $("#searchresults").show();
+ dtMemberResults.fnDraw();
}
//]]>
</script>
-
</head>
<body id="pat_member" class="pat">
[% INCLUDE 'header.inc' %]
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › [% IF ( searching ) %]<a href="/cgi-bin/koha/members/members-home.pl">Patrons</a> › Search results[% ELSE %]Patrons[% END %]</div>
-<div id="doc2" class="yui-t7">
+<div id="doc3" class="yui-t2">
+ <div id="bd">
+ <div id="yui-main">
+ <div class="yui-b">
+ <div class="yui-g">
+ [% IF CAN_user_tools_manage_patron_lists %]
+ <div id="patron_list_dialog" class="dialog alert">
+ Added <span class="patrons-length"></span> patrons to <a></a>.
+ </div>
+ [% END %]
- <div id="bd">
- <div id="yui-main">
- <div class="yui-b">
- <div class="yui-g">
+ [% INCLUDE 'patron-toolbar.inc' %]
+ [% IF ( no_add ) %]
+ <div class="dialog alert">
+ <h3>Cannot add patron</h3>
+ [% 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 %]
+ [% 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>
+ [% END %]
+ <div class="browse">
+ Browse by last name:
+ [% FOREACH letter IN alphabet.split(' ') %]
+ <a style="cursor:pointer" onclick="filterByFirstLetterSurname('[% letter %]');">[% letter %]</a>
+ [% END %]
+ </div>
- [% IF patron_list %]
- <div class="dialog alert">
- Added [% patrons_added_to_list.size %] patrons to <a href="/cgi-bin/koha/patron_lists/list.pl?patron_list_id=[% patron_list.patron_list_id %]">[% patron_list.name %]</a>.
- </div>
- [% END %]
+ [% IF ( CAN_user_borrowers && pending_borrower_modifications ) %]
+ <div class="pending-info" id="patron_updates_pending">
+ <a href="/cgi-bin/koha/members/members-update.pl">Patrons requesting modifications</a>:
+ <span class="holdcount"><a href="/cgi-bin/koha/members/members-update.pl">[% pending_borrower_modifications %]</a></span>
+ </div>
+ [% END %]
+
+ <div id="searchresults">
+ <div id="searchheader">
+ <h3>Results found <span id="searchpattern">[% IF searchmember %] for '[% searchmember %]'[% END %]</span></h3>
+ </div>
+ [% IF CAN_user_tools_manage_patron_lists %]
+ <div id="searchheader">
+ <div>
+ <a href="javascript:void(0)" onclick="$('.selection').prop('checked', true)">Select all</a>
+ |
+ <a href="javascript:void(0)" onclick="$('.selection').prop('checked', false)">Clear all</a>
+ |
+ <span>
+ Add selected patrons
+ <label for="add_to_patron_list">to:</label>
+ <select id="add_to_patron_list" name="add_to_patron_list">
+ <option value=""></option>
+ [% IF patron_lists %]
+ <optgroup label="Patron lists:">
+ [% FOREACH pl IN patron_lists %]
+ <option value="[% pl.patron_list_id %]">[% pl.name %]</option>
+ [% END %]
+ </optgroup>
+ [% END %]
+
+ <option value="new">[ New list ]</option>
+ </select>
+
+ <input type="text" id="new_patron_list" name="new_patron_list" id="new_patron_list" />
- [% INCLUDE 'patron-toolbar.inc' %]
-
- [% IF ( no_add ) %]<div class="dialog alert"><h3>Cannot add patron</h3>
- [% 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 %]
- [% 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>
- [% END %]
-
- <div class="browse">
- Browse by last name:
- [% FOREACH letter IN alphabet.split(' ') %]
- <a href="/cgi-bin/koha/members/member.pl?quicksearch=1&surname=[% letter %]">[% letter %]</a>
- [% END %]
- </div>
-
- [% IF ( CAN_user_borrowers && pending_borrower_modifications ) %]
- <div class="pending-info" id="patron_updates_pending">
- <a href="/cgi-bin/koha/members/members-update.pl">Patrons requesting modifications</a>:
- <span class="holdcount"><a href="/cgi-bin/koha/members/members-update.pl">[% pending_borrower_modifications %]</a></span>
- </div>
- [% END %]
-
- [% IF ( resultsloop ) %]
- [% IF (CAN_user_tools_manage_patron_lists) %]
- <form id="add-patrons-to-list-form" method="post" action="member.pl" onsubmit="return CheckForm()">
- [% END %]
- <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>
-
- [% IF (CAN_user_tools_manage_patron_lists) %]
- <div>
- <a href="javascript:void(0)" onclick="$('.selection').prop('checked', true)">Select all</a>
- |
- <a href="javascript:void(0)" onclick="$('.selection').prop('checked', false)">Clear all</a>
- |
- <span>
- <label for="add_to_patron_list_which">Add:</label>
- <select id="add_to_patron_list_which" name="add_to_patron_list_which">
- <option value="selected">Selected patrons</option>
- <option value="all">All resultant patrons</option>
- </select>
-
- <label for="add_to_patron_list">to:</label>
- <select id="add_to_patron_list" name="add_to_patron_list">
- <option value=""></option>
- [% IF patron_lists %]
- <optgroup label="Patron lists:">
- [% FOREACH pl IN patron_lists %]
- <option value="[% pl.patron_list_id %]">[% pl.name %]</option>
- [% END %]
- </optgroup>
- [% END %]
-
- <option value="new">[ New list ]</option>
- </select>
-
- <input type="text" id="new_patron_list" name="new_patron_list" id="new_patron_list" />
-
- [% FOREACH key IN search_parameters.keys %]
- <input type="hidden" name="[% key %]" value="[% search_parameters.$key %]" />
- [% END %]
-
- <input id="add_to_patron_list_submit" type="submit" class="submit" value="Save">
- </span>
- </div>
- [% END %]
- </div>
- <div class="searchresults">
-
- <table id="memberresultst">
- <thead>
- <tr>
- [% IF (CAN_user_tools_manage_patron_lists) %]
- <th> </th>
- [% END %]
- <th>Card</th>
- <th>Name</th>
- <th>Cat</th>
- <th>Library</th>
- <th>Expires on</th>
- <th>OD/Checkouts</th>
- <th>Fines</th>
- <th>Circ note</th>
- <th> </th>
- </tr>
- </thead>
- <tbody>
- [% FOREACH resultsloo IN resultsloop %]
- [% IF ( resultsloo.overdue ) %]
- <tr class="problem">
- [% ELSE %]
- [% UNLESS ( loop.odd ) %]
- <tr class="highlight">
- [% ELSE %]
- <tr>
- [% END %]
- [% END %]
- [% IF (CAN_user_tools_manage_patron_lists) %]
- <td><input type="checkbox" class="selection" name="borrowernumber" value="[% resultsloo.borrowernumber %]" /></td>
- [% END %]
- <td>[% resultsloo.cardnumber %]</td>
- <td style="white-space: nowrap;">
- <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% resultsloo.borrowernumber %]">
- [% 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%]
- </a> <br />
- [% 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 %]
- [% IF (resultsloo.email ) %]<br/>Email: <a href="mailto:[% resultsloo.email %]">[% resultsloo.email %]</a>[% END %]
- </td>
- <td>[% resultsloo.category_description %] ([% resultsloo.category_type %])</td>
- <td>[% resultsloo.branchname %]</td>
- <td>[% resultsloo.dateexpiry %]</td>
- <td>[% IF ( resultsloo.overdues ) %]<span class="overdue"><strong>[% resultsloo.overdues %]</strong></span>[% ELSE %][% resultsloo.overdues %][% END %]/[% resultsloo.issues %]</td>
- <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>
- <td>[% resultsloo.borrowernotes %]</td>
- <td>[% IF ( resultsloo.category_type ) %]
- <a href="/cgi-bin/koha/members/memberentry.pl?op=modify&destination=circ&borrowernumber=[% resultsloo.borrowernumber %]&category_type=[% resultsloo.category_type %]">Edit</a>
- [% ELSE %] <!-- try with categorycode if no category_type -->
- [% IF ( resultsloo.categorycode ) %]
- <a href="/cgi-bin/koha/members/memberentry.pl?op=modify&destination=circ&borrowernumber=[% resultsloo.borrowernumber %]&categorycode=[% resultsloo.categorycode %]">Edit</a>
- [% ELSE %] <!-- if no categorycode, set category_type to A by default -->
- <a href="/cgi-bin/koha/members/memberentry.pl?op=modify&destination=circ&borrowernumber=[% resultsloo.borrowernumber %]&category_type=A">Edit</a>
- [% END %]
- [% END %]</td>
- </tr>
- [% END %]
- </tbody>
- </table>
- <div class="pages">[% IF ( multipage ) %][% paginationbar %][% END %]</div>
- </div>
- [% IF (CAN_user_tools_manage_patron_lists) %]
- </form>
- [% END %]
- [% ELSE %]
- [% IF ( searching ) %]
- <div class="dialog alert">No results found</div>
- [% END %]
- [% END %]
-
- </div>
- </div>
-
- <div class="yui-g">
- [% INCLUDE 'members-menu.inc' %]
- </div>
+ <input id="add_to_patron_list_submit" type="submit" class="submit" value="Save">
+ </span>
+ </div>
+ </div>
+ [% END %]
+ <table id="memberresultst">
+ <thead>
+ <tr>
+ <th> </th>
+ <th>Card</th>
+ <th>Name</th>
+ <th>Category</th>
+ <th>Library</th>
+ <th>Expires on</th>
+ <th>OD/Checkouts</th>
+ <th>Fines</th>
+ <th>Circ note</th>
+ <th> </th>
+ </tr>
+ </thead>
+ <tbody></tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="yui-b">
+ <form onsubmit="return filter();" id="searchform">
+ <input type="hidden" id="firstletter_filter" value="" />
+ <fieldset class="brief">
+ <h3>Filters</h3>
+ <ol>
+ <li>
+ <label for="searchmember_filter">Search:</label>
+ <input type="text" id="searchmember_filter" value="[% searchmember %]"/>
+ </li>
+ <li>
+ <label for="searchfieldstype_filter">Search fields:</label>
+ <select name="searchfieldstype" id="searchfieldstype_filter">
+ [% IF searchfieldstype == "standard" %]
+ <option selected="selected" value='standard'>Standard</option>
+ [% ELSE %]
+ <option value='standard'>Standard</option>
+ [% END %]
+ [% IF searchfieldstype == "email" %]
+ <option selected="selected" value='email'>Email</option>
+ [% ELSE %]
+ <option value='email'>Email</option>
+ [% END %]
+ [% IF searchfieldstype == "borrowernumber" %]
+ <option selected="selected" value='borrowernumber'>Borrower number</option>
+ [% ELSE %]
+ <option value='borrowernumber'>Borrower number</option>
+ [% END %]
+ [% IF searchfieldstype == "phone" %]
+ <option selected="selected" value='phone'>Phone number</option>
+ [% ELSE %]
+ <option value='phone'>Phone number</option>
+ [% END %]
+ [% IF searchfieldstype == "address" %]
+ <option selected="selected" value='address'>Street address</option>
+ [% ELSE %]
+ <option value='address'>Street address</option>
+ [% END %]
+ [% IF searchfieldstype == "dateofbirth" %]
+ <option selected="selected" value='dateofbirth'>Date of birth</option>
+ [% ELSE %]
+ <option value='dateofbirth'>Date of birth</option>
+ [% END %]
+ [% IF searchfieldstype == "sort1" %]
+ <option selected="selected" value='sort1'>Sort field 1</option>
+ [% ELSE %]
+ <option value='sort1'>Sort field 1</option>
+ [% END %]
+ [% IF searchfieldstype == "sort2" %]
+ <option selected="selected" value='sort2'>Sort field 2</option>
+ [% ELSE %]
+ <option value='sort2'>Sort field 2</option>
+ [% END %]
+ </select>
+ </li>
+ <li>
+ <label for="searchtype_filter">Search type:</label>
+ <select name="searchtype" id="searchtype_filter">
+ <option value='start_with'>Starts with</option>
+ [% IF searchtype == "contain" %]
+ <option value="contain" selected="selected">Contains</option>
+ [% ELSE %]
+ <option value="contain" selected="selected">Contains</option>
+ [% END %]
+ </select>
+ </li>
+ <li>
+ <label for="categorycode_filter">Category:</label>
+ <select id="categorycode_filter">
+ <option value="">Any</option>
+ [% FOREACH cat IN categories %]
+ [% IF cat.selected %]
+ <option selected="selected" value="[% cat.categorycode %]">[% cat.description %]</option>
+ [% ELSE %]
+ <option value="[% cat.categorycode %]">[% cat.description %]</option>
+ [% END %]
+ [% END %]
+ </select>
+ </li>
+ <li>
+ <label for="branchcode_filter">Branch:</label>
+ <select id="branchcode_filter">
+ [% IF branchloop.size != 1 %]
+ <option value="">Any</option>
+ [% END %]
+ [% FOREACH b IN branchloop %]
+ [% IF b.selected %]
+ <option selected="selected" value="[% b.branchcode %]">[% b.branchname %]</option>
+ [% ELSE %]
+ <option value="[% b.branchcode %]">[% b.branchname %]</option>
+ [% END %]
+ [% END %]
+ </select>
+ </li>
+ </ol>
+ <fieldset class="action">
+ <input type="submit" value="Search" />
+ <input type="button" value="Clear" onclick="clearFilters(true);" />
+ </fieldset>
+ </fieldset>
+ </form>
</div>
+ </div>
+ <div class="yui-g">
+ [% INCLUDE 'members-menu.inc' %]
+ </div>
</div>
[% INCLUDE 'intranet-bottom.inc' %]
--- /dev/null
+{
+ "sEcho": [% sEcho %],
+ "iTotalRecords": [% iTotalRecords %],
+ "iTotalDisplayRecords": [% iTotalDisplayRecords %],
+ "aaData": [
+ [% FOREACH data IN aaData %]
+ {
+ [% IF CAN_user_tools_manage_patron_lists %]
+ "dt_borrowernumber":
+ "<input type='checkbox' class='selection' name='borrowernumber' value='[% data.borrowernumber %]' />",
+ [% END %]
+ "dt_cardnumber":
+ "[% data.cardnumber %]",
+ "dt_name":
+ "<span style='white-space:nowrap'><a href='/cgi-bin/koha/members/moremember.pl?borrowernumber=[% data.borrowernumber %]'>[% INCLUDE 'patron-title.inc' borrowernumber = data.borrowernumber category_type = data.category_type firstname = data.firstname surname = data.surname othernames = data.othernames cardnumber = data.cardnumber invert_name = 1%]</a><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>",
+ "dt_category":
+ "[% data.category_description |html %]([% data.category_type |html %])",
+ "dt_branch":
+ "[% data.branchname |html %]",
+ "dt_dateexpiry":
+ "[% data.dateexpiry %]",
+ "dt_od_checkouts":
+ "[% IF data.overdues %]<span class='overdue'><strong>[% data.overdues %]</strong></span>[% ELSE %][% data.overdues %][% END %] / [% data.issues %]",
+ "dt_fines":
+ "[% 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>",
+ "dt_borrowernotes":
+ "[% data.borrowernotes |html |html_line_break |collapse %]",
+ "dt_action":
+ "[% IF data.category_type %]<a href='/cgi-bin/koha/members/memberentry.pl?op=modify&destination=circ&borrowernumber=[% data.borrowernumber %]&category_type=[% data.category_type %]'>Edit</a>[% ELSE %][% IF data.categorycode %]<a href='/cgi-bin/koha/members/memberentry.pl?op=modify&destination=circ&borrowernumber=[% data.borrowernumber %]&categorycode=[% data.categorycode %]'>Edit</a>[% ELSE %]<a href='/cgi-bin/koha/members/memberentry.pl?op=modify&destination=circ&borrowernumber=[% data.borrowernumber %]&category_type=A'>Edit</a>[% END %][% END %]",
+ "borrowernumber":
+ "[% data.borrowernumber %]"
+ }[% UNLESS loop.last %],[% END %]
+ [% END %]
+ ]
+}
# Copyright 2000-2002 Katipo Communications
-# Copyright 2010 BibLibre
+# Copyright 2013 BibLibre
#
# This file is part of Koha.
#
use C4::Auth;
use C4::Output;
use CGI;
-use C4::Members;
use C4::Branch;
use C4::Category;
+use C4::Members qw( GetMember );
use Koha::DateUtils;
use Koha::List::Patron;
my $input = new CGI;
-my $quicksearch = $input->param('quicksearch') || '';
-my $startfrom = $input->param('startfrom') || 1;
-my $resultsperpage = $input->param('resultsperpage') || C4::Context->preference("PatronsPerPage") || 20;
my ($template, $loggedinuser, $cookie)
- = get_template_and_user({template_name => "members/member.tmpl",
+ = get_template_and_user({template_name => "members/member.tt",
query => $input,
type => "intranet",
authnotrequired => 0,
my $theme = $input->param('theme') || "default";
-my $add_to_patron_list = $input->param('add_to_patron_list');
-my $add_to_patron_list_which = $input->param('add_to_patron_list_which');
-my $new_patron_list = $input->param('new_patron_list');
-my @borrowernumbers = $input->param('borrowernumber');
-$input->delete(
- 'add_to_patron_list', 'add_to_patron_list_which',
- 'new_patron_list', 'borrowernumber',
-);
-
my $patron = $input->Vars;
foreach (keys %$patron){
- delete $$patron{$_} unless($$patron{$_});
-}
-my @categories=C4::Category->all;
-
-my $branches = GetBranches;
-my @branchloop;
-
-foreach (sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} } keys %$branches) {
- my $selected;
- $selected = 1 if $patron->{branchcode} && $branches->{$_}->{branchcode} eq $patron->{branchcode};
- my %row = ( value => $_,
- selected => $selected,
- branchname => $branches->{$_}->{branchname},
- );
- push @branchloop, \%row;
-}
-
-my %categories_dislay;
-
-foreach my $category (@categories){
- my $hash={
- category_description=>$$category{description},
- category_type=>$$category{category_type}
- };
- $categories_dislay{$$category{categorycode}} = $hash;
+ delete $patron->{$_} unless($patron->{$_});
}
-my $AddPatronLists = C4::Context->preference("AddPatronLists") || '';
-$template->param(
- "AddPatronLists_$AddPatronLists" => "1",
- );
-if ($AddPatronLists=~/code/){
- $categories[0]->{'first'}=1;
-}
-
-my $member=$input->param('member') || '';
-my $orderbyparams=$input->param('orderby') || '';
-my @orderby;
-if ($orderbyparams){
- my @orderbyelt=split(/,/,$orderbyparams);
- push @orderby, {$orderbyelt[0]=>$orderbyelt[1]||0};
-}
-else {
- @orderby = ({surname=>0},{firstname=>0});
-}
-
-$member =~ s/,//g; #remove any commas from search string
-$member =~ s/\*/%/g;
-my $from = ( $startfrom - 1 ) * $resultsperpage;
-my $to = $from + $resultsperpage;
+my $searchmember = $input->param('searchmember');
+my $quicksearch = $input->param('quicksearch') // 0;
-my ($count,$results);
-if ($member || keys %$patron) {
- my $searchfields = $input->param('searchfields') || '';
- my @searchfields = $searchfields ? split( ',', $searchfields ) : ( "firstname", "surname", "othernames", "cardnumber", "userid", "email" );
-
- if ( $searchfields eq "dateofbirth" ) {
- $member = output_pref({dt => dt_from_string($member), dateformat => 'iso', dateonly => 1});
+if ( $quicksearch ) {
+ my $branchcode;
+ if ( C4::Branch::onlymine ) {
+ my $userenv = C4::Context->userenv;
+ $branchcode = $userenv->{'branch'};
+ }
+ my $member = GetMember(
+ cardnumber => $searchmember,
+ ( $branchcode ? ( branchcode => $branchcode ) : () ),
+ );
+ if( $member ){
+ print $input->redirect("/cgi-bin/koha/members/moremember.pl?borrowernumber=" . $member->{borrowernumber});
+ exit;
}
+}
- my $searchtype = $input->param('searchtype');
- my $search_scope =
- $quicksearch ? "field_start_with"
- : $searchtype ? $searchtype
- : "start_with";
+my $searchfieldstype = $input->param('searchfieldstype') || 'standard';
- ($results) = Search( $member || $patron, \@orderby, undef, undef, \@searchfields, $search_scope );
+if ( $searchfieldstype eq "dateofbirth" ) {
+ $searchmember = output_pref({dt => dt_from_string($searchmember), dateformat => 'iso', dateonly => 1});
}
-if ($add_to_patron_list) {
- my $patron_list;
-
- if ( $add_to_patron_list eq 'new' ) {
- $patron_list = AddPatronList( { name => $new_patron_list } );
- }
- else {
- $patron_list =
- [ GetPatronLists( { patron_list_id => $add_to_patron_list } ) ]->[0];
+my $branches = C4::Branch::GetBranches;
+my @branches_loop;
+if ( C4::Branch::onlymine ) {
+ my $userenv = C4::Context->userenv;
+ my $branch = C4::Branch::GetBranchDetail( $userenv->{'branch'} );
+ push @branches_loop, {
+ value => $branch->{branchcode},
+ branchcode => $branch->{branchcode},
+ branchname => $branch->{branchname},
+ selected => 1
}
-
- if ( $add_to_patron_list_which eq 'all' ) {
- @borrowernumbers = map { $_->{borrowernumber} } @$results;
+} else {
+ foreach ( sort { lc($branches->{$a}->{branchname}) cmp lc($branches->{$b}->{branchname}) } keys %$branches ) {
+ my $selected = 0;
+ $selected = 1 if($patron->{branchcode} and $patron->{branchcode} eq $_);
+ push @branches_loop, {
+ value => $_,
+ branchcode => $_,
+ branchname => $branches->{$_}->{branchname},
+ selected => $selected
+ };
}
-
- my @patrons_added_to_list = AddPatronsToList( { list => $patron_list, borrowernumbers => \@borrowernumbers } );
-
- $template->param(
- patron_list => $patron_list,
- patrons_added_to_list => \@patrons_added_to_list,
- )
}
-if ($results) {
- for my $field ('categorycode','branchcode'){
- next unless ($patron->{$field});
- @$results = grep { $_->{$field} eq $patron->{$field} } @$results;
- }
- $count = scalar(@$results);
-} else {
- $count = 0;
+my @categories = C4::Category->all;
+if ( $patron->{categorycode} ) {
+ foreach my $category ( grep { $_->{categorycode} eq $patron->{categorycode} } @categories ) {
+ $category->{selected} = 1;
+ }
}
-if($count == 1){
- print $input->redirect("/cgi-bin/koha/members/moremember.pl?borrowernumber=" . @$results[0]->{borrowernumber});
- exit;
-}
+$template->param( 'alphabet' => C4::Context->preference('alphabet') || join ' ', 'A' .. 'Z' );
-my @resultsdata;
-$to=($count>$to?$to:$count);
-my $index=$from;
-foreach my $borrower(@$results[$from..$to-1]){
- #find out stats
- my ($od,$issue,$fines)=GetMemberIssuesAndFines($$borrower{'borrowernumber'});
- $fines ||= 0;
- $$borrower{'dateexpiry'}= C4::Dates->new($$borrower{'dateexpiry'},'iso')->output('syspref');
-
- my %row = (
- count => $index++,
- %$borrower,
- (defined $categories_dislay{ $borrower->{categorycode} }? %{ $categories_dislay{ $borrower->{categorycode} } }:()),
- overdues => $od,
- issues => $issue,
- odissue => "$od/$issue",
- fines => sprintf("%.2f",$fines),
- branchname => $branches->{$borrower->{branchcode}}->{branchname},
- );
- push(@resultsdata, \%row);
+my $orderby = $input->param('orderby') // '';
+if(defined $orderby and $orderby ne '') {
+ $orderby =~ s/[, ]/_/g;
}
-if ($$patron{categorycode}){
- foreach my $category (grep{$_->{categorycode} eq $$patron{categorycode}}@categories){
- $$category{selected}=1;
- }
-}
-my %parameters=
- ( %$patron
- , 'orderby' => $orderbyparams
- , 'resultsperpage' => $resultsperpage
- , 'type'=> 'intranet');
-my $base_url =
- 'member.pl?&'
- . join(
- '&',
- map { "$_=$parameters{$_}" } (keys %parameters)
- );
-
-my @letters = map { {letter => $_} } ( 'A' .. 'Z');
+my $view = $input->request_method() eq "GET" ? "show_form" : "show_results";
$template->param(
- %$patron,
- letters => \@letters,
- paginationbar => pagination_bar(
- $base_url,
- int( $count / $resultsperpage ) + ( $count % $resultsperpage ? 1 : 0 ),
- $startfrom,
- 'startfrom'
- ),
- startfrom => $startfrom,
- from => ( $startfrom - 1 ) * $resultsperpage + 1,
- to => $to,
- multipage => ( $count != $to || $startfrom != 1 ),
- advsearch => ( $$patron{categorycode} || $$patron{branchcode} ),
- branchloop => \@branchloop,
- categories => \@categories,
- searching => "1",
- numresults => $count,
- resultsloop => \@resultsdata,
- results_per_page => $resultsperpage,
- member => $member,
- search_parameters => \%parameters,
patron_lists => [ GetPatronLists() ],
+ searchmember => $searchmember,
+ branchloop => \@branches_loop,
+ categories => \@categories,
+ branchcode => $patron->{branchcode},
+ categorycode => $patron->{categorycode},
+ searchtype => $input->param('searchtype') || 'start_with',
+ searchfieldstype => $searchfieldstype,
+ "orderby_$orderby" => 1,
+ PatronsPerPage => C4::Context->preference("PatronsPerPage") || 20,
+ view => $view,
);
output_html_with_http_headers $input, $cookie, $template->output;
my $branches = GetBranches;
my @branchloop;
-foreach (sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} } keys %{$branches}) {
+if ( C4::Branch::onlymine ) {
+ my $userenv = C4::Context->userenv;
+ my $branch = C4::Branch::GetBranchDetail( $userenv->{'branch'} );
push @branchloop, {
- value => $_,
- selected => ($branches->{$_}->{branchcode} eq $branch),
- branchname => $branches->{$_}->{branchname},
- };
+ value => $branch->{branchcode},
+ branchcode => $branch->{branchcode},
+ branchname => $branch->{branchname},
+ selected => 1
+ }
+} else {
+ foreach (sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} } keys %{$branches}) {
+ push @branchloop, {
+ value => $_,
+ selected => ($branches->{$_}->{branchcode} eq $branch),
+ branchname => $branches->{$_}->{branchname},
+ };
+ }
}
my @categories;
no_add => $no_add,
pending_borrower_modifications => $pending_borrower_modifications,
);
-$template->param( 'alphabet' => C4::Context->preference('alphabet') || join ' ', 'A' .. 'Z' );
+
+$template->param(
+ alphabet => C4::Context->preference('alphabet') || join (' ', 'A' .. 'Z'),
+ PatronsPerPage => C4::Context->preference("PatronsPerPage") || 20,
+);
output_html_with_http_headers $query, $cookie, $template->output;
my $quickslip = 0;
my $flagsrequired;
-if ($print eq "page") {
+if (defined $print and $print eq "page") {
$template_name = "members/moremember-print.tmpl";
# circ staff who process checkouts but can't edit
# patrons still need to be able to access print view
$flagsrequired = { circulate => "circulate_remaining_permissions" };
-} elsif ($print eq "slip") {
+} elsif (defined $print and $print eq "slip") {
$template_name = "members/moremember-receipt.tmpl";
# circ staff who process checkouts but can't edit
# patrons still need to be able to print receipts
$flagsrequired = { circulate => "circulate_remaining_permissions" };
-} elsif ($print eq "qslip") {
+} elsif (defined $print and $print eq "qslip") {
$template_name = "members/moremember-receipt.tmpl";
$quickslip = 1;
$flagsrequired = { circulate => "circulate_remaining_permissions" };
-} elsif ($print eq "brief") {
+} elsif (defined $print and $print eq "brief") {
$template_name = "members/moremember-brief.tmpl";
$flagsrequired = { borrowers => 1 };
} else {
}
$data->{'ethnicity'} = fixEthnicity( $data->{'ethnicity'} );
-$data->{ "sex_".$data->{'sex'}."_p" } = 1;
+$data->{ "sex_".$data->{'sex'}."_p" } = 1 if defined $data->{sex};
my $catcode;
if ( $category_type eq 'C') {
$getreserv{barcodereserv} = $getiteminfo->{'barcode'};
$getreserv{itemtype} = $itemtypeinfo->{'description'};
- # check if we have a waitin status for reservations
- if ( $num_res->{'found'} eq 'W' ) {
+ # check if we have a waitin status for reservations
+ if ( defined $num_res->{found} and $num_res->{'found'} eq 'W' ) {
$getreserv{color} = 'reserved';
$getreserv{waiting} = 1;
}
- # check transfers with the itemnumber foud in th reservation loop
+ # check transfers with the itemnumber foud in th reservation loop
if ($transfertwhen) {
$getreserv{color} = 'transfered';
$getreserv{transfered} = 1;
SuspendHoldsIntranet => C4::Context->preference('SuspendHoldsIntranet'),
RoutingSerials => C4::Context->preference('RoutingSerials'),
debarments => GetDebarments({ borrowernumber => $borrowernumber }),
+ PatronsPerPage => C4::Context->preference("PatronsPerPage") || 20,
);
$template->param( $error => 1 ) if $error;
--- /dev/null
+#!/usr/bin/perl
+
+# Copyright 2013 BibLibre
+#
+# This file is part of Koha
+#
+# Koha is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with Koha; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+use CGI;
+
+use C4::Auth qw( check_cookie_auth );
+use JSON qw( to_json );
+use Koha::List::Patron;
+
+my $input = new CGI;
+
+my ( $auth_status, $sessionID ) = check_cookie_auth(
+ $input->cookie('CGISESSID'),
+ { tools => 'manage_patron_lists' },
+);
+
+exit 0 if $auth_status ne "ok";
+my $add_to_patron_list = $input->param('add_to_patron_list');
+my $new_patron_list = $input->param('new_patron_list');
+my @borrowernumbers = $input->param('borrowernumbers[]');
+
+my $response;
+if ($add_to_patron_list) {
+ my $patron_list = [];
+
+ if ( $add_to_patron_list eq 'new' ) {
+ $patron_list = AddPatronList( { name => $new_patron_list } );
+ }
+ else {
+ $patron_list =
+ [ GetPatronLists( { patron_list_id => $add_to_patron_list } ) ]->[0];
+ }
+
+ my @patrons_added_to_list = AddPatronsToList( { list => $patron_list, borrowernumbers => \@borrowernumbers } );
+
+ $response->{patron_list} = { patron_list_id => $patron_list->patron_list_id, name => $patron_list->name };
+ $response->{patrons_added_to_list} = scalar( @patrons_added_to_list );
+}
+
+binmode STDOUT, ":encoding(UTF-8)";
+print $input->header(
+ -type => 'application/json',
+ -charset => 'UTF-8'
+);
+
+print to_json( $response );
--- /dev/null
+#!/usr/bin/perl
+
+# Copyright 2013 BibLibre
+#
+# This file is part of Koha
+#
+# Koha is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any later
+# version.
+#
+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with Koha; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use Modern::Perl;
+use CGI;
+
+use C4::Auth qw( get_template_and_user );
+use C4::Output qw( output_with_http_headers );
+use C4::Utils::DataTables qw( dt_get_params );
+use C4::Utils::DataTables::Members qw( search );
+
+my $input = new CGI;
+
+exit unless $input->param('template_path');
+
+my ($template, $user, $cookie) = get_template_and_user({
+ template_name => $input->param('template_path'),
+ query => $input,
+ type => "intranet",
+ authnotrequired => 0,
+ flagsrequired => { borrowers => 1 }
+});
+
+my $searchmember = $input->param('searchmember');
+my $firstletter = $input->param('firstletter');
+my $categorycode = $input->param('categorycode');
+my $branchcode = $input->param('branchcode');
+my $searchtype = $input->param('searchtype');
+my $searchfieldstype = $input->param('searchfieldstype');
+
+# variable information for DataTables (id)
+my $sEcho = $input->param('sEcho');
+
+my %dt_params = dt_get_params($input);
+foreach (grep {$_ =~ /^mDataProp/} keys %dt_params) {
+ $dt_params{$_} =~ s/^dt_//;
+}
+
+# Perform the patrons search
+my $results = C4::Utils::DataTables::Members::search(
+ {
+ searchmember => $searchmember,
+ firstletter => $firstletter,
+ categorycode => $categorycode,
+ branchcode => $branchcode,
+ searchtype => $searchtype,
+ searchfieldstype => $searchfieldstype,
+ dt_params => \%dt_params,
+
+ }
+);
+
+$template->param(
+ sEcho => $sEcho,
+ iTotalRecords => $results->{iTotalRecords},
+ iTotalDisplayRecords => $results->{iTotalDisplayRecords},
+ aaData => $results->{patrons}
+);
+
+output_with_http_headers $input, $cookie, $template->output, 'json';
+
+__END__
+
+=head1 NAME
+
+search - a search script for finding patrons
+
+=head1 SYNOPSIS
+
+This script provides a service for template for patron search using DataTables
+
+=head2 Performing a search
+
+Call this script from a DataTables table my $searchmember = $input->param('searchmember');
+All following params are optional:
+ searchmember => the search terms
+ firstletter => search patrons with surname begins with this pattern (currently only used for 1 letter)
+ categorycode and branchcode => search patrons belong to a given categorycode or a branchcode
+ searchtype: can be 'contain' or 'start_with'
+ searchfieldstype: Can be 'standard', 'email', 'borrowernumber', 'phone' or 'address'
+
+=cut
+
+=back
+
+=head1 LICENSE
+
+Copyright 2013 BibLibre
+
+This file is part of Koha.
+
+Koha is free software; you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the Free Software
+Foundation; either version 2 of the License, or (at your option) any later
+version.
+
+Koha is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with Koha; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--- /dev/null
+use Modern::Perl;
+use Test::More tests => 4;
+
+use_ok( "C4::Utils::DataTables::Members" );
+
+my $patrons = C4::Utils::DataTables::Members::search({
+ searchmember => "Doe",
+ searchfieldstype => 'standard',
+ searchtype => 'contains'
+});
+
+isnt( $patrons->{iTotalDisplayRecords}, undef, "The iTotalDisplayRecords key is defined");
+isnt( $patrons->{iTotalRecords}, undef, "The iTotalRecords key is defined");
+is( ref $patrons->{patrons}, 'ARRAY', "The patrons key is an arrayref");