X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=C4%2FLetters.pm;h=2420e4a0ecb50c3408c5cf812f3ebbf2eacd5aa9;hb=9c06057f21f1cdbc0a87ecbbdf84306e51e3d6a0;hp=72f4f54d6d6b8f16d04ffe9925e88f2baeb1a065;hpb=8e0b1fe58f7e4f6e595b18d43c939c203833dac1;p=koha_fer diff --git a/C4/Letters.pm b/C4/Letters.pm index 72f4f54d6d..2420e4a0ec 100644 --- a/C4/Letters.pm +++ b/C4/Letters.pm @@ -13,19 +13,24 @@ 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::Branch; use C4::Log; use C4::SMS; use C4::Debug; +use Date::Calc qw( Add_Delta_Days ); use Encode; use Carp; @@ -37,7 +42,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 +155,7 @@ sub addalert ($$$) { parameters : - alertid : the alert id deletes the alert - + =cut sub delalert ($) { @@ -271,7 +276,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 +288,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}"; } @@ -318,12 +323,14 @@ sub SendAlerts { $letter->{content} =~ s/<>/$userenv->{surname}/g; $letter->{content} =~ s/<>/$userenv->{emailaddress}/g; - foreach my $data (@$dataorders) { - my $line = $1 if ( $letter->{content} =~ m/(<<.*>>)/ ); - foreach my $field ( keys %$data ) { - $line =~ s/(<<[^\.]+.$field>>)/$data->{$field}/; + foreach my $data ( @{$dataorders} ) { + if ( $letter->{content} =~ m/(<<.*>>)/ ) { + my $line = $1; + foreach my $field ( keys %{$data} ) { + $line =~ s/(<<[^\.]+.$field>>)/$data->{$field}/; + } + $letter->{content} =~ s/(<<.*>>)/$line\n$1/; } - $letter->{content} =~ s/(<<.*>>)/$line\n$1/; } $letter->{content} =~ s/<<[^>]*>>//g; my $innerletter = $letter; @@ -344,9 +351,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( @@ -388,12 +393,14 @@ sub SendAlerts { $letter->{content} =~ s/<>/$userenv->{surname}/g; $letter->{content} =~ s/<>/$userenv->{emailaddress}/g; - foreach my $data (@$dataorders) { - my $line = $1 if ( $letter->{content} =~ m/(<<.*>>)/ ); - foreach my $field ( keys %$data ) { - $line =~ s/(<<[^\.]+.$field>>)/$data->{$field}/; + foreach my $data ( @{$dataorders} ) { + if ( $letter->{content} =~ m/(<<.*>>)/ ) { + my $line = $1; + foreach my $field ( keys %{$data} ) { + $line =~ s/(<<[^\.]+.$field>>)/$data->{$field}/; + } + $letter->{content} =~ s/(<<.*>>)/$line\n$1/; } - $letter->{content} =~ s/(<<.*>>)/$line\n$1/; } $letter->{content} =~ s/<<[^>]*>>//g; my $innerletter = $letter; @@ -422,7 +429,7 @@ sub SendAlerts { Message => $mail_msg, 'Content-Type' => 'text/plain; charset="utf8"', ); - sendmail(%mail); + sendmail(%mail) or carp $Mail::Sendmail::error; logaction( "ACQUISITION", "CLAIM ISSUE", @@ -435,25 +442,24 @@ 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' ) { - $letter->{content} =~ s/<>/$externalid->{'title'}/g; - $letter->{content} =~ s/<>/$externalid->{'firstname'}/g; - $letter->{content} =~ s/<>/$externalid->{'surname'}/g; - $letter->{content} =~ s/<>/$externalid->{'userid'}/g; + # must parse the password special, before it's hashed. $letter->{content} =~ s/<>/$externalid->{'password'}/g; + parseletter( $letter, 'borrowers', $externalid->{'borrowernumber'}); + parseletter( $letter, 'branches', $externalid->{'branchcode'} ); + + my $branchdetails = GetBranchDetail($externalid->{'branchcode'}); my %mail = ( To => $externalid->{'emailaddr'}, - From => C4::Context->preference("KohaAdminEmailAddress"), + From => $branchdetails->{'branchemail'} || C4::Context->preference("KohaAdminEmailAddress"), Subject => $letter->{'title'}, Message => $letter->{'content'}, 'Content-Type' => 'text/plain; charset="utf8"', ); - sendmail(%mail); + sendmail(%mail) or carp $Mail::Sendmail::error; } } @@ -483,11 +489,11 @@ sub parseletter_sth { ($table eq 'biblio' ) ? "SELECT * FROM $table WHERE biblionumber = ?" : ($table eq 'biblioitems' ) ? "SELECT * FROM $table WHERE biblionumber = ?" : ($table eq 'items' ) ? "SELECT * FROM $table WHERE itemnumber = ?" : - ($table eq 'suggestions' ) ? "SELECT * FROM $table WHERE borrowernumber = ? and biblionumber = ?" : + ($table eq 'issues' ) ? "SELECT * FROM $table WHERE itemnumber = ?" : ($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 borrowernumber = ? and biblionumber = ?" : + ($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'"; @@ -506,7 +512,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."; @@ -519,23 +524,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 @@ -543,8 +563,6 @@ cronjob when it calls SendQueuedMessages. return true on success -=back - =cut sub EnqueueLetter ($) { @@ -590,16 +608,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 (;$) { @@ -615,7 +629,7 @@ sub SendQueuedMessages (;$) { # This is just begging for subclassing next MESSAGE if ( lc($message->{'message_transport_type'}) eq 'rss' ); if ( lc( $message->{'message_transport_type'} ) eq 'email' ) { - _send_message_by_email( $message ); + _send_message_by_email( $message, $params->{'username'}, $params->{'password'}, $params->{'method'} ); } elsif ( lc( $message->{'message_transport_type'} ) eq 'sms' ) { _send_message_by_sms( $message ); @@ -626,14 +640,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 { @@ -648,19 +658,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 { @@ -770,8 +792,9 @@ ENDSQL return $sth->fetchall_arrayref({}); } -sub _send_message_by_email ($) { +sub _send_message_by_email ($;$$$) { my $message = shift or return; + my ($username, $password, $method) = @_; my $to_address = $message->{to_address}; unless ($to_address) { @@ -782,7 +805,14 @@ sub _send_message_by_email ($) { status => 'failed' } ); return; } - unless ($to_address = $member->{email}) { # assigment, not comparison + 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'}, @@ -791,31 +821,31 @@ sub _send_message_by_email ($) { } } - my $content = encode('utf8', $message->{'content'}); + my $utf8 = decode('MIME-Header', $message->{'subject'} ); + $message->{subject}= encode('MIME-Header', $utf8); + my $content = encode('utf8', $message->{'content'}); my %sendmail_params = ( To => $to_address, From => $message->{'from_address'} || C4::Context->preference('KohaAdminEmailAddress'), - Subject => $message->{'subject'}, + Subject => encode('utf8', $message->{'subject'}), charset => 'utf8', Message => $content, 'content-type' => $message->{'content_type'} || 'text/plain; charset="UTF-8"', ); + $sendmail_params{'Auth'} = {user => $username, pass => $password, method => $method} if $username; 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; + _update_message_to_address($message->{'message_id'},$to_address) unless $message->{to_address}; #if initial message address was empty, coming here means that a to address was found and queue should be updated + 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; } } @@ -833,6 +863,12 @@ sub _send_message_by_sms ($) { return $success; } +sub _update_message_to_address { + my ($id, $to)= @_; + my $dbh = C4::Context->dbh(); + $dbh->do('UPDATE message_queue SET to_address=? WHERE message_id=?',undef,($to,$id)); +} + sub _set_message_status ($) { my $params = shift or return undef;