You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1566 lines
64 KiB

<?php
/*
* edih_csv_parse.php
*
* Copyright 2016 Kevin McCormick Carrollton, Texas
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3 or later. You should have
* received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* <http://opensource.org/licenses/gpl-license.php>
*
*
*
* @link: https://www.open-emr.org
* @package ediHistory
*/
/* ========= notes
* EDI files may contain multiple ISA envelopes. Each ISA envelope is treated as a "file" here.
* The same file name may have one or more ISA control numbers
* The ISA control number is associated with each GS and ST envelope and each included transaction.
* Each transaction will also link to the ISA control number as a means of retrieving the file.
*
* The CSV data column headers are the array keys for each EDI file type.
*/
/**
* Provide a more user-friendly date in csv tables
*
* @param string YYYYMMDD
* @return string YYYY-MM-DD
*/
function edih_parse_date($strdate)
{
if (strlen($strdate) == 6) {
$gtdt = getdate();
$cy = (string)$gtdt['year'];
$dt1 = substr($cy, 0, 2) . $strdate;
} elseif (strpos($strdate, '-') >= 6) {
$dt1 = substr($strdate, 0, strpos($strdate, '-') - 1);
} elseif (strlen($strdate) == 8) {
$dt1 = $strdate;
} else {
// bad argument
csv_edihist_log('edih_parse_date: invalid argument ' . $strdate);
return false;
}
//
return substr($dt1, 0, 4) . '-' . substr($dt1, 4, 2) . '-' . substr($dt1, 6, 2);
}
/** remittance 835 files
*
* Each payment trace number (Control) gets a row in the csv file record.
* Each claim payment transaction gets a row in the csv claim record
* <pre>
*
* $array
* [$icn]['type']
* [$icn]['file'][$i] => array keys match csv_table_head() output
* [$icn]['claim'][$i] => array keys match csv_table_head() output
*
* </pre>
*
* @uses csv_file_type()
* @uses edih_parse_date()
* @uses edih_x12_transaction()
* @uses edih_get_segment()
* @param object edih_x12_obj
* @return array
*/
function edih_835_csv_data($obj835)
{
//
$ret_ar = array();
//
$seg_ar = $obj835->edih_segments();
$env_ar = $obj835->edih_envelopes();
$de = $obj835->edih_delimiters()['e'];
$fn = $obj835->edih_filename();
//$tp = $obj835->edih_type();
//
// since 835 "files" table uses transaction trace as the "Control"
// we must assemble the 'files' array in the ST loop
// ['ISA'][$icn]
foreach ($env_ar['ISA'] as $icn => $isa) {
//
$ret_ar[$icn]['claim'] = array();
$ret_ar[$icn]['file'] = array();
//
$gsdate = '';
$trace = '';
//
if (array_key_exists('GS', $env_ar)) {
// for unlikely case of 'mixed' GS types in file
foreach ($env_ar['GS'] as $gs) {
if ($gs['icn'] == $icn) {
$ft = $gs['type'];
$gsdate = $gs['date'];
$payer_id = $gs['srcid']; // from TRN03
break;
}
}
}
$ret_ar[$icn]['type'] = csv_file_type($ft);
$gsdate = ($gsdate) ? $gsdate : edih_parse_date($isa['date']);
//
$fdx = count($ret_ar[$icn]['file']);
//
// ['ST'][$stky]=>['start']['count']['stn']['gsn']['icn']['type']['trace']['acct']
// ['ST'][$stky]['acct'][i]=>pid-enc$$ret_ar[$icn]['claim'][$cdx]['SvcDate'] =
foreach ($env_ar['ST'] as $st) {
if ($st['icn'] != $icn) {
continue;
}
// the "files" table has a row for each payment trace
//
if ($trace != $st['trace']) {
$fdx = count($ret_ar[$icn]['file']);
//
$ret_ar[$icn]['file'][$fdx]['Date'] = $gsdate;
$ret_ar[$icn]['file'][$fdx]['FileName'] = $fn;
$ret_ar[$icn]['file'][$fdx]['Control'] = (string)$icn;
$ret_ar[$icn]['file'][$fdx]['Trace'] = $st['trace'];
$ret_ar[$icn]['file'][$fdx]['Claim_ct'] = (string)count($st['acct']);
$ret_ar[$icn]['file'][$fdx]['Denied'] = 0;
$ret_ar[$icn]['file'][$fdx]['Payer'] = $payer_id;
//
$trace = $st['trace'];
}
//
$stsegs = array_slice($seg_ar, $st['start'], $st['count']);
$stacct = array_values(array_unique($st['acct']));
$clmct = count($stacct);
$payer = '';
$denied = 0;
//
$n1pr = $obj835->edih_get_segment('N1', 'N1' . $de . 'PR' . $de, $stsegs);
$payer = '';
if ($n1pr) {
foreach ($n1pr as $n1) {
$sar = explode($de, $n1);
$payer = (isset($sar[2])) ? $sar[2] : '';
}
if ($payer) {
$ret_ar[$icn]['file'][$fdx]['Payer'] = $payer;
}
} // end if ($n1pr)
//
//
for ($i = 0; $i < $clmct; $i++) {
$clpsegs = $obj835->edih_x12_transaction($stacct[$i], $st['stn']);
if (!is_array($clpsegs) || !count($clpsegs)) {
//
csv_edihist_log('edih_835_csv_data: no segments for account ' . $st['acct'][$i]);
continue;
}
//
foreach ($clpsegs as $trans) {
//
$cdx = count($ret_ar[$icn]['claim']);
foreach ($trans as $seg) {
//
if (strncmp($seg, 'CLP' . $de, 4) === 0) {
$sar = explode($de, $seg);
//
$ret_ar[$icn]['claim'][$cdx]['CLM01'] = (isset($sar[1])) ? $sar[1] : '';
$ret_ar[$icn]['claim'][$cdx]['Status'] = (isset($sar[2])) ? $sar[2] : '';
$ret_ar[$icn]['claim'][$cdx]['Pmt'] = (isset($sar[4])) ? sprintf("%01.02f", $sar[4]) : '';
$ret_ar[$icn]['claim'][$cdx]['PtResp'] = ( isset($sar[5]) ) ? sprintf("%01.02f", $sar[5]) : '';
$ret_ar[$icn]['claim'][$cdx]['ClaimID'] = ( isset($sar[7]) ) ? trim($sar[7]) : '';
$ret_ar[$icn]['claim'][$cdx]['FileName'] = $fn;
$ret_ar[$icn]['claim'][$cdx]['Trace'] = $st['trace'];
$ret_ar[$icn]['claim'][$cdx]['Payer'] = $payer;
$ret_ar[$icn]['claim'][$cdx]['PtName'] = '';
$ret_ar[$icn]['claim'][$cdx]['SvcDate'] = '';
//
if ($sar[2] == '4' || $sar[2] == '22' || $sar[2] == '23') {
$denied++;
}
$loopid = "2100";
continue;
}
//
if (strncmp($seg, 'NM1' . $de . 'QC' . $de, 7) === 0) {
$sar = explode($de, $seg);
$midn = ( isset($sar[5]) && strlen($sar[5]) ) ? ', ' . $sar[5] : "";
$ret_ar[$icn]['claim'][$cdx]['PtName'] = $sar[3] . ', ' . $sar[4] . $midn;
continue;
}
if (strncmp($seg, 'DTM' . $de . '232' . $de, 8) === 0) {
$sar = explode($de, $seg);
$ret_ar[$icn]['claim'][$cdx]['SvcDate'] = $sar[2];
continue;
}
if (strncmp($seg, 'DTM' . $de . '472' . $de, 8) === 0) {
$sar = explode($de, $seg);
$ret_ar[$icn]['claim'][$cdx]['SvcDate'] = $sar[2];
continue;
}
} // end foreach($trans as $seg)
} // end foreach($clpsegs as $trans) {
} // end for($i=0; $i<$clmct; $i++)
// get denied count
$ret_ar[$icn]['file'][$fdx]['Denied'] = ($denied) ? $denied : '0';
//
} // end foreach($env_ar['ST'] as $st)
} // end foreach($env_ar['ISA'] as $icn => $isa)
//
return $ret_ar;
}
/*
* Parse csv data from 837 files
* Note that this can return false provider values for extensive claims
* since loops are not tracked and 837 claims can have numerous
* providers, but probably not an issue for OpenEMR
*
* @param object edih_x12_ file object
* @return array data to write csv file and csv clain table rows
*/
function edih_837_csv_data($obj837)
{
//
$ret_ar = array();
//
$seg_ar = $obj837->edih_segments();
$env_ar = $obj837->edih_envelopes();
$de = $obj837->edih_delimiters()['e'];
$fn = $obj837->edih_filename();
//$ft = csv_file_type( $obj837->edih_type() );
//
if (!isset($env_ar['ST'])) {
csv_edihist_log('edih_837_csv_data: envelope error');
return $ret_ar;
}
//['file'] = array('Date', 'FileName', 'Control', 'Claim_ct', 'x12_partner');
//['claim'] =
// array('PtName', 'SvcDate', 'CLM01', 'InsLevel', 'Control', 'File_837', 'Fee', 'PtPaid', 'Provider' );
foreach ($env_ar['ISA'] as $icn => $isa) {
//
$ret_ar[$icn]['claim'] = array();
$ret_ar[$icn]['file'] = array();
//$ret_ar[$icn]['type'] = $ft;
foreach ($env_ar['GS'] as $gs) {
if ($gs['icn'] == $icn) {
$ret_ar[$icn]['type'] = csv_file_type($gs['type']);
$gsdate = $gs['date'];
break;
}
}
//
$fdx = count($ret_ar[$icn]['file']);
//
$ret_ar[$icn]['file'][$fdx]['Date'] = (string)$gsdate;
$ret_ar[$icn]['file'][$fdx]['FileName'] = $fn;
// if GS06 were unique, it could be used as the 'Control'
$ret_ar[$icn]['file'][$fdx]['Control'] = (string)$icn;
$ret_ar[$icn]['file'][$fdx]['x12Partner'] = (string)$isa['receiver'];
//
$clm_ct = 0;
//
foreach ($env_ar['ST'] as $st) {
// claims should be in the correct ISA envelope
if ($st['icn'] != $icn) {
continue;
}
//
$stsegs = array_slice($seg_ar, $st['start'], $st['count']);
$stacct = array_values(array_unique($st['acct']));
$clmct = count($stacct);
// $st['icn'] is the ISA control number for the ISA envelope containing the ST--SE
$date = $env_ar['ISA'][$st['icn']]['date'];
$stn = $st['stn'];
for ($i = 0; $i < $clmct; $i++) {
//echo '=== ACCT '.$stacct[$i].' '.$st['stn'].'<br />'.PHP_EOL;
$asegs = $obj837->edih_x12_transaction($stacct[$i], $st['stn']);
if (!is_array($asegs) || !count($asegs)) {
csv_edihist_log('edih_837_csv_data: no segments for account ' . $st['acct'][$i]);
continue;
}
foreach ($asegs as $trans) {
//
//array('PtName'=>0, 'SvcDate'=>1, 'CLM01'=>2, 'InsLevel'=>3, 'Control'=>4, 'FileName'=>5, 'Fee'=>6, 'PtPaid'=>7, 'Provider'=>8 );
//'f837': $hdr = array('PtName', 'SvcDate', 'CLM01', 'InsLevel', 'Control', 'FileName', 'Fee', 'PtPaid', 'Provider' )
foreach ($trans as $seg) {
if (strncmp($seg, 'BHT' . $de, 4) === 0) {
$cdx = count($ret_ar[$icn]['claim']);
$sar = explode($de, $seg);
$bht03 = $sar[3];
$hl = '';
$clm_ct++;
//
$ret_ar[$icn]['claim'][$cdx]['PtName'] = '';
$ret_ar[$icn]['claim'][$cdx]['SvcDate'] = '';
$ret_ar[$icn]['claim'][$cdx]['CLM01'] = '';
$ret_ar[$icn]['claim'][$cdx]['InsLevel'] = '';
//
$ret_ar[$icn]['claim'][$cdx]['BHT03'] = (strlen($bht03) == 13) ? $bht03 : sprintf("%s%04d", $st['icn'], $st['stn']);
$ret_ar[$icn]['claim'][$cdx]['FileName'] = $fn;
//
$ret_ar[$icn]['claim'][$cdx]['Fee'] = '0';
$ret_ar[$icn]['claim'][$cdx]['PtPaid'] = '0';
$ret_ar[$icn]['claim'][$cdx]['Provider'] = '';
}
if (strncmp($seg, 'HL' . $de, 3) === 0) {
$sar = explode($de, $seg);
$hl = $sar[3];
continue;
}
if (intval($hl) == 20) {
if (strncmp($seg, 'NM1' . $de, 4) === 0) {
$sar = explode($de, $seg);
if ($sar[2] == '82' || $sar[2] == '85') {
$ret_ar[$icn]['claim'][$cdx]['Provider'] = $sar[9];
}
continue;
}
} // end if $hl == '20'
if (intval($hl) >= 22) {
if (strncmp($seg, 'SBR' . $de, 4) === 0) {
$sar = explode($de, $seg);
$ret_ar[$icn]['claim'][$cdx]['InsLevel'] = $sar[1];
}
if (strncmp($seg, 'CLM' . $de, 4) === 0) {
$sar = explode($de, $seg);
$ret_ar[$icn]['claim'][$cdx]['CLM01'] = $sar[1];
$ret_ar[$icn]['claim'][$cdx]['Fee'] = $sar[2];
continue;
}
if (strncmp($seg, 'AMT' . $de . 'F5' . $de, 7) === 0) {
$sar = explode($de, $seg);
$ret_ar[$icn]['claim'][$cdx]['PtPaid'] = $sar[2];
continue;
}
if (strncmp($seg, 'NM1' . $de, 4) === 0) {
$sar = explode($de, $seg);
if (strpos('|IL|QC', $sar[1])) {
$midn = ( isset($sar[5]) && strlen($sar[5]) ) ? ', ' . $sar[5] : '';
$ret_ar[$icn]['claim'][$cdx]['PtName'] = $sar[3] . ', ' . $sar[4] . $midn;
continue;
}
if ($sar[1] == '82') {
$ret_ar[$icn]['claim'][$cdx]['Provider'] = $sar[9];
continue;
}
}
if (strncmp($seg, 'DTP' . $de . '472' . $de, 8) === 0) {
$sar = explode($de, $seg);
$ret_ar[$icn]['claim'][$cdx]['SvcDate'] = $sar[3];
continue;
}
} // end if $hl >= '22'
} // end foreach($trans as $seg)
} // end foreach($asegs as $trans)
} // end for($i=0; $i<$clmct; $i++)
} // end foreach($obj837->envelopes['ST'] as $st)
// claim count
$ret_ar[$icn]['file'][$fdx]['Claim_ct'] = (string)$clm_ct;
} // end foreach($env_ar['ISA'] as $icn => $isa)
//
return $ret_ar;
}
/*
* extract csv table row data for x12 277 files
*
* @param object edih_x12_file object of type 276/277
* @return array
*/
function edih_277_csv_data($obj277)
{
//
$ret_ar = array();
//
$seg_ar = $obj277->edih_segments();
$env_ar = $obj277->edih_envelopes();
$de = $obj277->edih_delimiters()['e'];
$fn = $obj277->edih_filename();
$tp = $obj277->edih_type();
// 'HN' 277 'HR' 276 )
$env_ar = $obj277->edih_envelopes();
//
if (!isset($env_ar['ST'])) {
csv_edihist_log('edih_277_csv_data: envelope error');
return $ret_ar;
}
if (!isset($env_ar['GS'])) {
csv_edihist_log('edih_277_csv_data: envelope error');
return $ret_ar;
}
//
foreach ($env_ar['ISA'] as $icn => $isa) {
//
$ret_ar[$icn]['claim'] = array();
$ret_ar[$icn]['file'] = array();
//
$rspdate = $isa['date'];
foreach ($env_ar['GS'] as $gs) {
if ($gs['icn'] == $icn) {
$ret_ar[$icn]['type'] = csv_file_type($gs['type']);
$rspdate = $gs['date'];
break;
}
}
//$ret_ar[$icn]['type'] = csv_file_type($ft);
//
$fdx = count($ret_ar[$icn]['file']);
//['f277']['file'] = array('Date', 'FileName', 'Control', 'Accept', 'AccAmt', 'Reject', 'RejAmt');
//'f276': $hdr = array('Date', 'FileName', 'Control', 'Claim_ct', 'x12Partner');
$ret_ar[$icn]['file'][$fdx]['Date'] = $rspdate;
$ret_ar[$icn]['file'][$fdx]['FileName'] = $fn;
// could be GS06 for 276 if it were unique
$ret_ar[$icn]['file'][$fdx]['Control'] = (string)$icn;
if ($tp == 'HN') {
$ret_ar[$icn]['file'][$fdx]['Accept'] = 0;
$ret_ar[$icn]['file'][$fdx]['Reject'] = 0;
$ret_ar[$icn]['file'][$fdx]['AccAmt'] = 0;
$ret_ar[$icn]['file'][$fdx]['RejAmt'] = 0;
} else {
$ret_ar[$icn]['file'][$fdx]['Claim_ct'] = 0;
$ret_ar[$icn]['file'][$fdx]['x12Partner'] = $isa['receiver'];
}
//
$clmct = 0;
//
//['ST'][$stky]=>['start']['count']['stn']['gsn']['icn']['type']['trace']['acct']
// ['ST'][$stky]['acct'][i]=>pid-enc
//'f277': $hdr = array('PtName', 'SvcDate', 'CLM01', 'Status', 'BHT03', 'FileName', 'Payer', 'Trace');
foreach ($env_ar['ST'] as $st) {
//
if ($st['icn'] != $icn) {
continue;
}
//
$stsegs = array_slice($seg_ar, $st['start'], $st['count']);
$stacct = array_values(array_unique($st['bht03']));
$clmct += count($stacct);
$st_icn = $st['icn']; // same value as $obj277->envelopes['ISA']['icn']
$stn = $st['stn'];
//
if ($tp == 'HR') {
$ret_ar[$icn]['file'][$fdx]['Claim_ct'] = $clmct;
}
//
//for($i=0; $i<$clmct; $i++) {
for ($i = 0; $i < count($stacct); $i++) {
//
$asegs = $obj277->edih_x12_transaction($stacct[$i]);
//
foreach ($asegs as $trans) {
//
foreach ($trans as $seg) {
//
if (strncmp($seg, 'BHT' . $de, 4) === 0) {
$cdx = count($ret_ar[$icn]['claim']);
//
$sar = explode($de, $seg);
if ($sar[2] != '08') {
csv_edihist_log('Claim Status BHT purpose code: ' . $sar[2] . ' in ST ' . $st['stn'] . ' in file ' . $fn);
}
$trns_tp = (isset($sar[6]) && $sar[6]) ? $sar[6] : '';
if ($trns_tp == 'TH') {
$bht_id = 'ack'; // 277CA
} elseif ($trns_tp == 'DG') {
$bht_id = 'rsp'; // 277
} else {
$bht_id = 'sub'; // 276
}
//
$ret_ar[$icn]['claim'][$cdx]['PtName'] = '';
$ret_ar[$icn]['claim'][$cdx]['SvcDate'] = '';
$ret_ar[$icn]['claim'][$cdx]['CLM01'] = '';
//
if ($tp == 'HN') {
// 277
$ret_ar[$icn]['claim'][$cdx]['Status'] = '';
$ret_ar[$icn]['claim'][$cdx]['BHT03'] = $sar[3];
} elseif ($tp == 'HR') {
//276
$ret_ar[$icn]['claim'][$cdx]['ClaimID'] = '';
$ret_ar[$icn]['claim'][$cdx]['BHT03'] = sprintf("%s%04d", $st_icn, $stn);
}
//
$ret_ar[$icn]['claim'][$cdx]['FileName'] = $fn;
//
$ret_ar[$icn]['claim'][$cdx]['Payer'] = '';
//$ret_ar[$icn]['claim'][$cdx]['Ins_ID'] = '';
$ret_ar[$icn]['claim'][$cdx]['Trace'] = '';
continue;
}
//
if (strncmp($seg, 'HL' . $de, 3) === 0) {
$sar = explode($de, $seg);
$hl = (string)$sar[3];
}
//
if ($hl == '20') {
// information source
if (strncmp($seg, 'NM1' . $de, 4) === 0) {
$sar = explode($de, $seg);
$ret_ar[$icn]['claim'][$cdx]['Payer'] = ($sar[1] == 'PR' || $sar[1] == 'AY') ? $sar[3] : '';
continue;
}
}
//
if ($hl == '21') {
// information source or receiver level rejection
// -- user should view the transaction
// -- don't include in csv data so Trace only refers to 276
//if ( strncmp($seg, 'TRN'.$de, 4) === 0) {
//$sar = explode($de, $seg);
//$ret_ar[$icn]['claim'][$cdx]['Trace'] = $sar[2];
//}
if (strncmp($seg, 'STC' . $de, 4) === 0) {
$sar = explode($de, $seg);
$ret_ar[$icn]['claim'][$cdx]['Status'] = $sar[1];
}
if (strncmp($seg, 'QTY' . $de, 4) === 0) {
$sar = explode($de, $seg);
if ($sar[1] == '90') {
$ret_ar[$icn]['file'][$fdx]['Accept'] += $sar[2];
}
if ($sar[1] == 'AA') {
$ret_ar[$icn]['file'][$fdx]['Reject'] += $sar[2];
}
}
if (strncmp($seg, 'AMT' . $de, 4) === 0) {
$sar = explode($de, $seg);
if ($sar[1] == 'YU') {
$ret_ar[$icn]['file'][$fdx]['AccAmt'] += $sar[2];
}
if ($sar[1] == 'YY') {
$ret_ar[$icn]['file'][$fdx]['RejAmt'] += $sar[2];
}
}
continue;
}
//
if ($hl == '19') {
// provider level rejection
// -- user should view the transaction
// -- don't include in csv data so Trace only refers to 276
//if ( strncmp($seg, 'TRN'.$de, 4) === 0) {
//$sar = explode($de, $seg);
//$ret_ar[$icn]['claim'][$cdx]['Trace'] = $sar[2];
//}
if (strncmp($seg, 'STC' . $de, 4) === 0) {
$sar = explode($de, $seg);
$ret_ar[$icn]['claim'][$cdx]['Status'] = $sar[1];
}
continue;
}
//
if ($hl == '22' || $hl == '23') {
// subscriber or dependent
if (strncmp($seg, 'NM1' . $de, 4) === 0) {
$sar = explode($de, $seg);
if ($sar[1] == 'IL' || $sar[1] == 'QC') {
$midn = ( isset($sar[5]) && strlen($sar[5]) ) ? ', ' . $sar[5] : "";
$ret_ar[$icn]['claim'][$cdx]['PtName'] = $sar[3] . ', ' . $sar[4] . $midn;
//if (isset($sar[8]) && $sar[8] == 'MI') {
//$ret_ar[$icn]['claim'][$cdx]['Ins_ID'] = (isset($sar[9])) ? $sar[9] : '';
//}
}
continue;
}
// in response to 276, this is the reference given in TRN02
if (strncmp($seg, 'TRN' . $de . '2' . $de, 4) === 0) {
$sar = explode($de, $seg);
$ret_ar[$icn]['claim'][$cdx]['Trace'] = $sar[2];
continue;
}
// REF*EJ* will give the payer assigned claim number
// not used much in 277CA files
if (strncmp($seg, 'REF' . $de . 'EJ' . $de, 7) === 0) {
$sar = explode($de, $seg);
$ret_ar[$icn]['claim'][$cdx]['CLM01'] = $sar[2];
continue;
}
if (strncmp($seg, 'REF' . $de . '1K' . $de, 7) === 0) {
// hopefully OpenEMR will include the claim number in 276
if ($tp == 'HR') {
$sar = explode($de, $seg);
$ret_ar[$icn]['claim'][$cdx]['ClaimID'] = $sar[2];
}
continue;
}
// REF*D9*(Claim number)~
if (strncmp($seg, 'STC' . $de, 4) === 0) {
// STC is only present in 277
$sar = explode($de, $seg);
$ret_ar[$icn]['claim'][$cdx]['Status'] = $sar[1];
continue;
}
continue;
}
if ($hl == 'PT') {
// 277CA
if (strncmp($seg, 'NM1' . $de, 4) === 0) {
$sar = explode($de, $seg);
if ($sar[1] == 'IL' || $sar[1] == 'QC') {
$midn = ( isset($sar[5]) && strlen($sar[5]) ) ? ', ' . $sar[5] : "";
$ret_ar[$icn]['claim'][$cdx]['PtName'] = $sar[3] . ', ' . $sar[4] . $midn;
//$ret_ar[$icn]['claim'][$cdx]['Ins_ID'] = (isset($sar[9])) ? $sar[9] : '';
}
continue;
}
if (strncmp($seg, 'TRN' . $de . '2' . $de, 6) === 0) {
$sar = explode($de, $seg);
$ret_ar[$icn]['claim'][$cdx]['CLM01'] = $sar[2];
continue;
}
if (strncmp($seg, 'STC' . $de, 4) === 0) {
$sar = explode($de, $seg);
$ret_ar[$icn]['claim'][$cdx]['Status'] = $sar[1];
continue;
}
//if ( strncmp($seg, 'REF'.$de.'1K'.$de, 7) === 0) {
//$sar = explode($de, $seg);
//$ret_ar[$icn]['claim'][$cdx]['ClaimID'] = $sar[2];
//continue;
//}
if (strncmp($seg, 'DTP' . $de . '472' . $de, 8) === 0) {
$sar = explode($de, $seg);
// D8-CCYYMMDD RD8-CCYYMMDD-CCYYMMDD only take initial date
$ret_ar[$icn]['claim'][$cdx]['SvcDate'] = substr($sar[3], 0, 8);
continue;
}
}
} // end foreach($trans as $seg)
} // end foreach($asegs as $trans)
} // end for($i=0; $i<$clmct; $i++)
}// end foreach($obj277->envelopes['ST'] as $st)
} // end foreach($env_ar['ISA'] as $icn => $isa)
//
return $ret_ar;
}
/**
* parse an x12 278 file into data rows for csv tables
*
* @param object x12_file_object
* @return array
*/
function edih_278_csv_data($obj278)
{
//
// f278 file = array('Date', 'FileName', 'Control', 'TrnCount', 'Auth', 'Payer');
// f278 claim = array('PtName', 'FileDate', 'Trace', 'Status' 'BHT03', 'FileName', 'Auth', 'Payer');
//
$ret_ar = array();
//
$de = $obj278->edih_delimiters()['e'];
$ds = $obj278->edih_delimiters()['s'];
$fn = $obj278->edih_filename();
$seg_ar = $obj278->edih_segments();
$env_ar = $obj278->edih_envelopes();
$ft = csv_file_type($obj278->edih_type());
//
// $ft: 'HI'=>'278'
if (!isset($env_ar['ST'])) {
csv_edihist_log('edih_278_csv_data: envelope error ' . $fn);
return false;
}
//
if (!isset($env_ar['GS'])) {
csv_edihist_log('edih_278_csv_data: envelope error ' . $fn);
return $ret_ar;
}
//
foreach ($env_ar['ISA'] as $icn => $isa) {
// array('Date', 'FileName', 'Control', 'ta1ctrl', 'RejCt');
$ret_ar[$icn]['type'] = $ft;
$ret_ar[$icn]['claim'] = array();
$ret_ar[$icn]['file'] = array();
$rspdate = $isa['date'];
//
foreach ($env_ar['GS'] as $gs) {
if ($gs['icn'] == $icn) {
$rspdate = $gs['date'];
break;
}
}
foreach ($env_ar['ST'] as $st) {
//
if ($st['icn'] != $icn) {
continue;
}
//
$stsegs = array_slice($seg_ar, $st['start'], $st['count']);
$loopid = '0';
$hl = 0;
//$isasender = $env_ar['ISA'][$st['icn']]['sender'];
//$isadate = $env_ar['ISA'][$st['icn']]['date'];
$isaicn = $st['icn'];
$has_le = false;
//
// for "claim" array
//
foreach ($stsegs as $seg) {
//
if (strncmp($seg, 'BHT' . $de, 4) === 0) {
// new transaction
// bht01 0007 --> Src, Rcv, Sbr, Dep, Event, Services
$rqst = '';
$status = 'A';
$cdx = count($ret_ar[$icn]['claim']);
//
$sar = explode($de, $seg);
if (isset($sar[2])) {
if ($sar[2] == '01') {
$rqst = 'Cancel';
}
if ($sar[2] == '13') {
$rqst = 'Req';
}
if ($sar[2] == '11') {
$rqst = 'Rsp';
}
if ($sar[2] == '36') {
$rqst = 'Reply';
}
}
$loopid = 0;
//
$ret_ar[$icn]['claim'][$cdx]['PtName'] = '';
$ret_ar[$icn]['claim'][$cdx]['FileDate'] = $rspdate;
$ret_ar[$icn]['claim'][$cdx]['Trace'] = '';
$ret_ar[$icn]['claim'][$cdx]['Status'] = '';
$ret_ar[$icn]['claim'][$cdx]['BHT03'] = $sar[3]; //bht03 = $sar[3];
$ret_ar[$icn]['claim'][$cdx]['FileName'] = $fn;
$ret_ar[$icn]['claim'][$cdx]['Auth'] = $rqst;
$ret_ar[$icn]['claim'][$cdx]['Payer'] = '';
//
continue;
}
//
if (strncmp($seg, 'HL' . $de, 3) === 0) {
$sar = explode($de, $seg);
$hl = $sar[1];
$hlpc = $sar[2]; // parent code
$hllc = $sar[3];
$hlcc = (isset($sar[4])) ? $sar[4] : ''; // child code
if ($sar[3] == '20') { // level code
$loopid = '2000A'; // info source (payer)
} elseif ($sar[3] == '21') {
$loopid = '2000B'; // info receiver (clinic)
} elseif ($sar[3] == '22') {
$loopid = '2000C'; // subscriber
} elseif ($sar[3] == '23') {
$loopid = '2000D'; // dependent
} elseif ($sar[3] == 'EV') {
$loopid = '2000E'; // patient event
} elseif ($sar[3] == 'SS') {
$loopid = '2000F'; // service
} else {
//debug
csv_edihist_log('HL has no level ' . $seg . ' in ' . $fn);
}
continue;
}
//
if (strncmp($seg, 'NM1' . $de, 4) === 0) {
$sar = explode($de, $seg);
$nm101 = $sar[1];
$nm103 = $sar[3];
$nm103 = ($sar[4]) ? $nm103 . ', ' . $sar[4] : $nm103;
$nm103 = ($sar[5]) ? $nm103 . ' ' . $sar[5] : $nm103;
if ($loopid == '2000A') {
$ret_ar[$icn]['claim'][$cdx]['Payer'] = $nm103; //
$payer_name = $nm103;
} elseif ($loopid == '2000C') {
$ret_ar[$icn]['claim'][$cdx]['PtName'] = $nm103; //$ptname = $nm1;
$loopid = '2010C';
} elseif ($loopid == '2000D') {
$ret_ar[$icn]['claim'][$cdx]['PtName'] = $nm103; //$ptname = $nm1;
$loopid = '2010D';
} elseif (strpos('|2000E', $loopid)) {
$loopid = '2000E';
$loopid = (strpos('|71|72|73|77|AAJ|DD|DK|DN|FA|G3|P3|QB|QV|SJ', $nm101) ) ? '2010EA' : $loopid;
$loopid = (strpos('|45|FS|ND|PW|R3', $nm101) ) ? '2010EB' : $loopid;
$loopid = ($nm101 == 'L5') ? '2010EC' : $loopid;
} elseif ($loopid == '2000F') {
$loopid = '2000F';
$loopid = (strpos('|71|72|73|77|AAJ|DD|DK|DN|FA|G3|P3|QB|QV|SJ', $nm101) ) ? '2010FA' : $loopid;
}
continue;
}
// for 278 eligibility response (invalid data in 278 request)
if (strncmp($seg, 'AAA' . $de, 4) === 0) {
$sar = explode($de, $seg);
$status = 'R';
$rej_ct++;
$aaa_code = $sar[3];
$rsp_code = $sar[4];
if ($loopid == '2000A') {
$status .= ' Src ' . $aaa_code;
} elseif ($loopid == '2000B') {
$status .= ' Rcv ' . $aaa_code;
} elseif ($loopid == '2000C') {
$status .= ' Sbr ' . $aaa_code;
} elseif ($loopid == '2000D') {
$status .= ' Dep ' . $aaa_code;
} elseif ($loopid == '2000E') {
$status .= ' Pt ' . $aaa_code;
} elseif ($loopid == '2000F') {
$status .= ' Svc ' . $aaa_code;
} elseif ($loopid == '2010FA') {
$status .= ' Prv ' . $aaa_code;
} elseif ($loopid == '2010EA') {
$status .= ' Svc ' . $aaa_code;
} elseif ($loopid == '2010EC') {
$status .= ' Tpt ' . $aaa_code;
}
//
$ret_ar[$icn]['claim'][$cdx]['Status'] = $status;
//
continue;
}
//
// for 278 tracking
// this assumes OpenEMR will include a TRN segment in requests
if (strncmp($seg, 'TRN' . $de, 4) === 0) {
$sar = explode($de, $seg);
if ($rqst == 'Req') {
if (isset($sar[1]) && $sar[1] == '1') {
$ret_ar[$icn]['claim'][$cdx]['Trace'] = (isset($sar[2])) ? $sar[2] : '';
}
} else {
if (isset($sar[1]) && $sar[1] == '2') {
$ret_ar[$icn]['claim'][$cdx]['Trace'] = (isset($sar[2])) ? $sar[2] : '';
}
}
}
} // end foreach($stsegs as $seg)
//
} // endforeach($env_ar['ST'] as $st
$fdx = count($ret_ar[$icn]['file']);
//
$ret_ar[$icn]['file'][$fdx]['Date'] = $rspdate;
$ret_ar[$icn]['file'][$fdx]['FileName'] = $fn;
// could be GS06 for 278 request type
$ret_ar[$icn]['file'][$fdx]['Control'] = $icn;
$ret_ar[$icn]['file'][$fdx]['TrnCount'] = $cdx;
$ret_ar[$icn]['file'][$fdx]['Auth'] = $rqst;
$ret_ar[$icn]['file'][$fdx]['Payer'] = $payer_name;
//
} // endforeach($env_ar['ISA'] as $icn=>$isa)
//
return $ret_ar;
}
/**
* Obtain claim information from batch 837|270|276|278 file to match 997/999 response
* Note, we assume each batch ST envelope contains a single transaction.
* Manual inspection is required if more than one transaction in an ST block,
*
* The 997/999 parse script creates a BHT03 reference by concatenating the
* response ISA13 (in TA1 segment) and the ST02 from the AK2 segment
* return array ['pt_name'] ['clm01'] ['svcdate'] ['batch_name'] ['stn']
*
* @uses csv_file_type()
* @uses csv_search_record()
*
* @param string concatenate ISA13 and ST02 for source file
* @param string type of source file
* @return array
*/
function edih_rsp_st_match($rsp_trace, $file_type)
{
//
$info_ar = array();
//
if (strlen($rsp_trace) == 13) {
$bticn = substr($rsp_trace, 0, 9);
$stn = substr($rsp_trace, -4);
$btsrch = $rsp_trace;
} else {
// debug
csv_edihist_log('edih_rsp_st_match() invalid trace argument ' . $rsp_trace);
return $info_ar;
}
//
$ft = csv_file_type($file_type);
//
if (strpos('|f837|f276|f270|f278', $ft) === false) {
// debug
csv_edihist_log('edih_rsp_st_match: file type ' . $ft . ' not in |f837|f276|f270|278');
return $info_ar;
}
//
$batch_srch = csv_search_record($ft, 'claim', array('s_val' => $rsp_trace, 's_col' => 4, 'r_cols' => 'All'), '1');
if (is_array($batch_srch) && count($batch_srch[0])) {
$info_ar['pt_name'] = $batch_srch[0][0]; // $batch_srch['PtName'];
$info_ar['clm01'] = ($rtp == 'f837') ? $batch_srch[0][2] : $batch_srch[0][4]; // $batch_srch['CLM01'] : $batch_srch['BHT03'];
$info_ar['svcdate'] = $batch_srch[0][1]; // ($rtp == 'f270') ? $batch_srch['ReqDate'] : $batch_srch['SvcDate'];
$info_ar['batch_name'] = $batch_srch[0][5]; // $batch_srch['FileName'];
}
//
return $info_ar;
}
/** Extract csv file data rows from 997/999 files
*
* <pre> Creates array
* ['claim'][$i] = array('PtName', 'SvcDate', 'CLM01', 'Status', 'ak_num', 'File_997', 'Control', 'err_seg');
* ['file'][$i] = array('Date', 'FileName', 'Control', 'TA1ctrl', 'RejCt');
* </pre>
*
* @uses edih_x12_file() edi HC file class
* @uses edih_997_837_st_match()
* @param object edih_x12_file object of type 999/997
* @return array
*/
function edih_997_csv_data($obj997)
{
//
$ret_ar = array();
//
$de = $obj997->edih_delimiters()['e'];
$ds = $obj997->edih_delimiters()['s'];
$fn = $obj997->edih_filename();
$seg_ar = $obj997->edih_segments();
$env_ar = $obj997->edih_envelopes();
//
if (!isset($env_ar['ST'])) {
csv_edihist_log('edih_997_csv_data: envelope error');
return $ret_ar;
}
if (!isset($env_ar['GS'])) {
csv_edihist_log('edih_997_csv_data: envelope error');
return $ret_ar;
}
foreach ($env_ar['ISA'] as $icn => $isa) {
//
$ret_ar[$icn]['claim'] = array();
$ret_ar[$icn]['file'] = array();
foreach ($env_ar['GS'] as $gs) {
if ($gs['icn'] == $icn) {
$ret_ar[$icn]['type'] = csv_file_type($gs['type']);
$rspdate = $gs['date'];
break;
}
}
//
$fdx = count($ret_ar[$icn]['file']);
//
$ret_ar[$icn]['file'][$fdx]['Date'] = ($rspdate) ? $rspdate : $isa['date'];
$ret_ar[$icn]['file'][$fdx]['FileName'] = $fn;
$ret_ar[$icn]['file'][$fdx]['Control'] = $icn;
//
$rej_ct = 0;
// CTX segment identifiers
$trans_id = array('837' => 'CLM01', '270' => 'TRN02', '276' => 'TRN02');
//
//['f997']['claim'] = array('PtName', 'RspDate', 'CLM01', 'Status', 'ak_num', 'File_997', 'Control', 'err_seg');
foreach ($env_ar['ST'] as $st) {
//
if ($st['icn'] != $icn) {
continue;
}
//
$stsegs = array_slice($seg_ar, $st['start'], $st['count']);
$loopid = '0';
//$isasender = $env_ar['ISA'][$st['icn']]['sender'];
$isadate = $env_ar['ISA'][$st['icn']]['date'];
$isaicn = $st['icn'];
// match 997/999 response to sent file ISA control
$ret_ar[$icn]['file'][$fdx]['Trace'] = ($st['trace']) ? $st['trace'] : '';
$bticn = ($st['trace']) ? $st['trace'] : '';
if (!$st['trace']) {
//
csv_edihist_log('edih_997_csv_data: no trace to submitted file! ' . $fn);
}
//RspType
foreach ($stsegs as $seg) {
//
if (strncmp($seg, 'AK1' . $de, 4) === 0) {
$sar = explode($de, $seg);
$loopid = '2000';
$rsptype = csv_file_type($sar[1]);
// AK102 could be the 'trace' value if it were unique
$rspgsn = $sar[2];
//
continue;
}
if (strncmp($seg, 'AK2' . $de, 4) === 0) {
$sar = explode($de, $seg);
$rspsttype = csv_file_type($sar[1]);
$rspstn = (string)$sar[2];
$bht03syn = sprintf("%s%04d", $isaicn, $rspstn);
$iserr = false;
$err_seg = '';
$have_pt = false;
$ptname = '';
$svcdate = '';
continue;
}
if (strncmp($seg, 'IK3' . $de, 4) === 0 || strncmp($seg, 'AK3' . $de, 4) === 0) {
// >> try err_seg = str_replace($de, '*', $seg)
$sar = explode($de, $seg);
$iserr = true;
$loopid = '2100';
$ctx_ct = 0;
//
$err_seg .= ($err_seg) ? '' : $bht03syn . '*IK3*'; // ISA13+ST02 * invalid segment ID
$err_seg .= (isset($sar[1])) ? '*' . $sar[1] : '*';
$err_seg .= (isset($sar[2])) ? '*' . $sar[2] : '*'; // segment position
//$err_seg .= (isset($sar[3])) ? '*'.$sar[3] : '*'; // loop, first 4 characters
//$err_seg .= (isset($sar[4])) ? '*'.$sar[4] : '*'; // error code
//$err_seg .= '*'.;
// example IK3*NM1*16*2010*8~ |IK3*SegID*SegNum*Loop*ErrCode*$bht03syn
// locate segment (#16 in ST-SE envelope)
// ['err_seg'] = '|IK3*segID*segpos*loop*errcode*bht03syn|CTX-IK3*transID*segID*segpos*elempos
// |IK4*elempos*errcode*elem*CTX-IK4*segID*segpos*elempos'
//
// ///// retrieve original submitted claim
if (!$have_pt) {
//
$pt_info = edih_rsp_st_match($bht03syn, $rspsttype);
//return array ['pt_name']['svcdate']['clm01']['batch_name'];
if ($pt_info) {
$ptname = (isset($pt_info['pt_name']) && strlen($pt_info['pt_name'])) ? $pt_info['pt_name'] : 'Unknown';
$have_pt = true;
} else {
$ptname = 'Unknown';
}
}
// /////////////////////////
continue;
}
//
//if ( strncmp($seg, 'IK4'.$de, 4) === 0 || strncmp($seg, 'AK4'.$de, 4) === 0 ) {
//// data element error
//$sar = explode($de, $seg);
//$loopid == '2110';
//$iserr = true;
//$ctx_ct = 0;
//$err_seg .= ($err_seg) ? '|IK4' : '';
//$err_seg .= (isset($sar[1])) ? '*'.$sar[1] : '*';
//$err_seg .= (isset($sar[2])) ? '*'.$sar[2] : '*';
////$err_seg .= (isset($sar[3])) ? '*'.$sar[3] : '*';
////$err_seg .= (isset($sar[4])) ? '*'.$sar[4] : '*';
//// |IK4|elempos|errcode|elem
//continue;
//}
//
//if ( strncmp($seg, 'CTX'.$de, 4) === 0 ) {
//$sar = explode($de, $seg);
//$ctx_ct++;
//if ($loopid == '2100') {
//$err_seg .= '|CTX-IK3';
//}
//if ($loopid == '2110') {
//$err_seg .= '|CTX-IK4';
//}
//// CTX segment identifiers $trans_id['837'] ['270'] ['276']
//if ( isset($trans_id[$rsptype]) && strpos($seg, $trans_id[$rsptype]) ) {
//$err_seg .= (isset($sar[1]) && $sar[1]) ? '*'.$sar[1] : '';
//}
//if(strncmp($sar[1], 'SITUA', 5) === 0 ) {
//// SITUATIONAL TRIGGER
//$err_seg .= (isset($sar[2]) && $sar[2]) ? '*'.$sar[2] : '*';
//$err_seg .= (isset($sar[3]) && $sar[3]) ? '*'.$sar[3] : '*';
//$err_seg .= (isset($sar[5]) && $sar[5]) ? '*'.$sar[5] : '*';
//// |CTX-IK3*segID*segPos*loopLS*elemPos:compositePos:repPos
//} elseif ($ctx_ct > 1) {
//$err_seg .= '*'.$sar[2];
//if (!$have_pt) {
//$p1 = strpos($sar[1],$ds);
//$p2 = ($p1) ? strlen($sar[1])-$p1-1 : strlen($sar[1]);
//$ret_ar[$icn]['claim'][$cdx]['CLM01'] = substr($sar[1], -$p2);
//}
//}
//continue;
//}
//
if (strncmp($seg, 'AK5' . $de, 4) === 0 || strncmp($seg, 'IK5' . $de, 4) === 0) {
// only store claims entries if there is an error
$sar = explode($de, $seg);
if ($sar[1] == 'A') {
continue;
} else {
$rej_ct++;
//
$cdx = count($ret_ar[$icn]['claim']);
//array('PtName', 'RspDate', 'Trace', 'Status', 'Control', 'FileName', 'RspType', 'err_seg');
$ret_ar[$icn]['claim'][$cdx]['PtName'] = $ptname;
$ret_ar[$icn]['claim'][$cdx]['RspDate'] = $svcdate;
//
$ret_ar[$icn]['claim'][$cdx]['Trace'] = $bht03syn;
$ret_ar[$icn]['claim'][$cdx]['Status'] = $sar[1];
$ret_ar[$icn]['claim'][$cdx]['Control'] = $icn;
$ret_ar[$icn]['claim'][$cdx]['FileName'] = $fn;
$ret_ar[$icn]['claim'][$cdx]['RspType'] = $rspsttype;
//
$ret_ar[$icn]['claim'][$cdx]['err_seg'] = $err_seg;
//
// AK502 = Code indicating implementation error found based on the syntax editing of a transaction set
}
}
//
} // end foreach($env_ar['ST'] as $st)
$ret_ar[$icn]['file'][$fdx]['RejCt'] = $rej_ct;
$ret_ar[$icn]['file'][$fdx]['RspType'] = $rsptype;
} // end foreach($env_ar['ISA'] as $icn => $isa)
}
//
return $ret_ar;
}
/**
* parse an x12 270/271 file into data rows for csv tables
*
* @param object x12_file_object
* @return array
*/
function edih_271_csv_data($obj270)
{
//'f270 claim = array('PtName', 'ReqDate', 'PtAcct', 'InsLevel', 'BHT03', 'FileName', 'Payer');
//'f270 file = array('Date', 'FileName', 'Control', 'Claim_ct', 'x12_partner');
//'f271 file = array('Date', 'FileName', 'Control', 'Claim_ct', 'Denied', 'Payer');
//'f271 claim = array('PtName', 'RspDate', 'Trace', 'Status', 'BHT03', 'FileName', 'Payer');
//
$ret_ar = array();
//
$de = $obj270->edih_delimiters()['e'];
$ds = $obj270->edih_delimiters()['s'];
$fn = $obj270->edih_filename();
$seg_ar = $obj270->edih_segments();
$env_ar = $obj270->edih_envelopes();
$ft = csv_file_type($obj270->edih_type());
//
// $rsptype = array('HS'=>'270', 'HB'=>'271', 'HC'=>'837', 'HR'=>'276', 'HI'=>'278');
if (!isset($env_ar['ST'])) {
csv_edihist_log('edih_271_csv_data: envelope error ' . $fn);
return $ret_ar;
}
//
if (!isset($env_ar['GS'])) {
csv_edihist_log('edih_271_csv_data: envelope error');
return $ret_ar;
}
//
foreach ($env_ar['ISA'] as $icn => $isa) {
// array('Date', 'FileName', 'Control', 'ta1ctrl', 'RejCt');
$ret_ar[$icn]['type'] = $ft;
$ret_ar[$icn]['claim'] = array();
$ret_ar[$icn]['file'] = array();
$rspdate = $isa['date'];
$x12ptnr = $isa['receiver'];
//
foreach ($env_ar['GS'] as $gs) {
if ($gs['icn'] == $icn) {
$gsdate = $gs['date'];
break;
}
}
foreach ($env_ar['ST'] as $st) {
//
if ($st['icn'] != $icn) {
continue;
}
//
$stsegs = array_slice($seg_ar, $st['start'], $st['count']);
$loopid = '0';
$hl = 0;
//
$isaicn = $st['icn'];
$stn = $st['stn'];
$has_le = false;
//
// for "claim" array
// 'f270' array('PtName', 'ReqDate', 'Trace', 'InsBnft', 'BHT03', 'FileName', 'Payer'); break;
// 'f271'array('PtName', 'RspDate', 'Trace', 'Status', 'BHT03', 'FileName', 'Payer'); break;
//
foreach ($stsegs as $seg) {
//
if (strncmp($seg, 'BHT' . $de, 4) === 0) {
// new transaction
$cdx = (isset($ret_ar[$icn]['claim']) ) ? count($ret_ar[$icn]['claim']) : 0;
//
$sar = explode($de, $seg);
//
$isrqst = (isset($sar[2]) && $sar[2] == '13') ? true : false;
$isrsp = (isset($sar[2]) && $sar[2] == '11') ? true : false;
$loopid = 0;
$bnfteq = '';
$rej_ct = 0;
//
$dtkey = ($ft == 'f271') ? 'RspDate' : 'ReqDate';
//
$ret_ar[$icn]['claim'][$cdx]['PtName'] = '';
$ret_ar[$icn]['claim'][$cdx][$dtkey] = $gsdate;
$ret_ar[$icn]['claim'][$cdx]['Trace'] = '';
if ($isrsp || $ft == 'f271') {
$ret_ar[$icn]['claim'][$cdx]['Status'] = 'A'; // 271
$ret_ar[$icn]['claim'][$cdx]['BHT03'] = (isset($sar[3])) ? $sar[3] : ''; //bht03 = $sar[3];
} else {
$ret_ar[$icn]['claim'][$cdx]['InsBnft'] = ''; // 270
$ret_ar[$icn]['claim'][$cdx]['BHT03'] = sprintf("%s%04d", $isaicn, $stn);
}
$ret_ar[$icn]['claim'][$cdx]['FileName'] = $fn;
$ret_ar[$icn]['claim'][$cdx]['Payer'] = '';
//
continue;
}
//
if (strncmp($seg, 'HL' . $de, 3) === 0) {
$sar = explode($de, $seg);
$hl = $sar[1];
$hlpc = $sar[2]; // parent code
$hllc = $sar[3];
$hlcc = (isset($sar[4])) ? $sar[4] : ''; // child code
if ($sar[3] == '20') { // level code
$loopid = '2000A'; // info source (payer)
} elseif ($sar[3] == '21') {
$loopid = '2000B'; // info receiver (clinic)
} elseif ($sar[3] == '22') {
$loopid = '2000C'; // subscriber
} elseif ($sar[3] == '23') {
$loopid = '2000D'; // dependent
} else {
//debug
csv_edihist_log('HL has no level ' . $seg . ' in ' . $fn);
}
continue;
}
//
if (strncmp($seg, 'NM1' . $de, 4) === 0) {
$sar = explode($de, $seg);
$nm1 = $sar[3];
$nm1 = ($sar[4]) ? $nm1 . ', ' . $sar[4] : $nm1;
$nm1 = ($sar[5]) ? $nm1 . ' ' . $sar[5] : $nm1;
if ($loopid == '2000A') {
$ret_ar[$icn]['claim'][$cdx]['Payer'] = $nm1; //
$payer_name = $nm1;
} elseif ($loopid == '2000C' || $loopid == '2000D') {
$ret_ar[$icn]['claim'][$cdx]['PtName'] = $nm1; //$ptname = $nm1;
}
continue;
}
// for 271 eligibility response (invalid data in 270 request)
if (strncmp($seg, 'AAA' . $de, 4) === 0) {
$sar = explode($de, $seg);
$status = 'R';
$rej_ct++;
$aaa_code = $sar[3];
$rsp_code = $sar[4];
if ($loopid == '2000A') {
$status = $status . ' Src ' . $aaa_code;
} elseif ($loopid == '2000B') {
$status = $status . ' Rcv ' . $aaa_code;
} elseif ($loopid == '2000C') {
$status = $status . ' Sbr ' . $aaa_code;
} elseif ($loopid == '2000D') {
$status = $status . ' Dep ' . $aaa_code;
}
//
$ret_ar[$icn]['claim'][$cdx]['Status'] = $status;
//
continue;
}
//
// for 270 eligibility request
if (strncmp($seg, 'EQ' . $de, 3) === 0) {
if (strlen((string)$sar[1])) {
$bnfteq .= ($bnfteq) ? '|' . $sar[1] : $sar[1];
} elseif (strlen((string)$sar[2])) {
$bnfteq .= ($bnfteq) ? '|' . $sar[2] : $sar[2];
} else {
csv_edihist_log('Invalid EQ segment, missing benefit type in ' . $fn);
continue;
}
$ret_ar[$icn]['claim'][$cdx]['InsBnft'] = $bnfteq;
continue;
}
// overridden by REF*EJ* (not)
if (strncmp($seg, 'TRN' . $de, 4) === 0) {
if ($loopid = '2000C' || $loopid == '2000D') {
$sar = explode($de, $seg);
$ret_ar[$icn]['claim'][$cdx]['Trace'] = $sar[2]; //$ptacct = $sar[2];
}
//
continue;
}
// for 271 eligibility response
if (strncmp($seg, 'EB' . $de, 3) === 0) {
$status = ( isset($status) ) ? $status : '';
//
if (strpos($ret_ar[$icn]['claim'][$cdx]['Status'], 'tive')) {
continue;
}
//
$sar = explode($de, $seg);
//
if (isset($sar[2])) {
if ($sar[2] == '6' || $sar[2] == '7' || $sar[2] == '8') {
$status = 'Inactive';
} elseif ($sar[2] == 'I') {
$status = 'Non-Covered';
$rej_ct++;
} elseif ($sar[2] == 'E') {
$status = 'Exclusions';
$rej_ct++;
} elseif ($sar[2] == 'N') {
$status = 'Restricted';
$rej_ct++;
} elseif ($sar[2] == 'V') {
$status = 'Unknown';
$rej_ct++;
} elseif ($sar[2] == 'T') {
$status = 'Card Lost';
$rej_ct++;
} elseif ($sar[2] == 'U') {
$status = 'Contact';
$rej_ct++;
} elseif ($sar[2] == '1') {
$status = 'Active';
} elseif ($sar[2] == '2' || $sar[2] == '3' || $sar[2] == '4') {
$status = 'Active Cap';
}
}
//
$ret_ar[$icn]['claim'][$cdx]['Status'] = $status;
//
continue;
}
//
if (strncmp($seg, 'DTP' . $de, 4) === 0) {
$sar = explode($de, $seg);
$dtp03 = (isset($sar[2]) && $sar[2] == 'D8') ? $sar[3] : substr($sar[3], 0, 8);
if ($isrsp) {
if ($loopid == '2100C' || $loopid == '2110C') {
$ret_ar[$icn]['claim'][$cdx]['RspDate'] = $dtp03;
} elseif ($loopid == '2100D' || $loopid == '2110D') {
$ret_ar[$icn]['claim'][$cdx]['RspDate'] = $dtp03;
}
} else {
if ($loopid == '2100C' || $loopid == '2110C') {
$ret_ar[$icn]['claim'][$cdx]['ReqDate'] = $dtp03;
} elseif ($loopid == '2100D' || $loopid == '2110D') {
$ret_ar[$icn]['claim'][$cdx]['ReqDate'] = $dtp03;
}
}
//
continue;
}
//
/*
if (strncmp($seg, 'REF'.$de.'EJ'.$de, 7) === 0 ) {
// patient account -- replaces or replaced by TRN02
$sar = explode($de, $seg);
$ret_ar[$icn]['claim'][$cdx]['PtAcct'] = $sar[2]; //$ptacct = $sar[2];
//
continue;
}
*/
//
} // end foreach($stsegs as $seg)
//
} // endforeach($env_ar['ST'] as $st
// file: 'f271': array('Date', 'FileName', 'Control', 'Claim_ct', 'Reject', 'Payer')
$fdx = count($ret_ar[$icn]['file']);
//'f270': $hdr = array('Date', 'FileName', 'Control', 'Claim_ct', 'x12Partner');
$ret_ar[$icn]['file'][$fdx]['Date'] = $gsdate;
$ret_ar[$icn]['file'][$fdx]['FileName'] = $fn;
// for 270 type, could use GSO6 if it were unique
$ret_ar[$icn]['file'][$fdx]['Control'] = $icn;
$ret_ar[$icn]['file'][$fdx]['Claim_ct'] = $cdx;
if ($isrsp || $ft == 'f271') {
$ret_ar[$icn]['file'][$fdx]['Reject'] = $rej_ct;
$ret_ar[$icn]['file'][$fdx]['Payer'] = $payer_name;
} else {
$ret_ar[$icn]['file'][$fdx]['x12Partner'] = $x12ptnr;
}
//
} // endforeach($env_ar['ISA'] as $icn=>$isa)
//
return $ret_ar;
}
/*
* this function opens the x12 file in the object and routes
* the object to the parsing function according to the x12 type
* csvdata array design:
* [$icn]['claims'][i] [$icn]['files'][i] [$icn]['type']
*
* @uses edih_835_csv_data()
* @uses edih_837_csv_data()
* @uses edih_277_csv_data()
* @uses edih_271_csv_data()
* @uses edih_278_csv_data()
* @uses edih_997_csv_data()
*
* @param string path to file
* @return array data for csv table records
*/
function edih_parse_select($file_path)
{
$csvdata = array();
// csvdata array design:
// $csvdata[$icn]['claims'][i] [$icn]['files'][i] [$icn]['type']
//
$x12_obj = csv_check_x12_obj($file_path);
//$x12_obj = new edih_x12_file($file_path);
if ($x12_obj instanceof edih_x12_file) {
$ft = $x12_obj->edih_type();
} else {
csv_edihist_log('edih_parse_select: error in file path');
return $csvdata;
}
//'HB'=>'271', 'HS'=>'270', 'HR'=>'276', 'HI'=>'278',
//'HN'=>'277', 'HP'=>'835', 'FA'=>'999', 'HC'=>'837'
//
if ($ft == 'HP') {
$csvdata = edih_835_csv_data($x12_obj);
} elseif ($ft == 'HC') {
$csvdata = edih_837_csv_data($x12_obj);
} elseif ($ft == 'HN' || $ft == 'HR') {
$csvdata = edih_277_csv_data($x12_obj);
} elseif ($ft == 'FA') {
$csvdata = edih_997_csv_data($x12_obj);
} elseif ($ft == 'HB' || $ft == 'HS') {
$csvdata = edih_271_csv_data($x12_obj);
} elseif ($ft == 'HI') {
$csvdata = edih_278_csv_data($x12_obj);
} else {
// debug
csv_edihist_log('edih_parse_select(): unsupported file type ' . $ft . ' name: ' . basename($file_path));
}
//
return $csvdata;
}