Add New FMC code from Intesync
[openemr.git] / interface / patient_file / pos_checkout.php
blob1121b84fc09c398a0602bf188fa3a1fec93b43e5
1 <?php
2 // Copyright (C) 2006-2010 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 module supports a popup window to handle patient checkout
10 // as a point-of-sale transaction. Support for in-house drug sales
11 // is included.
13 // Important notes about system design:
15 // (1) Drug sales may or may not be associated with an encounter;
16 // they are if they are paid for concurrently with an encounter, or
17 // if they are "product" (non-prescription) sales via the Fee Sheet.
18 // (2) Drug sales without an encounter will have 20YYMMDD, possibly
19 // with a suffix, as the encounter-number portion of their invoice
20 // number.
21 // (3) Payments are saved as AR only, don't mess with the billing table.
22 // See library/classes/WSClaim.class.php for posting code.
23 // (4) On checkout, the billing and drug_sales table entries are marked
24 // as billed and so become unavailable for further billing.
25 // (5) Receipt printing must be a separate operation from payment,
26 // and repeatable.
29 // TBD:
30 // If this user has 'irnpool' set
31 // on display of checkout form
32 // show pending next invoice number
33 // on applying checkout
34 // save next invoice number to form_encounter
35 // compute new next invoice number
36 // on receipt display
37 // show invoice number
40 require_once("../globals.php");
41 require_once("$srcdir/acl.inc");
42 require_once("$srcdir/patient.inc");
43 require_once("$srcdir/billing.inc");
44 require_once("$srcdir/sql-ledger.inc");
45 require_once("$srcdir/freeb/xmlrpc.inc");
46 require_once("$srcdir/freeb/xmlrpcs.inc");
47 require_once("$srcdir/formatting.inc.php");
48 require_once("$srcdir/formdata.inc.php");
49 require_once("../../custom/code_types.inc.php");
51 $currdecimals = $GLOBALS['currency_decimals'];
53 $INTEGRATED_AR = $GLOBALS['oer_config']['ws_accounting']['enabled'] === 2;
55 $details = empty($_GET['details']) ? 0 : 1;
57 // Get the patient's name and chart number.
58 $patdata = getPatientData($pid, 'fname,mname,lname,pubpid,street,city,state,postal_code');
60 // Get the "next invoice reference number" from this user's pool.
62 function getInvoiceRefNumber() {
63 $trow = sqlQuery("SELECT lo.notes " .
64 "FROM users AS u, list_options AS lo " .
65 "WHERE u.username = '" . $_SESSION['authUser'] . "' AND " .
66 "lo.list_id = 'irnpool' AND lo.option_id = u.irnpool LIMIT 1");
67 return empty($trow['notes']) ? '' : $trow['notes'];
70 // Increment the "next invoice reference number" of this user's pool.
71 // This identifies the "digits" portion of that number and adds 1 to it.
72 // If it contains more than one string of digits, the last is used.
74 function updateInvoiceRefNumber() {
75 $irnumber = getInvoiceRefNumber();
76 // Here "?" specifies a minimal match, to get the most digits possible:
77 if (preg_match('/^(.*?)(\d+)(\D*)$/', $irnumber, $matches)) {
78 $newdigs = sprintf('%0' . strlen($matches[2]) . 'd', $matches[2] + 1);
79 $newnumber = add_escape_custom($matches[1] . $newdigs . $matches[3]);
80 sqlStatement("UPDATE users AS u, list_options AS lo " .
81 "SET lo.notes = '$newnumber' WHERE " .
82 "u.username = '" . $_SESSION['authUser'] . "' AND " .
83 "lo.list_id = 'irnpool' AND lo.option_id = u.irnpool");
85 return $irnumber;
88 //////////////////////////////////////////////////////////////////////
89 // The following functions are inline here temporarily, and should be
90 // moved to an includable module for common use. In particular
91 // WSClaim.class.php should be rewritten to use them.
92 //////////////////////////////////////////////////////////////////////
94 // Initialize the array of invoice information for posting to the
95 // accounting system.
97 function invoice_initialize(& $invoice_info, $patient_id, $provider_id,
98 $payer_id = 0, $encounter = 0, $dosdate = '')
100 $db = $GLOBALS['adodb']['db'];
102 // Get foreign ID (customer) for patient.
103 $sql = "SELECT foreign_id from integration_mapping as im " .
104 "LEFT JOIN patient_data as pd on im.local_id=pd.id " .
105 "where pd.pid = '" .
106 $patient_id .
107 "' and im.local_table='patient_data' and im.foreign_table='customer'";
108 $result = $db->Execute($sql);
109 if($result && !$result->EOF) {
110 $foreign_patient_id = $result->fields['foreign_id'];
112 else {
113 return "Patient '" . $patient_id . "' has not yet been posted to the accounting system.";
116 // Get foreign ID (salesman) for provider.
117 $sql = "SELECT foreign_id from integration_mapping WHERE " .
118 "local_id = $provider_id AND local_table='users' and foreign_table='salesman'";
119 $result = $db->Execute($sql);
120 if($result && !$result->EOF) {
121 $foreign_provider_id = $result->fields['foreign_id'];
123 else {
124 return "Provider '" . $provider_id . "' has not yet been posted to the accounting system.";
127 // Get foreign ID (customer) for insurance payer.
128 if ($payer_id && ! $GLOBALS['insurance_companies_are_not_customers']) {
129 $sql = "SELECT foreign_id from integration_mapping WHERE " .
130 "local_id = $payer_id AND local_table = 'insurance_companies' AND foreign_table='customer'";
131 $result = $db->Execute($sql);
132 if($result && !$result->EOF) {
133 $foreign_payer_id = $result->fields['foreign_id'];
135 else {
136 return "Payer '" . $payer_id . "' has not yet been posted to the accounting system.";
138 } else {
139 $foreign_payer_id = $payer_id;
142 // Create invoice notes for the new invoice that list the patient's
143 // insurance plans. This is so that when payments are posted, the user
144 // can easily see if a secondary claim needs to be submitted.
146 $insnotes = "";
147 $insno = 0;
148 foreach (array("primary", "secondary", "tertiary") as $instype) {
149 ++$insno;
150 $sql = "SELECT insurance_companies.name " .
151 "FROM insurance_data, insurance_companies WHERE " .
152 "insurance_data.pid = $patient_id AND " .
153 "insurance_data.type = '$instype' AND " .
154 "insurance_companies.id = insurance_data.provider " .
155 "ORDER BY insurance_data.date DESC LIMIT 1";
156 $result = $db->Execute($sql);
157 if ($result && !$result->EOF && $result->fields['name']) {
158 if ($insnotes) $insnotes .= "\n";
159 $insnotes .= "Ins$insno: " . $result->fields['name'];
162 $invoice_info['notes'] = $insnotes;
164 if (preg_match("/(\d\d\d\d)\D*(\d\d)\D*(\d\d)/", $dosdate, $matches)) {
165 $dosdate = $matches[2] . '-' . $matches[3] . '-' . $matches[1];
166 } else {
167 $dosdate = date("m-d-Y");
170 $invoice_info['salesman'] = $foreign_provider_id;
171 $invoice_info['customerid'] = $foreign_patient_id;
172 $invoice_info['payer_id'] = $foreign_payer_id;
173 $invoice_info['invoicenumber'] = $patient_id . "." . $encounter;
174 $invoice_info['dosdate'] = $dosdate;
175 $invoice_info['items'] = array();
176 $invoice_info['total'] = '0.00';
178 return '';
181 function invoice_add_line_item(& $invoice_info, $code_type, $code,
182 $code_text, $amount, $units=1)
184 $units = max(1, intval(trim($units)));
185 $amount = sprintf("%01.2f", $amount);
186 $price = $amount / $units;
187 $tmp = sprintf("%01.2f", $price);
188 if (abs($price - $tmp) < 0.000001) $price = $tmp;
189 $tii = array();
190 $tii['maincode'] = $code;
191 $tii['itemtext'] = "$code_type:$code";
192 if ($code_text) $tii['itemtext'] .= " $code_text";
193 $tii['qty'] = $units;
194 $tii['price'] = $price;
195 $tii['glaccountid'] = $GLOBALS['oer_config']['ws_accounting']['income_acct'];
196 $invoice_info['total'] = sprintf("%01.2f", $invoice_info['total'] + $amount);
197 $invoice_info['items'][] = $tii;
198 return '';
201 function invoice_post(& $invoice_info)
203 $function['ezybiz.add_invoice'] = array(new xmlrpcval($invoice_info, "struct"));
205 list($name, $var) = each($function);
206 $f = new xmlrpcmsg($name, $var);
208 $c = new xmlrpc_client($GLOBALS['oer_config']['ws_accounting']['url'],
209 $GLOBALS['oer_config']['ws_accounting']['server'],
210 $GLOBALS['oer_config']['ws_accounting']['port']);
212 $c->setCredentials($GLOBALS['oer_config']['ws_accounting']['username'],
213 $GLOBALS['oer_config']['ws_accounting']['password']);
215 $r = $c->send($f);
216 if (!$r) return "XMLRPC send failed";
218 // We are not doing anything with the return value yet... should we?
219 $tv = $r->value();
220 if (is_object($tv)) {
221 $value = $tv->getval();
223 else {
224 $value = null;
227 if ($r->faultCode()) {
228 return "Fault: Code: " . $r->faultCode() . " Reason '" . $r->faultString() . "'";
231 return '';
234 ///////////// End of SQL-Ledger invoice posting functions ////////////
236 // Output HTML for an invoice line item.
238 $prevsvcdate = '';
239 function receiptDetailLine($svcdate, $description, $amount, $quantity) {
240 global $prevsvcdate, $details;
241 if (!$details) return;
242 $amount = sprintf('%01.2f', $amount);
243 if (empty($quantity)) $quantity = 1;
244 $price = sprintf('%01.4f', $amount / $quantity);
245 $tmp = sprintf('%01.2f', $price);
246 if ($price == $tmp) $price = $tmp;
247 echo " <tr>\n";
248 echo " <td>" . ($svcdate == $prevsvcdate ? '&nbsp;' : oeFormatShortDate($svcdate)) . "</td>\n";
249 echo " <td>$description</td>\n";
250 echo " <td align='right'>" . oeFormatMoney($price) . "</td>\n";
251 echo " <td align='right'>$quantity</td>\n";
252 echo " <td align='right'>" . oeFormatMoney($amount) . "</td>\n";
253 echo " </tr>\n";
254 $prevsvcdate = $svcdate;
257 // Output HTML for an invoice payment.
259 function receiptPaymentLine($paydate, $amount, $description='') {
260 $amount = sprintf('%01.2f', 0 - $amount); // make it negative
261 echo " <tr>\n";
262 echo " <td>" . oeFormatShortDate($paydate) . "</td>\n";
263 echo " <td>" . xl('Payment') . " $description</td>\n";
264 echo " <td colspan='2'>&nbsp;</td>\n";
265 echo " <td align='right'>" . oeFormatMoney($amount) . "</td>\n";
266 echo " </tr>\n";
269 // Generate a receipt from the last-billed invoice for this patient,
270 // or for the encounter specified as a GET parameter.
272 function generate_receipt($patient_id, $encounter=0) {
273 global $sl_err, $sl_cash_acc, $css_header, $details, $INTEGRATED_AR;
275 // Get details for what we guess is the primary facility.
276 $frow = sqlQuery("SELECT * FROM facility " .
277 "ORDER BY billing_location DESC, accepts_assignment DESC, id LIMIT 1");
279 $patdata = getPatientData($patient_id, 'fname,mname,lname,pubpid,street,city,state,postal_code');
281 // Get the most recent invoice data or that for the specified encounter.
283 if ($INTEGRATED_AR) {
284 if ($encounter) {
285 $ferow = sqlQuery("SELECT id, date, encounter FROM form_encounter " .
286 "WHERE pid = '$patient_id' AND encounter = '$encounter'");
287 } else {
288 $ferow = sqlQuery("SELECT id, date, encounter FROM form_encounter " .
289 "WHERE pid = '$patient_id' " .
290 "ORDER BY id DESC LIMIT 1");
292 if (empty($ferow)) die(xl("This patient has no activity."));
293 $trans_id = $ferow['id'];
294 $encounter = $ferow['encounter'];
295 $svcdate = substr($ferow['date'], 0, 10);
297 else {
298 SLConnect();
300 $arres = SLQuery("SELECT * FROM ar WHERE " .
301 "invnumber LIKE '$patient_id.%' " .
302 "ORDER BY id DESC LIMIT 1");
303 if ($sl_err) die($sl_err);
304 if (!SLRowCount($arres)) die(xl("This patient has no activity."));
305 $arrow = SLGetRow($arres, 0);
307 $trans_id = $arrow['id'];
309 // Determine the date of service. An 8-digit encounter number is
310 // presumed to be a date of service imported during conversion or
311 // associated with prescriptions only. Otherwise look it up in the
312 // form_encounter table.
314 $svcdate = "";
315 list($trash, $encounter) = explode(".", $arrow['invnumber']);
316 if (strlen($encounter) >= 8) {
317 $svcdate = substr($encounter, 0, 4) . "-" . substr($encounter, 4, 2) .
318 "-" . substr($encounter, 6, 2);
320 else if ($encounter) {
321 $tmp = sqlQuery("SELECT date FROM form_encounter WHERE " .
322 "encounter = $encounter");
323 $svcdate = substr($tmp['date'], 0, 10);
325 } // end not $INTEGRATED_AR
327 // Get invoice reference number.
328 $encrow = sqlQuery("SELECT invoice_refno FROM form_encounter WHERE " .
329 "pid = '$patient_id' AND encounter = '$encounter' LIMIT 1");
330 $invoice_refno = $encrow['invoice_refno'];
332 <html>
333 <head>
334 <?php html_header_show(); ?>
335 <link rel='stylesheet' href='<?php echo $css_header ?>' type='text/css'>
336 <title><?php xl('Receipt for Payment','e'); ?></title>
337 <script type="text/javascript" src="../../library/dialog.js"></script>
338 <script language="JavaScript">
340 <?php require($GLOBALS['srcdir'] . "/restoreSession.php"); ?>
342 // Process click on Print button.
343 function printme() {
344 var divstyle = document.getElementById('hideonprint').style;
345 divstyle.display = 'none';
346 window.print();
347 return false;
350 // Process click on Delete button.
351 function deleteme() {
352 dlgopen('deleter.php?billing=<?php echo "$patient_id.$encounter"; ?>', '_blank', 500, 450);
353 return false;
356 // Called by the deleteme.php window on a successful delete.
357 function imdeleted() {
358 window.close();
361 </script>
362 </head>
363 <body class="body_top">
364 <center>
365 <p><b><?php echo $frow['name'] ?>
366 <br><?php echo $frow['street'] ?>
367 <br><?php echo $frow['city'] . ', ' . $frow['state'] . ' ' . $frow['postal_code'] ?>
368 <br><?php echo $frow['phone'] ?>
369 <br>&nbsp;
370 <br>
371 <?php
372 echo xl("Receipt Generated") . date(' F j, Y');
373 if ($invoice_refno) echo " " . xl("for Invoice") . " $invoice_refno";
375 <br>&nbsp;
376 </b></p>
377 </center>
379 <?php echo $patdata['fname'] . ' ' . $patdata['mname'] . ' ' . $patdata['lname'] ?>
380 <br><?php echo $patdata['street'] ?>
381 <br><?php echo $patdata['city'] . ', ' . $patdata['state'] . ' ' . $patdata['postal_code'] ?>
382 <br>&nbsp;
383 </p>
384 <center>
385 <table cellpadding='5'>
386 <tr>
387 <td><b><?php xl('Date','e'); ?></b></td>
388 <td><b><?php xl('Description','e'); ?></b></td>
389 <td align='right'><b><?php echo $details ? xl('Price') : '&nbsp;'; ?></b></td>
390 <td align='right'><b><?php echo $details ? xl('Qty' ) : '&nbsp;'; ?></b></td>
391 <td align='right'><b><?php xl('Total','e'); ?></b></td>
392 </tr>
394 <?php
395 $charges = 0.00;
397 if ($INTEGRATED_AR) {
398 // Product sales
399 $inres = sqlStatement("SELECT s.sale_id, s.sale_date, s.fee, " .
400 "s.quantity, s.drug_id, d.name " .
401 "FROM drug_sales AS s LEFT JOIN drugs AS d ON d.drug_id = s.drug_id " .
402 // "WHERE s.pid = '$patient_id' AND s.encounter = '$encounter' AND s.fee != 0 " .
403 "WHERE s.pid = '$patient_id' AND s.encounter = '$encounter' " .
404 "ORDER BY s.sale_id");
405 while ($inrow = sqlFetchArray($inres)) {
406 $charges += sprintf('%01.2f', $inrow['fee']);
407 receiptDetailLine($inrow['sale_date'], $inrow['name'],
408 $inrow['fee'], $inrow['quantity']);
410 // Service and tax items
411 $inres = sqlStatement("SELECT * FROM billing WHERE " .
412 "pid = '$patient_id' AND encounter = '$encounter' AND " .
413 // "code_type != 'COPAY' AND activity = 1 AND fee != 0 " .
414 "code_type != 'COPAY' AND activity = 1 " .
415 "ORDER BY id");
416 while ($inrow = sqlFetchArray($inres)) {
417 $charges += sprintf('%01.2f', $inrow['fee']);
418 receiptDetailLine($svcdate, $inrow['code_text'],
419 $inrow['fee'], $inrow['units']);
421 // Adjustments.
422 $inres = sqlStatement("SELECT " .
423 "a.code, a.modifier, a.memo, a.payer_type, a.adj_amount, a.pay_amount, " .
424 "s.payer_id, s.reference, s.check_date, s.deposit_date " .
425 "FROM ar_activity AS a " .
426 "LEFT JOIN ar_session AS s ON s.session_id = a.session_id WHERE " .
427 "a.pid = '$patient_id' AND a.encounter = '$encounter' AND " .
428 "a.adj_amount != 0 " .
429 "ORDER BY s.check_date, a.sequence_no");
430 while ($inrow = sqlFetchArray($inres)) {
431 $charges -= sprintf('%01.2f', $inrow['adj_amount']);
432 $payer = empty($inrow['payer_type']) ? 'Pt' : ('Ins' . $inrow['payer_type']);
433 receiptDetailLine($svcdate, $payer . ' ' . $inrow['memo'],
434 0 - $inrow['adj_amount'], 1);
436 } // end $INTEGRATED_AR
437 else {
438 // Request all line items with money belonging to the invoice.
439 $inres = SLQuery("SELECT * FROM invoice WHERE " .
440 "trans_id = $trans_id AND sellprice != 0 ORDER BY id");
441 if ($sl_err) die($sl_err);
442 for ($irow = 0; $irow < SLRowCount($inres); ++$irow) {
443 $row = SLGetRow($inres, $irow);
444 $amount = sprintf('%01.2f', $row['sellprice'] * $row['qty']);
445 $charges += $amount;
446 $desc = preg_replace('/^.{1,6}:/', '', $row['description']);
447 receiptDetailLine($svcdate, $desc, $amount, $row['qty']);
449 } // end not $INTEGRATED_AR
452 <tr>
453 <td colspan='5'>&nbsp;</td>
454 </tr>
455 <tr>
456 <td><?php echo oeFormatShortDate($svcdispdate); ?></td>
457 <td><b><?php xl('Total Charges','e'); ?></b></td>
458 <td align='right'>&nbsp;</td>
459 <td align='right'>&nbsp;</td>
460 <td align='right'><?php echo oeFormatMoney($charges, true) ?></td>
461 </tr>
462 <tr>
463 <td colspan='5'>&nbsp;</td>
464 </tr>
466 <?php
467 if ($INTEGRATED_AR) {
468 // Get co-pays.
469 $inres = sqlStatement("SELECT fee, code_text FROM billing WHERE " .
470 "pid = '$patient_id' AND encounter = '$encounter' AND " .
471 "code_type = 'COPAY' AND activity = 1 AND fee != 0 " .
472 "ORDER BY id");
473 while ($inrow = sqlFetchArray($inres)) {
474 $charges += sprintf('%01.2f', $inrow['fee']);
475 receiptPaymentLine($svcdate, 0 - $inrow['fee'], $inrow['code_text']);
477 // Get other payments.
478 $inres = sqlStatement("SELECT " .
479 "a.code, a.modifier, a.memo, a.payer_type, a.adj_amount, a.pay_amount, " .
480 "s.payer_id, s.reference, s.check_date, s.deposit_date " .
481 "FROM ar_activity AS a " .
482 "LEFT JOIN ar_session AS s ON s.session_id = a.session_id WHERE " .
483 "a.pid = '$patient_id' AND a.encounter = '$encounter' AND " .
484 "a.pay_amount != 0 " .
485 "ORDER BY s.check_date, a.sequence_no");
486 $payer = empty($inrow['payer_type']) ? 'Pt' : ('Ins' . $inrow['payer_type']);
487 while ($inrow = sqlFetchArray($inres)) {
488 $charges -= sprintf('%01.2f', $inrow['pay_amount']);
489 receiptPaymentLine($svcdate, $inrow['pay_amount'],
490 $payer . ' ' . $inrow['reference']);
492 } // end $INTEGRATED_AR
493 else {
494 $chart_id_cash = SLQueryValue("select id from chart where accno = '$sl_cash_acc'");
495 if ($sl_err) die($sl_err);
496 if (! $chart_id_cash) die("There is no COA entry for cash account '$sl_cash_acc'");
498 // Request all cash entries belonging to the invoice.
499 $atres = SLQuery("SELECT * FROM acc_trans WHERE " .
500 "trans_id = $trans_id AND chart_id = $chart_id_cash ORDER BY transdate");
501 if ($sl_err) die($sl_err);
503 for ($irow = 0; $irow < SLRowCount($atres); ++$irow) {
504 $row = SLGetRow($atres, $irow);
505 $amount = sprintf('%01.2f', $row['amount']); // negative
506 $charges += $amount;
507 $rowsource = $row['source'];
508 if (strtolower($rowsource) == 'co-pay') $rowsource = '';
509 receiptPaymentLine($row['transdate'], 0 - $amount, $rowsource);
511 } // end not $INTEGRATED_AR
513 <tr>
514 <td colspan='5'>&nbsp;</td>
515 </tr>
516 <tr>
517 <td>&nbsp;</td>
518 <td><b><?php xl('Balance Due','e'); ?></b></td>
519 <td colspan='2'>&nbsp;</td>
520 <td align='right'><?php echo oeFormatMoney($charges, true) ?></td>
521 </tr>
522 </table>
523 </center>
524 <div id='hideonprint'>
526 &nbsp;
527 <a href='#' onclick='return printme();'><?php xl('Print','e'); ?></a>
528 <?php if (acl_check('acct','disc')) { ?>
529 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
530 <a href='#' onclick='return deleteme();'><?php xl('Undo Checkout','e'); ?></a>
531 <?php } ?>
532 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
533 <?php if ($details) { ?>
534 <a href='pos_checkout.php?details=0&enc=<?php echo $encounter; ?>'><?php xl('Hide Details','e'); ?></a>
535 <?php } else { ?>
536 <a href='pos_checkout.php?details=1&enc=<?php echo $encounter; ?>'><?php xl('Show Details','e'); ?></a>
537 <?php } ?>
538 </p>
539 </div>
540 </body>
541 </html>
542 <?php
543 if (!$INTEGRATED_AR) SLClose();
544 } // end function generate_receipt()
546 // Function to output a line item for the input form.
548 $lino = 0;
549 function write_form_line($code_type, $code, $id, $date, $description,
550 $amount, $units, $taxrates) {
551 global $lino;
552 $amount = sprintf("%01.2f", $amount);
553 if (empty($units)) $units = 1;
554 $price = $amount / $units; // should be even cents, but ok here if not
555 if ($code_type == 'COPAY' && !$description) $description = xl('Payment');
556 echo " <tr>\n";
557 echo " <td>" . oeFormatShortDate($date);
558 echo "<input type='hidden' name='line[$lino][code_type]' value='$code_type'>";
559 echo "<input type='hidden' name='line[$lino][code]' value='$code'>";
560 echo "<input type='hidden' name='line[$lino][id]' value='$id'>";
561 echo "<input type='hidden' name='line[$lino][description]' value='$description'>";
562 echo "<input type='hidden' name='line[$lino][taxrates]' value='$taxrates'>";
563 echo "<input type='hidden' name='line[$lino][price]' value='$price'>";
564 echo "<input type='hidden' name='line[$lino][units]' value='$units'>";
565 echo "</td>\n";
566 echo " <td>$description</td>";
567 echo " <td align='right'>$units</td>";
568 echo " <td align='right'><input type='text' name='line[$lino][amount]' " .
569 "value='$amount' size='6' maxlength='8'";
570 // Modifying prices requires the acct/disc permission.
571 // if ($code_type == 'TAX' || ($code_type != 'COPAY' && !acl_check('acct','disc')))
572 echo " style='text-align:right;background-color:transparent' readonly";
573 // else echo " style='text-align:right' onkeyup='computeTotals()'";
574 echo "></td>\n";
575 echo " </tr>\n";
576 ++$lino;
579 // Create the taxes array. Key is tax id, value is
580 // (description, rate, accumulated total).
581 $taxes = array();
582 $pres = sqlStatement("SELECT option_id, title, option_value " .
583 "FROM list_options WHERE list_id = 'taxrate' ORDER BY seq");
584 while ($prow = sqlFetchArray($pres)) {
585 $taxes[$prow['option_id']] = array($prow['title'], $prow['option_value'], 0);
588 // Mark the tax rates that are referenced in this invoice.
589 function markTaxes($taxrates) {
590 global $taxes;
591 $arates = explode(':', $taxrates);
592 if (empty($arates)) return;
593 foreach ($arates as $value) {
594 if (!empty($taxes[$value])) $taxes[$value][2] = '1';
598 $payment_methods = array(
599 'Cash',
600 'Check',
601 'MC',
602 'VISA',
603 'AMEX',
604 'DISC',
605 'Other');
607 $alertmsg = ''; // anything here pops up in an alert box
609 // If the Save button was clicked...
611 if ($_POST['form_save']) {
613 // On a save, do the following:
614 // Flag drug_sales and billing items as billed.
615 // Post the corresponding invoice with its payment(s) to sql-ledger
616 // and be careful to use a unique invoice number.
617 // Call the generate-receipt function.
618 // Exit.
620 $form_pid = $_POST['form_pid'];
621 $form_encounter = $_POST['form_encounter'];
623 // Get the posting date from the form as yyyy-mm-dd.
624 $dosdate = date("Y-m-d");
625 if (preg_match("/(\d\d\d\d)\D*(\d\d)\D*(\d\d)/", $_POST['form_date'], $matches)) {
626 $dosdate = $matches[1] . '-' . $matches[2] . '-' . $matches[3];
629 // If there is no associated encounter (i.e. this invoice has only
630 // prescriptions) then assign an encounter number of the service
631 // date, with an optional suffix to ensure that it's unique.
633 if (! $form_encounter) {
634 $form_encounter = substr($dosdate,0,4) . substr($dosdate,5,2) . substr($dosdate,8,2);
635 $tmp = '';
636 if ($INTEGRATED_AR) {
637 while (true) {
638 $ferow = sqlQuery("SELECT id FROM form_encounter WHERE " .
639 "pid = '$form_pid' AND encounter = '$form_encounter$tmp'");
640 if (empty($ferow)) break;
641 $tmp = $tmp ? $tmp + 1 : 1;
644 else {
645 SLConnect();
646 while (SLQueryValue("select id from ar where " .
647 "invnumber = '$form_pid.$form_encounter$tmp'")) {
648 $tmp = $tmp ? $tmp + 1 : 1;
650 SLClose();
652 $form_encounter .= $tmp;
655 if ($INTEGRATED_AR) {
656 // Delete any TAX rows from billing because they will be recalculated.
657 sqlStatement("UPDATE billing SET activity = 0 WHERE " .
658 "pid = '$form_pid' AND encounter = '$form_encounter' AND " .
659 "code_type = 'TAX'");
661 else {
662 // Initialize an array of invoice information for posting.
663 $invoice_info = array();
664 $msg = invoice_initialize($invoice_info, $form_pid,
665 $_POST['form_provider'], $_POST['form_payer'], $form_encounter, $dosdate);
666 if ($msg) die($msg);
669 $form_amount = $_POST['form_amount'];
670 $lines = $_POST['line'];
672 for ($lino = 0; $lines[$lino]['code_type']; ++$lino) {
673 $line = $lines[$lino];
674 $code_type = $line['code_type'];
675 $id = $line['id'];
676 $amount = sprintf('%01.2f', trim($line['amount']));
678 if (!$INTEGRATED_AR) {
679 $msg = invoice_add_line_item($invoice_info, $code_type,
680 $line['code'], $line['description'], $amount, $line['units']);
681 if ($msg) die($msg);
684 if ($code_type == 'PROD') {
685 // Product sales. The fee and encounter ID may have changed.
686 $query = "update drug_sales SET fee = '$amount', " .
687 "encounter = '$form_encounter', billed = 1 WHERE " .
688 "sale_id = '$id'";
689 sqlQuery($query);
691 else if ($code_type == 'TAX') {
692 // In the SL case taxes show up on the invoice as line items.
693 // Otherwise we gotta save them somewhere, and in the billing
694 // table with a code type of TAX seems easiest.
695 // They will have to be stripped back out when building this
696 // script's input form.
697 addBilling($form_encounter, 'TAX', 'TAX', 'Taxes', $form_pid, 0, 0,
698 '', '', $amount, '', '', 1);
700 else {
701 // Because there is no insurance here, there is no need for a claims
702 // table entry and so we do not call updateClaim(). Note we should not
703 // eliminate billed and bill_date from the billing table!
704 $query = "UPDATE billing SET fee = '$amount', billed = 1, " .
705 "bill_date = NOW() WHERE id = '$id'";
706 sqlQuery($query);
710 // Post discount.
711 if ($_POST['form_discount']) {
712 if ($GLOBALS['discount_by_money']) {
713 $amount = sprintf('%01.2f', trim($_POST['form_discount']));
715 else {
716 $amount = sprintf('%01.2f', trim($_POST['form_discount']) * $form_amount / 100);
718 $memo = xl('Discount');
719 if ($INTEGRATED_AR) {
720 $time = date('Y-m-d H:i:s');
721 $query = "INSERT INTO ar_activity ( " .
722 "pid, encounter, code, modifier, payer_type, post_user, post_time, " .
723 "session_id, memo, adj_amount " .
724 ") VALUES ( " .
725 "'$form_pid', " .
726 "'$form_encounter', " .
727 "'', " .
728 "'', " .
729 "'0', " .
730 "'" . $_SESSION['authUserID'] . "', " .
731 "'$time', " .
732 "'0', " .
733 "'$memo', " .
734 "'$amount' " .
735 ")";
736 sqlStatement($query);
738 else {
739 $msg = invoice_add_line_item($invoice_info, 'DISCOUNT',
740 '', $memo, 0 - $amount);
741 if ($msg) die($msg);
745 // Post payment.
746 if ($_POST['form_amount']) {
747 $amount = sprintf('%01.2f', trim($_POST['form_amount']));
748 $form_source = trim($_POST['form_source']);
749 $paydesc = trim($_POST['form_method']);
750 if ($INTEGRATED_AR) {
751 // Post the payment as a billed copay into the billing table.
752 // Maybe this should even be done for the SL case.
753 if (!empty($form_source)) $paydesc .= " $form_source";
754 addBilling($form_encounter, 'COPAY', $amount, $paydesc, $form_pid,
755 0, 0, '', '', 0 - $amount, '', '', 1);
757 else {
758 $msg = invoice_add_line_item($invoice_info, 'COPAY',
759 $paydesc, $form_source, 0 - $amount);
760 if ($msg) die($msg);
764 if (!$INTEGRATED_AR) {
765 $msg = invoice_post($invoice_info);
766 if ($msg) die($msg);
769 // If applicable, set the invoice reference number.
770 $invoice_refno = '';
771 if (isset($_POST['form_irnumber'])) {
772 $invoice_refno = formData('form_irnumber', 'P', true);
774 else {
775 $invoice_refno = add_escape_custom(updateInvoiceRefNumber());
777 if ($invoice_refno) {
778 sqlStatement("UPDATE form_encounter " .
779 "SET invoice_refno = '$invoice_refno' " .
780 "WHERE pid = '$form_pid' AND encounter = '$form_encounter'");
783 generate_receipt($form_pid, $form_encounter);
784 exit();
787 // If an encounter ID was given, then we must generate a receipt.
789 if (!empty($_GET['enc'])) {
790 generate_receipt($pid, $_GET['enc']);
791 exit();
794 // Get the unbilled billing table items and product sales for
795 // this patient.
797 $query = "SELECT id, date, code_type, code, modifier, code_text, " .
798 "provider_id, payer_id, units, fee, encounter " .
799 "FROM billing WHERE pid = '$pid' AND activity = 1 AND " .
800 "billed = 0 AND code_type != 'TAX' " .
801 "ORDER BY encounter DESC, id ASC";
802 $bres = sqlStatement($query);
804 $query = "SELECT s.sale_id, s.sale_date, s.prescription_id, s.fee, " .
805 "s.quantity, s.encounter, s.drug_id, d.name, r.provider_id " .
806 "FROM drug_sales AS s " .
807 "LEFT JOIN drugs AS d ON d.drug_id = s.drug_id " .
808 "LEFT OUTER JOIN prescriptions AS r ON r.id = s.prescription_id " .
809 "WHERE s.pid = '$pid' AND s.billed = 0 " .
810 "ORDER BY s.encounter DESC, s.sale_id ASC";
811 $dres = sqlStatement($query);
813 // If there are none, just redisplay the last receipt and exit.
815 if (mysql_num_rows($bres) == 0 && mysql_num_rows($dres) == 0) {
816 generate_receipt($pid);
817 exit();
820 // Get the valid practitioners, including those not active.
821 $arr_users = array();
822 $ures = sqlStatement("SELECT id, username FROM users WHERE " .
823 "( authorized = 1 OR info LIKE '%provider%' ) AND username != ''");
824 while ($urow = sqlFetchArray($ures)) {
825 $arr_users[$urow['id']] = '1';
828 // Now write a data entry form:
829 // List unbilled billing items (cpt, hcpcs, copays) for the patient.
830 // List unbilled product sales for the patient.
831 // Present an editable dollar amount for each line item, a total
832 // which is also the default value of the input payment amount,
833 // and OK and Cancel buttons.
835 <html>
836 <head>
837 <link rel='stylesheet' href='<?php echo $css_header ?>' type='text/css'>
838 <title><?php xl('Patient Checkout','e'); ?></title>
839 <style>
840 </style>
841 <style type="text/css">@import url(../../library/dynarch_calendar.css);</style>
842 <script type="text/javascript" src="../../library/textformat.js"></script>
843 <script type="text/javascript" src="../../library/dynarch_calendar.js"></script>
844 <?php include_once("{$GLOBALS['srcdir']}/dynarch_calendar_en.inc.php"); ?>
845 <script type="text/javascript" src="../../library/dynarch_calendar_setup.js"></script>
846 <script type="text/javascript" src="../../library/dialog.js"></script>
847 <script type="text/javascript" src="../../library/js/jquery-1.2.2.min.js"></script>
848 <script language="JavaScript">
849 var mypcc = '<?php echo $GLOBALS['phone_country_code'] ?>';
851 <?php require($GLOBALS['srcdir'] . "/restoreSession.php"); ?>
853 // This clears the tax line items in preparation for recomputing taxes.
854 function clearTax(visible) {
855 var f = document.forms[0];
856 for (var lino = 0; true; ++lino) {
857 var pfx = 'line[' + lino + ']';
858 if (! f[pfx + '[code_type]']) break;
859 if (f[pfx + '[code_type]'].value != 'TAX') continue;
860 f[pfx + '[price]'].value = '0.00';
861 if (visible) f[pfx + '[amount]'].value = '0.00';
865 // For a given tax ID and amount, compute the tax on that amount and add it
866 // to the "price" (same as "amount") of the corresponding tax line item.
867 // Note the tax line items include their "taxrate" to make this easy.
868 function addTax(rateid, amount, visible) {
869 if (rateid.length == 0) return 0;
870 var f = document.forms[0];
871 for (var lino = 0; true; ++lino) {
872 var pfx = 'line[' + lino + ']';
873 if (! f[pfx + '[code_type]']) break;
874 if (f[pfx + '[code_type]'].value != 'TAX') continue;
875 if (f[pfx + '[code]'].value != rateid) continue;
876 var tax = amount * parseFloat(f[pfx + '[taxrates]'].value);
877 tax = parseFloat(tax.toFixed(<?php echo $currdecimals ?>));
878 var cumtax = parseFloat(f[pfx + '[price]'].value) + tax;
879 f[pfx + '[price]'].value = cumtax.toFixed(<?php echo $currdecimals ?>); // requires JS 1.5
880 if (visible) f[pfx + '[amount]'].value = cumtax.toFixed(<?php echo $currdecimals ?>); // requires JS 1.5
881 if (isNaN(tax)) alert('Tax rate not numeric at line ' + lino);
882 return tax;
884 return 0;
887 // This mess recomputes the invoice total and optionally applies a discount.
888 function computeDiscountedTotals(discount, visible) {
889 clearTax(visible);
890 var f = document.forms[0];
891 var total = 0.00;
892 for (var lino = 0; f['line[' + lino + '][code_type]']; ++lino) {
893 var code_type = f['line[' + lino + '][code_type]'].value;
894 // price is price per unit when the form was originally generated.
895 // By contrast, amount is the dynamically-generated discounted line total.
896 var price = parseFloat(f['line[' + lino + '][price]'].value);
897 if (isNaN(price)) alert('Price not numeric at line ' + lino);
898 if (code_type == 'COPAY' || code_type == 'TAX') {
899 // This works because the tax lines come last.
900 total += parseFloat(price.toFixed(<?php echo $currdecimals ?>));
901 continue;
903 var units = f['line[' + lino + '][units]'].value;
904 var amount = price * units;
905 amount = parseFloat(amount.toFixed(<?php echo $currdecimals ?>));
906 if (visible) f['line[' + lino + '][amount]'].value = amount.toFixed(<?php echo $currdecimals ?>);
907 total += amount;
908 var taxrates = f['line[' + lino + '][taxrates]'].value;
909 var taxids = taxrates.split(':');
910 for (var j = 0; j < taxids.length; ++j) {
911 addTax(taxids[j], amount, visible);
914 return total - discount;
917 // Recompute displayed amounts with any discount applied.
918 function computeTotals() {
919 var f = document.forms[0];
920 var discount = parseFloat(f.form_discount.value);
921 if (isNaN(discount)) discount = 0;
922 <?php if (!$GLOBALS['discount_by_money']) { ?>
923 // This site discounts by percentage, so convert it to a money amount.
924 if (discount > 100) discount = 100;
925 if (discount < 0 ) discount = 0;
926 discount = 0.01 * discount * computeDiscountedTotals(0, false);
927 <?php } ?>
928 var total = computeDiscountedTotals(discount, true);
929 f.form_amount.value = total.toFixed(<?php echo $currdecimals ?>);
930 return true;
933 </script>
934 </head>
936 <body class="body_top">
938 <form method='post' action='pos_checkout.php'>
939 <input type='hidden' name='form_pid' value='<?php echo $pid ?>' />
941 <center>
944 <table cellspacing='5'>
945 <tr>
946 <td colspan='3' align='center'>
947 <b><?php xl('Patient Checkout for ','e'); ?><?php echo $patdata['fname'] . " " .
948 $patdata['lname'] . " (" . $patdata['pubpid'] . ")" ?></b>
949 </td>
950 </tr>
951 <tr>
952 <td><b><?php xl('Date','e'); ?></b></td>
953 <td><b><?php xl('Description','e'); ?></b></td>
954 <td align='right'><b><?php xl('Qty','e'); ?></b></td>
955 <td align='right'><b><?php xl('Amount','e'); ?></b></td>
956 </tr>
957 <?php
958 $inv_encounter = '';
959 $inv_date = '';
960 $inv_provider = 0;
961 $inv_payer = 0;
962 $gcac_related_visit = false;
963 $gcac_service_provided = false;
965 // Process billing table items. Note this includes co-pays.
966 // Items that are not allowed to have a fee are skipped.
968 while ($brow = sqlFetchArray($bres)) {
969 // Skip all but the most recent encounter.
970 if ($inv_encounter && $brow['encounter'] != $inv_encounter) continue;
972 $thisdate = substr($brow['date'], 0, 10);
973 $code_type = $brow['code_type'];
975 // Collect tax rates, related code and provider ID.
976 $taxrates = '';
977 $related_code = '';
978 if (!empty($code_types[$code_type]['fee'])) {
979 $query = "SELECT taxrates, related_code FROM codes WHERE code_type = '" .
980 $code_types[$code_type]['id'] . "' AND " .
981 "code = '" . $brow['code'] . "' AND ";
982 if ($brow['modifier']) {
983 $query .= "modifier = '" . $brow['modifier'] . "'";
984 } else {
985 $query .= "(modifier IS NULL OR modifier = '')";
987 $query .= " LIMIT 1";
988 $tmp = sqlQuery($query);
989 $taxrates = $tmp['taxrates'];
990 $related_code = $tmp['related_code'];
991 markTaxes($taxrates);
994 write_form_line($code_type, $brow['code'], $brow['id'], $thisdate,
995 ucfirst(strtolower($brow['code_text'])), $brow['fee'], $brow['units'],
996 $taxrates);
997 if (!$inv_encounter) $inv_encounter = $brow['encounter'];
998 $inv_payer = $brow['payer_id'];
999 if (!$inv_date || $inv_date < $thisdate) $inv_date = $thisdate;
1001 // Custom logic for IPPF to determine if a GCAC issue applies.
1002 if ($GLOBALS['ippf_specific'] && $related_code) {
1003 $relcodes = explode(';', $related_code);
1004 foreach ($relcodes as $codestring) {
1005 if ($codestring === '') continue;
1006 list($codetype, $code) = explode(':', $codestring);
1007 if ($codetype !== 'IPPF') continue;
1008 if (preg_match('/^25222/', $code)) {
1009 $gcac_related_visit = true;
1010 if (preg_match('/^25222[34]/', $code))
1011 $gcac_service_provided = true;
1017 // Process drug sales / products.
1019 while ($drow = sqlFetchArray($dres)) {
1020 if ($inv_encounter && $drow['encounter'] && $drow['encounter'] != $inv_encounter) continue;
1022 $thisdate = $drow['sale_date'];
1023 if (!$inv_encounter) $inv_encounter = $drow['encounter'];
1025 if (!$inv_provider && !empty($arr_users[$drow['provider_id']]))
1026 $inv_provider = $drow['provider_id'] + 0;
1028 if (!$inv_date || $inv_date < $thisdate) $inv_date = $thisdate;
1030 // Accumulate taxes for this product.
1031 $tmp = sqlQuery("SELECT taxrates FROM drug_templates WHERE drug_id = '" .
1032 $drow['drug_id'] . "' ORDER BY selector LIMIT 1");
1033 // accumTaxes($drow['fee'], $tmp['taxrates']);
1034 $taxrates = $tmp['taxrates'];
1035 markTaxes($taxrates);
1037 write_form_line('PROD', $drow['drug_id'], $drow['sale_id'],
1038 $thisdate, $drow['name'], $drow['fee'], $drow['quantity'], $taxrates);
1041 // Write a form line for each tax that has money, adding to $total.
1042 foreach ($taxes as $key => $value) {
1043 if ($value[2]) {
1044 write_form_line('TAX', $key, $key, date('Y-m-d'), $value[0], 0, 1, $value[1]);
1048 // Note that we don't try to get anything from the ar_activity table. Since
1049 // this is the checkout, nothing should be there yet for this invoice.
1051 if ($inv_encounter) {
1052 $erow = sqlQuery("SELECT provider_id FROM form_encounter WHERE " .
1053 "pid = '$pid' AND encounter = '$inv_encounter' " .
1054 "ORDER BY id DESC LIMIT 1");
1055 $inv_provider = $erow['provider_id'] + 0;
1058 </table>
1061 <table border='0' cellspacing='4'>
1063 <tr>
1064 <td>
1065 <?php echo $GLOBALS['discount_by_money'] ? xl('Discount Amount') : xl('Discount Percentage'); ?>:
1066 </td>
1067 <td>
1068 <input type='text' name='form_discount' size='6' maxlength='8' value=''
1069 style='text-align:right' onkeyup='computeTotals()'>
1070 </td>
1071 </tr>
1073 <tr>
1074 <td>
1075 <?php xl('Payment Method','e'); ?>:
1076 </td>
1077 <td>
1078 <select name='form_method'>
1080 foreach ($payment_methods as $value) {
1081 echo " <option value='$value'";
1082 echo ">$value</option>\n";
1085 </select>
1086 </td>
1087 </tr>
1089 <tr>
1090 <td>
1091 <?php xl('Check/Reference Number','e'); ?>:
1092 </td>
1093 <td>
1094 <input type='text' name='form_source' size='10' value=''>
1095 </td>
1096 </tr>
1098 <tr>
1099 <td>
1100 <?php xl('Amount Paid','e'); ?>:
1101 </td>
1102 <td>
1103 <input type='text' name='form_amount' size='10' value='0.00'>
1104 </td>
1105 </tr>
1107 <tr>
1108 <td>
1109 <?php xl('Posting Date','e'); ?>:
1110 </td>
1111 <td>
1112 <input type='text' size='10' name='form_date' id='form_date'
1113 value='<?php echo $inv_date ?>'
1114 title='yyyy-mm-dd date of service'
1115 onkeyup='datekeyup(this,mypcc)' onblur='dateblur(this,mypcc)' />
1116 <img src='../pic/show_calendar.gif' align='absbottom' width='24' height='22'
1117 id='img_date' border='0' alt='[?]' style='cursor:pointer'
1118 title='Click here to choose a date'>
1119 </td>
1120 </tr>
1122 <?php
1123 // If this user has a non-empty irnpool assigned, show the pending
1124 // invoice reference number.
1125 $irnumber = getInvoiceRefNumber();
1126 if (!empty($irnumber)) {
1128 <tr>
1129 <td>
1130 <?php xl('Tentative Invoice Ref No','e'); ?>:
1131 </td>
1132 <td>
1133 <?php echo $irnumber; ?>
1134 </td>
1135 </tr>
1136 <?php
1138 // Otherwise if there is an invoice reference number mask, ask for the refno.
1139 else if (!empty($GLOBALS['gbl_mask_invoice_number'])) {
1141 <tr>
1142 <td>
1143 <?php xl('Invoice Reference Number','e'); ?>:
1144 </td>
1145 <td>
1146 <input type='text' name='form_irnumber' size='10' value=''
1147 onkeyup='maskkeyup(this,"<?php echo addslashes($GLOBALS['gbl_mask_invoice_number']); ?>")'
1148 onblur='maskblur(this,"<?php echo addslashes($GLOBALS['gbl_mask_invoice_number']); ?>")'
1150 </td>
1151 </tr>
1152 <?php
1156 <tr>
1157 <td colspan='2' align='center'>
1158 &nbsp;<br>
1159 <input type='submit' name='form_save' value='<?php xl('Save','e'); ?>' /> &nbsp;
1160 <?php if (empty($_GET['framed'])) { ?>
1161 <input type='button' value='Cancel' onclick='window.close()' />
1162 <?php } ?>
1163 <input type='hidden' name='form_provider' value='<?php echo $inv_provider ?>' />
1164 <input type='hidden' name='form_payer' value='<?php echo $inv_payer ?>' />
1165 <input type='hidden' name='form_encounter' value='<?php echo $inv_encounter ?>' />
1166 </td>
1167 </tr>
1169 </table>
1170 </center>
1172 </form>
1174 <script language='JavaScript'>
1175 Calendar.setup({inputField:"form_date", ifFormat:"%Y-%m-%d", button:"img_date"});
1176 computeTotals();
1177 <?php
1178 // The following is removed, perhaps temporarily, because gcac reporting
1179 // no longer depends on gcac issues. -- Rod 2009-08-11
1180 /*********************************************************************
1181 // Custom code for IPPF. Try to make sure that a GCAC issue is linked to this
1182 // visit if it contains GCAC-related services.
1183 if ($gcac_related_visit) {
1184 $grow = sqlQuery("SELECT l.id, l.title, l.begdate, ie.pid " .
1185 "FROM lists AS l " .
1186 "LEFT JOIN issue_encounter AS ie ON ie.pid = l.pid AND " .
1187 "ie.encounter = '$inv_encounter' AND ie.list_id = l.id " .
1188 "WHERE l.pid = '$pid' AND " .
1189 "l.activity = 1 AND l.type = 'ippf_gcac' " .
1190 "ORDER BY ie.pid DESC, l.begdate DESC LIMIT 1");
1191 // Note that reverse-ordering by ie.pid is a trick for sorting
1192 // issues linked to the encounter (non-null values) first.
1193 if (empty($grow['pid'])) { // if there is no linked GCAC issue
1194 if (!empty($grow)) { // there is one that is not linked
1195 echo " if (confirm('" . xl('OK to link the GCAC issue dated') . " " .
1196 $grow['begdate'] . " " . xl('to this visit?') . "')) {\n";
1197 echo " $.getScript('link_issue_to_encounter.php?issue=" . $grow['id'] .
1198 "&thisenc=$inv_encounter');\n";
1199 echo " } else";
1201 echo " if (confirm('" . xl('Are you prepared to complete a new GCAC issue for this visit?') . "')) {\n";
1202 echo " dlgopen('summary/add_edit_issue.php?thisenc=$inv_encounter" .
1203 "&thistype=ippf_gcac', '_blank', 700, 600);\n";
1204 echo " } else {\n";
1205 echo " $.getScript('link_issue_to_encounter.php?thisenc=$inv_encounter');\n";
1206 echo " }\n";
1208 } // end if ($gcac_related_visit)
1209 *********************************************************************/
1211 if ($gcac_related_visit && !$gcac_service_provided) {
1212 // Skip this warning if referral or abortion in TS.
1213 $grow = sqlQuery("SELECT COUNT(*) AS count FROM transactions " .
1214 "WHERE title = 'Referral' AND refer_date IS NOT NULL AND " .
1215 "refer_date = '$inv_date' AND pid = '$pid'");
1216 if (empty($grow['count'])) { // if there is no referral
1217 $grow = sqlQuery("SELECT COUNT(*) AS count FROM forms " .
1218 "WHERE pid = '$pid' AND encounter = '$inv_encounter' AND " .
1219 "deleted = 0 AND formdir = 'LBFgcac'");
1220 if (empty($grow['count'])) { // if there is no gcac form
1221 echo " alert('" . xl('This visit will need a GCAC form, referral or procedure service.') . "');\n";
1224 } // end if ($gcac_related_visit)
1226 </script>
1228 </body>
1229 </html>