package Role::Report;
use Moose::Role;
=begin
requires qw(screen_map signature_userid_map username_userid_map
substitute_screening_terms substitute_user);
=cut
has $_ => ( is => 'ro', isa => 'HashRef', lazy_build => 1 )
foreach qw(
status_map
diagnosis_map
renamed_diagnoses
change_options_map
specimen_quality_map
);
use Data::Dumper;
sub do_report {
my $self = shift;
my $vals = shift;
# if not yet screened, will not exist in Report table:
$vals->{rpt_id} || return 0;
my $dbh = $self->db->{dbix4};
{ # InitialDiag:
my $initialdiag = $vals->{initialdiag};
my $screen_id = $self->screen_map->{$initialdiag}
|| $self->substitute_screening_terms->{$initialdiag}
|| die "no screen id for $initialdiag ($vals->{dbid})";
my %data = (
request_id => $vals->{_request_id},
screen_id => $screen_id,
);
$dbh->insert('request_initial_screen', \%data);
}
# if reported, convert data for request_report table:
if ( $vals->{reportby} ) {
my $new_diagnosis = $vals->{newdiagnosis} || '';
my $quality = $vals->{specquality} || '';
my $status = $self->status_map->{$new_diagnosis} || 'default';
my $specimen_quality = $self->specimen_quality_map->{$quality}
|| 'adequate';
my $diagnosis_map = $self->diagnosis_map;
my $diagnosis = $self->_process_diagnosis_data($vals);
my $diagnosis_id = $diagnosis_map->{$diagnosis}
|| die "Cannot find diagnosis_id for $diagnosis";
my %data = (
request_id => $vals->{_request_id},
comment => $vals->{comment},
clinical_details => $vals->{clindetails},
specimen_quality => $specimen_quality,
status => $status,
diagnosis_id => $diagnosis_id,
created_at => '0000-00-00 00:00:00', # will be updated in History
updated_at => $vals->{reporttime},
);
$dbh->insert('request_report', \%data);
}
# gross description:
if ( my $gross_description = $vals->{grossdesc} ) {
my %data = (
request_id => $vals->{_request_id},
detail => $gross_description,
);
unless ( grep $gross_description eq $_, ('-', 'N/A') ) {
$dbh->insert('request_gross_description', \%data);
}
}
}
# updates request_diagnosis_history table with any ReviseDiag or Diagnosis
# returns FinalDiag, ReviseDiag or Diagnosis:
sub _process_diagnosis_data {
my $self = shift;
my $vals = shift;
my $diagnosis;
# first try FinalDiag, update request_diagnosis_history table:
if ( $diagnosis = $vals->{finaldiag} ) {
if ($vals->{revisediag}) {
if ( $vals->{revisediag} ne $vals->{diagnosis} ) {
# diagnosis-that-got-changed, who-changed-it, date, reason:
my %data = (
diagnosis => $vals->{diagnosis},
username => $vals->{revisedby},
datetime => $vals->{revisedate},
request_id => $vals->{_request_id},
reason => 'error',
);
$self->_do_diagnosis_history(\%data);
}
if ( $vals->{finaldiag} ne $vals->{revisediag} ) {
# diagnosis-that-got-changed, who-changed-it, date, reason:
my %data = (
diagnosis => $vals->{revisediag},
username => $vals->{finalby},
datetime => $vals->{finaldate},
request_id => $vals->{_request_id},
reason => 'update',
);
$self->_do_diagnosis_history(\%data);
}
}
elsif ( $vals->{finaldiag} ne $vals->{diagnosis} ) {
# diagnosis-that-got-changed, who-changed-it, date, reason:
my %data = (
diagnosis => $vals->{diagnosis},
username => $vals->{finalby},
datetime => $vals->{finaldate},
request_id => $vals->{_request_id},
reason => 'update',
);
$self->_do_diagnosis_history(\%data);
}
}
# next try ReviseDiag, update request_diagnosis_history table:
elsif ( $diagnosis = $vals->{revisediag} ) {
if ( $vals->{revisediag} ne $vals->{diagnosis} ) {
# diagnosis-that-got-changed, who-changed-it, date, reason:
my %data = (
diagnosis => $vals->{diagnosis},
username => $vals->{revisedby},
datetime => $vals->{revisedate},
request_id => $vals->{_request_id},
reason => 'error',
);
$self->_do_diagnosis_history(\%data);
}
}
# group of molecular samples from 2002/2003 with no diagnosis:
elsif ( ! $vals->{diagnosis} ) {
if ( $vals->{initialdiag} =~ /molecular|chimerism/i ) {
$diagnosis = 'Not required';
}
}
else {
$diagnosis = $vals->{diagnosis};
}
return $diagnosis;
}
sub _do_diagnosis_history {
my $self = shift;
my $data = shift;
my $dbh = $self->db->{dbix4};
my $diagnosis = $data->{diagnosis}; # original diagnosis
my $signature = $data->{username}; # who changed it
my $reason = $data->{reason}; # why
my $date = $data->{datetime} || '0000-00-00'; # early data didn't record date
my $diagnosis_map = $self->diagnosis_map;
my $options_map = $self->change_options_map;
my $user_id = $self->_get_user_id_from_sig($signature)
|| die "Cannot find users.id for $signature";
my $diagnosis_id = $diagnosis_map->{$diagnosis}
|| die "Cannot find diagnosis_id for $diagnosis";
my %data = (
request_id => $data->{request_id},
diagnosis_id => $diagnosis_id,
option_id => $options_map->{$reason},
user_id => $user_id,
time => join ' ', $date, '00:00:00',
);
$dbh->insert('request_diagnosis_history', \%data);
}
sub _build_status_map {
my $self = shift;
my %status_map = (
Y => 'new', # new_diagnosis = yes
R => 'relapse',
N => 'default', # new_diagnosis = no
);
return \%status_map;
}
sub _build_specimen_quality_map {
my $self = shift;
my %specimen_quality_map = (
Adequate => 'adequate',
Average => 'adequate',
Good => 'good',
Poor => 'poor',
);
return \%specimen_quality_map;
}
sub _build_renamed_diagnoses {
my $self = shift;
# add renamed terms:
my @renamed_pairs = (
'B-cell chronic lymphocytic leukaemia',
'B-cell chronic lymphocytic leukaemia (B-cell CLL)',
'B-CLL - minimal residual disease present',
'B-cell CLL - minimal residual disease present',
'Blastic variant of mantle cell lymphoma',
'Mantle cell lymphoma - blastic variant',
'Chronic myeloproliferative disorder with myelofibrosis',
'Chronic myeloproliferative neoplasm with myelofibrosis',
'CLL-associated EBV lymphoproliferative disorder',
'B-cell CLL-associated EBV lymphoproliferative disorder',
'CML - cytogenetic remission',
'Chronic myeloid leukaemia - cytogenetic remission',
'CML - major molecular response',
'Chronic myeloid leukaemia - major molecular response',
'CML - minor molecular response',
'Chronic myeloid leukaemia - minor molecular response',
'CML - satisfactory molecular response',
'Chronic myeloid leukaemia - satisfactory molecular response',
'CML - unsatisfactory molecular reponse', # originally mis-spelled
'Chronic myeloid leukaemia - unsatisfactory molecular response',
'Diffuse large B-cell lymphoma',
'Diffuse large B-cell lymphoma (DLBCL)',
'Extranodal MZL with rearrangement of MALT-1',
'Extranodal marginal zone lymphoma with rearrangement of MALT-1',
'Hodgkin lymphoma - HIV associated',
'Classical Hodgkin lymphoma - HIV associated',
'MDS treated <5% blasts',
'Myelodysplastic syndrome treated <5% blasts',
'Mixed phenotype acute leukaemia with MLL rearrangement',
'Acute leukaemia - mixed phenotype with MLL rearrangement',
'Monoclonal gammopathy of uncertain significance',
'Monoclonal gammopathy of undetermined significance (MGUS)',
'Myeloma - minimal residual disease present',
'Plasma cell myeloma - minimal residual disease present',
'Atypical CML',
'Atypical chronic myeloid leukaemia',
);
my %h = @renamed_pairs;
return \%h;
}
sub _build_change_options_map {
my $self = shift;
my $dbh = $self->db->{dbix4};
my $sql = q!select `option_name`, `id` from diagnosis_change_options!;
my $map = $dbh->query($sql)->map;
return $map;
}
sub _build_diagnosis_map {
my $self = shift;
my $dbh = $self->db->{dbix4};
my $map = $dbh->query( 'select name, id from diagnoses' )->map;
# add any diagnoses which have changed names:
my $renamed_diagnoses = $self->renamed_diagnoses;
while ( my ($old, $new) = each %$renamed_diagnoses ) {
$map->{$old} = $map->{$new}; # maps old term to new term for conversion
}
return $map;
}
sub _get_event_time {
my ($self, $function, $date_field, $lab_no) = @_;
my $sql;
if ($function eq 'screened') {
$sql = q!select Date, Time from History where HMDS = ? and
Action = 'screened'!;
}
else {
$sql = sprintf q!select Date, Time from History where HMDS = ? and
Action in ('%s', 'reported and authorised')!, $function;
}
if ( my @date_time = $self->db->{dbix3}->query( $sql, $lab_no )->list ) {
return join ' ', @date_time; # use Date/Time from History if available
}
elsif ($date_field) {
return join ' ', $date_field, '00:00:00'; # time unknown
}
else { # should never happen ?
warn Dumper [ $function, $date_field, $sql, $lab_no ];
return undef;
}
}
=begin # ? not used, was RequestHistory - function should be in Role::User:
sub __get_user_id {
my ($self, $function, $vals) = @_; # function = screener, reportby, authorisedby
my $signature = $vals->{$function} || return;
my $username = lc $self->signature_userid_map->{$signature};
my $user_id = $self->username_userid_map->{$username}
|| $self->substitute_user->{$signature}
|| warn "no user id for $signature ($vals->{dbid})"; # warn $user_id;
}
=cut
=begin # these are wrong !!
sub _do_history_for_revisediag {
my $self = shift;
my $vals = shift;
my $dbh = $self->db->{dbix4};
my $diagnosis = $vals->{diagnosis}; # original diagnosis
my $signature = $vals->{revisedby}; # who changed it
my $date = $vals->{revisedate} || '0000-00-00'; # early data didn't record date
my $diagnosis_map = $self->diagnosis_map;
my $user_id = $self->_get_user_id_from_sig($signature)
|| die "Cannot find users.id for $signature";
my $diagnosis_id = $diagnosis_map->{$diagnosis}
|| die "Cannot find diagnosis_id for $diagnosis";
my %data = (
request_id => $vals->{_request_id},
diagnosis_id => $diagnosis_id,
user_id => $user_id,
reason => 'error',
time => join ' ', $date, '00:00:00',
);
$dbh->insert('request_diagnosis_history', \%data);
}
sub _do_history_for_finaldiag {
my $self = shift;
my $vals = shift;
my $dbh = $self->db->{dbix4};
my $diagnosis = $vals->{diagnosis}; # original diagnosis
my $signature = $vals->{finalby}; # who changed it
my $date = $vals->{finaldate} || '0000-00-00'; # early data didn't record date
my $diagnosis_map = $self->diagnosis_map;
my $user_id = $self->_get_user_id_from_sig($signature)
|| die "Cannot find users.id for $signature";
my $diagnosis_id = $diagnosis_map->{$diagnosis}
|| die "Cannot find diagnosis_id for $diagnosis";
my %data = (
request_id => $vals->{_request_id},
diagnosis_id => $diagnosis_id,
user_id => $user_id,
reason => 'update',
time => join ' ', $date, '00:00:00',
);
$dbh->insert('request_diagnosis_history', \%data);
}
sub _update_request_diagnosis_with_diagnosis { # Diagnosis:
my $self = shift;
my $vals = shift;
my $dbh = $self->db->{dbix4};
my $diagnosis = $vals->{diagnosis};
my $signature = $vals->{reportby};
my $diagnosis_map = $self->diagnosis_map;
my $user_id = $self->_get_user_id_from_sig($signature)
|| die "Cannot find users.id for $signature";
my $diagnosis_id = $diagnosis_map->{$diagnosis}
|| die "Cannot find diagnosis_id for $diagnosis";
my $date = $vals->{reportdate} || '0000-00-00'; # early data didn't record date
my %data = (
request_id => $vals->{_request_id},
diagnosis_id => $diagnosis_id,
user_id => $user_id,
time => join ' ', $date, '00:00:00',
);
$dbh->insert('request_diagnosis_history', \%data);
}
sub _update_request_diagnosis_with_revised_diagnosis {
my $self = shift;
my $vals = shift;
my $dbh = $self->db->{dbix4};
my $diagnosis_map = $self->diagnosis_map;
my $diagnosis = $vals->{revisediag};
my $signature = $vals->{revisedby};
my $user_id = $self->_get_user_id_from_sig($signature)
|| die "Cannot find users.id for $signature";
my $diagnosis_id = $diagnosis_map->{$diagnosis}
|| die "Cannot find diagnosis_id for $diagnosis";
my $date = $vals->{revisedate} || '0000-00-00'; # early data didn't record date
my %data = (
request_id => $vals->{_request_id},
diagnosis_id => $diagnosis_id,
user_id => $user_id,
time => join ' ', $date, '00:00:00',
);
$dbh->insert('request_diagnosis_history', \%data);
}
=cut
1;