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>;.
27 * @author Rod Roark <rod@sunsetsystems.com>
28 * @author Brady Miller <brady.g.miller@gmail.com>
29 * @link http://www.open-emr.org
32 use OpenEMR\Core\Header
;
34 require_once("../globals.php");
35 require_once("$srcdir/patient.inc");
36 require_once("$srcdir/acl.inc");
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.
45 function bucks($amount)
48 echo oeFormatMoney($amount);
52 function thisLineItem(
64 global $form_report_by, $insarray, $grandpaytotal, $grandadjtotal;
66 if ($form_report_by != '1') { // reporting by method or check number
81 // Reporting by payer.
83 if ($_POST['form_details']) { // details are wanted
84 // Save everything for later sorting.
85 $insarray[] = array($patient_id, $encounter_id, $memo, $transdate,
86 $rowmethod, $rowpayamount, $rowadjamount, $payer_type, $irnumber);
87 } else { // details not wanted
88 if (empty($insarray[$rowmethod])) {
89 $insarray[$rowmethod] = array(0, 0);
92 $insarray[$rowmethod][0] +
= $rowpayamount;
93 $insarray[$rowmethod][1] +
= $rowadjamount;
94 $grandpaytotal +
= $rowpayamount;
95 $grandadjtotal +
= $rowadjamount;
99 function showLineItem(
111 global $paymethod, $paymethodleft, $methodpaytotal, $methodadjtotal,
112 $grandpaytotal, $grandadjtotal, $showing_ppd;
115 $rowmethod = 'Unknown';
118 $invnumber = $irnumber ?
$irnumber : "$patient_id.$encounter_id";
120 if ($paymethod != $rowmethod) {
122 // Print method total.
125 <tr bgcolor
="#ddddff">
126 <td
class="detail" colspan
="<?php echo $showing_ppd ? 7 : 4; ?>">
127 <?php
echo xl('Total for ') . $paymethod ?
>
130 <?php
bucks($methodadjtotal) ?
>
133 <?php
bucks($methodpaytotal) ?
>
141 $paymethod = $rowmethod;
142 $paymethodleft = $paymethod;
145 if ($_POST['form_details']) {
150 <?php
echo $paymethodleft; $paymethodleft = " " ?
>
153 <?php
echo oeFormatShortDate($transdate) ?
>
156 <?php
echo $invnumber ?
>
161 $pferow = sqlQuery("SELECT p.fname, p.mname, p.lname, fe.date " .
162 "FROM patient_data AS p, form_encounter AS fe WHERE " .
163 "p.pid = '$patient_id' AND fe.pid = p.pid AND " .
164 "fe.encounter = '$encounter_id' LIMIT 1");
165 $dos = substr($pferow['date'], 0, 10);
167 echo " <td class='dehead'>\n";
168 echo " " . $pferow['lname'] . ", " . $pferow['fname'] . " " . $pferow['mname'];
171 echo " <td class='dehead'>\n";
173 $ptarr = array(1 => 'primary', 2 => 'secondary', 3 => 'tertiary');
174 $insrow = getInsuranceDataByDate(
180 echo " " . $insrow['policy_number'];
185 echo " <td class='dehead'>\n";
186 echo " " . oeFormatShortDate($dos) . "\n";
195 <?php
bucks($rowadjamount) ?
>
198 <?php
bucks($rowpayamount) ?
>
204 $methodpaytotal +
= $rowpayamount;
205 $grandpaytotal +
= $rowpayamount;
206 $methodadjtotal +
= $rowadjamount;
207 $grandadjtotal +
= $rowadjamount;
210 // This is called by usort() when reporting by payer with details.
211 // Sorts by payer/date/patient/encounter/memo.
212 function payerCmp($a, $b)
214 foreach (array(4,3,0,1,2,7) as $i) {
215 if ($a[$i] < $b[$i]) {
219 if ($a[$i] > $b[$i]) {
227 if (! acl_check('acct', 'rep')) {
228 die(xl("Unauthorized access."));
232 $form_from_date = fixDate($_POST['form_from_date'], date('Y-m-d'));
233 $form_to_date = fixDate($_POST['form_to_date'], date('Y-m-d'));
234 $form_use_edate = $_POST['form_use_edate'];
235 $form_facility = $_POST['form_facility'];
236 $form_report_by = $_POST['form_report_by'];
237 $form_proc_codefull = trim($_POST['form_proc_codefull']);
238 // Parse the code type and the code from <code_type>:<code>
239 $tmp_code_array = explode(':', $form_proc_codefull);
240 $form_proc_codetype = $tmp_code_array[0];
241 $form_proc_code = $tmp_code_array[1];
247 <?php Header
::setupHeader(['datetime-picker', 'report-helper']); ?
>
249 <style type
="text/css">
250 /* specifically include & exclude from printing */
256 #report_parameters_daterange {
265 /* specifically exclude some from the screen */
267 #report_parameters_daterange {
273 table
.mymaintable
, table
.mymaintable td
{
274 border
: 1px solid
#aaaaaa;
275 border
-collapse
: collapse
;
277 table
.mymaintable td
{
278 padding
: 1pt
4pt
1pt
4pt
;
282 <script language
="JavaScript">
284 $
(document
).ready(function() {
285 oeFixedHeaderSetup(document
.getElementById('mymaintable'));
286 var win
= top
.printLogSetup ? top
: opener
.top
;
287 win
.printLogSetup(document
.getElementById('printbutton'));
289 $
('.datepicker').datetimepicker({
290 <?php
$datetimepicker_timepicker = false; ?
>
291 <?php
$datetimepicker_showseconds = false; ?
>
292 <?php
$datetimepicker_formatInput = false; ?
>
293 <?php
require($GLOBALS['srcdir'] . '/js/xl/jquery-datetimepicker-2-5-4.js.php'); ?
>
294 <?php
// can add any additional javascript settings to datetimepicker here; need to prepend first setting with a comma ?>
298 // This is for callback by the find-code popup.
299 // Erases the current entry
300 function set_related(codetype
, code
, selector
, codedesc
) {
301 var f
= document
.forms
[0];
302 var s
= f
.form_proc_codefull
.value
;
304 s
= codetype +
':' + code
;
308 f
.form_proc_codefull
.value
= s
;
311 // This invokes the find-code popup.
312 function sel_procedure() {
313 dlgopen('../patient_file/encounter/find_code_popup.php?codetype=<?php echo attr(collect_codetypes("procedure", "csv")) ?>', '_blank', 500, 400);
318 <title
><?
xl('Receipts Summary','e')?
></title
>
321 <body
class="body_top">
323 <span
class='title'><?php
xl('Report', 'e'); ?
> - <?php
xl('Receipts Summary', 'e'); ?
></span
>
325 <form method
='post' action
='receipts_by_method_report.php' id
='theform'>
327 <div id
="report_parameters">
329 <input type
='hidden' name
='form_refresh' id
='form_refresh' value
=''/>
334 <div style
='float:left'>
338 <td
class='control-label'>
339 <?php
xl('Report by', 'e'); ?
>
343 echo " <select name='form_report_by' class='form-control'>\n";
344 foreach (array(1 => 'Payer', 2 => 'Payment Method', 3 => 'Check Number') as $key => $value) {
345 echo " <option value='$key'";
346 if ($key == $form_report_by) {
350 echo ">" . xl($value) . "</option>\n";
353 echo " </select> \n"; ?
>
357 <?php
dropdown_facility(strip_escape_custom($form_facility), 'form_facility', false); ?
>
360 <td
class='control-label'>
361 <?php
if (!$GLOBALS['simplified_demographics']) {
362 echo ' ' . xl('Procedure/Service') . ':';
366 <input type
='text' name
='form_proc_codefull' class='form-control' size
='12' value
='<?php echo $form_proc_codefull; ?>' onclick
='sel_procedure()'
367 title
='<?php xl('Click to select optional procedure code
', 'e
'); ?>'
368 <?php
if ($GLOBALS['simplified_demographics']) {
369 echo "style='display:none'";
372 <div
class="checkbox">
373 <label
><input type
='checkbox' name
='form_details' value
='1'<?php
if ($_POST['form_details']) {
375 } ?
> /><?php
echo xl('Details')?
></label
>
382 <select name
='form_use_edate' class='form-control'>
383 <option value
='0'><?php
xl('Payment Date', 'e'); ?
></option
>
384 <option value
='1'<?php
if ($form_use_edate) {
386 } ?
>><?php
xl('Invoice Date', 'e'); ?
></option
>
390 <input type
='text' class='datepicker form-control' name
='form_from_date' id
="form_from_date" size
='10' value
='<?php echo $form_from_date ?>'
393 <td
class='control-label'>
394 <?php
xl('To', 'e'); ?
>:
397 <input type
='text' class='datepicker form-control' name
='form_to_date' id
="form_to_date" size
='10' value
='<?php echo $form_to_date ?>'
406 <td align
='left' valign
='middle' height
="100%">
407 <table style
='border-left:1px solid; width:100%; height:100%' >
410 <div
class="text-center">
411 <div
class="btn-group" role
="group">
412 <a href
='#' class='btn btn-default btn-save' onclick
='$("#form_refresh").attr("value","true"); $("#theform").submit();'>
413 <?php
echo xlt('Submit'); ?
>
415 <?php
if ($_POST['form_refresh']) { ?
>
416 <a href
='#' class='btn btn-default btn-print' id
='printbutton'>
417 <?php
echo xlt('Print'); ?
>
429 </div
> <!-- end of parameters
-->
432 if ($_POST['form_refresh']) {
434 <div id
="report_results">
436 <table width
='98%' id
='mymaintable' class='mymaintable'>
439 <tr bgcolor
="#dddddd">
441 <?php
xl('Method', 'e') ?
>
444 <?php
xl('Date', 'e') ?
>
447 <?php
xl('Invoice', 'e') ?
>
449 <?php
if ($showing_ppd) { ?
>
451 <?
xl('Patient','e')?
>
461 <?
xl('Procedure','e')?
>
464 <?
xl('Adjustments','e')?
>
467 <?
xl('Payments','e')?
>
474 if ($_POST['form_refresh']) {
475 $from_date = $form_from_date;
476 $to_date = $form_to_date;
486 // Get co-pays using the encounter date as the pay date. These will
487 // always be considered patient payments. Ignored if selecting by
490 if (!$form_proc_code ||
!$form_proc_codetype) {
491 $query = "SELECT b.fee, b.pid, b.encounter, b.code_type, " .
492 "fe.date, fe.facility_id, fe.invoice_refno " .
493 "FROM billing AS b " .
494 "JOIN form_encounter AS fe ON fe.pid = b.pid AND fe.encounter = b.encounter " .
495 "WHERE b.code_type = 'COPAY' AND b.activity = 1 AND b.fee != 0 AND " .
496 "fe.date >= '$from_date 00:00:00' AND fe.date <= '$to_date 23:59:59'";
497 // If a facility was specified.
498 if ($form_facility) {
499 $query .= " AND fe.facility_id = '$form_facility'";
502 $query .= " ORDER BY fe.date, b.pid, b.encounter, fe.id";
504 $res = sqlStatement($query);
505 while ($row = sqlFetchArray($res)) {
506 $rowmethod = $form_report_by == 1 ?
'Patient' : 'Co-Pay';
511 substr($row['date'], 0, 10),
516 $row['invoice_refno']
519 } // end if not form_proc_code
521 // Get all other payments and adjustments and their dates, corresponding
522 // payers and check reference data, and the encounter dates separately.
524 $query = "SELECT a.pid, a.encounter, a.post_time, a.pay_amount, " .
525 "a.adj_amount, a.memo, a.session_id, a.code, a.payer_type, fe.id, fe.date, " .
526 "fe.invoice_refno, s.deposit_date, s.payer_id, s.reference, i.name " .
527 "FROM ar_activity AS a " .
528 "JOIN form_encounter AS fe ON fe.pid = a.pid AND fe.encounter = a.encounter " .
529 "JOIN forms AS f ON f.pid = a.pid AND f.encounter = a.encounter AND f.formdir = 'newpatient' " .
530 "LEFT JOIN ar_session AS s ON s.session_id = a.session_id " .
531 "LEFT JOIN insurance_companies AS i ON i.id = s.payer_id " .
532 "WHERE ( a.pay_amount != 0 OR a.adj_amount != 0 )";
534 if ($form_use_edate) {
535 $query .= " AND fe.date >= '$from_date 00:00:00' AND fe.date <= '$to_date 23:59:59'";
537 $query .= " AND ( ( s.deposit_date IS NOT NULL AND " .
538 "s.deposit_date >= '$from_date' AND s.deposit_date <= '$to_date' ) OR " .
539 "( s.deposit_date IS NULL AND a.post_time >= '$from_date 00:00:00' AND " .
540 "a.post_time <= '$to_date 23:59:59' ) )";
543 // If a procedure code was specified.
544 if ($form_proc_code && $form_proc_codetype) {
545 // 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.
546 $query .= " AND ( a.code_type = '$form_proc_codetype' OR a.code_type = '' ) AND a.code LIKE '$form_proc_code%'";
549 // If a facility was specified.
550 if ($form_facility) {
551 $query .= " AND fe.facility_id = '$form_facility'";
555 if ($form_use_edate) {
556 $query .= " ORDER BY s.reference, fe.date, a.pid, a.encounter, fe.id";
558 $query .= " ORDER BY s.reference, s.deposit_date, a.post_time, a.pid, a.encounter, fe.id";
562 $res = sqlStatement($query);
563 while ($row = sqlFetchArray($res)) {
564 if ($form_use_edate) {
565 $thedate = substr($row['date'], 0, 10);
566 } else if (!empty($row['deposit_date'])) {
567 $thedate = $row['deposit_date'];
569 $thedate = substr($row['post_time'], 0, 10);
572 // Compute reporting key: insurance company name or payment method.
573 if ($form_report_by == '1') {
574 if (empty($row['payer_id'])) {
577 if (empty($row['name'])) {
578 $rowmethod = xl('Unnamed insurance company');
580 $rowmethod = $row['name'];
584 if (empty($row['session_id'])) {
585 $rowmethod = trim($row['memo']);
587 $rowmethod = trim($row['reference']);
590 if ($form_report_by != '3') {
591 // Extract only the first word as the payment method because any
592 // following text will be some petty detail like a check number.
593 $rowmethod = substr($rowmethod, 0, strcspn($rowmethod, ' /'));
607 $row['invoice_refno']
611 // Not payer summary.
612 if ($form_report_by != '1' ||
$_POST['form_details']) {
613 if ($form_report_by == '1') { // by payer with details
614 // Sort and dump saved info, and consolidate items with all key
615 // fields being the same.
616 usort($insarray, 'payerCmp');
618 foreach ($insarray as $a) {
620 $a[4] = xl('Patient');
627 foreach (array(4,3,0,1,2,7) as $i) {
628 if ($a[$i] != $b[$i]) {
637 showLineItem($b[0], $b[1], $b[2], $b[3], $b[4], $b[5], $b[6], $b[7], $b[8]);
644 showLineItem($b[0], $b[1], $b[2], $b[3], $b[4], $b[5], $b[6], $b[7], $b[8]);
646 } // end by payer with details
648 // Print last method total.
650 <tr bgcolor
="#ddddff">
651 <td
class="detail" colspan
="<?php echo $showing_ppd ? 7 : 4; ?>">
652 <?php
echo xl('Total for ') . $paymethod ?
>
655 <?php
bucks($methodadjtotal) ?
>
658 <?php
bucks($methodpaytotal) ?
>
662 } // Payer summary: need to sort and then print it all.
665 foreach ($insarray as $key => $value) {
667 $key = xl('Patient');
670 <tr bgcolor
="#ddddff">
671 <td
class="detail" colspan
="<?php echo $showing_ppd ? 7 : 4; ?>">
675 <?php
bucks($value[1]); ?
>
678 <?php
bucks($value[0]); ?
>
683 } // end payer summary
685 <tr bgcolor
="#ffdddd">
686 <td
class="detail" colspan
="<?php echo $showing_ppd ? 7 : 4; ?>">
687 <?php
xl('Grand Total', 'e') ?
>
690 <?php
bucks($grandadjtotal) ?
>
693 <?php
bucks($grandpaytotal) ?
>
698 } // end form refresh
706 <?php
echo xl('Please input search criteria above, and click Submit to view results.', 'e'); ?
>