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");
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';
36 if (!empty($_REQUEST['review_id'])) {
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");
51 if ($GLOBALS['kernel']->getEventDispatcher() instanceof EventDispatcher
) {
53 * @var EventDispatcher
55 $eventDispatcher = $GLOBALS['kernel']->getEventDispatcher();
57 throw new Exception("Could not get EventDispatcher from kernel", 1);
66 <?php
require $GLOBALS['srcdir'] . '/js/xl/dygraphs.js.php'; ?
>
68 <?php Header
::setupHeader(['common','esign','dygraphs', 'utility']); ?
>
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")) { ?
>
77 var csrf_token_js
= <?php
echo js_escape(CsrfUtils
::collectCsrfToken()); ?
>;
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">
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) {
93 "SELECT COUNT(*) AS count FROM procedure_order WHERE " .
94 "procedure_order_id = ? AND patient_id = ? AND encounter_id = 0 AND activity = 1",
97 if (!empty($tmp['count'])) {
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);
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
>
119 var formConfig
= <?php
echo $esignApi->formConfigToJson(); ?
>;
120 $
(".esign-button-form").esign(
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(
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') ) {
169 top
.restoreSession();
170 $
.post( "../../../library/ajax/amc_misc_data.php",
171 { amc_id
: "patient_edu_amc",
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') ) {
189 top
.restoreSession();
190 $
.post( "../../../library/ajax/amc_misc_data.php",
191 { amc_id
: "provide_sum_pat_amc",
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') ) {
205 // Enable the reconciliation checkbox
206 $
("#med_reconc_perf").removeAttr("disabled");
207 $
("#soc_provided").removeAttr("disabled");
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",
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";
235 var mode
= "uncomplete";
237 top
.restoreSession();
238 $
.post( "../../../library/ajax/amc_misc_data.php",
239 { amc_id
: "med_reconc_amc",
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";
254 var mode
= "no_soc_provided";
256 top
.restoreSession();
257 $
.post( "../../../library/ajax/amc_misc_data.php",
258 { amc_id
: "med_reconc_amc",
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(); });
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",
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();
299 $
(".encounter-summary-column:first").show();
300 $
(".title:first").text(<?php
echo xlj("Review"); ?
> +
" " + $
(".title:first").text() +
" ( " +
<?php
echo js_escape($encounter); ?
> +
" )");
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, '', '', {
314 // create new follow-up Encounter.
315 function createFollowUpEncounter() {
318 $result = sqlQuery("SELECT * FROM form_encounter WHERE pid = ? AND encounter = ?", array(
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();
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();
345 parent
.twAddFrameTab('enctabs', formname
, url
);
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';
370 .encounter
-summary
-container
{
375 .encounter
-summary
-column
{
392 button
::-moz
-focus
-inner
{
397 <!-- *************** -->
398 <!-- Form menu start
-->
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
;
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
);
425 var oldddmenuitem
= 0;
430 // cancel close timer
431 //mcancelclosetime();
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')){
444 oldddmenuitem
.style
.visibility
= 'hidden';
445 oldddmenuitem
.style
.display
= 'none';
447 ddmenuitem
.style
.visibility
= 'visible';
448 ddmenuitem
.style
.display
= 'block';
450 ddmenuitem
.style
.visibility
= 'hidden';
451 ddmenuitem
.style
.display
= 'none';
455 // close showed layer
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
);
473 if(obj
.offsetParent
) {
475 curleft +
= obj
.offsetLeft
;
476 if (!obj
.offsetParent
) {
479 obj
= obj
.offsetParent
;
485 PropertyWidth
= document
.getElementById(id
).offsetWidth
;
486 if (PropertyWidth
> curleft
) {
487 document
.getElementById(id
).style
.left
= 0;
491 function findPosY(obj
) {
493 if(obj
.offsetParent
) {
495 curtop +
= obj
.offsetTop
;
496 if(!obj
.offsetParent
) {
499 obj
= obj
.offsetParent
;
511 <?php
//DYNAMIC FORM RETREIVAL
512 require_once("$srcdir/registry.inc.php");
514 $reg = getFormsByCategory();
518 // To see if the encounter is locked. If it is, no new forms can be created
519 $encounterLocked = false;
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')) {
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);
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
567 AND attached_to='encounter'
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'];
578 $modulePath = $GLOBALS['zendModDir'];
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);
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);
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'>
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'>
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;
661 <div style
='margin-top: 8px;'>
663 // ESign for entire encounter
664 $esign = $esignApi->createEncounterESign($encounter);
665 if ($esign->isButtonViewable()) {
666 echo $esign->buttonHtml();
673 <div
class='encounter-summary-column'>
674 <?php
if ($esign->isLogViewable()) {
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">
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
/>
692 <input type
="checkbox" id
="prov_edu_res" />
696 <span
class="text"><?php
echo xlt('Provided Education Resource(s)?') ?
></span
>
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
/>
707 <input type
="checkbox" id
="provide_sum_pat_flag" />
711 <span
class="text"><?php
echo xlt('Provided Clinical Summary?') ?
></span
>
714 <?php
// Display the medication reconciliation checkboxes (AMC prompting)
715 $itemAMC = amcCollect("med_reconc_amc", $pid, 'form_encounter', $encounter);
717 <?php
if (!(empty($itemAMC))) { ?
>
720 <input type
="checkbox" id
="trans_trand_care" checked
/>
723 <span
class="text"><?php
echo xlt('Transition/Transfer of Care?') ?
></span
>
730 <?php
if (!(empty($itemAMC['date_completed']))) { ?
>
731 <input type
="checkbox" id
="med_reconc_perf" checked
/>
733 <input type
="checkbox" id
="med_reconc_perf" />
737 <span
class="text"><?php
echo xlt('Medication Reconciliation Performed?') ?
></span
>
742 <?php
if (!(empty($itemAMC['soc_provided']))) { ?
>
743 <input type
="checkbox" id
="soc_provided" checked
/>
745 <input type
="checkbox" id
="soc_provided" />
749 <span
class="text"><?php
echo xlt('Summary Of Care Provided?') ?
></span
>
756 <input type
="checkbox" id
="trans_trand_care" />
759 <span
class="text"><?php
echo xlt('Transition/Transfer of Care?') ?
></span
>
766 <input type
="checkbox" id
="med_reconc_perf" disabled
/>
769 <span
class="text"><?php
echo xlt('Medication Reconciliation Performed?') ?
></span
>
774 <input type
="checkbox" id
="soc_provided" disabled
/>
777 <span
class="text"><?php
echo xlt('Summary of Care Provided?') ?
></span
>
789 <!-- Get the documents tagged to this encounter
and display the links
and notes
as the tooltip
-->
791 if ($attendant_type == 'pid') {
792 $docs_list = getDocumentsByEncounter($pid, $_SESSION['encounter']);
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
>
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']));
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
>
830 ($result = getFormByEncounter(
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'>";
840 foreach ($result as $iter) {
841 $formdir = $iter['formdir'];
843 // skip forms whose 'deleted' flag is set to 1
844 if ($iter['deleted'] == 1) {
850 if (substr($formdir, 0, 3) == 'LBF') {
851 // Skip LBF forms that we are not authorized to see.
853 "SELECT grp_aco_spec " .
854 "FROM layout_group_properties WHERE " .
855 "grp_form_id = ? AND grp_group_id = '' AND grp_activity = 1",
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])) {
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])) {
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);
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>
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>
915 <div class='form_header_controls btn-group' role='group'>
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> " . xlt('Locked') . "</a>";
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']) . "' " .
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) . "' ";
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);
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']);
984 (new \OpenEMR\Common\Logging\
SystemLogger())->errorLogCaller("form is missing report function", ['formdir' => $formdir]);
987 (new \OpenEMR\Common\Logging\
SystemLogger())->errorLogCaller("form is missing report.php file", ['formdir' => $formdir]);
991 if ($esign->isLogViewable()) {
995 echo "</div></div></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
-->
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
);