LBF custom template (nation notes) fancybox replace.
[openemr.git] / interface / forms / LBF / new.php
blobe101004ee7be18af7a8061f32b5b273ddf6c8efb
1 <?php
2 /**
3 * LBF form.
5 * @package OpenEMR
6 * @link http://www.open-emr.org
7 * @author Rod Roark <rod@sunsetsystems.com>
8 * @author Brady Miller <brady.g.miller@gmail.com>
9 * @copyright Copyright (c) 2009-2017 Rod Roark <rod@sunsetsystems.com>
10 * @copyright Copyright (c) 2017 Brady Miller <brady.g.miller@gmail.com>
11 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
14 require_once("../../globals.php");
15 require_once("$srcdir/api.inc");
16 require_once("$srcdir/forms.inc");
17 require_once("$srcdir/options.inc.php");
18 require_once("$srcdir/patient.inc");
19 if ($GLOBALS['gbl_portal_cms_enable']) {
20 require_once("$include_root/cmsportal/portal.inc.php");
22 require_once($GLOBALS['fileroot'] . '/custom/code_types.inc.php');
23 require_once("$srcdir/FeeSheetHtml.class.php");
25 use OpenEMR\Core\Header;
27 $CPR = 4; // cells per row
29 $pprow = array();
31 $alertmsg = '';
33 function end_cell()
35 global $item_count, $cell_count, $historical_ids;
36 if ($item_count > 0) {
37 // echo "&nbsp;</td>";
38 echo "</td>";
40 foreach ($historical_ids as $key => $dummy) {
41 // $historical_ids[$key] .= "&nbsp;</td>";
42 $historical_ids[$key] .= "</td>";
45 $item_count = 0;
49 function end_row()
51 global $cell_count, $CPR, $historical_ids;
52 end_cell();
53 if ($cell_count > 0) {
54 for (; $cell_count < $CPR; ++$cell_count) {
55 echo "<td></td>";
56 foreach ($historical_ids as $key => $dummy) {
57 $historical_ids[$key] .= "<td></td>";
61 foreach ($historical_ids as $key => $dummy) {
62 echo $historical_ids[$key];
65 echo "</tr>\n";
66 $cell_count = 0;
70 // $is_lbf is defined in trend_form.php and indicates that we are being
71 // invoked from there; in that case the current encounter is irrelevant.
72 $from_trend_form = !empty($is_lbf);
73 // Yet another invocation from somewhere other than encounter.
74 // don't show any action buttons.
75 $from_lbf_edit = isset($_GET['isShow']) ? true : false;
76 // This is true if the page is loaded into an iframe in add_edit_issue.php.
77 $from_issue_form = !empty($_REQUEST['from_issue_form']);
79 $formname = isset($_GET['formname']) ? $_GET['formname'] : '';
80 $formid = isset($_GET['id']) ? intval($_GET['id']) : 0;
81 $portalid = isset($_GET['portalid']) ? intval($_GET['portalid']) : 0;
83 $visitid = intval(empty($_GET['visitid']) ? $encounter : $_GET['visitid']);
85 // If necessary get the encounter from the forms table entry for this form.
86 if ($formid && !$visitid) {
87 $frow = sqlQuery(
88 "SELECT pid, encounter FROM forms WHERE " .
89 "form_id = ? AND formdir = ? AND deleted = 0",
90 array($formid, $formname)
92 $visitid = intval($frow['encounter']);
93 if ($frow['pid'] != $pid) {
94 die("Internal error: patient ID mismatch!");
98 if (!$from_trend_form && !$visitid && !$from_lbf_edit) {
99 die("Internal error: we do not seem to be in an encounter!");
102 $grparr = array();
103 getLayoutProperties($formname, $grparr, '*');
104 $lobj = $grparr[''];
105 $formtitle = $lobj['grp_title'];
106 $formhistory = 0 + $lobj['grp_repeats'];
107 if (!empty($lobj['grp_columns'])) {
108 $CPR = intval($lobj['grp_columns']);
110 if (!empty($lobj['grp_size'])) {
111 $FONTSIZE = intval($lobj['grp_size']);
113 if (!empty($lobj['grp_issue_type'])) {
114 $LBF_ISSUE_TYPE = $lobj['grp_issue_type'];
116 if (!empty($lobj['grp_aco_spec'])) {
117 $LBF_ACO = explode('|', $lobj['grp_aco_spec']);
119 if ($lobj['grp_services']) {
120 $LBF_SERVICES_SECTION = $lobj['grp_services'] == '*' ? '' : $lobj['grp_services'];
122 if ($lobj['grp_products']) {
123 $LBF_PRODUCTS_SECTION = $lobj['grp_products'] == '*' ? '' : $lobj['grp_products'];
125 if ($lobj['grp_diags']) {
126 $LBF_DIAGS_SECTION = $lobj['grp_diags'] == '*' ? '' : $lobj['grp_diags'];
129 // Check access control.
130 if (!acl_check('admin', 'super') && !empty($LBF_ACO)) {
131 $auth_aco_write = acl_check($LBF_ACO[0], $LBF_ACO[1], '', 'write');
132 $auth_aco_addonly = acl_check($LBF_ACO[0], $LBF_ACO[1], '', 'addonly');
133 // echo "\n<!-- '$auth_aco_write' '$auth_aco_addonly' -->\n"; // debugging
134 if (!$auth_aco_write && !($auth_aco_addonly && !$formid)) {
135 die(xlt('Access denied'));
139 if (isset($LBF_SERVICES_SECTION) || isset($LBF_PRODUCTS_SECTION) || isset($LBF_DIAGS_SECTION)) {
140 $fs = new FeeSheetHtml($pid, $visitid);
143 if (!$from_trend_form) {
144 $fname = $GLOBALS['OE_SITE_DIR'] . "/LBF/$formname.plugin.php";
145 if (file_exists($fname)) {
146 include_once($fname);
150 // If Save was clicked, save the info.
152 if (!empty($_POST['bn_save']) || !empty($_POST['bn_save_print']) || !empty($_POST['bn_save_continue'])) {
153 $newid = 0;
154 if (!$formid) {
155 // Creating a new form. Get the new form_id by inserting and deleting a dummy row.
156 // This is necessary to create the form instance even if it has no native data.
157 $newid = sqlInsert("INSERT INTO lbf_data " .
158 "( field_id, field_value ) VALUES ( '', '' )");
159 sqlStatement("DELETE FROM lbf_data WHERE form_id = ? AND " .
160 "field_id = ''", array($newid));
161 addForm($visitid, $formtitle, $newid, $formname, $pid, $userauthorized);
164 $my_form_id = $formid ? $formid : $newid;
166 // If there is an issue ID, update it in the forms table entry.
167 if (isset($_POST['form_issue_id'])) {
168 sqlStatement(
169 "UPDATE forms SET issue_id = ? WHERE formdir = ? AND form_id = ? AND deleted = 0",
170 array($_POST['form_issue_id'], $formname, $my_form_id)
174 // If there is a provider ID, update it in the forms table entry.
175 if (isset($_POST['form_provider_id'])) {
176 sqlStatement(
177 "UPDATE forms SET provider_id = ? WHERE formdir = ? AND form_id = ? AND deleted = 0",
178 array($_POST['form_provider_id'], $formname, $my_form_id)
182 $sets = "";
183 $fres = sqlStatement("SELECT * FROM layout_options " .
184 "WHERE form_id = ? AND uor > 0 AND field_id != '' AND " .
185 "edit_options != 'H' AND edit_options NOT LIKE '%0%' " .
186 "ORDER BY group_id, seq", array($formname));
187 while ($frow = sqlFetchArray($fres)) {
188 $field_id = $frow['field_id'];
189 $data_type = $frow['data_type'];
190 // If the field was not in the web form, skip it.
191 // Except if it's checkboxes, if unchecked they are not returned.
193 // if ($data_type != 21 && !isset($_POST["form_$field_id"])) continue;
195 // The above statement commented out 2015-01-12 because a LBF plugin might conditionally
196 // disable a field that is not applicable, and we need the ability to clear out the old
197 // garbage in there so it does not show up in the "report" view of the data. So we will
198 // trust that it's OK to clear any field that is defined in the layout but not returned
199 // by the form.
201 if ($data_type == 31) {
202 continue; // skip static text fields
204 $value = get_layout_form_value($frow);
205 // If edit option P or Q, save to the appropriate different table and skip the rest.
206 $source = $frow['source'];
207 if ($source == 'D' || $source == 'H') {
208 // Save to patient_data, employer_data or history_data.
209 if ($source == 'H') {
210 $new = array($field_id => $value);
211 updateHistoryData($pid, $new);
212 } else if (strpos($field_id, 'em_') === 0) {
213 $field_id = substr($field_id, 3);
214 $new = array($field_id => $value);
215 updateEmployerData($pid, $new);
216 } else {
217 $esc_field_id = escape_sql_column_name($field_id, array('patient_data'));
218 sqlStatement(
219 "UPDATE patient_data SET `$esc_field_id` = ? WHERE pid = ?",
220 array($value, $pid)
224 continue;
225 } else if ($source == 'E') {
226 // Save to shared_attributes. Can't delete entries for empty fields because with the P option
227 // it's important to know when a current empty value overrides a previous value.
228 sqlStatement(
229 "REPLACE INTO shared_attributes SET " .
230 "pid = ?, encounter = ?, field_id = ?, last_update = NOW(), " .
231 "user_id = ?, field_value = ?",
232 array($pid, $visitid, $field_id, $_SESSION['authUserID'], $value)
234 continue;
235 } else if ($source == 'V') {
236 // Save to form_encounter.
237 $esc_field_id = escape_sql_column_name($field_id, array('form_encounter'));
238 sqlStatement(
239 "UPDATE form_encounter SET `$esc_field_id` = ? WHERE " .
240 "pid = ? AND encounter = ?",
241 array($value, $pid, $visitid)
243 continue;
246 // It's a normal form field, save to lbf_data.
247 if ($formid) { // existing form
248 if ($value === '') {
249 $query = "DELETE FROM lbf_data WHERE " .
250 "form_id = ? AND field_id = ?";
251 sqlStatement($query, array($formid, $field_id));
252 } else {
253 $query = "REPLACE INTO lbf_data SET field_value = ?, " .
254 "form_id = ?, field_id = ?";
255 sqlStatement($query, array($value, $formid, $field_id));
257 } else { // new form
258 if ($value !== '') {
259 sqlStatement(
260 "INSERT INTO lbf_data " .
261 "( form_id, field_id, field_value ) VALUES ( ?, ?, ? )",
262 array($newid, $field_id, $value)
268 if ($portalid) {
269 // Delete the request from the portal.
270 $result = cms_portal_call(array('action' => 'delpost', 'postid' => $portalid));
271 if ($result['errmsg']) {
272 die(text($result['errmsg']));
276 if (isset($fs)) {
277 $bill = is_array($_POST['form_fs_bill']) ? $_POST['form_fs_bill'] : null;
278 $prod = is_array($_POST['form_fs_prod']) ? $_POST['form_fs_prod'] : null;
279 $alertmsg = $fs->checkInventory($prod);
280 // If there is an inventory error then no services or products will be saved, and
281 // the form will be redisplayed with an error alert and everything else saved.
282 if (!$alertmsg) {
283 $fs->save($bill, $prod, null, null);
284 $fs->updatePriceLevel($_POST['form_fs_pricelevel']);
288 if (!$formid) {
289 $formid = $newid;
292 if (!$alertmsg && !$from_issue_form && empty($_POST['bn_save_continue'])) {
293 // Support custom behavior at save time, such as going to another form.
294 if (function_exists($formname . '_save_exit')) {
295 if (call_user_func($formname . '_save_exit')) {
296 exit;
299 formHeader("Redirecting....");
300 // If Save and Print, write the JavaScript to open a window for printing.
301 if (!empty($_POST['bn_save_print'])) {
302 echo "<script language='Javascript'>\n" .
303 "top.restoreSession();\n" .
304 "window.open('$rootdir/forms/LBF/printable.php?" .
305 "formname=" . urlencode($formname) .
306 "&formid=" . urlencode($formid) .
307 "&visitid=" . urlencode($visitid) .
308 "&patientid=" . urlencode($pid) .
309 "', '_blank');\n" .
310 "</script>\n";
312 formJump();
313 formFooter();
314 exit;
319 <html>
320 <head>
321 <?php Header::setupHeader(['opener', 'common', 'datetime-picker', 'jquery-ui',]); ?>
323 <style>
325 td, input, select, textarea {
326 font-family: Arial, Helvetica, sans-serif;
327 font-size: 10pt;
330 .table > tbody > tr > td {
331 border-top: 0;
334 div.section {
335 border: solid;
336 border-width: 1px;
337 border-color: #0000ff;
338 margin: 0 0 0 10pt;
339 padding: 5pt;
342 .form-control {
343 width: auto;
344 display: inline;
345 height: auto;
348 .RS {
349 border-style: solid;
350 border-width: 0 0 1px 0;
351 border-color: #999999;
354 .RO {
355 border-style: solid;
356 border-width: 1px 1px 1px 1px !important;
357 border-color: #999999;
360 </style>
362 <?php include_once("{$GLOBALS['srcdir']}/options.js.php"); ?>
364 <!-- LiterallyCanvas support -->
365 <?php echo lbf_canvas_head(); ?>
367 <script language="JavaScript">
369 // Support for beforeunload handler.
370 var somethingChanged = false;
372 function verifyCancel() {
373 if (somethingChanged) {
374 if (!confirm('<?php echo xl('You have unsaved changes. Do you really want to close this form?'); ?>')) {
375 return false;
378 somethingChanged = false;
379 parent.closeTab(window.name, false);
382 $(document).ready(function () {
384 if (window.tabbify) {
385 tabbify();
387 if (window.checkSkipConditions) {
388 checkSkipConditions();
391 $(".iframe_medium").on('click', function (e) {
392 e.preventDefault();
393 e.stopPropagation();
394 dlgopen('', '', 950, 550, '', '', {
395 buttons: [
396 {text: '<?php echo xla('Close'); ?>', close: true, style: 'default btn-sm'}
398 type: 'iframe',
399 url: $(this).attr('href')
403 // Support for beforeunload handler.
404 $('.lbfdata input, .lbfdata select, .lbfdata textarea').change(function () {
405 somethingChanged = true;
407 window.addEventListener("beforeunload", function (e) {
408 if (somethingChanged && !top.timed_out) {
409 var msg = "<?php echo xls('You have unsaved changes.'); ?>";
410 e.returnValue = msg; // Gecko, Trident, Chrome 34+
411 return msg; // Gecko, WebKit, Chrome <34
415 $('.datepicker').datetimepicker({
416 <?php $datetimepicker_timepicker = false; ?>
417 <?php $datetimepicker_showseconds = false; ?>
418 <?php $datetimepicker_formatInput = false; ?>
419 <?php require($GLOBALS['srcdir'] . '/js/xl/jquery-datetimepicker-2-5-4.js.php'); ?>
420 <?php // can add any additional javascript settings to datetimepicker here; need to prepend first setting with a comma ?>
422 $('.datetimepicker').datetimepicker({
423 <?php $datetimepicker_timepicker = true; ?>
424 <?php $datetimepicker_showseconds = false; ?>
425 <?php $datetimepicker_formatInput = false; ?>
426 <?php require($GLOBALS['srcdir'] . '/js/xl/jquery-datetimepicker-2-5-4.js.php'); ?>
427 <?php // can add any additional javascript settings to datetimepicker here; need to prepend first setting with a comma ?>
431 var mypcc = '<?php echo $GLOBALS['phone_country_code'] ?>';
433 // Supports customizable forms.
434 function divclick(cb, divid) {
435 var divstyle = document.getElementById(divid).style;
436 if (cb.checked) {
437 divstyle.display = 'block';
438 } else {
439 divstyle.display = 'none';
441 return true;
444 // The ID of the input element to receive a found code.
445 var current_sel_name = '';
447 // This is for callback by the find-code popup.
448 // Appends to or erases the current list of related codes.
449 function set_related(codetype, code, selector, codedesc) {
450 var f = document.forms[0];
451 <?php if (isset($fs)) { ?>
452 // This is the case of selecting a code for the Fee Sheet:
453 if (!current_sel_name) {
454 if (code) {
455 $.getScript('<?php echo $GLOBALS['web_root'] ?>/library/ajax/code_attributes_ajax.php' +
456 '?codetype=' + encodeURIComponent(codetype) +
457 '&code=' + encodeURIComponent(code) +
458 '&selector=' + encodeURIComponent(selector) +
459 '&pricelevel=' + encodeURIComponent(f.form_fs_pricelevel ? f.form_fs_pricelevel.value : ""));
461 return '';
463 <?php } ?>
464 // frc will be the input element containing the codes.
465 // frcd, if set, will be the input element containing their descriptions.
466 var frc = f[current_sel_name];
467 var frcd;
468 var matches = current_sel_name.match(/^(.*)__desc$/);
469 if (matches) {
470 frcd = frc;
471 frc = f[matches[1]];
473 // For LBFs we will allow only one code in a field.
474 var s = ''; // frc.value;
475 var sd = ''; // frcd ? frcd.value : s;
476 if (code) {
477 if (s.length > 0) {
478 s += ';';
479 sd += ';';
481 s += codetype + ':' + code;
482 sd += codedesc;
483 } else {
484 s = '';
485 sd = '';
487 frc.value = s;
488 if (frcd) frcd.value = sd;
489 return '';
492 // This invokes the "dynamic" find-code popup.
493 function sel_related(elem, codetype) {
494 current_sel_name = elem ? elem.name : '';
495 var url = '<?php echo $rootdir ?>/patient_file/encounter/find_code_dynamic.php';
496 if (codetype) url += '?codetype=' + codetype;
497 dlgopen(url, '_blank', 800, 500);
500 // Compute the length of a string without leading and trailing spaces.
501 function trimlen(s) {
502 var i = 0;
503 var j = s.length - 1;
504 for (; i <= j && s.charAt(i) == ' '; ++i) ;
505 for (; i <= j && s.charAt(j) == ' '; --j) ;
506 if (i > j) return 0;
507 return j + 1 - i;
510 // This capitalizes the first letter of each word in the passed input
511 // element. It also strips out extraneous spaces.
512 function capitalizeMe(elem) {
513 var a = elem.value.split(' ');
514 var s = '';
515 for (var i = 0; i < a.length; ++i) {
516 if (a[i].length > 0) {
517 if (s.length > 0) s += ' ';
518 s += a[i].charAt(0).toUpperCase() + a[i].substring(1);
521 elem.value = s;
524 // Validation logic for form submission.
525 function validate(f) {
526 <?php generate_layout_validation($formname); ?>
527 // Validation for Fee Sheet stuff. Skipping this because CV decided (2015-11-03)
528 // that these warning messages are not appropriate for layout based visit forms.
530 // if (window.jsLineItemValidation && !jsLineItemValidation(f)) return false;
531 somethingChanged = false; // turn off "are you sure you want to leave"
532 top.restoreSession();
533 return true;
536 <?php
537 if (isset($fs)) {
538 // jsLineItemValidation() function for the fee sheet stuff.
539 echo $fs->jsLineItemValidation('form_fs_bill', 'form_fs_prod');
542 // Add a service line item.
543 function fs_append_service(code_type, code, desc, price) {
544 var telem = document.getElementById('fs_services_table');
545 var lino = telem.rows.length - 1;
546 var trelem = telem.insertRow(telem.rows.length);
547 trelem.innerHTML =
548 "<td class='text'>" + code + "&nbsp;</td>" +
549 "<td class='text'>" + desc + "&nbsp;</td>" +
550 "<td class='text'>" +
551 "<select name='form_fs_bill[" + lino + "][provid]'>" +
552 "<?php echo addslashes($fs->genProviderOptionList('-- ' . xl('Default') . ' --')) ?>" +
553 "</select>&nbsp;" +
554 "</td>" +
555 "<td class='text' align='right'>" + price + "&nbsp;</td>" +
556 "<td class='text' align='right'>" +
557 "<input type='checkbox' name='form_fs_bill[" + lino + "][del]' value='1' />" +
558 "<input type='hidden' name='form_fs_bill[" + lino + "][code_type]' value='" + code_type + "' />" +
559 "<input type='hidden' name='form_fs_bill[" + lino + "][code]' value='" + code + "' />" +
560 "<input type='hidden' name='form_fs_bill[" + lino + "][price]' value='" + price + "' />" +
561 "</td>";
564 // Add a product line item.
565 function fs_append_product(code_type, code, desc, price, warehouses) {
566 var telem = document.getElementById('fs_products_table');
567 if (!telem) {
568 alert('<?php echo xla('A product was selected but there is no product section in this form.'); ?>');
569 return;
571 var lino = telem.rows.length - 1;
572 var trelem = telem.insertRow(telem.rows.length);
573 trelem.innerHTML =
574 "<td class='text'>" + desc + "&nbsp;</td>" +
575 "<td class='text'>" +
576 "<select name='form_fs_prod[" + lino + "][warehouse]'>" + warehouses + "</select>&nbsp;" +
577 "</td>" +
578 "<td class='text' align='right'>" +
579 "<input type='text' name='form_fs_prod[" + lino + "][units]' size='3' value='1' />&nbsp;" +
580 "</td>" +
581 "<td class='text' align='right'>" + price + "&nbsp;</td>" +
582 "<td class='text' align='right'>" +
583 "<input type='checkbox' name='form_fs_prod[" + lino + "][del]' value='1' />" +
584 "<input type='hidden' name='form_fs_prod[" + lino + "][drug_id]' value='" + code + "' />" +
585 "<input type='hidden' name='form_fs_prod[" + lino + "][price]' value='" + price + "' />" +
586 "</td>";
589 // Add a diagnosis line item.
590 function fs_append_diag(code_type, code, desc) {
591 var telem = document.getElementById('fs_diags_table');
592 // Adding 1000 because form_fs_bill[] is shared with services and we want to avoid collisions.
593 var lino = telem.rows.length - 1 + 1000;
594 var trelem = telem.insertRow(telem.rows.length);
595 trelem.innerHTML =
596 "<td class='text'>" + code + "&nbsp;</td>" +
597 "<td class='text'>" + desc + "&nbsp;</td>" +
598 "<td class='text' align='right'>" +
599 "<input type='checkbox' name='form_fs_bill[" + lino + "][del]' value='1' />" +
600 "<input type='hidden' name='form_fs_bill[" + lino + "][code_type]' value='" + code_type + "' />" +
601 "<input type='hidden' name='form_fs_bill[" + lino + "][code]' value='" + code + "' />" +
602 "<input type='hidden' name='form_fs_bill[" + lino + "][price]' value='" + 0 + "' />" +
603 "</td>";
606 // Respond to clicking a checkbox for adding (or removing) a specific service.
607 function fs_service_clicked(cb) {
608 var f = cb.form;
609 // The checkbox value is a JSON array containing the service's code type, code, description,
610 // and price for each price level.
611 var a = JSON.parse(cb.value);
612 if (!cb.checked) {
613 // The checkbox was UNchecked.
614 // Find last row with a matching code_type and code and set its del flag.
615 var telem = document.getElementById('fs_services_table');
616 var lino = telem.rows.length - 2;
617 for (; lino >= 0; --lino) {
618 var pfx = "form_fs_bill[" + lino + "]";
619 if (f[pfx + "[code_type]"].value == a[0] && f[pfx + "[code]"].value == a[1]) {
620 f[pfx + "[del]"].checked = true;
621 break;
624 return;
626 $.getScript('<?php echo $GLOBALS['web_root'] ?>/library/ajax/code_attributes_ajax.php' +
627 '?codetype=' + encodeURIComponent(a[0]) +
628 '&code=' + encodeURIComponent(a[1]) +
629 '&pricelevel=' + encodeURIComponent(f.form_fs_pricelevel.value));
632 // Respond to clicking a checkbox for adding (or removing) a specific product.
633 function fs_product_clicked(cb) {
634 var f = cb.form;
635 // The checkbox value is a JSON array containing the product's code type, code and selector.
636 var a = JSON.parse(cb.value);
637 if (!cb.checked) {
638 // The checkbox was UNchecked.
639 // Find last row with a matching product ID and set its del flag.
640 var telem = document.getElementById('fs_products_table');
641 var lino = telem.rows.length - 2;
642 for (; lino >= 0; --lino) {
643 var pfx = "form_fs_prod[" + lino + "]";
644 if (f[pfx + "[code_type]"].value == a[0] && f[pfx + "[code]"].value == a[1]) {
645 f[pfx + "[del]"].checked = true;
646 break;
649 return;
651 $.getScript('<?php echo $GLOBALS['web_root'] ?>/library/ajax/code_attributes_ajax.php' +
652 '?codetype=' + encodeURIComponent(a[0]) +
653 '&code=' + encodeURIComponent(a[1]) +
654 '&selector=' + encodeURIComponent(a[2]) +
655 '&pricelevel=' + encodeURIComponent(f.form_fs_pricelevel.value));
658 // Respond to clicking a checkbox for adding (or removing) a specific diagnosis.
659 function fs_diag_clicked(cb) {
660 var f = cb.form;
661 // The checkbox value is a JSON array containing the diagnosis's code type, code, description.
662 var a = JSON.parse(cb.value);
663 if (!cb.checked) {
664 // The checkbox was UNchecked.
665 // Find last row with a matching code_type and code and set its del flag.
666 var telem = document.getElementById('fs_diags_table');
667 var lino = telem.rows.length - 2 + 1000;
668 for (; lino >= 0; --lino) {
669 var pfx = "form_fs_bill[" + lino + "]";
670 if (f[pfx + "[code_type]"].value == a[0] && f[pfx + "[code]"].value == a[1]) {
671 f[pfx + "[del]"].checked = true;
672 break;
675 return;
677 $.getScript('<?php echo $GLOBALS['web_root'] ?>/library/ajax/code_attributes_ajax.php' +
678 '?codetype=' + encodeURIComponent(a[0]) +
679 '&code=' + encodeURIComponent(a[1]) +
680 '&pricelevel=' + encodeURIComponent(f.form_fs_pricelevel ? f.form_fs_pricelevel.value : ""));
683 // Respond to selecting a package of codes.
684 function fs_package_selected(sel) {
685 var f = sel.form;
686 // The option value is an encoded string of code types and codes.
687 if (sel.value) {
688 $.getScript('<?php echo $GLOBALS['web_root'] ?>/library/ajax/code_attributes_ajax.php' +
689 '?list=' + encodeURIComponent(sel.value) +
690 '&pricelevel=' + encodeURIComponent(f.form_fs_pricelevel ? f.form_fs_pricelevel.value : ""));
692 sel.selectedIndex = 0;
695 // This is called back by code_attributes_ajax.php to complete the appending of a line item.
696 function code_attributes_handler(codetype, code, desc, price, warehouses) {
697 if (codetype == 'PROD') {
698 fs_append_product(codetype, code, desc, price, warehouses);
700 else if (codetype == 'ICD9' || codetype == 'ICD10') {
701 fs_append_diag(codetype, code, desc);
703 else {
704 fs_append_service(codetype, code, desc, price);
708 function warehouse_changed(sel) {
709 if (!confirm('<?php echo xls('Do you really want to change Warehouse?'); ?>')) {
710 // They clicked Cancel so reset selection to its default state.
711 for (var i = 0; i < sel.options.length; ++i) {
712 sel.options[i].selected = sel.options[i].defaultSelected;
717 <?php } // end if (isset($fs))
719 if (function_exists($formname . '_javascript')) {
720 call_user_func($formname . '_javascript');
724 </script>
725 </head>
727 <body class="body_top"<?php if ($from_issue_form) {
728 echo " style='background-color:#ffffff'";
729 } ?>>
730 <div class='container'>
731 <?php
732 echo "<form method='post' " .
733 "action='$rootdir/forms/LBF/new.php?formname=" . attr($formname) . "&id=$formid&portalid=$portalid' " .
734 "onsubmit='return validate(this)'>\n";
736 $cmsportal_login = '';
737 $portalres = false;
740 if (!$from_trend_form) {
741 $enrow = sqlQuery("SELECT p.fname, p.mname, p.lname, p.cmsportal_login, " .
742 "fe.date FROM " .
743 "form_encounter AS fe, forms AS f, patient_data AS p WHERE " .
744 "p.pid = ? AND f.pid = p.pid AND f.encounter = ? AND " .
745 "f.formdir = 'newpatient' AND f.deleted = 0 AND " .
746 "fe.id = f.form_id LIMIT 1", array($pid, $visitid)); ?>
748 <div class="container-responsive">
749 <div class="row">
750 <div class="col-xs-12">
751 <div class="page-header">
752 <h3>
753 <?php echo text($formtitle) . " " . xlt('for') . ' ';
754 echo text($enrow['fname']) . ' ' . text($enrow['mname']) . ' ' . text($enrow['lname']);
755 echo ' ' . xlt('on') . ' ' . text(oeFormatShortDate(substr($enrow['date'], 0, 10))); ?>
756 </h3>
757 <?php
758 $firow = sqlQuery(
759 "SELECT issue_id, provider_id FROM forms WHERE " .
760 "formdir = ? AND form_id = ? AND deleted = 0",
761 array($formname, $formid)
763 $form_issue_id = empty($firow['issue_id']) ? 0 : intval($firow['issue_id']);
764 $form_provider_id = empty($firow['provider_id']) ? 0 : intval($firow['provider_id']);
766 // Provider selector.
767 echo "&nbsp;&nbsp;";
768 echo xlt('Provider') . ": ";
769 // TBD: Refactor this function out of the FeeSheetHTML class as that is not the best place for it.
770 echo FeeSheetHtml::genProviderSelect('form_provider_id', '-- ' . xl("Please Select") . ' --', $form_provider_id);
772 // If appropriate build a drop-down selector of issues of this type for this patient.
773 // We skip this if in an issue form tab because removing and adding visit form tabs is
774 // beyond the current scope of that code.
775 if (!empty($LBF_ISSUE_TYPE) && !$from_issue_form) {
776 echo "&nbsp;&nbsp;";
777 $query = "SELECT id, title, date, begdate FROM lists WHERE pid = ? AND type = ? " .
778 "ORDER BY COALESCE(begdate, date) DESC, id DESC";
779 $ires = sqlStatement($query, array($pid, $LBF_ISSUE_TYPE));
780 echo "<select name='form_issue_id'>\n";
781 echo " <option value='0'>-- " . xlt('Select Case') . " --</option>\n";
782 while ($irow = sqlFetchArray($ires)) {
783 $issueid = $irow['id'];
784 $issuedate = oeFormatShortDate(empty($irow['begdate']) ? $irow['date'] : $irow['begdate']);
785 echo " <option value='" . attr($issueid) . "'";
786 if ($issueid == $form_issue_id) {
787 echo " selected";
789 echo ">" . text("$issuedate " . $irow['title']) . "</option>\n";
791 echo "</select>\n";
794 </div>
795 </div>
797 <?php $cmsportal_login = $enrow['cmsportal_login'];
798 } // end not from trend form
800 // If loading data from portal, get the data.
801 if ($GLOBALS['gbl_portal_cms_enable'] && $portalid) {
802 $portalres = cms_portal_call(array('action' => 'getpost', 'postid' => $portalid));
803 if ($portalres['errmsg']) {
804 die(text($portalres['errmsg']));
809 <!-- This is where a chart might display. -->
810 <div id="chart"></div>
812 <?php
813 $shrow = getHistoryData($pid);
815 // Determine if this layout uses edit option "I" anywhere.
816 // If not we default to only the first group being initially open.
817 $tmprow = sqlQuery("SELECT form_id FROM layout_options " .
818 "WHERE form_id = ? AND uor > 0 AND edit_options LIKE '%I%' " .
819 "LIMIT 1", array($formname));
820 $some_group_is_open = !empty($tmprow['form_id']);
822 $fres = sqlStatement("SELECT * FROM layout_options " .
823 "WHERE form_id = ? AND uor > 0 " .
824 "ORDER BY group_id, seq", array($formname));
825 $cell_count = 0;
826 $item_count = 0;
827 $display_style = 'block';
829 // This string is the active group levels. Each leading substring represents an instance of nesting.
830 $group_levels = '';
832 // This indicates if </table> will need to be written to end the fields in a group.
833 $group_table_active = false;
835 // This is an array keyed on forms.form_id for other occurrences of this
836 // form type. The maximum number of such other occurrences to display is
837 // in list_options.option_value for this form's list item. Values in this
838 // array are work areas for building the ending HTML for each displayed row.
840 $historical_ids = array();
842 // True if any data items in this form can be graphed.
843 $form_is_graphable = false;
845 $condition_str = '';
847 while ($frow = sqlFetchArray($fres)) {
848 $this_group = $frow['group_id'];
849 $titlecols = $frow['titlecols'];
850 $datacols = $frow['datacols'];
851 $data_type = $frow['data_type'];
852 $field_id = $frow['field_id'];
853 $list_id = $frow['list_id'];
854 $edit_options = $frow['edit_options'];
855 $source = $frow['source'];
857 $graphable = isOption($edit_options, 'G') !== false;
858 if ($graphable) {
859 $form_is_graphable = true;
862 // Accumulate action conditions into a JSON expression for the browser side.
863 accumActionConditions($field_id, $condition_str, $frow['conditions']);
865 $currvalue = '';
867 if (isOption($edit_options, 'H') !== false) {
868 // This data comes from static history
869 if (isset($shrow[$field_id])) {
870 $currvalue = $shrow[$field_id];
872 } else {
873 if (!$formid && $portalres) {
874 // Copying CMS Portal form data into this field if appropriate.
875 $currvalue = cms_field_to_lbf($data_type, $field_id, $portalres['fields']);
878 if ($currvalue === '') {
879 $currvalue = lbf_current_value($frow, $formid, $is_lbf ? 0 : $encounter);
882 if ($currvalue === false) {
883 continue; // column does not exist, should not happen
886 // Handle "P" edit option to default to the previous value of a form field.
887 if (!$from_trend_form && empty($currvalue) && isOption($edit_options, 'P') !== false) {
888 if ($source == 'F' && !$formid) {
889 // Form attribute for new form, get value from most recent form instance.
890 // Form attributes of existing forms are expected to have existing values.
891 $tmp = sqlQuery(
892 "SELECT encounter, form_id FROM forms WHERE " .
893 "pid = ? AND formdir = ? AND deleted = 0 " .
894 "ORDER BY date DESC LIMIT 1",
895 array($pid, $formname)
897 if (!empty($tmp['encounter'])) {
898 $currvalue = lbf_current_value($frow, $tmp['form_id'], $tmp['encounter']);
900 } else if ($source == 'E') {
901 // Visit attribute, get most recent value as of this visit.
902 // Even if the form already exists for this visit it may have a readonly value that only
903 // exists in a previous visit and was created from a different form.
904 $tmp = sqlQuery(
905 "SELECT sa.field_value FROM form_encounter AS e1 " .
906 "JOIN form_encounter AS e2 ON " .
907 "e2.pid = e1.pid AND (e2.date < e1.date OR (e2.date = e1.date AND e2.encounter <= e1.encounter)) " .
908 "JOIN shared_attributes AS sa ON " .
909 "sa.pid = e2.pid AND sa.encounter = e2.encounter AND sa.field_id = ?" .
910 "WHERE e1.pid = ? AND e1.encounter = ? " .
911 "ORDER BY e2.date DESC, e2.encounter DESC LIMIT 1",
912 array($field_id, $pid, $visitid)
914 if (isset($tmp['field_value'])) {
915 $currvalue = $tmp['field_value'];
918 } // End "P" option logic.
921 $this_levels = $this_group;
922 $i = 0;
923 $mincount = min(strlen($this_levels), strlen($group_levels));
924 while ($i < $mincount && $this_levels[$i] == $group_levels[$i]) {
925 ++$i;
927 // $i is now the number of initial matching levels.
929 // If ending a group or starting a subgroup, terminate the current row and its table.
930 if ($group_table_active && ($i != strlen($group_levels) || $i != strlen($this_levels))) {
931 end_row();
932 echo " </table>\n";
933 $group_table_active = false;
936 // Close any groups that we are done with.
937 while (strlen($group_levels) > $i) {
938 $gname = $grparr[$group_levels]['grp_title'];
939 $group_levels = substr($group_levels, 0, -1); // remove last character
940 // No div for an empty group name.
941 if (strlen($gname)) {
942 echo "</div>\n";
946 // If there are any new groups, open them.
947 while ($i < strlen($this_levels)) {
948 end_row();
949 if ($group_table_active) {
950 echo " </table>\n";
951 $group_table_active = false;
953 $group_levels .= $this_levels[$i++];
954 $gname = $grparr[substr($group_levels, 0, $i)]['grp_title'];
955 $subtitle = $grparr[substr($group_levels, 0, $i)]['grp_subtitle'];
956 // Compute a short unique identifier for this group.
957 $group_seq = 'lbf' . $group_levels;
958 $group_name = $gname;
960 if ($some_group_is_open) {
961 // Must have edit option "I" in first item for its group to be initially open.
962 $display_style = isOption($edit_options, 'I') === false ? 'none' : 'block';
965 // If group name is blank, no checkbox or div.
966 if (strlen($gname)) {
967 echo "<br /><span class='bold'><input type='checkbox' name='form_cb_" . attr($group_seq) . "' value='1' " .
968 "onclick='return divclick(this,\"div_" . attr(addslashes($group_seq)) . "\");'";
969 if ($display_style == 'block') {
970 echo " checked";
973 echo " /><b>" . text(xl_layout_label($group_name)) . "</b></span>\n";
974 echo "<div id='div_" . attr($group_seq) . "' class='section table-responsive' style='display:" . attr($display_style) . ";'>\n";
977 $group_table_active = true;
978 echo " <table border='0' cellspacing='0' cellpadding='0' class='lbfdata'>\n";
980 if ($subtitle) {
981 // There is a group subtitle so show it.
982 echo "<tr><td class='bold' style='color:#0000ff' colspan='" . attr($CPR) . "'>" . text($subtitle) . "</td></tr>\n";
983 echo "<tr><td class='bold' style='height:4pt' colspan='" . attr($CPR) . "'></td></tr>\n";
986 $display_style = 'none';
988 // Initialize historical data array and write date headers.
989 $historical_ids = array();
990 if ($formhistory > 0) {
991 echo " <tr>";
992 echo "<td colspan='" . attr($CPR) . "' align='right' class='bold'>";
993 if (empty($is_lbf)) {
994 // Including actual date per IPPF request 2012-08-23.
995 echo text(oeFormatShortDate(substr($enrow['date'], 0, 10)));
996 echo ' (' . htmlspecialchars(xl('Current')) . ')';
999 echo "&nbsp;</td>\n";
1000 $hres = sqlStatement(
1001 "SELECT f.form_id, fe.date " .
1002 "FROM forms AS f, form_encounter AS fe WHERE " .
1003 "f.pid = ? AND f.formdir = ? AND " .
1004 "f.form_id != ? AND f.deleted = 0 AND " .
1005 "fe.pid = f.pid AND fe.encounter = f.encounter " .
1006 "ORDER BY fe.date DESC, f.encounter DESC, f.date DESC " .
1007 "LIMIT ?",
1008 array($pid, $formname, $formid, $formhistory)
1010 // For some readings like vitals there may be multiple forms per encounter.
1011 // We sort these sensibly, however only the encounter date is shown here;
1012 // at some point we may wish to show also the data entry date/time.
1013 while ($hrow = sqlFetchArray($hres)) {
1014 echo "<td colspan='" . attr($CPR) . "' align='right' class='bold'>&nbsp;" .
1015 text(oeFormatShortDate(substr($hrow['date'], 0, 10))) . "</td>\n";
1016 $historical_ids[$hrow['form_id']] = '';
1019 echo " </tr>";
1023 // Handle starting of a new row.
1024 if (($titlecols > 0 && $cell_count >= $CPR) || $cell_count == 0) {
1025 end_row();
1026 if (isOption($edit_options, 'RS')) {
1027 echo " <tr class='RS'>";
1028 } else if (isOption($edit_options, 'RO')) {
1029 echo " <tr class='RO'>";
1030 } else {
1031 echo " <tr>";
1034 // Clear historical data string.
1035 foreach ($historical_ids as $key => $dummy) {
1036 $historical_ids[$key] = '';
1040 if ($item_count == 0 && $titlecols == 0) {
1041 $titlecols = 1;
1044 // First item is on the "left-border"
1045 $leftborder = true;
1047 // Handle starting of a new label cell.
1048 if ($titlecols > 0) {
1049 end_cell();
1050 if (isOption($edit_options, 'SP')) {
1051 $datacols = 0;
1052 $titlecols = $CPR;
1053 echo "<td valign='top' colspan='" . attr($titlecols) . "'";
1054 } else {
1055 echo "<td valign='top' colspan='" . attr($titlecols) . "' nowrap";
1057 echo " class='";
1058 echo ($frow['uor'] == 2) ? "required" : "bold";
1059 if ($graphable) {
1060 echo " graph";
1063 echo "'";
1065 if ($cell_count > 0) {
1066 echo " style='padding-left:10pt'";
1068 // This ID is used by action conditions and also show_graph().
1069 echo " id='label_id_" . attr($field_id) . "'";
1070 echo ">";
1072 foreach ($historical_ids as $key => $dummy) {
1073 $historical_ids[$key] .= "<td valign='top' colspan='" . attr($titlecols) . "' class='text' nowrap>";
1076 $cell_count += $titlecols;
1079 ++$item_count;
1081 echo "<b>";
1082 if ($frow['title']) {
1083 $tmp = xl_layout_label($frow['title']);
1084 echo text($tmp);
1085 // Append colon only if label does not end with punctuation.
1086 if (strpos('?!.,:-=', substr($tmp, -1, 1)) === false) {
1087 echo ':';
1089 } else {
1090 echo "&nbsp;";
1092 echo "</b>";
1094 // Note the labels are not repeated in the history columns.
1096 // Handle starting of a new data cell.
1097 if ($datacols > 0) {
1098 end_cell();
1099 if (isOption($edit_options, 'DS')) {
1100 echo "<td valign='top' colspan='" . attr($datacols) . "' class='text RS'";
1102 if (isOption($edit_options, 'DO')) {
1103 echo "<td valign='top' colspan='" . attr($datacols) . "' class='text RO'";
1104 } else {
1105 echo "<td valign='top' colspan='" . attr($datacols) . "' class='text'";
1107 // This ID is used by action conditions.
1108 echo " id='value_id_" . attr($field_id) . "'";
1109 if ($cell_count > 0) {
1110 echo " style='padding-left:5pt'";
1113 echo ">";
1115 foreach ($historical_ids as $key => $dummy) {
1116 $historical_ids[$key] .= "<td valign='top' align='right' colspan='" . attr($datacols) . "' class='text'>";
1119 $cell_count += $datacols;
1122 ++$item_count;
1124 // Skip current-value fields for the display-only case.
1125 if (!$from_trend_form) {
1126 if ($frow['edit_options'] == 'H') {
1127 echo generate_display_field($frow, $currvalue);
1128 } else {
1129 generate_form_field($frow, $currvalue);
1133 // Append to historical data of other dates for this item.
1134 foreach ($historical_ids as $key => $dummy) {
1135 $value = lbf_current_value($frow, $key, 0);
1136 $historical_ids[$key] .= generate_display_field($frow, $value);
1140 // Close all open groups.
1141 if ($group_table_active) {
1142 end_row();
1143 echo " </table>\n";
1144 $group_table_active = false;
1146 while (strlen($group_levels)) {
1147 $gname = $grparr[$group_levels]['grp_title'];
1148 $group_levels = substr($group_levels, 0, -1); // remove last character
1149 // No div for an empty group name.
1150 if (strlen($gname)) {
1151 echo "</div>\n";
1155 $display_style = 'none';
1157 if (isset($LBF_SERVICES_SECTION) || isset($LBF_DIAGS_SECTION)) {
1158 $fs->loadServiceItems();
1161 if (isset($LBF_SERVICES_SECTION)) {
1162 // Create the checkbox and div for the Services Section.
1163 echo "<br /><span class='bold'><input type='checkbox' name='form_cb_fs_services' value='1' " .
1164 "onclick='return divclick(this, \"div_fs_services\");'";
1165 if ($display_style == 'block') {
1166 echo " checked";
1168 echo " /><b>" . xlt('Services') . "</b></span>\n";
1169 echo "<div id='div_fs_services' class='section' style='display:" . attr($display_style) . ";'>\n";
1170 echo "<center>\n";
1171 $display_style = 'none';
1173 // If there are associated codes, generate a checkbox for each one.
1174 if ($LBF_SERVICES_SECTION) {
1175 echo "<table cellpadding='0' cellspacing='0' width='100%'>\n";
1176 $cols = 3;
1177 $tdpct = (int)(100 / $cols);
1178 $count = 0;
1179 $relcodes = explode(';', $LBF_SERVICES_SECTION);
1180 foreach ($relcodes as $codestring) {
1181 if ($codestring === '') {
1182 continue;
1184 $codes_esc = htmlspecialchars($codestring, ENT_QUOTES);
1185 $cbval = $fs->genCodeSelectorValue($codestring);
1186 if ($count % $cols == 0) {
1187 if ($count) {
1188 echo " </tr>\n";
1190 echo " <tr>\n";
1192 echo " <td width='" . attr($tdpct) . "%'>";
1193 echo "<input type='checkbox' id='form_fs_services[$codes_esc]' " .
1194 "onclick='fs_service_clicked(this)' value='" . attr($cbval) . "'";
1195 if ($fs->code_is_in_fee_sheet) {
1196 echo " checked";
1198 list($codetype, $code) = explode(':', $codestring);
1199 $title = lookup_code_descriptions($codestring);
1200 $title = empty($title) ? $code : xl_list_label($title);
1201 echo " />" . htmlspecialchars($title, ENT_NOQUOTES);
1202 echo "</td>\n";
1203 ++$count;
1205 if ($count) {
1206 echo " </tr>\n";
1208 echo "</table>\n";
1211 // A row for Search, Add Package, Main Provider.
1212 $ctype = $GLOBALS['ippf_specific'] ? 'MA' : '';
1213 echo "<p class='bold'>";
1214 echo "<input type='button' value='" . xla('Search Services') . "' onclick='sel_related(null,\"$ctype\")' />&nbsp;&nbsp;\n";
1215 $fscres = sqlStatement("SELECT * FROM fee_sheet_options ORDER BY fs_category, fs_option");
1216 if (sqlNumRows($fscres)) {
1217 $last_category = '';
1218 echo "<select onchange='fs_package_selected(this)'>\n";
1219 echo " <option value=''>" . xlt('Add Package') . "</option>\n";
1220 while ($row = sqlFetchArray($fscres)) {
1221 $fs_category = $row['fs_category'];
1222 $fs_option = $row['fs_option'];
1223 $fs_codes = $row['fs_codes'];
1224 if ($fs_category !== $last_category) {
1225 if ($last_category) {
1226 echo " </optgroup>\n";
1228 echo " <optgroup label='" . xla(substr($fs_category, 1)) . "'>\n";
1229 $last_category = $fs_category;
1231 echo " <option value='" . attr($fs_codes) . "'>" . xlt(substr($fs_option, 1)) . "</option>\n";
1233 if ($last_category) {
1234 echo " </optgroup>\n";
1236 echo "</select>&nbsp;&nbsp;\n";
1238 echo xlt('Main Provider') . ": ";
1239 echo $fs->genProviderSelect("form_fs_provid", ' ', $fs->provider_id);
1240 echo "\n";
1241 echo "</p>\n";
1243 // Generate a line for each service already in this FS.
1244 echo "<table cellpadding='0' cellspacing='2' id='fs_services_table'>\n";
1245 echo " <tr>\n";
1246 echo " <td class='bold' colspan='2'>" . xlt('Services Provided') . "&nbsp;</td>\n";
1247 echo " <td class='bold'>" . xlt('Provider') . "&nbsp;</td>\n";
1248 echo " <td class='bold' align='right'>" . xlt('Price') . "&nbsp;</td>\n";
1249 echo " <td class='bold' align='right'>" . xlt('Delete') . "</td>\n";
1250 echo " </tr>\n";
1251 foreach ($fs->serviceitems as $lino => $li) {
1252 // Skip diagnoses; those would be in the Diagnoses section below.
1253 if ($code_types[$li['codetype']]['diag']) {
1254 continue;
1256 echo " <tr>\n";
1257 echo " <td class='text'>" . text($li['code']) . "&nbsp;</td>\n";
1258 echo " <td class='text'>" . text($li['code_text']) . "&nbsp;</td>\n";
1259 echo " <td class='text'>" .
1260 $fs->genProviderSelect("form_fs_bill[$lino][provid]", '-- ' . xl("Default") . ' --', $li['provid']) .
1261 " &nbsp;</td>\n";
1262 echo " <td class='text' align='right'>" . oeFormatMoney($li['price']) . "&nbsp;</td>\n";
1263 echo " <td class='text' align='right'>\n" .
1264 " <input type='checkbox' name='form_fs_bill[$lino][del]' " .
1265 "value='1'" . ($li['del'] ? " checked" : "") . " />\n";
1266 foreach ($li['hidden'] as $hname => $hvalue) {
1267 echo " <input type='hidden' name='form_fs_bill[$lino][" . attr($hname) . "]' value='" . attr($hvalue) . "' />\n";
1269 echo " </td>\n";
1270 echo " </tr>\n";
1272 echo "</table>\n";
1273 echo "</center>\n";
1274 echo "</div>\n";
1275 } // End Services Section
1277 if (isset($LBF_PRODUCTS_SECTION)) {
1278 // Create the checkbox and div for the Products Section.
1279 echo "<br /><span class='bold'><input type='checkbox' name='form_cb_fs_products' value='1' " .
1280 "onclick='return divclick(this, \"div_fs_products\");'";
1281 if ($display_style == 'block') {
1282 echo " checked";
1284 echo " /><b>" . xlt('Products') . "</b></span>\n";
1285 echo "<div id='div_fs_products' class='section' style='display:" . attr($display_style) . ";'>\n";
1286 echo "<center>\n";
1287 $display_style = 'none';
1289 // If there are associated codes, generate a checkbox for each one.
1290 if ($LBF_PRODUCTS_SECTION) {
1291 echo "<table cellpadding='0' cellspacing='0' width='100%'>\n";
1292 $cols = 3;
1293 $tdpct = (int)(100 / $cols);
1294 $count = 0;
1295 $relcodes = explode(';', $LBF_PRODUCTS_SECTION);
1296 foreach ($relcodes as $codestring) {
1297 if ($codestring === '') {
1298 continue;
1300 $codes_esc = htmlspecialchars($codestring, ENT_QUOTES);
1301 $cbval = $fs->genCodeSelectorValue($codestring);
1302 if ($count % $cols == 0) {
1303 if ($count) {
1304 echo " </tr>\n";
1306 echo " <tr>\n";
1308 echo " <td width='" . attr($tdpct) . "%'>";
1309 echo "<input type='checkbox' id='form_fs_products[$codes_esc]' " .
1310 "onclick='fs_product_clicked(this)' value='" . attr($cbval) . "'";
1311 if ($fs->code_is_in_fee_sheet) {
1312 echo " checked";
1314 list($codetype, $code) = explode(':', $codestring);
1315 $crow = sqlQuery(
1316 "SELECT name FROM drugs WHERE " .
1317 "drug_id = ? ORDER BY drug_id LIMIT 1",
1318 array($code)
1320 $title = empty($crow['name']) ? $code : xl_list_label($crow['name']);
1321 echo " />" . htmlspecialchars($title, ENT_NOQUOTES);
1322 echo "</td>\n";
1323 ++$count;
1325 if ($count) {
1326 echo " </tr>\n";
1328 echo "</table>\n";
1331 // A row for Search
1332 $ctype = $GLOBALS['ippf_specific'] ? 'MA' : '';
1333 echo "<p class='bold'>";
1334 echo "<input type='button' value='" . xla('Search Products') . "' onclick='sel_related(null,\"PROD\")' />&nbsp;&nbsp;";
1335 echo "</p>\n";
1337 // Generate a line for each product already in this FS.
1338 echo "<table cellpadding='0' cellspacing='2' id='fs_products_table'>\n";
1339 echo " <tr>\n";
1340 echo " <td class='bold'>" . xlt('Products Provided') . "&nbsp;</td>\n";
1341 echo " <td class='bold'>" . xlt('Warehouse') . "&nbsp;</td>\n";
1342 echo " <td class='bold' align='right'>" . xlt('Quantity') . "&nbsp;</td>\n";
1343 echo " <td class='bold' align='right'>" . xlt('Price') . "&nbsp;</td>\n";
1344 echo " <td class='bold' align='right'>" . xlt('Delete') . "</td>\n";
1345 echo " </tr>\n";
1346 $fs->loadProductItems();
1347 foreach ($fs->productitems as $lino => $li) {
1348 echo " <tr>\n";
1349 echo " <td class='text'>" . text($li['code_text']) . "&nbsp;</td>\n";
1350 echo " <td class='text'>" .
1351 $fs->genWarehouseSelect("form_fs_prod[$lino][warehouse]", '', $li['warehouse'], false, $li['hidden']['drug_id'], true) .
1352 " &nbsp;</td>\n";
1353 echo " <td class='text' align='right'>" .
1354 "<input type='text' name='form_fs_prod[$lino][units]' size='3' value='" . $li['units'] . "' />" .
1355 "&nbsp;</td>\n";
1356 echo " <td class='text' align='right'>" . oeFormatMoney($li['price']) . "&nbsp;</td>\n";
1357 echo " <td class='text' align='right'>\n" .
1358 " <input type='checkbox' name='form_fs_prod[$lino][del]' " .
1359 "value='1'" . ($li['del'] ? " checked" : "") . " />\n";
1360 foreach ($li['hidden'] as $hname => $hvalue) {
1361 echo " <input type='hidden' name='form_fs_prod[$lino][" . attr($hname) . "]' value='" . attr($hvalue) . "' />\n";
1363 echo " </td>\n";
1364 echo " </tr>\n";
1366 echo "</table>\n";
1367 echo "</center>\n";
1368 echo "</div>\n";
1369 } // End Products Section
1371 if (isset($LBF_DIAGS_SECTION)) {
1372 // Create the checkbox and div for the Diagnoses Section.
1373 echo "<br /><span class='bold'><input type='checkbox' name='form_cb_fs_diags' value='1' " .
1374 "onclick='return divclick(this, \"div_fs_diags\");'";
1375 if ($display_style == 'block') {
1376 echo " checked";
1378 echo " /><b>" . xlt('Diagnoses') . "</b></span>\n";
1379 echo "<div id='div_fs_diags' class='section' style='display:" . attr($display_style) . ";'>\n";
1380 echo "<center>\n";
1381 $display_style = 'none';
1383 // If there are associated codes, generate a checkbox for each one.
1384 if ($LBF_DIAGS_SECTION) {
1385 echo "<table cellpadding='0' cellspacing='0' width='100%'>\n";
1386 $cols = 3;
1387 $tdpct = (int)(100 / $cols);
1388 $count = 0;
1389 $relcodes = explode(';', $LBF_DIAGS_SECTION);
1390 foreach ($relcodes as $codestring) {
1391 if ($codestring === '') {
1392 continue;
1394 $codes_esc = htmlspecialchars($codestring, ENT_QUOTES);
1395 $cbval = $fs->genCodeSelectorValue($codestring);
1396 if ($count % $cols == 0) {
1397 if ($count) {
1398 echo " </tr>\n";
1400 echo " <tr>\n";
1402 echo " <td width='" . attr($tdpct) . "%'>";
1403 echo "<input type='checkbox' id='form_fs_diags[$codes_esc]' " .
1404 "onclick='fs_diag_clicked(this)' value='" . attr($cbval) . "'";
1405 if ($fs->code_is_in_fee_sheet) {
1406 echo " checked";
1408 list($codetype, $code) = explode(':', $codestring);
1409 $title = lookup_code_descriptions($codestring);
1410 $title = empty($title) ? $code : xl_list_label($title);
1411 echo " />" . htmlspecialchars($title, ENT_NOQUOTES);
1412 echo "</td>\n";
1413 ++$count;
1415 if ($count) {
1416 echo " </tr>\n";
1418 echo "</table>\n";
1421 // A row for Search.
1422 $ctype = collect_codetypes('diagnosis', 'csv');
1423 echo "<p class='bold'>";
1424 echo "<input type='button' value='" . xla('Search Diagnoses') . "' onclick='sel_related(null,\"$ctype\")' />";
1425 echo "</p>\n";
1427 // Generate a line for each diagnosis already in this FS.
1428 echo "<table cellpadding='0' cellspacing='2' id='fs_diags_table'>\n";
1429 echo " <tr>\n";
1430 echo " <td class='bold' colspan='2'>" . xlt('Diagnosis') . "&nbsp;</td>\n";
1431 echo " <td class='bold' align='right'>" . xlt('Delete') . "</td>\n";
1432 echo " </tr>\n";
1433 foreach ($fs->serviceitems as $lino => $li) {
1434 // Skip anything that is not a diagnosis; those are in the Services section above.
1435 if (!$code_types[$li['codetype']]['diag']) {
1436 continue;
1438 echo " <tr>\n";
1439 echo " <td class='text'>" . text($li['code']) . "&nbsp;</td>\n";
1440 echo " <td class='text'>" . text($li['code_text']) . "&nbsp;</td>\n";
1441 // The Diagnoses section shares the form_fs_bill array with the Services section.
1442 echo " <td class='text' align='right'>\n" .
1443 " <input type='checkbox' name='form_fs_bill[$lino][del]' " .
1444 "value='1'" . ($li['del'] ? " checked" : "") . " />\n";
1445 foreach ($li['hidden'] as $hname => $hvalue) {
1446 echo " <input type='hidden' name='form_fs_bill[$lino][" . attr($hname) . "]' value='" . attr($hvalue) . "' />\n";
1448 echo " </td>\n";
1449 echo " </tr>\n";
1451 echo "</table>\n";
1452 echo "</center>\n";
1453 echo "</div>\n";
1454 } // End Diagnoses Section
1457 <br>
1459 <div class="col-xs-12">
1460 <div class="btn-group">
1462 <?php
1463 if (!$from_trend_form && !$from_lbf_edit) {
1464 // Generate price level selector if we are doing services or products.
1465 if (isset($LBF_SERVICES_SECTION) || isset($LBF_PRODUCTS_SECTION)) {
1466 echo xlt('Price Level') . ": ";
1467 echo $fs->generatePriceLevelSelector('form_fs_pricelevel');
1468 echo "&nbsp;&nbsp;";
1471 <button type="submit" class="btn btn-default btn-save" name="bn_save"
1472 value="<?php echo xla('Save'); ?>">
1473 <?php echo xlt('Save'); ?>
1474 </button>
1476 &nbsp;
1477 <button type='submit' class="btn btn-link" name='bn_save_continue'
1478 value='<?php echo xla('Save and Continue') ?>'>
1479 <?php echo xlt('Save and Continue'); ?>
1480 </button>
1481 <?php
1482 if (!$from_issue_form) {
1484 &nbsp;
1485 <button type='submit' class="btn btn-link" name='bn_save_print'
1486 value='<?php echo xla('Save and Print') ?>'>
1487 <?php echo xlt('Save and Print'); ?>
1488 </button>
1489 <?php
1490 if (function_exists($formname . '_additional_buttons')) {
1491 // Allow the plug-in to insert more action buttons here.
1492 call_user_func($formname . '_additional_buttons');
1495 if ($form_is_graphable) {
1497 <button type='button' class="btn btn-default btn-graph"
1498 onclick="top.restoreSession();location='../../patient_file/encounter/trend_form.php?formname=<?php echo attr($formname); ?>'">
1499 <?php echo xlt('Show Graph') ?>
1500 </button>
1501 &nbsp;
1502 <?php
1503 } // end form is graphable
1505 <button type='button' class="btn btn-link btn-cancel" onclick="verifyCancel()">
1506 <?php echo xlt('Cancel'); ?>
1507 </button>
1508 <?php
1509 } // end not from issue form
1511 <?php
1512 } elseif (!$from_lbf_edit) { // $from_trend_form is true but lbf edit doesn't want button
1514 <button type='button' class="btn btn-default btn-back" onclick='window.history.back();'>
1515 <?php echo xlt('Back') ?>
1516 </button>
1517 <?php
1518 } // end from trend form
1520 </div>
1521 <hr>
1522 </div>
1523 <?php if (!$from_trend_form) { // end row and container divs ?>
1524 </div>
1525 </div>
1526 <?php } ?>
1528 <input type='hidden' name='from_issue_form' value='<?php echo text($from_issue_form); ?>'/>
1530 </form>
1532 <!-- include support for the list-add selectbox feature -->
1533 <?php include $GLOBALS['fileroot'] . "/library/options_listadd.inc"; ?>
1535 <script language="JavaScript">
1537 // Array of action conditions for the checkSkipConditions() function.
1538 var skipArray = [
1539 <?php echo $condition_str; ?>
1542 <?php echo $date_init; ?>
1543 <?php
1544 if (function_exists($formname . '_javascript_onload')) {
1545 call_user_func($formname . '_javascript_onload');
1548 // New form and this patient has a portal login and we have not loaded portal data.
1549 // Check if there is portal data pending for this patient and form type.
1550 if (!$alertmsg && !$formid && $GLOBALS['gbl_portal_cms_enable'] && $cmsportal_login && !$portalid) {
1551 $portalres = cms_portal_call(array('action' => 'checkptform', 'form' => $formname, 'patient' => $cmsportal_login));
1552 if ($portalres['errmsg']) {
1553 die(text($portalres['errmsg'])); // TBD: Change to alertmsg
1556 $portalid = $portalres['postid'];
1557 if ($portalid) {
1558 echo "if (confirm('" . xls('The portal has data for this patient and form. Load it now?') . "')) {\n";
1559 echo " top.restoreSession();\n";
1560 echo " document.location.href = 'load_form.php?formname=" . attr($formname) . "&portalid=$portalid';\n";
1561 echo "}\n";
1565 if ($alertmsg) {
1566 echo "alert('" . addslashes($alertmsg) . "');\n";
1569 </script>
1570 </div>
1571 </body>
1572 </html>