select billing line items to display by encounter date rather than data entry date
[openemr.git] / interface / billing / billing_report.php
blobe45de018450d2a8dabfb08e15b30a0f7cee6c052
1 <?
2 include_once("../globals.php");
4 include_once("$srcdir/patient.inc");
5 include_once("$srcdir/billrep.inc");
6 include_once(dirname(__FILE__) . "/../../library/classes/OFX.class.php");
7 include_once(dirname(__FILE__) . "/../../library/classes/X12Partner.class.php");
9 $alertmsg = '';
11 if ($_POST['mode'] == 'export') {
12 $sdate = $_POST['from_date'];
13 $edate = $_POST['to_date'];
15 $sql = "SELECT billing.*, concat(pd.fname, ' ', pd.lname) as name from billing "
16 . "join patient_data as pd on pd.pid = billing.pid where billed = '1' and "
17 . "(process_date > '" . mysql_real_escape_string($sdate)
18 . "' or DATE_FORMAT( process_date, '%Y-%m-%d' ) = '" . mysql_real_escape_string($sdate) ."') "
19 . "and (process_date < '" . mysql_real_escape_string($edate)
20 . "'or DATE_FORMAT( process_date, '%Y-%m-%d' ) = '" . mysql_real_escape_string($edate) ."') "
21 . "order by pid,encounter";
22 $db = get_db();
23 $results = $db->Execute($sql);
24 $billings = array();
25 if ($results->RecordCount() == 0) {
26 echo "No Bills Found to Include in OFX Export<br>";
28 else {
29 while(!$results->EOF) {
30 $billings[] = $results->fields;
31 $results->MoveNext();
33 $ofx = new OFX($billings);
34 header("Pragma: public");
35 header("Expires: 0");
36 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
37 header("Content-Disposition: attachment; filename=openemr_ofx.ofx");
38 header("Content-Type: text/xml");
39 echo $ofx->get_OFX();
40 exit;
44 if ($_POST['mode'] == 'process') {
45 if (exec("ps x | grep 'process_bills[.]php'")) {
46 $alertmsg = 'Request ignored - claims processing is already running!';
48 else {
49 exec("cd $webserver_root/library/freeb;" .
50 "php -q process_bills.php bill > process_bills.log 2>&1 &");
51 $alertmsg = 'Batch processing initiated; this may take a while.';
55 //global variables:
56 if (!isset($_POST["mode"])) {
57 if (!isset($_POST["from_date"])) {
58 $from_date=date("Y-m-d");
59 } else {
60 $from_date = $_POST["from_date"];
62 if (!isset($_POST["to_date"])) {
63 $to_date = date("Y-m-d");
64 } else {
65 $to_date = $_POST["to_date"];
67 if (!isset($_POST["code_type"])) {
68 $code_type="all";
69 } else {
70 $code_type = $_POST["code_type"];
72 if (!isset($_POST["unbilled"])) {
73 $unbilled = "on";
74 } else {
75 $unbilled = $_POST["unbilled"];
77 if (!isset($_POST["authorized"])) {
78 $my_authorized = "on";
79 } else {
80 $my_authorized = $_POST["authorized"];
82 } else {
83 $from_date = $_POST["from_date"];
84 $to_date = $_POST["to_date"];
85 $code_type = $_POST["code_type"];
86 $unbilled = $_POST["unbilled"];
87 $my_authorized = $_POST["authorized"];
90 $ofrom_date = $from_date;
91 $oto_date = $to_date;
92 $ocode_type = $code_type;
93 $ounbilled = $unbilled;
94 $oauthorized = $my_authorized;
98 <html>
99 <head>
101 <link rel=stylesheet href="<?echo $css_header;?>" type="text/css">
102 <script>
104 function select_all() {
105 for($i=0;$i < document.update_form.length;$i++) {
106 $name = document.update_form[$i].name;
107 if ($name.substring(0,7) == "claims[" && $name.substring($name.length -6) == "[bill]") {
108 document.update_form[$i].checked = true;
111 set_button_states();
114 function set_button_states() {
115 var f = document.update_form;
116 var count0 = 0;
117 var count1 = 0;
118 var count2 = 0;
119 for($i = 0; $i < f.length; ++$i) {
120 $name = f[$i].name;
121 if ($name.substring(0, 7) == "claims[" && $name.substring($name.length -6) == "[bill]" && f[$i].checked == true) {
122 if (f[$i].value == '0') ++count0;
123 else if (f[$i].value == '1' || f[$i].value == '5') ++count1;
124 else ++count2;
128 var can_generate = (count0 > 0 || count1 > 0 || count2 > 0);
129 var can_mark = (count1 == 0 && (count0 > 0 || count2 > 0));
130 var can_bill = (count0 == 0 && count1 == 0 && count2 > 0);
132 f.bn_hcfa_print.disabled = !can_generate;
133 f.bn_hcfa.disabled = !can_generate;
134 f.bn_x12.disabled = !can_generate;
135 f.bn_mark.disabled = !can_mark;
136 f.bn_electronic_file.disabled = !can_bill;
139 </script>
140 </head>
141 <body <?echo $top_bg_line;?> topmargin=0 rightmargin=0 leftmargin=2 bottommargin=0 marginwidth=2 marginheight=0>
143 <p style='margin-top:5px;margin-bottom:5px;margin-left:5px'>
145 if ($userauthorized) {
147 <a href="../main/main.php" target=Main><font class=title>Billing Report</font><font class=more> <?echo $tback;?></font></a>
148 <?} else {?>
149 <a href="../main/onotes/office_comments.php" target=Main><font class=title>Billing Report</font><font class=more><?echo $tback;?></font></a>
153 </p>
155 <form name=the_form method=post action=billing_report.php>
156 <input type=hidden name=mode value="change">
157 <table width=100% border="1" cellspacing="0" cellpadding="0">
158 <tr>
159 <td nowrap>&nbsp;<span class=text>From: </span><input type=entry name=from_date size=11 value="<?echo $from_date;?>"></td>
160 <td nowrap>&nbsp;<span class=text>To: </span><input type=entry name=to_date size=11 value="<?echo $to_date;?>">
161 <input type="hidden" name="code_type" value="%"></td>
162 <td nowrap><input type=checkbox name=unbilled <?if ($unbilled == "on") {echo "checked";};?>><span class=text>Show Unbilled Only</span></td>
163 <td nowrap><input type=checkbox name=authorized <?if ($my_authorized == "on") {echo "checked";};?>><span class=text>Show Authorized Only</span></td>
164 <td align='right' width='10%' nowrap>
165 &nbsp;<span class=text><a href="javascript:document.the_form.mode.value='change';document.the_form.submit()" class=link_submit>[Change View]</a>
167 <a href="javascript:document.the_form.mode.value='export';document.the_form.submit()" class=link_submit>[Export OFX]</a></span>&nbsp;
168 </td>
169 </tr>
170 <tr>
171 <td nowrap>&nbsp;<a href="print_billing_report.php?<?print "from_date=".urlencode($ofrom_date)."&to_date=".urlencode($oto_date)."&code_type=".urlencode($ocode_type)."&unbilled=".urlencode($ounbilled)."&authorized=".urlencode($oauthorized);?>" class=link_submit target=new>[View Printable Report]</a></td>
172 <td nowrap>
173 <?php
174 print '&nbsp;';
175 $acct_config = $GLOBALS['oer_config']['ws_accounting'];
176 if($acct_config['enabled'] == true) {
177 print '<span class=text><a href="javascript:void window.open(\''.$acct_config['url_path'].'\')">[Accounting System]</a></span>';
180 </td>
181 <td colspan='2' nowrap>
182 &nbsp;
183 <a href="javascript:document.the_form.mode.value='process';document.the_form.submit()" class="link_submit"
184 title="Process all queued bills to create electronic data (and print if requested)">[Start Batch Processing]</a>
185 &nbsp; <a href='../../library/freeb/process_bills.log' target='_blank' class='link_submit'
186 title='See messages from the last batch processing run'>[view log]</a></span>
187 </td>
188 <td align='right' nowrap>
189 <a href="javascript:select_all()" class="link_submit">[Select All]</a>&nbsp;
190 </td>
191 </tr>
192 </table>
193 </form>
195 <form name=update_form method=post action=billing_process.php>
197 <center>
198 <input type="submit" name="bn_hcfa_print" value="Generate HCFA &amp; Print" title="Queue for HCFA batch processing and printing">
199 <input type="submit" name="bn_hcfa" value="Generate HCFA" title="Queue for HCFA batch processing">
200 <input type="submit" name="bn_x12" value="Generate X12" title="Queue for X12 batch processing">
201 <input type="submit" name="bn_mark" value="Mark Bills as Cleared" title="Post to accounting and mark as billed">
202 <input type="submit" name="bn_electronic_file" value="Generate Electronic Batch &amp; Clear" title="Download billing file, post to accounting and mark as billed">
203 </center>
205 <input type=hidden name=mode value="bill">
206 <input type=hidden name=authorized value="<?echo $my_authorized;?>">
207 <input type=hidden name=unbilled value="<?echo $unbilled;?>">
208 <input type=hidden name=code_type value="%">
209 <input type=hidden name=to_date value="<?echo $to_date;?>">
210 <input type=hidden name=from_date value="<?echo $from_date;?>">
212 if ($my_authorized == "on" ) {
213 $my_authorized = "1";
214 } else {
215 $my_authorized = "%";
218 if ($unbilled == "on") {
219 $unbilled = "0";
220 } else {
221 $unbilled = "%";
224 <input type=hidden name=bill_list value="<?
225 $list = getBillsListBetween($from_date,$to_date,$my_authorized,$unbilled,"%");
226 print $list;
227 ?>">
228 <!-- new form for uploading -->
229 <?php
230 if (!isset($_POST["mode"])) {
231 if (!isset($_POST["from_date"])) {
232 $from_date=date("Y-m-d");
233 } else {
234 $from_date = $_POST["from_date"];
236 if (!isset($_POST["to_date"])) {
237 $to_date = date("Y-m-d");
238 } else {
239 $to_date = $_POST["to_date"];
241 if (!isset($_POST["code_type"])) {
242 $code_type="all";
243 } else {
244 $code_type = $_POST["code_type"];
246 if (!isset($_POST["unbilled"])) {
247 $unbilled = "on";
248 } else {
249 $unbilled = $_POST["unbilled"];
251 if (!isset($_POST["authorized"])) {
252 $my_authorized = "on";
253 } else {
254 $my_authorized = $_POST["authorized"];
256 } else {
257 $from_date = $_POST["from_date"];
258 $to_date = $_POST["to_date"];
259 $code_type = $_POST["code_type"];
260 $unbilled = $_POST["unbilled"];
261 $my_authorized = $_POST["authorized"];
263 if ($my_authorized == "on" ) {
264 $my_authorized = "1";
265 } else {
266 $my_authorized = "%";
269 if ($unbilled == "on") {
270 $unbilled = "0";
271 } else {
272 $unbilled = "%";
277 if (isset($_POST["mode"]) && $_POST["mode"] == "bill") {
278 billCodesList($list);
283 <table border="0" cellspacing="0" cellpadding="0" width="100%">
286 if ($ret = getBillsBetween($from_date,$to_date,$my_authorized,$unbilled,"%")) {
287 $loop = 0;
288 $oldcode = "";
289 $last_encounter_id = "";
290 $lhtml = "";
291 $rhtml = "";
292 $lcount = 0;
293 $rcount = 0;
294 $bgcolor = "";
295 $skipping = FALSE;
297 foreach ($ret as $iter) {
298 $name = getPatientData($iter['pid']);
299 $this_encounter_id = $iter['pid'] . "-" . $iter['encounter'];
301 if ($last_encounter_id != $this_encounter_id) {
302 if ($lhtml) {
303 while ($rcount < $lcount) {
304 $rhtml .= "<tr bgcolor='$bgcolor'><td colspan='7'>&nbsp;</td></tr>";
305 ++$rcount;
307 echo "<tr bgcolor='$bgcolor'>\n<td rowspan='$rcount' valign='top'>\n$lhtml</td>$rhtml\n";
308 echo "<tr bgcolor='$bgcolor'><td colspan='8' height='5'></td></tr>\n\n";
311 $lhtml = "";
312 $rhtml = "";
314 // If there are ANY unauthorized items in this encounter and this is
315 // the normal case of viewing only authorized billing, then skip the
316 // entire encounter.
318 $skipping = FALSE;
319 if ($my_authorized == '1') {
320 $res = sqlQuery("select count(*) as count from billing where " .
321 "encounter = '" . $iter['encounter'] . "' and " .
322 "pid='" . $iter['pid'] . "' and " .
323 "activity = 1 and authorized = 0");
324 if ($res['count'] > 0) {
325 $skipping = TRUE;
326 $last_encounter_id = $this_encounter_id;
327 continue;
331 ++$encount;
332 $bgcolor = "#" . (($encount & 1) ? "ddddff" : "ffdddd");
333 echo "<tr bgcolor='$bgcolor'><td colspan='8' height='5'></td></tr>\n";
334 $lcount = 3;
335 $rcount = 0;
336 $oldcode = "";
338 $lhtml .= "&nbsp;<span class=bold>". $name['fname'] . "&nbsp;" . $name['lname'] . "</span><span class=small>&nbsp;(" . $iter['pid'] . "-" . $iter['encounter'] . ")</span>";
339 $lhtml .= "&nbsp;&nbsp;&nbsp;<a class=\"link_submit\" href=\"" . $GLOBALS['webroot'] ."/interface/patient_file/encounter/patient_encounter.php?set_encounter=" . $iter['encounter'] . "&pid=" . $iter['pid'] . "\">[To&nbsp;Encounter]</a>";
340 $lhtml .= "&nbsp;&nbsp;&nbsp;<a class=\"link_submit\" href=\"" . $GLOBALS['webroot'] ."/interface/patient_file/summary/demographics_full.php?&pid=" . $iter['pid'] . "\">[To&nbsp;Demographics]</a>";
341 $lhtml .= "<br />\n";
342 $lhtml .= "&nbsp;<span class=text>Bill: ";
343 $lhtml .= "<select name='claims[" . $this_encounter_id . "][payer]' style='background-color:$bgcolor'>";
344 $query = "SELECT id.provider as id, id.type, ic.x12_default_partner_id as ic_x12id, ic.name as provider FROM insurance_data as id, insurance_companies as ic WHERE ic.id = id.provider AND pid = '" . mysql_escape_string($iter['pid']) . "' order by type";
346 $result = sqlStatement($query);
347 $count = 0;
348 $default_x12_partner = $iter['x12_partner_id'];
350 while ($row = mysql_fetch_array($result)) {
351 if (strlen($row['provider']) > 0) {
352 if ($count == 0) {
353 $lhtml .= "<option value=\"" .$row['id'] . "\" selected>" . $row['type'] . ": " . $row['provider']. "</option>";
354 if (!is_numeric($default_x12_partner)) $default_x12_partner = $row['ic_x12id'];
356 else {
357 $lhtml .= "<option value=\"" . $row['id'] . "\">" . $row['type'] . ": " . $row['provider']. "</option>";
360 $count++;
362 $lhtml .= "<option value='-1'>Unassigned</option>\n";
363 $lhtml .= "</select>&nbsp;&nbsp;\n";
364 $lhtml .= "<select name='claims[" . $this_encounter_id . "][partner]' style='background-color:$bgcolor'>";
365 $x = new X12Partner();
366 $partners = $x->_utility_array($x->x12_partner_factory());
367 foreach ($partners as $xid => $xname) {
368 $lhtml .= '<option label="' . $xname . '" value="' . $xid .'"';
369 if ($xid == $default_x12_partner) {
370 $lhtml .= "selected";
372 $lhtml .= '>' . $xname . '</option>';
374 $lhtml .= "</select>";
375 $lhtml .= "<br>\n&nbsp;Claim was initiated: " . $iter['date'];
376 if ($iter['billed'] == 1) {
377 $lhtml .= "<br>\n&nbsp;Claim was billed: " . $iter['bill_date'];
378 ++$lcount;
380 if ($iter['bill_process'] == 1) {
381 $lhtml .= "<br>\n&nbsp;Claim is queued for processing";
382 ++$lcount;
384 if ($iter['bill_process'] == 5) {
385 $lhtml .= "<br>\n&nbsp;Claim is queued for printing and processing";
386 ++$lcount;
388 if ($iter['bill_process'] == 2) {
389 $lhtml .= "<br>\n&nbsp;Claim was processed: " . $iter['process_date'];
390 $lhtml .= '<br>' . "\n" . '&nbsp;Claim is in file: <a href="get_claim_file.php?key=' . $iter['process_file'] .'">' . $iter['process_file'] . '</a> or ';
391 $lhtml .= '<a href="get_claim_file.php?action=print&key=' . $iter['process_file'] .'">Print It</a> or ';
392 $lhtml .= '<a target="_new" href="freebtest.php?format=' . $iter['target'] . '&billkey=' . $iter['pid'] . '-' . $iter['encounter'] . '">Run Test</a>';
393 $lhtml .= '<input type="hidden" name="claims[' . $this_encounter_id . '][file]" value="' . $iter['process_file'] . '">';
394 $lcount += 2;
396 if ($iter['bill_process'] == 3) {
397 $lhtml .= "<br>\n&nbsp;Claim was processed: " . $iter['process_date'] . " but there was an error: ". $iter['process_file'];
398 ++$lcount;
402 if ($skipping) continue;
404 ++$rcount;
405 if ($rhtml) {
406 $rhtml .= "<tr bgcolor='$bgcolor'>\n";
408 $rhtml .= "<td width='50'>";
409 if ($oldcode != $iter['code_type']) {
410 $rhtml .= "<span class=text>" . $iter['code_type'] . ": </span>";
412 $oldcode = $iter['code_type'];
413 $rhtml .= "</td>\n";
414 $justify = "";
415 if ($iter['code_type'] == "CPT4" || $iter['code_type'] == "HCPCS") {
416 $js = split(":",$iter['justify']);
417 $counter = 0;
418 foreach ($js as $j) {
419 if(!empty($j)) {
420 if ($counter == 0) {
421 $justify .= " (<b>$j</b>)";
423 else {
424 $justify .= " ($j)";
426 $counter++;
431 $rhtml .= "<td><span class=text>" . $iter{"code"}. "</span>" . '<span style="font-size:8pt;">' . $justify . "</span></td>\n";
432 $rhtml .= '<td align="right"><span style="font-size:8pt;">&nbsp;&nbsp;&nbsp;';
433 if ($iter['fee'] > 0) {
434 $rhtml .= '$' . $iter['fee'];
436 $rhtml .= "</span></td>\n";
437 $rhtml .= '<td><span style="font-size:8pt;">&nbsp;&nbsp;&nbsp;';
438 $rhtml .= getProviderName($iter['provider_id']);
439 $rhtml .= "</span></td>\n";
440 $rhtml .= '<td width=100>&nbsp;&nbsp;&nbsp;<span style="font-size:8pt;">' . date("Y-m-d",strtotime($iter{"date"})) . "</span></td>\n";
441 if ($iter['authorized'] != 1) {
442 $rhtml .= "<td><span class=alert>Note: This code was not entered by an authorized user. Only authorized codes may be uploaded to the Open Medical Billing Network for processing. If you wish to upload these codes, please select an authorized user here.</span></td>\n";
444 else {
445 $rhtml .= "<td></td>\n";
447 if ($last_encounter_id != $this_encounter_id) {
448 $rhtml .= "<td><input type='checkbox' value='" . $iter['bill_process'] . "$procstatus' name='claims[" . $this_encounter_id . "][bill]' onclick='set_button_states()'>&nbsp;</td>\n";
450 else {
451 $rhtml .= "<td></td>\n";
453 $rhtml .= "</tr>\n";
454 $last_encounter_id = $this_encounter_id;
457 if ($lhtml) {
458 while ($rcount < $lcount) {
459 $rhtml .= "<tr bgcolor='$bgcolor'><td colspan='7'>&nbsp;</td></tr>";
460 ++$rcount;
462 echo "<tr bgcolor='$bgcolor'>\n<td rowspan='$rcount' valign='top'>\n$lhtml</td>$rhtml\n";
463 echo "<tr bgcolor='$bgcolor'><td colspan='8' height='5'></td></tr>\n";
469 </table>
471 </form>
472 <script>
473 set_button_states();
476 if ($alertmsg) {
477 echo "alert('$alertmsg');\n";
481 </script>
482 </body>
483 </html>