Refactor previous name into dedicated service (#7571)
[openemr.git] / interface / patient_file / encounter / forms.php
blobe1d390505bed471ef952ae66d810f897b8e0f00e
1 <?php
3 /**
4 * forms.php
6 * @package OpenEMR
7 * @link http://www.open-emr.org
8 * @author Brady Miller <brady.g.miller@gmail.com>
9 * @author Jerry Padgett <sjpadgett@gmail.com>
10 * @copyright Copyright (c) 2018 Brady Miller <brady.g.miller@gmail.com>
11 * @copyright Copyright (c) 2018-2021 Jerry Padgett <sjpadgett@gmail.com>
12 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
15 require_once(__DIR__ . "/../../globals.php");
16 require_once("$srcdir/encounter.inc.php");
17 require_once("$srcdir/group.inc.php");
18 require_once("$srcdir/patient.inc.php");
19 require_once("$srcdir/amc.php");
20 require_once($GLOBALS['srcdir'] . '/ESign/Api.php');
21 require_once("$srcdir/../controllers/C_Document.class.php");
23 use ESign\Api;
24 use OpenEMR\Common\Acl\AclMain;
25 use OpenEMR\Common\Csrf\CsrfUtils;
26 use OpenEMR\Common\Twig\TwigContainer;
27 use OpenEMR\Core\Header;
28 use OpenEMR\Events\Encounter\EncounterMenuEvent;
29 use OpenEMR\Services\EncounterService;
30 use OpenEMR\Services\UserService;
31 use Symfony\Component\EventDispatcher\EventDispatcher;
32 use OpenEMR\Events\Encounter\EncounterFormsListRenderEvent;
34 $expand_default = (int)$GLOBALS['expand_form'] ? 'show' : 'hide';
35 $reviewMode = false;
36 if (!empty($_REQUEST['review_id'])) {
37 $reviewMode = true;
38 $encounter = sanitizeNumber($_REQUEST['review_id']);
41 $is_group = ($attendant_type == 'gid') ? true : false;
42 if ($attendant_type == 'gid') {
43 $groupId = $therapy_group;
45 $attendant_id = $attendant_type == 'pid' ? $pid : $therapy_group;
46 if ($is_group && !AclMain::aclCheckCore("groups", "glog", false, array('view','write'))) {
47 echo xlt("access not allowed");
48 exit();
51 if ($GLOBALS['kernel']->getEventDispatcher() instanceof EventDispatcher) {
52 /**
53 * @var EventDispatcher
55 $eventDispatcher = $GLOBALS['kernel']->getEventDispatcher();
56 } else {
57 throw new Exception("Could not get EventDispatcher from kernel", 1);
61 <!DOCTYPE html>
62 <html>
64 <head>
66 <?php require $GLOBALS['srcdir'] . '/js/xl/dygraphs.js.php'; ?>
68 <?php Header::setupHeader(['common','esign','dygraphs', 'utility']); ?>
70 <?php
71 $esignApi = new Api();
74 <?php // if the track_anything form exists, then include the styling and js functions (and js variable) for graphing
75 if (file_exists(dirname(__FILE__) . "/../../forms/track_anything/style.css")) { ?>
76 <script>
77 var csrf_token_js = <?php echo js_escape(CsrfUtils::collectCsrfToken()); ?>;
78 </script>
79 <script src="<?php echo $GLOBALS['web_root']?>/interface/forms/track_anything/report.js"></script>
80 <link rel="stylesheet" href="<?php echo $GLOBALS['web_root']?>/interface/forms/track_anything/style.css">
81 <?php } ?>
83 <?php
84 // If the user requested attachment of any orphaned procedure orders, do it.
85 if (!empty($_GET['attachid'])) {
86 $attachid = explode(',', $_GET['attachid']);
87 foreach ($attachid as $aid) {
88 $aid = intval($aid);
89 if (!$aid) {
90 continue;
92 $tmp = sqlQuery(
93 "SELECT COUNT(*) AS count FROM procedure_order WHERE " .
94 "procedure_order_id = ? AND patient_id = ? AND encounter_id = 0 AND activity = 1",
95 array($aid, $pid)
97 if (!empty($tmp['count'])) {
98 sqlStatement(
99 "UPDATE procedure_order SET encounter_id = ? WHERE " .
100 "procedure_order_id = ? AND patient_id = ? AND encounter_id = 0 AND activity = 1",
101 array($encounter, $aid, $pid)
103 addForm($encounter, "Procedure Order", $aid, "procedure_order", $pid, $userauthorized);
110 <?php
111 // If google sign-in enable then add scripts.
112 if (!empty($GLOBALS['google_signin_enabled']) && !empty($GLOBALS['google_signin_client_id'])) {?>
113 <script src="https://accounts.google.com/gsi/client" async defer></script>
114 <script src="<?php echo $GLOBALS['web_root']?>/library/js/gSignIn.js"></script>
115 <?php } ?>
117 <script>
118 $(function () {
119 var formConfig = <?php echo $esignApi->formConfigToJson(); ?>;
120 $(".esign-button-form").esign(
121 formConfig,
123 afterFormSuccess : function( response ) {
124 if ( response.locked ) {
125 var editButtonId = "form-edit-button-"+response.formDir+"-"+response.formId;
126 $("#"+editButtonId).replaceWith( response.editButtonHtml );
129 var logId = "esign-signature-log-"+response.formDir+"-"+response.formId;
130 $.post( formConfig.logViewAction, response, function( html ) {
131 $("#"+logId).replaceWith( html );
137 var encounterConfig = <?php echo $esignApi->encounterConfigToJson(); ?>;
138 $(".esign-button-encounter").esign(
139 encounterConfig,
141 afterFormSuccess : function( response ) {
142 // If the response indicates a locked encounter, replace all
143 // form edit buttons with a "disabled" button, and "disable" left
144 // nav visit form links
145 if ( response.locked ) {
146 // Lock the form edit buttons
147 $(".form-edit-button").replaceWith( response.editButtonHtml );
148 // Disable the new-form capabilities in left nav
149 top.window.parent.left_nav.syncRadios();
150 // Disable the new-form capabilities in top nav of the encounter
151 $(".encounter-form-category-li").remove();
154 var logId = "esign-signature-log-encounter-"+response.encounterId;
155 $.post( encounterConfig.logViewAction, response, function( html ) {
156 $("#"+logId).replaceWith( html );
162 $("#prov_edu_res").click(function() {
163 if ( $('#prov_edu_res').prop('checked') ) {
164 var mode = "add";
166 else {
167 var mode = "remove";
169 top.restoreSession();
170 $.post( "../../../library/ajax/amc_misc_data.php",
171 { amc_id: "patient_edu_amc",
172 complete: true,
173 mode: mode,
174 patient_id: <?php echo js_escape($pid); ?>,
175 object_category: "form_encounter",
176 object_id: <?php echo js_escape($encounter); ?>,
177 csrf_token_form: <?php echo js_escape(CsrfUtils::collectCsrfToken()); ?>
182 $("#provide_sum_pat_flag").click(function() {
183 if ( $('#provide_sum_pat_flag').prop('checked') ) {
184 var mode = "add";
186 else {
187 var mode = "remove";
189 top.restoreSession();
190 $.post( "../../../library/ajax/amc_misc_data.php",
191 { amc_id: "provide_sum_pat_amc",
192 complete: true,
193 mode: mode,
194 patient_id: <?php echo js_escape($pid); ?>,
195 object_category: "form_encounter",
196 object_id: <?php echo js_escape($encounter); ?>,
197 csrf_token_form: <?php echo js_escape(CsrfUtils::collectCsrfToken()); ?>
202 $("#trans_trand_care").click(function() {
203 if ( $('#trans_trand_care').prop('checked') ) {
204 var mode = "add";
205 // Enable the reconciliation checkbox
206 $("#med_reconc_perf").removeAttr("disabled");
207 $("#soc_provided").removeAttr("disabled");
209 else {
210 var mode = "remove";
211 //Disable the reconciliation checkbox (also uncheck it if applicable)
212 $("#med_reconc_perf").attr("disabled", true);
213 $("#med_reconc_perf").prop("checked",false);
214 $("#soc_provided").attr("disabled",true);
215 $("#soc_provided").prop("checked",false);
217 top.restoreSession();
218 $.post( "../../../library/ajax/amc_misc_data.php",
219 { amc_id: "med_reconc_amc",
220 complete: false,
221 mode: mode,
222 patient_id: <?php echo js_escape($pid); ?>,
223 object_category: "form_encounter",
224 object_id: <?php echo js_escape($encounter); ?>,
225 csrf_token_form: <?php echo js_escape(CsrfUtils::collectCsrfToken()); ?>
230 $("#med_reconc_perf").click(function() {
231 if ( $('#med_reconc_perf').prop('checked') ) {
232 var mode = "complete";
234 else {
235 var mode = "uncomplete";
237 top.restoreSession();
238 $.post( "../../../library/ajax/amc_misc_data.php",
239 { amc_id: "med_reconc_amc",
240 complete: true,
241 mode: mode,
242 patient_id: <?php echo js_escape($pid); ?>,
243 object_category: "form_encounter",
244 object_id: <?php echo js_escape($encounter); ?>,
245 csrf_token_form: <?php echo js_escape(CsrfUtils::collectCsrfToken()); ?>
249 $("#soc_provided").click(function(){
250 if($('#soc_provided').prop('checked')){
251 var mode = "soc_provided";
253 else{
254 var mode = "no_soc_provided";
256 top.restoreSession();
257 $.post( "../../../library/ajax/amc_misc_data.php",
258 { amc_id: "med_reconc_amc",
259 complete: true,
260 mode: mode,
261 patient_id: <?php echo js_escape($pid); ?>,
262 object_category: "form_encounter",
263 object_id: <?php echo js_escape($encounter); ?>,
264 csrf_token_form: <?php echo js_escape(CsrfUtils::collectCsrfToken()); ?>
269 $(".deleteme").click(function(evt) { deleteme(); evt.stopPropogation(); });
271 <?php
272 // If the user was not just asked about orphaned orders, build javascript for that.
273 if (!isset($_GET['attachid'])) {
274 $ares = sqlStatement(
275 "SELECT procedure_order_id, date_ordered " .
276 "FROM procedure_order WHERE " .
277 "patient_id = ? AND encounter_id = 0 AND activity = 1 " .
278 "ORDER BY procedure_order_id",
279 array($pid)
281 echo " // Ask about attaching orphaned orders to this encounter.\n";
282 echo " var attachid = '';\n";
283 while ($arow = sqlFetchArray($ares)) {
284 $orderid = $arow['procedure_order_id'];
285 $orderdate = $arow['date_ordered'];
286 echo " if (confirm(" . xlj('There is a lab order') . " + ' ' + " . js_escape($orderid) . " + ' ' + " .
287 xlj('dated') . " + ' ' + " . js_escape($orderdate) . " + ' ' + " .
288 xlj('for this patient not yet assigned to any encounter.') . " + ' ' + " .
289 xlj('Assign it to this one?') . ")) attachid += " . js_escape($orderid . ",") . ";\n";
291 echo " if (attachid) location.href = 'forms.php?attachid=' + encodeURIComponent(attachid);\n";
295 <?php if ($reviewMode) { ?>
296 $("body table:first").hide();
297 $(".encounter-summary-column").hide();
298 $(".btn").hide();
299 $(".encounter-summary-column:first").show();
300 $(".title:first").text(<?php echo xlj("Review"); ?> + " " + $(".title:first").text() + " ( " + <?php echo js_escape($encounter); ?> + " )");
301 <?php } ?>
304 // Process click on Delete link.
305 function deleteme() {
306 dlgopen('../deleter.php?encounterid=' + <?php echo js_url($encounter); ?> + '&csrf_token_form=' + <?php echo js_url(CsrfUtils::collectCsrfToken()); ?>, '_blank', 500, 200, '', '', {
307 allowResize: false,
308 allowDrag: true,
310 return false;
314 // create new follow-up Encounter.
315 function createFollowUpEncounter() {
317 <?php
318 $result = sqlQuery("SELECT * FROM form_encounter WHERE pid = ? AND encounter = ?", array(
319 $_SESSION['pid'],
320 $encounter
322 $encounterId = (!empty($result['parent_encounter_id'])) ? $result['parent_encounter_id'] : $result['id'];
324 var data = {encounterId: '<?php echo attr($encounterId); ?>', mode: 'follow_up_encounter'};
325 top.window.parent.newEncounter(data);
329 // Called by the deleter.php window on a successful delete.
330 function imdeleted(EncounterId) {
331 top.window.parent.left_nav.removeOptionSelected(EncounterId);
332 top.window.parent.left_nav.clearEncounter();
333 top.encounterList();
336 // Called to open the data entry form a specified encounter form instance.
337 function openEncounterForm(formdir, formname, formid) {
338 var url = <?php echo js_escape($rootdir); ?> + '/patient_file/encounter/view_form.php?formname=' +
339 encodeURIComponent(formdir) + '&id=' + encodeURIComponent(formid);
340 if (formdir == 'newpatient' || !parent.twAddFrameTab) {
341 top.restoreSession();
342 location.href = url;
344 else {
345 parent.twAddFrameTab('enctabs', formname, url);
347 return false;
350 // Called when an encounter form may changed something that requires a refresh here.
351 function refreshVisitDisplay() {
352 location.href = <?php echo js_escape($rootdir); ?> + '/patient_file/encounter/forms.php';
355 </script>
357 <style>
358 div.tab {
359 min-height: 50px;
360 padding: 8px;
363 div.formname {
364 float: left;
365 min-width: 160px;
366 padding: 0;
367 margin: 0;
370 .encounter-summary-container {
371 float: left;
372 width: 100%;
375 .encounter-summary-column {
376 width: 33.3%;
377 float: left;
378 display: inline;
379 margin-top: 10px;
382 #sddm {
383 margin: 0;
384 padding: 0;
385 z-index: 30;
388 button:focus {
389 outline: none;
392 button::-moz-focus-inner {
393 border: 0;
395 </style>
397 <!-- *************** -->
398 <!-- Form menu start -->
399 <script>
401 function openNewForm(sel, label) {
402 top.restoreSession();
403 let FormNameValueArray = sel.split('formname=');
404 if (FormNameValueArray[1] == 'newpatient') {
405 // TBD: Make this work when it's not the first frame.
406 parent.frames[0].location.href = sel;
407 } else {
408 if (FormNameValueArray[1] == 'questionnaire_assessments') {
409 sel += "&questionnaire_form=" + encodeURIComponent(label);
411 parent.twAddFrameTab('enctabs', label, sel);
415 function toggleFrame1(fnum) {
416 top.frames['left_nav'].document.forms[0].cb_top.checked=false;
417 top.window.parent.left_nav.toggleFrame(fnum);
419 </script>
420 <script>
422 var timeout = 500;
423 var closetimer = 0;
424 var ddmenuitem = 0;
425 var oldddmenuitem = 0;
426 var flag = 0;
428 // open hidden layer
429 function mopen(id) {
430 // cancel close timer
431 //mcancelclosetime();
433 flag = 10;
435 // close old layer
436 //if(ddmenuitem) ddmenuitem.style.visibility = 'hidden';
437 //if(ddmenuitem) ddmenuitem.style.display = 'none';
439 // get new layer and show it
440 oldddmenuitem = ddmenuitem;
441 ddmenuitem = document.getElementById(id);
442 if ((ddmenuitem.style.visibility == '')||(ddmenuitem.style.visibility == 'hidden')){
443 if (oldddmenuitem) {
444 oldddmenuitem.style.visibility = 'hidden';
445 oldddmenuitem.style.display = 'none';
447 ddmenuitem.style.visibility = 'visible';
448 ddmenuitem.style.display = 'block';
449 } else {
450 ddmenuitem.style.visibility = 'hidden';
451 ddmenuitem.style.display = 'none';
455 // close showed layer
456 function mclose() {
457 if (flag === 10) {
458 flag = 11;
459 return;
461 if (ddmenuitem) {
462 ddmenuitem.style.visibility = 'hidden';
463 ddmenuitem.style.display = 'none';
467 // close layer when click-out
468 document.onclick = mclose;
469 //=================================================
470 function findPosX(id) {
471 obj = document.getElementById(id);
472 var curleft = 0;
473 if(obj.offsetParent) {
474 while(1) {
475 curleft += obj.offsetLeft;
476 if (!obj.offsetParent) {
477 break;
479 obj = obj.offsetParent;
481 } else if(obj.x) {
482 curleft += obj.x;
485 PropertyWidth = document.getElementById(id).offsetWidth;
486 if (PropertyWidth > curleft) {
487 document.getElementById(id).style.left = 0;
491 function findPosY(obj) {
492 var curtop = 0;
493 if(obj.offsetParent) {
494 while(1) {
495 curtop += obj.offsetTop;
496 if(!obj.offsetParent) {
497 break;
499 obj = obj.offsetParent;
501 } else if (obj.y) {
502 curtop += obj.y;
504 return curtop;
506 </script>
508 </head>
509 <body>
510 <nav>
511 <?php //DYNAMIC FORM RETREIVAL
512 require_once("$srcdir/registry.inc.php");
514 $reg = getFormsByCategory();
515 $old_category = '';
516 $DivId = 1;
518 // To see if the encounter is locked. If it is, no new forms can be created
519 $encounterLocked = false;
520 if (
521 $esignApi->lockEncounters() &&
522 isset($GLOBALS['encounter']) &&
523 !empty($GLOBALS['encounter'])
525 $esign = $esignApi->createEncounterESign($GLOBALS['encounter']);
526 if ($esign->isLocked()) {
527 $encounterLocked = true;
532 // Convert the flat list of menu items into a multi-dimensional array based on the category
533 // decide what will be displayed (name or nickname)
534 $eventDispatcher->addListener(EncounterMenuEvent::MENU_RENDER, function (EncounterMenuEvent $menuEvent) {
535 $menuArray = $menuEvent->getMenuData();
536 $reg = getFormsByCategory();
537 foreach ($reg as $item) {
538 $tmp = explode('|', $item['aco_spec']);
539 if (!empty($tmp[1])) {
540 if (!AclMain::aclCheckCore($tmp[0], $tmp[1], '', 'write') && !AclMain::aclCheckCore($tmp[0], $tmp[1], '', 'addonly')) {
541 continue;
545 $_cat = trim($item['category'] ?? '');
546 $_cat = ($_cat == '') ? xl("Miscellaneous") : xl($_cat);
547 $item['displayText'] = (trim($item['nickname'] ?? '') != '') ? trim($item['nickname'] ?? '') : trim($item['name'] ?? '');
548 unset($item['category']);
549 unset($item['name']);
550 unset($item['nickname']);
551 $menuArray[$_cat]['children'][] = $item;
553 $menuEvent->setMenuData($menuArray);
554 return $menuEvent;
558 // Zend Module hooks
559 $eventDispatcher->addListener(EncounterMenuEvent::MENU_RENDER, function (EncounterMenuEvent $menuEvent) {
560 $module_query = sqlStatement("SELECT msh.*, ms.menu_name, ms.path, m.mod_ui_name, m.type
561 FROM modules_hooks_settings AS msh
562 LEFT OUTER JOIN modules_settings AS ms ON obj_name=enabled_hooks AND ms.mod_id=msh.mod_id
563 LEFT OUTER JOIN modules AS m ON m.mod_id=ms.mod_id
564 WHERE fld_type=3
565 AND mod_active=1
566 AND sql_run=1
567 AND attached_to='encounter'
568 ORDER BY mod_id");
570 $menuData = $menuEvent->getMenuData();
572 while ($row = sqlFetchArray($module_query)) {
573 $_cat = $row['mod_ui_name'];
574 if ($row['type'] == 0) {
575 $modulePath = $GLOBALS['customModDir'];
576 $added = "";
577 } else {
578 $modulePath = $GLOBALS['zendModDir'];
579 $added = "index";
582 $relativeLink = "../../modules/{$modulePath}/public/{$row['path']}";
583 $row['menu_name'] = $row['menu_name'] ?: "No_Name";
584 $row['href'] = $relativeLink;
585 $menuData[$_cat]['children'][] = $row;
588 $menuEvent->setMenuData($menuData);
589 return $menuEvent;
592 $dateres = getEncounterDateByEncounter($encounter);
593 $encounter_date = date("Y-m-d", strtotime($dateres["date"]));
594 $providerIDres = getProviderIdOfEncounter($encounter);
595 $providerNameRes = getProviderName($providerIDres, false);
597 // Check for group encounter
598 if ($attendant_type == 'pid' && is_numeric($pid)) {
599 $groupEncounter = false;
600 $result = getPatientData($pid, "fname,lname,squad");
601 $patientName = getPatientFullNameAsString($pid);
602 } else {
603 $groupEncounter = true;
604 $result = getGroup($groupId);
605 $patientName = $result['group_name'];
608 // Check for no access to the patient's squad.
609 if ($result['squad'] && !AclMain::aclCheckCore('squads', $result['squad'])) {
610 $pass_sens_squad = false;
613 $encounterMenuEvent = new EncounterMenuEvent();
614 $menu = $eventDispatcher->dispatch($encounterMenuEvent, EncounterMenuEvent::MENU_RENDER);
616 $twig = new TwigContainer(null, $GLOBALS['kernel']);
617 $t = $twig->getTwig();
618 echo $t->render('encounter/forms/navbar.html.twig', [
619 'encounterDate' => oeFormatShortDate($encounter_date),
620 'patientName' => $patientName,
621 'isAdminSuper' => AclMain::aclCheckCore("admin", "super"),
622 'enableFollowUpEncounters' => $GLOBALS['enable_follow_up_encounters'],
623 'menuArray' => $menu->getMenuData(),
627 <div id="encounter_forms" class="container-xl">
628 <div class='encounter-summary-container'>
629 <?php
630 $dispatcher = $GLOBALS['kernel']->getEventDispatcher();
631 if ($dispatcher instanceof EventDispatcher) {
632 $event = new EncounterFormsListRenderEvent($_SESSION['encounter'], $attendant_type);
633 $event->setGroupId($groupId ?? null);
634 $event->setPid($pid ?? null);
635 $dispatcher->dispatch($event, EncounterFormsListRenderEvent::EVENT_SECTION_RENDER_PRE);
638 <div class='encounter-summary-column'>
639 <div>
640 <?php
641 $pass_sens_squad = true;
642 //fetch acl for category of given encounter
643 $pc_catid = fetchCategoryIdByEncounter($encounter);
644 $postCalendarCategoryACO = AclMain::fetchPostCalendarCategoryACO($pc_catid);
645 if ($postCalendarCategoryACO) {
646 $postCalendarCategoryACO = explode('|', $postCalendarCategoryACO);
647 $authPostCalendarCategory = AclMain::aclCheckCore($postCalendarCategoryACO[0], $postCalendarCategoryACO[1]);
648 $authPostCalendarCategoryWrite = AclMain::aclCheckCore($postCalendarCategoryACO[0], $postCalendarCategoryACO[1], '', 'write');
649 } else { // if no aco is set for category
650 $authPostCalendarCategory = true;
651 $authPostCalendarCategoryWrite = true;
654 // Check for no access to the encounter's sensitivity level.
655 $sensitivity = (new EncounterService())->getSensitivity($pid, $encounter);
656 if (($sensitivity && !AclMain::aclCheckCore('sensitivities', $sensitivity)) || (!$authPostCalendarCategory ?? '')) {
657 $pass_sens_squad = false;
660 </div>
661 <div style='margin-top: 8px;'>
662 <?php
663 // ESign for entire encounter
664 $esign = $esignApi->createEncounterESign($encounter);
665 if ($esign->isButtonViewable()) {
666 echo $esign->buttonHtml();
670 </div>
671 </div>
673 <div class='encounter-summary-column'>
674 <?php if ($esign->isLogViewable()) {
675 $esign->renderLog();
676 } ?>
677 </div>
678 <div class='encounter-summary-column'>
679 <?php if ($GLOBALS['enable_amc_prompting']) { ?>
680 <div class="float-right border border-dark mb-2">
681 <a class="btn btn-link p-0 m-1 float-right" data-toggle="collapse" data-target="#amc-requires"><?php echo xlt('AMC Requires'); ?></a>
682 <div id="amc-requires" class="float-left m-2 collapse">
683 <table>
684 <tr>
685 <td>
686 <?php // Display the education resource checkbox (AMC prompting)
687 $itemAMC = amcCollect("patient_edu_amc", $pid, 'form_encounter', $encounter);
689 <?php if (!(empty($itemAMC))) { ?>
690 <input type="checkbox" id="prov_edu_res" checked />
691 <?php } else { ?>
692 <input type="checkbox" id="prov_edu_res" />
693 <?php } ?>
694 </td>
695 <td>
696 <span class="text"><?php echo xlt('Provided Education Resource(s)?') ?></span>
697 </td>
698 </tr>
699 <tr>
700 <td>
701 <?php // Display the Provided Clinical Summary checkbox (AMC prompting)
702 $itemAMC = amcCollect("provide_sum_pat_amc", $pid, 'form_encounter', $encounter);
704 <?php if (!(empty($itemAMC))) { ?>
705 <input type="checkbox" id="provide_sum_pat_flag" checked />
706 <?php } else { ?>
707 <input type="checkbox" id="provide_sum_pat_flag" />
708 <?php } ?>
709 </td>
710 <td>
711 <span class="text"><?php echo xlt('Provided Clinical Summary?') ?></span>
712 </td>
713 </tr>
714 <?php // Display the medication reconciliation checkboxes (AMC prompting)
715 $itemAMC = amcCollect("med_reconc_amc", $pid, 'form_encounter', $encounter);
717 <?php if (!(empty($itemAMC))) { ?>
718 <tr>
719 <td>
720 <input type="checkbox" id="trans_trand_care" checked />
721 </td>
722 <td>
723 <span class="text"><?php echo xlt('Transition/Transfer of Care?') ?></span>
724 </td>
725 </tr>
726 </table>
727 <table class="ml-4">
728 <tr>
729 <td>
730 <?php if (!(empty($itemAMC['date_completed']))) { ?>
731 <input type="checkbox" id="med_reconc_perf" checked />
732 <?php } else { ?>
733 <input type="checkbox" id="med_reconc_perf" />
734 <?php } ?>
735 </td>
736 <td>
737 <span class="text"><?php echo xlt('Medication Reconciliation Performed?') ?></span>
738 </td>
739 </tr>
740 <tr>
741 <td>
742 <?php if (!(empty($itemAMC['soc_provided']))) { ?>
743 <input type="checkbox" id="soc_provided" checked />
744 <?php } else { ?>
745 <input type="checkbox" id="soc_provided" />
746 <?php } ?>
747 </td>
748 <td>
749 <span class="text"><?php echo xlt('Summary Of Care Provided?') ?></span>
750 </td>
751 </tr>
752 </table>
753 <?php } else { ?>
754 <tr>
755 <td>
756 <input type="checkbox" id="trans_trand_care" />
757 </td>
758 <td>
759 <span class="text"><?php echo xlt('Transition/Transfer of Care?') ?></span>
760 </td>
761 </tr>
762 </table>
763 <table class="ml-4">
764 <tr>
765 <td>
766 <input type="checkbox" id="med_reconc_perf" disabled />
767 </td>
768 <td>
769 <span class="text"><?php echo xlt('Medication Reconciliation Performed?') ?></span>
770 </td>
771 </tr>
772 <tr>
773 <td>
774 <input type="checkbox" id="soc_provided" disabled />
775 </td>
776 <td>
777 <span class="text"><?php echo xlt('Summary of Care Provided?') ?></span>
778 </td>
779 </tr>
780 </table>
781 <?php } ?>
782 </div>
783 </div>
784 <?php } ?>
785 </div>
787 </div>
789 <!-- Get the documents tagged to this encounter and display the links and notes as the tooltip -->
790 <?php
791 if ($attendant_type == 'pid') {
792 $docs_list = getDocumentsByEncounter($pid, $_SESSION['encounter']);
793 } else {
794 // already doesn't exist document for therapy groups
795 $docs_list = array();
797 if (!empty($docs_list) && count($docs_list) > 0) {
799 <div class='enc_docs'>
800 <span class="font-weight-bold"><?php echo xlt("Document(s)"); ?>:</span>
801 <?php
802 $doc = new C_Document();
803 foreach ($docs_list as $doc_iter) {
804 $doc_url = $doc->getTemplateVars('CURRENT_ACTION') . "&view&patient_id=" . attr_url($pid) . "&document_id=" . attr_url($doc_iter['id']) . "&";
805 // Get notes for this document.
806 $queryString = "SELECT GROUP_CONCAT(note ORDER BY date DESC SEPARATOR '|') AS docNotes, GROUP_CONCAT(date ORDER BY date DESC SEPARATOR '|') AS docDates
807 FROM notes WHERE foreign_id = ? GROUP BY foreign_id";
808 $noteData = sqlQuery($queryString, array($doc_iter['id']));
809 $note = '';
810 if ($noteData) {
811 $notes = array();
812 $notes = explode("|", $noteData['docNotes']);
813 $dates = explode("|", $noteData['docDates']);
814 for ($i = 0, $iMax = count($notes); $i < $iMax; $i++) {
815 $note .= oeFormatShortDate(date('Y-m-d', strtotime($dates[$i]))) . " : " . $notes[$i] . "\n";
819 <a href="<?php echo $doc_url;?>" style="font-size: small;" onsubmit="return top.restoreSession()"><?php echo text($doc_iter['document_name']) . ": " . text(basename($doc_iter['name']));?></a>
820 <?php if ($note != '') {?>
821 <a href="javascript:void(0);" title="<?php echo attr($note);?>"><img src="<?php echo $GLOBALS['images_static_relative']; ?>/info.png"/></a>
822 <?php }?>
823 <?php } ?>
824 </div>
825 <?php } ?>
827 <?php
828 if (
829 $pass_sens_squad &&
830 ($result = getFormByEncounter(
831 $attendant_id,
832 $encounter,
833 "id, date, form_id, form_name, formdir, user, deleted",
835 "FIND_IN_SET(formdir,'newpatient') DESC, form_name, date DESC"
838 echo "<div class='w-100' id='partable'>";
839 $divnos = 1;
840 foreach ($result as $iter) {
841 $formdir = $iter['formdir'];
843 // skip forms whose 'deleted' flag is set to 1
844 if ($iter['deleted'] == 1) {
845 continue;
848 $aco_spec = false;
850 if (substr($formdir, 0, 3) == 'LBF') {
851 // Skip LBF forms that we are not authorized to see.
852 $lrow = sqlQuery(
853 "SELECT grp_aco_spec " .
854 "FROM layout_group_properties WHERE " .
855 "grp_form_id = ? AND grp_group_id = '' AND grp_activity = 1",
856 array($formdir)
858 if (!empty($lrow)) {
859 if (!empty($lrow['grp_aco_spec'])) {
860 $aco_spec = explode('|', $lrow['grp_aco_spec']);
861 if (!AclMain::aclCheckCore($aco_spec[0], $aco_spec[1])) {
862 continue;
866 } else {
867 // Skip non-LBF forms that we are not authorized to see.
868 $tmp = getRegistryEntryByDirectory($formdir, 'aco_spec');
869 if (!empty($tmp['aco_spec'])) {
870 $aco_spec = explode('|', $tmp['aco_spec']);
871 if (!AclMain::aclCheckCore($aco_spec[0], $aco_spec[1])) {
872 continue;
877 // $form_info = getFormInfoById($iter['id']);
878 $form_class_list = (strtolower(substr($iter['form_name'], 0, 5)) == 'camos') ? "" : "text onerow";
879 echo '<div id="' . attr($formdir) . '~' . attr($iter['form_id']) . '" title="' . xla("Edit Form") . '" class="form-holder ' . $form_class_list . '">';
881 $acl_groups = AclMain::aclCheckCore("groups", "glog", false, 'write') ? true : false;
882 $user = (new UserService())->getUserByUsername($iter['user']);
884 $form_name = ($formdir == 'newpatient') ? xl('Visit Summary') : xl_form_title($iter['form_name']);
886 // Create the ESign instance for this form
887 $esign = $esignApi->createFormESign($iter['id'], $formdir, $encounter);
889 // Figure out the correct author (encounter authors are the '$providerNameRes', while other
890 // form authors are the '$user['fname'] . " " . $user['lname']').
891 $form_author = ($formdir == 'newpatient') ? $providerNameRes :
892 ($user['fname'] ?? '') . " " .
893 (($user['mname'] ?? '') ? $user['mname'] . " " : " ") .
894 ($user['lname'] ?? '') .
895 (($user['suffix'] ?? '') ? ", " . $user['suffix'] : '') .
896 (($user['valedictory'] ?? '') ? ", " . ($user['valedictory']) : '');
897 $div_nums_attr = attr($divnos);
898 $title = xla("Expand/Collapse this form");
899 $display = text($form_name) . " " . xlt("by") . " " . text($form_author);
900 $author_text = text($form_author);
901 $by_text = xlt("by");
902 $chevron = "fa-chevron-down";
903 $form_text = text($form_name);
904 echo <<<HTML
905 <div class="form-header border-bottom border-dark w-100 d-flex align-items-center justify-content-between">
906 <button class="btn btn-sm btn-text" data-toggle="collapse" data-target="#divid_{$div_nums_attr}" title="{$title}">
907 <i class="fa fa-fw {$chevron}"></i>
908 </button>
909 <div class="form_header flex-fill">
910 <a href="#" data-toggle="collapse" data-target="#divid_{$div_nums_attr}" class="" id="aid_{$div_nums_attr}">
911 <h5 class="mb-0">{$form_text} <small class="text-muted">({$by_text} {$author_text})</small></h5>
912 </a>
913 </div>
914 <div>
915 <div class='form_header_controls btn-group' role='group'>
916 HTML;
918 // If the form is locked, it is no longer editable
919 if ($esign->isLocked()) {
920 echo "<a href='#' class='btn btn-text btn-sm form-edit-button-locked' id='form-edit-button-" . attr($formdir) . "-" . attr($iter['id']) . "'><i class='fa fa-lock fa-fw'></i>&nbsp;" . xlt('Locked') . "</a>";
921 } else {
922 if (
923 (!$aco_spec || AclMain::aclCheckCore($aco_spec[0], $aco_spec[1], '', 'write') and $is_group == 0 and $authPostCalendarCategoryWrite)
924 or (((!$aco_spec || AclMain::aclCheckCore($aco_spec[0], $aco_spec[1], '', 'write')) and $is_group and AclMain::aclCheckCore("groups", "glog", false, 'write')) and $authPostCalendarCategoryWrite)
926 echo "<a class='btn btn-text btn-sm form-edit-button btn-edit' " .
927 "id='form-edit-button-" . attr($formdir) . "-" . attr($iter['id']) . "' " .
928 "href='#' " .
929 "title='" . xla('Edit this form') . "' " .
930 "onclick=\"return openEncounterForm(" . attr_js($formdir) . ", " .
931 attr_js($form_name) . ", " . attr_js($iter['form_id']) . ")\">";
932 echo "" . xlt('Edit') . "</a>";
936 if (($esign->isButtonViewable() and $is_group == 0 and $authPostCalendarCategoryWrite) or ($esign->isButtonViewable() and $is_group and AclMain::aclCheckCore("groups", "glog", false, 'write') and $authPostCalendarCategoryWrite)) {
937 if (!$aco_spec || AclMain::aclCheckCore($aco_spec[0], $aco_spec[1], '', 'write')) {
938 echo $esign->buttonHtml();
942 if (substr($formdir, 0, 3) == 'LBF') {
943 // A link for a nice printout of the LBF
944 echo "<a target='_blank' " .
945 "href='$rootdir/forms/LBF/printable.php?" .
946 "formname=" . attr_url($formdir) .
947 "&formid=" . attr_url($iter['form_id']) .
948 "&visitid=" . attr_url($encounter) .
949 "&patientid=" . attr_url($pid) .
950 "' class='btn btn-text btn-sm' title='" . xla('Print this form') .
951 "' onclick='top.restoreSession()'>" . xlt('Print') . "</a>";
954 if (AclMain::aclCheckCore('admin', 'super')) {
955 if ($formdir != 'newpatient' && $formdir != 'newGroupEncounter') {
956 // a link to delete the form from the encounter
957 echo "<a href='$rootdir/patient_file/encounter/delete_form.php?" .
958 "formname=" . attr_url($formdir) .
959 "&id=" . attr_url($iter['id']) .
960 "&encounter=" . attr_url($encounter) .
961 "&pid=" . attr_url($pid) .
962 "' class='btn btn-text btn-sm btn-delete' title='" . xla('Delete this form') . "' onclick='top.restoreSession()'>" . xlt('Delete') . "</a>";
966 echo "</div>\n"; // Form header controls
967 echo "</div>"; // Form header controls holding div
968 echo "</div>\n"; // Header closing
969 echo "<div class='form-detail formrow'><div id='divid_" . attr($divnos) . "' class='mb-5 collapse " . attr($expand_default) . "' ";
970 echo "class='tab'>";
972 // Use the form's report.php for display. Forms with names starting with LBF
973 // are list-based forms sharing a single collection of code.
975 if (substr($formdir, 0, 3) == 'LBF') {
976 include_once($GLOBALS['incdir'] . "/forms/LBF/report.php");
977 lbf_report($attendant_id, $encounter, 2, $iter['form_id'], $formdir, true);
978 } else {
979 if (file_exists($GLOBALS['incdir'] . "/forms/$formdir/report.php")) {
980 include_once($GLOBALS['incdir'] . "/forms/$formdir/report.php");
981 if (function_exists($formdir . "_report")) {
982 call_user_func($formdir . "_report", $attendant_id, $encounter, 2, $iter['form_id']);
983 } else {
984 (new \OpenEMR\Common\Logging\SystemLogger())->errorLogCaller("form is missing report function", ['formdir' => $formdir]);
986 } else {
987 (new \OpenEMR\Common\Logging\SystemLogger())->errorLogCaller("form is missing report.php file", ['formdir' => $formdir]);
991 if ($esign->isLogViewable()) {
992 $esign->renderLog();
995 echo "</div></div></div>";
996 ++$divnos;
998 echo "</div>";
1000 if (!$pass_sens_squad) {
1001 echo xlt("Not authorized to view this encounter");
1004 $dispatcher = $GLOBALS['kernel']->getEventDispatcher();
1005 if ($dispatcher instanceof EventDispatcher) {
1006 $event = new EncounterFormsListRenderEvent($_SESSION['encounter'], $attendant_type);
1007 $event->setGroupId($groupId ?? null);
1008 $event->setPid($pid ?? null);
1009 $dispatcher->dispatch($event, EncounterFormsListRenderEvent::EVENT_SECTION_RENDER_POST);
1013 </div> <!-- end large encounter_forms DIV -->
1014 <script>
1015 function toggleChevron(e) {
1016 let i = e.target.closest('.form-holder').querySelector('i');
1017 let o = (i.classList.contains('fa-chevron-right')) ? 'fa-chevron-right' : 'fa-chevron-down';
1018 let n = (o == "fa-chevron-right") ? "fa-chevron-down" : "fa-chevron-right";
1019 i.classList.replace(o, n);
1021 $('.form-detail div').on('show.bs.collapse', toggleChevron);
1022 $('.form-detail div').on('hide.bs.collapse', toggleChevron);
1023 </script>
1024 </body>
1025 </html>