2 // Copyright (C) 2005-2010 Rod Roark <rod@sunsetsystems.com>
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
9 // This provides for manual posting of EOBs. It is invoked from
10 // sl_eob_search.php. For automated (X12 835) remittance posting
11 // see sl_eob_process.php.
13 require_once("../globals.php");
14 require_once("$srcdir/log.inc");
15 require_once("$srcdir/patient.inc");
16 require_once("$srcdir/forms.inc");
17 require_once("$srcdir/sl_eob.inc.php");
18 require_once("$srcdir/invoice_summary.inc.php");
19 require_once("../../custom/code_types.inc.php");
20 require_once("$srcdir/formdata.inc.php");
22 $debug = 0; // set to 1 for debugging mode
24 $INTEGRATED_AR = $GLOBALS['oer_config']['ws_accounting']['enabled'] === 2;
26 // If we permit deletion of transactions. Might change this later.
27 $ALLOW_DELETE = $INTEGRATED_AR;
31 // Format money for display.
33 function bucks($amount) {
35 printf("%.2f", $amount);
38 // Delete rows, with logging, for the specified table using the
39 // specified WHERE clause. Borrowed from deleter.php.
41 function row_delete($table, $where) {
42 $tres = sqlStatement("SELECT * FROM $table WHERE $where");
44 while ($trow = sqlFetchArray($tres)) {
46 foreach ($trow as $key => $value) {
47 if (! $value ||
$value == '0000-00-00 00:00:00') continue;
48 if ($logstring) $logstring .= " ";
49 $logstring .= $key . "='" . addslashes($value) . "'";
51 newEvent("delete", $_SESSION['authUser'], $_SESSION['authProvider'], 1, "$table: $logstring");
55 $query = "DELETE FROM $table WHERE $where";
56 echo $query . "<br>\n";
63 <?php
html_header_show(); ?
>
64 <link rel
=stylesheet href
="<?php echo $css_header;?>" type
="text/css">
65 <title
><?php
xl('EOB Posting - Invoice','e')?
></title
>
66 <script language
="JavaScript">
68 // An insurance radio button is selected.
69 function setins(istr
) {
70 <?php
if (!$INTEGRATED_AR) { ?
>
71 var f
= document
.forms
[0];
72 for (var i
= 0; i
< f
.elements
.length
; ++i
) {
73 var ename
= f
.elements
[i
].name
;
74 if (ename
.indexOf('[src]') < 0) continue;
75 var evalue
= f
.elements
[i
].value
;
76 var tmp
= evalue
.substring(0, 4).toLowerCase();
77 if (tmp
>= 'ins1' && tmp
<= 'ins3')
78 evalue
= evalue
.substring(4);
79 else if (evalue
.substring(0, 2).toLowerCase() == 'pt')
80 evalue
= evalue
.substring(2);
81 while (evalue
.substring(0, 1) == '/')
82 evalue
= evalue
.substring(1);
83 f
.elements
[i
].value
= istr +
'/' + evalue
;
89 // Compute an adjustment that writes off the balance:
90 function writeoff(code
) {
91 var f
= document
.forms
[0];
92 var belement
= f
['form_line[' + code +
'][bal]'];
93 var pelement
= f
['form_line[' + code +
'][pay]'];
94 var aelement
= f
['form_line[' + code +
'][adj]'];
95 var relement
= f
['form_line[' + code +
'][reason]'];
96 var tmp
= belement
.value
- pelement
.value
;
97 aelement
.value
= Number(tmp
).toFixed(2);
98 if (aelement
.value
&& ! relement
.value
) relement
.selectedIndex
= 1;
102 // Onsubmit handler. A good excuse to write some JavaScript.
103 function validate(f
) {
105 for (var i
= 0; i
< f
.elements
.length
; ++i
) {
106 var ename
= f
.elements
[i
].name
;
108 if (ename
.substring(0, 9) == 'form_del[') {
109 if (f
.elements
[i
].checked
) ++delcount
;
112 var pfxlen
= ename
.indexOf('[pay]');
113 if (pfxlen
< 0) continue;
114 var pfx
= ename
.substring(0, pfxlen
);
115 var code
= pfx
.substring(pfx
.indexOf('[')+
1, pfxlen
-1);
116 if (f
[pfx+
'[pay]'].value || f
[pfx+
'[adj]'].value
) {
117 <?php
if (!$INTEGRATED_AR) { // source validation not appropriate ?>
118 var srcobj
= f
[pfx+
'[src]'];
119 while (srcobj
.value
.length
) {
120 var tmp
= srcobj
.value
.substring(srcobj
.value
.length
- 1);
121 if (tmp
> ' ' && tmp
!= '/') break;
122 srcobj
.value
= srcobj
.value
.substring(0, srcobj
.value
.length
- 1);
124 var svalue
= srcobj
.value
;
126 alert('<?php xl('Source is missing
for code
','e
') ?>' + code
);
129 var tmp
= svalue
.substring(0, 4).toLowerCase();
130 if (tmp
>= 'ins1' && tmp
<= 'ins3') {
131 svalue
= svalue
.substring(4);
132 } else if (svalue
.substring(0, 2).toLowerCase() == 'pt') {
133 svalue
= svalue
.substring(2);
135 alert('<?php xl('Invalid
or missing payer in source
for code
','e
')?>' + code
);
139 if (svalue
.substring(0, 1) != '/') {
140 alert('<?php xl('Missing slash after payer in source
for code
','e
')?>' + code
);
143 if (false) { // Please keep this, Oakland Clinic wants it. -- Rod
144 tmp
= svalue
.substring(1, 3).toLowerCase();
145 if (tmp
!= 'nm' && tmp
!= 'ci' && tmp
!= 'cp' && tmp
!= 'ne' &&
146 tmp
!= 'it' && tmp
!= 'pf' && tmp
!= 'pp' && tmp
!= 'ok')
148 alert('<?php xl('Invalid source designation
"','e') ?>' + tmp + '<?php xl('" for code
','e
') ?>' + code
);
155 if (! f
[pfx+
'[date]'].value
) {
156 alert('<?php xl('Date is missing
for code
','e
')?>' + code
);
160 if (f
[pfx+
'[pay]'].value
&& isNaN(parseFloat(f
[pfx+
'[pay]'].value
))) {
161 alert('<?php xl('Payment value
for code
','e
') ?>' + code +
'<?php xl(' is not a number
','e
') ?>');
164 if (f
[pfx+
'[adj]'].value
&& isNaN(parseFloat(f
[pfx+
'[adj]'].value
))) {
165 alert('<?php xl('Adjustment value
for code
','e
') ?>' + code +
'<?php xl(' is not a number
','e
') ?>');
168 if (f
[pfx+
'[adj]'].value
&& ! f
[pfx+
'[reason]'].value
) {
169 alert('<?php xl('Please select an adjustment reason
for code
','e
') ?>' + code
);
172 // TBD: validate the date format
174 // Demand confirmation if deleting anything.
176 if (!confirm('<?php echo xl('Really delete
'); ?> ' + delcount +
177 ' <?php echo xl('transactions
'); ?>?' +
178 ' <?php echo xl('This action will be logged
'); ?>!')
184 <!-- Get current date
-->
186 function getFormattedToday()
188 var today
= new Date();
189 var dd
= today
.getDate();
190 var mm
= today
.getMonth()+
1; //January is 0!
191 var yyyy
= today
.getFullYear();
195 return (yyyy +
'-' + mm +
'-' + dd
);
198 <!-- Update Payment Fields
-->
200 function updateFields(payField
, adjField
, balField
, coPayField
, isFirstProcCode
)
205 var coPayAmount
= 0.0;
207 // coPayFiled will be null if there is no co-pay entry in the fee sheet
209 coPayAmount
= coPayField
.value
;
211 // if balance field is 0.00, its value comes back as null, so check for nul-ness first
213 balAmount
= (balField
.value
) ? balField
.value
: 0;
215 payAmount
= (payField
.value
) ? payField
.value
: 0;
217 //alert('balance = >' + balAmount +'< payAmount = ' + payAmount + ' copay = ' + coPayAmount + ' isFirstProcCode = ' + isFirstProcCode);
219 // subtract the co-pay only from the first procedure code
220 if (isFirstProcCode
== 1)
221 balAmount
= parseFloat(balAmount
) +
parseFloat(coPayAmount
);
223 adjAmount
= balAmount
- payAmount
;
225 // Assign rounded adjustment value back to TextField
226 adjField
.value
= adjAmount
= Math
.round(adjAmount
*100)/100;
231 <body leftmargin
='0' topmargin
='0' marginwidth
='0' marginheight
='0'>
233 $trans_id = 0 +
$_GET['id'];
234 if (! $trans_id) die(xl("You cannot access this page directly."));
236 if ($INTEGRATED_AR) {
237 // In the Integrated A/R case, $trans_id matches form_encounter.id.
238 $ferow = sqlQuery("SELECT e.*, p.fname, p.mname, p.lname " .
239 "FROM form_encounter AS e, patient_data AS p WHERE " .
240 "e.id = '$trans_id' AND p.pid = e.pid");
241 if (empty($ferow)) die("There is no encounter with form_encounter.id = '$trans_id'.");
242 $patient_id = 0 +
$ferow['pid'];
243 $encounter_id = 0 +
$ferow['encounter'];
244 $svcdate = substr($ferow['date'], 0, 10);
245 $form_payer_id = 0 +
$_POST['form_payer_id'];
246 $form_reference = $_POST['form_reference'];
247 $form_check_date = fixDate($_POST['form_check_date'], date('Y-m-d'));
248 $form_deposit_date = fixDate($_POST['form_deposit_date'], $form_check_date);
249 $form_pay_total = 0 +
$_POST['form_pay_total'];
256 if (preg_match('/^Ins(\d)/i', $_POST['form_insurance'], $matches)) {
257 $payer_type = $matches[1];
260 if ($_POST['form_save'] ||
$_POST['form_cancel']) {
261 if ($_POST['form_save']) {
263 echo xl("This module is in test mode. The database will not be changed.",'','<p><b>',"</b><p>\n");
266 if ($INTEGRATED_AR) {
267 $session_id = arGetSession($form_payer_id, $form_reference,
268 $form_check_date, $form_deposit_date, $form_pay_total);
269 // The sl_eob_search page needs its invoice links modified to invoke
270 // javascript to load form parms for all the above and submit.
271 // At the same time that page would be modified to work off the
272 // openemr database exclusively.
273 // And back to the sl_eob_invoice page, I think we may want to move
274 // the source input fields from row level to header level.
276 // Handle deletes. row_delete() is borrowed from deleter.php.
277 if ($ALLOW_DELETE && !$debug) {
278 foreach ($_POST['form_del'] as $arseq => $dummy) {
279 row_delete("ar_activity", "pid = '$patient_id' AND " .
280 "encounter = '$encounter_id' AND sequence_no = '$arseq'");
286 foreach ($_POST['form_line'] as $code => $cdata) {
287 if (!$INTEGRATED_AR) {
288 $thissrc = trim($cdata['src']);
289 $thisdate = trim($cdata['date']);
291 $thispay = trim($cdata['pay']);
292 $thisadj = trim($cdata['adj']);
293 $thisins = trim($cdata['ins']);
294 $reason = strip_escape_custom($cdata['reason']);
296 // Get the adjustment reason type. Possible values are:
297 // 1 = Charge adjustment
304 $tmp = sqlQuery("SELECT option_value FROM list_options WHERE " .
305 "list_id = 'adjreason' AND " .
306 "option_id = '" . add_escape_custom($reason) . "'");
307 if (empty($tmp['option_value'])) {
308 // This should not happen but if it does, apply old logic.
309 if (preg_match("/To copay/", $reason)) {
312 else if (preg_match("/To ded'ble/", $reason)) {
315 $info_msg .= xl("No adjustment reason type found for") . " \"$reason\". ";
318 $reason_type = $tmp['option_value'];
322 if (! $thisins) $thisins = 0;
325 if ($INTEGRATED_AR) {
326 arPostPayment($patient_id, $encounter_id, $session_id,
327 $thispay, $code, $payer_type, '', $debug);
329 slPostPayment($trans_id, $thispay, $thisdate, $thissrc, $code, $thisins, $debug);
331 $paytotal +
= $thispay;
334 // Be sure to record adjustment reasons, even for zero adjustments if
335 // they happen to be comments.
336 if ($thisadj ||
($reason && $reason_type == 5)) {
337 // "To copay" and "To ded'ble" need to become a comment in a zero
338 // adjustment, formatted just like sl_eob_process.php.
339 if ($reason_type == '2') {
340 $reason = $_POST['form_insurance'] . " coins: $thisadj";
343 else if ($reason_type == '3') {
344 $reason = $_POST['form_insurance'] . " dedbl: $thisadj";
347 else if ($reason_type == '4') {
348 $reason = $_POST['form_insurance'] . " ptresp: $thisadj $reason";
351 else if ($reason_type == '5') {
352 $reason = $_POST['form_insurance'] . " note: $thisadj $reason";
356 // An adjustment reason including "Ins" is assumed to be assigned by
357 // insurance, and in that case we identify which one by appending
358 // Ins1, Ins2 or Ins3.
359 if (strpos(strtolower($reason), 'ins') !== false)
360 $reason .= ' ' . $_POST['form_insurance'];
362 if ($INTEGRATED_AR) {
363 arPostAdjustment($patient_id, $encounter_id, $session_id,
364 $thisadj, $code, $payer_type, $reason, $debug);
366 slPostAdjustment($trans_id, $thisadj, $thisdate, $thissrc, $code, $thisins, $reason, $debug);
371 // Maintain which insurances are marked as finished.
373 if ($INTEGRATED_AR) {
374 $form_done = 0 +
$_POST['form_done'];
375 $form_stmt_count = 0 +
$_POST['form_stmt_count'];
376 sqlStatement("UPDATE form_encounter " .
377 "SET last_level_closed = $form_done, " .
378 "stmt_count = $form_stmt_count WHERE " .
379 "pid = '$patient_id' AND encounter = '$encounter_id'");
382 $form_duedate = fixDate($_POST['form_duedate']);
383 $form_notes = trim($_POST['form_notes']);
384 // We use the "Ship Via" field of the invoice to hold these.
386 foreach (array('Ins1', 'Ins2', 'Ins3') as $value) {
387 if ($_POST["form_done_$value"]) {
388 if ($form_eobs) $form_eobs .= ","; else $form_eobs = "Done: ";
389 $form_eobs .= $value;
392 $query = "UPDATE ar SET duedate = '$form_duedate', notes = '$form_notes', " .
393 "shipvia = '$form_eobs' WHERE id = $trans_id";
395 echo $query . "<br>\n";
398 if ($sl_err) die($sl_err);
402 if ($_POST['form_secondary']) {
403 if ($INTEGRATED_AR) {
404 arSetupSecondary($patient_id, $encounter_id, $debug);
406 slSetupSecondary($trans_id, $debug);
410 echo "<script language='JavaScript'>\n";
411 echo " if (opener.document.forms[0].form_amount) {\n";
412 echo " var tmp = opener.document.forms[0].form_amount.value - $paytotal;\n";
413 echo " opener.document.forms[0].form_amount.value = Number(tmp).toFixed(2);\n";
416 echo "<script language='JavaScript'>\n";
418 if ($info_msg) echo " alert('" . addslashes($info_msg) . "');\n";
419 if (! $debug) echo " window.close();\n";
420 echo "</script></body></html>\n";
421 if (!$INTEGRATED_AR) SLClose();
425 if ($INTEGRATED_AR) {
426 // Get invoice charge details.
427 $codes = ar_get_invoice_summary($patient_id, $encounter_id, true);
430 // Get invoice data into $arrow.
431 $arres = SLQuery("select ar.*, customer.name, employee.name as doctor " .
432 "from ar, customer, employee where ar.id = $trans_id and " .
433 "customer.id = ar.customer_id and employee.id = ar.employee_id");
434 if ($sl_err) die($sl_err);
435 $arrow = SLGetRow($arres, 0);
436 if (! $arrow) die(xl("There is no match for invoice id = ") . $trans_id);
438 // Determine the date of service. An 8-digit encounter number is
439 // presumed to be a date of service imported during conversion.
440 // Otherwise look it up in the form_encounter table.
443 list($patient_id, $encounter) = explode(".", $arrow['invnumber']);
444 if (strlen($encounter) == 8) {
445 $svcdate = substr($encounter, 0, 4) . "-" . substr($encounter, 4, 2) .
446 "-" . substr($encounter, 6, 2);
448 else if ($encounter) {
449 $tmp = sqlQuery("SELECT date FROM form_encounter WHERE " .
450 "encounter = $encounter");
451 $svcdate = substr($tmp['date'], 0, 10);
454 // Get invoice charge details.
455 $codes = get_invoice_summary($trans_id, true);
458 $pdrow = sqlQuery("select genericname2, genericval2 " .
459 "from patient_data where pid = '$patient_id' limit 1");
463 <form method
='post' action
='sl_eob_invoice.php?id=<?php echo $trans_id ?>'
464 onsubmit
='return validate(this)'>
466 <table border
='0' cellpadding
='3'>
469 <?php
xl('Patient:','e')?
>
473 if ($INTEGRATED_AR) {
474 echo $ferow['fname'] . ' ' . $ferow['mname'] . ' ' . $ferow['lname'];
481 <td colspan
="2" rowspan
="3">
483 if ($INTEGRATED_AR) {
484 for ($i = 1; $i <= 3; ++
$i) {
485 $payerid = arGetPayerID($patient_id, $svcdate, $i);
487 $tmp = sqlQuery("SELECT name FROM insurance_companies WHERE id = $payerid");
488 echo "Ins$i: " . $tmp['name'] . "<br />";
493 echo " <textarea name='form_notes' cols='50' style='height:100%'>";
494 echo $arrow['notes'];
495 echo "</textarea>\n";
500 if ($INTEGRATED_AR) {
501 echo "<td rowspan='3' valign='bottom'>\n";
502 echo xl('Statements Sent:');
504 echo "<td rowspan='3' valign='bottom'>\n";
505 echo "<input type='text' name='form_stmt_count' size='10' value='" .
506 (0 +
$ferow['stmt_count']) . "' />\n";
513 <?php
xl('Provider:','e')?
>
517 if ($INTEGRATED_AR) {
518 $tmp = sqlQuery("SELECT fname, mname, lname " .
519 "FROM users WHERE id = " . $ferow['provider_id']);
520 echo $tmp['fname'] . ' ' . $tmp['mname'] . ' ' . $tmp['lname'];
521 $tmp = sqlQuery("SELECT bill_date FROM billing WHERE " .
522 "pid = '$patient_id' AND encounter = '$encounter_id' AND " .
523 "activity = 1 ORDER BY fee DESC, id ASC LIMIT 1");
524 $billdate = substr(($tmp['bill_date'] . "Not Billed"), 0, 10);
527 echo $arrow['doctor'];
534 <?php
xl('Invoice:','e')?
>
538 if ($INTEGRATED_AR) {
539 echo "$patient_id.$encounter_id";
542 echo $arrow['invnumber'];
550 <?php
xl('Svc Date:','e'); ?
>
558 <?php
xl('Done with:','e',''," ")?
>;
560 // Write a checkbox for each insurance. It is to be checked when
561 // we no longer expect any payments from that company for the claim.
562 if ($INTEGRATED_AR) {
563 $last_level_closed = 0 +
$ferow['last_level_closed'];
564 foreach (array(0 => 'None', 1 => 'Ins1', 2 => 'Ins2', 3 => 'Ins3') as $key => $value) {
565 if ($key && !arGetPayerID($patient_id, $svcdate, $key)) continue;
566 $checked = ($last_level_closed == $key) ?
" checked" : "";
567 echo " <input type='radio' name='form_done' value='$key'$checked />$value \n";
571 // The information is stored in the 'shipvia' field of the invoice.
572 $insgot = strtolower($arrow['notes']);
573 $insdone = strtolower($arrow['shipvia']);
574 foreach (array('Ins1', 'Ins2', 'Ins3') as $value) {
575 $lcvalue = strtolower($value);
576 $checked = (strpos($insdone, $lcvalue) === false) ?
"" : " checked";
577 if (strpos($insgot, $lcvalue) !== false) {
578 echo " <input type='checkbox' name='form_done_$value' value='1'$checked />$value \n";
585 if ($INTEGRATED_AR) {
587 echo xl('Check/EOB No.:');
590 echo "<input type='text' name='form_reference' size='10' value='' />\n";
598 <?php
xl('Last Bill Date:','e') ?
>
602 if ($INTEGRATED_AR) {
606 echo $arrow['transdate'];
611 <?php
xl('Now posting for:','e',''," ")?
>;
614 // TBD: check the first not-done-with insurance, not always Ins1!
616 <input type
='radio' name
='form_insurance' value
='Ins1' onclick
='setins("Ins1")' checked
/><?php
xl('Ins1','e')?
> 
;
617 <input type
='radio' name
='form_insurance' value
='Ins2' onclick
='setins("Ins2")' /><?php
xl('Ins2','e')?
> 
;
618 <input type
='radio' name
='form_insurance' value
='Ins3' onclick
='setins("Ins3")' /><?php
xl('Ins3','e')?
> 
;
619 <input type
='radio' name
='form_insurance' value
='Pt' onclick
='setins("Pt")' /><?php
xl('Patient','e')?
>
622 // TBD: I think the following is unused and can be removed.
624 <input type
='hidden' name
='form_eobs' value
='<?php echo addslashes($arrow['shipvia
']) ?>' />
628 if ($INTEGRATED_AR) {
630 echo xl('Check/EOB Date:');
633 echo "<input type='text' name='form_check_date' size='10' value='' />\n";
641 if (!$INTEGRATED_AR) xl('Due Date:','e');
646 <?php
if (!$INTEGRATED_AR) { ?
>
647 <input type
='text' name
='form_duedate' size
='10' value
='<?php echo $arrow['duedate
'] ?>'
648 title
='<?php xl('Due date mm
/dd
/yyyy
or yyyy
-mm
-dd
','e
')?>'>
652 <input type
="checkbox" name
="form_secondary" value
="1"> <?php
xl('Needs secondary billing','e')?
>
654 <input type
='submit' name
='form_save' value
='<?php xl('Save
','e
')?>'>
656 <input type
='button' value
='<?php xl('Cancel
','e
')?>' onclick
='window.close()'>
659 if ($INTEGRATED_AR) {
661 echo xl('Deposit Date:');
664 echo "<input type='text' name='form_deposit_date' size='10' value='' />\n";
665 echo "<input type='hidden' name='form_payer_id' value='' />\n";
666 echo "<input type='hidden' name='form_orig_reference' value='' />\n";
667 echo "<input type='hidden' name='form_orig_check_date' value='' />\n";
668 echo "<input type='hidden' name='form_orig_deposit_date' value='' />\n";
669 echo "<input type='hidden' name='form_pay_total' value='' />\n";
674 <?php
if ($pdrow['genericname2'] == 'Billing') { ?
>
677 <?php
xl('Billing Note:','e')?
>
679 <td colspan
='3' style
='color:red'>
680 <?php
echo $pdrow['genericval2'] ?
>
690 <table border
='0' cellpadding
='2' cellspacing
='0' width
='98%'>
692 <tr bgcolor
="#cccccc">
694 <?php
xl('Code','e')?
>
696 <td
class="dehead" align
="right">
697 <?php
xl('Charge','e')?
>
699 <td
class="dehead" align
="right">
700 <?php
xl('Balance','e')?
> 
;
703 <?php
xl('By/Source','e')?
>
706 <?php
xl('Date','e')?
>
709 <?php
xl('Pay','e')?
>
712 <?php
xl('Adjust','e')?
>
715 <?php
xl('Reason','e')?
>
717 <?php
if ($ALLOW_DELETE) { ?
>
719 <?php
xl('Del','e')?
>
724 $firstProcCodeIndex = -1;
726 foreach ($codes as $code => $cdata) {
728 $bgcolor = "#" . (($encount & 1) ?
"ddddff" : "ffdddd");
731 // remember the index of the first entry whose code is not "CO-PAY", i.e. it's a legitimate proc code
732 if ($firstProcCodeIndex == -1 && strcmp($code, "CO-PAY") !=0)
733 $firstProcCodeIndex = $encount;
735 // this sorts the details more or less chronologically:
736 ksort($cdata['dtl']);
737 foreach ($cdata['dtl'] as $dkey => $ddata) {
738 $ddate = substr($dkey, 0, 10);
739 if (preg_match('/^(\d\d\d\d)(\d\d)(\d\d)\s*$/', $ddate, $matches)) {
740 $ddate = $matches[1] . '-' . $matches[2] . '-' . $matches[3];
744 /*****************************************************************
745 if ($ddata['chg'] > 0)
746 $tmpchg = $ddata['chg'];
747 else if ($ddata['chg'] < 0)
748 $tmpadj = 0 - $ddata['chg'];
749 *****************************************************************/
750 if ($ddata['chg'] != 0) {
751 if (isset($ddata['rsn'])) $tmpadj = 0 - $ddata['chg'];
752 else $tmpchg = $ddata['chg'];
755 <tr bgcolor
='<?php echo $bgcolor ?>'>
757 <?php
echo $dispcode; $dispcode = "" ?
>
759 <td
class="detail" align
="right">
760 <?php
bucks($tmpchg) ?
>
762 <td
class="detail" align
="right">
767 if (isset($ddata['plv'])) {
768 if (!$ddata['plv']) echo 'Pt/';
769 else echo 'Ins' . $ddata['plv'] . '/';
778 <?php
bucks($ddata['pmt']) ?
>
781 <?php
bucks($tmpadj) ?
>
784 <?php
echo $ddata['rsn'] ?
>
786 <?php
if ($ALLOW_DELETE) { ?
>
788 <?php
if (!empty($ddata['arseq'])) { ?
>
789 <input type
="checkbox" name
="form_del[<?php echo $ddata['arseq']; ?>]" />
797 } // end of prior detail line
799 <tr bgcolor
='<?php echo $bgcolor ?>'>
801 <?php
echo $dispcode; $dispcode = "" ?
>
803 <td
class="detail" align
="right">
806 <td
class="detail" align
="right">
807 <input type
="hidden" name
="form_line[<?php echo $code ?>][bal]" value
="<?php bucks($cdata['bal']) ?>">
808 <input type
="hidden" name
="form_line[<?php echo $code ?>][ins]" value
="<?php echo $cdata['ins'] ?>">
809 <?php
printf("%.2f", $cdata['bal']) ?
> 
;
813 <?php
if (!$INTEGRATED_AR) { ?
>
814 <input type
="text" name
="form_line[<?php echo $code ?>][src]" size
="10"
815 style
="background-color:<?php echo $bgcolor ?>" />
816 <!-- title
="NM=notmet, CI=coins, CP=copay, NE=notelig, IT=insterm, PF=ptfull, PP=ptpart" -->
822 <?php
if (!$INTEGRATED_AR) { ?
>
823 <input type
="text" name
="form_line[<?php echo $code ?>][date]" size
="10"
824 style
="background-color:<?php echo $bgcolor ?>" />
829 <input type
="text" name
="form_line[<?php echo $code ?>][pay]" size
="10"
830 style
="background-color:<?php echo $bgcolor ?>"
831 onKeyUp
="updateFields(document.forms[0]['form_line[<?php echo $code ?>][pay]'],
832 document.forms[0]['form_line[<?php echo $code ?>][adj]'],
833 document.forms[0]['form_line[<?php echo $code ?>][bal]'],
834 document.forms[0]['form_line[CO-PAY][bal]'],
835 <?php echo ($firstProcCodeIndex == $encount) ? 1 : 0 ?>)"/>
838 <input type
="text" name
="form_line[<?php echo $code ?>][adj]" size
="10"
839 value
='<?php echo $totalAdjAmount ?>'
840 style
="background-color:<?php echo $bgcolor ?>" />
841  
; <a href
="" onclick
="return writeoff('<?php echo $code ?>')">W
</a
>
844 <select name
="form_line[<?php echo $code ?>][reason]"
845 style
="background-color:<?php echo $bgcolor ?>">
847 // Adjustment reasons are now taken from the list_options table.
848 echo " <option value=''></option>\n";
849 $ores = sqlStatement("SELECT option_id, title, is_default FROM list_options " .
850 "WHERE list_id = 'adjreason' ORDER BY seq, title");
851 while ($orow = sqlFetchArray($ores)) {
852 echo " <option value='" . htmlspecialchars($orow['option_id'], ENT_QUOTES
) . "'";
853 if ($orow['is_default']) echo " selected";
854 echo ">" . htmlspecialchars($orow['title']) . "</option>\n";
860 // TBD: Maybe a comment field would be good here, for appending
865 <?php
if ($ALLOW_DELETE) { ?
>
874 if (!$INTEGRATED_AR) SLClose();
880 <script language
="JavaScript">
881 var f1
= opener
.document
.forms
[0];
882 var f2
= document
.forms
[0];
883 if (f1
.form_source
) {
885 if ($INTEGRATED_AR) {
886 // These support creation and lookup of ar_session table entries:
887 echo " f2.form_reference.value = f1.form_source.value;\n";
888 echo " f2.form_check_date.value = f1.form_paydate.value;\n";
889 echo " //f2.form_deposit_date.value = f1.form_deposit_date.value;\n";
890 echo " if (f1.form_deposit_date.value != '')\n";
891 echo " f2.form_deposit_date.value = f1.form_deposit_date.value;\n";
893 echo " f2.form_deposit_date.value = getFormattedToday();\n";
894 echo " f2.form_payer_id.value = f1.form_payer_id.value;\n";
895 echo " f2.form_pay_total.value = f1.form_amount.value;\n";
896 echo " f2.form_orig_reference.value = f1.form_source.value;\n";
897 echo " f2.form_orig_check_date.value = f1.form_paydate.value;\n";
898 echo " f2.form_orig_deposit_date.value = f1.form_deposit_date.value;\n";
900 // While I'm thinking about it, some notes about eob sessions.
901 // If they do not have all of the session key fields in the search
902 // page, then show a warning at the top of the invoice page.
903 // Also when they go to save the invoice page and a session key
904 // field has changed, alert them to that and allow a cancel.
906 // Another point... when posting EOBs, the incoming payer ID might
907 // not match the payer ID for the patient's insurance. This is
908 // because the same payer might be entered more than once into the
909 // insurance_companies table. I don't think it matters much.
912 foreach ($codes as $code => $cdata) {
913 echo " f2['form_line[$code][src]'].value = f1.form_source.value;\n";
914 echo " f2['form_line[$code][date]'].value = f1.form_paydate.value;\n";