//
// 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);
}
}
?>
\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");
?>