X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=C4%2FLetters.pm;h=0d092acc6ae75150b82e014c13a6ee7433ce0a65;hb=16548d39840c92d43a64ca08f63231156935c41c;hp=405dfed8a7610b82ed66efeaef21091a2f37b23e;hpb=54731a0ce10094b60fd0b9541c24fbffc49a2c05;p=koha.git diff --git a/C4/Letters.pm b/C4/Letters.pm index 405dfed8a7..0d092acc6a 100644 --- a/C4/Letters.pm +++ b/C4/Letters.pm @@ -4,18 +4,18 @@ package C4::Letters; # # This file is part of Koha. # -# Koha is free software; you can redistribute it and/or modify it under the -# terms of the GNU General Public License as published by the Free Software -# Foundation; either version 2 of the License, or (at your option) any later -# version. +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. # -# Koha is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY 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., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . use strict; use warnings; @@ -31,10 +31,13 @@ use C4::Log; use C4::SMS; use C4::Debug; use Koha::DateUtils; +use Koha::SMS::Providers; + use Date::Calc qw( Add_Delta_Days ); use Encode; use Carp; use Koha::Email; +use Koha::DateUtils qw( format_sqldatetime ); use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); @@ -207,8 +210,7 @@ sub GetLettersAvailableForALibrary { our %letter; sub getletter { my ( $module, $code, $branchcode, $message_transport_type ) = @_; - $message_transport_type ||= 'email'; - + $message_transport_type //= '%'; if ( C4::Context->preference('IndependentBranches') and $branchcode @@ -226,7 +228,8 @@ sub getletter { my $sth = $dbh->prepare(q{ SELECT * FROM letter - WHERE module=? AND code=? AND (branchcode = ? OR branchcode = '') AND message_transport_type = ? + WHERE module=? AND code=? AND (branchcode = ? OR branchcode = '') + AND message_transport_type LIKE ? ORDER BY branchcode DESC LIMIT 1 }); $sth->execute( $module, $code, $branchcode, $message_transport_type ); @@ -237,6 +240,7 @@ sub getletter { return { %$line }; } + =head2 DelLetter DelLetter( @@ -389,25 +393,34 @@ sub SendAlerts { if ( $type eq 'issue' ) { # prepare the letter... - # search the biblionumber + # search the subscriptionid my $sth = $dbh->prepare( - "SELECT biblionumber FROM subscription WHERE subscriptionid=?"); + "SELECT subscriptionid FROM serial WHERE serialid=?"); $sth->execute($externalid); - my ($biblionumber) = $sth->fetchrow + my ($subscriptionid) = $sth->fetchrow or warn( "No subscription for '$externalid'" ), return; + # search the biblionumber + $sth = + $dbh->prepare( + "SELECT biblionumber FROM subscription WHERE subscriptionid=?"); + $sth->execute($subscriptionid); + my ($biblionumber) = $sth->fetchrow + or warn( "No biblionumber for '$subscriptionid'" ), + return; + my %letter; # find the list of borrowers to alert - my $alerts = getalert( '', 'issue', $externalid ); + my $alerts = getalert( '', 'issue', $subscriptionid ); foreach (@$alerts) { my $borinfo = C4::Members::GetMember('borrowernumber' => $_->{'borrowernumber'}); my $email = $borinfo->{email} or next; # warn "sending issues..."; my $userenv = C4::Context->userenv; - my $branchdetails = GetBranchDetail($_->{'branchcode'}); + my $library = Koha::Libraries->find( $_->{branchcode} ); my $letter = GetPreparedLetter ( module => 'serial', letter_code => $letter_code, @@ -417,6 +430,8 @@ sub SendAlerts { 'biblio' => $biblionumber, 'biblioitems' => $biblionumber, 'borrowers' => $borinfo, + 'subscription' => $subscriptionid, + 'serial' => $externalid, }, want_librarian => 1, ) or return; @@ -426,12 +441,17 @@ sub SendAlerts { my %mail = $message->create_message_headers( { to => $email, - from => $branchdetails->{'branchemail'}, - replyto => $branchdetails->{'branchreplyto'}, - sender => $branchdetails->{'branchreturnpath'}, - subject => Encode::encode( "utf8", "" . $letter->{title} ), - message => $letter->{'is_html'} ? _wrap_html( Encode::encode( "utf8", $letter->{'content'} ), Encode::encode( "utf8", "" . $letter->{'title'} ) ) : Encode::encode( "utf8", "" . $letter->{'content'} ), - contenttype => $letter->{'is_html'} ? 'text/html; charset="utf-8"' : 'text/plain; charset="utf-8"', + from => $library->branchemail, + replyto => $library->branchreplyto, + sender => $library->branchreturnpath, + subject => Encode::encode( "UTF-8", "" . $letter->{title} ), + message => $letter->{'is_html'} + ? _wrap_html( Encode::encode( "UTF-8", $letter->{'content'} ), + Encode::encode( "UTF-8", "" . $letter->{'title'} )) + : Encode::encode( "UTF-8", "" . $letter->{'content'} ), + contenttype => $letter->{'is_html'} + ? 'text/html; charset="utf-8"' + : 'text/plain; charset="utf-8"', } ); sendmail(%mail) or carp $Mail::Sendmail::error; @@ -515,15 +535,22 @@ sub SendAlerts { To => join( ',', @email), Cc => join( ',', @cc), From => $userenv->{emailaddress}, - Subject => Encode::encode( "utf8", "" . $letter->{title} ), - Message => $letter->{'is_html'} ? _wrap_html( Encode::encode( "utf8", $letter->{'content'} ), Encode::encode( "utf8", "" . $letter->{'title'} ) ) : Encode::encode( "utf8", "" . $letter->{'content'} ), - 'Content-Type' => $letter->{'is_html'} ? 'text/html; charset="utf-8"' : 'text/plain; charset="utf-8"', + Subject => Encode::encode( "UTF-8", "" . $letter->{title} ), + Message => $letter->{'is_html'} + ? _wrap_html( Encode::encode( "UTF-8", $letter->{'content'} ), + Encode::encode( "UTF-8", "" . $letter->{'title'} )) + : Encode::encode( "UTF-8", "" . $letter->{'content'} ), + 'Content-Type' => $letter->{'is_html'} + ? 'text/html; charset="utf-8"' + : 'text/plain; charset="utf-8"', ); $mail{'Reply-to'} = C4::Context->preference('ReplytoDefault') if C4::Context->preference('ReplytoDefault'); $mail{'Sender'} = C4::Context->preference('ReturnpathDefault') if C4::Context->preference('ReturnpathDefault'); + $mail{'Bcc'} = $userenv->{emailaddress} + if C4::Context->preference("ClaimsBccCopy"); unless ( sendmail(%mail) ) { carp $Mail::Sendmail::error; @@ -544,13 +571,13 @@ sub SendAlerts { } # send an "account details" notice to a newly created user elsif ( $type eq 'members' ) { - my $branchdetails = GetBranchDetail($externalid->{'branchcode'}); + my $library = Koha::Libraries->find( $externalid->{branchcode} )->unblessed; my $letter = GetPreparedLetter ( module => 'members', letter_code => $letter_code, branchcode => $externalid->{'branchcode'}, tables => { - 'branches' => $branchdetails, + 'branches' => $library, 'borrowers' => $externalid->{'borrowernumber'}, }, substitute => { 'borrowers.password' => $externalid->{'password'} }, @@ -561,12 +588,17 @@ sub SendAlerts { my %mail = $email->create_message_headers( { to => $externalid->{'emailaddr'}, - from => $branchdetails->{'branchemail'}, - replyto => $branchdetails->{'branchreplyto'}, - sender => $branchdetails->{'branchreturnpath'}, - subject => Encode::encode( "utf8", "" . $letter->{'title'} ), - message => $letter->{'is_html'} ? _wrap_html( Encode::encode( "utf8", $letter->{'content'} ), Encode::encode( "utf8", "" . $letter->{'title'} ) ) : Encode::encode( "utf8", "" . $letter->{'content'} ), - contenttype => $letter->{'is_html'} ? 'text/html; charset="utf-8"' : 'text/plain; charset="utf-8"', + from => $library->{branchemail}, + replyto => $library->{branchreplyto}, + sender => $library->{branchreturnpath}, + subject => Encode::encode( "UTF-8", "" . $letter->{'title'} ), + message => $letter->{'is_html'} + ? _wrap_html( Encode::encode( "UTF-8", $letter->{'content'} ), + Encode::encode( "UTF-8", "" . $letter->{'title'} ) ) + : Encode::encode( "UTF-8", "" . $letter->{'content'} ), + contenttype => $letter->{'is_html'} + ? 'text/html; charset="utf-8"' + : 'text/plain; charset="utf-8"', } ); sendmail(%mail) or carp $Mail::Sendmail::error; @@ -618,6 +650,10 @@ sub GetPreparedLetter { if ($substitute) { while ( my ($token, $val) = each %$substitute ) { + if ( $token eq 'items.content' ) { + $val =~ s|\n|
|g if $letter->{is_html}; + } + $letter->{title} =~ s/<<$token>>/$val/g; $letter->{content} =~ s/<<$token>>/$val/g; } @@ -739,6 +775,8 @@ sub _parseletter_sth { ($table eq 'aqorders' ) ? "SELECT * FROM $table WHERE ordernumber = ?" : ($table eq 'opac_news' ) ? "SELECT * FROM $table WHERE idnew = ?" : ($table eq 'borrower_modifications') ? "SELECT * FROM $table WHERE verification_token = ?" : + ($table eq 'subscription') ? "SELECT * FROM $table WHERE subscriptionid = ?" : + ($table eq 'serial') ? "SELECT * FROM $table WHERE serialid = ?" : undef ; unless ($query) { warn "ERROR: No _parseletter_sth query for table '$table'"; @@ -756,24 +794,31 @@ sub _parseletter_sth { parameters : - $letter : a hash to letter fields (title & content useful) - $table : the Koha table to parse. - - $values : table record hashref + - $values_in : table record hashref parse all fields from a table, and replace values in title & content with the appropriate value (not exported sub, used only internally) =cut sub _parseletter { - my ( $letter, $table, $values ) = @_; + my ( $letter, $table, $values_in ) = @_; + + # Work on a local copy of $values_in (passed by reference) to avoid side effects + # in callers ( by changing / formatting values ) + my $values = $values_in ? { %$values_in } : {}; + + if ( $table eq 'borrowers' && $values->{'dateexpiry'} ){ + $values->{'dateexpiry'} = format_sqldatetime( $values->{'dateexpiry'} ); + } if ( $table eq 'reserves' && $values->{'waitingdate'} ) { my @waitingdate = split /-/, $values->{'waitingdate'}; $values->{'expirationdate'} = ''; - if( C4::Context->preference('ExpireReservesMaxPickUpDelay') && - C4::Context->preference('ReservesMaxPickUpDelay') ) { + if ( C4::Context->preference('ReservesMaxPickUpDelay') ) { my $dt = dt_from_string(); $dt->add( days => C4::Context->preference('ReservesMaxPickUpDelay') ); - $values->{'expirationdate'} = output_pref({ dt => $dt, dateonly => 1 }); + $values->{'expirationdate'} = output_pref( { dt => $dt, dateonly => 1 } ); } $values->{'waitingdate'} = output_pref({ dt => dt_from_string( $values->{'waitingdate'} ), dateonly => 1 }); @@ -786,14 +831,14 @@ sub _parseletter { } while ( my ($field, $val) = each %$values ) { - my $replacetablefield = "<<$table.$field>>"; - my $replacefield = "<<$field>>"; $val =~ s/\p{P}$// if $val && $table=~/biblio/; #BZ 9886: Assuming that we want to eliminate ISBD punctuation here #Therefore adding the test on biblio. This includes biblioitems, #but excludes items. Removed unneeded global and lookahead. $val = GetAuthorisedValueByCode ('ROADTYPE', $val, 0) if $table=~/^borrowers$/ && $field=~/^streettype$/; + + # Dates replacement my $replacedby = defined ($val) ? $val : ''; if ( $replacedby and not $replacedby =~ m|0000-00-00| @@ -802,19 +847,34 @@ sub _parseletter { { # If the value is XXXX-YY-ZZ[ AA:BB:CC] we assume it is a date my $dateonly = defined $1 ? 0 : 1; #$1 refers to the capture group wrapped in parentheses. In this case, that's the hours, minutes, seconds. - eval { - $replacedby = output_pref({ dt => dt_from_string( $replacedby ), dateonly => $dateonly }); - }; - warn "$replacedby seems to be a date but an error occurs on generating it ($@)" if $@; + my $re_dateonly_filter = qr{ $field( \s* \| \s* dateonly\s*)?>> }xms; + + for my $letter_field ( qw( title content ) ) { + my $filter_string_used = q{}; + if ( $letter->{ $letter_field } =~ $re_dateonly_filter ) { + # We overwrite $dateonly if the filter exists and we have a time in the datetime + $filter_string_used = $1 || q{}; + $dateonly = $1 unless $dateonly; + } + eval { + $replacedby = output_pref({ dt => dt_from_string( $replacedby ), dateonly => $dateonly }); + }; + + if ( $letter->{ $letter_field } ) { + $letter->{ $letter_field } =~ s/\Q<<$table.$field$filter_string_used>>\E/$replacedby/g; + $letter->{ $letter_field } =~ s/\Q<<$field$filter_string_used>>\E/$replacedby/g; + } + } + } + # Other fields replacement + else { + for my $letter_field ( qw( title content ) ) { + if ( $letter->{ $letter_field } ) { + $letter->{ $letter_field } =~ s/<<$table.$field>>/$replacedby/g; + $letter->{ $letter_field } =~ s/<<$field>>/$replacedby/g; + } + } } - ($letter->{title} ) and do { - $letter->{title} =~ s/$replacetablefield/$replacedby/g; - $letter->{title} =~ s/$replacefield/$replacedby/g; - }; - ($letter->{content}) and do { - $letter->{content} =~ s/$replacetablefield/$replacedby/g; - $letter->{content} =~ s/$replacefield/$replacedby/g; - }; } if ($table eq 'borrowers' && $letter->{content}) { @@ -925,7 +985,14 @@ sub SendQueuedMessages { _send_message_by_email( $message, $params->{'username'}, $params->{'password'}, $params->{'method'} ); } elsif ( lc( $message->{'message_transport_type'} ) eq 'sms' ) { - _send_message_by_sms( $message ); + if ( C4::Context->preference('SMSSendDriver') eq 'Email' ) { + my $member = C4::Members::GetMember( 'borrowernumber' => $message->{'borrowernumber'} ); + my $sms_provider = Koha::SMS::Providers->find( $member->{'sms_provider_id'} ); + $message->{to_address} .= '@' . $sms_provider->domain(); + _send_message_by_email( $message, $params->{'username'}, $params->{'password'}, $params->{'method'} ); + } else { + _send_message_by_sms( $message ); + } } } return scalar( @$unsent_messages ); @@ -1132,18 +1199,18 @@ sub _send_message_by_email { my $utf8 = decode('MIME-Header', $message->{'subject'} ); $message->{subject}= encode('MIME-Header', $utf8); - my $subject = encode('utf8', $message->{'subject'}); - my $content = encode('utf8', $message->{'content'}); + my $subject = encode('UTF-8', $message->{'subject'}); + my $content = encode('UTF-8', $message->{'content'}); my $content_type = $message->{'content_type'} || 'text/plain; charset="UTF-8"'; my $is_html = $content_type =~ m/html/io; my $branch_email = undef; my $branch_replyto = undef; my $branch_returnpath = undef; - if ($member){ - my $branchdetail = GetBranchDetail( $member->{'branchcode'} ); - $branch_email = $branchdetail->{'branchemail'}; - $branch_replyto = $branchdetail->{'branchreplyto'}; - $branch_returnpath = $branchdetail->{'branchreturnpath'}; + if ($member) { + my $library = Koha::Libraries->find( $member->{branchcode} ); + $branch_email = $library->branchemail; + $branch_replyto = $library->branchreplyto; + $branch_returnpath = $library->branchreturnpath; } my $email = Koha::Email->new(); my %sendmail_params = $email->create_message_headers( @@ -1164,6 +1231,7 @@ sub _send_message_by_email { } _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' } );