// // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This provides for manual posting of EOBs. It is invoked from // sl_eob_search.php. For automated (X12 835) remittance posting // see sl_eob_process.php. require_once("../globals.php"); require_once("$srcdir/log.inc"); require_once("$srcdir/patient.inc"); require_once("$srcdir/forms.inc"); require_once("$srcdir/sl_eob.inc.php"); require_once("$srcdir/invoice_summary.inc.php"); require_once("../../custom/code_types.inc.php"); require_once("$srcdir/formdata.inc.php"); $debug = 0; // set to 1 for debugging mode $INTEGRATED_AR = $GLOBALS['oer_config']['ws_accounting']['enabled'] === 2; // If we permit deletion of transactions. Might change this later. $ALLOW_DELETE = $INTEGRATED_AR; $info_msg = ""; // Format money for display. // function bucks($amount) { if ($amount) printf("%.2f", $amount); } // Delete rows, with logging, for the specified table using the // specified WHERE clause. Borrowed from deleter.php. // function row_delete($table, $where) { $tres = sqlStatement("SELECT * FROM $table WHERE $where"); $count = 0; while ($trow = sqlFetchArray($tres)) { $logstring = ""; foreach ($trow as $key => $value) { if (! $value || $value == '0000-00-00 00:00:00') continue; if ($logstring) $logstring .= " "; $logstring .= $key . "='" . addslashes($value) . "'"; } newEvent("delete", $_SESSION['authUser'], $_SESSION['authProvider'], 1, "$table: $logstring"); ++$count; } if ($count) { $query = "DELETE FROM $table WHERE $where"; echo $query . "
\n"; sqlStatement($query); } } ?> <?php xl('EOB Posting - Invoice','e')?> ',"

\n"); } if ($INTEGRATED_AR) { $session_id = arGetSession($form_payer_id, $form_reference, $form_check_date, $form_deposit_date, $form_pay_total); // The sl_eob_search page needs its invoice links modified to invoke // javascript to load form parms for all the above and submit. // At the same time that page would be modified to work off the // openemr database exclusively. // And back to the sl_eob_invoice page, I think we may want to move // the source input fields from row level to header level. // Handle deletes. row_delete() is borrowed from deleter.php. if ($ALLOW_DELETE && !$debug) { foreach ($_POST['form_del'] as $arseq => $dummy) { row_delete("ar_activity", "pid = '$patient_id' AND " . "encounter = '$encounter_id' AND sequence_no = '$arseq'"); } } } $paytotal = 0; foreach ($_POST['form_line'] as $code => $cdata) { if (!$INTEGRATED_AR) { $thissrc = trim($cdata['src']); $thisdate = trim($cdata['date']); } $thispay = trim($cdata['pay']); $thisadj = trim($cdata['adj']); $thisins = trim($cdata['ins']); $reason = strip_escape_custom($cdata['reason']); // Get the adjustment reason type. Possible values are: // 1 = Charge adjustment // 2 = Coinsurance // 3 = Deductible // 4 = Other pt resp // 5 = Comment $reason_type = '1'; if ($reason) { $tmp = sqlQuery("SELECT option_value FROM list_options WHERE " . "list_id = 'adjreason' AND " . "option_id = '" . add_escape_custom($reason) . "'"); if (empty($tmp['option_value'])) { // This should not happen but if it does, apply old logic. if (preg_match("/To copay/", $reason)) { $reason_type = 2; } else if (preg_match("/To ded'ble/", $reason)) { $reason_type = 3; } $info_msg .= xl("No adjustment reason type found for") . " \"$reason\". "; } else { $reason_type = $tmp['option_value']; } } if (! $thisins) $thisins = 0; if ($thispay) { if ($INTEGRATED_AR) { arPostPayment($patient_id, $encounter_id, $session_id, $thispay, $code, $payer_type, '', $debug); } else { slPostPayment($trans_id, $thispay, $thisdate, $thissrc, $code, $thisins, $debug); } $paytotal += $thispay; } // Be sure to record adjustment reasons, even for zero adjustments if // they happen to be comments. if ($thisadj || ($reason && $reason_type == 5)) { // "To copay" and "To ded'ble" need to become a comment in a zero // adjustment, formatted just like sl_eob_process.php. if ($reason_type == '2') { $reason = $_POST['form_insurance'] . " coins: $thisadj"; $thisadj = 0; } else if ($reason_type == '3') { $reason = $_POST['form_insurance'] . " dedbl: $thisadj"; $thisadj = 0; } else if ($reason_type == '4') { $reason = $_POST['form_insurance'] . " ptresp: $thisadj $reason"; $thisadj = 0; } else if ($reason_type == '5') { $reason = $_POST['form_insurance'] . " note: $thisadj $reason"; $thisadj = 0; } else { // An adjustment reason including "Ins" is assumed to be assigned by // insurance, and in that case we identify which one by appending // Ins1, Ins2 or Ins3. if (strpos(strtolower($reason), 'ins') !== false) $reason .= ' ' . $_POST['form_insurance']; } if ($INTEGRATED_AR) { arPostAdjustment($patient_id, $encounter_id, $session_id, $thisadj, $code, $payer_type, $reason, $debug); } else { slPostAdjustment($trans_id, $thisadj, $thisdate, $thissrc, $code, $thisins, $reason, $debug); } } } // Maintain which insurances are marked as finished. if ($INTEGRATED_AR) { $form_done = 0 + $_POST['form_done']; $form_stmt_count = 0 + $_POST['form_stmt_count']; sqlStatement("UPDATE form_encounter " . "SET last_level_closed = $form_done, " . "stmt_count = $form_stmt_count WHERE " . "pid = '$patient_id' AND encounter = '$encounter_id'"); } else { $form_duedate = fixDate($_POST['form_duedate']); $form_notes = trim($_POST['form_notes']); // We use the "Ship Via" field of the invoice to hold these. $form_eobs = ""; foreach (array('Ins1', 'Ins2', 'Ins3') as $value) { if ($_POST["form_done_$value"]) { if ($form_eobs) $form_eobs .= ","; else $form_eobs = "Done: "; $form_eobs .= $value; } } $query = "UPDATE ar SET duedate = '$form_duedate', notes = '$form_notes', " . "shipvia = '$form_eobs' WHERE id = $trans_id"; if ($debug) { echo $query . "
\n"; } else { SLQuery($query); if ($sl_err) die($sl_err); } } if ($_POST['form_secondary']) { if ($INTEGRATED_AR) { arSetupSecondary($patient_id, $encounter_id, $debug); } else { slSetupSecondary($trans_id, $debug); } } echo "\n"; if (!$INTEGRATED_AR) SLClose(); exit(); } if ($INTEGRATED_AR) { // Get invoice charge details. $codes = ar_get_invoice_summary($patient_id, $encounter_id, true); } else { // Get invoice data into $arrow. $arres = SLQuery("select ar.*, customer.name, employee.name as doctor " . "from ar, customer, employee where ar.id = $trans_id and " . "customer.id = ar.customer_id and employee.id = ar.employee_id"); if ($sl_err) die($sl_err); $arrow = SLGetRow($arres, 0); if (! $arrow) die(xl("There is no match for invoice id = ") . $trans_id); // // Determine the date of service. An 8-digit encounter number is // presumed to be a date of service imported during conversion. // Otherwise look it up in the form_encounter table. // $svcdate = ""; list($patient_id, $encounter) = explode(".", $arrow['invnumber']); if (strlen($encounter) == 8) { $svcdate = substr($encounter, 0, 4) . "-" . substr($encounter, 4, 2) . "-" . substr($encounter, 6, 2); } else if ($encounter) { $tmp = sqlQuery("SELECT date FROM form_encounter WHERE " . "encounter = $encounter"); $svcdate = substr($tmp['date'], 0, 10); } // Get invoice charge details. $codes = get_invoice_summary($trans_id, true); } $pdrow = sqlQuery("select genericname2, genericval2 " . "from patient_data where pid = '$patient_id' limit 1"); ?>

\n"; echo xl('Statements Sent:'); echo "\n"; echo "\n"; } ?> \n"; echo xl('Check/EOB No.:'); echo "\n"; echo "\n"; } ?> \n"; echo xl('Check/EOB Date:'); echo "\n"; echo "\n"; } ?> \n"; echo xl('Deposit Date:'); echo "\n"; echo "\n"; } ?>
"; } } } else { echo " \n"; } ?> \n"; echo "\n"; echo "
; 'None', 1 => 'Ins1', 2 => 'Ins2', 3 => 'Ins3') as $key => $value) { if ($key && !arGetPayerID($patient_id, $svcdate, $key)) continue; $checked = ($last_level_closed == $key) ? " checked" : ""; echo " $value \n"; } } else { // The information is stored in the 'shipvia' field of the invoice. $insgot = strtolower($arrow['notes']); $insdone = strtolower($arrow['shipvia']); foreach (array('Ins1', 'Ins2', 'Ins3') as $value) { $lcvalue = strtolower($value); $checked = (strpos($insdone, $lcvalue) === false) ? "" : " checked"; if (strpos($insgot, $lcvalue) !== false) { echo " $value \n"; } } } ?> \n"; echo "\n"; echo "
;       ' /> \n"; echo "\n"; echo "
' title=''>    '>   ' onclick='window.close()'> \n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "
$cdata) { ++$encount; $bgcolor = "#" . (($encount & 1) ? "ddddff" : "ffdddd"); $dispcode = $code; // remember the index of the first entry whose code is not "CO-PAY", i.e. it's a legitimate proc code if ($firstProcCodeIndex == -1 && strcmp($code, "CO-PAY") !=0) $firstProcCodeIndex = $encount; // this sorts the details more or less chronologically: ksort($cdata['dtl']); foreach ($cdata['dtl'] as $dkey => $ddata) { $ddate = substr($dkey, 0, 10); if (preg_match('/^(\d\d\d\d)(\d\d)(\d\d)\s*$/', $ddate, $matches)) { $ddate = $matches[1] . '-' . $matches[2] . '-' . $matches[3]; } $tmpchg = ""; $tmpadj = ""; /***************************************************************** if ($ddata['chg'] > 0) $tmpchg = $ddata['chg']; else if ($ddata['chg'] < 0) $tmpadj = 0 - $ddata['chg']; *****************************************************************/ if ($ddata['chg'] != 0) { if (isset($ddata['rsn'])) $tmpadj = 0 - $ddata['chg']; else $tmpchg = $ddata['chg']; } ?>
 
   
      W