5 * Copyright 2016 Kevin McCormick Carrollton, Texas
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; version 3 or later. You should have
16 * received a copy of the GNU General Public License along with this program;
17 * if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 * <http://opensource.org/licenses/gpl-license.php>
23 * @link: http://www.open-emr.org
28 * EDI files may contain multiple ISA envelopes. Each ISA envelope is treated as a "file" here.
29 * The same file name may have one or more ISA control numbers
30 * The ISA control number is associated with each GS and ST envelope and each included transaction.
31 * Each transaction will also link to the ISA control number as a means of retrieving the file.
33 * The CSV data column headers are the array keys for each EDI file type.
37 * Provide a more user-friendly date in csv tables
39 * @param string YYYYMMDD
40 * @return string YYYY-MM-DD
42 function edih_parse_date($strdate) {
43 if (strlen($strdate) == 6) {
45 $cy = (string)$gtdt['year'];
46 $dt1 = substr($cy, 0, 2) . $strdate;
47 } elseif (strpos($strdate, '-') >= 6) {
48 $dt1 = substr($strdate, 0, strpos($strdate, '-') - 1 );
49 } elseif (strlen($strdate) == 8) {
53 csv_edihist_log('edih_parse_date: invalid argument '.$strdate);
57 return substr($dt1, 0, 4) . '-' . substr($dt1, 4, 2) . '-' . substr($dt1, 6, 2);
60 /** remittance 835 files
62 * Each payment trace number (Control) gets a row in the csv file record.
63 * Each claim payment transaction gets a row in the csv claim record
68 * [$icn]['file'][$i] => array keys match csv_table_head() output
69 * [$icn]['claim'][$i] => array keys match csv_table_head() output
73 * @uses csv_file_type()
74 * @uses edih_parse_date()
75 * @uses edih_x12_transaction()
76 * @uses edih_get_segment()
77 * @param object edih_x12_obj
80 function edih_835_csv_data($obj835) {
84 $seg_ar = $obj835->edih_segments();
85 $env_ar = $obj835->edih_envelopes();
86 $de = $obj835->edih_delimiters()['e'];
87 $fn = $obj835->edih_filename();
88 //$tp = $obj835->edih_type();
90 // since 835 "files" table uses transaction trace as the "Control"
91 // we must assemble the 'files' array in the ST loop
93 foreach($env_ar['ISA'] as $icn => $isa) {
95 $ret_ar[$icn]['claim'] = array();
96 $ret_ar[$icn]['file'] = array();
101 if ( array_key_exists('GS', $env_ar) ) {
102 // for unlikely case of 'mixed' GS types in file
103 foreach($env_ar['GS'] as $gs) {
104 if ($gs['icn'] == $icn) {
106 $gsdate = $gs['date'];
107 $payer_id = $gs['srcid']; // from TRN03
112 $ret_ar[$icn]['type'] = csv_file_type($ft);
113 $gsdate = ($gsdate) ?
$gsdate : edih_parse_date($isa['date']);
115 $fdx = count($ret_ar[$icn]['file']);
117 // ['ST'][$stky]=>['start']['count']['stn']['gsn']['icn']['type']['trace']['acct']
118 // ['ST'][$stky]['acct'][i]=>pid-enc$$ret_ar[$icn]['claim'][$cdx]['SvcDate'] =
119 foreach($env_ar['ST'] as $st) {
120 if ($st['icn'] != $icn) { continue; }
121 // the "files" table has a row for each payment trace
123 if ($trace != $st['trace']) {
124 $fdx = count($ret_ar[$icn]['file']);
126 $ret_ar[$icn]['file'][$fdx]['Date'] = $gsdate;
127 $ret_ar[$icn]['file'][$fdx]['FileName'] = $fn;
128 $ret_ar[$icn]['file'][$fdx]['Control'] = (string)$icn;
129 $ret_ar[$icn]['file'][$fdx]['Trace'] = $st['trace'];
130 $ret_ar[$icn]['file'][$fdx]['Claim_ct'] = (string)count($st['acct']);
131 $ret_ar[$icn]['file'][$fdx]['Denied'] = 0;
132 $ret_ar[$icn]['file'][$fdx]['Payer'] = $payer_id;
134 $trace = $st['trace'];
137 $stsegs = array_slice($seg_ar, $st['start'], $st['count']);
138 $stacct = array_values(array_unique($st['acct']));
139 $clmct = count($stacct);
143 $n1pr = $obj835->edih_get_segment('N1', 'N1'.$de.'PR'.$de, $stsegs);
146 foreach($n1pr as $n1) {
147 $sar = explode($de, $n1);
148 $payer = (isset($sar[2])) ?
$sar[2] : '';
150 if ($payer) { $ret_ar[$icn]['file'][$fdx]['Payer'] = $payer; }
154 for($i=0; $i<$clmct; $i++
) {
155 $clpsegs = $obj835->edih_x12_transaction($stacct[$i], $st['stn']);
156 if ( !is_array($clpsegs) ||
!count($clpsegs) ) {
158 csv_edihist_log('edih_835_csv_data: no segments for account '.$st['acct'][$i]);
162 foreach($clpsegs as $trans) {
164 $cdx = count($ret_ar[$icn]['claim']);
165 foreach($trans as $seg) {
167 if (strncmp($seg, 'CLP'.$de, 4) === 0) {
168 $sar = explode($de, $seg);
170 $ret_ar[$icn]['claim'][$cdx]['CLM01'] = (isset($sar[1])) ?
$sar[1] : '';
171 $ret_ar[$icn]['claim'][$cdx]['Status'] = (isset($sar[2])) ?
$sar[2] : '';
172 $ret_ar[$icn]['claim'][$cdx]['Pmt'] = (isset($sar[4])) ?
sprintf("%01.02f", $sar[4]) : '';
173 $ret_ar[$icn]['claim'][$cdx]['PtResp'] = ( isset($sar[5]) ) ?
sprintf("%01.02f", $sar[5]) : '';
174 $ret_ar[$icn]['claim'][$cdx]['ClaimID'] = ( isset($sar[7]) ) ?
trim($sar[7]) : '';
175 $ret_ar[$icn]['claim'][$cdx]['FileName'] = $fn;
176 $ret_ar[$icn]['claim'][$cdx]['Trace'] = $st['trace'];
177 $ret_ar[$icn]['claim'][$cdx]['Payer'] = $payer;
178 $ret_ar[$icn]['claim'][$cdx]['PtName'] = '';
179 $ret_ar[$icn]['claim'][$cdx]['SvcDate'] = '';
181 if($sar[2]=='4' ||
$sar[2]=='22' ||
$sar[2]=='23') { $denied++
; }
186 if (strncmp($seg, 'NM1'.$de.'QC'.$de, 7) === 0) {
187 $sar = explode($de, $seg);
188 $midn = ( isset($sar[5]) && strlen($sar[5]) ) ?
', '.$sar[5]: "";
189 $ret_ar[$icn]['claim'][$cdx]['PtName'] = $sar[3].', '.$sar[4].$midn;
192 if (strncmp($seg, 'DTM'.$de.'232'.$de, 8) === 0) {
193 $sar = explode($de, $seg);
194 $ret_ar[$icn]['claim'][$cdx]['SvcDate'] = $sar[2];
197 if (strncmp($seg, 'DTM'.$de.'472'.$de, 8) === 0) {
198 $sar = explode($de, $seg);
199 $ret_ar[$icn]['claim'][$cdx]['SvcDate'] = $sar[2];
202 } // end foreach($trans as $seg)
203 } // end foreach($clpsegs as $trans) {
204 } // end for($i=0; $i<$clmct; $i++)
206 $ret_ar[$icn]['file'][$fdx]['Denied'] = ($denied) ?
$denied : '0';
208 } // end foreach($env_ar['ST'] as $st)
210 } // end foreach($env_ar['ISA'] as $icn => $isa)
217 * Parse csv data from 837 files
218 * Note that this can return false provider values for extensive claims
219 * since loops are not tracked and 837 claims can have numerous
220 * providers, but probably not an issue for OpenEMR
222 * @param object edih_x12_ file object
223 * @return array data to write csv file and csv clain table rows
225 function edih_837_csv_data($obj837) {
229 $seg_ar = $obj837->edih_segments();
230 $env_ar = $obj837->edih_envelopes();
231 $de = $obj837->edih_delimiters()['e'];
232 $fn = $obj837->edih_filename();
233 //$ft = csv_file_type( $obj837->edih_type() );
235 if ( !isset($env_ar['ST']) ) {
236 csv_edihist_log('edih_837_csv_data: envelope error');
239 //['file'] = array('Date', 'FileName', 'Control', 'Claim_ct', 'x12_partner');
241 // array('PtName', 'SvcDate', 'CLM01', 'InsLevel', 'Control', 'File_837', 'Fee', 'PtPaid', 'Provider' );
243 foreach($env_ar['ISA'] as $icn => $isa) {
245 $ret_ar[$icn]['claim'] = array();
246 $ret_ar[$icn]['file'] = array();
247 //$ret_ar[$icn]['type'] = $ft;
248 foreach($env_ar['GS'] as $gs) {
249 if ($gs['icn'] == $icn) {
250 $ret_ar[$icn]['type'] = csv_file_type( $gs['type'] );
251 $gsdate = $gs['date'];
256 $fdx = count($ret_ar[$icn]['file']);
258 $ret_ar[$icn]['file'][$fdx]['Date'] = (string)$gsdate;
259 $ret_ar[$icn]['file'][$fdx]['FileName'] = $fn;
260 // if GS06 were unique, it could be used as the 'Control'
261 $ret_ar[$icn]['file'][$fdx]['Control'] = (string)$icn;
262 $ret_ar[$icn]['file'][$fdx]['x12Partner'] = (string)$isa['receiver'];
266 foreach($env_ar['ST'] as $st) {
267 // claims should be in the correct ISA envelope
268 if ( $st['icn'] != $icn ) { continue; }
270 $stsegs = array_slice($seg_ar, $st['start'], $st['count']);
271 $stacct = array_values(array_unique($st['acct']));
272 $clmct = count($stacct);
273 // $st['icn'] is the ISA control number for the ISA envelope containing the ST--SE
274 $date = $env_ar['ISA'][$st['icn']]['date'];
276 for($i=0; $i<$clmct; $i++
) {
277 //echo '=== ACCT '.$stacct[$i].' '.$st['stn'].'<br />'.PHP_EOL;
278 $asegs = $obj837->edih_x12_transaction($stacct[$i], $st['stn']);
279 if ( !is_array($asegs) ||
!count($asegs) ) {
280 csv_edihist_log('edih_837_csv_data: no segments for account '.$st['acct'][$i]);
283 foreach($asegs as $trans) {
285 //array('PtName'=>0, 'SvcDate'=>1, 'CLM01'=>2, 'InsLevel'=>3, 'Control'=>4, 'FileName'=>5, 'Fee'=>6, 'PtPaid'=>7, 'Provider'=>8 );
287 //'f837': $hdr = array('PtName', 'SvcDate', 'CLM01', 'InsLevel', 'Control', 'FileName', 'Fee', 'PtPaid', 'Provider' )
288 foreach($trans as $seg) {
289 if ( strncmp($seg, 'BHT'.$de, 4) === 0 ) {
290 $cdx = count($ret_ar[$icn]['claim']);
291 $sar = explode($de, $seg);
296 $ret_ar[$icn]['claim'][$cdx]['PtName'] = '';
297 $ret_ar[$icn]['claim'][$cdx]['SvcDate'] = '';
298 $ret_ar[$icn]['claim'][$cdx]['CLM01'] = '';
299 $ret_ar[$icn]['claim'][$cdx]['InsLevel'] = '';
301 $ret_ar[$icn]['claim'][$cdx]['BHT03'] = (strlen($bht03) == 13) ?
$bht03 : sprintf("%s%04d", $st['icn'], $st['stn']);
302 $ret_ar[$icn]['claim'][$cdx]['FileName'] = $fn;
304 $ret_ar[$icn]['claim'][$cdx]['Fee'] = '0';
305 $ret_ar[$icn]['claim'][$cdx]['PtPaid'] = '0';
306 $ret_ar[$icn]['claim'][$cdx]['Provider'] = '';
308 if (strncmp($seg, 'HL'.$de, 3) === 0 ) {
309 $sar = explode($de, $seg);
314 if ( intval($hl) == 20 ) {
315 if ( strncmp($seg, 'NM1'.$de, 4) === 0 ) {
316 $sar = explode($de, $seg);
317 if ($sar[2] == '82' ||
$sar[2] == '85') {
318 $ret_ar[$icn]['claim'][$cdx]['Provider'] = $sar[9];
322 } // end if $hl == '20'
324 if ( intval($hl) >= 22 ) {
325 if ( strncmp($seg, 'SBR'.$de, 4) === 0 ) {
326 $sar = explode($de, $seg);
327 $ret_ar[$icn]['claim'][$cdx]['InsLevel'] = $sar[1];
329 if ( strncmp($seg, 'CLM'.$de, 4) === 0 ) {
330 $sar = explode($de, $seg);
331 $ret_ar[$icn]['claim'][$cdx]['CLM01'] = $sar[1];
332 $ret_ar[$icn]['claim'][$cdx]['Fee'] = $sar[2];
335 if ( strncmp($seg, 'AMT'.$de.'F5'.$de, 7) === 0 ) {
336 $sar = explode($de, $seg);
337 $ret_ar[$icn]['claim'][$cdx]['PtPaid'] = $sar[2];
340 if ( strncmp($seg, 'NM1'.$de, 4) === 0 ) {
341 $sar = explode($de, $seg);
342 if ( strpos('|IL|QC', $sar[1]) ) {
343 $midn = ( isset($sar[5]) && strlen($sar[5]) ) ?
', '.$sar[5]: '';
344 $ret_ar[$icn]['claim'][$cdx]['PtName'] = $sar[3].', '.$sar[4].$midn;
347 if ( $sar[1] == '82') {
348 $ret_ar[$icn]['claim'][$cdx]['Provider'] = $sar[9];
352 if ( strncmp($seg, 'DTP'.$de.'472'.$de, 8) === 0 ) {
353 $sar = explode($de, $seg);
354 $ret_ar[$icn]['claim'][$cdx]['SvcDate'] = $sar[3];
357 } // end if $hl >= '22'
358 } // end foreach($trans as $seg)
359 } // end foreach($asegs as $trans)
360 } // end for($i=0; $i<$clmct; $i++)
361 } // end foreach($obj837->envelopes['ST'] as $st)
363 $ret_ar[$icn]['file'][$fdx]['Claim_ct'] = (string)$clm_ct;
364 } // end foreach($env_ar['ISA'] as $icn => $isa)
370 * extract csv table row data for x12 277 files
372 * @param object edih_x12_file object of type 276/277
375 function edih_277_csv_data($obj277) {
379 $seg_ar = $obj277->edih_segments();
380 $env_ar = $obj277->edih_envelopes();
381 $de = $obj277->edih_delimiters()['e'];
382 $fn = $obj277->edih_filename();
383 $tp = $obj277->edih_type();
384 // 'HN' 277 'HR' 276 )
385 $env_ar = $obj277->edih_envelopes();
387 if ( !isset($env_ar['ST']) ) {
388 csv_edihist_log( 'edih_277_csv_data: envelope error');
391 if ( !isset($env_ar['GS']) ) {
392 csv_edihist_log('edih_277_csv_data: envelope error');
396 foreach($env_ar['ISA'] as $icn => $isa) {
398 $ret_ar[$icn]['claim'] = array();
399 $ret_ar[$icn]['file'] = array();
401 $rspdate = $isa['date'];
402 foreach($env_ar['GS'] as $gs) {
403 if ($gs['icn'] == $icn) {
404 $ret_ar[$icn]['type'] = csv_file_type($gs['type']);
405 $rspdate = $gs['date'];
409 //$ret_ar[$icn]['type'] = csv_file_type($ft);
411 $fdx = count($ret_ar[$icn]['file']);
412 //['f277']['file'] = array('Date', 'FileName', 'Control', 'Accept', 'AccAmt', 'Reject', 'RejAmt');
413 //'f276': $hdr = array('Date', 'FileName', 'Control', 'Claim_ct', 'x12Partner');
414 $ret_ar[$icn]['file'][$fdx]['Date'] = $rspdate;
415 $ret_ar[$icn]['file'][$fdx]['FileName'] = $fn;
416 // could be GS06 for 276 if it were unique
417 $ret_ar[$icn]['file'][$fdx]['Control'] = (string)$icn;
419 $ret_ar[$icn]['file'][$fdx]['Accept'] = 0;
420 $ret_ar[$icn]['file'][$fdx]['Reject'] = 0;
421 $ret_ar[$icn]['file'][$fdx]['AccAmt'] = 0;
422 $ret_ar[$icn]['file'][$fdx]['RejAmt'] = 0;
424 $ret_ar[$icn]['file'][$fdx]['Claim_ct'] = 0;
425 $ret_ar[$icn]['file'][$fdx]['x12Partner'] = $isa['receiver'];
430 //['ST'][$stky]=>['start']['count']['stn']['gsn']['icn']['type']['trace']['acct']
431 // ['ST'][$stky]['acct'][i]=>pid-enc
432 //'f277': $hdr = array('PtName', 'SvcDate', 'CLM01', 'Status', 'BHT03', 'FileName', 'Payer', 'Trace');
433 foreach($env_ar['ST'] as $st) {
435 if ( $st['icn'] != $icn ) { continue; }
437 $stsegs = array_slice($seg_ar, $st['start'], $st['count']);
438 $stacct = array_values(array_unique($st['bht03']));
439 $clmct +
= count($stacct);
440 $st_icn = $st['icn']; // same value as $obj277->envelopes['ISA']['icn']
443 if ($tp == 'HR') { $ret_ar[$icn]['file'][$fdx]['Claim_ct'] = $clmct; }
445 //for($i=0; $i<$clmct; $i++) {
446 for($i=0; $i<count($stacct); $i++
) {
448 $asegs = $obj277->edih_x12_transaction($stacct[$i]);
450 foreach($asegs as $trans) {
452 foreach($trans as $seg) {
454 if ( strncmp($seg, 'BHT'.$de, 4) === 0) {
455 $cdx = count($ret_ar[$icn]['claim']);
457 $sar = explode($de, $seg);
458 if ( $sar[2] != '08' ) {
459 csv_edihist_log('Claim Status BHT purpose code: '.$sar[2].' in ST '.$st['stn'].' in file '.$fn);
461 $trns_tp = (isset($sar[6]) && $sar[6]) ?
$sar[6] : '';
462 if ($trns_tp == 'TH') {
463 $bht_id = 'ack'; // 277CA
464 } elseif($trns_tp == 'DG') {
465 $bht_id = 'rsp'; // 277
467 $bht_id = 'sub'; // 276
470 $ret_ar[$icn]['claim'][$cdx]['PtName'] = '';
471 $ret_ar[$icn]['claim'][$cdx]['SvcDate'] = '';
472 $ret_ar[$icn]['claim'][$cdx]['CLM01'] = '';
476 $ret_ar[$icn]['claim'][$cdx]['Status'] = '';
477 $ret_ar[$icn]['claim'][$cdx]['BHT03'] = $sar[3];
478 } elseif ($tp == 'HR') {
480 $ret_ar[$icn]['claim'][$cdx]['ClaimID'] = '';
481 $ret_ar[$icn]['claim'][$cdx]['BHT03'] = sprintf("%s%04d", $st_icn, $stn);
485 $ret_ar[$icn]['claim'][$cdx]['FileName'] = $fn;
487 $ret_ar[$icn]['claim'][$cdx]['Payer'] = '';
488 //$ret_ar[$icn]['claim'][$cdx]['Ins_ID'] = '';
489 $ret_ar[$icn]['claim'][$cdx]['Trace'] = '';
493 if ( strncmp($seg, 'HL'.$de, 3) === 0) {
494 $sar = explode($de, $seg);
495 $hl = (string)$sar[3];
499 // information source
500 if ( strncmp($seg, 'NM1'.$de, 4) === 0) {
501 $sar = explode($de, $seg);
502 $ret_ar[$icn]['claim'][$cdx]['Payer'] = ($sar[1]=='PR' ||
$sar[1]=='AY') ?
$sar[3] : '';
508 // information source or receiver level rejection
509 // -- user should view the transaction
510 // -- don't include in csv data so Trace only refers to 276
511 //if ( strncmp($seg, 'TRN'.$de, 4) === 0) {
512 //$sar = explode($de, $seg);
513 //$ret_ar[$icn]['claim'][$cdx]['Trace'] = $sar[2];
515 if ( strncmp($seg, 'STC'.$de, 4) === 0) {
516 $sar = explode($de, $seg);
517 $ret_ar[$icn]['claim'][$cdx]['Status'] = $sar[1];
519 if ( strncmp($seg, 'QTY'.$de, 4) === 0) {
520 $sar = explode($de, $seg);
521 if ( $sar[1] == '90' ) { $ret_ar[$icn]['file'][$fdx]['Accept'] +
= $sar[2]; }
522 if ( $sar[1] == 'AA' ) { $ret_ar[$icn]['file'][$fdx]['Reject'] +
= $sar[2]; }
524 if ( strncmp($seg, 'AMT'.$de, 4) === 0) {
525 $sar = explode($de, $seg);
526 if ( $sar[1] == 'YU' ) { $ret_ar[$icn]['file'][$fdx]['AccAmt'] +
= $sar[2]; }
527 if ( $sar[1] == 'YY' ) { $ret_ar[$icn]['file'][$fdx]['RejAmt'] +
= $sar[2]; }
533 // provider level rejection
534 // -- user should view the transaction
535 // -- don't include in csv data so Trace only refers to 276
536 //if ( strncmp($seg, 'TRN'.$de, 4) === 0) {
537 //$sar = explode($de, $seg);
538 //$ret_ar[$icn]['claim'][$cdx]['Trace'] = $sar[2];
540 if ( strncmp($seg, 'STC'.$de, 4) === 0) {
541 $sar = explode($de, $seg);
542 $ret_ar[$icn]['claim'][$cdx]['Status'] = $sar[1];
547 if ( $hl == '22' ||
$hl == '23' ) {
548 // subscriber or dependent
549 if ( strncmp($seg, 'NM1'.$de, 4) === 0) {
550 $sar = explode($de, $seg);
551 if ( $sar[1] == 'IL' ||
$sar[1] == 'QC' ) {
552 $midn = ( isset($sar[5]) && strlen($sar[5]) ) ?
', '.$sar[5]: "";
553 $ret_ar[$icn]['claim'][$cdx]['PtName'] = $sar[3].', '.$sar[4].$midn;
554 //if (isset($sar[8]) && $sar[8] == 'MI') {
555 //$ret_ar[$icn]['claim'][$cdx]['Ins_ID'] = (isset($sar[9])) ? $sar[9] : '';
560 // in response to 276, this is the reference given in TRN02
561 if ( strncmp($seg, 'TRN'.$de.'2'.$de, 4) === 0) {
562 $sar = explode($de, $seg);
563 $ret_ar[$icn]['claim'][$cdx]['Trace'] = $sar[2];
566 // REF*EJ* will give the payer assigned claim number
567 // not used much in 277CA files
568 if ( strncmp($seg, 'REF'.$de.'EJ'.$de, 7) === 0) {
569 $sar = explode($de, $seg);
570 $ret_ar[$icn]['claim'][$cdx]['CLM01'] = $sar[2];
573 if ( strncmp($seg, 'REF'.$de.'1K'.$de, 7) === 0) {
574 // hopefully OpenEMR will include the claim number in 276
576 $sar = explode($de, $seg);
577 $ret_ar[$icn]['claim'][$cdx]['ClaimID'] = $sar[2];
581 // REF*D9*(Claim number)~
583 if ( strncmp($seg, 'STC'.$de, 4) === 0) {
584 // STC is only present in 277
585 $sar = explode($de, $seg);
586 $ret_ar[$icn]['claim'][$cdx]['Status'] = $sar[1];
594 if ( strncmp($seg, 'NM1'.$de, 4) === 0) {
595 $sar = explode($de, $seg);
596 if ( $sar[1] == 'IL' ||
$sar[1] == 'QC' ) {
597 $midn = ( isset($sar[5]) && strlen($sar[5]) ) ?
', '.$sar[5]: "";
598 $ret_ar[$icn]['claim'][$cdx]['PtName'] = $sar[3].', '.$sar[4].$midn;
599 //$ret_ar[$icn]['claim'][$cdx]['Ins_ID'] = (isset($sar[9])) ? $sar[9] : '';
603 if ( strncmp($seg, 'TRN'.$de.'2'.$de, 6) === 0) {
604 $sar = explode($de, $seg);
605 $ret_ar[$icn]['claim'][$cdx]['CLM01'] = $sar[2];
609 if ( strncmp($seg, 'STC'.$de, 4) === 0) {
610 $sar = explode($de, $seg);
611 $ret_ar[$icn]['claim'][$cdx]['Status'] = $sar[1];
614 //if ( strncmp($seg, 'REF'.$de.'1K'.$de, 7) === 0) {
615 //$sar = explode($de, $seg);
616 //$ret_ar[$icn]['claim'][$cdx]['ClaimID'] = $sar[2];
619 if ( strncmp($seg, 'DTP'.$de.'472'.$de, 8) === 0) {
620 $sar = explode($de, $seg);
621 // D8-CCYYMMDD RD8-CCYYMMDD-CCYYMMDD only take initial date
622 $ret_ar[$icn]['claim'][$cdx]['SvcDate'] = substr($sar[3],0,8);
626 } // end foreach($trans as $seg)
627 } // end foreach($asegs as $trans)
628 } // end for($i=0; $i<$clmct; $i++)
629 }// end foreach($obj277->envelopes['ST'] as $st)
630 } // end foreach($env_ar['ISA'] as $icn => $isa)
636 * parse an x12 278 file into data rows for csv tables
638 * @param object x12_file_object
641 function edih_278_csv_data($obj278) {
643 // f278 file = array('Date', 'FileName', 'Control', 'TrnCount', 'Auth', 'Payer');
644 // f278 claim = array('PtName', 'FileDate', 'Trace', 'Status' 'BHT03', 'FileName', 'Auth', 'Payer');
648 $de = $obj278->edih_delimiters()['e'];
649 $ds = $obj278->edih_delimiters()['s'];
650 $fn = $obj278->edih_filename();
651 $seg_ar = $obj278->edih_segments();
652 $env_ar = $obj278->edih_envelopes();
653 $ft = csv_file_type( $obj278->edih_type() );
656 if ( !isset($env_ar['ST']) ) {
657 csv_edihist_log('edih_278_csv_data: envelope error '.$fn);
661 if ( !isset($env_ar['GS']) ) {
662 csv_edihist_log('edih_278_csv_data: envelope error '.$fn);
666 foreach($env_ar['ISA'] as $icn => $isa) {
667 // array('Date', 'FileName', 'Control', 'ta1ctrl', 'RejCt');
668 $ret_ar[$icn]['type'] = $ft;
669 $ret_ar[$icn]['claim'] = array();
670 $ret_ar[$icn]['file'] = array();
671 $rspdate = $isa['date'];
673 foreach($env_ar['GS'] as $gs) {
674 if ($gs['icn'] == $icn) {
675 $rspdate = $gs['date'];
679 foreach($env_ar['ST'] as $st) {
681 if ( $st['icn'] != $icn ) { continue; }
683 $stsegs = array_slice($seg_ar, $st['start'], $st['count']);
686 //$isasender = $env_ar['ISA'][$st['icn']]['sender'];
687 //$isadate = $env_ar['ISA'][$st['icn']]['date'];
688 $isaicn = $st['icn'];
693 foreach($stsegs as $seg) {
695 if (strncmp($seg, 'BHT'.$de, 4) === 0 ) {
697 // bht01 0007 --> Src, Rcv, Sbr, Dep, Event, Services
700 $cdx = count($ret_ar[$icn]['claim']);
702 $sar = explode($de, $seg);
703 if ( isset($sar[2]) ) {
704 if ($sar[2] == '01') { $rqst = 'Cancel'; }
705 if ($sar[2] == '13') { $rqst = 'Req'; }
706 if ($sar[2] == '11') { $rqst = 'Rsp'; }
707 if ($sar[2] == '36') { $rqst = 'Reply'; }
711 $ret_ar[$icn]['claim'][$cdx]['PtName'] = '';
712 $ret_ar[$icn]['claim'][$cdx]['FileDate'] = $rspdate;
713 $ret_ar[$icn]['claim'][$cdx]['Trace'] = '';
714 $ret_ar[$icn]['claim'][$cdx]['Status'] = '';
715 $ret_ar[$icn]['claim'][$cdx]['BHT03'] = $sar[3]; //bht03 = $sar[3];
716 $ret_ar[$icn]['claim'][$cdx]['FileName'] = $fn;
717 $ret_ar[$icn]['claim'][$cdx]['Auth'] = $rqst;
718 $ret_ar[$icn]['claim'][$cdx]['Payer'] = '';
723 if (strncmp($seg, 'HL'.$de, 3) === 0 ) {
724 $sar = explode($de, $seg);
726 $hlpc = $sar[2]; // parent code
728 $hlcc = (isset($sar[4])) ?
$sar[4] : ''; // child code
729 if ($sar[3] == '20') { // level code
730 $loopid = '2000A'; // info source (payer)
731 } elseif ($sar[3] == '21') {
732 $loopid = '2000B'; // info receiver (clinic)
733 } elseif ($sar[3] == '22') {
734 $loopid = '2000C'; // subscriber
735 } elseif ($sar[3] == '23') {
736 $loopid = '2000D'; // dependent
737 } elseif ($sar[3] == 'EV') {
738 $loopid = '2000E'; // patient event
739 } elseif ($sar[3] == 'SS') {
740 $loopid = '2000F'; // service
743 csv_edihist_log('HL has no level '.$seg.' in '.$fn);
748 if (strncmp($seg, 'NM1'.$de, 4) === 0 ) {
749 $sar = explode($de, $seg);
752 $nm103 = ($sar[4]) ?
$nm103.', '.$sar[4] : $nm103;
753 $nm103 = ($sar[5]) ?
$nm103.' '.$sar[5] : $nm103;
754 if ($loopid == '2000A') {
755 $ret_ar[$icn]['claim'][$cdx]['Payer'] = $nm103; //
756 $payer_name = $nm103;
757 } elseif ( $loopid == '2000C' ) {
758 $ret_ar[$icn]['claim'][$cdx]['PtName'] = $nm103; //$ptname = $nm1;
760 } elseif ( $loopid == '2000D') {
761 $ret_ar[$icn]['claim'][$cdx]['PtName'] = $nm103; //$ptname = $nm1;
763 } elseif ( strpos( '|2000E',$loopid) ) {
765 $loopid = (strpos('|71|72|73|77|AAJ|DD|DK|DN|FA|G3|P3|QB|QV|SJ', $nm101) ) ?
'2010EA' : $loopid;
766 $loopid = (strpos('|45|FS|ND|PW|R3', $nm101) ) ?
'2010EB' : $loopid;
767 $loopid = ($nm101 == 'L5') ?
'2010EC' : $loopid;
768 } elseif ( $loopid == '2000F' ) {
770 $loopid = (strpos('|71|72|73|77|AAJ|DD|DK|DN|FA|G3|P3|QB|QV|SJ', $nm101) ) ?
'2010FA' : $loopid;
774 // for 278 eligibility response (invalid data in 278 request)
775 if (strncmp($seg, 'AAA'.$de, 4) === 0 ) {
776 $sar = explode($de, $seg);
781 if ($loopid == '2000A') {
782 $status .= ' Src '.$aaa_code;
783 } elseif ($loopid == '2000B') {
784 $status .= ' Rcv '.$aaa_code;
785 } elseif ($loopid == '2000C') {
786 $status .= ' Sbr '.$aaa_code;
787 } elseif ($loopid == '2000D') {
788 $status .= ' Dep '.$aaa_code;
789 } elseif ($loopid == '2000E') {
790 $status .= ' Pt '.$aaa_code;
791 } elseif ($loopid == '2000F') {
792 $status .= ' Svc '.$aaa_code;
793 } elseif ($loopid == '2010FA') {
794 $status .= ' Prv '.$aaa_code;
795 } elseif ($loopid == '2010EA') {
796 $status .= ' Svc '.$aaa_code;
797 } elseif ($loopid == '2010EC') {
798 $status .= ' Tpt '.$aaa_code;
801 $ret_ar[$icn]['claim'][$cdx]['Status'] = $status;
807 // this assumes OpenEMR will include a TRN segment in requests
808 if (strncmp($seg, 'TRN'.$de, 4) === 0 ) {
809 $sar = explode($de, $seg);
810 if ($rqst == 'Req') {
811 if ( isset($sar[1]) && $sar[1] == '1') {
812 $ret_ar[$icn]['claim'][$cdx]['Trace'] = (isset($sar[2])) ?
$sar[2] : '';
815 if ( isset($sar[1]) && $sar[1] == '2') {
816 $ret_ar[$icn]['claim'][$cdx]['Trace'] = (isset($sar[2])) ?
$sar[2] : '';
821 } // end foreach($stsegs as $seg)
823 } // endforeach($env_ar['ST'] as $st
824 $fdx = count($ret_ar[$icn]['file']);
826 $ret_ar[$icn]['file'][$fdx]['Date'] = $rspdate;
827 $ret_ar[$icn]['file'][$fdx]['FileName'] = $fn;
828 // could be GS06 for 278 request type
829 $ret_ar[$icn]['file'][$fdx]['Control'] = $icn;
830 $ret_ar[$icn]['file'][$fdx]['TrnCount'] = $cdx;
831 $ret_ar[$icn]['file'][$fdx]['Auth'] = $rqst;
832 $ret_ar[$icn]['file'][$fdx]['Payer'] = $payer_name;
834 } // endforeach($env_ar['ISA'] as $icn=>$isa)
841 * Obtain claim information from batch 837|270|276|278 file to match 997/999 response
842 * Note, we assume each batch ST envelope contains a single transaction.
843 * Manual inspection is required if more than one transaction in an ST block,
845 * The 997/999 parse script creates a BHT03 reference by concatenating the
846 * response ISA13 (in TA1 segment) and the ST02 from the AK2 segment
847 * return array ['pt_name'] ['clm01'] ['svcdate'] ['batch_name'] ['stn']
849 * @uses csv_file_type()
850 * @uses csv_search_record()
852 * @param string concatenate ISA13 and ST02 for source file
853 * @param string type of source file
856 function edih_rsp_st_match($rsp_trace, $file_type) {
860 if ( strlen($rsp_trace) == 13 ) {
861 $bticn = substr($rsp_trace, 0, 9);
862 $stn = substr($rsp_trace, -4);
863 $btsrch = $rsp_trace;
866 csv_edihist_log('edih_rsp_st_match() invalid trace argument '.$rsp_trace);
870 $ft = csv_file_type($file_type);
872 if ( strpos('|f837|f276|f270|f278', $ft) === false ) {
874 csv_edihist_log('edih_rsp_st_match: file type '.$ft.' not in |f837|f276|f270|278');
878 $batch_srch = csv_search_record($ft, 'claim', array('s_val'=>$rsp_trace, 's_col'=>4, 'r_cols'=>'All'), '1' );
879 if (is_array($batch_srch) && count($batch_srch[0])) {
880 $info_ar['pt_name'] = $batch_srch[0][0]; // $batch_srch['PtName'];
881 $info_ar['clm01'] = ($rtp == 'f837') ?
$batch_srch[0][2] : $batch_srch[0][4]; // $batch_srch['CLM01'] : $batch_srch['BHT03'];
882 $info_ar['svcdate'] = $batch_srch[0][1]; // ($rtp == 'f270') ? $batch_srch['ReqDate'] : $batch_srch['SvcDate'];
883 $info_ar['batch_name'] = $batch_srch[0][5]; // $batch_srch['FileName'];
890 /** Extract csv file data rows from 997/999 files
892 * <pre> Creates array
893 * ['claim'][$i] = array('PtName', 'SvcDate', 'CLM01', 'Status', 'ak_num', 'File_997', 'Control', 'err_seg');
894 * ['file'][$i] = array('Date', 'FileName', 'Control', 'TA1ctrl', 'RejCt');
897 * @uses edih_x12_file() edi HC file class
898 * @uses edih_997_837_st_match()
899 * @param object edih_x12_file object of type 999/997
902 function edih_997_csv_data($obj997) {
906 $de = $obj997->edih_delimiters()['e'];
907 $ds = $obj997->edih_delimiters()['s'];
908 $fn = $obj997->edih_filename();
909 $seg_ar = $obj997->edih_segments();
910 $env_ar = $obj997->edih_envelopes();
912 if ( !isset($env_ar['ST']) ) {
913 csv_edihist_log('edih_997_csv_data: envelope error');
916 if ( !isset($env_ar['GS']) ) {
917 csv_edihist_log('edih_997_csv_data: envelope error');
920 foreach($env_ar['ISA'] as $icn => $isa) {
922 $ret_ar[$icn]['claim'] = array();
923 $ret_ar[$icn]['file'] = array();
925 foreach($env_ar['GS'] as $gs) {
926 if ($gs['icn'] == $icn) {
927 $ret_ar[$icn]['type'] = csv_file_type( $gs['type'] );
928 $rspdate = $gs['date'];
933 $fdx = count($ret_ar[$icn]['file']);
935 $ret_ar[$icn]['file'][$fdx]['Date'] = ($rspdate) ?
$rspdate : $isa['date'];
936 $ret_ar[$icn]['file'][$fdx]['FileName'] = $fn;
937 $ret_ar[$icn]['file'][$fdx]['Control'] = $icn;
940 // CTX segment identifiers
941 $trans_id = array('837'=>'CLM01', '270'=>'TRN02', '276'=>'TRN02');
943 //['f997']['claim'] = array('PtName', 'RspDate', 'CLM01', 'Status', 'ak_num', 'File_997', 'Control', 'err_seg');
944 foreach($env_ar['ST'] as $st) {
946 if ( $st['icn'] != $icn ) { continue; }
948 $stsegs = array_slice($seg_ar, $st['start'], $st['count']);
950 //$isasender = $env_ar['ISA'][$st['icn']]['sender'];
951 $isadate = $env_ar['ISA'][$st['icn']]['date'];
952 $isaicn = $st['icn'];
953 // match 997/999 response to sent file ISA control
954 $ret_ar[$icn]['file'][$fdx]['Trace'] = ($st['trace']) ?
$st['trace'] : '';
955 $bticn = ($st['trace']) ?
$st['trace'] : '';
956 if ( !$st['trace'] ) {
958 csv_edihist_log('edih_997_csv_data: no trace to submitted file! '.$fn);
961 foreach($stsegs as $seg) {
963 if ( strncmp($seg, 'AK1'.$de, 4) === 0 ) {
964 $sar = explode($de, $seg);
967 $rsptype = csv_file_type($sar[1]);
968 // AK102 could be the 'trace' value if it were unique
973 if ( strncmp($seg, 'AK2'.$de, 4) === 0 ) {
974 $sar = explode($de, $seg);
975 $rspsttype = csv_file_type($sar[1]);
976 $rspstn = (string)$sar[2];
977 $bht03syn = sprintf("%s%04d", $isaicn, $rspstn);
985 if ( strncmp($seg, 'IK3'.$de, 4) === 0 ||
strncmp($seg, 'AK3'.$de, 4) === 0 ) {
986 // >> try err_seg = str_replace($de, '*', $seg)
987 $sar = explode($de, $seg);
992 $err_seg .= ($err_seg) ?
'' : $bht03syn.'*IK3*'; // ISA13+ST02 * invalid segment ID
993 $err_seg .= (isset($sar[1])) ?
'*'.$sar[1] : '*';
994 $err_seg .= (isset($sar[2])) ?
'*'.$sar[2] : '*'; // segment position
995 //$err_seg .= (isset($sar[3])) ? '*'.$sar[3] : '*'; // loop, first 4 characters
996 //$err_seg .= (isset($sar[4])) ? '*'.$sar[4] : '*'; // error code
998 // example IK3*NM1*16*2010*8~ |IK3*SegID*SegNum*Loop*ErrCode*$bht03syn
999 // locate segment (#16 in ST-SE envelope)
1000 // ['err_seg'] = '|IK3*segID*segpos*loop*errcode*bht03syn|CTX-IK3*transID*segID*segpos*elempos
1001 // |IK4*elempos*errcode*elem*CTX-IK4*segID*segpos*elempos'
1003 // ///// retrieve original submitted claim
1006 $pt_info = edih_rsp_st_match($bht03syn, $rspsttype);
1007 //return array ['pt_name']['svcdate']['clm01']['batch_name'];
1009 $ptname = (isset($pt_info['pt_name']) && strlen($pt_info['pt_name'])) ?
$pt_info['pt_name'] : 'Unknown';
1012 $ptname = 'Unknown';
1015 // /////////////////////////
1019 //if ( strncmp($seg, 'IK4'.$de, 4) === 0 || strncmp($seg, 'AK4'.$de, 4) === 0 ) {
1020 //// data element error
1021 //$sar = explode($de, $seg);
1022 //$loopid == '2110';
1026 //$err_seg .= ($err_seg) ? '|IK4' : '';
1027 //$err_seg .= (isset($sar[1])) ? '*'.$sar[1] : '*';
1028 //$err_seg .= (isset($sar[2])) ? '*'.$sar[2] : '*';
1029 ////$err_seg .= (isset($sar[3])) ? '*'.$sar[3] : '*';
1030 ////$err_seg .= (isset($sar[4])) ? '*'.$sar[4] : '*';
1031 //// |IK4|elempos|errcode|elem
1035 //if ( strncmp($seg, 'CTX'.$de, 4) === 0 ) {
1036 //$sar = explode($de, $seg);
1038 //if ($loopid == '2100') {
1039 //$err_seg .= '|CTX-IK3';
1041 //if ($loopid == '2110') {
1042 //$err_seg .= '|CTX-IK4';
1044 //// CTX segment identifiers $trans_id['837'] ['270'] ['276']
1045 //if ( isset($trans_id[$rsptype]) && strpos($seg, $trans_id[$rsptype]) ) {
1046 //$err_seg .= (isset($sar[1]) && $sar[1]) ? '*'.$sar[1] : '';
1049 //if(strncmp($sar[1], 'SITUA', 5) === 0 ) {
1050 //// SITUATIONAL TRIGGER
1051 //$err_seg .= (isset($sar[2]) && $sar[2]) ? '*'.$sar[2] : '*';
1052 //$err_seg .= (isset($sar[3]) && $sar[3]) ? '*'.$sar[3] : '*';
1053 //$err_seg .= (isset($sar[5]) && $sar[5]) ? '*'.$sar[5] : '*';
1054 //// |CTX-IK3*segID*segPos*loopLS*elemPos:compositePos:repPos
1055 //} elseif ($ctx_ct > 1) {
1056 //$err_seg .= '*'.$sar[2];
1058 //$p1 = strpos($sar[1],$ds);
1059 //$p2 = ($p1) ? strlen($sar[1])-$p1-1 : strlen($sar[1]);
1060 //$ret_ar[$icn]['claim'][$cdx]['CLM01'] = substr($sar[1], -$p2);
1067 if ( strncmp($seg, 'AK5'.$de, 4) === 0 ||
strncmp($seg, 'IK5'.$de, 4) === 0 ) {
1068 // only store claims entries if there is an error
1069 $sar = explode($de, $seg);
1070 if ($sar[1] == 'A') {
1075 $cdx = count($ret_ar[$icn]['claim']);
1076 //array('PtName', 'RspDate', 'Trace', 'Status', 'Control', 'FileName', 'RspType', 'err_seg');
1077 $ret_ar[$icn]['claim'][$cdx]['PtName'] = $ptname;
1078 $ret_ar[$icn]['claim'][$cdx]['RspDate'] = $svcdate;
1080 $ret_ar[$icn]['claim'][$cdx]['Trace'] = $bht03syn;
1081 $ret_ar[$icn]['claim'][$cdx]['Status'] = $sar[1];
1082 $ret_ar[$icn]['claim'][$cdx]['Control'] = $icn;
1083 $ret_ar[$icn]['claim'][$cdx]['FileName'] = $fn;
1084 $ret_ar[$icn]['claim'][$cdx]['RspType'] = $rspsttype;
1086 $ret_ar[$icn]['claim'][$cdx]['err_seg'] = $err_seg;
1088 // AK502 = Code indicating implementation error found based on the syntax editing of a transaction set
1092 } // end foreach($env_ar['ST'] as $st)
1093 $ret_ar[$icn]['file'][$fdx]['RejCt'] = $rej_ct;
1094 $ret_ar[$icn]['file'][$fdx]['RspType'] = $rsptype;
1095 } // end foreach($env_ar['ISA'] as $icn => $isa)
1103 * parse an x12 270/271 file into data rows for csv tables
1105 * @param object x12_file_object
1108 function edih_271_csv_data($obj270) {
1109 //'f270 claim = array('PtName', 'ReqDate', 'PtAcct', 'InsLevel', 'BHT03', 'FileName', 'Payer');
1110 //'f270 file = array('Date', 'FileName', 'Control', 'Claim_ct', 'x12_partner');
1111 //'f271 file = array('Date', 'FileName', 'Control', 'Claim_ct', 'Denied', 'Payer');
1112 //'f271 claim = array('PtName', 'RspDate', 'Trace', 'Status', 'BHT03', 'FileName', 'Payer');
1116 $de = $obj270->edih_delimiters()['e'];
1117 $ds = $obj270->edih_delimiters()['s'];
1118 $fn = $obj270->edih_filename();
1119 $seg_ar = $obj270->edih_segments();
1120 $env_ar = $obj270->edih_envelopes();
1121 $ft = csv_file_type( $obj270->edih_type() );
1123 // $rsptype = array('HS'=>'270', 'HB'=>'271', 'HC'=>'837', 'HR'=>'276', 'HI'=>'278');
1124 if ( !isset($env_ar['ST']) ) {
1125 csv_edihist_log('edih_271_csv_data: envelope error '.$fn);
1129 if ( !isset($env_ar['GS']) ) {
1130 csv_edihist_log('edih_271_csv_data: envelope error');
1134 foreach($env_ar['ISA'] as $icn => $isa) {
1135 // array('Date', 'FileName', 'Control', 'ta1ctrl', 'RejCt');
1136 $ret_ar[$icn]['type'] = $ft;
1137 $ret_ar[$icn]['claim'] = array();
1138 $ret_ar[$icn]['file'] = array();
1139 $rspdate = $isa['date'];
1140 $x12ptnr = $isa['receiver'];
1142 foreach($env_ar['GS'] as $gs) {
1143 if ($gs['icn'] == $icn) {
1144 $gsdate = $gs['date'];
1148 foreach($env_ar['ST'] as $st) {
1150 if ( $st['icn'] != $icn ) { continue; }
1152 $stsegs = array_slice($seg_ar, $st['start'], $st['count']);
1156 $isaicn = $st['icn'];
1160 // for "claim" array
1161 // 'f270' array('PtName', 'ReqDate', 'Trace', 'InsBnft', 'BHT03', 'FileName', 'Payer'); break;
1162 // 'f271'array('PtName', 'RspDate', 'Trace', 'Status', 'BHT03', 'FileName', 'Payer'); break;
1164 foreach($stsegs as $seg) {
1166 if (strncmp($seg, 'BHT'.$de, 4) === 0 ) {
1168 $cdx = (isset($ret_ar[$icn]['claim']) ) ?
count($ret_ar[$icn]['claim']) : 0;
1170 $sar = explode($de, $seg);
1172 $isrqst = (isset($sar[2]) && $sar[2] == '13') ?
true : false;
1173 $isrsp = (isset($sar[2]) && $sar[2] == '11') ?
true : false;
1178 $dtkey = ($ft == 'f271') ?
'RspDate' : 'ReqDate';
1180 $ret_ar[$icn]['claim'][$cdx]['PtName'] = '';
1181 $ret_ar[$icn]['claim'][$cdx][$dtkey] = $gsdate;
1182 $ret_ar[$icn]['claim'][$cdx]['Trace'] = '';
1183 if ($isrsp ||
$ft == 'f271') {
1184 $ret_ar[$icn]['claim'][$cdx]['Status'] = 'A'; // 271
1185 $ret_ar[$icn]['claim'][$cdx]['BHT03'] = (isset($sar[3])) ?
$sar[3] : ''; //bht03 = $sar[3];
1187 $ret_ar[$icn]['claim'][$cdx]['InsBnft'] = ''; // 270
1188 $ret_ar[$icn]['claim'][$cdx]['BHT03'] = sprintf("%s%04d", $isaicn, $stn);
1190 $ret_ar[$icn]['claim'][$cdx]['FileName'] = $fn;
1191 $ret_ar[$icn]['claim'][$cdx]['Payer'] = '';
1196 if (strncmp($seg, 'HL'.$de, 3) === 0 ) {
1197 $sar = explode($de, $seg);
1199 $hlpc = $sar[2]; // parent code
1201 $hlcc = (isset($sar[4])) ?
$sar[4] : ''; // child code
1202 if ($sar[3] == '20') { // level code
1203 $loopid = '2000A'; // info source (payer)
1204 } elseif ($sar[3] == '21') {
1205 $loopid = '2000B'; // info receiver (clinic)
1206 } elseif ($sar[3] == '22') {
1207 $loopid = '2000C'; // subscriber
1208 } elseif ($sar[3] == '23') {
1209 $loopid = '2000D'; // dependent
1212 csv_edihist_log('HL has no level '.$seg.' in '.$fn);
1217 if (strncmp($seg, 'NM1'.$de, 4) === 0 ) {
1218 $sar = explode($de, $seg);
1220 $nm1 = ($sar[4]) ?
$nm1.', '.$sar[4] : $nm1;
1221 $nm1 = ($sar[5]) ?
$nm1.' '.$sar[5] : $nm1;
1222 if ($loopid == '2000A') {
1223 $ret_ar[$icn]['claim'][$cdx]['Payer'] = $nm1; //
1225 } elseif ($loopid == '2000C' ||
$loopid == '2000D') {
1226 $ret_ar[$icn]['claim'][$cdx]['PtName'] = $nm1; //$ptname = $nm1;
1230 // for 271 eligibility response (invalid data in 270 request)
1231 if (strncmp($seg, 'AAA'.$de, 4) === 0 ) {
1232 $sar = explode($de, $seg);
1235 $aaa_code = $sar[3];
1236 $rsp_code = $sar[4];
1237 if ($loopid == '2000A') {
1238 $status = $status.' Src '.$aaa_code;
1239 } elseif ($loopid == '2000B') {
1240 $status = $status.' Rcv '.$aaa_code;
1241 } elseif ($loopid == '2000C') {
1242 $status = $status.' Sbr '.$aaa_code;
1243 } elseif ($loopid == '2000D') {
1244 $status = $status.' Dep '.$aaa_code;
1247 $ret_ar[$icn]['claim'][$cdx]['Status'] = $status;
1252 // for 270 eligibility request
1253 if (strncmp($seg, 'EQ'.$de, 3) === 0 ) {
1254 if ( strlen((string)$sar[1]) ) {
1255 $bnfteq .= ($bnfteq) ?
'|'.$sar[1] : $sar[1];
1256 } elseif ( strlen((string)$sar[2]) ) {
1257 $bnfteq .= ($bnfteq) ?
'|'.$sar[2] : $sar[2];
1259 csv_edihist_log('Invalid EQ segment, missing benefit type in '.$fn);
1262 $ret_ar[$icn]['claim'][$cdx]['InsBnft'] = $bnfteq;
1265 // overridden by REF*EJ* (not)
1266 if (strncmp($seg, 'TRN'.$de, 4) === 0 ) {
1267 if ($loopid = '2000C' ||
$loopid == '2000D') {
1268 $sar = explode($de, $seg);
1269 $ret_ar[$icn]['claim'][$cdx]['Trace'] = $sar[2]; //$ptacct = $sar[2];
1274 // for 271 eligibility response
1275 if (strncmp($seg, 'EB'.$de, 3) === 0 ) {
1276 $status = ( isset($status) ) ?
$status : '';
1278 if ( strpos($ret_ar[$icn]['claim'][$cdx]['Status'], 'tive') ) {
1282 $sar = explode($de, $seg);
1284 if ( isset($sar[2]) ) {
1285 if ( $sar[2] == '6' ||
$sar[2] == '7' ||
$sar[2] == '8' ) {
1286 $status = 'Inactive';
1287 } elseif ($sar[2] == 'I') {
1288 $status = 'Non-Covered';
1290 } elseif ($sar[2] == 'E') {
1291 $status = 'Exclusions';
1293 } elseif ($sar[2] == 'N') {
1294 $status = 'Restricted';
1296 } elseif ($sar[2] == 'V') {
1297 $status = 'Unknown';
1299 } elseif ($sar[2] == 'T') {
1300 $status = 'Card Lost';
1302 } elseif ($sar[2] == 'U') {
1303 $status = 'Contact';
1305 } elseif ($sar[2] == '1') {
1307 } elseif ($sar[2] == '2' ||
$sar[2] == '3' ||
$sar[2] == '4') {
1308 $status = 'Active Cap';
1312 $ret_ar[$icn]['claim'][$cdx]['Status'] = $status;
1317 if (strncmp($seg, 'DTP'.$de, 4) === 0 ) {
1318 $sar = explode($de, $seg);
1319 $dtp03 = (isset($sar[2]) && $sar[2] == 'D8') ?
$sar[3] : substr($sar[3], 0, 8);
1321 if ($loopid == '2100C' ||
$loopid == '2110C') {
1322 $ret_ar[$icn]['claim'][$cdx]['RspDate'] = $dtp03;
1323 } elseif ($loopid == '2100D' ||
$loopid == '2110D') {
1324 $ret_ar[$icn]['claim'][$cdx]['RspDate'] = $dtp03;
1327 if ($loopid == '2100C' ||
$loopid == '2110C') {
1328 $ret_ar[$icn]['claim'][$cdx]['ReqDate'] = $dtp03;
1329 } elseif ($loopid == '2100D' ||
$loopid == '2110D') {
1330 $ret_ar[$icn]['claim'][$cdx]['ReqDate'] = $dtp03;
1338 if (strncmp($seg, 'REF'.$de.'EJ'.$de, 7) === 0 ) {
1339 // patient account -- replaces or replaced by TRN02
1340 $sar = explode($de, $seg);
1341 $ret_ar[$icn]['claim'][$cdx]['PtAcct'] = $sar[2]; //$ptacct = $sar[2];
1347 } // end foreach($stsegs as $seg)
1349 } // endforeach($env_ar['ST'] as $st
1350 // file: 'f271': array('Date', 'FileName', 'Control', 'Claim_ct', 'Reject', 'Payer')
1351 $fdx = count($ret_ar[$icn]['file']);
1352 //'f270': $hdr = array('Date', 'FileName', 'Control', 'Claim_ct', 'x12Partner');
1353 $ret_ar[$icn]['file'][$fdx]['Date'] = $gsdate;
1354 $ret_ar[$icn]['file'][$fdx]['FileName'] = $fn;
1355 // for 270 type, could use GSO6 if it were unique
1356 $ret_ar[$icn]['file'][$fdx]['Control'] = $icn;
1357 $ret_ar[$icn]['file'][$fdx]['Claim_ct'] = $cdx;
1358 if ($isrsp ||
$ft == 'f271') {
1359 $ret_ar[$icn]['file'][$fdx]['Reject'] = $rej_ct;
1360 $ret_ar[$icn]['file'][$fdx]['Payer'] = $payer_name;
1362 $ret_ar[$icn]['file'][$fdx]['x12Partner'] = $x12ptnr;
1365 } // endforeach($env_ar['ISA'] as $icn=>$isa)
1371 * this function opens the x12 file in the object and routes
1372 * the object to the parsing function according to the x12 type
1373 * csvdata array design:
1374 * [$icn]['claims'][i] [$icn]['files'][i] [$icn]['type']
1376 * @uses edih_835_csv_data()
1377 * @uses edih_837_csv_data()
1378 * @uses edih_277_csv_data()
1379 * @uses edih_271_csv_data()
1380 * @uses edih_278_csv_data()
1381 * @uses edih_997_csv_data()
1383 * @param string path to file
1384 * @return array data for csv table records
1386 function edih_parse_select($file_path) {
1388 // csvdata array design:
1389 // $csvdata[$icn]['claims'][i] [$icn]['files'][i] [$icn]['type']
1391 $x12_obj = csv_check_x12_obj($file_path);
1392 //$x12_obj = new edih_x12_file($file_path);
1393 if ($x12_obj instanceof edih_x12_file
) {
1394 $ft = $x12_obj->edih_type();
1396 csv_edihist_log('edih_parse_select: error in file path');
1399 //'HB'=>'271', 'HS'=>'270', 'HR'=>'276', 'HI'=>'278',
1400 //'HN'=>'277', 'HP'=>'835', 'FA'=>'999', 'HC'=>'837'
1402 if ( $ft == 'HP' ) {
1403 $csvdata = edih_835_csv_data($x12_obj);
1404 } elseif ( $ft == 'HC' ) {
1405 $csvdata = edih_837_csv_data($x12_obj);
1406 } elseif ( $ft == 'HN' ||
$ft == 'HR' ) {
1407 $csvdata = edih_277_csv_data($x12_obj);
1408 } elseif ( $ft == 'FA') {
1409 $csvdata = edih_997_csv_data($x12_obj);
1410 } elseif ( $ft == 'HB' ||
$ft == 'HS') {
1411 $csvdata = edih_271_csv_data($x12_obj);
1412 } elseif ( $ft == 'HI') {
1413 $csvdata = edih_278_csv_data($x12_obj);
1416 csv_edihist_log( 'edih_parse_select(): unsupported file type '.$ft.' name: '.basename($file_path));