Bug 4133 Ensure that orders have a valid quantity received
[koha_gimpoz] / C4 / Members.pm
index 4b525f0..98adc27 100644 (file)
@@ -244,6 +244,41 @@ sub SearchMember {
     return ( scalar(@$data), $data );
 }
 
+=over 2
+
+=item Search
+
+  $borrowers_result_array_ref = &Search($filter,$orderby, $limit, $columns_out, $search_on_fields,$searchtype);
+
+=back
+
+Looks up patrons (borrowers) on filter.
+
+BUGFIX 499: C<$type> is now used to determine type of search.
+if $type is "simple", search is performed on the first letter of the
+surname only.
+
+$category_type is used to get a specified type of user. 
+(mainly adults when creating a child.)
+
+C<$filter> can be
+   - a space-separated list of search terms. Implicit AND is done on them
+   - a hash ref containing fieldnames associated with queried value
+   - an array ref combining the two previous elements Implicit OR is done between each array element
+
+
+C<$orderby> is an arrayref of hashref. Contains the name of the field and 0 or 1 depending if order is ascending or descending
+
+C<$limit> is there to allow limiting number of results returned
+
+C<&columns_out> is an array ref to the fieldnames you want to see in the result list
+
+C<&search_on_fields> is an array ref to the fieldnames you want to limit search on when you are using string search
+
+C<&searchtype> is a string telling the type of search you want todo : start_with, exact or contains are allowed
+
+=cut
+
 sub Search {
     my ($filter,$orderby, $limit, $columns_out, $search_on_fields,$searchtype) = @_;
        my @filters;
@@ -480,36 +515,62 @@ sub patronflags {
 
   $borrower = &GetMember(%information);
 
-Looks up information about a patron (borrower) by either card number
-,firstname, or borrower number, depending on $type value.
-If C<$type> == 'cardnumber', C<&GetBorrower>
-searches by cardnumber then by firstname if not found in cardnumber; 
-otherwise, it searches by borrowernumber.
+Retrieve the first patron record meeting on criteria listed in the
+C<%information> hash, which should contain one or more
+pairs of borrowers column names and values, e.g.,
+
+   $borrower = GetMember(borrowernumber => id);
 
 C<&GetBorrower> returns a reference-to-hash whose keys are the fields of
 the C<borrowers> table in the Koha database.
 
+FIXME: GetMember() is used throughout the code as a lookup
+on a unique key such as the borrowernumber, but this meaning is not
+enforced in the routine itself.
+
 =cut
 
 #'
 sub GetMember {
     my ( %information ) = @_;
+    if (exists $information{borrowernumber} && !defined $information{borrowernumber}) {
+        #passing mysql's kohaadmin?? Makes no sense as a query
+        return;
+    }
     my $dbh = C4::Context->dbh;
-    my $sth;
-    my $select = "
-SELECT borrowers.*, categories.category_type, categories.description
-FROM borrowers 
-LEFT JOIN categories on borrowers.categorycode=categories.categorycode 
-";
-    $select.=" WHERE ".join(" AND ",map {"$_ = ?"}keys %information);
-    $select=~s/AND $//;
+    my $select =
+    q{SELECT borrowers.*, categories.category_type, categories.description
+    FROM borrowers 
+    LEFT JOIN categories on borrowers.categorycode=categories.categorycode WHERE };
+    my $more_p = 0;
+    my @values = ();
+    for (keys %information ) {
+        if ($more_p) {
+            $select .= ' AND ';
+        }
+        else {
+            $more_p++;
+        }
+
+        if (defined $information{$_}) {
+            $select .= "$_ = ?";
+            push @values, $information{$_};
+        }
+        else {
+            $select .= "$_ IS NULL";
+        }
+    }
     $debug && warn $select, " ",values %information;
-    $sth = $dbh->prepare("$select");
+    my $sth = $dbh->prepare("$select");
     $sth->execute(map{$information{$_}} keys %information);
     my $data = $sth->fetchall_arrayref({});
-    return undef if (scalar(@$data)==0);        
-    if (scalar(@$data)==1) {return $$data[0];}
-    ($data) and return $data;
+    #FIXME interface to this routine now allows generation of a result set
+    #so whole array should be returned but bowhere in the current code expects this
+    if (@{$data} ) {
+        return $data->[0];
+    }
+
+    return;
 }
 
 
@@ -680,7 +741,7 @@ Returns the borrowernumber
 sub AddMember {
     my (%data) = @_;
     my $dbh = C4::Context->dbh;
-    $data{'userid'} = '' unless $data{'password'};
+    $data{'password'} = '!' if (not $data{'password'} and $data{'userid'});
     $data{'password'} = md5_base64( $data{'password'} ) if $data{'password'};
        $data{'borrowernumber'}=InsertInTable("borrowers",\%data);      
     # mysql_insertid is probably bad.  not necessarily accurate and mysql-specific at best.
@@ -1234,16 +1295,20 @@ Return date is also in ISO format.
 
 sub GetExpiryDate {
     my ( $categorycode, $dateenrolled ) = @_;
-    my $enrolmentperiod = 12;   # reasonable default
+    my $enrolments;
     if ($categorycode) {
         my $dbh = C4::Context->dbh;
-        my $sth = $dbh->prepare("select enrolmentperiod from categories where categorycode=?");
+        my $sth = $dbh->prepare("SELECT enrolmentperiod,enrolmentperioddate FROM categories WHERE categorycode=?");
         $sth->execute($categorycode);
-        $enrolmentperiod = $sth->fetchrow;
+        $enrolments = $sth->fetchrow_hashref;
     }
     # die "GetExpiryDate: for enrollmentperiod $enrolmentperiod (category '$categorycode') starting $dateenrolled.\n";
-    my @date = split /-/,$dateenrolled;
-    return sprintf("%04d-%02d-%02d", Add_Delta_YM(@date,0,$enrolmentperiod));
+    my @date = split (/-/,$dateenrolled);
+    if($enrolments->{enrolmentperiod}){
+        return sprintf("%04d-%02d-%02d", Add_Delta_YM(@date,0,$enrolments->{enrolmentperiod}));
+    }else{
+        return $enrolments->{enrolmentperioddate};
+    }
 }
 
 =head2 checkuserpassword (OUEST-PROVENCE)
@@ -1689,7 +1754,7 @@ Looks up the different title . Returns array  with all borrowers title
 =cut
 
 sub GetTitles {
-    my @borrowerTitle = split /,|\|/,C4::Context->preference('BorrowersTitles');
+    my @borrowerTitle = split (/,|\|/,C4::Context->preference('BorrowersTitles'));
     unshift( @borrowerTitle, "" );
     my $count=@borrowerTitle;
     if ($count == 1){
@@ -1792,9 +1857,8 @@ this function get all borrowers who haven't borrowed since the date given on inp
 =cut
 
 sub GetBorrowersWhoHaveNotBorrowedSince {
-### TODO : It could be dangerous to delete Borrowers who have just been entered and who have not yet borrowed any book. May be good to add a dateexpiry or dateenrolled filter.      
-       
-                my $filterdate = shift||POSIX::strftime("%Y-%m-%d",localtime());
+    my $filterdate = shift||POSIX::strftime("%Y-%m-%d",localtime());
+    my $filterexpiry = shift;
     my $filterbranch = shift || 
                         ((C4::Context->preference('IndependantBranches') 
                              && C4::Context->userenv 
@@ -1804,20 +1868,29 @@ sub GetBorrowersWhoHaveNotBorrowedSince {
                          : "");  
     my $dbh   = C4::Context->dbh;
     my $query = "
-        SELECT borrowers.borrowernumber,max(issues.timestamp) as latestissue
+        SELECT borrowers.borrowernumber,
+               max(old_issues.timestamp) as latestissue,
+               max(issues.timestamp) as currentissue
         FROM   borrowers
         JOIN   categories USING (categorycode)
-        LEFT JOIN issues ON borrowers.borrowernumber = issues.borrowernumber
+        LEFT JOIN old_issues USING (borrowernumber)
+        LEFT JOIN issues USING (borrowernumber) 
         WHERE  category_type <> 'S'
+        AND borrowernumber NOT IN (SELECT guarantorid FROM borrowers WHERE guarantorid IS NOT NULL AND guarantorid <> 0) 
    ";
     my @query_params;
     if ($filterbranch && $filterbranch ne ""){ 
         $query.=" AND borrowers.branchcode= ?";
         push @query_params,$filterbranch;
-    }    
+    }
+    if($filterexpiry){
+        $query .= " AND dateexpiry < ? ";
+        push @query_params,$filterdate;
+    }
     $query.=" GROUP BY borrowers.borrowernumber";
     if ($filterdate){ 
-        $query.=" HAVING latestissue <? OR latestissue IS NULL";
+        $query.=" HAVING (latestissue < ? OR latestissue IS NULL) 
+                  AND currentissue IS NULL";
         push @query_params,$filterdate;
     }
     warn $query if $debug;