Fully responsive globals.php with vertical menu (#2460)
[openemr.git] / interface / billing / sl_eob_invoice.php
blob460030c5db5f09d07f1647d346ac3fbf839d45f4
1 <?php
2 /**
3 * This provides for manual posting of EOBs. It is invoked from
4 * sl_eob_search.php. For automated (X12 835) remittance posting
5 * see sl_eob_process.php.
7 * @package OpenEMR
8 * @link http://www.open-emr.org
9 * @author Rod Roark <rod@sunsetsystems.com>
10 * @author Roberto Vasquez <robertogagliotta@gmail.com>
11 * @author Terry Hill <terry@lillysystems.com>
12 * @author Jerry Padgett <sjpadgett@gmail.com>
13 * @author Stephen Waite <stephen.waite@cmsvt.com>
14 * @author Brady Miller <brady.g.miller@gmail.com>
15 * @copyright Copyright (c) 2005-2016 Rod Roark <rod@sunsetsystems.com>
16 * @copyright Copyright (c) 2018-2019 Stephen Waite <stephen.waite@cmsvt.com>
17 * @copyright Copyright (c) 2019 Brady Miller <brady.g.miller@gmail.com>
18 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
22 require_once("../globals.php");
23 require_once("$srcdir/patient.inc");
24 require_once("$srcdir/forms.inc");
25 require_once("$srcdir/invoice_summary.inc.php");
26 require_once("../../custom/code_types.inc.php");
27 require_once "$srcdir/user.inc";
29 use OpenEMR\Billing\SLEOB;
30 use OpenEMR\Common\Logging\EventAuditLogger;
31 use OpenEMR\Core\Header;
33 $debug = 0; // set to 1 for debugging mode
34 $save_stay = $_REQUEST['form_save'] == '1' ? true : false;
35 $from_posting = (0 + $_REQUEST['isPosting']) ? 1 : 0;
36 $g_posting_adj_disable = $GLOBALS['posting_adj_disable'] ? 'checked' : '';
37 if ($from_posting) {
38 $posting_adj_disable = prevSetting('sl_eob_search.', 'posting_adj_disable', 'posting_adj_disable', $g_posting_adj_disable);
39 } else {
40 $posting_adj_disable = $g_posting_adj_disable;
43 // If we permit deletion of transactions. Might change this later.
44 $ALLOW_DELETE = true;
46 $info_msg = "";
48 // Format money for display.
50 function bucks($amount)
52 if ($amount) {
53 return sprintf("%.2f", $amount);
57 // Delete rows, with logging, for the specified table using the
58 // specified WHERE clause. Borrowed from deleter.php.
60 function row_delete($table, $where)
62 $tres = sqlStatement("SELECT * FROM " . escape_table_name($table) . " WHERE $where");
63 $count = 0;
64 while ($trow = sqlFetchArray($tres)) {
65 $logstring = "";
66 foreach ($trow as $key => $value) {
67 if (!$value || $value == '0000-00-00 00:00:00') {
68 continue;
71 if ($logstring) {
72 $logstring .= " ";
75 $logstring .= $key . "='" . addslashes($value) . "'";
78 EventAuditLogger::instance()->newEvent("delete", $_SESSION['authUser'], $_SESSION['authProvider'], 1, "$table: $logstring");
79 ++$count;
82 if ($count) { // Lets not echo the query for stay and save
83 $query = "DELETE FROM " . escape_table_name($table) . " WHERE $where";
84 sqlStatement($query);
89 <html>
90 <head>
91 <?php Header::setupHeader(['datetime-picker', 'opener', 'no_dialog']); ?>
92 <title><?php echo xlt('EOB Posting - Invoice') ?></title>
93 <script language="JavaScript">
94 var adjDisable = <?php echo js_escape($posting_adj_disable); ?>;
95 // An insurance radio button is selected.
96 function setins(istr) {
97 return true;
100 function goEncounterSummary(pid) {
101 if(pid) {
102 if(typeof opener.toEncSummary === 'function') {
103 opener.toEncSummary(pid);
106 window.close();
108 function doClose() {
109 window.close();
111 // Compute an adjustment that writes off the balance:
112 function writeoff(code) {
113 var f = document.forms[0];
114 var belement = f['form_line[' + code + '][bal]'];
115 var pelement = f['form_line[' + code + '][pay]'];
116 var aelement = f['form_line[' + code + '][adj]'];
117 var relement = f['form_line[' + code + '][reason]'];
118 var tmp = belement.value - pelement.value;
119 aelement.value = Number(tmp).toFixed(2);
120 if (aelement.value && !relement.value) relement.selectedIndex = 1;
121 return false;
124 // Onsubmit handler. A good excuse to write some JavaScript.
125 function validate(f) {
126 let delcount = 0;
127 let allempty = true;
129 for (var i = 0; i < f.elements.length; ++i) {
130 let ename = f.elements[i].name;
131 // Count deletes.
132 if (ename.substring(0, 9) == 'form_del[') {
133 if (f.elements[i].checked) ++delcount;
134 continue;
136 let pfxlen = ename.indexOf('[pay]');
137 if (pfxlen < 0) continue;
138 let pfx = ename.substring(0, pfxlen);
139 let code = pfx.substring(pfx.indexOf('[') + 1, pfxlen - 1);
140 let cPay = parseFloat(f[pfx + '[pay]'].value).toFixed(2);
141 let cAdjust = parseFloat(f[pfx + '[adj]'].value).toFixed(2);
143 if ((cPay != 0) || cAdjust != 0) {
144 allempty = false;
146 if(adjDisable) {
147 if ((cAdjust == 0 && f[pfx + '[reason]'].value)) {
148 allempty = false;
151 if ((cPay != 0) && isNaN(parseFloat(f[pfx + '[pay]'].value))) {
152 alert(<?php echo xlj('Payment value for code ') ?> + code + <?php echo xlj(' is not a number') ?>);
153 return false;
155 if ((cAdjust != 0) && isNaN(parseFloat(f[pfx + '[adj]'].value))) {
156 alert(<?php echo xlj('Adjustment value for code ') ?> + code + <?php echo xlj(' is not a number') ?>);
157 return false;
159 if ((cAdjust != 0) && !f[pfx + '[reason]'].value) {
160 alert(<?php echo xlj('Please select an adjustment reason for code ') ?> + code);
161 return false;
163 // TBD: validate the date format
165 // Check if save is clicked with nothing to post.
166 if (allempty && delcount === 0) {
167 alert(<?php echo xlj('Nothing to Post! Please review entries or use Cancel to exit transaction')?>);
168 return false;
170 // Demand confirmation if deleting anything.
171 if (delcount > 0) {
172 if (!confirm(<?php echo xlj('Really delete'); ?> + ' ' + delcount +
173 ' ' + <?php echo xlj('transactions'); ?> + '?' +
174 ' ' + <?php echo xlj('This action will be logged'); ?> + '!')
175 ) return false;
178 return true;
181 <!-- Get current date -->
183 function getFormattedToday() {
184 let today = new Date();
185 let dd = today.getDate();
186 let mm = today.getMonth() + 1; //January is 0!
187 let yyyy = today.getFullYear();
188 if (dd < 10) {
189 dd = '0' + dd
191 if (mm < 10) {
192 mm = '0' + mm
195 return (yyyy + '-' + mm + '-' + dd);
198 <!-- Update Payment Fields -->
200 function updateFields(payField, adjField, balField, coPayField, isFirstProcCode) {
201 let payAmount = 0.0;
202 let adjAmount = 0.0;
203 let balAmount = 0.0;
204 let coPayAmount = 0.0;
206 // coPayFiled will be null if there is no co-pay entry in the fee sheet
207 if (coPayField)
208 coPayAmount = coPayField.value;
210 // if balance field is 0.00, its value comes back as null, so check for nul-ness first
211 if (balField)
212 balAmount = (balField.value) ? balField.value : 0;
213 if (payField)
214 payAmount = (payField.value) ? payField.value : 0;
216 //alert('balance = >' + balAmount +'< payAmount = ' + payAmount + ' copay = ' + coPayAmount + ' isFirstProcCode = ' + isFirstProcCode);
218 // subtract the co-pay only from the first procedure code
219 if (isFirstProcCode == 1)
220 balAmount = parseFloat(balAmount) + parseFloat(coPayAmount);
221 if (adjDisable) return;
223 adjAmount = balAmount - payAmount;
224 // Assign rounded adjustment value back to TextField
225 adjField.value = adjAmount = Math.round(adjAmount * 100) / 100;
228 $(function () {
229 $('.datepicker').datetimepicker({
230 <?php $datetimepicker_timepicker = false; ?>
231 <?php $datetimepicker_showseconds = false; ?>
232 <?php $datetimepicker_formatInput = true; ?>
233 <?php require($GLOBALS['srcdir'] . '/js/xl/jquery-datetimepicker-2-5-4.js.php'); ?>
234 <?php // can add any additional javascript settings to datetimepicker here; need to prepend first setting with a comma ?>
238 </script>
239 <style>
240 @media only screen and (max-width: 768px) {
241 [class*="col-"] {
242 width: 100%;
243 text-align: left !Important;
247 .table {
248 margin: auto;
249 width: 99%;
252 .table > tbody > tr > td {
253 border-top: none;
256 .last_detail {
257 border-bottom: 1px black solid;
258 margin-top: 2px;
261 @media (min-width: 992px) {
262 .modal-lg {
263 width: 1000px !Important;
267 /*.modalclass {
268 overflow-x: hidden !Important;
270 .oe-ckbox-label{
271 padding-left: 30px;
272 font-weight: 500;
274 </style>
275 </head>
276 <body>
277 <?php
278 $trans_id = 0 + $_GET['id'];
279 if (!$trans_id) {
280 die(xlt("You cannot access this page directly."));
283 // A/R case, $trans_id matches form_encounter.id.
284 $ferow = sqlQuery("SELECT e.*, p.fname, p.mname, p.lname FROM form_encounter AS e, patient_data AS p WHERE e.id = ? AND p.pid = e.pid", array($trans_id));
285 if (empty($ferow)) {
286 die("There is no encounter with form_encounter.id = '" . text($trans_id) . "'.");
288 $patient_id = 0 + $ferow['pid'];
289 $encounter_id = 0 + $ferow['encounter'];
290 $svcdate = substr($ferow['date'], 0, 10);
291 $form_payer_id = ($_POST['$form_payer_id']) ? (0 + $_POST['form_payer_id']) : 0;
292 $form_reference = $_POST['form_reference'];
293 $form_check_date = ($_POST['form_check_date']) ? DateToYYYYMMDD($_POST['form_check_date']) : date('Y-m-d');
294 $form_deposit_date = ($_POST['form_deposit_date']) ? DateToYYYYMMDD($_POST['form_deposit_date']) : date('Y-m-d');
295 $form_pay_total = ($_POST['form_pay_total']) ? (0 + $_POST['form_pay_total']) : 0;
298 $payer_type = 0;
299 if (preg_match('/^Ins(\d)/i', $_POST['form_insurance'], $matches)) {
300 $payer_type = $matches[1];
303 if (($_POST['form_save'] || $_POST['form_cancel'])) {
304 if ($_POST['form_save']) {
305 if (!verifyCsrfToken($_POST["csrf_token_form"])) {
306 csrfNotVerified();
309 if ($debug) {
310 echo "<p><b>" . xlt("This module is in test mode. The database will not be changed.") . "</b><p>\n";
313 $session_id = SLEOB::arGetSession($form_payer_id, $form_reference, $form_check_date, $form_deposit_date, $form_pay_total);
314 // The sl_eob_search page needs its invoice links modified to invoke
315 // javascript to load form parms for all the above and submit.
316 // At the same time that page would be modified to work off the
317 // openemr database exclusively.
318 // And back to the sl_eob_invoice page, I think we may want to move
319 // the source input fields from row level to header level.
321 // Handle deletes. row_delete() is borrowed from deleter.php.
322 if ($ALLOW_DELETE && !$debug) {
323 if (is_array($_POST['form_del'])) {
324 foreach ($_POST['form_del'] as $arseq => $dummy) {
325 row_delete("ar_activity", "pid = '" . add_escape_custom($patient_id) . "' AND " . "encounter = '" . add_escape_custom($encounter_id) . "' AND sequence_no = '" . add_escape_custom($arseq) . "'");
330 $paytotal = 0;
331 foreach ($_POST['form_line'] as $code => $cdata) {
332 $thispay = trim($cdata['pay']);
333 $thisadj = trim($cdata['adj']);
334 $thisins = trim($cdata['ins']);
335 $thiscodetype = trim($cdata['code_type']);
336 $reason = $cdata['reason'];
338 // Get the adjustment reason type. Possible values are:
339 // 1 = Charge adjustment
340 // 2 = Coinsurance
341 // 3 = Deductible
342 // 4 = Other pt resp
343 // 5 = Comment
344 $reason_type = '1';
345 if ($reason) {
346 $tmp = sqlQuery("SELECT option_value FROM list_options WHERE list_id = 'adjreason' AND activity = 1 AND option_id = ?", array($reason));
347 if (empty($tmp['option_value'])) {
348 // This should not happen but if it does, apply old logic.
349 if (preg_match("/To copay/", $reason)) {
350 $reason_type = 2;
351 } elseif (preg_match("/To ded'ble/", $reason)) {
352 $reason_type = 3;
354 $info_msg .= xl("No adjustment reason type found for") . " \"$reason\". ";
355 } else {
356 $reason_type = $tmp['option_value'];
360 if (!$thisins) {
361 $thisins = 0;
364 if (0.0 + $thispay) {
365 SLEOB::arPostPayment($patient_id, $encounter_id, $session_id, $thispay, $code, $payer_type, '', $debug, '', $thiscodetype);
366 $paytotal += $thispay;
369 // Be sure to record adjustment reasons, even for zero adjustments if
370 // they happen to be comments.
371 if ((0.0 + $thisadj) ||
372 ($reason && $reason_type == 5) ||
373 ($reason && ($reason_type > 1 && $reason_type < 6))) {
374 // "To copay" and "To ded'ble" need to become a comment in a zero
375 // adjustment, formatted just like sl_eob_process.php.
376 if ($reason_type == '2') {
377 $reason = $_POST['form_insurance'] . " coins: $thisadj";
378 $thisadj = 0;
379 } elseif ($reason_type == '3') {
380 $reason = $_POST['form_insurance'] . " dedbl: $thisadj";
381 $thisadj = 0;
382 } elseif ($reason_type == '4') {
383 $reason = $_POST['form_insurance'] . " ptresp: $thisadj $reason";
384 $thisadj = 0;
385 } elseif ($reason_type == '5') {
386 $reason = $_POST['form_insurance'] . " note: $thisadj $reason";
387 $thisadj = 0;
388 } else {
389 // An adjustment reason including "Ins" is assumed to be assigned by
390 // insurance, and in that case we identify which one by appending
391 // Ins1, Ins2 or Ins3.
392 if (strpos(strtolower($reason), 'ins') != false) {
393 $reason .= ' ' . $_POST['form_insurance'];
396 SLEOB::arPostAdjustment($patient_id, $encounter_id, $session_id, $thisadj, $code, $payer_type, $reason, $debug, '', $thiscodetype);
400 // Maintain which insurances are marked as finished.
402 $form_done = 0 + $_POST['form_done'];
403 $form_stmt_count = 0 + $_POST['form_stmt_count'];
404 sqlStatement("UPDATE form_encounter SET last_level_closed = ?, stmt_count = ? WHERE pid = ? AND encounter = ?", array($form_done, $form_stmt_count, $patient_id, $encounter_id));
406 if ($_POST['form_secondary']) {
407 SLEOB::arSetupSecondary($patient_id, $encounter_id, $debug);
409 echo "<script language='JavaScript'>\n";
410 echo " if (opener.document.forms[0] != undefined) {\n";
411 echo " if (opener.document.forms[0].form_amount) {\n";
412 echo " var tmp = opener.document.forms[0].form_amount.value - " . attr($paytotal) . ";\n";
413 echo " opener.document.forms[0].form_amount.value = Number(tmp).toFixed(2);\n";
414 echo " }\n";
415 echo " }\n";
416 } else {
417 echo "<script language='JavaScript'>\n";
419 if ($info_msg) {
420 echo " alert(" . js_escape($info_msg) . ");\n";
422 if (!$debug && !$save_stay) {
423 echo "doClose();\n";
425 echo "</script></body></html>\n";
426 if (!$save_stay) {
427 exit();
431 // Get invoice charge details.
432 $codes = ar_get_invoice_summary($patient_id, $encounter_id, true);
433 $pdrow = sqlQuery("select billing_note from patient_data where pid = ? limit 1", array($patient_id));
436 <div class="container">
437 <div class="row">
438 <div class="page-header">
439 <h2><?php echo xlt('EOB Invoice'); ?></h2>
440 </div>
441 </div>
442 <div class="row">
443 <form action='sl_eob_invoice.php?id=<?php echo attr_url($trans_id); ?>' method='post' onsubmit='return validate(this)'>
444 <input type="hidden" name="csrf_token_form" value="<?php echo attr(collectCsrfToken()); ?>"/>
445 <input type="hidden" name="isPosting" value="<?php echo attr($from_posting); ?>"/>
446 <fieldset>
447 <legend><?php echo xlt('Invoice Actions'); ?></legend>
448 <div class="col-xs-12 oe-custom-line">
449 <div class="col-xs-3">
450 <label class="control-label" for="form_name"><?php echo xlt('Patient'); ?>:</label>
451 <input type="text" class="form-control" class="form-control" class="form-control" id='form_name'
452 name='form_name'
453 value="<?php echo attr($ferow['fname']) . ' ' . attr($ferow['mname']) . ' ' . attr($ferow['lname']); ?>"
454 disabled>
455 </div>
456 <div class="col-xs-3">
457 <label class="control-label" for="form_provider"><?php echo xlt('Provider'); ?>:</label>
458 <?php
459 $tmp = sqlQuery("SELECT fname, mname, lname " .
460 "FROM users WHERE id = ?", array($ferow['provider_id']));
461 $provider = text($tmp['fname']) . ' ' . text($tmp['mname']) . ' ' . text($tmp['lname']);
462 $tmp = sqlQuery("SELECT bill_date FROM billing WHERE " .
463 "pid = ? AND encounter = ? AND " .
464 "activity = 1 ORDER BY fee DESC, id ASC LIMIT 1", array($patient_id, $encounter_id));
465 $billdate = substr(($tmp['bill_date'] . "Not Billed"), 0, 10);
467 <input type="text" class="form-control" class="form-control" id='form_provider'
468 name='form_provider' value="<?php echo attr($provider); ?>" disabled>
469 </div>
470 <div class="col-xs-2">
471 <label class="control-label" for="form_invoice"><?php echo xlt('Invoice'); ?>:</label>
472 <input type="text" class="form-control" class="form-control" id='form_provider'
473 name='form_provider' value='<?php echo attr($patient_id) . "." . attr($encounter_id); ?>'
474 disabled>
475 </div>
476 <div class="col-xs-2">
477 <label class="control-label" for="svc_date"><?php echo xlt('Svc Date'); ?>:</label>
478 <input type="text" class="form-control" class="form-control" id='svc_date' name='form_provider'
479 value='<?php echo attr($svcdate); ?>' disabled>
480 </div>
481 <div class="col-xs-2">
482 <label class="control-label" for="insurance_name"><?php echo xlt('Insurance'); ?>:</label>
483 <?php
484 for ($i = 1; $i <= 3; ++$i) {
485 $payerid = SLEOB::arGetPayerID($patient_id, $svcdate, $i);
486 if ($payerid) {
487 $tmp = sqlQuery("SELECT name FROM insurance_companies WHERE id = ?", array($payerid));
488 $insurance .= "$i: " . $tmp['name'] . "\n";
492 <textarea name="insurance_name" id="insurance_name" class="form-control" cols="5" rows="2"
493 readonly><?php echo attr($insurance); ?></textarea>
494 </div>
495 </div>
496 <div class="col-xs-12 oe-custom-line">
497 <div class="col-xs-3">
498 <label class="control-label" for="form_stmt_count"><?php echo xlt('Statements Sent'); ?>
499 :</label>
500 <input type='text' name='form_stmt_count' id='form_stmt_count' class="form-control"
501 value='<?php echo attr((0 + $ferow['stmt_count'])); ?>'/>
502 </div>
503 <div class="col-xs-3">
504 <label class="control-label" for="form_reference"><?php echo xlt('Check/EOB No.'); ?>:</label>
505 <input type='text' name='form_reference' id='form_reference' class="form-control" value=''/>
506 </div>
507 <div class="col-xs-2">
508 <label class="control-label" for="form_check_date"><?php echo xlt('Check/EOB Date'); ?>:</label>
509 <input type='text' name='form_check_date' class='form-control datepicker' value=''/>
510 </div>
511 <div class="col-xs-2">
512 <label class="control-label" for="form_deposit_date"><?php echo xlt('Deposit Date'); ?>:</label>
513 <input type='text' name='form_deposit_date' id='form_deposit_date' class='form-control datepicker' value=''/>
514 <input type='hidden' name='form_payer_id' value=''/>
515 <input type='hidden' name='form_orig_reference' value=''/>
516 <input type='hidden' name='form_orig_check_date' value=''/>
517 <input type='hidden' name='form_orig_deposit_date' value=''/>
518 <input type='hidden' name='form_pay_total' value=''/>
519 </div>
520 </div>
521 <div class="col-xs-12 oe-custom-line">
522 <div class="col-xs-4">
523 <label class="control-label" for="type_code"><?php echo xlt('Now posting for'); ?>:</label>
524 <div style="padding-left:15px">
525 <?php
526 $last_level_closed = 0 + $ferow['last_level_closed'];
528 <label class="radio-inline">
529 <input <?php echo $last_level_closed === 0 ? attr('checked') : ''; ?> name='form_insurance' onclick='setins("Ins1")' type='radio'
530 value='Ins1'><?php echo xlt('Ins1') ?>
531 </label>
532 <label class="radio-inline">
533 <input <?php echo $last_level_closed === 1 ? attr('checked') : ''; ?> name='form_insurance' onclick='setins("Ins2")' type='radio'
534 value='Ins2'><?php echo xlt('Ins2') ?>
535 </label>
536 <label class="radio-inline">
537 <input <?php echo $last_level_closed === 2 ? attr('checked') : ''; ?> name='form_insurance' onclick='setins("Ins3")' type='radio'
538 value='Ins3'><?php echo xlt('Ins3') ?>
539 </label>
540 <label class="radio-inline">
541 <input <?php echo $last_level_closed === 3 ? attr('checked') : ''; ?> name='form_insurance' onclick='setins("Pt")' type='radio'
542 value='Pt'><?php echo xlt('Patient') ?>
543 </label>
544 <?php
545 // TBD: I think the following is unused and can be removed.
547 <input name='form_eobs' type='hidden' value='<?php echo attr($arrow['shipvia']) ?>'/>
548 </div>
549 </div>
550 <div class="col-xs-4">
551 <label class="control-label" for=""><?php echo xlt('Done with'); ?>:</label>
552 <div style="padding-left:15px">
553 <?php
554 // Write a checkbox for each insurance. It is to be checked when
555 // we no longer expect any payments from that company for the claim.
556 $last_level_closed = 0 + $ferow['last_level_closed'];
557 foreach (array(0 => 'None', 1 => 'Ins1', 2 => 'Ins2', 3 => 'Ins3') as $key => $value) {
558 if ($key && !SLEOB::arGetPayerID($patient_id, $svcdate, $key)) {
559 continue;
561 $checked = ($last_level_closed == $key) ? " checked" : "";
562 echo "<label class='radio-inline'>";
563 echo "<input type='radio' name='form_done' value='" . attr($key) . "'$checked />" . text($value);
564 echo "</label>";
567 </div>
568 </div>
569 <div class="col-xs-4">
570 <label class="control-label" for=""><?php echo xlt('Secondary billing'); ?>:</label>
571 <div style="padding-left:15px">
572 <label class="checkbox-inline">
573 <input name="form_secondary" type="checkbox"
574 value="1"><?php echo xlt('Needs secondary billing') ?>
575 </label>
576 </div>
577 </div>
578 </div>
580 </fieldset>
581 <fieldset>
582 <legend><?php echo xlt('Invoice Details'); ?></legend>
583 <div class="table-responsive">
584 <table class="table table-condensed">
585 <thead>
586 <tr>
587 <th><?php echo xlt('Code') ?></th>
588 <th align="right"><?php echo xlt('Charge') ?></th>
589 <th align="right"><?php echo xlt('Balance') ?>&nbsp;</th>
590 <th><?php echo xlt('By/Source') ?></th>
591 <th><?php echo xlt('Date') ?></th>
592 <th><?php echo xlt('Pay') ?></th>
593 <th><?php echo xlt('Adjust') ?></th>
594 <th>&nbsp;</th>
595 <th><?php echo xlt('Reason') ?></th>
596 <?php
597 if ($ALLOW_DELETE) { ?>
598 <th><?php echo xlt('Del') ?></th>
599 <?php
600 } ?>
601 </tr>
602 </thead>
603 <?php
604 $firstProcCodeIndex = -1;
605 $encount = 0;
606 foreach ($codes as $code => $cdata) {
607 ++$encount;
608 $dispcode = $code;
610 // remember the index of the first entry whose code is not "CO-PAY", i.e. it's a legitimate proc code
611 if ($firstProcCodeIndex == -1 && strcmp($code, "CO-PAY") != 0) {
612 $firstProcCodeIndex = $encount;
615 // this sorts the details more or less chronologically:
616 ksort($cdata['dtl']);
617 foreach ($cdata['dtl'] as $dkey => $ddata) {
618 $ddate = substr($dkey, 0, 10);
619 if (preg_match('/^(\d\d\d\d)(\d\d)(\d\d)\s*$/', $ddate, $matches)) {
620 $ddate = $matches[1] . '-' . $matches[2] . '-' . $matches[3];
622 $tmpchg = "";
623 $tmpadj = "";
624 if ($ddata['chg'] != 0) {
625 if (isset($ddata['rsn'])) {
626 $tmpadj = 0 - $ddata['chg'];
627 } else {
628 $tmpchg = $ddata['chg'];
632 <tr>
633 <td class="detail"
634 style="background:<?php echo $dispcode ? 'lightyellow' : ''; ?>"><?php echo text($dispcode);
635 $dispcode = "" ?></td>
636 <td class="detail" class="detail"><?php echo text(bucks($tmpchg)); ?></td>
637 <td class="detail" class="detail">&nbsp;</td>
638 <td class="detail">
639 <?php
640 if (isset($ddata['plv'])) {
641 if (!$ddata['plv']) {
642 echo 'Pt/';
643 } else {
644 echo 'Ins' . text($ddata['plv']) . '/';
647 echo text($ddata['src']);
649 </td>
650 <td class="detail"><?php echo text($ddate); ?></td>
651 <td class="detail"><?php echo text(bucks($ddata['pmt'])); ?></td>
652 <td class="detail"><?php echo text(bucks($tmpadj)); ?></td>
653 <td class="detail">&nbsp;</td>
654 <td class="detail"><?php echo text($ddata['rsn']); ?></td>
655 <?php
656 if ($ALLOW_DELETE) { ?>
657 <td class="detail">
658 <?php
659 if (!empty($ddata['arseq'])) { ?>
660 <input name="form_del[<?php echo attr($ddata['arseq']); ?>]"
661 type="checkbox">
662 <?php
663 } else {
664 ?> &nbsp;
665 <?php
666 } ?>
667 </td>
668 <?php } ?>
669 </tr>
670 <?php } // end of prior detail line ?>
671 <tr>
672 <td class="last_detail"><?php echo text($dispcode);
673 $dispcode = "" ?></td>
674 <td class="last_detail">&nbsp;</td>
675 <td class="last_detail">
676 <input name="form_line[<?php echo attr($code); ?>][bal]" type="hidden"
677 value="<?php echo attr(bucks($cdata['bal'])); ?>">
678 <input name="form_line[<?php echo attr($code); ?>][ins]" type="hidden"
679 value="<?php echo attr($cdata['ins']); ?>">
680 <input name="form_line[<?php echo attr($code); ?>][code_type]" type="hidden"
681 value="<?php echo attr($cdata['code_type']); ?>"> <?php echo text(sprintf("%.2f", $cdata['bal'])); ?>
682 &nbsp;
683 </td>
684 <td class="last_detail"></td>
685 <td class="last_detail"></td>
686 <td class="last_detail">
687 <input name="form_line[<?php echo attr($code); ?>][pay]"
688 onkeyup="updateFields(document.forms[0]['form_line[<?php echo attr($code); ?>][pay]'], document.forms[0]['form_line[<?php echo attr($code); ?>][adj]'], document.forms[0]['form_line[<?php echo attr($code); ?>][bal]'], document.forms[0]['form_line[CO-PAY][bal]'], <?php echo ($firstProcCodeIndex == $encount) ? 1 : 0 ?>)"
689 onfocus="this.select()" autofocus size="10" type="text" class="form-control"
690 value="0.00"></td>
691 <td class="last_detail">
692 <input name="form_line[<?php echo attr($code); ?>][adj]" size="10" type="text"
693 class="form-control"
694 value='<?php echo attr($totalAdjAmount ? $totalAdjAmount : '0.00'); ?>'
695 onclick="this.select()">
696 </td>
697 <td class="last_detail" align="center"><a href=""
698 onclick="return writeoff(<?php echo attr_js($code); ?>)">WO</a>
699 </td>
700 <td class="last_detail">
701 <select class="form-control" name="form_line[<?php echo attr($code); ?>][reason]">
702 <?php
703 // Adjustment reasons are now taken from the list_options table.
704 echo " <option value=''></option>\n";
705 $ores = sqlStatement("SELECT option_id, title, is_default FROM list_options " .
706 "WHERE list_id = 'adjreason' AND activity = 1 ORDER BY seq, title");
707 while ($orow = sqlFetchArray($ores)) {
708 echo " <option value='" . attr($orow['option_id']) . "'";
709 if ($orow['is_default']) {
710 echo " selected";
712 echo ">" . text($orow['title']) . "</option>\n";
715 </select>
716 <?php
717 // TBD: Maybe a comment field would be good here, for appending
718 // to the reason.
720 </td>
721 <?php if ($ALLOW_DELETE) { ?>
722 <td class="last_detail">&nbsp;</td>
723 <?php } ?>
724 </tr>
725 <?php } // end of code ?>
726 </table>
727 </div>
728 </fieldset>
729 <?php //can change position of buttons by creating a class 'position-override' and adding rule text-align:center or right as the case may be in individual stylesheets ?>
730 <div class="form-group clearfix">
731 <div class="col-sm-12 text-left position-override" id="search-btn">
732 <div class="btn-group" role="group">
733 <button type='submit' class="btn btn-default btn-save" name='form_save' id="btn-save-stay"
734 onclick="this.value='1';"><?php echo xlt("Save Current"); ?></button>
735 <button type='submit' class="btn btn-default btn-save" name='form_save' id="btn-save"
736 onclick="this.value='2';"><?php echo xlt("Save & Exit"); ?></button>
737 <button type='button' class="btn btn-link btn-cancel btn-separate-left" name='form_cancel'
738 id="btn-cancel" onclick='doClose()'><?php echo xlt("Close"); ?></button>
739 </div>
740 <?php if ($GLOBALS['new_tabs_layout'] && $from_posting) { ?>
741 <button type='button' class="btn btn-default btn-view pull-right" name='form_goto' id="btn-goto"
742 onclick="goEncounterSummary(<?php echo attr_js($patient_id) ?>)"><?php echo xlt("Past Encounters"); ?></button>
743 <?php } ?>
744 </div>
745 </div>
746 </form>
747 </div>
748 </div><!--End of container div-->
749 <?php if ($from_posting) { ?>
750 <script language="JavaScript">
751 var f1 = opener.document.forms[0];
752 var f2 = document.forms[0];
753 if (f1.form_source) {
754 <?php
755 // These support creation and lookup of ar_session table entries:
756 echo " f2.form_reference.value = f1.form_source.value;\n";
757 echo " f2.form_check_date.value = f1.form_paydate.value;\n";
758 echo " //f2.form_deposit_date.value = f1.form_deposit_date.value;\n";
759 echo " if (f1.form_deposit_date.value != '')\n";
760 echo " f2.form_deposit_date.value = f1.form_deposit_date.value;\n";
761 echo " else\n";
762 echo " f2.form_deposit_date.value = getFormattedToday();\n";
763 echo " f2.form_payer_id.value = f1.form_payer_id.value;\n";
764 echo " f2.form_pay_total.value = f1.form_amount.value;\n";
765 echo " f2.form_orig_reference.value = f1.form_source.value;\n";
766 echo " f2.form_orig_check_date.value = f1.form_paydate.value;\n";
767 echo " f2.form_orig_deposit_date.value = f1.form_deposit_date.value;\n";
769 // While I'm thinking about it, some notes about eob sessions.
770 // If they do not have all of the session key fields in the search
771 // page, then show a warning at the top of the invoice page.
772 // Also when they go to save the invoice page and a session key
773 // field has changed, alert them to that and allow a cancel.
775 // Another point... when posting EOBs, the incoming payer ID might
776 // not match the payer ID for the patient's insurance. This is
777 // because the same payer might be entered more than once into the
778 // insurance_companies table. I don't think it matters much.
781 setins("Ins1");
782 </script>
783 <?php } ?>
784 </body>
785 </html>