Bug 20443: Remove SearchIdMatchingAttribute
[srvgit] / C4 / Utils / DataTables / Members.pm
index a215006..b7887a8 100644 (file)
@@ -1,9 +1,7 @@
 package C4::Utils::DataTables::Members;
 
 use Modern::Perl;
-use C4::Branch qw/onlymine/;
 use C4::Context;
-use C4::Members qw/GetMemberIssuesAndFines/;
 use C4::Utils::DataTables;
 use Koha::DateUtils;
 
@@ -21,17 +19,42 @@ sub search {
         $searchmember = $dt_params->{sSearch} // '';
     }
 
-    my ($iTotalRecords, $iTotalDisplayRecords);
-
     # If branches are independent 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 $userenv = C4::Context->userenv;
+    my $logged_in_user = Koha::Patrons->find( $userenv->{number} );
+    my @restricted_branchcodes = $logged_in_user->libraries_where_can_see_patrons;
 
+    my ($sth, $query, $iTotalQuery, $iTotalRecords, $iTotalDisplayRecords);
+    my $dbh = C4::Context->dbh;
+    # Get the iTotalRecords DataTable variable
+    $query = $iTotalQuery = "SELECT COUNT(borrowers.borrowernumber) FROM borrowers";
+    if ( @restricted_branchcodes ) {
+        $iTotalQuery .= " WHERE borrowers.branchcode IN (" . join( ',', ('?') x @restricted_branchcodes ) . ")";
+    }
+    ($iTotalRecords) = $dbh->selectrow_array( $iTotalQuery, undef, @restricted_branchcodes );
+
+    # Do that after iTotalQuery!
+    if ( defined $branchcode and $branchcode ) {
+        @restricted_branchcodes = @restricted_branchcodes
+            ? grep { $_ eq $branchcode } @restricted_branchcodes
+                ? ($branchcode)
+                : (undef) # Do not return any results
+            : ($branchcode);
+    }
+
+    if ( $searchfieldstype eq 'dateofbirth' ) {
+        # Return an empty list if the date of birth is not correctly formatted
+        $searchmember = eval { output_pref( { str => $searchmember, dateformat => 'iso', dateonly => 1 } ); };
+        if ( $@ or not $searchmember ) {
+            return {
+                iTotalRecords        => $iTotalRecords,
+                iTotalDisplayRecords => 0,
+                patrons              => [],
+            };
+        }
     }
 
-    my $dbh = C4::Context->dbh;
     my $select = "SELECT
         borrowers.borrowernumber, borrowers.surname, borrowers.firstname,
         borrowers.streetnumber, borrowers.streettype, borrowers.address,
@@ -40,7 +63,7 @@ sub search {
         borrowers.borrowernotes, borrowers.branchcode, borrowers.email,
         borrowers.userid, borrowers.dateofbirth, borrowers.categorycode,
         categories.description AS category_description, categories.category_type,
-        branches.branchname";
+        branches.branchname, borrowers.phone";
     my $from = "FROM borrowers
         LEFT JOIN branches ON borrowers.branchcode = branches.branchcode
         LEFT JOIN categories ON borrowers.categorycode = categories.categorycode";
@@ -54,22 +77,17 @@ sub search {
         push @where_strs, "borrowers.categorycode = ?";
         push @where_args, $categorycode;
     }
-    if(defined $branchcode and $branchcode ne '') {
-        push @where_strs, "borrowers.branchcode = ?";
-        push @where_args, $branchcode;
+    if(@restricted_branchcodes ) {
+        push @where_strs, "borrowers.branchcode IN (" . join( ',', ('?') x @restricted_branchcodes ) . ")";
+        push @where_args, @restricted_branchcodes;
     }
 
     my $searchfields = {
-        standard => 'surname,firstname,othernames,cardnumber,userid',
-        surname => 'surname',
+        standard => C4::Context->preference('DefaultPatronSearchFields') || 'surname,firstname,othernames,cardnumber,userid',
         email => 'email,emailpro,B_email',
         borrowernumber => 'borrowernumber',
-        userid => 'userid',
         phone => 'phone,phonepro,B_phone,altcontactphone,mobile',
-        address => 'streettype,address,address2,city,state,zipcode,country',
-        dateofbirth => 'dateofbirth',
-        sort1 => 'sort1',
-        sort2 => 'sort2',
+        address => 'streetnumber,streettype,address,address2,city,state,zipcode,country',
     };
 
     # * is replaced with % for sql
@@ -88,21 +106,33 @@ sub search {
     foreach my $term (@terms) {
         next unless $term;
 
-        $term .= '%' # end with anything
-            if $term !~ /%$/;
-        $term = "%$term" # begin with anythin unless start_with
-            if $searchtype eq 'contain' && $term !~ /^%/;
+        my $term_dt = eval { local $SIG{__WARN__} = {}; output_pref( { str => $term, dateonly => 1, dateformat => 'sql' } ); };
+
+        if ($term_dt) {
+            $term = $term_dt;
+        } else {
+            $term .= '%'    # end with anything
+              if $term !~ /%$/;
+            $term = "%$term"    # begin with anythin unless start_with
+              if $searchtype eq 'contain' && $term !~ /^%/;
+        }
 
         my @where_strs_or;
-        for my $searchfield ( split /,/, $searchfields->{$searchfieldstype} ) {
-            push @where_strs_or, "borrowers." . $dbh->quote_identifier($searchfield) . " LIKE ?";
+        if ( defined $searchfields->{$searchfieldstype} ) {
+            for my $searchfield ( split /,/, $searchfields->{$searchfieldstype} ) {
+                push @where_strs_or, "borrowers." . $dbh->quote_identifier($searchfield) . " LIKE ?";
+                push @where_args, $term;
+            }
+        } else {
+            push @where_strs_or, "borrowers." . $dbh->quote_identifier($searchfieldstype) . " LIKE ?";
             push @where_args, $term;
         }
 
-        if ( C4::Context->preference('ExtendedPatronAttributes') and $searchmember ) {
-            my $matching_borrowernumbers = C4::Members::Attributes::SearchIdMatchingAttribute($searchmember);
 
-            for my $borrowernumber ( @$matching_borrowernumbers ) {
+        if ( $searchfieldstype eq 'standard' and C4::Context->preference('ExtendedPatronAttributes') and $searchmember ) {
+            my @matching_borrowernumbers = Koha::Patrons->filter_by_attribute_value($searchmember)->get_column('borrowernumber');
+
+            for my $borrowernumber ( @matching_borrowernumbers ) {
                 push @where_strs_or, "borrowers.borrowernumber = ?";
                 push @where_args, $borrowernumber;
             }
@@ -127,7 +157,7 @@ sub search {
         $limit = "LIMIT $dt_params->{iDisplayStart},$dt_params->{iDisplayLength}";
     }
 
-    my $query = join(
+    $query = join(
         " ",
         ($select ? $select : ""),
         ($from ? $from : ""),
@@ -135,7 +165,7 @@ sub search {
         ($orderby ? $orderby : ""),
         ($limit ? $limit : "")
     );
-    my $sth = $dbh->prepare($query);
+    $sth = $dbh->prepare($query);
     $sth->execute(@where_args);
     my $patrons = $sth->fetchall_arrayref({});
 
@@ -145,22 +175,21 @@ sub search {
     $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} = output_pref( { dt => dt_from_string( $patron->{dateexpiry}, 'iso'), dateonly => 1} );
+        my $patron_object = Koha::Patrons->find( $patron->{borrowernumber} );
+        $patron->{overdues} = $patron_object->get_overdues->count;
+        $patron->{issues} = $patron_object->checkouts->count;
+        my $balance = $patron_object->account->balance;
+        # FIXME Should be formatted from the template
+        $patron->{fines} = sprintf("%.2f", $balance);
+
+        if( $patron->{dateexpiry} ) {
+            # FIXME We should not format the date here, do it in template-side instead
+            $patron->{dateexpiry} = output_pref( { dt => scalar dt_from_string( $patron->{dateexpiry}, 'iso'), dateonly => 1} );
         } else {
             $patron->{dateexpiry} = '';
         }
-        $patron->{fines} = sprintf("%.2f", $patron->{fines} || 0);
     }
 
     return {