Skip to content

Commit

Permalink
Add Reason support to careplan Fixes #5267 (#5268)
Browse files Browse the repository at this point in the history
Added the reason code and start and end date selectors for the care plan
entries.  Also added the ability to have more code type selectors in the
reason code popup.  Added comments to explain the low and high on the
reason code in care plan.

Also added a comment in FHIR to explain how we'd leverage reason code if
we start reporting on the overall activity for CarePlan.
  • Loading branch information
adunsulag committed May 3, 2022
1 parent 354c7e7 commit faadfff
Show file tree
Hide file tree
Showing 11 changed files with 265 additions and 100 deletions.
118 changes: 118 additions & 0 deletions interface/forms/care_plan/careplan.js
@@ -0,0 +1,118 @@
(function(window, oeUI) {

function init(webroot, reasonCodeTypes) {
// we want to setup our reason code widgets
if (oeUI.reasonCodeWidget) {
oeUI.reasonCodeWidget.init(webroot, reasonCodeTypes);
} else {
console.error("Missing required dependency reasonCodeWidget");
return;
}
}

let form = {
"init": init
};
window.careplanForm = form;
})(window, window.oeUI || {});

function duplicateRow(e) {
var newRow = e.cloneNode(true);
e.parentNode.insertBefore(newRow, e.nextSibling);
changeIds('tb_row');
changeIds('description');
changeIds('code');
changeIds('codetext');
changeIds('code_date');
changeIds('displaytext');
changeIds('care_plan_type');
changeIds('user');
changeIds('count');
changeIds('reason_code');
changeDatasetIds('toggle-container', 'toggleContainer', 'reason_code');
clearReasonCode(newRow);
removeVal(newRow.id);
// reload our widget event listeners.
window.oeUI.reasonCodeWidget.reload();
}

function removeVal(rowid) {
rowid1 = rowid.split('tb_row_');
document.getElementById("description_" + rowid1[1]).value = '';
document.getElementById("code_" + rowid1[1]).value = '';
document.getElementById("codetext_" + rowid1[1]).value = '';
document.getElementById("code_date_" + rowid1[1]).value = '';
document.getElementById("displaytext_" + rowid1[1]).innerHTML = '';
document.getElementById("care_plan_type_" + rowid1[1]).value = '';
document.getElementById("user_" + rowid1[1]).value = '';
if (typeof doTemplateEditor !== 'undefined') {
document.getElementById("description_" + rowid1[1]).addEventListener('dblclick', event => {
doTemplateEditor(this, event, event.target.dataset.textcontext);
})
}
}

function changeDatasetIds(propertySelector, dataSetProperty, keyPrefix) {
var elements = document.querySelectorAll('[data-' + propertySelector + ']');
if (elements) {
elements.forEach(function(element, index) {
element.dataset[dataSetProperty] = keyPrefix + "_" + (index + 1);
});
}
}

function clearReasonCode(newRow) {
// make sure we clear everything out.
let inputs = newRow.querySelectorAll(".reasonCodeContainer input");
inputs.forEach(function(input) {
input.value = "";
});
// make sure we are hiding the thing.
let container = newRow.querySelector(".reasonCodeContainer");
container.classList.add("d-none");
}

function changeIds(class_val) {
var elem = document.getElementsByClassName(class_val);
for (let i = 0; i < elem.length; i++) {
if (elem[i].id) {
index = i + 1;
elem[i].id = class_val + "_" + index;
}
if(class_val == 'count') {
elem[i].value = index;
}
}
}

function deleteRow(event, rowId) {
event.stopPropagation();
event.preventDefault();
if (rowId != 'tb_row_1') {
let elem = document.getElementById(rowId);
elem.parentNode.removeChild(elem);
}
window.oeUI.reasonCodeWidget.reload();
}

function sel_code(webroot, id) {
id = id.split('tb_row_');
let checkId = '_' + id[1];
if (typeof checkId === 'undefined') {
checkId = 1;
}
document.getElementById('clickId').value = checkId;
window.top.restoreSession();
dlgopen(webroot + "/interface/patient_file/encounter/find_code_popup.php?default=SNOMED-CT", '_blank', 700, 400);
}

function set_related(codetype, code, selector, codedesc) {
let checkId = document.getElementById('clickId').value;
if (codetype !== "") {
document.getElementById("code" + checkId).value = (codetype + ":" + code);
} else {
document.getElementById("code" + checkId).value = "";
}
document.getElementById("codetext" + checkId).value = codedesc;
document.getElementById("displaytext" + checkId).innerHTML = codedesc;
}
104 changes: 16 additions & 88 deletions interface/forms/care_plan/new.php
Expand Up @@ -21,6 +21,7 @@
require_once($GLOBALS['fileroot'] . '/custom/code_types.inc.php');

use OpenEMR\Common\Csrf\CsrfUtils;
use OpenEMR\Common\Forms\ReasonStatusCodes;
use OpenEMR\Core\Header;

$returnurl = 'encounter_top.php';
Expand Down Expand Up @@ -48,90 +49,25 @@
foreach ($result as $value) :
$care_plan_type[] = $value;
endforeach;
$reasonCodeStatii = ReasonStatusCodes::getCodesWithDescriptions();
$reasonCodeStatii[ReasonStatusCodes::EMPTY]['description'] = xl("Select a status code");
?>
<html>
<head>
<title><?php echo xlt("Care Plan Form"); ?></title>

<?php Header::setupHeader(['datetime-picker']);?>
<?php Header::setupHeader(['datetime-picker', 'reason-code-widget']);?>
<script src="<?php echo attr($GLOBALS['webroot']); ?>/interface/forms/care_plan/careplan.js?v=<?php echo attr($GLOBALS['v_js_includes']); ?>" type="text/javascript"></script>
<script>
function duplicateRow(e) {
var newRow = e.cloneNode(true);
e.parentNode.insertBefore(newRow, e.nextSibling);
changeIds('tb_row');
changeIds('description');
changeIds('code');
changeIds('codetext');
changeIds('code_date');
changeIds('displaytext');
changeIds('care_plan_type');
changeIds('user');
changeIds('count');
removeVal(newRow.id);
}

function removeVal(rowid) {
rowid1 = rowid.split('tb_row_');
document.getElementById("description_" + rowid1[1]).value = '';
document.getElementById("code_" + rowid1[1]).value = '';
document.getElementById("codetext_" + rowid1[1]).value = '';
document.getElementById("code_date_" + rowid1[1]).value = '';
document.getElementById("displaytext_" + rowid1[1]).innerHTML = '';
document.getElementById("care_plan_type_" + rowid1[1]).value = '';
document.getElementById("user_" + rowid1[1]).value = '';
if (typeof doTemplateEditor !== 'undefined') {
document.getElementById("description_" + rowid1[1]).addEventListener('dblclick', event => {
doTemplateEditor(this, event, event.target.dataset.textcontext);
})
}
}

function changeIds(class_val) {
var elem = document.getElementsByClassName(class_val);
for (let i = 0; i < elem.length; i++) {
if (elem[i].id) {
index = i + 1;
elem[i].id = class_val + "_" + index;
}
if(class_val == 'count') {
elem[i].value = index;
}
}
}

function deleteRow(rowId) {
if (rowId != 'tb_row_1') {
let elem = document.getElementById(rowId);
elem.parentNode.removeChild(elem);
}
}

function sel_code(id) {
id = id.split('tb_row_');
let checkId = '_' + id[1];
if (typeof checkId === 'undefined') {
checkId = 1;
}
document.getElementById('clickId').value = checkId;
dlgopen('<?php echo $GLOBALS['webroot'] . "/interface/patient_file/encounter/" ?>find_code_popup.php?default=SNOMED-CT', '_blank', 700, 400);
}

function set_related(codetype, code, selector, codedesc) {
let checkId = document.getElementById('clickId').value;
if (codetype !== "") {
document.getElementById("code" + checkId).value = (codetype + ":" + code);
} else {
document.getElementById("code" + checkId).value = "";
}
document.getElementById("codetext" + checkId).value = codedesc;
document.getElementById("displaytext" + checkId).innerHTML = codedesc;
}
window.addEventListener('DOMContentLoaded', function() {
window.careplanForm.init(<?php echo js_url($GLOBALS['webroot']); ?>);
});

$(function () {
// special case to deal with static and dynamic datepicker items
$(document).on('mouseover','.datepicker', function(){
$(this).datetimepicker({
<?php $datetimepicker_timepicker = false; ?>
<?php $datetimepicker_timepicker = true; ?>
<?php $datetimepicker_showseconds = false; ?>
<?php $datetimepicker_formatInput = false; ?>
<?php require($GLOBALS['srcdir'] . '/js/xl/jquery-datetimepicker-2-5-4.js.php'); ?>
Expand Down Expand Up @@ -163,14 +99,14 @@ function set_related(codetype, code, selector, codedesc) {
<div class="form-row">
<div class="forms col-md-2">
<label for="code_<?php echo attr($key) + 1; ?>" class="h5"><?php echo xlt('Code'); ?>:</label>
<input type="text" id="code_<?php echo attr($key) + 1; ?>" name="code[]" class="form-control code" value="<?php echo attr($obj["code"]); ?>" onclick='sel_code(this.parentElement.parentElement.parentElement.id);' />
<input type="text" id="code_<?php echo attr($key) + 1; ?>" name="code[]" class="form-control code" value="<?php echo attr($obj["code"]); ?>" onclick='sel_code(<?php echo js_url($GLOBALS['webroot']) ?>, this.parentElement.parentElement.parentElement.id);' />
<span id="displaytext_<?php echo attr($key) + 1; ?>" class="displaytext help-block"><?php echo text($obj["codetext"] ?? ''); ?></span>
<input type="hidden" id="codetext_<?php echo attr($key) + 1; ?>" name="codetext[]" class="codetext" value="<?php echo attr($obj["codetext"]); ?>" />
<input type="hidden" id="user_<?php echo attr($key) + 1; ?>" name="user[]" class="user" value="<?php echo attr($obj["user"]); ?>" />
</div>
<div class="forms col-md-2">
<label for="code_date_<?php echo attr($key) + 1; ?>" class="h5"><?php echo xlt('Date'); ?>:</label>
<input type='text' id="code_date_<?php echo attr($key) + 1; ?>" name='code_date[]' class="form-control code_date datepicker" value='<?php echo attr($obj["date"]); ?>' title='<?php echo xla('yyyy-mm-dd Date of service'); ?>' />
<input type='text' id="code_date_<?php echo attr($key) + 1; ?>" name='code_date[]' class="form-control code_date datepicker" value='<?php echo attr($obj["date"]); ?>' title='<?php echo xla('yyyy-mm-dd HH:MM Date of service'); ?>' />
</div>
<div class="forms col-md-2">
<label for="care_plan_type_<?php echo attr($key) + 1; ?>" class="h5"><?php echo xlt('Type'); ?>:</label>
Expand All @@ -192,15 +128,11 @@ function set_related(codetype, code, selector, codedesc) {
</div>
<div class="form-row w-100 mt-2 text-center">
<div class="forms col-md-12">
<button type="button" class="btn btn-primary btn-add btn-sm" onclick="duplicateRow(this.parentElement.parentElement.parentElement.parentElement);" title='<?php echo xla('Click here to duplicate the row'); ?>'>
<?php echo xlt('Add'); ?>
</button>
<button class="btn btn-danger btn-sm" onclick="deleteRow(this.parentElement.parentElement.parentElement.parentElement.id);" title='<?php echo xla('Click here to delete the row'); ?>'>
<?php echo xlt('Delete'); ?>
</button>
<?php include("templates/careplan_actions.php"); ?>
</div>
<input type="hidden" name="count[]" id="count_<?php echo attr($key) + 1; ?>" class="count" value="<?php echo attr($key) + 1;?>" />
</div>
<?php include "templates/careplan_reason_row.php"; ?>
</div>
<hr />
</div>
Expand All @@ -210,7 +142,7 @@ function set_related(codetype, code, selector, codedesc) {
<div class="form-row">
<div class="forms col-md-2">
<label for="code_1" class="h5"><?php echo xlt('Code'); ?>:</label>
<input type="text" id="code_1" name="code[]" class="form-control code" value="<?php echo attr($obj["code"] ?? ''); ?>" onclick='sel_code(this.parentElement.parentElement.parentElement.id || "");'>
<input type="text" id="code_1" name="code[]" class="form-control code" value="<?php echo attr($obj["code"] ?? ''); ?>" onclick='sel_code(<?php echo js_url($GLOBALS['webroot']) ?>, this.parentElement.parentElement.parentElement.id || "");'>
<input type="hidden" id="user_1" name="user[]" class="user" value="<?php echo attr($obj["user"] ?? $_SESSION["authUser"]); ?>" />
<span id="displaytext_1" class="displaytext help-block"></span>
<input type="hidden" id="codetext_1" name="codetext[]" class="codetext" value="<?php echo attr($obj["codetext"] ?? ''); ?>">
Expand All @@ -236,17 +168,13 @@ function set_related(codetype, code, selector, codedesc) {
</div>
<div class="form-row w-100 mt-2 text-center">
<div class="forms col-md-12">
<button type="button" class="btn btn-primary btn-add btn-sm" onclick="duplicateRow(this.parentElement.parentElement.parentElement.parentElement);" title='<?php echo xla('Click here to duplicate the row'); ?>'>
<?php echo xlt('Add'); ?>
</button>
<button type="button" class="btn btn-danger btn-delete btn-sm" onclick="deleteRow(this.parentElement.parentElement.parentElement.parentElement.id);" title='<?php echo xla('Click here to delete the row'); ?>'>
<?php echo xlt('Delete'); ?>
</button>
<?php include("templates/careplan_actions.php"); ?>
</div>
<input type="hidden" name="count[]" id="count_1" class="count" value="1" />
</div>
<hr />
</div>
<?php include "templates/careplan_reason_row.php"; ?>
</div>
<?php } ?>
</div>
Expand Down
33 changes: 31 additions & 2 deletions interface/forms/care_plan/save.php
Expand Up @@ -36,6 +36,11 @@
$care_plan_type = $_POST['care_plan_type'];
$care_plan_user = $_POST["user"];
$note_relations = "";
$reasonCode = $_POST['reasonCode'];
$reasonStatusCode = $_POST['reasonCodeStatus'];
$reasonCodeText = $_POST['reasonCodeText'];
$reasonDateLow = $_POST['reasonDateLow'] ?? '';
$reasonDateHigh = $_POST['reasonDateHigh'] ?? '';

if ($id && $id != 0) {
sqlStatement("DELETE FROM `form_care_plan` WHERE id=? AND pid = ? AND encounter = ?", array($id, $_SESSION["pid"], $_SESSION["encounter"]));
Expand All @@ -61,6 +66,20 @@
$care_plan_type_val = $care_plan_type[$key] ?: '';
$care_user_val = $care_plan_user[$key] ?: $_SESSION["authUser"];
$note_relations = parse_note($description_val);
$reason_code = trim($reasonCode[$key] ?? '');
$reason_status = trim($reasonStatusCode[$key] ?? '');
$reason_description = trim($reasonCodeText[$key] ?? '');
$reason_low = trim($reasonDateLow[$key] ?? '');
$reason_high = trim($reasonDateHigh[$key] ?? '');

if (empty($reasonCode)) {
// just as a failsafe we will set everything else to be empty if we don't have a reason code
$reason_status = '';
$reason_description = '';
$reason_low = '';
$reason_high = '';
}

$sets = "id = ?,
pid = ?,
groupname = ?,
Expand All @@ -73,7 +92,12 @@
description = ?,
date = ?,
care_plan_type = ?,
note_related_to = ?";
note_related_to = ?,
reason_code = ?,
reason_status = ?,
reason_description = ?,
reason_date_low = ?,
reason_date_high = ?";
sqlStatement(
"INSERT INTO form_care_plan SET " . $sets,
[
Expand All @@ -88,7 +112,12 @@
$description_val,
$code_date[$key],
$care_plan_type_val,
$note_relations
$note_relations,
$reason_code,
$reason_status,
$reason_description,
$reason_low,
$reason_high
]
);
endforeach;
Expand Down
21 changes: 21 additions & 0 deletions interface/forms/care_plan/templates/careplan_actions.php
@@ -0,0 +1,21 @@
<?php

/**
* careplan_actions.php is a template file for the action buttons displayed in the careplan form
* @package openemr
* @link http://www.open-emr.org
* @author Stephen Nielson <snielson@discoverandchange.com>
* @copyright Copyright (c) 2022 Discover and Change <snielson@discoverandchange.com>
* @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
*/

?>
<button type="button" class="btn btn-primary btn-add btn-sm" onclick="duplicateRow(this.parentElement.parentElement.parentElement.parentElement);" title='<?php echo xla('Click here to duplicate the row'); ?>'>
<?php echo xlt('Add'); ?>
</button>
<button class="btn btn-danger btn-sm" onclick="deleteRow(event, this.parentElement.parentElement.parentElement.parentElement.id);" title='<?php echo xla('Click here to delete the row'); ?>'>
<?php echo xlt('Delete'); ?>
</button>
<button class="btn btn-secondary reason-code-btn btn-sm"
title='<?php echo xla('Click here to provide an explanation for the observation value (or lack of value)'); ?>'
data-toggle-container="reason_code_<?php echo attr($key); ?>"><i class="fa fa-asterisk"></i> <?php echo xlt("Add Reason"); ?></button>

0 comments on commit faadfff

Please sign in to comment.