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 anatomical_sites_map { my %map = map +($_->id => $_->as_tree), @{ shift->model('Coding')->get_anatomical_sites }; return \%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 lab_test_accreditation_map { my $self = shift; my $data = $self->model('Base')->get_objects('LabTestAccreditation'); my %h = map { $_->lab_test_id => $_->accreditation_date } @$data; return \%h; } # ------------------------------------------------------------------------------ sub diagnosis_lab_test_map { my $self = shift; my %map; my $data = $self->model('Base')->get_objects('DiagnosisLabTest'); for (@$data) { my $diagnosis_id = $_->diagnosis_id; my $lab_test_id = $_->lab_test_id; $map{$diagnosis_id}{$lab_test_id}++; } return \%map; } # ------------------------------------------------------------------------------ sub results_summary_lab_test_map { my $self = shift; my %map; my $data = $self->model('Base')->get_objects('ResultSummaryLabTest'); for (@$data) { my $summary_id = $_->result_summary_id; my $lab_test_id = $_->lab_test_id; $map{$summary_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_test_section_map { my $self =shift; my $lab_tests = $self->model('LabTest')->get_lab_tests; my %map = map { $_->id => { field_label => $_->field_label, lab_section => $_->lab_section->section_name, } } @$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 { # !!! very similar name to lab_test_data_types_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; for my $t (@$lab_test_data_type) { my $test_id = $t->lab_test_id; # warn $test_id; $map{$test_id}{data_type}{active} = $t->is_active; $map{$test_id}{data_type}{type} = $t->data_type->description; $map{$test_id}{data_type}{id} = $t->data_type_id; $map{$test_id}{field_label} = $t->lab_test->field_label; } return \%map; } #------------------------------------------------------------------------------- sub lab_test_data_types_map { # !!! very similar name to lab_test_data_type_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, active => $_->is_active, 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 $o = do { my @args = ( 'LabSectionStatusOption', # class { sort_by => 'lab_section.section_name' }, # optional args, passed through [ 'lab_section', 'status_option' ], # optional require_objects ); $self->model('Base')->get_objects(@args); }; my %h; for ( sort by_position (@$o) ) { my $section = $_->lab_section->section_name; push @{ $h{$section} }, $_->as_tree; } return \%h; } sub by_position { # use position if configured, otherwise just return status_option_id: my $itemA = $a->position || $a->status_option_id; my $itemB = $b->position || $b->status_option_id; # warn Dumper [$itemA, $itemB]; return $itemA <=> $itemB; } 1;