package LIMS::Controller::PrintRun;
use base 'LIMS::Base';
use LIMS::Local::Utils;
use Data::Dumper;
use Moose;
with (
'LIMS::Controller::Roles::DataMap',
'LIMS::Controller::Roles::RecordHandler',
'LIMS::Controller::Roles::ResultHandler',
);
has reports => (
is => 'ro',
isa => 'ArrayRef[Str]',
default => sub { [] },
lazy => 1,
traits => ['Array'],
handles => {
add_to_reports => 'push',
},
);
__PACKAGE__->meta->make_immutable(inline_constructor => 0);
#-------------------------------------------------------------------------------
sub default : StartRunmode {
my $self = shift; $self->_debug_path($self->get_current_runmode);
return $self->forbidden() unless $self->user_can('print_all');
my $last_working_day = $self->_get_last_working_day();
$self->tt_params(
date => $last_working_day,
);
return $self->tt_process();
}
#-------------------------------------------------------------------------------
sub do : Runmode {
my $self = shift; $self->_debug_path($self->get_current_runmode);
# get start & end datetime objects:
my $start = $self->_get_start_date; # warn Dumper $start;
my $end = $self->_get_end_date; # warn Dumper $end;
# first find out how many have been requested:
my $count = $self->model('Request')->get_print_run_size($start, $end);
if (! $count) {
$self->flash( info => $self->messages('search')->{no_records_found} );
return $self->redirect( $self->query->url . '/printrun' );
}
# if more than max print_run size (defined in settings), split load:
elsif ($count > $self->cfg('settings')->{print_run_max}) {
my %args = (
count => $count,
start_date => $start,
# $end defaults to 00:00:00 on current_date (unless use_today selected)
end_date => $end->subtract(seconds => 1), # so subtract 1 sec for .tt param
);
return $self->tt_process(\%args);
}
else {
return $self->_do_print($start, $end);
}
}
#-------------------------------------------------------------------------------
# converts form start & end date strings back to DT objects, forwards to _do_print():
sub do_offset : Runmode {
my $self = shift; $self->_debug_path($self->get_current_runmode);
my $p = $self->query->Vars();
# to_datetime_using_parsedate() seems to work:
# my $start = LIMS::Local::Utils::to_datetime_using_parsedate($p->{start});
# my $end = LIMS::Local::Utils::to_datetime_using_parsedate($p->{end});
# to_datetime_using_strptime() config'd to use supplied pattern:
my $pattern = '%F' . 'T%T'; # datetime string eg 2010-01-01T00:00:00
my $start
= LIMS::Local::Utils::to_datetime_using_strptime($p->{start}, $pattern);
my $end
= LIMS::Local::Utils::to_datetime_using_strptime($p->{end}, $pattern);
return $self->_do_print($start, $end);
}
#-------------------------------------------------------------------------------
sub _do_print {
my ($self, $start, $end) = @_; $self->_debug_path();
my @sort_by = qw(referrer.name requests.year requests.request_number);
my %args = (
start => $start,
end => $end,
sort_by => \@sort_by,
);
# offset supplied if total > max print_run size (maybe '0' so use defined):
# if ( defined $self->query->param('offset') ) { # always submitted now
$args{offset} = $self->query->param('offset') || 0; # default to beginning
$args{limit} = $self->cfg('settings')->{print_run_max} || 50; # sensible default
# }
# get request id's for records amended between start & end datetimes:
my $request_ids
= $self->model('Request')->get_print_run_request_ids(\%args);
unless (@$request_ids) { # should never get here - count checked in do()
$self->flash( info => $self->messages('search')->{no_records_found} );
return $self->redirect( $self->query->url . '/printrun' );
}
# allowed report error_codes:
my $report_error_codes = $self->report_error_codes_map;
# diagnosis_context_warnings:
my $context_warning = $self->diagnosis_context_warning_map;
# categories exempt from 'use NHS number':
my $nhs_number_exempt = $self->nhs_number_exempt;
# preserve 'app_url' & 'active_link' tt_params for use in loop:
my %required_tt_params = map {
$_ => $self->tt_params->{$_};
} qw(app_url active_link);
# my $i;
foreach my $request_id (@$request_ids) { # last if $i++ > 1; # for testing
# format request data for template:
my $request_data = $self->format_print_record_request_data($request_id); # warn Dumper $request_id;
# add data maps for template:
$self->tt_params(
context_warning_map => $context_warning,
nhs_number_exempt => $nhs_number_exempt,
report_error_codes => $report_error_codes,
request => $request_data,
);
# template depends on whether it's outreach data:
my $tmpl = $request_data->{outreach}
? 'outreach/report_body.tt'
: 'record/body.tt'; # warn $tmpl;
# render template & add to 'reports' attr:
my $html = $self->render_view($tmpl);
$self->add_to_reports($$html); # dereference first
{ # has copy_to been requested?
my $request_options = $request_data->{request_options};
# warn Dumper $request_options;
if ( $request_options->{copy_to}->{is_selected} ) {
my $cc = $self->_generate_copy($html);
$self->add_to_reports($cc); # already deref'ed
}
}
$self->tt_clear_params; # clear all template params for next loop
$self->tt_params(\%required_tt_params); # add required ones back
}
return $self->tt_process('printrun/wrapper.tt', { reports => $self->reports });
}
#-------------------------------------------------------------------------------
sub _generate_copy {
my ($self, $tmpl_ref) = @_; $self->_debug_path();
my $html = ${$tmpl_ref}; # de-reference tmpl var
my $q = $self->query;
# replace referrer details with blank 'Copy to' line:
my $str = $q->span({-style => 'color: #f00'}, 'Copy to:') . $q->br;
$html =~ s/Referrer: .*/$str/;
return $html;
}
#-------------------------------------------------------------------------------
sub _get_start_date {
my $self = shift; $self->_debug_path();
my $q = $self->query;
my $datetime;
# expect params 'last_working_day' OR 'date', and optional 'today':
if ( $q->param('last_working_day') ) {
$datetime = $self->_get_last_working_day();
}
elsif ( my $date = $q->param('date') ) {
$datetime = LIMS::Local::Utils::to_datetime_using_datecalc($date)
|| return $self->error("cannot decode date-string $date");
} # warn Dumper $datetime;
# in case start date not supplied:
$datetime ||= LIMS::Local::Utils::today(); # beginning of day (00:00:00)
return $datetime;
}
#-------------------------------------------------------------------------------
sub _get_end_date {
my $self = shift; $self->_debug_path();
my $datetime = $self->query->param('today')
? LIMS::Local::Utils::time_now() # up to current time (BST-aware)
: LIMS::Local::Utils::today(); # beginning of day (00:00:00)
return $datetime;
}
#-------------------------------------------------------------------------------
sub _get_last_working_day { # doesn't consider public holidays
my $self = shift; $self->_debug_path();
my $dt = DateTime->today->subtract( days => 1 ); # yesterday at 00:00:00
# day 6 is Saturday, day 7 is Sunday
while ( $dt->day_of_week >= 6 ) {
$dt->subtract( days => 1 );
} # warn Dumper $dt;
return $dt;
}
1;