tranlsation function xl()
[openemr.git] / interface / billing / sl_eob_search.php
blob325cbf534dbd8b424ffccc119feff5fe25f075fc
1 <?
2 // Copyright (C) 2005 Rod Roark <rod@sunsetsystems.com>
3 //
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 is the first of two pages to support posting of EOBs.
10 // The second is sl_eob_invoice.php.
12 include_once("../globals.php");
13 include_once("../../library/patient.inc");
14 include_once("../../library/sql-ledger.inc");
15 include_once("../../library/invoice_summary.inc.php");
16 include_once("../../custom/statement.inc.php");
18 $DEBUG = 0; // set to 0 for production, 1 to test
20 $alertmsg = '';
22 function bucks($amount) {
23 if ($amount)
24 printf("%.2f", $amount);
27 $today = date("Y-m-d");
29 SLConnect();
31 // Print statements if requested.
33 if ($_POST['form_print'] && $_POST['form_cb']) {
35 $fhprint = fopen($STMT_TEMP_FILE, 'w');
37 $where = "";
38 foreach ($_POST['form_cb'] as $key => $value) $where .= " OR ar.id = $key";
39 $where = substr($where, 4);
41 // Sort by patient so that multiple invoices can be
42 // represented on a single statement.
43 $res = SLQuery("SELECT ar.*, customer.name, " .
44 "customer.address1, customer.address2, " .
45 "customer.city, customer.state, customer.zipcode " .
46 "FROM ar, customer WHERE ( $where ) AND " .
47 "customer.id = ar.customer_id " .
48 "ORDER BY ar.customer_id, ar.transdate");
49 if ($sl_err) die($sl_err);
51 $stmt = array();
53 for ($irow = 0; $irow < SLRowCount($res); ++$irow) {
54 $row = SLGetRow($res, $irow);
56 // Determine the date of service. An 8-digit encounter number is
57 // presumed to be a date of service imported during conversion.
58 // Otherwise look it up in the form_encounter table.
60 $svcdate = "";
61 list($pid, $encounter) = explode(".", $row['invnumber']);
62 if (strlen($encounter) == 8) {
63 $svcdate = substr($encounter, 0, 4) . "-" . substr($encounter, 4, 2) .
64 "-" . substr($encounter, 6, 2);
65 } else if ($encounter) {
66 $tmp = sqlQuery("SELECT date FROM form_encounter WHERE " .
67 "encounter = $encounter");
68 $svcdate = substr($tmp['date'], 0, 10);
71 // How many times have we dunned them for this invoice?
72 $intnotes = trim($row['intnotes']);
73 $duncount = substr_count(strtolower($intnotes), "statement sent");
75 // If this is a new patient then print the pending statement
76 // and start a new one. This is an associative array:
78 // pid = patient ID
79 // patient = patient name
80 // amount = total amount due
81 // duedate = due date of the oldest included invoice
82 // age = number of days from duedate to today
83 // to = array of addressee name/address lines
84 // lines = array of:
85 // dos = date of service "yyyy-mm-dd"
86 // desc = description
87 // amount = charge less adjustments
88 // paid = amount paid
89 // notice = 1 for first notice, 2 for second, etc.
91 if ($stmt['pid'] != $row['customer_id']) {
92 fwrite($fhprint, create_statement($stmt));
93 $stmt['pid'] = $row['customer_id'];
94 $stmt['patient'] = $row['name'];
95 $stmt['to'] = array($row['name']);
96 if ($row['address1']) $stmt['to'][] = $row['address1'];
97 if ($row['address2']) $stmt['to'][] = $row['address2'];
98 $stmt['to'][] = $row['city'] . ", " . $row['state'] . " " . $row['zipcode'];
99 $stmt['lines'] = array();
100 $stmt['amount'] = '0.00';
101 $stmt['today'] = $today;
102 $stmt['duedate'] = $row['duedate'];
103 } else {
104 // Report the oldest due date.
105 if ($row['duedate'] < $stmt['duedate']) {
106 $stmt['duedate'] = $row['duedate'];
110 $stmt['age'] = round((strtotime($today) - strtotime($stmt['duedate'])) /
111 (24 * 60 * 60));
113 $invlines = get_invoice_summary($row['id']);
114 foreach ($invlines as $key => $value) {
115 $line = array();
116 $line['dos'] = $svcdate;
117 $line['desc'] = "Procedure $key";
118 $line['amount'] = sprintf("%.2f", $value['chg']);
119 $line['paid'] = sprintf("%.2f", $value['chg'] - $value['bal']);
120 $line['notice'] = $duncount + 1;
121 $stmt['lines'][] = $line;
122 $stmt['amount'] = sprintf("%.2f", $stmt['amount'] + $value['bal']);
125 // Record something in ar.intnotes about this statement run.
126 if ($intnotes) $intnotes .= "\n";
127 $intnotes = addslashes($intnotes . "Statement sent $today");
128 if (! $DEBUG && ! $_POST['form_without']) {
129 SLQuery("UPDATE ar SET intnotes = '$intnotes' WHERE id = " . $row['id']);
130 if ($sl_err) die($sl_err);
134 fwrite($fhprint, create_statement($stmt));
136 if ($DEBUG) {
137 $alertmsg = "Printing skipped; see test output in $STMT_TEMP_FILE";
138 } else {
139 exec("$STMT_PRINT_CMD $STMT_TEMP_FILE");
140 if ($_POST['form_without']) {
141 $alertmsg = "Now printing statements; invoices will not be updated.";
142 } else {
143 $alertmsg = "Now printing statements and updating invoices.";
148 <html>
149 <head>
150 <link rel=stylesheet href="<?echo $css_header;?>" type="text/css">
151 <title>EOB Posting - Search</title>
153 <script language="JavaScript">
155 function checkAll(checked) {
156 var f = document.forms[0];
157 for (var i = 0; i < f.elements.length; ++i) {
158 var ename = f.elements[i].name;
159 if (ename.indexOf('form_cb[') == 0)
160 f.elements[i].checked = checked;
164 function npopup(pid) {
165 window.open('sl_eob_patient_note.php?patient_id=' + pid, '_blank', 'width=500,height=250,resizable=1');
166 return false;
169 </script>
171 </head>
173 <body leftmargin='0' topmargin='0' marginwidth='0' marginheight='0'>
174 <center>
176 <form method='post' action='sl_eob_search.php'>
178 <table border='0' cellpadding='5' cellspacing='0'>
180 <tr>
181 <td height="1" colspan="10">
182 </td>
183 </tr>
185 <tr>
186 <td colspan='2'>
187 &nbsp;
188 </td>
189 <td>
190 Source:
191 </td>
192 <td>
193 <input type='text' name='form_source' size='10' value='<? echo $_POST['form_source']; ?>'
194 title='A check number or claim number to identify the payment'>
195 </td>
196 <td>
197 Pay Date:
198 </td>
199 <td>
200 <input type='text' name='form_paydate' size='10' value='<? echo $_POST['form_paydate']; ?>'
201 title='Date of payment mm/dd/yyyy'>
202 </td>
203 <td>
204 Amount:
205 </td>
206 <td>
207 <input type='text' name='form_amount' size='10' value='<? echo $_POST['form_amount']; ?>'
208 title='Paid amount that you will allocate'>
209 </td>
210 <td colspan='2' align='right'>
211 <a href='sl_eob_help.php' target='_blank'>Help</a>
212 </td>
213 </tr>
215 <tr>
216 <td height="1" colspan="10">
217 </td>
218 </tr>
220 <tr bgcolor='#ddddff'>
221 <td>
222 Name:
223 </td>
224 <td>
225 <input type='text' name='form_name' size='10' value='<? echo $_POST['form_name']; ?>'
226 title='Any part of the patient name'>
227 </td>
228 <td>
229 Chart ID:
230 </td>
231 <td>
232 <input type='text' name='form_pid' size='10' value='<? echo $_POST['form_pid']; ?>'
233 title='Patient chart ID'>
234 </td>
235 <td>
236 Encounter:
237 </td>
238 <td>
239 <input type='text' name='form_encounter' size='10' value='<? echo $_POST['form_encounter']; ?>'
240 title='Encounter number'>
241 </td>
242 <td>
243 Svc Date:
244 </td>
245 <td>
246 <input type='text' name='form_date' size='10' value='<? echo $_POST['form_date']; ?>'
247 title='Date of service mm/dd/yyyy'>
248 </td>
249 <td>
250 <select name='form_category'>
252 foreach (array('Open', 'All', 'Due') as $value) {
253 echo " <option value='$value'";
254 if ($_POST['form_category'] == $value) echo " selected";
255 echo ">$value</option>\n";
258 </select>
259 </td>
260 <td>
261 <input type='submit' name='form_search' value='Search'>
262 </td>
263 </tr>
265 <tr>
266 <td height="1" colspan="10">
267 </td>
268 </tr>
270 </table>
272 <table border='0' cellpadding='1' cellspacing='2' width='98%'>
274 <tr bgcolor="#dddddd">
275 <td class="dehead">
276 &nbsp;Patient
277 </td>
278 <td class="dehead">
279 &nbsp;Invoice
280 </td>
281 <td class="dehead">
282 &nbsp;Svc Date
283 </td>
284 <td class="dehead">
285 &nbsp;Due Date
286 </td>
287 <td class="dehead" align="right">
288 Amount&nbsp;
289 </td>
290 <td class="dehead" align="right">
291 Paid&nbsp;
292 </td>
293 <td class="dehead" align="right">
294 Balance&nbsp;
295 </td>
296 <td class="dehead" align="center">
298 </td>
299 <td class="dehead" align="center">
301 </td>
302 </tr>
304 if ($_POST['form_search'] || $_POST['form_print']) {
305 $form_name = trim($_POST['form_name']);
306 $form_pid = trim($_POST['form_pid']);
307 $form_encounter = trim($_POST['form_encounter']);
308 $form_date = fixDate($_POST['form_date'], "");
310 $where = "";
312 if ($form_name) {
313 // Allow the last name to be followed by a comma and some part of a first name.
314 if (preg_match('/^(.*\S)\s*,\s*(.*)/', $form_name, $matches)) {
315 $form_name = $matches[2] . '% ' . $matches[1] . '%';
316 } else {
317 $form_name = "%$form_name%";
319 if ($where) $where .= " AND ";
320 $where .= "customer.name ILIKE '$form_name'";
323 if ($form_pid && $form_encounter) {
324 if ($where) $where .= " AND ";
325 $where .= "ar.invnumber = '$form_pid.$form_encounter'";
327 else if ($form_pid) {
328 if ($where) $where .= " AND ";
329 $where .= "ar.invnumber LIKE '$form_pid.%'";
331 else if ($form_encounter) {
332 if ($where) $where .= " AND ";
333 $where .= "ar.invnumber like '%.$form_encounter'";
336 if ($form_date) {
337 if ($where) $where .= " AND ";
338 $where .= "(ar.invnumber LIKE '%." . substr($form_date, 0, 4) . substr($form_date, 5, 2) .
339 substr($form_date, 8, 2) . "'";
340 $rez = sqlStatement("SELECT pid, encounter FROM form_encounter WHERE date = '$form_date'");
341 while ($row = sqlFetchArray($rez)) {
342 $where .= " OR ar.invnumber = '" . $row['pid'] . "." . $row['encounter'] . "'";
344 $where .= ")";
347 if (! $where) {
348 if ($_POST['form_category'] == 'All') {
349 die("At least one search parameter is required if you select All.");
350 } else {
351 $where = "1 = 1";
355 $query = "SELECT ar.id, ar.invnumber, ar.duedate, ar.amount, ar.paid, " .
356 "ar.intnotes, ar.notes, ar.shipvia, customer.name " .
357 "FROM ar, customer WHERE $where AND customer.id = ar.customer_id ";
358 if ($_POST['form_category'] != 'All') {
359 $query .= "AND ar.amount != ar.paid ";
360 // if ($_POST['form_category'] == 'Due') {
361 // $query .= "AND ar.duedate <= CURRENT_DATE ";
362 // }
364 $query .= "ORDER BY customer.name, ar.invnumber";
366 // echo "<!-- $query -->\n"; // debugging
368 $t_res = SLQuery($query);
369 if ($sl_err) die($sl_err);
371 for ($irow = 0; $irow < SLRowCount($t_res); ++$irow) {
372 $row = SLGetRow($t_res, $irow);
374 // $duncount was originally supposed to be the number of times that
375 // the patient was sent a statement for this invoice.
377 $duncount = substr_count(strtolower($row['intnotes']), "statement sent");
379 // But if we have not yet billed the patient, then compute $duncount as a
380 // negative count of the number of insurance plans for which we have not
381 // yet closed out insurance.
383 if (! $duncount) {
384 $insgot = strtolower($row['notes']);
385 $inseobs = strtolower($row['shipvia']);
386 foreach (array('ins1', 'ins2', 'ins3') as $value) {
387 if (strpos($insgot, $value) !== false &&
388 strpos($inseobs, $value) === false)
389 --$duncount;
393 // $isdue = ($row['duedate'] <= $today && $row['amount'] > $row['paid']) ? " checked" : "";
395 // An invoice is now due if money is owed and we are not waiting for
396 // insurance to pay. We no longer look at the due date for this.
398 $isdue = ($duncount >= 0 &&
399 sprintf("%.2f",$row['amount']) > sprintf("%.2f",$row['paid']))
400 ? " checked" : "";
402 // Skip non-due invoices if the user asked for only those due.
404 if ($_POST['form_category'] == 'Due' && ! $isdue) continue;
406 $bgcolor = (($irow & 1) ? "#ffdddd" : "#ddddff");
408 // Determine the date of service. If this was a search parameter
409 // then we already know it. Or an 8-digit encounter number is
410 // presumed to be a date of service imported during conversion.
411 // Otherwise look it up in the form_encounter table.
413 $svcdate = "";
414 list($pid, $encounter) = explode(".", $row['invnumber']);
415 if ($form_date) {
416 $svcdate = $form_date;
418 else if (strlen($encounter) == 8) {
419 $svcdate = substr($encounter, 0, 4) . "-" . substr($encounter, 4, 2) .
420 "-" . substr($encounter, 6, 2);
422 else if ($encounter) {
423 $tmp = sqlQuery("SELECT date FROM form_encounter WHERE " .
424 "encounter = $encounter");
425 $svcdate = substr($tmp['date'], 0, 10);
428 <tr bgcolor='<? echo $bgcolor ?>'>
429 <td class="detail">
430 &nbsp;<a href="" onclick="return npopup(<? echo $pid ?>)"><? echo $row['name'] ?></a>
431 </td>
432 <td class="detail">
433 &nbsp;<a href="sl_eob_invoice.php?id=<? echo $row['id'] ?>"
434 target="_blank"><? echo $row['invnumber'] ?></a>
435 </td>
436 <td class="detail">
437 &nbsp;<? echo $svcdate ?>
438 </td>
439 <td class="detail">
440 &nbsp;<? echo $row['duedate'] ?>
441 </td>
442 <td class="detail" align="right">
443 <? bucks($row['amount']) ?>&nbsp;
444 </td>
445 <td class="detail" align="right">
446 <? bucks($row['paid']) ?>&nbsp;
447 </td>
448 <td class="detail" align="right">
449 <? bucks($row['amount'] - $row['paid']) ?>&nbsp;
450 </td>
451 <td class="detail" align="center">
452 <? echo $duncount ? $duncount : "&nbsp;" ?>
453 </td>
454 <td class="detail" align="center">
455 <input type='checkbox' name='form_cb[<? echo($row['id']) ?>]'<? echo $isdue ?> />
456 </td>
457 </tr>
461 SLClose();
464 </table>
467 <input type='button' value='Select All' onclick='checkAll(true)' /> &nbsp;
468 <input type='button' value='Clear All' onclick='checkAll(false)' /> &nbsp;
469 <input type='submit' name='form_print' value='Print Selected Statements' /> &nbsp;
470 <input type='checkbox' name='form_without' value='1' /> Without Update
471 </p>
473 </form>
474 </center>
475 <script>
477 if ($alertmsg) {
478 echo "alert('$alertmsg');\n";
481 </script>
482 </body>
483 </html>