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

(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/messaging-preference-form.inc (+2 lines)
Lines 17-22 Link Here
17
    <tr>
17
    <tr>
18
      <td>[% IF ( messaging_preference.Item_Due ) %]Item due
18
      <td>[% IF ( messaging_preference.Item_Due ) %]Item due
19
          [% ELSIF ( messaging_preference.Advance_Notice ) %]Advance notice
19
          [% ELSIF ( messaging_preference.Advance_Notice ) %]Advance notice
20
          [% ELSIF ( messaging_preference.Upcoming_Events ) %]Upcoming events
20
          [% ELSIF ( messaging_preference.Hold_Filled ) %]Hold filled
21
          [% ELSIF ( messaging_preference.Hold_Filled ) %]Hold filled
21
          [% ELSIF ( messaging_preference.Item_Check_in ) %]Item check-in
22
          [% ELSIF ( messaging_preference.Item_Check_in ) %]Item check-in
22
          [% ELSIF ( messaging_preference.Item_Checkout ) %]
23
          [% ELSIF ( messaging_preference.Item_Checkout ) %]
Lines 27-32 Link Here
27
            [% END %]
28
            [% END %]
28
          [% ELSIF ( messaging_preference.Ill_ready ) %]Interlibrary loan ready
29
          [% ELSIF ( messaging_preference.Ill_ready ) %]Interlibrary loan ready
29
          [% ELSIF ( messaging_preference.Ill_unavailable ) %]Interlibrary loan unavailable
30
          [% ELSIF ( messaging_preference.Ill_unavailable ) %]Interlibrary loan unavailable
31
          [% ELSIF ( messaging_preference.Auto_Renewals ) %]Auto renewals
30
          [% ELSE %]Unknown [% END %]</td>
32
          [% ELSE %]Unknown [% END %]</td>
31
      [% IF ( messaging_preference.takes_days ) %]
33
      [% IF ( messaging_preference.takes_days ) %]
32
      <td>
34
      <td>
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-messaging.tt (+1 lines)
Lines 69-74 Link Here
69
                                                    [% END %]
69
                                                    [% END %]
70
                                                [% ELSIF ( messaging_preference.Ill_ready ) %]Interlibrary loan ready
70
                                                [% ELSIF ( messaging_preference.Ill_ready ) %]Interlibrary loan ready
71
                                                [% ELSIF ( messaging_preference.Ill_unavailable ) %]Interlibrary loan unavailable
71
                                                [% ELSIF ( messaging_preference.Ill_unavailable ) %]Interlibrary loan unavailable
72
                                                [% ELSIF ( messaging_preference.Auto_Renewals ) %]Auto renewals
72
                                                [% ELSE %]Unknown [% END %]</td>
73
                                                [% ELSE %]Unknown [% END %]</td>
73
                                            [% IF ( messaging_preference.takes_days ) %]
74
                                            [% IF ( messaging_preference.takes_days ) %]
74
                                                <td><select class="input-mini" name="[% messaging_preference.message_attribute_id | html %]-DAYS">
75
                                                <td><select class="input-mini" name="[% messaging_preference.message_attribute_id | html %]-DAYS">
(-)a/misc/cronjobs/automatic_renewals.pl (-19 / +166 lines)
Lines 2-8 Link Here
2
2
3
# This file is part of Koha.
3
# This file is part of Koha.
4
#
4
#
5
# Copyright (C) 2014 Hochschule für Gesundheit (hsg), Germany
5
# Copyright (C) 2014 Hochschule für Gesundheit (hsg), Germany
6
#
6
#
7
# Koha is free software; you can redistribute it and/or modify it
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
8
# under the terms of the GNU General Public License as published by
Lines 23-32 automatic_renewals.pl - cron script to renew loans Link Here
23
23
24
=head1 SYNOPSIS
24
=head1 SYNOPSIS
25
25
26
./automatic_renewals.pl [-c|--confirm] [--send-notices]
26
./automatic_renewals.pl [-c|--confirm] [-s|--send-notices] [-d|--digest] [-b|--digest-per-branch] [-v|--verbose]
27
27
28
or, in crontab:
28
or, in crontab:
29
0 3 * * * automatic_renewals.pl -c
29
# Once every day for digest messages
30
0 3 * * * automatic_renewals.pl -c -d
31
# Three times a day for non digest messages
32
0 0,8,16 * * * automatic_renewals.pl -c
30
33
31
=head1 DESCRIPTION
34
=head1 DESCRIPTION
32
35
Lines 38-49 and the renewal isn't premature (No Renewal before) the issue is renewed. Link Here
38
41
39
=over
42
=over
40
43
41
=item B<--send-notices>
44
=item B<-s|--send-notices>
42
45
43
Send AUTO_RENEWALS notices to patrons if the auto renewal has been done.
46
Send AUTO_RENEWALS notices to patrons if the auto renewal has been done.
44
47
45
Note that this option does not support digest yet.
46
47
=item B<-v|--verbose>
48
=item B<-v|--verbose>
48
49
49
Print report to standard out.
50
Print report to standard out.
Lines 52-57 Print report to standard out. Link Here
52
53
53
Without this parameter no changes will be made
54
Without this parameter no changes will be made
54
55
56
=item B<-d|--digest>
57
58
Flag to indicate that this script should process digest messages.
59
60
=item B<-b|--digest-per-branch>
61
62
Flag to indicate that generation of message digests should be
63
performed separately for each branch. Needs --digest option.
64
65
A patron could potentially have loans at several different branches
66
There is no natural branch to set as the sender on the aggregated
67
message in this situation so the default behavior is to use the
68
borrowers home branch.  This could surprise to the borrower when
69
message sender is a library where they have not borrowed anything.
70
71
Enabling this flag ensures that the issuing library is the sender of
72
the digested message.  It has no effect unless the borrower has
73
chosen 'Digests only' on the advance messages.
74
55
=back
75
=back
56
76
57
=cut
77
=cut
Lines 69-104 use Koha::Checkouts; Link Here
69
use Koha::Libraries;
89
use Koha::Libraries;
70
use Koha::Patrons;
90
use Koha::Patrons;
71
91
72
my ( $help, $send_notices, $verbose, $confirm );
92
my ( $help, $send_notices, $verbose, $confirm, $digest, $digest_per_branch );
73
GetOptions(
93
GetOptions(
74
    'h|help' => \$help,
94
    'h|help' => \$help,
75
    'send-notices' => \$send_notices,
95
    's|send-notices' => \$send_notices,
76
    'v|verbose'    => \$verbose,
96
    'v|verbose'    => \$verbose,
77
    'c|confirm'     => \$confirm,
97
    'c|confirm'     => \$confirm,
98
    'd|digest|' => \$digest,
99
    'b|digest-per-branch' => \$digest_per_branch,
78
) || pod2usage(1);
100
) || pod2usage(1);
79
101
80
pod2usage(0) if $help;
102
pod2usage(0) if $help;
103
104
# Since advance notice options are not visible in the web-interface
105
# unless EnhancedMessagingPreferences is on, let the user know that
106
# this script probably isn't going to do much
107
if ( ! C4::Context->preference('EnhancedMessagingPreferences') ) {
108
    warn <<'END_WARN';
109
110
The "EnhancedMessagingPreferences" syspref is off.
111
Therefore, it is unlikely that this script will actually produce any messages to be sent.
112
To change this, edit the "EnhancedMessagingPreferences" syspref.
113
114
END_WARN
115
}
116
81
cronlogaction();
117
cronlogaction();
82
118
119
$verbose = 1 unless $verbose or $confirm;
120
print "Test run only\n" unless $confirm;
121
122
print "getting auto renewals\n" if $verbose;
83
my $auto_renews = Koha::Checkouts->search({ auto_renew => 1, 'borrower.autorenew_checkouts' => 1 },{ join => 'borrower'});
123
my $auto_renews = Koha::Checkouts->search({ auto_renew => 1, 'borrower.autorenew_checkouts' => 1 },{ join => 'borrower'});
124
print "found " . $auto_renews->count . " auto renewals\n" if $verbose;
84
125
126
my $renew_digest = {};
85
my %report;
127
my %report;
86
$verbose = 1 unless $verbose or $confirm;
87
print "Test run only\n" unless $confirm;
88
while ( my $auto_renew = $auto_renews->next ) {
128
while ( my $auto_renew = $auto_renews->next ) {
129
    print "examining item '" . $auto_renew->itemnumber . "' to auto renew\n" if $verbose;
130
131
    my $borrower_preferences = C4::Members::Messaging::GetMessagingPreferences( { borrowernumber => $auto_renew->borrowernumber,
132
                                                                                   message_name   => 'auto_renewals' } );
133
134
    next if !$digest && $borrower_preferences && $borrower_preferences->{'wants_digest'};
89
135
90
    # CanBookBeRenewed returns 'auto_renew' when the renewal should be done by this script
136
    # CanBookBeRenewed returns 'auto_renew' when the renewal should be done by this script
91
    my ( $ok, $error ) = CanBookBeRenewed( $auto_renew->borrowernumber, $auto_renew->itemnumber, undef, 1 );
137
    my ( $ok, $error ) = CanBookBeRenewed( $auto_renew->borrowernumber, $auto_renew->itemnumber, undef, 1 );
92
    if ( $error eq 'auto_renew' ) {
138
    if ( $error eq 'auto_renew' ) {
93
        if ($verbose) {
139
        if ($verbose) {
94
            say sprintf "Issue id: %s for borrower: %s and item: %s ". ( $confirm ? 'will' : 'would') . " be renewed.",
140
            say sprintf "Issue id: %s for borrower: %s and item: %s %s be renewed.",
95
              $auto_renew->issue_id, $auto_renew->borrowernumber, $auto_renew->itemnumber;
141
              $auto_renew->issue_id, $auto_renew->borrowernumber, $auto_renew->itemnumber, $confirm ? 'will' : 'would';
96
        }
142
        }
97
        if ($confirm){
143
        if ($confirm){
98
            my $date_due = AddRenewal( $auto_renew->borrowernumber, $auto_renew->itemnumber, $auto_renew->branchcode, undef, undef, undef, 0 );
144
            my $date_due = AddRenewal( $auto_renew->borrowernumber, $auto_renew->itemnumber, $auto_renew->branchcode, undef, undef, undef, 0 );
99
            $auto_renew->auto_renew_error(undef)->store;
145
            $auto_renew->auto_renew_error(undef)->store;
100
        }
146
        }
101
        push @{ $report{ $auto_renew->borrowernumber } }, $auto_renew;
147
        push @{ $report{ $auto_renew->borrowernumber } }, $auto_renew unless $borrower_preferences && (!$borrower_preferences->{transports} || !$borrower_preferences->{transports}->{email} || $borrower_preferences->{'wants_digest'});
102
    } elsif ( $error eq 'too_many'
148
    } elsif ( $error eq 'too_many'
103
        or $error eq 'on_reserve'
149
        or $error eq 'on_reserve'
104
        or $error eq 'restriction'
150
        or $error eq 'restriction'
Lines 110-127 while ( my $auto_renew = $auto_renews->next ) { Link Here
110
        or $error eq 'auto_too_soon'
156
        or $error eq 'auto_too_soon'
111
        or $error eq 'item_denied_renewal' ) {
157
        or $error eq 'item_denied_renewal' ) {
112
        if ( $verbose ) {
158
        if ( $verbose ) {
113
            say sprintf "Issue id: %s for borrower: %s and item: %s ". ( $confirm ? 'will' : 'would') . " not be renewed. (%s)",
159
            say sprintf "Issue id: %s for borrower: %s and item: %s %s not be renewed. (%s)",
114
              $auto_renew->issue_id, $auto_renew->borrowernumber, $auto_renew->itemnumber, $error;
160
              $auto_renew->issue_id, $auto_renew->borrowernumber, $auto_renew->itemnumber, $confirm ? 'will' : 'would', $error;
115
        }
161
        }
116
        if ( not $auto_renew->auto_renew_error or $error ne $auto_renew->auto_renew_error ) {
162
        if ( not $auto_renew->auto_renew_error or $error ne $auto_renew->auto_renew_error ) {
117
            $auto_renew->auto_renew_error($error)->store if $confirm;
163
            $auto_renew->auto_renew_error($error)->store if $confirm;
118
            push @{ $report{ $auto_renew->borrowernumber } }, $auto_renew
164
            push @{ $report{ $auto_renew->borrowernumber } }, $auto_renew
119
              if $error ne 'auto_too_soon';    # Do not notify if it's too soon
165
              if $error ne 'auto_too_soon' && (!$borrower_preferences || ($borrower_preferences->{transports} && $borrower_preferences->{transports}->{email} && !$borrower_preferences->{'wants_digest'}));    # Do not notify if it's too soon
120
        }
166
        }
121
    }
167
    }
168
169
    if ( $borrower_preferences && $borrower_preferences->{transports} && $borrower_preferences->{transports}->{email} && $borrower_preferences->{'wants_digest'} ) {
170
        # cache this one to process after we've run through all of the items.
171
        if ($digest_per_branch) {
172
            $renew_digest->{ $auto_renew->branchcode }->{ $auto_renew->borrowernumber }->{success}++ if $error eq 'auto_renew';
173
            $renew_digest->{ $auto_renew->branchcode }->{ $auto_renew->borrowernumber }->{error}++ unless $error eq 'auto_renew' || $error == 'auto_too_soon' ;
174
        } else {
175
            $renew_digest->{ $auto_renew->borrowernumber }->{success} ++ if $error eq 'auto_renew';
176
            $renew_digest->{ $auto_renew->borrowernumber }->{error}++ unless $error eq 'auto_renew' || $error eq 'auto_too_soon' ;
177
        }
178
    }
179
122
}
180
}
123
181
124
if ( $send_notices ) {
182
if ( $send_notices && $confirm ) {
125
    for my $borrowernumber ( keys %report ) {
183
    for my $borrowernumber ( keys %report ) {
126
        my $patron = Koha::Patrons->find($borrowernumber);
184
        my $patron = Koha::Patrons->find($borrowernumber);
127
        for my $issue ( @{ $report{$borrowernumber} } ) {
185
        for my $issue ( @{ $report{$borrowernumber} } ) {
Lines 147-153 if ( $send_notices ) { Link Here
147
                    message_transport_type => 'email',
205
                    message_transport_type => 'email',
148
                    from_address           => $admin_email_address,
206
                    from_address           => $admin_email_address,
149
                }
207
                }
150
            ) if $confirm;
208
            );
209
        }
210
    }
211
212
    if ($digest_per_branch) {
213
        while (my ($branchcode, $digests) = each %$renew_digest) {
214
            send_digests({
215
                digests => $digests,
216
                branchcode => $branchcode,
217
                letter_code => 'AUTO_RENEWALS_DGST',
218
            });
219
        }
220
    } else {
221
        send_digests({
222
            digests => $renew_digest,
223
            letter_code => 'AUTO_RENEWALS_DGST',
224
        });
225
    }
226
}
227
228
=head1 METHODS
229
230
=head2 send_digests
231
232
    send_digests({
233
        digests => ...,
234
        letter_code => ...,
235
    })
236
237
Enqueue digested letters.
238
239
Parameters:
240
241
=over 4
242
243
=item C<$digests>
244
245
Reference to the array of digested messages.
246
247
=item C<$letter_code>
248
249
String that denote the letter code.
250
251
=back
252
253
=cut
254
255
sub send_digests {
256
    my $params = shift;
257
258
    my $admin_email_address = C4::Context->preference('KohaAdminEmailAddress');
259
260
    PATRON: while ( my ( $borrowernumber, $digest ) = each %{$params->{digests}} ) {
261
        my $borrower_preferences =
262
            C4::Members::Messaging::GetMessagingPreferences(
263
                {
264
                    borrowernumber => $borrowernumber,
265
                    message_name   => 'auto_renewals'
266
                }
267
            );
268
269
        next PATRON unless $borrower_preferences; # how could this happen?
270
271
        my $patron = Koha::Patrons->find( $borrowernumber );
272
        my $library = Koha::Libraries->find( $params->{branchcode} );
273
        my $from_address = $library->{branchemail} || $admin_email_address;
274
275
        foreach my $transport ( keys %{ $borrower_preferences->{'transports'} } ) {
276
            my $letter = C4::Letters::GetPreparedLetter (
277
                module => 'circulation',
278
                letter_code => $params->{letter_code},
279
                branchcode => $params->{branchcode},
280
                lang => $patron->lang,
281
                substitute => {
282
                    error => $digest->{error}||0,
283
                    success => $digest->{success}||0,
284
                },
285
                tables      => {
286
                    borrowers => $patron->borrowernumber,
287
                },
288
                message_transport_type => $transport,
289
            ) || warn "no letter of type '$params->{letter_code}' found for borrowernumber $borrowernumber. Please see sample_notices.sql";
290
291
            next unless $letter;
292
293
            C4::Letters::EnqueueLetter({
294
                letter                 => $letter,
295
                borrowernumber         => $borrowernumber,
296
                from_address           => $from_address,
297
                message_transport_type => $transport
298
            });
151
        }
299
        }
152
    }
300
    }
153
}
301
}
154
- 

Return to bug 18532