@@ -, +, @@ - 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 | 5 +- .../prog/en/modules/members/member.tt | 401 +++++++++++++++----- .../en/modules/members/tables/members_results.tt | 31 ++ members/member.pl | 179 +++------ members/members-home.pl | 27 +- members/moremember.pl | 19 +- svc/members/search | 119 ++++++ 11 files changed, 848 insertions(+), 327 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 @@ + + [% 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 %] @@ -493,4 +494,4 @@ jQuery.extend( jQuery.fn.dataTableExt.oSort, { "title-string-desc": function ( a, b ) { return ((a < b) ? 1 : ((a > b) ? -1 : 0)); } -} ); +} ); --- 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' %] - - - - - - - - - - - - - - - - [% FOREACH resultsloo IN resultsloop %] - [% IF ( resultsloo.overdue ) %] - - [% ELSE %] - [% UNLESS ( loop.odd ) %] - - [% ELSE %] - - [% END %] - [% END %] - - - - - - - - - - - [% END %] - -
CardNameCatLibraryExpires onOD/CheckoutsFinesCirc note 
[% resultsloo.cardnumber %] - - [% 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%] -
- [% IF ( resultsloo.streetnumber ) %][% resultsloo.streetnumber %] [% END %][% resultsloo.address %][% IF ( resultsloo.address2 ) %]
[% resultsloo.address2 %][% END %][% IF ( resultsloo.city ) %]
[% 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 %]
[% resultsloo.category_description %] ([% resultsloo.category_type %])[% resultsloo.branchname %][% resultsloo.dateexpiry %][% IF ( resultsloo.overdues ) %][% resultsloo.overdues %][% ELSE %][% resultsloo.overdues %][% END %]/[% resultsloo.issues %][% IF ( resultsloo.fines < 0 ) %][% resultsloo.fines %] [% ELSIF resultsloo.fines > 0 %] [% resultsloo.fines %] [% ELSE %] [% resultsloo.fines %] [% END %][% resultsloo.borrowernotes %][% IF ( resultsloo.category_type ) %] - Edit - [% ELSE %] - [% IF ( resultsloo.categorycode ) %] - Edit - [% ELSE %] - Edit - [% END %] - [% END %]
-
[% IF ( multipage ) %][% paginationbar %][% END %]
- - [% ELSE %] - [% IF ( searching ) %] -
No results found
- [% END %] - [% 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 ) %] + + [% END %] +
+

Results found [% IF searchmember %] for '[% searchmember %]'[% END %]

+
+
+ + + + + + + + + + + + + + + +
CardNameCatLibraryExpires onOD/CheckoutsFinesCirc note 
+
+
+
+
+
+
+ +
+

Filters

+
    +
  1. + + +
  2. +
  3. + + +
  4. +
  5. + + +
  6. +
  7. + + +
  8. +
  9. + + +
  10. +
+
+ + +
+
+
+
+
+ [% INCLUDE 'members-menu.inc' %] +
[% INCLUDE 'intranet-bottom.inc' %] --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/tables/members_results.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/members/tables/members_results.tt @@ -0,0 +1,31 @@ +{ + "sEcho": [% sEcho %], + "iTotalRecords": [% iTotalRecords %], + "iTotalDisplayRecords": [% iTotalDisplayRecords %], + "aaData": [ + [% FOREACH data IN aaData %] + { + "dt_cardnumber": + "[% data.cardnumber %]", + "dt_name": + "[% 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%]
[% IF ( data.streetnumber ) %][% data.streetnumber %] [% END %][% data.address %][% IF ( data.address2 ) %]
[% data.address2 %][% END %][% IF ( data.city ) %]
[% 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 %]
", + "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 %][% data.overdues %][% ELSE %][% data.overdues %][% END %] / [% data.issues %]", + "dt_fines": + "[% IF data.fines < 0 %][% data.fines |html %] [% ELSIF data.fines > 0 %] [% data.fines |html %] [% ELSE %] [% data.fines |html%] [% END %]", + "dt_borrowernotes": + "[% data.borrowernotes |html %]", + "dt_action": + "[% IF data.category_type %]Edit[% ELSE %][% IF data.categorycode %]Edit[% ELSE %]Edit[% END %][% END %]", + "borrowernumber": + "[% data.borrowernumber %]" + }[% UNLESS loop.last %],[% END %] + [% END %] + ] +} --- a/members/member.pl +++ a/members/member.pl @@ -6,7 +6,7 @@ # Copyright 2000-2002 Katipo Communications -# Copyright 2010 BibLibre +# Copyright 2013 BibLibre # # This file is part of Koha. # @@ -23,21 +23,16 @@ # with Koha; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -use strict; -#use warnings; FIXME - Bug 2505 +use Modern::Perl; use C4::Auth; use C4::Output; use CGI; -use C4::Members; use C4::Branch; use C4::Category; use Koha::DateUtils; use File::Basename; 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", @@ -47,147 +42,69 @@ my ($template, $loggedinuser, $cookie) flagsrequired => {borrowers => 1}, }); -my $theme = $input->param('theme') || "default"; - 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 $branches->{$_}->{branchcode} eq $$patron{branchcode}; - my %row = ( value => $_, - selected => $selected, - branchname => $branches->{$_}->{branchname}, - ); - push @branchloop, \%row; + delete $patron->{$_} unless($patron->{$_}); } -my %categories_dislay; - -foreach my $category (@categories){ - my $hash={ - category_description=>$$category{description}, - category_type=>$$category{category_type} - }; - $categories_dislay{$$category{categorycode}} = $hash; -} 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 ($count,$results); -if ($member || keys %$patron) { - my $searchfields = $input->param('searchfields'); - my @searchfields = $searchfields ? split( ',', $searchfields ) : ( "firstname", "surname", "othernames", "cardnumber", "userid", "email" ); +my $searchfieldstype = $input->param('searchfieldstype') || 'standard'; - if ( $searchfields eq "dateofbirth" ) { - $member = output_pref(dt_from_string($member), 'iso', undef, 1); - } - - my $search_scope = ( $quicksearch ? "field_start_with" : "start_with" ); - ($results) = Search( $member || $patron, \@orderby, undef, undef, \@searchfields, $search_scope ); +if ( $searchfieldstype eq "dateofbirth" ) { + $searchmember = output_pref(dt_from_string($searchmember), 'iso', undef, 1); } -if ($results) { - for my $field ('categorycode','branchcode'){ - next unless ($patron->{$field}); - @$results = grep { $_->{$field} eq $patron->{$field} } @$results; - } - $count = scalar(@$results); +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 + } +} 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 + }; + } } -if($count == 1){ - print $input->redirect("/cgi-bin/koha/members/moremember.pl?borrowernumber=" . @$results[0]->{borrowernumber}); - exit; +my @categories = C4::Category->all; +if ( $patron->{categorycode} ) { + foreach my $category ( grep { $_->{categorycode} eq $patron->{categorycode} } @categories ) { + $category->{selected} = 1; + } } -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'}); - - $$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); -} +$template->param( 'alphabet' => C4::Context->preference('alphabet') || join ' ', 'A' .. 'Z' ); -if ($$patron{categorycode}){ - foreach my $category (grep{$_->{categorycode} eq $$patron{categorycode}}@categories){ - $$category{selected}=1; - } +my $orderby = $input->param('orderby') // ''; +if(defined $orderby and $orderby ne '') { + $orderby =~ s/[, ]/_/g; } -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'); $template->param( - 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", - actionname =>basename($0), - %$patron, - numresults => $count, - resultsloop => \@resultsdata, - ); + 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, +); output_html_with_http_headers $input, $cookie, $template->output; --- a/members/members-home.pl +++ a/members/members-home.pl @@ -45,12 +45,23 @@ my ($template, $loggedinuser, $cookie) 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; @@ -86,6 +97,10 @@ $template->param( 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; --- a/members/moremember.pl +++ a/members/moremember.pl @@ -53,8 +53,6 @@ use C4::Form::MessagingPreferences; use List::MoreUtils qw/uniq/; use C4::Members::Attributes qw(GetBorrowerAttributes); -#use Smart::Comments; -#use Data::Dumper; use DateTime; use Koha::DateUtils; @@ -82,21 +80,21 @@ my $template_name; 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 { @@ -157,7 +155,7 @@ if ($debar) { } $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') { @@ -281,13 +279,13 @@ if ($borrowernumber) { $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; @@ -426,6 +424,7 @@ $template->param( AutoResumeSuspendedHolds => C4::Context->preference('AutoResumeSuspendedHolds'), SuspendHoldsIntranet => C4::Context->preference('SuspendHoldsIntranet'), RoutingSerials => C4::Context->preference('RoutingSerials'), + PatronsPerPage => C4::Context->preference("PatronsPerPage") || 20, ); $template->param( $error => 1 ) if $error; --- a/svc/members/search +++ a/svc/members/search @@ -0,0 +1,119 @@ +#!/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. --