-#!/usr/bin/perl -w
+#!/usr/bin/perl
# Copyright 2008 LibLime
#
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
-# You should have received a copy of the GNU General Public License along with
-# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
-# Suite 330, Boston, MA 02111-1307 USA
+# You should have received a copy of the GNU General Public License along
+# with Koha; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
=head1 NAME
use C4::Members;
use C4::Members::Messaging;
use C4::Overdues;
+use Koha::DateUtils;
# These are defaults for command line options.
my $nomail; # -n: No mail. Will not send any emails.
my $mindays = 0; # -m: Maximum number of days in advance to send notices
my $maxdays = 30; # -e: the End of the time period
-my $fromaddress = C4::Context->preference('KohaAdminEmailAddress'); # -f: From address for the emails
my $verbose = 0; # -v: verbose
+my $itemscontent = join(',',qw( issuedate title barcode author ));
-GetOptions( 'c' => \$confirm,
- 'n' => \$nomail,
- 'm:i' => \$maxdays,
- 'f:s' => \$fromaddress,
- 'v' => \$verbose,
+GetOptions( 'c' => \$confirm,
+ 'n' => \$nomail,
+ 'm:i' => \$maxdays,
+ 'v' => \$verbose,
+ 'itemscontent=s' => \$itemscontent,
);
my $usage = << 'ENDUSAGE';
the process_message_queue.pl cronjob.
See the comments in the script for directions on changing the script.
This script has the following parameters :
- -c Confirm and remove this help & warning
- -m maximum number of days in advance to send advance notices.
- -f from address for the emails. Defaults to KohaAdminEmailAddress system preference
- -n send No mail. Instead, all mail messages are printed on screen. Usefull for testing purposes.
- -v verbose
-
+ -c Confirm and remove this help & warning
+ -m maximum number of days in advance to send advance notices.
+ -n send No mail. Instead, all mail messages are printed on screen. Usefull for testing purposes.
+ -v verbose
ENDUSAGE
# Since advance notice options are not visible in the web-interface
}
+# The fields that will be substituted into <<items.content>>
+my @item_content_fields = split(/,/,$itemscontent);
warn 'getting upcoming due issues' if $verbose;
my $upcoming_dues = C4::Circulation::GetUpcomingDueIssues( { days_in_advance => $maxdays } );
my $upcoming_digest;
my $due_digest;
+my $dbh = C4::Context->dbh();
+my $sth = $dbh->prepare(<<'END_SQL');
+SELECT biblio.*, items.*, issues.*
+ FROM issues,items,biblio
+ WHERE items.itemnumber=issues.itemnumber
+ AND biblio.biblionumber=items.biblionumber
+ AND issues.borrowernumber = ?
+ AND issues.itemnumber = ?
+ AND (TO_DAYS(date_due)-TO_DAYS(NOW()) = ?)
+END_SQL
+
+my $admin_adress = C4::Context->preference('KohaAdminEmailAddress');
+
UPCOMINGITEM: foreach my $upcoming ( @$upcoming_dues ) {
warn 'examining ' . $upcoming->{'itemnumber'} . ' upcoming due items' if $verbose;
# warn( Data::Dumper->Dump( [ $upcoming ], [ 'overdue' ] ) );
-
+
+ my $from_address = $upcoming->{branchemail} || $admin_adress;
+
my $letter;
my $borrower_preferences;
if ( 0 == $upcoming->{'days_until_due'} ) {
# This item is due today. Send an 'item due' message.
$borrower_preferences = C4::Members::Messaging::GetMessagingPreferences( { borrowernumber => $upcoming->{'borrowernumber'},
- message_name => 'item due' } );
+ message_name => 'item_due' } );
# warn( Data::Dumper->Dump( [ $borrower_preferences ], [ 'borrower_preferences' ] ) );
- next DUEITEM unless $borrower_preferences;
+ next unless $borrower_preferences;
if ( $borrower_preferences->{'wants_digest'} ) {
# cache this one to process after we've run through all of the items.
- $due_digest->{$upcoming->{'borrowernumber'}}++;
+ my $digest = $due_digest->{$upcoming->{'borrowernumber'}} ||= {};
+ $digest->{email} ||= $from_address;
+ $digest->{count}++;
} else {
my $biblio = C4::Biblio::GetBiblioFromItemNumber( $upcoming->{'itemnumber'} );
my $letter_type = 'DUE';
- $letter = C4::Letters::getletter( 'circulation', $letter_type );
- die "no letter of type '$letter_type' found. Please see sample_notices.sql" unless $letter;
-
- $letter = parse_letter( { letter => $letter,
+ $sth->execute($upcoming->{'borrowernumber'},$upcoming->{'itemnumber'},'0');
+ my $titles = "";
+ while ( my $item_info = $sth->fetchrow_hashref()) {
+ my @item_info = map { $_ =~ /^date|date$/ ? format_date($item_info->{$_}) : $item_info->{$_} || '' } @item_content_fields;
+ $titles .= join("\t",@item_info) . "\n";
+ }
+
+ ## Get branch info for borrowers home library.
+ $letter = parse_letter( { letter_code => $letter_type,
borrowernumber => $upcoming->{'borrowernumber'},
- branchchode => $upcoming->{'branchcode'},
- biblionumber => $biblio->{'biblionumber'} } );
+ branchcode => $upcoming->{'branchcode'},
+ biblionumber => $biblio->{'biblionumber'},
+ itemnumber => $upcoming->{'itemnumber'},
+ substitute => { 'items.content' => $titles }
+ } )
+ or die "no letter of type '$letter_type' found. Please see sample_notices.sql";
}
} else {
$borrower_preferences = C4::Members::Messaging::GetMessagingPreferences( { borrowernumber => $upcoming->{'borrowernumber'},
- message_name => 'advance notice' } );
+ message_name => 'advance_notice' } );
# warn( Data::Dumper->Dump( [ $borrower_preferences ], [ 'borrower_preferences' ] ) );
next UPCOMINGITEM unless $borrower_preferences && exists $borrower_preferences->{'days_in_advance'};
next UPCOMINGITEM unless $borrower_preferences->{'days_in_advance'} == $upcoming->{'days_until_due'};
-
+
if ( $borrower_preferences->{'wants_digest'} ) {
# cache this one to process after we've run through all of the items.
- $upcoming_digest->{$upcoming->{'borrowernumber'}}++;
+ my $digest = $upcoming_digest->{$upcoming->{'borrowernumber'}} ||= {};
+ $digest->{email} ||= $from_address;
+ $digest->{count}++;
} else {
my $biblio = C4::Biblio::GetBiblioFromItemNumber( $upcoming->{'itemnumber'} );
my $letter_type = 'PREDUE';
- $letter = C4::Letters::getletter( 'circulation', $letter_type );
- die "no letter of type '$letter_type' found. Please see sample_notices.sql" unless $letter;
-
- $letter = parse_letter( { letter => $letter,
+ $sth->execute($upcoming->{'borrowernumber'},$upcoming->{'itemnumber'},$borrower_preferences->{'days_in_advance'});
+ my $titles = "";
+ while ( my $item_info = $sth->fetchrow_hashref()) {
+ my @item_info = map { $_ =~ /^date|date$/ ? format_date($item_info->{$_}) : $item_info->{$_} || '' } @item_content_fields;
+ $titles .= join("\t",@item_info) . "\n";
+ }
+
+ ## Get branch info for borrowers home library.
+ $letter = parse_letter( { letter_code => $letter_type,
borrowernumber => $upcoming->{'borrowernumber'},
- branchchode => $upcoming->{'branchcode'},
- biblionumber => $biblio->{'biblionumber'} } );
+ branchcode => $upcoming->{'branchcode'},
+ biblionumber => $biblio->{'biblionumber'},
+ itemnumber => $upcoming->{'itemnumber'},
+ substitute => { 'items.content' => $titles }
+ } )
+ or die "no letter of type '$letter_type' found. Please see sample_notices.sql";
}
}
# If we have prepared a letter, send it.
- if ( $letter ) {
- foreach my $transport ( @{$borrower_preferences->{'transports'}} ) {
+ if ($letter) {
+ if ($nomail) {
+ local $, = "\f";
+ print $letter->{'content'};
+ }
+ else {
+ foreach my $transport ( keys %{$borrower_preferences->{'transports'}} ) {
C4::Letters::EnqueueLetter( { letter => $letter,
borrowernumber => $upcoming->{'borrowernumber'},
+ from_address => $from_address,
message_transport_type => $transport } );
}
+ }
}
-
}
# warn( Data::Dumper->Dump( [ $upcoming_digest ], [ 'upcoming_digest' ] ) );
# Now, run through all the people that want digests and send them
-PATRON: while ( my ( $borrowernumber, $count ) = each %$upcoming_digest ) {
+
+$sth = $dbh->prepare(<<'END_SQL');
+SELECT biblio.*, items.*, issues.*
+ FROM issues,items,biblio
+ WHERE items.itemnumber=issues.itemnumber
+ AND biblio.biblionumber=items.biblionumber
+ AND issues.borrowernumber = ?
+ AND (TO_DAYS(date_due)-TO_DAYS(NOW()) = ?)
+END_SQL
+
+PATRON: while ( my ( $borrowernumber, $digest ) = each %$upcoming_digest ) {
+ my $count = $digest->{count};
+ my $from_address = $digest->{email};
+
my $borrower_preferences = C4::Members::Messaging::GetMessagingPreferences( { borrowernumber => $borrowernumber,
- message_name => 'advance notice' } );
+ message_name => 'advance_notice' } );
# warn( Data::Dumper->Dump( [ $borrower_preferences ], [ 'borrower_preferences' ] ) );
next PATRON unless $borrower_preferences; # how could this happen?
my $letter_type = 'PREDUEDGST';
- my $letter = C4::Letters::getletter( 'circulation', $letter_type );
- die "no letter of type '$letter_type' found. Please see sample_notices.sql" unless $letter;
- $letter = parse_letter( { letter => $letter,
- borrowernumber => $borrowernumber,
- substitute => { count => $count }
- } );
- foreach my $transport ( @{$borrower_preferences->{'transports'}} ) {
+ $sth->execute($borrowernumber,$borrower_preferences->{'days_in_advance'});
+ my $titles = "";
+ while ( my $item_info = $sth->fetchrow_hashref()) {
+ my @item_info = map { $_ =~ /^date|date$/ ? format_date($item_info->{$_}) : $item_info->{$_} || '' } @item_content_fields;
+ $titles .= join("\t",@item_info) . "\n";
+ }
+
+ ## Get branch info for borrowers home library.
+ my %branch_info = get_branch_info( $borrowernumber );
+
+ my $letter = parse_letter( { letter_code => $letter_type,
+ borrowernumber => $borrowernumber,
+ substitute => { count => $count,
+ 'items.content' => $titles,
+ %branch_info,
+ }
+ } )
+ or die "no letter of type '$letter_type' found. Please see sample_notices.sql";
+ if ($nomail) {
+ local $, = "\f";
+ print $letter->{'content'};
+ }
+ else {
+ foreach my $transport ( keys %{$borrower_preferences->{'transports'}} ) {
C4::Letters::EnqueueLetter( { letter => $letter,
borrowernumber => $borrowernumber,
+ from_address => $from_address,
message_transport_type => $transport } );
+ }
}
}
# Now, run through all the people that want digests and send them
-PATRON: while ( my ( $borrowernumber, $count ) = each %$due_digest ) {
+PATRON: while ( my ( $borrowernumber, $digest ) = each %$due_digest ) {
+ my $count = $digest->{count};
+ my $from_address = $digest->{email};
+
my $borrower_preferences = C4::Members::Messaging::GetMessagingPreferences( { borrowernumber => $borrowernumber,
- message_name => 'item due' } );
+ message_name => 'item_due' } );
# warn( Data::Dumper->Dump( [ $borrower_preferences ], [ 'borrower_preferences' ] ) );
next PATRON unless $borrower_preferences; # how could this happen?
my $letter_type = 'DUEDGST';
- my $letter = C4::Letters::getletter( 'circulation', $letter_type );
- die "no letter of type '$letter_type' found. Please see sample_notices.sql" unless $letter;
- $letter = parse_letter( { letter => $letter,
- borrowernumber => $borrowernumber,
- substitute => { count => $count }
- } );
+ $sth->execute($borrowernumber,'0');
+ my $titles = "";
+ while ( my $item_info = $sth->fetchrow_hashref()) {
+ my @item_info = map { $_ =~ /^date|date$/ ? format_date($item_info->{$_}) : $item_info->{$_} || '' } @item_content_fields;
+ $titles .= join("\t",@item_info) . "\n";
+ }
+
+ ## Get branch info for borrowers home library.
+ my %branch_info = get_branch_info( $borrowernumber );
- foreach my $transport ( @{$borrower_preferences->{'transports'}} ) {
+ my $letter = parse_letter( { letter_code => $letter_type,
+ borrowernumber => $borrowernumber,
+ substitute => { count => $count,
+ 'items.content' => $titles,
+ %branch_info,
+ }
+ } )
+ or die "no letter of type '$letter_type' found. Please see sample_notices.sql";
+
+ if ($nomail) {
+ local $, = "\f";
+ print $letter->{'content'};
+ }
+ else {
+ foreach my $transport ( keys %{$borrower_preferences->{'transports'}} ) {
C4::Letters::EnqueueLetter( { letter => $letter,
borrowernumber => $borrowernumber,
+ from_address => $from_address,
message_transport_type => $transport } );
+ }
}
}
=head2 parse_letter
-
-
=cut
sub parse_letter {
my $params = shift;
- foreach my $required ( qw( letter borrowernumber ) ) {
+ foreach my $required ( qw( letter_code borrowernumber ) ) {
return unless exists $params->{$required};
}
- if ( $params->{'substitute'} ) {
- while ( my ($key, $replacedby) = each %{$params->{'substitute'}} ) {
- my $replacefield = "<<$key>>";
-
- $params->{'letter'}->{title} =~ s/$replacefield/$replacedby/g;
- $params->{'letter'}->{content} =~ s/$replacefield/$replacedby/g;
- }
+ my %table_params = ( 'borrowers' => $params->{'borrowernumber'} );
+
+ if ( my $p = $params->{'branchcode'} ) {
+ $table_params{'branches'} = $p;
+ }
+ if ( my $p = $params->{'itemnumber'} ) {
+ $table_params{'issues'} = $p;
+ $table_params{'items'} = $p;
+ }
+ if ( my $p = $params->{'biblionumber'} ) {
+ $table_params{'biblio'} = $p;
+ $table_params{'biblioitems'} = $p;
}
- C4::Letters::parseletter( $params->{'letter'}, 'borrowers', $params->{'borrowernumber'} );
+ return C4::Letters::GetPreparedLetter (
+ module => 'circulation',
+ letter_code => $params->{'letter_code'},
+ branchcode => $table_params{'branches'},
+ substitute => $params->{'substitute'},
+ tables => \%table_params,
+ );
+}
- if ( $params->{'branchcode'} ) {
- C4::Letters::parseletter( $params->{'letter'}, 'branches', $params->{'branchcode'} );
- }
-
- if ( $params->{'biblionumber'} ) {
- C4::Letters::parseletter( $params->{'letter'}, 'biblio', $params->{'biblionumber'} );
- C4::Letters::parseletter( $params->{'letter'}, 'biblioitems', $params->{'biblionumber'} );
+sub format_date {
+ my $date_string = shift;
+ my $dt=dt_from_string($date_string);
+ return output_pref($dt);
+}
+
+=head2 get_branch_info
+
+=cut
+
+sub get_branch_info {
+ my ( $borrowernumber ) = @_;
+
+ ## Get branch info for borrowers home library.
+ my $borrower_details = C4::Members::GetMember( borrowernumber => $borrowernumber );
+ my $borrower_branchcode = $borrower_details->{'branchcode'};
+ my $branch = C4::Branch::GetBranchDetail( $borrower_branchcode );
+ my %branch_info;
+ foreach my $key( keys %$branch ) {
+ $branch_info{"branches.$key"} = $branch->{$key};
}
- return $params->{'letter'};
+ return %branch_info;
}
1;