package LIMS::Controller::Search;
use base 'LIMS::Base';
use Moose;
with (
'LIMS::Controller::Roles::History',
'LIMS::Controller::Roles::DataMap',
'LIMS::Controller::Roles::RecordHandler',
'LIMS::Controller::Roles::ResultHandler',
'LIMS::Controller::Roles::SearchConstraint', # generate_search_constraints()
);
__PACKAGE__->meta->make_immutable(inline_constructor => 0);
use Data::Dumper;
# can't use __PACKAGE__->authz->authz_runmodes() - crashes on non-logged-in user
#-------------------------------------------------------------------------------
sub default : StartRunmode {
my $self = shift; $self->_debug_path($self->get_current_runmode);
my $errs = shift; $self->stash(errs => $errs);
return $self->forbidden() unless $self->user_can('search');
my $trials = $self->model('ClinicalTrial')->get_trials;
$self->tt_params( trials => $trials );
return $self->render_view($self->tt_template_name, $errs);
}
#-------------------------------------------------------------------------------
# recieves url for a single record, by request.id:
sub load : Runmode {
my $self = shift; $self->_debug_path($self->get_current_runmode);
return $self->forbidden() unless $self->user_can('search');
my $id = $self->param('id') || return $self->forward('default');
return $self->_get_single_record($id);
}
#-------------------------------------------------------------------------------
sub do_search : Runmode {
my $self = shift; $self->_debug_path($self->get_current_runmode);
return $self->forbidden() unless $self->user_can('search');
my $dfv = $self->check_rm('default', $self->validate('search') )
|| return $self->dfv_error_page;
my $data = $dfv->valid; # $self->debug($data);
my $search_constraints = $self->generate_search_constraints($data)
|| return $self->forward('default'); # protect against submission of empty form
# $self->debug($search_constraints);
# how many records match submitted search params:
my $requests_count = $self->model('Request')
->search_requests_count($search_constraints); # $self->debug($requests_count);
# stash requests_count for possible use later (eg _get_multiple_records):
$self->stash( requests_count => $requests_count );
# zero hits, or too many to handle:
if (! $requests_count || $requests_count > 1000 ) {
$self->stash->{status_msg} = $requests_count ?
sprintf $self->messages('search')->{too_many_records}, $requests_count
: $self->messages('search')->{no_records_found};
my $html = $self->forward('default');
return $self->fill_form($html);
}
# if we only have 1 record, get request.id & pass to _get_single_record():
elsif ($requests_count == 1) {
my $request_id
= $self->model('Request')->get_request_id($search_constraints);
return $request_id
? $self->_get_single_record($request_id)
: $self->error('no request_id returned from model');
}
# have between 2 & 1000 records
else {
return $self->_get_multiple_records($search_constraints);
}
}
#-------------------------------------------------------------------------------
sub deleted_record : Runmode {
my $self = shift; $self->_debug_path();
if ( my %vars = $self->query->Vars ) { # warn Dumper \%vars;
return $self->redirect( $self->query->url . '/search/deleted_record' )
unless grep $vars{$_}, qw( first_name last_name hmds_ref );
my $data = $self->model('History')->get_deleted_records(\%vars); # warn Dumper $data;
if (! @$data) {
$self->flash(info => $self->messages('search')->{no_records_found});
}
$self->tt_params( result => $data );
}
return $self->tt_process;
}
#-------------------------------------------------------------------------------
sub _get_multiple_records {
my ($self, $search_constraints) = @_; $self->_debug_path();
my $q = $self->query;
my %args_for_search = do {
my @params = ( $q->param('sort_by') || 'id' ); # supply default
push @params,
$q->param('sort_order') ? uc $q->param('sort_order') : 'DESC' ;
sort_by => join ' ', @params;
}; # warn Dumper \%args_for_search;
# retrieve requests_count from do_search():
my $requests_count = $self->stash->{requests_count};
# entries per page from form or use config default:
my $entries_per_page = $q->param('entries_per_page')
|| $self->cfg('settings')->{entries_per_page}; # warn $entries_per_page;
# if > 10, invoke pager for template and add limit & offset params to \%args:
if ( $requests_count > $entries_per_page ) {
$self->pager({ query => \%args_for_search, total => $requests_count });
} # $self->debug(\%args_for_search);
{ # get record & specimens map data structures into tt_params:
my %local_args = (
search_constraints => $search_constraints,
args_for_search => \%args_for_search,
); # warn Dumper \%local_args;
# get records matching search_contraints + args_for_search:
my $records = $self->model('Request')->find_requests(\%local_args);
my @request_ids = map { $_->id } @$records;
# get specimen_map for all requests so we have 1 db hit not 1 per request:
my $specimen_map = $self->specimen_map(\@request_ids);
# request_options map:
my $req_opts = $self->request_options_map(\@request_ids); # warn Dumper $req_opts;
$self->tt_params(
records => $records,
specimen_map => $specimen_map,
request_opts => $req_opts,
);
}
# get request_histories for all requests so we have 1 db hit not 1 per request:
# my $history_map = $self->get_request_histories($records); # using 'requests.created_at' now
$self->tt_params( total_count => $requests_count );
# send template through render_view() to apply symbolise() function:
return $self->render_view('search/multiple_records.tt');
}
#-------------------------------------------------------------------------------
sub _get_single_record {
my $self = shift; $self->_debug_path();
my $request_id = shift
|| return $self->error('no id passed to '.$self->get_current_runmode);
# functions transferred to LIMS::Controller::Roles::RecordHandler
my $request_data = $self->get_single_request_data($request_id)
|| return $self->error("request_id '$request_id' does not exist");
# format lab_test data for template:
$self->format_raw_lab_test_data($request_data);
$self->process_raw_lab_test_data($request_data);
# log event:
$self->history_log_event({ request_id => $request_id, event => 'view' });
# using render_view() for access to join_hash_values:
return $self->render_view('record/default.tt', $request_data);
}
1;