View | Details | Raw Unified | Return to bug 12802
Collapse All | Expand All

(-)a/C4/Auth.pm (-1 / +1 lines)
Lines 1390-1396 sub checkauth { Link Here
1390
        $template->param(
1390
        $template->param(
1391
            TwoFA_prompt => 1,
1391
            TwoFA_prompt => 1,
1392
            invalid_otp_token => $invalid_otp_token,
1392
            invalid_otp_token => $invalid_otp_token,
1393
            notice_email_address => $patron->notice_email_address, # We could also pass logged_in_user if necessary
1393
            notice_email_addresses => $patron->notice_email_addresses, # We could also pass logged_in_user if necessary
1394
        );
1394
        );
1395
    }
1395
    }
1396
1396
(-)a/C4/Auth_with_ldap.pm (-5 / +6 lines)
Lines 236-245 sub checkpw_ldap { Link Here
236
236
237
        # Send welcome email if enabled
237
        # Send welcome email if enabled
238
        if ( $config{welcome} ) {
238
        if ( $config{welcome} ) {
239
            my $emailaddr = $patron->notice_email_address;
239
            my $emailaddrs = $patron->notice_email_addresses;
240
240
241
            # if we manage to find a valid email address, send notice
241
            # if we manage to find a valid email address, send notice
242
            if ($emailaddr) {
242
            if (@$emailaddrs) {
243
                my $letter = C4::Letters::GetPreparedLetter(
243
                my $letter = C4::Letters::GetPreparedLetter(
244
                    module      => 'members',
244
                    module      => 'members',
245
                    letter_code => 'WELCOME',
245
                    letter_code => 'WELCOME',
Lines 252-267 sub checkpw_ldap { Link Here
252
                    want_librarian => 1,
252
                    want_librarian => 1,
253
                ) or return;
253
                ) or return;
254
254
255
                my $message_id = C4::Letters::EnqueueLetter(
255
                my @message_ids = C4::Letters::EnqueueLetter(
256
                    {
256
                    {
257
                        letter                 => $letter,
257
                        letter                 => $letter,
258
                        borrowernumber         => $patron->id,
258
                        borrowernumber         => $patron->id,
259
                        to_address             => $emailaddr,
260
                        message_transport_type => 'email'
259
                        message_transport_type => 'email'
261
                    }
260
                    }
262
                );
261
                );
263
262
264
                C4::Letters::SendQueuedMessages( { message_id => $message_id } );
263
                foreach my $message_id (@message_ids) {
264
                    C4::Letters::SendQueuedMessages( { message_id => $message_id } );
265
                }
265
            }
266
            }
266
        }
267
        }
267
   } else {
268
   } else {
(-)a/C4/Auth_with_shibboleth.pm (-5 / +6 lines)
Lines 144-153 sub _autocreate { Link Here
144
144
145
    # Send welcome email if enabled
145
    # Send welcome email if enabled
146
    if ( $config->{welcome} ) {
146
    if ( $config->{welcome} ) {
147
        my $emailaddr = $patron->notice_email_address;
147
        my $emailaddrs = $patron->notice_email_addresses;
148
148
149
        # if we manage to find a valid email address, send notice
149
        # if we manage to find a valid email address, send notice
150
        if ($emailaddr) {
150
        if (@$emailaddrs) {
151
            my $letter = C4::Letters::GetPreparedLetter(
151
            my $letter = C4::Letters::GetPreparedLetter(
152
                module      => 'members',
152
                module      => 'members',
153
                letter_code => 'WELCOME',
153
                letter_code => 'WELCOME',
Lines 161-175 sub _autocreate { Link Here
161
                want_librarian => 1,
161
                want_librarian => 1,
162
            ) or return;
162
            ) or return;
163
163
164
            my $message_id = C4::Letters::EnqueueLetter(
164
            my @message_ids = C4::Letters::EnqueueLetter(
165
                {
165
                {
166
                    letter                 => $letter,
166
                    letter                 => $letter,
167
                    borrowernumber         => $patron->id,
167
                    borrowernumber         => $patron->id,
168
                    to_address             => $emailaddr,
169
                    message_transport_type => 'email'
168
                    message_transport_type => 'email'
170
                }
169
                }
171
            );
170
            );
172
            C4::Letters::SendQueuedMessages( { message_id => $message_id } );
171
            foreach my $message_id (@message_ids) {
172
                C4::Letters::SendQueuedMessages( { message_id => $message_id } );
173
            }
173
        }
174
        }
174
    }
175
    }
175
    return ( 1, $patron->cardnumber, $patron->userid );
176
    return ( 1, $patron->cardnumber, $patron->userid );
(-)a/C4/Circulation.pm (-4 / +6 lines)
Lines 3654-3667 sub SendCirculationAlert { Link Here
3654
3654
3655
        C4::Context->dbh->do(q|LOCK TABLE message_queue READ|) unless $do_not_lock;
3655
        C4::Context->dbh->do(q|LOCK TABLE message_queue READ|) unless $do_not_lock;
3656
        C4::Context->dbh->do(q|LOCK TABLE message_queue WRITE|) unless $do_not_lock;
3656
        C4::Context->dbh->do(q|LOCK TABLE message_queue WRITE|) unless $do_not_lock;
3657
        my $message = C4::Message->find_last_message($borrower, $type, $mtt);
3657
        my @messages = C4::Message->find_last_messages($borrower, $type, $mtt);
3658
        unless ( $message ) {
3658
        unless ( @messages ) {
3659
            C4::Context->dbh->do(q|UNLOCK TABLES|) unless $do_not_lock;
3659
            C4::Context->dbh->do(q|UNLOCK TABLES|) unless $do_not_lock;
3660
            my $patron = Koha::Patrons->find($borrower->{borrowernumber});
3660
            my $patron = Koha::Patrons->find($borrower->{borrowernumber});
3661
            C4::Message->enqueue($letter, $patron, $mtt);
3661
            C4::Message->enqueue($letter, $patron, $mtt);
3662
        } else {
3662
        } else {
3663
            $message->append($letter);
3663
            foreach my $message (@messages) {
3664
            $message->update;
3664
                $message->append($letter);
3665
                $message->update;
3666
            }
3665
        }
3667
        }
3666
        C4::Context->dbh->do(q|UNLOCK TABLES|) unless $do_not_lock;
3668
        C4::Context->dbh->do(q|UNLOCK TABLES|) unless $do_not_lock;
3667
    }
3669
    }
(-)a/C4/Letters.pm (-57 / +83 lines)
Lines 30-36 use C4::Log qw( logaction ); Link Here
30
use C4::SMS;
30
use C4::SMS;
31
use C4::Templates;
31
use C4::Templates;
32
use Koha::SMS::Providers;
32
use Koha::SMS::Providers;
33
33
use Koha::Database;
34
use Koha::Email;
34
use Koha::Email;
35
use Koha::Notice::Messages;
35
use Koha::Notice::Messages;
36
use Koha::Notice::Templates;
36
use Koha::Notice::Templates;
Lines 880-899 sub _parseletter { Link Here
880
880
881
=head2 EnqueueLetter
881
=head2 EnqueueLetter
882
882
883
  my $success = EnqueueLetter( { letter => $letter, 
883
    my @message_ids = EnqueueLetter({
884
        borrowernumber => '12', message_transport_type => 'email' } )
884
        letter => $letter,
885
        borrowernumber => '12',
886
        message_transport_type => 'email'
887
    });
885
888
886
Places a letter in the message_queue database table, which will
889
Places a letter in the message_queue database table, which will
887
eventually get processed (sent) by the process_message_queue.pl
890
eventually get processed (sent) by the process_message_queue.pl
888
cronjob when it calls SendQueuedMessages.
891
cronjob when it calls SendQueuedMessages.
889
892
890
Return message_id on success
893
return the list of message ids
891
894
892
Parameters
895
Parameters
893
* letter - required; A letter hashref as returned from GetPreparedLetter
896
* letter - required; A letter hashref as returned from GetPreparedLetter
894
* message_transport_type - required; One of the available mtts
897
* message_transport_type - required; One of the available mtts
895
* borrowernumber - optional if 'to_address' is passed; The borrowernumber of the patron we enqueuing the notice for
898
* borrowernumber - optional if 'to_address' is passed; The borrowernumber of the patron we enqueuing the notice for
896
* to_address - optional if 'borrowernumber' is passed; The destination email address for the notice (defaults to patron->notice_email_address)
899
* to_address - optional if 'borrowernumber' is passed; The destination email address for the notice (defaults to patron->notice_email_addresses)
897
* from_address - optional; The from address for the notice, defaults to patron->library->from_email_address
900
* from_address - optional; The from address for the notice, defaults to patron->library->from_email_address
898
* reply_address - optional; The reply address for the notice, defaults to patron->library->reply_to
901
* reply_address - optional; The reply address for the notice, defaults to patron->library->reply_to
899
902
Lines 903-909 sub EnqueueLetter { Link Here
903
    my $params = shift or return;
906
    my $params = shift or return;
904
907
905
    return unless exists $params->{'letter'};
908
    return unless exists $params->{'letter'};
906
#   return unless exists $params->{'borrowernumber'};
907
    return unless exists $params->{'message_transport_type'};
909
    return unless exists $params->{'message_transport_type'};
908
910
909
    my $content = $params->{letter}->{content};
911
    my $content = $params->{letter}->{content};
Lines 922-951 sub EnqueueLetter { Link Here
922
        );
924
        );
923
    }
925
    }
924
926
925
    my $dbh       = C4::Context->dbh();
927
    my @to_addresses;
926
    my $statement = << 'ENDSQL';
928
    if ( $params->{to_address} ) {
927
INSERT INTO message_queue
929
        @to_addresses = ( $params->{to_address} );
928
( letter_id, borrowernumber, subject, content, metadata, letter_code, message_transport_type, status, time_queued, to_address, from_address, reply_address, content_type, failure_code )
930
    } elsif ( $params->{borrowernumber} and $params->{message_transport_type} eq 'email' ) {
929
VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, CAST(NOW() AS DATETIME), ?, ?, ?, ?, ? )
931
        my $patron = Koha::Patrons->find( $params->{borrowernumber} );
930
ENDSQL
932
        if ($patron) {
931
933
            @to_addresses = @{ $patron->notice_email_addresses };
932
    my $sth    = $dbh->prepare($statement);
934
        }
933
    my $result = $sth->execute(
935
    }
934
        $params->{letter}->{id} || undef,         # letter.id
936
935
        $params->{'borrowernumber'},              # borrowernumber
937
    my $from_address;
936
        $params->{'letter'}->{'title'},           # subject
938
    if ( $params->{from_address} ) {
937
        $params->{'letter'}->{'content'},         # content
939
        $from_address = $params->{from_address};
938
        $params->{'letter'}->{'metadata'} || '',  # metadata
940
    } elsif ( $params->{message_transport_type} eq 'email' ) {
939
        $params->{'letter'}->{'code'}     || '',  # letter_code
941
        if ( $params->{borrowernumber} ) {
940
        $params->{'message_transport_type'},      # message_transport_type
942
            my $rs = Koha::Database->schema->resultset('Borrower')->search( { borrowernumber => $params->{borrowernumber} }, { join => 'branchcode' } );
941
        'pending',                                # status
943
            $from_address = $rs->next->branchcode->branchemail;
942
        $params->{'to_address'},                  # to_address
944
        }
943
        $params->{'from_address'},                # from_address
945
944
        $params->{'reply_address'},               # reply_address
946
        $from_address ||= C4::Context->preference('KohaAdminEmailAddress');
945
        $params->{'letter'}->{'content-type'},    # content_type
947
    }
946
        $params->{'failure_code'}        || '',   # failure_code
948
947
    );
949
    my @message_ids;
948
    return $dbh->last_insert_id(undef,undef,'message_queue', undef);
950
951
    my $rs = Koha::Database->schema->resultset('MessageQueue');
952
    if ( $params->{message_transport_type} eq 'email' ) {
953
        for my $to_address (@to_addresses) {
954
            my $message = $rs->create(
955
                {   letter_id              => $params->{letter}->{id} || undef,
956
                    borrowernumber         => $params->{borrowernumber},
957
                    subject                => $params->{letter}->{title},
958
                    content                => $params->{letter}->{content},
959
                    metadata               => ( $params->{letter}->{metadata} || '' ),
960
                    letter_code            => ( $params->{letter}->{code}     || '' ),
961
                    message_transport_type => $params->{message_transport_type},
962
                    status                 => 'pending',
963
                    time_queued            => \'NOW()',
964
                    to_address             => $to_address,
965
                    from_address           => $from_address,
966
                    reply_address          => $params->{reply_address},
967
                    content_type           => $params->{letter}->{'content-type'},
968
                    failure_code           => $params->{failure_code} || '',
969
                }
970
            );
971
            push @message_ids, $message->id();
972
        }
973
    } else {
974
        my $message = $rs->create(
975
            {   letter_id              => $params->{letter}->{id} || undef,
976
                borrowernumber         => $params->{borrowernumber},
977
                subject                => $params->{letter}{title},
978
                content                => $params->{letter}{content},
979
                metadata               => ( $params->{letter}{metadata} || '' ),
980
                letter_code            => ( $params->{letter}{code}     || '' ),
981
                message_transport_type => $params->{message_transport_type},
982
                status                 => 'pending',
983
                time_queued            => \'NOW()',
984
                from_address           => $from_address,
985
                reply_address          => $params->{reply_address},
986
                content_type           => $params->{letter}{'content-type'},
987
                failure_code           => $params->{failure_code} || '',
988
            }
989
        );
990
        push @message_ids, $message->id();
991
    }
992
993
    return @message_ids;
949
}
994
}
950
995
951
=head2 SendQueuedMessages ([$hashref]) 
996
=head2 SendQueuedMessages ([$hashref]) 
Lines 1085-1115 Return is an arrayref of hashes, each has represents a message in the message qu Link Here
1085
sub GetQueuedMessages {
1130
sub GetQueuedMessages {
1086
    my $params = shift;
1131
    my $params = shift;
1087
1132
1088
    my $dbh = C4::Context->dbh();
1133
    my ( %cond, %attrs );
1089
    my $statement = << 'ENDSQL';
1090
SELECT message_id, borrowernumber, subject, content, message_transport_type, status, time_queued, updated_on, failure_code
1091
FROM message_queue
1092
ENDSQL
1093
1094
    my @query_params;
1095
    my @whereclauses;
1096
    if ( exists $params->{'borrowernumber'} ) {
1097
        push @whereclauses, ' borrowernumber = ? ';
1098
        push @query_params, $params->{'borrowernumber'};
1099
    }
1100
1134
1101
    if ( @whereclauses ) {
1135
    $cond{borrowernumber} = $params->{borrowernumber} if $params->{borrowernumber};
1102
        $statement .= ' WHERE ' . join( 'AND', @whereclauses );
1103
    }
1104
1136
1105
    if ( defined $params->{'limit'} ) {
1137
    $attrs{rows} = $params->{limit} if $params->{limit};
1106
        $statement .= ' LIMIT ? ';
1107
        push @query_params, $params->{'limit'};
1108
    }
1109
1138
1110
    my $sth = $dbh->prepare( $statement );
1139
    my $rs = Koha::Database->schema->resultset('MessageQueue')->search( \%cond, \%attrs );
1111
    my $result = $sth->execute( @query_params );
1140
    $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
1112
    return $sth->fetchall_arrayref({});
1141
    return [ $rs->all ];
1113
}
1142
}
1114
1143
1115
=head2 GetMessageTransportTypes
1144
=head2 GetMessageTransportTypes
Lines 1173-1181 sub ResendMessage { Link Here
1173
            status => 'pending',
1202
            status => 'pending',
1174
        });
1203
        });
1175
        $rv = $rv > 0? 1: 0;
1204
        $rv = $rv > 0? 1: 0;
1176
        # Clear destination email address to force address update
1177
        _update_message_to_address( $message_id, undef ) if $rv &&
1178
            $message->{message_transport_type} eq 'email';
1179
    }
1205
    }
1180
    return $rv;
1206
    return $rv;
1181
}
1207
}
Lines 1317-1324 sub _send_message_by_email { Link Here
1317
            );
1343
            );
1318
            return;
1344
            return;
1319
        }
1345
        }
1320
        $to_address = $patron->notice_email_address;
1346
        my $to_addresses = $patron->notice_email_addresses;
1321
        unless ($to_address) {  
1347
        unless (@$to_addresses) {
1322
            # warn "FAIL: No 'to_address' and no email for " . ($member->{surname} ||'') . ", borrowernumber ($message->{borrowernumber})";
1348
            # warn "FAIL: No 'to_address' and no email for " . ($member->{surname} ||'') . ", borrowernumber ($message->{borrowernumber})";
1323
            # warning too verbose for this more common case?
1349
            # warning too verbose for this more common case?
1324
            _set_message_status(
1350
            _set_message_status(
(-)a/C4/Message.pm (-35 / +8 lines)
Lines 54-60 How to update a borrower's last checkout message: Link Here
54
54
55
  use C4::Message;
55
  use C4::Message;
56
  my $borrower = { borrowernumber => 1 };
56
  my $borrower = { borrowernumber => 1 };
57
  my $message  = C4::Message->find_last_message($borrower, 'CHECKOUT', 'email');
57
  my $message  = C4::Message->find_last_messages($borrower, 'CHECKOUT', 'email');
58
  $message->append("you also checked out some other book....");
58
  $message->append("you also checked out some other book....");
59
  $message->update;
59
  $message->update;
60
60
Lines 111-127 sub find { Link Here
111
    }
111
    }
112
}
112
}
113
113
114
=head3 C4::Message->find_last_message($borrower, $letter_code, $transport)
114
=head3 C4::Message->find_last_messages($borrower, $letter_code, $transport)
115
115
116
This method is used to get the borrower's most recent, pending, check-in or
116
This method is used to get the borrower's most recent, pending, check-in or
117
checkout message.  (This makes it possible to add more information to the
117
checkout messages.  (This makes it possible to add more information to the
118
message before it gets sent out.)
118
message before it gets sent out.)
119
119
120
=cut
120
=cut
121
121
122
# C4::Message->find_last_message($borrower, $letter_code, $transport)
122
# C4::Message->find_last_messages($borrower, $letter_code, $transport)
123
# -- get the borrower's most recent pending checkin or checkout notification
123
# -- get the borrower's most recent pending checkin or checkout notifications
124
sub find_last_message {
124
sub find_last_messages {
125
    my ($class, $borrower, $letter_code, $transport) = @_;
125
    my ($class, $borrower, $letter_code, $transport) = @_;
126
    # $type is the message_transport_type
126
    # $type is the message_transport_type
127
    $transport ||= 'email';
127
    $transport ||= 'email';
Lines 140-150 sub find_last_message { Link Here
140
        $letter_code,
140
        $letter_code,
141
        $transport,
141
        $transport,
142
    );
142
    );
143
    if (@$msgs) {
143
144
        return $class->new($msgs->[0]);
144
    return map { $class->new($_) } @$msgs;
145
    } else {
146
        return;
147
    }
148
}
145
}
149
146
150
147
Lines 159-165 the message. Link Here
159
sub enqueue {
156
sub enqueue {
160
    my ( $class, $letter, $patron, $transport ) = @_;
157
    my ( $class, $letter, $patron, $transport ) = @_;
161
    my $metadata   = _metadata($letter);
158
    my $metadata   = _metadata($letter);
162
    my $to_address = _to_address( $patron, $transport );
163
159
164
    # Same as render_metadata
160
    # Same as render_metadata
165
    my $format ||= sub { $_[0] || "" };
161
    my $format ||= sub { $_[0] || "" };
Lines 172-204 sub enqueue { Link Here
172
            letter                 => $letter,
168
            letter                 => $letter,
173
            borrowernumber         => $patron->id,
169
            borrowernumber         => $patron->id,
174
            message_transport_type => $transport,
170
            message_transport_type => $transport,
175
            to_address             => $to_address,
176
        }
171
        }
177
    );
172
    );
178
}
173
}
179
174
180
# based on message $transport, pick an appropriate address to send to
181
sub _to_address {
182
    my ( $patron, $transport ) = @_;
183
    my $address;
184
    if ( $transport eq 'email' ) {
185
        $address = $patron->notice_email_address;
186
    }
187
    elsif ( $transport eq 'sms' ) {
188
        $address = $patron->smsalertnumber;
189
    }
190
    else {
191
        warn "'$transport' is an unknown message transport.";
192
    }
193
    if ( not defined $address ) {
194
        warn "An appropriate $transport address "
195
          . "for borrower "
196
          . $patron->userid
197
          . "could not be found.";
198
    }
199
    return $address;
200
}
201
202
# _metadata($letter) -- return the letter split into head/body/footer
175
# _metadata($letter) -- return the letter split into head/body/footer
203
sub _metadata {
176
sub _metadata {
204
    my ($letter) = @_;
177
    my ($letter) = @_;
(-)a/C4/Reserves.pm (-6 / +7 lines)
Lines 791-802 SELECT COUNT(*) FROM reserves WHERE biblionumber=? AND borrowernumber<>? Link Here
791
Takes an itemnumber and returns the status of the reserve placed on it.
791
Takes an itemnumber and returns the status of the reserve placed on it.
792
If several reserves exist, the reserve with the lower priority is given.
792
If several reserves exist, the reserve with the lower priority is given.
793
793
794
=cut
795
796
## FIXME: I don't think this does what it thinks it does.
794
## FIXME: I don't think this does what it thinks it does.
797
## It only ever checks the first reserve result, even though
795
## It only ever checks the first reserve result, even though
798
## multiple reserves for that bib can have the itemnumber set
796
## multiple reserves for that bib can have the itemnumber set
799
## the sub is only used once in the codebase.
797
## the sub is only used once in the codebase.
798
799
=cut
800
800
sub GetReserveStatus {
801
sub GetReserveStatus {
801
    my ($itemnumber) = @_;
802
    my ($itemnumber) = @_;
802
803
Lines 1879-1887 sub _koha_notify_reserve { Link Here
1879
1880
1880
    my $patron = Koha::Patrons->find( $borrowernumber );
1881
    my $patron = Koha::Patrons->find( $borrowernumber );
1881
1882
1882
    # Try to get the borrower's email address
1883
    my $to_address = $patron->notice_email_address;
1884
1885
    my $messagingprefs = C4::Members::Messaging::GetMessagingPreferences( {
1883
    my $messagingprefs = C4::Members::Messaging::GetMessagingPreferences( {
1886
            borrowernumber => $borrowernumber,
1884
            borrowernumber => $borrowernumber,
1887
            message_name => 'Hold_Filled'
1885
            message_name => 'Hold_Filled'
Lines 1924-1932 sub _koha_notify_reserve { Link Here
1924
        } );
1922
        } );
1925
    };
1923
    };
1926
1924
1925
    # Try to get the borrower's email addresses
1926
    my $to_addresses = $patron->notice_email_addresses;
1927
1927
    while ( my ( $mtt, $letter_code ) = each %{ $messagingprefs->{transports} } ) {
1928
    while ( my ( $mtt, $letter_code ) = each %{ $messagingprefs->{transports} } ) {
1928
        next if (
1929
        next if (
1929
               ( $mtt eq 'email' and not $to_address ) # No email address
1930
               ( $mtt eq 'email' and not @$to_addresses ) # No email address
1930
            or ( $mtt eq 'sms'   and not $patron->smsalertnumber ) # No SMS number
1931
            or ( $mtt eq 'sms'   and not $patron->smsalertnumber ) # No SMS number
1931
            or ( $mtt eq 'itiva' and C4::Context->preference('TalkingTechItivaPhoneNotification') ) # Notice is handled by TalkingTech_itiva_outbound.pl
1932
            or ( $mtt eq 'itiva' and C4::Context->preference('TalkingTechItivaPhoneNotification') ) # Notice is handled by TalkingTech_itiva_outbound.pl
1932
            or ( $mtt eq 'phone' and not $patron->phone ) # No phone number to call
1933
            or ( $mtt eq 'phone' and not $patron->phone ) # No phone number to call
(-)a/Koha/Patron.pm (-18 / +26 lines)
Lines 894-903 sub set_password { Link Here
894
    if ( C4::Context->preference('NotifyPasswordChange') ) {
894
    if ( C4::Context->preference('NotifyPasswordChange') ) {
895
        my $self_from_storage = $self->get_from_storage;
895
        my $self_from_storage = $self->get_from_storage;
896
        if ( !C4::Auth::checkpw_hash( $password, $self_from_storage->password ) ) {
896
        if ( !C4::Auth::checkpw_hash( $password, $self_from_storage->password ) ) {
897
            my $emailaddr = $self_from_storage->notice_email_address;
897
            my $emailaddrs = $self_from_storage->notice_email_addresses;
898
898
899
            # if we manage to find a valid email address, send notice
899
            # if we manage to find a valid email address, send notice
900
            if ($emailaddr) {
900
            if (@$emailaddrs) {
901
                my $letter = C4::Letters::GetPreparedLetter(
901
                my $letter = C4::Letters::GetPreparedLetter(
902
                    module      => 'members',
902
                    module      => 'members',
903
                    letter_code => 'PASSWORD_CHANGE',
903
                    letter_code => 'PASSWORD_CHANGE',
Lines 911-925 sub set_password { Link Here
911
                    want_librarian => 1,
911
                    want_librarian => 1,
912
                ) or return;
912
                ) or return;
913
913
914
                my $message_id = C4::Letters::EnqueueLetter(
914
                my @message_ids = C4::Letters::EnqueueLetter(
915
                    {
915
                    {
916
                        letter                 => $letter,
916
                        letter                 => $letter,
917
                        borrowernumber         => $self_from_storage->id,
917
                        borrowernumber         => $self_from_storage->id,
918
                        to_address             => $emailaddr,
919
                        message_transport_type => 'email'
918
                        message_transport_type => 'email'
920
                    }
919
                    }
921
                );
920
                );
922
                C4::Letters::SendQueuedMessages( { message_id => $message_id } );
921
                foreach my $message_id (@message_ids) {
922
                    C4::Letters::SendQueuedMessages( { message_id => $message_id } );
923
                }
923
            }
924
            }
924
        }
925
        }
925
    }
926
    }
Lines 1388-1412 sub return_claims { Link Here
1388
    return Koha::Checkouts::ReturnClaims->_new_from_dbic( $return_claims );
1389
    return Koha::Checkouts::ReturnClaims->_new_from_dbic( $return_claims );
1389
}
1390
}
1390
1391
1391
=head3 notice_email_address
1392
=head3 notice_email_addresses
1392
1393
1393
  my $email = $patron->notice_email_address;
1394
  my $emails = $patron->notice_email_addresses;
1394
1395
1395
Return the email address of patron used for notices.
1396
Return an arrayref containing the email addresses of patron used for notices.
1396
Returns the empty string if no email address.
1397
1397
1398
=cut
1398
=cut
1399
1399
1400
sub notice_email_address{
1400
sub notice_email_addresses {
1401
    my ( $self ) = @_;
1401
    my ( $self ) = @_;
1402
1402
1403
    my $which_address = C4::Context->preference("AutoEmailPrimaryAddress");
1403
    my $which_addresses = C4::Context->preference("AutoEmailPrimaryAddress");
1404
    # if syspref is set to 'first valid' (value == OFF), look up email address
1404
    my @email_addresses;
1405
    if ( $which_address eq 'OFF' ) {
1405
    for my $email_address_field (split /,/, $which_addresses) {
1406
        return $self->first_valid_email_address;
1406
        # if syspref is set to 'first valid' (value == OFF), look up email address
1407
        if ( $email_address_field eq 'OFF' ) {
1408
            return [ $self->first_valid_email_address ];
1409
        }
1410
1411
        my $email_address = $self->$email_address_field;
1412
        push @email_addresses, $email_address if $email_address;
1407
    }
1413
    }
1408
1414
1409
    return $self->$which_address || '';
1415
    return \@email_addresses;
1410
}
1416
}
1411
1417
1412
=head3 first_valid_email_address
1418
=head3 first_valid_email_address
Lines 2191-2197 sub queue_notice { Link Here
2191
    foreach my $mtt (@message_transports){
2197
    foreach my $mtt (@message_transports){
2192
        next if ($mtt eq 'itiva' and C4::Context->preference('TalkingTechItivaPhoneNotification') );
2198
        next if ($mtt eq 'itiva' and C4::Context->preference('TalkingTechItivaPhoneNotification') );
2193
        # Notice is handled by TalkingTech_itiva_outbound.pl
2199
        # Notice is handled by TalkingTech_itiva_outbound.pl
2194
        if (   ( $mtt eq 'email' and not $self->notice_email_address )
2200
        my $email_addresses = $self->notice_email_addresses;
2201
        if (   ( $mtt eq 'email' and not @$email_addresses )
2195
            or ( $mtt eq 'sms'   and not $self->smsalertnumber )
2202
            or ( $mtt eq 'sms'   and not $self->smsalertnumber )
2196
            or ( $mtt eq 'phone' and not $self->phone ) )
2203
            or ( $mtt eq 'phone' and not $self->phone ) )
2197
        {
2204
        {
Lines 2330-2346 sub notify_library_of_registration { Link Here
2330
                || C4::Context->preference('KohaAdminEmailAddress');
2337
                || C4::Context->preference('KohaAdminEmailAddress');
2331
        }
2338
        }
2332
2339
2333
        my $message_id = C4::Letters::EnqueueLetter(
2340
        my ($message_id) = C4::Letters::EnqueueLetter(
2334
            {
2341
            {
2335
                letter                 => $letter,
2342
                letter                 => $letter,
2336
                borrowernumber         => $self->borrowernumber,
2343
                borrowernumber         => $self->borrowernumber,
2337
                to_address             => $to_address,
2344
                to_address             => $to_address,
2338
                message_transport_type => 'email'
2345
                message_transport_type => 'email'
2339
            }
2346
            }
2340
        ) or warn "can't enqueue letter $letter";
2347
        );
2341
        if ( $message_id ) {
2348
        if ( $message_id ) {
2342
            return 1;
2349
            return 1;
2343
        }
2350
        }
2351
        warn "can't enqueue letter $letter";
2344
    }
2352
    }
2345
}
2353
}
2346
2354
(-)a/Koha/Patron/Password/Recovery.pm (-3 / +6 lines)
Lines 148-154 sub SendPasswordRecoveryEmail { Link Here
148
    my $library = $borrower->library;
148
    my $library = $borrower->library;
149
    my $kohaEmail = $library->from_email_address; # send from patron's branch or Koha Admin
149
    my $kohaEmail = $library->from_email_address; # send from patron's branch or Koha Admin
150
150
151
    my $message_id = C4::Letters::EnqueueLetter(
151
    my @message_ids = C4::Letters::EnqueueLetter(
152
        {
152
        {
153
            letter                 => $letter,
153
            letter                 => $letter,
154
            borrowernumber         => $borrower->borrowernumber,
154
            borrowernumber         => $borrower->borrowernumber,
Lines 158-165 sub SendPasswordRecoveryEmail { Link Here
158
        }
158
        }
159
    );
159
    );
160
160
161
    my $num_letters_attempted =
161
    my $num_letters_attempted = 0;
162
      C4::Letters::SendQueuedMessages( { message_id => $message_id } );
162
    foreach my $message_id (@message_ids) {
163
        $num_letters_attempted +=
164
          C4::Letters::SendQueuedMessages( { message_id => $message_id } );
165
    }
163
166
164
    return ($num_letters_attempted > 0);
167
    return ($num_letters_attempted > 0);
165
}
168
}
(-)a/Koha/Patrons/Import.pm (-5 / +4 lines)
Lines 448-457 sub import_patrons { Link Here
448
448
449
        # Send WELCOME welcome email is the user is new and we're set to send mail
449
        # Send WELCOME welcome email is the user is new and we're set to send mail
450
        if ($send_welcome && $is_new) {
450
        if ($send_welcome && $is_new) {
451
            my $emailaddr = $patron->notice_email_address;
451
            my $emailaddrs = $patron->notice_email_addresses;
452
452
453
            # if we manage to find a valid email address, send notice
453
            # if we manage to find a valid email address, send notice
454
            if ($emailaddr) {
454
            if (@$emailaddrs) {
455
                eval {
455
                eval {
456
                    my $letter = GetPreparedLetter(
456
                    my $letter = GetPreparedLetter(
457
                        module      => 'members',
457
                        module      => 'members',
Lines 465-475 sub import_patrons { Link Here
465
                        want_librarian => 1,
465
                        want_librarian => 1,
466
                    ) or return;
466
                    ) or return;
467
467
468
                    my $message_id = EnqueueLetter(
468
                    EnqueueLetter(
469
                        {
469
                        {
470
                            letter                 => $letter,
470
                            letter                 => $letter,
471
                            borrowernumber         => $patron->id,
471
                            borrowernumber         => $patron->id,
472
                            to_address             => $emailaddr,
473
                            message_transport_type => 'email'
472
                            message_transport_type => 'email'
474
                        }
473
                        }
475
                    );
474
                    );
Lines 482-488 sub import_patrons { Link Here
482
                        {
481
                        {
483
                            feedback     => 1,
482
                            feedback     => 1,
484
                            name         => 'welcome_sent',
483
                            name         => 'welcome_sent',
485
                            value        => $borrower{'surname'} . ' / ' . $borrowernumber . ' / ' . $emailaddr
484
                            value        => $borrower{'surname'} . ' / ' . $borrowernumber . ' / ' . join(', ', @$emailaddrs)
486
                        }
485
                        }
487
                    );
486
                    );
488
                }
487
                }
(-)a/Koha/REST/V1/TwoFactorAuth.pm (-9 / +11 lines)
Lines 55-76 sub send_otp_token { Link Here
55
                borrowers => $patron->unblessed,
55
                borrowers => $patron->unblessed,
56
            }
56
            }
57
        );
57
        );
58
        my $message_id = C4::Letters::EnqueueLetter(
58
        my @message_ids = C4::Letters::EnqueueLetter(
59
            {
59
            {
60
                letter                 => $letter,
60
                letter                 => $letter,
61
                borrowernumber         => $patron->borrowernumber,
61
                borrowernumber         => $patron->borrowernumber,
62
                message_transport_type => 'email'
62
                message_transport_type => 'email'
63
            }
63
            }
64
        );
64
        );
65
        C4::Letters::SendQueuedMessages({message_id => $message_id});
65
        foreach my $message_id (@message_ids) {
66
            C4::Letters::SendQueuedMessages( { message_id => $message_id } );
66
67
67
        my $message = C4::Letters::GetMessage($message_id);
68
            my $message = C4::Letters::GetMessage($message_id);
68
69
            if ( $message->{status} ne 'sent' ) {
69
        if ( $message->{status} eq 'sent' ) {
70
                return $c->render( status => 400, openapi => { error => 'email_not_sent' } );
70
            return $c->render(status => 200, openapi => {});
71
            }
71
        } elsif ( $message->{status} eq 'failed' ) {
72
            return $c->render(status => 400, openapi => { error => 'email_not_sent'});
73
        }
72
        }
73
74
        return $c->render( status => 200, openapi => {} );
75
74
    }
76
    }
75
    catch {
77
    catch {
76
        $c->unhandled_exception($_);
78
        $c->unhandled_exception($_);
Lines 155-161 sub verification { Link Here
155
        # FIXME Generate a (new?) secret
157
        # FIXME Generate a (new?) secret
156
        $patron->encode_secret($secret32);
158
        $patron->encode_secret($secret32);
157
        $patron->auth_method('two-factor')->store;
159
        $patron->auth_method('two-factor')->store;
158
        if ( $patron->notice_email_address ) {
160
        if ( @{ $patron->notice_email_addresses } ) {
159
            $patron->queue_notice(
161
            $patron->queue_notice(
160
                {
162
                {
161
                    letter_params => {
163
                    letter_params => {
(-)a/Koha/Ticket.pm (-7 / +12 lines)
Lines 124-138 sub store { Link Here
124
        );
124
        );
125
125
126
        if ($acknowledgement_letter) {
126
        if ($acknowledgement_letter) {
127
            my $acknowledgement_message_id = C4::Letters::EnqueueLetter(
127
            my @acknowledgement_message_ids = C4::Letters::EnqueueLetter(
128
                {
128
                {
129
                    letter                 => $acknowledgement_letter,
129
                    letter                 => $acknowledgement_letter,
130
                    message_transport_type => 'email',
130
                    message_transport_type => 'email',
131
                    borrowernumber         => $self->reporter_id,
131
                    borrowernumber         => $self->reporter_id,
132
                }
132
                }
133
            );
133
            );
134
            C4::Letters::SendQueuedMessages(
134
            foreach my $acknowledgement_message_id (@acknowledgement_message_ids) {
135
                { message_id => $acknowledgement_message_id } );
135
                C4::Letters::SendQueuedMessages(
136
                    { message_id => $acknowledgement_message_id } );
137
            }
136
        }
138
        }
137
139
138
        # Notify cataloger by email
140
        # Notify cataloger by email
Lines 147-163 sub store { Link Here
147
            );
149
            );
148
150
149
            if ($notify_letter) {
151
            if ($notify_letter) {
150
                my $message_id = C4::Letters::EnqueueLetter(
152
                my ($reporter_first_notice_email_address) = $self->reporter->notice_email_addresses;
153
                my @message_ids = C4::Letters::EnqueueLetter(
151
                    {
154
                    {
152
                        letter                 => $notify_letter,
155
                        letter                 => $notify_letter,
153
                        message_transport_type => 'email',
156
                        message_transport_type => 'email',
154
                        to_address             =>
157
                        to_address             =>
155
                          C4::Context->preference('CatalogerEmails'),
158
                          C4::Context->preference('CatalogerEmails'),
156
                        reply_address => $self->reporter->notice_email_address,
159
                        reply_address => $reporter_first_notice_email_address,
157
                    }
160
                    }
158
                );
161
                );
159
                C4::Letters::SendQueuedMessages(
162
                foreach my $message_id (@message_ids) {
160
                    { message_id => $message_id } );
163
                    C4::Letters::SendQueuedMessages(
164
                        { message_id => $message_id } );
165
                }
161
            }
166
            }
162
        }
167
        }
163
    }
168
    }
(-)a/circ/pendingreserves.pl (-1 / +1 lines)
Lines 93-99 if ( $op eq 'cancel_reserve' and $reserve_id ) { Link Here
93
                        from_address           => $from_address,
93
                        from_address           => $from_address,
94
                    }
94
                    }
95
                );
95
                );
96
                unless ( $patron->notice_email_address ) {
96
                unless ( @{ $patron->notice_email_addresses } ) {
97
                    push @messages, {type => 'alert', code => 'no_email_address', };
97
                    push @messages, {type => 'alert', code => 'no_email_address', };
98
                }
98
                }
99
                push @messages, { type => 'message', code => 'letter_enqueued' };
99
                push @messages, { type => 'message', code => 'letter_enqueued' };
(-)a/installer/data/mysql/atomicupdate/bug-12802.pl (+12 lines)
Line 0 Link Here
1
use Modern::Perl;
2
3
return {
4
    bug_number  => '12802',
5
    description => 'Change type of system preference AutoEmailPrimaryAddress to multiple',
6
    up          => sub {
7
        my ($args) = @_;
8
        my ( $dbh, $out ) = @$args{qw(dbh out)};
9
10
        $dbh->do("UPDATE systempreferences SET type='multiple' WHERE variable='AutoEmailPrimaryAddress'");
11
    },
12
};
(-)a/installer/data/mysql/mandatory/sysprefs.sql (-1 / +1 lines)
Lines 80-86 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
80
('AutoCreateAuthorities','0',NULL,'Automatically create authorities that do not exist when cataloging records.','YesNo'),
80
('AutoCreateAuthorities','0',NULL,'Automatically create authorities that do not exist when cataloging records.','YesNo'),
81
('AutoCreditNumber', '', '', 'Automatically generate a number for account credits', 'Choice'),
81
('AutoCreditNumber', '', '', 'Automatically generate a number for account credits', 'Choice'),
82
('AutoEmailNewUser','0',NULL,'Send an email to newly created patrons.','YesNo'),
82
('AutoEmailNewUser','0',NULL,'Send an email to newly created patrons.','YesNo'),
83
('AutoEmailPrimaryAddress','OFF','email|emailpro|B_email|cardnumber|OFF','Defines the default email address where \'Account Details\' emails are sent.','Choice'),
83
('AutoEmailPrimaryAddress','OFF','email|emailpro|B_email|cardnumber|OFF','Defines the default email address where \'Account Details\' emails are sent.','multiple'),
84
('AutoShareWithMana','subscription','','defines datas automatically shared with mana','multiple'),
84
('AutoShareWithMana','subscription','','defines datas automatically shared with mana','multiple'),
85
('AutoLocation','0',NULL,'If ON, IP authentication is enabled, blocking access to the staff interface from unauthorized IP addresses','YesNo'),
85
('AutoLocation','0',NULL,'If ON, IP authentication is enabled, blocking access to the staff interface from unauthorized IP addresses','YesNo'),
86
('AutomaticItemReturn','1',NULL,'If ON, Koha will automatically set up a transfer of this item to its homebranch','YesNo'),
86
('AutomaticItemReturn','1',NULL,'If ON, Koha will automatically set up a transfer of this item to its homebranch','YesNo'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref (-1 / +1 lines)
Lines 176-182 Patrons: Link Here
176
         - "Use"
176
         - "Use"
177
         - pref: AutoEmailPrimaryAddress
177
         - pref: AutoEmailPrimaryAddress
178
           default: "OFF"
178
           default: "OFF"
179
           choices:
179
           multiple:
180
               email: home
180
               email: home
181
               emailpro: work
181
               emailpro: work
182
               B_email: alternate
182
               B_email: alternate
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/auth.tt (-1 / +1 lines)
Lines 226-232 Link Here
226
226
227
            $("#send_otp").on("click", function(e){
227
            $("#send_otp").on("click", function(e){
228
                e.preventDefault();
228
                e.preventDefault();
229
                [% UNLESS notice_email_address %]
229
                [% UNLESS notice_email_addresses.size > 0 %]
230
                    alert("Cannot send the notice, you don't have an email address defined.")
230
                    alert("Cannot send the notice, you don't have an email address defined.")
231
                [% ELSE %]
231
                [% ELSE %]
232
                $("#email_success").hide();
232
                $("#email_success").hide();
(-)a/members/memberentry.pl (-5 / +6 lines)
Lines 426-434 if ((!$nok) and $nodouble and ($op eq 'insert' or $op eq 'save')){ Link Here
426
        # If 'AutoEmailNewUser' syspref is on, email user their account details from the 'notice' that matches the user's branchcode.
426
        # If 'AutoEmailNewUser' syspref is on, email user their account details from the 'notice' that matches the user's branchcode.
427
        if ( $patron && C4::Context->preference("AutoEmailNewUser") ) {
427
        if ( $patron && C4::Context->preference("AutoEmailNewUser") ) {
428
            #look for defined primary email address, if blank - attempt to use borr.email and borr.emailpro instead
428
            #look for defined primary email address, if blank - attempt to use borr.email and borr.emailpro instead
429
            my $emailaddr = $patron->notice_email_address;
429
            my $emailaddrs = $patron->notice_email_addresses;
430
            # if we manage to find a valid email address, send notice 
430
            # if we manage to find a valid email address, send notice 
431
            if ($emailaddr) {
431
            if (@$emailaddrs) {
432
                eval {
432
                eval {
433
                    my $letter = GetPreparedLetter(
433
                    my $letter = GetPreparedLetter(
434
                        module      => 'members',
434
                        module      => 'members',
Lines 442-456 if ((!$nok) and $nodouble and ($op eq 'insert' or $op eq 'save')){ Link Here
442
                        want_librarian => 1,
442
                        want_librarian => 1,
443
                    ) or return;
443
                    ) or return;
444
444
445
                    my $message_id = EnqueueLetter(
445
                    my @message_ids = EnqueueLetter(
446
                        {
446
                        {
447
                            letter                 => $letter,
447
                            letter                 => $letter,
448
                            borrowernumber         => $patron->id,
448
                            borrowernumber         => $patron->id,
449
                            to_address             => $emailaddr,
450
                            message_transport_type => 'email'
449
                            message_transport_type => 'email'
451
                        }
450
                        }
452
                    );
451
                    );
453
                    SendQueuedMessages({ message_id => $message_id });
452
                    foreach my $message_id (@message_ids) {
453
                        SendQueuedMessages({ message_id => $message_id });
454
                    }
454
                };
455
                };
455
                if ($@) {
456
                if ($@) {
456
                    $template->param( error_alert => $@ );
457
                    $template->param( error_alert => $@ );
(-)a/members/notices.pl (-7 / +6 lines)
Lines 62-71 if ( $op eq 'resend_notice' ) { Link Here
62
}
62
}
63
63
64
if ( $op eq 'send_welcome' ) {
64
if ( $op eq 'send_welcome' ) {
65
    my $emailaddr = $patron->notice_email_address;
65
    my $emailaddrs = $patron->notice_email_addresses;
66
66
67
    # if we manage to find a valid email address, send notice
67
    # if we manage to find a valid email address, send notice
68
    if ($emailaddr) {
68
    if (@$emailaddrs) {
69
        eval {
69
        eval {
70
            my $letter = GetPreparedLetter(
70
            my $letter = GetPreparedLetter(
71
                module      => 'members',
71
                module      => 'members',
Lines 79-89 if ( $op eq 'send_welcome' ) { Link Here
79
                want_librarian => 1,
79
                want_librarian => 1,
80
            ) or return;
80
            ) or return;
81
81
82
            my $message_id = EnqueueLetter(
82
            EnqueueLetter(
83
                {
83
                {
84
                    letter                 => $letter,
84
                    letter                 => $letter,
85
                    borrowernumber         => $patron->id,
85
                    borrowernumber         => $patron->id,
86
                    to_address             => $emailaddr,
87
                    message_transport_type => 'email'
86
                    message_transport_type => 'email'
88
                }
87
                }
89
            );
88
            );
Lines 96-107 if ( $op eq 'send_welcome' ) { Link Here
96
95
97
if ( $op eq 'send_password_reset' ) {
96
if ( $op eq 'send_password_reset' ) {
98
97
99
    my $emailaddr = $patron->notice_email_address;
98
    my $emailaddrs = $patron->notice_email_addresses;
100
99
101
    if ($emailaddr) {
100
    if (@$emailaddrs) {
102
101
103
        # send staff initiated password recovery
102
        # send staff initiated password recovery
104
        SendPasswordRecoveryEmail( $patron, $emailaddr, 1 );
103
        SendPasswordRecoveryEmail( $patron, undef, 1 );
105
    }
104
    }
106
105
107
    # redirect to self to avoid form submission on refresh
106
    # redirect to self to avoid form submission on refresh
(-)a/members/two_factor_auth.pl (-1 / +1 lines)
Lines 63-69 else { Link Here
63
          Koha::Auth::TwoFactorAuth->new( { patron => $logged_in_user } );
63
          Koha::Auth::TwoFactorAuth->new( { patron => $logged_in_user } );
64
        $logged_in_user->secret(undef);
64
        $logged_in_user->secret(undef);
65
        $logged_in_user->auth_method('password')->store;
65
        $logged_in_user->auth_method('password')->store;
66
        if ( $logged_in_user->notice_email_address ) {
66
        if ( @{ $logged_in_user->notice_email_addresses } ) {
67
            $logged_in_user->queue_notice(
67
            $logged_in_user->queue_notice(
68
                {
68
                {
69
                    letter_params => {
69
                    letter_params => {
(-)a/misc/cronjobs/notice_unprocessed_suggestions.pl (-2 / +2 lines)
Lines 47-55 for my $number_of_days (@days) { Link Here
47
47
48
        my $budget = C4::Budgets::GetBudget( $suggestion->{budgetid} );
48
        my $budget = C4::Budgets::GetBudget( $suggestion->{budgetid} );
49
        my $patron = Koha::Patrons->find( $budget->{budget_owner_id} );
49
        my $patron = Koha::Patrons->find( $budget->{budget_owner_id} );
50
        my $email_address = $patron->notice_email_address;
50
        my $email_addresses = $patron->notice_email_addresses;
51
51
52
        if ($email_address) {
52
        if (@$email_addresses) {
53
            say "Patron " . $patron->borrowernumber . " is going to be notified" if $verbose;
53
            say "Patron " . $patron->borrowernumber . " is going to be notified" if $verbose;
54
            my $letter = C4::Letters::GetPreparedLetter(
54
            my $letter = C4::Letters::GetPreparedLetter(
55
                module      => 'suggestions',
55
                module      => 'suggestions',
(-)a/misc/cronjobs/overdue_notices.pl (-4 / +4 lines)
Lines 604-610 END_SQL Link Here
604
604
605
                my $patron = Koha::Patrons->find( $borrowernumber );
605
                my $patron = Koha::Patrons->find( $borrowernumber );
606
                @emails_to_use = ();
606
                @emails_to_use = ();
607
                my $notice_email = $patron->notice_email_address;
608
                unless ($nomail) {
607
                unless ($nomail) {
609
                    if (@emails) {
608
                    if (@emails) {
610
                        foreach (@emails) {
609
                        foreach (@emails) {
Lines 612-618 END_SQL Link Here
612
                        }
611
                        }
613
                    }
612
                    }
614
                    else {
613
                    else {
615
                        push @emails_to_use, $notice_email if ($notice_email);
614
                        my $notice_emails = $patron->notice_email_addresses;
615
                        push @emails_to_use, @$notice_emails;
616
                    }
616
                    }
617
                }
617
                }
618
618
Lines 770-776 END_SQL Link Here
770
                              letternumber   => $i,
770
                              letternumber   => $i,
771
                              postcode       => $data->{'zipcode'},
771
                              postcode       => $data->{'zipcode'},
772
                              country        => $data->{'country'},
772
                              country        => $data->{'country'},
773
                              email          => $notice_email,
773
                              email          => ( scalar( @emails_to_use ) ? $emails_to_use[0] : undef ),
774
                              itemcount      => $itemcount,
774
                              itemcount      => $itemcount,
775
                              titles         => $titles,
775
                              titles         => $titles,
776
                              outputformat   => defined $csvfilename ? 'csv' : defined $htmlfilename ? 'html' : defined $text_filename ? 'text' : '',
776
                              outputformat   => defined $csvfilename ? 'csv' : defined $htmlfilename ? 'html' : defined $text_filename ? 'text' : '',
Lines 789-795 END_SQL Link Here
789
                                  city           => $data->{'city'},
789
                                  city           => $data->{'city'},
790
                                  postcode       => $data->{'zipcode'},
790
                                  postcode       => $data->{'zipcode'},
791
                                  country        => $data->{'country'},
791
                                  country        => $data->{'country'},
792
                                  email          => $notice_email,
792
                                  email          => ( scalar( @emails_to_use ) ? $emails_to_use[0] : undef ),
793
                                  itemcount      => $itemcount,
793
                                  itemcount      => $itemcount,
794
                                  titles         => $titles,
794
                                  titles         => $titles,
795
                                  outputformat   => defined $csvfilename ? 'csv' : defined $htmlfilename ? 'html' : defined $text_filename ? 'text' : '',
795
                                  outputformat   => defined $csvfilename ? 'csv' : defined $htmlfilename ? 'html' : defined $text_filename ? 'text' : '',
(-)a/misc/cronjobs/thirdparty/TalkingTech_itiva_outbound.pl (-2 / +5 lines)
Lines 122-128 foreach my $type (@types) { Link Here
122
    my $patrons;
122
    my $patrons;
123
    foreach my $issues (@loop) {
123
    foreach my $issues (@loop) {
124
        $patrons->{$issues->{borrowernumber}} ||= Koha::Patrons->find( $issues->{borrowernumber} ) if $skip_patrons_with_email;
124
        $patrons->{$issues->{borrowernumber}} ||= Koha::Patrons->find( $issues->{borrowernumber} ) if $skip_patrons_with_email;
125
        next if $skip_patrons_with_email && $patrons->{$issues->{borrowernumber}}->notice_email_address;
125
        if ($skip_patrons_with_email) {
126
            my $email_addresses = $patrons->{$issues->{borrowernumber}}->notice_email_addresses;
127
            next if @$email_addresses;
128
        }
126
129
127
        my $date_dt = dt_from_string ( $issues->{'date_due'} );
130
        my $date_dt = dt_from_string ( $issues->{'date_due'} );
128
        my $due_date = output_pref( { dt => $date_dt, dateonly => 1, dateformat =>'metric' } );
131
        my $due_date = output_pref( { dt => $date_dt, dateonly => 1, dateformat =>'metric' } );
Lines 143-149 foreach my $type (@types) { Link Here
143
146
144
        my $message_id = 0;
147
        my $message_id = 0;
145
        if ($outfile) {
148
        if ($outfile) {
146
            $message_id = C4::Letters::EnqueueLetter(
149
            ($message_id) = C4::Letters::EnqueueLetter(
147
                {   letter                 => $letter,
150
                {   letter                 => $letter,
148
                    borrowernumber         => $issues->{'borrowernumber'},
151
                    borrowernumber         => $issues->{'borrowernumber'},
149
                    message_transport_type => 'itiva',
152
                    message_transport_type => 'itiva',
(-)a/opac/opac-memberentry.pl (-10 / +11 lines)
Lines 202-217 if ( $action eq 'create' ) { Link Here
202
                },
202
                },
203
            );
203
            );
204
204
205
            my $message_id = C4::Letters::EnqueueLetter(
205
            my @message_ids = C4::Letters::EnqueueLetter(
206
                {
206
                {
207
                    borrowernumber         => $borrower{borrowernumber},
207
                    letter                 => $letter,
208
                    letter                 => $letter,
208
                    message_transport_type => 'email',
209
                    message_transport_type => 'email',
209
                    to_address             => $borrower{'email'},
210
                    from_address =>
211
                      C4::Context->preference('KohaAdminEmailAddress'),
212
                }
210
                }
213
            );
211
            );
214
            C4::Letters::SendQueuedMessages({ message_id => $message_id });
212
            for my $message_id (@message_ids) {
213
                C4::Letters::SendQueuedMessages({ message_id => $message_id });
214
            }
215
        }
215
        }
216
        else {
216
        else {
217
            $borrower{password}         ||= Koha::AuthUtils::generate_password(Koha::Patron::Categories->find($borrower{categorycode}));
217
            $borrower{password}         ||= Koha::AuthUtils::generate_password(Koha::Patron::Categories->find($borrower{categorycode}));
Lines 255-263 if ( $action eq 'create' ) { Link Here
255
                # If 'AutoEmailNewUser' syspref is on, email user their account details from the 'notice' that matches the user's branchcode.
255
                # If 'AutoEmailNewUser' syspref is on, email user their account details from the 'notice' that matches the user's branchcode.
256
                if ( C4::Context->preference("AutoEmailNewUser") ) {
256
                if ( C4::Context->preference("AutoEmailNewUser") ) {
257
                    #look for defined primary email address, if blank - attempt to use borr.email and borr.emailpro instead
257
                    #look for defined primary email address, if blank - attempt to use borr.email and borr.emailpro instead
258
                    my $emailaddr = $patron->notice_email_address;
258
                    my $emailaddrs = $patron->notice_email_addresses;
259
                    # if we manage to find a valid email address, send notice
259
                    # if we manage to find a valid email address, send notice
260
                    if ($emailaddr) {
260
                    if (@$emailaddrs) {
261
                        eval {
261
                        eval {
262
                            my $letter = GetPreparedLetter(
262
                            my $letter = GetPreparedLetter(
263
                                module      => 'members',
263
                                module      => 'members',
Lines 271-285 if ( $action eq 'create' ) { Link Here
271
                                want_librarian => 1,
271
                                want_librarian => 1,
272
                            ) or return;
272
                            ) or return;
273
273
274
                            my $message_id = EnqueueLetter(
274
                            my @message_ids = EnqueueLetter(
275
                                {
275
                                {
276
                                    letter                 => $letter,
276
                                    letter                 => $letter,
277
                                    borrowernumber         => $patron->id,
277
                                    borrowernumber         => $patron->id,
278
                                    to_address             => $emailaddr,
279
                                    message_transport_type => 'email'
278
                                    message_transport_type => 'email'
280
                                }
279
                                }
281
                            );
280
                            );
282
                            SendQueuedMessages({ message_id => $message_id });
281
                            foreach my $message_id (@message_ids) {
282
                                SendQueuedMessages({ message_id => $message_id });
283
                            }
283
                        };
284
                        };
284
                    }
285
                    }
285
                }
286
                }
(-)a/opac/opac-registration-verify.pl (-5 / +6 lines)
Lines 96-104 if ( Link Here
96
        # If 'AutoEmailNewUser' syspref is on, email user their account details from the 'notice' that matches the user's branchcode.
96
        # If 'AutoEmailNewUser' syspref is on, email user their account details from the 'notice' that matches the user's branchcode.
97
        if ( C4::Context->preference("AutoEmailNewUser") ) {
97
        if ( C4::Context->preference("AutoEmailNewUser") ) {
98
            # Look up correct email address taking AutoEmailPrimaryAddress into account
98
            # Look up correct email address taking AutoEmailPrimaryAddress into account
99
            my $emailaddr = $patron->notice_email_address;
99
            my $emailaddrs = $patron->notice_email_addresses;
100
            # if we manage to find a valid email address, send notice
100
            # if we manage to find a valid email address, send notice
101
            if ($emailaddr) {
101
            if (@$emailaddrs) {
102
                eval {
102
                eval {
103
                    my $letter = GetPreparedLetter(
103
                    my $letter = GetPreparedLetter(
104
                        module      => 'members',
104
                        module      => 'members',
Lines 112-126 if ( Link Here
112
                        want_librarian => 1,
112
                        want_librarian => 1,
113
                    ) or return;
113
                    ) or return;
114
114
115
                    my $message_id = EnqueueLetter(
115
                    my @message_ids = EnqueueLetter(
116
                        {
116
                        {
117
                            letter                 => $letter,
117
                            letter                 => $letter,
118
                            borrowernumber         => $patron->id,
118
                            borrowernumber         => $patron->id,
119
                            to_address             => $emailaddr,
120
                            message_transport_type => 'email'
119
                            message_transport_type => 'email'
121
                        }
120
                        }
122
                    );
121
                    );
123
                    SendQueuedMessages({ message_id => $message_id });
122
                    foreach my $message_id (@message_ids) {
123
                        SendQueuedMessages({ message_id => $message_id });
124
                    }
124
                };
125
                };
125
            }
126
            }
126
        }
127
        }
(-)a/opac/opac-shareshelf.pl (-5 / +2 lines)
Lines 164-170 sub notify_owner { Link Here
164
    my $patron = Koha::Patrons->find( $param->{owner} );
164
    my $patron = Koha::Patrons->find( $param->{owner} );
165
    return unless $patron;
165
    return unless $patron;
166
166
167
    my $toaddr = $patron->notice_email_address or return;
167
    return unless @{ $patron->notice_email_addresses };
168
168
169
    #prepare letter
169
    #prepare letter
170
    my $letter = C4::Letters::GetPreparedLetter(
170
    my $letter = C4::Letters::GetPreparedLetter(
Lines 179-188 sub notify_owner { Link Here
179
    #send letter to queue
179
    #send letter to queue
180
    C4::Letters::EnqueueLetter(
180
    C4::Letters::EnqueueLetter(
181
        {
181
        {
182
            borrowernumber         => $param->{owner},
182
            letter                 => $letter,
183
            letter                 => $letter,
183
            message_transport_type => 'email',
184
            message_transport_type => 'email',
184
            from_address => C4::Context->preference('KohaAdminEmailAddress'),
185
            to_address   => $toaddr,
186
        }
185
        }
187
    );
186
    );
188
}
187
}
Lines 208-214 sub process_addrlist { Link Here
208
207
209
sub send_invitekey {
208
sub send_invitekey {
210
    my ($param) = @_;
209
    my ($param) = @_;
211
    my $fromaddr = C4::Context->preference('KohaAdminEmailAddress');
212
    my $url =
210
    my $url =
213
        C4::Context->preference('OPACBaseURL')
211
        C4::Context->preference('OPACBaseURL')
214
      . "/cgi-bin/koha/opac-shareshelf.pl?shelfnumber="
212
      . "/cgi-bin/koha/opac-shareshelf.pl?shelfnumber="
Lines 250-256 sub send_invitekey { Link Here
250
            {
248
            {
251
                letter                 => $letter,
249
                letter                 => $letter,
252
                message_transport_type => 'email',
250
                message_transport_type => 'email',
253
                from_address           => $fromaddr,
254
                to_address             => $a,
251
                to_address             => $a,
255
            }
252
            }
256
        );
253
        );
(-)a/opac/opac-shelves.pl (-2 / +2 lines)
Lines 270-277 if ( $op eq 'add_form' ) { Link Here
270
        my $patrons = [];
270
        my $patrons = [];
271
        my $shares = $shelf->get_shares->search({ borrowernumber => { '!=' => undef } });
271
        my $shares = $shelf->get_shares->search({ borrowernumber => { '!=' => undef } });
272
        while( my $share = $shares->next ) {
272
        while( my $share = $shares->next ) {
273
            my $email = $share->sharee->notice_email_address;
273
            my $emails = $share->sharee->notice_email_addresses;
274
            push @$patrons, { email => $email, borrowernumber => $share->get_column('borrowernumber') } if $email;
274
            push @$patrons, { email => $emails->[0], borrowernumber => $share->get_column('borrowernumber') } if @$emails;
275
        }
275
        }
276
        if( @$patrons ) {
276
        if( @$patrons ) {
277
            $template->param( shared_users => $patrons );
277
            $template->param( shared_users => $patrons );
(-)a/pos/pay.pl (-2 / +4 lines)
Lines 106-112 if ( $action eq 'send' ) { Link Here
106
    );
106
    );
107
107
108
    # Add letter to the queue
108
    # Add letter to the queue
109
    my $message_id = EnqueueLetter(
109
    my @message_ids = EnqueueLetter(
110
        {
110
        {
111
            letter                 => $letter,
111
            letter                 => $letter,
112
            message_transport_type => 'email',
112
            message_transport_type => 'email',
Lines 116-122 if ( $action eq 'send' ) { Link Here
116
    );
116
    );
117
117
118
    # Send immediately
118
    # Send immediately
119
    SendQueuedMessages( { message_id => $message_id } );
119
    foreach my $message_id (@message_ids) {
120
        SendQueuedMessages( { message_id => $message_id } );
121
    }
120
122
121
    # Set variables for template to allow printing still
123
    # Set variables for template to allow printing still
122
    $template->param(
124
    $template->param(
(-)a/suggestion/suggestion.pl (-3 / +2 lines)
Lines 196-204 if ( $op =~ /save/i ) { Link Here
196
196
197
            if ( $notify ) {
197
            if ( $notify ) {
198
                my $patron = Koha::Patrons->find( $suggestion_only->{managedby} );
198
                my $patron = Koha::Patrons->find( $suggestion_only->{managedby} );
199
                my $email_address = $patron->notice_email_address;
199
                my $email_addresses = $patron->notice_email_addresses;
200
                if ($patron->notice_email_address) {
200
                if (@$email_addresses) {
201
202
                    my $letter = C4::Letters::GetPreparedLetter(
201
                    my $letter = C4::Letters::GetPreparedLetter(
203
                        module      => 'suggestions',
202
                        module      => 'suggestions',
204
                        letter_code => 'NOTIFY_MANAGER',
203
                        letter_code => 'NOTIFY_MANAGER',
(-)a/t/db_dependent/Koha/Patrons.t (-5 / +12 lines)
Lines 1061-1076 subtest 'holds and old_holds' => sub { Link Here
1061
    $patron->delete;
1061
    $patron->delete;
1062
};
1062
};
1063
1063
1064
subtest 'notice_email_address' => sub {
1064
subtest 'notice_email_addresses' => sub {
1065
    plan tests => 2;
1065
    plan tests => 3;
1066
1066
1067
    my $patron = $builder->build_object({ class => 'Koha::Patrons' });
1067
    my $patron = $builder->build_object({ class => 'Koha::Patrons' });
1068
1068
1069
    t::lib::Mocks::mock_preference( 'AutoEmailPrimaryAddress', 'OFF' );
1069
    t::lib::Mocks::mock_preference( 'AutoEmailPrimaryAddress', 'OFF' );
1070
    is ($patron->notice_email_address, $patron->email, "Koha::Patron->notice_email_address returns correct value when AutoEmailPrimaryAddress is off");
1070
    is_deeply( $patron->notice_email_addresses, [ $patron->email ], "Koha::Patron->notice_email_addresses returns correct value when AutoEmailPrimaryAddress is off" );
1071
1071
1072
    t::lib::Mocks::mock_preference( 'AutoEmailPrimaryAddress', 'emailpro' );
1072
    t::lib::Mocks::mock_preference( 'AutoEmailPrimaryAddress', 'emailpro' );
1073
    is ($patron->notice_email_address, $patron->emailpro, "Koha::Patron->notice_email_address returns correct value when AutoEmailPrimaryAddress is emailpro");
1073
    is_deeply( $patron->notice_email_addresses, [ $patron->emailpro ], "Koha::Patron->notice_email_addresses returns correct value when AutoEmailPrimaryAddress is emailpro" );
1074
1075
    t::lib::Mocks::mock_preference( 'AutoEmailPrimaryAddress', 'email,emailpro' );
1076
    is_deeply(
1077
        $patron->notice_email_addresses,
1078
        [ $patron->email, $patron->emailpro ],
1079
        "Koha::Patron->notice_email_addresses returns correct value when AutoEmailPrimaryAddress is email,emailpro"
1080
    );
1074
1081
1075
    $patron->delete;
1082
    $patron->delete;
1076
};
1083
};
Lines 1983-1989 subtest '->set_password' => sub { Link Here
1983
    t::lib::Mocks::mock_preference( 'NotifyPasswordChange', 1 );
1990
    t::lib::Mocks::mock_preference( 'NotifyPasswordChange', 1 );
1984
    $patron->set_password({ password => 'abcd   c' });
1991
    $patron->set_password({ password => 'abcd   c' });
1985
    my $queued_notices = Koha::Notice::Messages->search({ borrowernumber => $patron->borrowernumber });
1992
    my $queued_notices = Koha::Notice::Messages->search({ borrowernumber => $patron->borrowernumber });
1986
    is( $queued_notices->count, 1, "One notice queued when NotifyPasswordChange enabled" );
1993
    is( $queued_notices->count, scalar @{ $patron->notice_email_addresses }, "One notice queued for each notice email address when NotifyPasswordChange enabled" );
1987
    my $THE_notice = $queued_notices->next;
1994
    my $THE_notice = $queued_notices->next;
1988
    is( $THE_notice->status, 'failed', "The notice was handled immediately and failed on wrong email address."); #FIXME Mock sending mail
1995
    is( $THE_notice->status, 'failed', "The notice was handled immediately and failed on wrong email address."); #FIXME Mock sending mail
1989
    $schema->storage->txn_rollback;
1996
    $schema->storage->txn_rollback;
(-)a/t/db_dependent/Koha/Recall.t (-1 / +1 lines)
Lines 129-135 is( t::lib::Dates::compare( $expirationdate, $expected_expirationdate ), 0, "Exp Link Here
129
$recall2->set_waiting({ expirationdate => $expirationdate });
129
$recall2->set_waiting({ expirationdate => $expirationdate });
130
is( $recall2->waiting, 1, "Recall is waiting" );
130
is( $recall2->waiting, 1, "Recall is waiting" );
131
131
132
my $notice = C4::Message->find_last_message( $patron1->unblessed, 'PICKUP_RECALLED_ITEM', 'email' );
132
my ($notice) = C4::Message->find_last_messages( $patron1->unblessed, 'PICKUP_RECALLED_ITEM', 'email' );
133
ok( defined $notice, "Patron was notified to pick up waiting recall" );
133
ok( defined $notice, "Patron was notified to pick up waiting recall" );
134
134
135
$recall2->set_expired({ interface => 'COMMANDLINE' });
135
$recall2->set_expired({ interface => 'COMMANDLINE' });
(-)a/t/db_dependent/Letters.t (-14 / +92 lines)
Lines 112-119 my $my_message = { Link Here
112
    to_address             => undef,
112
    to_address             => undef,
113
    from_address           => 'from@example.com',
113
    from_address           => 'from@example.com',
114
};
114
};
115
my $message_id = C4::Letters::EnqueueLetter($my_message);
115
is( C4::Letters::EnqueueLetter($my_message), undef, 'EnqueueLetter without the letter argument returns undef' );
116
is( $message_id, undef, 'EnqueueLetter without the letter argument returns undef' );
117
116
118
delete $my_message->{message_transport_type};
117
delete $my_message->{message_transport_type};
119
$my_message->{letter} = {
118
$my_message->{letter} = {
Lines 124-136 $my_message->{letter} = { Link Here
124
    content_type => 'text/plain',
123
    content_type => 'text/plain',
125
};
124
};
126
125
127
$message_id = C4::Letters::EnqueueLetter($my_message);
126
my @message_ids = C4::Letters::EnqueueLetter($my_message);
128
is( $message_id, undef, 'EnqueueLetter without the message type argument argument returns undef' );
127
is( scalar @message_ids, 0, 'EnqueueLetter without the message type argument argument returns an empty list' );
129
128
130
$my_message->{message_transport_type} = 'sms';
129
$my_message->{message_transport_type} = 'sms';
131
$message_id = C4::Letters::EnqueueLetter($my_message);
130
@message_ids = C4::Letters::EnqueueLetter($my_message);
132
ok(defined $message_id && $message_id > 0, 'new message successfully queued');
131
is(scalar @message_ids, 1, 'new message successfully queued');
133
134
132
135
# GetQueuedMessages
133
# GetQueuedMessages
136
my $messages = C4::Letters::GetQueuedMessages();
134
my $messages = C4::Letters::GetQueuedMessages();
Lines 138-144 is( @$messages, 1, 'GetQueuedMessages without argument returns all the entries' Link Here
138
136
139
$messages = C4::Letters::GetQueuedMessages({ borrowernumber => $borrowernumber });
137
$messages = C4::Letters::GetQueuedMessages({ borrowernumber => $borrowernumber });
140
is( @$messages, 1, 'one message stored for the borrower' );
138
is( @$messages, 1, 'one message stored for the borrower' );
141
is( $messages->[0]->{message_id}, $message_id, 'EnqueueLetter returns the message id correctly' );
142
is( $messages->[0]->{borrowernumber}, $borrowernumber, 'EnqueueLetter stores the borrower number correctly' );
139
is( $messages->[0]->{borrowernumber}, $borrowernumber, 'EnqueueLetter stores the borrower number correctly' );
143
is( $messages->[0]->{subject}, $my_message->{letter}->{title}, 'EnqueueLetter stores the subject correctly' );
140
is( $messages->[0]->{subject}, $my_message->{letter}->{title}, 'EnqueueLetter stores the subject correctly' );
144
is( $messages->[0]->{content}, $my_message->{letter}->{content}, 'EnqueueLetter stores the content correctly' );
141
is( $messages->[0]->{content}, $my_message->{letter}->{content}, 'EnqueueLetter stores the content correctly' );
Lines 847-854 subtest 'Test SMS handling in SendQueuedMessages' => sub { Link Here
847
    is( $@, '', 'SendQueuedMessages should not explode if the patron does not have a sms provider set' );
844
    is( $@, '', 'SendQueuedMessages should not explode if the patron does not have a sms provider set' );
848
845
849
    my $sms_pro = $builder->build_object({ class => 'Koha::SMS::Providers', value => { domain => 'kidclamp.rocks' } });
846
    my $sms_pro = $builder->build_object({ class => 'Koha::SMS::Providers', value => { domain => 'kidclamp.rocks' } });
850
    $patron->set( { smsalertnumber => '5555555555', sms_provider_id => $sms_pro->id() } )->store;
847
    $patron->set( { smsalertnumber => '5555555555', sms_provider_id => $sms_pro->id(), email => '', emailpro => '' } )->store;
851
    $message_id = C4::Letters::EnqueueLetter($my_message); #using datas set around line 95 and forward
848
    C4::Letters::EnqueueLetter($my_message); #using datas set around line 95 and forward
852
849
853
    warning_like { C4::Letters::SendQueuedMessages(); }
850
    warning_like { C4::Letters::SendQueuedMessages(); }
854
        qr|Fake send_or_die|,
851
        qr|Fake send_or_die|,
Lines 871-877 subtest 'Test SMS handling in SendQueuedMessages' => sub { Link Here
871
868
872
    t::lib::Mocks::mock_preference('EmailSMSSendDriverFromAddress', 'override@example.com');
869
    t::lib::Mocks::mock_preference('EmailSMSSendDriverFromAddress', 'override@example.com');
873
870
874
    $message_id = C4::Letters::EnqueueLetter($my_message);
871
    C4::Letters::EnqueueLetter($my_message);
875
    warning_like { C4::Letters::SendQueuedMessages(); }
872
    warning_like { C4::Letters::SendQueuedMessages(); }
876
        qr|Fake send_or_die|,
873
        qr|Fake send_or_die|,
877
        "SendAlerts is using the mocked send_or_die routine (claimissues)";
874
        "SendAlerts is using the mocked send_or_die routine (claimissues)";
Lines 889-895 subtest 'Test SMS handling in SendQueuedMessages' => sub { Link Here
889
886
890
    $schema->resultset('MessageQueue')->search({borrowernumber => $borrowernumber,status => 'sent'})->delete(); #clear borrower queue
887
    $schema->resultset('MessageQueue')->search({borrowernumber => $borrowernumber,status => 'sent'})->delete(); #clear borrower queue
891
    $my_message->{to_address} = 'fixme@kidclamp.iswrong';
888
    $my_message->{to_address} = 'fixme@kidclamp.iswrong';
892
    $message_id = C4::Letters::EnqueueLetter($my_message);
889
    C4::Letters::EnqueueLetter($my_message);
893
890
894
    my $number_attempted = C4::Letters::SendQueuedMessages({
891
    my $number_attempted = C4::Letters::SendQueuedMessages({
895
        borrowernumber => -1, # -1 still triggers the borrowernumber condition
892
        borrowernumber => -1, # -1 still triggers the borrowernumber condition
Lines 903-908 subtest 'Test SMS handling in SendQueuedMessages' => sub { Link Here
903
900
904
    my $sms_message_address = $schema->resultset('MessageQueue')->search({
901
    my $sms_message_address = $schema->resultset('MessageQueue')->search({
905
        borrowernumber => $borrowernumber,
902
        borrowernumber => $borrowernumber,
903
        message_transport_type => 'sms',
906
        status => 'sent'
904
        status => 'sent'
907
    })->next()->to_address();
905
    })->next()->to_address();
908
    is( $sms_message_address, '5555555555@kidclamp.rocks', 'SendQueuedMessages populates the to address correctly for SMS by email when to_address is set incorrectly' );
906
    is( $sms_message_address, '5555555555@kidclamp.rocks', 'SendQueuedMessages populates the to address correctly for SMS by email when to_address is set incorrectly' );
Lines 1091-1097 subtest 'Test message_id parameter for SendQueuedMessages' => sub { Link Here
1091
        'message_transport_type' => 'email',
1089
        'message_transport_type' => 'email',
1092
        'from_address'           => '@example.com' # invalid from_address
1090
        'from_address'           => '@example.com' # invalid from_address
1093
    };
1091
    };
1094
    my $message_id = C4::Letters::EnqueueLetter($my_message);
1092
    my ($message_id) = C4::Letters::EnqueueLetter($my_message);
1095
    my $processed = C4::Letters::SendQueuedMessages( { message_id => $message_id } );
1093
    my $processed = C4::Letters::SendQueuedMessages( { message_id => $message_id } );
1096
    is( $processed, 1, 'Processed 1 message when one message_id passed' );
1094
    is( $processed, 1, 'Processed 1 message when one message_id passed' );
1097
    my $message_1 = C4::Letters::GetMessage($message_id);
1095
    my $message_1 = C4::Letters::GetMessage($message_id);
Lines 1099-1105 subtest 'Test message_id parameter for SendQueuedMessages' => sub { Link Here
1099
    is( $message_1->{failure_code}, 'INVALID_EMAIL:from', 'Failure code set correctly for invalid email parameter');
1097
    is( $message_1->{failure_code}, 'INVALID_EMAIL:from', 'Failure code set correctly for invalid email parameter');
1100
1098
1101
    $my_message->{from_address} = 'root@example.org'; # valid from_address
1099
    $my_message->{from_address} = 'root@example.org'; # valid from_address
1102
    $message_id = C4::Letters::EnqueueLetter($my_message);
1100
    ($message_id) = C4::Letters::EnqueueLetter($my_message);
1103
    warning_like { C4::Letters::SendQueuedMessages( { message_id => $message_id } ); }
1101
    warning_like { C4::Letters::SendQueuedMessages( { message_id => $message_id } ); }
1104
        qr|Fake send_or_die|,
1102
        qr|Fake send_or_die|,
1105
        "SendQueuedMessages is using the mocked send_or_die routine";
1103
        "SendQueuedMessages is using the mocked send_or_die routine";
Lines 1108-1110 subtest 'Test message_id parameter for SendQueuedMessages' => sub { Link Here
1108
    is( $message_1->{status}, 'failed', 'Message 1 status is unchanged' );
1106
    is( $message_1->{status}, 'failed', 'Message 1 status is unchanged' );
1109
    is( $message_2->{status}, 'sent', 'Valid from_address => status sent' );
1107
    is( $message_2->{status}, 'sent', 'Valid from_address => status sent' );
1110
};
1108
};
1109
1110
subtest 'EnqueueLetter and AutoEmailPrimaryAddress' => sub {
1111
    plan tests => 19;
1112
1113
    my ( $email, $emailpro ) = ( 'email@example.org', 'emailpro@example.org' );
1114
    my $borrowernumber = Koha::Patron->new(
1115
        {   firstname      => 'Jane',
1116
            surname        => 'Smith',
1117
            categorycode   => $patron_category,
1118
            branchcode     => $library->{branchcode},
1119
            dateofbirth    => $date,
1120
            smsalertnumber => undef,
1121
            email          => $email,
1122
            emailpro       => $emailpro,
1123
        }
1124
    )->store->borrowernumber;
1125
1126
    my $my_message = {
1127
        borrowernumber         => $borrowernumber,
1128
        message_transport_type => 'email',
1129
        to_address             => 'to@example.com',
1130
        from_address           => 'from@example.com',
1131
        letter                 => {
1132
            content      => 'a message',
1133
            title        => 'message title',
1134
            metadata     => 'metadata',
1135
            code         => 'TEST_MESSAGE',
1136
            content_type => 'text/plain',
1137
        },
1138
    };
1139
1140
    $dbh->do(q|DELETE FROM message_queue|);
1141
    t::lib::Mocks::mock_preference( 'AutoEmailPrimaryAddress', 'email' );
1142
    @message_ids = C4::Letters::EnqueueLetter($my_message);
1143
    is( scalar @message_ids, 1, 'message successfully queued' );
1144
    $messages = C4::Letters::GetQueuedMessages( { borrowernumber => $borrowernumber } );
1145
    is( scalar(@$messages),         1,                'The message has been queued for the expected patron' );
1146
    is( $messages->[0]{to_address}, 'to@example.com', 'AutoEmailPrimaryAddress=email, EnqueueLetter used the to_address given in parameter' );
1147
1148
    $dbh->do(q|DELETE FROM message_queue|);
1149
    delete $my_message->{to_address};
1150
    @message_ids = C4::Letters::EnqueueLetter($my_message);
1151
    is( scalar @message_ids, 1, 'message successfully queued' );
1152
    $messages = C4::Letters::GetQueuedMessages( { borrowernumber => $borrowernumber } );
1153
    is( scalar(@$messages),         1,      'The message has been queued for the expected patron' );
1154
    is( $messages->[0]{to_address}, $email, 'AutoEmailPrimaryAddress=email, EnqueueLetter used the patron email address if no to_address is given in parameter' );
1155
1156
    $dbh->do(q|DELETE FROM message_queue|);
1157
    t::lib::Mocks::mock_preference( 'AutoEmailPrimaryAddress', 'emailpro' );
1158
    @message_ids = C4::Letters::EnqueueLetter($my_message);
1159
    is( scalar @message_ids, 1, 'message successfully queued' );
1160
    $messages = C4::Letters::GetQueuedMessages( { borrowernumber => $borrowernumber } );
1161
    is( scalar(@$messages),         1,         'The message has been queued for the expected patron' );
1162
    is( $messages->[0]{to_address}, $emailpro, 'AutoEmailPrimaryAddress=emailpro, EnqueueLetter used the patron emailpro address if no to_address is given in parameter' );
1163
1164
    $dbh->do(q|DELETE FROM message_queue|);
1165
    t::lib::Mocks::mock_preference( 'AutoEmailPrimaryAddress', 'OFF' );
1166
    @message_ids = C4::Letters::EnqueueLetter($my_message);
1167
    is( scalar @message_ids, 1, 'message successfully queued' );
1168
    $messages = C4::Letters::GetQueuedMessages( { borrowernumber => $borrowernumber } );
1169
    is( scalar(@$messages),         1,      'The message has been queued for the expected patron' );
1170
    is( $messages->[0]{to_address}, $email, 'AutoEmailPrimaryAddress=OFF, EnqueueLetter used the patron email address if no to_address is given in parameter' );
1171
1172
    $dbh->do(q|DELETE FROM message_queue|);
1173
    t::lib::Mocks::mock_preference( 'AutoEmailPrimaryAddress', 'email,OFF,emailpro' );    # This is no consistent. OFF should be alone.
1174
    @message_ids = C4::Letters::EnqueueLetter($my_message);
1175
    is( scalar @message_ids, 1, 'message successfully queued' );
1176
    $messages = C4::Letters::GetQueuedMessages( { borrowernumber => $borrowernumber } );
1177
    is( scalar(@$messages),         1,      'The message has been queued for the expected patron' );
1178
    is( $messages->[0]{to_address}, $email, 'AutoEmailPrimaryAddress=email,OFF,emailpro, EnqueueLetter used the patron email address if no to_address is given in parameter' );
1179
1180
    $dbh->do(q|DELETE FROM message_queue|);
1181
    t::lib::Mocks::mock_preference( 'AutoEmailPrimaryAddress', 'email,emailpro' );
1182
    @message_ids = C4::Letters::EnqueueLetter($my_message);
1183
    is( scalar @message_ids, 2, 'messages successfully queued' );
1184
    $messages = C4::Letters::GetQueuedMessages( { borrowernumber => $borrowernumber } );
1185
    is( scalar(@$messages),         2,         'The messages have been queued for the expected patron' );
1186
    is( $messages->[0]{to_address}, $email,    'AutoEmailPrimaryAddress=email,emailpro, EnqueueLetter used the patron email address for the first letter' );
1187
    is( $messages->[1]{to_address}, $emailpro, 'AutoEmailPrimaryAddress=email,emailpro, EnqueueLetter used the patron emailpro address for the second letter' );
1188
};
(-)a/t/db_dependent/Message.t (-4 / +3 lines)
Lines 52-58 my $letter = C4::Letters::GetPreparedLetter( Link Here
52
52
53
t::lib::Mocks::mock_preference( 'AutoEmailPrimaryAddress', 'OFF' );
53
t::lib::Mocks::mock_preference( 'AutoEmailPrimaryAddress', 'OFF' );
54
C4::Message->enqueue($letter, $patron, 'email');
54
C4::Message->enqueue($letter, $patron, 'email');
55
my $message = C4::Message->find_last_message($patron->unblessed, 'TEST_MESSAGE', 'email');
55
my ($message) = C4::Message->find_last_messages($patron->unblessed, 'TEST_MESSAGE', 'email');
56
like( $message->{metadata}, qr{heÄllo} );
56
like( $message->{metadata}, qr{heÄllo} );
57
is ($message->{to_address}, $patron->email, "To address set correctly for AutoEmailPrimaryAddress 'off'");
57
is ($message->{to_address}, $patron->email, "To address set correctly for AutoEmailPrimaryAddress 'off'");
58
58
Lines 71-75 like( $message->{metadata}, qr{hell❤️} ); Link Here
71
71
72
t::lib::Mocks::mock_preference( 'AutoEmailPrimaryAddress', 'emailpro' );
72
t::lib::Mocks::mock_preference( 'AutoEmailPrimaryAddress', 'emailpro' );
73
C4::Message->enqueue($letter, $patron, 'email');
73
C4::Message->enqueue($letter, $patron, 'email');
74
$message = C4::Message->find_last_message($patron->unblessed, 'TEST_MESSAGE', 'email');
74
($message) = C4::Message->find_last_messages($patron->unblessed, 'TEST_MESSAGE', 'email');
75
is ($patron->notice_email_address, $patron->emailpro, "To address set correctly for AutoEmailPrimaryAddress 'emailpro'");
75
is_deeply ($patron->notice_email_addresses, [$patron->emailpro], "To address set correctly for AutoEmailPrimaryAddress 'emailpro'");
76
- 

Return to bug 12802