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 _get_multiple_records { my ($self, $search_constraints) = @_; $self->_debug_path(); my $q = $self->query; my %args_for_search = ( sort_by => join ' ', $q->param('sort_by'), uc $q->param('sort_order'), ); # $self->debug(\%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); # get specimen_map for all requests so we have 1 db hit not 1 per request: my @request_ids = map { $_->id } @$records; my $specimen_map = $self->specimen_map(\@request_ids); $self->tt_params( records => $records, specimen_map => $specimen_map, ); } # 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;