edihistory -- claim status, fixed locating response in 277 file issues; csvTable...
[openemr.git] / library / edihistory / ibr_277_read.php
blob2e020f9776a20fe4760910fbff3230b18e920f5b
1 <?php
2 /**
3 * ibr_277_read.php
4 *
5 * read x12 277 claim status responses, especially the 277CA variety
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 3 or later.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. You should have received
15 * a copy of the GNU General Public License along with this program;
16 * if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 * <http://opensource.org/licenses/gpl-license.php>
20 * @author Kevin McCormick
21 * @link: http://www.open-emr.org
22 * @package OpenEMR
23 * @subpackage ediHistory
26 // /**
27 // * a security measure to prevent direct web access to this file
28 // */
29 // if (!defined('SITE_IN')) die('Direct access not allowed!');
33 /**
34 * get the segments or array_slice parameters for ISA...IEA in a 277 file
36 * @todo adapt this to general purpose x12 section getter
38 * @uses csv_verify_file()
39 * @uses csv_x12_segments()
40 * @param string $filename name of file
41 * @param string $isa13 the ISA control number
42 * @param bool $slice_params whether to return array_slice() parameters or the segments
43 * @return array
44 */
45 function ibr_277_isa_block($filename, $isa13, $slice_params=false) {
47 $isa_str = '';
48 $srchval = strval($isa13);
49 // get segments
50 $x12seg = csv_x12_segments($filename, 'f277', false);
51 if ( !$x12seg || ! isset($x12seg['segments']) ) {
52 $isa_str .= "ibr_277_isa_block: failed to get segments for ".basename($filename).PHP_EOL;
53 csv_edihist_log("ibr_277_isa_block: failed to get segments for $filename");
54 return $isa_str;
57 $elem_d = $x12seg['delimiters']['e'];
58 $isa277 = array();
59 $isa_slice = array();
60 $isa_pos = 0;
61 $idx = -1;
62 foreach($x12seg['segments'] as $segstr) {
63 $idx++;
64 if (substr($segstr, 0, 4) == 'ISA'.$elem_d) {
65 $seg = explode($elem_d, $segstr);
66 $isfound = (strval($seg[13]) == $srchval);
67 $isa_pos = $idx;
70 if ($isfound && !$slice_params) { $isa277[] = $segstr; }
72 if (substr($segstr, 0, 4) == 'IEA'.$elem_d) {
73 $seg = explode($elem_d, $segstr);
74 if (strval($seg[2]) == $srchval) {
75 $isa_slice['start'] = $isa_pos;
76 $isa_slice['count'] = $idx - $isa_pos + 1;
77 //$isfound = false;
78 break;
83 if ( !count($isa277) && !count($isa_slice) ) {
84 $isa_str .= "ibr_277_isa_block: did not find $isa13 in " . basename($filename).PHP_EOL;
85 csv_edihist_log("ibr_277_isa_block: did not find $isa13 in $filename");
86 return $isa_str;
89 if ($slice_params) {
90 return $isa_slice;
91 } else {
92 return $isa277;
97 /**
98 * Selected values from $ar277['claim'] array for claims_277.csv
100 * these are for initial batch return files, basically saying the claims are accepted
101 * for "adjudication" or rejected due to some error or omission
102 * close match to Availity ebr|ibr files, which are derived from these
103 * This uses an edit to the OpenEMR billing_process.php script to create
104 * a unique BHT03 id number, since that is how the claims are identified
106 * @uses ibr_batch_by_ctln()
107 * @param array $ar_277 the array from {@see ibr_277_parse()}
108 * @return array
110 function ibr_277_csv_claim_data($ar_277_clm) {
112 // the $ar_277_vals [ $ar277['claim'] ] array:
113 // <pre>
114 // $arRSP[$isa_ct]['key']
115 // ['BHT'] ['isa_id']['gs06']['iea02']
117 // $arRSP["claim"][$isa_ct]=>["ISA13"]["GS04"]["GS06"]["IEA02"]
118 // =>['BHT']['bht_ct']['key']
119 // =>['ENV"]=>['BHT01']['BHT02']['BHT03']['BHT04']
120 // ['BHT06']["FILE"]["ISA13"]["ST02"]["SE01"]
121 // =>['A']=>['NM101']["NM102"]["NM103"]["NM104"]["NM105"]
122 // ["NM107"]["NM108"]["NM109"]["TRN01"]["TRN02"]
123 // ["DTP03050"]["DTP03009"]
124 // =>['B']=>['NM101']["NM102"]["NM103"]["NM104"]["NM105"]
125 // ["NM107"]["NM108"]["NM109"]["TRN01"]["TRN02"]
126 // ["STC011"]["STC012"]["STC013"]["STC014"]
127 // ["STC02"]["STC03"]["STC04"]["QTY01"]["QTY02"]
128 // ["AMT01"]["AMT02"]
129 // =>['C']=>['NM101']["NM102"]["NM103"]["NM104"]["NM105"]
130 // ["NM107"]["NM108"]["NM109"]["TRN01"]["TRN02"]
131 // ["REFTJ"]
132 // =>['D']=>['NM101']["NM102"]["NM103"]["NM104"]["NM105"]
133 // ["NM107"]["NM108"]["NM109"]["TRN01"]["TRN02"]
134 // ["REF1K"]["REFD9"]["DTP03FROM"]["DTP03TO"]
135 // =>["STC"][i]=>["STC011"]["STC012"]["STC013"]
136 // ["STC014"]["STC02"]["STC03"]["STC04"]
137 // </pre>
138 if (!is_array($ar_277_clm) || count($ar_277_clm) == 0 ) {
139 return FALSE;
142 $codes277 = new status_code_arrays();
144 $csv_ar = array();
146 foreach($ar_277_clm['BHT'] as $bht) {
147 $status = ""; $message = ""; $bfl = ""; $ctlnum = ""; $stnum = "";
148 // this is the BHT03 value from the batch file
149 $bt_bht03 = strval($bht['B']['TRN02']);
151 $st_277 = $bht['ENV']['ISA13'].'_'.$bht['ENV']['ST02']; // this is to find the response later
152 $file_277 = $bht['ENV']['FILE'];
153 $payer_name = isset($bht['A']['NM103'] ) ? $bht['A']['NM103'] : "Unknown Payer";
154 // if no claim_id, but ['TRN02'], find the pid-encounter with batch file and st02
155 if ( isset($bht['D']['REF1K']) ) {
156 $claim_id = $bht['D']['REF1K'];
157 } elseif (isset($bht['D']['REFD9'])) {
158 $claim_id = $bht['D']['REFD9'];
159 } elseif (isset($bht['D']['REFEA'])) {
160 $claim_id = $bht['D']['REFEA'];
161 } elseif (isset($bht['D']['REFBLT'])) {
162 $claim_id = $bht['D']['REFBLT'];
163 } elseif (isset($bht['D']['REFEJ'])) {
164 $claim_id = $bht['D']['REFEJ'];
165 } elseif (isset($bht['D']['REFXZ'])) {
166 $claim_id = $bht['D']['REFXZ'];
167 } elseif (isset($bht['D']['REFVV'])) {
168 $claim_id = $bht['D']['REFVV'];
169 } else {
170 $claim_id = "NF";
172 $pt_name = $bht['D']['NM103'] . ", " . $bht['D']['NM104'];
173 $date = $bht['D']['DTP03FROM'];
174 $pid = $bht['D']['TRN02']; //$pidenc[0]
175 foreach ($bht['D']['STC'] as $stc) {
177 $status = $stc['STC011'];
179 if ($stc['STC011'] == "A1" ) {
180 $status = "A1 Ack";
181 } elseif ($stc['STC011'] == "A2" ) {
182 $status = "A2 Acpt";
183 } elseif ($stc['STC011'] == "A3" ) {
184 $status = "A3 Rej";
185 } elseif ($stc['STC011'] == "A4" ) {
186 $status = "A4 Nfnd";
187 } elseif ($stc['STC011'] == "A5" ) {
188 $status = "A5 Split";
189 } elseif ($stc['STC011'] == "A6" ) {
190 $status = "A6 Rej";
191 } elseif ($stc['STC011'] == "A7" ) {
192 $status = "A7 Rej";
193 } elseif ($stc['STC011'] == "A8" ) {
194 $status = "A8 Rej";
195 } elseif ($stc['STC011'] == "DO" ) {
196 $status = "DO Fail";
198 if ($stc['STC03'] == "15") { $status .= " Resubmit"; }
200 // error message expected in STC12, but not always given
201 if (isset($stc['STC12'])) {
202 $message .= trim($stc['STC12']) . " ";
203 } elseif (strpos("|A1|A2|A5|", $stc['STC011']) === FALSE) {
204 $message .= 'Reject: ';
205 if (isset($stc['STC012'])) {
206 $cd = $codes277->get_STC_Status_Code( $stc['STC012'] );
207 $message .= $cd[0] . ' ' . $cd[1];
209 if (isset($stc['STC013'])) {
210 $cd = $codes277->get_STC_Entity_Code( $stc['STC013'] );
211 $message .= ' | ' . $cd[1];
215 // revised csv layout
216 //['f277']['claim'] = array('PtName', 'SvcDate', 'clm01', 'Status', 'st_277', 'File_277', 'payer_name', 'claim_id', 'bht03_837');
217 $csv_ar[] = array('pt_name'=>$pt_name, 'date'=>$date, 'pid'=>$pid, 'status'=>$status,
218 'st_277'=>$st_277, 'file_277'=>$file_277, 'payer_name'=>$payer_name,
219 'claim_id'=>$claim_id, 'bht03_837'=>$bt_bht03, 'message'=>$message);
221 }// end foreach ($ar_277_vals as $isa)
223 return $csv_ar;
228 * write data to csv file
230 * @deprecated
231 * @uses csv_write_record()
232 * @param array $ar_claim_data the data array, either file data or claim data
233 * @param string $type either claim or file, claim if omitted
234 * @return int character count from fputcsv()
236 function ibr_277_write_csv($ar_data, $type = "claim") {
238 $ct = ($type == "claim") ? 'claim' : 'file';
239 $rslt = csv_write_record($ar_data, "f277", $ct);
240 return $rslt;
244 * create an html string for a table to display in a web page
246 * @param $ar_data array produced by function ibr_ebr_data_ar
247 * @param $err_only boolean ignore claim information if no 3e subarray is in the claim data
248 * @return string
250 function ibr_277_html ($ar_data, $err_only=FALSE) {
251 //$ar_hd = $ar_data['head'];
252 //$ar_cd = $ar_data['claims'];
253 $idx = 0;
254 $idf = 0;
255 $has3 = FALSE;
256 $hasclm = FALSE;
257 $clm_html = "";
258 $str_html = "";
260 $dtl = ($err_only) ? "Errors only" : "All included claims";
261 //$ar_col_hdr = array('mtime', 'directory', 'file_name', 'text_name', 'claim_ct', 'reject');
262 // the table heading for files'mtime', 'directory', 'file_name', 'claim_ct', 'amt_accpt','reject', 'amt_rej'
263 $f_hdg = "<table cols=6 class=\"f277\">
264 <caption>277 Files Summary {$dtl} </caption>
265 <thead>
266 <tr>
267 <th>Date</th><th>277 File</th><th>Claims</th><th>Amt Total</th><th>Rejects</th><th>Amt Rej</th>
268 </tr>
269 </thead>
270 <tbody>";
272 // the details table heading'pt_name''date''pid''status''st_277''claim_id''payer_name''message'
273 $clm_hdg = "<table cols=6 class=\"f277\">
274 <thead>
275 <tr>
276 <th>Patient Name</th><th>Date</th><th>PtCtln</th><th>Status</th><th>Payer Name</th><th>Claim No</th>
277 </tr>
278 <tr>
279 <th colspan=6 align=left>Message</th>
280 </tr>
281 </thead>
282 <tbody>";
284 // start with the table heading
285 $str_html .= $f_hdg;
287 foreach ($ar_data as $ardt) {
288 // alternate colors
289 $bgf = ($idf % 2 == 1 ) ? 'fodd' : 'feven';
290 $idf++;
292 // if any individual claims detail is to be output
293 // a claims table was inserted, so put the files heading in
294 if ($hasclm) { $str_html .= $f_hdg; }
295 // reset variables for whether there are claims
296 $clm_html = "";
297 $has3 = FALSE;
298 $hasclm = FALSE;
300 if (isset($ardt['file'])) {
301 // 'filetime''filename''isa13_277''claim_ct''amt_accpt''claim_rct''amt_rej'
303 $str_html .= "
304 <tr class=\"{$bgf}\">
305 <td>{$ardt['file']['filetime']};</td>
306 <td><a href=\"edi_history_main.php?fvkey={$ardt['file']['filename']}\" target=\"_blank\">{$ardt['file']['filename']}</a></td>
307 <td>{$ardt['file']['claim_ct']}</td>
308 <td>{$ardt['file']['amt_accpt']}</td>
309 <td>{$ardt['file']['claim_rct']}</td>
310 <td>{$ardt['file']['amt_rej']}</td>
311 </tr>";
313 if (isset($ardt['claim']) ) {
314 foreach ($ardt['claim'] as $val) {
315 if ($err_only && $val['message'] == "" ) { continue; }
316 $bgc = ($idx % 2 == 1 ) ? 'odd' : 'even';
317 $hasclm = TRUE;
318 $clm_html .= "<tr class=\"{$bgc}\">
319 <td>{$val['pt_name']}</td>
320 <td>{$val['date']}</td>
321 <td><a class='btclm' target='_blank' href='edi_history_main.php?fvbatch={$val['bht03_837']}&btpid={$val['pid']}'>{$val['pid']}</td>
322 <td><a class='clmstatus' target='_blank' href='edi_history_main.php?rspfile={$val['file_277']}&pidenc={$val['pid']}&rspstnum={$val['st_277']}'>{$val['status']}</td>
323 <td>{$val['payer_name']}</td>
324 <td>{$val['claim_id']}</td>
325 </tr>
326 <tr class=\"{$bgc}\">
327 <td colspan = 7>{$val['message']}</td>
328 </tr>";
329 $idx++;
332 // if there were any claims detailed
333 if ( $hasclm && strlen($clm_html) ) {
334 $str_html .= $clm_hdg.$clm_html.PHP_EOL."</tbody></table>".PHP_EOL;
337 // finish the table
338 $str_html .= "</tbody></table>";
340 return $str_html;
345 * Parse x12 277 file into array
347 * The x12 277 claim status response file contains many fields that are useful for
348 * different purposes, so there is a lot of surplus information depending on your
349 * reason for viewing the file. This function is really based on 277CA files,
350 * but it should mostly work with plain 277 files, (if there was a 276 generator)
352 * <pre>
353 * Return array has keys 'file' and 'claim'
354 * The 'claim' array is detailed here:
355 * $arRSP[$isa_ct]['key']
356 * ['BHT'] ['isa_id']['gs06']['iea02']
358 * $arRSP[$isa_ct]['BHT']['bht_ct']['key']
359 * ['ENV"] ['A'] ['B'] ['C'] ['D']['BHT01']['BHT02']['BHT03']['BHT04']['BHT06']
361 * $arRSP[$isa_ct]['BHT']['bht_ct']['ENV"]
362 * ['ISA13'] ['ST02'] ['SE01'] ['FILE']
364 * $arRSP[$isa_ct]['BHT']['bht_ct']['A'] (sender -- insurance company or clearinghouse)
365 * ['NM103']['NM109']['TRN02']['DTP03050']['DTP03009']['PER01']['PER02']['PER03']['PER04']
367 * $arRSP[$isa_ct]['BHT']['bht_ct']['B'] (receiver -- practice or biller)
368 * ['STC011']['STC012']['STC013']['STC014']
369 * ['STC01']['STC02']['STC03']['STC04']['STC05']['STC06']['STC07']['STC08'] ['STC09']
370 * ['STC101']['STC102']['STC103']['STC104']
371 * ['STC111']['STC112']['STC113']['STC114']
372 * ['QTY01']['QTY02']['AMT01']['AMT02']
374 * $arRSP[$isa_ct]['BHT']['bht_ct']['C'] (provider -- practice or individual)
375 * ['NM103']['NM104']['NM105']['NM107']['NM108']['NM109']['TRN01'] ['TRN02']
376 * ['REF01']['REF02']['QTY01']['QTY02']['AMT01']['AMT02']
378 * $arRSP[$isa_ct]['BHT']['bht_ct']['D'] (patient -- individual)
379 * ['NM102']['NM103']['NM104']['NM105']['NM107']['NM108']['NM109']['TRN01']['TRN02']
380 * ['REF1K']['REFD9']['REFEA']['REFBLT']['REFEJ']['REFXZ']['REFVV']
381 * ['DTP03FROM'] ['DTP03TO']
383 * $arRSP[$isa_ct]['BHT']['bht_ct']['D']['STC'][stccount]['key']
384 * ['STC011']['STC012']['STC013']['STC014']['STC011']['STC012']
385 * ['STC02']['STC03']['STC04']['STC05']['STC06']['STC07']['STC08']['STC09']
386 * ['STC101']['STC102']['STC103']['STC104']
387 * ['STC111']['STC112']['STC113']['STC114']
389 * $arRSP[$isa_ct]['BHT']['bht_ct']['D']['SVC'][svccount]['key']
390 * ['SVC011']['SVC012']['SVC013']['SVC014']['SVC015']['SVC016']['SVC017']
391 * ['SVC02']['SVC03']['SVC04']['SVC05']['SVC06']['SVC07']
392 * $arRSP[$isa_ct]['BHT']['bht_ct']['D']['SVC'][svccount]['STC'][stccount]['key']
393 * ['STC011']['STC012']['STC013']['STC014']
394 * ['STC02']['STC03']['STC04']['STC05']['STC06']['STC07']['STC08']['STC09']
395 * ['STC101']['STC102']['STC103']['STC104']
396 * ['STC111']['STC112']['STC113']['STC114']
397 * ['STC12']
398 * </pre>
400 * @todo refactor array design -- does not account well enough for x12 controls or references
401 * @param array $ar_segments -- from ibr_277_process_new and csv_record_include.php
402 * @return array
404 function ibr_277_parse($ar_segments) {
407 // read each segment and parse for desired data
409 // $ar_vals['hl_prv']
410 // ['prv_name']['prv_id']
411 // $ar_vals['hl_prv']['clm_ct']
413 // ISA*00
414 // GS*HN
415 // - ST*277
416 // 0085 expect - BHT*0085
417 // HL*1 NM1*PR TRN*1 DTP*050 DTP*009 // HL03 NM103 NM109
418 // HL*2 NM1*41 TRN*2 STC*A1 QTY*90*1 AMT*YU //
419 // HL*3 NM1*85 TRN*1 REF*TJ QTY*QA*1 AMT*YU
420 // HL*4 NM1*QC TRN*2 STC*A1 REF*1K REF*D9 DTP*472
421 // - repeat BHT series
422 // - SE*27
423 // GE*26
424 // IEA*1
426 if (is_array($ar_segments) && count($ar_segments['segments']) ) {
427 $fdir = dirname($ar_segments['path']);
428 $fname = basename($ar_segments['path']);
429 $fmtime = date('Ymd', filemtime($ar_segments['path']) );
431 $ar_277_segments = $ar_segments['segments'];
433 $elem_d = $ar_segments['delimiters']['e'];
434 $rep_d = $ar_segments['delimiters']['r'];
435 $sub_d = $ar_segments['delimiters']['s'];
436 } else {
437 csv_edihist_log("ibr_277_parse: error invalid segments array");
438 return FALSE;
441 //$arRSP = array();
442 $ar277 = array();
444 $bct = -1;
445 $ict = -1;
446 $st_ct = 0;
447 $svc_ct = 0;
448 $clm_ct = 0;
449 $rej_ct = 0;
450 $amt_accpt = 0;
451 $amt_rej = 0;
452 $hl_code = "";
453 $loopid = "0";
455 foreach($ar_277_segments as $segline) {
456 // explode the segment into an array of elements
458 $seg = explode($elem_d, $segline);
459 // set counters, loops, etc. here
460 // count segments to verify ST--SE blocks
461 // $st_seg_ct is set to 1 in "ST"
462 $st_seg_ct = isset($st_seg_ct) ? $st_seg_ct+1 : 0;
464 if ($seg[0] == "ISA") {
465 // x12-277 files may have multiple ISA--IEA segment blocks
466 $ict++;
468 $isa13 = $seg[13];
469 $fmtime = '20'.strval($seg[9]);
471 // reset the ST count and BHT count
472 $st_ct = 0;
473 $st_seg_ct = 0;
474 $bct = -1;
476 $loopid = "0";
477 // paranoia check
478 if ($rep_d != $seg[11] ) {
479 $rep_d = $seg[11];
481 if ($sub_d != $seg[16] ) {
482 $sub_d = $seg[16];
485 continue;
488 if ($seg[0] == "IEA") {
489 //$ar277[$ict]['claim']['IEA02'] = $seg[2];
490 if ($seg[2] != $isa13) {
491 echo "ibr_277_read: ISA Mismatch IEA {$seg[2]} vs ISA $isa13 <br />" . PHP_EOL;
493 // consider indexing file array on ISA -- will increase csv table x2 or x3
494 //$ar_col_hdr = array('mtime', 'directory', 'file_name', 'claim_ct', 'amt_accpt','reject', 'amt_rej');
495 $ar277[$ict]['file']['filetime'] = $fmtime;
496 $ar277[$ict]['file']['filename'] = $fname;
497 $ar277[$ict]['file']['isa13_277'] = $isa13;
498 $ar277[$ict]['file']['claim_ct'] = $clm_ct;
499 $ar277[$ict]['file']['amt_accpt'] = $amt_accpt;
500 $ar277[$ict]['file']['claim_rct'] = $rej_ct;
501 $ar277[$ict]['file']['amt_rej'] = $amt_rej;
503 $amt_accpt = 0; $amt_rej = 0; $clm_ct = 0; $rej_ct =0;
504 $isa13 = ''; $fmtime = '';
505 continue;
508 if ($seg[0] == "GS") {
509 $fmtime = strval($seg[4]);
510 $gs04 = strval($seg[4]); // File date
511 $gs06 = strval($seg[6]); // Group Control Number
513 continue;
516 if ($seg[0] == "ST") {
518 $st01 = $seg[1]; //R 277 Transaction Set Identifier Code
519 $st02 = $seg[2]; //R Transaction Set Control Number
520 $st03 = $seg[3]; //R 005010X214 Implementation Convention Reference
522 $st_seg_ct = 1; // the ST segment is included in the segment count
523 $st_ct++;
524 $stc_ct = 0; // STC segments (status) at claim level may repear
526 continue;
529 if ($seg[0] == "SE") {
530 // check segment count
531 $se01 = $seg[1];
532 $se02 = $seg[2];
533 if ($se01 != $st_seg_ct) {
534 csv_edihist_log ("ibr_277_read: SE segment count mismatch $se01 $st_seg_ct $fname<br />");
536 if ($se02 != $st02) {
537 csv_edihist_log ("ibr_277_read: SE ST id mismatch $se02 $st02 $fname<br />");
539 $ar277[$ict]['claim']['BHT'][$bct]['ENV']['SE01'] = $se01;
541 continue;
544 if ($seg[0] == "BHT") {
545 // There may be many BHT's Begin Hierarchical Transaction
547 $bct++;
548 // define the HL structure of the transaction set
549 // 0010 Information Source, Information Receiver, Provider of Service, Subscriber, Dependent
550 // 0085 (Guess ?? ) Information Source, Information Receiver, Provider of Service, Patient
551 //['BHT02']['BHT03']['BHT04']['BHT06']
552 $ar277[$ict]['claim']['BHT'][$bct]['ENV']['BHT01'] = $seg[1]; //R 0010 0085 Hierarchical Structure Code
553 $ar277[$ict]['claim']['BHT'][$bct]['ENV']['BHT02'] = $seg[2]; //R 08 (status) TRANSACTION SET PURPOSE CODE
554 // issue with the Originator reference is that it apparently is created by Availity
555 // and is not our batch file control number
556 // relating back to our claims will require the encounter number (2000D TRN03)
557 $ar277[$ict]['claim']['BHT'][$bct]['ENV']['BHT03'] = $seg[3]; //R Originater REFERENCE IDENTIFICATION
558 $ar277[$ict]['claim']['BHT'][$bct]['ENV']['BHT04'] = $seg[4]; //R CCYYMMDD Transaction Set Creation Date
559 $ar277[$ict]['claim']['BHT'][$bct]['ENV']['BHT06'] = $seg[6]; //R DG CH TH Transaction Type Code
560 //['ISA13'] ['ST02'] ['SE01'] ['FILE']
561 $ar277[$ict]['claim']['BHT'][$bct]['ENV']['FILE'] = $fname; //basename($fp);
562 $ar277[$ict]['claim']['BHT'][$bct]['ENV']['ISA13'] = $isa13;
563 $ar277[$ict]['claim']['BHT'][$bct]['ENV']['GS04'] = $gs04;
564 $ar277[$ict]['claim']['BHT'][$bct]['ENV']['ST02'] = $st02;
566 $hlhaschild = '';
567 $hlchildof = '';
568 $hlischild = '';
569 $hlcount = '';
570 $hlparent = '';
572 $clm_ct++; // treat each BHT as a claim detail
574 $ky = '';
576 continue;
579 if ($seg[0] == "HL") {
580 // loop 2000A, 2000B, 2000C, 2000D ??
581 // set the $ky variable acording to HL level
582 // HL identified loops can repeat -- that case is not handled
583 // the values for the last instance only will be recorded in the array
584 if ($seg[3] == "20") {
585 // HL*1**20*1~ HL*1 NM1*PR TRN*1 DTP*050 DTP*009
586 $loopid = "2000A";
587 $ky = 'A';
588 } elseif ($seg[3] == "21") {
589 // HL*2*1*21*1~ NM1*41 TRN*2 STC QTY AMT
590 $loopid = "2000B";
591 $ky = 'B';
592 } elseif ($seg[3] == "19") {
593 // HL*3*2*19*1~ NM1*85 TRN*1 REF QTY AMT
594 $loopid = "2000C";
595 $ky = 'C';
596 } elseif ($seg[3] == "PT" || $seg[3] == "22") {
597 // HL*4*3*PT~ patient NM1*QC TRN*2 STC REF REF DTP
598 // HL*4*3*22*1~ subscriber NM1*IL TRN*2 STC REF REF DTP
599 $loopid = "2000D";
600 $ky = 'D';
602 $lp2100D = false;
603 $lp2200D = false;
604 $lp2220D = false; // used to indicate SVC segment in D or E
605 } elseif ($seg[3] == "23") {
606 $loopid = "2000E";
607 $ky = 'E';
609 $lp2100E = false;
610 $lp2200E = false;
611 $lp2220E = false;
613 // a preliminary scheme for testing HL parent/child relationship
614 $hlhaschild = (isset($seg[4]) || $seg[4] != '0')? $seg[4] : '0';
615 $hlchildof = $seg[2];
616 $hlischild = (!$hlchildof) ? false : (($hlchildof == $hlparent) ? true : false);
617 $hlparent = ($hlischild) ? $seg[2] : $seg[1];
618 $hlcount = $seg[1];
619 //////////////// end parent/child identification
621 $hl_code = $seg[3];
622 // reset stc segment counter
623 $stc_ct = -1;
625 continue;
628 // testing
629 if ($loopid == "2000A" && $ky != 'A') { echo "HL loop mismatch, $hl_code $loopid $ky $segline $fname<br />" . PHP_EOL; }
630 if ($loopid == "2000B" && $ky != 'B') { echo "HL loop mismatch, $hl_code $loopid $ky $segline $fname<br />" . PHP_EOL; }
631 if ($loopid == "2000C" && $ky != 'C') { echo "HL loop mismatch, $hl_code $loopid $ky $segline $fname<br />" . PHP_EOL; }
632 if ($loopid == "2000D" && $ky != 'D') { echo "HL loop mismatch, $hl_code $loopid $ky $segline $fname<br />" . PHP_EOL; }
633 if ($loopid == "2000E" && $ky != 'E') { echo "HL loop mismatch, $hl_code $loopid $ky $segline $fname<br />" . PHP_EOL; }
635 if ($seg[0] == "NM1") {
636 // this segment may repeat (rare), but only last NM1 is stored in array
638 // if ($loopid == "2000A") { $loopid = "2100A" } // NM1*PR payer NM1*AY clearinghouse repeat=1
639 // if ($loopid == "2000B") { $loopid = "2100B" } // NM1*41 submitter NM1*AY clearinghouse repeat=1
640 // if ($loopid == "2000C") { $loopid = "2100C" } // NM1*1P provider repeat=1
641 // if ($loopid == "2000D") { $loopid = "2100D" } // NM1*PT patient NM1*IL subscriber/insured NM1*QC repeat=1
642 $ar277[$ict]['claim']['BHT'][$bct][$ky]['NM101'] = $seg[1];
643 $ar277[$ict]['claim']['BHT'][$bct][$ky]['NM102'] = $seg[2];
644 $ar277[$ict]['claim']['BHT'][$bct][$ky]['NM103'] = $seg[3]; // Last name or company name
645 $ar277[$ict]['claim']['BHT'][$bct][$ky]['NM104'] = $seg[4]; // first name or blank
646 $ar277[$ict]['claim']['BHT'][$bct][$ky]['NM105'] = $seg[5]; // middle name or blank
647 $ar277[$ict]['claim']['BHT'][$bct][$ky]['NM107'] = $seg[7]; // name suffix
648 $ar277[$ict]['claim']['BHT'][$bct][$ky]['NM108'] = $seg[8]; // PI|XV|XX|46|FI|SV|24|II|MI Identification Code Qualifier
649 $ar277[$ict]['claim']['BHT'][$bct][$ky]['NM109'] = $seg[9]; // taxID, NPI, payerID, memberID
651 continue;
654 if ($seg[0] == "TRN") {
655 // if ($loopid == "2100B") { $loopid = "2200B" } // TRN02 is BHT03 ['B']['TRN02'] (277CA <> 837; 277 <> 276)
656 // if ($loopid == "2100C") { $loopid = "2200C" }
657 // if ($loopid == "2100D") { $loopid = "2200D" } // TRN02 is pid-encounter ['D']['TRN02']
658 $ar277[$ict]['claim']['BHT'][$bct][$ky]['TRN01'] = $seg[1];
659 $ar277[$ict]['claim']['BHT'][$bct][$ky]['TRN02'] = $seg[2];
661 continue;
664 if ($seg[0] == "DTP") {
665 if ($seg[1] == "050") { $ar277[$ict]['claim']['BHT'][$bct][$ky]['DTP03050'] = $seg[3]; }
666 if ($seg[1] == "009") { $ar277[$ict]['claim']['BHT'][$bct][$ky]['DTP03009'] = $seg[3]; }
667 if ($seg[1] == "472") {
668 if ($seg[2] == "RD8") {
669 // service dates
670 $sp = strpos($seg[3], "-");
671 $ar277[$ict]['claim']['BHT'][$bct][$ky]['DTP03FROM'] = ($sp) ? substr($seg[3], 0, $sp) : $seg[3];
672 $ar277[$ict]['claim']['BHT'][$bct][$ky]['DTP03TO'] = ($sp) ? substr($seg[3], $sp+1) : $seg[3];
674 if ($seg[2] == "D8") {
675 $ar277[$ict]['claim']['BHT'][$bct]['D']['DTP03FROM'] = $seg[3];
679 continue;
682 if ($seg[0] == "PER") {
683 $ar277[$ict]['claim']['BHT'][$bct][$ky]['PER01'] = $seg[1]; //R IC Contact Function Code R
684 $ar277[$ict]['claim']['BHT'][$bct][$ky]['PER02'] = $seg[2]; //S Payer Contact Name
685 $ar277[$ict]['claim']['BHT'][$bct][$ky]['PER03'] = $seg[3]; //R ED, EM, TE, FX Communication Number Qualifier
686 $ar277[$ict]['claim']['BHT'][$bct][$ky]['PER04'] = $seg[4]; //R Communication Number
688 continue;
691 // take quantity and amount from 2000B loop since that probably sums to totals for claims in ISA envelope
692 if ($seg[0] == "QTY" && $loopid == "2000B") {
693 $ar277[$ict]['claim']['BHT'][$bct]['B']['QTY01'] = $seg[1]; // QTY TOTAL ACCEPTED QUANTITY "90" 2200B QTY TOTAL REJECTED QUANTITY "AA" 2200B
694 $ar277[$ict]['claim']['BHT'][$bct]['B']['QTY02'] = $seg[2]; // count of accepted or rejected items
695 // for 277CA -- QTY segment not in 277 segment list
696 if ($seg[1] == '90') {
697 $clm_ct += $seg[2];
698 } else {
699 $rej_ct += $seg[2];
701 continue;
704 if ($seg[0] == "AMT" && $loopid == "2000B") {
705 $ar277[$ict]['claim']['BHT'][$bct]['B']['AMT01'] = $seg[1]; // AMT TOTAL ACCEPTED AMOUNT "YU" 2200B AMT TOTAL REJECTED AMOUNT "YY"
706 $ar277[$ict]['claim']['BHT'][$bct]['B']['AMT02'] = $seg[2]; // quantity, i.e. dollars, accepted or rejected
707 // for 277CA -- AMT segment not in 277 segment list
708 if ($seg[1] == 'YU') {
709 $amt_accpt += $seg[2];
710 } else {
711 $amt_rej += $seg[2];
714 continue;
717 if ($seg[0] == "STC" && !$lp2220D ) {
718 // increment stc count, it is reset to -1 at each HL segment (ky change)
719 $stc_ct++;
721 if ( strpos($seg[1], $sub_d) ) {
722 $sp = strpos($seg[1], $sub_d);
723 $stc01 = explode($sub_d, $seg[1]); // A1:20 is expected here
724 if ( is_array($stc01) ) {
725 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC011'] = isset($stc01[0]) ? $stc01[0] : ""; //STC01-1 Health Care Claim Status Category Code AN 01/30/12 R D0, E
726 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC012'] = isset($stc01[1]) ? $stc01[1] : ""; //STC01-2 Health Care Claim Status Code AN 01/30/12 R
727 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC013'] = isset($stc01[2]) ? $stc01[2] : ""; //STC01-3 Entity Identifier Code ID 02/03/12 S     1P
728 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC014'] = isset($stc01[3]) ? $stc01[3] : ""; //STC01-4 Code List Qualifier Code ID 01/03/12 N/U  
729 } else {
730 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC01'] = isset($seg[1]) ? $seg[1] : "";
734 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC02'] = isset($seg[2]) ? $seg[2] : ""; //STC02 Status Information Effective Date DT 08/08/12 R     CCYYMMDD
735 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC03'] = isset($seg[3]) ? $seg[3] : ""; //STC03 Action Code ID 01/02/12 N/U
736 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC04'] = isset($seg[4]) ? $seg[4] : ""; //STC04 Monetary Amount R 01/18/12 N/U
737 // no segments beyond STC04 are expected in loop 2200B STC
738 if ( !isset($seg[5]) ) { continue; }
740 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC05'] = isset($seg[5]) ? $seg[5] : ""; //STC05 Monetary Amount R 01/18/12 N/U
741 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC06'] = isset($seg[6]) ? $seg[6] : ""; //STC06 Date DT 08/08/12 N/U  
742 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC07'] = isset($seg[7]) ? $seg[7] : ""; //STC07 Payment Method Code ID 03/03/12 N/U
743 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC08'] = isset($seg[8]) ? $seg[8] : ""; //STC08 Date DT 08/08/12 N/U  
744 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC09'] = isset($seg[9]) ? $seg[9] : ""; //STC09 Check Number AN 01/16/12 N/U
746 if ( !isset($seg[10]) ) { continue; }
747 //STC10 HEALTH CARE CLAIM STATUS     S
748 if ( isset($seg[10]) ) {
749 if ( strpos($seg[10], $sub_d) ) {
750 $stc10 = explode($sub_d, $seg[10]);
751 if ( is_array($stc01) ) {
752 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC101'] = isset($stc10[0]) ? $stc10[0] : ""; //STC10-1 Health Care Claim Status Category Code AN 01/30/12 R     D0, E
753 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC102'] = isset($stc10[1]) ? $stc10[1] : ""; //STC10-2 Health Care Claim Status Code AN 01/30/12 R
754 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC103'] = isset($stc10[2]) ? $stc10[2] : ""; //STC10-3 Entity Identifier Code ID 02/03/12 S     1P
755 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC104'] = isset($stc10[3]) ? $stc10[3] : ""; //STC10-4 Code List Qualifier Code ID 01/03/12 N/U
756 } else {
757 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC10'] = $seg[10];
759 } else {
760 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC10'] = isset($seg[10]) ? $seg[10] : "";
764 //STC11 HEALTH CARE CLAIM STATUS
765 if ( isset($seg[11]) ) {
766 if ( strpos($seg[11], $sub_d) ) {
767 $stc11 = explode($sub_d, $seg[10]);
768 if ( is_array($stc11) ) {
769 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC111'] = isset($stc11[0]) ? $stc11[0] : ""; //STC11-1 Health Care Claim Status Category Code AN 01/30/12 R     D0, E
770 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC112'] = isset($stc11[1]) ? $stc11[1] : ""; //STC11-2 Health Care Claim Status Code AN 01/30/12 R
771 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC113'] = isset($stc11[2]) ? $stc11[2] : ""; //STC11-3 Entity Identifier Code ID 02/03/12 S     1P
772 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC114'] = isset($stc11[3]) ? $stc11[3] : ""; //STC11-4 Code List Qualifier Code ID 01/03/12 N/U
773 } else {
774 // sub-element detected, but no array -- unexpected
775 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC11'] = $seg[11];
777 } else {
778 $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC11'] = $seg[11];
781 //STC12 Free-Form Message Text AN 01/01/64 N/U      
782 if ( isset($seg[12]) ) { $ar277[$ict]['claim']['BHT'][$bct][$ky]['STC'][$stc_ct]['STC12'] = $seg[12]; }
787 if ($seg[0] == "REF") {
788 if ($ky == "C") {
789 if ($seg[1] == "TJ") { $ar277[$ict]['claim']['BHT'][$bct][$ky]['REFTJ'] = $seg[2]; }
790 } elseif ($ky == "D") {
791 // ref, 1K, EJ, D9 will be expected
792 if ($seg[1] == "1K") {
793 // REF*1K*<<subscriber number >>~REF02 Payer Claim Control Number AN 1-50 R
794 $ar277[$ict]['claim']['BHT'][$bct][$ky]['REF1K'] = $seg[2];
795 } elseif ($seg[1] == "D9") {
796 // REF*D9*NA~ clearinghouse ID
797 $ar277[$ict]['claim']['BHT'][$bct][$ky]['REFD9'] = $seg[2];
798 } elseif ($seg[1] == "EA") {
799 // record ID
800 $ar277[$ict]['claim']['BHT'][$bct][$ky]['REFEA'] = $seg[2];
801 } elseif ($seg[1] == "BLT") {
802 // institutional ID
803 $ar277[$ict]['claim']['BHT'][$bct][$ky]['REFBLT'] = $seg[2];
804 } elseif ($seg[1] == "EJ") {
805 // control ID
806 $ar277[$ict]['claim']['BHT'][$bct][$ky]['REFEJ'] = $seg[2];
807 } elseif ($seg[1] == "XZ") {
808 // prescripton ID
809 $ar277[$ict]['claim']['BHT'][$bct][$ky]['REFXZ'] = $seg[2];
810 } elseif ($seg[1] == "VV") {
811 // voucher ID
812 $ar277[$ict]['claim']['BHT'][$bct][$ky]['REFVV'] = $seg[2];
815 } else {
816 $refkey = 'REF'.$seg[1];
817 $ar277[$ict]['claim']['BHT'][$bct][$ky][$refkey] = $seg[1] . ":" . $seg[2]; // qualifier:value
820 continue;
823 if ($seg[0] == "SVC") {
824 // loop 2220D
825 // set another loop id
826 //$lp2200D = FALSE;
827 $lp2220D = TRUE;
829 // SVC SERVICE LINE INFORMATION   1 S 2220D >1  
830 $sbr_svc01 = $seg[1]; // SVC01 COMPOSITE MEDICAL PROCEDURE INDENTIFIER R
831 $svc01 = explode($sub_d, $seg[1]);
832 //     AD, ER, HC, HP, IV, N4, NU, WK
834 if ( is_array($stc01) ) {
835 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['SVC011'] = isset($svc01[0]) ? $svc01[0] : ""; //SVC01-1 Product/Service ID Qualifier ID 02/02/12 R
836 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['SVC012'] = isset($svc01[1]) ? $svc01[1] : ""; //SVC01-2 Service Identification Code AN 01/01/48 R
837 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['SVC013'] = isset($svc01[2]) ? $svc01[2] : ""; //SVC01-3 Procedure Modifier AN 02/02/12 S
838 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['SVC014'] = isset($svc01[3]) ? $svc01[3] : ""; //SVC01-4 Procedure Modifier AN 02/02/12 S
839 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['SVC015'] = isset($svc01[4]) ? $svc01[4] : ""; //SVC01-5 Procedure Modifier AN 02/02/12 S
840 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['SVC016'] = isset($svc01[5]) ? $svc01[5] : ""; //SVC01-6 Procedure Modifier AN 02/02/12 S
841 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['SVC017'] = isset($svc01[6]) ? $svc01[6] : ""; //SVC01-7 Description AN 01/01/80 N/U  
842 } else {
843 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['SVC01'] = isset($seg[1]) ? $seg[1] : "";
845 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['SVC02'] = isset($seg[2]) ? $seg[2] : ""; //SVC02 Line Item Charge Amount S9(7)V99 R 01/18/12 R
846 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['SVC03'] = isset($seg[2]) ? $seg[3] : ""; //SVC03 Line Item Payment Amount S9(7)V99 R 01/18/12 R
847 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['SVC04'] = isset($seg[2]) ? $seg[4] : ""; //SVC04 Revenue Code AN 01/01/48 S
848 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['SVC05'] = isset($seg[2]) ? $seg[5] : ""; //SVC05 Quantity R 01/15/12 N/U  
849 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['SVC06'] = isset($seg[2]) ? $seg[6] : ""; //SVC06 COMPOSITE MEDICAL PROCEDURE INDENTIFIER     N/U
850 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['SVC07'] = isset($seg[2]) ? $seg[7] : ""; //SVC07 Units of Service Count S9(3)V9 R 01/15/12 S
852 $svc_ct++;
853 continue;
856 if ($seg[0] == "STC" && $lp2220D ) {
857 // loop 2220D
858 // this is an STC segment following a SVC segment -- status for a particular service
859 //STC*A1:20*20120217*WQ*65~
860 if (!isset($ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC'])) {
861 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC'] = array();
863 $svcstc_ct = count($ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC']);
864 if ( strpos($seg[1], $sub_d) ) {
865 $sp = strpos($sub_d, $seg[1]);
866 $stcsvc01 = explode($sub_d, $seg[1]); // 2200D STC01-1 Health Care Claim Status Category Code
867 if ( is_array($stc01) ) { // "A2" Accept , "A3" Reject, or “R3” Warning 1/30
868 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC'][$svcstc_ct]['STC011'] = isset($stc01[0]) ? $stcsvc01[0] : ""; //STC01-1 Health Care Claim Status Category Code AN 01/30/12 R D0, E
869 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC'][$svcstc_ct]['STC012'] = isset($stc01[1]) ? $stcsvc01[1] : ""; //STC01-2 Health Care Claim Status Code AN 01/30/12 R
870 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC'][$svcstc_ct]['STC013'] = isset($stc01[1]) ? $stcsvc01[1] : ""; //STC01-3 Entity Identifier Code ID 02/03/12 S     1P
871 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC'][$svcstc_ct]['STC014'] = isset($stc01[1]) ? $stcsvc01[1] : ""; //STC01-4 Code List Qualifier Code ID 01/03/12 N/U  
872 } else {
873 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC'][$svcstc_ct]['STC011'] = isset($seg[1]) ? $seg[1] : "";
877 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC'][$svcstc_ct]['STC02'] = isset($seg[2]) ? $seg[2] : ""; //STC02 Status Information Effective Date DT 08/08/12 R CCYYMMDD
878 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC'][$svcstc_ct]['STC03'] = isset($seg[3]) ? $seg[3] : ""; //STC03 Action Code ID 01/02/12 N/U
879 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC'][$svcstc_ct]['STC04'] = isset($seg[4]) ? $seg[4] : ""; //STC04 Monetary Amount R 01/18/12 N/U
880 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC'][$svcstc_ct]['STC05'] = isset($seg[5]) ? $seg[5] : ""; //STC05 Monetary Amount R 01/18/12 N/U
881 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC'][$svcstc_ct]['STC06'] = isset($seg[6]) ? $seg[6] : ""; //STC06 Date DT 08/08/12 N/U
882 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC'][$svcstc_ct]['STC07'] = isset($seg[7]) ? $seg[7] : ""; //STC07 Payment Method Code ID 03/03/12 N/U  
883 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC'][$svcstc_ct]['STC08'] = isset($seg[8]) ? $seg[8] : ""; //STC08 Date DT 08/08/12 N/U
884 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC'][$svcstc_ct]['STC09'] = isset($seg[9]) ? $seg[9] : ""; //STC09 Check Number AN 01/16/12 N/U
885 //STC10 HEALTH CARE CLAIM STATUS     S
886 if ( isset($seg[10]) && strpos($seg[10], $sub_d) ) {
887 $stc10 = explode($sub_d, $seg[10]);
888 if ( is_array($stc01) ) {
889 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC'][$svcstc_ct]['STC101'] = isset($stc10[0]) ? $stc10[0] : ""; //STC10-1 Health Care Claim Status Category Code AN 01/30/12 R     D0, E
890 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC'][$svcstc_ct]['STC102'] = isset($stc10[1]) ? $stc10[1] : ""; //STC10-2 Health Care Claim Status Code AN 01/30/12 R
891 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC'][$svcstc_ct]['STC103'] = isset($stc10[2]) ? $stc10[2] : ""; //STC10-3 Entity Identifier Code ID 02/03/12 S     1P
892 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC'][$svcstc_ct]['STC104'] = isset($stc10[3]) ? $stc10[3] : ""; //STC10-4 Code List Qualifier Code ID 01/03/12 N/U
893 } else {
894 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC'][$svcstc_ct]['STC101'] = isset($seg[10]) ? $seg[10] : "";
898 //STC11 HEALTH CARE CLAIM STATUS     S
899 if ( isset($seg[11]) && strpos($seg[11], $sub_d) ) {
900 $stc11 = explode($sub_d, $seg[10]);
901 if ( is_array($stc11) ) {
902 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC111'] = isset($stc11[0]) ? $stc11[0] : ""; //STC11-1 Health Care Claim Status Category Code AN 01/30/12 R     D0, E
903 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC112'] = isset($stc11[1]) ? $stc11[1] : ""; //STC11-2 Health Care Claim Status Code AN 01/30/12 R
904 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC113'] = isset($stc11[2]) ? $stc11[2] : ""; //STC11-3 Entity Identifier Code ID 02/03/12 S     1P
905 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC114'] = isset($stc11[3]) ? $stc11[3] : ""; //STC11-4 Code List Qualifier Code ID 01/03/12 N/U
906 } else {
907 $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC111'] = isset($seg[11]) ? $seg[11] : "";
910 //STC12 Free-Form Message Text AN 01/01/64 N/U      
911 if ( isset($seg[12]) ) { $ar277[$ict]['claim']['BHT'][$bct][$ky]['SVC'][$svc_ct]['STC12'] = $seg[12]; }
913 if( $loopid == "2000D" || $loopid == "2000E") { $svc_ct++; }
915 continue;
917 } // end if ($seg[0] == "STC" && $lp2220D ) in loop 2200D
919 } // end foreach ( )
921 return $ar277;
926 * Process new files for csv table and html output
928 * @uses csv_newfile_list()
929 * @uses csv_parameters()
930 * @uses csv_x12_segments()
931 * @uses ibr_277_parse()
932 * @uses ibr_277_csv_claim_data()
933 * @uses csv_write_record()
934 * @param bool $html_out -- whether to return html output
935 * @param bool $err_only -- only list claims with errors in output
936 * @param array $files_ar -- list of new files from upload script
937 * @return string
939 function ibr_277_process_new($files_ar = NULL, $html_out = FALSE, $err_only = TRUE) {
941 if ( $files_ar === NULL || !is_array($files_ar) || count($files_ar) == 0) {
942 $ar_files = csv_newfile_list("f277");
943 } else {
944 $ar_files = $files_ar;
945 //$need_dir = FALSE;
948 if ( count($ar_files) == 0 ) {
949 if($html_out) {
950 $html_str .= "<p>ibr_277_process_new: no new f277 files <br />";
951 return $html_str;
954 // we have some new ones, verify and get complete path
955 foreach($ar_files as $fbt) {
956 $fp = csv_verify_file($fbt, 'f277', false);
957 if ($fp) { $ar_277files[] = $fp; }
960 if (!is_array($ar_277files) || count($ar_277files) == 0 ) {
961 $html_str = "ibr_277_process_new: no new f277 files found <br />" . PHP_EOL;
962 return $html_str;
963 } else {
964 $f277count = count($ar_277files);
966 // OK, we have some new files
967 $html_str = "";
968 $idx = 0;
969 $chr_c = 0;
970 $chr_f = 0;
972 foreach ($ar_277files as $file_277) {
973 // since the newfiles routine is updated, the need_dir test is not necessary
974 //$path_277 = ($need_dir) ? $dir.DIRECTORY_SEPARATOR.$file_277 : $file_277;
975 $path_277 = $file_277;
977 $ar_277seg = csv_x12_segments($path_277, "f277", FALSE);
979 if (is_array($ar_277seg) && count($ar_277seg['segments']) ) {
980 $ar_277_vals = ibr_277_parse($ar_277seg);
981 if (!$ar_277_vals) {
982 $html_str .= "failed to get segments for $file_277 <br />" .PHP_EOL;
983 continue;
985 } else {
986 $html_str .= "failed to get segments for $file_277 <br />" .PHP_EOL;
987 continue;
989 // since main array is indexed on isa segment and there may be more
990 // than one per file, the 'file' csv table has a row for each ISA segment
991 // and the 'claim' csv table has a row for each BHT segment
993 foreach($ar_277_vals as $isa) {
994 $ar_csvf = $isa['file'];
995 $ar_csvc = ibr_277_csv_claim_data($isa['claim']);
997 if ($html_out) {
998 $ar_h[$idx]['file'] = $ar_csvf;
999 $ar_h[$idx]['claim'] = $ar_csvc;
1000 $idx++;
1002 // still too much in claim csv record, drop the message
1003 //['f277']['claim'] = array('PtName', 'SvcDate', 'clm01', 'Status', 'st_277', 'File_277', 'payer_name', 'claim_id', 'bht03_837');
1004 $ar_csvclm = array();
1005 foreach($ar_csvc as $clm) {
1006 $ar_csvclm[] = array_slice($clm, 0, 9);
1008 $chr_f += csv_write_record($ar_csvf, "f277", "file");
1009 $chr_c += csv_write_record($ar_csvclm, "f277", "claim");
1012 } // end foreach ($ar_files as $file_277)
1014 if ($html_out) {
1015 $html_str .= ibr_277_html($ar_h, $err_only);
1016 } else {
1017 $html_str .= "x12_277 files: processed $f277count x12-277 files <br />". PHP_EOL;
1019 csv_edihist_log("ibr_277_process_new: $chr_f characters written to files_277.csv");
1020 csv_edihist_log("ibr_277_process_new: $chr_c characters written to claims_277.csv");
1023 return $html_str;
1028 * Create html output for a 277 file, same as the process new output
1030 * @uses csv_verify_file()
1031 * @uses csv_x12_segments()
1032 * @uses ibr_277_parse()
1033 * @uses ibr_277_csv_claim_data()
1034 * @uses ibr_277_html()
1035 * @param string $filepath -- filename or full path to file
1036 * @return string
1038 function ibr_277_filetohtml($filepath, $err_only = false) {
1040 // simply create an html output for the file like processing new
1042 $html_str = "";
1044 $fp = csv_verify_file($filepath, "f277");
1045 if ($fp) {
1046 $ar_277_seg = csv_x12_segments($fp, "f277", false);
1047 if (is_array($ar_277_seg) && count($ar_277_seg['segments']) ) {
1048 $ar_277_vals = ibr_277_parse($ar_277_segs);
1049 } else {
1050 $html_str .= "failed to get segments for $fp <br />" .PHP_EOL;
1051 continue;
1053 $idx = 0;
1054 foreach($ar_277_vals as $isa) {
1055 $ar_csvf = $isa['file'];
1056 $ar_csvc = ibr_277_csv_claim_data($isa['claim']);
1058 $ar_h[$idx]['file'] = $ar_csvf;
1059 $ar_h[$idx]['claim'] = $ar_csvc;
1060 $idx++;
1062 $html_str .= ibr_277_html ($ar_h, $err_only);
1063 } else {
1064 csv_edihist_log ("ibr_277_filetohtml: verification failed $filepath");
1065 $html_str .= "ibr_277_filetohtml: Error, validation failed $filepath <br />";
1068 return $html_str;
1072 ////////////////////////////////
1073 // html for claim status -- ties into revision of csv files becasue they
1074 // are too hard to work with with error messages
1075 // csv claims files will be simplified -- no messages
1076 // just status and link to this function
1077 // also x12 csv file record to be modified
1078 ////////////////////////////////
1081 * parse a bht segment group into a multi-dimensonal array
1083 * @param array $segments the ST...SE segments of the response
1084 * @param array $delimiters the delimiters array
1085 * @return array
1087 function ibr_277_bht_array($segments, $delimiters) {
1088 // parse a bht segment group into html output
1089 if (is_array($delimiters) && array_keys($delimiters) == array('t', 'e', 's', 'r')) {
1090 $seg_d = $delimiters['t'];
1091 $elem_d = $delimiters['e'];
1092 $sub_d = $delimiters['s'];
1093 $rep_d = $delimiters['r'];
1094 } else {
1095 csv_edihist_log ("ibr_277_bht_html: invalid delimiters");
1096 return false;
1099 if (!is_array($segments) || count($segments) == 0) {
1100 csv_edihist_log ("ibr_277_bht_html: invalid segments ");
1101 return false;
1104 // open the codes lookup class
1105 $codes277 = new status_code_arrays();
1107 // initialize variables
1108 $bht277_ar = array();
1109 $x12var = '';
1110 $idx = -1;
1111 foreach($segments as $segstr) {
1113 $seg = explode($elem_d, $segstr);
1115 // determine loops
1116 if ($seg[0] == 'ST') { $loopid = '0'; continue; }
1117 if ($seg[0] == 'BHT') { $loopid = '0'; }
1118 if ($seg[0] == 'HL') {
1119 //echo "ibr_277_bht_array HL segment".HP_EOL;
1121 if ($seg[3] == '20') { $loopid = '2000A'; $ky = 'A'; }
1122 if ($seg[3] == '21') { $loopid = '2000B'; $ky = 'B'; }
1123 if ($seg[3] == '19') { $loopid = '2000C'; $ky = 'C'; }
1124 if ($seg[3] == '22') { $loopid = '2000D'; $ky = 'D'; }
1125 if ($seg[3] == 'PT') { $loopid = '2000D'; $ky = 'D'; }
1126 if ($seg[3] == '23') { $loopid = '2000E'; $ky = 'E'; }
1127 // SVC in 2000D or 2000E will set this to true, for related STC
1128 $lp2220D = false;
1130 if ($seg[0] == 'NM1'){
1131 if ( $loopid == '2000A') { $loopid = '2100A'; $level = 'Source'; }
1132 if ( $loopid == '2000B') { $loopid = '2100B'; $level = 'Receiver'; }
1133 if ( $loopid == '2000C') { $loopid = '2100C'; $level = 'Provider'; }
1134 if ( $loopid == '2000D') { $loopid = '2100D'; $level = 'Subscriber'; }
1135 if ( $loopid == '2000E') { $loopid = '2100E'; $level = 'Dependent'; }
1137 if ($seg[0] == 'TRN'){
1138 if ( $loopid == '2100A') { $loopid = '2200A'; $x12var = 'CA'; }
1139 if ( $loopid == '2100B') { $loopid = '2200B'; $x12var = ''; }
1140 if ( $loopid == '2100C') { $loopid = '2200C'; $x12var = ''; }
1141 if ( $loopid == '2100D') { $loopid = '2200D'; $x12var = ''; }
1143 if ($seg[0] == 'SVC'){
1144 if ( $loopid == '2200C') { $loopid = '2220C'; }
1145 if ( $loopid == '2200D') { $loopid = '2220D'; }
1146 if ( $loopid == '2200E') { $loopid = '2220E'; }
1149 // create $bht277_ar array so values can be organized for output
1150 // this design can work because the segment order is
1151 // NM1* ~TRN* ~STC* ~REF* ~DTP* ~SVC* ~DTP
1152 if ($loopid == '2000A') {
1153 // $ky should be 'A'
1154 $bht277_ar['A'] = array('loop'=>'', 'level'=>'', 'entity'=>'', 'name'=>'', 'id'=>'',
1155 'sourcerefid'=>'', 'pername'=>'', 'percontact'=>'',
1156 'pernumtype'=>'', 'pernumber'=>'', 'perextra'=>'',
1157 'trace'=>'', 'dtrec'=>'', 'dtproc'=>'',
1158 'STC'=>array());
1160 if ($loopid == '2000B') {
1161 $bht277_ar['B'] = array('loop'=>'', 'level'=>'', 'entity'=>'', 'name'=>'', 'id'=>'', 'trace'=>'',
1162 'qtyacc'=>'', 'amtacc'=>'', 'qtyrej'=>'', 'amtrej'=>'',
1163 'STC'=>array(), 'dtsvc'=>'', );
1165 if ($loopid == '2000C') {
1166 $bht277_ar['C'] = array('loop'=>'', 'level'=>'', 'entity'=>'', 'name'=>'', 'id'=>'', 'trace'=>'',
1167 'qtyacc'=>'', 'amtacc'=>'', 'qtyrej'=>'', 'amtrej'=>'',
1168 'STC'=>array(), 'dtsvc'=>'' );
1169 //'stcat'=>'', 'ststat'=>'', 'stentity'=>'', 'stclqual'=>'',
1170 //'stdate'=>'','staction'=>'','stamount'=>'', 'stmessage'=>''
1171 //'stcat2'=>'','ststat2'=>'','stentity2'=>'','stclqual2'
1172 //'stcat3'=>'','ststat3'=>'','stentity3'=>'','stclqual3'
1174 if ($loopid == '2000D') {
1175 $bht277_ar['D'] = array('loop'=>'', 'level'=>'', 'entity'=>'', 'name'=>'', 'id'=>'', 'trace'=>'',
1176 'qtyacc'=>'', 'amtacc'=>'', 'qtyrej'=>'', 'amtrej'=>'',
1177 'STC'=>array(), 'dtsvc'=>'', 'SVC'=>array());
1178 //'stccat'=>'', 'stcstat'=>'', 'stcentity'=>'', 'stcclqual'=>'',
1179 //'stcdate'=>'','stcaction'=>'','stcamount'=>'', 'stcmessage'=>''
1180 //'stccat2'=>'','stcstat2'=>'','stcentity2'=>'','stcclqual2'
1181 //'stccat3'=>'','stcstat3'=>'','stcentity3'=>'','stcclqual3'
1184 if ($loopid == '2000E') {
1185 $bht277_ar['E'] = array('loop'=>'', 'level'=>'', 'entity'=>'', 'name'=>'', 'id'=>'', 'trace'=>'',
1186 'qtyacc'=>'', 'amtacc'=>'', 'qtyrej'=>'', 'amtrej'=>'',
1187 'STC'=>array(), 'dtsvc'=>'', 'SVC'=>array());
1188 //'stccat'=>'', 'stcstat'=>'', 'stcentity'=>'', 'stcclqual'=>'',
1189 //'stcdate'=>'','stcaction'=>'','stcamount'=>'', 'stcmessage'=>''
1190 //'stccat2'=>'','stcstat2'=>'','stcentity2'=>'','stcclqual2'
1191 //'stccat3'=>'','stcstat3'=>'','stcentity3'=>'','stcclqual3'
1195 if ($seg[0] == 'BHT') {
1196 if (isset($seg[3])) { $sourcerefid = $seg[3]; }
1199 if ($seg[0] == 'NM1') {
1200 // get entity type
1201 $entity = $codes277->get_STC_Entity_Code($seg[1]);
1202 //$entity = ($seg[1]) ? : '&nbsp;';
1203 // assemble name last:$seg[3] first:$seg[4] middle:$seg[5]
1204 $name = ($seg[2] == '1') ? $seg[3].', '.$seg[4].' '.$seg[5] : $seg[3];
1206 $id = ($seg[8] == 'PI') ? 'EDI: '.$seg[9] : '';
1207 $id = ($seg[8] == 'XV') ? 'CMS: '.$seg[9] : $id;
1208 $id = ($seg[8] == '46') ? 'ETIN: '.$seg[9] : $id;
1209 $id = ($seg[8] == '24') ? 'EIN: '.$seg[9] : $id;
1210 $id = ($seg[8] == 'II') ? 'UHI: '.$seg[9] : $id;
1211 $id = ($seg[8] == 'MI') ? 'MbrID: '.$seg[9] : $id;
1212 $id = ($seg[8] == 'FI') ? 'TIN: '.$seg[9] : $id;
1213 $id = ($seg[8] == 'SV') ? 'SPN: '.$seg[9] : $id;
1214 $id = ($seg[8] == 'XX') ? 'NPI: '.$seg[9] : $id;
1215 if ($id == '' && isset($seg[8])) { $id = $seg[8].' '.$seg[9]; }
1217 $bht277_ar[$ky]['loop'] = $loopid;
1218 $bht277_ar[$ky]['level'] = $level;
1219 $bht277_ar[$ky]['entity'] = $entity[1];
1220 $bht277_ar[$ky]['name'] = $name;
1221 $bht277_ar[$ky]['id'] = $id;
1225 if ($seg[0] == 'PER') {
1226 // contact information is not sent in the 277CA variety
1227 $bht277_ar[$ky]['percontact'] = $seg[1];
1228 $bht277_ar[$ky]['pernumtype'] = $seg[2];
1229 $bht277_ar[$ky]['pernumber'] = $seg[3];
1230 if ( isset($seg[5]) && isset($seg[6]) ) {
1231 $bht277_ar[$ky]['perextra'] = $seg[5] . ' ' . $seg[6];
1235 if ($seg[0] == 'TRN') {
1236 // transaction reference, but which one?
1237 $trtype = ($seg[1] == '1') ? 'This transaction ' : 'Referenced transaction ' ;
1238 // trace in loop
1239 $trace = ($loopid == '2200A') ? 'Xmit RefID: '.$seg[2] : ''; // ''837 BHT03: '.$seg[2] : '';
1240 // according to CMS Versions 5010 and D.0 & 3.0
1241 // 837 BHT03 is mapped to the 277CA response in the 2200B.TRN02 data element
1242 $trace = ($loopid == '2200B') ? (($x12var == 'CA') ? '276 BHT03: '.$seg[2] : '837 BHT03: '.$seg[2]) : $trace;
1243 $trace = ($loopid == '2200C' && $seg[2]) ? '837 BHT03: '.$seg[2] : $trace;
1244 $trace = ($loopid == '2200D') ? '837 CLM01: '.$seg[2] : $trace;
1245 $trace = ($loopid == '2200E') ? '837 CLM01: '.$seg[2] : $trace;
1246 if ($trace == '' && isset($seg[9])) { $trace = $loopid.' trace '.$seg[9]; }
1248 $bht277_ar[$ky]['trace'] = ($trace) ? $trtype . ' ' . $trace : '';
1249 // from BHT segment
1250 if ($loopid == '2200A') { $bht277_ar[$ky]['sourcerefid'] = 'Reference: ' .$sourcerefid; }
1253 if ($seg[0] == 'DTP') {
1254 if ($seg[2] == 'D8') {
1255 $dt = substr($seg[3],0,4) .'-'. substr($seg[3],4,2) .'-'. substr($seg[3],6,2);
1257 if ($seg[2] == 'D8') {
1258 if ($seg[1] == '050') { $bht277_ar[$ky]['dtrec'] = $dt; }
1259 if ($seg[1] == '009') { $bht277_ar[$ky]['dtproc'] = $dt; }
1260 if ($seg[1] == '472') { $bht277_ar[$ky]['dtsvc'] = $dt; }
1262 if ($seg[2] == 'RD8') {
1263 $dt_ar = preg_split('/\D/', $seg[3]);
1264 $dt1 = substr($dt_ar[0],0,4) .'-'. substr($dt_ar[0],4,2) .'-'. substr($dt_ar[0],6,2);
1265 $dt2 = substr($dt_ar[1],0,4) .'-'. substr($dt_ar[1],4,2) .'-'. substr($dt_ar[1],6,2);
1266 if ($seg[1] == '472') { $bht277_ar[$ky]['dtsvc'] = $dt1 .' to '. $dt2; }
1267 if ($seg[1] == '434') { $bht277_ar[$ky]['dtstmt'] = $dt1 .' to '. $dt2; }
1271 if ($seg[0] == 'QTY') {
1272 // 277CA type
1273 if ($seg[1] == '90') { $bht277_ar[$ky]['qtyacc'] = $seg[2]; }
1274 if ($seg[1] == 'AA') { $bht277_ar[$ky]['qtyrej'] = $seg[2]; }
1276 if ($seg[0] == 'AMT') {
1277 // 277CA
1278 if ($seg[1] == 'YU') { $bht277_ar[$ky]['amtacc'] = sprintf("%0.02f", $seg[2]); }
1279 if ($seg[1] == 'YY') { $bht277_ar[$ky]['amtrej'] = sprintf("%0.02f", $seg[2]); }
1281 //'stcat''ststat''stentity''stclqual''stdate''staction''stamount'
1282 if ($seg[0] == 'STC') {
1283 // since there can be multiple STC segments in a loop
1284 $idx = count($bht277_ar[$ky]['STC']);
1285 // loop identification
1286 $bht277_ar[$ky]['STC'][$idx]['loop'] = $loopid;
1288 if ( strpos($seg[1], $sub_d) ) {
1289 $stc01 = explode($sub_d, $seg[1]);
1290 if ( isset($stc01[0]) ) {
1291 $cat = $codes277->get_STC_Category_Code($stc01[0]);
1292 $bht277_ar[$ky]['STC'][$idx]['stccat'] = $cat[1];
1294 if ( isset($stc01[1]) ) {
1295 $stat = $codes277->get_STC_Status_Code($stc01[1]);
1296 $bht277_ar[$ky]['STC'][$idx]['stcstat'] = $stat[1];
1298 if ( isset($stc01[2]) ) {
1299 $entity = $codes277->get_STC_Entity_Code($stc01[2]);
1300 $bht277_ar[$ky]['STC'][$idx]['stcentity'] = $entity[1];
1302 if ( isset($stc01[3]) ) {
1303 // this seems to be used only in special situations, like a pharmacy claim
1304 $bht277_ar[$ky]['STC'][$idx]['stcclqual'] = $stc01[3];
1308 $bht277_ar[$ky]['STC'][$idx]['stcdate'] = $seg[2];
1310 if ( isset($seg[3]) ) {
1311 if ($seg[3]== 'WQ') { $bht277_ar[$ky]['STC'][$idx]['stcaction'] = $seg[3] . ' Accepted'; }
1312 if ($seg[3]== 'U') { $bht277_ar[$ky]['STC'][$idx]['stcaction'] = $seg[3] . ' Rejected'; }
1314 if ( isset($seg[4]) ) {
1315 $bht277_ar[$ky]['STC'][$idx]['stcamount'] = sprintf("%0.02f", $seg[4]);
1317 if ( isset($seg[10]) ) {
1318 if ( strpos($seg[10], $sub_d) ) {
1319 $stc10 = explode($sub_d, $seg[10]);
1320 if ( isset($stc10[0]) ) {
1321 $cat = $codes277->get_STC_Category_Code($stc10[0]);
1322 $bht277_ar[$ky]['STC'][$idx]['stccat2'] = $cat[1];
1324 if ( isset($stc10[1]) ) {
1325 $stat = $codes277->get_STC_Status_Code($stc10[1]);
1326 $bht277_ar[$ky]['STC'][$idx]['stcstat2'] = $stat[1];
1328 if ( isset($stc10[2]) ) {
1329 $entity = $codes277->get_STC_Entity_Code($stc10[2]);
1330 $bht277_ar[$ky]['STC'][$idx]['stcentity2'] = $entity[1];
1332 if ( isset($stc10[3]) ) {
1333 // this seems to be used only in special situations, like a pharmacy claim
1334 $bht277_ar[$ky]['STC'][$idx]['stcclqual2'] = $stc10[3];
1338 if ( isset($seg[11]) ) {
1339 if ( strpos($seg[11], $sub_d) ) {
1340 $stc11 = explode($sub_d, $seg[10]);
1341 if ( isset($stc11[0]) ) {
1342 $cat = $codes277->get_STC_Category_Code($stc11[0]);
1343 $bht277_ar[$ky]['STC'][$idx]['stccat3'] = $cat[1];
1345 if ( isset($stc11[1]) ) {
1346 $stat = $codes277->get_STC_Status_Code($stc11[1]);
1347 $bht277_ar[$ky]['STC'][$idx]['stcstat3'] = $stat[1];
1349 if ( isset($stc11[2]) ) {
1350 $entity = $codes277->get_STC_Entity_Code($stc11[2]);
1351 $bht277_ar[$ky]['STC'][$idx]['stcentity3'] = $entity[1];
1353 if ( isset($stc11[3]) ) {
1354 // this seems to be used only in special situations, like a pharmacy claim
1355 $bht277_ar[$ky]['STC'][$idx]['stcclqual3'] = $stc11[3];
1359 if ( isset($seg[12]) ) {
1360 $bht277_ar[$ky]['STC'][$idx]['stcmessage'] = $seg[12];
1362 // if the STC segment is in reference to a SVC segment
1363 // expect SVC followed by STC
1364 if ($lp2220D && count($bht277_ar[$ky]['SVC'])) {
1365 $bht277_ar[$ky]['SVC'][$svc_ct]['STC'][] = $bht277_ar[$ky]['STC'][$idx];
1366 unset($bht277_ar[$ky]['STC'][$idx]);
1370 if ($seg[0] == 'REF') {
1371 //'ref1K''refD9''refEA''refBLT''refEJ''refXZ''refVV''refFJ'
1372 $refkey = 'ref' . strtolower($seg[1]);
1373 $refstr = '';
1374 if ($seg[1] == '1K') { $refstr = 'Payer Ctl No '; }
1375 if ($seg[1] == 'BLT') { $refstr = 'Billing Type '; }
1376 if ($seg[1] == 'EJ') { $refstr = 'Pt Acct No '; }
1377 if ($seg[1] == 'XZ') { $refstr = 'Rx No '; }
1378 if ($seg[1] == 'VV') { $refstr = 'Voucher No '; }
1379 if ($seg[1] == 'FJ') { $refstr = 'Svc Item Info '; }
1380 if ($seg[1] == 'D9') { $refstr = 'Clearinghouse ID No '; }
1381 if ($seg[1] == 'TJ') { $refstr = 'Fed Tax ID No '; }
1383 $bht277_ar[$ky][$refkey] = $refstr . $seg[2];
1386 if ($seg[0] == 'SVC') {
1387 // SVC segment only occurs in 2200D or 2200E
1388 if ($ky == 'D' || $ky == 'E') {
1389 $lp2220D = true;
1390 $svc_ct = count($bht277_ar[$ky]['SVC']);
1391 // loop identification
1392 $bht277_ar[$ky]['SVC'][$svc_ct]['loop'] = $loopid;
1393 // required elements
1394 $bht277_ar[$ky]['SVC'][$svc_ct]['svccode'] = $seg[1];
1395 $bht277_ar[$ky]['SVC'][$svc_ct]['svcfee'] = $seg[2];
1396 $bht277_ar[$ky]['SVC'][$svc_ct]['svcpmt'] = $seg[3];
1397 // situational elements
1398 if (isset($seg[4])) { $bht277_ar[$ky]['SVC'][$svc_ct]['svcnub'] = $seg[4]; }
1399 if (isset($seg[5])) { $bht277_ar[$ky]['SVC'][$svc_ct]['svcqty'] = $seg[5]; }
1400 if (isset($seg[5])) { $bht277_ar[$ky]['SVC'][$svc_ct]['svcqty'] = $seg[5]; }
1401 if (isset($seg[6])) { $bht277_ar[$ky]['SVC'][$svc_ct]['svccompid'] = $seg[6]; }
1402 // required, but test anyway
1403 if (isset($seg[7])) { $bht277_ar[$ky]['SVC'][$svc_ct]['svcqty'] = $seg[7]; }
1407 // return the array
1408 return $bht277_ar;
1412 * create an html table to display the claim status response
1414 * @param array $bhtarray the multidimesional array from {@see ibr_277_bht_array()}
1415 * @return string
1417 function ibr_277_bhthtml($bhtarray) {
1419 if (is_array($bhtarray)) {
1420 $bar = $bhtarray;
1421 } else {
1422 csv_edihist_log("ibr_277_bhthtml: error, argument not array");
1423 return false;
1425 // derive the caption
1426 $capstr = 'Claim Status: ';
1427 if ($bar['D']['trace']) { $capstr .= $bar['D']['trace']; }
1428 if (isset($bar['D']['ref1k'])) { $capstr .= ' ' . $bar['D']['ref1k']; }
1430 $str_html = "<table class='bht277' cols=5 caption='$capstr'>
1431 <thead>
1432 <tr>
1433 <th>Level</th>
1434 <th colspan='4'>Information</th>
1435 </tr>
1436 </thead>
1437 <tbody>".PHP_EOL;
1439 if (isset($bar['A'])) {
1440 // Source level
1441 $str_html .= "<tr class='leva'>
1442 <td>{$bar['A']['level']}</td>
1443 <td colspan='2'>{$bar['A']['entity']} {$bar['A']['name']}</td>
1444 <td colspan='2'>{$bar['A']['id']}</td>
1445 </tr>
1446 <tr class='leva'>
1447 <td>&nbsp;</td>
1448 <td colspan='2'>{$bar['A']['sourcerefid']}</td>
1449 <td colspan='2'>{$bar['A']['trace']} </td>
1450 </tr>
1451 <tr class='leva'>
1452 <td>&nbsp;</td>
1453 <td colspan='4'>Recieved {$bar['A']['dtrec']} Processed {$bar['A']['dtproc']}</td>
1454 </tr>".PHP_EOL;
1455 if ($bar['A']['percontact']) {
1456 $str_html .= "<tr class='leva'>
1457 <td>&nbsp;</td>
1458 <td colspan='4'>{$bar['A']['pername']} {$bar['A']['percontact']} {$bar['A']['pernumtype']} {$bar['A']['pernumber']} </td>
1459 </tr>".PHP_EOL;
1463 if (isset($bar['B'])) {
1464 // Reciever level
1465 $acp = '';
1466 if ($bar['B']['qtyacc']) { $acp .= ' Accepted ' . $bar['B']['qtyacc'] . ': ' . $bar['B']['amtacc']; }
1467 if ($bar['B']['qtyrej']) { $acp .= ' Rejected ' . $bar['B']['qtyrej'] . ': ' . $bar['B']['amtrej']; }
1468 $str_html .= "<tr class='levb'>
1469 <td>{$bar['B']['level']}</td>
1470 <td colspan='4'>{$bar['B']['entity']} {$bar['B']['name']} {$bar['B']['id']}</td>
1471 </tr>
1472 <tr class='levb'>
1473 <td>&nbsp;</td>
1474 <td colspan='4'>$acp {$bar['B']['trace']} </td>
1475 </tr>".PHP_EOL;
1476 if (count($bar['B']['STC'])) {
1477 foreach($bar['B']['STC'] as $stc) {
1478 $str_html .= "<tr class='levb'>
1479 <td>&nbsp;</td>
1480 <td colspan='4'>{$stc['stcamount']} {$stc['stcaction']} {$stc['stccat']} </td>
1481 </tr>".PHP_EOL;
1482 if (isset($stc['stcamount2'])) {
1483 $str_html .= "<tr class='levb'>
1484 <td>&nbsp;</td>
1485 <td colspan='4'>{$stc['stcamount2']} {$stc['stcaction2']} {$stc['stccat2']} </td>
1486 </tr>".PHP_EOL;
1488 if (isset($stc['stcamount3'])) {
1489 $str_html .= "<tr class='levb'>
1490 <td>&nbsp;</td>
1491 <td colspan='4'>{$stc['stcamount3']} {$stc['stcaction3']} {$stc['stccat3']} </td>
1492 </tr>".PHP_EOL;
1498 if (isset($bar['C'])) {
1499 // Reciever level
1500 $acp = ''; $ref = '';
1501 if ($bar['C']['qtyacc']) { $acp .= ' Accepted ' . $bar['C']['qtyacc'] . ': ' . $bar['C']['amtacc']; }
1502 if ($bar['C']['qtyrej']) { $acp .= ' Rejected ' . $bar['C']['qtyrej'] . ': ' . $bar['C']['amtrej']; }
1503 $str_html .= "<tr class='levc'>
1504 <td>{$bar['C']['level']}</td>
1505 <td colspan='4'>{$bar['C']['entity']} {$bar['C']['name']} {$bar['C']['id']}</td>
1506 </tr>".PHP_EOL;
1507 // trace is not really expected in 2000C
1508 if ($bar['C']['trace']) { $ref = $bar['C']['trace']; }
1509 // we expect a reftj (tax id) in 2000C
1510 if (isset($bar['C']['reftj'])) { $ref .= ' ' .$bar['C']['reftj']; }
1511 if ($ref) {
1512 $str_html .= "<tr class='levc'>
1513 <td>&nbsp;</td>
1514 <td colspan='4'>$ref</td>
1515 </tr>".PHP_EOL;
1517 if (count($bar['C']['STC'])) {
1518 foreach($bar['C']['STC'] as $stc) {
1519 $str_html .= "<tr class='levc'>
1520 <td>&nbsp;</td>
1521 <td colspan='4'>{$stc['stcamount']} {$stc['stcaction']} {$stc['stccat']} </td>
1522 </tr>".PHP_EOL;
1523 if (isset($stc['stcamount2'])) {
1524 $str_html .= "<tr class='levc'>
1525 <td>&nbsp;</td>
1526 <td colspan='4'>{$stc['stcamount2']} {$stc['stcaction2']} {$stc['stccat2']} </td>
1527 </tr>".PHP_EOL;
1529 if (isset($stc['stcamount3'])) {
1530 $str_html .= "<tr class='levc'>
1531 <td>&nbsp;</td>
1532 <td colspan='4'>{$stc['stcamount3']} {$stc['stcaction3']} {$stc['stccat3']} </td>
1533 </tr>".PHP_EOL;
1539 if (isset($bar['D'])) {
1540 // Subscriber level
1541 // do not expect amounts or quantities in D
1542 $acp = ''; $ref = '';
1543 if ($bar['D']['qtyacc']) { $acp .= ' Accepted ' . $bar['D']['qtyacc'] . ': ' . $bar['D']['amtacc']; }
1544 if ($bar['D']['qtyrej']) { $acp .= ' Rejected ' . $bar['D']['qtyrej'] . ': ' . $bar['D']['amtrej']; }
1545 $str_html .= "<tr class='levd'>
1546 <td>{$bar['D']['level']}</td>
1547 <td colspan='4'>{$bar['D']['entity']} {$bar['D']['name']} &nbsp;{$bar['D']['id']}</td>
1548 </tr>".PHP_EOL;
1549 if ($bar['D']['dtsvc']) {
1550 $str_html .= "<tr class='levd'>
1551 <td>&nbsp;</td>
1552 <td colspan='4'>Service Date: {$bar['D']['dtsvc']}</td>
1553 </tr>".PHP_EOL;
1555 // our pid-encounter and possibly payer claim number and intermediary trace
1556 if (isset($bar['D']['trace'])) { $ref .= $bar['D']['trace']; }
1557 if (isset($bar['D']['ref1k'])) { $ref .= ' ' . $bar['D']['ref1k']; }
1558 if (isset($bar['D']['refvv'])) { $ref .= ' ' . $bar['D']['refvv']; }
1559 if (isset($bar['D']['refd9'])) { $ref .= ' ' . $bar['D']['refd9']; }
1560 if ($ref) {
1561 $str_html .= "<tr class='levd'>
1562 <td>&nbsp;</td>
1563 <td colspan='4'>$ref</td>
1564 </tr>".PHP_EOL;
1567 if (count($bar['D']['STC'])) {
1568 foreach($bar['D']['STC'] as $stc) {
1569 $stcstatus = isset($stc['stcstat']) ? $stc['stcstat'] : '';
1570 $stcstatus .= isset($stc['stcentity']) ? ' (' . $stc['stcentity'] . ')' : '';
1571 $str_html .= "<tr class='levd'>
1572 <td>&nbsp;</td>
1573 <td colspan='4'>{$stc['stcamount']} {$stc['stcaction']} {$stc['stccat']} </td>
1574 </tr>
1575 <tr class='levd'>
1576 <td>&nbsp;</td>
1577 <td colspan='4'>&nbsp;&nbsp;$stcstatus</td>
1578 </tr>
1579 <tr class='levd'>
1580 <td>&nbsp;</td>
1581 <td colspan='4'>{$stc['stcmessage']}</td>
1582 </tr>".PHP_EOL;
1583 if (isset($stc['stcamount2'])) {
1584 $str_html .= "<tr class='levd'>
1585 <td>&nbsp;</td>
1586 <td colspan='4'>{$stc['stcamount2']} {$stc['stcaction2']} {$stc['stccat2']} </td>
1587 </tr>".PHP_EOL;
1589 if (isset($stc['stcamount3'])) {
1590 $str_html .= "<tr class='levd'>
1591 <td>&nbsp;</td>
1592 <td colspan='4'>{$stc['stcamount3']} {$stc['stcaction3']} {$stc['stccat3']} </td>
1593 </tr>".PHP_EOL;
1598 if (count($bar['D']['SVC'])) {
1599 foreach($bar['D']['SVC'] as $svc) {
1600 $str_html .= "<tr class='levd'>
1601 <td>&nbsp;</td>
1602 <td colspan='4'>{$svc['svccode']} {$svc['svcfee']} {$svc['svcpmt']} {$svc['svcqty']} </td>
1603 </tr>".PHP_EOL;
1604 if (isset($svc['STC']) && count($svc['STC'])) {
1605 foreach($svc['STC'] as $svcstc) {
1606 $str_html .= "<tr class='levd'>
1607 <td>&nbsp;</td>
1608 <td colspan='4'>{$svcstc['stcamount']} {$stc['stcaction']} {$stc['stccat']} </td>
1609 </tr>".PHP_EOL;
1610 if (isset($stc['stccat2'])) {
1611 $str_html .= "<tr class='levd'>
1612 <td>&nbsp;</td>
1613 <td colspan='4'>{$stc['stccat2']} {$stc['stcstat2']} {$stc['stcentity2']} </td>
1614 </tr>".PHP_EOL;
1616 if (isset($stc['stccat3'])) {
1617 $str_html .= "<tr class='levd'>
1618 <td>&nbsp;</td>
1619 <td colspan='4'>{$stc['stccat3']} {$stc['stcstat3']} {$stc['stcentity3']} </td>
1620 </tr>".PHP_EOL;
1628 if (isset($bar['E'])) {
1629 // Dependent level
1630 // do not expect amounts or quantities
1631 $acp = ''; $ref = '';
1632 if ($bar['E']['qtyacc']) { $acp .= ' Accepted ' . $bar['E']['qtyacc'] . ': ' . $bar['E']['amtacc']; }
1633 if ($bar['E']['qtyrej']) { $rej .= ' Rejected ' . $bar['E']['qtyrej'] . ': ' . $bar['E']['amtrej']; }
1634 $str_html .= "<tr class='leve'>
1635 <td>{$bar['E']['level']}</td>
1636 <td colspan='4'>{$bar['E']['entity']} {$bar['E']['name']} &nbsp;{$bar['E']['id']}</td>
1637 </tr>".PHP_EOL;
1638 if ($bar['E']['dtsvc']) {
1639 $str_html .= "<tr class='leve'>
1640 <td>&nbsp;</td>
1641 <td colspan='4'>Service Date: {$bar['E']['dtsvc']}</td>
1642 </tr>".PHP_EOL;
1644 // our pid-encounter and possibly payer claim number and intermediary trace
1645 if (isset($bar['E']['trace'])) { $ref .= $bar['E']['trace']; }
1646 if (isset($bar['E']['ref1k'])) { $ref .= ' ' . $bar['E']['ref1k']; }
1647 if (isset($bar['D']['refvv'])) { $ref .= ' ' . $bar['D']['refvv']; }
1648 if (isset($bar['E']['refd9'])) { $ref .= ' ' . $bar['E']['refd9']; }
1649 if ($ref) {
1650 $str_html .= "<tr class='leve'>
1651 <td>&nbsp;</td>
1652 <td colspan='4'>$ref</td>
1653 </tr>".PHP_EOL;
1656 if (count($bar['E']['STC'])) {
1657 foreach($bar['E']['STC'] as $stc) {
1658 $stcstatus = isset($stc['stcstat']) ? $stc['stcstat'] : '';
1659 $stcstatus .= isset($stc['stcentity']) ? ' (' . $stc['stcentity'] . ')' : '';
1660 $str_html .= "<tr class='leve'>
1661 <td>&nbsp;</td>
1662 <td colspan='4'>{$stc['stcamount']} {$stc['stcaction']} {$stc['stccat']} </td>
1663 </tr>
1664 <tr class='leve'>
1665 <td>&nbsp;</td>
1666 <td colspan='4'>&nbsp;&nbsp;$stcstatus</td>
1667 </tr>
1668 <tr class='leve'>
1669 <td>&nbsp;</td>
1670 <td colspan='4'>{$stc['stcmessage']}</td>
1671 </tr>".PHP_EOL;
1672 if (isset($stc['stcamount2'])) {
1673 $str_html .= "<tr class='leve'>
1674 <td>&nbsp;</td>
1675 <td colspan='4'>{$stc['stcamount2']} {$stc['stcaction2']} {$stc['stccat2']} </td>
1676 </tr>".PHP_EOL;
1678 if (isset($stc['stcamount3'])) {
1679 $str_html .= "<tr class='leve'>
1680 <td>&nbsp;</td>
1681 <td colspan='4'>{$stc['stcamount3']} {$stc['stcaction3']} {$stc['stccat3']} </td>
1682 </tr>".PHP_EOL;
1687 if (count($bar['E']['SVC'])) {
1688 foreach($bar['E']['SVC'] as $svc) {
1689 $str_html .= "<tr class='leve'>
1690 <td>&nbsp;</td>
1691 <td colspan='4'>{$svc['svccode']} Fee: {$svc['svcfee']} Pmt: {$svc['svcpmt']} Qty: {$svc['svcqty']} </td>
1692 </tr>".PHP_EOL;
1693 if (isset($svc['STC']) && count($svc['STC'])) {
1694 foreach($svc['STC'] as $svcstc) {
1695 $str_html .= "<tr class='leve'>
1696 <td>&nbsp;</td>
1697 <td colspan='4'>{$svcstc['stcamount']} {$stc['stcaction']} {$stc['stccat']} </td>
1698 </tr>".PHP_EOL;
1699 if (isset($stc['stccat2'])) {
1700 $str_html .= "<tr class='leve'>
1701 <td>&nbsp;</td>
1702 <td colspan='4'>{$stc['stccat2']} {$stc['stcstat2']} {$stc['stcentity2']} </td>
1703 </tr>".PHP_EOL;
1705 if (isset($stc['stccat3'])) {
1706 $str_html .= "<tr class='leve'>
1707 <td>&nbsp;</td>
1708 <td colspan='4'>{$stc['stccat3']} {$stc['stcstat3']} {$stc['stcentity3']} </td>
1709 </tr>".PHP_EOL;
1716 $str_html .= "</tbody>
1717 </table>".PHP_EOL;
1719 return $str_html;
1725 * determine the array_slice parameters for the particular claim status transaction
1727 * parameters to slice ST...SE transaction segments out of the the file segments array
1729 * @param array the segments array of the 277 file
1730 * @param array the delimiters array
1731 * @param string the bht03 value we are looking for in loop 2000C TRN
1732 * @param string the patient control (pid-enc or encounter) from 837 CLM01
1733 * @param string the ST02 number from claims_f277.csv, from 277 file initial processing
1734 * @param string the ISA control number from the envelope wrapping the ST02 number
1735 * @return array the parameters for array_slice (start, count, searchval)
1737 function ibr_277_bhtblock($segments, $delimiters, $clm01 = '', $bht03 = '', $st02 = '') {
1738 // derive the array_slice parameters for the bht segments block
1739 // need to add the isa13 parameter, multiple ISA--IEA in 277 files
1740 $useclm = false;
1741 $useenc = false;
1742 $usebht = false;
1743 $usest = false;
1744 $isfound = false;
1745 $slice_ar = array();
1746 $isanum = '';
1748 $elem_d = $delimiters['e'];
1750 if (!is_array($segments)) {
1751 csv_edihist_log ("ibr_277_bhtblock: segment array error");
1752 // debug
1753 //echo "ibr_277_bhtblock: segment array error".PHP_EOL;
1754 return false;
1756 if (!$clm01 && !$bht03 && !$st02) {
1757 csv_edihist_log ("ibr_277_bhtblock: no specifier arguments given");
1758 return false;
1759 } elseif (strpos($st02, '_')) {
1760 $dpos = strpos($st02, '_');
1761 $srchval = substr($st02, $dpos+1);
1762 $isanum = substr($st02, 0, $dpos);
1763 //$srchval = (strlen($st02) < 4) ? str_pad ($st02, 4, "0", STR_PAD_LEFT) : strval($st02);
1764 $usest = true;
1765 } elseif (strlen($bht03) == 13) {
1766 $srchval = strval($bht03);
1767 $usebht = true;
1768 } elseif (strlen($clm01) && strpos($clm01, '-')) {
1769 $useclm = true;
1770 $srchval = strval($clm01);
1771 } elseif (strlen($clm01) && !strpos($clm01, '-')) {
1772 $useenc = true;
1773 $srchval = strval($clm01);
1774 } else {
1775 csv_edihist_log ("error: status response - unable to determine search string");
1776 return false;
1779 $isastr = 'ISA'.$elem_d;
1780 $ststr = 'ST'.$elem_d;
1781 $trnstr = 'TRN'.$elem_d.'2'.$elem_d;
1782 $bhtstr = 'BHT'.$elem_d;
1783 $sestr = 'SE'.$elem_d;
1784 $idx = -1;
1786 foreach($segments as $segstr) {
1787 // increment index
1788 $idx++;
1789 // check ISA envelope
1790 if (substr($segstr, 0, 4) == $isastr) {
1791 $seg = explode($elem_d, $segstr);
1792 $isisa = ($seg[13] == $isanum) ? true : false;
1793 continue;
1795 if (substr($segstr, 0, 4) == 'IEA'.$elem_d) {
1796 $isisa = false;
1797 continue;
1799 // get position of ST segment
1800 if (substr($segstr, 0, 3) == $ststr) {
1801 $stpos = $idx;
1802 $isfound = false;
1803 $seg = explode($elem_d, $segstr);
1804 $stnum = strval($seg[2]);
1805 if ($usest && $isisa && ($stnum == $srchval)) {
1806 $isfound = true;
1808 continue;
1810 // use the BHT03 reference from the file
1811 if (substr($segstr, 0, 4) == $bhtstr && $usebht ) {
1812 $seg = explode($elem_d, $segstr);
1813 if ($seg[3] === $srchval) {
1814 $isfound = true;
1815 $slice_ar[0] = $stpos;
1819 if (substr($segstr, 0, 6) == $trnstr) {
1820 if ($useclm) {
1821 $seg = explode($elem_d, $segstr);
1822 if ($seg[2] == $srchval) {
1823 $isfound = true;
1824 $slice_ar[0] = $stpos;
1828 if ($useenc) {
1829 $seg = explode($elem_d, $segstr);
1830 if (substr($seg[2], -strlen($srchval)) == $srchval) {
1831 $isfound = true;
1832 $slice_ar[0] = $stpos;
1835 continue;
1838 if ($isfound && (substr($segstr, 0, 3) == $sestr) ) {
1839 $seg = explode($elem_d, $segstr);
1840 if ($stnum == $seg[2]) {
1841 $slice_ar[1] = $seg[1];
1842 $slice_ar[2] = $srchval;
1845 if ($idx - $stpos + 1 != $seg[1]) {
1846 $ct = $idx - $stpos + 1;
1847 csv_edihist_log ("ibr_277_bhtblock: $srchval st count error se02 {$seg[1]} count $ct ");
1850 // we expect only one match in a file
1851 break;
1855 // return the slice or the slice parameters? slice parameters
1856 return $slice_ar;
1860 * create a display for an individual claim status response
1862 * @uses csv_file_by_controlnum()
1863 * @uses csv_x12_segments()
1864 * @uses ibr_277_bhtblock()
1865 * @uses ibr_277_bht_array()
1866 * @uses ibr_277_bhthtml()
1867 * @param string $filename the filename
1868 * @param string $isa13 the isa13 control number for the file
1869 * @param string $bht03 the identifier from the 837 bht segment
1870 * @param string $clm01 the pid-encounter from the 837 clm segment
1871 * @param string $st02 the st number from the 277 file
1872 * @return string either an error message or a table with the information from the response
1874 function ibr_277_response_html($filename = '', $isa13 = '', $bht03 = '', $clm01 = '', $st02 = '' ) {
1875 // create a display for an individual 277 response
1876 $html_str = '';
1878 if (!$filename && !$isa13) {
1879 csv_edihist_log ("ibr_277_response_html: called with no file arguments");
1880 $html_str .= "Error, no file given<br />".PHP_EOL;
1881 return $html_str;
1882 } elseif (!$filename && $isa13) {
1883 $fn = csv_file_by_controlnum('f277', $isa13);
1884 } elseif ($filename) {
1885 $fn = basename($filename);
1888 if ($fn) {
1890 $ar_277_seg = csv_x12_segments($fn, "f277", false);
1891 if (!is_array($ar_277_seg)) {
1892 $html_str .= "Error in file name or file parsing <br />".PHP_EOL;
1893 return $html_str;
1897 if ($bht03 || $clm01 || $st02) {
1899 $sliceparams = ibr_277_bhtblock($ar_277_seg['segments'], $ar_277_seg['delimiters'], $clm01, $bht03, $st02);
1900 if ($sliceparams) {
1901 $bhtsegs = array_slice($ar_277_seg['segments'], $sliceparams[0], $sliceparams[1]);
1902 $bht_ar = ibr_277_bht_array($bhtsegs, $ar_277_seg['delimiters']);
1903 $bht_html = ibr_277_bhthtml($bht_ar);
1904 if ($bht_html) {
1905 $html_str .= $bht_html;
1906 } else {
1907 $html_str .= "Error encountered in generating display <br />".PHP_EOL;
1910 } else {
1911 $html_str .= "Did not find status for $bht03 $clm01 $st02 in $fn <br />".PHP_EOL;
1913 } else {
1914 csv_edihist_log ("ibr_277_response_html: called with no claim identifying arguments");
1915 $html_str .= "Error, no claim identification given<br />".PHP_EOL;
1918 return $html_str;