4 * import_template_ui.php
7 * @link https://www.open-emr.org
8 * @author Jerry Padgett <sjpadgett@gmail.com>
9 * @author Brady Miller <brady.g.miller@gmail.com>
10 * @copyright Copyright (c) 2016-2021 Jerry Padgett <sjpadgett@gmail.com>
11 * @copyright Copyright (c) 2019 Brady Miller <brady.g.miller@gmail.com>
12 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
15 require_once("../interface/globals.php");
17 use OpenEMR\Core\Header
;
18 use OpenEMR\Services\DocumentTemplates\DocumentTemplateService
;
20 $templateService = new DocumentTemplateService();
22 $patient = $_REQUEST['selected_patients'] ??
null;
23 $patient = $patient ?
: ($_REQUEST['upload_pid'] ??
0);
25 $category = $_REQUEST['template_category'] ??
'';
26 $category_list = $templateService->getDefaultCategories();
28 $none_message = xlt("Nothing to show for current actions.");
30 function getAuthUsers()
32 $response = sqlStatement("SELECT `pid`, Concat_Ws(', ', `lname`, `fname`) as ptname FROM `patient_data` WHERE `allow_patient_portal` = 'YES' ORDER BY `lname`");
35 ['pid' => '0', 'ptname' => 'All Patients'],
36 ['pid' => '-1', 'ptname' => 'Repository'],
38 while ($row = sqlFetchArray($response)) {
39 $result_data[] = $row;
48 <meta charset
="UTF-8">
49 <title
><?php
echo xlt('Portal'); ?
> |
<?php
echo xlt('Templates'); ?
></title
>
50 <meta name
="description" content
="Developed By sjpadgett@gmail.com">
51 <?php Header
::setupHeader(['datetime-picker', 'select2', 'ckeditor']); ?
>
56 let templateEdit
= function (id
, flag
= '') {
58 handleTemplate(id
, 'get', '', flag
);
62 let templateSave
= function () {
63 //let editor = CKEDITOR.instances.templateContent;
64 let markup
= CKEDITOR
.instances
.templateContent
.getData();
65 handleTemplate(currentEdit
, 'save', markup
);
68 let templateDelete
= function (id
) {
69 let delok
= confirm(<?php
echo xlj('You are about to delete a template'); ?
> +
70 ": " +
"\n" +
<?php
echo xlj('Is this Okay?'); ?
>);
72 handleTemplate(id
, 'delete', '')
77 function getSendChecks() {
79 $
('input:checked[name=send]:checked').each(function () {
80 checked
.push($
(this
).val());
85 function updateCategory(id
) {
87 let url
= 'import_template.php';
88 let category
= event
.currentTarget
.value
;
89 const data
= new FormData();
90 data
.append('docid', id
);
91 data
.append('category', category
);
92 data
.append('mode', 'update_category');
96 }).then(rtn
=> rtn
.text()).then((rtn
) => {
98 await
asyncAlertMsg(rtn
, time
, 'success', 'lg');
99 })(2000).then(rtn
=> {
100 //document.edit_form.submit();
102 }).catch((error
) => {
103 console
.error('Error:', error
);
107 function sendTemplate(mode
= 'send', content
= '') {
108 top
.restoreSession();
109 let url
= 'import_template.php';
110 let ids
= $
('#selected_patients').select2('val');
111 let category
= $
('#template_category').val();
112 let checked
= getSendChecks();
113 const data
= new FormData();
114 data
.append('docid', JSON
.stringify(ids
));
115 data
.append('category', category
);
116 data
.append('checked', JSON
.stringify(checked
));
117 data
.append('mode', mode
);
118 data
.append('content', content
);
122 }).then(rtn
=> rtn
.text()).then((rtn
) => {
124 await
asyncAlertMsg(rtn
, time
, 'success', 'lg');
125 })(1000).then(rtn
=> {
126 document
.edit_form
.submit();
128 }).catch((error
) => {
129 console
.error('Error:', error
);
133 function handleTemplate(id
, mode
, content
= '', isDocument
= '') {
134 top
.restoreSession();
135 let libUrl
= 'import_template.php';
136 let renderUrl
= 'import_template.php?mode=editor_render_html&docid=' + id
;
138 if (document
.getElementById('is_modal').checked
) {
139 dialog
.popUp(renderUrl
, null, 'edit' + id
);
142 if (isDocument
== true) {
143 dialog
.popUp(renderUrl
, null, ('edit' + id
));
147 renderUrl +
= '&dialog=true';
148 dlgopen(renderUrl
, 'pop-editor', 'modal-lg', 850, '', '', {
150 {text: <?php echo xlj('Save'); ?>, close: false, style: 'success btn-sm', click: templateSave},
151 {text: <?php echo xlj('Dismiss'); ?>, style: 'danger btn-sm', close: true}
153 resolvePromiseOn
: 'show',
163 data
: {docid
: id
, mode
: mode
, content
: content
},
164 error
: function (qXHR
, textStatus
, errorThrow
) {
165 console
.log("There was an error");
166 alert(<?php
echo xlj("File Error") ?
> +
"\n" + id
)
168 success
: function (templateHtml
, textStatus
, jqXHR
) {
169 if (mode
=== 'save') {
171 } else if (mode
=== 'delete') {
179 $
('#fetch_files').on('click touchstart', function () {
182 $
('#fetch_files').change(function (e
) {
183 $
('#upload_submit').removeClass('d-none');
186 $
('.select-dropdown').select2({
187 placeholder
: xl("Type to search."),
188 minimumResultsForSearch
: 15,
191 closeOnSelect
: false,
192 <?php
require($GLOBALS['srcdir'] . '/js/xl/select2.js.php'); ?
>
195 $
('input:checkbox[name=send]').change(function () {
196 let checked
= getSendChecks();
197 if (checked
.length
> 0) {
198 $
('#send-button').removeClass('d-none');
199 $
('#category_group').addClass('d-none');
201 $
('#send-button').addClass('d-none');
202 $
('#category_group').removeClass('d-none');
206 let select_focus
= false;
207 /* Can't use if we want multi selects for locations. so ??? */
208 /* $('#selected_patients').change(function () {
209 if (checkCategory()) {
211 $('#edit_form').submit();
214 $
('#selected_patients').on('select2:close', function (e
) {
215 $
('#edit_form').submit();
218 $
('#upload-nav').on('hidden.bs.collapse', function () {
219 $
('#upload-nav-value').val('hidden');
221 $
('#upload-nav').on('show.bs.collapse', function () {
222 $
('#upload-nav-value').val('show');
223 //$('#edit_form').submit();
226 $
("#template_category").change(function () {
227 if (checkCategory()) {
228 $
("#edit_form").submit();
233 let selCat
= $
('#template_category').find(':selected').text();
234 let ids
= $
('#selected_patients').find(':selected').each(function () {
235 selText +
= $
(this
).text() +
'; ';
237 $
('#upload_scope_category').empty().append(' ' +
xl('For Category') +
': ' + selCat
);
238 $
("#upload_scope").empty().append(xl('To Locations') +
': ' + selText
);
240 function checkCategory() {
241 let cat
= $
("#template_category").val();
242 let patient
= $
("#selected_patients").val();
247 $
(document
).on('select2:open', () => {
248 document
.querySelector('.select2-search__field').focus();
252 .modal
.modal
-wide
.modal
-dialog
{
256 .modal
-wide
.modal
-body
{
261 caption
-side
: top
!important
;
265 <body
class="body-top">
266 <div
class='container'>
267 <div
class='col col-12'>
268 <div
class='ml-0 mt-2'><span
class="title"><?php
echo xlt('Template Maintenance'); ?
></span
>
270 <div
class='btn-group ml-1'>
271 <button type
='button' class='btn btn-secondary' data
-toggle
='collapse' data
-target
='#help-panel'>
272 <?php
echo xlt('Help') ?
>
274 <button
class='btn btn-success' type
='button' onclick
="location.href='./patient/provider'">
275 <?php
echo xlt('Dashboard'); ?
>
281 <?php
include_once('./../Documentation/help_files/template_maintenace_help.php'); ?
>
282 <!-- Actions Scope to act on
-->
283 <nav
class='navbar navbar-dark bg-dark text-light sticky-top'>
284 <form id
="edit_form" name
="edit_form" class="row form-inline w-100" action
="" method
="get">
285 <a
class='navbar-brand ml-1'><?php
echo xlt('Scope'); ?
></a
>
286 <div
class="form-group">
287 <label
class='font-weight-bold mx-1' for='selected_patients'><?php
echo xlt('Location'); ?
></label
>
288 <select
class="form-control select-dropdown" id
="selected_patients" name
="selected_patients[]" multiple
>
290 $ppt = getAuthUsers();
291 foreach ($ppt as $pt) {
292 if ((is_array($patient) && !in_array($pt['pid'], $patient)) ||
empty($patient)) {
293 echo '<option value=' . attr($pt['pid']) . '>' . text($pt['ptname']) . '</option>';
295 echo "<option value='" . attr($pt['pid']) . "' selected='selected'>" . text($pt['ptname'] . ' ') . '</option>';
300 <a
class='btn-refresh ml-1' onclick
="$('#selected_patients').val(null).trigger('change');" role
="button"></a
>
302 $select_cat_options = '<option value="">' . xlt('General') . "</option>\n";
303 foreach ($category_list as $option_category) {
304 if (stripos($option_category['option_id'], 'repository') !== false) {
307 if ($category === $option_category['option_id']) {
308 $select_cat_options .= "<option value='" . attr($option_category['option_id']) . "' selected>" . text($option_category['title']) . "</option>\n";
310 $select_cat_options .= "<option value='" . attr($option_category['option_id']) . "'>" . text($option_category['title']) . "</option>\n";
314 <div
class="form-group" id
="category_group">
315 <label
class="font-weight-bold mx-1" for="template_category"><?php
echo xlt('Category'); ?
></label
>
316 <select
class="form-control" id
="template_category" name
="template_category">
317 <?php
echo $select_cat_options ?
>
321 <div
class='btn-group ml-1'>
322 <button type
='submit' class='btn btn-search btn-light'><?php
/*echo xlt('Refresh'); */ ?
></button
>
323 <button type
='button' id
="send-button" class='btn btn-transmit btn-success d-none' onclick
="return sendTemplate()">
324 <?php
echo xlt('Send'); ?
>
326 <button type
='button' id
="upload-nav-button" name
='upload-nav-button' class='btn btn-primary' data
-toggle
='collapse' data
-target
='#upload-nav'>
327 <?php
echo xlt('Files') ?
>
330 <div
class="ml-auto">
331 <label
class="form-check"><?php
echo xlt('Use Popout Editor'); ?
>
332 <input type
='checkbox' class='form-check-inline mx-1' id
='is_modal' name
='is_modal' checked
='checked' />
335 <input type
='hidden' id
='upload-nav-value' name
='upload-nav-value' value
='<?php echo attr($_REQUEST['upload
-nav
-value
']) ?? 'hidden
' ?>' />
339 <nav
class="collapse my-2 <?php echo attr($_REQUEST['upload-nav-value']) ?>" id
="upload-nav">
340 <div
class='col col-12'>
341 <form id
='form_upload' class='form-inline row' action
='import_template.php' method
='post' enctype
='multipart/form-data'>
344 <div id
='upload_scope_category'></div
>
345 <div
class='mb-2' id
='upload_scope'></div
>
347 <div
class='form-group col'>
348 <div
class='form-group'>
349 <input type
='file' class='btn btn-outline-info' id
="fetch_files" name
='template_files[]' multiple
/>
350 <button
class='btn btn-outline-success d-none' type
='submit' name
='upload_submit' id
='upload_submit'><i
class='fa fa-upload' aria
-hidden
='true'></i
></button
>
353 <input type
='hidden' name
='upload_pid' value
='<?php echo attr(json_encode($patient)); ?>' />
354 <input type
='hidden' name
="template_category" value
='<?php echo attr($category); ?>' />
360 <div
class='col col-12' data
-toggle
='collapse' data
-target
='#repository-collapse'>
361 <h5
><i
class='fa fa-eye mr-1' role
='button' title
="<?php echo xlt('Click to expand or collapse Repository templates panel.'); ?>"></i
><?php
echo xlt('Template Repository') ?
></h5
>
363 <!-- Repository table
-->
364 <div
class='col col-12 table-responsive collapse show' id
="repository-collapse">
367 $show_cat_flag = false;
368 if (!empty($category)) {
369 $templates = $templateService->getTemplateListByCategory($category, -1);
370 //$templates = $templateService->getTemplateListAllCategories(-1);
372 $templates = $templateService->getTemplateListAllCategories(-1);
374 echo "<table class='table table-sm table-striped table-bordered'>\n";
375 /* echo '<caption role="button" data-toggle="collapse" data-target="#repository-collapse" title="' .
376 xlt('Click to expand or collapse Repository templates panel.') .
377 '"><h5>' . xlt('Repository Available Templates') . '</h5></caption>';*/
380 "<th>" . xlt('Send') . "</th>" .
381 '<th>' . xlt('Category') . '</th>' .
382 "<th>" . xlt("Template Actions") . "</th>" .
383 "<th>" . xlt("Size") . "</th>" .
384 "<th>" . xlt("Last Modified") . "</th>" .
388 foreach ($templates as $cat => $files) {
390 $cat = xlt('Default');
392 foreach ($files as $file) {
393 $template_id = $file['id'];
394 $this_cat = $file['category'];
395 $notify_flag = false;
396 $select_cat_options = '<option value="">' . xlt('General') . "</option>\n";
397 foreach ($category_list as $option_category) {
398 if (stripos($option_category['option_id'], 'repository') !== false) {
401 if ($this_cat === $option_category['option_id']) {
402 $select_cat_options .= "<option value='" . attr($option_category['option_id']) . "' selected>" . text($option_category['title']) . "</option>\n";
404 $select_cat_options .= "<option value='" . attr($option_category['option_id']) . "'>" . text($option_category['title']) . "</option>\n";
408 if ($file['mime'] == 'application/pdf') {
409 $this_cat = xlt('PDF Document');
411 echo '<td>' . '*' . '</td>';
412 echo "<td>" . $this_cat . " Id: " . attr($template_id) . "</td>";
414 echo "<td><input type='checkbox' class='form-check-inline' id='send' name='send' value='" . attr($template_id) . "' /></td>";
415 echo '<td><select class="form-control form-control-sm" id="category_table' . attr($template_id) .
416 '" onchange="updateCategory(' . attr_js($template_id) . ')" value="' . attr($this_cat) . '">' .
417 $select_cat_options . '</select></td>';
420 '<button id="templateEdit' . attr($template_id) .
421 '" class="btn btn-sm btn-outline-primary" onclick="templateEdit(' . attr_js($template_id) . ',' . attr_js($notify_flag) . ')" type="button">' . text($file['template_name']) . /*' '. attr($template_id) .*/
423 '<button id="templateDelete' . attr($template_id) .
424 '" class="btn btn-sm btn-outline-danger float-right" onclick="templateDelete(' . attr_js($template_id) . ')" type="button">' . xlt("Delete") .
426 echo "<td>" . text($file['size']) . "</td>";
427 echo "<td>" . text(date('m/d/Y H:i:s', strtotime($file['modified_date']))) . "</td>";
433 if (empty($template_id)) {
434 echo '<tr><td>' . $none_message . "</td></tr>\n";
442 <div
class='col col-12' data
-toggle
='collapse' data
-target
='#template-collapse'>
443 <h5
><i
class='fa fa-eye mr-1' role
='button' title
="<?php echo xlt('Click to expand or collapse All active patient templates panel.'); ?>"></i
><?php
echo '' . xlt('All Patient Templates') . '' ?
></h5
>
445 <div
class='col col-12 table-responsive collapse show' id
='template-collapse'>
448 $show_cat_flag = false;
449 if (!empty($category)) {
450 $templates = $templateService->getTemplateListByCategory($category);
452 $templates = $templateService->getTemplateListAllCategories();
454 echo "<table class='table table-sm table-striped table-bordered'>\n";
455 /*echo '<caption role="button" data-toggle="collapse" data-target="#template-collapse"><h6>' .
456 xlt('All Patients Templates') .
460 /*'<th>' . xlt('Send') . '</th>' .*/
461 '<th>' . xlt('Category') . '</th>' .
462 '<th>' . xlt('Template Actions') . '</th>' .
463 '<th>' . xlt('Size') . '</th>' .
464 '<th>' . xlt('Last Modified') . '</th>' .
468 foreach ($templates as $cat => $files) {
470 $cat = xlt('Default');
472 foreach ($files as $file) {
473 $template_id = $file['id'];
475 /*echo "<td><input type='checkbox' class='form-check-inline' id='send' name='send' value='" . attr($template_id) . "' /></td>";*/
476 echo '<td>' . text(ucwords($cat)) . '</td><td>';
477 echo '<button id="templateEdit' . attr($template_id) .
478 '" class="btn btn-sm btn-outline-primary" onclick="templateEdit(' . attr_js($template_id) . ')" type="button">' . text($file['template_name']) . '</button>' .
479 /*'<button id="sendTemplate' . attr($template_id) .
480 '" class="btn btn-sm btn-outline-success" onclick="templateSend(' . attr_js($template_id) . ')" type="button">' . xlt('Send') . '</button>' .*/
481 '<button id="templateDelete' . attr($template_id) .
482 '" class="btn btn-sm btn-outline-danger" onclick="templateDelete(' . attr_js($template_id) . ')" type="button">' . xlt('Delete') . '</button>';
483 echo '<td>' . text($file['size']) . '</td>';
484 echo '<td>' . text(date('m/d/Y H:i:s', strtotime($file['modified_date']))) . '</td>';
491 echo '<tr><td>' . $none_message . "</td></tr>\n";
499 <div
class='col col-12 table-responsive'>
501 // by categories and patient pid.
503 $show_cat_flag = false;
505 // Category selected so get all of them for pids
506 if (!empty($category) && !empty($patient)) {
507 $templates = $templateService->getTemplateCategoriesByPids($patient, $category);
508 } elseif (empty($patient)) {// All templates for all patients
509 $templates = $templateService->getTemplateCategoriesByPatient(0, $category);
510 } elseif (empty($category) && !empty($patient)) {
511 $templates = $templateService->getTemplateCategoriesByPids($patient);
513 echo "<table class='table table-sm table-striped table-bordered'>\n";
514 echo '<caption><h5>' . xlt("Patient Assigned Templates") . '</h5></caption>';
517 '<th>' . xlt('Patient') . '</th>' .
518 '<th>' . xlt('Category') . '</th>' .
519 '<th>' . xlt('Template Actions') .
520 '</th><th>' . xlt('Status') .
521 '</th><th>' . xlt('Size') .
522 '</th><th>' . xlt('Last Modified') . '</th>' .
526 foreach ($templates as $cat => $files) {
528 $cat = xlt('Default');
530 foreach ($files as $file) {
531 $template_id = $file['id'];
532 echo '<tr><td>' . text($file['location']) . '</td>';
533 echo '<td>' . text(ucwords($cat)) . '</td>';
535 '<button type="button" id="patientEdit' . attr($template_id) .
536 '" class="btn btn-sm btn-outline-primary" onclick="templateEdit(' . attr_js($template_id) . ')">' .
537 text($file['template_name']) . "</button>\n" .
538 '<button type="button" id="patientDelete' . attr($template_id) .
539 '" class="btn btn-sm btn-outline-danger" onclick="templateDelete(' . attr_js($template_id) . ')">' . xlt('Delete') . "</button></td>\n";
540 echo '<td>' . text($file['status']) . '</td>';
541 echo '<td>' . text($file['size']) . '</td>';
542 echo '<td>' . text(date('m/d/Y H:i:s', strtotime($file['modified_date']))) . '</td>';
547 echo '<tr><td>' . $none_message . "</td></tr>\n";