* @author Brady Miller * @copyright Copyright (c) 2006-2020 Rod Roark * @copyright Copyright (c) 2017-2018 Brady Miller * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3 */ require_once("../globals.php"); require_once("$srcdir/patient.inc"); require_once("$srcdir/payment.inc.php"); require_once("$srcdir/forms.inc"); require_once("../../custom/code_types.inc.php"); require_once("$srcdir/options.inc.php"); require_once("$srcdir/encounter_events.inc.php"); use OpenEMR\Billing\BillingUtilities; use OpenEMR\Common\Acl\AclMain; use OpenEMR\Common\Csrf\CsrfUtils; use OpenEMR\Common\Twig\TwigContainer; use OpenEMR\Core\Header; use OpenEMR\OeUI\OemrUI; use OpenEMR\PaymentProcessing\Sphere\SpherePayment; use OpenEMR\Services\FacilityService; if (!empty($_REQUEST['receipt']) && empty($_POST['form_save'])) { if (!AclMain::aclCheckCore('acct', 'bill') && !AclMain::aclCheckCore('acct', 'rep_a') && !AclMain::aclCheckCore('patients', 'rx')) { echo (new TwigContainer(null, $GLOBALS['kernel']))->getTwig()->render('core/unauthorized.html.twig', ['pageTitle' => xl("Receipt for Payment")]); exit; } } else { if (!AclMain::aclCheckCore('acct', 'bill', '', 'write')) { if (!empty($_POST['form_save'])) { $pageTitle = xl("Receipt for Payment"); } else { $pageTitle = xl("Record Payment"); } echo (new TwigContainer(null, $GLOBALS['kernel']))->getTwig()->render('core/unauthorized.html.twig', ['pageTitle' => $pageTitle]); exit; } } $pid = (!empty($_REQUEST['hidden_patient_code']) && ($_REQUEST['hidden_patient_code'] > 0)) ? $_REQUEST['hidden_patient_code'] : $pid; $facilityService = new FacilityService(); ?> \n"; echo " " . text(oeFormatShortDate($date)) . "\n"; echo " " . text($encounter) . "\n"; echo " " . text(bucks($charges)) . "\n"; echo " " . text(bucks($inspaid * -1)) . "\n"; echo " " . text(bucks($ptpaid * -1)) . "\n"; echo " " . text(bucks($patcopay)) . "\n"; echo " " . text(bucks($copay)) . "\n"; echo " " . text(bucks($balance)) . "\n"; echo " " . text(bucks(round($duept, 2) * 1)) . "\n"; echo " \n"; echo " \n"; } // We use this to put dashes, colons, etc. back into a timestamp. // function decorateString($fmt, $str) { $res = ''; while ($fmt) { $fc = substr($fmt, 0, 1); $fmt = substr($fmt, 1); if ($fc == '.') { $res .= substr($str, 0, 1); $str = substr($str, 1); } else { $res .= $fc; } } return $res; } // Compute taxes from a tax rate string and a possibly taxable amount. // function calcTaxes($row, $amount) { $total = 0; if (empty($row['taxrates'])) { return $total; } $arates = explode(':', $row['taxrates']); if (empty($arates)) { return $total; } foreach ($arates as $value) { if (empty($value)) { continue; } $trow = sqlQuery("SELECT option_value FROM list_options WHERE " . "list_id = 'taxrate' AND option_id = ? AND activity = 1 LIMIT 1", array($value)); if (empty($trow['option_value'])) { echo "\n"; continue; } $tax = sprintf("%01.2f", $amount * $trow['option_value']); // echo "\n"; $total += $tax; } return $total; } $now = time(); $today = date('Y-m-d', $now); $timestamp = date('Y-m-d H:i:s', $now); $patdata = sqlQuery("SELECT " . "p.fname, p.mname, p.lname, p.pubpid,p.pid, i.copay " . "FROM patient_data AS p " . "LEFT OUTER JOIN insurance_data AS i ON " . "i.pid = p.pid AND i.type = 'primary' " . "WHERE p.pid = ? ORDER BY i.date DESC LIMIT 1", array($pid)); $alertmsg = ''; // anything here pops up in an alert box // If the Save button was clicked... if (!empty($_POST['form_save'])) { if (!CsrfUtils::verifyCsrfToken($_POST["csrf_token_form"])) { CsrfUtils::csrfNotVerified(); } $form_pid = $_POST['form_pid']; $form_method = trim($_POST['form_method']); $form_source = trim($_POST['form_source']); $patdata = getPatientData($form_pid, 'fname,mname,lname,pubpid'); $NameNew = $patdata['fname'] . " " . $patdata['lname'] . " " . $patdata['mname']; if ($_REQUEST['radio_type_of_payment'] == 'pre_payment') { $payment_id = sqlInsert( "insert into ar_session set " . "payer_id = ?" . ", patient_id = ?" . ", user_id = ?" . ", closed = ?" . ", reference = ?" . ", check_date = now() , deposit_date = now() " . ", pay_total = ?" . ", payment_type = 'patient'" . ", description = ?" . ", adjustment_code = 'pre_payment'" . ", post_to_date = now() " . ", payment_method = ?", array(0, $form_pid, $_SESSION['authUserID'], 0, $form_source, $_REQUEST['form_prepayment'], $NameNew, $form_method) ); frontPayment($form_pid, 0, $form_method, $form_source, $_REQUEST['form_prepayment'], 0, $timestamp);//insertion to 'payments' table. } if ($_POST['form_upay'] && $_REQUEST['radio_type_of_payment'] != 'pre_payment') { foreach ($_POST['form_upay'] as $enc => $payment) { $payment = floatval($payment); if ($amount = $payment) { $zero_enc = $enc; if ($_REQUEST['radio_type_of_payment'] == 'invoice_balance') { if (!$enc) { $enc = calendar_arrived($form_pid); } } else { if (!$enc) { $enc = calendar_arrived($form_pid); } } //---------------------------------------------------------------------------------------------------- //Fetching the existing code and modifier $ResultSearchNew = sqlStatement( "SELECT * FROM billing LEFT JOIN code_types ON billing.code_type=code_types.ct_key " . "WHERE code_types.ct_fee=1 AND billing.activity!=0 AND billing.pid =? AND encounter=? ORDER BY billing.code,billing.modifier", array($form_pid, $enc) ); if ($RowSearch = sqlFetchArray($ResultSearchNew)) { $Codetype = $RowSearch['code_type']; $Code = $RowSearch['code']; $Modifier = $RowSearch['modifier']; } else { $Codetype = ''; $Code = ''; $Modifier = ''; } //---------------------------------------------------------------------------------------------------- if ($_REQUEST['radio_type_of_payment'] == 'copay') {//copay saving to ar_session and ar_activity tables $session_id = sqlInsert( "INSERT INTO ar_session (payer_id,user_id,reference,check_date,deposit_date,pay_total," . " global_amount,payment_type,description,patient_id,payment_method,adjustment_code,post_to_date) " . " VALUES ('0',?,?,now(),now(),?,'','patient','COPAY',?,?,'patient_payment',now())", array($_SESSION['authUserID'], $form_source, $amount, $form_pid, $form_method) ); sqlBeginTrans(); $sequence_no = sqlQuery("SELECT IFNULL(MAX(sequence_no),0) + 1 AS increment FROM ar_activity WHERE pid = ? AND encounter = ?", array($form_pid, $enc)); $insrt_id = sqlInsert( "INSERT INTO ar_activity (pid,encounter,sequence_no,code_type,code,modifier,payer_type,post_time,post_user,session_id,pay_amount,account_code)" . " VALUES (?,?,?,?,?,?,0,now(),?,?,?,'PCP')", array($form_pid, $enc, $sequence_no['increment'], $Codetype, $Code, $Modifier, $_SESSION['authUserID'], $session_id, $amount) ); sqlCommitTrans(); frontPayment($form_pid, $enc, $form_method, $form_source, $amount, 0, $timestamp);//insertion to 'payments' table. } if ($_REQUEST['radio_type_of_payment'] == 'invoice_balance' || $_REQUEST['radio_type_of_payment'] == 'cash') { //Payment by patient after insurance paid, cash patients similar to do not bill insurance in feesheet. if ($_REQUEST['radio_type_of_payment'] == 'cash') { sqlStatement( "update form_encounter set last_level_closed=? where encounter=? and pid=? ", array(4, $enc, $form_pid) ); sqlStatement( "update billing set billed=? where encounter=? and pid=?", array(1, $enc, $form_pid) ); } $adjustment_code = 'patient_payment'; $payment_id = sqlInsert( "insert into ar_session set " . "payer_id = ?" . ", patient_id = ?" . ", user_id = ?" . ", closed = ?" . ", reference = ?" . ", check_date = now() , deposit_date = now() " . ", pay_total = ?" . ", payment_type = 'patient'" . ", description = ?" . ", adjustment_code = ?" . ", post_to_date = now() " . ", payment_method = ?", array(0, $form_pid, $_SESSION['authUserID'], 0, $form_source, $amount, $NameNew, $adjustment_code, $form_method) ); //-------------------------------------------------------------------------------------------------------------------- frontPayment($form_pid, $enc, $form_method, $form_source, 0, $amount, $timestamp);//insertion to 'payments' table. //-------------------------------------------------------------------------------------------------------------------- $resMoneyGot = sqlStatement( "SELECT sum(pay_amount) as PatientPay FROM ar_activity where pid =? and " . "encounter = ? and payer_type = 0 and account_code = 'PCP' AND deleted IS NULL", array($form_pid, $enc) );//new fees screen copay gives account_code='PCP' $rowMoneyGot = sqlFetchArray($resMoneyGot); $Copay = $rowMoneyGot['PatientPay']; //-------------------------------------------------------------------------------------------------------------------- //Looping the existing code and modifier $ResultSearchNew = sqlStatement( "SELECT * FROM billing LEFT JOIN code_types ON billing.code_type=code_types.ct_key WHERE code_types.ct_fee=1 " . "AND billing.activity!=0 AND billing.pid =? AND encounter=? ORDER BY billing.code,billing.modifier", array($form_pid, $enc) ); while ($RowSearch = sqlFetchArray($ResultSearchNew)) { $Codetype = $RowSearch['code_type']; $Code = $RowSearch['code']; $Modifier = $RowSearch['modifier']; $Fee = $RowSearch['fee']; $resMoneyGot = sqlStatement( "SELECT sum(pay_amount) as MoneyGot FROM ar_activity where pid = ? AND deleted IS NULL " . "and code_type=? and code=? and modifier=? and encounter =? and !(payer_type=0 and account_code='PCP')", array($form_pid, $Codetype, $Code, $Modifier, $enc) ); //new fees screen copay gives account_code='PCP' $rowMoneyGot = sqlFetchArray($resMoneyGot); $MoneyGot = $rowMoneyGot['MoneyGot']; $resMoneyAdjusted = sqlStatement( "SELECT sum(adj_amount) as MoneyAdjusted FROM ar_activity where " . "pid = ? and code_type = ? and code = ? and modifier = ? and encounter = ? AND deleted IS NULL", array($form_pid, $Codetype, $Code, $Modifier, $enc) ); $rowMoneyAdjusted = sqlFetchArray($resMoneyAdjusted); $MoneyAdjusted = $rowMoneyAdjusted['MoneyAdjusted']; $Remainder = $Fee - $Copay - $MoneyGot - $MoneyAdjusted; $Copay = 0; if (round($Remainder, 2) != 0 && $amount != 0) { if ($amount - $Remainder >= 0) { $insert_value = $Remainder; $amount = $amount - $Remainder; } else { $insert_value = $amount; $amount = 0; } sqlBeginTrans(); $sequence_no = sqlQuery("SELECT IFNULL(MAX(sequence_no),0) + 1 AS increment FROM ar_activity WHERE pid = ? AND encounter = ?", array($form_pid, $enc)); sqlStatement( "insert into ar_activity set " . "pid = ?" . ", encounter = ?" . ", sequence_no = ?" . ", code_type = ?" . ", code = ?" . ", modifier = ?" . ", payer_type = ?" . ", post_time = now() " . ", post_user = ?" . ", session_id = ?" . ", pay_amount = ?" . ", adj_amount = ?" . ", account_code = 'PP'", array($form_pid, $enc, $sequence_no['increment'], $Codetype, $Code, $Modifier, 0, $_SESSION['authUserID'], $payment_id, $insert_value, 0) ); sqlCommitTrans(); }//if }//while if ($amount != 0) {//if any excess is there. sqlBeginTrans(); $sequence_no = sqlQuery("SELECT IFNULL(MAX(sequence_no),0) + 1 AS increment FROM ar_activity WHERE pid = ? AND encounter = ?", array($form_pid, $enc)); sqlStatement( "insert into ar_activity set " . "pid = ?" . ", encounter = ?" . ", sequence_no = ?" . ", code_type = ?" . ", code = ?" . ", modifier = ?" . ", payer_type = ?" . ", post_time = now() " . ", post_user = ?" . ", session_id = ?" . ", pay_amount = ?" . ", adj_amount = ?" . ", account_code = 'PP'", array($form_pid, $enc, $sequence_no['increment'], $Codetype, $Code, $Modifier, 0, $_SESSION['authUserID'], $payment_id, $amount, 0) ); sqlCommitTrans(); } //-------------------------------------------------------------------------------------------------------------------- }//invoice_balance }//if ($amount = 0 + $payment) }//foreach }//if ($_POST['form_upay']) }//if ($_POST['form_save']) if (!empty($_POST['form_save']) || !empty($_REQUEST['receipt'])) { if (!empty($_REQUEST['receipt'])) { $form_pid = $_GET['patient']; $timestamp = decorateString('....-..-.. ..:..:..', $_GET['time']); } // Get details for what we guess is the primary facility. $frow = $facilityService->getPrimaryBusinessEntity(array("useLegacyImplementation" => true)); // Get the patient's name and chart number. $patdata = getPatientData($form_pid, 'fname,mname,lname,pubpid'); // Re-fetch payment info. $payrow = sqlQuery("SELECT " . "SUM(amount1) AS amount1, " . "SUM(amount2) AS amount2, " . "MAX(method) AS method, " . "MAX(source) AS source, " . "MAX(dtime) AS dtime, " . // "MAX(user) AS user " . "MAX(user) AS user, " . "MAX(encounter) as encounter " . "FROM payments WHERE " . "pid = ? AND dtime = ?", array($form_pid, $timestamp)); // Create key for deleting, just in case. $ref_id = ($_REQUEST['radio_type_of_payment'] == 'copay') ? $session_id : $payment_id; $payment_key = $form_pid . '.' . preg_replace('/[^0-9]/', '', $timestamp) . '.' . $ref_id; if ($_REQUEST['radio_type_of_payment'] != 'pre_payment') { // get facility from encounter $tmprow = sqlQuery("SELECT `facility_id` FROM `form_encounter` WHERE `encounter` = ?", array($payrow['encounter'])); $frow = $facilityService->getById($tmprow['facility_id']); } else { // if pre_payment, then no encounter yet, so get main office address $frow = $facilityService->getPrimaryBillingLocation(); } // Now proceed with printing the receipt. ?> <?php echo xlt('Receipt for Payment'); ?>




:
:
: '1', 'list_id' => 'payment_method'), $payrow['method']); ?>
:
:
:
:
\n"; } ?>
<?php echo xlt('Record Payment'); ?> <?php echo xlt('Record Payment'); ?> xl('Accept Payment'), 'include_patient_name' => true,// use only in appropriate pages 'expandable' => false, 'expandable_files' => array(),//all file names need suffix _xpd 'action' => "",//conceal, reveal, search, reset, link or back 'action_title' => "", 'action_href' => "",//only for actions - reset, link or back 'show_help_icon' => false, 'help_file_name' => "" ); $oemr_ui = new OemrUI($arrOeUiSettings); ?>
pageHeading() . "\r\n"; ?>
' />
$brow['encounter'], 'date' => $brow['encdate'], 'last_level_closed' => $brow['last_level_closed'], 'charges' => 0, 'payments' => 0); } if ($brow['code_type'] === 'COPAY') { //$encs[$key]['payments'] -= $brow['fee']; } else { $encs[$key]['charges'] += $brow['fee']; // Add taxes. $sql_array = array(); $query = "SELECT taxrates FROM codes WHERE " . "code_type = ? AND " . "code = ? AND "; array_push($sql_array, ($code_types[$brow['code_type']]['id'] ?? null), $brow['code']); if ($brow['modifier']) { $query .= "modifier = ?"; array_push($sql_array, $brow['modifier']); } else { $query .= "(modifier IS NULL OR modifier = '')"; } $query .= " LIMIT 1"; $trow = sqlQuery($query, $sql_array); $encs[$key]['charges'] += calcTaxes($trow, $brow['fee']); } } // Do the same for unbilled product sales. // $query = "SELECT fe.encounter, s.drug_id, s.fee, " . "LEFT(fe.date, 10) AS encdate,fe.last_level_closed " . "FROM form_encounter AS fe left join drug_sales AS s " . "on s.pid = ? AND s.fee != 0 " . //AND s.billed = 0 "AND fe.pid = s.pid AND fe.encounter = s.encounter " . "where fe.pid = ? " . "ORDER BY s.encounter"; $dres = sqlStatement($query, array($pid, $pid)); // while ($drow = sqlFetchArray($dres)) { $key = 0 - $drow['encounter']; if (empty($encs[$key])) { $encs[$key] = array( 'encounter' => $drow['encounter'], 'date' => $drow['encdate'], 'last_level_closed' => $drow['last_level_closed'], 'charges' => 0, 'payments' => 0); } $encs[$key]['charges'] += $drow['fee']; // Add taxes. $trow = sqlQuery("SELECT taxrates FROM drug_templates WHERE drug_id = ? " . "ORDER BY selector LIMIT 1", array($drow['drug_id'])); $encs[$key]['charges'] += calcTaxes($trow, $drow['fee']); } ksort($encs, SORT_NUMERIC); $gottoday = false; //Bringing on top the Today always foreach ($encs as $key => $value) { $dispdate = $value['date']; if (strcmp($dispdate, $today) == 0 && !$gottoday) { $gottoday = true; break; } } // If no billing was entered yet for today, then generate a line for // entering today's co-pay. // if (!$gottoday) { echoLine("form_upay[0]", date("Y-m-d"), 0, 0, 0, 0 /*$duept*/);//No encounter yet defined. } $gottoday = false; foreach ($encs as $key => $value) { $enc = $value['encounter']; $dispdate = $value['date']; if (strcmp($dispdate, $today) == 0 && !$gottoday) { $dispdate = date("Y-m-d"); $gottoday = true; } //------------------------------------------------------------------------------------ $inscopay = BillingUtilities::getCopay($pid, $dispdate); $patcopay = BillingUtilities::getPatientCopay($pid, $enc); //Insurance Payment //----------------- $drow = sqlQuery( "SELECT SUM(pay_amount) AS payments, " . "SUM(adj_amount) AS adjustments FROM ar_activity WHERE " . "deleted IS NULL AND pid = ? and encounter = ? and " . "payer_type != 0 and account_code!='PCP' ", array($pid, $enc) ); $dpayment = $drow['payments']; $dadjustment = $drow['adjustments']; //Patient Payment //--------------- $drow = sqlQuery( "SELECT SUM(pay_amount) AS payments, " . "SUM(adj_amount) AS adjustments FROM ar_activity WHERE " . "deleted IS NULL AND pid = ? and encounter = ? and " . "payer_type = 0 and account_code!='PCP' ", array($pid, $enc) ); $dpayment_pat = $drow['payments']; //------------------------------------------------------------------------------------ //NumberOfInsurance $ResultNumberOfInsurance = sqlStatement("SELECT COUNT( DISTINCT TYPE ) NumberOfInsurance FROM insurance_data where pid = ? and provider>0 ", array($pid)); $RowNumberOfInsurance = sqlFetchArray($ResultNumberOfInsurance); $NumberOfInsurance = $RowNumberOfInsurance['NumberOfInsurance'] * 1; //------------------------------------------------------------------------------------ $duept = 0; if ((($NumberOfInsurance == 0 || $value['last_level_closed'] == 4 || $NumberOfInsurance == $value['last_level_closed']))) {//Patient balance $brow = sqlQuery("SELECT SUM(fee) AS amount FROM billing WHERE " . "pid = ? and encounter = ? AND activity = 1", array($pid, $enc)); $srow = sqlQuery("SELECT SUM(fee) AS amount FROM drug_sales WHERE " . "pid = ? and encounter = ? ", array($pid, $enc)); $drow = sqlQuery("SELECT SUM(pay_amount) AS payments, " . "SUM(adj_amount) AS adjustments FROM ar_activity WHERE " . "deleted IS NULL AND pid = ? and encounter = ? ", array($pid, $enc)); $duept = $brow['amount'] + $srow['amount'] - $drow['payments'] - $drow['adjustments']; } echoLine( "form_upay[$enc]", $dispdate, $value['charges'], $dpayment_pat, ($dpayment + $dadjustment), $duept, $enc, $inscopay, $patcopay ); } // Continue with display of the data entry form. ?>
' . xlt("Credit Card Pay") . ''; if (!empty($GLOBALS['cc_stripe_terminal'])) { echo ''; } } } ?>
renderSphereJs(); } ?>
oeBelowContainerDiv(); } // forms else close ?>