Fully responsive globals.php with vertical menu (#2460)
[openemr.git] / interface / billing / sl_eob_search.php
bloba30bea0e8f705ca3735c92a6c6993e442107f7a1
1 <?php
2 /**
3 * This the first of two pages to support posting of EOBs.
4 * The second is sl_eob_invoice.php.
6 * @package OpenEMR
7 * @link http://www.open-emr.org
8 * @author Rod Roark <rod@sunsetsystems.com>
9 * @author Bill Cernansky
10 * @author Tony McCormick
11 * @author Roberto Vasquez <robertogagliotta@gmail.com>
12 * @author Jerry Padgett <sjpadgett@gmail.com>
13 * @author Brady Miller <brady.g.miller@gmail.com>
14 * @copyright Copyright (c) 2005-2010 Rod Roark <rod@sunsetsystems.com>
15 * @copyright Copyright (c) 2018-2019 Brady Miller <brady.g.miller@gmail.com>
16 * @copyright Copyright (c) 2018 Jerry Padgett <sjpadgett@gmail.com>
17 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
20 // Updated by Growlingflea Software. now generates correct service and billing facility on statement.
21 // any questions contact Daniel Pflieger at daniel@growlingflea.com
23 require_once("../globals.php");
24 require_once("$srcdir/patient.inc");
25 require_once("$srcdir/invoice_summary.inc.php");
26 require_once("$srcdir/appointments.inc.php");
27 require_once($GLOBALS['OE_SITE_DIR'] . "/statement.inc.php");
28 require_once("$srcdir/api.inc");
29 require_once("$srcdir/forms.inc");
30 require_once("$srcdir/../controllers/C_Document.class.php");
31 require_once("$srcdir/documents.php");
32 require_once("$srcdir/options.inc.php");
33 require_once("$srcdir/acl.inc");
34 require_once "$srcdir/user.inc";
36 use Mpdf\Mpdf;
37 use OpenEMR\Billing\ParseERA;
38 use OpenEMR\Billing\SLEOB;
39 use OpenEMR\Core\Header;
40 use OpenEMR\OeUI\OemrUI;
42 $DEBUG = 0; // set to 0 for production, 1 to test
43 $alertmsg = '';
44 $where = '';
45 $eraname = '';
46 $eracount = 0;
47 $g_posting_adj_disable = $GLOBALS['posting_adj_disable'] ? 'checked' : '';
48 $posting_adj_disable = prevSetting('sl_eob_search.', 'posting_adj_disable', 'posting_adj_disable', $g_posting_adj_disable);
50 /* Load dependencies only if we need them */
51 if (!empty($GLOBALS['portal_onsite_two_enable'])) {
52 /* Addition of onsite portal patient notify of invoice and reformated invoice - sjpadgett 01/2017 */
53 require_once("../../portal/lib/portal_mail.inc");
54 require_once("../../portal/lib/appsql.class.php");
56 function is_auth_portal($pid = 0)
58 if ($pData = sqlQuery("SELECT id, allow_patient_portal, fname, lname FROM `patient_data` WHERE `pid` = ?", array($pid))) {
59 if ($pData['allow_patient_portal'] != "YES") {
60 return false;
61 } else {
62 $_SESSION['portalUser'] = strtolower($pData['fname']) . $pData['id'];
63 return true;
65 } else {
66 return false;
70 function notify_portal($thispid, array $invoices, $template, $invid)
72 $builddir = $GLOBALS['OE_SITE_DIR'] . '/documents/onsite_portal_documents/templates/' . $thispid;
73 if (!is_dir($builddir)) {
74 mkdir($builddir, 0755, true);
77 if (fixup_invoice($template, $builddir . '/invoice' . $invid . '.tpl') != true) {
78 return false;
81 if (SavePatientAudit($thispid, $invoices) != true) {
82 return false;
83 } // this is all the invoice data for portal auditing
84 $note = xl('You have an invoice due for payment in your Patient Documents. There you may pay, download or print the invoice. Thank you.');
85 if (sendMail($_SESSION['authUser'], $note, xlt('Bill/Collect'), '', '0', $_SESSION['authUser'], $_SESSION['authUser'], $_SESSION['portalUser'], $invoices[0]['patient'], "New", '0') == 1) { // remind admin this was sent
86 sendMail($_SESSION['portalUser'], $note, xlt('Bill/Collect'), '', '0', $_SESSION['authUser'], $_SESSION['authUser'], $_SESSION['portalUser'], $invoices[0]['patient'], "New", '0'); // notify patient
87 } else {
88 return false;
91 return true;
94 function fixup_invoice($template, $ifile)
96 $data = file_get_contents($template);
97 if ($data == "") {
98 return false;
101 if (!file_put_contents($ifile, $data)) {
102 return false;
105 return true;
108 function SavePatientAudit($pid, $invs)
110 $appsql = new ApplicationTable();
111 try {
112 $audit = array();
113 $audit['patient_id'] = $pid;
114 $audit['activity'] = "invoice";
115 $audit['require_audit'] = "0";
116 $audit['pending_action'] = "payment";
117 $audit['action_taken'] = "";
118 $audit['status'] = "waiting transaction";
119 $audit['narrative'] = "Request patient online payment.";
120 $audit['table_action'] = '';
121 $audit['table_args'] = json_encode($invs);
122 $audit['action_user'] = $pid;
123 $audit['action_taken_time'] = "";
124 $audit['checksum'] = "";
125 $edata = $appsql->getPortalAudit($pid, 'payment', 'invoice', "waiting transaction", 0);
126 if ($edata['id'] > 0) {
127 $appsql->portalAudit('update', $edata['id'], $audit);
128 } else {
129 $appsql->portalAudit('insert', '', $audit);
131 } catch (Exception $ex) {
132 return $ex;
135 return true;
139 // This is called back by ParseERA::parse_era() if we are processing X12 835's.
140 function era_callback(&$out)
142 global $where, $eracount, $eraname;
143 // print_r($out); // debugging
144 ++$eracount;
145 // $eraname = $out['isa_control_number'];
146 $eraname = $out['gs_date'] . '_' . ltrim($out['isa_control_number'], '0') .
147 '_' . ltrim($out['payer_id'], '0');
148 list($pid, $encounter, $invnumber) = SLEOB::slInvoiceNumber($out);
150 if ($pid && $encounter) {
151 if ($where) {
152 $where .= ' OR ';
155 $where .= "( f.pid = '" . add_escape_custom($pid) . "' AND f.encounter = '" . add_escape_custom($encounter) . "' )";
159 function bucks($amount)
161 if ($amount) {
162 return oeFormatMoney($amount);
166 function validEmail($email)
168 if (preg_match("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$^", $email)) {
169 return true;
172 return false;
175 function emailLogin($patient_id, $message)
177 $patientData = sqlQuery("SELECT * FROM `patient_data` WHERE `pid`=?", array($patient_id));
178 if ($patientData['hipaa_allowemail'] != "YES" || empty($patientData['email']) || empty($GLOBALS['patient_reminder_sender_email'])) {
179 return false;
182 if (!(validEmail($patientData['email']))) {
183 return false;
186 if (!(validEmail($GLOBALS['patient_reminder_sender_email']))) {
187 return false;
190 if ($_SESSION['pc_facility']) {
191 $sql = "select * from facility where id=?";
192 $facility = sqlQuery($sql, array($_SESSION['pc_facility']));
193 } else {
194 $sql = "SELECT * FROM facility ORDER BY billing_location DESC LIMIT 1";
195 $facility = sqlQuery($sql);
198 $mail = new MyMailer();
199 $pt_name = $patientData['fname'] . ' ' . $patientData['lname'];
200 $pt_email = $patientData['email'];
201 $email_subject = ($facility['name'] . ' ' . xl('Patient Statement Bill'));
202 $email_sender = $GLOBALS['patient_reminder_sender_email'];
203 $mail->AddReplyTo($email_sender, $email_sender);
204 $mail->SetFrom($email_sender, $email_sender);
205 $mail->AddAddress($pt_email, $pt_name);
206 $mail->Subject = $email_subject;
207 $mail->MsgHTML("<html><body><div class='wrapper'>" . $message . "</div></body></html>");
208 $mail->IsHTML(true);
209 $mail->AltBody = $message;
211 if ($mail->Send()) {
212 return true;
213 } else {
214 $email_status = $mail->ErrorInfo;
215 error_log("EMAIL ERROR: " . errorLogEscape($email_status), 0);
216 return false;
220 // Upload a file to the client's browser
222 function upload_file_to_client($file_to_send)
224 header("Pragma: public");
225 header("Expires: 0");
226 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
227 header("Content-Type: application/force-download");
228 header("Content-Length: " . filesize($file_to_send));
229 header("Content-Disposition: attachment; filename=" . basename($file_to_send));
230 header("Content-Description: File Transfer");
231 readfile($file_to_send);
232 // flush the content to the browser. If you don't do this, the text from the subsequent
233 // output from this script will be in the file instead of sent to the browser.
234 flush();
235 exit(); //added to exit from process properly in order to stop bad html code -ehrlive
236 // sleep one second to ensure there's no follow-on.
237 sleep(1);
240 function upload_file_to_client_email($ppid, $file_to_send)
242 $message = "";
243 global $STMT_TEMP_FILE_PDF;
244 $file = fopen($file_to_send, "r");//this file contains the text to be converted to pdf.
245 while (!feof($file)) {
246 $OneLine = fgets($file);//one line is read
248 $message = $message . $OneLine . '<br>';
250 $countline++;
253 emailLogin($ppid, $message);
256 function upload_file_to_client_pdf($file_to_send, $aPatFirstName = '', $aPatID = null, $flagCFN = false)
258 //modified for statement title name
259 //Function reads a HTML file and converts to pdf.
261 $aPatFName = convert_safe_file_dir_name($aPatFirstName); //modified for statement title name
262 if ($flagCFN) {
263 $STMT_TEMP_FILE_PDF = $GLOBALS['temporary_files_dir'] . "/Stmt_{$aPatFName}_{$aPatID}.pdf";
264 } else {
265 global $STMT_TEMP_FILE_PDF;
268 global $srcdir;
270 if ($GLOBALS['statement_appearance'] == '1') {
271 $config_mpdf = array(
272 'tempDir' => $GLOBALS['MPDF_WRITE_DIR'],
273 'mode' => $GLOBALS['pdf_language'],
274 'format' => $GLOBALS['pdf_size'],
275 'default_font_size' => '9',
276 'default_font' => 'dejavusans',
277 'margin_left' => $GLOBALS['pdf_left_margin'],
278 'margin_right' => $GLOBALS['pdf_right_margin'],
279 'margin_top' => $GLOBALS['pdf_top_margin'],
280 'margin_bottom' => $GLOBALS['pdf_bottom_margin'],
281 'margin_header' => '',
282 'margin_footer' => '',
283 'orientation' => $GLOBALS['pdf_layout'],
284 'shrink_tables_to_fit' => 1,
285 'use_kwt' => true,
286 'autoScriptToLang' => true,
287 'keep_table_proportions' => true
289 $pdf2 = new mPDF($config_mpdf);
290 if ($_SESSION['language_direction'] == 'rtl') {
291 $pdf2->SetDirectionality('rtl');
293 ob_start();
294 readfile($file_to_send, "r");//this file contains the HTML to be converted to pdf.
295 //echo $file;
296 $content = ob_get_clean();
298 // Fix a nasty html2pdf bug - it ignores document root!
299 // TODO - now use mPDF, so should test if still need this fix
300 global $web_root, $webserver_root;
301 $i = 0;
302 $wrlen = strlen($web_root);
303 $wsrlen = strlen($webserver_root);
304 while (true) {
305 $i = stripos($content, " src='/", $i + 1);
306 if ($i === false) {
307 break;
310 if (substr($content, $i + 6, $wrlen) === $web_root &&
311 substr($content, $i + 6, $wsrlen) !== $webserver_root) {
312 $content = substr($content, 0, $i + 6) . $webserver_root . substr($content, $i + 6 + $wrlen);
316 $pdf2->WriteHTML($content);
317 $temp_filename = $STMT_TEMP_FILE_PDF;
318 $content_pdf = $pdf2->Output($STMT_TEMP_FILE_PDF, 'F');
319 } else {
320 $pdf = new Cezpdf('LETTER');//pdf creation starts
321 $pdf->ezSetMargins(45, 9, 36, 10);
322 $pdf->selectFont('Courier');
323 $pdf->ezSetY($pdf->ez['pageHeight'] - $pdf->ez['topMargin']);
324 $countline = 1;
325 $file = fopen($file_to_send, "r");//this file contains the text to be converted to pdf.
326 while (!feof($file)) {
327 $OneLine = fgets($file);//one line is read
328 if (stristr($OneLine, "\014") == true && !feof($file)) {//form feed means we should start a new page.
329 $pdf->ezNewPage();
330 $pdf->ezSetY($pdf->ez['pageHeight'] - $pdf->ez['topMargin']);
331 str_replace("\014", "", $OneLine);
334 if (stristr($OneLine, 'REMIT TO') == true || stristr($OneLine, 'Visit Date') == true || stristr($OneLine, 'Future Appointments') == true || stristr($OneLine, 'Current') == true) { //lines are made bold when 'REMIT TO' or 'Visit Date' is there.
335 $pdf->ezText('<b>' . $OneLine . '</b>', 12, array('justification' => 'left', 'leading' => 6));
336 } else {
337 $pdf->ezText($OneLine, 12, array('justification' => 'left', 'leading' => 6));
340 $countline++;
343 $fh = @fopen($STMT_TEMP_FILE_PDF, 'w');//stored to a pdf file
344 if ($fh) {
345 fwrite($fh, $pdf->ezOutput());
346 fclose($fh);
350 header("Pragma: public");//this section outputs the pdf file to browser
351 header("Expires: 0");
352 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
353 header("Content-Type: application/force-download");
354 header("Content-Length: " . filesize($STMT_TEMP_FILE_PDF));
355 header("Content-Disposition: attachment; filename=" . basename($STMT_TEMP_FILE_PDF));
356 header("Content-Description: File Transfer");
357 readfile($STMT_TEMP_FILE_PDF);
358 // flush the content to the browser. If you don't do this, the text from the subsequent
359 // output from this script will be in the file instead of sent to the browser.
360 flush();
361 exit(); //added to exit from process properly in order to stop bad html code -ehrlive
362 // sleep one second to ensure there's no follow-on.
363 sleep(1);
367 $today = date("Y-m-d");
368 // Print or download statements if requested.
370 if (($_REQUEST['form_print'] || $_REQUEST['form_download'] || $_REQUEST['form_email'] || $_REQUEST['form_pdf']) || $_REQUEST['form_portalnotify'] && $_REQUEST['form_cb']) {
371 if (!verifyCsrfToken($_REQUEST["csrf_token_form"])) {
372 csrfNotVerified();
375 $fhprint = fopen($STMT_TEMP_FILE, 'w');
377 $sqlBindArray = array();
378 $where = "";
379 foreach ($_REQUEST['form_cb'] as $key => $value) {
380 $where .= " OR f.id = ?";
381 array_push($sqlBindArray, $key);
384 if (!empty($where)) {
385 $where = substr($where, 4);
386 $where = '( ' . $where . ' ) AND';
389 $res = sqlStatement("SELECT " .
390 "f.id, f.date, f.pid, f.encounter, f.stmt_count, f.last_stmt_date, f.last_level_closed, f.last_level_billed, f.billing_note as enc_billing_note, " .
391 "p.fname, p.mname, p.lname, p.street, p.city, p.state, p.postal_code, p.billing_note as pat_billing_note, f.provider_id " .
392 "FROM form_encounter AS f, patient_data AS p " .
393 "WHERE $where " .
394 "p.pid = f.pid " .
395 "ORDER BY p.lname, p.fname, f.pid, f.date, f.encounter", $sqlBindArray);
397 $stmt = array();
398 $stmt_count = 0;
400 $flagT = true;
401 $aPatientFirstName = '';
402 $aPatientID = null;
403 $multiplePatients = false;
404 $usePatientNamePdf = false;
406 // get pids for delimits
407 // need to only use summary invoice for multi visits
408 $inv_pid = array();
409 $inv_count = -1;
410 if ($_REQUEST['form_portalnotify']) {
411 foreach ($_REQUEST['form_invpids'] as $key => $v) {
412 if ($_REQUEST['form_cb'][$key]) {
413 array_push($inv_pid, key($v));
417 $rcnt = 0;
418 while ($row = sqlFetchArray($res)) {
419 $rows[] = $row;
420 if (!$inv_pid[$rcnt]) {
421 array_push($inv_pid, $row['pid']);
423 $rcnt++;
425 // This loops once for each invoice/encounter.
427 $rcnt = 0;
428 while ($row = $rows[$rcnt++]) {
429 $svcdate = substr($row['date'], 0, 10);
430 $duedate = $svcdate; // TBD?
431 $duncount = $row['stmt_count'];
432 $enc_note = $row['enc_billing_note'];
434 if ($flagT) {
435 $flagT = false;
436 $aPatientFirstName = $row['fname'];
437 $aPatientID = $row['pid'];
438 $usePatientNamePdf = true;
439 } elseif (!$multiplePatients) {
440 if ($aPatientID != $row['pid']) {
441 $multiplePatients = true;
442 $aPatientFirstName = '';
443 $aPatientID = null;
444 $usePatientNamePdf = false;
448 // If this is a new patient then print the pending statement
449 // and start a new one. This is an associative array:
451 // cid = same as pid
452 // pid = OpenEMR patient ID
453 // patient = patient name
454 // amount = total amount due
455 // adjust = adjustments (already applied to amount)
456 // duedate = due date of the oldest included invoice
457 // age = number of days from duedate to today
458 // to = array of addressee name/address lines
459 // lines = array of:
460 // dos = date of service "yyyy-mm-dd"
461 // desc = description
462 // amount = charge less adjustments
463 // paid = amount paid
464 // notice = 1 for first notice, 2 for second, etc.
465 // detail = array of details, see invoice_summary.inc.php
467 if ($stmt['cid'] != $row['pid']) {
468 if (!empty($stmt)) {
469 ++$stmt_count;
471 $stmt['fid'] = $row['id'];
472 $stmt['cid'] = $row['pid'];
473 $stmt['pid'] = $row['pid'];
474 $stmt['dun_count'] = $row['stmt_count'];
475 $stmt['bill_note'] = $row['pat_billing_note'];
476 $stmt['enc_bill_note'] = $row['enc_billing_note'];
477 $stmt['bill_level'] = $row['last_level_billed'];
478 $stmt['level_closed'] = $row['last_level_closed'];
479 $stmt['patient'] = $row['fname'] . ' ' . $row['lname'];
480 $stmt['encounter'] = $row['encounter'];
481 $stmt['provider_id'] = $row['provider_id'];
482 #If you use the field in demographics layout called
483 #guardiansname this will allow you to send statements to the parent
484 #of a child or a guardian etc
485 if (strlen($row['guardiansname']) == 0) {
486 $stmt['to'] = array($row['fname'] . ' ' . $row['lname']);
487 } else {
488 $stmt['to'] = array($row['guardiansname']);
491 if ($row['street']) {
492 $stmt['to'][] = $row['street'];
495 $stmt['to'][] = $row['city'] . ", " . $row['state'] . " " . $row['postal_code'];
496 $stmt['lines'] = array();
497 $stmt['amount'] = '0.00';
498 $stmt['ins_paid'] = 0;
499 $stmt['today'] = $today;
500 $stmt['duedate'] = $duedate;
501 } else {
502 // Report the oldest due date.
503 if ($duedate < $stmt['duedate']) {
504 $stmt['duedate'] = $duedate;
508 // Recompute age at each invoice.
509 $stmt['age'] = round((strtotime($today) - strtotime($stmt['duedate'])) / (24 * 60 * 60));
511 $invlines = ar_get_invoice_summary($row['pid'], $row['encounter'], true);
512 foreach ($invlines as $key => $value) {
513 $line = array();
514 $line['dos'] = $svcdate;
515 if ($GLOBALS['use_custom_statement']) {
516 $line['desc'] = ($key == 'CO-PAY') ? "Patient Payment" : $value['code_text'];
517 } else {
518 $line['desc'] = ($key == 'CO-PAY') ? "Patient Payment" : "Procedure $key";
521 $line['amount'] = sprintf("%.2f", $value['chg']);
522 $line['adjust'] = sprintf("%.2f", $value['adj']);
523 $line['paid'] = sprintf("%.2f", $value['chg'] - $value['bal']);
524 $line['notice'] = $duncount + 1;
525 $line['detail'] = $value['dtl'];
526 $stmt['lines'][] = $line;
527 $stmt['amount'] = sprintf("%.2f", $stmt['amount'] + $value['bal']);
528 $stmt['ins_paid'] = $stmt['ins_paid'] + $value['ins'];
531 // Record that this statement was run.
532 if (!$DEBUG && !$_REQUEST['form_without']) {
533 sqlStatement("UPDATE form_encounter SET " .
534 "last_stmt_date = ?, stmt_count = stmt_count + 1 " .
535 "WHERE id = ?", array($today, $row['id']));
537 $inv_count += 1;
538 if ($_REQUEST['form_portalnotify']) {
539 if (!is_auth_portal($stmt['pid'])) {
540 $alertmsg = xlt('Notification FAILED: Not Portal Authorized');
541 break;
543 $pvoice[] = $stmt;
544 // we don't want to send the portal multiple invoices, thus this. Last invoice for pid is summary.
545 if ($inv_pid[$inv_count] != $inv_pid[$inv_count + 1]) {
546 fwrite($fhprint, make_statement($stmt));
547 if (!notify_portal($stmt['pid'], $pvoice, $STMT_TEMP_FILE, $stmt['pid'] . "-" . $stmt['encounter'])) {
548 $alertmsg = xlt('Notification FAILED');
549 break;
552 $pvoice = array();
553 flush();
554 ftruncate($fhprint, 0);
555 } else {
556 continue;
558 } else {
559 if ($inv_pid[$inv_count] != $inv_pid[$inv_count + 1]) {
560 $tmp = make_statement($stmt);
561 if (empty($tmp)) {
562 $tmp = xlt("This EOB item does not meet minimum print requirements setup in Globals or there is an unknown error.") . " " . xlt("EOB Id") . ":" . text($inv_pid[$inv_count]) . " " . xlt("Encounter") . ":" . text($stmt[encounter]) . "\n";
563 $tmp .= "<br />\n\014<br /><br />";
565 fwrite($fhprint, $tmp);
568 } // end while
570 if (!empty($stmt)) {
571 ++$stmt_count;
574 fclose($fhprint);
575 sleep(1);
576 // Download or print the file, as selected
577 if ($_REQUEST['form_download']) {
578 upload_file_to_client($STMT_TEMP_FILE);
579 } elseif ($_REQUEST['form_pdf']) {
580 upload_file_to_client_pdf($STMT_TEMP_FILE, $aPatientFirstName, $aPatientID, $usePatientNamePdf);
581 } elseif ($_REQUEST['form_email']) {
582 upload_file_to_client_email($stmt['pid'], $STMT_TEMP_FILE);
583 } elseif ($_REQUEST['form_portalnotify']) {
584 if ($alertmsg == "") {
585 $alertmsg = xl('Sending Invoice to Patient Portal Completed');
587 } else { // Must be print!
588 if ($DEBUG) {
589 $alertmsg = xl("Printing skipped; see test output in") . ' ' . $STMT_TEMP_FILE;
590 } else {
591 exec(escapeshellcmd($STMT_PRINT_CMD) . " " . escapeshellarg($STMT_TEMP_FILE));
592 if ($_REQUEST['form_without']) {
593 $alertmsg = xl('Now printing') . ' ' . $stmt_count . ' ' . xl('statements; invoices will not be updated.');
594 } else {
595 $alertmsg = xl('Now printing') . ' ' . $stmt_count . ' ' . xl('statements and updating invoices.');
597 } // end not debug
598 } // end not form_download
599 } // end statements requested
601 <html>
602 <head>
603 <?php Header::setupHeader(['datetime-picker']); ?>
604 <title><?php echo xlt('EOB Posting - Search'); ?></title>
605 <script language="JavaScript">
606 var mypcc = '1';
607 function reSubmit() {
608 opener.$('#btn-inv-search').click();
610 function editInvoice(e, id) {
611 let url = './sl_eob_invoice.php?isPosting=1&id=' + encodeURIComponent(id);
612 dlgopen(url,'','modal-lg',750,false,'', {
613 onClosed: 'reSubmit'
617 function checkAll(checked) {
618 var f = document.forms[0];
619 for (var i = 0; i < f.elements.length; ++i) {
620 var ename = f.elements[i].name;
621 if (ename.indexOf('form_cb[') == 0)
622 f.elements[i].checked = checked;
626 function persistCriteria(el, e) {
627 e.preventDefault();
628 let target = "sl_eob_search.posting_adj_disable";
629 let val = el.checked ? 'checked' : '';
630 $.post("./../../library/ajax/user_settings.php",
632 target: target,
633 setting: val,
634 csrf_token_form: <?php echo js_escape(collectCsrfToken()); ?>
639 function npopup(pid) {
640 window.open('sl_eob_patient_note.php?patient_id=' + encodeURIComponent(pid), '_blank', 'width=500,height=250,resizable=1');
641 return false;
644 function toEncSummary(pid) {
645 // Tabs only
646 top.restoreSession();
647 let encurl = 'patient_file/history/encounters.php?billing=1&issue=0&pagesize=20&pagestart=0';
648 let paturl = "patient_file/summary/demographics.php?set_pid=" + encodeURIComponent(pid);
649 parent.left_nav.loadFrame('pat2', 'pat', paturl);
650 // need a little time so can force a billing view
651 setTimeout(function(){parent.left_nav.loadFrame('enc2', 'enc', encurl);}, 3000);
654 $(function () {
655 $('.datepicker').datetimepicker({
656 <?php $datetimepicker_timepicker = false; ?>
657 <?php $datetimepicker_showseconds = false; ?>
658 <?php $datetimepicker_formatInput = false; ?>
659 <?php require($GLOBALS['srcdir'] . '/js/xl/jquery-datetimepicker-2-5-4.js.php'); ?>
660 <?php // can add any additional javascript settings to datetimepicker here; need to prepend first setting with a comma ?>
664 </script>
665 <style>
666 @media only screen and (max-width: 768px) {
667 [class*="col-"] {
668 width: 100%;
669 text-align: left !Important;
673 @media only screen and (max-width: 1004px) and (min-width: 641px) {
674 .oe-large {
675 display: none;
678 .oe-small {
679 display: inline-block;
683 @media print {
684 body * {
685 visibility: hidden;
688 .modal-body, .modal-body * {
689 visibility: visible;
692 .modal-body {
693 position: absolute;
694 left: 0;
695 top: 0;
696 width: 100%;
697 height: 10000px;
700 </style>
701 <?php
702 $arrOeUiSettings = array(
703 'heading_title' => xl('EOB Posting - Search'),
704 'include_patient_name' => false,
705 'expandable' => true,
706 'expandable_files' => array('sl_eob_search_xpd'),//all file names need suffix _xpd
707 'action' => "reset",
708 'action_title' => "",
709 'action_href' => "sl_eob_search.php",//only for actions - reset, link or back
710 'show_help_icon' => true,
711 'help_file_name' => "sl_eob_help.php"
713 $oemr_ui = new OemrUI($arrOeUiSettings);
716 </head>
718 <body>
719 <div id="container_div" class="<?php echo attr($oemr_ui->oeContainer()); ?>">
720 <div class="row">
721 <div class="col-sm-12">
722 <div class="page-header">
723 <?php echo $oemr_ui->pageHeading() . "\r\n"; ?>
724 </div>
725 </div>
726 </div>
727 <div class="row">
728 <div class="col-sm-12">
729 <form id="formSearch" action="" enctype='multipart/form-data' method='post'>
730 <input type="hidden" name="csrf_token_form" value="<?php echo attr(collectCsrfToken()); ?>"/>
731 <fieldset id="payment-allocate" class="oe-show-hide">
732 <legend>
733 &nbsp;<?php echo xlt('Post Item'); ?><i id="payment-info-do-not-remove"> </i>
734 </legend>
735 <div class="col-xs-12 oe-custom-line">
736 <div class="col-xs-3">
737 <label class="control-label" for="form_payer_id"> <?php echo xlt('Payer'); ?>:</label>
738 <?php
739 $insurancei = getInsuranceProviders();
740 echo " <select name='form_payer_id'id='form_payer_id' class='form-control'>\n";
741 echo " <option value='0'>-- " . xlt('Patient') . " --</option>\n";
742 foreach ($insurancei as $iid => $iname) {
743 echo "<option value='" . attr($iid) . "'";
744 if ($iid == $_REQUEST['form_payer_id']) {
745 echo " selected";
747 echo ">" . text($iname) . "</option>\n";
749 echo " </select>\n";
751 </div>
752 <div class="col-xs-2">
753 <label class="control-label" for="form_source"><?php echo xlt('Source'); ?>:</label>
754 <input type='text' name='form_source' id='form_source' class='form-control'
755 value='<?php echo attr($_REQUEST['form_source']); ?>'
756 title='<?php echo xla("A check number or claim number to identify the payment"); ?>'>
757 </div>
758 <div class="col-xs-2">
759 <label class="control-label" for="form_paydate"><?php echo xlt('Pay Date'); ?>:</label>
760 <input type='text' name='form_paydate' id='form_paydate' class='form-control datepicker'
761 value='<?php echo attr($_REQUEST['form_paydate']); ?>'
762 onkeyup='datekeyup(this,mypcc)' onblur='dateblur(this,mypcc)'
763 title='<?php echo xla("Date of payment yyyy-mm-dd"); ?>'>
764 </div>
765 <div class="col-xs-2">
766 <label class="control-label oe-large"
767 for="form_deposit_date"><?php echo xlt('Deposit Date'); ?>:</label>
768 <label class="control-label oe-small" for="form_deposit_date"><?php echo xlt('Dep Date'); ?>
769 :</label>
770 <input type='text' name='form_deposit_date' id='form_deposit_date'
771 class='form-control datepicker'
772 value='<?php echo attr($_REQUEST['form_deposit_date']); ?>'
773 onkeyup='datekeyup(this,mypcc)' onblur='dateblur(this,mypcc)'
774 title='<?php echo xla("Date of bank deposit yyyy-mm-dd"); ?>'>
775 </div>
776 <div class="col-xs-2">
777 <label class="control-label" for="form_amount"><?php echo xlt('Amount'); ?>:</label>
778 <input type='text' name='form_amount' id='form_amount' class='form-control'
779 value='<?php echo attr($_REQUEST['form_amount']); ?>'
780 title='<?php echo xla("Paid amount that you will allocate"); ?>'>
781 </div>
782 <div class="col-xs-1">
783 <label class="control-label oe-large" for="only_with_debt"><?php echo xlt('Pt Debt'); ?>:</label>
785 <label class="control-label oe-small" for="only_with_debt"><?php echo xlt('Debt'); ?>:</label>
787 <div class="text-center">
788 <input <?php echo $_REQUEST['only_with_debt'] ? 'checked=checked' : ''; ?>
789 type="checkbox" name="only_with_debt" id="only_with_debt"/>
790 </div>
791 </div>
792 </div>
793 </fieldset>
794 <fieldset id="search-upload">
795 <legend>
796 <i id='select-method-tooltip' class="fa fa-info-circle" aria-hidden="true"></i>
797 <div id="radio-div" class="pull-left oe-legend-radio">
798 <label class="radio-inline">
799 <input type="radio" id="invoice_search" name="radio-search" onclick=""
800 value="inv-search"><?php echo xlt('Invoice Search'); ?>
801 </label>
802 <label class="radio-inline">
803 <input type="radio" id="era_upload" name="radio-search" onclick=""
804 value="era-upld"><?php echo xlt('ERA Upload'); ?>
805 </label>
806 </div>
808 <input type="hidden" id="hid1" value="<?php echo xla('Invoice Search'); ?>">
809 <input type="hidden" id="hid2" value="<?php echo xla('ERA Upload'); ?>">
810 <input type="hidden" id="hid3" value="<?php echo xla('Select Method'); ?>">
811 </legend>
812 <div class="col-xs-12 .oe-custom-line oe-show-hide" id='inv-search'>
813 <div class="col-xs-3">
814 <label class="control-label" for="form_name"><?php echo xlt('Name'); ?>:</label>
815 <input type='text' name='form_name' id='form_name' class='form-control'
816 value='<?php echo attr($_REQUEST['form_name']); ?>'
817 title='<?php echo xla("Any part of the patient name, or \"last,first\", or \"X-Y\""); ?>'
818 placeholder='<?php echo xla('Last name, First name'); ?>'>
819 </div>
820 <div class="col-xs-2">
821 <label class="control-label" for="form_pid"><?php echo xlt('Chart ID'); ?>:</label>
822 <input type='text' name='form_pid' id='form_pid' class='form-control'
823 value='<?php echo attr($_REQUEST['form_pid']); ?>'
824 title='<?php echo xla("Patient chart ID"); ?>'>
825 </div>
826 <div class="col-xs-2">
827 <label class="control-label" for="form_encounter"><?php echo xlt('Encounter'); ?>:</label>
828 <input type='text' name='form_encounter' id='form_encounter' class='form-control'
829 value='<?php echo attr($_REQUEST['form_encounter']); ?>'
830 title='<?php echo xla("Encounter number"); ?>'>
831 </div>
832 <div class="col-xs-2">
833 <label class="control-label oe-large"
834 for="form_date"><?php echo xlt('Service Date From'); ?>:</label>
835 <label class="control-label oe-small" for="form_date"><?php echo xlt('Svc Date'); ?>
836 :</label>
837 <input type='text' name='form_date' id='form_date' class='form-control datepicker'
838 value='<?php echo attr($_REQUEST['form_date']); ?>'
839 title='<?php echo xla("Date of service mm/dd/yyyy"); ?>'>
840 </div>
841 <div class="col-xs-2">
842 <label class="control-label" for="form_to_date"><?php echo xlt('Service Date To'); ?>
843 :</label>
844 <input type='text' name='form_to_date' id='form_to_date' class='form-control datepicker'
845 value='<?php echo attr($_REQUEST['form_to_date']); ?>'
846 title='<?php echo xla("Ending DOS mm/dd/yyyy if you wish to enter a range"); ?>'>
847 </div>
848 <div class="col-xs-1" style="padding-right:0px">
849 <label class="control-label" for="type_name"><?php echo xlt('Type'); ?>:</label>
850 <select name='form_category' id='form_category' class='form-control'>
851 <?php
852 foreach (array(xl('Open'), xl('All'), xl('Due Pt'), xl('Due Ins')) as $value) {
853 echo " <option value='" . attr($value) . "'";
854 if ($_REQUEST['form_category'] == $value) {
855 echo " selected";
857 echo ">" . text($value) . "</option>\n";
860 </select>
861 </div>
862 </div>
863 <div class="col-xs-12 .oe-custom-line oe-show-hide" id='era-upld'>
864 <div class="form-group col-xs9 oe-file-div">
865 <div class="input-group">
866 <label class="input-group-btn">
867 <span class="btn btn-default">Browse&hellip;<input type="file" id="uploadedfile" name="form_erafile" style="display: none;">
868 <input name="MAX_FILE_SIZE" type="hidden" value="5000000">
869 </span>
870 </label>
871 <input type="text" class="form-control"
872 placeholder="<?php echo xla('Click Browse and select one Electronic Remittance Advice (ERA) file...'); ?>"
873 readonly>
874 </div>
875 </div>
876 </div>
877 </fieldset>
878 <?php //can change position of buttons by creating a class 'position-override' and adding rule text-alig:center or right as the case may be in individual stylesheets ?>
879 <div class="form-group clearfix">
880 <div class="col-sm-12 position-override oe-show-hide" id="search-btn">
881 <div class="btn-group" role="group">
882 <button type='submit' class="btn btn-default btn-search oe-show-hide" name='form_search'
883 id="btn-inv-search"
884 value='<?php echo xla("Search"); ?>'><?php echo xlt("Search"); ?></button>
885 <button type='submit' class="btn btn-default btn-save oe-show-hide" name='form_search'
886 id="btn-era-upld"
887 value='<?php echo xla("Upload"); ?>'><?php echo xlt("Upload"); ?></button>
888 </div>
889 </div>
890 </div>
891 <fieldset id="search-results" class="oe-show-hide">
892 <legend><span><?php echo xlt('Search Results'); ?></span>
893 <div class="pull-right oe-legend-radio">
894 <label class="checkbox-inline">
895 <input type="checkbox" id="posting_adj_disable" name="posting_adj_disable"
896 onchange='persistCriteria(this, event)'
897 title="<?php echo xlt("Disable automatically calculating balance adjustments for invoice posting") ?>"
898 value="<?php echo attr($posting_adj_disable); ?>"
899 <?php echo ' ' . attr($posting_adj_disable); ?> /><?php echo xlt('Disable Auto Adjustments'); ?>
900 </label>
901 </div>
902 </legend>
903 <div class="table-responsive">
904 <?php
905 if ($_REQUEST['form_search'] || $_REQUEST['form_print']) {
906 if (!verifyCsrfToken($_REQUEST["csrf_token_form"])) {
907 csrfNotVerified();
910 $form_name = trim($_REQUEST['form_name']);
911 $form_pid = trim($_REQUEST['form_pid']);
912 $form_encounter = trim($_REQUEST['form_encounter']);
913 $form_date = fixDate($_REQUEST['form_date'], "");
914 $form_to_date = fixDate($_REQUEST['form_to_date'], "");
916 $where = "";
918 // Handle X12 835 file upload.
920 if ($_FILES['form_erafile']['size']) {
921 $tmp_name = $_FILES['form_erafile']['tmp_name'];
923 // Handle .zip extension if present. Probably won't work on Windows.
924 if (strtolower(substr($_FILES['form_erafile']['name'], -4)) == '.zip') {
925 rename($tmp_name, "$tmp_name.zip");
926 exec("unzip -p " . escapeshellarg($tmp_name . ".zip") . " > " . escapeshellarg($tmp_name));
927 unlink("$tmp_name.zip");
930 echo "<!-- Notes from ERA upload processing:\n";
931 $alertmsg .= ParseERA::parse_era($tmp_name, 'era_callback');
932 echo "-->\n";
933 $erafullname = $GLOBALS['OE_SITE_DIR'] . "/documents/era/$eraname.edi";
935 if (is_file($erafullname)) {
936 $alertmsg .= "Warning: Set $eraname was already uploaded ";
937 if (is_file($GLOBALS['OE_SITE_DIR'] . "/documents/era/$eraname.html")) {
938 $alertmsg .= "and processed. ";
939 } else {
940 $alertmsg .= "but not yet processed. ";
943 rename($tmp_name, $erafullname);
944 } // End 835 upload
946 if ($eracount) {
947 // Note that ParseERA::parse_era() modified $eracount and $where.
948 if (!$where) {
949 $where = '1 = 2';
951 } else {
952 if ($form_name) {
953 if ($where) {
954 $where .= " AND ";
956 // Allow the last name to be followed by a comma and some part of a first name.
957 if (preg_match('/^(.*\S)\s*,\s*(.*)/', $form_name, $matches)) {
958 $where .= "p.lname LIKE '" . add_escape_custom($matches[1]) . "%' AND p.fname LIKE '" . add_escape_custom($matches[2]) . "%'";
959 // Allow a filter like "A-C" on the first character of the last name.
960 } elseif (preg_match('/^(\S)\s*-\s*(\S)$/', $form_name, $matches)) {
961 $tmp = '1 = 2';
962 while (ord($matches[1]) <= ord($matches[2])) {
963 $tmp .= " OR p.lname LIKE '" . add_escape_custom($matches[1]) . "%'";
964 $matches[1] = chr(ord($matches[1]) + 1);
966 $where .= "( $tmp ) ";
967 } else {
968 $where .= "p.lname LIKE '%" . add_escape_custom($form_name) . "%'";
971 if ($form_pid) {
972 if ($where) {
973 $where .= " AND ";
975 $where .= "f.pid = '" . add_escape_custom($form_pid) . "'";
977 if ($form_encounter) {
978 if ($where) {
979 $where .= " AND ";
981 $where .= "f.encounter = '" . add_escape_custom($form_encounter) . "'";
983 if ($form_date) {
984 if ($where) {
985 $where .= " AND ";
987 if ($form_to_date) {
988 $where .= "f.date >= '" . add_escape_custom($form_date) . "' AND f.date <= '" . add_escape_custom($form_to_date) . "'";
989 } else {
990 $where .= "f.date = '" . add_escape_custom($form_date) . "'";
993 if (!$where) {
994 if ($_REQUEST['form_category'] == 'All') {
995 $alertmsg .= xlt("At least one search parameter is required if you select All.");
996 } else {
997 $where = "1 = 1";
1002 // Notes that as of release 4.1.1 the copays are stored
1003 // in the ar_activity table marked with a PCP in the account_code column.
1004 $query = "SELECT f.id, f.pid, f.encounter, f.date, " .
1005 "f.last_level_billed, f.last_level_closed, f.last_stmt_date, f.stmt_count, " .
1006 "p.fname, p.mname, p.lname, p.pubpid, p.billing_note, " .
1007 "( SELECT SUM(b.fee) FROM billing AS b WHERE " .
1008 "b.pid = f.pid AND b.encounter = f.encounter AND " .
1009 "b.activity = 1 AND b.code_type != 'COPAY' ) AS charges, " .
1010 "( SELECT SUM(a.pay_amount) FROM ar_activity AS a WHERE " .
1011 "a.pid = f.pid AND a.encounter = f.encounter AND a.payer_type = 0 AND a.account_code = 'PCP')*-1 AS copays, " .
1012 "( SELECT SUM(a.pay_amount) FROM ar_activity AS a WHERE " .
1013 "a.pid = f.pid AND a.encounter = f.encounter AND a.account_code != 'PCP') AS payments, " .
1014 "( SELECT SUM(a.adj_amount) FROM ar_activity AS a WHERE " .
1015 "a.pid = f.pid AND a.encounter = f.encounter ) AS adjustments " .
1016 "FROM form_encounter AS f " .
1017 "JOIN patient_data AS p ON p.pid = f.pid " .
1018 "WHERE $where " .
1019 "ORDER BY p.lname, p.fname, p.mname, f.pid, f.encounter";
1021 // Note that unlike the SQL-Ledger case, this query does not weed
1022 // out encounters that are paid up. Also the use of sub-selects
1023 // will require MySQL 4.1 or greater.
1025 // echo "<!-- $query -->\n"; // debugging
1026 $num_invoices = 0;
1027 if (!$alertmsg) {
1028 $t_res = sqlStatement($query);
1029 $num_invoices = sqlNumRows($t_res);
1032 if ($eracount && $num_invoices != $eracount) {
1033 $alertmsg .= "Of $eracount remittances, there are $num_invoices " .
1034 "matching encounters in OpenEMR. ";
1037 <table class="table table-striped table-condensed">
1038 <thead>
1039 <tr>
1040 <th class="id dehead"><?php echo xlt('id'); ?></th>
1041 <th class="dehead">&nbsp;<?php echo xlt('Patient'); ?></th>
1042 <th class="dehead">&nbsp;<?php echo xlt('Invoice'); ?></th>
1043 <th class="dehead">&nbsp;<?php echo xlt('Svc Date'); ?></th>
1044 <th class="dehead">&nbsp;<?php echo xlt('Last Stmt'); ?></th>
1045 <th align="right" class="dehead"><?php echo xlt('Charge'); ?>&nbsp;</th>
1046 <th align="right" class="dehead"><?php echo xlt('Adjust'); ?>&nbsp;</th>
1047 <th align="right" class="dehead"><?php echo xlt('Paid'); ?>&nbsp;</th>
1048 <th align="right" class="dehead"><?php echo xlt('Balance'); ?>&nbsp;</th>
1049 <th align="center" class="dehead"><?php echo xlt('Prv'); ?></th>
1050 <?php
1051 if (!$eracount) { ?>
1052 <th align="left" class="dehead"><?php echo xlt('Sel'); ?></th>
1053 <th align="center" class="dehead"><?php echo xlt('Email'); ?></th>
1054 <?php
1055 } ?>
1056 </tr>
1057 </thead>
1058 <?php
1059 $orow = -1;
1061 while ($row = sqlFetchArray($t_res)) {
1062 $balance = sprintf("%.2f", $row['charges'] + $row['copays'] - $row['payments'] - $row['adjustments']);
1063 //new filter only patients with debt.
1064 if ($_REQUEST['only_with_debt'] && $balance <= 0) {
1065 continue;
1069 if ($_REQUEST['form_category'] != 'All' && $eracount == 0 && $balance == 0) {
1070 continue;
1073 // Determine if customer is in collections.
1075 $billnote = $row['billing_note'];
1076 $in_collections = stristr($billnote, 'IN COLLECTIONS') !== false;
1078 // $duncount was originally supposed to be the number of times that
1079 // the patient was sent a statement for this invoice.
1081 $duncount = $row['stmt_count'];
1083 // But if we have not yet billed the patient, then compute $duncount as a
1084 // negative count of the number of insurance plans for which we have not
1085 // yet closed out insurance.
1087 if (!$duncount) {
1088 for ($i = 1; $i <= 3 && SLEOB::arGetPayerID($row['pid'], $row['date'], $i);
1089 ++$i) {
1091 $duncount = $row['last_level_closed'] + 1 - $i;
1094 $isdueany = ($balance > 0);
1096 // An invoice is now due from the patient if money is owed and we are
1097 // not waiting for insurance to pay.
1099 $isduept = ($duncount >= 0 && $isdueany && !$in_collections) ? " checked" : "";
1101 // Skip invoices not in the desired "Due..." category.
1103 if (substr($_REQUEST['form_category'], 0, 3) == 'Due' && !$isdueany) {
1104 continue;
1106 if ($_REQUEST['form_category'] == 'Due Ins' && ($duncount >= 0 || !$isdueany)) {
1107 continue;
1109 if ($_REQUEST['form_category'] == 'Due Pt' && ($duncount < 0 || !$isdueany)) {
1110 continue;
1113 $bgcolor = ((++$orow & 1) ? "#ffdddd" : "#ddddff");
1115 $svcdate = substr($row['date'], 0, 10);
1116 $last_stmt_date = empty($row['last_stmt_date']) ? '' : $row['last_stmt_date'];
1119 <tr>
1120 <td class="detail">
1121 <a href=""
1122 onclick="return npopup(<?php echo attr_js($row['pid']); ?>)"><?php echo text($row['pid']); ?></a>
1123 </td>
1124 <td class="detail">&nbsp;
1125 <a href=""
1126 onclick="return npopup(<?php echo attr_js($row['pid']); ?>)"><?php echo text($row['lname']) . ', ' . text($row['fname']); ?></a>
1127 </td>
1128 <td class="detail">&nbsp;
1129 <a onclick="editInvoice(event,<?php echo attr_js($row['id']); ?>)"><?php echo text($row['pid']) . '.' . text($row['encounter']); ?></a>
1130 </td>
1131 <td class="detail">&nbsp;<?php echo text(oeFormatShortDate($svcdate)); ?></td>
1132 <td class="detail">
1133 &nbsp;<?php echo text(oeFormatShortDate($last_stmt_date)); ?></td>
1134 <td align="right" class="detail"><?php echo text(bucks($row['charges'])); ?>&nbsp;
1135 </td>
1136 <td align="right" class="detail"><?php echo text(bucks($row['adjustments'])); ?>
1137 &nbsp;
1138 </td>
1139 <td align="right"
1140 class="detail"><?php echo text(bucks($row['payments'] - $row['copays'])); ?>
1141 &nbsp;
1142 </td>
1143 <td align="right" class="detail"><?php echo text(bucks($balance)); ?>&nbsp;</td>
1144 <td align="center"
1145 class="detail"><?php echo $duncount ? text($duncount) : "&nbsp;" ?></td>
1146 <?php if (!$eracount) { ?>
1147 <td class="detail" align="left">
1148 <input type='checkbox'
1149 name='form_cb[<?php echo attr($row['id']) ?>]'<?php echo text($isduept); ?> />
1150 <?php
1151 if ($in_collections) {
1152 echo "<b><font color='red'>IC</font></b>";
1153 } ?>
1154 <?php
1155 if (function_exists('is_auth_portal') ? is_auth_portal($row['pid']) : false) {
1156 echo(' PPt');
1157 echo("<input type='hidden' name='form_invpids[" . attr($row['id']) . "][" . attr($row['pid']) . "]' />");
1158 $is_portal = true;
1159 } ?>
1160 </td>
1161 <?php } ?>
1162 <td align="left" class="detail">
1163 <?php
1164 $patientData = sqlQuery("SELECT * FROM `patient_data` WHERE `pid`=?", array($row['pid']));
1165 if ($patientData['hipaa_allowemail'] == "YES" && $patientData['allow_patient_portal'] == "YES" && $patientData['hipaa_notice'] == "YES" && validEmail($patientData['email'])) {
1166 echo xlt("YES");
1167 } else {
1168 echo xlt("NO");
1171 </td>
1172 </tr>
1173 <?php
1174 } // end while
1175 } // end search/print logic
1177 </table>
1178 </div><!--End of table-responsive div-->
1179 </fieldset>
1180 <?php //can change position of buttons by creating a class 'position-override' and adding rule text-alig:center or right as the case may be in individual stylesheets ?>
1181 <div class="form-group clearfix">
1182 <div class="col-sm-12 text-left position-override oe-show-hide" id="statement-download">
1183 <div class="btn-group" role="group">
1184 <?php
1185 if ($eracount) { ?>
1186 <button type="button" class="btn btn-default btn-save" name="Submit"
1187 onclick='processERA()' value="<?php echo xla('Process ERA File'); ?>">
1188 <?php echo xlt('Process ERA File'); ?></button>
1189 <?php
1190 } else { ?>
1191 <button type="button" class="btn btn-default btn-save" name="Submit1"
1192 onclick='checkAll(true)'><?php echo xlt('Select All'); ?></button>
1193 <button type="button" class="btn btn-default btn-undo" name="Submit2"
1194 onclick='checkAll(false)'><?php echo xlt('Clear All'); ?></button>
1195 <?php if ($GLOBALS['statement_appearance'] != '1') { ?>
1196 <button type="submit" class="btn btn-default btn-print" name='form_print'
1197 value="<?php echo xla('Print Selected Statements'); ?>">
1198 <?php echo xlt('Print Selected Statements'); ?></button>
1199 <button type="submit" class="btn btn-default btn-download" name='form_download'
1200 value="<?php echo xla('Download Selected Statements'); ?>">
1201 <?php echo xlt('Download Selected Statements'); ?></button>
1202 <?php } ?>
1203 <button type="submit" class="btn btn-default btn-download" name='form_pdf'
1204 value="<?php echo xla('PDF Download Selected Statements'); ?>">
1205 <?php echo xlt('PDF Download Selected Statements'); ?></button>
1206 <button type="submit" class="btn btn-default btn-mail" name='form_download'
1207 value="<?php echo xla('Email Selected Statements'); ?>">
1208 <?php echo xlt('Email Selected Statements'); ?></button>
1209 <?php
1210 if ($is_portal) { ?>
1211 <button type="submit" class="btn btn-default btn-save" name='form_portalnotify'
1212 value="<?php echo xla('Notify via Patient Portal'); ?>">
1213 <?php echo xlt('Notify via Patient Portal'); ?></button>
1214 <?php
1218 <input type='checkbox' class="btn-separate-left" name='form_without'
1219 value='1'/><?php echo xlt('Without Update'); ?>
1220 </div>
1221 </div>
1222 </div>
1223 </form>
1224 </div>
1225 </div>
1226 </div> <!--End of Container div-->
1227 <?php $oemr_ui->oeBelowContainerDiv();?>
1229 <script language="JavaScript">
1231 function processERA() {
1232 var f = document.forms[0];
1233 var debug = f.form_without.checked ? '1' : '0';
1234 var paydate = f.form_paydate.value;
1235 window.open('sl_eob_process.php?eraname=' + <?php echo js_url($eraname); ?> + '&debug=' + encodeURIComponent(debug) + '&paydate=' + encodeURIComponent(paydate) + '&original=original' + '&csrf_token_form=' + <?php echo js_url(collectCsrfToken()); ?>, '_blank');
1236 return false;
1239 $(function () {
1240 //https://www.abeautifulsite.net/whipping-file-inputs-into-shape-with-bootstrap-3
1241 // We can attach the `fileselect` event to all file inputs on the page
1242 $(document).on('change', ':file', function () {
1243 var input = $(this),
1244 numFiles = input.get(0).files ? input.get(0).files.length : 1,
1245 label = input.val().replace(/\\/g, '/').replace(/.*\//, '');
1246 input.trigger('fileselect', [numFiles, label]);
1249 // We can watch for our custom `fileselect` event like this
1250 $(function () {
1251 $(':file').on('fileselect', function (event, numFiles, label) {
1252 var input = $(this).parents('.input-group').find(':text'),
1253 log = numFiles > 1 ? numFiles + ' files selected' : label;
1255 if (input.length) {
1256 input.val(log);
1258 else {
1259 if (log) alert(log);
1265 //to dynamically show /hide relevant divs and change Fieldset legends
1266 $(function () {
1267 $("input[name=radio-search]").on("change", function () {
1269 let flip = $(this).val();
1270 $(".oe-show-hide").hide();
1271 $("#" + flip).show();
1272 if (flip == 'inv-search') {
1273 $("#search-upload").insertAfter("#payment-allocate");
1274 $('#payment-allocate').show();
1275 $('#search-btn').show();
1276 $('#btn-inv-search').show();
1277 var legend_text = $('#hid1').val();
1278 $('#search-upload').find('legend').find('span').text(legend_text);
1279 $('#search-upload').find('#form_name').focus();
1280 $('#select-method-tooltip').hide();
1282 else if (flip == 'era-upld') {
1283 $('#payment-allocate').hide();
1284 $('#search-btn').show();
1285 $('#btn-era-upld').show();
1286 var legend_text = $('#hid2').val();
1287 $('#search-upload').find('legend').find('span').text(legend_text);
1288 $('#select-method-tooltip').hide();
1290 else {
1291 $('#payment-allocate').hide();
1292 $('#search-btn').hide();
1293 var legend_text = $('#hid3').val();
1294 $('#search-upload').find('legend').find('span').text(legend_text);
1295 $('#select-method-tooltip').show();
1299 <?php
1300 if ($alertmsg) {
1301 echo "alert('" . addslashes($alertmsg) . "');\n";
1305 $(function () {
1306 //using jquery-ui-1-12-1 tooltip instead of bootstrap tooltip
1307 $('#select-method-tooltip').attr("title", <?php echo xlj('Click on either the Invoice Search button on the far right, for manual entry or ERA Upload button for uploading an entire electronic remittance advice ERA file'); ?>).tooltip();
1309 </script>
1310 <?php
1311 $tr_str = xl('Search');
1312 if ($_REQUEST['form_search'] == "$tr_str") { ?>
1313 <script>
1314 $("#payment-allocate").insertAfter("#search-upload");
1315 $('#payment-allocate').show();
1316 $("#search-results").show();
1317 $("#statement-download").show();
1318 </script>
1319 <?php
1322 <?php
1323 $tr_str = xl('Upload');
1324 if ($_REQUEST['form_search'] == "$tr_str") { ?>
1325 <script>
1326 $('#era-upld').show();
1327 $('#search-results').show();
1328 $("#statement-download").show();
1329 </script>
1330 <?php
1335 </body>
1336 </html>