Solved

Help me understand these errors...

Posted on 2016-08-11
8
47 Views
Last Modified: 2016-08-18
Here are the errors that showed up in the log of a recent "mailing" of some statements:

[10-Aug-2016 15:02:53 America/Chicago] PHP Notice:  Undefined index: message in /var/www/dig.mypatientcredit.com/application/helpers/StatementImager/StatementImage.php on line 505
[10-Aug-2016 15:02:53 America/Chicago] PHP Notice:  Undefined index: legal_front in /var/www/dig.mypatientcredit.com/application/helpers/StatementImager/StatementImage.php on line 506
[10-Aug-2016 15:02:53 America/Chicago] PHP Notice:  Undefined index: legal_back in /var/www/dig.mypatientcredit.com/application/helpers/StatementImager/StatementImage.php on line 507
[10-Aug-2016 15:02:53 America/Chicago] PHP Notice:  Undefined index: legal_color in /var/www/dig.mypatientcredit.com/application/helpers/StatementImager/StatementImage.php on line 508

Here's the function that's apparently coughing and sputtering:

protected function toPipeDelim($st){

        //Loop through and create the PipeDelim field
        $file = "";
        /**
            Add Statement Segment
        **/
        //krumo($st);
        // Set the Silly Variables cause some folks don't like reading the array object in the string generation
        $totalcharges = number_format($st['TotalCharges'], 2, '.', '');
        $totaladjustments = number_format($st['TotalAdjustments'], 2, '.', '');
        $totalpayments = number_format($st['TotalPayments'], 2, '.', '');
        $stbalance = number_format($totalcharges+$totalpayments+$totaladjustments, 2, '.', '');
        $amountdue = ($st['AmountDue'] == '0')?$stbalance:number_format($st['AmountDue'], 2, '.', '');
        if($st['duedate'] == '0'){
            $duedate = 'Due Upon Receipt';
        } else {
            $duedate = date('m/').$st['duedate'].date('/Y');
            if(strtotime($duedate) < strtotime('now')) {
                $duedate = Date('m/d/Y', strtotime("$duedate + 1 month"));
            }
            $duedate = 'Due on ' . $duedate;
        }
        $statementdate = date('m/d/Y');
        $planbalance = number_format($st['planbalance'], 2, '.', '');

        $message = $st['parameters']['message'];
        $mmessage = $st['parameters']['legal_front'];
        $lmessage = $st['parameters']['legal_back'];
        $mmessagecolor = $st['parameters']['legal_color'];

        $statementpin = $st['statementid'] != '' ? "T".$st['statementid'] : "PREVIEW";
        $templateid = $st['templateid'];
        $accountid = $st['AccountID'];
        $accountnumber = $st['PracticeAccountID']."-".$accountid;
        $statementurl = "https://".strtolower($st['ClientTetrisID']).".patientfocus.com/?=$statementpin";
        $lastclaimdate = $st['lastclaimdate'] ? date('m/d/Y',strtotime($st['lastclaimdate'])) : '';

        $file .= "S2|$templateid|$totalcharges|$totalpayments|$totaladjustments|$stbalance|$amountdue|$duedate|$statementdate|$statementpin|$accountid|$accountnumber|$statementurl|$message|$lastclaimdate|$mmessagecolor|$mmessage|$lmessage\r\n";
        /**
            Add Client Segment
        **/
           // Set the Silly Variables cause some folks don't like reading the array object in the string generation
        $practicename = $st['PracticeName'];
        $clientname = $st['ClientName'];
        $logofile = strtolower($st['ClientTetrisID']).".jpg";
        $phonenumber = $st['twiliophone'];
        /* Temporary option to disinguish if the account has an encounter in placementgroup 1353 for the URMC lockbox move */
        if(($st['1353'] == null && $st['ClientID'] == '21')){
          $lad1 = "P.O. Box 1079";
          $lad2 = "";
          $ladcity = "Manchester";
          $ladstate = "TN";
          $ladzip = "37349";
        }else{
          $lad1 = $st['lockboxAddress1'];
          $lad2 = $st['lockboxAddress2'];
          $ladcity = $st['lockboxCity'];
          $ladstate = $st['lockboxState'];
          $ladzip = $st['lockboxZip'];
        }
        $portalurl = "https://".strtolower($st['ClientTetrisID']).".patientfocus.com/";
        $rad1 = "PO BOX 291569";
        $rad2 = "";
        $radcity = "Nashville";
        $radstate = "TN";
        $radzip = "37229";
        $fax = '8885511910';
        $email = 'support@patientfocus.com';
        $hours = 'Open Monday - Friday 8am - 6pm Central';
        $file .= "C3|$practicename|$clientname|$logofile|$portalurl|$phonenumber|$lad1|$lad2|$ladcity|$ladstate|$ladzip|$rad1|$rad2|$radcity|$radstate|$radzip|$fax|$email|$hours\r\n";

        /**
            Set the Guarantor Information
        **/
        $gfname = $st['patientfname'];
        $glname = $st['patientlname'];
        $patssn = $st['patientssn'];
        $gmi = $st['patientinitial'];
        if($st['patientdob'] != null){
            $gdob = date('Ymd', strtotime($st['patientdob']));
        }else{
            $gdob = $st['patientdob'];
        }
        if($st['patientdod'] != null){
            $gdod = date('Ymd', strtotime($st['patientdod']));
        }else{
            $gdod = $st['patientdod'];
        }
        $gaddress1 = $st['maddress1'];
        $gaddress2 = $st['maddress2'];
        $gaddress3 = $st['maddress3'];
        $gcity = $st['mcity'];
        $gstate = $st['mstate'];
        $gzip = $st['mzip'];
        $gphonenumber = $st['phonenumber'];

        $file .="G4|$glname|$gmi|$gfname|$gdob|$gaddress1|$gaddress2|$gaddress3|$gcity|$gstate|$gzip|$gphonenumber|0|$patssn\r\n";


        /**
            Set the Patient Information
        **/
            $file .="P5|$glname|$gmi|$gfname|$gdob\r\n";

        /**
            New and old txn info
         */
        //NEW
        if(isset($st['newtxns'][0])){
            foreach($st['newtxns'] as $newtxn){
                if($newtxn['balance'] > 0){
                    $practclaimid = $newtxn['practclaimid'];
                    $type = $newtxn['txntype'];
                    $physicianid = $newtxn['physicianid'];
                    $description = $newtxn['description'];
                    $amount = number_format($newtxn['amount'], 2, '.','');
                    $lefttopay = number_format($newtxn['balance'], 2, '.','');
                    $date =date('Ymd',strtotime($newtxn['date']));

                    $file .= "N6|$practclaimid|$physicianid|$date|$type|$description|$amount|$lefttopay\r\n";
                }
            }
        }
        //OLD
        if(isset($st['oldtxns'][0])){
            foreach($st['oldtxns'] as $oldtxn){
                if($oldtxn['left_to_pay'] > 0){
                    $practclaimid = $oldtxn['encountercode'];
                    $physicianid = ($oldtxn['provider'])?$oldtxn['provider']:"";
                    $description = $oldtxn['description'];
                    $dos = date('Ymd', strtotime($oldtxn['dos']));
                    $charges = number_format($oldtxn['total_charges'],2,'.','');
                    $adjs = number_format($oldtxn['total_adjustments'],2,'.','');
                    $payments  = number_format($oldtxn['total_payments'],2,'.','');
                    $balance = number_format($oldtxn['left_to_pay'],2,'.','');

                    $file .= "A6|$practclaimid|$physicianid|$description|$dos|$charges|$adjs|$payments|$balance\r\n";
                }
            }
        }

        /**
          Are they Elegible for a Payment Plan?  If So, let's add that segment.
        **/
        //krumo($duedate);exit();
        if($stbalance >= '180' && $st['duedate'] == '0'){
            $opt1 = number_format(ceil($stbalance/3),2,'.','');
            $opt2 = number_format(ceil($stbalance/6),2,'.','');
            $opt3 = number_format(ceil($stbalance/9),2,'.','');
            $file .= "O7|$opt1|$opt2|$opt3\r\n";
        }

        /**
          Are they on a Payment PLan?  If So, Let's add that segment.
        **/
        if($st['duedate'] != '0' ){
            //krumo($st);exit();
            $progress = number_format(($planbalance-$stbalance)/$planbalance, 2);
            $remaining = ceil($stbalance/$amountdue);
            $file .= "P8|$amountdue|$progress|$stbalance|$remaining\r\n";
        }

        return $file;
    }

Open in new window


First off, the concern right now is that these "notices" resulted in the failure of the script failing. That's not my impression based on the manual (http://www.php.net/manual/en/errorfunc.constants.php). But still, an "undefined index" seems like it could be a dealbreaker.


"legal_front," "legal_back" etc are all parameters coming from the "StatementParameter" table. "message" is a value in the "parameter" column. In most cases, the "value" column will have a value, but in some there isn't a value. See the screenshot below:

screenshot
Is that where my error is coming from? The fact that I've got some parameters that don't have a corresponding value in the StatementParameter table? Or, is an "undefined index" go deeper than that and I'm contending with something that goes beyond an empty column?
0
Comment
Question by:brucegust
  • 3
  • 3
  • 2
8 Comments
 
LVL 51

Assisted Solution

by:Julian Hansen
Julian Hansen earned 250 total points
ID: 41752593
 $message = $st['parameters']['message'];

Open in new window

The error is saying that the index message does not exist in the parametes array in the $st object.

What you need to do is a var_dump, print_r, var_export of $st at the start of the function - so you can see what the object actually looks like.

Once we have seen what is actually being passed in we can trace it back to where toPipeDelim is called from.

Get us the dump of $st so we can see what it looks like.
0
 
LVL 108

Accepted Solution

by:
Ray Paseur earned 250 total points
ID: 41752618
You may  be running up against some very old and incompetently written PHP programming.  PHP, in its design to be "easy" decided that Notices, which include such things as undefined variables and array indexes, should be suppressed by default.  As a result a lot of novice programmers believed that undefined information "just worked" like the falsy values -- zero, NULL, FALSE, etc.  They never learned that undefined  could also mean unpredictable  and they wrote their programming with the Notice messages turned off, assuming that everything would be OK.

Today, in the 21st century, we don't do that any more.  We find and correct the issues that underlie Notice messages.  We test variables with isset() or empty() to see if they exist before we use them.

Here's my heretical guess at what might give you quick mitigation.  Try setting error_reporting() to the PHP default which is more or less like error_reporting(E_ALL & ~E_NOTICE);.  If the programming was written with the PHP default error_reporting as a baseline assumption, you might find that this change suppresses spurious output, and after that, the script works to produce the PDF.

It may not be necessary to understand  the errors - it may be enough to just make the messages go away.
0
 

Author Comment

by:brucegust
ID: 41752669
Wise counsel...

Stand by...
0
 

Author Comment

by:brucegust
ID: 41752790
Alright, gentlemen, here's what I've got:

First off, a screenshot of the example I've isolated in a sandbox:

severity screenshot
You can see the "var_dump" at the top. It looks like this, just so you don't have to squint:

string(320) "S2|4|0.00|0.00|0.00|0.00|0.00|Due Upon Receipt|08/11/2016|T2067159|12160119|21316-12160119|https://bcmh.patientfocus.com/?=T2067159|Thank you for choosing Barton County Memorial Hospital, Lamar, MO. We hope to serve you again in the future.||black|This statement does not include any accounts with a collection agency. "
A PHP Error was encountered

Severity: Notice

Message: Undefined offset: 17

Filename: StatementImager/StatementImage.php

Line Number: 107

string(0) "" string(438) "We offer a Charity Care Program to assist patients with their account balance. For information on applying or qualifying please call us at 888-551-1910 or email service@patientfocus.|Barton County Memorial Hospital is committed to providing our patients with the best care possible and working with you to arrange payments on all accounts. BCMH is a certified Medicare and Missouri/Kansas Medicaid Provider. Non-approved/covered services," string(308) "C3|Barton County Memorial Hospital|Barton County Memorial Hospital, Lamar, MO|bcmh.jpg|https://bcmh.patientfocus.com/|4172326938|Payment Processing Center|P.O. BOX 305172 DEPT #126|Nashville|TN|37230|PO BOX 291569||Nashville|TN|37229|8885511910|support@patientfocus.com|Open Monday - Friday 8am - 6pm Central" string(72) "G4|STEPHENSON| |PENNY|19700128|700 MADISON| | |GOLDEN CITY|MO|64748| |0|" string(30) "P5|STEPHENSON| |PENNY|19700128" string(0) ""

Open in new window


The "S2" case is the one where an error is being thrown. It breaks down like this:

S2| - case
4| - template id
0.00| - total charges
0.00| - total payments
0.00| - total adjustments
0.00| - balance
0.00| - amount due
Due Upon Receipt| - due date
08/11/2016| - statement date
T2067159| - statement pin
12160119| - account id
21316-12160119| - account number
https://bcmh.patientfocus.com/?=T2067159| - URL
Thank you for choosing Barton County Memorial Hospital, Lamar, MO. We hope to serve you again in the future.| - message
| - last claim date
black| - legal copy color
This statement does not include any accounts with a collection agency. " - legal copy

What's missing, according to the code is at line #107, which is this:

$statement['statement']['legal_copy_back']   = $line[17];

So, there should be something after "legal copy color, " and there's nothing there. I've got to do some digging to see what's actually in the table, but I'm smelling something that says I need to do an "isset" before I attempt to refer to them in order to avoid the errors, correct?
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 108

Expert Comment

by:Ray Paseur
ID: 41752827
I need to do an "isset" before I attempt to refer to them...
Yes, in a perfect world, that is one correct way to write the code.  But this code did not come from a perfect world at all.

My recommendation would be to turn off the reporting of Notice messages.  Then try the script again.  That's an easy step and might provide a quick fix.  You might also want to ask the customer if this script has ever worked correctly!

If Notice suppression does not fix it, or the customer says the script has never worked, then going into the world of isset() -- or providing default values -- is likely to be one of the paths to resolution.
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 41752971
So from the output it looks like you are expecting an array but you are getting a string which indicates that whatever process is calling the function is not preparing the $st parameter correctly.

It looks like you should be parsing the string into an array before sending it to the function.

If this is part of an already working code base then what is different about this situation that the string is not being parsed into the correct array format before being submitted to the function?

You could explode the array and then assign the respective elements to named keys and then pass the result through - but that seems a bit pedestrian for code that should have this base covered already - so I am interested to see the code that does the actual calling of the function.
0
 

Author Comment

by:brucegust
ID: 41760850
Guys, the next day I was able to confirm the script worked fine. It wasn't a PHP / syntax issue. It was a database issue that our DBO was able to remedy. Your counsel helped me be able to talk some of the concerned parties of the ledge and while there may still be some issues that need to be cleaned up, it works and that's the bottom line for now.

Thank you!
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 41760876
You are welcome Bruce,
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Suggested Solutions

Generating table dynamically is the most common issue faced by php developers.... So it seems there is a need of an article that explains the basic concept of generating tables dynamically. It just requires a basic knowledge of html and little maths…
Nothing in an HTTP request can be trusted, including HTTP headers and form data.  A form token is a tool that can be used to guard against request forgeries (CSRF).  This article shows an improved approach to form tokens, making it more difficult to…
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn how to count occurrences of each item in an array.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now