Centralized formatting.inc.php include
[openemr.git] / interface / billing / sl_eob_search.php
blobe97aa873207850784209f54cc285ccedbfa7e43e
1 <?php
2 /**
3 * This the first of two pages to support posting of EOBs.
4 * The second is sl_eob_invoice.php.
5 * Windows compatibility and statement downloading:
6 * 2009 Bill Cernansky and Tony McCormick [mi-squared.com]
8 * Copyright (C) 2005-2010 Rod Roark <rod@sunsetsystems.com>
10 * LICENSE: This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://opensource.org/licenses/gpl-license.php>;.
21 * @package OpenEMR
22 * @author Rod Roark <rod@sunsetsystems.com>
23 * @author Roberto Vasquez <robertogagliotta@gmail.com>
24 * @link http://www.open-emr.org
26 require_once("../globals.php");
27 require_once("$srcdir/patient.inc");
28 require_once("$srcdir/invoice_summary.inc.php");
29 require_once("$srcdir/appointments.inc.php");
30 require_once($GLOBALS['OE_SITE_DIR'] . "/statement.inc.php");
31 require_once("$srcdir/parse_era.inc.php");
32 require_once("$srcdir/sl_eob.inc.php");
33 require_once("$srcdir/api.inc");
34 require_once("$srcdir/forms.inc");
35 require_once("$srcdir/../controllers/C_Document.class.php");
36 require_once("$srcdir/documents.php");
37 require_once("$srcdir/options.inc.php");
38 require_once("$srcdir/acl.inc");
40 $DEBUG = 0; // set to 0 for production, 1 to test
42 $alertmsg = '';
43 $where = '';
44 $eraname = '';
45 $eracount = 0;
47 // This is called back by parse_era() if we are processing X12 835's.
48 function era_callback(&$out) {
49 global $where, $eracount, $eraname;
50 // print_r($out); // debugging
51 ++$eracount;
52 // $eraname = $out['isa_control_number'];
53 $eraname = $out['gs_date'] . '_' . ltrim($out['isa_control_number'], '0') .
54 '_' . ltrim($out['payer_id'], '0');
55 list($pid, $encounter, $invnumber) = slInvoiceNumber($out);
57 if ($pid && $encounter) {
58 if ($where) $where .= ' OR ';
59 $where .= "( f.pid = '$pid' AND f.encounter = '$encounter' )";
63 function bucks($amount) {
64 if ($amount) echo oeFormatMoney($amount);
67 // Upload a file to the client's browser
69 function upload_file_to_client($file_to_send) {
70 header("Pragma: public");
71 header("Expires: 0");
72 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
73 header("Content-Type: application/force-download");
74 header("Content-Length: " . filesize($file_to_send));
75 header("Content-Disposition: attachment; filename=" . basename($file_to_send));
76 header("Content-Description: File Transfer");
77 readfile($file_to_send);
78 // flush the content to the browser. If you don't do this, the text from the subsequent
79 // output from this script will be in the file instead of sent to the browser.
80 flush();
81 exit(); //added to exit from process properly in order to stop bad html code -ehrlive
82 // sleep one second to ensure there's no follow-on.
83 sleep(1);
85 function upload_file_to_client_pdf($file_to_send) {
86 //Function reads a HTML file and converts to pdf.
88 global $STMT_TEMP_FILE_PDF;
89 global $srcdir;
91 if ($GLOBALS['statement_appearance'] == '1') {
92 require_once("$srcdir/html2pdf/vendor/autoload.php");
93 $pdf2 = new HTML2PDF ($GLOBALS['pdf_layout'],
94 $GLOBALS['pdf_size'],
95 $GLOBALS['pdf_language'],
96 true, // default unicode setting is true
97 'UTF-8', // default encoding setting is UTF-8
98 array($GLOBALS['pdf_left_margin'],$GLOBALS['pdf_top_margin'],$GLOBALS['pdf_right_margin'],$GLOBALS['pdf_bottom_margin']),
99 $_SESSION['language_direction'] == 'rtl' ? true : false
101 ob_start();
102 echo readfile($file_to_send, "r");//this file contains the HTML to be converted to pdf.
103 //echo $file;
104 $content = ob_get_clean();
106 // Fix a nasty html2pdf bug - it ignores document root!
107 global $web_root, $webserver_root;
108 $i = 0;
109 $wrlen = strlen($web_root);
110 $wsrlen = strlen($webserver_root);
111 while (true) {
112 $i = stripos($content, " src='/", $i + 1);
113 if ($i === false) break;
114 if (substr($content, $i+6, $wrlen) === $web_root &&
115 substr($content, $i+6, $wsrlen) !== $webserver_root) {
116 $content = substr($content, 0, $i + 6) . $webserver_root . substr($content, $i + 6 + $wrlen);
119 $pdf2->WriteHTML($content);
120 $temp_filename = $STMT_TEMP_FILE_PDF;
121 $content_pdf = $pdf2->Output($STMT_TEMP_FILE_PDF,'F');
122 } else {
123 $pdf = new Cezpdf('LETTER');//pdf creation starts
124 $pdf->ezSetMargins(45,9,36,10);
125 $pdf->selectFont('Courier');
126 $pdf->ezSetY($pdf->ez['pageHeight'] - $pdf->ez['topMargin']);
127 $countline=1;
128 $file = fopen($file_to_send, "r");//this file contains the text to be converted to pdf.
129 while(!feof($file)) {
130 $OneLine=fgets($file);//one line is read
131 if(stristr($OneLine, "\014") == true && !feof($file))//form feed means we should start a new page.
133 $pdf->ezNewPage();
134 $pdf->ezSetY($pdf->ez['pageHeight'] - $pdf->ez['topMargin']);
135 str_replace("\014", "", $OneLine);
138 if(stristr($OneLine, 'REMIT TO') == true || stristr($OneLine, 'Visit Date') == true || stristr($OneLine, 'Future Appointments') == true || stristr($OneLine, 'Current') == true)//lines are made bold when 'REMIT TO' or 'Visit Date' is there.
139 $pdf->ezText('<b>'.$OneLine.'</b>', 12, array('justification' => 'left', 'leading' => 6));
140 else
141 $pdf->ezText($OneLine, 12, array('justification' => 'left', 'leading' => 6));
142 $countline++;
144 $fh = @fopen($STMT_TEMP_FILE_PDF, 'w');//stored to a pdf file
145 if ($fh) {
146 fwrite($fh, $pdf->ezOutput());
147 fclose($fh);
150 header("Pragma: public");//this section outputs the pdf file to browser
151 header("Expires: 0");
152 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
153 header("Content-Type: application/force-download");
154 header("Content-Length: " . filesize($STMT_TEMP_FILE_PDF));
155 header("Content-Disposition: attachment; filename=" . basename($STMT_TEMP_FILE_PDF));
156 header("Content-Description: File Transfer");
157 readfile($STMT_TEMP_FILE_PDF);
158 // flush the content to the browser. If you don't do this, the text from the subsequent
159 // output from this script will be in the file instead of sent to the browser.
160 flush();
161 exit(); //added to exit from process properly in order to stop bad html code -ehrlive
162 // sleep one second to ensure there's no follow-on.
163 sleep(1);
167 $today = date("Y-m-d");
168 // Print or download statements if requested.
170 if (($_POST['form_print'] || $_POST['form_download'] || $_POST['form_pdf']) && $_POST['form_cb']) {
172 $fhprint = fopen($STMT_TEMP_FILE, 'w');
173 $sqlBindArray = array();
174 $where = "";
175 foreach ($_POST['form_cb'] as $key => $value) {
176 $where .= " OR f.id = ?";
177 array_push($sqlBindArray, $key);
179 $where = substr($where, 4);
181 $res = sqlStatement("SELECT " .
182 "f.id, f.date, f.pid, f.encounter, f.stmt_count, f.last_stmt_date, f.last_level_closed, f.last_level_billed, f.billing_note as enc_billing_note, " .
183 "p.fname, p.mname, p.lname, p.street, p.city, p.state, p.postal_code, p.billing_note as pat_billing_note " .
184 "FROM form_encounter AS f, patient_data AS p " .
185 "WHERE ( $where ) AND " .
186 "p.pid = f.pid " .
187 "ORDER BY p.lname, p.fname, f.pid, f.date, f.encounter", $sqlBindArray);
189 $stmt = array();
190 $stmt_count = 0;
192 // This loops once for each invoice/encounter.
194 while ($row = sqlFetchArray($res)) {
195 $svcdate = substr($row['date'], 0, 10);
196 $duedate = $svcdate; // TBD?
197 $duncount = $row['stmt_count'];
198 $enc_note = $row['enc_billing_note'];
200 // If this is a new patient then print the pending statement
201 // and start a new one. This is an associative array:
203 // cid = same as pid
204 // pid = OpenEMR patient ID
205 // patient = patient name
206 // amount = total amount due
207 // adjust = adjustments (already applied to amount)
208 // duedate = due date of the oldest included invoice
209 // age = number of days from duedate to today
210 // to = array of addressee name/address lines
211 // lines = array of:
212 // dos = date of service "yyyy-mm-dd"
213 // desc = description
214 // amount = charge less adjustments
215 // paid = amount paid
216 // notice = 1 for first notice, 2 for second, etc.
217 // detail = array of details, see invoice_summary.inc.php
219 if ($stmt['cid'] != $row['pid']) {
220 if (!empty($stmt)) ++$stmt_count;
221 $stmt['cid'] = $row['pid'];
222 $stmt['pid'] = $row['pid'];
223 $stmt['dun_count'] = $row['stmt_count'];
224 $stmt['bill_note'] = $row['pat_billing_note'];
225 $stmt['enc_bill_note'] = $row['enc_billing_note'];
226 $stmt['bill_level'] = $row['last_level_billed'];
227 $stmt['level_closed'] = $row['last_level_closed'];
228 $stmt['patient'] = $row['fname'] . ' ' . $row['lname'];
229 $stmt['encounter'] = $row['encounter'];
230 #If you use the field in demographics layout called
231 #guardiansname this will allow you to send statements to the parent
232 #of a child or a guardian etc
233 if(strlen($row['guardiansname']) == 0) {
234 $stmt['to'] = array($row['fname'] . ' ' . $row['lname']);
236 else
238 $stmt['to'] = array($row['guardiansname']);
240 if ($row['street']) $stmt['to'][] = $row['street'];
241 $stmt['to'][] = $row['city'] . ", " . $row['state'] . " " . $row['postal_code'];
242 $stmt['lines'] = array();
243 $stmt['amount'] = '0.00';
244 $stmt['ins_paid'] = 0;
245 $stmt['today'] = $today;
246 $stmt['duedate'] = $duedate;
247 } else {
248 // Report the oldest due date.
249 if ($duedate < $stmt['duedate']) {
250 $stmt['duedate'] = $duedate;
254 // Recompute age at each invoice.
255 $stmt['age'] = round((strtotime($today) - strtotime($stmt['duedate'])) / (24 * 60 * 60));
257 $invlines = ar_get_invoice_summary($row['pid'], $row['encounter'], true);
258 foreach ($invlines as $key => $value) {
259 $line = array();
260 $line['dos'] = $svcdate;
261 if ($GLOBALS['use_custom_statement']) {
262 $line['desc'] = ($key == 'CO-PAY') ? "Patient Payment" : $value['code_text'];
263 } else {
264 $line['desc'] = ($key == 'CO-PAY') ? "Patient Payment" : "Procedure $key";
266 $line['amount'] = sprintf("%.2f", $value['chg']);
267 $line['adjust'] = sprintf("%.2f", $value['adj']);
268 $line['paid'] = sprintf("%.2f", $value['chg'] - $value['bal']);
269 $line['notice'] = $duncount + 1;
270 $line['detail'] = $value['dtl'];
271 $stmt['lines'][] = $line;
272 $stmt['amount'] = sprintf("%.2f", $stmt['amount'] + $value['bal']);
273 $stmt['ins_paid'] = $stmt['ins_paid'] + $value['ins'];
276 // Record that this statement was run.
277 if (! $DEBUG && ! $_POST['form_without']) {
278 sqlStatement("UPDATE form_encounter SET " .
279 "last_stmt_date = '$today', stmt_count = stmt_count + 1 " .
280 "WHERE id = " . $row['id']);
282 fwrite($fhprint, make_statement($stmt));
284 } // end while
286 if (!empty($stmt)) ++$stmt_count;
287 fclose($fhprint);
288 sleep(1);
290 // Download or print the file, as selected
291 if ($_POST['form_download']) {
292 upload_file_to_client($STMT_TEMP_FILE);
293 } elseif ($_POST['form_pdf']) {
294 upload_file_to_client_pdf($STMT_TEMP_FILE);
295 } else { // Must be print!
296 if ($DEBUG) {
297 $alertmsg = xl("Printing skipped; see test output in") .' '. $STMT_TEMP_FILE;
298 } else {
299 exec("$STMT_PRINT_CMD $STMT_TEMP_FILE");
300 if ($_POST['form_without']) {
301 $alertmsg = xl('Now printing') .' '. $stmt_count .' '. xl('statements; invoices will not be updated.');
302 } else {
303 $alertmsg = xl('Now printing') .' '. $stmt_count .' '. xl('statements and updating invoices.');
305 } // end not debug
306 } // end not form_download
307 } // end statements requested
309 <html>
310 <head>
311 <?php html_header_show(); ?>
312 <link rel=stylesheet href="<?php echo $css_header;?>" type="text/css">
313 <title><?php xl('EOB Posting - Search','e'); ?></title>
314 <script type="text/javascript" src="../../library/textformat.js"></script>
316 <script language="JavaScript">
318 var mypcc = '1';
320 function checkAll(checked) {
321 var f = document.forms[0];
322 for (var i = 0; i < f.elements.length; ++i) {
323 var ename = f.elements[i].name;
324 if (ename.indexOf('form_cb[') == 0)
325 f.elements[i].checked = checked;
329 function npopup(pid) {
330 window.open('sl_eob_patient_note.php?patient_id=' + pid, '_blank', 'width=500,height=250,resizable=1');
331 return false;
334 </script>
336 </head>
338 <body leftmargin='0' topmargin='0' marginwidth='0' marginheight='0'>
339 <center>
341 <form method='post' action='sl_eob_search.php' enctype='multipart/form-data'>
343 <table border='0' cellpadding='5' cellspacing='0'>
344 <tr>
346 <?php
347 // Identify the payer to support resumable posting sessions.
348 echo " <td>\n";
349 echo " " . xl('Payer') . ":\n";
350 echo " </td>\n";
351 echo " <td>\n";
352 $insurancei = getInsuranceProviders();
353 echo " <select name='form_payer_id'>\n";
354 echo " <option value='0'>-- " . xl('Patient') . " --</option>\n";
355 foreach ($insurancei as $iid => $iname) {
356 echo "<option value='$iid'";
357 if ($iid == $_POST['form_payer_id']) echo " selected";
358 echo ">" . $iname . "</option>\n";
360 echo " </select>\n";
361 echo " </td>\n";
364 <td>
365 <?php xl('Source:','e'); ?>
366 </td>
367 <td>
368 <input type='text' name='form_source' size='10' value='<?php echo $_POST['form_source']; ?>'
369 title='<?php xl("A check number or claim number to identify the payment","e"); ?>'>
370 </td>
371 <td>
372 <?php xl('Pay Date:','e'); ?>
373 </td>
374 <td>
375 <input type='text' name='form_paydate' size='10' value='<?php echo $_POST['form_paydate']; ?>'
376 onkeyup='datekeyup(this,mypcc)' onblur='dateblur(this,mypcc)'
377 title='<?php xl("Date of payment yyyy-mm-dd","e"); ?>'>
378 </td>
380 <td>
381 <?php xl('Deposit Date:','e'); ?>
382 </td>
383 <td>
384 <input type='text' name='form_deposit_date' size='10' value='<?php echo $_POST['form_deposit_date']; ?>'
385 onkeyup='datekeyup(this,mypcc)' onblur='dateblur(this,mypcc)'
386 title='<?php xl("Date of bank deposit yyyy-mm-dd","e"); ?>'>
387 </td>
389 <td>
390 <?php xl('Amount:','e'); ?>
391 </td>
392 <td>
393 <input type='text' name='form_amount' size='10' value='<?php echo $_POST['form_amount']; ?>'
394 title='<?php xl("Paid amount that you will allocate","e"); ?>'>
395 </td>
396 <td align='right'>
397 <a href='sl_eob_help.php' target='_blank'><?php xl('Help','e'); ?></a>
398 </td>
400 </tr>
401 </table>
403 <table border='0' cellpadding='5' cellspacing='0'>
405 <tr bgcolor='#ddddff'>
406 <td>
407 <?php xl('Name:','e'); ?>
408 </td>
409 <td>
410 <input type='text' name='form_name' size='10' value='<?php echo $_POST['form_name']; ?>'
411 title='<?php xl("Any part of the patient name, or \"last,first\", or \"X-Y\"","e"); ?>'>
412 </td>
413 <td>
414 <?php xl('Chart ID:','e'); ?>
415 </td>
416 <td>
417 <input type='text' name='form_pid' size='10' value='<?php echo $_POST['form_pid']; ?>'
418 title='<?php xl("Patient chart ID","e"); ?>'>
419 </td>
420 <td>
421 <?php xl('Encounter:','e'); ?>
422 </td>
423 <td>
424 <input type='text' name='form_encounter' size='10' value='<?php echo $_POST['form_encounter']; ?>'
425 title='<?php xl("Encounter number","e"); ?>'>
426 </td>
427 <td>
428 <?php xl('Svc Date:','e'); ?>
429 </td>
430 <td>
431 <input type='text' name='form_date' size='10' value='<?php echo $_POST['form_date']; ?>'
432 title='<?php xl("Date of service mm/dd/yyyy","e"); ?>'>
433 </td>
434 <td>
435 <?php xl('To:','e'); ?>
436 </td>
437 <td>
438 <input type='text' name='form_to_date' size='10' value='<?php echo $_POST['form_to_date']; ?>'
439 title='<?php xl("Ending DOS mm/dd/yyyy if you wish to enter a range","e"); ?>'>
440 </td>
441 <td>
442 <select name='form_category'>
443 <?php
444 foreach (array(xl('Open'), xl('All'), xl('Due Pt'), xl('Due Ins')) as $value) {
445 echo " <option value='$value'";
446 if ($_POST['form_category'] == $value) echo " selected";
447 echo ">$value</option>\n";
450 </select>
451 </td>
452 <td>
453 <input type='submit' name='form_search' value='<?php xl("Search","e"); ?>'>
454 </td>
455 </tr>
457 <!-- Support for X12 835 upload -->
458 <tr bgcolor='#ddddff'>
459 <td colspan='12'>
460 <?php xl('Or upload ERA file:','e'); ?>
461 <input type="hidden" name="MAX_FILE_SIZE" value="5000000" />
462 <input name="form_erafile" type="file" />
463 </td>
464 </tr>
466 <tr>
467 <td height="1" colspan="10">
468 </td>
469 </tr>
471 </table>
473 <?php
474 if ($_POST['form_search'] || $_POST['form_print']) {
475 $form_name = trim($_POST['form_name']);
476 $form_pid = trim($_POST['form_pid']);
477 $form_encounter = trim($_POST['form_encounter']);
478 $form_date = fixDate($_POST['form_date'], "");
479 $form_to_date = fixDate($_POST['form_to_date'], "");
481 $where = "";
483 // Handle X12 835 file upload.
485 if ($_FILES['form_erafile']['size']) {
486 $tmp_name = $_FILES['form_erafile']['tmp_name'];
488 // Handle .zip extension if present. Probably won't work on Windows.
489 if (strtolower(substr($_FILES['form_erafile']['name'], -4)) == '.zip') {
490 rename($tmp_name, "$tmp_name.zip");
491 exec("unzip -p $tmp_name.zip > $tmp_name");
492 unlink("$tmp_name.zip");
495 echo "<!-- Notes from ERA upload processing:\n";
496 $alertmsg .= parse_era($tmp_name, 'era_callback');
497 echo "-->\n";
498 $erafullname = $GLOBALS['OE_SITE_DIR'] . "/era/$eraname.edi";
500 if (is_file($erafullname)) {
501 $alertmsg .= "Warning: Set $eraname was already uploaded ";
502 if (is_file($GLOBALS['OE_SITE_DIR'] . "/era/$eraname.html"))
503 $alertmsg .= "and processed. ";
504 else
505 $alertmsg .= "but not yet processed. ";
507 rename($tmp_name, $erafullname);
508 } // End 835 upload
510 if ($eracount) {
511 // Note that parse_era() modified $eracount and $where.
512 if (! $where) $where = '1 = 2';
514 else {
515 if ($form_name) {
516 if ($where) $where .= " AND ";
517 // Allow the last name to be followed by a comma and some part of a first name.
518 if (preg_match('/^(.*\S)\s*,\s*(.*)/', $form_name, $matches)) {
519 $where .= "p.lname LIKE '" . $matches[1] . "%' AND p.fname LIKE '" . $matches[2] . "%'";
520 // Allow a filter like "A-C" on the first character of the last name.
521 } else if (preg_match('/^(\S)\s*-\s*(\S)$/', $form_name, $matches)) {
522 $tmp = '1 = 2';
523 while (ord($matches[1]) <= ord($matches[2])) {
524 $tmp .= " OR p.lname LIKE '" . $matches[1] . "%'";
525 $matches[1] = chr(ord($matches[1]) + 1);
527 $where .= "( $tmp ) ";
528 } else {
529 $where .= "p.lname LIKE '%$form_name%'";
532 if ($form_pid) {
533 if ($where) $where .= " AND ";
534 $where .= "f.pid = '$form_pid'";
536 if ($form_encounter) {
537 if ($where) $where .= " AND ";
538 $where .= "f.encounter = '$form_encounter'";
540 if ($form_date) {
541 if ($where) $where .= " AND ";
542 if ($form_to_date) {
543 $where .= "f.date >= '$form_date' AND f.date <= '$form_to_date'";
545 else {
546 $where .= "f.date = '$form_date'";
549 if (! $where) {
550 if ($_POST['form_category'] == 'All') {
551 die(xl("At least one search parameter is required if you select All."));
552 } else {
553 $where = "1 = 1";
558 // Notes that as of release 4.1.1 the copays are stored
559 // in the ar_activity table marked with a PCP in the account_code column.
560 $query = "SELECT f.id, f.pid, f.encounter, f.date, " .
561 "f.last_level_billed, f.last_level_closed, f.last_stmt_date, f.stmt_count, " .
562 "p.fname, p.mname, p.lname, p.pubpid, p.billing_note, " .
563 "( SELECT SUM(b.fee) FROM billing AS b WHERE " .
564 "b.pid = f.pid AND b.encounter = f.encounter AND " .
565 "b.activity = 1 AND b.code_type != 'COPAY' ) AS charges, " .
566 "( SELECT SUM(a.pay_amount) FROM ar_activity AS a WHERE " .
567 "a.pid = f.pid AND a.encounter = f.encounter AND a.payer_type = 0 AND a.account_code = 'PCP')*-1 AS copays, " .
568 "( SELECT SUM(a.pay_amount) FROM ar_activity AS a WHERE " .
569 "a.pid = f.pid AND a.encounter = f.encounter AND a.account_code != 'PCP') AS payments, " .
570 "( SELECT SUM(a.adj_amount) FROM ar_activity AS a WHERE " .
571 "a.pid = f.pid AND a.encounter = f.encounter ) AS adjustments " .
572 "FROM form_encounter AS f " .
573 "JOIN patient_data AS p ON p.pid = f.pid " .
574 "WHERE $where " .
575 "ORDER BY p.lname, p.fname, p.mname, f.pid, f.encounter";
577 // Note that unlike the SQL-Ledger case, this query does not weed
578 // out encounters that are paid up. Also the use of sub-selects
579 // will require MySQL 4.1 or greater.
581 // echo "<!-- $query -->\n"; // debugging
583 $t_res = sqlStatement($query);
585 $num_invoices = sqlNumRows($t_res);
586 if ($eracount && $num_invoices != $eracount) {
587 $alertmsg .= "Of $eracount remittances, there are $num_invoices " .
588 "matching encounters in OpenEMR. ";
592 <table border='0' cellpadding='1' cellspacing='2' width='98%'>
594 <tr bgcolor="#dddddd">
595 <td class="dehead">
596 &nbsp;<?php xl('Patient','e'); ?>
597 </td>
598 <td class="dehead">
599 &nbsp;<?php xl('Invoice','e'); ?>
600 </td>
601 <td class="dehead">
602 &nbsp;<?php xl('Svc Date','e'); ?>
603 </td>
604 <td class="dehead">
605 &nbsp;<?php xl('Last Stmt','e'); ?>
606 </td>
607 <td class="dehead" align="right">
608 <?php xl('Charge','e'); ?>&nbsp;
609 </td>
610 <td class="dehead" align="right">
611 <?php xl('Adjust','e'); ?>&nbsp;
612 </td>
613 <td class="dehead" align="right">
614 <?php xl('Paid','e'); ?>&nbsp;
615 </td>
616 <td class="dehead" align="right">
617 <?php xl('Balance','e'); ?>&nbsp;
618 </td>
619 <td class="dehead" align="center">
620 <?php xl('Prv','e'); ?>
621 </td>
622 <?php if (!$eracount) { ?>
623 <td class="dehead" align="left">
624 <?php xl('Sel','e'); ?>
625 </td>
626 <?php } ?>
627 </tr>
629 <?php
630 $orow = -1;
632 while ($row = sqlFetchArray($t_res)) {
633 $balance = sprintf("%.2f", $row['charges'] + $row['copays'] - $row['payments'] - $row['adjustments']);
635 if ($_POST['form_category'] != 'All' && $eracount == 0 && $balance == 0) continue;
637 // $duncount was originally supposed to be the number of times that
638 // the patient was sent a statement for this invoice.
640 $duncount = $row['stmt_count'];
642 // But if we have not yet billed the patient, then compute $duncount as a
643 // negative count of the number of insurance plans for which we have not
644 // yet closed out insurance.
646 if (! $duncount) {
647 for ($i = 1; $i <= 3 && arGetPayerID($row['pid'], $row['date'], $i); ++$i) ;
648 $duncount = $row['last_level_closed'] + 1 - $i;
651 $isdueany = ($balance > 0);
653 // An invoice is now due from the patient if money is owed and we are
654 // not waiting for insurance to pay.
656 $isduept = ($duncount >= 0 && $isdueany) ? " checked" : "";
658 // Skip invoices not in the desired "Due..." category.
660 if (substr($_POST['form_category'], 0, 3) == 'Due' && !$isdueany) continue;
661 if ($_POST['form_category'] == 'Due Ins' && ($duncount >= 0 || !$isdueany)) continue;
662 if ($_POST['form_category'] == 'Due Pt' && ($duncount < 0 || !$isdueany)) continue;
664 $bgcolor = ((++$orow & 1) ? "#ffdddd" : "#ddddff");
666 $svcdate = substr($row['date'], 0, 10);
667 $last_stmt_date = empty($row['last_stmt_date']) ? '' : $row['last_stmt_date'];
669 // Determine if customer is in collections.
671 $billnote = $row['billing_note'];
672 $in_collections = stristr($billnote, 'IN COLLECTIONS') !== false;
674 <tr bgcolor='<?php echo $bgcolor ?>'>
675 <td class="detail">
676 &nbsp;<a href="" onclick="return npopup(<?php echo $row['pid'] ?>)"
677 ><?php echo $row['lname'] . ', ' . $row['fname']; ?></a>
678 </td>
679 <td class="detail">
680 &nbsp;<a href="sl_eob_invoice.php?id=<?php echo $row['id'] ?>"
681 target="_blank"><?php echo $row['pid'] . '.' . $row['encounter']; ?></a>
682 </td>
683 <td class="detail">
684 &nbsp;<?php echo oeFormatShortDate($svcdate) ?>
685 </td>
686 <td class="detail">
687 &nbsp;<?php echo oeFormatShortDate($last_stmt_date) ?>
688 </td>
689 <td class="detail" align="right">
690 <?php bucks($row['charges']) ?>&nbsp;
691 </td>
692 <td class="detail" align="right">
693 <?php bucks($row['adjustments']) ?>&nbsp;
694 </td>
695 <td class="detail" align="right">
696 <?php bucks($row['payments'] - $row['copays']); ?>&nbsp;
697 </td>
698 <td class="detail" align="right">
699 <?php bucks($balance); ?>&nbsp;
700 </td>
701 <td class="detail" align="center">
702 <?php echo $duncount ? $duncount : "&nbsp;" ?>
703 </td>
704 <?php if (!$eracount) { ?>
705 <td class="detail" align="left">
706 <input type='checkbox' name='form_cb[<?php echo($row['id']) ?>]'<?php echo $isduept ?> />
707 <?php if ($in_collections) echo "<b><font color='red'>IC</font></b>"; ?>
708 </td>
709 <?php } ?>
710 </tr>
711 <?php
712 } // end while
713 } // end search/print logic
717 </table>
720 <?php if ($eracount) { ?>
721 <input type='button' value='<?php xl('Process ERA File','e')?>' onclick='processERA()' /> &nbsp;
722 <?php } else { ?>
723 <input type='button' value='<?php xl('Select All','e')?>' onclick='checkAll(true)' /> &nbsp;
724 <input type='button' value='<?php xl('Clear All','e')?>' onclick='checkAll(false)' /> &nbsp;
725 <?php if ($GLOBALS['statement_appearance'] != '1') { ?>
726 <input type='submit' name='form_print' value='<?php xl('Print Selected Statements','e'); ?>' /> &nbsp;
727 <input type='submit' name='form_download' value='<?php xl('Download Selected Statements','e'); ?>' /> &nbsp;
728 <?php } ?>
729 <input type='submit' name='form_pdf' value='<?php xl('PDF Download Selected Statements','e'); ?>' /> &nbsp;
730 <?php } ?>
731 <input type='checkbox' name='form_without' value='1' /> <?php xl('Without Update','e'); ?>
732 </p>
734 </form>
735 </center>
736 <script language="JavaScript">
737 function processERA() {
738 var f = document.forms[0];
739 var debug = f.form_without.checked ? '1' : '0';
740 var paydate = f.form_paydate.value;
741 window.open('sl_eob_process.php?eraname=<?php echo $eraname ?>&debug=' + debug + '&paydate=' + paydate + '&original=original', '_blank');
742 return false;
744 <?php
745 if ($alertmsg) {
746 echo "alert('" . htmlentities($alertmsg) . "');\n";
750 </script>
751 </body>
752 </html>