4 * This screen handles the cash/cheque entry and its distribution to various charges.
6 * The functions of this class support the billing process like the script billing_process.php.
9 * @link http://www.open-emr.org
10 * @author Eldho Chacko <eldho@zhservices.com>
11 * @author Paul Simon K <paul@zhservices.com>
12 * @author Stephen Waite <stephen.waite@cmsvt.com>
13 * @author Brady Miller <brady.g.miller@gmail.com>
14 * @copyright Copyright (c) Z&H Consultancy Services Private Limited <sam@zhservices.com>
15 * @copyright Copyright (C) 2018 Stephen Waite <stephen.waite@cmsvt.com>
16 * @copyright Copyright (c) 2019 Brady Miller <brady.g.miller@gmail.com>
17 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
20 require_once("../globals.php");
21 require_once("../../custom/code_types.inc.php");
22 require_once("$srcdir/patient.inc.php");
23 require_once("$srcdir/options.inc.php");
24 require_once("$srcdir/payment.inc.php");
26 use OpenEMR\Billing\ParseERA
;
27 use OpenEMR\Common\Acl\AclMain
;
28 use OpenEMR\Common\Twig\TwigContainer
;
29 use OpenEMR\Core\Header
;
30 use OpenEMR\OeUI\OemrUI
;
32 if (!AclMain
::aclCheckCore('acct', 'bill', '', 'write') && !AclMain
::aclCheckCore('acct', 'eob', '', 'write')) {
33 echo (new TwigContainer(null, $GLOBALS['kernel']))->getTwig()->render('core/unauthorized.html.twig', ['pageTitle' => xl("New Payment")]);
37 //===============================================================================
38 $screen = 'new_payment';
39 //===============================================================================
41 $mode = isset($_POST['mode']) ?
$_POST['mode'] : '';
42 $payment_id = isset($_REQUEST['payment_id']) ?
$_REQUEST['payment_id'] +
0 : 0;
43 $request_payment_id = $payment_id ;
44 $hidden_patient_code = isset($_REQUEST['hidden_patient_code']) ?
$_REQUEST['hidden_patient_code'] : '';
45 $default_search_patient = isset($_POST['default_search_patient']) ?
$_POST['default_search_patient'] : '';
46 $hidden_type_code = isset($_REQUEST['hidden_type_code']) ?
$_REQUEST['hidden_type_code'] : '';
47 //===============================================================================
48 //ar_session addition code
49 //===============================================================================
51 if ($mode == "new_payment" ||
$mode == "distribute") {
52 if (trim($_POST['type_name']) == 'insurance') {
53 $QueryPart = "payer_id = '" . add_escape_custom($hidden_type_code) . "', patient_id = '0" ;
54 } elseif (trim($_POST['type_name']) == 'patient') {
55 $QueryPart = "payer_id = '0', patient_id = '" . add_escape_custom($hidden_type_code);
57 $user_id = $_SESSION['authUserID'];
59 $modified_time = date('Y-m-d H:i:s');
60 $check_date = DateToYYYYMMDD(formData('check_date'));
61 $deposit_date = DateToYYYYMMDD(formData('deposit_date'));
62 $post_to_date = DateToYYYYMMDD(formData('post_to_date'));
63 if ($post_to_date == '') {
64 $post_to_date = date('Y-m-d');
66 if ($_POST['deposit_date'] == '') {
67 $deposit_date = $post_to_date;
69 $payment_id = sqlInsert("insert into ar_session set " .
71 "', user_id = '" . trim(add_escape_custom($user_id)) .
72 "', closed = '" . trim(add_escape_custom($closed)) .
73 "', reference = '" . trim(formData('check_number')) .
74 "', check_date = '" . trim(add_escape_custom($check_date)) .
75 "', deposit_date = '" . trim(add_escape_custom($deposit_date)) .
76 "', pay_total = '" . trim(formData('payment_amount')) .
77 "', modified_time = '" . trim(add_escape_custom($modified_time)) .
78 "', payment_type = '" . trim(formData('type_name')) .
79 "', description = '" . trim(formData('description')) .
80 "', adjustment_code = '" . trim(formData('adjustment_code')) .
81 "', post_to_date = '" . trim(add_escape_custom($post_to_date)) .
82 "', payment_method = '" . trim(formData('payment_method')) .
86 //===============================================================================
87 //ar_activity addition code
88 //===============================================================================
89 if ($mode == "PostPayments" ||
$mode == "FinishPayments") {
90 $user_id = $_SESSION['authUserID'];
91 $created_time = date('Y-m-d H:i:s');
92 for ($CountRow = 1;; $CountRow++
) {
93 if (isset($_POST["HiddenEncounter$CountRow"])) {
94 DistributionInsert($CountRow, $created_time, $user_id);
99 if ($_REQUEST['global_amount'] == 'yes') {
100 sqlStatement("update ar_session set global_amount=? where session_id =?", [(isset($_POST["HidUnappliedAmount"]) ?
trim($_POST["HidUnappliedAmount"]) : ''), $payment_id]);
102 if ($mode == "FinishPayments") {
103 // @todo This is not useful. Gonna let fall through to form init.
104 header("Location: edit_payment.php?payment_id=" . urlencode($payment_id) . "&ParentPage=new_payment");
108 $_POST['mode'] = $mode;
111 //==============================================================================
112 //===============================================================================
113 $payment_id = $payment_id * 1 > 0 ?
$payment_id +
0 : $request_payment_id +
0;
114 //===============================================================================
116 //==============================================================================
117 //===============================================================================
122 <?php Header
::setupHeader(['common', 'datetime-picker']);?
>
128 <?php
include_once("{$GLOBALS['srcdir']}/payment_jav.inc.php"); ?
>
129 <?php
include_once("{$GLOBALS['srcdir']}/ajax/payment_ajax_jav.inc.php"); ?
>
131 function CancelDistribute() {
132 // Used in the cancel button.Helpful while cancelling the distribution.
133 if (confirm(<?php
echo xlj('Would you like to Cancel Distribution for this Patient?') ?
>)) {
134 document
.getElementById('hidden_patient_code').value
='';
135 document
.getElementById('mode').value
='search';
136 top
.restoreSession();
137 document
.forms
[0].submit();
143 function PostPayments() {
144 // Used in saving the allocation
145 if (CompletlyBlank()) {
146 // Checks whether any of the allocation row is filled.
147 alert(<?php
echo xlj('Fill the Row.'); ?
>);
150 if (!CheckPayingEntityAndDistributionPostFor()) {
151 // Ensures that Insurance payment is distributed under Ins1,Ins2,Ins3 and Patient paymentat under Pat.
154 PostValue
= CheckUnappliedAmount();
155 // Decides TdUnappliedAmount >0, or <0 or =0
156 if (PostValue
== 1) {
157 alert(<?php
echo xlj('Cannot Post Payments.Undistributed is Negative.'); ?
>);
160 if (confirm(<?php
echo xlj('Would you like to Post Payments?'); ?
>)) {
161 document
.getElementById('mode').value
='PostPayments';
162 top
.restoreSession();
163 document
.forms
[0].submit();
169 function FinishPayments() {
170 // Used in finishig the allocation.Usually done when the amount gets reduced to zero.
171 // After this is pressed a confirmation screen comes,where you can edit if needed.
172 // Checks whether any of the allocation row is filled.
173 if (CompletlyBlank()) {
174 alert(<?php
echo xlj('Fill the Row.'); ?
>);
177 // Ensures that Insurance payment is distributed under Ins1,Ins2,Ins3 and Patient paymentat under Pat.
178 if (!CheckPayingEntityAndDistributionPostFor()){
181 PostValue
= CheckUnappliedAmount();
182 // Decides TdUnappliedAmount >0, or <0 or =0
183 if (PostValue
== 1) {
184 alert(<?php
echo xlj('Cannot Post Payments.Undistributed is Negative.'); ?
>);
188 if (PostValue
== 2) {
189 if (confirm(<?php
echo xlj('Would you like to Post and Finish Payments?'); ?
>)) {
190 UnappliedAmount
= document
.getElementById('TdUnappliedAmount').innerHTML
*1;
191 if(confirm(<?php
echo xlj('Undistributed is'); ?
> +
' ' + UnappliedAmount +
'.' +
'\n' +
<?php
echo xlj('Would you like the balance amount to apply to Global Account?'); ?
>)) {
192 document
.getElementById('mode').value
='FinishPayments';
193 document
.getElementById('global_amount').value
='yes';
194 top
.restoreSession();
195 document
.forms
[0].submit();
197 document
.getElementById('mode').value
='FinishPayments';
198 top
.restoreSession();
199 document
.forms
[0].submit();
205 if (confirm(<?php
echo xlj('Would you like to Post and Finish Payments?'); ?
>)) {
206 document
.getElementById('mode').value
='FinishPayments';
207 top
.restoreSession();
208 document
.forms
[0].submit();
215 function CompletlyBlank() {
216 // Checks whether any of the allocation row is filled.
217 for (RowCount
= 1;;RowCount++
) {
218 if(!document
.getElementById('Payment'+RowCount
)) {
221 if(document
.getElementById('Allowed'+RowCount
).value
==''
222 && document
.getElementById('Payment'+RowCount
).value
==''
223 && document
.getElementById('AdjAmount'+RowCount
).value
==''
224 && document
.getElementById('Deductible'+RowCount
).value
==''
225 && document
.getElementById('Takeback'+RowCount
).value
==''
226 && document
.getElementById('FollowUp'+RowCount
).checked
==false) {
236 function OnloadAction() {
237 // Displays message after saving to master table.
238 after_value
= document
.getElementById("after_value").value
;
239 payment_id
= document
.getElementById('payment_id').value
;
240 if (after_value
=== 'distribute') {
242 } else if (after_value
=='new_payment') {
243 if (document
.getElementById('TablePatientPortion')) {
244 document
.getElementById('TablePatientPortion').style
.display
= 'none';
246 if (confirm(<?php
echo xlj('Successfully Saved.Would you like to Allocate?'); ?
>)) {
247 if (document
.getElementById('TablePatientPortion')) {
248 document
.getElementById('TablePatientPortion').style
.display
= '';
249 document
.getElementById('TablePatientPortion').scrollIntoView(false);
255 function ResetForm() {
256 // Resets form used in the 'Cancel Changes' button in the master screen.
257 document
.forms
[0].reset();
258 document
.getElementById('TdUnappliedAmount').innerHTML
= '0.00';
259 document
.getElementById('div_insurance_or_patient').innerHTML
= ' ';
260 CheckVisible('yes'); // Payment Method is made 'Check Payment' and the Check box is made visible.
261 PayingEntityAction(); // Paying Entity is made 'insurance' and Payment Category is 'Insurance Payment'
264 function FillUnappliedAmount(){
265 // Filling the amount
266 document
.getElementById('TdUnappliedAmount').innerHTML
= document
.getElementById('payment_amount').value
;
270 $
('.datepicker').datetimepicker({
271 <?php
$datetimepicker_timepicker = false; ?
>
272 <?php
$datetimepicker_showseconds = false; ?
>
273 <?php
$datetimepicker_formatInput = true; ?
>
274 <?php
require($GLOBALS['srcdir'] . '/js/xl/jquery-datetimepicker-2-5-4.js.php'); ?
>
275 <?php
// can add any additional javascript settings to datetimepicker here; need to prepend first setting with a comma ?>
278 document
.getElementById('payment_amount').addEventListener('focus', (event
) => {
279 event
.target
.select();
283 document
.onclick
= HideTheAjaxDivs
;
293 <title
><?php
echo xlt('New Payment'); ?
></title
>
295 $arrOeUiSettings = array(
296 'heading_title' => xl('Payments'),
297 'include_patient_name' => false,// use only in appropriate pages
298 'expandable' => true,
299 'expandable_files' => array("new_payment_xpd", "search_payments_xpd", "era_payments_xpd"),//all file names need suffix _xpd
300 'action' => "",//conceal, reveal, search, reset, link or back
301 'action_title' => "",
302 'action_href' => "",//only for actions - reset, link or back
303 'show_help_icon' => false,
304 'help_file_name' => ""
306 $oemr_ui = new OemrUI($arrOeUiSettings);
309 <body onload
="OnloadAction()">
310 <div id
="container_div" class="<?php echo attr($oemr_ui->oeContainer()); ?> mt-3">
312 <div
class="col-sm-12">
313 <?php
echo $oemr_ui->pageHeading() . "\r\n"; ?
>
316 <nav
class="navbar navbar-nav navbar-expand-md navbar-light text-body bg-light mb-4 p-2">
317 <button
class="navbar-toggler icon-bar" data
-target
="#myNavbar" data
-toggle
="collapse" type
="button"> <span
class="navbar-toggler-icon"></span
></button
>
318 <div
class="collapse navbar-collapse" id
="myNavbar">
319 <ul
class="navbar-nav mr-auto">
320 <li
class="nav-item">
321 <a
class="nav-link active font-weight-bold" href
='new_payment.php'><?php
echo xlt('New Payment'); ?
></a
>
323 <li
class="nav-item">
324 <a
class="nav-link font-weight-bold" href
='search_payments.php'><?php
echo xlt('Search Payment'); ?
></a
>
326 <li
class="nav-item">
327 <a
class="nav-link font-weight-bold" href
='era_payments.php'><?php
echo xlt('ERA Posting'); ?
></a
>
332 <div
class="col-sm-12">
333 <form action
="new_payment.php" id
="new_payment" method
='post' name
='new_payment' onsubmit
="
335 if ($payment_id * 1 == 0) {
336 echo 'top.restoreSession();';
338 echo 'return false;';
339 }?>" style
="display:inline">
342 <div
class="jumbotron py-4">
344 require_once("payment_master.inc.php"); //Check/cash details are entered here.
349 if ($payment_id * 1 > 0) {
352 if ($PaymentType == 'patient' && $default_search_patient != "default_search_patient") {
353 $default_search_patient = "default_search_patient";
354 $_POST['default_search_patient'] = $default_search_patient;
355 $hidden_patient_code = $TypeCode;
356 $_REQUEST['hidden_patient_code'] = $hidden_patient_code;
357 $_REQUEST['RadioPaid'] = 'Show_Paid';
359 require_once("payment_pat_sel.inc.php"); //Patient ajax section and listing of charges.
362 if ($CountIndexBelow > 0) {
364 <?php
//can change position of buttons by creating a class 'position-override' and adding rule text-align:center or right as the case may be in individual stylesheets ?>
366 <div
class="form-group clearfix">
367 <div
class="col-sm-12 text-left position-override">
369 <div
class="btn-group" role
="group">
370 <button
class="btn btn-primary btn-save" href
="#" onclick
="return PostPayments();"><?php
echo xlt('Post Payments');?
></button
>
371 <button
class="btn btn-primary btn-save" href
="#" onclick
="return FinishPayments();"><?php
echo xlt('Finish Payments');?
></button
>
372 <button
class="btn btn-secondary btn-cancel" href
="#" onclick
="CancelDistribute()"><?php
echo xlt('Cancel');?
></button
>
377 }//if($CountIndexBelow>0)
383 <input id
="hidden_patient_code" name
="hidden_patient_code" type
="hidden" value
="<?php echo attr($hidden_patient_code);?>" />
384 <input id
='mode' name
='mode' type
='hidden' value
='' />
385 <input id
='default_search_patient' name
='default_search_patient' type
='hidden' value
='<?php echo attr($default_search_patient); ?>' />
386 <input id
='ajax_mode' name
='ajax_mode' type
='hidden' value
='' />
387 <input id
="after_value" name
="after_value" type
="hidden" value
="<?php echo attr($mode);?>" />
388 <input id
="payment_id" name
="payment_id" type
="hidden" value
="<?php echo attr($payment_id);?>" />
389 <input id
="hidden_type_code" name
="hidden_type_code" type
="hidden" value
="<?php echo attr($hidden_type_code);?>" />
390 <input id
='global_amount' name
='global_amount' type
='hidden' value
='' />
393 <!-- end of row div
-->
394 <div
class="clearfix">.</div
>
395 </div
><!-- end of container div
-->
396 <?php
$oemr_ui->oeBelowContainerDiv();?
>
397 <script src
= '<?php echo $webroot;?>/library/js/oeUI/oeFileUploads.js'></script
>
400 $
('select').removeClass('class1 text');