From 7943e3a594f2768ae7473356a792aa63bd7a1654 Mon Sep 17 00:00:00 2001 From: erickson Date: Thu, 10 Aug 2006 21:28:11 +0000 Subject: [PATCH] moved to new module, cleaned up, abastracted more git-svn-id: svn://svn.open-ils.org/ILS/trunk@5445 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- .../OpenILS/Application/Circ/HoldNotify.pm | 325 +++++++++++++++++++++ 1 file changed, 325 insertions(+) create mode 100644 Open-ILS/src/perlmods/OpenILS/Application/Circ/HoldNotify.pm diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ/HoldNotify.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ/HoldNotify.pm new file mode 100644 index 0000000000..3b857f7a6e --- /dev/null +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ/HoldNotify.pm @@ -0,0 +1,325 @@ +# --------------------------------------------------------------- +# Copyright (C) 2005 Georgia Public Library Service +# Bill Erickson + +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# --------------------------------------------------------------- + + +package OpenILS::Application::Circ::HoldNotify; +use base qw/OpenSRF::Application/; +use strict; use warnings; +use OpenSRF::EX qw(:try); +use vars q/$AUTOLOAD/; +use OpenILS::Event; +use OpenSRF::Utils::Logger qw(:logger); +use OpenILS::Utils::CStoreEditor q/:funcs/; +use OpenSRF::Utils::SettingsClient; +use OpenILS::Application::AppUtils; +use OpenILS::Const qw/:const/; +use OpenILS::Utils::Fieldmapper; +use Email::Send; +use Data::Dumper; +my $U = 'OpenILS::Application::AppUtils'; + + +__PACKAGE__->register_method( + method => 'send_email_notify_pub', + api_name => 'open-ils.circ.send_hold_notify.email', +); + + +sub send_email_notify_pub { + my( $self, $conn, $auth, $hold_id ) = @_; + my $e = new_editor(authtoken => $auth, xact =>1); + return $e->event unless $e->checkauth; + return $e->event unless $e->allowed('CREATE_HOLD_NOTIFICATION'); + my $notifier = __PACKAGE__->new(editor=> $e, hold_id => $hold_id); + return $notifier->event if $notifier->event; + my $stat = $notifier->send_email_notify; + $e->commit if $stat == '1'; + return $stat; +} + + + + + +# --------------------------------------------------------------- +# Define the notifier object +# --------------------------------------------------------------- + +my @AUTOLOAD_FIELDS = qw/ + hold + copy + volume + title + editor + patron + event + pickup_lib + smtp_server + settings_client +/; + +sub AUTOLOAD { + my $self = shift; + my $type = ref($self) or die "$self is not an object"; + my $data = shift; + my $name = $AUTOLOAD; + $name =~ s/.*://o; + + unless (grep { $_ eq $name } @AUTOLOAD_FIELDS) { + $logger->error("$type: invalid autoload field: $name"); + die "$type: invalid autoload field: $name\n" + } + + { + no strict 'refs'; + *{"${type}::${name}"} = sub { + my $s = shift; + my $v = shift; + $s->{$name} = $v if defined $v; + return $s->{$name}; + } + } + return $self->$name($data); +} + + +sub new { + my( $class, %args ) = @_; + $class = ref($class) || $class; + my $self = bless( {}, $class ); + $self->editor( ($args{editor}) ? $args{editor} : new_editor()); + $self->fetch_data($args{hold_id}); + return $self; +} + + +sub send_email_notify { + my $self = shift; + + $logger->info("hold_notify: attempting email notify on hold ".$self->hold->id); + + return OpenILS::Event->new('PATRON_NO_EMAIL_ADDRESS') + unless $self->patron->email and + $self->patron->email =~ /.+\@.+/; # see if it's remotely email-esque + + my $sclient = OpenSRF::Utils::SettingsClient->new; + $self->settings_client($sclient); + my $template = $sclient->config_value('email_notify', 'template'); + my $str = $self->flesh_template($self->load_template($template)); + + unless( $str ) { + $logger->error("No email notifiy template found - cannot notify"); + return 0; + } + + $logger->info("hold_notify: fleshed template: $str"); + + $self->send_email($str); + + my $notify = Fieldmapper::action::hold_notification->new; + $notify->hold($self->hold->id); + $notify->notify_staff($self->editor->requestor->id); + $notify->notify_time('now'); + $notify->method('email'); + + $self->editor->create_action_hold_notification($notify) + or return $self->editor->event; + + return 1; +} + +sub send_email { + my( $self, $text ) = @_; + + my $smtp = $self->settings_client->config_value('email_notify', 'smtp_server'); + + $logger->info("hold_notify: sending email notice to ". + $self->patron->email." with SMTP server $smtp"); + + my $sender = Email::Send->new({mailer => 'SMTP'}); + $sender->mailer_args([Host => $smtp]); + my $stat = $sender->send($text); + + if( $stat->type eq 'success' ) { + $logger->info("hold_notify: successfully sent hold notification"); + return 1; + } else { + $logger->warn("hold_notify: unable to send hold notification: ".Dumper($stat)); + return 0; + } + + return undef; +} + + +# ------------------------------------------------------------------------- +# Fetches all of the hold-related data +# ------------------------------------------------------------------------- +sub fetch_data { + my $self = shift; + my $holdid = shift; + my $e = $self->editor; + + $self->hold($e->retrieve_action_hold_request($holdid)) or $self->event($e->event); + $self->copy($e->retrieve_asset_copy($self->hold->current_copy)) or $self->event($e->event); + $self->volume($e->retrieve_asset_call_number($self->copy->call_number)) or $self->event($e->event); + $self->title($e->retrieve_biblio_record_entry($self->volume->record)) or $self->event($e->event); + $self->patron($e->retrieve_actor_user($self->hold->usr)) or $self->event($e->event); + $self->pickup_lib($e->retrieve_actor_org_unit($self->hold->pickup_lib)) or $self->event($e->event); +} + + +sub extract_data { + my $self = shift; + my $e = $self->editor; + + my $patron = $self->patron; + my $o_name = $self->pickup_lib->name; + my $o_addr = $self->pickup_lib->holds_address; + my $p_name = $patron->first_given_name .' '.$patron->family_name; + + # try to find a suitable address for the patron + my $p_addr; + my $p_addrs; + unless( $p_addr = + $e->retrieve_actor_user_address($patron->billing_address)) { + unless( $p_addr = + $e->retrieve_actor_user_address($patron->mailing_address)) { + $logger->warn("No address for user ".$patron->id); + $p_addrs = ""; + } + } + + unless( defined $p_addrs ) { + $p_addrs = + $p_addr->street1."\n". + $p_addr->street2."\n". + $p_addr->city."\n". + $p_addr->state."\n". + $p_addr->post_code."\n"; + } + + my @time = localtime(); + my $day = $time[3]; + my $month = $time[4] + 1; + my $year = $time[5] + 1900; + + my $title; + my $author; + + if( $self->title->id == OILS_PRECAT_RECORD ) { + $title = ($self->copy->dummy_title) ? + $self->copy->dummy_title : ""; + $author = ($self->copy->dummy_author) ? + $self->copy->dummy_author : ""; + } else { + my $mods = $U->record_to_mvr($self->title); + $title = ($mods->title) ? $mods->title : ""; + $author = ($mods->author) ? $mods->author : ""; + } + + + return { + patron_email => $self->patron->email, + pickup_lib_name => $o_name, + pickup_lib_addr => $o_addr, + patron_name => $p_name, + patron_addr => $p_addrs, + title => $title, + author => $author, + call_number => $self->volume->label, + copy_barcode => $self->copy->barcode, + copy_number => $self->copy->copy_number, + }; +} + + + +sub load_template { + my $self = shift; + my $template = shift; + + unless( open(F, $template) ) { + $logger->error("Unable to open hold notification template file: $template"); + return undef; + } + + # load the template, strip comments + my @lines = ; + close(F); + + my $str = ''; + for(@lines) { + chomp $_; + next if $_ =~ /^\s*\#/o; + $_ =~ s/\#.*//og; + $str .= "$_\n"; + } + + return $str; +} + +sub flesh_template { + my( $self, $str ) = @_; + return undef unless $str; + + my @time = localtime(); + my $day = $time[3]; + my $month = $time[4] + 1; + my $year = $time[5] + 1900; + + my $data = $self->extract_data; + + my $email = $$data{patron_email}; + my $p_name = $$data{patron_name}; + my $p_addr = $$data{patron_addr}; + my $o_name = $$data{pickup_lib_name}; + my $o_addr = $$data{pickup_lib_addr}; + my $title = $$data{title}; + my $author = $$data{author}; + my $cn = $$data{call_number}; + my $barcode = $$data{copy_barcode}; + my $copy_number = $$data{copy_number}; + + my $sender = $self->settings_client->config_value('email_notify', 'sender_address'); + #my $reply_to = $self->pickup_lib-> + my $reply_to = $sender; # XXX + + + $str =~ s/\${EMAIL_SENDER}/$sender/; + $str =~ s/\${EMAIL_RECIPIENT}/$email/; + $str =~ s/\${EMAIL_REPLY_TO}/$reply_to/; + $str =~ s/\${EMAIL_HEADERS}/\n\r\n\r/; + + $str =~ s/\${DATE}/$year-$month-$day/; + $str =~ s/\${LIBRARY}/$o_name/; + $str =~ s/\${LIBRARY_ADDRESS}/$o_addr/; + $str =~ s/\${PATRON_NAME}/$p_name/; + $str =~ s/\${PATRON_ADDRESS}/$p_addr/; + + $str =~ s/\${TITLE}/$title/; + $str =~ s/\${AUTHOR}/$author/; + $str =~ s/\${CALL_NUMBER}/$cn/; + $str =~ s/\${COPY_BARCODE}/$barcode/; + $str =~ s/\${COPY_NUMBER}/$copy_number/; + + return $str; +} + + + + + +1; -- 2.11.0