@@ -, +, @@
- 1 module C4/Utils/DataTables/Members.pm
- 1 service svc/members/search
- 1 template members/tables/members_results.tt
- 1 new practice which is to add template for DataTables in a
subdirectory named 'tables'.
- Check that there is no regression on searching patrons.
- Try filters on the left of the screen
- Try to sort each column
- Try the "Browse by last name" links.
- Check that the "Clear" button clears yours filters.
- Try with IndependantBranches ON and OFF
---
C4/Members.pm | 6 +-
C4/Utils/DataTables/Members.pm | 201 ++++++++++
.../prog/en/includes/patron-search.inc | 143 ++++---
.../prog/en/includes/patron-title.inc | 44 +--
koha-tmpl/intranet-tmpl/prog/en/js/datatables.js | 3 +-
.../prog/en/modules/members/member.tt | 401 +++++++++++++++-----
.../en/modules/members/tables/members_results.tt | 31 ++
members/member.pl | 181 +++------
members/members-home.pl | 27 +-
members/moremember.pl | 19 +-
svc/members/search | 119 ++++++
11 files changed, 845 insertions(+), 330 deletions(-)
create mode 100644 C4/Utils/DataTables/Members.pm
create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/members/tables/members_results.tt
create mode 100755 svc/members/search
--- a/C4/Members.pm
+++ a/C4/Members.pm
@@ -250,7 +250,7 @@ sub Search {
$filter = [ $filter ];
push @$filter, {"borrowernumber"=>$matching_records};
}
- }
+ }
}
# $showallbranches was not used at the time SearchMember() was mainstreamed into Search().
@@ -274,7 +274,7 @@ sub Search {
else {
$filter = { '' => $filter, branchcode => $branch };
}
- }
+ }
}
}
@@ -283,7 +283,7 @@ sub Search {
}
$searchtype ||= "start_with";
- return SearchInTable( "borrowers", $filter, $orderby, $limit, $columns_out, $search_on_fields, $searchtype );
+ return SearchInTable( "borrowers", $filter, $orderby, $limit, $columns_out, $search_on_fields, $searchtype );
}
=head2 GetMemberDetails
--- a/C4/Utils/DataTables/Members.pm
+++ a/C4/Utils/DataTables/Members.pm
@@ -0,0 +1,201 @@
+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 SQL_CALC_FOUND_ROWS
+ 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',
+ };
+ 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(defined $dt_params->{iDisplayStart} and defined $dt_params->{iDisplayLength}) {
+ # In order to avoir sql injection
+ $dt_params->{iDisplayStart} =~ s/\D//g;
+ $dt_params->{iDisplayLength} =~ s/\D//g;
+ $limit = "LIMIT $dt_params->{iDisplayStart},$dt_params->{iDisplayLength}";
+ }
+
+ my $query = join(" ", $select, $from, $where, $orderby, $limit);
+ my $sth = $dbh->prepare($query);
+ $sth->execute(@where_args);
+ my $patrons = $sth->fetchall_arrayref({});
+
+ # Get the iTotalDisplayRecords DataTable variable
+ $query = "SELECT FOUND_ROWS()";
+ $sth = $dbh->prepare($query);
+ $sth->execute;
+ ($iTotalDisplayRecords) = $sth->fetchrow_array;
+
+ # Get the iTotalRecords DataTable variable
+ $query = "SELECT COUNT(*) 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'
+
+=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.
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/patron-search.inc
+++ a/koha-tmpl/intranet-tmpl/prog/en/includes/patron-search.inc
@@ -5,73 +5,94 @@
Enter patron card number or partial name:
+
+ [% IF ( branchloop ) %]
+
+
+
+
+ [% END %]
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/patron-title.inc
+++ a/koha-tmpl/intranet-tmpl/prog/en/includes/patron-title.inc
@@ -1,23 +1,23 @@
-[% 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 %]
+[%- 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 -%]
--- a/koha-tmpl/intranet-tmpl/prog/en/js/datatables.js
+++ a/koha-tmpl/intranet-tmpl/prog/en/js/datatables.js
@@ -23,7 +23,7 @@ var dataTablesDefaults = {
"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>'
};
@@ -471,6 +471,7 @@ jQuery.extend( jQuery.fn.dataTableExt.oSort, {
} );
}());
+
/* Plugin to allow sorting on data stored in a span's title attribute
*
* Ex:
[% formatted_date %]
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/member.tt
+++ a/koha-tmpl/intranet-tmpl/prog/en/modules/members/member.tt
@@ -1,110 +1,327 @@
[% INCLUDE 'doc-head-open.inc' %]
Koha › Patrons [% IF ( searching ) %]› Search results[% END %]
[% INCLUDE 'doc-head-close.inc' %]
-
-
-[% INCLUDE 'header.inc' %]
-[% INCLUDE 'patron-search.inc' %]
+
+
+
+
+
+
+[% INCLUDE 'header.inc' %]
+[% INCLUDE 'patron-search.inc' %]
-
-
-
-
Card
-
Name
-
Cat
-
Library
-
Expires on
-
OD/Checkouts
-
Fines
-
Circ note
-
-
-
-
- [% FOREACH resultsloo IN resultsloop %]
- [% IF ( resultsloo.overdue ) %]
-
[% IF ( resultsloo.category_type ) %]
- Edit
- [% ELSE %]
- [% IF ( resultsloo.categorycode ) %]
- Edit
- [% ELSE %]
- Edit
- [% END %]
- [% END %]
-
- [% END %]
-
-
-
[% IF ( multipage ) %][% paginationbar %][% END %]
-
- [% ELSE %]
- [% IF ( searching ) %]
-
No results found
- [% END %]
- [% END %]
+
Home › [% IF ( searching ) %]Patrons › Search results[% ELSE %]Patrons[% END %]
-
-
+
+
+
+
+
+ [% INCLUDE 'patron-toolbar.inc' %]
+ [% IF ( no_add ) %]
+
+
Cannot add patron
+ [% IF ( no_branches ) %]
+
There are no libraries defined. [% IF ( CAN_user_parameters ) %]Please add a library.[% ELSE %]An administrator must define at least one library.[% END %]
+ [% END %]
+ [% IF ( no_categories ) %]
+
There are no patron categories defined. [% IF ( CAN_user_parameters ) %]Please add a patron category.[% ELSE %]An administrator must define at least one patron category.[% END %]
+ [% END %]
+
+ [% END %]
+
+ Browse by last name:
+ [% FOREACH letter IN alphabet.split(' ') %]
+ [% letter %]
+ [% END %]
+
-
- [% INCLUDE 'members-menu.inc' %]
-
+ [% IF ( CAN_user_borrowers && pending_borrower_modifications ) %]
+