7 * @link http://www.open-emr.org
8 * @author Rod Roark <rod@sunsetsystems.com>
9 * @author Brady Miller <brady.g.miller@gmail.com>
10 * @copyright Copyright (c) 2006-2020 Rod Roark <rod@sunsetsystems.com>
11 * @copyright Copyright (c) 2017-2018 Brady Miller <brady.g.miller@gmail.com>
12 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
15 require_once("../globals.php");
16 require_once("$srcdir/patient.inc.php");
17 require_once("$srcdir/payment.inc.php");
18 require_once("$srcdir/forms.inc.php");
19 require_once("../../custom/code_types.inc.php");
20 require_once("$srcdir/options.inc.php");
21 require_once("$srcdir/encounter_events.inc.php");
23 use OpenEMR\Billing\BillingUtilities
;
24 use OpenEMR\Common\Acl\AclMain
;
25 use OpenEMR\Common\Csrf\CsrfUtils
;
26 use OpenEMR\Common\Twig\TwigContainer
;
27 use OpenEMR\Core\Header
;
28 use OpenEMR\OeUI\OemrUI
;
29 use OpenEMR\PaymentProcessing\Sphere\SpherePayment
;
30 use OpenEMR\Services\FacilityService
;
32 if (!empty($_REQUEST['receipt']) && empty($_POST['form_save'])) {
33 if (!AclMain
::aclCheckCore('acct', 'bill') && !AclMain
::aclCheckCore('acct', 'rep_a') && !AclMain
::aclCheckCore('patients', 'rx')) {
34 echo (new TwigContainer(null, $GLOBALS['kernel']))->getTwig()->render('core/unauthorized.html.twig', ['pageTitle' => xl("Receipt for Payment")]);
38 if (!AclMain
::aclCheckCore('acct', 'bill', '', 'write')) {
39 if (!empty($_POST['form_save'])) {
40 $pageTitle = xl("Receipt for Payment");
42 $pageTitle = xl("Record Payment");
44 echo (new TwigContainer(null, $GLOBALS['kernel']))->getTwig()->render('core/unauthorized.html.twig', ['pageTitle' => $pageTitle]);
49 $pid = (!empty($_REQUEST['hidden_patient_code']) && ($_REQUEST['hidden_patient_code'] > 0)) ?
$_REQUEST['hidden_patient_code'] : $pid;
51 $facilityService = new FacilityService();
57 <?php Header
::setupHeader(['opener']);?
>
58 <?php
if ($GLOBALS['payment_gateway'] == 'Stripe') { ?
>
59 <script src
="https://js.stripe.com/v3/"></script
>
61 <?php
if ($GLOBALS['payment_gateway'] == 'AuthorizeNet') {
62 // Must be loaded from their server
63 $script = "https://jstest.authorize.net/v1/Accept.js"; // test script
64 if ($GLOBALS['gateway_mode_production']) {
65 $script = "https://js.authorize.net/v1/Accept.js"; // Production script
67 <script src
=<?php
echo $script; ?
> charset
="utf-8"></script
>
70 // Format dollars for display.
72 function bucks($amount)
75 $amount = oeFormatMoney($amount);
81 function rawbucks($amount)
84 $amount = sprintf("%.2f", $amount);
90 // Display a row of data for an encounter.
93 function echoLine($iname, $date, $charges, $ptpaid, $inspaid, $duept, $encounter = 0, $copay = 0, $patcopay = 0)
97 $balance = bucks($charges - $ptpaid - $inspaid);
98 $balance = (round($duept, 2) != 0) ?
0 : $balance;//if balance is due from patient, then insurance balance is displayed as zero
99 $encounter = $encounter ?
$encounter : '';
100 echo " <tr id='tr_" . attr($var_index) . "' >\n";
101 echo " <td>" . text(oeFormatShortDate($date)) . "</td>\n";
102 echo " <td class='text-center' id='" . attr($date) . "'>" . text($encounter) . "</td>\n";
103 echo " <td class='text-center' id='td_charges_$var_index' >" . text(bucks($charges)) . "</td>\n";
104 echo " <td class='text-center' id='td_inspaid_$var_index' >" . text(bucks($inspaid * -1)) . "</td>\n";
105 echo " <td class='text-center' id='td_ptpaid_$var_index' >" . text(bucks($ptpaid * -1)) . "</td>\n";
106 echo " <td class='text-center' id='td_patient_copay_$var_index' >" . text(bucks($patcopay)) . "</td>\n";
107 echo " <td class='text-center' id='td_copay_$var_index' >" . text(bucks($copay)) . "</td>\n";
108 echo " <td class='text-center' id='balance_$var_index'>" . text(bucks($balance)) . "</td>\n";
109 echo " <td class='text-center' id='duept_$var_index'>" . text(bucks(round($duept, 2) * 1)) . "</td>\n";
110 echo " <td class='text-right'><input type='text' class='form-control' name='" . attr($iname) . "' id='paying_" . attr($var_index) . "' " .
111 " value='' onchange='coloring();calctotal()' autocomplete='off' " .
112 "onkeyup='calctotal()'/></td>\n";
116 // We use this to put dashes, colons, etc. back into a timestamp.
118 function decorateString($fmt, $str)
122 $fc = substr($fmt, 0, 1);
123 $fmt = substr($fmt, 1);
125 $res .= substr($str, 0, 1);
126 $str = substr($str, 1);
135 // Compute taxes from a tax rate string and a possibly taxable amount.
137 function calcTaxes($row, $amount)
140 if (empty($row['taxrates'])) {
144 $arates = explode(':', $row['taxrates']);
145 if (empty($arates)) {
149 foreach ($arates as $value) {
154 $trow = sqlQuery("SELECT option_value FROM list_options WHERE " .
155 "list_id = 'taxrate' AND option_id = ? AND activity = 1 LIMIT 1", array($value));
156 if (empty($trow['option_value'])) {
157 echo "<!-- Missing tax rate '" . text($value) . "'! -->\n";
161 $tax = sprintf("%01.2f", $amount * $trow['option_value']);
162 // echo "<!-- Rate = '$value', amount = '$amount', tax = '$tax' -->\n";
170 $today = date('Y-m-d', $now);
171 $timestamp = date('Y-m-d H:i:s', $now);
173 $patdata = sqlQuery("SELECT " .
174 "p.fname, p.mname, p.lname, p.pubpid,p.pid, i.copay " .
175 "FROM patient_data AS p " .
176 "LEFT OUTER JOIN insurance_data AS i ON " .
177 "i.pid = p.pid AND i.type = 'primary' " .
178 "WHERE p.pid = ? ORDER BY i.date DESC LIMIT 1", array($pid));
180 $alertmsg = ''; // anything here pops up in an alert box
182 // If the Save button was clicked...
183 if (!empty($_POST['form_save'])) {
184 if (!CsrfUtils
::verifyCsrfToken($_POST["csrf_token_form"])) {
185 CsrfUtils
::csrfNotVerified();
188 $form_pid = $_POST['form_pid'];
189 $form_method = trim($_POST['form_method']);
190 $form_source = trim($_POST['form_source']);
191 $patdata = getPatientData($form_pid, 'fname,mname,lname,pubpid');
192 $NameNew = $patdata['fname'] . " " . $patdata['lname'] . " " . $patdata['mname'];
194 if ($_REQUEST['radio_type_of_payment'] == 'pre_payment') {
195 $payment_id = sqlInsert(
196 "insert into ar_session set " .
202 ", check_date = now() , deposit_date = now() " .
204 ", payment_type = 'patient'" .
205 ", description = ?" .
206 ", adjustment_code = 'pre_payment'" .
207 ", post_to_date = now() " .
208 ", payment_method = ?",
209 array(0, $form_pid, $_SESSION['authUserID'], 0, $form_source, $_REQUEST['form_prepayment'], $NameNew, $form_method)
212 frontPayment($form_pid, 0, $form_method, $form_source, $_REQUEST['form_prepayment'], 0, $timestamp);//insertion to 'payments' table.
215 if ($_POST['form_upay'] && $_REQUEST['radio_type_of_payment'] != 'pre_payment') {
216 foreach ($_POST['form_upay'] as $enc => $payment) {
217 $payment = floatval($payment);
218 if ($amount = $payment) {
220 if ($_REQUEST['radio_type_of_payment'] == 'invoice_balance') {
222 $enc = calendar_arrived($form_pid);
226 $enc = calendar_arrived($form_pid);
230 //----------------------------------------------------------------------------------------------------
231 //Fetching the existing code and modifier
232 $ResultSearchNew = sqlStatement(
233 "SELECT * FROM billing LEFT JOIN code_types ON billing.code_type=code_types.ct_key " .
234 "WHERE code_types.ct_fee=1 AND billing.activity!=0 AND billing.pid =? AND encounter=? ORDER BY billing.code,billing.modifier",
235 array($form_pid, $enc)
237 if ($RowSearch = sqlFetchArray($ResultSearchNew)) {
238 $Codetype = $RowSearch['code_type'];
239 $Code = $RowSearch['code'];
240 $Modifier = $RowSearch['modifier'];
247 //----------------------------------------------------------------------------------------------------
248 if ($_REQUEST['radio_type_of_payment'] == 'copay') {//copay saving to ar_session and ar_activity tables
249 $session_id = sqlInsert(
250 "INSERT INTO ar_session (payer_id,user_id,reference,check_date,deposit_date,pay_total," .
251 " global_amount,payment_type,description,patient_id,payment_method,adjustment_code,post_to_date) " .
252 " VALUES ('0',?,?,now(),now(),?,'','patient','COPAY',?,?,'patient_payment',now())",
253 array($_SESSION['authUserID'], $form_source, $amount, $form_pid, $form_method)
257 $sequence_no = sqlQuery("SELECT IFNULL(MAX(sequence_no),0) + 1 AS increment FROM ar_activity WHERE pid = ? AND encounter = ?", array($form_pid, $enc));
258 $insrt_id = sqlInsert(
259 "INSERT INTO ar_activity (pid,encounter,sequence_no,code_type,code,modifier,payer_type,post_time,post_user,session_id,pay_amount,account_code)" .
260 " VALUES (?,?,?,?,?,?,0,now(),?,?,?,'PCP')",
261 array($form_pid, $enc, $sequence_no['increment'], $Codetype, $Code, $Modifier, $_SESSION['authUserID'], $session_id, $amount)
265 frontPayment($form_pid, $enc, $form_method, $form_source, $amount, 0, $timestamp);//insertion to 'payments' table.
268 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.
269 if ($_REQUEST['radio_type_of_payment'] == 'cash') {
271 "update form_encounter set last_level_closed=? where encounter=? and pid=? ",
272 array(4, $enc, $form_pid)
275 "update billing set billed=? where encounter=? and pid=?",
276 array(1, $enc, $form_pid)
280 $adjustment_code = 'patient_payment';
281 $payment_id = sqlInsert(
282 "insert into ar_session set " .
288 ", check_date = now() , deposit_date = now() " .
290 ", payment_type = 'patient'" .
291 ", description = ?" .
292 ", adjustment_code = ?" .
293 ", post_to_date = now() " .
294 ", payment_method = ?",
295 array(0, $form_pid, $_SESSION['authUserID'], 0, $form_source, $amount, $NameNew, $adjustment_code, $form_method)
298 //--------------------------------------------------------------------------------------------------------------------
300 frontPayment($form_pid, $enc, $form_method, $form_source, 0, $amount, $timestamp);//insertion to 'payments' table.
302 //--------------------------------------------------------------------------------------------------------------------
304 $resMoneyGot = sqlStatement(
305 "SELECT sum(pay_amount) as PatientPay FROM ar_activity where pid =? and " .
306 "encounter = ? and payer_type = 0 and account_code = 'PCP' AND deleted IS NULL",
307 array($form_pid, $enc)
308 );//new fees screen copay gives account_code='PCP'
309 $rowMoneyGot = sqlFetchArray($resMoneyGot);
310 $Copay = $rowMoneyGot['PatientPay'];
312 //--------------------------------------------------------------------------------------------------------------------
314 //Looping the existing code and modifier
315 $ResultSearchNew = sqlStatement(
316 "SELECT * FROM billing LEFT JOIN code_types ON billing.code_type=code_types.ct_key WHERE code_types.ct_fee=1 " .
317 "AND billing.activity!=0 AND billing.pid =? AND encounter=? ORDER BY billing.code,billing.modifier",
318 array($form_pid, $enc)
320 while ($RowSearch = sqlFetchArray($ResultSearchNew)) {
321 $Codetype = $RowSearch['code_type'];
322 $Code = $RowSearch['code'];
323 $Modifier = $RowSearch['modifier'];
324 $Fee = $RowSearch['fee'];
326 $resMoneyGot = sqlStatement(
327 "SELECT sum(pay_amount) as MoneyGot FROM ar_activity where pid = ? AND deleted IS NULL " .
328 "and code_type=? and code=? and modifier=? and encounter =? and !(payer_type=0 and account_code='PCP')",
329 array($form_pid, $Codetype, $Code, $Modifier, $enc)
331 //new fees screen copay gives account_code='PCP'
332 $rowMoneyGot = sqlFetchArray($resMoneyGot);
333 $MoneyGot = $rowMoneyGot['MoneyGot'];
335 $resMoneyAdjusted = sqlStatement(
336 "SELECT sum(adj_amount) as MoneyAdjusted FROM ar_activity where " .
337 "pid = ? and code_type = ? and code = ? and modifier = ? and encounter = ? AND deleted IS NULL",
338 array($form_pid, $Codetype, $Code, $Modifier, $enc)
340 $rowMoneyAdjusted = sqlFetchArray($resMoneyAdjusted);
341 $MoneyAdjusted = $rowMoneyAdjusted['MoneyAdjusted'];
343 $Remainder = $Fee - $Copay - $MoneyGot - $MoneyAdjusted;
345 if (round($Remainder, 2) != 0 && $amount != 0) {
346 if ($amount - $Remainder >= 0) {
347 $insert_value = $Remainder;
348 $amount = $amount - $Remainder;
350 $insert_value = $amount;
355 $sequence_no = sqlQuery("SELECT IFNULL(MAX(sequence_no),0) + 1 AS increment FROM ar_activity WHERE pid = ? AND encounter = ?", array($form_pid, $enc));
357 "insert into ar_activity set " .
360 ", sequence_no = ?" .
365 ", post_time = now() " .
370 ", account_code = 'PP'",
371 array($form_pid, $enc, $sequence_no['increment'], $Codetype, $Code, $Modifier, 0, $_SESSION['authUserID'], $payment_id, $insert_value, 0)
376 if ($amount != 0) {//if any excess is there.
378 $sequence_no = sqlQuery("SELECT IFNULL(MAX(sequence_no),0) + 1 AS increment FROM ar_activity WHERE pid = ? AND encounter = ?", array($form_pid, $enc));
380 "insert into ar_activity set " .
383 ", sequence_no = ?" .
388 ", post_time = now() " .
393 ", account_code = 'PP'",
394 array($form_pid, $enc, $sequence_no['increment'], $Codetype, $Code, $Modifier, 0, $_SESSION['authUserID'], $payment_id, $amount, 0)
399 //--------------------------------------------------------------------------------------------------------------------
401 }//if ($amount = 0 + $payment)
403 }//if ($_POST['form_upay'])
404 }//if ($_POST['form_save'])
406 if (!empty($_POST['form_save']) ||
!empty($_REQUEST['receipt'])) {
407 if (!empty($_REQUEST['receipt'])) {
408 $form_pid = $_GET['patient'];
409 $timestamp = decorateString('....-..-.. ..:..:..', $_GET['time']);
412 // Get details for what we guess is the primary facility.
413 $frow = $facilityService->getPrimaryBusinessEntity(array("useLegacyImplementation" => true));
415 // Get the patient's name and chart number.
416 $patdata = getPatientData($form_pid, 'fname,mname,lname,pubpid');
418 // Re-fetch payment info.
419 $payrow = sqlQuery("SELECT " .
420 "SUM(amount1) AS amount1, " .
421 "SUM(amount2) AS amount2, " .
422 "MAX(method) AS method, " .
423 "MAX(source) AS source, " .
424 "MAX(dtime) AS dtime, " .
425 // "MAX(user) AS user " .
426 "MAX(user) AS user, " .
427 "MAX(encounter) as encounter " .
428 "FROM payments WHERE " .
429 "pid = ? AND dtime = ?", array($form_pid, $timestamp));
431 // Create key for deleting, just in case.
432 $ref_id = ($_REQUEST['radio_type_of_payment'] == 'copay') ?
$session_id : $payment_id;
433 $payment_key = $form_pid . '.' . preg_replace('/[^0-9]/', '', $timestamp) . '.' . $ref_id;
435 if ($_REQUEST['radio_type_of_payment'] != 'pre_payment') {
436 // get facility from encounter
437 $tmprow = sqlQuery("SELECT `facility_id` FROM `form_encounter` WHERE `encounter` = ?", array($payrow['encounter']));
438 $frow = $facilityService->getById($tmprow['facility_id']);
440 // if pre_payment, then no encounter yet, so get main office address
441 $frow = $facilityService->getPrimaryBillingLocation();
444 // Now proceed with printing the receipt.
447 <title
><?php
echo xlt('Receipt for Payment'); ?
></title
>
448 <?php Header
::setupHeader(); ?
>
451 <?php
require($GLOBALS['srcdir'] . "/restoreSession.php"); ?
>
454 var win
= top
.printLogSetup ? top
: opener
.top
;
455 win
.printLogSetup(document
.getElementById('printbutton'));
458 function closeHow(e
) {
463 top
.activateTabByName('pat', true);
464 top
.tabCloseByName(window
.name
);
467 // This is action to take before printing and is called from restoreSession.php.
468 function printlog_before_print() {
469 let divstyle
= document
.getElementById('hideonprint').style
;
470 divstyle
.display
= 'none';
471 // currently exit is not hidden by default in case receipt print is not needed
472 // and left here for future option to force users to print via global etc..
473 // can still print later via reports.
474 divstyle
= document
.getElementById('showonprint').style
;
475 divstyle
.display
= '';
478 // Process click on Delete button.
479 function deleteme() {
480 dlgopen('deleter.php?payment=' +
<?php
echo js_url($payment_key); ?
> +
'&csrf_token_form=' +
<?php
echo js_url(CsrfUtils
::collectCsrfToken()); ?
>, '_blank', 500, 450);
484 // Called by the deleteme.php window on a successful delete.
485 function imdeleted() {
487 dlgclose(); // we're in reports/leftnav and callback reloads.
489 window
.history
.back(); // this is us full screen.
493 // Called to switch to the specified encounter having the specified DOS.
494 // This also closes the popup window.
495 function toencounter(enc
, datestr
, topframe
) {
496 top
.restoreSession();
497 top
.goToEncounter(enc
);
498 if (opener
) dlgclose();
511 <div
class="container mt-3">
513 <div
class="col-12 text-center">
514 <h2
><?php
echo xlt('Receipt for Payment'); ?
></h2
>
516 <?php
echo text($frow['name']) ?
>
518 <?php
echo text($frow['street']) ?
>
520 <?php
echo text($frow['city'] . ', ' . $frow['state']) . ' ' . text($frow['postal_code']) ?
>
522 <?php
echo text($frow['phone']) ?
>
525 <div
class="table-responsive">
526 <table
class="table table-borderless">
528 <td
><?php
echo xlt('Date'); ?
>:</td
>
529 <td
><?php
echo text(oeFormatSDFT(strtotime($payrow['dtime']))) ?
></td
>
532 <td
><?php
echo xlt('Patient'); ?
>:</td
>
533 <td
><?php
echo text($patdata['fname']) . " " . text($patdata['mname']) . " " .
534 text($patdata['lname']) . " (" . text($patdata['pubpid']) . ")" ?
></td
>
537 <td
><?php
echo xlt('How Paid'); ?
>:</td
>
538 <td
><?php
echo generate_display_field(array('data_type' => '1', 'list_id' => 'payment_method'), $payrow['method']); ?
></td
>
541 <td
><?php
echo xlt('Check or Reference Number'); ?
>:</td
>
542 <td
><?php
echo text($payrow['source']) ?
></td
>
545 <td
><?php
echo xlt('Amount for This Visit'); ?
>:</td
>
546 <td
><?php
echo text(oeFormatMoney($payrow['amount1'])) ?
></td
>
551 if ($_REQUEST['radio_type_of_payment'] == 'pre_payment') {
552 echo xlt('Pre-payment Amount');
554 echo xlt('Amount for Past Balance');
558 <td
><?php
echo text(oeFormatMoney($payrow['amount2'])) ?
></td
>
561 <td
><?php
echo xlt('Received By'); ?
>:</td
>
562 <td
><?php
echo text($payrow['user']) ?
></td
>
566 <div id
='hideonprint'>
567 <button type
="button" class="btn btn-primary btn-print" value
='<?php echo xla('Print'); ?>' id
='printbutton'>
568 <?php
echo xlt('Print'); ?
>
572 $todaysenc = todaysEncounterIf($pid);
573 if ($todaysenc && $todaysenc != $encounter) {
574 echo " <input type='button' class='btn btn-primary' " .
575 "value='" . xla('Open Today`s Visit') . "' " .
576 "onclick='toencounter(" . attr_js($todaysenc) . ", " . attr_js($today) . ", (opener ? opener.top : top))' />\n";
580 <?php
if (AclMain
::aclCheckCore('admin', 'super') || AclMain
::aclCheckCore('acct', 'bill')) {
581 // allowing biller to delete payments ?>
582 <button type
="button" class="btn btn-danger btn-delete" value
='<?php echo xla('Delete
'); ?>' onclick
="deleteme()">
583 <?php
echo xlt('Delete'); ?
>
587 <div
class='mt-3' id
='showonprint'>
588 <button type
="button" class="btn btn-secondary btn-cancel" value
='<?php echo xla('Exit'); ?>' id
='donebutton' onclick
="closeHow(event)">
589 <?php
echo xlt('Exit'); ?
>
599 // End of receipt printing logic.
603 // Here we display the form for data entry.
606 <title
><?php
echo xlt('Record Payment'); ?
></title
>
612 background
-color
: #FBFDD0;
613 border
: 1px solid
#ccc;
617 <!--Removed standard dependencies
12/29/17 as not needed any longer since moved to a tab
/frame not popup
.-->
619 <!-- supporting javascript code
-->
623 <?php
include_once("{$GLOBALS['srcdir']}/ajax/payment_ajax_jav.inc.php"); ?
>
625 document
.onclick
=HideTheAjaxDivs
;
628 <?php Header
::setupAssets('topdialog'); ?
>
630 <script src
="<?php echo $GLOBALS['assets_static_relative']; ?>/jquery-creditcardvalidator/jquery.creditCardValidator.js"></script
>
633 var chargeMsg
= <?php
echo xlj('Payment was successfully authorized and charged. Thank You.'); ?
>;
634 var publicKey
= <?php
echo json_encode($cryptoGen->decryptStandard($GLOBALS['gateway_public_key'])); ?
>;
635 var apiKey
= <?php
echo json_encode($cryptoGen->decryptStandard($GLOBALS['gateway_api_key'])); ?
>;
637 $
('#openPayModal').on('show.bs.modal', function () {
638 let total
= $
("[name='form_paytotal']").val();
639 let prepay
= $
("#form_prepayment").val();
640 if (Number(total
) < 1) {
641 if (Number(prepay
) < 1) {
642 let error
= <?php
echo xlj("Please enter a payment amount"); ?
>;
648 $
("#form_method").val('credit_card');
649 $
("#payTotal").text(total
);
650 $
("#paymentAmount").val(total
);
653 <?php
require($GLOBALS['srcdir'] . "/restoreSession.php"); ?
>
654 function closeHow(e
) {
659 top
.activateTabByName('pat', true);
660 top
.tabCloseByName(window
.name
);
662 function calctotal() {
663 var f
= document
.forms
[0];
665 for (var i
= 0; i
< f
.elements
.length
; ++i
) {
666 var elem
= f
.elements
[i
];
667 var ename
= elem
.name
;
668 if (ename
.indexOf('form_upay[') == 0 || ename
.indexOf('form_bpay[') == 0) {
669 if (elem
.value
.length
> 0) total +
= Number(elem
.value
);
672 f
.form_paytotal
.value
= Number(total
).toFixed(2);
676 function coloring() {
677 for (var i
= 1; ; ++i
) {
678 if (document
.getElementById('paying_' + i
)) {
679 paying
= document
.getElementById('paying_' + i
).value
* 1;
680 patient_balance
= document
.getElementById('duept_' + i
).innerHTML
* 1;
682 //balance=document.getElementById('balance_'+i).innerHTML*1;
683 if (patient_balance
> 0 && paying
> 0) {
684 if (paying
> patient_balance
) {
685 document
.getElementById('paying_' + i
).style
.background
= '#FF0000';
687 else if (paying
< patient_balance
) {
688 document
.getElementById('paying_' + i
).style
.background
= '#99CC00';
690 else if (paying
== patient_balance
) {
691 document
.getElementById('paying_' + i
).style
.background
= 'var(--white)';
694 document
.getElementById('paying_' + i
).style
.background
= 'var(--white)';
703 function CheckVisible(MakeBlank
) { //Displays and hides the check number text box.
704 if (document
.getElementById('form_method').options
[document
.getElementById(
705 'form_method').selectedIndex
].value
== 'check_payment' || document
.getElementById(
706 'form_method').options
[document
.getElementById('form_method').selectedIndex
]
707 .value
== 'bank_draft') {
708 document
.getElementById('check_number').disabled
= false;
710 document
.getElementById('check_number').disabled
= true;
714 function validate(notSubmit
= false) {
715 var f
= document
.forms
[0];
717 top
.restoreSession();
719 // prevent an empty form submission
721 for (let i
= 0; i
< f
.elements
.length
; ++i
) {
722 let ename
= f
.elements
[i
].name
;
723 if (f
.elements
[i
].value
== 'pre_payment' && f
.elements
[i
].checked
=== true) {
724 if (Number(f
.elements
.namedItem("form_prepayment").value
) !== 0) {
729 if (ename
.indexOf('form_upay[') === 0 || ename
.indexOf('form_bpay[') === 0) {
730 if (Number(f
.elements
[i
].value
) !== 0) flgempty
= false;
734 alert(<?php
echo xlj('A Payment is Required!. Please input a payment line item entry.'); ?
>);
737 // continue validation.
738 if (((document
.getElementById('form_method').options
[document
.getElementById('form_method').selectedIndex
].value
== 'check_payment' ||
739 document
.getElementById('form_method').options
[document
.getElementById('form_method').selectedIndex
].value
== 'bank_draft') &&
740 document
.getElementById('check_number').value
== '')) {
741 alert(<?php
echo xlj('Please Fill the Check or Reference Number'); ?
>);
742 document
.getElementById('check_number').focus();
745 if (document
.getElementById('radio_type_of_payment_self1').checked
== false &&
746 document
.getElementById('radio_type_of_payment1').checked
== false &&
747 document
.getElementById('radio_type_of_payment2').checked
== false &&
748 document
.getElementById('radio_type_of_payment4').checked
== false) {
749 alert(<?php
echo xlj('Please Select Type Of Payment.'); ?
>);
752 if (document
.getElementById('radio_type_of_payment_self1').checked
== true ||
753 document
.getElementById('radio_type_of_payment1').checked
== true) {
754 for (var i
= 0; i
< f
.elements
.length
; ++i
) {
755 var elem
= f
.elements
[i
];
756 var ename
= elem
.name
;
757 if (ename
.indexOf('form_upay[0') == 0) //Today is this text box.
759 if (elem
.value
* 1 > 0) {//A warning message, if the amount is posted with out encounter.
760 if (confirm(<?php
echo xlj('If patient has appointment click OK to create encounter otherwise, cancel this and then create an encounter for today visit.'); ?
>)) {
772 if (document
.getElementById('radio_type_of_payment1').checked
== true){//CO-PAY
774 for (var i
= 0; i
< f
.elements
.length
; ++i
) {
775 var elem
= f
.elements
[i
];
776 var ename
= elem
.name
;
777 if (ename
.indexOf('form_upay[0]') == 0) {//Today is this text box.
778 if (f
.form_paytotal
.value
* 1 != elem
.value
* 1) {//Total CO-PAY is not posted against today
779 //A warning message, if the amount is posted against an old encounter.
780 if (confirm(<?php
echo xlj('You are posting against an old encounter?'); ?
>)) {
791 else if (document
.getElementById('radio_type_of_payment2').checked
== true) {//Invoice Balance
792 for (var i
= 0; i
< f
.elements
.length
; ++i
) {
793 var elem
= f
.elements
[i
];
794 var ename
= elem
.name
;
795 if (ename
.indexOf('form_upay[0') == 0) {
796 if (elem
.value
* 1 > 0) {
797 alert(<?php
echo xlj('Invoice Balance cannot be posted. No Encounter is created.'); ?
>);
808 if (confirm(<?php
echo xlj('Would you like to save?'); ?
>)) {
818 function cursor_pointer() { //Point the cursor to the latest encounter(Today)
819 var f
= document
.forms
[0];
821 for (var i
= 0; i
< f
.elements
.length
; ++i
) {
822 var elem
= f
.elements
[i
];
823 var ename
= elem
.name
;
824 if (ename
.indexOf('form_upay[') == 0) {
830 //=====================================================
831 function make_it_hide_enc_pay() {
832 document
.getElementById('td_head_insurance_payment').style
.display
= "none";
833 document
.getElementById('td_head_patient_co_pay').style
.display
= "none";
834 document
.getElementById('td_head_co_pay').style
.display
= "none";
835 document
.getElementById('td_head_insurance_balance').style
.display
= "none";
836 for (var i
= 1; ; ++i
) {
837 var td_inspaid_elem
= document
.getElementById('td_inspaid_' + i
)
838 var td_patient_copay_elem
= document
.getElementById('td_patient_copay_' + i
)
839 var td_copay_elem
= document
.getElementById('td_copay_' + i
)
840 var balance_elem
= document
.getElementById('balance_' + i
)
841 if (td_inspaid_elem
) {
842 td_inspaid_elem
.style
.display
= "none";
843 td_patient_copay_elem
.style
.display
= "none";
844 td_copay_elem
.style
.display
= "none";
845 balance_elem
.style
.display
= "none";
850 document
.getElementById('td_total_4').style
.display
= "none";
851 document
.getElementById('td_total_7').style
.display
= "none";
852 document
.getElementById('td_total_8').style
.display
= "none";
853 document
.getElementById('td_total_6').style
.display
= "none";
854 document
.getElementById('table_display').width
= "420px";
856 //=====================================================
857 function make_visible() {
858 document
.getElementById('td_head_rep_doc').style
.display
= "";
859 document
.getElementById('td_head_description').style
.display
= "";
860 document
.getElementById('td_head_total_charge').style
.display
= "none";
861 document
.getElementById('td_head_insurance_payment').style
.display
= "none";
862 document
.getElementById('td_head_patient_payment').style
.display
= "none";
863 document
.getElementById('td_head_patient_co_pay').style
.display
= "none";
864 document
.getElementById('td_head_co_pay').style
.display
= "none";
865 document
.getElementById('td_head_insurance_balance').style
.display
= "none";
866 document
.getElementById('td_head_patient_balance').style
.display
= "none";
867 for (var i
= 1; ; ++i
) {
868 var td_charges_elem
= document
.getElementById('td_charges_' + i
)
869 var td_inspaid_elem
= document
.getElementById('td_inspaid_' + i
)
870 var td_ptpaid_elem
= document
.getElementById('td_ptpaid_' + i
)
871 var td_patient_copay_elem
= document
.getElementById('td_patient_copay_' + i
)
873 var td_copay_elem
= document
.getElementById('td_copay_' + i
)
874 var balance_elem
= document
.getElementById('balance_' + i
)
875 var duept_elem
= document
.getElementById('duept_' + i
)
876 if (td_charges_elem
) {
877 td_charges_elem
.style
.display
= "none";
878 td_inspaid_elem
.style
.display
= "none";
879 td_ptpaid_elem
.style
.display
= "none";
880 td_patient_copay_elem
.style
.display
= "none";
881 td_copay_elem
.style
.display
= "none";
882 balance_elem
.style
.display
= "none";
883 duept_elem
.style
.display
= "none";
888 document
.getElementById('td_total_7').style
.display
= "";
889 document
.getElementById('td_total_8').style
.display
= "";
890 document
.getElementById('td_total_1').style
.display
= "none";
891 document
.getElementById('td_total_2').style
.display
= "none";
892 document
.getElementById('td_total_3').style
.display
= "none";
893 document
.getElementById('td_total_4').style
.display
= "none";
894 document
.getElementById('td_total_5').style
.display
= "none";
895 document
.getElementById('td_total_6').style
.display
= "none";
896 document
.getElementById('table_display').width
= "505px";
899 function make_it_hide() {
900 document
.getElementById('td_head_rep_doc').style
.display
= "none";
901 document
.getElementById('td_head_description').style
.display
= "none";
902 document
.getElementById('td_head_total_charge').style
.display
= "";
903 document
.getElementById('td_head_insurance_payment').style
.display
= "";
904 document
.getElementById('td_head_patient_payment').style
.display
= "";
905 document
.getElementById('td_head_patient_co_pay').style
.display
= "";
906 document
.getElementById('td_head_co_pay').style
.display
= "";
907 document
.getElementById('td_head_insurance_balance').style
.display
= "";
908 document
.getElementById('td_head_patient_balance').style
.display
= "";
909 for (var i
= 1; ; ++i
) {
910 var td_charges_elem
= document
.getElementById('td_charges_' + i
)
911 var td_inspaid_elem
= document
.getElementById('td_inspaid_' + i
)
912 var td_ptpaid_elem
= document
.getElementById('td_ptpaid_' + i
)
913 var td_patient_copay_elem
= document
.getElementById('td_patient_copay_' + i
)
915 var td_copay_elem
= document
.getElementById('td_copay_' + i
)
916 var balance_elem
= document
.getElementById('balance_' + i
)
917 var duept_elem
= document
.getElementById('duept_' + i
)
918 if (td_charges_elem
) {
919 td_charges_elem
.style
.display
= "";
920 td_inspaid_elem
.style
.display
= "";
921 td_ptpaid_elem
.style
.display
= "";
922 td_patient_copay_elem
.style
.display
= "";
923 td_copay_elem
.style
.display
= "";
924 balance_elem
.style
.display
= "";
925 duept_elem
.style
.display
= "";
930 document
.getElementById('td_total_1').style
.display
= "";
931 document
.getElementById('td_total_2').style
.display
= "";
932 document
.getElementById('td_total_3').style
.display
= "";
933 document
.getElementById('td_total_4').style
.display
= "";
934 document
.getElementById('td_total_5').style
.display
= "";
935 document
.getElementById('td_total_6').style
.display
= "";
936 document
.getElementById('td_total_7').style
.display
= "";
937 document
.getElementById('td_total_8').style
.display
= "";
938 document
.getElementById('table_display').width
= "635px";
941 function make_visible_radio() {
942 document
.getElementById('tr_radio1').style
.display
= "";
943 document
.getElementById('tr_radio2').style
.display
= "none";
946 function make_hide_radio() {
947 document
.getElementById('tr_radio1').style
.display
= "none";
948 document
.getElementById('tr_radio2').style
.display
= "";
951 function make_visible_row() {
952 document
.getElementById('table_display').style
.display
= "";
953 document
.getElementById('table_display_prepayment').style
.display
= "none";
956 function make_hide_row() {
957 document
.getElementById('table_display').style
.display
= "none";
958 document
.getElementById('table_display_prepayment').style
.display
= "";
961 function make_self() {
964 make_it_hide_enc_pay();
965 document
.getElementById('radio_type_of_payment_self1').checked
= true;
969 function make_insurance() {
973 document
.getElementById('radio_type_of_payment1').checked
= true;
978 @media
(min
-width
: 992px
) {
980 width
: 1000px
!Important
;
984 <title
><?php
echo xlt('Record Payment'); ?
></title
>
985 <?php
$NameNew = $patdata['fname'] . " " . $patdata['lname'] . " " . $patdata['mname']; ?
>
987 $arrOeUiSettings = array(
988 'heading_title' => xl('Accept Payment'),
989 'include_patient_name' => true,// use only in appropriate pages
990 'expandable' => false,
991 'expandable_files' => array(),//all file names need suffix _xpd
992 'action' => "",//conceal, reveal, search, reset, link or back
993 'action_title' => "",
994 'action_href' => "",//only for actions - reset, link or back
995 'show_help_icon' => false,
996 'help_file_name' => ""
998 $oemr_ui = new OemrUI($arrOeUiSettings);
1002 <div
class="container mt-3"><!--begin container div
for form
-->
1004 <div
class="col-sm-12">
1005 <?php
echo $oemr_ui->pageHeading() . "\r\n"; ?
>
1009 <div
class="col-sm-12">
1010 <form
class="form form-vertical" method
='post' action
='front_payment.php<?php echo (!empty($payid)) ? "?payid=" . attr_url($payid) : ""; ?>' onsubmit
='return validate();'>
1011 <input type
="hidden" name
="csrf_token_form" value
="<?php echo attr(CsrfUtils::collectCsrfToken()); ?>" />
1012 <input name
='form_pid' type
='hidden' value
='<?php echo attr($pid) ?>' />
1014 <legend
><?php
echo xlt('Payment'); ?
></legend
>
1015 <div
class="col-12 oe-custom-line">
1016 <label
class="control-label" for="form_method"><?php
echo xlt('Payment Method'); ?
>:</label
>
1017 <select
class="form-control" id
="form_method" name
="form_method" onchange
='CheckVisible("yes")'>
1019 $query1112 = "SELECT * FROM list_options where activity=1 AND list_id=? ORDER BY seq, title ";
1020 $bres1112 = sqlStatement($query1112, array('payment_method'));
1021 while ($brow1112 = sqlFetchArray($bres1112)) {
1022 if ($brow1112['option_id'] == 'electronic' ||
$brow1112['option_id'] == 'bank_draft') {
1025 echo "<option value='" . attr($brow1112['option_id']) . "'>" . text(xl_list_label($brow1112['title'])) . "</option>";
1030 <div
class="col-12 oe-custom-line">
1031 <label
class="control-label" for="check_number"><?php
echo xlt('Check or Reference Number'); ?
>:</label
>
1032 <div id
="ajax_div_patient" style
="display:none;"></div
>
1033 <input type
='text' id
="check_number" name
='form_source' class='form-control' value
='<?php echo attr($payrow['source
'] ?? ''); ?>' />
1035 <div
class="col-12 oe-custom-line">
1036 <label
class="control-label" for="form_discount"><?php
echo xla('Patient Coverage'); ?
>:</label
>
1038 <label
class="radio-inline">
1039 <input id
="radio_type_of_coverage1" name
="radio_type_of_coverage" onclick
="make_visible_radio();make_self();" type
="radio" value
="self"><?php
echo xlt('Self'); ?
>
1041 <label
class="radio-inline">
1042 <input checked
="checked" id
="radio_type_of_coverag2" name
="radio_type_of_coverage" onclick
="make_hide_radio();make_insurance();" type
="radio" value
="insurance"><?php
echo xlt('Insurance'); ?
>
1046 <div
class="col-12 oe-custom-line">
1047 <label
class="control-label" for=""><?php
echo xlt('Payment against'); ?
>:</label
>
1048 <div id
="tr_radio1" style
="padding-left:15px; display:none"><!-- For radio Insurance
-->
1049 <label
class="radio-inline">
1050 <input id
="radio_type_of_payment_self1" name
="radio_type_of_payment" onclick
="make_visible_row();make_it_hide_enc_pay();cursor_pointer();" type
="radio" value
="cash"><?php
echo xlt('Encounter Payment'); ?
>
1053 <div id
="tr_radio2" style
="padding-left:15px"><!-- For radio self
-->
1054 <label
class="radio-inline">
1055 <input checked
="checked" id
="radio_type_of_payment1" name
="radio_type_of_payment" onclick
="make_visible_row();cursor_pointer();" type
="radio" value
="copay"><?php
echo xlt('Co Pay'); ?
>
1057 <label
class="radio-inline">
1058 <input id
="radio_type_of_payment2" name
="radio_type_of_payment" onclick
="make_visible_row();" type
="radio" value
="invoice_balance"><?php
echo xlt('Invoice Balance'); ?
><br
/>
1060 <label
class="radio-inline">
1061 <input id
="radio_type_of_payment4" name
="radio_type_of_payment" onclick
="make_hide_row();" type
="radio" value
="pre_payment"><?php
echo xlt('Pre Pay'); ?
>
1065 <div
class="col-12 oe-custom-line">
1066 <div id
="table_display_prepayment" style
="display:none">
1067 <label
class="control-label" for="form_prepayment"><?php
echo xlt('Pre Payment'); ?
>:</label
>
1068 <input name
='form_prepayment' id
='form_prepayment'class='form-control' type
='text' value
='' />
1073 <legend
><?php
echo xlt('Collect For'); ?
></legend
>
1074 <div
class="table-responsive">
1075 <table
class="table" id
="table_display">
1077 <tr
class="table-active" id
="tr_head">
1078 <th
class="font-weight-bold" width
="70"><?php
echo xlt('DOS'); ?
></td
>
1079 <th
class="font-weight-bold" width
="65"><?php
echo xlt('Encounter'); ?
></td
>
1080 <th
class="font-weight-bold text-center" id
="td_head_total_charge" width
="80"><?php
echo xlt('Total Charge'); ?
></td
>
1081 <th
class="font-weight-bold text-center" id
="td_head_rep_doc" style
='display:none' width
="70"><?php
echo xlt('Report/ Form'); ?
></td
>
1082 <th
class="font-weight-bold text-center" id
="td_head_description" style
='display:none' width
="200"><?php
echo xlt('Description'); ?
></td
>
1083 <th
class="font-weight-bold text-center" id
="td_head_insurance_payment" width
="80"><?php
echo xlt('Insurance Payment'); ?
></td
>
1084 <th
class="font-weight-bold text-center" id
="td_head_patient_payment" width
="80"><?php
echo xlt('Patient Payment'); ?
></td
>
1085 <th
class="font-weight-bold text-center" id
="td_head_patient_co_pay" width
="55"><?php
echo xlt('Co Pay Paid'); ?
></td
>
1086 <th
class="font-weight-bold text-center" id
="td_head_co_pay" width
="55"><?php
echo xlt('Required Co Pay'); ?
></td
>
1087 <th
class="font-weight-bold text-center" id
="td_head_insurance_balance" width
="80"><?php
echo xlt('Insurance Balance'); ?
></td
>
1088 <th
class="font-weight-bold text-center" id
="td_head_patient_balance" width
="80"><?php
echo xlt('Patient Balance'); ?
></td
>
1089 <th
class="font-weight-bold text-center" width
="50"><?php
echo xlt('Paying'); ?
></th
>
1095 // Get the unbilled service charges and payments by encounter for this patient.
1097 $query = "SELECT fe.encounter, b.code_type, b.code, b.modifier, b.fee, " .
1098 "LEFT(fe.date, 10) AS encdate ,fe.last_level_closed " .
1099 "FROM form_encounter AS fe left join billing AS b on " .
1100 "b.pid = ? AND b.activity = 1 AND " . //AND b.billed = 0
1101 "b.code_type != 'TAX' AND b.fee != 0 " .
1102 "AND fe.pid = b.pid AND fe.encounter = b.encounter " .
1103 "where fe.pid = ? " .
1104 "ORDER BY b.encounter";
1105 $bres = sqlStatement($query, array($pid, $pid));
1107 while ($brow = sqlFetchArray($bres)) {
1108 $key = 0 - $brow['encounter'];
1109 if (empty($encs[$key])) {
1110 $encs[$key] = array(
1111 'encounter' => $brow['encounter'],
1112 'date' => $brow['encdate'],
1113 'last_level_closed' => $brow['last_level_closed'],
1118 if ($brow['code_type'] === 'COPAY') {
1119 //$encs[$key]['payments'] -= $brow['fee'];
1121 $encs[$key]['charges'] +
= $brow['fee'];
1123 $sql_array = array();
1124 $query = "SELECT taxrates FROM codes WHERE " .
1125 "code_type = ? AND " .
1127 array_push($sql_array, ($code_types[$brow['code_type']]['id'] ??
null), $brow['code']);
1128 if ($brow['modifier']) {
1129 $query .= "modifier = ?";
1130 array_push($sql_array, $brow['modifier']);
1132 $query .= "(modifier IS NULL OR modifier = '')";
1135 $query .= " LIMIT 1";
1136 $trow = sqlQuery($query, $sql_array);
1137 $encs[$key]['charges'] +
= calcTaxes($trow, $brow['fee']);
1141 // Do the same for unbilled product sales.
1143 $query = "SELECT fe.encounter, s.drug_id, s.fee, " .
1144 "LEFT(fe.date, 10) AS encdate,fe.last_level_closed " .
1145 "FROM form_encounter AS fe left join drug_sales AS s " .
1146 "on s.pid = ? AND s.fee != 0 " . //AND s.billed = 0
1147 "AND fe.pid = s.pid AND fe.encounter = s.encounter " .
1148 "where fe.pid = ? " .
1149 "ORDER BY s.encounter";
1151 $dres = sqlStatement($query, array($pid, $pid));
1153 while ($drow = sqlFetchArray($dres)) {
1154 $key = 0 - $drow['encounter'];
1155 if (empty($encs[$key])) {
1156 $encs[$key] = array(
1157 'encounter' => $drow['encounter'],
1158 'date' => $drow['encdate'],
1159 'last_level_closed' => $drow['last_level_closed'],
1164 $encs[$key]['charges'] +
= $drow['fee'];
1166 $trow = sqlQuery("SELECT taxrates FROM drug_templates WHERE drug_id = ? " .
1167 "ORDER BY selector LIMIT 1", array($drow['drug_id']));
1168 $encs[$key]['charges'] +
= calcTaxes($trow, $drow['fee']);
1171 ksort($encs, SORT_NUMERIC
);
1173 //Bringing on top the Today always
1174 foreach ($encs as $key => $value) {
1175 $dispdate = $value['date'];
1176 if (strcmp($dispdate, $today) == 0 && !$gottoday) {
1182 // If no billing was entered yet for today, then generate a line for
1183 // entering today's co-pay.
1186 echoLine("form_upay[0]", date("Y-m-d"), 0, 0, 0, 0 /*$duept*/);//No encounter yet defined.
1190 foreach ($encs as $key => $value) {
1191 $enc = $value['encounter'];
1192 $dispdate = $value['date'];
1193 if (strcmp($dispdate, $today) == 0 && !$gottoday) {
1194 $dispdate = date("Y-m-d");
1197 //------------------------------------------------------------------------------------
1198 $inscopay = BillingUtilities
::getCopay($pid, $dispdate);
1199 $patcopay = BillingUtilities
::getPatientCopay($pid, $enc);
1203 "SELECT SUM(pay_amount) AS payments, " .
1204 "SUM(adj_amount) AS adjustments FROM ar_activity WHERE " .
1205 "deleted IS NULL AND pid = ? and encounter = ? and " .
1206 "payer_type != 0 and account_code!='PCP' ",
1209 $dpayment = $drow['payments'];
1210 $dadjustment = $drow['adjustments'];
1214 "SELECT SUM(pay_amount) AS payments, " .
1215 "SUM(adj_amount) AS adjustments FROM ar_activity WHERE " .
1216 "deleted IS NULL AND pid = ? and encounter = ? and " .
1217 "payer_type = 0 and account_code!='PCP' ",
1220 $dpayment_pat = $drow['payments'];
1222 //------------------------------------------------------------------------------------
1224 $ResultNumberOfInsurance = sqlStatement("SELECT COUNT( DISTINCT TYPE ) NumberOfInsurance FROM insurance_data
1225 where pid = ? and provider>0 ", array($pid));
1226 $RowNumberOfInsurance = sqlFetchArray($ResultNumberOfInsurance);
1227 $NumberOfInsurance = $RowNumberOfInsurance['NumberOfInsurance'] * 1;
1228 //------------------------------------------------------------------------------------
1230 if ((($NumberOfInsurance == 0 ||
$value['last_level_closed'] == 4 ||
$NumberOfInsurance == $value['last_level_closed']))) {//Patient balance
1231 $brow = sqlQuery("SELECT SUM(fee) AS amount FROM billing WHERE " .
1232 "pid = ? and encounter = ? AND activity = 1", array($pid, $enc));
1233 $srow = sqlQuery("SELECT SUM(fee) AS amount FROM drug_sales WHERE " .
1234 "pid = ? and encounter = ? ", array($pid, $enc));
1235 $drow = sqlQuery("SELECT SUM(pay_amount) AS payments, " .
1236 "SUM(adj_amount) AS adjustments FROM ar_activity WHERE " .
1237 "deleted IS NULL AND pid = ? and encounter = ? ", array($pid, $enc));
1238 $duept = $brow['amount'] +
$srow['amount'] - $drow['payments'] - $drow['adjustments'];
1246 ($dpayment +
$dadjustment),
1253 // Continue with display of the data entry form.
1256 <tr
class="table-active">
1257 <td
class="font-weight-bold" id
='td_total_1'></td
>
1258 <td
class="font-weight-bold" id
='td_total_2'></td
>
1259 <td
class="font-weight-bold" id
='td_total_3'></td
>
1260 <td
class="font-weight-bold" id
='td_total_4'></td
>
1261 <td
class="font-weight-bold" id
='td_total_5'></td
>
1262 <td
class="font-weight-bold" id
='td_total_6'></td
>
1263 <td
class="font-weight-bold" id
='td_total_7'></td
>
1264 <td
class="font-weight-bold" id
='td_total_8'></td
>
1265 <td
class="font-weight-bold text-right"><?php
echo xlt('Total');?
></td
>
1266 <td
class="font-weight-bold text-right">
1267 <input type
='text' class='form-control text-success' name
='form_paytotal' value
='' readonly
/>
1273 <div
class="form-group">
1274 <div
class="col-sm-12 text-left position-override">
1275 <div
class="form-group" role
="group">
1276 <button type
='submit' class="btn btn-primary btn-save" name
='form_save' value
='<?php echo xla('Generate Invoice
');?>'><?php
echo xlt('Generate Invoice');?
></button
>
1277 <?php
if (!empty($GLOBALS['cc_front_payments']) && $GLOBALS['payment_gateway'] != 'InHouse') {
1278 if ($GLOBALS['payment_gateway'] == 'Sphere') {
1279 echo SpherePayment
::renderSphereHtml('clinic');
1281 echo '<button type="button" class="btn btn-success btn-transmit mx-1" data-toggle="modal" data-target="#openPayModal">' . xlt("Credit Card Pay") . '</button>';
1282 if (!empty($GLOBALS['cc_stripe_terminal'])) {
1283 echo '<button type="button" class="btn btn-success btn-transmit mx-1" onclick="posDialog()">' . xlt("POS Payment") . '</button>';
1287 <button type
='button' class="btn btn-secondary btn-cancel" value
='<?php echo xla('Cancel
'); ?>' onclick
='closeHow(event)'><?php
echo xlt('Cancel'); ?
></button
>
1288 <input type
="hidden" name
="hidden_patient_code" id
="hidden_patient_code" value
="<?php echo attr($pid);?>"/>
1289 <input type
='hidden' name
='ajax_mode' id
='ajax_mode' value
='' />
1290 <input type
='hidden' name
='mode' id
='mode' value
='' />
1300 <!-- credit payment modal
-->
1301 <div id
="openPayModal" class="modal fade" role
="dialog">
1302 <div
class="modal-dialog">
1303 <div
class="modal-content">
1304 <div
class="modal-header">
1305 <h4
><?php
echo xlt('Submit Payment for Authorization'); ?
></h4
>
1307 <div
class="modal-body">
1308 <?php
if ($GLOBALS['payment_gateway'] == 'AuthorizeNet') { ?
>
1309 <form id
='paymentForm' method
='post' action
='./front_payment_cc.php'>
1311 <div
class="form-group">
1313 class="control-label"><?php
echo xlt('Name on Card'); ?
></label
>
1314 <div
class="controls">
1315 <input name
="cardHolderName" id
="cardHolderName" type
="text" class="form-control"
1317 title
="<?php echo xla('Fill your first and last name'); ?>"
1318 value
="<?php echo attr($patdata['fname']) . ' ' . attr($patdata['lname']) ?>" />
1321 <div
class="form-group">
1323 <div
class="col-sm-6">
1324 <label
class="control-label"><?php
echo xlt('Card Number'); ?
></label
>
1325 <input name
="cardNumber" id
="cardNumber" type
="text"
1326 class="form-control"
1327 autocomplete
="off" maxlength
="19" pattern
="\d"
1328 onchange
="validateCC()"
1329 title
="<?php echo xla('Card Number'); ?>" value
="" /> 
; 
;
1331 <span
class="col-sm-6">
1332 <label
class="control-label"><?php
echo xlt('Entry Status'); ?
></label
>
1333 <h5 name
="cardtype" id
="cardtype" style
="color:#cc0000;"><?php
echo xlt('Validating') ?
></h5
>
1337 <div
class="form-group">
1339 class="control-label"><?php
echo xlt('Card Expiry Date and Card Holders Zip'); ?
></label
>
1341 <div
class="col-md-4">
1342 <select name
="month" id
="expMonth" class="form-control">
1343 <option value
=""><?php
echo xlt('Select Month'); ?
></option
>
1344 <option value
="01"><?php
echo xlt('January'); ?
></option
>
1345 <option value
="02"><?php
echo xlt('February'); ?
></option
>
1346 <option value
="03"><?php
echo xlt('March'); ?
></option
>
1347 <option value
="04"><?php
echo xlt('April'); ?
></option
>
1348 <option value
="05"><?php
echo xlt('May'); ?
></option
>
1349 <option value
="06"><?php
echo xlt('June'); ?
></option
>
1350 <option value
="07"><?php
echo xlt('July'); ?
></option
>
1351 <option value
="08"><?php
echo xlt('August'); ?
></option
>
1352 <option value
="09"><?php
echo xlt('September'); ?
></option
>
1353 <option value
="10"><?php
echo xlt('October'); ?
></option
>
1354 <option value
="11"><?php
echo xlt('November'); ?
></option
>
1355 <option value
="12"><?php
echo xlt('December'); ?
></option
>
1358 <div
class="col-md-4">
1359 <select name
="year" id
="expYear" class="form-control">
1360 <option value
=""><?php
echo xlt('Select Year'); ?
></option
>
1361 <option value
="2021">2021</option
>
1362 <option value
="2022">2022</option
>
1363 <option value
="2023">2023</option
>
1364 <option value
="2024">2024</option
>
1365 <option value
="2025">2025</option
>
1366 <option value
="2026">2026</option
>
1367 <option value
="2027">2027</option
>
1368 <option value
="2028">2028</option
>
1369 <option value
="2028">2029</option
>
1370 <option value
="2028">2030</option
>
1373 <div
class="col-md-4">
1374 <input name
="zip" id
="cczip" type
="text" class="form-control"
1376 title
="<?php echo xla('Enter Your Zip'); ?>"
1377 placeholder
="<?php echo xla('Card Holder Zip'); ?>"
1378 value
="<?php echo attr($patdata['postal_code']) ?>" />
1382 <div
class="form-group">
1383 <label
class="control-label"><?php
echo xlt('Card CVV'); ?
></label
>
1385 <div
class="col-md-3">
1386 <input name
="cardCode" id
="cardCode" type
="text" class="form-control"
1387 autocomplete
="off" maxlength
="4" onfocus
="validateCC()"
1388 title
="<?php echo xla('Three or four digits at back of your card'); ?>"
1391 <div
class="col-md-3">
1392 <img src
='./../../portal/images/img_cvc.png' style
='height: 40px; width: auto'>
1394 <div
class="col-md-6">
1395 <h4 style
="display: inline-block;"><?php
echo xlt('Payment Amount'); ?
>: 
;
1396 <strong
><span id
="payTotal"></span
></strong
></h4
>
1400 <input type
='hidden' name
='pid' id
='pid' value
='<?php echo attr($pid) ?>' />
1401 <input type
='hidden' name
='mode' id
='mode' value
='' />
1402 <input type
='hidden' name
='cc_type' id
='cc_type' value
='' />
1403 <input type
='hidden' name
='payment' id
='paymentAmount' value
='' />
1404 <input type
='hidden' name
='invValues' id
='invValues' value
='' />
1405 <input type
="hidden" name
="dataValue" id
="dataValue" />
1406 <input type
="hidden" name
="dataDescriptor" id
="dataDescriptor" />
1410 if ($GLOBALS['payment_gateway'] == 'Stripe') { ?
>
1411 <form
class="form" method
="post" name
="payment-form" id
="payment-form">
1413 <div
class="form-group">
1414 <label
for="cardHolderName" class="control-label"><?php
echo xlt('Name on Card'); ?
></label
>
1415 <input name
="cardHolderName" id
="cardHolderName" type
="text"
1416 class="form-control"
1418 title
="<?php echo xla('Fill your first and last name'); ?>"
1419 value
="<?php echo attr($patdata['fname']) . ' ' . attr($patdata['lname']) ?>" />
1421 <div
class="form-group">
1422 <label
for="card-element"><?php
echo xlt('Credit or Debit Card') ?
></label
>
1423 <div
class="form-group" id
="card-element"></div
>
1424 <div
class="text-danger" id
="card-errors" role
="alert"></div
>
1426 <div
class="form-row">
1427 <?php
echo xlt('Payment Amount'); ?
>: 
;<span id
="payTotal"></span
>
1429 <input type
='hidden' name
='mode' id
='mode' value
='' />
1430 <input type
='hidden' name
='cc_type' id
='cc_type' value
='' />
1431 <input type
='hidden' name
='payment' id
='paymentAmount' value
='' />
1432 <input type
='hidden' name
='invValues' id
='invValues' value
='' />
1433 <input type
='hidden' name
='encs' id
='encs' value
='' />
1439 <div
class="modal-footer">
1440 <div
class="button-group">
1441 <button type
="button" class="btn btn-default" data
-dismiss
="modal"><?php
echo xlt('Cancel'); ?
></button
>
1443 if ($GLOBALS['payment_gateway'] == 'AuthorizeNet') { ?
>
1444 <button id
="payAurhorizeNet" class="btn btn-primary"
1445 onclick
="sendPaymentDataToAnet(event)"><?php
echo xlt('Pay Now'); ?
></button
>
1447 if ($GLOBALS['payment_gateway'] == 'Stripe') { ?
>
1448 <button id
="stripeSubmit" class="btn btn-primary"><?php
echo xlt('Pay Now'); ?
></button
>
1456 <?php
if ($GLOBALS['payment_gateway'] == 'AuthorizeNet') {
1457 // Include Authorize.Net dependency to tokenize card.
1458 // Will return a token to use for payment request keeping
1459 // credit info off the server.
1462 var ccerr
= <?php
echo xlj('Invalid Credit Card Number'); ?
>
1464 // In House CC number Validation
1465 $
('#cardNumber').validateCreditCard(function (result
) {
1466 var r
= (result
.card_type
=== null ?
'' : result
.card_type
.name
.toUpperCase())
1467 var v
= (result
.valid
=== true ?
' Valid Number' : ' Validating')
1468 if (result
.valid
=== true) {
1469 document
.getElementById("cardtype").style
.color
= "#00aa00";
1471 document
.getElementById("cardtype").style
.color
= "#aa0000";
1473 $
('#cardtype').text(r + v
);
1477 function validateCC() {
1478 var result
= $
('#cardNumber').validateCreditCard();
1479 var r
= (result
.card_type
== null ?
'' : result
.card_type
.name
.toUpperCase())
1480 var v
= (result
.valid
=== true ?
' Valid Card Number' : ' Invalid Card Number')
1481 if (result
.valid
=== true) {
1482 document
.getElementById("cardtype").style
.color
= "#00aa00";
1484 document
.getElementById("cardtype").style
.color
= "#aa0000";
1486 $
('#cardtype').text(r + v
);
1487 $
('#cc_type').val(r
);
1488 if (!result
.valid
) {
1497 function sendPaymentDataToAnet(e
) {
1499 const authData
= {};
1500 authData
.clientKey
= publicKey
;
1501 authData
.apiLoginID
= apiKey
;
1503 const cardData
= {};
1504 cardData
.cardNumber
= document
.getElementById("cardNumber").value
;
1505 cardData
.month
= document
.getElementById("expMonth").value
;
1506 cardData
.year
= document
.getElementById("expYear").value
;
1507 cardData
.cardCode
= document
.getElementById("cardCode").value
;
1508 cardData
.fullName
= document
.getElementById("cardHolderName").value
;
1509 cardData
.zip
= document
.getElementById("cczip").value
;
1511 const secureData
= {};
1512 secureData
.authData
= authData
;
1513 secureData
.cardData
= cardData
;
1515 Accept
.dispatchData(secureData
, acceptResponseHandler
);
1517 function acceptResponseHandler(response
) {
1518 if (response
.messages
.resultCode
=== "Error") {
1521 while (i
< response
.messages
.message
.length
) {
1522 errorMsg
= errorMsg + response
.messages
.message
[i
].code +
": " +response
.messages
.message
[i
].text
;
1523 console
.log(errorMsg
);
1528 paymentFormUpdate(response
.opaqueData
);
1533 function paymentFormUpdate(opaqueData
) {
1534 // this is card tokenized
1535 document
.getElementById("dataDescriptor").value
= opaqueData
.dataDescriptor
;
1536 document
.getElementById("dataValue").value
= opaqueData
.dataValue
;
1537 let oForm
= document
.forms
['paymentForm'];
1538 oForm
.elements
['mode'].value
= "AuthorizeNet";
1539 // empty out the fields before submitting to server.
1540 document
.getElementById("cardNumber").value
= "";
1541 document
.getElementById("expMonth").value
= "";
1542 document
.getElementById("expYear").value
= "";
1543 document
.getElementById("cardCode").value
= "";
1545 // Submit payment to server
1546 fetch('./front_payment_cc.php', {
1548 body
: new FormData(oForm
)
1549 }).then((response
) => {
1551 throw Error(response
.statusText
);
1553 return response
.json();
1554 }).then(function(data
) {
1555 if(data
.status
!== 'ok') {
1559 document
.getElementById("check_number").value
= data
.authCode
;
1560 alert(chargeMsg +
"\n" +
'Auth: ' + data
.authCode +
' TransId: ' + data
.transId
);
1561 $
("[name='form_save']").click();
1562 }).catch(function(error
) {
1567 <?php
} // end authorize.net ?>
1569 <?php
if ($GLOBALS['payment_gateway'] == 'Stripe') { // Begin Include Stripe ?>
1571 // await validation function.
1572 const waitValidate
= async (state
= false) => {
1573 return await
validate(state
);
1575 const stripe
= Stripe(publicKey
);
1576 const elements
= stripe
.elements();
1580 lineHeight
: '1.2rem',
1581 fontSmoothing
: 'antialiased',
1588 iconColor
: '#ff0000'
1592 // Create an instance of the card Element.
1593 const card
= elements
.create('card', {style
: style
});
1594 // Add an instance of the card Element into the `card-element` <div>.
1595 card
.mount('#card-element');
1596 // Handle real-time validation errors from the card Element.
1597 card
.addEventListener('change', function (event
) {
1598 let displayError
= document
.getElementById('card-errors');
1600 displayError
.textContent
= event
.error
.message
;
1602 displayError
.textContent
= '';
1605 // Handle form submission.
1606 let form
= document
.getElementById('stripeSubmit');
1607 form
.addEventListener('click', function (event
) {
1608 event
.preventDefault();
1609 stripe
.createToken(card
).then(function (result
) {
1611 // Inform the user if there was an error.
1612 let errorElement
= document
.getElementById('card-errors');
1613 errorElement
.textContent
= result
.error
.message
;
1615 // Send the token to server.
1616 stripeTokenHandler(result
.token
);
1621 // Submit the form with the token ID.
1622 function stripeTokenHandler(token
) {
1623 // below for manual cc audit
1624 const encDates
= (() => {
1627 $
('#table_display tbody tr').each(function () {
1628 if (this
.className
== 'table-active') {
1632 return false; // breaks on max 5 encounters
1634 invDates +
= 'item' + ++i +
': ';
1636 $
(this
).find('td').each(function() {
1638 invDates +
= this
.innerText +
' ';
1644 // Insert the token ID into the form so it gets submitted to the server
1645 let oForm
= document
.forms
['payment-form'];
1646 oForm
.elements
['mode'].value
= "Stripe";
1647 oForm
.elements
['encs'].value
= encDates
;
1649 let hiddenInput
= document
.createElement('input');
1650 hiddenInput
.setAttribute('type', 'hidden');
1651 hiddenInput
.setAttribute('name', 'stripeToken');
1652 hiddenInput
.setAttribute('value', token
.id
);
1653 oForm
.appendChild(hiddenInput
);
1655 // Submit payment to server
1656 fetch('./front_payment_cc.php', {
1658 body
: new FormData(oForm
)
1659 }).then((response
) => {
1661 throw Error(response
.statusText
);
1663 return response
.json();
1664 }).then(function (data
) {
1665 if (data
.status
!== 'ok') {
1669 document
.getElementById("check_number").value
= data
.transId
;
1670 alert(chargeMsg +
"\n" +
'Auth: ' + data
.authCode +
' TransId: ' + data
.transId
);
1671 $
("[name='form_save']").click();
1672 }).catch(function (error
) {
1673 alert(error
.message
);
1677 <?php
if (!empty($GLOBALS['cc_stripe_terminal'])) { ?
>
1678 // Dialog function for Stripe terminal payment.
1679 // Will post on successful credit payment.
1680 function posDialog() {
1681 // to pass validation check and saving a user having to click.
1682 $
("#form_method").val('credit_card');
1683 // let's validate prior to collect payment from terminal
1684 // we'll use an await and validate promise to proceed.
1685 waitValidate(true).then((validateOk
) => {
1686 // validation failed for some reason that user is aware
1687 // by alerts or a quite fail we'll handle.
1688 if (validateOk
=== false || typeof validateOk
=== 'undefined') {
1691 // if 2 then need an encounter so credit is no no!
1692 // 1 would be posting against old encounter. will allow.
1693 if (validateOk
=== 2) {
1694 alert(xl("Must have an encounter to take credit card payment."));
1697 let total
= $
("[name='form_paytotal']").val();
1698 let prepay
= $
("#form_prepayment").val();
1699 // just to be sure. validate() should catch...
1700 if (Number(total
) < 1) {
1701 if (Number(prepay
) < 1) {
1702 let error
= xl("Please enter a payment amount");
1708 $
("#payTotal").text(total
);
1709 $
("#paymentAmount").val(total
);
1710 let title
= xl("POS Payment");
1711 let url
= "./front_payment_terminal.php?total=" +
encodeURIComponent(total
);
1712 dlgopen(url
, 'terminal', 'modal-md', '550', '', title
, {
1714 {text
: xl('Cancel'), close
: false, id
: "closeBtn", style
: 'secondary btn-cancel'}
1724 if ($GLOBALS['payment_gateway'] == 'Sphere') {
1725 echo (new SpherePayment('clinic', $pid))->renderSphereJs();
1729 </div
><!--end of container div of accept payment i
.e the form
-->
1731 $oemr_ui->oeBelowContainerDiv();
1732 } // forms else close