<!-- BEGIN [% component.name # called from record/report_body.tt %] -->
[%- # (re)define request-specific vars - supports single or multiple requests:
c.debug("==== ${component.name}; id = ${request_data.id} ====");
lab_number = INCLUDE site/lab_number.tt skip_prefix = 1;
text_str.amended_report = 'amended report supersedes any previous '
_ "issued on ${settings.lab_name_abbreviation} ref $lab_number";
ref_time = status_options.authorised.is_active.match('yes')
? history.authorised.time : history.reported.time; # ref_time;
is_gp = data.referrer_department.hospital_department_code.match('600') ? 1 : 0;
# INCLUDE dumper.tt dump = has_optional;
IF has_optional.report
AND status_options.authorised.is_active.match('yes')
AND NOT history.authorised.size # not authorised
AND request_data.year > 2005; # eg Molecular Misc requests pre-2006 never auth'd
# reset report:
report = 0; # 'here';
END; # request_data = {}; # for testing
have_secondary_diagnosis = request_data.request_secondary_diagnosis ? 1 : 0;
is_amended_report = report.comment.match('[Aa]dditional [Cc]omment') ? 1 : 0;
IF ref_time AND NOT is_amended_report; # date calcs need ref_time
FOREACH d IN previous_diagnoses;
# if diagnosis change > auth date:
IF d.time.subtract_datetime(ref_time).delta_days > 0;
is_amended_report = 1;
is_updated_diagnosis = 1; # to flag on report
LAST;
END; END;
UNLESS is_amended_report; # irrelevant if already set
FOREACH entry IN result_summaries; # PROCESS dumper.tt dump = entry.value.time;
NEXT UNLESS entry.value.time; # fatal in cmp if unset
# if result summary updated AFTER authorisation date:
IF entry.value.time.subtract_datetime(ref_time).delta_days > 0;
is_amended_report = 1; LAST;
END; END; END; # is_amended_report;
END;
BLOCK debug_delta_days;
INCLUDE dumper.tt dump = [
ref_time.datetime, o.datetime, o.subtract_datetime(ref_time).delta_days
];
END;
-%]
<!-- container -->
[% class = ['container' ]; class.push('printHide') UNLESS is_print_request %]
<div class="[% class.join %]">
<div class="row">
[% banner = outreach ? 'outreach_logo.jpg' : c.cfg('settings').report_header %]
<img src="/images/[% banner %]" />
</div>
[% UNLESS is_print_request; INCLUDE record/report/navbar.tt; END %]
<!--[if lt IE 7]>
<h3 align="center" class="alert alert-error">YOUR BROWSER IS TOO OLD TO
FORMAT THIS PAGE PROPERLY - PLEASE USE A MODERN BROWSER</h3>
<![endif]-->
<div class="row">
[% IF has_optional.clinical_trial;
trial_number = get_trial_number(patient.id, data.request_trial.trial_id) %]
<h3 class="text-warning text-center">
CLINICAL TRIAL [% data.request_trial.trial.trial_name %]
[% IF trial_number %][ [% trial_number %] ][% END %]
</h3>
[% ELSIF is_outreach # not large enough %]
<h3 class="text-warning text-center">Outreach</h3>
[% END %]
[% # class = is_print_request ? 'span8' : 'span7 offset1' # need to adjust for PDF view
# need to allow sufficient space for 'please use nhs number' & main-div
# span2/min-width & span8/pull-right works OK for HTML & PDF
%]
[% min_width = 200; # span2.5 best on FF, but not official, and not supported by IE <8 %]
<div class="span2" style="min-width: [% min_width %]px">
[% INCLUDE record/report/patient.tt %]
</div>
<div class="span9 pull-right">
<div class="main-div">
[% IF report; # PROCESS dumper.tt dump = report.as_tree %]
<div class="diagnosis bright"><!-- style="white-space: nowrap" // doesn't scale with screen resolution -->
[% '1.' IF have_secondary_diagnosis;
class = is_updated_diagnosis ? 'warning' : 'normal' -%]
<span class="[% class %]">[% report.diagnosis.name %]</span>
[% IF report.diagnosis.icdo3 %]
[[% report.diagnosis.icdo3 %]]
[% END %]
[% IF c.cfg('settings').have_hmrn_info_link AND NOT is_print_request %]
<sup>[% INCLUDE site/snippets/hmrn_info_link.tt
diagnosis = request_data.request_report.diagnosis %]</sup>
[% END %]
</div>
[% IF have_secondary_diagnosis %]
<div class="diagnosis bright">2.
[% request_data.request_secondary_diagnosis.diagnosis.name %]
[% IF request_data.request_secondary_diagnosis.diagnosis.icdo3 %]
[[% request_data.request_secondary_diagnosis.diagnosis.icdo3 %]]
[% END %]
[% UNLESS is_print_request %]
<sup>[% INCLUDE site/snippets/hmrn_info_link.tt
diagnosis = request_data.request_secondary_diagnosis.diagnosis %]</sup>
[% END %]
</div>
[% END %]
[% ELSE %]
<div class="diagnosis bright">[ REPORT IN PROGRESS ]</div>
[% END %]
<p class="indent">
[% INCLUDE record/report/specimen.tt %]
</p>
[% # report comment:
IF report.comment; # PROCESS dumper.tt dump = report.comment;
IF report_history.size; # INCLUDE dumper.tt dump = report_history.last.as_tree;
entry = report_history.last; # INCLUDE dumper.tt dump = entry.as_tree;
# if last comment update > auth_date:
IF want_inline AND (entry.time AND ref_time) # fatal if either unset:
AND entry.time.delta_days(ref_time).days;
# comment.push(' '); # line space
comment_update_by = 'Amended by ' _
entry.user.first_name.ucfirst _ ' ' _
entry.user.last_name.ucfirst _ ' on ' _
entry.time.strftime('%a %d.%b.%Y') _ ' @ ' _
entry.time.strftime('%H:%M');
report.comment = report.comment _ ' ' _ comment_update_by;
END;
END;
comment = [];
UNLESS special_formatting.no_comment;
formatted_comment = symbolise(report.comment).replace(
'[Aa]dditional [Cc]omment','ADDITIONAL COMMENT') | html_line_break;
# to split comment on full-stop:
# re = '\.\s+'; # for legacy comment; keep space to retain decimal numbers
# FOREACH line IN formatted_comment.split(re);
# comment.push(line);
# END;
comment.push(formatted_comment); # if not splitting on '.'
END;
IF outreach;
follow_opt_id = outreach.followup.followup_option_id;
option = outreach.menu_options.followup_options.item(follow_opt_id).option;
label = outreach.menu_options.followup_options.item(follow_opt_id).label;
IF option.match('clinic_return');
comment.push(text_str.clinic_return);
ELSIF option.match('zero');
str = text_str.pack_dispatch _ ' immediately.';
comment.push(str);
ELSIF option.match('month|week');
str = text_str.pack_dispatch _ ' in ' _ label _ '.';
comment.push(str);
END;
END;
IF report_history.size; # INCLUDE dumper.tt dump = report_history.last.as_tree;
entry = report_history.last;
# if last comment update > auth_date:
IF ( entry.time AND ref_time ) # fatal if either unset:
AND entry.time.delta_days(ref_time).days;
# comment.push(' '); # line space
comment_update_by = 'Amended by ' _
entry.user.first_name.ucfirst _ ' ' _
entry.user.last_name.ucfirst _ ' on ' _
entry.time.strftime('%a %d.%b.%Y') _ ' @ ' _
entry.time.strftime('%H:%M');
comment.push(comment_update_by);
END;
END;
%]
<p class="diagnosis-comment">[% comment.join('<br />') %]</p>
[% END %]
[% # context warnings:
context_warnings = [];
context_warning_map = report_data_maps.context_warning_map;
IF report AND context_warning_map.size AND NOT outreach.size;
warning = context_warning_map.item(report.diagnosis.id);
IF warning; context_warnings.push(warning); END;
END;
IF specimen_map.item(data.id).description.grep('CSF').size
AND report AND NOT report.diagnosis.icdo3.match('/3'); # non-ICDO3 + CSF
context_warnings.push(text_str.csf);
END;
IF context_warnings.size;
%]
<ul>
[% FOREACH entry IN context_warnings %]
<li class="dark">[% entry %]</li>
[% END %]
[% FOREACH entry IN diagnosis_riders %]
<li class="normal">[% entry %]</li>
[% END %]
</ul>
[% END %]
</div>
[% # additional comments:
additional_comments = [];
text_highlights = [];
IF report AND NOT report.status.match('default');
str = 'this is a ' _ report.status.upper _ ' diagnosis';
text_highlights.push(str);
END;
IF is_amended_report;
text_highlights.push(text_str.amended_report);
END;
IF outstanding_tests.size;
str = text_str.tests_pending;
sections = outstanding_tests.keys.join('; ');
additional_comments.push(str _ ' [' _ sections.lower _ ']');
END;
IF request_errors.size; # PROCESS dumper.tt dump = report_data_maps.report_error_codes;
FOREACH entry IN request_errors;
err_code = entry.error_code.code;
# only want reportable errs:
NEXT UNLESS report_data_maps.report_error_codes.item(err_code);
str = report_data_maps.report_error_codes.item(err_code).description
_ ' [' _ err_code.upper _ ']';
additional_comments.push(str);
END;
END;
specimen = specimen_map.item(data.id).sample_code;
IF specimen.grep('BMA').size AND NOT specimen.grep('PB').size
AND NOT request_data.request_trial;
additional_comments.push(text_str.pb_sample);
END;
IF is_print_request AND NOT outreach; # print report or print run
additional_comments.push(text_str.service_url);
END;
# UKAS unaccredited tests:
# INCLUDE dumper.tt dump = raw_lab_test_data.ukas_unaccredited_tests;
IF raw_lab_test_data.ukas_unaccredited_tests; # maybe empty array
USE String text = text_str.ukas;
IF raw_lab_test_data.ukas_unaccredited_tests.size; # may not be any for this request
CALL String.append('except:'); # CALL suppresses printing here
FOREACH t IN raw_lab_test_data.ukas_unaccredited_tests; # INCLUDE dumper.tt dump = t;
CALL String.append("<div>⚬ ${t.field_label} ");
CALL String.append('panel ') IF t.test_type.match('panel'); # only for panels
CALL String.append("[${t.lab_section.section_name}]</div>");
END;
END;
additional_comments.push(String.text);
END;
%]
[% IF text_highlights.size OR additional_comments.size %]
<div class="comments">
<ul>
[% FOREACH entry IN text_highlights %]
<li class="text-error bold">[% entry %]</li>
[% END %]
[% FOREACH entry IN additional_comments %]
<li class="text-info bold">[% entry %]</li>
[% END %]
</ul>
</div>
[% END %]
</div>
</div>
[% IF outreach.size; INCLUDE record/report/outreach.tt; ELSIF is_gp %]
<table class="table table-bordered demographics">
<tr>
<td>
[% data.referrer_department.referrer.name || 'UNKNOWN' %],
[% data.patient_case.referral_source.display_name | html %]
</td>
</tr>
</table>
[% END %]
[% IF report AND ( report.morphology OR result_summaries.size );
INCLUDE record/report/results.tt;
ELSE # spacer: %]
<p class="spacer"></p>
[% END %]
[% IF history.reported;
reporter = history.reported.user;
authoriser = history.authorised.user;
users = []; # to avoid repeat user-contact icons
BLOCK contact_user;
UNLESS is_print_request;
IF user.active.match('yes') AND NOT users.grep(user.username).size;
users.push(user.username) %]
<a href="[% app_url %]/resources/user_messages/[% user.id %]/[% data.id %]">
<span class="badge badge-bright"><i class="icon-user icon-white"></i></span>
</a>
[% END; END; END; %]
<div class="_no-break" style="border: 1px solid #fff"><!-- no-break causes occasional loss of content -->
<div class="row">
<div class="row span7">
<span class="rich">Reported by:
<b>[% reporter.first_name | ucfirst %]</b>
<b>[% reporter.last_name | ucfirst %]</b>
</span>
on <b>[% history.reported.time.strftime('%a %d.%b.%Y @ %H:%M') %]</b>
[% INCLUDE contact_user user = reporter %]
</div>
[% IF authoriser; # in case pre-2004 %]
<div class="row span7">
<span class="rich">Authorised by:
<b>[% authoriser.first_name | ucfirst %]</b>
<b>[% authoriser.last_name | ucfirst %]</b>
</span>
on <b>[% history.authorised.time.strftime('%a %d.%b.%Y @ %H:%M') %]</b>
[% INCLUDE contact_user user = authoriser %]
</div>
[% END %]
</div>
[% IF previous_diagnoses.size;
# PROCESS dumper.tt dump = rec.as_tree FOREACH rec IN previous_diagnoses;
BLOCK amended_report_update; # PROCESS dumper.tt dump = entry.as_tree %]
<div class="row">
<div class="row span10">
<span class="rich">Amended report (diagnosis update) issued by:
<b>[% entry.user.first_name | ucfirst %]</b>
<b>[% entry.user.last_name | ucfirst %]</b>
</span>
on <b>[% entry.time.strftime('%a %d.%b.%Y') %]
@ [% entry.time.strftime('%T').match('00:00:00') # for legacy data
? '??:??' : entry.time.strftime('%H:%M') %]</b>
[% INCLUDE contact_user user = entry.user %]
</div>
</div>
[% END;
IF ref_time;# or subtract_datetime dies
FOREACH entry IN previous_diagnoses; # INCLUDE debug_delta_days o = entry.time;
IF entry.time.subtract_datetime(ref_time).delta_days > 0;
PROCESS amended_report_update;
END; END; END;
END;
%]
</div><!-- /no-break -->
[% IF dispatch_log.size %]
<div class="_no-break" style="margin-top: 5px"><!-- no-break causes occasional loss of content -->
<div class="row">
<div class="row span7">Report sent to:
<ul>
[% FOREACH report IN dispatch_log %]
<li>[% report.recipient %] on
[% report.time.strftime('%d.%b.%Y @ %H:%M') %]</li>
[% END %]
</ul>
</div>
</div>
</div>
[% END %]
[% END %]
</div><!-- /container -->
<!-- END [% component.name %] -->