Example #1
0
/**
 * copy the substring of text containing claim payment information for a claim
 * 
 * The filename must be found in the files.csv table, i.e. previously processed
 * 
 * @uses csv_verify_file()
 * @uses csv_x12_delimiters()
 * @param string $clp_clm_num  the pid-encounter value
 * @param string $era_file     the filename
 * @return string 			   newline characters are added to each segment end
 */
function ibr_era_get_clp_text($clp_clm_num, $era_file, $html_out = true)
{
    // @param string $clp_clm_num -- CLP01 value, pid-encounter
    // @param string $era_file path to 835 file containing the $clp_clm_num
    // segment block CLP to CLP, SE, LX
    // get the substring of the era file containing the ST number
    //
    $fp = csv_verify_file($era_file, "era");
    if (!$fp) {
        csv_edihist_log("ibr_era_get_clp_text: failed to read {$era_file}");
        $str_clp .= "failed to read {$era_file}";
        return $str_clp;
    } else {
        //
        $bstr = file_get_contents($fp);
        if (!$bstr) {
            csv_edihist_log("ibr_era_get_clp_text: failed to get contents of {$era_file}");
            $str_clp .= "failed to read {$era_file}";
            return $str_clp;
        }
        // get the delimiters
        $str_isa = substr($bstr, 0, 126);
        //
        $ar_delim = csv_x12_delimiters($str_isa, "GS");
        $seg_delim = $ar_delim['t'];
        //
        $seg_clp = "CLP*" . $clp_clm_num;
        // CLP segment that begins remittance detail
        //
        $clp_pos = strpos($bstr, $seg_clp, 0);
        // break it off if $st_pos is not found
        if ($clp_pos == FALSE) {
            csv_edihist_log("Error: {$clp_clm_num} not found in {$era_file}");
            $str_clp .= "Error: {$clp_clm_num} not found in {$era_file}";
            return $str_clp;
        }
        //
        $seg_se = "SE*";
        $seg_lx = "LX*";
        $seg_clpx = "CLP*";
        // see if we can find a closing segment
        $pos_ar[] = strpos($bstr, $seg_se, $clp_pos);
        // $se_pos =
        $pos_ar[] = strpos($bstr, $seg_lx, $clp_pos);
        // $lx_pos =
        $pos_ar[] = strpos($bstr, $seg_clpx, $clp_pos + 10);
        //$clpx_pos =
        //
        // choose the best closing position, closest to $clp_pos
        asort($pos_ar);
        foreach ($pos_ar as $p) {
            // echo "clp_pos $clp_pos  pos_ar $p". PHP_EOL;
            if ($p > $clp_pos) {
                $end_pos = $p;
                break;
            }
        }
        //
        $str_clp = substr($bstr, $clp_pos, $end_pos - $clp_pos);
        //
        // add newlines so each segment is on its own line
        if (strpos($str_clp, $seg_delim . PHP_EOL)) {
            // if true, assume the file has newlines ending segments
        } else {
            // we could get fancy and make an html table or add line numbers
            $str_clp = str_replace($seg_delim, $seg_delim . PHP_EOL, $str_clp);
        }
    }
    //
    if ($html_out) {
        $str_html = "<div class=\"filetext\">";
        $str_html .= "<p>{$pe} &nbsp;&nbsp;" . basename($fp) . " </p>" . PHP_EOL . "<pre><code>";
        $str_html .= $str_clp;
        $str_html .= PHP_EOL . "</code></pre>" . PHP_EOL . "</div>" . PHP_EOL;
        return $str_html;
    } else {
        return $str_clp;
    }
}
Example #2
0
/**
 * Parse x12 file into array of segments.
 * 
 * This function relies on csv_x12_delimiters() to get the delimiters array 
 * and on csv_verify_file() to supply the next_segment value.
 * There are some basic verifications and failures are noted in the log.
 * <pre>
 *  'path'=>pathtofile
 *  'delimiters'=>array from x12_delimiters()
 *  'segments'=>segments[i]=>segment text
 *     if $seg_array is true then segments[i]=>array of elements
 * </pre>
 * 
 * @uses csv_x12_delimiters() 
 * @uses csv_verify_file()
 * @param string $file_path  the full path for the file
 * @param string $type       one of  batch|837|era|835|997|999|277|271
 * @param bool $seg_array    whether each segment should be made into an array of elements
 * @return array|bool        array['delimiters']['segments']['path'], or false on error
 */
function csv_x12_segments($file_path, $type, $seg_array = FALSE)
{
    // do verifications
    $fp_ar = csv_verify_file($file_path, $type, TRUE);
    //
    if (!$fp_ar || !$fp_ar[0]) {
        csv_edihist_log("csv_x12_segments: verification failed for {$file_path}");
        return FALSE;
    }
    //
    if ($fp_ar) {
        //
        $fp = $fp_ar[0];
        $next_segment = $fp_ar[1];
        $f_str = file_get_contents($fp);
        //
        // verify $delimiters
        $delimiters = csv_x12_delimiters(substr($f_str, 0, 126), $next_segment);
        $dlm_ok = FALSE;
        // here, expect $delimiters['t'] ['e'] ['s'] ['r']
        if (is_array($delimiters) && array_keys($delimiters) == array('t', 'e', 's', 'r')) {
            $dlm_ok = TRUE;
            $seg_d = $delimiters['t'];
            $elem_d = $delimiters['e'];
            $subelem_d = $delimiters['s'];
            $rep_d = $delimiters['r'];
        } else {
            csv_edihist_log("csv_x12_segments: invalid delimiters or delimiters wrong for {$fp}");
            return FALSE;
        }
    }
    // OK, now initialize variables
    $fn = basename($fp);
    $ar_seg = array();
    $ar_seg['path'] = $fp;
    $ar_seg['delimiters'] = $delimiters;
    $ar_seg['segments'] = array();
    $seg_pos = 0;
    // position where segment begins
    $st_segs_ct = 0;
    // segments in ST-SE envelope
    $se_seg_ct = "";
    // segment count from SE segment
    $isa_segs_ct = 0;
    // segments in ISA envelope
    $isa_ct = 0;
    // ISA envelope count
    $iea_ct = 0;
    // IEA count
    $trnset_seg_ct = 0;
    // segments by sum of isa segment count
    //
    $isa_str = "ISA" . $elem_d;
    // to reduce evaluations
    $iea_str = "IEA" . $elem_d;
    $st_str = "ST" . $elem_d;
    $se_str = "SE" . $elem_d;
    //
    $idx = -1;
    $moresegs = true;
    while ($moresegs) {
        $idx++;
        // extract each segment from the file text
        $seg_end = strpos($f_str, $seg_d, $seg_pos);
        $moresegs = strpos($f_str, $seg_d, $seg_end + 1);
        //
        $seg_text = substr($f_str, $seg_pos, $seg_end - $seg_pos);
        $seg_pos = $seg_end + 1;
        //
        // we trim in case there are line or carriage returns
        $seg_text = trim($seg_text);
        //
        // check for non ASCII basic characters.  Note reg_ex '/[^\x20-\xFF]/' allows extended ASCII characters
        // this is partly file syntax and partly protection -- we don't want to process an imposter
        // We are mostly concerned with \x00 to \x19, the "control" characters, but apparently some are allowed
        //
        if (preg_match_all('/[^\\x20-\\x7E]/', $seg_text, $matches)) {
            csv_edihist_log("csv_x12_segments: Non-basic ASCII character in segment ({$idx}) in file {$fn}");
            // quit here? return false;  -- actually files have probably been scanned before in upload.php
            // also x12 files have more allowed characters than these
        }
        if ($seg_array) {
            $ar_seg['segments'][] = explode($elem_d, $seg_text);
        } else {
            $ar_seg['segments'][] = $seg_text;
        }
        $st_segs_ct++;
        $isa_segs_ct++;
        //
        // some checks, if wanted
        if (substr($seg_text, 0, 4) == $isa_str) {
            $isa_seg = explode($elem_d, $seg_text);
            $isa_id = $isa_seg[13];
            $isa_segs_ct = 1;
            $isa_ct++;
            continue;
        }
        //
        if (substr($seg_text, 0, 3) == $st_str) {
            // $e = strpos($seg_text, $elem_d, 8);  // ST*835* is 7 characters
            // $st02 = substr($seg_text, 7, $e-7);
            $st_ar = explode($elem_d, $seg_text);
            $st_num = $st_ar[2];
            $st_segs_ct = 1;
            continue;
        }
        if (substr($seg_text, 0, 3) == $se_str) {
            $se_ar = explode($elem_d, $seg_text);
            $se_seg_ct = $se_ar[1];
            $se_num = $se_ar[2];
            if ($se_num != $st_num) {
                csv_edihist_log("csv_x12_segments: ST-SE number mismatch {$st_num} {$se_num} in {$fn}");
            }
            if (intval($se_seg_ct) != $st_segs_ct) {
                csv_edihist_log("csv_x12_segments: ST-SE segment count mismatch {$st_segs_ct} {$se_seg_ct} in {$fn}");
            }
            continue;
        }
        if (substr($seg_text, 0, 4) == $iea_str) {
            $iea_seg = explode($elem_d, $seg_text);
            $iea_id = $iea_seg[2];
            $iea_ct++;
            //
            if ($isa_id != $iea_id) {
                csv_edihist_log("csv_x12_segments: ISA-IEA identifier mismatch set {$iea_ct} in {$fn}");
            }
            if ($iea_ct == $isa_ct) {
                $trnset_seg_ct += $isa_segs_ct;
                if ($idx + 1 != $trnset_seg_ct) {
                    //
                    csv_edihist_log("csv_x12_segments: IEA segment count error ({idx+1}:{$trnset_seg_ct} set) {$iea_ct} in {$fn}");
                }
            } else {
                csv_edihist_log("csv_x12_segments: ISA-IEA count mismatch set {$isa_ct} {$iea_ct} in {$fn}");
            }
        }
        //
    }
    //
    return $ar_seg;
}