Fee sheet and Codes revenue code (#7415)
[openemr.git] / interface / patient_file / front_payment.php
blob5c1de65db85d7d8c1f01b0da1f59df65dd43b004
1 <?php
3 /**
4 * Front payment gui.
6 * @package OpenEMR
7 * @link http://www.open-emr.org
8 * @author Rod Roark <rod@sunsetsystems.com>
9 * @author Brady Miller <brady.g.miller@gmail.com>
10 * @author Stephen Waite <stephen.waite@open-emr.org>
11 * @copyright Copyright (c) 2006-2020 Rod Roark <rod@sunsetsystems.com>
12 * @copyright Copyright (c) 2017-2018 Brady Miller <brady.g.miller@gmail.com>
13 * @copyright Copyright (c) 2024 Stephen Waite <stephen.waite@open-emr.org>
14 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
17 require_once("../globals.php");
18 require_once("$srcdir/patient.inc.php");
19 require_once("$srcdir/payment.inc.php");
20 require_once("$srcdir/forms.inc.php");
21 require_once("../../custom/code_types.inc.php");
22 require_once("$srcdir/options.inc.php");
23 require_once("$srcdir/encounter_events.inc.php");
25 use OpenEMR\Billing\BillingUtilities;
26 use OpenEMR\Common\Acl\AclMain;
27 use OpenEMR\Common\Csrf\CsrfUtils;
28 use OpenEMR\Common\Twig\TwigContainer;
29 use OpenEMR\Common\Utils\FormatMoney;
30 use OpenEMR\Core\Header;
31 use OpenEMR\Events\Billing\Payments\PostFrontPayment;
32 use OpenEMR\OeUI\OemrUI;
33 use OpenEMR\PaymentProcessing\Sphere\SpherePayment;
34 use OpenEMR\Services\FacilityService;
35 use Symfony\Component\EventDispatcher\EventDispatcher;
38 if (!empty($_REQUEST['receipt']) && empty($_POST['form_save'])) {
39 if (!AclMain::aclCheckCore('acct', 'bill') && !AclMain::aclCheckCore('acct', 'rep_a') && !AclMain::aclCheckCore('patients', 'rx')) {
40 echo (new TwigContainer(null, $GLOBALS['kernel']))->getTwig()->render('core/unauthorized.html.twig', ['pageTitle' => xl("Receipt for Payment")]);
41 exit;
43 } else {
44 if (!AclMain::aclCheckCore('acct', 'bill', '', 'write')) {
45 if (!empty($_POST['form_save'])) {
46 $pageTitle = xl("Receipt for Payment");
47 } else {
48 $pageTitle = xl("Record Payment");
50 echo (new TwigContainer(null, $GLOBALS['kernel']))->getTwig()->render('core/unauthorized.html.twig', ['pageTitle' => $pageTitle]);
51 exit;
55 $pid = (!empty($_REQUEST['hidden_patient_code']) && ($_REQUEST['hidden_patient_code'] > 0)) ? $_REQUEST['hidden_patient_code'] : $pid;
57 $facilityService = new FacilityService();
60 <!DOCTYPE html>
61 <html>
62 <head>
63 <?php Header::setupHeader(['opener']);?>
64 <?php if ($GLOBALS['payment_gateway'] == 'Stripe') { ?>
65 <script src="https://js.stripe.com/v3/"></script>
66 <?php } ?>
67 <?php if ($GLOBALS['payment_gateway'] == 'AuthorizeNet') {
68 // Must be loaded from their server
69 $script = "https://jstest.authorize.net/v1/Accept.js"; // test script
70 if ($GLOBALS['gateway_mode_production']) {
71 $script = "https://js.authorize.net/v1/Accept.js"; // Production script
72 } ?>
73 <script src=<?php echo $script; ?> charset="utf-8"></script>
74 <?php } ?>
75 <?php
77 // Display a row of data for an encounter.
79 $var_index = 0;
80 function echoLine($iname, $date, $charges, $ptpaid, $inspaid, $duept, $encounter = 0, $copay = 0, $patcopay = 0)
82 global $var_index;
83 $var_index++;
84 $balance = $charges - $ptpaid - $inspaid;
85 $balance = (round($duept, 2) != 0) ? 0 : $balance;//if balance is due from patient, then insurance balance is displayed as zero
86 $encounter = $encounter ? $encounter : '';
87 echo " <tr id='tr_" . attr($var_index) . "' >\n";
88 echo " <td>" . text(oeFormatShortDate($date)) . "</td>\n";
89 echo " <td class='text-center' id='" . attr($date) . "'>" . text($encounter) . "</td>\n";
90 echo " <td class='text-center' id='td_charges_$var_index' >" . text(FormatMoney::getBucks($charges)) . "</td>\n";
91 echo " <td class='text-center' id='td_inspaid_$var_index' >" . text(FormatMoney::getBucks($inspaid * -1)) . "</td>\n";
92 echo " <td class='text-center' id='td_ptpaid_$var_index' >" . text(FormatMoney::getBucks($ptpaid * -1)) . "</td>\n";
93 echo " <td class='text-center' id='td_patient_copay_$var_index' >" . text(FormatMoney::getBucks($patcopay)) . "</td>\n";
94 echo " <td class='text-center' id='td_copay_$var_index' >" . text(FormatMoney::getBucks($copay)) . "</td>\n";
95 echo " <td class='text-center' id='balance_$var_index'>" . text(FormatMoney::getBucks($balance)) . "</td>\n";
96 echo " <td class='text-center' id='duept_$var_index'>" . text(FormatMoney::getBucks(round($duept, 2) * 1)) . "</td>\n";
97 echo " <td class='text-right'><input type='text' class='form-control' name='" . attr($iname) . "' id='paying_" . attr($var_index) . "' " .
98 " value='' onchange='coloring();calctotal()' autocomplete='off' " .
99 "onkeyup='calctotal()'/></td>\n";
100 echo " </tr>\n";
103 // We use this to put dashes, colons, etc. back into a timestamp.
105 function decorateString($fmt, $str)
107 $res = '';
108 while ($fmt) {
109 $fc = substr($fmt, 0, 1);
110 $fmt = substr($fmt, 1);
111 if ($fc == '.') {
112 $res .= substr($str, 0, 1);
113 $str = substr($str, 1);
114 } else {
115 $res .= $fc;
119 return $res;
122 // Compute taxes from a tax rate string and a possibly taxable amount.
124 function calcTaxes($row, $amount)
126 $total = 0;
127 if (empty($row['taxrates'])) {
128 return $total;
131 $arates = explode(':', $row['taxrates']);
132 if (empty($arates)) {
133 return $total;
136 foreach ($arates as $value) {
137 if (empty($value)) {
138 continue;
141 $trow = sqlQuery("SELECT option_value FROM list_options WHERE " .
142 "list_id = 'taxrate' AND option_id = ? AND activity = 1 LIMIT 1", array($value));
143 if (empty($trow['option_value'])) {
144 echo "<!-- Missing tax rate '" . text($value) . "'! -->\n";
145 continue;
148 $tax = sprintf("%01.2f", $amount * $trow['option_value']);
149 // echo "<!-- Rate = '$value', amount = '$amount', tax = '$tax' -->\n";
150 $total += $tax;
153 return $total;
156 $now = time();
157 $today = date('Y-m-d', $now);
158 $timestamp = date('Y-m-d H:i:s', $now);
160 $patdata = sqlQuery("SELECT " .
161 "p.fname, p.mname, p.lname, p.pubpid,p.pid, i.copay " .
162 "FROM patient_data AS p " .
163 "LEFT OUTER JOIN insurance_data AS i ON " .
164 "i.pid = p.pid AND i.type = 'primary' " .
165 "WHERE p.pid = ? ORDER BY i.date DESC LIMIT 1", array($pid));
167 $invoice_refno = BillingUtilities::updateInvoiceRefNumber();
169 $alertmsg = ''; // anything here pops up in an alert box
171 // If the Save button was clicked...
172 if (!empty($_POST['form_save'])) {
173 if (!CsrfUtils::verifyCsrfToken($_POST["csrf_token_form"])) {
174 CsrfUtils::csrfNotVerified();
177 $form_pid = $_POST['form_pid'];
178 $form_method = trim($_POST['form_method']);
179 $form_source = trim($_POST['form_source'] ?? ''); // check number not always entered
180 $patdata = getPatientData($form_pid, 'fname,mname,lname,pubpid');
181 $NameNew = $patdata['fname'] . " " . $patdata['lname'] . " " . $patdata['mname'];
183 //Update the invoice_refno
184 sqlStatement(
185 "update form_encounter set invoice_refno=? where encounter=? and pid=? ",
186 array($invoice_refno, $encounter, $form_pid)
189 if ($_REQUEST['radio_type_of_payment'] == 'pre_payment') {
190 $payment_id = sqlInsert(
191 "insert into ar_session set " .
192 "payer_id = ?" .
193 ", patient_id = ?" .
194 ", user_id = ?" .
195 ", closed = ?" .
196 ", reference = ?" .
197 ", check_date = now() , deposit_date = now() " .
198 ", pay_total = ?" .
199 ", payment_type = 'patient'" .
200 ", description = ?" .
201 ", adjustment_code = 'pre_payment'" .
202 ", post_to_date = now() " .
203 ", payment_method = ?",
204 array(0, $form_pid, $_SESSION['authUserID'], 0, $form_source, $_REQUEST['form_prepayment'], $NameNew, $form_method)
207 frontPayment($form_pid, 0, $form_method, $form_source, $_REQUEST['form_prepayment'], 0, $timestamp);//insertion to 'payments' table.
210 if ($_POST['form_upay'] && $_REQUEST['radio_type_of_payment'] != 'pre_payment') {
211 foreach ($_POST['form_upay'] as $enc => $payment) {
212 $payment = floatval($payment);
213 if ($amount = $payment) {
214 $zero_enc = $enc;
215 if ($_REQUEST['radio_type_of_payment'] == 'invoice_balance') {
216 if (!$enc) {
217 $enc = calendar_arrived($form_pid);
219 } else {
220 if (!$enc) {
221 $enc = calendar_arrived($form_pid);
225 //----------------------------------------------------------------------------------------------------
226 //Fetching the existing code and modifier
227 $ResultSearchNew = sqlStatement(
228 "SELECT * FROM billing LEFT JOIN code_types ON billing.code_type=code_types.ct_key " .
229 "WHERE code_types.ct_fee=1 AND billing.activity!=0 AND billing.pid =? AND encounter=? ORDER BY billing.code,billing.modifier",
230 array($form_pid, $enc)
232 if ($RowSearch = sqlFetchArray($ResultSearchNew)) {
233 $Codetype = $RowSearch['code_type'];
234 $Code = $RowSearch['code'];
235 $Modifier = $RowSearch['modifier'];
236 } else {
237 $Codetype = '';
238 $Code = '';
239 $Modifier = '';
242 //----------------------------------------------------------------------------------------------------
243 if ($_REQUEST['radio_type_of_payment'] == 'copay') {//copay saving to ar_session and ar_activity tables
244 $session_id = sqlInsert(
245 "INSERT INTO ar_session (payer_id,user_id,reference,check_date,deposit_date,pay_total," .
246 " global_amount,payment_type,description,patient_id,payment_method,adjustment_code,post_to_date) " .
247 " VALUES ('0',?,?,now(),now(),?,'','patient','COPAY',?,?,'patient_payment',now())",
248 array($_SESSION['authUserID'], $form_source, $amount, $form_pid, $form_method)
251 sqlBeginTrans();
252 $sequence_no = sqlQuery("SELECT IFNULL(MAX(sequence_no),0) + 1 AS increment FROM ar_activity WHERE pid = ? AND encounter = ?", array($form_pid, $enc));
253 $insrt_id = sqlInsert(
254 "INSERT INTO ar_activity (pid,encounter,sequence_no,code_type,code,modifier,payer_type,post_time,post_user,session_id,pay_amount,account_code)" .
255 " VALUES (?,?,?,?,?,?,0,now(),?,?,?,'PCP')",
256 array($form_pid, $enc, $sequence_no['increment'], $Codetype, $Code, $Modifier, $_SESSION['authUserID'], $session_id, $amount)
258 sqlCommitTrans();
260 frontPayment($form_pid, $enc, $form_method, $form_source, $amount, 0, $timestamp);//insertion to 'payments' table.
263 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.
264 if ($_REQUEST['radio_type_of_payment'] == 'cash') {
265 sqlStatement(
266 "update form_encounter set last_level_closed=? where encounter=? and pid=? ",
267 array(4, $enc, $form_pid)
269 sqlStatement(
270 "update billing set billed=? where encounter=? and pid=?",
271 array(1, $enc, $form_pid)
275 $adjustment_code = 'patient_payment';
276 $payment_id = sqlInsert(
277 "insert into ar_session set " .
278 "payer_id = ?" .
279 ", patient_id = ?" .
280 ", user_id = ?" .
281 ", closed = ?" .
282 ", reference = ?" .
283 ", check_date = now() , deposit_date = now() " .
284 ", pay_total = ?" .
285 ", payment_type = 'patient'" .
286 ", description = ?" .
287 ", adjustment_code = ?" .
288 ", post_to_date = now() " .
289 ", payment_method = ?",
290 array(0, $form_pid, $_SESSION['authUserID'], 0, $form_source, $amount, $NameNew, $adjustment_code, $form_method)
293 //--------------------------------------------------------------------------------------------------------------------
295 frontPayment($form_pid, $enc, $form_method, $form_source, 0, $amount, $timestamp);//insertion to 'payments' table.
297 //--------------------------------------------------------------------------------------------------------------------
299 $resMoneyGot = sqlStatement(
300 "SELECT sum(pay_amount) as PatientPay FROM ar_activity where pid =? and " .
301 "encounter = ? and payer_type = 0 and account_code = 'PCP' AND deleted IS NULL",
302 array($form_pid, $enc)
303 );//new fees screen copay gives account_code='PCP'
304 $rowMoneyGot = sqlFetchArray($resMoneyGot);
305 $Copay = $rowMoneyGot['PatientPay'];
307 //--------------------------------------------------------------------------------------------------------------------
309 //Looping the existing code and modifier
310 $ResultSearchNew = sqlStatement(
311 "SELECT * FROM billing LEFT JOIN code_types ON billing.code_type=code_types.ct_key WHERE code_types.ct_fee=1 " .
312 "AND billing.activity!=0 AND billing.pid =? AND encounter=? ORDER BY billing.code,billing.modifier",
313 array($form_pid, $enc)
315 while ($RowSearch = sqlFetchArray($ResultSearchNew)) {
316 $Codetype = $RowSearch['code_type'];
317 $Code = $RowSearch['code'];
318 $Modifier = $RowSearch['modifier'];
319 $Fee = $RowSearch['fee'];
321 $resMoneyGot = sqlStatement(
322 "SELECT sum(pay_amount) as MoneyGot FROM ar_activity where pid = ? AND deleted IS NULL " .
323 "and code_type=? and code=? and modifier=? and encounter =? and !(payer_type=0 and account_code='PCP')",
324 array($form_pid, $Codetype, $Code, $Modifier, $enc)
326 //new fees screen copay gives account_code='PCP'
327 $rowMoneyGot = sqlFetchArray($resMoneyGot);
328 $MoneyGot = $rowMoneyGot['MoneyGot'];
330 $resMoneyAdjusted = sqlStatement(
331 "SELECT sum(adj_amount) as MoneyAdjusted FROM ar_activity where " .
332 "pid = ? and code_type = ? and code = ? and modifier = ? and encounter = ? AND deleted IS NULL",
333 array($form_pid, $Codetype, $Code, $Modifier, $enc)
335 $rowMoneyAdjusted = sqlFetchArray($resMoneyAdjusted);
336 $MoneyAdjusted = $rowMoneyAdjusted['MoneyAdjusted'];
338 $Remainder = $Fee - $Copay - $MoneyGot - $MoneyAdjusted;
339 $Copay = 0;
340 if (round($Remainder, 2) != 0 && $amount != 0) {
341 if ($amount - $Remainder >= 0) {
342 $insert_value = $Remainder;
343 $amount = $amount - $Remainder;
344 } else {
345 $insert_value = $amount;
346 $amount = 0;
349 sqlBeginTrans();
350 $sequence_no = sqlQuery("SELECT IFNULL(MAX(sequence_no),0) + 1 AS increment FROM ar_activity WHERE pid = ? AND encounter = ?", array($form_pid, $enc));
351 sqlStatement(
352 "insert into ar_activity set " .
353 "pid = ?" .
354 ", encounter = ?" .
355 ", sequence_no = ?" .
356 ", code_type = ?" .
357 ", code = ?" .
358 ", modifier = ?" .
359 ", payer_type = ?" .
360 ", post_time = now() " .
361 ", post_user = ?" .
362 ", session_id = ?" .
363 ", pay_amount = ?" .
364 ", adj_amount = ?" .
365 ", account_code = 'PP'",
366 array($form_pid, $enc, $sequence_no['increment'], $Codetype, $Code, $Modifier, 0, $_SESSION['authUserID'], $payment_id, $insert_value, 0)
368 sqlCommitTrans();
369 }//if
370 }//while
371 if ($amount != 0) {//if any excess is there.
372 sqlBeginTrans();
373 $sequence_no = sqlQuery("SELECT IFNULL(MAX(sequence_no),0) + 1 AS increment FROM ar_activity WHERE pid = ? AND encounter = ?", array($form_pid, $enc));
374 sqlStatement(
375 "insert into ar_activity set " .
376 "pid = ?" .
377 ", encounter = ?" .
378 ", sequence_no = ?" .
379 ", code_type = ?" .
380 ", code = ?" .
381 ", modifier = ?" .
382 ", payer_type = ?" .
383 ", post_time = now() " .
384 ", post_user = ?" .
385 ", session_id = ?" .
386 ", pay_amount = ?" .
387 ", adj_amount = ?" .
388 ", account_code = 'PP'",
389 array($form_pid, $enc, $sequence_no['increment'], $Codetype, $Code, $Modifier, 0, $_SESSION['authUserID'], $payment_id, $amount, 0)
391 sqlCommitTrans();
394 //--------------------------------------------------------------------------------------------------------------------
395 }//invoice_balance
396 }//if ($amount = 0 + $payment)
397 }//foreach
398 }//if ($_POST['form_upay'])
399 }//if ($_POST['form_save'])
401 if (!empty($_POST['form_save']) || !empty($_REQUEST['receipt'])) {
402 if (!empty($_REQUEST['receipt'])) {
403 $form_pid = $_GET['patient'];
404 $timestamp = decorateString('....-..-.. ..:..:..', $_GET['time']);
407 // Get details for what we guess is the primary facility.
408 $frow = $facilityService->getPrimaryBusinessEntity(array("useLegacyImplementation" => true));
410 // Get the patient's name and chart number.
411 $patdata = getPatientData($form_pid, 'fname,mname,lname,pubpid');
413 // Re-fetch payment info.
414 $payrow = sqlQuery("SELECT " .
415 "SUM(amount1) AS amount1, " .
416 "SUM(amount2) AS amount2, " .
417 "MAX(method) AS method, " .
418 "MAX(source) AS source, " .
419 "MAX(dtime) AS dtime, " .
420 // "MAX(user) AS user " .
421 "MAX(user) AS user, " .
422 "MAX(encounter) as encounter " .
423 "FROM payments WHERE " .
424 "pid = ? AND dtime = ?", array($form_pid, $timestamp));
426 // Create key for deleting, just in case.
427 $ref_id = ($_REQUEST['radio_type_of_payment'] == 'copay') ? $session_id : $payment_id;
428 $payment_key = $form_pid . '.' . preg_replace('/[^0-9]/', '', $timestamp) . '.' . $ref_id;
430 if ($_REQUEST['radio_type_of_payment'] != 'pre_payment') {
431 // get facility from encounter
432 $tmprow = sqlQuery("SELECT `facility_id` FROM `form_encounter` WHERE `encounter` = ?", array($payrow['encounter']));
433 $frow = $facilityService->getById($tmprow['facility_id']);
434 } else {
435 // if pre_payment, then no encounter yet, so get main office address
436 $frow = $facilityService->getPrimaryBillingLocation();
439 // Now proceed with printing the receipt.
442 <title><?php echo xlt('Receipt for Payment'); ?></title>
443 <?php Header::setupHeader(); ?>
444 <script>
446 <?php require($GLOBALS['srcdir'] . "/restoreSession.php"); ?>
448 $(function () {
449 var win = top.printLogSetup ? top : opener.top;
450 win.printLogSetup(document.getElementById('printbutton'));
453 function closeHow(e) {
454 if (opener) {
455 dlgclose();
456 return;
458 top.activateTabByName('pat', true);
459 top.tabCloseByName(window.name);
462 // This is action to take before printing and is called from restoreSession.php.
463 function printlog_before_print() {
464 let divstyle = document.getElementById('hideonprint').style;
465 divstyle.display = 'none';
466 // currently exit is not hidden by default in case receipt print is not needed
467 // and left here for future option to force users to print via global etc..
468 // can still print later via reports.
469 divstyle = document.getElementById('showonprint').style;
470 divstyle.display = '';
473 // Process click on Delete button.
474 function deleteme() {
475 dlgopen('deleter.php?payment=' + <?php echo js_url($payment_key); ?> + '&csrf_token_form=' + <?php echo js_url(CsrfUtils::collectCsrfToken()); ?>, '_blank', 500, 450);
476 return false;
479 // Called by the deleteme.php window on a successful delete.
480 function imdeleted() {
481 if (opener) {
482 dlgclose(); // we're in reports/leftnav and callback reloads.
483 } else {
484 window.history.back(); // this is us full screen.
488 // Called to switch to the specified encounter having the specified DOS.
489 // This also closes the popup window.
490 function toencounter(enc, datestr, topframe) {
491 top.restoreSession();
492 top.goToEncounter(enc);
493 if (opener) dlgclose();
496 </script>
497 <style>
498 @media print {
499 #donebutton {
500 display: none;
503 .main-section {
504 display: grid;
505 grid-template-columns: 50% auto;
506 grid-template-areas: "section-2 section-1";
508 .section-1 {
509 grid-area: section-1;
510 height: fit-content;
511 align-self: center;
512 padding-left: 208px;
513 margin-top: -7em;
515 .section-2 {
516 grid-area: section-2;
517 text-align: left;
519 table,td,th {
520 border: 1px solid black; text-align: left;
522 table {
523 border-collapse: collapse; width: 100%;
525 th,td {
526 padding: 7px;
528 .table td {
529 padding: 7px;
531 .mini_table {
532 width: 100%;
534 table.mini_table>tbody>tr>th {
535 background-color: var(--secondary);
536 text-align: center;
538 body>table.mini_table>tbody>tr>td {
539 text-align: center;
541 body>table.mini_table>tbody>tr>td {
542 border: 1px solid #fff;
544 body>table.mini_table>tbody>tr>th {
545 border: 1px solid var(--secondary);
547 .bg-color {
548 background-color: var(--secondary);
549 padding: 2px;
550 font-weight: 600;
551 -webkit-print-color-adjust: exact;
553 .bg-color-w {
554 background-color: var(--secondary);
555 font-weight: 600;
556 -webkit-print-color-adjust: exact!important; }
557 @media print {
558 body {
559 -webkit-print-color-adjust: exact !important;
562 tr.bg-color-w{
563 background-color: var(--secondary)!important;
564 -webkit-print-color-adjust: exact;
566 tr.bg-color{
567 background-color: var(--secondary) !important;
568 -webkit-print-color-adjust: exact;
571 </style>
572 </head>
573 <body>
574 <div class="container mt-3">
575 <div class="row">
576 <!-- Omega -->
577 <div class="col-12 justify-content-center">
578 <h2 class="text-center"><?php echo xlt('Receipt for Payment'); ?></h2>
579 <div class="main-section mb-5 mt-10">
580 <div class="section-2">
581 <p style="font-weight:600;">
582 <bold class="bg-color"><?php echo text($frow['name']) ?></bold> <br /> <br />
583 <?php echo text($frow['street']) ?><br />
584 <?php echo text($frow['city'] . ', ' . $frow['state']) . ' ' . text($frow['postal_code']) ?><br />
585 <?php echo text("[Phone]" . $frow['phone']) ?><br />
586 <?php echo text("[Email] " . $frow['email']) ?><br />
589 <br />
590 <?php echo xlt('How Paid'); ?>:
591 <?php echo generate_display_field(array('data_type' => '1', 'list_id' => 'payment_method'), $payrow['method']); ?>
593 <br />
594 <?php echo xlt('Check or Reference Number'); ?>:
595 <?php echo text($payrow['source']); ?>
597 <br />
598 <?php
599 if ($_REQUEST['radio_type_of_payment'] == 'pre_payment') {
600 echo xlt('Pre-payment Amount');
601 } else {
602 echo xlt('Amount for Past Balance');
605 <?php echo text(oeFormatMoney($payrow['amount2'])); ?>
607 <br />
608 <?php echo xlt('Amount for This Visit'); ?>:
609 <?php echo text(oeFormatMoney($payrow['amount1'])); ?>
611 <br />
612 <?php echo xlt('Received By'); ?>:
613 <?php echo text($payrow['user']); ?>
614 </p>
616 </div>
617 <div class="section-1">
618 <?php if (file_exists($GLOBALS['OE_SITE_WEBROOT'] . "/images/logo_1.png")) { ?>
619 <img src=<?php echo $GLOBALS['OE_SITE_WEBROOT'] . "/images/logo_1.png" ?> alt="facility_logo" class="img-fluid">
620 <?php } ?>
622 <table class="mini_table text-center">
623 <tr>
624 <th><?php echo xlt('Invoice No.'); ?></th>
625 <th><?php echo xlt('Date'); ?></th>
626 </tr>
627 <tr class="text-center">
628 <td class="text-center"><?php echo text($invoice_refno); ?></td>
629 <td class="text-center"><?php echo text(oeFormatSDFT(strtotime($payrow['dtime']))); ?></td>
630 </tr>
631 </table>
632 </div>
633 </div>
635 <div class="table-responsive">
637 <table>
638 <!-- Omega Itemized Invoice -->
639 <tr class="bg-color-w">
640 <th><?php echo xlt('Description'); ?></th>
641 <th><?php echo xlt('Price'); ?></th>
642 <th><?php echo xlt('Qty'); ?></th>
643 <th><?php echo xlt('Total'); ?></th>
644 </tr>
645 <!-- Omega Itemized Invoice -->
646 <?php
647 $row_data = sqlStatement(
648 "SELECT * FROM billing WHERE " .
649 "pid = ? AND encounter = ? AND " .
650 // "code_type != 'COPAY' AND activity = 1 AND fee != 0 " .
651 "code_type != 'COPAY' AND activity = 1 " .
652 "ORDER BY id",
653 array($pid,$encounter)
655 while ($each_row = sqlFetchArray($row_data)) {
657 <tr>
658 <td><?php echo text($each_row['code_text']); ?></td>
659 <td><?php echo text($each_row['fee']); ?></td>
660 <td><?php echo text($each_row['units']); ?></td>
661 <td><?php echo text($each_row['fee'] * $each_row['units']); ?></td>
662 </tr>
663 <?php } ?>
665 <?php
666 $query = "SELECT s.sale_id, s.sale_date, s.prescription_id, s.fee, " .
667 "s.quantity, s.encounter, s.drug_id, d.name, r.provider_id " .
668 "FROM drug_sales AS s " .
669 "LEFT JOIN drugs AS d ON d.drug_id = s.drug_id " .
670 "LEFT OUTER JOIN prescriptions AS r ON r.id = s.prescription_id " .
671 "WHERE s.pid = ? AND s.encounter = ? AND s.billed = 0 " .
672 "ORDER BY s.encounter DESC, s.sale_id ASC";
673 $dres = sqlStatement($query, array($pid, $encounter));
674 while ($myproducts = sqlFetchArray($dres)) {
676 <tr>
677 <td><?php echo text($myproducts['name']); ?></td>
678 <td><?php echo text($myproducts['fee']); ?></td>
679 <td><?php echo text($myproducts['quantity']); ?></td>
680 <td><?php echo text($myproducts['fee'] * $myproducts['quantity']); ?></td>
681 </tr>
682 <?php } ?>
684 <tr>
685 <td style="border-right-color:white !important;"></td>
686 <td ></td>
687 <td class="text-right bg-color-w"><?php echo text("Total"); ?></td>
688 <td class="text-left bg-color-w"><?php echo text(oeFormatMoney($payrow['amount1'] + $payrow['amount2'])); ?></td>
689 </tr>
691 </table>
693 </div>
694 <div id='hideonprint' class="text-center pt-4">
695 <button type="button" class="btn btn-primary btn-print" value='<?php echo xla('Print'); ?>' id='printbutton'>
696 <?php echo xlt('Print'); ?>
697 </button>
699 <?php
700 $todaysenc = todaysEncounterIf($pid);
701 if ($todaysenc && $todaysenc != $encounter) {
702 echo "&nbsp;<input type='button' class='btn btn-primary' " .
703 "value='" . xla('Open Today`s Visit') . "' " .
704 "onclick='toencounter(" . attr_js($todaysenc) . ", " . attr_js($today) . ", (opener ? opener.top : top))' />\n";
708 <?php if (AclMain::aclCheckCore('admin', 'super') || AclMain::aclCheckCore('acct', 'bill')) {
709 // allowing biller to delete payments ?>
710 <button type="button" class="btn btn-danger btn-delete" value='<?php echo xla('Delete'); ?>' onclick="deleteme()">
711 <?php echo xlt('Delete'); ?>
712 </button>
713 <?php } ?>
714 </div>
715 <div class='mt-3 text-center' id='showonprint'>
716 <button type="button" class="btn btn-secondary btn-cancel" value='<?php echo xla('Exit'); ?>' id='donebutton' onclick="closeHow(event)">
717 <?php echo xlt('Exit'); ?>
718 </button>
719 </div>
720 </div>
721 </div>
722 </div>
723 </body>
725 <?php
727 // End of receipt printing logic.
729 } else {
731 // Here we display the form for data entry.
734 <title><?php echo xlt('Record Payment'); ?></title>
736 <style>
737 #ajax_div_patient {
738 position: absolute;
739 z-index:10;
740 background-color: #FBFDD0;
741 border: 1px solid #ccc;
742 padding: 10px;
744 </style>
745 <!--Removed standard dependencies 12/29/17 as not needed any longer since moved to a tab/frame not popup.-->
747 <!-- supporting javascript code -->
748 <script>
749 var mypcc = '1';
750 </script>
751 <?php include_once("{$GLOBALS['srcdir']}/ajax/payment_ajax_jav.inc.php"); ?>
752 <script>
753 document.onclick=HideTheAjaxDivs;
754 </script>
756 <?php Header::setupAssets('topdialog'); ?>
758 <script src="<?php echo $GLOBALS['assets_static_relative']; ?>/jquery-creditcardvalidator/jquery.creditCardValidator.js"></script>
760 <script>
761 var chargeMsg = <?php echo xlj('Payment was successfully authorized and charged. Thank You.'); ?>;
762 var publicKey = <?php echo json_encode($cryptoGen->decryptStandard($GLOBALS['gateway_public_key'])); ?>;
763 var apiKey = <?php echo json_encode($cryptoGen->decryptStandard($GLOBALS['gateway_api_key'])); ?>;
764 $(function() {
765 $('#openPayModal').on('show.bs.modal', function () {
766 let total = $("[name='form_paytotal']").val();
767 let prepay = $("#form_prepayment").val();
768 if (Number(total) < 1) {
769 if (Number(prepay) < 1) {
770 let error = <?php echo xlj("Please enter a payment amount"); ?>;
771 alert(error);
772 return false;
774 total = prepay;
776 $("#form_method").val('credit_card');
777 $("#payTotal").text(total);
778 $("#paymentAmount").val(total);
781 <?php require($GLOBALS['srcdir'] . "/restoreSession.php"); ?>
782 function closeHow(e) {
783 if (opener) {
784 dlgclose();
785 return;
787 top.activateTabByName('pat', true);
788 top.tabCloseByName(window.name);
790 function calctotal() {
791 var f = document.forms[0];
792 var total = 0;
793 for (var i = 0; i < f.elements.length; ++i) {
794 var elem = f.elements[i];
795 var ename = elem.name;
796 if (ename.indexOf('form_upay[') == 0 || ename.indexOf('form_bpay[') == 0) {
797 if (elem.value.length > 0) total += Number(elem.value);
800 f.form_paytotal.value = Number(total).toFixed(2);
801 return true;
804 function coloring() {
805 for (var i = 1; ; ++i) {
806 if (document.getElementById('paying_' + i)) {
807 paying = document.getElementById('paying_' + i).value * 1;
808 patient_balance = document.getElementById('duept_' + i).innerHTML * 1;
810 //balance=document.getElementById('balance_'+i).innerHTML*1;
811 if (patient_balance > 0 && paying > 0) {
812 if (paying > patient_balance) {
813 document.getElementById('paying_' + i).style.background = '#FF0000';
815 else if (paying < patient_balance) {
816 document.getElementById('paying_' + i).style.background = '#99CC00';
818 else if (paying == patient_balance) {
819 document.getElementById('paying_' + i).style.background = 'var(--white)';
821 } else {
822 document.getElementById('paying_' + i).style.background = 'var(--white)';
825 else {
826 break;
831 function CheckVisible(MakeBlank) { //Displays and hides the check number text box.
832 if (document.getElementById('form_method').options[document.getElementById(
833 'form_method').selectedIndex].value == 'check_payment' || document.getElementById(
834 'form_method').options[document.getElementById('form_method').selectedIndex]
835 .value == 'bank_draft') {
836 document.getElementById('check_number').disabled = false;
837 } else {
838 document.getElementById('check_number').disabled = true;
842 function validate(notSubmit = false) {
843 var f = document.forms[0];
844 let ok = -1;
845 top.restoreSession();
846 issue = 'no';
847 // prevent an empty form submission
848 let flgempty = true;
849 for (let i = 0; i < f.elements.length; ++i) {
850 let ename = f.elements[i].name;
851 if (f.elements[i].value == 'pre_payment' && f.elements[i].checked === true) {
852 if (Number(f.elements.namedItem("form_prepayment").value) !== 0) {
853 flgempty = false;
855 break;
857 if (ename.indexOf('form_upay[') === 0 || ename.indexOf('form_bpay[') === 0) {
858 if (Number(f.elements[i].value) !== 0) flgempty = false;
861 if (flgempty) {
862 alert(<?php echo xlj('A Payment is Required!. Please input a payment line item entry.'); ?>);
863 return false;
865 // continue validation.
866 if (((document.getElementById('form_method').options[document.getElementById('form_method').selectedIndex].value == 'check_payment' ||
867 document.getElementById('form_method').options[document.getElementById('form_method').selectedIndex].value == 'bank_draft') &&
868 document.getElementById('check_number').value == '')) {
869 alert(<?php echo xlj('Please Fill the Check or Reference Number'); ?>);
870 document.getElementById('check_number').focus();
871 return false;
873 if (document.getElementById('radio_type_of_payment_self1').checked == false &&
874 document.getElementById('radio_type_of_payment1').checked == false &&
875 document.getElementById('radio_type_of_payment2').checked == false &&
876 document.getElementById('radio_type_of_payment4').checked == false) {
877 alert(<?php echo xlj('Please Select Type Of Payment.'); ?>);
878 return false;
880 if (document.getElementById('radio_type_of_payment_self1').checked == true ||
881 document.getElementById('radio_type_of_payment1').checked == true) {
882 for (var i = 0; i < f.elements.length; ++i) {
883 var elem = f.elements[i];
884 var ename = elem.name;
885 if (ename.indexOf('form_upay[0') == 0) //Today is this text box.
887 if (elem.value * 1 > 0) {//A warning message, if the amount is posted with out encounter.
888 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.'); ?>)) {
889 ok = 2;
890 } else {
891 elem.focus();
892 return false;
895 break;
900 if (document.getElementById('radio_type_of_payment1').checked == true){//CO-PAY
901 var total = 0;
902 for (var i = 0; i < f.elements.length; ++i) {
903 var elem = f.elements[i];
904 var ename = elem.name;
905 if (ename.indexOf('form_upay[0]') == 0) {//Today is this text box.
906 if (f.form_paytotal.value * 1 != elem.value * 1) {//Total CO-PAY is not posted against today
907 //A warning message, if the amount is posted against an old encounter.
908 if (confirm(<?php echo xlj('You are posting against an old encounter?'); ?>)) {
909 ok = 1;
910 } else {
911 elem.focus();
912 return false;
915 break;
918 }//Co Pay
919 else if (document.getElementById('radio_type_of_payment2').checked == true) {//Invoice Balance
920 for (var i = 0; i < f.elements.length; ++i) {
921 var elem = f.elements[i];
922 var ename = elem.name;
923 if (ename.indexOf('form_upay[0') == 0) {
924 if (elem.value * 1 > 0) {
925 alert(<?php echo xlj('Invoice Balance cannot be posted. No Encounter is created.'); ?>);
926 return false;
928 break;
932 if (notSubmit) {
933 return true;
935 if (ok === -1) {
936 if (confirm(<?php echo xlj('Would you like to save?'); ?>)) {
937 return true;
939 else {
940 return false;
943 return ok;
946 function cursor_pointer() { //Point the cursor to the latest encounter(Today)
947 var f = document.forms[0];
948 var total = 0;
949 for (var i = 0; i < f.elements.length; ++i) {
950 var elem = f.elements[i];
951 var ename = elem.name;
952 if (ename.indexOf('form_upay[') == 0) {
953 elem.focus();
954 break;
958 //=====================================================
959 function make_it_hide_enc_pay() {
960 document.getElementById('td_head_insurance_payment').style.display = "none";
961 document.getElementById('td_head_patient_co_pay').style.display = "none";
962 document.getElementById('td_head_co_pay').style.display = "none";
963 document.getElementById('td_head_insurance_balance').style.display = "none";
964 for (var i = 1; ; ++i) {
965 var td_inspaid_elem = document.getElementById('td_inspaid_' + i)
966 var td_patient_copay_elem = document.getElementById('td_patient_copay_' + i)
967 var td_copay_elem = document.getElementById('td_copay_' + i)
968 var balance_elem = document.getElementById('balance_' + i)
969 if (td_inspaid_elem) {
970 td_inspaid_elem.style.display = "none";
971 td_patient_copay_elem.style.display = "none";
972 td_copay_elem.style.display = "none";
973 balance_elem.style.display = "none";
974 } else {
975 break;
978 document.getElementById('td_total_4').style.display = "none";
979 document.getElementById('td_total_7').style.display = "none";
980 document.getElementById('td_total_8').style.display = "none";
981 document.getElementById('td_total_6').style.display = "none";
982 document.getElementById('table_display').width = "420px";
984 //=====================================================
985 function make_visible() {
986 document.getElementById('td_head_rep_doc').style.display = "";
987 document.getElementById('td_head_description').style.display = "";
988 document.getElementById('td_head_total_charge').style.display = "none";
989 document.getElementById('td_head_insurance_payment').style.display = "none";
990 document.getElementById('td_head_patient_payment').style.display = "none";
991 document.getElementById('td_head_patient_co_pay').style.display = "none";
992 document.getElementById('td_head_co_pay').style.display = "none";
993 document.getElementById('td_head_insurance_balance').style.display = "none";
994 document.getElementById('td_head_patient_balance').style.display = "none";
995 for (var i = 1; ; ++i) {
996 var td_charges_elem = document.getElementById('td_charges_' + i)
997 var td_inspaid_elem = document.getElementById('td_inspaid_' + i)
998 var td_ptpaid_elem = document.getElementById('td_ptpaid_' + i)
999 var td_patient_copay_elem = document.getElementById('td_patient_copay_' + i)
1001 var td_copay_elem = document.getElementById('td_copay_' + i)
1002 var balance_elem = document.getElementById('balance_' + i)
1003 var duept_elem = document.getElementById('duept_' + i)
1004 if (td_charges_elem) {
1005 td_charges_elem.style.display = "none";
1006 td_inspaid_elem.style.display = "none";
1007 td_ptpaid_elem.style.display = "none";
1008 td_patient_copay_elem.style.display = "none";
1009 td_copay_elem.style.display = "none";
1010 balance_elem.style.display = "none";
1011 duept_elem.style.display = "none";
1012 } else {
1013 break;
1016 document.getElementById('td_total_7').style.display = "";
1017 document.getElementById('td_total_8').style.display = "";
1018 document.getElementById('td_total_1').style.display = "none";
1019 document.getElementById('td_total_2').style.display = "none";
1020 document.getElementById('td_total_3').style.display = "none";
1021 document.getElementById('td_total_4').style.display = "none";
1022 document.getElementById('td_total_5').style.display = "none";
1023 document.getElementById('td_total_6').style.display = "none";
1024 document.getElementById('table_display').width = "505px";
1027 function make_it_hide() {
1028 document.getElementById('td_head_rep_doc').style.display = "none";
1029 document.getElementById('td_head_description').style.display = "none";
1030 document.getElementById('td_head_total_charge').style.display = "";
1031 document.getElementById('td_head_insurance_payment').style.display = "";
1032 document.getElementById('td_head_patient_payment').style.display = "";
1033 document.getElementById('td_head_patient_co_pay').style.display = "";
1034 document.getElementById('td_head_co_pay').style.display = "";
1035 document.getElementById('td_head_insurance_balance').style.display = "";
1036 document.getElementById('td_head_patient_balance').style.display = "";
1037 for (var i = 1; ; ++i) {
1038 var td_charges_elem = document.getElementById('td_charges_' + i)
1039 var td_inspaid_elem = document.getElementById('td_inspaid_' + i)
1040 var td_ptpaid_elem = document.getElementById('td_ptpaid_' + i)
1041 var td_patient_copay_elem = document.getElementById('td_patient_copay_' + i)
1043 var td_copay_elem = document.getElementById('td_copay_' + i)
1044 var balance_elem = document.getElementById('balance_' + i)
1045 var duept_elem = document.getElementById('duept_' + i)
1046 if (td_charges_elem) {
1047 td_charges_elem.style.display = "";
1048 td_inspaid_elem.style.display = "";
1049 td_ptpaid_elem.style.display = "";
1050 td_patient_copay_elem.style.display = "";
1051 td_copay_elem.style.display = "";
1052 balance_elem.style.display = "";
1053 duept_elem.style.display = "";
1054 } else {
1055 break;
1058 document.getElementById('td_total_1').style.display = "";
1059 document.getElementById('td_total_2').style.display = "";
1060 document.getElementById('td_total_3').style.display = "";
1061 document.getElementById('td_total_4').style.display = "";
1062 document.getElementById('td_total_5').style.display = "";
1063 document.getElementById('td_total_6').style.display = "";
1064 document.getElementById('td_total_7').style.display = "";
1065 document.getElementById('td_total_8').style.display = "";
1066 document.getElementById('table_display').width = "635px";
1069 function make_visible_radio() {
1070 document.getElementById('tr_radio1').style.display = "";
1071 document.getElementById('tr_radio2').style.display = "none";
1074 function make_hide_radio() {
1075 document.getElementById('tr_radio1').style.display = "none";
1076 document.getElementById('tr_radio2').style.display = "";
1079 function make_visible_row() {
1080 document.getElementById('table_display').style.display = "";
1081 document.getElementById('table_display_prepayment').style.display = "none";
1084 function make_hide_row() {
1085 document.getElementById('table_display').style.display = "none";
1086 document.getElementById('table_display_prepayment').style.display = "";
1089 function make_self() {
1090 make_visible_row();
1091 make_it_hide();
1092 make_it_hide_enc_pay();
1093 document.getElementById('radio_type_of_payment_self1').checked = true;
1094 cursor_pointer();
1097 function make_insurance() {
1098 make_visible_row();
1099 make_it_hide();
1100 cursor_pointer();
1101 document.getElementById('radio_type_of_payment1').checked = true;
1103 </script>
1105 <style>
1106 @media (min-width: 992px) {
1107 .modal-lg {
1108 width: 1000px !Important;
1111 </style>
1112 <title><?php echo xlt('Record Payment'); ?></title>
1113 <?php $NameNew = $patdata['fname'] . " " . $patdata['lname'] . " " . $patdata['mname']; ?>
1114 <?php
1115 $arrOeUiSettings = array(
1116 'heading_title' => xl('Accept Payment'),
1117 'include_patient_name' => true,// use only in appropriate pages
1118 'expandable' => false,
1119 'expandable_files' => array(),//all file names need suffix _xpd
1120 'action' => "",//conceal, reveal, search, reset, link or back
1121 'action_title' => "",
1122 'action_href' => "",//only for actions - reset, link or back
1123 'show_help_icon' => false,
1124 'help_file_name' => ""
1126 $oemr_ui = new OemrUI($arrOeUiSettings);
1128 </head>
1129 <body>
1130 <div class="container mt-3"><!--begin container div for form-->
1131 <div class="row">
1132 <div class="col-sm-12">
1133 <?php echo $oemr_ui->pageHeading() . "\r\n"; ?>
1134 </div>
1135 </div>
1136 <div class="row">
1137 <div class="col-sm-12">
1138 <form class="form form-vertical" method='post' action='front_payment.php<?php echo (!empty($payid)) ? "?payid=" . attr_url($payid) : ""; ?>' onsubmit='return validate();'>
1139 <input type="hidden" name="csrf_token_form" value="<?php echo attr(CsrfUtils::collectCsrfToken()); ?>" />
1140 <input name='form_pid' type='hidden' value='<?php echo attr($pid) ?>' />
1141 <fieldset>
1142 <legend><?php echo xlt('Payment'); ?></legend>
1143 <?php
1144 $prepayment_bal = get_unallocated_patient_balance($pid);
1145 if ($prepayment_bal > 0) : ?>
1146 <div class="col-12 oe-custom-line">
1147 <label class="control-label" for="unallocated"><?php
1148 echo xlt('Patient has an unallocated pre-payment amount of ') .
1149 text($prepayment_bal); ?></label><br>
1150 <a href="../billing/edit_payment.php?payment_id=<?php
1151 echo attr_url(get_unallocated_payment_id($pid)); ?>"
1152 target="_self"><?php echo xlt('Apply unallocated pre-payments here') ?></a>
1153 </div><br>
1154 <?php endif; ?>
1155 <div class="col-12 oe-custom-line">
1156 <label class="control-label" for="form_method"><?php echo xlt('Payment Method'); ?>:</label>
1157 <select class="form-control" id="form_method" name="form_method" onchange='CheckVisible("yes")'>
1158 <?php
1159 $query1112 = "SELECT * FROM `list_options` where activity=1 AND list_id=? ORDER BY seq, title ";
1160 $bres1112 = sqlStatement($query1112, array('payment_method'));
1161 while ($brow1112 = sqlFetchArray($bres1112)) {
1162 if ($brow1112['option_id'] == 'electronic' || $brow1112['option_id'] == 'bank_draft') {
1163 continue;
1165 echo "<option value='" . attr($brow1112['option_id']) . "'" .
1166 ($brow1112['is_default'] ? ' selected' : '') . ">" . text(xl_list_label($brow1112['title'])) . "</option>";
1169 </select>
1170 </div>
1171 <div class="col-12 oe-custom-line">
1172 <label class="control-label" for="check_number"><?php echo xlt('Check or Reference Number'); ?>:</label>
1173 <div id="ajax_div_patient" style="display:none;"></div>
1174 <input type='text' id="check_number" name='form_source' class='form-control' value='<?php echo attr($payrow['source'] ?? ''); ?>' />
1175 </div>
1176 <div class="col-12 oe-custom-line">
1177 <label class="control-label" for="form_discount"><?php echo xla('Patient Coverage'); ?>:</label>
1178 <div class="pl-3">
1179 <label class="radio-inline">
1180 <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'); ?>
1181 </label>
1182 <label class="radio-inline">
1183 <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'); ?>
1184 </label>
1185 </div>
1186 </div>
1187 <div class="col-12 oe-custom-line">
1188 <label class="control-label" for=""><?php echo xlt('Payment against'); ?>:</label>
1189 <div id="tr_radio1" style="padding-left:15px; display:none"><!-- For radio Insurance -->
1190 <label class="radio-inline">
1191 <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'); ?>
1192 </label>
1193 </div>
1194 <div id="tr_radio2" style="padding-left:15px"><!-- For radio self -->
1195 <label class="radio-inline">
1196 <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'); ?>
1197 </label>
1198 <label class="radio-inline">
1199 <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 />
1200 </label>
1201 <label class="radio-inline">
1202 <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'); ?>
1203 </label>
1204 </div>
1205 </div>
1206 <div class="col-12 oe-custom-line">
1207 <div id="table_display_prepayment" style="display:none">
1208 <label class="control-label" for="form_prepayment"><?php echo xlt('Pre Payment'); ?>:</label>
1209 <input name='form_prepayment' id='form_prepayment'class='form-control' type='text' value ='' />
1210 </div>
1211 </div>
1212 </fieldset>
1213 <fieldset>
1214 <legend><?php echo xlt('Collect For'); ?></legend>
1215 <div class="table-responsive">
1216 <table class="table" id="table_display">
1217 <thead>
1218 <tr class="table-active" id="tr_head">
1219 <th class="font-weight-bold" width="70"><?php echo xlt('DOS'); ?></th>
1220 <th class="font-weight-bold" width="65"><?php echo xlt('Encounter'); ?></th>
1221 <th class="font-weight-bold text-center" id="td_head_total_charge" width="80"><?php echo xlt('Total Charge'); ?></th>
1222 <th class="font-weight-bold text-center" id="td_head_rep_doc" style='display:none' width="70"><?php echo xlt('Report/ Form'); ?></th>
1223 <th class="font-weight-bold text-center" id="td_head_description" style='display:none' width="200"><?php echo xlt('Description'); ?></th>
1224 <th class="font-weight-bold text-center" id="td_head_insurance_payment" width="80"><?php echo xlt('Insurance Payment'); ?></th>
1225 <th class="font-weight-bold text-center" id="td_head_patient_payment" width="80"><?php echo xlt('Patient Payment'); ?></th>
1226 <th class="font-weight-bold text-center" id="td_head_patient_co_pay" width="55"><?php echo xlt('Co Pay Paid'); ?></th>
1227 <th class="font-weight-bold text-center" id="td_head_co_pay" width="55"><?php echo xlt('Required Co Pay'); ?></th>
1228 <th class="font-weight-bold text-center" id="td_head_insurance_balance" width="80"><?php echo xlt('Insurance Balance'); ?></th>
1229 <th class="font-weight-bold text-center" id="td_head_patient_balance" width="80"><?php echo xlt('Patient Balance'); ?></th>
1230 <th class="font-weight-bold text-center" width="50"><?php echo xlt('Paying'); ?></th>
1231 </tr>
1232 </thead>
1233 <?php
1234 $encs = array();
1236 // Get the unbilled service charges and payments by encounter for this patient.
1238 $query = "SELECT fe.encounter, b.code_type, b.code, b.modifier, b.fee, " .
1239 "LEFT(fe.date, 10) AS encdate ,fe.last_level_closed " .
1240 "FROM form_encounter AS fe left join billing AS b on " .
1241 "b.pid = ? AND b.activity = 1 AND " . //AND b.billed = 0
1242 "b.code_type != 'TAX' AND b.fee != 0 " .
1243 "AND fe.pid = b.pid AND fe.encounter = b.encounter " .
1244 "where fe.pid = ? " .
1245 "ORDER BY b.encounter";
1246 $bres = sqlStatement($query, array($pid, $pid));
1248 while ($brow = sqlFetchArray($bres)) {
1249 $key = 0 - $brow['encounter'];
1250 if (empty($encs[$key])) {
1251 $encs[$key] = array(
1252 'encounter' => $brow['encounter'],
1253 'date' => $brow['encdate'],
1254 'last_level_closed' => $brow['last_level_closed'],
1255 'charges' => 0,
1256 'payments' => 0);
1259 if ($brow['code_type'] === 'COPAY') {
1260 //$encs[$key]['payments'] -= $brow['fee'];
1261 } else {
1262 $encs[$key]['charges'] += $brow['fee'];
1263 // Add taxes.
1264 $sql_array = array();
1265 $query = "SELECT taxrates FROM `codes` WHERE " .
1266 "code_type = ? AND " .
1267 "code = ? AND ";
1268 array_push($sql_array, ($code_types[$brow['code_type']]['id'] ?? null), $brow['code']);
1269 if ($brow['modifier']) {
1270 $query .= "modifier = ?";
1271 array_push($sql_array, $brow['modifier']);
1272 } else {
1273 $query .= "(modifier IS NULL OR modifier = '')";
1276 $query .= " LIMIT 1";
1277 $trow = sqlQuery($query, $sql_array);
1278 $encs[$key]['charges'] += calcTaxes($trow, $brow['fee']);
1282 // Do the same for unbilled product sales.
1284 $query = "SELECT fe.encounter, s.drug_id, s.fee, " .
1285 "LEFT(fe.date, 10) AS encdate,fe.last_level_closed " .
1286 "FROM form_encounter AS fe left join drug_sales AS s " .
1287 "on s.pid = ? AND s.fee != 0 " . //AND s.billed = 0
1288 "AND fe.pid = s.pid AND fe.encounter = s.encounter " .
1289 "where fe.pid = ? " .
1290 "ORDER BY s.encounter";
1292 $dres = sqlStatement($query, array($pid, $pid));
1294 while ($drow = sqlFetchArray($dres)) {
1295 $key = 0 - $drow['encounter'];
1296 if (empty($encs[$key])) {
1297 $encs[$key] = array(
1298 'encounter' => $drow['encounter'],
1299 'date' => $drow['encdate'],
1300 'last_level_closed' => $drow['last_level_closed'],
1301 'charges' => 0,
1302 'payments' => 0);
1305 $encs[$key]['charges'] += $drow['fee'];
1306 // Add taxes.
1307 $trow = sqlQuery("SELECT taxrates FROM `drug_templates` WHERE drug_id = ? " .
1308 "ORDER BY selector LIMIT 1", array($drow['drug_id']));
1309 $encs[$key]['charges'] += calcTaxes($trow, $drow['fee']);
1312 ksort($encs, SORT_NUMERIC);
1313 $gottoday = false;
1314 //Bringing on top the Today always
1315 foreach ($encs as $key => $value) {
1316 $dispdate = $value['date'];
1317 if (strcmp($dispdate, $today) == 0 && !$gottoday) {
1318 $gottoday = true;
1319 break;
1323 // If no billing was entered yet for today, then generate a line for
1324 // entering today's co-pay.
1326 if (!$gottoday) {
1327 echoLine("form_upay[0]", date("Y-m-d"), 0, 0, 0, 0 /*$duept*/);//No encounter yet defined.
1330 $gottoday = false;
1331 foreach ($encs as $key => $value) {
1332 $enc = $value['encounter'];
1333 $dispdate = $value['date'];
1334 if (strcmp($dispdate, $today) == 0 && !$gottoday) {
1335 $dispdate = date("Y-m-d");
1336 $gottoday = true;
1338 //------------------------------------------------------------------------------------
1339 $inscopay = BillingUtilities::getCopay($pid, $dispdate);
1340 $patcopay = BillingUtilities::getPatientCopay($pid, $enc);
1341 //Insurance Payment
1342 //-----------------
1343 $drow = sqlQuery(
1344 "SELECT SUM(pay_amount) AS payments, " .
1345 "SUM(adj_amount) AS adjustments FROM ar_activity WHERE " .
1346 "deleted IS NULL AND pid = ? and encounter = ? and " .
1347 "payer_type != 0 and account_code!='PCP' ",
1348 array($pid, $enc)
1350 $dpayment = $drow['payments'];
1351 $dadjustment = $drow['adjustments'];
1352 //Patient Payment
1353 //---------------
1354 $drow = sqlQuery(
1355 "SELECT SUM(pay_amount) AS payments, " .
1356 "SUM(adj_amount) AS adjustments FROM ar_activity WHERE " .
1357 "deleted IS NULL AND pid = ? and encounter = ? and " .
1358 "payer_type = 0 and account_code!='PCP' ",
1359 array($pid, $enc)
1361 $dpayment_pat = $drow['payments'];
1363 //------------------------------------------------------------------------------------
1364 //NumberOfInsurance
1365 $ResultNumberOfInsurance = sqlStatement("SELECT COUNT( DISTINCT TYPE ) NumberOfInsurance FROM `insurance_data`
1366 where pid = ? and provider>0 ", array($pid));
1367 $RowNumberOfInsurance = sqlFetchArray($ResultNumberOfInsurance);
1368 $NumberOfInsurance = $RowNumberOfInsurance['NumberOfInsurance'] * 1;
1369 //------------------------------------------------------------------------------------
1370 $duept = 0;
1371 if ((($NumberOfInsurance == 0 || $value['last_level_closed'] == 4 || $NumberOfInsurance == $value['last_level_closed']))) {//Patient balance
1372 $brow = sqlQuery("SELECT SUM(fee) AS amount FROM `billing` WHERE " .
1373 "pid = ? and encounter = ? AND activity = 1", array($pid, $enc));
1374 $srow = sqlQuery("SELECT SUM(fee) AS amount FROM `drug_sales` WHERE " .
1375 "pid = ? and encounter = ? ", array($pid, $enc));
1376 $drow = sqlQuery("SELECT SUM(pay_amount) AS payments, " .
1377 "SUM(adj_amount) AS adjustments FROM ar_activity WHERE " .
1378 "deleted IS NULL AND pid = ? and encounter = ? ", array($pid, $enc));
1379 $duept = $brow['amount'] + $srow['amount'] - $drow['payments'] - $drow['adjustments'];
1382 echoLine(
1383 "form_upay[$enc]",
1384 $dispdate,
1385 $value['charges'],
1386 $dpayment_pat,
1387 ($dpayment + $dadjustment),
1388 $duept,
1389 $enc,
1390 $inscopay,
1391 $patcopay
1394 // Continue with display of the data entry form.
1397 <tr class="table-active">
1398 <td class="font-weight-bold" id='td_total_1'></td>
1399 <td class="font-weight-bold" id='td_total_2'></td>
1400 <td class="font-weight-bold" id='td_total_3'></td>
1401 <td class="font-weight-bold" id='td_total_4'></td>
1402 <td class="font-weight-bold" id='td_total_5'></td>
1403 <td class="font-weight-bold" id='td_total_6'></td>
1404 <td class="font-weight-bold" id='td_total_7'></td>
1405 <td class="font-weight-bold" id='td_total_8'></td>
1406 <td class="font-weight-bold text-right"><?php echo xlt('Total');?></td>
1407 <td class="font-weight-bold text-right">
1408 <input type='text' class='form-control text-success' name='form_paytotal' value='' readonly />
1409 </td>
1410 </tr>
1411 </table>
1412 </div>
1413 </fieldset>
1414 <div class="form-group">
1415 <div class="col-sm-12 text-left position-override">
1416 <div class="form-group" role="group" id="button-group">
1417 <button type='submit' class="btn btn-primary btn-save" name='form_save' value='<?php echo xla('Generate Invoice');?>'><?php echo xlt('Generate Invoice');?></button>
1418 <?php if (!empty($GLOBALS['cc_front_payments']) && $GLOBALS['payment_gateway'] != 'InHouse') {
1419 if ($GLOBALS['payment_gateway'] == 'Sphere') {
1420 echo SpherePayment::renderSphereHtml('clinic');
1421 } else {
1422 echo '<button type="button" class="btn btn-success btn-transmit mx-1" data-toggle="modal" data-target="#openPayModal">' . xlt("Credit Card Pay") . '</button>';
1423 if (!empty($GLOBALS['cc_stripe_terminal'])) {
1424 echo '<button type="button" class="btn btn-success btn-transmit mx-1" onclick="posDialog()">' . xlt("POS Payment") . '</button>';
1427 } ?>
1428 <button type='button' class="btn btn-secondary btn-cancel" value='<?php echo xla('Cancel'); ?>' onclick='closeHow(event)'><?php echo xlt('Cancel'); ?></button>
1429 <input type="hidden" name="hidden_patient_code" id="hidden_patient_code" value="<?php echo attr($pid);?>"/>
1430 <input type='hidden' name='ajax_mode' id='ajax_mode' value='' />
1431 <input type='hidden' name='mode' id='mode' value='' />
1432 </div>
1433 </div>
1434 </div>
1435 </form>
1436 </div>
1437 </div>
1438 <script>
1439 calctotal();
1440 </script>
1441 <!-- credit payment modal -->
1442 <div id="openPayModal" class="modal fade" role="dialog">
1443 <div class="modal-dialog">
1444 <div class="modal-content">
1445 <div class="modal-header">
1446 <h4><?php echo xlt('Submit Payment for Authorization'); ?></h4>
1447 </div>
1448 <div class="modal-body">
1449 <?php if ($GLOBALS['payment_gateway'] == 'AuthorizeNet') { ?>
1450 <form id='paymentForm' method='post' action='./front_payment_cc.php'>
1451 <fieldset>
1452 <div class="form-group">
1453 <label
1454 class="control-label"><?php echo xlt('Name on Card'); ?></label>
1455 <div class="controls">
1456 <input name="cardHolderName" id="cardHolderName" type="text" class="form-control"
1457 pattern="\w+ \w+.*"
1458 title="<?php echo xla('Fill your first and last name'); ?>"
1459 value="<?php echo attr($patdata['fname']) . ' ' . attr($patdata['lname']) ?>" />
1460 </div>
1461 </div>
1462 <div class="form-group">
1463 <div class="row">
1464 <div class="col-sm-6">
1465 <label class="control-label"><?php echo xlt('Card Number'); ?></label>
1466 <input name="cardNumber" id="cardNumber" type="text"
1467 class="form-control"
1468 autocomplete="off" maxlength="19" pattern="\d"
1469 onchange="validateCC()"
1470 title="<?php echo xla('Card Number'); ?>" value="" />&nbsp;&nbsp;
1471 </div>
1472 <span class="col-sm-6">
1473 <label class="control-label"><?php echo xlt('Entry Status'); ?></label>
1474 <h5 name="cardtype" id="cardtype" style="color:#cc0000;"><?php echo xlt('Validating') ?></h5>
1475 </span>
1476 </div>
1477 </div>
1478 <div class="form-group">
1479 <label
1480 class="control-label"><?php echo xlt('Card Expiry Date and Card Holders Zip'); ?></label>
1481 <div class="row">
1482 <div class="col-md-4">
1483 <select name="month" id="expMonth" class="form-control">
1484 <option value=""><?php echo xlt('Select Month'); ?></option>
1485 <option value="01"><?php echo xlt('January'); ?></option>
1486 <option value="02"><?php echo xlt('February'); ?></option>
1487 <option value="03"><?php echo xlt('March'); ?></option>
1488 <option value="04"><?php echo xlt('April'); ?></option>
1489 <option value="05"><?php echo xlt('May'); ?></option>
1490 <option value="06"><?php echo xlt('June'); ?></option>
1491 <option value="07"><?php echo xlt('July'); ?></option>
1492 <option value="08"><?php echo xlt('August'); ?></option>
1493 <option value="09"><?php echo xlt('September'); ?></option>
1494 <option value="10"><?php echo xlt('October'); ?></option>
1495 <option value="11"><?php echo xlt('November'); ?></option>
1496 <option value="12"><?php echo xlt('December'); ?></option>
1497 </select>
1498 </div>
1499 <div class="col-md-4">
1500 <select name="year" id="expYear" class="form-control">
1501 <option value=""><?php echo xlt('Select Year'); ?></option>
1502 <option value="2021">2021</option>
1503 <option value="2022">2022</option>
1504 <option value="2023">2023</option>
1505 <option value="2024">2024</option>
1506 <option value="2025">2025</option>
1507 <option value="2026">2026</option>
1508 <option value="2027">2027</option>
1509 <option value="2028">2028</option>
1510 <option value="2028">2029</option>
1511 <option value="2028">2030</option>
1512 </select>
1513 </div>
1514 <div class="col-md-4">
1515 <input name="zip" id="cczip" type="text" class="form-control"
1516 pattern="\d"
1517 title="<?php echo xla('Enter Your Zip'); ?>"
1518 placeholder="<?php echo xla('Card Holder Zip'); ?>"
1519 value="<?php echo attr($patdata['postal_code']) ?>" />
1520 </div>
1521 </div>
1522 </div>
1523 <div class="form-group">
1524 <label class="control-label"><?php echo xlt('Card CVV'); ?></label>
1525 <div class="row">
1526 <div class="col-md-3">
1527 <input name="cardCode" id="cardCode" type="text" class="form-control"
1528 autocomplete="off" maxlength="4" onfocus="validateCC()"
1529 title="<?php echo xla('Three or four digits at back of your card'); ?>"
1530 value="" />
1531 </div>
1532 <div class="col-md-3">
1533 <img src='./../../portal/images/img_cvc.png' style='height: 40px; width: auto'>
1534 </div>
1535 <div class="col-md-6">
1536 <h4 style="display: inline-block;"><?php echo xlt('Payment Amount'); ?>:&nbsp;
1537 <strong><span id="payTotal"></span></strong></h4>
1538 </div>
1539 </div>
1540 </div>
1541 <input type='hidden' name='pid' id='pid' value='<?php echo attr($pid) ?>' />
1542 <input type='hidden' name='mode' id='mode' value='' />
1543 <input type='hidden' name='cc_type' id='cc_type' value='' />
1544 <input type='hidden' name='payment' id='paymentAmount' value='' />
1545 <input type='hidden' name='invValues' id='invValues' value='' />
1546 <input type="hidden" name="dataValue" id="dataValue" />
1547 <input type="hidden" name="dataDescriptor" id="dataDescriptor" />
1548 </fieldset>
1549 </form>
1550 <?php }
1551 if ($GLOBALS['payment_gateway'] == 'Stripe') { ?>
1552 <form class="form" method="post" name="payment-form" id="payment-form">
1553 <fieldset>
1554 <div class="form-group">
1555 <label for="cardHolderName" class="control-label"><?php echo xlt('Name on Card'); ?></label>
1556 <input name="cardHolderName" id="cardHolderName" type="text"
1557 class="form-control"
1558 pattern="\w+ \w+.*"
1559 title="<?php echo xla('Fill your first and last name'); ?>"
1560 value="<?php echo attr($patdata['fname']) . ' ' . attr($patdata['lname']) ?>" />
1561 </div>
1562 <div class="form-group">
1563 <label for="card-element"><?php echo xlt('Credit or Debit Card') ?></label>
1564 <div class="form-group" id="card-element"></div>
1565 <div class="text-danger" id="card-errors" role="alert"></div>
1566 </div>
1567 <div class="form-row">
1568 <?php echo xlt('Payment Amount'); ?>:&nbsp;<span id="payTotal"></span>
1569 </div>
1570 <input type='hidden' name='mode' id='mode' value='' />
1571 <input type='hidden' name='cc_type' id='cc_type' value='' />
1572 <input type='hidden' name='payment' id='paymentAmount' value='' />
1573 <input type='hidden' name='invValues' id='invValues' value='' />
1574 <input type='hidden' name='encs' id='encs' value='' />
1575 </fieldset>
1576 </form>
1577 <?php } ?>
1578 </div>
1579 <!-- Body -->
1580 <div class="modal-footer">
1581 <div class="button-group">
1582 <button type="button" class="btn btn-default" data-dismiss="modal"><?php echo xlt('Cancel'); ?></button>
1583 <?php
1584 if ($GLOBALS['payment_gateway'] == 'AuthorizeNet') { ?>
1585 <button id="payAurhorizeNet" class="btn btn-primary"
1586 onclick="sendPaymentDataToAnet(event)"><?php echo xlt('Pay Now'); ?></button>
1587 <?php }
1588 if ($GLOBALS['payment_gateway'] == 'Stripe') { ?>
1589 <button id="stripeSubmit" class="btn btn-primary"><?php echo xlt('Pay Now'); ?></button>
1590 <?php } ?>
1591 </div>
1592 </div>
1593 </div>
1594 </div>
1595 </div>
1597 <?php if ($GLOBALS['payment_gateway'] == 'AuthorizeNet') {
1598 // Include Authorize.Net dependency to tokenize card.
1599 // Will return a token to use for payment request keeping
1600 // credit info off the server.
1602 <script>
1603 var ccerr = <?php echo xlj('Invalid Credit Card Number'); ?>
1605 // In House CC number Validation
1606 $('#cardNumber').validateCreditCard(function (result) {
1607 var r = (result.card_type === null ? '' : result.card_type.name.toUpperCase())
1608 var v = (result.valid === true ? ' Valid Number' : ' Validating')
1609 if (result.valid === true) {
1610 document.getElementById("cardtype").style.color = "#00aa00";
1611 } else {
1612 document.getElementById("cardtype").style.color = "#aa0000";
1614 $('#cardtype').text(r + v);
1617 // Authorize.net
1618 function validateCC() {
1619 var result = $('#cardNumber').validateCreditCard();
1620 var r = (result.card_type == null ? '' : result.card_type.name.toUpperCase())
1621 var v = (result.valid === true ? ' Valid Card Number' : ' Invalid Card Number')
1622 if (result.valid === true) {
1623 document.getElementById("cardtype").style.color = "#00aa00";
1624 } else {
1625 document.getElementById("cardtype").style.color = "#aa0000";
1627 $('#cardtype').text(r + v);
1628 $('#cc_type').val(r);
1629 if (!result.valid) {
1630 alert(ccerr);
1631 return false;
1633 else {
1634 return true;
1638 function sendPaymentDataToAnet(e) {
1639 e.preventDefault();
1640 const authData = {};
1641 authData.clientKey = publicKey;
1642 authData.apiLoginID = apiKey;
1644 const cardData = {};
1645 cardData.cardNumber = document.getElementById("cardNumber").value;
1646 cardData.month = document.getElementById("expMonth").value;
1647 cardData.year = document.getElementById("expYear").value;
1648 cardData.cardCode = document.getElementById("cardCode").value;
1649 cardData.fullName = document.getElementById("cardHolderName").value;
1650 cardData.zip = document.getElementById("cczip").value;
1652 const secureData = {};
1653 secureData.authData = authData;
1654 secureData.cardData = cardData;
1656 Accept.dispatchData(secureData, acceptResponseHandler);
1658 function acceptResponseHandler(response) {
1659 if (response.messages.resultCode === "Error") {
1660 let i = 0;
1661 let errorMsg = '';
1662 while (i < response.messages.message.length) {
1663 errorMsg = errorMsg + response.messages.message[i].code + ": " +response.messages.message[i].text;
1664 console.log(errorMsg);
1665 i = i + 1;
1667 alert(errorMsg);
1668 } else {
1669 paymentFormUpdate(response.opaqueData);
1674 function paymentFormUpdate(opaqueData) {
1675 // this is card tokenized
1676 document.getElementById("dataDescriptor").value = opaqueData.dataDescriptor;
1677 document.getElementById("dataValue").value = opaqueData.dataValue;
1678 let oForm = document.forms['paymentForm'];
1679 oForm.elements['mode'].value = "AuthorizeNet";
1680 // empty out the fields before submitting to server.
1681 document.getElementById("cardNumber").value = "";
1682 document.getElementById("expMonth").value = "";
1683 document.getElementById("expYear").value = "";
1684 document.getElementById("cardCode").value = "";
1686 // Submit payment to server
1687 fetch('./front_payment_cc.php', {
1688 method: 'POST',
1689 body: new FormData(oForm)
1690 }).then((response) => {
1691 if (!response.ok) {
1692 throw Error(response.statusText);
1694 return response.json();
1695 }).then(function(data) {
1696 if(data.status !== 'ok') {
1697 alert(data);
1698 return;
1700 document.getElementById("check_number").value = data.authCode;
1701 alert(chargeMsg + "\n" + 'Auth: ' + data.authCode + ' TransId: ' + data.transId);
1702 $("[name='form_save']").click();
1703 }).catch(function(error) {
1704 alert(error)
1707 </script>
1708 <?php } // end authorize.net ?>
1710 <?php if ($GLOBALS['payment_gateway'] == 'Stripe') { // Begin Include Stripe ?>
1711 <script>
1712 // await validation function.
1713 const waitValidate = async (state = false) => {
1714 return await validate(state);
1716 const stripe = Stripe(publicKey);
1717 const elements = stripe.elements();
1718 const style = {
1719 base: {
1720 color: '#32325d',
1721 lineHeight: '1.2rem',
1722 fontSmoothing: 'antialiased',
1723 '::placeholder': {
1724 color: '#ccc'
1727 invalid: {
1728 color: '#f42c03',
1729 iconColor: '#ff0000'
1733 // Create an instance of the card Element.
1734 const card = elements.create('card', {style: style});
1735 // Add an instance of the card Element into the `card-element` <div>.
1736 card.mount('#card-element');
1737 // Handle real-time validation errors from the card Element.
1738 card.addEventListener('change', function (event) {
1739 let displayError = document.getElementById('card-errors');
1740 if (event.error) {
1741 displayError.textContent = event.error.message;
1742 } else {
1743 displayError.textContent = '';
1746 // Handle form submission.
1747 let form = document.getElementById('stripeSubmit');
1748 form.addEventListener('click', function (event) {
1749 event.preventDefault();
1750 stripe.createToken(card).then(function (result) {
1751 if (result.error) {
1752 // Inform the user if there was an error.
1753 let errorElement = document.getElementById('card-errors');
1754 errorElement.textContent = result.error.message;
1755 } else {
1756 // Send the token to server.
1757 stripeTokenHandler(result.token);
1762 // Submit the form with the token ID.
1763 function stripeTokenHandler(token) {
1764 // below for manual cc audit
1765 const encDates = (() => {
1766 let i = 0, c;
1767 let invDates = '';
1768 $('#table_display tbody tr').each(function () {
1769 if (this.className == 'table-active') {
1770 return false;
1772 if(i > 4) {
1773 return false; // breaks on max 5 encounters
1775 invDates += 'item' + ++i + ': ';
1776 c = 0;
1777 $(this).find('td').each(function() {
1778 if (++c < 3) {
1779 invDates += this.innerText + ' ';
1783 return invDates;
1784 })();
1785 // Insert the token ID into the form so it gets submitted to the server
1786 let oForm = document.forms['payment-form'];
1787 oForm.elements['mode'].value = "Stripe";
1788 oForm.elements['encs'].value = encDates;
1790 let hiddenInput = document.createElement('input');
1791 hiddenInput.setAttribute('type', 'hidden');
1792 hiddenInput.setAttribute('name', 'stripeToken');
1793 hiddenInput.setAttribute('value', token.id);
1794 oForm.appendChild(hiddenInput);
1796 // Submit payment to server
1797 fetch('./front_payment_cc.php', {
1798 method: 'POST',
1799 body: new FormData(oForm)
1800 }).then((response) => {
1801 if (!response.ok) {
1802 throw Error(response.statusText);
1804 return response.json();
1805 }).then(function (data) {
1806 if (data.status !== 'ok') {
1807 alert(data);
1808 return;
1810 document.getElementById("check_number").value = data.transId;
1811 alert(chargeMsg + "\n" + 'Auth: ' + data.authCode + ' TransId: ' + data.transId);
1812 $("[name='form_save']").click();
1813 }).catch(function (error) {
1814 alert(error.message);
1817 // terminal
1818 <?php if (!empty($GLOBALS['cc_stripe_terminal'])) { ?>
1819 // Dialog function for Stripe terminal payment.
1820 // Will post on successful credit payment.
1821 function posDialog() {
1822 // to pass validation check and saving a user having to click.
1823 $("#form_method").val('credit_card');
1824 // let's validate prior to collect payment from terminal
1825 // we'll use an await and validate promise to proceed.
1826 waitValidate(true).then((validateOk) => {
1827 // validation failed for some reason that user is aware
1828 // by alerts or a quite fail we'll handle.
1829 if (validateOk === false || typeof validateOk === 'undefined') {
1830 return false;
1832 // if 2 then need an encounter so credit is no no!
1833 // 1 would be posting against old encounter. will allow.
1834 if (validateOk === 2) {
1835 alert(xl("Must have an encounter to take credit card payment."));
1836 return true;
1838 let total = $("[name='form_paytotal']").val();
1839 let prepay = $("#form_prepayment").val();
1840 // just to be sure. validate() should catch...
1841 if (Number(total) < 1) {
1842 if (Number(prepay) < 1) {
1843 let error = xl("Please enter a payment amount");
1844 alert(error);
1845 return false;
1847 total = prepay;
1849 $("#payTotal").text(total);
1850 $("#paymentAmount").val(total);
1851 let title = xl("POS Payment");
1852 let url = "./front_payment_terminal.php?total=" + encodeURIComponent(total);
1853 dlgopen(url, 'terminal', 'modal-md', '550', '', title, {
1854 buttons: [
1855 {text: xl('Cancel'), close: false, id: "closeBtn", style: 'secondary btn-cancel'}
1860 <?php } ?>
1861 </script>
1862 <?php } ?>
1864 <?php
1865 if ($GLOBALS['payment_gateway'] == 'Sphere') {
1866 echo (new SpherePayment('clinic', $pid))->renderSphereJs();
1870 </div><!--end of container div of accept payment i.e the form-->
1871 <?php
1872 $oemr_ui->oeBelowContainerDiv();
1873 } // forms else close
1875 </body>
1876 <?php $GLOBALS['kernel']->getEventDispatcher()->dispatch(new PostFrontPayment(), PostFrontPayment::ACTION_POST_FRONT_PAYMENT, 10); ?>
1877 </html>