RSS Git Download  Clone
Raw Blame History
#!/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);
}