Add back RingCentral to our FaxSMS Module (#7542)
[openemr.git] / library / edihistory / edih_segments.php
blob653d04e066fa6206370b7a23630a30dc229e1d55
1 <?php
3 /**
4 * edih_segments.php
6 * @package OpenEMR
7 * @link http://www.open-emr.org
8 * @author Kevin McCormick Longview, Texas
9 * @author Stephen Waite <stephen.waite@cmsvt.com>
10 * @copyright Copyright (c) 2016 Kevin McCormick Longview, Texas
11 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
15 /**
16 * increment loop values ($lpval is a reference)
18 * @param $lptest the prospective loop value
19 * @param &$lpval the present loop value -- reassigned here
20 * @return integer value from strcmp()
22 function edih_change_loop($lptest, &$lpval)
24 // strcmp($str1,$str2) Returns < 0 if str1 is less than str2; > 0 if str1 is greater than str2, and 0 if they are equal.
25 if (strcmp($lptest, $lpval) > 0) {
26 //echo "$lptest greater than $lpval" .PHP_EOL;
27 $lpval = $lptest;
30 return strcmp($lptest, $lpval);
33 /**
34 * format segments for display of x12 edi files
36 * @param array $segments
37 * @param string $delimiter
38 * return string
40 function edih_segments_text($segments, $delimiter)
43 $str_html = '';
45 if (!is_array($segments) || !count($segments) || strlen($delimiter) != 1) {
46 // debug
47 csv_edihist_log('edih_generic_text: invalid argument');
48 $str_html = "Invalid arguments for view of x12 file text<br />";
49 return $str_html;
53 $de = $delimiter;
54 $loopid = " -- ";
55 $idx = 0;
57 foreach ($segments as $key => $seg) {
58 $idx++;
60 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
64 return $str_html;
67 /**
68 * identify loops and format segments for display
69 * of 837 (professional claim) type x12 edi files
71 * @param array $segments
72 * @param string $delimiter
73 * return string
75 function edih_837_text($segments, $delimiter, $err_seg = '')
78 $str_html = '';
79 $err_ar = array();
81 if (!is_array($segments) || !count($segments) || strlen($delimiter) != 1) {
82 // debug
83 csv_edihist_log('edih_837_text: invalid argument');
84 $str_html .= "Invalid arguments for view of x12 file text<br />";
85 return $str_html;
88 // to highlight identified errors listed in 999/997 ack
89 if ($err_seg) {
90 $er = edih_errseg_parse($err_seg);
91 $erstn = (isset($er['trace'])) ? substr($er['trace'], -4) : '';
92 $erseg = (isset($er['err'])) ? $er['err'] : array();
93 } else {
94 $erstn = '';
95 $erseg = array();
99 $de = $delimiter;
100 $loopid = "0";
101 $idx = 0;
102 $stkey = 0;
103 $segnum = 0;
104 $stsegct = 0;
105 $bterr = 'btseg';
107 foreach ($segments as $key => $seg) {
108 $idx++;
109 $title = '';
110 $stsegct++;
111 $bterr = 'btseg';
113 if ($erstn && ($erstn == $stn)) {
114 $bterr = (in_array($stsegct, $erseg)) ? 'bterr' : 'btseg';
118 if (strncmp('ST' . $de, $seg, 3) === 0) {
119 $loopid = 'Header';
120 $stkey = (int)$key;
121 $stsegct = 1;
122 $stn = explode($de, $seg)[2];
123 $str_html .= "<tr><td class='btloop' title='" . attr($title) . "'>" . text($loopid) . "</td><td class='btnum' title='" . attr($key) . "'>" . text($stsegct) . "</td><td class='" . attr($bterr) . "'>" . text($seg) . "</td></tr>" . PHP_EOL;
124 continue;
128 if (strncmp('BHT' . $de, $seg, 4) === 0) {
129 $loopid = 'Begin';
130 $stsegct = 2;
131 $str_html .= "<tr><td class='btloop' title='" . attr($title) . "'>" . text($loopid) . "</td><td class='btnum' title='" . attr($key) . "'>" . text($stsegct) . "</td><td class='" . attr($bterr) . "'>" . text($seg) . "</td></tr>" . PHP_EOL;
132 continue;
136 if (strncmp('HL' . $de, $seg, 3) === 0) {
137 $sar = explode($de, $seg);
138 if ($sar[3] == '20') { // level code
139 $loopid = '2000A'; // billing provider (clinic)
140 } elseif ($sar[3] == '22') {
141 $loopid = '2000B'; // subscriber
142 } elseif ($sar[3] == '23' || $sar[3] == 'PT') {
143 $loopid = '2000C'; // dependent
144 $has_eb = false;
145 } else {
146 //debug
147 csv_edihist_log('edih_837_text: HL has no level ' . $seg);
151 $str_html .= "<tr><td class='btloop' title='" . attr($title) . "'>" . text($loopid) . "</td><td class='btnum' title='" . attr($key) . "'>" . text($stsegct) . "</td><td class='" . attr($bterr) . "'>" . text($seg) . "</td></tr>" . PHP_EOL;
152 continue;
156 if (strncmp('CLM' . $de, $seg, 4) === 0) {
157 $loopid = '2300';
158 $title = 'Claim';
159 $str_html .= "<tr><td class='btloop' title='" . attr($title) . "'>" . text($loopid) . "</td><td class='btnum' title='" . attr($key) . "'>" . text($stsegct) . "</td><td class='" . attr($bterr) . "'>" . text($seg) . "</td></tr>" . PHP_EOL;
160 $title = '';
161 continue;
165 if (strncmp('SBR' . $de, $seg, 4) === 0) {
166 if ($loopid == '2000B') {
167 $title = 'Subscriber';
168 $str_html .= "<tr><td class='btloop' title='" . attr($title) . "'>" . text($loopid) . "</td><td class='btnum' title='" . attr($key) . "'>" . text($stsegct) . "</td><td class='" . attr($bterr) . "'>" . text($seg) . "</td></tr>" . PHP_EOL;
169 } else {
170 $title = 'Other Subscriber';
171 $loopid = '2320';
172 $str_html .= "<tr><td class='btloop' title='" . attr($title) . "'> -- </td><td class='btnum' title='" . attr($key) . "'>" . text($stsegct) . "</td><td class='" . attr($bterr) . "'>" . text($seg) . "</td></tr>" . PHP_EOL;
175 $title = '';
176 continue;
180 if (strncmp('LX' . $de, $seg, 3) === 0) {
181 $loopid = '2400';
182 $title = 'Svc Line Number';
183 $str_html .= "<tr><td class='btloop' title='" . attr($title) . "'>" . text($loopid) . "</td><td class='btnum' title='" . attr($key) . "'>" . text($stsegct) . "</td><td class='" . attr($bterr) . "'>" . text($seg) . "</td></tr>" . PHP_EOL;
184 $title = '';
185 continue;
189 if (strncmp('LIN' . $de, $seg, 4) === 0) {
190 $loopid = '2410';
191 $title = 'Drug ID';
192 $str_html .= "<tr><td class='btloop' title='" . attr($title) . "'>" . text($loopid) . "</td><td class='btnum' title='" . attr($key) . "'>" . text($stsegct) . "</td><td class='" . attr($bterr) . "'>" . text($seg) . "</td></tr>" . PHP_EOL;
193 $title = '';
194 continue;
198 if (strncmp('SVD' . $de, $seg, 4) === 0) {
199 $loopid = '2430';
200 $title = 'Line Adjudication';
201 $str_html .= "<tr></tr><td class='btloop' title='" . attr($title) . "'>" . text($loopid) . "</td><td class='btnum' title='" . attr($key) . "'>" . text($stsegct) . "</td><td class='" . attr($bterr) . "'>" . text($seg) . "</td></tr>" . PHP_EOL;
202 $title = '';
203 continue;
207 if (strncmp('NM1' . $de, $seg, 4) === 0) {
208 $sar = explode($de, $seg);
209 $nm101 = ( isset($sar[1]) ) ? $sar[1] : '';
210 if ($loopid == 'Begin' || strcmp(substr($loopid, 0, 4), '2320') < 0) {
211 if ($nm101 == '41') {
212 $loopid = '1000A';
213 $title = 'Submitter';
214 } elseif ($nm101 == '40') {
215 $loopid = '1000B';
216 $title = 'Receiver';
217 } elseif ($nm101 == '85') {
218 $loopid = '2010AA';
219 $title = 'Billing';
220 } elseif ($nm101 == '87') {
221 $loopid = '2010AB';
222 $title = 'Pay to';
223 } elseif ($nm101 == 'PE') {
224 $loopid = '2010AC';
225 $title = 'Pay to Plan';
226 } elseif ($nm101 == 'IL') {
227 $loopid = '2010BA';
228 $title = 'Subscriber';
229 } elseif ($nm101 == 'PR') {
230 $loopid = '2010BB';
231 $title = 'Payer';
232 } elseif ($nm101 == 'QC') {
233 $loopid = '2010CA';
234 $title = 'Patient';
235 } elseif ($nm101 == 'DN') {
236 $loopid = '2310A';
237 $title = 'Referring Provider';
238 } elseif ($nm101 == 'P3') {
239 $loopid = '2310A';
240 $title = 'Primary Care Provider';
241 } elseif ($nm101 == '82') {
242 $loopid = '2310B';
243 $title = 'Rendering Provider';
244 } elseif ($nm101 == '77') {
245 $loopid = '2310C';
246 $title = 'Service Facility';
247 } elseif ($nm101 == 'DQ') {
248 $loopid = '2310D';
249 $title = 'Supervising Provider';
250 } elseif ($nm101 == 'PW') {
251 $loopid = '2310E';
252 $title = 'Ambulance pickup';
253 } elseif ($nm101 == '45') {
254 $loopid = '2310F';
255 $title = 'Ambulance dropoff';
257 } elseif (strcmp(substr($loopid, 0, 4), '2400') < 0) {
258 if ($nm101 == 'IL') {
259 $loopid = '2330A';
260 $title = 'Other Subscriber';
261 } elseif ($nm101 == 'PR') {
262 $loopid = '2330B';
263 $title = 'Other Payer';
264 } elseif ($nm101 == 'PR') {
265 $loopid = '2330C';
266 $title = 'Other Referring Provider';
267 } elseif ($nm101 == '82') {
268 $loopid = '2330D';
269 $title = 'Other Rendering Provider';
270 } elseif ($nm101 == '77') {
271 $loopid = '2330E';
272 $title = 'Other Svc Facility';
273 } elseif ($nm101 == 'DQ') {
274 $loopid = '2330F';
275 $title = 'Other Supervising Provider';
276 } elseif ($nm101 == '85') {
277 $loopid = '2330G';
278 $title = 'Other Billing Provider';
280 } else {
281 if ($nm101 == '82') {
282 $loopid = '2420A';
283 $title = 'Rendering Provider';
284 } elseif ($nm101 == 'QB') {
285 $loopid = '2420B';
286 $title = 'Purchased Svc Provider';
287 } elseif ($nm101 == '77') {
288 $loopid = '2420C';
289 $title = 'Service Facility';
290 } elseif ($nm101 == 'DQ') {
291 $loopid = '2420D';
292 $title = 'Supervising Provider';
293 } elseif ($nm101 == 'DK') {
294 $loopid = '2420E';
295 $title = 'Ordering Provider';
296 } elseif ($nm101 == 'DN') {
297 $loopid = '2420F';
298 $title = 'Referring Provider';
299 } elseif ($nm101 == 'P3') {
300 $loopid = '2420F';
301 $title = 'Primary Care Provider';
302 } elseif ($nm101 == 'PW') {
303 $loopid = '2420G';
304 $title = 'Ambulance pickup';
305 } elseif ($nm101 == '45') {
306 $loopid = '2420H';
307 $title = 'Ambulance dropoff';
312 $str_html .= "<tr><td class='btloop' title='" . attr($title) . "'>" . text($loopid) . "</td><td class='btnum' title='" . attr($key) . "'>" . text($stsegct) . "</td><td class='" . attr($bterr) . "'>" . text($seg) . "</td></tr>" . PHP_EOL;
313 $title = '';
314 continue;
318 if (strncmp('SE' . $de, $seg, 3) === 0) {
319 $loopid = 'Trailer';
320 $str_html .= "<tr><td class='btloop' title='" . attr($title) . "'>" . text($loopid) . "</td><td class='btnum' title='" . attr($key) . "'>" . text($stsegct) . "</td><td class='" . attr($bterr) . "'>" . text($seg) . "</td></tr>" . PHP_EOL;
321 $title = '';
322 continue;
325 // for all the segments that do not begin loops
326 $str_html .= "<tr><td class='btloop' title='" . attr($title) . "'> -- </td><td class='btnum' title='" . attr($key) . "'>" . text($stsegct) . "</td><td class='" . attr($bterr) . "'>" . text($seg) . "</td></tr>" . PHP_EOL;
331 return $str_html;
335 * identify loops and format segments for display
336 * of 270/271 (eligibility) type x12 edi files
338 * @param array $segments
339 * @param string $delimiter
340 * return string
342 function edih_271_text($segments, $delimiter, $err_seg = '')
345 $str_html = '';
347 if (!is_array($segments) || !count($segments) || strlen($delimiter) != 1) {
348 // debug
349 csv_edihist_log('edih_271_text: invalid argument');
350 $str_html .= "Invalid arguments for view of x12 file text<br />";
351 return $str_html;
355 $de = $delimiter;
356 $prevseg = '';
357 $loopid = "0";
358 $lx_ct = 0;
359 $hasst = false;
360 $idx = 0;
361 $stsegct = 0;
363 // to highlight identified errors listed in 999/997 ack (for 270)
364 if ($err_seg) {
365 $er = edih_errseg_parse($err_seg);
366 $erstn = (isset($er['trace'])) ? substr($er['trace'], -4) : '';
367 $erseg = (isset($er['err'])) ? $er['err'] : array();
368 } else {
369 $erstn = '';
370 $erseg = array();
374 if ($err_seg) {
375 $er = edih_errseg_parse($err_seg);
376 if (is_array($er) && count($er)) {
377 $err_ar = $er;
382 foreach ($segments as $key => $seg) {
383 $sar = array();
384 $idx++;
385 $stsegct++;
386 $bterr = 'btseg';
388 if ($erstn && ($erstn == $stn)) {
389 $bterr = (in_array($stsegct, $erseg)) ? 'bterr' : 'btseg';
393 if (strncmp('ST' . $de, $seg, 3) === 0) {
394 $sar = explode($de, $seg);
395 $loopid = 'Header';
396 $hasst = true;
397 $stsegct = 1;
398 $sttp = (isset($seg[1])) ? $seg[1] : '';
399 $stn = (isset($seg[2])) ? $seg[2] : '';
400 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
401 continue;
405 if (strncmp('BHT' . $de, $seg, 4) === 0) {
406 $loopid = 'Begin';
407 // 2nd seg in transaction, ST may not be included if segments are transaction slice
408 if ($stsegct < 2) {
409 $stsegct = 2;
412 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
413 continue;
417 if (strncmp('HL' . $de, $seg, 3) === 0) {
418 $sar = explode($de, $seg);
419 if ($sar[3] == '20') { // level code
420 $loopid = '2000A'; // info source (payer)
421 } elseif ($sar[3] == '21') {
422 $loopid = '2000B'; // info receiver (clinic)
423 } elseif ($sar[3] == '22') {
424 $loopid = '2000C'; // subscriber
425 $has_eb = false;
426 } elseif ($sar[3] == '23') {
427 $loopid = '2000D'; // dependent
428 $has_eb = false;
429 } else {
430 //debug
431 csv_edihist_log('edih_271_text: HL has no level ' . $seg);
435 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
436 $prevseg = 'HL' . $de;
437 continue;
441 if (strncmp('NM1' . $de, $seg, 4) === 0) {
442 if (strncmp('NM1' . $de, $prevseg, 4) === 0) {
443 $str_html .= "<tr><td class='btloop'> -- </td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
444 continue;
447 switch ((string)$loopid) {
448 case '2000A':
449 $loopid = '2100A';
450 break; // edih_change_loop($lptest, &$lpval)
451 case '2000B':
452 $loopid = '2100B';
453 break;
454 case '2000C':
455 $loopid = '2100C';
456 break;
457 case '2000D':
458 $loopid = '2100D';
459 break;
460 default:
461 $loopid = $loopid;
464 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
465 $prevseg = 'NM1' . $de;
466 continue;
470 if (strncmp('EB' . $de, $seg, 3) === 0 || strncmp('EQ' . $de, $seg, 3) === 0) {
471 // EB* segment is in 271 type, EQ* is corresponding segment in 270 type
472 if (strncmp($seg, $prevseg, 3) === 0) {
473 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
474 $prevseg = substr($seg, 0, 3);
475 continue;
478 if ($loopid = '2100C' || $loopid = '2115C' || $loopid = '2120C') {
479 $loopid = '2110C';
480 } elseif ($loopid = '2100D' || $loopid = '2115D' || $loopid = '2120D') {
481 $loopid = '2110D';
484 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
485 $prevseg = substr($seg, 0, 3);
486 $has_eb = (strncmp('EB' . $de, $seg, 3) === 0);
487 $has_iii = false;
488 continue;
492 if (strncmp('III' . $de, $seg, 4) === 0 && $has_eb) {
493 // the III segment begins a loop in 271 type, but not in 270
494 if ($loopid = '2110C') {
495 $loopid = '2115C';
498 if ($loopid = '2100D') {
499 $loopid = '2115D';
502 if ($has_iii) {
503 $str_html .= "<tr><td class='btloop'></td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
504 } else {
505 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
506 $has_iii = true;
509 $prevseg = substr($seg, 0, 4);
510 continue;
514 if (strncmp('LS' . $de, $seg, 3) === 0) {
515 if ($loopid = '2110C' || $loopid = '2115C') {
516 $loopid = '2120C';
517 } elseif ($loopid = '2110D' || $loopid = '2115D') {
518 $loopid = '2120D';
521 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
522 continue;
526 if (strncmp('SE' . $de, $seg, 3) === 0) {
527 $str_html .= "<tr><td class='btloop'>Trailer</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
528 $loopid = '0';
529 continue;
532 // for all the segments that do not begin loops
533 $prevseg = substr($seg, 0, strpos($seg, $de) + 1);
534 $str_html .= "<tr><td class='btloop'> -- </td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
539 return $str_html;
543 function edih_835_text($segments, $delimiter, $err_seg = '')
546 $str_html = '';
547 if (!is_array($segments) || !count($segments) || strlen($delimiter) != 1) {
548 //debug
549 csv_edihist_log('edih_835_text: invalid segments');
550 $str_html .= "Invalid arguments for view of x12 file text<br />";
551 return $str_html;
555 $de = $delimiter;
556 $prevseg = '';
557 $loopid = "0";
558 $lx_ct = 0;
559 $idx = 0;
561 foreach ($segments as $key => $seg) {
562 //$idx++;
564 if (strncmp('ST' . $de, $seg, 3) === 0) {
565 $loopid = 'Header';
566 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
567 continue;
571 if (strncmp('N1' . $de, $seg, 3) === 0) {
572 $sar = explode($de, $seg);
573 if ($sar[1] == 'PR') {
574 $loopid = '1000A';
575 } elseif ($sar[1] == 'PE') {
576 $loopid = '1000B';
579 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
580 $prevseg = 'N1' . $de;
581 continue;
585 if (strncmp('LX' . $de, $seg, 3) === 0) {
586 $loopid = '2000';
587 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
588 $prevseg = 'LX' . $de;
589 continue;
593 if (strncmp('TS3' . $de, $seg, 4) === 0) {
594 if ($loopid == '2000') {
595 $str_html .= "<tr><td class='btloop'> -- </td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
596 } else {
597 $loopid = '2000';
598 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
601 $prevseg = 'TS3' . $de;
602 continue;
606 if (strncmp('CLP' . $de, $seg, 4) === 0) {
607 $loopid = '2100';
608 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
609 $prevseg = 'CLP' . $de;
610 continue;
614 if (strncmp('SVC' . $de, $seg, 4) === 0) {
615 $loopid = '2110';
616 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
617 $prevseg = 'SVC' . $de;
618 continue;
622 if (strncmp('PLB' . $de, $seg, 4) === 0) {
623 $loopid = 'Adjust';
624 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
625 $prevseg = 'PLB' . $de;
626 continue;
630 if (strncmp('SE' . $de, $seg, 3) === 0) {
631 $loopid = 'Trailer';
632 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
633 $prevseg = 'SE' . $de;
634 continue;
637 // for all the segments that do not begin loops
638 $prevseg = substr($seg, 0, 3);
639 $prevseg .= $de;
640 $str_html .= "<tr><td class='btloop'> -- </td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
645 return $str_html;
650 * identify loops and format segments for display
651 * of 277 (claim status) type x12 edi files
653 * @param array $segments
654 * @param string $delimiter
655 * return string
657 function edih_277_text($segments, $delimiter, $stpos = '')
660 $str_html = '';
661 if (!is_array($segments) || !count($segments) || strlen($delimiter) != 1) {
662 //debug
663 csv_edihist_log('edih_277_text: invlid segments');
664 $str_html .= "Invalid arguments for view of x12 file text<br />";
665 return $str_html;
669 // to highlight identified errors listed in 999/997 ack (for 276)
670 //if ($err_seg) {
671 //$er = edih_errseg_parse($err_seg);
672 //$erstn = (isset($er['trace'])) ? substr($er['trace'], -4) : '';
673 //$erseg = (isset($er['err'])) ? $er['err'] : array();
674 //} else {
675 //$erstn = '';
676 //$erseg = array();
679 $de = $delimiter;
680 $prevseg = '';
681 $loopid = "0";
682 $lx_ct = 0;
683 $stsegct = 0;
684 //$idx = 0;
686 foreach ($segments as $idx => $seg) {
687 //$idx++;
688 $stsegct++;
689 $key = ($stpos) ? $idx - $stpos : $idx;
690 // if 276 transactions are parsed, 999 errors may be present
691 //if ($erstn && ($erstn == $stn)) {
692 //$bterr = (in_array($stsegct, $erseg)) ? 'bterr' : 'btseg';
695 if (strncmp('ST' . $de, $seg, 3) === 0) {
696 $loopid = 'Header';
697 $stsegct = 1;
698 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
699 continue;
703 if (strncmp('BHT' . $de, $seg, 4) === 0) {
704 $loopid = 'Begin';
705 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
706 continue;
710 if (strncmp('HL' . $de, $seg, 3) === 0) {
711 $sar = explode($de, $seg);
712 if ($sar[3] == '20') { // level code
713 $loopid = '2000A'; // info source (payer)
714 } elseif ($sar[3] == '21') {
715 $loopid = '2000B'; // info receiver (clinic)
716 } elseif ($sar[3] == '19') {
717 $loopid = '2000C'; // provider
718 } elseif ($sar[3] == '22' || $sar[3] == 'PT') {
719 $loopid = '2000D'; // subscriber
720 } elseif ($sar[3] == '23') {
721 $loopid = '2000E'; // dependent
722 } else {
723 //debug
724 csv_edihist_log('edih_277_text: HL has no level ' . $seg);
728 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
729 $prevseg = 'HL' . $de;
730 continue;
735 if (strncmp('NM1' . $de, $seg, 4) === 0) {
736 if (strncmp('NM1' . $de, $prevseg, 4) === 0) {
737 $str_html .= "<tr><td class='btloop'> -- </td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
738 continue;
741 switch ((string)$loopid) {
742 case '2000A':
743 $loopid = '2100A';
744 break; // edih_change_loop($lptest, &$lpval)
745 case '2000B':
746 $loopid = '2100B';
747 break;
748 case '2000C':
749 $loopid = '2100C';
750 break;
751 case '2000D':
752 $loopid = '2100D';
753 break;
754 case '2000E':
755 $loopid = '2100E';
756 break;
759 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
760 $prevseg = 'NM1';
761 continue;
765 if (strncmp('TRN' . $de, $seg, 4) === 0) {
766 if (strncmp('TRN' . $de, $prevseg, 4) === 0) {
767 $str_html .= "<tr><td class='btloop'> -- </td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
768 continue;
771 switch ((string)$loopid) {
772 case '2100A':
773 $loopid = '2200A';
774 break;
775 case '2100B':
776 $loopid = '2200B';
777 break;
778 case '2100C':
779 $loopid = '2200C';
780 break;
781 case '2100D':
782 $loopid = '2200D';
783 break;
784 case '2100E':
785 $loopid = '2200E';
786 break;
789 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
790 $prevseg = 'TRN';
791 continue;
795 if (strncmp('SVC' . $de, $seg, 4) === 0) {
796 if (strncmp('SVC' . $de, $prevseg, 4) === 0) {
797 $str_html .= "<tr><td class='btloop'> -- </td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
798 continue;
801 switch ((string)$loopid) {
802 case '2200D':
803 $loopid = '2220D';
804 break;
805 case '2200E':
806 $loopid = '2220E';
807 break;
810 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
811 $prevseg = 'SVC';
812 continue;
816 if (strncmp('SE' . $de, $seg, 3) === 0) {
817 $loopid = 'Trailer';
818 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
819 $prevseg = 'SE';
820 continue;
823 // for all the segments that do not begin loops
824 $prevseg = substr($seg, 0, 3);
825 $prevseg .= $de;
826 $str_html .= "<tr><td class='btloop'> -- </td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
830 return $str_html;
834 * identify loops and format segments for display
835 * of 278 (authorization) type x12 edi files
837 * @param array $segments
838 * @param string $delimiter
839 * return string
841 function edih_278_text($segments, $delimiter, $err_seg = '')
844 $str_html = '';
846 if (!is_array($segments) || !count($segments) || strlen($delimiter) != 1) {
847 // debug
848 csv_edihist_log('edih_278_text(): invalid argument');
849 $str_html .= "Invalid arguments for view of x12 file text<br />";
850 return $str_html;
854 $de = $delimiter;
855 $prevseg = '';
856 $loopid = "0";
857 $lx_ct = 0;
858 $hasst = false;
859 $err_ar = array();
860 $idx = 0;
861 $stsegct = 0;
863 // to highlight identified errors listed in 999/997 ack
864 if ($err_seg) {
865 $er = edih_errseg_parse($err_seg);
866 $erstn = (isset($er['trace'])) ? substr($er['trace'], -4) : '';
867 $erseg = (isset($er['err'])) ? $er['err'] : array();
868 } else {
869 $erstn = '';
870 $erseg = array();
874 foreach ($segments as $key => $seg) {
875 $idx++;
876 $stsegct++;
877 $title = '';
878 $bterr = 'btseg';
880 if ($erstn && ($erstn == $stn)) {
881 $bterr = (in_array($stsegct, $erseg)) ? 'bterr' : 'btseg';
885 if (strncmp('ST' . $de, $seg, 3) === 0) {
886 $loopid = 'Header';
887 $hasst = true;
888 $stsegct = 1;
889 $stn = explode($de, $seg)[2];
890 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='" . attr($bterr) . "'>" . text($seg) . "</td></tr>" . PHP_EOL;
891 continue;
895 if (strncmp('BHT' . $de, $seg, 4) === 0) {
896 $loopid = 'Begin';
897 // 2nd seg in transaction, ST may not be included if segments are transaction slice
898 if ($stsegct < 2) {
899 $stsegct = 2;
902 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='" . attr($bterr) . "'>" . text($seg) . "</td></tr>" . PHP_EOL;
903 continue;
907 if (strncmp($seg, 'HL' . $de, 3) === 0) {
908 $sar = explode($de, $seg);
909 $hl = $sar[1];
910 $hlpc = $sar[2]; // parent code
911 $hllc = $sar[3];
912 $hlcc = (isset($sar[4])) ? $sar[4] : ''; // child code
913 if ($sar[3] == '20') { // level code
914 $loopid = '2000A'; // info source (payer)
915 $title = 'Info Source';
916 } elseif ($sar[3] == '21') {
917 $loopid = '2000B'; // info receiver (clinic)
918 $title = 'Info Receiver';
919 } elseif ($sar[3] == '22') {
920 $loopid = '2000C'; // subscriber
921 $title = 'Subscriber';
922 } elseif ($sar[3] == '23') {
923 $loopid = '2000D'; // dependent
924 $title = 'Dependent';
925 } elseif ($sar[3] == 'EV') {
926 $loopid = '2000E'; // patient event
927 $title = 'Patient Event';
928 } elseif ($sar[3] == 'SS') {
929 $loopid = '2000F'; // service
930 $title = 'Service';
931 } else {
932 //debug
933 csv_edihist_log('edih_278_text: HL has no level ' . $seg);
937 $str_html .= "<tr><td class='btloop' title='" . attr($title) . "'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='" . attr($bterr) . "'>" . text($seg) . "</td></tr>" . PHP_EOL;
938 $prevseg = 'HL';
939 continue;
943 if (strncmp($seg, 'NM1' . $de, 4) === 0) {
944 $sar = explode($de, $seg);
945 $nm101 = $sar[1];
946 if ($loopid == '2000A') {
947 $loopid == '2010A'; // Source
948 } elseif ($loopid == '2000B') {
949 $loopid = '2010B'; // Receiver
950 } elseif ($loopid == '2000C') {
951 $loopid = '2010C'; // Subscriber
952 } elseif ($loopid == '2000D') {
953 $loopid = '2010D'; // Dependent
954 } elseif ($loopid == '2000E' || strpos($loopid, '010E')) { // Patient Event
955 $loopid = (strpos('|71|72|73|77|AAJ|DD|DK|DN|FA|G3|P3|QB|QV|SJ', $nm101) ) ? '2010EA' : $loopid;
956 $loopid = (strpos('|45|FS|ND|PW|R3', $nm101) ) ? '2010EB' : $loopid;
957 $loopid = ($nm101 == 'L5') ? '2010EC' : $loopid;
958 } elseif ($loopid == '2000F' || strpos($loopid, '010F')) { // Service
959 $loopid = (strpos('|71|72|73|77|AAJ|DD|DK|DN|FA|G3|P3|QB|QV|SJ', $nm101) ) ? '2010FA' : $loopid;
963 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='" . attr($bterr) . "'>" . text($seg) . "</td></tr>" . PHP_EOL;
964 $prevseg = 'NM1';
965 continue;
969 if (strncmp('SE' . $de, $seg, 3) === 0) {
970 $str_html .= "<tr><td class='btloop'>Trailer</td><td class='btnum'>" . text($key) . "</td><td class='" . attr($bterr) . "'>" . text($seg) . "</td></tr>" . PHP_EOL;
971 $loopid = '0';
972 $prevseg = 'SE';
973 continue;
976 // for all the segments that do not begin loops
977 $prevseg = substr($seg, 0, strpos($seg, $de));
978 $str_html .= "<tr><td class='btloop'> -- </td><td class='btnum'>" . text($key) . "</td><td class='" . attr($bterr) . "'>" . text($seg) . "</td></tr>" . PHP_EOL;
983 return $str_html;
987 * identify loops and format segments for display
988 * of 997/999 (acknowledgement) type x12 edi files
990 * @param array $segments
991 * @param string $delimiter
992 * return string
994 function edih_997_text($segments, $delimiter)
997 $str_html = '';
998 if (!is_array($segments) || !count($segments) || strlen($delimiter) != 1) {
999 //debug
1000 csv_edihist_log('edih_997_text(): invalid segments');
1001 return $str_html;
1005 $de = $delimiter;
1006 $loopid = "0";
1008 //echo 'edih_997_text() foreach segment count: '.count($segments).PHP_EOL;
1010 foreach ($segments as $key => $seg) {
1012 //echo var_dump($seg).PHP_EOL;
1014 if (strncmp('TA1' . $de, $seg, 4) === 0) {
1015 $sar = explode($de, $seg);
1016 $rspicn = $sar[1];
1017 $loopid = 'ACK'; // not official
1018 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
1019 unset($sar);
1020 $loopid = ''; // reset loop for subsequent segments
1021 continue;
1025 if (strncmp('ST' . $de, $seg, 3) === 0) {
1026 $loopid = 'Header';
1027 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
1028 continue;
1032 if (strncmp('AK1' . $de, $seg, 4) === 0) {
1033 $sar = explode($de, $seg);
1034 $rsptp = csv_file_type($sar[1]);
1035 if ($rspicn && $rsptp) {
1036 $rspfile = csv_file_by_controlnum($rsptp, $rspicn);
1039 $title = ($rspfile) ? 'response to ' . $rspfile : '';
1040 $loopid = '2000';
1041 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td title='" . attr($title) . "' class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
1042 unset($sar);
1043 continue;
1047 if (strncmp('AK2' . $de, $seg, 4) === 0) {
1048 $loopid = 'AK2';
1049 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
1050 continue;
1054 if (strncmp('IK3' . $de, $seg, 4) === 0 || strncmp('AK3' . $de, $seg, 4) === 0) {
1055 $loopid = '2100';
1056 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
1057 continue;
1061 if (strncmp('IK4' . $de, $seg, 4) === 0 || strncmp('AK4' . $de, $seg, 4) === 0) {
1062 $loopid = '2110';
1063 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
1064 continue;
1068 if (strncmp('SE' . $de, $seg, 3) === 0) {
1069 $loopid = 'Trailer';
1070 $str_html .= "<tr><td class='btloop'>" . text($loopid) . "</td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
1071 continue;
1074 // for all the segments that do not begin loops ;
1075 $str_html .= "<tr><td class='btloop'> -- </td><td class='btnum'>" . text($key) . "</td><td class='btseg'>" . text($seg) . "</td></tr>" . PHP_EOL;
1079 return $str_html;
1083 * Display of x12 edi transaction listing or all segments in the files.
1084 * When using $err_info, you must use the filepath of the submitted file
1086 * @param string $filepath path to desired file
1087 * @param string $filetype used when filepath is just filename
1088 * @param string optional $claimid CLM01, or BHT03 to identify a transaction or a trace value
1089 * @param bool false: $claimid is pt transaction, true: $claimid is trace from 835 or 999
1090 * @param string optional $err_info the prepared error info from a 997/999 response
1091 * @return string html for display of file segments
1093 function edih_display_text($filepath, $filetype = '', $claimid = '', $trace = false, $err_info = '')
1096 $str_html = '';
1097 $de = '';
1098 $segments = '';
1099 $stsegkey = '';
1100 $ft = ($filetype) ? $filetype : '';
1101 $errs = ( strlen($err_info) ) ? $err_info : '';
1102 $bht03 = '';
1104 // verify x12 file
1105 $x12obj = csv_check_x12_obj($filepath, $ft);
1107 if ($x12obj && 'edih_x12_file' == get_class($x12obj)) {
1108 $ftype = $x12obj->edih_type();
1109 $ft = csv_file_type($ftype);
1110 $delims = $x12obj->edih_delimiters();
1111 $de = $delims['e'];
1112 $fn = $x12obj->edih_filename();
1113 $segs_ar = $x12obj->edih_segments();
1114 $env_ar = $x12obj->edih_envelopes();
1115 if (!$de || strlen($de) != 1) {
1116 // error in object
1117 // debug
1118 $str_html = 'edih_display_text(): error in delimiters<br />' . PHP_EOL;
1119 $str_html .= $x12obj->edih_message() . PHP_EOL;
1120 return $str_html;
1123 if (!is_array($segs_ar) || !count($segs_ar)) {
1124 // unknown error
1125 $str_html = "<p>unknown error retrieving segments for " . text($fn) . "</p>" . PHP_EOL;
1126 $str_html .= $x12obj->edih_message() . PHP_EOL;
1127 return $str_html;
1129 } else {
1130 //debug
1131 csv_edihist_log('edih_transaction_text(): invalid path ' . $filepath);
1132 $str_html = 'edih_display_text(): error accessing file<br />' . PHP_EOL;
1133 return $str_html;
1137 if ($claimid) {
1138 // claimid can be for transaction, payment, or error response
1139 if ($trace && array_key_exists($claimid, $env_ar['ISA'])) {
1140 $arg_ar = array('ISA13' => $claimid, 'keys' => true);
1141 $segments = $x12obj->edih_x12_slice($arg_ar);
1142 } else {
1143 // claimid alone can be clm01 or bht03, if trace=true, expect trn02 for claimid
1144 foreach ($env_ar['ST'] as $st) {
1145 if ($trace && $claimid == $st['trace']) {
1146 $arg_ar = array('ISA13' => $st['icn'], 'GS06' => $st['gsn'], 'trace' => $claimid, 'keys' => true);
1147 $segments = $x12obj->edih_x12_slice($arg_ar);
1148 break;
1149 } elseif (in_array($claimid, $st['acct'])) {
1150 if ($errs) {
1151 $arg_ar = array('ST02' => $st['stn'], 'ISA13' => $st['icn'], 'GS06' => $st['gsn'], 'keys' => true);
1152 $segments = $x12obj->edih_x12_slice($arg_ar);
1153 } else {
1154 // request for individual transaction segments
1155 $segments = $x12obj->edih_x12_transaction($claimid);
1158 break;
1159 } elseif (in_array($claimid, $st['bht03'])) {
1160 // also possible that bht03 number is given for claimid
1161 // this will likely be a 27x
1162 if ($errs) {
1163 $arg_ar = array('ST02' => $st['stn'], 'ISA13' => $st['icn'], 'GS06' => $st['gsn'], 'keys' => true);
1164 $segments = $x12obj->edih_x12_slice($arg_ar);
1165 } else {
1166 $segments = $x12obj->edih_x12_transaction($claimid);
1169 $bht03 = $claimid;
1170 break;
1174 } else {
1175 $segments = $segs_ar;
1179 // now check if we have segments
1180 if (empty($segments) || !count($segments)) {
1181 if ($claimid) {
1182 $str_html = "<p>error: transaction " . text($claimid) . " not found in " . text($fn) . "</p>" . PHP_EOL;
1183 $str_html .= $x12obj->edih_message() . PHP_EOL;
1184 return $str_html;
1185 } else {
1186 // unknown error
1187 $str_html = "<p>unknown error retrieving segments for " . text($fn) . "</p>" . PHP_EOL;
1188 $str_html .= $x12obj->edih_message() . PHP_EOL;
1189 return $str_html;
1193 // if the segments are from a slice or transaction
1194 // a multidimensional array segs[i][j] must be flattened
1195 $ar_sngl = csv_singlerecord_test($segments);
1196 // false when segments are a transaction or trace only
1197 if (!$ar_sngl) {
1199 // append segments to single array
1200 // keys should not duplicate since all segments
1201 // are from the same x12 file
1202 $trnsegs = array();
1203 for ($i = 0; $i < count($segments); $i++) {
1204 $trnsegs = array_merge($trnsegs, $segments[$i]);
1207 $segments = $trnsegs;
1208 unset($trnsegs);
1212 $capstr = '';
1213 $tbl_id = ($claimid) ? $claimid : $fn;
1215 //'HB'=>'271', 'HS'=>'270', 'HR'=>'276', 'HI'=>'278','HN'=>'277', 'HP'=>'835', 'FA'=>'999', 'HC'=>'837');
1216 switch ((string)$ftype) {
1217 case 'HC':
1218 $capstr = "Claim "; //$cls = "txt837";
1219 $trn_html = edih_837_text($segments, $de, $errs);
1220 break;
1221 case 'HP':
1222 $capstr = "Payment "; //$cls = "txt835";
1223 $trn_html = edih_835_text($segments, $de);
1224 break;
1225 case 'HR':
1226 $capstr = "Status Query "; //$cls = "txt276";
1227 $trn_html = edih_277_text($segments, $de, $errs);
1228 break;
1229 case 'HN':
1230 $capstr = "Claim Status "; //$cls = "txt277";
1231 $trn_html = edih_277_text($segments, $de, $stsegkey);
1232 break;
1233 case 'HS':
1234 $capstr = "Eligibility Query "; //$cls = "txt270";
1235 $trn_html = edih_271_text($segments, $de, $errs);
1236 break;
1237 case 'HB':
1238 $capstr = "Eligibility Report "; //$cls = "txt271";
1239 $trn_html = edih_271_text($segments, $de);
1240 break;
1241 case 'HI':
1242 $capstr = "Authorization "; //$cls = "txt278";
1243 $trn_html = edih_278_text($segments, $de, $errs);
1244 break;
1245 case 'FA':
1246 $capstr = "Batch Acknowledgment "; //$cls = "txt997";
1247 $trn_html = edih_997_text($segments, $de);
1248 break;
1249 default:
1250 $capstr = "x12 $ftype "; //$cls = "txt_x12";
1251 $trn_html = edih_segments_text($segments, $de);
1252 break;
1256 $capstr .= ($claimid) ? " ID: " . text($claimid) : "";
1258 $str_html .= "<table id=" . attr($tbl_id) . " cols=3 class='segtxt'><caption>" . text($capstr) . "</caption>" . PHP_EOL;
1259 $str_html .= "<thead>" . PHP_EOL;
1260 $str_html .= "<tr><th class='btloop'>Loop</th><th class='btloop'>Num</th>";
1261 $str_html .= "<th class='segtxt'>Segment (<em>File:</em> " . text($fn) . ")</th></tr>" . PHP_EOL;
1262 $str_html .= "</thead>" . PHP_EOL . "<tbody>" . PHP_EOL;
1264 $str_html .= $trn_html;
1266 $str_html .= "</tbody></table>" . PHP_EOL;
1268 return $str_html;