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")]);
44 if (!AclMain
::aclCheckCore('acct', 'bill', '', 'write')) {
45 if (!empty($_POST['form_save'])) {
46 $pageTitle = xl("Receipt for Payment");
48 $pageTitle = xl("Record Payment");
50 echo (new TwigContainer(null, $GLOBALS['kernel']))->getTwig()->render('core/unauthorized.html.twig', ['pageTitle' => $pageTitle]);
55 $pid = (!empty($_REQUEST['hidden_patient_code']) && ($_REQUEST['hidden_patient_code'] > 0)) ?
$_REQUEST['hidden_patient_code'] : $pid;
57 $facilityService = new FacilityService();
63 <?php Header
::setupHeader(['opener']);?
>
64 <?php
if ($GLOBALS['payment_gateway'] == 'Stripe') { ?
>
65 <script src
="https://js.stripe.com/v3/"></script
>
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
73 <script src
=<?php
echo $script; ?
> charset
="utf-8"></script
>
77 // Display a row of data for an encounter.
80 function echoLine($iname, $date, $charges, $ptpaid, $inspaid, $duept, $encounter = 0, $copay = 0, $patcopay = 0)
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";
103 // We use this to put dashes, colons, etc. back into a timestamp.
105 function decorateString($fmt, $str)
109 $fc = substr($fmt, 0, 1);
110 $fmt = substr($fmt, 1);
112 $res .= substr($str, 0, 1);
113 $str = substr($str, 1);
122 // Compute taxes from a tax rate string and a possibly taxable amount.
124 function calcTaxes($row, $amount)
127 if (empty($row['taxrates'])) {
131 $arates = explode(':', $row['taxrates']);
132 if (empty($arates)) {
136 foreach ($arates as $value) {
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";
148 $tax = sprintf("%01.2f", $amount * $trow['option_value']);
149 // echo "<!-- Rate = '$value', amount = '$amount', tax = '$tax' -->\n";
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
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 " .
197 ", check_date = now() , deposit_date = now() " .
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) {
215 if ($_REQUEST['radio_type_of_payment'] == 'invoice_balance') {
217 $enc = calendar_arrived($form_pid);
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'];
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)
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)
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') {
266 "update form_encounter set last_level_closed=? where encounter=? and pid=? ",
267 array(4, $enc, $form_pid)
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 " .
283 ", check_date = now() , deposit_date = now() " .
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;
340 if (round($Remainder, 2) != 0 && $amount != 0) {
341 if ($amount - $Remainder >= 0) {
342 $insert_value = $Remainder;
343 $amount = $amount - $Remainder;
345 $insert_value = $amount;
350 $sequence_no = sqlQuery("SELECT IFNULL(MAX(sequence_no),0) + 1 AS increment FROM ar_activity WHERE pid = ? AND encounter = ?", array($form_pid, $enc));
352 "insert into ar_activity set " .
355 ", sequence_no = ?" .
360 ", post_time = now() " .
365 ", account_code = 'PP'",
366 array($form_pid, $enc, $sequence_no['increment'], $Codetype, $Code, $Modifier, 0, $_SESSION['authUserID'], $payment_id, $insert_value, 0)
371 if ($amount != 0) {//if any excess is there.
373 $sequence_no = sqlQuery("SELECT IFNULL(MAX(sequence_no),0) + 1 AS increment FROM ar_activity WHERE pid = ? AND encounter = ?", array($form_pid, $enc));
375 "insert into ar_activity set " .
378 ", sequence_no = ?" .
383 ", post_time = now() " .
388 ", account_code = 'PP'",
389 array($form_pid, $enc, $sequence_no['increment'], $Codetype, $Code, $Modifier, 0, $_SESSION['authUserID'], $payment_id, $amount, 0)
394 //--------------------------------------------------------------------------------------------------------------------
396 }//if ($amount = 0 + $payment)
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']);
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(); ?
>
446 <?php
require($GLOBALS['srcdir'] . "/restoreSession.php"); ?
>
449 var win
= top
.printLogSetup ? top
: opener
.top
;
450 win
.printLogSetup(document
.getElementById('printbutton'));
453 function closeHow(e
) {
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);
479 // Called by the deleteme.php window on a successful delete.
480 function imdeleted() {
482 dlgclose(); // we're in reports/leftnav and callback reloads.
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();
505 grid
-template
-columns
: 50% auto
;
506 grid
-template
-areas
: "section-2 section-1";
509 grid
-area
: section
-1;
516 grid
-area
: section
-2;
520 border
: 1px solid black
; text
-align
: left
;
523 border
-collapse
: collapse
; width
: 100%
;
534 table
.mini_table
>tbody
>tr
>th
{
535 background
-color
: var(--secondary
);
538 body
>table
.mini_table
>tbody
>tr
>td
{
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
);
548 background
-color
: var(--secondary
);
551 -webkit
-print-color
-adjust
: exact
;
554 background
-color
: var(--secondary
);
556 -webkit
-print-color
-adjust
: exact
!important
; }
559 -webkit
-print-color
-adjust
: exact
!important
;
563 background
-color
: var(--secondary
)!important
;
564 -webkit
-print-color
-adjust
: exact
;
567 background
-color
: var(--secondary
) !important
;
568 -webkit
-print-color
-adjust
: exact
;
574 <div
class="container mt-3">
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
/>
590 <?php
echo xlt('How Paid'); ?
>:
591 <?php
echo generate_display_field(array('data_type' => '1', 'list_id' => 'payment_method'), $payrow['method']); ?
>
594 <?php
echo xlt('Check or Reference Number'); ?
>:
595 <?php
echo text($payrow['source']); ?
>
599 if ($_REQUEST['radio_type_of_payment'] == 'pre_payment') {
600 echo xlt('Pre-payment Amount');
602 echo xlt('Amount for Past Balance');
605 <?php
echo text(oeFormatMoney($payrow['amount2'])); ?
>
608 <?php
echo xlt('Amount for This Visit'); ?
>:
609 <?php
echo text(oeFormatMoney($payrow['amount1'])); ?
>
612 <?php
echo xlt('Received By'); ?
>:
613 <?php
echo text($payrow['user']); ?
>
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">
622 <table
class="mini_table text-center">
624 <th
><?php
echo xlt('Invoice No.'); ?
></th
>
625 <th
><?php
echo xlt('Date'); ?
></th
>
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
>
635 <div
class="table-responsive">
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
>
645 <!-- Omega Itemized Invoice
-->
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 " .
653 array($pid,$encounter)
655 while ($each_row = sqlFetchArray($row_data)) {
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
>
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)) {
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
>
685 <td style
="border-right-color:white !important;"></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
>
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'); ?
>
700 $todaysenc = todaysEncounterIf($pid);
701 if ($todaysenc && $todaysenc != $encounter) {
702 echo " <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'); ?
>
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'); ?
>
727 // End of receipt printing logic.
731 // Here we display the form for data entry.
734 <title
><?php
echo xlt('Record Payment'); ?
></title
>
740 background
-color
: #FBFDD0;
741 border
: 1px solid
#ccc;
745 <!--Removed standard dependencies
12/29/17 as not needed any longer since moved to a tab
/frame not popup
.-->
747 <!-- supporting javascript code
-->
751 <?php
include_once("{$GLOBALS['srcdir']}/ajax/payment_ajax_jav.inc.php"); ?
>
753 document
.onclick
=HideTheAjaxDivs
;
756 <?php Header
::setupAssets('topdialog'); ?
>
758 <script src
="<?php echo $GLOBALS['assets_static_relative']; ?>/jquery-creditcardvalidator/jquery.creditCardValidator.js"></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'])); ?
>;
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"); ?
>;
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
) {
787 top
.activateTabByName('pat', true);
788 top
.tabCloseByName(window
.name
);
790 function calctotal() {
791 var f
= document
.forms
[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);
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)';
822 document
.getElementById('paying_' + i
).style
.background
= 'var(--white)';
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;
838 document
.getElementById('check_number').disabled
= true;
842 function validate(notSubmit
= false) {
843 var f
= document
.forms
[0];
845 top
.restoreSession();
847 // prevent an empty form submission
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) {
857 if (ename
.indexOf('form_upay[') === 0 || ename
.indexOf('form_bpay[') === 0) {
858 if (Number(f
.elements
[i
].value
) !== 0) flgempty
= false;
862 alert(<?php
echo xlj('A Payment is Required!. Please input a payment line item entry.'); ?
>);
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();
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.'); ?
>);
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.'); ?
>)) {
900 if (document
.getElementById('radio_type_of_payment1').checked
== true){//CO-PAY
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?'); ?
>)) {
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.'); ?
>);
936 if (confirm(<?php
echo xlj('Would you like to save?'); ?
>)) {
946 function cursor_pointer() { //Point the cursor to the latest encounter(Today)
947 var f
= document
.forms
[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) {
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";
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";
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
= "";
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() {
1092 make_it_hide_enc_pay();
1093 document
.getElementById('radio_type_of_payment_self1').checked
= true;
1097 function make_insurance() {
1101 document
.getElementById('radio_type_of_payment1').checked
= true;
1106 @media
(min
-width
: 992px
) {
1108 width
: 1000px
!Important
;
1112 <title
><?php
echo xlt('Record Payment'); ?
></title
>
1113 <?php
$NameNew = $patdata['fname'] . " " . $patdata['lname'] . " " . $patdata['mname']; ?
>
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);
1130 <div
class="container mt-3"><!--begin container div
for form
-->
1132 <div
class="col-sm-12">
1133 <?php
echo $oemr_ui->pageHeading() . "\r\n"; ?
>
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) ?>' />
1142 <legend
><?php
echo xlt('Payment'); ?
></legend
>
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
>
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")'>
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') {
1165 echo "<option value='" . attr($brow1112['option_id']) . "'" .
1166 ($brow1112['is_default'] ?
' selected' : '') . ">" . text(xl_list_label($brow1112['title'])) . "</option>";
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
'] ?? ''); ?>' />
1176 <div
class="col-12 oe-custom-line">
1177 <label
class="control-label" for="form_discount"><?php
echo xla('Patient Coverage'); ?
>:</label
>
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'); ?
>
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'); ?
>
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'); ?
>
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'); ?
>
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
/>
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'); ?
>
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
='' />
1214 <legend
><?php
echo xlt('Collect For'); ?
></legend
>
1215 <div
class="table-responsive">
1216 <table
class="table" id
="table_display">
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
>
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'],
1259 if ($brow['code_type'] === 'COPAY') {
1260 //$encs[$key]['payments'] -= $brow['fee'];
1262 $encs[$key]['charges'] +
= $brow['fee'];
1264 $sql_array = array();
1265 $query = "SELECT taxrates FROM `codes` WHERE " .
1266 "code_type = ? 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']);
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'],
1305 $encs[$key]['charges'] +
= $drow['fee'];
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
);
1314 //Bringing on top the Today always
1315 foreach ($encs as $key => $value) {
1316 $dispdate = $value['date'];
1317 if (strcmp($dispdate, $today) == 0 && !$gottoday) {
1323 // If no billing was entered yet for today, then generate a line for
1324 // entering today's co-pay.
1327 echoLine("form_upay[0]", date("Y-m-d"), 0, 0, 0, 0 /*$duept*/);//No encounter yet defined.
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");
1338 //------------------------------------------------------------------------------------
1339 $inscopay = BillingUtilities
::getCopay($pid, $dispdate);
1340 $patcopay = BillingUtilities
::getPatientCopay($pid, $enc);
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' ",
1350 $dpayment = $drow['payments'];
1351 $dadjustment = $drow['adjustments'];
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' ",
1361 $dpayment_pat = $drow['payments'];
1363 //------------------------------------------------------------------------------------
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 //------------------------------------------------------------------------------------
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'];
1387 ($dpayment +
$dadjustment),
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
/>
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');
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>';
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
='' />
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
>
1448 <div
class="modal-body">
1449 <?php
if ($GLOBALS['payment_gateway'] == 'AuthorizeNet') { ?
>
1450 <form id
='paymentForm' method
='post' action
='./front_payment_cc.php'>
1452 <div
class="form-group">
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"
1458 title
="<?php echo xla('Fill your first and last name'); ?>"
1459 value
="<?php echo attr($patdata['fname']) . ' ' . attr($patdata['lname']) ?>" />
1462 <div
class="form-group">
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
="" /> 
; 
;
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
>
1478 <div
class="form-group">
1480 class="control-label"><?php
echo xlt('Card Expiry Date and Card Holders Zip'); ?
></label
>
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
>
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
>
1514 <div
class="col-md-4">
1515 <input name
="zip" id
="cczip" type
="text" class="form-control"
1517 title
="<?php echo xla('Enter Your Zip'); ?>"
1518 placeholder
="<?php echo xla('Card Holder Zip'); ?>"
1519 value
="<?php echo attr($patdata['postal_code']) ?>" />
1523 <div
class="form-group">
1524 <label
class="control-label"><?php
echo xlt('Card CVV'); ?
></label
>
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'); ?>"
1532 <div
class="col-md-3">
1533 <img src
='./../../portal/images/img_cvc.png' style
='height: 40px; width: auto'>
1535 <div
class="col-md-6">
1536 <h4 style
="display: inline-block;"><?php
echo xlt('Payment Amount'); ?
>: 
;
1537 <strong
><span id
="payTotal"></span
></strong
></h4
>
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" />
1551 if ($GLOBALS['payment_gateway'] == 'Stripe') { ?
>
1552 <form
class="form" method
="post" name
="payment-form" id
="payment-form">
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"
1559 title
="<?php echo xla('Fill your first and last name'); ?>"
1560 value
="<?php echo attr($patdata['fname']) . ' ' . attr($patdata['lname']) ?>" />
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
>
1567 <div
class="form-row">
1568 <?php
echo xlt('Payment Amount'); ?
>: 
;<span id
="payTotal"></span
>
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
='' />
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
>
1584 if ($GLOBALS['payment_gateway'] == 'AuthorizeNet') { ?
>
1585 <button id
="payAurhorizeNet" class="btn btn-primary"
1586 onclick
="sendPaymentDataToAnet(event)"><?php
echo xlt('Pay Now'); ?
></button
>
1588 if ($GLOBALS['payment_gateway'] == 'Stripe') { ?
>
1589 <button id
="stripeSubmit" class="btn btn-primary"><?php
echo xlt('Pay Now'); ?
></button
>
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.
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";
1612 document
.getElementById("cardtype").style
.color
= "#aa0000";
1614 $
('#cardtype').text(r + v
);
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";
1625 document
.getElementById("cardtype").style
.color
= "#aa0000";
1627 $
('#cardtype').text(r + v
);
1628 $
('#cc_type').val(r
);
1629 if (!result
.valid
) {
1638 function sendPaymentDataToAnet(e
) {
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") {
1662 while (i
< response
.messages
.message
.length
) {
1663 errorMsg
= errorMsg + response
.messages
.message
[i
].code +
": " +response
.messages
.message
[i
].text
;
1664 console
.log(errorMsg
);
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', {
1689 body
: new FormData(oForm
)
1690 }).then((response
) => {
1692 throw Error(response
.statusText
);
1694 return response
.json();
1695 }).then(function(data
) {
1696 if(data
.status
!== 'ok') {
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
) {
1708 <?php
} // end authorize.net ?>
1710 <?php
if ($GLOBALS['payment_gateway'] == 'Stripe') { // Begin Include Stripe ?>
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();
1721 lineHeight
: '1.2rem',
1722 fontSmoothing
: 'antialiased',
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');
1741 displayError
.textContent
= event
.error
.message
;
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
) {
1752 // Inform the user if there was an error.
1753 let errorElement
= document
.getElementById('card-errors');
1754 errorElement
.textContent
= result
.error
.message
;
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
= (() => {
1768 $
('#table_display tbody tr').each(function () {
1769 if (this
.className
== 'table-active') {
1773 return false; // breaks on max 5 encounters
1775 invDates +
= 'item' + ++i +
': ';
1777 $
(this
).find('td').each(function() {
1779 invDates +
= this
.innerText +
' ';
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', {
1799 body
: new FormData(oForm
)
1800 }).then((response
) => {
1802 throw Error(response
.statusText
);
1804 return response
.json();
1805 }).then(function (data
) {
1806 if (data
.status
!== 'ok') {
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
);
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') {
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."));
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");
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
, {
1855 {text
: xl('Cancel'), close
: false, id
: "closeBtn", style
: 'secondary btn-cancel'}
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
-->
1872 $oemr_ui->oeBelowContainerDiv();
1873 } // forms else close
1876 <?php
$GLOBALS['kernel']->getEventDispatcher()->dispatch(new PostFrontPayment(), PostFrontPayment
::ACTION_POST_FRONT_PAYMENT
, 10); ?
>