chore(deps): bump twig/twig from 3.17.1 to 3.19.0 (#7951)
[openemr.git] / interface / billing / billing_tracker.php
blobd3561d6039b6291fb00776496db769078ce81b1c
1 <?php
3 /**
4 * Interface that provides tracking information for a claim batch
6 * The back-end ajax that goes with this datatables implementation is
7 * located in library/ajax/billing_tracker_ajax.php
9 * @package OpenEMR
10 * @link http://www.open-emr.org
11 * @author Ken Chapple <ken@mi-squared.com>
12 * @copyright Copyright (c) 2021 Ken Chapple <ken@mi-squared.com>
13 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
16 require_once(__DIR__ . "/../globals.php");
17 require_once "$srcdir/options.inc.php";
19 use OpenEMR\Common\{
20 Acl\AclMain,
21 Csrf\CsrfUtils,
22 Twig\TwigContainer
24 use OpenEMR\Core\Header;
26 //ensure user has proper access
27 if (!AclMain::aclCheckCore('acct', 'eob', '', 'write') && !AclMain::aclCheckCore('acct', 'bill', '', 'write')) {
28 echo (
29 new TwigContainer(null, $GLOBALS['kernel']))->getTwig()->render(
30 'core/unauthorized.html.twig',
31 ['pageTitle' => xl("Billing Manager")]
33 exit;
37 <html>
38 <head>
39 <?php Header::setupHeader(['datatables', 'datatables-colreorder', 'datatables-dt', 'datatables-bs']); ?>
40 <title><?php echo xlt("Claim File Tracker"); ?></title>
41 <style>
42 table.dataTable td.details-control:before {
43 content: '\f152';
44 font-family: 'Font Awesome\ 5 Free';
45 cursor: pointer;
46 font-size: 22px;
47 color: #55a4be;
49 table.dataTable tr.shown td.details-control:before {
50 content: '\f150';
51 color: black;
53 </style>
54 <script type="text/javascript">
55 $(document).ready(function() {
56 const serverUrl = "<?php echo $GLOBALS['webroot']; ?>/library/ajax/billing_tracker_ajax.php?csrf_token_form=" + <?php echo js_url(CsrfUtils::collectCsrfToken()); ?>;
57 const oTable = $('#billing-tracker-table').DataTable({
58 "processing": true,
59 // next 2 lines invoke server side processing
60 "ajax": {
61 "type" : "GET",
62 "url" : serverUrl,
63 "dataSrc": function (json) {
64 return json.data;
67 "columns": [
69 "class": 'details-control',
70 "orderable": false,
71 "data": null,
72 "defaultContent": ''
75 "data": "status",
76 "render": function(data, type, row, meta) {
77 // Format the status with a nice looking badge
78 if (type === 'display') {
79 if (data == 'success') {
80 data = '<span class="badge badge-success">' + jsText(data) + '</span>';
81 } else if (data == 'waiting') {
82 data = '<span class="badge badge-info">' + jsText(data) + '</span>';
83 } else {
84 data = '<span class="badge badge-warning">' + jsText(data) + '</span>';
88 return data;
91 { "data": "x12_partner_name" },
93 "data": "x12_filename",
94 "render": function(data, type, row, meta) {
95 // Build the URL so the user can download the claim batch file
96 if (type === 'display') {
97 const url = '<?php echo $GLOBALS['webroot']; ?>/interface/billing/get_claim_file.php?' +
98 'key=' + encodeURIComponent(data) +
99 '&csrf_token_form=' + <?php echo js_url(CsrfUtils::collectCsrfToken()); ?> +
100 '&partner=' + encodeURIComponent(row.x12_partner_id);
101 data = '<a href="' + jsAttr(url) + '">' + jsText(data) + '</a>';
104 return data;
107 { "data": "created_at" },
108 { "data": "updated_at" },
110 "order": [[4, 'desc']] // Order by 'Date Created' with newest first
113 oTable.on('preXhr.dt', function (e, settings, data) {
114 console.log("before ajax call");
115 top.restoreSession();
118 /* Formatting function for row details - modify as you need */
119 function format (d) {
120 // `d` is the original data object for the row
121 // First output any messages from the SFTP
122 let output = '';
123 if (d.messages !== null) {
124 d.messages.forEach(message => {
125 output += '<div class="alert alert-info">' + jsText(message) + '</div>';
129 // Now output the claims in this batch
130 output += '<table class="table" cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">';
131 output +=
132 '<thead>' +
133 '<tr>' +
134 '<th>' + jsText(<?php echo xlj('Patient ID'); ?>) + '</th>' +
135 '<th>' + jsText(<?php echo xlj('Encounter ID'); ?>) + '</th>' +
136 '<th>' + jsText(<?php echo xlj('Payor ID'); ?>) + '</th>' +
137 '</tr>' +
138 '</thead>';
139 output += '<tbody>';
140 d.claims.forEach(claim => {
141 output +=
142 '<tr>' +
143 '<td>' + jsText(claim.pid) + '</td>' +
144 '<td>' + jsText(claim.encounter) + '</td>' +
145 '<td>' + jsText(claim.payor_id) + '</td>' +
146 '</tr>';
148 output += '</tbody>';
150 return output;
153 // Add event listener for opening and closing details
154 $('#billing-tracker-table tbody').on('click', 'td.details-control', function () {
155 var tr = $(this).parents('tr');
156 var row = oTable.row( tr );
158 if ( row.child.isShown() ) {
159 // This row is already open - close it
160 row.child.hide();
161 tr.removeClass('shown');
163 else {
164 // Open this row
165 row.child( format(row.data()) ).show();
166 tr.addClass('shown');
168 } );
170 </script>
171 </head>
172 <body>
173 <div id="container_div" class="mt-3">
174 <div class="w-100 p-4">
176 <table id="billing-tracker-table">
177 <thead>
178 <tr>
179 <th>&nbsp;</th>
180 <th><?php echo xlt('Status') ?></th>
181 <th><?php echo xlt('X-12 Partner') ?></th>
182 <th><?php echo xlt('File') ?></th>
183 <th><?php echo xlt('Date Created') ?></th>
184 <th><?php echo xlt('Date Updated') ?></th>
185 </tr>
186 </thead>
187 <tfoot>
188 <tr>
189 <th>&nbsp;</th>
190 <th><?php echo xlt('Status') ?></th>
191 <th><?php echo xlt('X-12 Partner') ?></th>
192 <th><?php echo xlt('File') ?></th>
193 <th><?php echo xlt('Date Created') ?></th>
194 <th><?php echo xlt('Date Updated') ?></th>
195 </tr>
196 </tfoot>
197 </table>
198 </div>
199 </div>
200 </body>
201 </html>