added statistical reporting for ippf and code categories as another way to organize...
[openemr.git] / library / billing.inc
bloba9eb495b30e615166632806e3ac9dceb943ea044
1 <?php
3 // require_once("{$GLOBALS['srcdir']}/sql.inc");
4 require_once(dirname(__FILE__) . "/sql.inc");
6 function getBillingById ($id, $cols = "*")
8         return sqlQuery("select $cols from billing where id='$id' and activity=1 order by date DESC limit 0,1");
11 function getBillingByPid ($pid, $cols = "*")
13         return  sqlQuery("select $cols from billing where pid ='$pid' and activity=1 order by date DESC limit 0,1");
16 function getBillingByEncounter ($pid,$encounter, $cols = "code_type, code, code_text")
18         $res = sqlStatement("select $cols from billing where encounter = '$encounter' and pid='$pid' and activity=1 order by code_type, date ASC");
20         for($iter=0; $row=sqlFetchArray($res); $iter++)
21         {
22                 $all[$iter] = $row;
23         }
24         return $all;
27 function addBilling($encounter_id, $code_type, $code, $code_text, $pid,
28   $authorized="0", $provider, $modifier="", $units="", $fee="0.00",
29   $ndc_info='', $justify='')
31   $sql = "insert into billing (date, encounter, code_type, code, code_text, " .
32     "pid, authorized, user, groupname, activity, billed, provider_id, " .
33     "modifier, units, fee, ndc_info, justify) values (" .
34     "NOW(), '$encounter_id', '$code_type', '$code', '$code_text', '$pid', " .
35     "'$authorized', '" . $_SESSION['authId'] . "', '" .
36     $_SESSION['authProvider'] . "', 1, 0, $provider, '$modifier', '$units', " .
37     "'$fee', '$ndc_info', '$justify')";
38   return sqlInsert($sql);
41 function authorizeBilling($id, $authorized = "1")
43         sqlQuery("update billing set authorized = '$authorized' where id = '$id'");
46 function deleteBilling($id)
48         sqlStatement("update billing set activity = 0 where id = '$id'");
51 function clearBilling($id)
53         sqlStatement("update billing set justify = '' where id = '$id'");
56 // This function supports the Billing page (billing_process.php), freeb
57 // processing (process_bills.php), and initiation of secondary processing
58 // (sl_eob.inc.php).  It is called in the following situations:
60 // * billing_process.php sets bill_time, bill_process, payer and target on
61 //   queueing a claim for freeb processing.  Create claims row.
62 // * billing_process.php sets claim status to 2, and payer, on marking a
63 //   claim as billed without actually generating any billing.  Create a
64 //   claims row.  In this case bill_process will remain at 0 and process_time
65 //   and process_file will not be set.
66 // * billing_process.php sets bill_process, payer, target and x12 partner
67 //   before calling gen_x12_837.  Create a claims row.
68 // * billing_process.php sets claim status to 2 (billed), bill_process to 2,
69 //   process_time and process_file after calling gen_x12_837.  Claims row
70 //   already exists.
71 // * process_bills.php sets bill_process to 2, process_time, and process_file
72 //   after invoking freeb to process a claim.  Claims row already exists.
73 // * billing_process.php sets claim status to 2 (billed) after creating
74 //   an electronic freeb batch (hcfa-only with recent changes).  Claims
75 //   row already exists.
76 // * EOB posting updates claim status to mark a payer as done.  Claims row
77 //   already exists.
78 // * EOB posting reopens an encounter for billing a secondary payer.  Create
79 //   a claims row.
81 // $newversion should be passed to us to indicate if a new claims row
82 // is to be generated, otherwise one must already exist.  The payer, if
83 // passed in for the latter case, must match the existing claim.
85 // Currently on the billing page the user can select any of the patient's
86 // payers.  That logic will tailor the payer choices to the encounter date.
88 function updateClaim($newversion, $patient_id, $encounter_id, $payer_id=-1,
89   $status=-1, $bill_process=-1, $process_file='', $target='', $partner_id=-1)
91   if (!$newversion) {
92     $sql = "SELECT * FROM claims WHERE patient_id = '$patient_id' AND " .
93       "encounter_id = '$encounter_id' AND status > 0 AND status < 4 ";
94     if ($payer_id >= 0) $sql .= "AND payer_id = '$payer_id' ";
95     $sql .= "ORDER BY version DESC LIMIT 1";
96     $row = sqlQuery($sql);
97     if (!$row) return 0;
98     if ($payer_id     < 0) $payer_id     = $row['payer_id'];
99     if ($status       < 0) $status       = $row['status'];
100     if ($bill_process < 0) $bill_process = $row['bill_process'];
101     if ($partner_id   < 0) $partner_id   = $row['x12_partner_id'];
102     if (!$process_file   ) $process_file = $row['process_file'];
103     if (!$target         ) $target       = $row['target'];
104   }
106   $claimset = "";
107   $billset = "";
108   if (empty($payer_id) || $payer_id < 0) $payer_id = 0;
110   if ($status >= 0) {
111     $claimset .= ", status = '$status'";
112     if ($status > 1) {
113       $billset .= ", billed = 1";
114       if ($status == 2) $billset  .= ", bill_date = NOW()";
115     } else {
116       $billset .= ", billed = 0";
117     }
118   }
119   if ($bill_process >= 0) {
120     $claimset .= ", bill_process = '$bill_process'";
121     $billset  .= ", bill_process = '$bill_process'";
122   }
123   if ($process_file) {
124     $claimset .= ", process_file = '$process_file', process_time = NOW()";
125     $billset  .= ", process_file = '$process_file', process_date = NOW()";
126   }
127   if ($target) {
128     $claimset .= ", target = '$target'";
129     $billset  .= ", target = '$target'";
130   }
131   if ($payer_id >= 0) {
132     $claimset .= ", payer_id = '$payer_id'";
134     // TBD: Compute and include payer type... or remove payer type from the schema?
136     $billset  .= ", payer_id = '$payer_id'";
137   }
138   if ($partner_id >= 0) {
139     $claimset .= ", x12_partner_id = '$partner_id'";
140     $billset  .= ", x12_partner_id = '$partner_id'";
141   }
143   if ($billset) {
144     $billset = substr($billset, 2);
145     sqlStatement("UPDATE billing SET $billset WHERE " .
146       "encounter = '$encounter_id' AND pid='$patient_id' AND activity = 1");
147   }
149   // If a new claim version is requested, insert its row.
150   //
151   if ($newversion) {
152     /****
153     $payer_id = ($payer_id < 0) ? $row['payer_id'] : $payer_id;
154     $bill_process = ($bill_process < 0) ? $row['bill_process'] : $bill_process;
155     $process_file = ($process_file) ? $row['process_file'] : $process_file;
156     $target = ($target) ? $row['target'] : $target;
157     $partner_id = ($partner_id < 0) ? $row['x12_partner_id'] : $partner_id;
158     $sql = "INSERT INTO claims SET " .
159       "patient_id = '$patient_id', " .
160       "encounter_id = '$encounter_id', " .
161       "bill_time = UNIX_TIMESTAMP(NOW()), " .
162       "payer_id = '$payer_id', " .
163       "status = '$status', " .
164       "payer_type = '" . $row['payer_type'] . "', " .
165       "bill_process = '$bill_process', " .
166       "process_time = '" . $row['process_time'] . "', " .
167       "process_file = '$process_file', " .
168       "target = '$target', " .
169       "x12_partner_id = '$partner_id'";
170     ****/
171     $sql = "INSERT INTO claims SET " .
172       "patient_id = '$patient_id', " .
173       "encounter_id = '$encounter_id', " .
174       "bill_time = NOW() $claimset";
175     sqlStatement($sql);
176   }
178   // Otherwise update the existing claim row.
179   //
180   else if ($claimset) {
181     $claimset = substr($claimset, 2);
182     sqlStatement("UPDATE claims SET $claimset WHERE " .
183       "patient_id = '$patient_id' AND encounter_id = '$encounter_id' AND " .
184       // "payer_id = '" . $row['payer_id'] . "' AND " .
185       "version = '" . $row['version'] . "'");
186   }
188   // Whenever a claim is marked billed, post it to SQL-Ledger.
189   //
190   if ($status == 2) {
191     $ws = new WSClaim($patient_id, $encounter_id);
192   }
194   return 1;