# updates hilis4.request_storage dna concentrations from xl src in
# "I:\MiSeq\Myeloid\HILIS concentration upload" and adds comment to
# request_lab_test_history
# usage: perl storage_dna_update.pl -f [-t] MiSeq_Myeloid_20xx_xx_upload.xlsx
use Getopt::Std;
getopts('f:t'); # filename, testing
our($opt_f, $opt_t); # warn $opt_t; exit;
use lib '/home/raj/perl-lib';
use FindBin qw($Bin); # warn $Bin;
use Data::Printer alias => 'p', use_prototypes => 1;
use Math::Round qw(round);
use Spreadsheet::Read;
use Local::DB;
use Modern::Perl;
use IO::All;
#===============================================================================
my $db = 'hilis4';
my $src = $opt_f or die 'require source filename'; # p $src;
my $JUST_TESTING = $opt_t || 0; # prints update but doesn't do it
#===============================================================================
my $dbix = Local::DB->dbix({ dbname => 'hilis4' });
$dbix->lc_columns = 0; # vialId
my $xls = ReadData($Bin . '/' . $src); # p $xls;
my $log = $src =~ s/xlsx$/log/r; # p $log; # r = non-destructive;
my $sheet = $xls->[1]; # p $sheet; # 1st sheet
# rows() not exported so call as fully qualified method:
my @rows = Spreadsheet::Read::rows($sheet); # p @rows; # AoA
my $headers = shift @rows;
$_ =~ s/\s/_/ for @$headers;
$_ =~ s/(\w+)/lc $1/eg for @$headers; # p $headers; exit;
my $request_query = q!select r.id, p.last_name from hilis4.requests r join
patient_case pc on r.patient_case_id = pc.id join patients p on
pc.patient_id = p.id where request_number = ? and year = ?!;
my $storage_query = qq!select vialId, concentration from $db.request_storage
where request_id = ? and specimen_id = ?!;
my $specimen_map = $dbix->select('specimens', ['sample_code','id'])->map; # p $specimen_map;
my $user_id; # set inside block
my $i = 0; # update success counter
ROW:
for my $row (@rows) { # arrayref
my $data = _to_hash($row); # p $data; next;
# get user - may only occur once in spreadsheet, needs to be 1st row:
if ( my $user = trim($data->{user}) ) {
$user_id ||= $dbix->select('users', 'id', { username => $user})->value
or die "cannot find user_id for user $user"; # p $user_id;
}
# check we have a valid user_id:
defined $user_id || die 'cannot find a valid user_id';
# get request_number & year from sample col:
my ($req_num, $yr) = $data->{sample} =~ m!H?(\d+)/(\d{2})!; # p $req_num; p $yr;
# get request_id & last_name from hilis4 db:
my ($req_id, $last_name)
= $dbix->query($request_query, $req_num, $yr + 2000)->row; # p $req_id; p $last_name;
unless ( lc $last_name eq lc trim($data->{last_name}) ) {
my $msg = sprintf "request %s/%s last name mismatch (%s, %s)",
$req_num, $yr, $last_name, $data->{last_name};
$JUST_TESTING
? say $msg
: io($Bin . '/'. $log)->append($msg . "\n");
next ROW;
}
# get specimen from specimen col & get specimen_id from hilis4:
my $specimen = trim($data->{specimen}); # p $specimen;
my $specimen_id = $specimen_map->{$specimen} or
say qq!don't recognise "$specimen"! and next ROW;
# get concentration result from xl col:
my $new_value = round($data->{concentration}); # p $concentration;
# get db request_storage vialId & current value for request_id/specimen:
my ($vialId, $old_value)
= $dbix->query($storage_query, $req_id, $specimen_id)->row;
unless ( $vialId && $old_value ) {
my $msg = sprintf "request %s/%s does not have %s stored",
$req_num, $yr, $specimen;
$JUST_TESTING
? say $msg
: io($Bin . '/'. $log)->append($msg . "\n");
next ROW;
}
# end of block if just testing:
say "will update $req_num/$yr $vialId/$specimen $old_value -> $new_value"
and next ROW if $JUST_TESTING;
{ # update request_storage table:
my $result = $dbix->update("$db.request_storage",
{ concentration => $new_value },
{ vialId => $vialId, part_number => 1 });
unless ( $result->rows ) {
my $msg = sprintf "request %s/%s failed to update with %s/%s",
$req_num, $yr, $specimen, $new_value;
$JUST_TESTING
? say $msg
: io($Bin . '/'. $log)->append($msg . "\n");
next ROW;
}
my $msg = sprintf "updated request %s/%s %s DNA concentration from %s to %s",
$req_num, $yr, $specimen, $old_value, $new_value;
io($Bin . '/'. $log)->append($msg . "\n");
$i += $result->rows;
}
{ # do request_lab_test_history:
my %h = (
request_id => $req_id,
user_id => $user_id,
action => "batch-updated $specimen storage vial DNA concentration value",
);
my $result = $dbix->insert("$db.request_lab_test_history", \%h);
unless ( $result->rows ) {
my $msg = sprintf
"failed to update request_lab_test_history for request %s/%s",
$req_num, $yr;
}
}
}
say sprintf "updated %s of %s rows", $i, scalar @rows;
sub trim {
local $_ = shift || return;
$_ =~ s/^\s+|\s+$//g;
return $_;
}
sub _to_hash {
my $ref = shift; # p $ref; # arrayref
my %h;
my $i = 0;
for (@$headers) { # p $_;
$h{$_} = $ref->[$i++];
} # p %h;
return \%h;
}