#!/usr/bin/env perl # alerts Outreach admins of low blood counts for Outreach patients # requires heamatology result to be available at time of screening # runs every 3 hrs #=============================================================================== my @recipients = qw(rawstron martin raj detute); my $low_neutr_threshold = 10; # equivalent to 1.0 my $low_plt_threshold = 50; my $low_hb_threshold = 100; #=============================================================================== use strict; use warnings; use lib '/home/raj/perl5/lib/perl5'; use FindBin qw($Bin); # warn $Bin; exit; use Getopt::Std; use Data::Printer; use SQL::Abstract::More; use lib ("$Bin/../../../lib", '/home/raj/perl-lib'); use LIMS::Local::ScriptHelpers; getopts('d:qt:'); # duration (hours), query output, testing our($opt_d,$opt_t,$opt_q); # warn $opt_d; exit; # emails only raj: my $JUST_TESTING = $opt_t || 0; my $duration = $opt_d || 3; # hours my $query_output = $opt_q; # get tools from LIMS::Local::ScriptHelpers: my $tools = LIMS::Local::ScriptHelpers->new(); $tools->test_only($JUST_TESTING); my $config = $tools->config(); my $dbix = $tools->dbix; my ($sql, @bind) = _get_query(); # p $sql; p @bind; my @results = $dbix->query($sql, @bind)->arrays; # p @results; exit; exit unless @results; for my $aref (@results) { my ($request_number, $year, $hb, $plts, $neutr) = @$aref; my $labno = join '/', $request_number, $year - 2000; my $message = sprintf '%s: Hb = %s, Plts = %s, Neutr = %s', $labno, int $hb, int $plts, $neutr ne '*000' ? ( sprintf '%.1f', $neutr / 10 ) : 'FAIL'; # p $message; my %mail = ( subject => 'Outreach patient low blood count alert', message => $message, config => $config, ); # p %mail; $tools->send_mail(\%mail, \@recipients); } sub _get_query { # request_haematology table vars don't work in placeholders - WTF?? #=begin return qq! SELECT r.request_number, r.`year`, rh2.hb, rh2.plt, rh2.neutr FROM requests r JOIN request_initial_screen ris ON ris.request_id = r.id JOIN screens s ON ris.screen_id = s.id JOIN request_history rh1 ON rh1.request_id = r.id JOIN request_haematology rh2 ON rh2.lab_number = CONCAT( r.`year` - 2000, '_', LPAD(r.request_number, 5, 0) ) WHERE rh1.`action` = 'screened' AND rh1.`time` >= DATE_SUB(NOW(), INTERVAL ? HOUR) AND s.description RLIKE 'Outreach' /* to accommodate Outreach CML, etc */ AND ( rh2.hb < $low_hb_threshold OR rh2.plt < $low_plt_threshold OR ( rh2.neutr <> '*000' AND rh2.neutr < $low_neutr_threshold ) )!, $duration; #=cut # this does not work - rh2 table variables are ignored in placeholders, # either when generated by SQLA or supplied direct as a query statement: my $rh_tbl_join = q!CONCAT(r.year - 2000, '_', LPAD(r.request_number,5,0))!; my $ref_time = $tools->time_now->subtract( hours => $duration ); my @cols = ('r.request_number', 'r.year', 'rh2.hb', 'rh2.plt', 'rh2.neutr'); my @rels = ( 'requests|r' , 'ris.request_id=r.id' => 'request_initial_screen|ris' , 'ris.screen_id = s.id' => 'screens|s' , 'rh1.request_id=r.id' => 'request_history|rh1' , { # need to use operator/condition for complex CONCAT: operator => '<=>', # options are <=>, <=, =>, == condition => { 'rh2.lab_number' => { # ident prevents addition to @bind: '=' => { -ident => $rh_tbl_join }, }, }, } => 'request_haematology|rh2' , ); my %where = ( 'rh1.action' => 'screened', 'rh1.time' => { '>=' => $ref_time }, 's.description' => { -rlike => 'Outreach' }, # to accommodate Outreach CML, etc -or => { 'rh2.hb' => { '<' => $low_hb_threshold }, 'rh2.plt' => { '<' => $low_plt_threshold }, -and => [ 'rh2.neutr' => { '!=' => '*000' }, 'rh2.neutr' => { '<' => $low_neutr_threshold }, ], }, ); my @args = ( -columns => \@cols, -from => [ -join => @rels ], -where => \%where, ); # p @args; my ($sql, @bind) = SQL::Abstract::More->new->select(@args); # p $sql; p \@bind; $dbix->dump_query($sql, @bind) if $query_output; # exit; return ($sql, @bind); }