Bug 5510: prepend output with system name
[koha.git] / C4 / Letters.pm
index 3d83c88..d32b3cf 100644 (file)
@@ -13,19 +13,23 @@ package C4::Letters;
 # 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., 59 Temple Place,
-# Suite 330, Boston, MA  02111-1307 USA
+# 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 strict;
 use warnings;
 
 use MIME::Lite;
 use Mail::Sendmail;
+use Encode;
+use Carp;
+
 use C4::Members;
 use C4::Log;
 use C4::SMS;
 use C4::Debug;
+use Date::Calc qw( Add_Delta_Days );
 use Encode;
 use Carp;
 
@@ -37,7 +41,7 @@ BEGIN {
        $VERSION = 3.01;
        @ISA = qw(Exporter);
        @EXPORT = qw(
-       &GetLetters &getletter &addalert &getalert &delalert &findrelatedto &SendAlerts
+       &GetLetters &getletter &addalert &getalert &delalert &findrelatedto &SendAlerts GetPrintMessages
        );
 }
 
@@ -150,7 +154,7 @@ sub addalert ($$$) {
     parameters :
     - alertid : the alert id
     deletes the alert
-    
+
 =cut
 
 sub delalert ($) {
@@ -271,7 +275,7 @@ sub SendAlerts {
 
             # and parse borrower ...
             my $innerletter = $letter;
-            my $borinfo = GetMember( $_->{'borrowernumber'}, 'borrowernumber' );
+            my $borinfo = C4::Members::GetMember('borrowernumber' => $_->{'borrowernumber'});
             parseletter( $innerletter, 'borrowers', $_->{'borrowernumber'} );
 
             # ... then send mail
@@ -283,7 +287,7 @@ sub SendAlerts {
                     Message => "" . $innerletter->{content},
                     'Content-Type' => 'text/plain; charset="utf8"',
                     );
-                sendmail(%mail);
+                sendmail(%mail) or carp $Mail::Sendmail::error;
 
 # warn "sending to $mail{To} From $mail{From} subj $mail{Subject} Mess $mail{Message}";
             }
@@ -344,9 +348,7 @@ sub SendAlerts {
                 Message        => "" . $innerletter->{content},
                 'Content-Type' => 'text/plain; charset="utf8"',
             );
-            sendmail(%mail);
-            warn
-"sending to $mail{To} From $mail{From} subj $mail{Subject} Mess $mail{Message}";
+            sendmail(%mail) or carp $Mail::Sendmail::error;
         }
         if ( C4::Context->preference("LetterLog") ) {
             logaction(
@@ -400,21 +402,29 @@ sub SendAlerts {
 
         # ... then send mail
         if (   $databookseller->{bookselleremail}
-            || $databookseller->{contemail} )
-        {
+            || $databookseller->{contemail} ) {
+            my $mail_to = $databookseller->{bookselleremail};
+            if ($databookseller->{contemail}) {
+                if (!$mail_to) {
+                    $mail_to = $databookseller->{contemail};
+                } else {
+                    $mail_to .= q|,|;
+                    $mail_to .= $databookseller->{contemail};
+                }
+            }
+            my $mail_subj = $innerletter->{title};
+            my $mail_msg  = $innerletter->{content};
+            $mail_msg  ||= q{};
+            $mail_subj ||= q{};
+
             my %mail = (
-                To => $databookseller->{bookselleremail}
-                  . (
-                    $databookseller->{contemail}
-                    ? "," . $databookseller->{contemail}
-                    : ""
-                  ),
+                To => $mail_to,
                 From    => $userenv->{emailaddress},
-                Subject => "" . $innerletter->{title},
-                Message => "" . $innerletter->{content},
+                Subject => $mail_subj,
+                Message => $mail_msg,
                 'Content-Type' => 'text/plain; charset="utf8"',
             );
-            sendmail(%mail);
+            sendmail(%mail) or carp $Mail::Sendmail::error;
             logaction(
                 "ACQUISITION",
                 "CLAIM ISSUE",
@@ -427,8 +437,6 @@ sub SendAlerts {
                   . $innerletter->{content}
             ) if C4::Context->preference("LetterLog");
         }
-        warn
-"sending to From $userenv->{emailaddress} subj $innerletter->{title} Mess $innerletter->{content}";
     }    
    # send an "account details" notice to a newly created user 
     elsif ( $type eq 'members' ) {
@@ -445,7 +453,7 @@ sub SendAlerts {
                 Message => $letter->{'content'},
                 'Content-Type' => 'text/plain; charset="utf8"',
         );
-        sendmail(%mail);
+        sendmail(%mail) or carp $Mail::Sendmail::error;
     }
 }
 
@@ -478,6 +486,7 @@ sub parseletter_sth {
     ($table eq 'reserves'     ) ? "SELECT * FROM $table WHERE borrowernumber = ? and biblionumber = ?" :
     ($table eq 'borrowers'    ) ? "SELECT * FROM $table WHERE borrowernumber = ?"                      :
     ($table eq 'branches'     ) ? "SELECT * FROM $table WHERE     branchcode = ?"                      :
+    ($table eq 'suggestions'  ) ? "SELECT * FROM $table WHERE   suggestionid = ?"                      :
     ($table eq 'aqbooksellers') ? "SELECT * FROM $table WHERE             id = ?"                      : undef ;
     unless ($query) {
         warn "ERROR: No parseletter_sth query for table '$table'";
@@ -496,7 +505,6 @@ sub parseletter {
         carp "ERROR: parseletter() 1st argument 'letter' empty";
         return;
     }
-    #  warn "Parseletter : ($letter, $table, $pk ...)";
     my $sth = parseletter_sth($table);
     unless ($sth) {
         warn "parseletter_sth('$table') failed to return a valid sth.  No substitution will be done for that table.";
@@ -509,23 +517,38 @@ sub parseletter {
     }
 
     my $values = $sth->fetchrow_hashref;
+    
+    # TEMPORARY hack until the expirationdate column is added to reserves
+    if ( $table eq 'reserves' && $values->{'waitingdate'} ) {
+        my @waitingdate = split /-/, $values->{'waitingdate'};
+
+        $values->{'expirationdate'} = C4::Dates->new(
+            sprintf(
+                '%04d-%02d-%02d',
+                Add_Delta_Days( @waitingdate, C4::Context->preference( 'ReservesMaxPickUpDelay' ) )
+            ),
+            'iso'
+        )->output();
+    }
+
 
     # and get all fields from the table
     my $columns = C4::Context->dbh->prepare("SHOW COLUMNS FROM $table");
     $columns->execute;
     while ( ( my $field ) = $columns->fetchrow_array ) {
         my $replacefield = "<<$table.$field>>";
+        $values->{$field} =~ s/\p{P}(?=$)//g if $values->{$field};
         my $replacedby   = $values->{$field} || '';
         ($letter->{title}  ) and $letter->{title}   =~ s/$replacefield/$replacedby/g;
         ($letter->{content}) and $letter->{content} =~ s/$replacefield/$replacedby/g;
     }
+    return $letter;
 }
 
 =head2 EnqueueLetter
 
-=over 4
-
-my $success = EnqueueLetter( { letter => $letter, borrowernumber => '12', message_transport_type => 'email' } )
+  my $success = EnqueueLetter( { letter => $letter, 
+        borrowernumber => '12', message_transport_type => 'email' } )
 
 places a letter in the message_queue database table, which will
 eventually get processed (sent) by the process_message_queue.pl
@@ -533,8 +556,6 @@ cronjob when it calls SendQueuedMessages.
 
 return true on success
 
-=back
-
 =cut
 
 sub EnqueueLetter ($) {
@@ -580,16 +601,12 @@ ENDSQL
 
 =head2 SendQueuedMessages ([$hashref]) 
 
-=over 4
+  my $sent = SendQueuedMessages( { verbose => 1 } );
 
 sends all of the 'pending' items in the message queue.
 
-my $sent = SendQueuedMessages( { verbose => 1 } );
-
 returns number of messages sent.
 
-=back
-
 =cut
 
 sub SendQueuedMessages (;$) {
@@ -607,7 +624,7 @@ sub SendQueuedMessages (;$) {
         if ( lc( $message->{'message_transport_type'} ) eq 'email' ) {
             _send_message_by_email( $message );
         }
-        if ( lc( $message->{'message_transport_type'} ) eq 'sms' ) {
+        elsif ( lc( $message->{'message_transport_type'} ) eq 'sms' ) {
             _send_message_by_sms( $message );
         }
     }
@@ -616,14 +633,10 @@ sub SendQueuedMessages (;$) {
 
 =head2 GetRSSMessages
 
-=over 4
-
-my $message_list = GetRSSMessages( { limit => 10, borrowernumber => '14' } )
+  my $message_list = GetRSSMessages( { limit => 10, borrowernumber => '14' } )
 
 returns a listref of all queued RSS messages for a particular person.
 
-=back
-
 =cut
 
 sub GetRSSMessages {
@@ -638,19 +651,31 @@ sub GetRSSMessages {
                                    borrowernumber         => $params->{'borrowernumber'}, } );
 }
 
-=head2 GetQueuedMessages ([$hashref])
+=head2 GetPrintMessages
+
+  my $message_list = GetPrintMessages( { borrowernumber => $borrowernumber } )
+
+Returns a arrayref of all queued print messages (optionally, for a particular
+person).
+
+=cut
+
+sub GetPrintMessages {
+    my $params = shift || {};
+    
+    return _get_unsent_messages( { message_transport_type => 'print',
+                                   borrowernumber         => $params->{'borrowernumber'}, } );
+}
 
-=over 4
+=head2 GetQueuedMessages ([$hashref])
 
-my $messages = GetQueuedMessage( { borrowernumber => '123', limit => 20 } );
+  my $messages = GetQueuedMessage( { borrowernumber => '123', limit => 20 } );
 
 fetches messages out of the message queue.
 
 returns:
 list of hashes, each has represents a message in the message queue.
 
-=back
-
 =cut
 
 sub GetQueuedMessages {
@@ -760,45 +785,63 @@ ENDSQL
     return $sth->fetchall_arrayref({});
 }
 
-sub _send_message_by_email ($) {
-    my $message = shift or return undef;
-
-    my $member = C4::Members::GetMember( $message->{'borrowernumber'} );
-    return unless $message->{'to_address'} or $member->{'email'};
+sub _send_message_by_email ($;$$$) {
+    my $message = shift or return;
+
+    my $to_address = $message->{to_address};
+    unless ($to_address) {
+        my $member = C4::Members::GetMember( 'borrowernumber' => $message->{'borrowernumber'} );
+        unless ($member) {
+            warn "FAIL: No 'to_address' and INVALID borrowernumber ($message->{borrowernumber})";
+            _set_message_status( { message_id => $message->{'message_id'},
+                                   status     => 'failed' } );
+            return;
+        }
+        my $which_address = C4::Context->preference('AutoEmailPrimaryAddress');
+        # If the system preference is set to 'first valid' (value == OFF), look up email address
+        if ($which_address eq 'OFF') {
+            $to_address = GetFirstValidEmailAddress( $message->{'borrowernumber'} );
+        } else {
+            $to_address = $member->{$which_address};
+        }
+        unless ($to_address) {  
+            # warn "FAIL: No 'to_address' and no email for " . ($member->{surname} ||'') . ", borrowernumber ($message->{borrowernumber})";
+            # warning too verbose for this more common case?
+            _set_message_status( { message_id => $message->{'message_id'},
+                                   status     => 'failed' } );
+            return;
+        }
+    }
 
        my $content = encode('utf8', $message->{'content'});
     my %sendmail_params = (
-        To   => $message->{'to_address'}   || $member->{'email'},
+        To   => $to_address,
         From => $message->{'from_address'} || C4::Context->preference('KohaAdminEmailAddress'),
-        Subject => $message->{'subject'},
-               charset => 'utf8',
+        Subject => encode('utf8', $message->{'subject'}),
+        charset => 'utf8',
         Message => $content,
+        'content-type' => $message->{'content_type'} || 'text/plain; charset="UTF-8"',
     );
-    if ($message->{'content_type'}) {
-        $sendmail_params{'content-type'} = $message->{'content_type'};
-    }else{
-        $sendmail_params{'content-type'} = 'text/plain; charset="UTF-8"';
+    if ( my $bcc = C4::Context->preference('OverdueNoticeBcc') ) {
+       $sendmail_params{ Bcc } = $bcc;
     }
     
-    my $success = sendmail( %sendmail_params );
 
-    if ( $success ) {
-        # warn "Sendmail OK. Log says: " .  $Mail::Sendmail::log;
+    if ( sendmail( %sendmail_params ) ) {
         _set_message_status( { message_id => $message->{'message_id'},
-                               status     => 'sent' } );
-        return $success;
+                status     => 'sent' } );
+        return 1;
     } else {
-        # warn "Mail::Sendmail::error - " . $Mail::Sendmail::error;
-        # warn "Mail::Sendmail::log   - " . $Mail::Sendmail::log;
         _set_message_status( { message_id => $message->{'message_id'},
-                               status     => 'failed' } );
+                status     => 'failed' } );
+        carp $Mail::Sendmail::error;
         return;
     }
 }
 
 sub _send_message_by_sms ($) {
     my $message = shift or return undef;
-    my $member = C4::Members::GetMember( $message->{'borrowernumber'} );
+    my $member = C4::Members::GetMember( 'borrowernumber' => $message->{'borrowernumber'} );
     return unless $member->{'smsalertnumber'};
 
     my $success = C4::SMS->send_sms( { destination => $member->{'smsalertnumber'},