Skip to content

Commit

Permalink
Auto-create encounter reason flag and some forgotten fixes. (openemr#…
Browse files Browse the repository at this point in the history
…7681)

* Auto-create encounter reason flag and some forgotten fixes.
remove purifier global property
new global in Calender to prevent using appointmnet comment as new visit reason.
refactor encounter report twig to have visit reason on it's own line instead of header.

* oops! new config global for appointment comment

* revert cron job for sms/email reminders to correct script

* add jsGlobals from main.php to portal for issue openemr#7688

* set default portal appointment category duration to 15 minutes for categories where a duration is not set. Otherwise calendar timeslot appears as a line.

* Add past appointments view
limit max appointments to 10
refactor limit reached message to a card

* spelling

* Normalize category path/title to an acceptable category class name get_patient_documents
  • Loading branch information
sjpadgett authored Sep 2, 2024
1 parent 7dccf9d commit 26ef93c
Show file tree
Hide file tree
Showing 12 changed files with 246 additions and 142 deletions.
8 changes: 5 additions & 3 deletions interface/forms/newpatient/templates/report.html.twig
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
<div class="w-100">
{% for e in encounters %}
{% set _reason = (e.reason) ? " - " ~ e.reason|text|nl2br : "" %}
<h3>{{ e.category|text }}{{ _reason }}</h3>
<h5 class="text-muted">{{ e.provider|text }} ({{ e.facility|text }})</h5>
<h3>{{ e.category|text }}</h3>
<span class="text-muted" style="font-size: 1.0rem;">{{ "Reason For Visit"|xlt }}</span><span style="font-size: 1.0rem;">{{ _reason }}</span>
<h6 class="text-muted">{{ e.provider|text }} ({{ e.facility|text }})</h6>
{% if e.posCode %}
{{ "POS Code"|xlt }} - {{ e.posCode|text }}
{% endif %}
{% if e.referringProvider %}
<br>{{ "Referring Provider"|xlt }} - {{ e.referringProvider|text }}
<br />{{ "Referring Provider"|xlt }} - {{ e.referringProvider|text }}
{% endif %}

{% endfor %}
</div>

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions library/encounter_events.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ function todaysEncounterCheck($patient_id, $enc_date = '', $reason = '', $fac_id

$dos = $enc_date ? $enc_date : $today;
$visit_reason = $reason ? $reason : xl('Please indicate visit reason');
if (!empty($GLOBALS['auto_create_prevent_reason'] ?? 0)) {
$visit_reason = 'Please indicate visit reason';
}
$tmprow = sqlQuery("SELECT username, facility, facility_id FROM users WHERE id = ?", array($_SESSION["authUserID"]));
$username = $tmprow['username'];
$facility = $tmprow['facility'];
Expand Down
7 changes: 7 additions & 0 deletions library/globals.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -1897,6 +1897,13 @@ function gblTimeZones()
xl('The appointment status changes and encounter creations are managed through the Patient Tracker.')
),

'auto_create_prevent_reason' => array(
xl('Prevent Appointment Comment as Visit Reason'),
'bool', // data type
'0', // default
xl('Check this if you do not want to allow the appointments comment as the visit reason when auto-creating new encounter for appointment.')
),

'allow_early_check_in' => array(
xl('Allow Early Check In'),
'bool', // data type
Expand Down
4 changes: 2 additions & 2 deletions portal/add_edit_event_user.php
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,7 @@
function change_provider() {
var f = document.forms.namedItem("theaddform");
// use today's date but reset everything else when changing providers so we can
// search on availability.
// search on availability. jsGlobals['date_display_format']
f.form_date.value = window.top.oeFormatters.I18NDateFormat(new Date());
f.form_hour.value = '';
f.form_minute.value = '';
Expand Down Expand Up @@ -804,7 +804,7 @@ function set_category() {
if (s.selectedIndex >= 0) {
var catid = s.options[s.selectedIndex].value;
f.form_title.value = s.options[s.selectedIndex].text;
f.form_duration.value = durations[catid];
f.form_duration.value = durations[catid] || '15';
set_display();
}
}
Expand Down
7 changes: 4 additions & 3 deletions portal/get_patient_documents.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,20 +125,21 @@ function validateForm(event) {
} else {
$normalizedTitle = $title;
}
$normalizedCategory = preg_replace('/[^a-zA-Z0-9]/', '', $title);
?>
<div class="col-md-6">
<div class="card mb-4">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0"><?php echo text($normalizedTitle); ?></h5>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="selectAll<?php echo attr($normalizedTitle); ?>" onclick="toggleCheckboxes('category-<?php echo attr($normalizedTitle); ?>', this)">
<label class="form-check-label" for="selectAll<?php echo attr($normalizedTitle); ?>"><?php echo xlt("Select All"); ?></label>
<input class="form-check-input" type="checkbox" id="selectAll<?php echo attr($normalizedCategory); ?>" onclick="toggleCheckboxes('category-<?php echo attr($normalizedCategory); ?>', this)">
<label class="form-check-label" for="selectAll<?php echo attr($normalizedCategory); ?>"><?php echo xlt("Select All"); ?></label>
</div>
</div>
<div class="card-body">
<?php foreach ($docs as $doc) { ?>
<div class="form-check">
<input class="form-check-input category-<?php echo attr($normalizedTitle); ?>" type="checkbox" name="documents[]" value="<?php echo attr($doc['id']); ?>" id="doc<?php echo attr($doc['id']); ?>">
<input class="form-check-input category-<?php echo attr($normalizedCategory); ?>" type="checkbox" name="documents[]" value="<?php echo attr($doc['id']); ?>" id="doc<?php echo attr($doc['id']); ?>">
<label class="form-check-label" for="doc<?php echo attr($doc['id']); ?>">
<?php echo text($doc['name']); ?>
</label>
Expand Down
48 changes: 46 additions & 2 deletions portal/home.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,11 @@
$isEasyPro = $GLOBALS['easipro_enable'] && !empty($GLOBALS['easipro_server']) && !empty($GLOBALS['easipro_name']);

$current_date2 = date('Y-m-d');
$apptLimit = 30;
$apptLimit = 10;
$appts = fetchNextXAppts($current_date2, $pid, $apptLimit);
$past_appts = fetchXPastAppts($pid, 10);

$appointments = array();
$appointments = $past_appointments = array();
if ($appts) {
$stringCM = '(' . xl('Comments field entry present') . ')';
$stringR = '(' . xl('Recurring appointment') . ')';
Expand Down Expand Up @@ -113,7 +114,44 @@
$appointments[] = $filteredEvent->getAppointment() ?? $formattedRecord;
}
}
if ($past_appts) {
$stringCM = '(' . xl('Comments field entry present') . ')';
$stringR = '(' . xl('Recurring appointment') . ')';
$pastCount = 0;
foreach ($past_appts as $row) {
$status_title = getListItemTitle('apptstat', $row['pc_apptstatus']);
$pastCount++;
$dayname = xl(date('l', strtotime($row['pc_eventDate'])));
$dispampm = 'am';
$disphour = (int)substr($row['pc_startTime'], 0, 2);
$dispmin = substr($row['pc_startTime'], 3, 2);
if ($disphour >= 12) {
$dispampm = 'pm';
if ($disphour > 12) {
$disphour -= 12;
}
}

if ($row['pc_hometext'] != '') {
$etitle = xl('Comments') . ': ' . $row['pc_hometext'] . "\r\n";
} else {
$etitle = '';
}

$formattedRecord = [
'appointmentDate' => $dayname . ', ' . oeFormatShortDate($row['pc_eventDate']) . ' ' . $disphour . ':' . $dispmin . ' ' . $dispampm,
'appointmentType' => xl('Type') . ': ' . $row['pc_catname'],
'provider' => xl('Provider') . ': ' . $row['ufname'] . ' ' . $row['ulname'],
'status' => xl('Status') . ': ' . $status_title,
'mode' => (int)$row['pc_recurrtype'] > 0 ? 'recurring' : $row['pc_recurrtype'],
'icon_type' => (int)$row['pc_recurrtype'] > 0,
'etitle' => $etitle,
'pc_eid' => $row['pc_eid'],
];
$filteredEvent = $GLOBALS['kernel']->getEventDispatcher()->dispatch(new AppointmentFilterEvent($row, $formattedRecord), AppointmentFilterEvent::EVENT_NAME);
$past_appointments[] = $filteredEvent->getAppointment() ?? $formattedRecord;
}
}
$current_theme = sqlQuery("SELECT `setting_value` FROM `patient_settings` WHERE setting_patient = ? AND `setting_label` = ?", array($pid, 'portal_theme'))['setting_value'] ?? '';
function collectStyles(): array
{
Expand Down Expand Up @@ -301,9 +339,11 @@ function buildNav($newcnt, $pid, $result): array
'csrfUtils' => CsrfUtils::collectCsrfToken(),
'isEasyPro' => $isEasyPro,
'appointments' => $appointments,
'pastAppointments' => $past_appointments,
'appts' => $appts,
'appointmentLimit' => $apptLimit,
'appointmentCount' => $count ?? null,
'pastAppointmentCount' => $pastCount ?? null,
'displayLimitLabel' => xl('Display limit reached'),
'site_id' => $_SESSION['site_id'] ?? ($_GET['site'] ?? 'default'), // one way or another, we will have a site_id.
'portal_timeout' => $GLOBALS['portal_timeout'] ?? 1800, // timeout is in seconds
Expand All @@ -313,6 +353,10 @@ function buildNav($newcnt, $pid, $result): array
'ccdaOk' => $ccdaOk,
'allow_custom_report' => $GLOBALS['allow_custom_report'] ?? '0',
'immunRecords' => $immunRecords,
'languageDirection' => $_SESSION['language_direction'] ?? 'ltr',
'dateDisplayFormat' => $GLOBALS['date_display_format'],
'timezone' => $GLOBALS['gbl_time_zone'] ?? '',
'assetVersion' => $GLOBALS['v_js_includes'],
'eventNames' => [
'sectionRenderPost' => RenderEvent::EVENT_SECTION_RENDER_POST,
'scriptsRenderPre' => RenderEvent::EVENT_SCRIPTS_RENDER_PRE,
Expand Down
6 changes: 5 additions & 1 deletion src/Services/AppointmentService.php
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,10 @@ public function createEncounterForAppointment($eid)
[$appointment['pc_facility']]
);

$visit_reason = $appointment['pc_hometext'] ?? xl('Please indicate visit reason');
if (!empty($GLOBALS['auto_create_prevent_reason'] ?? 0)) {
$visit_reason = 'Please indicate visit reason';
}
$data = [
'pc_catid' => $appointment['pc_catid']
// TODO: where would we get this information if it wasn't defaulted to ambulatory? Should this be a globals setting?
Expand All @@ -623,7 +627,7 @@ public function createEncounterForAppointment($eid)
,'puuid' => $patientUuid
,'pid' => $appointment['pid']
,'provider_id' => $user['id']
,'reason' => $appointment['pc_hometext'] ?? xl('Please indicate visit reason')
,'reason' => $visit_reason
,'facility_id' => $appointment['pc_facility']
,'billing_facility' => $appointment['pc_billing_location']
,'pos_code' => $pos_code
Expand Down
1 change: 0 additions & 1 deletion src/Services/DocumentTemplates/DocumentTemplateRender.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ public function doRender($template_id, $template_content = null, $json_data = nu
}
$config->set('Cache.SerializerPath', $purifyTempFile);
$config->set('Core.Encoding', 'UTF-8');
$config->set('CSS.AllowedProperties', '*');
$purify = new HTMLPurifier($config);
$edata = $purify->purify($template);
// Purify escapes URIs.
Expand Down
2 changes: 2 additions & 0 deletions templates/portal/appointment-item.html.twig
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<div class="card m-0 col-12 col-md-6 col-lg-4">
<div class="card-header">
{% if past == false %}
<a href="#" onclick="editAppointment({{ appt.mode | attr_js }},{{ appt.pc_eid | attr_js }})" title="{{ appt.etitle | attr }}">
<i class='float-right fa fa-edit fa-lg {% if appt.pc_recurrtype > 0 %} text-danger {% else %} text-success {% endif %} bg-light font-weight-light'></i>
</a>
{% endif %}
</div>
<div class="card-body p-0 font-weight-bold">
<p>
Expand Down
7 changes: 7 additions & 0 deletions templates/portal/home.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@
tab_mode = true,
isPortal = 1;
var jsLanguageDirection = {{ languageDirection | js_escape }};
var jsGlobals = {
languageDirection: jsLanguageDirection,
date_display_format: {{ dateDisplayFormat | js_escape }},
timezone: {{ timezone | js_escape }},
assetVersion: {{ assetVersion | js_escape }}
};
function restoreSession() {
return true;
}
Expand Down
42 changes: 35 additions & 7 deletions templates/portal/partial/cards/_appointment_card.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -50,28 +50,56 @@
dialog.ajax(params);
}
</script>
<div class="collapse mt-2 overflow-auto" data-parent="#cardgroup" id="appointmentcard">
<div class="collapse my-2 overflow-auto" data-parent="#cardgroup" id="appointmentcard">
<div class="container-fluid">
<h3 class="text-center">{{ 'Appointments' | xlt }}</h3>
<h3 class="text-center">{{ 'Future Appointments' | xlt }}</h3>
<div class="row">
{% if appointments|length > 0 %}
{% for appt in appointments %}
{% include 'portal/appointment-item.html.twig' with {appt: appt} %}
{% include 'portal/appointment-item.html.twig' with {appt: appt, past: false} %}
{% endfor %}
{% if appointmentLimit == appointmentCount %}
<p>{{ 'Display limit reached' | xlt }}
<br>
{{ 'More appointments may exist' | xlt }}</p>
<div class="card">
<div class="card-body">
<h5>{{ 'Display limit reached' | xlt }}
<br>
{{ 'More upcoming appointments may exist' | xlt }}</h5>
</div>
</div>
{% endif %}
{% else %}
<div class="col-12">
<div class="alert alert-info"><h5 class='text-center'>{{ 'No Appointments' | xlt }}</h5></div>
</div>
{% endif %}
</div>
<div class="mb-3">
<div class="mt-3">
<a class='btn btn-primary btn-block' href='#' onclick="editAppointment('add',{{ patientID | attr_js }})">{{ 'Schedule A New Appointment' | xlt }}</a>
</div>
</div>
<div class="container-fluid">
<h3 class="text-center">{{ 'Past Appointments' | xlt }}</h3>
<div class="row">
{% if pastAppointments|length > 0 %}
{% for appt in pastAppointments %}
{% include 'portal/appointment-item.html.twig' with {appt: appt, past: true} %}
{% endfor %}
{% if appointmentLimit == pastAppointmentCount %}
<div class="card">
<div class="card-body">
<h5>{{ 'Display limit reached' | xlt }}
<br>
{{ 'More past appointments may exist' | xlt }}</h5>
</div>
</div>
{% endif %}
{% else %}
<div class="col-12">
<div class="alert alert-info"><h5 class='text-center'>{{ 'No Past Appointments' | xlt }}</h5></div>
</div>
{% endif %}
</div>
</div>
</div>

0 comments on commit 26ef93c

Please sign in to comment.