4 * The functions of this class support the billing process like the script billing_process.php.
7 * @link http://www.open-emr.org
8 * @author Eldho Chacko <eldho@zhservices.com>
9 * @author Paul Simon K <paul@zhservices.com>
10 * @author Stephen Waite <stephen.waite@cmsvt.com>
11 * @author Brady Miller <brady.g.miller@gmail.com>
12 * @copyright Copyright (c) Z&H Consultancy Services Private Limited <sam@zhservices.com>
13 * @copyright Copyright (C) 2018 Stephen Waite <stephen.waite@cmsvt.com>
14 * @copyright Copyright (c) 2019 Brady Miller <brady.g.miller@gmail.com>
15 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
19 require_once("../globals.php");
20 require_once("$srcdir/patient.inc.php");
21 require_once($GLOBALS['OE_SITE_DIR'] . "/statement.inc.php");
22 require_once("$srcdir/options.inc.php");
24 use OpenEMR\Billing\ParseERA
;
25 use OpenEMR\Billing\SLEOB
;
26 use OpenEMR\Common\Acl\AclMain
;
27 use OpenEMR\Common\Csrf\CsrfUtils
;
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("ERA Posting")]);
37 $hidden_type_code = isset($_POST['hidden_type_code']) ?
$_POST['hidden_type_code'] : '';
38 $check_date = isset($_POST['check_date']) ?
$_POST['check_date'] : '';
39 $post_to_date = isset($_POST['post_to_date']) ?
$_POST['post_to_date'] : '';
40 $deposit_date = isset($_POST['deposit_date']) ?
$_POST['deposit_date'] : '';
41 $type_code = isset($_POST['type_code']) ?
$_POST['type_code'] : '';
43 //===============================================================================
44 // This is called back by ParseERA::parseERA() if we are processing X12 835's.
50 function era_callback(&$out)
52 global $where, $eracount, $eraname;
54 $eraname = $out['gs_date'] . '_' . ltrim($out['isa_control_number'], '0') .
55 '_' . ltrim($out['payer_id'], '0');
56 list($pid, $encounter, $invnumber) = SLEOB
::slInvoiceNumber($out);
57 if ($pid && $encounter) {
61 $where .= "( f.pid = '" . add_escape_custom($pid) . "' AND f.encounter = '" . add_escape_custom($encounter) . "' )";
64 //===============================================================================
65 // Handle X12 835 file upload.
66 if (!empty($_FILES['form_erafile']['size'])) {
67 if (!CsrfUtils
::verifyCsrfToken($_POST["csrf_token_form"])) {
68 CsrfUtils
::csrfNotVerified();
71 $tmp_name = $_FILES['form_erafile']['tmp_name'];
72 // Handle .zip extension if present. Probably won't work on Windows.
73 if (strtolower(substr($_FILES['form_erafile']['name'], -4)) == '.zip') {
74 rename($tmp_name, "$tmp_name.zip");
75 exec("unzip -p " . escapeshellarg($tmp_name . ".zip") . " > " . escapeshellarg($tmp_name));
76 unlink("$tmp_name.zip");
78 $alertmsg .= ParseERA
::parseERA($tmp_name, 'era_callback');
79 $erafullname = $GLOBALS['OE_SITE_DIR'] . "/documents/era/$eraname.edi";
80 if (is_file($erafullname)) {
81 $alertmsg .= xl("Warning") . ': ' . xl("Set") . ' ' . $eraname . ' ' . xl("was already uploaded") . ' ';
82 if (is_file($GLOBALS['OE_SITE_DIR'] . "/documents/era/$eraname.html")) {
84 $alertmsg .= xl("and processed.") . ' ';
86 $alertmsg .= xl("but not yet processed.") . ' ';
89 rename($tmp_name, $erafullname);
91 //===============================================================================
93 //===============================================================================
98 <?php Header
::setupHeader(['datetime-picker', 'common']);?
>
99 <?php
require_once("{$GLOBALS['srcdir']}/ajax/payment_ajax_jav.inc.php"); ?
>
103 if(document
.getElementById('uploadedfile').value
=='')
105 alert(<?php
echo xlj('Please Choose a file');?
>);
108 if(document
.getElementById('hidden_type_code').value
=='')
110 alert(<?php
echo xlj('Select Insurance, by typing'); ?
>);
111 document
.getElementById('type_code').focus();
114 if(document
.getElementById('hidden_type_code').value
!=document
.getElementById('div_insurance_or_patient').innerHTML
)
116 alert(<?php
echo xlj('Take Insurance, from Drop Down'); ?
>);
117 document
.getElementById('type_code').focus();
120 top
.restoreSession();
121 document
.forms
[0].submit();
123 function OnloadAction()
124 {//Displays message after upload action,and popups the details.
125 after_value
=document
.getElementById('after_value').value
;
131 if (!empty($_FILES['form_erafile']['size'])) {
133 var f
= document
.forms
[0];
134 var debug
= <?php
echo js_escape(($_REQUEST['form_without'] ??
null) * 1); ?
> ;
135 var paydate
= f
.check_date
.value
;
136 var post_to_date
= f
.post_to_date
.value
;
137 var deposit_date
= f
.deposit_date
.value
;
138 window
.open('sl_eob_process.php?eraname=' +
<?php
echo js_url($eraname); ?
> +
'&debug=' +
encodeURIComponent(debug
) +
'&paydate=' +
encodeURIComponent(paydate
) +
'&post_to_date=' +
encodeURIComponent(post_to_date
) +
'&deposit_date=' +
encodeURIComponent(deposit_date
) +
'&original=original' +
'&InsId=' +
<?php
echo js_url($hidden_type_code); ?
> +
'&csrf_token_form=' +
<?php
echo js_url(CsrfUtils
::collectCsrfToken()); ?
>, '_blank');
146 $
('.datepicker').datetimepicker({
147 <?php
$datetimepicker_timepicker = false; ?
>
148 <?php
$datetimepicker_showseconds = false; ?
>
149 <?php
$datetimepicker_formatInput = true; ?
>
150 <?php
require($GLOBALS['srcdir'] . '/js/xl/jquery-datetimepicker-2-5-4.js.php'); ?
>
151 <?php
// can add any additional javascript settings to datetimepicker here; need to prepend first setting with a comma ?>
156 document
.onclick
=HideTheAjaxDivs
;
159 #ajax_div_insurance {
162 background
-color
: #FBFDD0;
163 border
: 1px solid
var(--gray
);
167 border
-bottom
:1px solid
var(--black
);
170 border
-top
:1px solid
var(--black
);
173 border
-left
:1px solid
var(--black
);
176 border
-right
:1px solid
var(--black
);
178 @media only screen
and (max
-width
: 768px
) {
181 text
-align
: left
!important
;
186 @media only screen
and (max
-width
: 700px
) {
189 text
-align
: left
!important
;
192 margin
-left
: 0px
!important
;
196 .input
-group
.form
-control
{
201 margin
-left
: 5px
!important
;
205 //to determine and set the form to open in the desired state - expanded or centered, any selection the user makes will
206 //become the user-specific default for that page. collectAndOrganizeExpandSetting() contains a single array as an
207 //argument, containing one or more elements, the name of the current file is the first element, if there are linked
208 // files they should be listed thereafter, please add _xpd suffix to the file name
209 $arr_files_php = array("era_payments_xpd", "search_payments_xpd", "new_payment_xpd");
210 $current_state = collectAndOrganizeExpandSetting($arr_files_php);
211 require_once("$srcdir/expand_contract_inc.php");
213 <title
><?php
echo xlt('ERA Posting'); ?
></title
>
215 $arrOeUiSettings = array(
216 'heading_title' => xl('Payments'),
217 'include_patient_name' => false,// use only in appropriate pages
218 'expandable' => true,
219 'expandable_files' => array("era_payments_xpd", "search_payments_xpd", "new_payment_xpd"),//all file names need suffix _xpd
220 'action' => "",//conceal, reveal, search, reset, link or back
221 'action_title' => "",
222 'action_href' => "",//only for actions - reset, link or back
223 'show_help_icon' => false,
224 'help_file_name' => ""
226 $oemr_ui = new OemrUI($arrOeUiSettings);
229 <body onload
="OnloadAction()">
230 <div id
="container_div" class="<?php echo attr($oemr_ui->oeContainer());?> mt-3">
232 <div
class="col-sm-12">
233 <?php
echo $oemr_ui->pageHeading() . "\r\n"; ?
>
236 <nav
class="navbar navbar-nav navbar-expand-md navbar-light text-body bg-light mb-4 p-4">
237 <button
class="navbar-toggler icon-bar" data
-target
="#myNavbar" data
-toggle
="collapse" type
="button"> <span
class="navbar-toggler-icon"></span
></button
>
238 <div
class="collapse navbar-collapse" id
="myNavbar">
239 <ul
class="navbar-nav mr-auto">
240 <li
class="nav-item">
241 <a
class="nav-link font-weight-bold" href
='new_payment.php'><?php
echo xlt('New Payment'); ?
></a
>
243 <li
class="nav-item">
244 <a
class="nav-link font-weight-bold" href
='search_payments.php'><?php
echo xlt('Search Payment'); ?
></a
>
246 <li
class="nav-item">
247 <a
class="nav-link active font-weight-bold" href
='era_payments.php'><?php
echo xlt('ERA Posting'); ?
></a
>
253 <div
class="col-sm-12">
254 <form action
='era_payments.php' enctype
="multipart/form-data" method
='post' style
="display:inline">
255 <input type
="hidden" name
="csrf_token_form" value
="<?php echo attr(CsrfUtils::collectCsrfToken()); ?>" />
257 <div
class="jumbotron py-4">
259 <?php
echo xlt('ERA Posting'); ?
>
262 <div
class="form-group col-12 oe-file-div">
263 <div
class="input-group">
264 <label
class="input-group-prepend">
265 <span
class="btn btn-secondary">
266 <?php
echo xlt('Browse'); ?
>&hellip
;<input type
="file" id
="uploadedfile" name
="form_erafile" style
="display: none;" />
267 <input name
="MAX_FILE_SIZE" type
="hidden" value
="5000000" />
270 <input type
="text" class="form-control" placeholder
="<?php echo xla('Click Browse and select one Electronic Remittance Advice (ERA) file...'); ?>" readonly
/>
275 <div
class="form-group col-3">
276 <label
class="control-label" for="check_date"><?php
echo xlt('Date'); ?
>:</label
>
277 <input
class="form-control datepicker" id
='check_date' name
='check_date' onkeydown
="PreventIt(event)" type
='text' value
="<?php echo attr($check_date); ?>" />
279 <div
class="form-group col-3">
280 <label
class="control-label" for="post_to_date"><?php
echo xlt('Post To Date'); ?
>:</label
>
281 <input
class="form-control datepicker" id
='post_to_date' name
='post_to_date' onkeydown
="PreventIt(event)" type
='text' value
="<?php echo attr($post_to_date); ?>" />
283 <div
class="form-group col-3 clearfix">
284 <label
class="control-label" for="form_without"><?php
echo xlt('Select'); ?
>:</label
>
285 <label
class="checkbox">
286 <input name
='form_without' id
='form_without' type
='checkbox' value
='1' />
287 <span
class="oe-ckbox-label"><?php
echo xlt('Without Update'); ?
></span
>
290 <div
class="form-group col-3">
291 <label
class="control-label" for="deposit_date"><?php
echo xlt('Deposit Date'); ?
>:</label
>
292 <input
class="form-control datepicker" id
='deposit_date' name
='deposit_date' onkeydown
="PreventIt(event)" type
='text' value
="<?php echo attr($deposit_date); ?>" />
296 <div
class="form-group col-6">
297 <label
class="control-label" for="type_code"><?php
echo xlt('Insurance'); ?
>:</label
>
298 <input id
="hidden_ajax_close_value" type
="hidden" value
="<?php echo attr($type_code); ?>" />
299 <input autocomplete
="off" class="form-control" id
='type_code' name
='type_code' onkeydown
="PreventIt(event)" type
="text" value
="<?php echo attr($type_code); ?>" />
301 <!--onKeyUp
="ajaxFunction(event,'non','search_payments.php');"-->
302 <div id
='ajax_div_insurance_section'>
303 <div id
='ajax_div_insurance_error'></div
>
304 <div id
="ajax_div_insurance" style
="display:none;"></div
>
307 <div
class="form-group col-6">
308 <label
class="control-label" for="div_insurance_or_patient"><?php
echo xlt('Insurance ID'); ?
>:</label
>
309 <div
class="form-control" id
="div_insurance_or_patient" >
310 <?php
echo text($hidden_type_code); ?
>
312 <input id
="description" name
="description" type
="hidden" />
315 <!-- 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
-->
316 <div
class="form-group mt-3">
317 <div
class="col-sm-12 text-left position-override">
318 <div
class="btn-group" role
="group">
319 <a
class="btn btn-primary btn-save" href
="#" onclick
="javascript:return Validate();"><?php
echo xlt('Process ERA File');?
></a
>
325 <input type
="hidden" name
="after_value" id
="after_value" value
="<?php echo attr($alertmsg); ?>" />
326 <input type
="hidden" name
="hidden_type_code" id
="hidden_type_code" value
="<?php echo attr($hidden_type_code); ?>" />
327 <input type
='hidden' name
='ajax_mode' id
='ajax_mode' value
='' />
331 </div
><!-- End of Container Div
-->
332 <?php
$oemr_ui->oeBelowContainerDiv();?
>
333 <script src
= '<?php echo $webroot;?>/library/js/oeUI/oeFileUploads.js'></script
>