new datepicker in encounter
[openemr.git] / interface / reports / receipts_by_method_report.php
blobb2c444a279e66ea3e977c5ee98d924b4fa0e1444
1 <?php
2 /**
3 * This is a report of receipts by payer or payment method.
5 * The payer option means an insurance company name or "Patient".
7 * The payment method option is most useful for sites using
8 * pos_checkout.php (e.g. weight loss clinics) because this plugs
9 * a payment method like Cash, Check, VISA, etc. into the "source"
10 * column of the SQL-Ledger acc_trans table or ar_session table.
12 * Copyright (C) 2006-2016 Rod Roark <rod@sunsetsystems.com>
13 * Copyright (C) 2017 Brady Miller <brady.g.miller@gmail.com>
15 * LICENSE: This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <http://opensource.org/licenses/gpl-license.php>;.
26 * @package OpenEMR
27 * @author Rod Roark <rod@sunsetsystems.com>
28 * @author Brady Miller <brady.g.miller@gmail.com>
29 * @link http://www.open-emr.org
33 require_once("../globals.php");
34 require_once("$srcdir/patient.inc");
35 require_once("$srcdir/acl.inc");
36 require_once("$srcdir/formatting.inc.php");
37 require_once "$srcdir/options.inc.php";
38 require_once("../../custom/code_types.inc.php");
40 // This controls whether we show pt name, policy number and DOS.
41 $showing_ppd = true;
43 $insarray = array();
45 function bucks($amount) {
46 if ($amount) echo oeFormatMoney($amount);
49 function thisLineItem($patient_id, $encounter_id, $memo, $transdate,
50 $rowmethod, $rowpayamount, $rowadjamount, $payer_type=0, $irnumber='')
52 global $form_report_by, $insarray, $grandpaytotal, $grandadjtotal;
54 if ($form_report_by != '1') { // reporting by method or check number
55 showLineItem($patient_id, $encounter_id, $memo, $transdate,
56 $rowmethod, $rowpayamount, $rowadjamount, $payer_type, $irnumber);
57 return;
60 // Reporting by payer.
62 if ($_POST['form_details']) { // details are wanted
63 // Save everything for later sorting.
64 $insarray[] = array($patient_id, $encounter_id, $memo, $transdate,
65 $rowmethod, $rowpayamount, $rowadjamount, $payer_type, $irnumber);
67 else { // details not wanted
68 if (empty($insarray[$rowmethod])) $insarray[$rowmethod] = array(0, 0);
69 $insarray[$rowmethod][0] += $rowpayamount;
70 $insarray[$rowmethod][1] += $rowadjamount;
71 $grandpaytotal += $rowpayamount;
72 $grandadjtotal += $rowadjamount;
76 function showLineItem($patient_id, $encounter_id, $memo, $transdate,
77 $rowmethod, $rowpayamount, $rowadjamount, $payer_type=0, $irnumber='')
79 global $paymethod, $paymethodleft, $methodpaytotal, $methodadjtotal,
80 $grandpaytotal, $grandadjtotal, $showing_ppd;
82 if (! $rowmethod) $rowmethod = 'Unknown';
84 $invnumber = $irnumber ? $irnumber : "$patient_id.$encounter_id";
86 if ($paymethod != $rowmethod) {
87 if ($paymethod) {
88 // Print method total.
91 <tr bgcolor="#ddddff">
92 <td class="detail" colspan="<?php echo $showing_ppd ? 7 : 4; ?>">
93 <?php echo xl('Total for ') . $paymethod ?>
94 </td>
95 <td align="right">
96 <?php bucks($methodadjtotal) ?>
97 </td>
98 <td align="right">
99 <?php bucks($methodpaytotal) ?>
100 </td>
101 </tr>
102 <?php
104 $methodpaytotal = 0;
105 $methodadjtotal = 0;
106 $paymethod = $rowmethod;
107 $paymethodleft = $paymethod;
110 if ($_POST['form_details']) {
113 <tr>
114 <td class="detail">
115 <?php echo $paymethodleft; $paymethodleft = "&nbsp;" ?>
116 </td>
117 <td>
118 <?php echo oeFormatShortDate($transdate) ?>
119 </td>
120 <td class="detail">
121 <?php echo $invnumber ?>
122 </td>
124 <?php
125 if ($showing_ppd) {
126 $pferow = sqlQuery("SELECT p.fname, p.mname, p.lname, fe.date " .
127 "FROM patient_data AS p, form_encounter AS fe WHERE " .
128 "p.pid = '$patient_id' AND fe.pid = p.pid AND " .
129 "fe.encounter = '$encounter_id' LIMIT 1");
130 $dos = substr($pferow['date'], 0, 10);
132 echo " <td class='dehead'>\n";
133 echo " " . $pferow['lname'] . ", " . $pferow['fname'] . " " . $pferow['mname'];
134 echo " </td>\n";
136 echo " <td class='dehead'>\n";
137 if ($payer_type) {
138 $ptarr = array(1 => 'primary', 2 => 'secondary', 3 => 'tertiary');
139 $insrow = getInsuranceDataByDate($patient_id, $dos,
140 $ptarr[$payer_type], "policy_number");
141 echo " " . $insrow['policy_number'];
143 echo " </td>\n";
145 echo " <td class='dehead'>\n";
146 echo " " . oeFormatShortDate($dos) . "\n";
147 echo " </td>\n";
151 <td>
152 <?php echo $memo ?>
153 </td>
154 <td align="right">
155 <?php bucks($rowadjamount) ?>
156 </td>
157 <td align="right">
158 <?php bucks($rowpayamount) ?>
159 </td>
160 </tr>
161 <?php
163 $methodpaytotal += $rowpayamount;
164 $grandpaytotal += $rowpayamount;
165 $methodadjtotal += $rowadjamount;
166 $grandadjtotal += $rowadjamount;
169 // This is called by usort() when reporting by payer with details.
170 // Sorts by payer/date/patient/encounter/memo.
171 function payerCmp($a, $b) {
172 foreach (array(4,3,0,1,2,7) as $i) {
173 if ($a[$i] < $b[$i]) return -1;
174 if ($a[$i] > $b[$i]) return 1;
176 return 0;
179 if (! acl_check('acct', 'rep')) die(xl("Unauthorized access."));
182 $form_from_date = fixDate($_POST['form_from_date'], date('Y-m-d'));
183 $form_to_date = fixDate($_POST['form_to_date'] , date('Y-m-d'));
184 $form_use_edate = $_POST['form_use_edate'];
185 $form_facility = $_POST['form_facility'];
186 $form_report_by = $_POST['form_report_by'];
187 $form_proc_codefull = trim($_POST['form_proc_codefull']);
188 // Parse the code type and the code from <code_type>:<code>
189 $tmp_code_array = explode(':',$form_proc_codefull);
190 $form_proc_codetype = $tmp_code_array[0];
191 $form_proc_code = $tmp_code_array[1];
194 <html>
195 <head>
197 <?php if (function_exists('html_header_show')) html_header_show(); ?>
199 <link rel='stylesheet' href='<?php echo $css_header ?>' type='text/css'>
200 <link rel="stylesheet" href="<?php echo $GLOBALS['assets_static_relative']; ?>/jquery-datetimepicker-2-5-4/build/jquery.datetimepicker.min.css">
202 <style type="text/css">
203 /* specifically include & exclude from printing */
204 @media print {
205 #report_parameters {
206 visibility: hidden;
207 display: none;
209 #report_parameters_daterange {
210 visibility: visible;
211 display: inline;
213 #report_results {
214 margin-top: 30px;
218 /* specifically exclude some from the screen */
219 @media screen {
220 #report_parameters_daterange {
221 visibility: hidden;
222 display: none;
226 table.mymaintable, table.mymaintable td {
227 border: 1px solid #aaaaaa;
228 border-collapse: collapse;
230 table.mymaintable td {
231 padding: 1pt 4pt 1pt 4pt;
233 </style>
235 <script type="text/javascript" src="../../library/dialog.js?v=<?php echo $v_js_includes; ?>"></script>
236 <script type="text/javascript" src="<?php echo $GLOBALS['assets_static_relative']; ?>/jquery-min-3-1-1/index.js"></script>
237 <script type="text/javascript" src="../../library/js/report_helper.js?v=<?php echo $v_js_includes; ?>"></script>
238 <script type="text/javascript" src="<?php echo $GLOBALS['assets_static_relative']; ?>/jquery-datetimepicker-2-5-4/build/jquery.datetimepicker.full.min.js"></script>
240 <script language="JavaScript">
242 $(document).ready(function() {
243 oeFixedHeaderSetup(document.getElementById('mymaintable'));
244 var win = top.printLogSetup ? top : opener.top;
245 win.printLogSetup(document.getElementById('printbutton'));
247 $('.datepicker').datetimepicker({
248 <?php $datetimepicker_timepicker = false; ?>
249 <?php $datetimepicker_formatInput = false; ?>
250 <?php require($GLOBALS['srcdir'] . '/js/xl/jquery-datetimepicker-2-5-4.js.php'); ?>
251 <?php // can add any additional javascript settings to datetimepicker here; need to prepend first setting with a comma ?>
255 // This is for callback by the find-code popup.
256 // Erases the current entry
257 function set_related(codetype, code, selector, codedesc) {
258 var f = document.forms[0];
259 var s = f.form_proc_codefull.value;
260 if (code) {
261 s = codetype + ':' + code;
262 } else {
263 s = '';
265 f.form_proc_codefull.value = s;
268 // This invokes the find-code popup.
269 function sel_procedure() {
270 dlgopen('../patient_file/encounter/find_code_popup.php?codetype=<?php echo attr(collect_codetypes("procedure","csv")) ?>', '_blank', 500, 400);
273 </script>
275 <title><?xl('Receipts Summary','e')?></title>
276 </head>
278 <body class="body_top">
280 <span class='title'><?php xl('Report','e'); ?> - <?php xl('Receipts Summary','e'); ?></span>
282 <form method='post' action='receipts_by_method_report.php' id='theform'>
284 <div id="report_parameters">
286 <input type='hidden' name='form_refresh' id='form_refresh' value=''/>
288 <table>
289 <tr>
290 <td width='630px'>
291 <div style='float:left'>
293 <table class='text'>
294 <tr>
295 <td class='label'>
296 <?php xl('Report by','e'); ?>
297 </td>
298 <td>
299 <?php
300 echo " <select name='form_report_by'>\n";
301 foreach (array(1 => 'Payer', 2 => 'Payment Method', 3 => 'Check Number') as $key => $value) {
302 echo " <option value='$key'";
303 if ($key == $form_report_by) echo ' selected';
304 echo ">" . xl($value) . "</option>\n";
306 echo " </select>&nbsp;\n"; ?>
307 </td>
309 <td>
310 <?php dropdown_facility(strip_escape_custom($form_facility), 'form_facility', false); ?>
311 </td>
313 <td>
314 <?php if (!$GLOBALS['simplified_demographics']) echo '&nbsp;' . xl('Procedure/Service') . ':'; ?>
315 </td>
316 <td>
317 <input type='text' name='form_proc_codefull' size='12' value='<?php echo $form_proc_codefull; ?>' onclick='sel_procedure()'
318 title='<?php xl('Click to select optional procedure code','e'); ?>'
319 <?php if ($GLOBALS['simplified_demographics']) echo "style='display:none'"; ?> />
320 <br>
321 &nbsp;<input type='checkbox' name='form_details' value='1'<?php if ($_POST['form_details']) echo " checked"; ?> /><?xl('Details','e')?>
322 </td>
323 </tr>
324 <tr>
325 <td>&nbsp;</td>
326 <td>
327 <select name='form_use_edate'>
328 <option value='0'><?php xl('Payment Date','e'); ?></option>
329 <option value='1'<?php if ($form_use_edate) echo ' selected' ?>><?php xl('Invoice Date','e'); ?></option>
330 </select>
331 </td>
332 <td>
333 <input type='text' class='datepicker' name='form_from_date' id="form_from_date" size='10' value='<?php echo $form_from_date ?>'
334 title='yyyy-mm-dd'>
335 </td>
336 <td class='label'>
337 <?php xl('To','e'); ?>:
338 </td>
339 <td>
340 <input type='text' class='datepicker' name='form_to_date' id="form_to_date" size='10' value='<?php echo $form_to_date ?>'
341 title='yyyy-mm-dd'>
342 </td>
343 </tr>
344 </table>
346 </div>
348 </td>
349 <td align='left' valign='middle' height="100%">
350 <table style='border-left:1px solid; width:100%; height:100%' >
351 <tr>
352 <td>
353 <div style='margin-left:15px'>
354 <a href='#' class='css_button' onclick='$("#form_refresh").attr("value","true"); $("#theform").submit();'>
355 <span>
356 <?php xl('Submit','e'); ?>
357 </span>
358 </a>
360 <?php if ($_POST['form_refresh']) { ?>
361 <a href='#' class='css_button' id='printbutton'>
362 <span>
363 <?php xl('Print','e'); ?>
364 </span>
365 </a>
366 <?php } ?>
367 </div>
368 </td>
369 </tr>
370 </table>
371 </td>
372 </tr>
373 </table>
375 </div> <!-- end of parameters -->
377 <?php
378 if ($_POST['form_refresh']) {
380 <div id="report_results">
382 <table width='98%' id='mymaintable' class='mymaintable'>
384 <thead>
385 <tr bgcolor="#dddddd">
386 <th>
387 <?php xl('Method','e') ?>
388 </th>
389 <th>
390 <?php xl('Date','e') ?>
391 </th>
392 <th>
393 <?php xl('Invoice','e') ?>
394 </th>
395 <?php if ($showing_ppd) { ?>
396 <th>
397 <?xl('Patient','e')?>
398 </th>
399 <th>
400 <?xl('Policy','e')?>
401 </th>
402 <th>
403 <?xl('DOS','e')?>
404 </th>
405 <?php } ?>
406 <th>
407 <?xl('Procedure','e')?>
408 </th>
409 <th align="right">
410 <?xl('Adjustments','e')?>
411 </th>
412 <th align="right">
413 <?xl('Payments','e')?>
414 </th>
415 </tr>
416 </thead>
417 <tbody>
418 <?php
420 if ($_POST['form_refresh']) {
421 $from_date = $form_from_date;
422 $to_date = $form_to_date;
424 $paymethod = "";
425 $paymethodleft = "";
426 $methodpaytotal = 0;
427 $grandpaytotal = 0;
428 $methodadjtotal = 0;
429 $grandadjtotal = 0;
432 // Get co-pays using the encounter date as the pay date. These will
433 // always be considered patient payments. Ignored if selecting by
434 // billing code.
436 if (!$form_proc_code || !$form_proc_codetype) {
437 $query = "SELECT b.fee, b.pid, b.encounter, b.code_type, " .
438 "fe.date, fe.facility_id, fe.invoice_refno " .
439 "FROM billing AS b " .
440 "JOIN form_encounter AS fe ON fe.pid = b.pid AND fe.encounter = b.encounter " .
441 "WHERE b.code_type = 'COPAY' AND b.activity = 1 AND b.fee != 0 AND " .
442 "fe.date >= '$from_date 00:00:00' AND fe.date <= '$to_date 23:59:59'";
443 // If a facility was specified.
444 if ($form_facility) $query .= " AND fe.facility_id = '$form_facility'";
445 $query .= " ORDER BY fe.date, b.pid, b.encounter, fe.id";
447 $res = sqlStatement($query);
448 while ($row = sqlFetchArray($res)) {
449 $rowmethod = $form_report_by == 1 ? 'Patient' : 'Co-Pay';
450 thisLineItem($row['pid'], $row['encounter'], $row['code_text'],
451 substr($row['date'], 0, 10), $rowmethod, 0 - $row['fee'], 0, 0, $row['invoice_refno']);
453 } // end if not form_proc_code
455 // Get all other payments and adjustments and their dates, corresponding
456 // payers and check reference data, and the encounter dates separately.
458 $query = "SELECT a.pid, a.encounter, a.post_time, a.pay_amount, " .
459 "a.adj_amount, a.memo, a.session_id, a.code, a.payer_type, fe.id, fe.date, " .
460 "fe.invoice_refno, s.deposit_date, s.payer_id, s.reference, i.name " .
461 "FROM ar_activity AS a " .
462 "JOIN form_encounter AS fe ON fe.pid = a.pid AND fe.encounter = a.encounter " .
463 "JOIN forms AS f ON f.pid = a.pid AND f.encounter = a.encounter AND f.formdir = 'newpatient' " .
464 "LEFT JOIN ar_session AS s ON s.session_id = a.session_id " .
465 "LEFT JOIN insurance_companies AS i ON i.id = s.payer_id " .
466 "WHERE ( a.pay_amount != 0 OR a.adj_amount != 0 )";
468 if ($form_use_edate) {
469 $query .= " AND fe.date >= '$from_date 00:00:00' AND fe.date <= '$to_date 23:59:59'";
470 } else {
471 $query .= " AND ( ( s.deposit_date IS NOT NULL AND " .
472 "s.deposit_date >= '$from_date' AND s.deposit_date <= '$to_date' ) OR " .
473 "( s.deposit_date IS NULL AND a.post_time >= '$from_date 00:00:00' AND " .
474 "a.post_time <= '$to_date 23:59:59' ) )";
476 // If a procedure code was specified.
477 if ($form_proc_code && $form_proc_codetype) {
478 // if a code_type is entered into the ar_activity table, then use it. If it is not entered in, then do not use it.
479 $query .= " AND ( a.code_type = '$form_proc_codetype' OR a.code_type = '' ) AND a.code LIKE '$form_proc_code%'";
481 // If a facility was specified.
482 if ($form_facility) $query .= " AND fe.facility_id = '$form_facility'";
484 if ($form_use_edate) {
485 $query .= " ORDER BY s.reference, fe.date, a.pid, a.encounter, fe.id";
486 } else {
487 $query .= " ORDER BY s.reference, s.deposit_date, a.post_time, a.pid, a.encounter, fe.id";
490 $res = sqlStatement($query);
491 while ($row = sqlFetchArray($res)) {
492 if ($form_use_edate) {
493 $thedate = substr($row['date'], 0, 10);
494 } else if (!empty($row['deposit_date'])) {
495 $thedate = $row['deposit_date'];
496 } else {
497 $thedate = substr($row['post_time'], 0, 10);
499 // Compute reporting key: insurance company name or payment method.
500 if ($form_report_by == '1') {
501 if (empty($row['payer_id'])) {
502 $rowmethod = '';
503 } else {
504 if (empty($row['name'])) $rowmethod = xl('Unnamed insurance company');
505 else $rowmethod = $row['name'];
508 else {
509 if (empty($row['session_id'])) {
510 $rowmethod = trim($row['memo']);
511 } else {
512 $rowmethod = trim($row['reference']);
514 if ($form_report_by != '3') {
515 // Extract only the first word as the payment method because any
516 // following text will be some petty detail like a check number.
517 $rowmethod = substr($rowmethod, 0, strcspn($rowmethod, ' /'));
521 thisLineItem($row['pid'], $row['encounter'], $row['code'], $thedate,
522 $rowmethod, $row['pay_amount'], $row['adj_amount'], $row['payer_type'],
523 $row['invoice_refno']);
526 // Not payer summary.
527 if ($form_report_by != '1' || $_POST['form_details']) {
529 if ($form_report_by == '1') { // by payer with details
530 // Sort and dump saved info, and consolidate items with all key
531 // fields being the same.
532 usort($insarray, 'payerCmp');
533 $b = array();
534 foreach ($insarray as $a) {
535 if (empty($a[4])) $a[4] = xl('Patient');
536 if (empty($b)) {
537 $b = $a;
539 else {
540 $match = true;
541 foreach (array(4,3,0,1,2,7) as $i) if ($a[$i] != $b[$i]) $match = false;
542 if ($match) {
543 $b[5] += $a[5];
544 $b[6] += $a[6];
545 } else {
546 showLineItem($b[0], $b[1], $b[2], $b[3], $b[4], $b[5], $b[6], $b[7], $b[8]);
547 $b = $a;
551 if (!empty($b)) {
552 showLineItem($b[0], $b[1], $b[2], $b[3], $b[4], $b[5], $b[6], $b[7], $b[8]);
554 } // end by payer with details
556 // Print last method total.
558 <tr bgcolor="#ddddff">
559 <td class="detail" colspan="<?php echo $showing_ppd ? 7 : 4; ?>">
560 <?php echo xl('Total for ') . $paymethod ?>
561 </td>
562 <td align="right">
563 <?php bucks($methodadjtotal) ?>
564 </td>
565 <td align="right">
566 <?php bucks($methodpaytotal) ?>
567 </td>
568 </tr>
569 <?php
572 // Payer summary: need to sort and then print it all.
573 else {
574 ksort($insarray);
575 foreach ($insarray as $key => $value) {
576 if (empty($key)) $key = xl('Patient');
578 <tr bgcolor="#ddddff">
579 <td class="detail" colspan="<?php echo $showing_ppd ? 7 : 4; ?>">
580 <?php echo $key; ?>
581 </td>
582 <td align="right">
583 <?php bucks($value[1]); ?>
584 </td>
585 <td align="right">
586 <?php bucks($value[0]); ?>
587 </td>
588 </tr>
589 <?php
590 } // end foreach
591 } // end payer summary
593 <tr bgcolor="#ffdddd">
594 <td class="detail" colspan="<?php echo $showing_ppd ? 7 : 4; ?>">
595 <?php xl('Grand Total','e') ?>
596 </td>
597 <td align="right">
598 <?php bucks($grandadjtotal) ?>
599 </td>
600 <td align="right">
601 <?php bucks($grandpaytotal) ?>
602 </td>
603 </tr>
605 <?php
606 } // end form refresh
609 </tbody>
610 </table>
611 </div>
612 <?php } else { ?>
613 <div class='text'>
614 <?php echo xl('Please input search criteria above, and click Submit to view results.', 'e' ); ?>
615 </div>
616 <?php } ?>
618 </form>
619 </body>
621 </html>