package LIMS::Controller::Roles::DataMap;
use Sort::Naturally;
use Data::Dumper;
use Moose::Role;
# most methods take arrayref of request_ids, return hashref of request.id => function
#-------------------------------------------------------------------------------
# maps request to its specimen(s) via request.id => [ sample_code ]
sub specimen_map {
my $self = shift;
my $request_ids = shift; # arrayref of request_ids
return undef unless @$request_ids; # or will die in get_request_specimens();
# get request_specimen object, ie:
# SELECT * FROM request_specimen, specimens WHERE request_id IN (@$request_ids)
my $rs = $self->model('Specimen')->get_request_specimens($request_ids);
# create specimen_map of keys = request_id, vals = [ sample_code(s) ]
my %specimen_map;
foreach my $request_specimen( @{ $rs } ) {
my $request_id = $request_specimen->request_id;
my $sample_code = $request_specimen->specimen->sample_code;
my $description = $request_specimen->specimen->description;
# create request_id key with empty hashref (if not aleady exists):
$specimen_map{ $request_id } ||= {}; # not strictly necessary though
# sample_code:
push @{ $specimen_map{$request_id}{sample_code} }, $sample_code;
# description:
push @{ $specimen_map{$request_id}{description} }, $description;
}
return \%specimen_map
}
# ------------------------------------------------------------------------------
sub request_status_options_map {
my $self = shift;
my $status_options = LIMS::DB::StatusOption::Manager->get_status_options;
my %map = map {
$_->description => $_->as_tree;
} @$status_options;
return \%map;
}
# ------------------------------------------------------------------------------
# return hashref of { request_id => $request_options }:
sub request_options_map {
my ($self, $request_ids) = @_;
my %map = ();
my $ro = $self->model('Request')->get_request_options($request_ids);
foreach my $request_option( @{ $ro } ) {
next unless $request_option->option->is_active eq 'yes';
my $request_id = $request_option->request_id;
my $option = $request_option->option->option_name;
$map{$request_id}{$option} = 1;
} # $self->debug(\%map);
return \%map;
}
# ------------------------------------------------------------------------------
sub report_error_codes_map {
my $self = shift;
my $error_codes = $self->model('Base')->get_objects('ReportErrorCode');
my %map = map {
$_->code => $_->as_tree;
} @$error_codes;
return \%map;
}
# ------------------------------------------------------------------------------
sub diagnosis_context_warning_map {
my $self = shift;
my $o = $self->model('Diagnosis')->get_diagnosis_context_warnings;
my %map = map {
$_->diagnosis_id => $_->context_warning->description;
} @$o;
return \%map;
}
# ------------------------------------------------------------------------------
sub panel_lab_test_map {
my $self = shift;
my %map;
my $data = $self->model('Base')->get_objects('PanelLabTest');
for (@$data) {
my $panel_test_id = $_->panel_test_id;
my $lab_test_id = $_->lab_test_id;
$map{$panel_test_id}{$lab_test_id}++;
}
return \%map;
}
# ------------------------------------------------------------------------------
sub usernames_map {
my $self = shift;
my $users = $self->model('Base')->get_objects('User');
my %map = map {
$_->id => $_->as_tree;
} @$users;
return \%map;
}
# ------------------------------------------------------------------------------
sub user_locations_map { # get list of locations from user_locations table:
my $self = shift;
my $locations = $self->model('Base')->get_objects('UserLocation');
my %map = map {
$_->location_name => $_->region_code;
} grep { $_->region_code } @$locations;
return \%map;
=begin # using email_contacts table to find local network locations:
my $locations = $self->model('ReferralSource')->get_email_contacts;
my %locations_map = map {
# get 1st 3 chars of organisation_code if it's an organisation:
my $org_code = $_->scope eq 'organisation'
? substr $_->referral_source->organisation_code, 0, 3
: $_->referral_source->organisation_code; # else full 5 chars
$_->display_name => $org_code;
} grep $_->scope ne 'department', @$locations; # skip depts.
# warn Dumper \%locations_map;
return \%locations_map;
=cut
}
# ------------------------------------------------------------------------------
sub user_functions_map {
my $self = shift;
my $functions = $self->model('User')->get_user_functions;
my %map = map +($_->id => $_->function_detail), @$functions;
return \%map;
}
# ------------------------------------------------------------------------------
sub lab_test_status_for_field_label_map {
my $self = shift;
my $args = shift; # warn Dumper $args;
my $request_ids = $args->{request_ids};
my $field_label = $args->{field_label}; # warn Dumper $field_label;
my %status_map; # hash of request.id's => { $status => 1 }
my $lab_name = $self->cfg('settings')->{lab_name_abbreviation};
my $users = $self->model('User')->get_users_for_location($lab_name);
my @usernames = map { uc $_->username } @$users; # warn Dumper \@usernames;
my $test_status = sub {
my ($history, $test) = @_; # warn $entry; warn $test;
my $expr = qr{set $test status to (.*)};
if ( my ($status) = $history->action =~ $expr ) { # warn $status;
# remove 'for USERNAME' if exists:
map { $status =~ s/(\sfor\s$_)\Z// } @usernames;
return $status;
}
};
REQUEST:
for my $id (@$request_ids) { # warn $id;
my $history = $self->model('History')->get_lab_test_history($id);
HISTORY: # is arrayref:
for my $entry (@$history) { # warn $_->action;
if (ref $field_label eq 'ARRAY') { # warn 'ARRAY';
LBL:
for my $lbl (@$field_label) { # warn $lbl;
my $status = &$test_status($entry, $lbl) || next LBL;
$status_map{$id}{$lbl}{$status}++;
}
}
else {
my $status = &$test_status($entry, $field_label) || next HISTORY;
$status_map{$id}{$status}++;
}
}
} # warn Dumper \%status_map;
return \%status_map;
}
# ------------------------------------------------------------------------------
sub lab_test_status_options_map {
my $self = shift;
my $key = shift; # which col to use as key
my $status_options = # OK until need to target options to section:
$self->model('Base')->get_objects('LabTestStatusOption');
my %map = map {
$_->$key => $_->as_tree;
} @$status_options;
return \%map;
}
# ------------------------------------------------------------------------------
sub request_history_map {
my ($self, $request_id) = @_;
my $request_history
= $self->model('History')->get_request_history($request_id);
my %map = map {
$_->action => $_->as_tree(deflate => 0); # or datetime object converted to scalar
} @$request_history;
return \%map;
}
# ------------------------------------------------------------------------------
sub request_section_notes_map {
my ($self, $request_ids) = @_;
my $lab_section = $self->stash->{lab_section}; # $self->debug($lab_section);
# does section have lab_test_details?
return unless $lab_section->has_section_notes eq 'yes';
# set template flag:
$self->tt_params(section_has_test_details => 1);
my %map = ();
my $o = $self->model('Request')->get_section_notes($request_ids);
foreach my $row( @{ $o } ) {
next unless $row->lab_section_id == $lab_section->id;
my $request_id = $row->request_id;
$map{$request_id} = $row->details;
}
return \%map;
}
# ------------------------------------------------------------------------------
sub time_duration_map {
my $self = shift;
my $data = shift;
my %map = map {
my $duration = $_->created_at->delta_days(DateTime->today)->delta_days;
$_->id => $duration;
} @$data; # $self->debug(\%map);
return \%map;
}
# ------------------------------------------------------------------------------
sub lab_tests_map {
my $self =shift;
my $lab_tests = $self->model('LabTest')->get_lab_tests;
my %map = map {
$_->id => $_->field_label;
} @$lab_tests;
return \%map;
}
#-------------------------------------------------------------------------------
sub lab_sections_map {
my $self = shift;
my $lab_sections = $self->model('Base')->get_objects('LabSection');
my %map = map {
$_->section_name => $_->as_tree;
} @$lab_sections;
return \%map;
}
#-------------------------------------------------------------------------------
sub lab_test_data_type_map {
my $self = shift;
my $lab_test_data_type = $self->model('LabTest')->get_lab_test_data_types;
$self->stash( lab_test_data_type => $lab_test_data_type ); # stash for later
# create hash of label => id for each lab_test_id in lab_test_data_type table:
my %map;
map {
my $test_id = $_->lab_test_id;
my $label = $_->lab_test->field_label;
$map{$test_id}{data_type}{type} = $_->data_type->description;
$map{$test_id}{data_type}{id} = $_->data_type_id;
$map{$test_id}{field_label} = $label;
} @$lab_test_data_type;
return \%map;
}
#-------------------------------------------------------------------------------
sub lab_test_data_types_map {
my $self = shift;
my $data_types = $self->model('LabTest')->get_lab_test_data_types;
my %map = map {
$_->lab_test_id => {
id => $_->data_type_id,
description => $_->data_type->description,
};
} @$data_types;
return \%map;
}
#-------------------------------------------------------------------------------
sub section_resultable_lab_tests_map {
my $self = shift;
my $lab_test_data_type = $self->stash->{lab_test_data_type};
my %map;
foreach (@$lab_test_data_type) {
my $section_name = $_->lab_test->lab_section->section_name;
my $test_label = $_->lab_test->field_label;
my $lab_test_id = $_->lab_test_id;
$map{$section_name}{$test_label} = $lab_test_id;
}
return \%map;
}
#-------------------------------------------------------------------------------
sub lab_test_result_options_map {
my $self = shift;
my $options = $self->model('LabTest')->get_lab_test_result_options;
# create hash of data_type_id => sorted array(ref) of lab_test_result_options:
my %options_map = my %sorted_options_map = ();
map {
my $data_type_id = $_->data_type_id;
$options_map{$data_type_id}{$_->value} = $_->as_tree;
} @$options; # warn Dumper \%options_map;
# sort options into alphanumeric order for template:
while ( my ($id, $data ) = each %options_map ) { # warn Dumper $data;
my @opts = keys %$data; # warn Dumper \@opts;
my @sorted_opts = Sort::Naturally::nsort(@opts); # warn Dumper \@sorted_opts;
$sorted_options_map{$id} = [ @{$data}{@sorted_opts} ]; # ref to array of sorted opts
} # warn Dumper \%sorted_options_map;
return \%sorted_options_map;
}
#-------------------------------------------------------------------------------
sub diagnoses_categories_map {
my $self = shift;
my $diagnoses = $self->model('Diagnosis')->get_all_diagnoses;
my %map;
map {
my $category = $_->diagnostic_category->description;
my %data = (
id => $_->id,
name => $_->name,
active => $_->active,
);
push @{ $map{$category} }, \%data;
} @$diagnoses;
return \%map;
}
#-------------------------------------------------------------------------------
sub diagnoses_map {
my $self = shift;
my $key = shift;
my $diagnoses = $self->model('Diagnosis')->get_all_diagnoses;
my %map = map {
$_->$key => $_->as_tree;
} @$diagnoses;
return \%map;
}
#-------------------------------------------------------------------------------
sub section_notes_map {
my ($self, $request_id) = @_;
my $request_section_notes
= $self->model('Request')->get_section_notes($request_id);
my %map = map {
$_->lab_section_id => $_->details;
} @$request_section_notes;
return \%map;
}
#-------------------------------------------------------------------------------
sub specimen_lab_test_map {
my $self = shift;
my $specimen_lab_tests = $self->model('Specimen')->get_specimen_lab_tests;
my %map;
while ( my $row = $specimen_lab_tests->next ) {
my $specimen_id = $row->specimen_id;
my $lab_test_id = $row->lab_test_id;
my $field_label = $row->lab_test->field_label;
# $map{$specimen_id}{lab_test_id} = $lab_test_id;
# $map{$specimen_id}{lab_test_name} = $o->lab_test->field_label;
push @{ $map{$specimen_id}{lab_test_names} }, $field_label;
push @{ $map{$specimen_id}{lab_test_ids} }, $lab_test_id;
}
return \%map;
}
#-------------------------------------------------------------------------------
sub lab_test_specimen_map {
my ($self, $lab_test_id) = @_;
my $o = $self->model('Specimen')->get_specimen_lab_tests;
# create hashref of lab_test_id => [ specimen_id(s) ]:
my %map;
while ( my $row = $o->next ) {
my $lab_test_id = $row->lab_test_id;
push @{ $map{$lab_test_id} }, $row->specimen->sample_code;
}
return \%map;
}
#-------------------------------------------------------------------------------
sub error_codes_map {
my $self = shift;
my $err_codes = $self->model('ErrorCode')->get_error_codes;
my %map = map {
$_->code => $_->as_tree;
} @$err_codes;
return \%map;
}
#-------------------------------------------------------------------------------
sub lab_section_status_options_map {
my ($self, $section_id) = @_;
my $o = $self->model('LabSection')->get_section_status_options($section_id);
my %map = map {
$_->status_option->description => $_->status_option_id;
} @$o;
return \%map;
}
#-------------------------------------------------------------------------------
sub all_lab_section_status_options_map {
my $self = shift;
# get list of section status options table data:
my @args = (
'LabSectionStatusOption', # class
{ sort_by => 'lab_section.section_name' }, # optional args, passed through
[ 'lab_section', 'status_option' ], # optional require_objects
);
my $section_options = $self->model('Base')->get_objects(@args);
my %map;
for ( sort by_position (@$section_options) ) {
my $description = $_->status_option->description;
my $section = $_->lab_section->section_name;
push @{ $map{$section} }, $description;
}
return \%map;
}
sub by_position {
return $a->position <=> $b->position;
}
1;