#!/usr/bin/perl =begin ------------------------------------------------------------------------- Compiles & emails authorised (or amended) reports as PDF attachments for locations specified in email_contacts table, where 'type' col is set to 'report' Required entries must be in email_contacts table (doesn't use lib/contacts.lib as most of addresses are the same as for mdt contact), with 'type' col set to 'report'. Also requires entries in %report_status map, and %departments if required - see config section below. Scope = organisation, hospital or department. If set to 'organisation', records are retrieved using parent_organisation_id; if scope set to 'department', expects entry in %departments map to provide hospital_department.display_name to filter on; if set to hospital, uses the referral_source_id to retrieve records Uses LIMS::Controller::Roles::format_report() to generate PDF reports, via LIMS::Local::Reports to provide methods - render_view(), model(), etc - required by LIMS methods =cut --------------------------------------------------------------------------- use strict; use warnings; my $JUST_TESTING = 1; # skips history file update, emails just raj ################################################################################ use constant APP_URL => 'http://localhost:8080/hmds'; # # app address - for charts my %departments = ( # key = email_contacts.id, value = hospital_departments.display_name # tbl.id | display_name: 25 => 'histopathology', 26 => 'histopathology', 27 => 'histopathology', 28 => 'histopathology', ); my %report_status = ( # key = email_contacts.id, value = new or all (diagnoses) # tbl.id | rpt_status: 18 => 'all', 19 => 'all', 20 => 'new', 21 => 'new', 22 => 'all', 23 => 'all', 24 => 'all', 25 => 'all', 26 => 'all', 27 => 'all', 28 => 'all', ); my $delta = 1; # days ago - 1 for production ################################################################################ BEGIN { use FindBin qw($Bin); # warn $Bin; exit; use lib ( "$Bin/../../../lib", '/home/raj/perl5/lib/perl5', ); # override default db test: $ENV{ROSEDB_DEVINIT} = "$Bin/../../../config/rosedb_devinit_prod.pl"; } use IO::All; use Config::Auto; use Data::Dumper; use DateTime::Format::MySQL; use LIMS::Local::Reports; use LIMS::Local::ScriptHelpers; my $cfg_file = "$Bin/../lib/settings.cfg"; my $settings = Config::Auto::parse($cfg_file); # warn Dumper $settings; # get tools from LIMS::Local::ScriptHelpers: my $tools = LIMS::Local::ScriptHelpers->new(); my $sql_lib = $tools->sql_lib(); my $config = $tools->config(); my $dbix = $tools->dbix(); my $today = $tools->time_now(); my $date = $today->subtract( days => $delta )->ymd; # warn $date; # substitutes LIMS methods required by Role::RecordHandler : my $lims = LIMS::Local::Reports->new({tools => $tools}); $lims->tt_params( app_url => APP_URL ); # for charts # common vars for email message: my %mail = ( config => $config, ); # go: { # get contents of email_contacts table: my $email_contacts = get_email_contacts(); # AoH # get base query, appended with restriction depending on scope (dept, hospital, organisation) my $base_sql = $sql_lib->retr('mail_reports_request_ids'); # get list of request_ids to send to compile_reports(): ENTRY: # loop through each contact and get request_id's as required: for my $recipient (@$email_contacts) { # warn Dumper $recipient; next ENTRY unless $recipient->{is_active} eq 'yes'; my $email_address = $recipient->{contact_address}; my $ref_src_id = $recipient->{referral_source_id}; my $entry_id = $recipient->{id}; # email_contacts.id my $scope = $recipient->{scope}; # dept, hospital or organisation # copy of $base_sql initial state (gets modified inside blocks): my $local_sql = $base_sql; my @bind = ($date); # re-initialise with $date - universally required # reports can be for department, hospital or organisation: if ( $scope eq 'department' ) { # add restrictions: $local_sql .= q! AND rs.id = ? AND hd.display_name = ?!; my $department = $departments{$entry_id} # warn $department; || die "cannot find data for email_contacts.id = $entry_id"; push @bind, ($ref_src_id, $department); } elsif ( $scope eq 'organisation' ) { # add restrictions: $local_sql .= q! AND rd.parent_organisation_id = ?!; # find parent_organisation of ref_src_id: my $sql = q!select parent_organisation_id from referral_sources where id = ?!; $dbix->query( $sql, $ref_src_id )->into( my $parent_org_id ); push @bind, $parent_org_id; } elsif ( $scope eq 'hospital' ) { # add restrictions: $local_sql .= q! AND rs.id = ?!; push @bind, $ref_src_id; } else { die "unknown scope: $scope" } # restrict to new reports only if required: my $require_new_only = get_required_report_status($entry_id); if ($require_new_only) { # restrict to new reports if required $local_sql .= q! AND rr.status = 'new'!; } my $request_ids = $dbix->query($local_sql, @bind)->flat; compile_reports($email_address, $request_ids) if @$request_ids; } # compile_reports('ra.jones@nhs.net', [139936]); # has chart } { # tidy up cgisess files in /tmp from LIMS::Local::Reports session() my @files = io('/tmp')->all_files; # get all files in /tmp map $_->unlink, grep $_->filename =~ /\Acgisess_/, @files; } sub compile_reports { my ($email_address, $request_ids) = @_; for my $request_id (@$request_ids) { # warn $request_id; my $report = $lims->format_report($request_id); # L::C::Roles::RecordHandler # $report > io("reports/$request_id.pdf"); my $data = $lims->model('Request')->get_referrer_department($request_id); my $referrer_department = $data->{referrer_department}; my $subject = sprintf 'HMDS Report for %s / %s', $referrer_department->{hospital_department}->{display_name}, # speciality $referrer_department->{referrer}->{name}, # referrer my $filename = sprintf '%02d_%05d.pdf', $data->{year} - 2000, $data->{request_number}; $mail{attachment} = $report; $mail{recipient} = $email_address; $mail{filename} = $filename; $mail{subject} = $subject; # warn Dumper \%mail; dispatch_report({ request_id => $request_id, message => \%mail }); } } sub dispatch_report { my $args = shift; my $request_id = $args->{request_id}; my $message = $args->{message}; # my $rtn = LIMS::Model::Email->send_attachment($message); # returns hashref: # if ($rtn->{success}) { # print "$0 reports " . lc $rtn->{message} . " to $email_address\n"; my %data = ( request_id => $request_id, recipient => $message->{recipient}, ); { # log details in request_dispatch_log & request_history tables: my $rtn = $lims->model('Request')->update_request_dispatch_log(\%data); warn "Error in $0: $rtn" if $rtn; } # } # else { # warn $rtn->{message}; # email_admin('foo'); # } } sub get_email_contacts { my $sql = q!select * from email_contacts where type = 'report'!; my $email_contacts = $dbix->query($sql)->hashes; # warn Dumper $email_contacts; return $email_contacts; } sub get_required_report_status { my $id = shift; my $status = $report_status{$id} || die "cannot find data for email_contacts.id = $id"; return ($status eq 'new'); # returns true if report_status = 'new' }