Added support for repeating events like "2nd Tuesday" or "Last Friday" of the month.
[openemr.git] / library / edihistory / ibr_ebr_read.php
blob03ba44b0cd811d712472cfd0692742559d34e907
1 <?php
2 /**
3 * ibr_ebr_read.php
4 *
5 * Copyright 2012 Kevin McCormick Longview Texas
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; version 3 or later. You should have
15 * received a copy of the GNU General Public License along with this program;
16 * if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * <http://opensource.org/licenses/gpl-license.php>
22 * @author Kevin McCormick
23 * @link: http://www.open-emr.org
24 * @package OpenEMR
25 * @subpackage ediHistory
28 // a security measure to prevent direct web access to this file
29 // must be accessed through the main calling script ibr_history.php
30 // from admin at rune-city dot com; found in php manual
31 //if (!defined('SITE_IN')) die('Direct access not allowed!');
33 // define constants
34 if (!defined("IBR_DELIMITER")) define("IBR_DELIMITER", "|"); // per Availity edi guide
35 if (!defined("DPR_MSG_DELIM")) define("DPR_MSG_DELIM", "^");
36 //if (!defined("IBR_ENCOUNTER_DIGIT_LENGTH")) define("IBR_ENCOUNTER_DIGIT_LENGTH", "4");
39 /**
40 * derive 'text' version name from ebr, ibr, and dpr files
42 * specific to Availity LLC -- see their EDI Guide
43 * also added 999 files, since availity practice is 99T for 'text' version
45 * @param string file name of related ebr, ibr, or dpr file
46 * @return string
48 function ibr_ebr_ebt_name ($ebr_fname) {
49 // based upon Availity conventions: see availity_edi_guide
50 // the EBR-*-<<seq>>.ebr --> EBT-*-<<seq>>.ebt is the change made here
51 // Availity gives the text version with a sequence number increased by 1
52 // examples:
53 // DPR-MULTIPAYER-201204250830-001-320101111-1821101111.dpr
54 // DPT-MULTIPAYER-201204250830-002-320101111-1821101111.dpt
56 // EBR-MULTIPAYER-201204210230-001.ebr
57 // EBT-MULTIPAYER-201204210230-002.ebt
59 // not tested with more complex file names, but it should work
60 // this concept also applies to .997 files, but they are too simple
62 // get the sequence, relying on it being the only 3 digit part of the filename
63 $re_seq = '/-([0-9]{3})[\-|.]{1}/';
64 preg_match ($re_seq, $ebr_fname, $matches);
65 $m_seq = $matches[1];
67 // increment the sequence and reform as 3 byte count
68 $f_seq = ltrim ($m_seq, "0");
69 $f_seq += 1;
70 $f_seq = str_pad($f_seq, 3, "0", STR_PAD_LEFT);
71 // insert leading "-" to avoid substitution error
72 $m_seq = str_pad($m_seq, 4, "-", STR_PAD_LEFT);
73 $f_seq = str_pad($f_seq, 4, "-", STR_PAD_LEFT);
75 // file names will begin with IBR- EBR- DPR-
76 $f_type = strtoupper(substr($ebr_fname, -4));
78 if ($f_type == ".EBR" ) {
79 // replace the EBR and .ebr parts
80 $f_txt_name = str_replace ("EBR-", "EBT-", $ebr_fname);
81 //echo "1: $f_txt_name" . PHP_EOL;
82 $f_txt_name = str_replace (".ebr", ".ebt", $f_txt_name);
83 $f_txt_name = str_replace ($m_seq, $f_seq, $f_txt_name);
84 } elseif ($f_type == ".IBR" ) {
85 // replace the IBR and .ibr parts
86 $f_txt_name = str_replace ("IBR-", "IBT-", $ebr_fname);
87 //echo "1: $f_txt_name" . PHP_EOL;
88 $f_txt_name = str_replace (".ibr", ".ibt", $f_txt_name);
89 // Availity apparently does not change sequence numbers on IBR -- IBT files
90 } elseif ($f_type == ".DPR" ) {
91 // replace the DPR and .dpr parts
92 // (if DPR files are added to this script)
93 $f_txt_name = str_replace ("DPR-", "DPT-", $ebr_fname);
94 //echo "1: $f_txt_name" . PHP_EOL;
95 $f_txt_name = str_replace (".dpr", ".dpt", $f_txt_name);
96 $f_txt_name = str_replace ($m_seq, $f_seq, $f_txt_name);
97 } elseif ($f_type == ".997" ) {
98 // also Availity 999 to 99T files
99 $f_txt_name = str_replace (".999", ".99T", $f_txt_name);
102 // insert the incremented sequence number
103 //$f_txt_name = str_replace ($m_seq, $f_seq, $f_txt_name);
104 // return the text version file name
105 return $f_txt_name;
110 * read the .ibr .ebr or .dpr file into an array of arrays
112 * Clearinghouse specific format, not x12
114 * @deprecated
115 * @param string file path
116 * @return array
118 function ibr_ebr_filetoarray ($file_path ) {
120 // since the file is multi-line, use fgets()
121 //$delim = "|";
122 $fh = fopen($file_path, 'r');
123 if ($fh) {
124 while (($buffer = fgets($fh, 4096)) !== false) {
125 $ar_ibr[] = explode ( IBR_DELIMITER, trim($buffer) );
127 } else {
128 // trigger_error("class.ibr_read.php : failed to read $file_path" );
129 csv_edihist_log( "ibr_ebr_filetoarray Error: failed to read " . $file_path );
131 fclose($fh);
132 return $ar_ibr;
135 /* ************ DPR functions *************** */
138 * Find and retrieve the claim response message in the dpr file.
140 * The message for given for a particular claim is returned in
141 * html format. The message is strangely formatted, so the
142 * output may not be as clean as desired.
144 * @uses csv_verify_file()
145 * @uses csv_ebr_filetoarray(
146 * @param string
147 * @param string
148 * @return string
150 function ibr_dpr_message($dpr_filepath, $clm01) {
152 $str_html = '';
153 $fp = csv_verify_file($dpr_filepath, 'dpr', false);
154 if ($fp) {
155 //$dpr_ar = ibr_ebr_filetoarray ($fp);
156 $dpr_ar = csv_ebr_filetoarray($fp);
157 } else {
158 csv_edihist_log("ibr_dpr_message: file read error $dpr_filepath");
159 $str_html = "Unable to read " . basename($dpr_filepath) . "<br />".PHP_EOL;
160 return $str_html;
162 if (!is_array($dpr_ar) || !count($dpr_ar) ) {
163 csv_edihist_log("ibr_dpr_message: file read error $dpr_filepath");
164 $str_html = "Unable to read " . basename($dpr_filepath) . "<br />".PHP_EOL;
165 return $str_html;
167 foreach($dpr_ar as $fld) {
168 if ($fld[0] == 'CST' && $fld[2] == $clm01) {
169 $msgstr = $fld[9];
170 $msgstr = str_replace('\\', '', $msgstr);
171 $msgstr = str_replace('^^^', '<br />', $msgstr);
172 $msgstr = str_replace('A^^', '', $msgstr);
173 $msgstr = wordwrap($msgstr, 46, '<br />'.PHP_EOL);
174 $str_html .= "<p class='ibrmsg'>$msgstr</p>";
176 break;
179 if (!$str_html) {
180 $str_html .= "Did not find $clm01 in " . basename($fp) . "<br />".PHP_EOL;
182 return $str_html;
186 * order the claim data array for csv file
188 * @param array individual claim array
189 * @return array
191 function ibr_dpr_csv_claims($claim_ar) {
193 $errstr ='';
194 // ['dpr']['claim'] = array('PtName','SvcDate', 'clm01', 'Status', 'Batch', 'FileName', 'Payer');
195 $f_claim_data[0] = $claim_ar['pt_name'];
196 $f_claim_data[1] = $claim_ar['date'];
197 $f_claim_data[2] = $claim_ar['clm01'];
198 $f_claim_data[3] = $claim_ar['status'];
199 $f_claim_data[4] = $claim_ar['batch_name'];
200 $f_claim_data[5] = $claim_ar['dpr_name'];
201 $f_claim_data[6] = $claim_ar['payer_name'];
203 return $f_claim_data;
208 * parse dpr file into an array
210 * @uses ibr_ebr_ebt_name()
211 * @param array the array from csv_ebr_filetoarray()
212 * @param string the file path
213 * @return array
215 function ibr_dpr_values ( $ar_dpr_fields, $dpr_filepath) {
216 // the .dpr file is one DPR line for each batch file
217 // followed by a CST for each patient for that payer in the batch file
219 if ($dpr_filepath) {
220 $fname = basename($dpr_filepath);
221 $dpt_name = ibr_ebr_ebt_name ($fname);
222 } else {
223 csv_edihist_log("ibr_dpr_values: no file path provided");
224 return FALSE;
226 if (!is_array($ar_dpr_fields) && count($ar_dpr_fields) > 0) {
227 csv_edihist_log("ibr_dpr_values: no values array provided");
228 return FALSE;
231 $ar_dpr_clm = array();
233 foreach ( $ar_dpr_fields as $fld ) {
235 if ( $fld[0] == "DPR" ) {
236 $batch_ctrl = $fld[3];
237 $batch_name = $fld[6];
238 continue;
240 if ($fld[0] = "CST" ) {
241 // CST line -- there may be one or more for each DPR line, but we just create a line entry for
242 // each CST line
243 // -- only have a claims_dpr.csv file
245 $ar_pid = preg_split('/\D/', $fld[2], 2, PREG_SPLIT_NO_EMPTY);
246 if ( count($ar_pid) == 2) {
247 $pid = $ar_pid[0];
248 $enctr = $ar_pid[1];
249 } else {
250 $enctr = substr($fld[2], -IBR_ENCOUNTER_DIGIT_LENGTH);
251 $pid = substr($fld[2], 0, strlen($fld[2]) - IBR_ENCOUNTER_DIGIT_LENGTH);
254 $clm01 = $fld[2];
255 $payer_id = $fld[3];
256 $pt_name = $fld[5];
257 $frm_date = $fld[6];
258 $payer_name = $fld[15];
259 // take the fields out of order because the message precedes the status
261 $clm_status = $fld[11]; // Status| "REJ" or "ACK"
263 $msg_txt = "";
264 // DPR_MSG_DELIM is '^' and '^' is a PCRE metacharacter
265 // the DPR layout leaves a lot to be desired, there is no telling what you will get
266 // but it appears to be a distillation of the 277
267 $msg_ar = explode(DPR_MSG_DELIM, $fld[9]);
268 if (is_array($msg_ar) && count($msg_ar)) {
269 for($i=0; $i<count($msg_ar); $i++) {
270 $statuspos = strpos($msg_ar[$i], 'Status:');
271 if ($statuspos) {
272 $msg_txt = substr($msg_ar[$i], $statuspos) . ' ' . substr($msg_ar[$i], 0, $statuspos-1);
273 } else {
274 $msg_txt .= (strpos($msg_ar[$i], '\\') === false) ? $msg_ar[$i] : str_replace('\\', ' ', $msg_ar[$i]);
278 $msg_txt = trim($msg_txt);
280 $clm_ins_id = $fld[12]; // Payer Claim Number|
281 $clm_ins_name = $fld[15]; // Payer Name|
283 //$csv_hd_ar['dpr']['claim'] = array('PtName','SvcDate', 'clm01', 'Status', 'Batch', 'FileName', 'Payer')
284 // add the values to the output array
285 $ar_dpr_clm[] = array(
286 'pt_name' => $pt_name,
287 'date' => $frm_date,
288 'clm01' => $clm01,
289 'status' => $clm_status,
290 'payer_name' => $payer_name,
291 'batch_name' => $batch_name,
292 'dpr_name' => $fname,
293 'dpr_text'=> $dpt_name,
294 'message' => $msg_txt
297 // 'pt_name''date''pid''enctr''ext''status''batch_name''file_text''message'
298 } // end foreach
300 return $ar_dpr_clm;
301 } // end function ibr_dpr_values
305 * Create html table for processing of file
307 * If all claims are accepted then only a message so indicating is shown
309 * @param array data array from ibr_dpr_values()
310 * @param bool only show rejected claims if true
311 * @return string
313 function ibr_dpr_html ($ar_dpr_data, $err_only=FALSE) {
315 $hasclm = FALSE;
316 $str_html = "";
317 $idx = 0;
318 $rj_ct = 0;
319 $ack_ct = 0;
320 // the details table heading
321 $clm_hdg = "<table cols=6 class=\"ibr_dpr\">
322 <thead>
323 <tr>
324 <th>Patient Name</th><th>Date</th><th>Claim</th><th>Account</th>
325 <th>Status</th><th>DPR Name</th><th>BatchFile</th>
326 </tr>
327 <tr>
328 <th colspan=6 align=left>Message</th>
329 </tr>
330 </thead>
331 <tbody>";
332 //'pt_name''date''pid''enctr''ext''status''dpr_name''batch_name''file_text''message'
334 if (is_array($ar_dpr_data) && count($ar_dpr_data) > 0) {
335 // create html output for the claims
336 foreach ($ar_dpr_data as $val) {
338 $idx++;
339 // if $err_only, then only get information on rejected claims
340 // rejected claims will have one or more 3e subarrays
341 if ($val['status'] == 'ACK') { $ack_ct++; }
342 if ($err_only && $val['status'] == 'ACK') { continue; }
344 if ($val['status'] == 'REJ') { $rj_ct++; }
345 $hasclm = TRUE;
346 // alternate row background colors
347 $bgc = ($rj_ct % 2 == 1 ) ? 'odd' : 'even';
349 $clm_html .= "<tr class=\"{$bgc}\">
350 <td>{$val['pt_name']}</td>
351 <td>{$val['date']}</td>
352 <td><a class=\"btclm\" target=\"_blank\" href=\"edi_history_main.php?fvbatch={$val['batch_name']}&btpid={$val['clm01']}\">{$val['clm01']}</a></td>
353 <td><a class=\"clmstatus\" target=\"_blank\" href=\"edi_history_main.php?dprfile={$val['dpr_name']}&dprclm={$val['clm01']}\">{$val['status']}</a></td>
354 <td><a target=\"_blank\" href=\"edi_history_main.php?fvkey={$val['dpr_name']}\">{$val['dpr_name']}</a></td>
355 <td title={$val['payer_id']}>{$val['payer_name']}</td>
356 </tr>
357 <tr class=\"{$bgc}\">
358 <td colspan=6>{$val['message']}</td>
359 </tr>";
360 } // end foreach(($ar_cd as $val)
362 // if there were any claims detailed
363 if ( $hasclm && strlen($clm_html) ) {
364 $str_html .= $clm_hdg . $clm_html;
365 // finish the table and add a <p>
366 $str_html .= "</tbody></table>
367 <p></p>";
368 $str_html .="<p class=dpr_notice>Of $idx dpr claims, there were $rj_ct reported REJ and $ack_ct reported ACK </p>";
369 } else {
370 $str_html .="<p class=dpr_notice>All $idx dpr claims reported ACK (accepted)</p>";
372 } //
374 return $str_html;
379 * main function to process new dpr files
381 * @uses csv_newfile_list()
382 * @uses csv_verify_file()
383 * @uses csv_ebr_filetoarray()
384 * @uses ibr_dpr_values()
385 * @uses csv_write_record()
386 * @uses ibr_dpr_html()
387 * @param array optional files array
388 * @param bool whether to create html output
389 * @param bool whether to only generate output for errors
390 * @return string
392 function ibr_dpr_process_new($files_ar=NULL, $html_out=TRUE, $err_only=TRUE ) {
394 $html_str = "";
395 // get the new files in an array
396 if ( is_array($files_ar) && count($files_ar) ) {
397 $f_list = $files_ar;
398 } else {
399 $f_list = csv_newfile_list('dpr');
402 // see if we got any
403 if ( count($f_list) == 0 ) {
404 if($html_out) {
405 $html_str .= "<p>No new DPR files found.</p>";
406 return $html_str;
407 } else {
408 return false;
410 } else {
411 $fdprcount = count($f_list);
413 // OK, so we have some files
414 $html_str = "";
415 $ar_dpr = array();
416 $chrc = 0;
418 // sort ascending so latest files are last to be output
419 $is_sort = asort($f_list); // returns true on success
422 // Step 2: file data written to csv files
423 // also html string created if $html_out = TRUE
424 foreach ($f_list as $f_name) {
426 $f_path = csv_verify_file($f_name, 'dpr');
427 if ($f_path) {
428 //$ar_dprfld = ibr_ebr_filetoarray($f_path);
429 $ar_dprfld = csv_ebr_filetoarray($f_path);
430 if ($ar_dprfld) {
432 $ar_dprval = ibr_dpr_values ($ar_dprfld, $f_path);
433 // the $ar_dprfld array is array of arrays
434 // one for each CST line, so we append them to our
435 // array for csv and html output
436 foreach($ar_dprval as $cst) {
437 $ar_out[] = $cst;
438 $ar_csv[] = ibr_dpr_csv_claims($cst);
440 } else {
441 $html_str .= "<p>Error: failed to parse $f_name </p>" .PHP_EOL;
442 csv_edihist_log("ibr_dpr_process_new: failed to parse $f_name");
444 } else {
445 $html_str .= "<p>Error: invalid path for $f_name </p>" .PHP_EOL;
446 csv_edihist_log("ibr_dpr_process_new: invalid path for $f_name");
449 //$ar_csv
450 //$chrc += csv_write_record($ar_out, 'dpr', 'claim');
451 $chrc += csv_write_record($ar_csv, 'dpr', 'claim');
453 if ($html_out) {
454 $html_str .= ibr_dpr_html($ar_out, $err_only);
455 } else {
456 $html_str .= "DPR files: processed $fdprcount files <br />".PHP_EOL;
459 return $html_str;
463 /* ******************** EBR/IBR functions ******************** */
466 * locate and retrieve the message for a claim in an ebr or ibr file
468 * @uses csv_verify_file()
469 * @uses csv_ebr_filetoarray()
470 * @param string filename
471 * @param string claim id (pid-encounter) or 'err' for all in file with errors
472 * @return string html formatted paragraph
474 function ibr_ebr_message($ebrfile, $clm01, $batchnm = '') {
475 // a particular encounter may appear more than once in an ibr or ebr file
476 // if it is sent again in a new batch very quickly, depending on how the
477 // clearinghouse aggregated its responses.
478 // Therefore, we need to try and check for batch name match
479 $str_html = '';
481 $ext = substr($ebrfile, -3);
482 $fp = csv_verify_file($ebrfile, $ext, false);
483 if ($fp) {
484 $fname = basename($fp);
485 $ext = strtolower(substr($fname, -4));
486 //$ebr_ar = ibr_ebr_filetoarray ($fp);
487 $ebr_ar = csv_ebr_filetoarray($fp);
488 } else {
489 csv_edihist_log("ibr_ebr_message: file read error $ebrfile");
490 $str_html = "Unable to read file " . basename($ebrfile) . "<br />".PHP_EOL;
491 return $str_html;
493 if (!is_array($ebr_ar) || !count($ebr_ar) ) {
494 csv_edihist_log("ibr_ebr_message: file read error $ebrfile");
495 $str_html = "Unable to read file " . basename($ebrfile) . "<br />".PHP_EOL;
496 return $str_html;
498 $usebatch = ($batchnm) ? true : false;
499 $isbatch = false;
500 $isfound = false;
501 $msgstr = '';
502 foreach($ebr_ar as $fld) {
503 // since true value can match '1'
504 if (strval($fld[0]) === '1') {
505 $btnm = ($ext == '.ibr') ? $fld[15] : $fld[8];
506 if ($usebatch) {
507 $isbatch = ($ext == '.ibr') ? ($fld[15] == $batchnm) : ($fld[8] == $batchnm);
509 continue;
512 if ($fld[0] == '3') {
513 if ($usebatch & !$isbatch) {
514 $isfound = false;
515 continue;
517 $isfound = ($fld[4] == $clm01);
518 if ($clm01 == 'any' || $isfound) {
519 $nm = $fld[1];
520 $pe = $fld[4];
521 $sts = ($ext == '.ibr') ? $fld[11] : '';
523 if ($isfound && $ext == '.ibr' && $sts == 'A') {
525 $msgstr = "<p class='ibrmsg'>".PHP_EOL;
526 $msgstr .= "$nm &nbsp;$pe <br />".PHP_EOL;
527 $msgstr .= "$btnm <br />".PHP_EOL;
528 $msgstr .= "Status: $sts<br />".PHP_EOL;
529 $msgstr .= '</p>'.PHP_EOL;
532 continue;
535 if ($isfound) {
536 // there should be only one of these three possibilities, but maybe more than one 3e
537 if ($fld[0] == '3e') {
538 //3e│Error Initiator│R│Error Code – if available, otherwise NA│Error Message | Loop│Segment ID│Element # ││││Version |
539 // different for older 4010, one less field, so loop gives segment, segment gives element, element is blank
540 $sts = ($ext == '.ebr') ? $fld[2] : $sts;
541 $msgstr .= "<p class='ibrmsg'>".PHP_EOL;
542 $msgstr .= "$nm &nbsp;$pe <br />".PHP_EOL;
543 $msgstr .= "$btnm <br />".PHP_EOL;
544 $msgstr .= "Status: $sts<br />".PHP_EOL;
545 $msgstr .= "Error Initiator: {$fld[1]} Code: {$fld[3]} <br />".PHP_EOL;
546 $msgstr .= "Loop: {$fld[5]} Segment: {$fld[6]} Element: {$fld[7]} <br />".PHP_EOL;
547 $msgstr .= wordwrap($fld[4], 46, "<br />".PHP_EOL);
548 $msgstr .= "</p>".PHP_EOL;
549 } elseif ($fld[0] == '3c') {
550 $sts = ($ext == '.ebr') ? $fld[2] : $sts;
551 $msgstr .= "<p class='ibrmsg'>".PHP_EOL;
552 $msgstr .= "$nm &nbsp;$pe <br />".PHP_EOL;
553 $msgstr .= "$btnm <br />".PHP_EOL;
554 $msgstr .= "Status: $sts<br />".PHP_EOL;
555 $msgstr .= wordwrap($fld[4], 46, '<br />'.PHP_EOL);
556 $msgstr .= '</p>'.PHP_EOL;
557 } elseif ($fld[0] == '3a') {
558 //3a│Bill Type│Allowed Amount│Non-Covered Amount │Deductible Amount │Co-Pay Amount │Co-insurance Amount │Withhold
559 //Amount │Estimated Payment Amount │Patient Liability│Message Code│Message Text││
561 $msgstr .= "<p class='ibrmsg'>".PHP_EOL;
562 $msgstr .= "$nm &nbsp;$pe <br />".PHP_EOL;
563 $msgstr .= "$btnm <br />".PHP_EOL;
564 $msgstr .= "Type: {$fld[1]} <br />".PHP_EOL;
565 $msgstr .= ($fld[2] =='NA') ? "" : "Allowed: {$fld[2]}";
566 $msgstr .= ($fld[8] =='NA') ? "" : " Payment: {$fld[8]}";
567 $msgstr .= ($fld[9] =='NA') ? "<br />".PHP_EOL : " Pt Resp: {$fld[9]} <br />".PHP_EOL;
568 $msgstr .= ($fld[10] =='NA') ? "" : "Code: {$fld[10]} ";
569 $msgstr .= ($fld[11] =='NA') ? "" : wordwrap($fld[11], 46, "<br />".PHP_EOL);
570 $msgstr .= "</p>".PHP_EOL;
572 } elseif ($clm01 == 'any') {
573 if ($usebatch & !$isbatch) { continue; }
575 if ($fld[0] == '3e') {
576 // gather all errors
577 $msgstr .= "<p class='ibrmsg'>".PHP_EOL;
578 $msgstr .= "$nm &nbsp;$pe <br />".PHP_EOL;
579 $msgstr .= "$btnm <br />".PHP_EOL;
580 $msgstr .= "Error Initiator: {$fld[1]} Code: {$fld[3]} <br />".PHP_EOL;
581 $msgstr .= "Loop: {$fld[5]} Segment: {$fld[6]} Element: {$fld[7]} <br />".PHP_EOL;
582 $msgstr .= wordwrap($fld[4], 46, "<br />".PHP_EOL)."<br />".PHP_EOL;
583 $msgstr .= "~~~~~~~~<br />".PHP_EOL;
584 $msgstr .= "</p>".PHP_EOL;
588 } // end foreach($ebr_ar as $fld)
590 $str_html .= $msgstr;
592 if (!$str_html) {
593 $str_html .= "Did not find $clm01 in $fname <br />".PHP_EOL;
595 return $str_html;
600 * parse the ebr file format into an array
602 * The array is indexed in different batch files, indicated by line '1'
603 * So a new line will appear in the csv files table for each line '1'
604 * The structure is:
605 * <pre>
606 * $ar_val[$b]['file']
607 * ['date']['f_name']['clrhsid']['batch']['clm_ct']['clm_rej']['chg_r']
609 * $ar_val[$b]['claims'][$c]
610 * ['pt_name'] ['svcdate']['clm01']['status']['batch']['f_name']['payer']
611 * ['providerid']['prclmnum']['payerid']
612 * -- with ['3c']
613 * ['err_seg']['err_msg']
614 * ['3a']
615 * ['pmt']['msg']
616 * ['3e'][i]
617 * ['err_type']['err_code']['err_msg']['err_loop']['err_seg']['err_elem']
619 * </pre>
621 * @see ibr_ebr_process_new_files()
622 * @uses ibr_ebr_ebt_name()
623 * @uses csv_ebr_filetoarray()
624 * @param string path to ebr file
625 * @return array
627 function ibr_ebr_values($file_path) {
629 // get file information
630 if (is_readable($file_path)) {
631 // string setlocale ( int $category , array $locale ) // may be needed
632 $path_parts = pathinfo($file_path);
633 } else {
634 // error, unable to read file
635 csv_edihist_log("Error, unable to read file $file_path");
636 return FALSE;
638 $path_parts = pathinfo($file_path);
639 //$ebr_dir = $path_parts['dirname'];
640 $ebr_fname = $path_parts['basename'];
641 $ebr_ext = $path_parts['extension'];
643 if ($ebr_ext != 'ebr') {
644 csv_edihist_log("ibr_ebr_values: incorrect file extension $ebr_ext $ebr_fname");
645 return false;
648 $ebr_mtime = date ("Ymd", filemtime($file_path));
650 $ar_val = array();
652 $clm_ct = 0;
653 $rjct_ct = 0;
654 $b = -1;
655 $c = -1;
656 // get file contents transformed to array
657 //$ar_ebr = ibr_ebr_filetoarray ($file_path);
658 $ar_ebr = csv_ebr_filetoarray($file_path);
659 if (!is_array($ar_ebr) || !count($ar_ebr)) {
660 csv_edihist_log("ibr_ibr_values: failed to read $ebr_fname");
661 return false;
664 foreach($ar_ebr as $ln) {
666 if (strval($ln[0]) === '1') {
667 //['ibr']['file'] = array('Date', 'FileName', 'clrhsid', 'claim_ct', 'reject_ct', 'Batch');
668 $b++;
669 $c = -1;
671 if (preg_match('/\d{4}\D\d{2}\D\d{2}/', $ln[1])) {
672 $fdate = preg_replace('/\D/', '', $ln[1]);
673 } else {
674 $fdate = $ebr_mtime;
676 $batch_name = $ln[8];
677 //['date']['f_name']['clrhsid']['batch']['clm_ct']['clm_rej']['chg_r']
678 $ar_val[$b]['file']['date'] = $fdate; // ibr file date
679 $ar_val[$b]['file']['f_name'] = $ebr_fname;
680 $ar_val[$b]['file']['clrhsid'] = $ln[7]; // availity clearinghouse file id
681 $ar_val[$b]['file']['batch'] = $batch_name; // batch file name
683 $clm_ct = 0;
684 $clm_acc = 0;
685 $clm_acc_chg = 0;
686 $clm_rej = 0;
687 $clm_rej_chg = 0;
689 continue;
692 if (strval($ln[0]) == '2') {
693 $payer = $ln[1];
695 $clm_ct += intval($ln[2]);
696 $clm_rej += intval($ln[6]);
697 $clm_rej_chg += floatval($ln[7]);
699 $payerid = $ln[8];
701 $ar_val[$b]['file']['clm_ct'] = $clm_ct; // claim count
702 $ar_val[$b]['file']['clm_rej'] = $clm_rej; // rejected claims count
703 $ar_val[$b]['file']['chg_r'] = $clm_rej_chg; // rejected charges
705 continue;
707 //['pt_name'] ['svcdate']['clm01']['status']['batch']['f_name']['payer'] ['providerid']['prclmnum']['payerid']['3c']['3e']['3a']
708 if (strval($ln[0]) == '3') {
709 //['ibr']['claim'] = array('PtName','SvcDate', 'clm01', 'Status', 'Batch', 'FileName', 'Payer');
710 $c++;
711 $err_ct = -1;
713 $ar_val[$b]['claims'][$c]['pt_name'] = $ln[1];
714 $ar_val[$b]['claims'][$c]['svcdate'] = $ln[2];
715 $ar_val[$b]['claims'][$c]['clm01'] = $ln[4];
716 $ar_val[$b]['claims'][$c]['batch'] = $batch_name;
717 $ar_val[$b]['claims'][$c]['f_name'] = $ebr_fname;
718 $ar_val[$b]['claims'][$c]['payer'] = $payer;
720 $ar_val[$b]['claims'][$c]['providerid'] = $ln[6];
721 $ar_val[$b]['claims'][$c]['prclmnum'] = $ln[8];
722 $ar_val[$b]['claims'][$c]['payerid'] = $payerid;
724 continue;
727 if (strval($ln[0]) == '3c') {
729 $msg = ''; $err_seg = '';
731 if ($ln[2] != 'A' && $ln[3] == 'NA') {
732 $ar_val[$b]['claims'][$c]['status'] = 'A';
733 } else {
734 $ar_val[$b]['claims'][$c]['status'] = $ln[2];
736 //['err_seg']['err_msg']
737 $err_seg .= (strlen($ln[5]) && $ln[5] != 'NA') ? $ln[5].' | ' : '';
738 $err_seg .= (strlen($ln[6]) && $ln[6] != 'NA') ? $ln[6].' | ' : '';
739 $err_seg .= (strlen($ln[7]) && $ln[7] != 'NA') ? $ln[7].' | ' : '';
741 $msg .= (strlen($ln[1]) && $ln[1] != 'NA') ? $ln[1].' ' : '';
742 $msg .= (strlen($ln[2]) && $ln[2] != 'NA') ? 'Type: '.$ln[2].' ' : '';
743 $msg .= (strlen($ln[4]) && $ln[4] != 'NA') ? $ln[4] : '';
745 $ar_val[$b]['claims'][$c]['3c']['err_seg'] = $err_seg;
746 $ar_val[$b]['claims'][$c]['3c']['err_msg'] = $msg;
748 continue;
751 if (strval($ln[0]) == '3e') {
752 $err_ct++;
754 if ($ln[2] != 'R' && $ln[3] != 'NA') {
755 $ar_val[$b]['claims'][$c]['status'] = 'R';
756 } else {
757 $ar_val[$b]['claims'][$c]['status'] = $ln[2];
759 //['err_type']['err_code']['err_msg']['err_loop']['err_seg']['err_elem']
760 $ar_val[$b]['claims'][$c]['3e'][$err_ct]['err_type'] = $ln[1]; // Error Initiator
761 $ar_val[$b]['claims'][$c]['3e'][$err_ct]['err_code'] = $ln[3]; // Error Code or NA
762 $ar_val[$b]['claims'][$c]['3e'][$err_ct]['err_msg'] = $ln[4]; // Error Message
763 $ar_val[$b]['claims'][$c]['3e'][$err_ct]['err_loop'] = $ln[5]; // Loop
764 $ar_val[$b]['claims'][$c]['3e'][$err_ct]['err_seg'] = $ln[6]; // Segment ID
765 $ar_val[$b]['claims'][$c]['3e'][$err_ct]['err_elem'] = $ln[7]; // Element #
767 continue;
770 if (strval($ln[0]) == '3a') {
772 $ar_val[$b]['claims'][$c]['status'] = 'A';
774 $msg = ''; $msg_txt = '';
775 //['pmt']['msg']
776 $msg .= (strlen($ln[1]) && $ln[1] != 'NA') ? 'Bill Type: '.$ln[1] : '';
777 $msg .= (strlen($ln[2]) && $ln[2] != 'NA') ? 'Allowed: '.$ln[2] : '';
778 $msg .= (strlen($ln[3]) && $ln[3] != 'NA') ? 'Non Covered: '.$ln[3] : '';
779 $msg .= (strlen($ln[4]) && $ln[4] != 'NA') ? 'Deductible '.$ln[4] : '';
780 $msg .= (strlen($ln[5]) && $ln[5] != 'NA') ? 'Co-Pay: '.$ln[5] : '';
781 $msg .= (strlen($ln[6]) && $ln[6] != 'NA') ? 'Co-ins: '.$ln[6] : '';
782 $msg .= (strlen($ln[7]) && $ln[7] != 'NA') ? 'Withhold: '.$ln[7] : '';
783 $msg .= (strlen($ln[8]) && $ln[8] != 'NA') ? 'Est Pmt: '.$ln[8] : '';
784 $msg .= (strlen($ln[9]) && $ln[9] != 'NA') ? 'Pt Rsp: '.$ln[9] : '';
786 $msg_txt .= (strlen($ln[10]) && $ln[10] != 'NA') ? 'Code: '.$ln[10] : '';
787 $msg_txt .= (strlen($ln[11]) && $ln[11] != 'NA') ? ' '.$ln[11] : '';
789 $ar_val[$b]['claims'][$c]['3a']['pmt'] = $msg;
790 $ar_val[$b]['claims'][$c]['3a']['msg'] = $msg_txt;
794 return $ar_val;
799 * parse the ibr file format into an array
801 * Very similar to ibr_ebr_values(), with slight differences
802 * The array is indexed in different batch files, indicated by line '1'.
803 * So a new line will appear in the csv files table for each line '1'.
804 * The structure is:
805 * <pre>
806 * $ar_val[$b]['file']
807 * ['date']['f_name']['clrhsid']['batch']['clm_ct']['clm_rej']['chg_r']
809 * $ar_val[$b]['claims'][$c]
810 * ['pt_name'] ['svcdate']['clm01']['status']['batch']['f_name']['payer']
811 * ['providerid']['bht03']['payerid']
812 * -- with ['3e'][i]
813 * ['err_type']['err_code']['err_msg']['err_loop']['err_seg']['err_elem']
815 * </pre>
817 * @see ibr_ebr_process_new_files()
818 * @uses ibr_ebr_ebt_name()
819 * @uses csv_ebr_filetoarray()
820 * @param string path to ibr file
821 * @return array
823 function ibr_ibr_values($file_path) {
825 // get file information
826 if (is_readable($file_path)) {
827 // string setlocale ( int $category , array $locale ) // may be needed
828 $path_parts = pathinfo($file_path);
829 } else {
830 // error, unable to read file
831 csv_edihist_log("ibr_ibr_values: Error, unable to read file $file_path");
832 return FALSE;
834 $path_parts = pathinfo($file_path);
835 //$ibr_dir = $path_parts['dirname'];
836 $ibr_fname = $path_parts['basename'];
837 $ibr_ext = $path_parts['extension'];
839 if ($ibr_ext != 'ibr') {
840 csv_edihist_log("ibr_ibr_values: incorrect file extension $ibr_ext $ibr_fname");
841 return false;
844 $ibr_mtime = date ("Ymd", filemtime($file_path));
846 $ar_ih = array();
848 //$clm_ct = 0;
849 //$rjct_ct = 0;
850 $b = -1;
851 //$p = -1;
852 $c = -1;
853 // get file contents transformed to array
854 //$ar_ibr = ibr_ebr_filetoarray ($file_path);
855 $ar_ibr = csv_ebr_filetoarray($file_path);
856 if (!is_array($ar_ibr) || !count($ar_ibr)) {
857 csv_edihist_log("ibr_ibr_values: failed to read $ibr_fname");
858 return false;
861 foreach($ar_ibr as $ln) {
863 if (strval($ln[0]) === '1') {
864 //['ibr']['file'] = array('Date', 'FileName', 'clrhsid', 'claim_ct', 'reject_ct', 'Batch');
865 $b++;
866 $c = -1;
868 $batch_name = $ln[15];
869 $batch_ctl = $ln[5];
871 if (preg_match('/\d{4}\D\d{2}\D\d{2}/', $ln[1])) {
872 $fdate = preg_replace('/\D/', '', $ln[1]);
873 } else {
874 $fdate = $ibr_mtime;
876 $ar_ih[$b]['file']['date'] = $fdate; // ibr file date
877 $ar_ih[$b]['file']['f_name'] = $ibr_fname;
878 $ar_ih[$b]['file']['btctln'] = $ln[5]; // batch control number [ISA13]
879 $ar_ih[$b]['file']['clm_ct'] = $ln[6]; // claim count
880 //$ar_ih[$b]['file']['chg_s'] = $ln[8]; // submitted charges total [CLM02 ?]
881 $ar_ih[$b]['file']['clm_rej'] = $ln[10]; // rejected claims count
882 $ar_ih[$b]['file']['chg_r'] = $ln[11]; // rejected charges
883 $ar_ih[$b]['file']['clrhsid'] = $ln[14]; // availity clearinghouse file id
884 $ar_ih[$b]['file']['batch'] = $ln[15]; // batch file name
886 continue;
889 if (strval($ln[0]) == '2') {
890 $payer = $ln[1];
891 $payerid = $ln[8];
893 continue;
895 //['pt_name'] ['svcdate']['clm01']['status']['batch']['filename']['payer'] ['providerid']['bht03']['payerid']
896 if (strval($ln[0]) == '3') {
897 //['ibr']['claim'] = array('PtName','SvcDate', 'clm01', 'Status', 'Batch', 'FileName', 'Payer');
898 $c++;
899 $err_ct = -1;
901 $ar_ih[$b]['claims'][$c]['pt_name'] = $ln[1];
902 $ar_ih[$b]['claims'][$c]['svcdate'] = $ln[2];
903 $ar_ih[$b]['claims'][$c]['clm01'] = $ln[4];
904 $ar_ih[$b]['claims'][$c]['status'] = $ln[11];
905 $ar_ih[$b]['claims'][$c]['batch'] = $batch_name;
906 $ar_ih[$b]['claims'][$c]['f_name'] = $ibr_fname;
907 $ar_ih[$b]['claims'][$c]['payer'] = $payer;
909 $ar_ih[$b]['claims'][$c]['providerid'] = $ln[6];
910 $ar_ih[$b]['claims'][$c]['bht03'] = (strlen($ln[10]) >= 9) ? $ln[10] : $batch_ctl;
911 $ar_ih[$b]['claims'][$c]['payerid'] = $payerid;
913 continue;
916 if (strval($ln[0]) == "3e") {
917 // increment error count -- more than one error is possible
918 // ibr files have a 3e only in error case, no 3a or 3c
919 $err_ct++;
921 $ar_ih[$b]['claims'][$c]['3e'][$err_ct]['err_type'] = $ln[1]; // Error Initiator
922 $ar_ih[$b]['claims'][$c]['3e'][$err_ct]['err_code'] = $ln[3]; // Error Code or NA
923 $ar_ih[$b]['claims'][$c]['3e'][$err_ct]['err_msg'] = $ln[4]; // Error Message
924 $ar_ih[$b]['claims'][$c]['3e'][$err_ct]['err_loop'] = $ln[5]; // Loop
925 $ar_ih[$b]['claims'][$c]['3e'][$err_ct]['err_seg'] = $ln[6]; // Segment ID
926 $ar_ih[$b]['claims'][$c]['3e'][$err_ct]['err_elem'] = $ln[7]; // Element #
928 continue;
930 } // end foreach
932 return $ar_ih;
937 * Create html table for displaying processing results
939 * @param array $ar_data array produced by function ibr_ebr_data_ar
940 * @param $err_only boolean ignore claim information if no 3e subarray is in the claim data
941 * @return string
943 function ibr_ebr_html ($ar_data, $err_only=false) {
944 // create an html string for a table to display in a web page
946 $idx = 0;
947 $idf = 0;
948 $has3 = false;
949 $hasclm = false;
950 $clm_html = "";
951 $str_html = "";
953 $dtl = ($err_only) ? "Errors only" : "All included claims";
955 // the table heading for files
956 $f_hdg = "<table cols=5 class=\"ibr_ebr\">
957 <caption>IBR-EBR Files Summary {$dtl} </caption>
958 <thead>
959 <tr>
960 <th>IBR-EBR File</th><th>Date</th>
961 <th>Batch</th><th>Claims</th><th>Rej</th>
962 </tr>
963 </thead>
964 <tbody>".PHP_EOL;
966 // the details table heading
967 $clm_hdg = "<table cols=5 class=\"ibr_ebr\">
968 <thead>
969 <tr>
970 <th>Patient Name</th><th>Date</th><th>CtlNum</th>
971 <th>Status</th><th>Payer Name</th>
972 </tr>
973 <tr>
974 <th>Type|Code|Loop|Segment|Field</th><th colspan=4>Message</th>
975 </tr>
976 </thead>
977 <tbody>".PHP_EOL;
979 // start with the table heading
980 $str_html .= $f_hdg;
982 foreach ($ar_data as $ardt) {
983 // alternate colors
984 $bgf = ($idf % 2 == 1 ) ? 'fodd' : 'feven';
985 $idf++;
987 $ar_hd = isset($ardt['file']) ? $ardt['file'] : NULL ;
988 $ar_cd = isset($ardt['claims']) ? $ardt['claims'] : NULL ;
990 if (!$ar_hd && !$ar_cd) {
991 $str_html .= "ibr_ebr_html: empty array or wrong keys <br />" . PHP_EOL;
992 continue;
994 // if we had a claim detail in last pass, we need to append the files heading
995 if ($hasclm) { $str_html .= $f_hdg; }
997 // if any individual claims detail is to be output this will be set true
998 $clm_html = "";
999 $has3 = FALSE;
1000 $hasclm = FALSE;
1001 //['date']['f_name']['availid']['batch']['clm_acc']['chg_s']['clm_rej']['chg_r']
1002 $str_html .= "<tr class=\"{$bgf}\">" .PHP_EOL;
1003 $str_html .= "<td>{$ar_hd['date']}</td>
1004 <td><a target=\"_blank\" href=\"edi_history_main.php?fvkey={$ar_hd['f_name']}\">{$ar_hd['f_name']}</a> <a target=\"_blank\" href=\"edi_history_main.php?fvkey={$ar_hd['f_name']}&readable=yes\">Text</a></td>
1005 <td><a target=\"_blank\" href=\"edi_history_main.php?fvkey={$ar_hd['batch']}\">{$ar_hd['batch']}</a></td>
1006 <td>{$ar_hd['clm_ct']}</td>
1007 <td>{$ar_hd['clm_rej']}</td>".PHP_EOL;
1008 $str_html .= "</tr>" .PHP_EOL;
1009 // now the individual claims details
1010 //['pt_name'] ['svcdate']['clm01']['status']['batch']['filename']['payer'] ['providerid']['bht03']['payerid']
1011 if ($ar_cd) {
1012 // create html output for the claims
1013 foreach ($ar_cd as $val) {
1014 // if $err_only, then only get information on claims with 3e
1015 if ($err_only && !array_key_exists("3e", $val) ) { continue; }
1017 // alternate row background colors
1018 $bgc = ($idx % 2 == 1 ) ? 'odd' : 'even';
1019 $idx++;
1020 // since we are here, we have claim details in the output
1021 $hasclm = TRUE;
1023 $clm_html .= "<tr class=\"{$bgc}\">
1024 <td>{$val['pt_name']}</td>
1025 <td>{$val['svcdate']}</td>
1026 <td><a class=\"btclm\" target=\"_blank\" href=\"edi_history_main.php?fvbatch={$val['batch']}&btpid={$val['clm01']}\">{$val['clm01']}</a></td>
1027 <td><a class=\"clmstatus\" target=\"_blank\" href=\"edi_history_main.php?ebrfile={$val['f_name']}&ebrclm={$val['clm01']}\">{$val['status']}</a></td>
1028 <td title=\"{$val['payerid']}\">{$val['payer']}</td>
1029 </tr>";
1030 if (array_key_exists("3e", $val)) {
1031 // there may be more than one error reported
1032 foreach ($val['3e'] as $er) {
1033 $clm_html .= "<tr class=\"{$bgc}\">".PHP_EOL;
1034 $clm_html .= "<td>{$er['err_type']}&nbsp;{$er['err_code']}&nbsp;{$er['err_loop']}&nbsp;{$er['err_seg']}&nbsp;{$er['err_elem']}</td>
1035 <td colspan=4>{$er['err_msg']}</td>
1036 </tr>".PHP_EOL;
1037 } // end foreach ($val['3e'] as $er)
1038 } elseif (array_key_exists("3a", $val)) {
1039 $clm_html .= "<tr class=\"{$bgc}\">
1040 <td>{$val['3a']['msg']}</td><td colspan=4>{$val['3a']['msg_txt']}</td>
1041 </tr>".PHP_EOL;
1042 } elseif (array_key_exists("3c", $val)) {
1043 $clm_html .= "<tr class=\"{$bgc}\">
1044 <td>{$val['3c']['err_seg']}</td><td colspan=4>{$val['3c']['err_msg']}</td>
1045 </tr>".PHP_EOL;
1048 } // end foreach(($ar_cd as $val)
1050 // if there were any claims detailed
1051 if ( $hasclm && strlen($clm_html) ) {
1052 $str_html .= "</tbody>".PHP_EOL;
1053 $str_html .= $clm_hdg . $clm_html;
1055 } // end if ($ar_cd)
1056 } // end foreach ($ar_data as $ardt)
1058 // finish the table
1059 $str_html .= "</tbody></table>".PHP_EOL;
1061 return $str_html;
1065 * order array of file information for csv table
1067 * @param array file array created elswhere
1068 * @return array
1070 function ibr_ebr_csv_files($head_ar) {
1071 // the file record csv file
1072 //['ebr']['file'] = array('Date', 'FileName', 'clrhsid', 'claim_ct', 'reject_ct', 'Batch');
1073 $f_file_data = array();
1074 $f_file_data[0] = $head_ar['date'];
1075 $f_file_data[1] = $head_ar['f_name'];
1076 // put file id as column 2 $f_file_data[2] = $head_ar['availid']
1077 $f_file_data[2] = $head_ar['clrhsid'];
1078 $f_file_data[3] = $head_ar['clm_ct'];
1079 $f_file_data[4] = $head_ar['clm_rej'];
1080 $f_file_data[5] = $head_ar['batch'];
1082 return $f_file_data;
1087 * order the claim data array for csv file
1089 * @param array individual claim array
1090 * @return array
1092 function ibr_ebr_csv_claims($claim_ar) {
1094 $f_claim_data = array();
1095 //['ebr']['claim'] = array('PtName','SvcDate', 'clm01', 'Status', 'Batch', 'FileName', 'Payer')
1096 $f_claim_data[0] = $claim_ar['pt_name'];
1097 $f_claim_data[1] = $claim_ar['svcdate'];
1098 $f_claim_data[2] = $claim_ar['clm01'];
1099 $f_claim_data[3] = $claim_ar['status'];
1100 $f_claim_data[5] = $claim_ar['batch'];
1101 $f_claim_data[6] = $claim_ar['f_name'];
1102 $f_claim_data[4] = $claim_ar['payer'];
1104 return $f_claim_data;
1109 * the main function for ebr and ibr files in this script
1111 * @uses csv_newfile_list()
1112 * @uses csv_verify_file()
1113 * @uses csv_write_record()
1114 * @uses ibr_ebr_values()
1115 * @uses ibr_ibr_values()
1116 * @uses ibr_ebr_csv_files()
1117 * @uses ibr_ebr_csv_claims()
1118 * @param array optional array of filenames or null
1119 * @param string $extension one of ibr, or ebr; default is ibr
1120 * @param bool $html_out true or false whether html output string should be created and returned
1121 * @param bool $err_only true or false whether html output shows files and only errors or all claims
1122 * @return string|bool html output string or boolean
1124 function ibr_ebr_process_new_files($files_ar=NULL, $extension='ibr', $html_out=TRUE, $err_only=TRUE ) {
1126 // process new ebr or ibr files by calling the functions in this script
1127 // three optional arguments to be passed to functions and used within
1129 $html_str = "";
1130 $f_list = array();
1131 // patterned from ibr_batch_read.php
1132 if ( $files_ar === NULL || !is_array($files_ar) || count($files_ar) == 0) {
1133 $f_new = csv_newfile_list($extension);
1134 } elseif ( is_array($files_ar) && count($files_ar) ) {
1135 $f_new = $files_ar;
1138 if ( count($f_new) == 0 ) {
1139 if($html_out) {
1140 $html_str .= "<p>IBR/EBR files: no new $extension files <br />";
1141 return $html_str;
1142 } else {
1143 return false;
1146 // we have some new files
1147 // verify and get complete path
1148 foreach($f_new as $fbt) {
1149 $fp = csv_verify_file($fbt, $extension, false);
1150 if ($fp) {
1151 $f_list[] = $fp;
1152 } else {
1153 $html_str .= "verification failed for $fbt <br />".PHP_EOL;
1154 csv_edihist_log("ibr_ebr_process_new_files: verification failed for $fbt");
1157 $fibrcount = count($f_list);
1159 // initialize variables
1160 $data_ar = array();
1161 $wf = array();
1162 $wc = array();
1163 $chrf = 0;
1164 $chrc = 0;
1165 $idx = 0;
1167 // sort ascending so latest files are last to be output
1168 $is_sort = asort($f_list); // returns true on success
1170 // Step 2: file data written to csv files
1171 // also html string created if $html_out = TRUE
1172 foreach ($f_list as $f_name) {
1173 // get the data array for the file
1175 // verify extension
1176 if (substr($f_name, -3) != $extension) {
1177 csv_edihist_log("ibr_ebr_process_new_files: type mismatch $extension " . basename($f_name));
1178 continue;
1181 if ($extension == 'ibr') {
1182 $data_vals = ibr_ibr_values($f_name);
1183 } elseif ($extension == 'ebr') {
1184 $data_vals = ibr_ebr_values($f_name);
1185 } else {
1186 csv_edihist_log("ibr_ebr_process_new_files: incorrect extension $ext " . basename($f_name));
1187 continue;
1190 if (is_array($data_vals) && count($data_vals)) {
1191 foreach($data_vals as $dm) {
1192 $wf[] = ibr_ebr_csv_files($dm['file']);
1193 foreach($dm['claims'] as $cl) {
1194 // array for csv
1195 $wc[] = ibr_ebr_csv_claims($cl);
1197 $data_ar[$idx]['file'] = $dm['file'];
1198 $data_ar[$idx]['claims'] = $dm['claims'];
1199 $idx++;
1204 $chrf += csv_write_record($wf, $extension, "file");
1205 $chrc += csv_write_record($wc, $extension, "claim");
1207 if ($html_out) {
1208 $html_str .= ibr_ebr_html ($data_ar, $err_only);
1209 } else {
1210 $html_str .= "IBR/EBR files: processed $fibrcount $extension files <br />".PHP_EOL;
1212 return $html_str;
1217 * generate output as if file is being processed
1219 * @param string filename
1220 * @param bool display errors only
1221 * @return string
1223 function ibr_ebr_filetohtml($filepath, $err_only=false) {
1224 // simply create an html output for the file
1225 $html_str = "";
1226 $data_ar = array();
1227 $fp = false;
1228 $ext = substr($filepath, -3);
1229 if ( strpos('|ibr|ebr', $ext) ) {
1230 $fp = csv_verify_file( $filepath, "ebr");
1233 if ($fp) {
1234 if ($ext == 'ebr') {
1235 $data_ar = ibr_ebr_values($fp);
1236 } elseif ($ext == 'ibr') {
1237 $data_ar = ibr_ibr_values($fp);
1238 } else {
1239 csv_edihist_log ("ibr_ebr_filetohtml: invalid extension $ext " . basename($fp) );
1240 return "<p>invalid extension $ext </p>".PHP_EOL;
1243 $html_str .= ibr_ebr_html ($data_ar, $err_only);
1244 } else {
1245 csv_edihist_log ("ibr_ebr_filetohtml: verification failed $filepath");
1246 $html_str .= "Error, validation failed $filepath <br />";
1249 return $html_str;