package LIMS::Controller::Roles::FormData;
use Moose::Role;
use Data::Dumper;
has results_data_validation => ( is => 'ro', lazy_build => 1 );
sub _build_results_data_validation {
$_[0]->get_yaml_file('results_data_validation');
}
has test_name_map => ( is => 'ro', lazy_build => 1 ); # don't use name 'lab_tests_map'
sub _build_test_name_map {
my $aref = $_[0]->model('LabTest')->get_lab_tests; # warn Dumper $aref;
my %h = map { $_->id => $_->test_name } @$aref; # warn Dumper \%h;
return \%h;
}
has results_input_errors => (
is => 'ro',
isa => 'ArrayRef[Str]',
traits => ['Array'],
default => sub { [] },
handles => {
all_results_errors => 'elements',
have_results_errors => 'count',
add_results_error => 'push',
},
);
use Data::FormValidator;
use LIMS::Local::Config;
sub get_data_from_dfv {
my $self = shift;
my $profile = shift
|| return $self->error('no profile passed to get_data_from_dfv()');
my $validator = $self->_get_validator(); # warn Dumper $validator;
my $dfv = $validator->check($self->query, $profile);
my $data = $dfv->valid(); # $self->debug($data);
return $data;
}
sub validate_form_params {
my $self = shift;
my $profile = shift
|| return $self->error('no profile passed to get_data_from_dfv()');
my $params = shift || $self->query(); # optional - uses CGI if not passed
my $validator = $self->_get_validator(); # warn Dumper $validator;
my $results = $validator->check($params, $profile); # warn Dumper $results;
return $results;
}
sub validate_results_data_entry {
my ($self, $ref) = @_; # warn Dumper $ref;
my $data_type = $ref->{data_type};
my $test_id = $ref->{test_id};
# form param test name for results passed as lab_test_id_<x>:
my $test_name = 'lab_test_id_' . $test_id;
# generic validation for data type:
my $profile_name = 'data_entry_' . $data_type;
# not all data types need or have validators:
return 0 unless LIMS::Validate->can($profile_name);
# get validation method & error msg for profile name:
my $validator = $self->validate($profile_name); # warn Dumper $validator;
my $validation_method = $validator->{method};
my $validation_profile = {
required => [ $test_name ], # or param is ignored
constraint_methods => {
$test_name => $validation_method,
},
}; # warn Dumper $validation_profile;
my $dfv = $self->validate_form_params($validation_profile); # warn Dumper $dfv;
# add failure msg if invalid:
$self->add_results_error($validator->{err_msg}) if $dfv->has_invalid;
# validate against specific format (from yml file) if entry exists:
unless ( $self->have_results_errors ) { # don't need named param validation
if ( my $cfg = $self->results_data_validation ) { # warn Dumper $cfg;
my $lab_test = $self->test_name_map->{$test_id};
if ( my $profile = $cfg->{$lab_test} ) { # warn Dumper $profile;
my $messages = $self->messages('dfv_msgs');
my $result = $self->query->param($test_name); # warn $param;
# regex:
if ( my $format = $profile->{format} ) { # warn $format;
# warn $param =~ /^$format$/ ? 'match' : 'no match';
$self->add_results_error($messages->{invalid_format})
unless $result =~ /^$format$/;
}
# length:
if ( my $length = $profile->{length} ) { # warn $length;
$self->add_results_error($messages->{invalid_length})
unless length $result == $length;
}
}
}
}
my $pass = $self->have_results_errors ? 0 : 1;
return { pass => $pass }
}
# loads dfv_defaults from LIMS config:
sub _get_validator {
my $self = shift;
my $cfg = LIMS::Local::Config->instance;
my $dfv = Data::FormValidator->new({}, $cfg->{dfv_defaults});
return $dfv;
}
1;