Bug 10693: (follow-up) fix parameter checking in CreateBranchTransferLimit()
[koha.git] / C4 / Members.pm
index 5c857f6..7ac69df 100644 (file)
@@ -66,6 +66,7 @@ BEGIN {
         &getidcity
 
         &GetFirstValidEmailAddress
+        &GetNoticeEmailAddress
 
         &GetAge
         &GetCities
@@ -255,12 +256,10 @@ sub Search {
     # $showallbranches was not used at the time SearchMember() was mainstreamed into Search().
     # Mentioning for the reference
 
-    if ( C4::Context->preference("IndependantBranches") ) { # && !$showallbranches){
+    if ( C4::Context->preference("IndependentBranches") ) { # && !$showallbranches){
         if ( my $userenv = C4::Context->userenv ) {
             my $branch =  $userenv->{'branch'};
-            if ( ($userenv->{flags} % 2 !=1) &&
-                 $branch && $branch ne "insecure" ){
-
+            if ( ($userenv->{flags} % 2 !=1) && $branch ){
                 if (my $fr = ref $filter) {
                     if ( $fr eq "HASH" ) {
                         $filter->{branchcode} = $branch;
@@ -436,7 +435,7 @@ sub patronflags {
     if ( $owing > 0 ) {
         my %flaginfo;
         my $noissuescharge = C4::Context->preference("noissuescharge") || 5;
-        $flaginfo{'message'} = sprintf "Patron owes \$%.02f", $owing;
+        $flaginfo{'message'} = sprintf 'Patron owes %.02f', $owing;
         $flaginfo{'amount'}  = sprintf "%.02f", $owing;
         if ( $owing > $noissuescharge && !C4::Context->preference("AllowFineOverride") ) {
             $flaginfo{'noissues'} = 1;
@@ -445,7 +444,7 @@ sub patronflags {
     }
     elsif ( $balance < 0 ) {
         my %flaginfo;
-        $flaginfo{'message'} = sprintf "Patron has credit of \$%.02f", -$balance;
+        $flaginfo{'message'} = sprintf 'Patron has credit of %.02f', -$balance;
         $flaginfo{'amount'}  = sprintf "%.02f", $balance;
         $flags{'CREDITS'} = \%flaginfo;
     }
@@ -696,10 +695,42 @@ sub GetMemberIssuesAndFines {
     return ($overdue_count, $issue_count, $total_fines);
 }
 
-sub columns(;$) {
-    return @{C4::Context->dbh->selectcol_arrayref("SHOW columns from borrowers")};
+
+=head2 columns
+
+  my @columns = C4::Member::columns();
+
+Returns an array of borrowers' table columns on success,
+and an empty array on failure.
+
+=cut
+
+sub columns {
+
+    # Pure ANSI SQL goodness.
+    my $sql = 'SELECT * FROM borrowers WHERE 1=0;';
+
+    # Get the database handle.
+    my $dbh = C4::Context->dbh;
+
+    # Run the SQL statement to load STH's readonly properties.
+    my $sth = $dbh->prepare($sql);
+    my $rv = $sth->execute();
+
+    # This only fails if the table doesn't exist.
+    # This will always be called AFTER an install or upgrade,
+    # so borrowers will exist!
+    my @data;
+    if ($sth->{NUM_OF_FIELDS}>0) {
+        @data = @{$sth->{NAME}};
+    }
+    else {
+        @data = ();
+    }
+    return @data;
 }
 
+
 =head2 ModMember
 
   my $success = ModMember(borrowernumber => $borrowernumber,
@@ -722,6 +753,7 @@ sub ModMember {
             $data{password} = md5_base64($data{password});
         }
     }
+    my $old_categorycode = GetBorrowerCategorycode( $data{borrowernumber} );
        my $execute_success=UpdateInTable("borrowers",\%data);
     if ($execute_success) { # only proceed if the update was a success
         # ok if its an adult (type) it may have borrowers that depend on it as a guarantor
@@ -732,12 +764,17 @@ sub ModMember {
             # is adult check guarantees;
             UpdateGuarantees(%data);
         }
+
+        # If the patron changes to a category with enrollment fee, we add a fee
+        if ( $data{categorycode} and $data{categorycode} ne $old_categorycode ) {
+            AddEnrolmentFeeIfNeeded( $data{categorycode}, $data{borrowernumber} );
+        }
+
         logaction("MEMBERS", "MODIFY", $data{'borrowernumber'}, "UPDATE (executed w/ arg: $data{'borrowernumber'})") if C4::Context->preference("BorrowersLog");
     }
     return $execute_success;
 }
 
-
 =head2 AddMember
 
   $borrowernumber = &AddMember(%borrower);
@@ -774,29 +811,29 @@ sub AddMember {
 
     # mysql_insertid is probably bad.  not necessarily accurate and mysql-specific at best.
     logaction("MEMBERS", "CREATE", $data{'borrowernumber'}, "") if C4::Context->preference("BorrowersLog");
-    
-    # check for enrollment fee & add it if needed
-    my $sth = $dbh->prepare("SELECT enrolmentfee FROM categories WHERE categorycode=?");
-    $sth->execute($data{'categorycode'});
-    my ($enrolmentfee) = $sth->fetchrow;
-    if ($sth->err) {
-        warn sprintf('Database returned the following error: %s', $sth->errstr);
-        return;
-    }
-    if ($enrolmentfee && $enrolmentfee > 0) {
-        # insert fee in patron debts
-        manualinvoice($data{'borrowernumber'}, '', '', 'A', $enrolmentfee);
-    }
+
+    AddEnrolmentFeeIfNeeded( $data{categorycode}, $data{borrowernumber} );
 
     return $data{'borrowernumber'};
 }
 
+=head2 Check_Userid
+
+    my $uniqueness = Check_Userid($userid,$borrowernumber);
+
+    $borrowernumber is optional (i.e. it can contain a blank value). If $userid is passed with a blank $borrowernumber variable, the database will be checked for all instances of that userid (i.e. userid=? AND borrowernumber != '').
+
+    If $borrowernumber is provided, the database will be checked for every instance of that userid coupled with a different borrower(number) than the one provided.
+
+    return :
+        0 for not unique (i.e. this $userid already exists)
+        1 for unique (i.e. this $userid does not exist, or this $userid/$borrowernumber combination already exists)
+
+=cut
 
 sub Check_Userid {
     my ($uid,$member) = @_;
     my $dbh = C4::Context->dbh;
-    # Make sure the userid chosen is unique and not theirs if non-empty. If it is not,
-    # Then we need to tell the user and have them create a new one.
     my $sth =
       $dbh->prepare(
         "SELECT * FROM borrowers WHERE userid=? AND borrowernumber != ?");
@@ -809,10 +846,24 @@ sub Check_Userid {
     }
 }
 
+=head2 Generate_Userid
+
+    my $newuid = Generate_Userid($borrowernumber, $firstname, $surname);
+
+    Generate a userid using the $surname and the $firstname (if there is a value in $firstname).
+
+    $borrowernumber is optional (i.e. it can contain a blank value). A value is passed when generating a new userid for an existing borrower. When a new userid is created for a new borrower, a blank value is passed to this sub.
+
+    return :
+        new userid ($firstname.$surname if there is a $firstname, or $surname if there is no value in $firstname) plus offset (0 if the $newuid is unique, or a higher numeric value if Check_Userid finds an existing match for the $newuid in the database).
+
+=cut
+
 sub Generate_Userid {
   my ($borrowernumber, $firstname, $surname) = @_;
   my $newuid;
   my $offset = 0;
+  #The script will "do" the following code and increment the $offset until Check_Userid = 1 (i.e. until $newuid comes back as unique)
   do {
     $firstname =~ s/[[:digit:][:space:][:blank:][:punct:][:cntrl:]]//g;
     $surname =~ s/[[:digit:][:space:][:blank:][:punct:][:cntrl:]]//g;
@@ -1359,6 +1410,35 @@ sub GetFirstValidEmailAddress {
     }
 }
 
+=head2 GetNoticeEmailAddress
+
+  $email = GetNoticeEmailAddress($borrowernumber);
+
+Return the email address of borrower used for notices, given the borrowernumber.
+Returns the empty string if no email address.
+
+=cut
+
+sub GetNoticeEmailAddress {
+    my $borrowernumber = shift;
+
+    my $which_address = C4::Context->preference("AutoEmailPrimaryAddress");
+    # if syspref is set to 'first valid' (value == OFF), look up email address
+    if ( $which_address eq 'OFF' ) {
+        return GetFirstValidEmailAddress($borrowernumber);
+    }
+    # specified email address field
+    my $dbh = C4::Context->dbh;
+    my $sth = $dbh->prepare( qq{
+        SELECT $which_address AS primaryemail
+        FROM borrowers
+        WHERE borrowernumber=?
+    } );
+    $sth->execute($borrowernumber);
+    my $data = $sth->fetchrow_hashref;
+    return $data->{'primaryemail'} || '';
+}
+
 =head2 GetExpiryDate 
 
   $expirydate = GetExpiryDate($categorycode, $dateenrolled);
@@ -1792,15 +1872,10 @@ UPDATE borrowers
 SET  dateexpiry='$date' 
 WHERE borrowernumber='$borrowerid'
 EOF
-    # add enrolmentfee if needed
-    $sth = $dbh->prepare("SELECT enrolmentfee FROM categories WHERE categorycode=?");
-    $sth->execute($borrower->{'categorycode'});
-    my ($enrolmentfee) = $sth->fetchrow;
-    if ($enrolmentfee && $enrolmentfee > 0) {
-        # insert fee in patron debts
-        manualinvoice($borrower->{'borrowernumber'}, '', '', 'A', $enrolmentfee);
-    }
-     logaction("MEMBERS", "RENEW", $borrower->{'borrowernumber'}, "Membership renewed")if C4::Context->preference("BorrowersLog");
+
+    AddEnrolmentFeeIfNeeded( $borrower->{categorycode}, $borrower->{borrowernumber} );
+
+    logaction("MEMBERS", "RENEW", $borrower->{'borrowernumber'}, "Membership renewed")if C4::Context->preference("BorrowersLog");
     return $date if ($sth);
     return 0;
 }
@@ -1989,7 +2064,7 @@ sub GetBorrowersToExpunge {
     my $filterexpiry   = $params->{'expired_before'};
     my $filtercategory = $params->{'category_code'};
     my $filterbranch   = $params->{'branchcode'} ||
-                        ((C4::Context->preference('IndependantBranches') 
+                        ((C4::Context->preference('IndependentBranches')
                              && C4::Context->userenv 
                              && C4::Context->userenv->{flags} % 2 !=1 
                              && C4::Context->userenv->{branch})
@@ -2055,7 +2130,7 @@ I<$result> is a ref to an array which all elements are a hasref.
 
 sub GetBorrowersWhoHaveNeverBorrowed {
     my $filterbranch = shift || 
-                        ((C4::Context->preference('IndependantBranches') 
+                        ((C4::Context->preference('IndependentBranches')
                              && C4::Context->userenv 
                              && C4::Context->userenv->{flags} % 2 !=1 
                              && C4::Context->userenv->{branch})
@@ -2105,7 +2180,7 @@ sub GetBorrowersWithIssuesHistoryOlderThan {
     my $dbh  = C4::Context->dbh;
     my $date = shift ||POSIX::strftime("%Y-%m-%d",localtime());
     my $filterbranch = shift || 
-                        ((C4::Context->preference('IndependantBranches') 
+                        ((C4::Context->preference('IndependentBranches')
                              && C4::Context->userenv 
                              && C4::Context->userenv->{flags} % 2 !=1 
                              && C4::Context->userenv->{branch})
@@ -2356,14 +2431,14 @@ sub IssueSlip {
 
     my $issueslist = GetPendingIssues($borrowernumber);
     foreach my $it (@$issueslist){
-        if ((substr $it->{'issuedate'}, 0, 10) eq $now) {
+        if ((substr $it->{'issuedate'}, 0, 10) eq $now || (substr $it->{'lastreneweddate'}, 0, 10) eq $now) {
             $it->{'now'} = 1;
         }
         elsif ((substr $it->{'date_due'}, 0, 10) le $now) {
             $it->{'overdue'} = 1;
         }
-
-        $it->{'date_due'}=format_date($it->{'date_due'});
+        my $dt = dt_from_string( $it->{'date_due'} );
+        $it->{'date_due'} = output_pref( $dt );;
     }
     my @issues = sort { $b->{'timestamp'} <=> $a->{'timestamp'} } @$issueslist;
 
@@ -2456,6 +2531,35 @@ sub AddMember_Opac {
     return ( $borrowernumber, $password );
 }
 
+=head2 AddEnrolmentFeeIfNeeded
+
+    AddEnrolmentFeeIfNeeded( $borrower->{categorycode}, $borrower->{borrowernumber} );
+
+Add enrolment fee for a patron if needed.
+
+=cut
+
+sub AddEnrolmentFeeIfNeeded {
+    my ( $categorycode, $borrowernumber ) = @_;
+    # check for enrollment fee & add it if needed
+    my $dbh = C4::Context->dbh;
+    my $sth = $dbh->prepare(q{
+        SELECT enrolmentfee
+        FROM categories
+        WHERE categorycode=?
+    });
+    $sth->execute( $categorycode );
+    if ( $sth->err ) {
+        warn sprintf('Database returned the following error: %s', $sth->errstr);
+        return;
+    }
+    my ($enrolmentfee) = $sth->fetchrow;
+    if ($enrolmentfee && $enrolmentfee > 0) {
+        # insert fee in patron debts
+        C4::Accounts::manualinvoice( $borrowernumber, '', '', 'A', $enrolmentfee );
+    }
+}
+
 END { }    # module clean-up code here (global destructor)
 
 1;