c26ee89b0e0a087ade14b4bd577adb11e72f3c93
[openemr.git] / interface / forms / fee_sheet / new.php
blobc26ee89b0e0a087ade14b4bd577adb11e72f3c93
1 <?php
2 // Copyright (C) 2005-2011 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 $fake_register_globals=false;
10 $sanitize_all_escapes=true;
12 require_once("../../globals.php");
13 require_once("$srcdir/acl.inc");
14 require_once("$srcdir/api.inc");
15 require_once("codes.php");
16 require_once("../../../custom/code_types.inc.php");
17 require_once("../../drugs/drugs.inc.php");
18 require_once("$srcdir/formatting.inc.php");
19 require_once("$srcdir/options.inc.php");
20 require_once("$srcdir/formdata.inc.php");
22 // Some table cells will not be displayed unless insurance billing is used.
23 $usbillstyle = $GLOBALS['ippf_specific'] ? " style='display:none'" : "";
25 function alphaCodeType($id) {
26 global $code_types;
27 foreach ($code_types as $key => $value) {
28 if ($value['id'] == $id) return $key;
30 return '';
33 // Helper function for creating drop-lists.
34 function endFSCategory() {
35 global $i, $last_category, $FEE_SHEET_COLUMNS;
36 if (! $last_category) return;
37 echo " </select>\n";
38 echo " </td>\n";
39 if ($i >= $FEE_SHEET_COLUMNS) {
40 echo " </tr>\n";
41 $i = 0;
45 // Generate JavaScript to build the array of diagnoses.
46 function genDiagJS($code_type, $code) {
47 global $code_types;
48 if ($code_types[$code_type]['diag']) {
49 echo "diags.push('" . attr($code_type) . "|" . attr($code) . "');\n";
53 // For IPPF only. Returns 0 = none, 1 = nonsurgical, 2 = surgical.
55 function contraceptionClass($code_type, $code) {
56 global $code_types;
57 if (!$GLOBALS['ippf_specific']) return 0;
58 $contra = 0;
59 // Get the related service codes.
60 $codesrow = sqlQuery("SELECT related_code FROM codes WHERE " .
61 "code_type = ? " .
62 " AND code = ? LIMIT 1", array($code_types[$code_type]['id'],$code) );
63 if (!empty($codesrow['related_code']) && $code_type == 'MA') {
64 $relcodes = explode(';', $codesrow['related_code']);
65 foreach ($relcodes as $relstring) {
66 if ($relstring === '') continue;
67 list($reltype, $relcode) = explode(':', $relstring);
68 if ($reltype !== 'IPPF') continue;
69 if (preg_match('/^11....110/' , $relcode)) $contra |= 1;
70 else if (preg_match('/^11....999/' , $relcode)) $contra |= 1;
71 else if (preg_match('/^112152010/' , $relcode)) $contra |= 1;
72 else if (preg_match('/^11317[1-2]111/', $relcode)) $contra |= 1;
73 else if (preg_match('/^12118[1-2].13/', $relcode)) $contra |= 2;
74 else if (preg_match('/^12118[1-2]999/', $relcode)) $contra |= 2;
77 return $contra;
80 // This writes a billing line item to the output page.
82 function echoLine($lino, $codetype, $code, $modifier, $ndc_info='',
83 $auth = TRUE, $del = FALSE, $units = NULL, $fee = NULL, $id = NULL,
84 $billed = FALSE, $code_text = NULL, $justify = NULL, $provider_id = 0, $notecodes='')
86 global $code_types, $ndc_applies, $ndc_uom_choices, $justinit, $pid;
87 global $contraception, $usbillstyle, $hasCharges;
89 if ($codetype == 'COPAY') {
90 if (!$code_text) $code_text = 'Cash';
91 if ($fee > 0) $fee = 0 - $fee;
93 if (! $code_text) {
94 $sqlArray = array();
95 $query = "select id, units, code_text from codes where code_type = ? " .
96 " and " .
97 "code = ? and ";
98 array_push($sqlArray,$code_types[$codetype]['id'],$code);
99 if ($modifier) {
100 $query .= "modifier = ?";
101 array_push($sqlArray,$modifier);
102 } else {
103 $query .= "(modifier is null or modifier = '')";
105 $result = sqlQuery($query, $sqlArray);
106 $code_text = $result['code_text'];
107 if (empty($units)) $units = max(1, intval($result['units']));
108 if (!isset($fee)) {
109 // Fees come from the prices table now.
110 $query = "SELECT prices.pr_price " .
111 "FROM patient_data, prices WHERE " .
112 "patient_data.pid = ? AND " .
113 "prices.pr_id = ? AND " .
114 "prices.pr_selector = '' AND " .
115 "prices.pr_level = patient_data.pricelevel " .
116 "LIMIT 1";
117 echo "\n<!-- $query -->\n"; // debugging
118 $prrow = sqlQuery($query, array($pid,$result['id']) );
119 $fee = empty($prrow) ? 0 : $prrow['pr_price'];
122 $fee = sprintf('%01.2f', $fee);
123 if (empty($units)) $units = 1;
124 $units = max(1, intval($units));
125 // We put unit price on the screen, not the total line item fee.
126 $price = $fee / $units;
127 $strike1 = ($id && $del) ? "<strike>" : "";
128 $strike2 = ($id && $del) ? "</strike>" : "";
129 echo " <tr>\n";
130 echo " <td class='billcell'>$strike1" .
131 ($codetype == 'COPAY' ? xl($codetype) : $codetype) . $strike2;
132 //if the line to ouput is copay, show the date here passed as $ndc_info,
133 //since this variable is not applicable in the case of copay.
134 if($codetype == 'COPAY'){
135 echo "(".htmlspecialchars($ndc_info).")";
136 $ndc_info = '';
138 if ($id) {
139 echo "<input type='hidden' name='bill[".attr($lino)."][id]' value='$id'>";
141 echo "<input type='hidden' name='bill[".attr($lino)."][code_type]' value='".attr($codetype)."'>";
142 echo "<input type='hidden' name='bill[".attr($lino)."][code]' value='".attr($code)."'>";
143 echo "<input type='hidden' name='bill[".attr($lino)."][billed]' value='".attr($billed)."'>";
144 echo "</td>\n";
145 if ($codetype != 'COPAY') {
146 echo " <td class='billcell'>$strike1" . text($code) . "$strike2</td>\n";
147 } else {
148 echo " <td class='billcell'>&nbsp;</td>\n";
150 if ($billed) {
151 if (modifiers_are_used(true)) {
152 echo " <td class='billcell'>$strike1" . text($modifier) . "$strike2" .
153 "<input type='hidden' name='bill[".attr($lino)."][mod]' value='".attr($modifier)."'></td>\n";
155 if (fees_are_used()) {
156 echo " <td class='billcell' align='right'>" . text(oeFormatMoney($price)) . "</td>\n";
157 if ($codetype != 'COPAY') {
158 echo " <td class='billcell' align='center'>" . text($units) . "</td>\n";
159 } else {
160 echo " <td class='billcell'>&nbsp;</td>\n";
163 if (justifiers_are_used()) {
164 echo " <td class='billcell' align='center'$usbillstyle>" . text($justify) . "</td>\n";
167 // Show provider for this line.
168 echo " <td class='billcell' align='center'>";
169 genProviderSelect('', '-- '.xl("Default").' --', $provider_id, true);
170 echo "</td>\n";
171 if ($code_types[$codetype]['claim'] && !$code_types[$codetype]['diag']) {
172 echo " <td class='billcell' align='center'$usbillstyle>" .
173 htmlspecialchars($notecodes, ENT_NOQUOTES) . "</td>\n";
175 else {
176 echo " <td class='billcell' align='center'$usbillstyle></td>\n";
178 echo " <td class='billcell' align='center'$usbillstyle><input type='checkbox'" .
179 ($auth ? " checked" : "") . " disabled /></td>\n";
180 echo " <td class='billcell' align='center'><input type='checkbox'" .
181 " disabled /></td>\n";
183 else { // not billed
184 if (modifiers_are_used(true)) {
185 if ($codetype != 'COPAY' && ($code_types[$codetype]['mod'] || $modifier)) {
186 echo " <td class='billcell'><input type='text' name='bill[".attr($lino)."][mod]' " .
187 "value='" . attr($modifier) . "' " .
188 "title='" . xla("Multiple modifiers can be separated by colons or spaces, maximum of 4 (M1:M2:M3:M4)") . "' " .
189 "value='" . attr($modifier) . "' size='" . attr($code_types[$codetype]['mod']) . "'></td>\n";
190 } else {
191 echo " <td class='billcell'>&nbsp;</td>\n";
194 if (fees_are_used()) {
195 if ($codetype == 'COPAY' || $code_types[$codetype]['fee'] || $fee != 0) {
196 echo " <td class='billcell' align='right'>" .
197 "<input type='text' name='bill[".attr($lino)."][price]' " .
198 "value='" . attr($price) . "' size='6'";
199 if (acl_check('acct','disc'))
200 echo " style='text-align:right'";
201 else
202 echo " style='text-align:right;background-color:transparent' readonly";
203 echo "></td>\n";
204 echo " <td class='billcell' align='center'>";
205 if ($codetype != 'COPAY') {
206 echo "<input type='text' name='bill[".attr($lino)."][units]' " .
207 "value='" . attr($units) . "' size='2' style='text-align:right'>";
208 } else {
209 echo "<input type='hidden' name='bill[".attr($lino)."][units]' value='" . attr($units) . "'>";
211 echo "</td>\n";
212 } else {
213 echo " <td class='billcell'>&nbsp;</td>\n";
214 echo " <td class='billcell'>&nbsp;</td>\n";
217 if (justifiers_are_used()) {
218 if ($code_types[$codetype]['just'] || $justify) {
219 echo " <td class='billcell' align='center'$usbillstyle ";
220 echo "title='" . xla("Select one or more diagnosis codes to justify the service") . "' >";
221 echo "<select name='bill[".attr($lino)."][justify]' onchange='setJustify(this)'>";
222 echo "<option value='" . attr($justify) . "'>" . text($justify) . "</option></select>";
223 echo "</td>\n";
224 $justinit .= "setJustify(f['bill[".attr($lino)."][justify]']);\n";
225 } else {
226 echo " <td class='billcell'$usbillstyle>&nbsp;</td>\n";
230 // Provider drop-list for this line.
231 echo " <td class='billcell' align='center'>";
232 genProviderSelect("bill[$lino][provid]", '-- '.xl("Default").' --', $provider_id);
233 echo "</td>\n";
234 if ($code_types[$codetype]['claim'] && !$code_types[$codetype]['diag']) {
235 echo " <td class='billcell' align='center'$usbillstyle><input type='text' name='bill[".attr($lino)."][notecodes]' " .
236 "value='" . htmlspecialchars($notecodes, ENT_QUOTES) . "' maxlength='10' size='8' /></td>\n";
238 else {
239 echo " <td class='billcell' align='center'$usbillstyle></td>\n";
241 echo " <td class='billcell' align='center'$usbillstyle><input type='checkbox' name='bill[".attr($lino)."][auth]' " .
242 "value='1'" . ($auth ? " checked" : "") . " /></td>\n";
243 echo " <td class='billcell' align='center'><input type='checkbox' name='bill[".attr($lino)."][del]' " .
244 "value='1'" . ($del ? " checked" : "") . " /></td>\n";
247 echo " <td class='billcell'>$strike1" . text($code_text) . "$strike2</td>\n";
248 echo " </tr>\n";
250 // If NDC info exists or may be required, add a line for it.
251 if ($codetype == 'HCPCS' && $ndc_applies && !$billed) {
252 $ndcnum = ''; $ndcuom = ''; $ndcqty = '';
253 if (preg_match('/^N4(\S+)\s+(\S\S)(.*)/', $ndc_info, $tmp)) {
254 $ndcnum = $tmp[1]; $ndcuom = $tmp[2]; $ndcqty = $tmp[3];
256 echo " <tr>\n";
257 echo " <td class='billcell' colspan='2'>&nbsp;</td>\n";
258 echo " <td class='billcell' colspan='6'>&nbsp;NDC:&nbsp;";
259 echo "<input type='text' name='bill[".attr($lino)."][ndcnum]' value='" . attr($ndcnum) . "' " .
260 "size='11' style='background-color:transparent'>";
261 echo " &nbsp;Qty:&nbsp;";
262 echo "<input type='text' name='bill[".attr($lino)."][ndcqty]' value='" . attr($ndcqty) . "' " .
263 "size='3' style='background-color:transparent;text-align:right'>";
264 echo " ";
265 echo "<select name='bill[".attr($lino)."][ndcuom]' style='background-color:transparent'>";
266 foreach ($ndc_uom_choices as $key => $value) {
267 echo "<option value='" . attr($key) . "'";
268 if ($key == $ndcuom) echo " selected";
269 echo ">" . text($value) . "</option>";
271 echo "</select>";
272 echo "</td>\n";
273 echo " </tr>\n";
275 else if ($ndc_info) {
276 echo " <tr>\n";
277 echo " <td class='billcell' colspan='2'>&nbsp;</td>\n";
278 echo " <td class='billcell' colspan='6'>&nbsp;" . xlt("NDC Data") . ": " . text($ndc_info) . "</td>\n";
279 echo " </tr>\n";
282 // For IPPF. Track contraceptive services.
283 if (!$del) $contraception |= contraceptionClass($codetype, $code);
285 if ($fee != 0) $hasCharges = true;
288 // This writes a product (drug_sales) line item to the output page.
290 function echoProdLine($lino, $drug_id, $del = FALSE, $units = NULL,
291 $fee = NULL, $sale_id = 0, $billed = FALSE)
293 global $code_types, $ndc_applies, $pid, $usbillstyle, $hasCharges;
295 $drow = sqlQuery("SELECT name FROM drugs WHERE drug_id = ?", array($drug_id) );
296 $code_text = $drow['name'];
298 $fee = sprintf('%01.2f', $fee);
299 if (empty($units)) $units = 1;
300 $units = max(1, intval($units));
301 // We put unit price on the screen, not the total line item fee.
302 $price = $fee / $units;
303 $strike1 = ($sale_id && $del) ? "<strike>" : "";
304 $strike2 = ($sale_id && $del) ? "</strike>" : "";
305 echo " <tr>\n";
306 echo " <td class='billcell'>{$strike1}" . xlt("Product") . "$strike2";
307 echo "<input type='hidden' name='prod[".attr($lino)."][sale_id]' value='" . attr($sale_id) . "'>";
308 echo "<input type='hidden' name='prod[".attr($lino)."][drug_id]' value='" . attr($drug_id) . "'>";
309 echo "<input type='hidden' name='prod[".attr($lino)."][billed]' value='" . attr($billed) . "'>";
310 echo "</td>\n";
311 echo " <td class='billcell'>$strike1" . text($drug_id) . "$strike2</td>\n";
312 if (modifiers_are_used(true)) {
313 echo " <td class='billcell'>&nbsp;</td>\n";
315 if ($billed) {
316 if (fees_are_used()) {
317 echo " <td class='billcell' align='right'>" . text(oeFormatMoney($price)) . "</td>\n";
318 echo " <td class='billcell' align='center'>" . text($units) . "</td>\n";
320 if (justifiers_are_used()) {
321 echo " <td class='billcell' align='center'$usbillstyle>&nbsp;</td>\n"; // justify
323 echo " <td class='billcell' align='center'>&nbsp;</td>\n"; // provider
324 echo " <td class='billcell' align='center'$usbillstyle>&nbsp;</td>\n"; // auth
325 echo " <td class='billcell' align='center'><input type='checkbox'" . // del
326 " disabled /></td>\n";
327 } else {
328 if (fees_are_used()) {
329 echo " <td class='billcell' align='right'>" .
330 "<input type='text' name='prod[".attr($lino)."][price]' " .
331 "value='" . attr($price) . "' size='6'";
332 if (acl_check('acct','disc'))
333 echo " style='text-align:right'";
334 else
335 echo " style='text-align:right;background-color:transparent' readonly";
336 echo "></td>\n";
337 echo " <td class='billcell' align='center'>";
338 echo "<input type='text' name='prod[".attr($lino)."][units]' " .
339 "value='" . attr($units) . "' size='2' style='text-align:right'>";
340 echo "</td>\n";
342 if (justifiers_are_used()) {
343 echo " <td class='billcell'$usbillstyle>&nbsp;</td>\n"; // justify
345 echo " <td class='billcell' align='center'>&nbsp;</td>\n"; // provider
346 echo " <td class='billcell' align='center'$usbillstyle>&nbsp;</td>\n"; // auth
347 echo " <td class='billcell' align='center'><input type='checkbox' name='prod[".attr($lino)."][del]' " .
348 "value='1'" . ($del ? " checked" : "") . " /></td>\n";
351 echo " <td class='billcell'>$strike1" . text($code_text) . "$strike2</td>\n";
352 echo " </tr>\n";
354 if ($fee != 0) $hasCharges = true;
357 // Build a drop-down list of providers. This includes users who
358 // have the word "provider" anywhere in their "additional info"
359 // field, so that we can define providers (for billing purposes)
360 // who do not appear in the calendar.
362 function genProviderSelect($selname, $toptext, $default=0, $disabled=false) {
363 $query = "SELECT id, lname, fname FROM users WHERE " .
364 "( authorized = 1 OR info LIKE '%provider%' ) AND username != '' " .
365 "AND active = 1 AND ( info IS NULL OR info NOT LIKE '%Inactive%' ) " .
366 "ORDER BY lname, fname";
367 $res = sqlStatement($query);
368 echo " <select name='" . attr($selname) . "'";
369 if ($disabled) echo " disabled";
370 echo ">\n";
371 echo " <option value=''>" . text($toptext) . "\n";
372 while ($row = sqlFetchArray($res)) {
373 $provid = $row['id'];
374 echo " <option value='" . attr($provid) . "'";
375 if ($provid == $default) echo " selected";
376 echo ">" . text($row['lname'] . ", " . $row['fname']) . "\n";
378 echo " </select>\n";
381 // This is just for IPPF, to indicate if the visit includes contraceptive services.
382 $contraception = 0;
384 // Possible units of measure for NDC drug quantities.
386 $ndc_uom_choices = array(
387 'ML' => 'ML',
388 'GR' => 'Grams',
389 'ME' => 'Milligrams',
390 'F2' => 'I.U.',
391 'UN' => 'Units'
394 // $FEE_SHEET_COLUMNS should be defined in codes.php.
395 if (empty($FEE_SHEET_COLUMNS)) $FEE_SHEET_COLUMNS = 2;
397 $returnurl = $GLOBALS['concurrent_layout'] ? 'encounter_top.php' : 'patient_encounter.php';
399 // Update price level in patient demographics.
400 if (!empty($_POST['pricelevel'])) {
401 sqlStatement("UPDATE patient_data SET pricelevel = ? WHERE pid = ?", array($_POST['pricelevel'],$pid) );
404 // Get some info about this visit.
405 $visit_row = sqlQuery("SELECT fe.date, opc.pc_catname " .
406 "FROM form_encounter AS fe " .
407 "LEFT JOIN openemr_postcalendar_categories AS opc ON opc.pc_catid = fe.pc_catid " .
408 "WHERE fe.pid = ? AND fe.encounter = ? LIMIT 1", array($pid,$encounter) );
409 $visit_date = substr($visit_row['date'], 0, 10);
411 // If Save or Save-and-Close was clicked, save the new and modified billing
412 // lines; then if no error, redirect to $returnurl.
414 if ($_POST['bn_save'] || $_POST['bn_save_close']) {
415 $main_provid = 0 + $_POST['ProviderID'];
416 $main_supid = 0 + $_POST['SupervisorID'];
417 if ($main_supid == $main_provid) $main_supid = 0;
418 $default_warehouse = $_POST['default_warehouse'];
420 $bill = $_POST['bill'];
421 $copay_update = FALSE;
422 $update_session_id = '';
423 $ct0 = '';//takes the code type of the first fee type code type entry from the fee sheet, against which the copay is posted
424 $cod0 = '';//takes the code of the first fee type code type entry from the fee sheet, against which the copay is posted
425 $mod0 = '';//takes the modifier of the first fee type code type entry from the fee sheet, against which the copay is posted
426 for ($lino = 1; $bill["$lino"]['code_type']; ++$lino) {
427 $iter = $bill["$lino"];
428 $code_type = $iter['code_type'];
429 $code = $iter['code'];
430 $del = $iter['del'];
432 // Skip disabled (billed) line items.
433 if ($iter['billed']) continue;
435 $id = $iter['id'];
436 $modifier = trim($iter['mod']);
437 if( !($cod0) && ($code_types[$code_type]['fee'] == 1) ){
438 $mod0 = $modifier;
439 $cod0 = $code;
440 $ct0 = $code_type;
442 $units = max(1, intval(trim($iter['units'])));
443 $fee = sprintf('%01.2f',(0 + trim($iter['price'])) * $units);
445 if($code_type == 'COPAY'){
446 if($id == ''){
447 //adding new copay from fee sheet into ar_session and ar_activity tables
448 if($fee < 0){
449 $fee = $fee * -1;
451 $session_id = idSqlStatement("INSERT INTO ar_session(payer_id,user_id,pay_total,payment_type,description,".
452 "patient_id,payment_method,adjustment_code,post_to_date) VALUES('0',?,?,'patient','COPAY',?,'','patient_payment',now())",
453 array($_SESSION['authId'],$fee,$pid));
454 SqlStatement("INSERT INTO ar_activity (pid,encounter,code_type,code,modifier,payer_type,post_time,post_user,session_id,".
455 "pay_amount,account_code) VALUES (?,?,?,?,?,0,now(),?,?,?,'PCP')",
456 array($pid,$encounter,$ct0,$cod0,$mod0,$_SESSION['authId'],$session_id,$fee));
457 }else{
458 //editing copay saved to ar_session and ar_activity
459 if($fee < 0){
460 $fee = $fee * -1;
462 $session_id = $id;
463 $res_amount = sqlQuery("SELECT pay_amount FROM ar_activity WHERE pid=? AND encounter=? AND session_id=?",
464 array($pid,$encounter,$session_id));
465 if($fee != $res_amount['pay_amount']){
466 sqlStatement("UPDATE ar_session SET user_id=?,pay_total=?,modified_time=now(),post_to_date=now() WHERE session_id=?",
467 array($_SESSION['authId'],$fee,$session_id));
468 sqlStatement("UPDATE ar_activity SET code_type=?, code=?, modifier=?, post_user=?, post_time=now(),".
469 "pay_amount=?, modified_time=now() WHERE pid=? AND encounter=? AND account_code='PCP' AND session_id=?",
470 array($ct0,$cod0,$mod0,$_SESSION['authId'],$fee,$pid,$encounter,$session_id));
473 if(!$cod0){
474 $copay_update = TRUE;
475 $update_session_id = $session_id;
477 continue;
479 $justify = trim($iter['justify']);
480 $notecodes = trim($iter['notecodes']);
481 if ($justify) $justify = str_replace(',', ':', $justify) . ':';
482 // $auth = $iter['auth'] ? "1" : "0";
483 $auth = "1";
484 $provid = 0 + $iter['provid'];
486 $ndc_info = '';
487 if ($iter['ndcnum']) {
488 $ndc_info = 'N4' . trim($iter['ndcnum']) . ' ' . $iter['ndcuom'] .
489 trim($iter['ndcqty']);
492 // If the item is already in the database...
493 if ($id) {
494 if ($del) {
495 deleteBilling($id);
497 else {
498 // authorizeBilling($id, $auth);
499 sqlQuery("UPDATE billing SET code = ?, " .
500 "units = ?, fee = ?, modifier = ?, " .
501 "authorized = ?, provider_id = ?, " .
502 "ndc_info = ?, justify = ?, notecodes = ? " .
503 "WHERE " .
504 "id = ? AND billed = 0 AND activity = 1", array($code,$units,$fee,$modifier,$auth,$provid,$ndc_info,$justify,$notecodes,$id) );
508 // Otherwise it's a new item...
509 else if (! $del) {
510 $code_text = lookup_code_descriptions($code_type.":".$code);
511 addBilling($encounter, $code_type, $code, $code_text, $pid, $auth,
512 $provid, $modifier, $units, $fee, $ndc_info, $justify, 0, $notecodes);
514 } // end for
516 //if modifier is not inserted during loop update the record using the first
517 //non-empty modifier and code
518 if($copay_update == TRUE && $update_session_id != '' && $mod0 != ''){
519 sqlStatement("UPDATE ar_activity SET code_type=?, code=?, modifier=?".
520 " WHERE pid=? AND encounter=? AND account_code='PCP' AND session_id=?",
521 array($ct0,$cod0,$mod0,$pid,$encounter,$update_session_id));
524 // Doing similarly to the above but for products.
525 $prod = $_POST['prod'];
526 for ($lino = 1; $prod["$lino"]['drug_id']; ++$lino) {
527 $iter = $prod["$lino"];
529 if (!empty($iter['billed'])) continue;
531 $drug_id = $iter['drug_id'];
532 $sale_id = $iter['sale_id']; // present only if already saved
533 $units = max(1, intval(trim($iter['units'])));
534 $fee = sprintf('%01.2f',(0 + trim($iter['price'])) * $units);
535 $del = $iter['del'];
537 // If the item is already in the database...
538 if ($sale_id) {
539 if ($del) {
540 // Zero out this sale and reverse its inventory update. We bring in
541 // drug_sales twice so that the original quantity can be referenced
542 // unambiguously.
543 sqlStatement("UPDATE drug_sales AS dsr, drug_sales AS ds, " .
544 "drug_inventory AS di " .
545 "SET di.on_hand = di.on_hand + dsr.quantity, " .
546 "ds.quantity = 0, ds.fee = 0 WHERE " .
547 "dsr.sale_id = ? AND ds.sale_id = dsr.sale_id AND " .
548 "di.inventory_id = ds.inventory_id", array($sale_id) );
549 // And delete the sale for good measure.
550 sqlStatement("DELETE FROM drug_sales WHERE sale_id = ?", array($sale_id) );
552 else {
553 // Modify the sale and adjust inventory accordingly.
554 $query = "UPDATE drug_sales AS dsr, drug_sales AS ds, " .
555 "drug_inventory AS di " .
556 "SET di.on_hand = di.on_hand + dsr.quantity - " . add_escape_custom($units) . ", " .
557 "ds.quantity = ?, ds.fee = ?, " .
558 "ds.sale_date = ? WHERE " .
559 "dsr.sale_id = ? AND ds.sale_id = dsr.sale_id AND " .
560 "di.inventory_id = ds.inventory_id";
561 sqlStatement($query, array($units,$fee,$visit_date,$sale_id) );
565 // Otherwise it's a new item...
566 else if (! $del) {
567 $sale_id = sellDrug($drug_id, $units, $fee, $pid, $encounter, 0,
568 $visit_date, '', $default_warehouse);
569 if (!$sale_id) die(xlt("Insufficient inventory for product ID") . " \"" . text($drug_id) . "\".");
571 } // end for
573 // Set the main/default service provider in the new-encounter form.
574 /*******************************************************************
575 sqlStatement("UPDATE forms, users SET forms.user = users.username WHERE " .
576 "forms.pid = '$pid' AND forms.encounter = '$encounter' AND " .
577 "forms.formdir = 'newpatient' AND users.id = '$provid'");
578 *******************************************************************/
579 sqlStatement("UPDATE form_encounter SET provider_id = ?, " .
580 "supervisor_id = ? WHERE " .
581 "pid = ? AND encounter = ?", array($main_provid,$main_supid,$pid,$encounter) );
583 // Save-and-Close is currently IPPF-specific but might be more generally
584 // useful. It provides the ability to mark an encounter as billed
585 // directly from the Fee Sheet, if there are no charges.
586 if ($_POST['bn_save_close']) {
587 $tmp1 = sqlQuery("SELECT SUM(ABS(fee)) AS sum FROM drug_sales WHERE " .
588 "pid = ? AND encounter = ?", array($pid,$encounter) );
589 $tmp2 = sqlQuery("SELECT SUM(ABS(fee)) AS sum FROM billing WHERE " .
590 "pid = ? AND encounter = ? AND billed = 0 AND " .
591 "activity = 1", array($pid,$encounter) );
592 if ($tmp1['sum'] + $tmp2['sum'] == 0) {
593 sqlStatement("update drug_sales SET billed = 1 WHERE " .
594 "pid = ? AND encounter = ? AND billed = 0", array($pid,$encounter));
595 sqlStatement("UPDATE billing SET billed = 1, bill_date = NOW() WHERE " .
596 "pid = ? AND encounter = ? AND billed = 0 AND " .
597 "activity = 1", array($pid,$encounter));
599 else {
600 // Would be good to display an error message here... they clicked
601 // Save and Close but the close could not be done. However the
602 // framework does not provide an easy way to do that.
606 // More IPPF stuff.
607 if (!empty($_POST['contrastart'])) {
608 $contrastart = $_POST['contrastart'];
609 sqlStatement("UPDATE patient_data SET contrastart = ?" .
610 " WHERE pid = ?", array($contrastart,$pid) );
613 // Note: Taxes are computed at checkout time (in pos_checkout.php which
614 // also posts to SL). Currently taxes with insurance claims make no sense,
615 // so for now we'll ignore tax computation in the insurance billing logic.
617 formHeader("Redirecting....");
618 formJump();
619 formFooter();
620 exit;
623 $billresult = getBillingByEncounter($pid, $encounter, "*");
625 <html>
626 <head>
627 <?php html_header_show(); ?>
628 <link rel="stylesheet" href="<?php echo $css_header;?>" type="text/css">
629 <style>
630 .billcell { font-family: sans-serif; font-size: 10pt }
631 </style>
632 <script language="JavaScript">
634 var diags = new Array();
636 <?php
637 if ($billresult) {
638 foreach ($billresult as $iter) {
639 genDiagJS($iter["code_type"], trim($iter["code"]));
642 if ($_POST['bill']) {
643 foreach ($_POST['bill'] as $iter) {
644 if ($iter["del"]) continue; // skip if Delete was checked
645 if ($iter["id"]) continue; // skip if it came from the database
646 genDiagJS($iter["code_type"], $iter["code"]);
649 if ($_POST['newcodes']) {
650 $arrcodes = explode('~', $_POST['newcodes']);
651 foreach ($arrcodes as $codestring) {
652 if ($codestring === '') continue;
653 $arrcode = explode('|', $codestring);
654 list($code, $modifier) = explode(":", $arrcode[1]);
655 genDiagJS($arrcode[0], $code);
660 // This is invoked by <select onchange> for the various dropdowns,
661 // including search results.
662 function codeselect(selobj) {
663 var i = selobj.selectedIndex;
664 if (i > 0) {
665 top.restoreSession();
666 var f = document.forms[0];
667 f.newcodes.value = selobj.options[i].value;
668 f.submit();
672 function copayselect() {
673 top.restoreSession();
674 var f = document.forms[0];
675 f.newcodes.value = 'COPAY||';
676 f.submit();
679 function validate(f) {
680 for (var lino = 1; f['bill['+lino+'][code_type]']; ++lino) {
681 var pfx = 'bill['+lino+']';
682 if (f[pfx+'[ndcnum]'] && f[pfx+'[ndcnum]'].value) {
683 // Check NDC number format.
684 var ndcok = true;
685 var ndc = f[pfx+'[ndcnum]'].value;
686 var a = ndc.split('-');
687 if (a.length != 3) {
688 ndcok = false;
690 else if (a[0].length < 1 || a[1].length < 1 || a[2].length < 1 ||
691 a[0].length > 5 || a[1].length > 4 || a[2].length > 2) {
692 ndcok = false;
694 else {
695 for (var i = 0; i < 3; ++i) {
696 for (var j = 0; j < a[i].length; ++j) {
697 var c = a[i].charAt(j);
698 if (c < '0' || c > '9') ndcok = false;
702 if (!ndcok) {
703 alert('<?php echo addslashes(xl('Format incorrect for NDC')) ?> "' + ndc +
704 '", <?php echo addslashes(xl('should be like nnnnn-nnnn-nn')) ?>');
705 if (f[pfx+'[ndcnum]'].focus) f[pfx+'[ndcnum]'].focus();
706 return false;
708 // Check for valid quantity.
709 var qty = f[pfx+'[ndcqty]'].value - 0;
710 if (isNaN(qty) || qty <= 0) {
711 alert('<?php echo addslashes(xl('Quantity for NDC')) ?> "' + ndc +
712 '" <?php echo addslashes(xl('is not valid (decimal fractions are OK).')) ?>');
713 if (f[pfx+'[ndcqty]'].focus) f[pfx+'[ndcqty]'].focus();
714 return false;
718 top.restoreSession();
719 return true;
722 // When a justify selection is made, apply it to the current list for
723 // this procedure and then rebuild its selection list.
725 function setJustify(seljust) {
726 var theopts = seljust.options;
727 var jdisplay = theopts[0].text;
728 // Compute revised justification string. Note this does nothing if
729 // the first entry is still selected, which is handy at startup.
730 if (seljust.selectedIndex > 0) {
731 var newdiag = seljust.value;
732 if (newdiag.length == 0) {
733 jdisplay = '';
735 else {
736 if (jdisplay.length) jdisplay += ',';
737 jdisplay += newdiag;
740 // Rebuild selection list.
741 var jhaystack = ',' + jdisplay + ',';
742 var j = 0;
743 theopts.length = 0;
744 theopts[j++] = new Option(jdisplay,jdisplay,true,true);
745 for (var i = 0; i < diags.length; ++i) {
746 if (jhaystack.indexOf(',' + diags[i] + ',') < 0) {
747 theopts[j++] = new Option(diags[i],diags[i],false,false);
750 theopts[j++] = new Option('Clear','',false,false);
753 </script>
754 </head>
756 <body class="body_top">
757 <form method="post" action="<?php echo $rootdir; ?>/forms/fee_sheet/new.php"
758 onsubmit="return validate(this)">
759 <span class="title"><?php echo xlt('Fee Sheet'); ?></span><br>
760 <input type='hidden' name='newcodes' value=''>
762 <center>
764 <?php
765 $isBilled = isEncounterBilled($pid, $encounter);
766 if ($isBilled) {
767 echo "<p><font color='green'>" . xlt("This encounter has been billed. If you need to change it, it must be re-opened.") . "</font></p>\n";
769 else { // the encounter is not yet billed
772 <table width='95%'>
773 <?php
774 $i = 0;
775 $last_category = '';
777 // Create drop-lists based on the fee_sheet_options table.
778 $res = sqlStatement("SELECT * FROM fee_sheet_options " .
779 "ORDER BY fs_category, fs_option");
780 while ($row = sqlFetchArray($res)) {
781 $fs_category = $row['fs_category'];
782 $fs_option = $row['fs_option'];
783 $fs_codes = $row['fs_codes'];
784 if($fs_category !== $last_category) {
785 endFSCategory();
786 $last_category = $fs_category;
787 ++$i;
788 echo ($i <= 1) ? " <tr>\n" : "";
789 echo " <td width='50%' align='center' nowrap>\n";
790 echo " <select style='width:96%' onchange='codeselect(this)'>\n";
791 echo " <option value=''> " . text(substr($fs_category, 1)) . "</option>\n";
793 echo " <option value='" . attr($fs_codes) . "'>" . text(substr($fs_option, 1)) . "</option>\n";
795 endFSCategory();
797 // Create drop-lists based on categories defined within the codes.
798 $pres = sqlStatement("SELECT option_id, title FROM list_options " .
799 "WHERE list_id = 'superbill' ORDER BY seq");
800 while ($prow = sqlFetchArray($pres)) {
801 global $code_types;
802 ++$i;
803 echo ($i <= 1) ? " <tr>\n" : "";
804 echo " <td width='50%' align='center' nowrap>\n";
805 echo " <select style='width:96%' onchange='codeselect(this)'>\n";
806 echo " <option value=''> " . text($prow['title']) . "\n";
807 $res = sqlStatement("SELECT code_type, code, code_text,modifier FROM codes " .
808 "WHERE superbill = ? AND active = 1 " .
809 "ORDER BY code_text", array($prow['option_id']) );
810 while ($row = sqlFetchArray($res)) {
811 $ctkey = alphaCodeType($row['code_type']);
812 if ($code_types[$ctkey]['nofs']) continue;
813 echo " <option value='" . attr($ctkey) . "|" .
814 attr($row['code']) . ':'. attr($row['modifier']) . "|'>" . text($row['code_text']) . "</option>\n";
816 echo " </select>\n";
817 echo " </td>\n";
818 if ($i >= $FEE_SHEET_COLUMNS) {
819 echo " </tr>\n";
820 $i = 0;
824 // Create one more drop-list, for Products.
825 if ($GLOBALS['sell_non_drug_products']) {
826 ++$i;
827 echo ($i <= 1) ? " <tr>\n" : "";
828 echo " <td width='50%' align='center' nowrap>\n";
829 echo " <select name='Products' style='width:96%' onchange='codeselect(this)'>\n";
830 echo " <option value=''> " . xlt('Products') . "\n";
831 $tres = sqlStatement("SELECT dt.drug_id, dt.selector, d.name " .
832 "FROM drug_templates AS dt, drugs AS d WHERE " .
833 "d.drug_id = dt.drug_id AND d.active = 1 " .
834 "ORDER BY d.name, dt.selector, dt.drug_id");
835 while ($trow = sqlFetchArray($tres)) {
836 echo " <option value='PROD|" . attr($trow['drug_id']) . '|' . attr($trow['selector']) . "'>" .
837 text($trow['drug_id']) . ':' . text($trow['selector']);
838 if ($trow['name'] !== $trow['selector']) echo ' ' . text($trow['name']);
839 echo "</option>\n";
841 echo " </select>\n";
842 echo " </td>\n";
843 if ($i >= $FEE_SHEET_COLUMNS) {
844 echo " </tr>\n";
845 $i = 0;
849 $search_type = $default_search_type;
850 if ($_POST['search_type']) $search_type = $_POST['search_type'];
852 $ndc_applies = true; // Assume all payers require NDC info.
854 echo $i ? " <td></td>\n </tr>\n" : "";
855 echo " <tr>\n";
856 echo " <td colspan='" . attr($FEE_SHEET_COLUMNS) . "' align='center' nowrap>\n";
858 // If Search was clicked, do it and write the list of results here.
859 // There's no limit on the number of results!
861 $numrows = 0;
862 if ($_POST['bn_search'] && $_POST['search_term']) {
863 $res = sequential_code_set_search($search_type,$_POST['search_term']);
864 if (!empty($res)) {
865 $numrows = sqlNumRows($res);
869 echo " <select name='Search Results' style='width:98%' " .
870 "onchange='codeselect(this)'";
871 if (! $numrows) echo ' disabled';
872 echo ">\n";
873 echo " <option value=''> " . xlt("Search Results") . " ($numrows " . xlt("items") . ")\n";
875 if ($numrows) {
876 while ($row = sqlFetchArray($res)) {
877 $code = $row['code'];
878 if ($row['modifier']) $code .= ":" . $row['modifier'];
879 echo " <option value='" . attr($search_type) . "|" . attr($code) . "|'>" . text($code) . " " .
880 text($row['code_text']) . "</option>\n";
884 echo " </select>\n";
885 echo " </td>\n";
886 echo " </tr>\n";
889 </table>
891 <p style='margin-top:8px;margin-bottom:8px'>
892 <table>
893 <tr>
894 <td>
895 <input type='button' value='<?php echo xla('Add Copay');?>'
896 onclick="copayselect()" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
897 </td>
898 <td>
899 <?php echo xlt('Search'); ?>&nbsp;
900 <select name='search_type'>
901 <?php
902 foreach ($code_types as $key => $value) {
903 if (!empty($value['nofs'])) continue;
904 echo " <option value='" . attr($key) . "'";
905 if ($key == $default_search_type) echo " selected";
906 echo " />" . xlt($value['label']) . "</option>";
909 </select>
910 <?php echo xlt('for'); ?>&nbsp;
911 </td>
912 <td>
913 <input type='text' name='search_term' value=''> &nbsp;
914 </td>
915 <td>
916 <input type='submit' name='bn_search' value='<?php echo xla('Search');?>'>
917 </td>
918 </tr>
919 </table>
920 </p>
921 <p style='margin-top:16px;margin-bottom:8px'>
923 <?php } // end encounter not billed ?>
925 <table cellspacing='5'>
926 <tr>
927 <td class='billcell'><b><?php echo xlt('Type');?></b></td>
928 <td class='billcell'><b><?php echo xlt('Code');?></b></td>
929 <?php if (modifiers_are_used(true)) { ?>
930 <td class='billcell'><b><?php echo xlt('Modifiers');?></b></td>
931 <?php } ?>
932 <?php if (fees_are_used()) { ?>
933 <td class='billcell' align='right'><b><?php echo xlt('Price');?></b>&nbsp;</td>
934 <td class='billcell' align='center'><b><?php echo xlt('Units');?></b></td>
935 <?php } ?>
936 <?php if (justifiers_are_used()) { ?>
937 <td class='billcell' align='center'<?php echo $usbillstyle; ?>><b><?php echo xlt('Justify');?></b></td>
938 <?php } ?>
939 <td class='billcell' align='center'><b><?php echo xlt('Provider');?></b></td>
940 <td class='billcell' align='center'<?php echo $usbillstyle; ?>><b><?php echo xlt('Note Codes');?></b></td>
941 <td class='billcell' align='center'<?php echo $usbillstyle; ?>><b><?php echo xlt('Auth');?></b></td>
942 <td class='billcell' align='center'><b><?php echo xlt('Delete');?></b></td>
943 <td class='billcell'><b><?php echo xlt('Description');?></b></td>
944 </tr>
946 <?php
947 $justinit = "var f = document.forms[0];\n";
949 // $encounter_provid = -1;
951 $hasCharges = false;
953 // Generate lines for items already in the billing table for this encounter,
954 // and also set the rendering provider if we come across one.
956 $bill_lino = 0;
957 if ($billresult) {
958 foreach ($billresult as $iter) {
959 ++$bill_lino;
960 $bline = $_POST['bill']["$bill_lino"];
961 $del = $bline['del']; // preserve Delete if checked
963 $modifier = trim($iter["modifier"]);
964 $units = $iter["units"];
965 $fee = $iter["fee"];
966 $authorized = $iter["authorized"];
967 $ndc_info = $iter["ndc_info"];
968 $justify = trim($iter['justify']);
969 $notecodes = trim($iter['notecodes']);
970 if ($justify) $justify = substr(str_replace(':', ',', $justify), 0, strlen($justify) - 1);
971 $provider_id = $iter['provider_id'];
973 // Also preserve other items from the form, if present.
974 if ($bline['id'] && !$iter["billed"]) {
975 $modifier = trim($bline['mod']);
976 $units = max(1, intval(trim($bline['units'])));
977 $fee = sprintf('%01.2f',(0 + trim($bline['price'])) * $units);
978 $authorized = $bline['auth'];
979 $ndc_info = '';
980 if ($bline['ndcnum']) {
981 $ndc_info = 'N4' . trim($bline['ndcnum']) . ' ' . $bline['ndcuom'] .
982 trim($bline['ndcqty']);
984 $justify = $bline['justify'];
985 $notecodes = trim($bline['notecodes']);
986 $provider_id = 0 + $bline['provid'];
989 if($iter['code_type'] == 'COPAY'){//moved copay display to below
990 --$bill_lino;
991 continue;
994 // list($code, $modifier) = explode("-", $iter["code"]);
995 echoLine($bill_lino, $iter["code_type"], trim($iter["code"]),
996 $modifier, $ndc_info, $authorized,
997 $del, $units, $fee, $iter["id"], $iter["billed"],
998 $iter["code_text"], $justify, $provider_id, $notecodes);
1002 $resMoneyGot = sqlStatement("SELECT pay_amount as PatientPay,session_id as id,date(post_time) as date ".
1003 "FROM ar_activity where pid =? and encounter =? and payer_type=0 and account_code='PCP'",
1004 array($pid,$encounter));//new fees screen copay gives account_code='PCP'
1005 while($rowMoneyGot = sqlFetchArray($resMoneyGot)){
1006 $PatientPay=$rowMoneyGot['PatientPay']*-1;
1007 $id=$rowMoneyGot['id'];
1008 echoLine(++$bill_lino,'COPAY','','',$rowMoneyGot['date'],'1','','',$PatientPay,$id);
1011 // Echo new billing items from this form here, but omit any line
1012 // whose Delete checkbox is checked.
1014 if ($_POST['bill']) {
1015 foreach ($_POST['bill'] as $key => $iter) {
1016 if ($iter["id"]) continue; // skip if it came from the database
1017 if ($iter["del"]) continue; // skip if Delete was checked
1018 $ndc_info = '';
1019 if ($iter['ndcnum']) {
1020 $ndc_info = 'N4' . trim($iter['ndcnum']) . ' ' . $iter['ndcuom'] .
1021 trim($iter['ndcqty']);
1023 // $fee = 0 + trim($iter['fee']);
1024 $units = max(1, intval(trim($iter['units'])));
1025 $fee = sprintf('%01.2f',(0 + trim($iter['price'])) * $units);
1026 //the date is passed as $ndc_info, since this variable is not applicable in the case of copay.
1027 $ndc_info = '';
1028 if ($iter['code_type'] == 'COPAY'){
1029 $ndc_info = date("Y-m-d");
1030 if($fee > 0)
1031 $fee = 0 - $fee;
1033 echoLine(++$bill_lino, $iter["code_type"], $iter["code"], trim($iter["mod"]),
1034 $ndc_info, $iter["auth"], $iter["del"], $units,
1035 $fee, NULL, FALSE, NULL, $iter["justify"], 0 + $iter['provid'],
1036 $iter['notecodes']);
1040 // Generate lines for items already in the drug_sales table for this encounter.
1042 $query = "SELECT * FROM drug_sales WHERE " .
1043 "pid = ? AND encounter = ? " .
1044 "ORDER BY sale_id";
1045 $sres = sqlStatement($query, array($pid,$encounter) );
1046 $prod_lino = 0;
1047 while ($srow = sqlFetchArray($sres)) {
1048 ++$prod_lino;
1049 $pline = $_POST['prod']["$prod_lino"];
1050 $del = $pline['del']; // preserve Delete if checked
1051 $sale_id = $srow['sale_id'];
1052 $drug_id = $srow['drug_id'];
1053 $units = $srow['quantity'];
1054 $fee = $srow['fee'];
1055 $billed = $srow['billed'];
1056 // Also preserve other items from the form, if present and unbilled.
1057 if ($pline['sale_id'] && !$srow['billed']) {
1058 // $units = trim($pline['units']);
1059 // $fee = trim($pline['fee']);
1060 $units = max(1, intval(trim($pline['units'])));
1061 $fee = sprintf('%01.2f',(0 + trim($pline['price'])) * $units);
1063 echoProdLine($prod_lino, $drug_id, $del, $units, $fee, $sale_id, $billed);
1066 // Echo new product items from this form here, but omit any line
1067 // whose Delete checkbox is checked.
1069 if ($_POST['prod']) {
1070 foreach ($_POST['prod'] as $key => $iter) {
1071 if ($iter["sale_id"]) continue; // skip if it came from the database
1072 if ($iter["del"]) continue; // skip if Delete was checked
1073 // $fee = 0 + trim($iter['fee']);
1074 $units = max(1, intval(trim($iter['units'])));
1075 $fee = sprintf('%01.2f',(0 + trim($iter['price'])) * $units);
1076 echoProdLine(++$prod_lino, $iter['drug_id'], FALSE, $units, $fee);
1080 // If new billing code(s) were <select>ed, add their line(s) here.
1082 if ($_POST['newcodes']) {
1083 $arrcodes = explode('~', $_POST['newcodes']);
1084 foreach ($arrcodes as $codestring) {
1085 if ($codestring === '') continue;
1086 $arrcode = explode('|', $codestring);
1087 $newtype = $arrcode[0];
1088 $newcode = $arrcode[1];
1089 $newsel = $arrcode[2];
1090 if ($newtype == 'COPAY') {
1091 $tmp = sqlQuery("SELECT copay FROM insurance_data WHERE pid = ? " .
1092 "AND type = 'primary' ORDER BY date DESC LIMIT 1", array($pid) );
1093 $code = sprintf('%01.2f', 0 + $tmp['copay']);
1094 echoLine(++$bill_lino, $newtype, $code, '', date("Y-m-d"), '1', '0', '1',
1095 sprintf('%01.2f', 0 - $code));
1097 else if ($newtype == 'PROD') {
1098 $result = sqlQuery("SELECT * FROM drug_templates WHERE " .
1099 "drug_id = ? AND selector = ?", array($newcode,$newsel) );
1100 $units = max(1, intval($result['quantity']));
1101 $prrow = sqlQuery("SELECT prices.pr_price " .
1102 "FROM patient_data, prices WHERE " .
1103 "patient_data.pid = ? AND " .
1104 "prices.pr_id = ? AND " .
1105 "prices.pr_selector = ? AND " .
1106 "prices.pr_level = patient_data.pricelevel " .
1107 "LIMIT 1", array($pid,$newcode,$newsel) );
1108 $fee = empty($prrow) ? 0 : $prrow['pr_price'];
1109 echoProdLine(++$prod_lino, $newcode, FALSE, $units, $fee);
1111 else {
1112 list($code, $modifier) = explode(":", $newcode);
1113 $ndc_info = '';
1114 // If HCPCS, find last NDC string used for this code.
1115 if ($newtype == 'HCPCS' && $ndc_applies) {
1116 $tmp = sqlQuery("SELECT ndc_info FROM billing WHERE " .
1117 "code_type = ? AND code = ? AND ndc_info LIKE 'N4%' " .
1118 "ORDER BY date DESC LIMIT 1", array($newtype,$code) );
1119 if (!empty($tmp)) $ndc_info = $tmp['ndc_info'];
1121 echoLine(++$bill_lino, $newtype, $code, trim($modifier), $ndc_info);
1126 $tmp = sqlQuery("SELECT provider_id, supervisor_id FROM form_encounter " .
1127 "WHERE pid = ? AND encounter = ? " .
1128 "ORDER BY id DESC LIMIT 1", array($pid,$encounter) );
1129 $encounter_provid = 0 + $tmp['provider_id'];
1130 $encounter_supid = 0 + $tmp['supervisor_id'];
1132 </table>
1133 </p>
1135 <br />
1136 &nbsp;
1138 <?php
1139 // Choose rendering and supervising providers.
1140 echo "<span class='billcell'><b>\n";
1141 echo xlt('Providers') . ": &nbsp;";
1143 echo "&nbsp;&nbsp;" . xlt('Rendering') . "\n";
1144 genProviderSelect('ProviderID', '-- '.xl("Please Select").' --', $encounter_provid, $isBilled);
1146 if (!$GLOBALS['ippf_specific']) {
1147 echo "&nbsp;&nbsp;" . xlt('Supervising') . "\n";
1148 genProviderSelect('SupervisorID', '-- '.xl("N/A").' --', $encounter_supid, $isBilled);
1151 echo "</b></span>\n";
1155 &nbsp;
1157 <?php
1158 // If applicable, ask for the contraceptive services start date.
1159 $trow = sqlQuery("SELECT count(*) AS count FROM layout_options WHERE " .
1160 "form_id = 'DEM' AND field_id = 'contrastart' AND uor > 0");
1161 if ($trow['count'] && $contraception && !$isBilled) {
1162 $date1 = substr($visit_row['date'], 0, 10);
1163 // If admission or surgical, then force contrastart.
1164 if ($contraception > 1 ||
1165 strpos(strtolower($visit_row['pc_catname']), 'admission') !== false)
1167 echo " <input type='hidden' name='contrastart' value='" . attr($date1) . "' />\n";
1169 else {
1170 // echo "<!-- contraception = $contraception -->\n"; // debugging
1171 $trow = sqlQuery("SELECT contrastart " .
1172 "FROM patient_data WHERE " .
1173 "pid = ? LIMIT 1", array($pid) );
1174 if (empty($trow['contrastart']) || substr($trow['contrastart'], 0, 4) == '0000') {
1175 $date0 = date('Y-m-d', strtotime($date1) - (60 * 60 * 24));
1176 echo " <select name='contrastart'>\n";
1177 echo " <option value='" . attr($date1) . "'>" . xlt('This visit begins new contraceptive use') . "</option>\n";
1178 echo " <option value='" . attr($date0) . "'>" . xlt('Contraceptive services previously started') . "</option>\n";
1179 echo " <option value=''>" . xlt('None of the above') . "</option>\n";
1180 echo " </select>\n";
1181 echo "&nbsp; &nbsp; &nbsp;\n";
1186 // If there is a choice of warehouses, allow override of user default.
1187 if ($prod_lino > 0) { // if any products are in this form
1188 $trow = sqlQuery("SELECT count(*) AS count FROM list_options WHERE list_id = 'warehouse'");
1189 if ($trow['count'] > 1) {
1190 $trow = sqlQuery("SELECT default_warehouse FROM users WHERE username = ?", array($_SESSION['authUser']) );
1191 echo " <span class='billcell'><b>" . xlt('Warehouse') . ":</b></span>\n";
1192 echo generate_select_list('default_warehouse', 'warehouse',
1193 $trow['default_warehouse'], '');
1194 echo "&nbsp; &nbsp; &nbsp;\n";
1198 // Allow the patient price level to be fixed here.
1199 $plres = sqlStatement("SELECT option_id, title FROM list_options " .
1200 "WHERE list_id = 'pricelevel' ORDER BY seq");
1201 if (true) {
1202 $trow = sqlQuery("SELECT pricelevel FROM patient_data WHERE " .
1203 "pid = ? LIMIT 1", array($pid) );
1204 $pricelevel = $trow['pricelevel'];
1205 echo " <span class='billcell'><b>" . xlt('Price Level') . ":</b></span>\n";
1206 echo " <select name='pricelevel'";
1207 if ($isBilled) echo " disabled";
1208 echo ">\n";
1209 while ($plrow = sqlFetchArray($plres)) {
1210 $key = $plrow['option_id'];
1211 $val = $plrow['title'];
1212 echo " <option value='" . attr($key) . "'";
1213 if ($key == $pricelevel) echo ' selected';
1214 echo ">" . text($val) . "</option>\n";
1216 echo " </select>\n";
1220 &nbsp; &nbsp; &nbsp;
1222 <?php if (!$isBilled) { ?>
1223 <input type='submit' name='bn_save' value='<?php echo xla('Save');?>' />
1224 &nbsp;
1225 <?php if (!$hasCharges) { ?>
1226 <input type='submit' name='bn_save_close' value='<?php echo xla('Save and Close');?>' />
1227 &nbsp;
1228 <?php } ?>
1229 <input type='submit' name='bn_refresh' value='<?php echo xla('Refresh');?>'>
1230 &nbsp;
1231 <?php } ?>
1233 <input type='button' value='<?php echo xla('Cancel');?>'
1234 onclick="top.restoreSession();location='<?php echo "$rootdir/patient_file/encounter/$returnurl" ?>'" />
1236 <?php if ($code_types['UCSMC']) { ?>
1237 <p style='font-family:sans-serif;font-size:8pt;color:#666666;'>
1238 &nbsp;<br>
1239 <?php echo xlt('UCSMC codes provided by the University of Calgary Sports Medicine Centre');?>
1240 </p>
1241 <?php } ?>
1243 </center>
1245 </form>
1247 <?php
1248 // TBD: If $alertmsg, display it with a JavaScript alert().
1251 <script language='JavaScript'>
1252 <?php echo $justinit; ?>
1253 </script>
1255 </body>
1256 </html>