Merge pull request #1128 from bradymiller/unique-insurance-report-cleanup_1
[openemr.git] / interface / billing / sl_eob_invoice.php
blob988788d6cf38dde6a2fee6d649443071633c6afc
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 * Copyright (C) 2005-2016 Rod Roark <rod@sunsetsystems.com>
9 * LICENSE: This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://opensource.org/licenses/gpl-license.php>;.
20 * @package OpenEMR
21 * @author Rod Roark <rod@sunsetsystems.com>
22 * @author Roberto Vasquez <robertogagliotta@gmail.com>
23 * @author Terry Hill <terry@lillysystems.com>
24 * @link http://www.open-emr.org
27 require_once("../globals.php");
28 require_once("$srcdir/log.inc");
29 require_once("$srcdir/patient.inc");
30 require_once("$srcdir/forms.inc");
31 require_once("$srcdir/sl_eob.inc.php");
32 require_once("$srcdir/invoice_summary.inc.php");
33 require_once("../../custom/code_types.inc.php");
35 $debug = 0; // set to 1 for debugging mode
38 // If we permit deletion of transactions. Might change this later.
39 $ALLOW_DELETE = true;
41 $info_msg = "";
43 // Format money for display.
45 function bucks($amount)
47 if ($amount) {
48 printf("%.2f", $amount);
52 // Delete rows, with logging, for the specified table using the
53 // specified WHERE clause. Borrowed from deleter.php.
55 function row_delete($table, $where)
57 $tres = sqlStatement("SELECT * FROM $table WHERE $where");
58 $count = 0;
59 while ($trow = sqlFetchArray($tres)) {
60 $logstring = "";
61 foreach ($trow as $key => $value) {
62 if (! $value || $value == '0000-00-00 00:00:00') {
63 continue;
66 if ($logstring) {
67 $logstring .= " ";
70 $logstring .= $key . "='" . addslashes($value) . "'";
73 newEvent("delete", $_SESSION['authUser'], $_SESSION['authProvider'], 1, "$table: $logstring");
74 ++$count;
77 if ($count) {
78 $query = "DELETE FROM $table WHERE $where";
79 echo $query . "<br>\n";
80 sqlStatement($query);
84 <html>
85 <head>
86 <?php html_header_show(); ?>
87 <link rel=stylesheet href="<?php echo $css_header;?>" type="text/css">
88 <title><?php xl('EOB Posting - Invoice', 'e')?></title>
89 <script language="JavaScript">
91 // An insurance radio button is selected.
92 function setins(istr) {
93 return true;
96 // Compute an adjustment that writes off the balance:
97 function writeoff(code) {
98 var f = document.forms[0];
99 var belement = f['form_line[' + code + '][bal]'];
100 var pelement = f['form_line[' + code + '][pay]'];
101 var aelement = f['form_line[' + code + '][adj]'];
102 var relement = f['form_line[' + code + '][reason]'];
103 var tmp = belement.value - pelement.value;
104 aelement.value = Number(tmp).toFixed(2);
105 if (aelement.value && ! relement.value) relement.selectedIndex = 1;
106 return false;
109 // Onsubmit handler. A good excuse to write some JavaScript.
110 function validate(f) {
111 var delcount = 0;
112 for (var i = 0; i < f.elements.length; ++i) {
113 var ename = f.elements[i].name;
114 // Count deletes.
115 if (ename.substring(0, 9) == 'form_del[') {
116 if (f.elements[i].checked) ++delcount;
117 continue;
119 var pfxlen = ename.indexOf('[pay]');
120 if (pfxlen < 0) continue;
121 var pfx = ename.substring(0, pfxlen);
122 var code = pfx.substring(pfx.indexOf('[')+1, pfxlen-1);
123 if (f[pfx+'[pay]'].value || f[pfx+'[adj]'].value) {
124 if (! f[pfx+'[date]'].value) {
125 alert('<?php xl('Date is missing for code ', 'e')?>' + code);
126 return false;
129 if (f[pfx+'[pay]'].value && isNaN(parseFloat(f[pfx+'[pay]'].value))) {
130 alert('<?php xl('Payment value for code ', 'e') ?>' + code + '<?php xl(' is not a number', 'e') ?>');
131 return false;
133 if (f[pfx+'[adj]'].value && isNaN(parseFloat(f[pfx+'[adj]'].value))) {
134 alert('<?php xl('Adjustment value for code ', 'e') ?>' + code + '<?php xl(' is not a number', 'e') ?>');
135 return false;
137 if (f[pfx+'[adj]'].value && ! f[pfx+'[reason]'].value) {
138 alert('<?php xl('Please select an adjustment reason for code ', 'e') ?>' + code);
139 return false;
141 // TBD: validate the date format
143 // Demand confirmation if deleting anything.
144 if (delcount > 0) {
145 if (!confirm('<?php echo xl('Really delete'); ?> ' + delcount +
146 ' <?php echo xl('transactions'); ?>?' +
147 ' <?php echo xl('This action will be logged'); ?>!')
148 ) return false;
150 return true;
153 <!-- Get current date -->
155 function getFormattedToday()
157 var today = new Date();
158 var dd = today.getDate();
159 var mm = today.getMonth()+1; //January is 0!
160 var yyyy = today.getFullYear();
161 if(dd<10){dd='0'+dd}
162 if(mm<10){mm='0'+mm}
164 return (yyyy + '-' + mm + '-' + dd);
167 <!-- Update Payment Fields -->
169 function updateFields(payField, adjField, balField, coPayField, isFirstProcCode)
171 var payAmount = 0.0;
172 var adjAmount = 0.0;
173 var balAmount = 0.0;
174 var coPayAmount = 0.0;
176 // coPayFiled will be null if there is no co-pay entry in the fee sheet
177 if (coPayField)
178 coPayAmount = coPayField.value;
180 // if balance field is 0.00, its value comes back as null, so check for nul-ness first
181 if (balField)
182 balAmount = (balField.value) ? balField.value : 0;
183 if (payField)
184 payAmount = (payField.value) ? payField.value : 0;
186 //alert('balance = >' + balAmount +'< payAmount = ' + payAmount + ' copay = ' + coPayAmount + ' isFirstProcCode = ' + isFirstProcCode);
188 // subtract the co-pay only from the first procedure code
189 if (isFirstProcCode == 1)
190 balAmount = parseFloat(balAmount) + parseFloat(coPayAmount);
192 adjAmount = balAmount - payAmount;
194 // Assign rounded adjustment value back to TextField
195 adjField.value = adjAmount = Math.round(adjAmount*100)/100;
198 </script>
199 </head>
200 <body leftmargin='0' topmargin='0' marginwidth='0' marginheight='0'>
201 <?php
202 $trans_id = 0 + $_GET['id'];
203 if (! $trans_id) {
204 die(xl("You cannot access this page directly."));
207 // A/R case, $trans_id matches form_encounter.id.
208 $ferow = sqlQuery("SELECT e.*, p.fname, p.mname, p.lname " .
209 "FROM form_encounter AS e, patient_data AS p WHERE " .
210 "e.id = '$trans_id' AND p.pid = e.pid");
211 if (empty($ferow)) {
212 die("There is no encounter with form_encounter.id = '$trans_id'.");
215 $patient_id = 0 + $ferow['pid'];
216 $encounter_id = 0 + $ferow['encounter'];
217 $svcdate = substr($ferow['date'], 0, 10);
218 $form_payer_id = 0 + $_POST['form_payer_id'];
219 $form_reference = $_POST['form_reference'];
220 $form_check_date = fixDate($_POST['form_check_date'], date('Y-m-d'));
221 $form_deposit_date = fixDate($_POST['form_deposit_date'], $form_check_date);
222 $form_pay_total = 0 + $_POST['form_pay_total'];
224 $payer_type = 0;
225 if (preg_match('/^Ins(\d)/i', $_POST['form_insurance'], $matches)) {
226 $payer_type = $matches[1];
229 if ($_POST['form_save'] || $_POST['form_cancel']) {
230 if ($_POST['form_save']) {
231 if ($debug) {
232 echo xl("This module is in test mode. The database will not be changed.", '', '<p><b>', "</b><p>\n");
235 $session_id = arGetSession(
236 $form_payer_id,
237 $form_reference,
238 $form_check_date,
239 $form_deposit_date,
240 $form_pay_total
242 // The sl_eob_search page needs its invoice links modified to invoke
243 // javascript to load form parms for all the above and submit.
244 // At the same time that page would be modified to work off the
245 // openemr database exclusively.
246 // And back to the sl_eob_invoice page, I think we may want to move
247 // the source input fields from row level to header level.
249 // Handle deletes. row_delete() is borrowed from deleter.php.
250 if ($ALLOW_DELETE && !$debug) {
251 if (is_array($_POST['form_del'])) {
252 foreach ($_POST['form_del'] as $arseq => $dummy) {
253 row_delete("ar_activity", "pid = '$patient_id' AND " .
254 "encounter = '$encounter_id' AND sequence_no = '$arseq'");
259 $paytotal = 0;
260 foreach ($_POST['form_line'] as $code => $cdata) {
261 $thispay = trim($cdata['pay']);
262 $thisadj = trim($cdata['adj']);
263 $thisins = trim($cdata['ins']);
264 $thiscodetype = trim($cdata['code_type']);
265 $reason = strip_escape_custom($cdata['reason']);
267 // Get the adjustment reason type. Possible values are:
268 // 1 = Charge adjustment
269 // 2 = Coinsurance
270 // 3 = Deductible
271 // 4 = Other pt resp
272 // 5 = Comment
273 $reason_type = '1';
274 if ($reason) {
275 $tmp = sqlQuery("SELECT option_value FROM list_options WHERE " .
276 "list_id = 'adjreason' AND activity = 1 AND " .
277 "option_id = '" . add_escape_custom($reason) . "'");
278 if (empty($tmp['option_value'])) {
279 // This should not happen but if it does, apply old logic.
280 if (preg_match("/To copay/", $reason)) {
281 $reason_type = 2;
282 } else if (preg_match("/To ded'ble/", $reason)) {
283 $reason_type = 3;
286 $info_msg .= xl("No adjustment reason type found for") . " \"$reason\". ";
287 } else {
288 $reason_type = $tmp['option_value'];
292 if (! $thisins) {
293 $thisins = 0;
296 if ($thispay) {
297 arPostPayment(
298 $patient_id,
299 $encounter_id,
300 $session_id,
301 $thispay,
302 $code,
303 $payer_type,
305 $debug,
307 $thiscodetype
309 $paytotal += $thispay;
312 // Be sure to record adjustment reasons, even for zero adjustments if
313 // they happen to be comments.
314 if ($thisadj || ($reason && $reason_type == 5)) {
315 // "To copay" and "To ded'ble" need to become a comment in a zero
316 // adjustment, formatted just like sl_eob_process.php.
317 if ($reason_type == '2') {
318 $reason = $_POST['form_insurance'] . " coins: $thisadj";
319 $thisadj = 0;
320 } else if ($reason_type == '3') {
321 $reason = $_POST['form_insurance'] . " dedbl: $thisadj";
322 $thisadj = 0;
323 } else if ($reason_type == '4') {
324 $reason = $_POST['form_insurance'] . " ptresp: $thisadj $reason";
325 $thisadj = 0;
326 } else if ($reason_type == '5') {
327 $reason = $_POST['form_insurance'] . " note: $thisadj $reason";
328 $thisadj = 0;
329 } else {
330 // An adjustment reason including "Ins" is assumed to be assigned by
331 // insurance, and in that case we identify which one by appending
332 // Ins1, Ins2 or Ins3.
333 if (strpos(strtolower($reason), 'ins') !== false) {
334 $reason .= ' ' . $_POST['form_insurance'];
338 arPostAdjustment(
339 $patient_id,
340 $encounter_id,
341 $session_id,
342 $thisadj,
343 $code,
344 $payer_type,
345 $reason,
346 $debug,
348 $thiscodetype
353 // Maintain which insurances are marked as finished.
355 $form_done = 0 + $_POST['form_done'];
356 $form_stmt_count = 0 + $_POST['form_stmt_count'];
357 sqlStatement("UPDATE form_encounter " .
358 "SET last_level_closed = $form_done, " .
359 "stmt_count = $form_stmt_count WHERE " .
360 "pid = '$patient_id' AND encounter = '$encounter_id'");
362 if ($_POST['form_secondary']) {
363 arSetupSecondary($patient_id, $encounter_id, $debug);
366 echo "<script language='JavaScript'>\n";
367 echo " if (opener.document.forms[0] !== undefined) {\n";
368 echo " if (opener.document.forms[0].form_amount) {\n";
369 echo " var tmp = opener.document.forms[0].form_amount.value - $paytotal;\n";
370 echo " opener.document.forms[0].form_amount.value = Number(tmp).toFixed(2);\n";
371 echo " }\n";
372 echo " }\n";
373 } else {
374 echo "<script language='JavaScript'>\n";
377 if ($info_msg) {
378 echo " alert('" . addslashes($info_msg) . "');\n";
381 if (! $debug) {
382 echo " window.close();\n";
385 echo "</script></body></html>\n";
386 exit();
389 // Get invoice charge details.
390 $codes = ar_get_invoice_summary($patient_id, $encounter_id, true);
392 $pdrow = sqlQuery("select billing_note " .
393 "from patient_data where pid = '$patient_id' limit 1");
395 <center>
397 <form method='post' action='sl_eob_invoice.php?id=<?php echo $trans_id ?>'
398 onsubmit='return validate(this)'>
400 <table border='0' cellpadding='3'>
401 <tr>
402 <td>
403 <?php xl('Patient:', 'e')?>
404 </td>
405 <td>
406 <?php
407 echo $ferow['fname'] . ' ' . $ferow['mname'] . ' ' . $ferow['lname'];
409 </td>
410 <td colspan="2" rowspan="3">
411 <?php
412 for ($i = 1; $i <= 3; ++$i) {
413 $payerid = arGetPayerID($patient_id, $svcdate, $i);
414 if ($payerid) {
415 $tmp = sqlQuery("SELECT name FROM insurance_companies WHERE id = $payerid");
416 echo "Ins$i: " . $tmp['name'] . "<br />";
420 </td>
421 <?php
422 echo "<td rowspan='3' valign='bottom'>\n";
423 echo xl('Statements Sent:');
424 echo "</td>\n";
425 echo "<td rowspan='3' valign='bottom'>\n";
426 echo "<input type='text' name='form_stmt_count' size='10' value='" .
427 (0 + $ferow['stmt_count']) . "' />\n";
428 echo "</td>\n";
430 </tr>
431 <tr>
432 <td>
433 <?php xl('Provider:', 'e')?>
434 </td>
435 <td>
436 <?php
437 $tmp = sqlQuery("SELECT fname, mname, lname " .
438 "FROM users WHERE id = " . $ferow['provider_id']);
439 echo text($tmp['fname']) . ' ' . text($tmp['mname']) . ' ' . text($tmp['lname']);
440 $tmp = sqlQuery("SELECT bill_date FROM billing WHERE " .
441 "pid = '$patient_id' AND encounter = '$encounter_id' AND " .
442 "activity = 1 ORDER BY fee DESC, id ASC LIMIT 1");
443 $billdate = substr(($tmp['bill_date'] . "Not Billed"), 0, 10);
445 </td>
446 </tr>
447 <tr>
448 <td>
449 <?php xl('Invoice:', 'e')?>
450 </td>
451 <td>
452 <?php
453 echo "$patient_id.$encounter_id";
455 </td>
456 </tr>
458 <tr>
459 <td>
460 <?php xl('Svc Date:', 'e'); ?>
461 </td>
462 <td>
463 <?php
464 echo $svcdate;
466 </td>
467 <td colspan="2">
468 <?php xl('Done with:', 'e', '', "&nbsp")?>;
469 <?php
470 // Write a checkbox for each insurance. It is to be checked when
471 // we no longer expect any payments from that company for the claim.
472 $last_level_closed = 0 + $ferow['last_level_closed'];
473 foreach (array(0 => 'None', 1 => 'Ins1', 2 => 'Ins2', 3 => 'Ins3') as $key => $value) {
474 if ($key && !arGetPayerID($patient_id, $svcdate, $key)) {
475 continue;
478 $checked = ($last_level_closed == $key) ? " checked" : "";
479 echo " <input type='radio' name='form_done' value='$key'$checked />$value&nbsp;\n";
482 </td>
483 <?php
484 echo "<td>\n";
485 echo xl('Check/EOB No.:');
486 echo "</td>\n";
487 echo "<td>\n";
488 echo "<input type='text' name='form_reference' size='10' value='' />\n";
489 echo "</td>\n";
491 </tr>
493 <tr>
494 <td>
495 <?php xl('Last Bill Date:', 'e') ?>
496 </td>
497 <td>
498 <?php
499 echo $billdate;
501 </td>
502 <td colspan="2">
503 <?php xl('Now posting for:', 'e', '', "&nbsp")?>;
505 <?php
506 // TBD: check the first not-done-with insurance, not always Ins1!
508 <input type='radio' name='form_insurance' value='Ins1' onclick='setins("Ins1")' checked /><?php xl('Ins1', 'e')?>&nbsp;
509 <input type='radio' name='form_insurance' value='Ins2' onclick='setins("Ins2")' /><?php xl('Ins2', 'e')?>&nbsp;
510 <input type='radio' name='form_insurance' value='Ins3' onclick='setins("Ins3")' /><?php xl('Ins3', 'e')?>&nbsp;
511 <input type='radio' name='form_insurance' value='Pt' onclick='setins("Pt")' /><?php xl('Patient', 'e')?>
513 <?php
514 // TBD: I think the following is unused and can be removed.
516 <input type='hidden' name='form_eobs' value='<?php echo addslashes($arrow['shipvia']) ?>' />
518 </td>
519 <?php
520 echo "<td>\n";
521 echo xl('Check/EOB Date:');
522 echo "</td>\n";
523 echo "<td>\n";
524 echo "<input type='text' name='form_check_date' size='10' value='' />\n";
525 echo "</td>\n";
527 </tr>
528 <tr>
529 <td>
530 </td>
531 <td>
532 </td>
533 <td colspan="2">
534 <input type="checkbox" name="form_secondary" value="1"> <?php xl('Needs secondary billing', 'e')?>
535 &nbsp;&nbsp;
536 <input type='submit' name='form_save' value='<?php xl('Save', 'e')?>'>
537 &nbsp;
538 <input type='button' value='<?php xl('Cancel', 'e')?>' onclick='window.close()'>
539 </td>
540 <?php
541 echo "<td>\n";
542 echo xl('Deposit Date:');
543 echo "</td>\n";
544 echo "<td>\n";
545 echo "<input type='text' name='form_deposit_date' size='10' value='' />\n";
546 echo "<input type='hidden' name='form_payer_id' value='' />\n";
547 echo "<input type='hidden' name='form_orig_reference' value='' />\n";
548 echo "<input type='hidden' name='form_orig_check_date' value='' />\n";
549 echo "<input type='hidden' name='form_orig_deposit_date' value='' />\n";
550 echo "<input type='hidden' name='form_pay_total' value='' />\n";
551 echo "</td>\n";
553 </tr>
554 <?php if (!empty($pdrow['billing_note'])) { ?>
555 <tr>
556 <td>
557 <?php xl('Billing Note:', 'e')?>
558 </td>
559 <td colspan='3' style='color:red'>
560 <?php echo $pdrow['billing_note'] ?>
561 </td>
562 </tr>
563 <?php } ?>
564 <tr>
565 <td height="1">
566 </td>
567 </tr>
568 </table>
570 <table border='0' cellpadding='2' cellspacing='0' width='98%'>
572 <tr bgcolor="#cccccc">
573 <td class="dehead">
574 <?php xl('Code', 'e')?>
575 </td>
576 <td class="dehead" align="right">
577 <?php xl('Charge', 'e')?>
578 </td>
579 <td class="dehead" align="right">
580 <?php xl('Balance', 'e')?>&nbsp;
581 </td>
582 <td class="dehead">
583 <?php xl('By/Source', 'e')?>
584 </td>
585 <td class="dehead">
586 <?php xl('Date', 'e')?>
587 </td>
588 <td class="dehead">
589 <?php xl('Pay', 'e')?>
590 </td>
591 <td class="dehead">
592 <?php xl('Adjust', 'e')?>
593 </td>
594 <td class="dehead">
595 <?php xl('Reason', 'e')?>
596 </td>
597 <?php if ($ALLOW_DELETE) { ?>
598 <td class="dehead">
599 <?php xl('Del', 'e')?>
600 </td>
601 <?php } ?>
602 </tr>
603 <?php
604 $firstProcCodeIndex = -1;
605 $encount = 0;
606 foreach ($codes as $code => $cdata) {
607 ++$encount;
608 $bgcolor = "#" . (($encount & 1) ? "ddddff" : "ffdddd");
609 $dispcode = $code;
611 // remember the index of the first entry whose code is not "CO-PAY", i.e. it's a legitimate proc code
612 if ($firstProcCodeIndex == -1 && strcmp($code, "CO-PAY") !=0) {
613 $firstProcCodeIndex = $encount;
616 // this sorts the details more or less chronologically:
617 ksort($cdata['dtl']);
618 foreach ($cdata['dtl'] as $dkey => $ddata) {
619 $ddate = substr($dkey, 0, 10);
620 if (preg_match('/^(\d\d\d\d)(\d\d)(\d\d)\s*$/', $ddate, $matches)) {
621 $ddate = $matches[1] . '-' . $matches[2] . '-' . $matches[3];
624 $tmpchg = "";
625 $tmpadj = "";
626 /*****************************************************************
627 if ($ddata['chg'] > 0)
628 $tmpchg = $ddata['chg'];
629 else if ($ddata['chg'] < 0)
630 $tmpadj = 0 - $ddata['chg'];
631 *****************************************************************/
632 if ($ddata['chg'] != 0) {
633 if (isset($ddata['rsn'])) {
634 $tmpadj = 0 - $ddata['chg'];
635 } else {
636 $tmpchg = $ddata['chg'];
640 <tr bgcolor='<?php echo $bgcolor ?>'>
641 <td class="detail">
642 <?php echo $dispcode; $dispcode = "" ?>
643 </td>
644 <td class="detail" align="right">
645 <?php bucks($tmpchg) ?>
646 </td>
647 <td class="detail" align="right">
648 &nbsp;
649 </td>
650 <td class="detail">
651 <?php
652 if (isset($ddata['plv'])) {
653 if (!$ddata['plv']) {
654 echo 'Pt/';
655 } else {
656 echo 'Ins' . $ddata['plv'] . '/';
660 echo $ddata['src'];
662 </td>
663 <td class="detail">
664 <?php echo $ddate ?>
665 </td>
666 <td class="detail">
667 <?php bucks($ddata['pmt']) ?>
668 </td>
669 <td class="detail">
670 <?php bucks($tmpadj) ?>
671 </td>
672 <td class="detail">
673 <?php echo $ddata['rsn'] ?>
674 </td>
675 <?php if ($ALLOW_DELETE) { ?>
676 <td class="detail">
677 <?php if (!empty($ddata['arseq'])) { ?>
678 <input type="checkbox" name="form_del[<?php echo $ddata['arseq']; ?>]" />
679 <?php } else { ?>
680 &nbsp;
681 <?php } ?>
682 </td>
683 <?php } ?>
684 </tr>
685 <?php
686 } // end of prior detail line
688 <tr bgcolor='<?php echo $bgcolor ?>'>
689 <td class="detail">
690 <?php echo $dispcode; $dispcode = "" ?>
691 </td>
692 <td class="detail" align="right">
693 &nbsp;
694 </td>
695 <td class="detail" align="right">
696 <input type="hidden" name="form_line[<?php echo $code ?>][bal]" value="<?php bucks($cdata['bal']) ?>">
697 <input type="hidden" name="form_line[<?php echo $code ?>][ins]" value="<?php echo $cdata['ins'] ?>">
698 <input type="hidden" name="form_line[<?php echo $code ?>][code_type]" value="<?php echo $cdata['code_type'] ?>">
699 <?php printf("%.2f", $cdata['bal']) ?>&nbsp;
700 </td>
701 <td class="detail">
704 </td>
705 <td class="detail">
708 </td>
709 <td class="detail">
710 <input type="text" name="form_line[<?php echo $code ?>][pay]" size="10"
711 style="background-color:<?php echo $bgcolor ?>"
712 onKeyUp="updateFields(document.forms[0]['form_line[<?php echo $code ?>][pay]'],
713 document.forms[0]['form_line[<?php echo $code ?>][adj]'],
714 document.forms[0]['form_line[<?php echo $code ?>][bal]'],
715 document.forms[0]['form_line[CO-PAY][bal]'],
716 <?php echo ($firstProcCodeIndex == $encount) ? 1 : 0 ?>)"/>
717 </td>
718 <td class="detail">
719 <input type="text" name="form_line[<?php echo $code ?>][adj]" size="10"
720 value='<?php echo $totalAdjAmount ?>'
721 style="background-color:<?php echo $bgcolor ?>" />
722 &nbsp; <a href="" onclick="return writeoff('<?php echo $code ?>')">W</a>
723 </td>
724 <td class="detail">
725 <select name="form_line[<?php echo $code ?>][reason]"
726 style="background-color:<?php echo $bgcolor ?>">
727 <?php
728 // Adjustment reasons are now taken from the list_options table.
729 echo " <option value=''></option>\n";
730 $ores = sqlStatement("SELECT option_id, title, is_default FROM list_options " .
731 "WHERE list_id = 'adjreason' AND activity = 1 ORDER BY seq, title");
732 while ($orow = sqlFetchArray($ores)) {
733 echo " <option value='" . htmlspecialchars($orow['option_id'], ENT_QUOTES) . "'";
734 if ($orow['is_default']) {
735 echo " selected";
738 echo ">" . htmlspecialchars($orow['title']) . "</option>\n";
742 </select>
743 <?php
744 // TBD: Maybe a comment field would be good here, for appending
745 // to the reason.
747 </td>
749 <?php if ($ALLOW_DELETE) { ?>
750 <td class="detail">
751 &nbsp;
752 </td>
753 <?php } ?>
755 </tr>
756 <?php
757 } // end of code
760 </table>
761 </form>
762 </center>
763 <script language="JavaScript">
764 var f1 = opener.document.forms[0];
765 var f2 = document.forms[0];
766 if (f1.form_source) {
767 <?php
768 // These support creation and lookup of ar_session table entries:
769 echo " f2.form_reference.value = f1.form_source.value;\n";
770 echo " f2.form_check_date.value = f1.form_paydate.value;\n";
771 echo " //f2.form_deposit_date.value = f1.form_deposit_date.value;\n";
772 echo " if (f1.form_deposit_date.value != '')\n";
773 echo " f2.form_deposit_date.value = f1.form_deposit_date.value;\n";
774 echo " else\n";
775 echo " f2.form_deposit_date.value = getFormattedToday();\n";
776 echo " f2.form_payer_id.value = f1.form_payer_id.value;\n";
777 echo " f2.form_pay_total.value = f1.form_amount.value;\n";
778 echo " f2.form_orig_reference.value = f1.form_source.value;\n";
779 echo " f2.form_orig_check_date.value = f1.form_paydate.value;\n";
780 echo " f2.form_orig_deposit_date.value = f1.form_deposit_date.value;\n";
782 // While I'm thinking about it, some notes about eob sessions.
783 // If they do not have all of the session key fields in the search
784 // page, then show a warning at the top of the invoice page.
785 // Also when they go to save the invoice page and a session key
786 // field has changed, alert them to that and allow a cancel.
788 // Another point... when posting EOBs, the incoming payer ID might
789 // not match the payer ID for the patient's insurance. This is
790 // because the same payer might be entered more than once into the
791 // insurance_companies table. I don't think it matters much.
794 setins("Ins1");
795 </script>
796 </body>
797 </html>