aethelwulffe wrote on Friday, December 23, 2011:
OK,
I re-did my analysis of my 835 file parse_era.inc.php
First, I am not sure how I am supposed to handle repeat segments. I know that segments DO repeat in a claim (designated by a maximum number of repeats allowed for a segment in the standards), but when there are new segments added with the same name (for instance, a series of REF statements in a loop, where there was only one before) and the original code is not looking for an identifier element in the segment, do we need to add ignore code? I am also unsure of how important the sequence of the code the parses the segments is. Our code seems to not be in the same order as the standard, examples of which I will address in my following review.
I can’t color code on this forum, so I will try to bold the few serious questions I would like answered before I post any code. I still have not gotten back a 5010 835 from my test batches sent with my own 5010 code (though the claims have showed up) as the remittances have come back in 4010. I have not yet tested the variant of Rod’s 5010 837 stuff from Patch 5, as I had to do alterations to it last night to get it to work with our X12 partners.
Anywho, here it goes:
835 change notes:
We need to version GS08 (version/release) if we want to continue supporting 4010 standards like we are for 837’s, but this late in the game it seems pretty close to meaningless.
BPR01 has code U and X added, but we don’t parse those anyway.
BPR02 says it has a name change, but that seems to be incorrrect in the documentation, and does not affect us, though we do parse it= Total Actual provider payment Amount S9(8)V99…someone should check the real guide on this just because the comparison docs look funny here.
This next item is the only one that I see that is a real problem other than the simple parsing questions I have:
BPR10, Payer Identifier, which we don’t parse used to equal TRN03. Now TRN03 is not used. We parse BPR and TRN like this:
else if ($segid == 'BPR') {
if ($out['loopid']) return 'Unexpected BPR segment';
$out['check_amount'] = trim($seg[2]);
$out['check_date'] = trim($seg[16]); // yyyymmdd
// TBD: BPR04 is a payment method code.
}
else if ($segid == 'TRN') {
if ($out['loopid']) return 'Unexpected TRN segment';
$out['check_number'] = trim($seg[2]);
$out['payer_tax_id'] = substr($seg[3], 1); // 9 digits
$out['payer_id'] = trim($seg[4]);
// Note: TRN04 further qualifies the paying entity within the
// organization identified by TRN03.
}
I assume we need to parse BPR10 as a replacement for TRN03 like so:
else if ($segid == 'BPR') {
if ($out['loopid']) return 'Unexpected BPR segment';
$out['check_amount'] = trim($seg[2]);
$out['payer_tax_id'] = substr($seg[10], 1); // 9 digits
$out['check_date'] = trim($seg[16]); // yyyymmdd
// TBD: BPR04 is a payment method code.
}
else if ($segid == 'TRN') {
if ($out['loopid']) return 'Unexpected TRN segment';
$out['check_number'] = trim($seg[2]);
$out['payer_id'] = trim($seg[4]);////////////////////////////!!Not used
// Note: TRN04 further qualifies the paying entity within the
// organization identified by TRN03.
}
The two values we are looking for are payer_tax_id and payer_id.
I could use some suggestions as to where we should be getting these two values, and the impact on their usage in the EMR. Furthermore, the EFT and check number can now be up to 50 digits, and we should check to see if we otherwise support that.
Next:
CUR and the first REF segment are parsed in reverse order in the original file. It reads Ref-CUR-REF, and it is really CUR-REF-REF. I don’t know if this hurts anything in a linear process. CUR should never have anything in it, and I have no idea what our treatment of the first Ref segment (Reference Identification is supposed to do for us, except throw an error if there is anything in it. All the same, for multi-site support, perhaps we should consider using the first ref segment so that we can make sure we are loading the era into the correct clinic….unless the data in Loop 1000B N1 N104 is better used.
else if ($segid == 'REF' && $seg[1] == 'EV') {
if ($out['loopid']) return 'Unexpected REF|EV segment';
}
else if ($segid == 'CUR' && ! $out['loopid']) {
if ($seg[3] && $seg[3] != 1.0) {
return("We cannot handle foreign currencies!");
}
}
else if ($segid == 'REF' && ! $out['loopid']) {
// ignore
}
Should we switch these around?
The same sort of thing happens at the end of the 1000A Loop. We now have three PER segments: Payer Business Contact, Payer Technical Contact, and Payer Website. We ignore the original PER segment like so:
else if ($segid == 'PER' && $out['loopid'] == '1000A') {
// TBD: Report payer contact information as a note.
}
Does this need a triple repeat? (I should hope not, but I don’t know much about parsing text files with php) Should we store/report or log the contact info for biller troubleshooting? In Loop 2100 PER we do have some warnings code that lists claim contact info, but I don’t know how effective that is.
At the end of loop 1000B there is a new segment RDM, Remittance Delivery Method. Unless there is a use for this, I suggest ignoring it like so:
else if ($segid == 'RDM' && $out['loopid'] == '1000B') {
// Used to report delivery method. Ignored.
}
NEXT: Loop 2000
We ignore segment TS2, but according to the documentation it comes after TS3, do we need to re-order?:
else if ($segid == 'TS2' && $out['loopid'] == '2000') {
// ignore
}
LOOP 2100:
CLP02 has some claim status codes deleted. Now only 1,2,3,4,19,20,21,22, and 23 are used. How does this affect us?
CLP07 limit increased to 50 characters. This loads to payer_claim_id. We parse this. Will this affect us anywhere?
First CAS element used to just have one adjustment reason, code, and amount. Some reason codes were deleted. Now it allows for six different adjustments per claim (up to CAS19). In my code, I have not added anything here. I could really use a wiser head here on how we should treat this. Should they be parsed, added, and then all the adjustment reasons stored and reported sequentially? How will this affect the payments module? parse_era_2100() is supposed to attend to stuff here, and I don’t think I understand enough about the underlying system.
NM1 NM103/104 patient name fields have increased to 60/35 characters, which we trim. Will this affect us?
DTM- There are now 4 DTM segments. We ignore the original. Code changes needed to ignore the new ones? I once again suppose and hope not, but since this section gives us coverage data, I think it is really foolish not to put some effort into using it if payers are providing it.
Second CAS element (Service Adjustment) pops out warning to us about contractual Obligation differences. There seems to be a lot of this going on, and perhaps we need to get some better reporting into the payments module along with the payer contact data, Ja?
There are two new REF segments:
1. Service identification REF segment that gives us a line item control number supporting the above. This relates to data we could send with the 837 regarding this, and may help with reporting for the Service Adjustment. There is no value listed for the reference ID Qualifier for this REF segment, unlike the next one (same as the 4010 Rendering Provider Information) which is identified with ‘HPI’, and the second new one identified with ‘0K’ (Zero Kilo). Currently we ignore the Ref segment, but now there are three, which brings back the question of how/if the repeated segments are handled, i.e.:
else if ($segid == 'REF' && $out['loopid'] == '2110') {
// ignore
}
Finally, Segment PLB is out of order. It is shown to be after LQ Once again, I wonder if these Provider Level Adjustments should be better reported than just in the warnings in the HTML report.