Improvements in the translation table building script, take 2.
[openemr.git] / library / edihistory / ibr_271_read.php
blob56fbd54566e31f8d40ac835ffa4c80571bd9f0e4
1 <?php
2 /**
3 * ibr_271_read.php
4 *
5 * This program is distributed in the hope that it will be useful,
6 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8 * GNU General Public License for more details.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 3 or later. You should have
13 * received a copy of the GNU General Public License along with this program;
14 * if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * <http://opensource.org/licenses/gpl-license.php>
18 * Strictly pre-alpha script to read x12 271 eligibility inquiry response files
20 * @author Kevin McCormick
21 * @link: http://www.open-emr.org
22 * @package OpenEMR
23 * @subpackage ediHistory
25 /* ********************
26 from http://www.faima.com/edi_4010/ts271.htm
28 These are version 4010, but still informative
30 270 Eligibility, Coverage or Benefit Inquiry
31 FUNCTIONAL GROUP = HS
33 This Draft Standard for Trial Use contains the format and establishes the data contents
34 of the Eligibility, Coverage or Benefit Inquiry Transaction Set (270) for use within the
35 context of an Electronic Data Interchange (EDI) environment. This transaction set can be
36 used to inquire about the eligibility, coverages or benefits associated with a benefit plan,
37 employer, plan sponsor, subscriber or a dependent under the subscriber's policy.
38 The transaction set is intended to be used by all lines of insurance such as Health,
39 Life, and Property and Casualty.
42 Table 1
44 0010 ST Transaction Set Header M 1
45 0020 BHT Beginning of Hierarchical Transaction M 1
47 Table 2
49 ---- LOOP ID - 2000 ----------------------------- >1-----------+
50 0010 HL Hierarchical Level M 1 |
51 N 0020 TRN Trace O 9 |
52 ---- LOOP ID - 2100 ----------------------------- >1----------+|
53 0030 NM1 Individual or Organizational Name M 1 ||
54 0040 REF Reference Identification O 9 ||
55 0050 N2 Additional Name Information O 1 ||
56 0060 N3 Address Information O 1 ||
57 0070 N4 Geographic Location O 1 ||
58 0080 PER Administrative Communications Contact O 3 ||
59 0090 PRV Provider Information O 1 ||
60 0100 DMG Demographic Information O 1 ||
61 0110 INS Insured Benefit O 1 ||
62 0120 DTP Date or Time or Period O 9 ||
63 ---- LOOP ID - 2110 ----------------------------- 99---------+||
64 0130 EQ Eligibility or Benefit Inquiry O 1 |||
65 0135 AMT Monetary Amount O 2 |||
66 0140 VEH Vehicle Information O 1 |||
67 0150 PDR Property Description - Real O 1 |||
68 0160 PDP Property Description - Personal O 1 |||
69 0170 III Information O 10 |||
70 0190 REF Reference Identification O 1 |||
71 0200 DTP Date or Time or Period O 9---------+++
72 0210 SE Transaction Set Trailer M 1
75 Notes:
76 2/020 If the Eligibility, Coverage or Benefit Inquiry Transaction Set (270) includes
77 a TRN segment, then the Eligibility, Coverage or Benefit Information
78 Transaction Set (271) must return the trace number identified in the TRN
79 segment.
84 271 Eligibility, Coverage or Benefit Information
85 FUNCTIONAL GROUP = HB
87 This Draft Standard for Trial Use contains the format and establishes the data contents
88 of the Eligibility, Coverage or Benefit Information Transaction Set (271) for use within
89 the context of an Electronic Data Interchange (EDI) environment. This transaction set can
90 be used to communicate information about or changes to eligibility, coverage or benefits
91 from information sources (such as - insurers, sponsors, payors) to information receivers
92 (such as - physicians, hospitals, repair facilities, third party administrators,
93 governmental agencies). This information includes but is not limited to: benefit status,
94 explanation of benefits, coverages, dependent coverage level, effective dates, amounts
95 for co-insurance, co-pays, deductibles, exclusions and limitations.
98 Table 1
100 0010 ST Transaction Set Header M 1
101 0020 BHT Beginning of Hierarchical Transaction M 1
103 Table 2
105 ---- LOOP ID - 2000 ----------------------------- >1-----------+
106 0010 HL Hierarchical Level M 1 |
107 N 0020 TRN Trace O 9 |
108 0025 AAA Request Validation O 9 |
109 ---- LOOP ID - 2100 ----------------------------- >1----------+|
110 0030 NM1 Individual or Organizational Name O 1 ||
111 0040 REF Reference Identification O 9 ||
112 0050 N2 Additional Name Information O 1 ||
113 0060 N3 Address Information O 1 ||
114 0070 N4 Geographic Location O 1 ||
115 0080 PER Administrative Communications Contact O 3 ||
116 0085 AAA Request Validation O 9 ||
117 0090 PRV Provider Information O 1 ||
118 0100 DMG Demographic Information O 1 ||
119 0110 INS Insured Benefit O 1 ||
120 0120 DTP Date or Time or Period O 9 ||
121 ---- LOOP ID - 2110 ----------------------------- >1---------+||
122 0130 EB Eligibility or Benefit Information O 1 |||
123 0135 HSD Health Care Services Delivery O 9 |||
124 0140 REF Reference Identification O 9 |||
125 0150 DTP Date or Time or Period O 20 |||
126 0160 AAA Request Validation O 9 |||
127 0170 VEH Vehicle Information O 1 |||
128 0180 PID Product/Item Description O 1 |||
129 0190 PDR Property Description - Real O 1 |||
130 0200 PDP Property Description - Personal O 1 |||
131 0210 LIN Item Identification O 1 |||
132 0220 EM Equipment Characteristics O 1 |||
133 0230 SD1 Safety Data O 1 |||
134 0240 PKD Packaging Description O 1 |||
135 0250 MSG Message Text O 10 |||
136 ---- LOOP ID - 2115 ----------------------------- >1--------+|||
137 0260 III Information O 1 ||||
138 0270 DTP Date or Time or Period O 5 ||||
139 0280 AMT Monetary Amount O 5 ||||
140 0290 PCT Percent Amounts O 5 ||||
141 ---- LOOP ID - 2117 ----------------------------- >1-------+||||
142 0300 LQ Industry Code O 1 |||||
143 0310 AMT Monetary Amount O 5 |||||
144 0320 PCT Percent Amounts O 5-------++|||
145 0330 LS Loop Header O 1 |||
146 ---- LOOP ID - 2120 ----------------------------- 1--------+|||
147 0340 NM1 Individual or Organizational Name O 1 ||||
148 0350 N2 Additional Name Information O 1 ||||
149 0360 N3 Address Information O 1 ||||
150 0370 N4 Geographic Location O 1 ||||
151 0380 PER Administrative Communications Contact O 3 ||||
152 0390 PRV Provider Information O 1--------+|||
153 0400 LE Loop Trailer O 1---------+++
154 0410 SE Transaction Set Trailer M 1
157 Notes:
158 2/020 If the Eligibility, Coverage or Benefit Inquiry Transaction Set (270) includes
159 a TRN segment, then the Eligibility, Coverage or Benefit Information
160 Transaction Set (271) must return the trace number identified in the TRN
161 segment.
164 Rendered layout
165 * loop 2000A
166 * | Payer Name | Payer ID | Payer Contact |
167 * loop 2000B (omit or append to 2000A)
168 * | Provider Name | Provider ID | Provider Contact |
169 * loop 2000C/2000D
170 * | Subscriber Name | Date of Birth | Sex | Street, City, Postal
171 * | Policy ID | Group Number | Effective Date | Coverage | Primary? | Waiting Period Pre-existing?
172 * foreach(EB as b) -- then b['EB01'] b['EB02'], etc.
173 * | EB01=A : Co-Ins | EB02=IND : individual only | EB03=[repetitions - service type] : Professional (Physician) Visit - Office, etc.
174 * | EB04=MB : Medicare Part B | EB05='product or plan name' | EB06=27 : Visit | EB07='' : co-pay not specified | EB08=20 : 20% Co-Ins
178 ***************** */
179 // need entity identifier code
181 function ibr_271_codes($segment_id, $code) {
183 $code271 = array();
184 // AAA rejection reasons
185 $code271['AAA'] = array(
186 '15'=>'Required application data missing',
187 '35'=>'Out of Network',
188 '41'=>'Authorization/Access restrictions',
189 '43'=>'Invalid/Missing provider information',
190 '44'=>'Invalid/Missing provider name',
191 '45'=>'Invalid/Missing provider speciality',
192 '46'=>'Invalid/Missing provider phone number',
193 '47'=>'Invalid/Missing provider state',
194 '48'=>'Invalid/Missing referring provider identification number',
195 '49'=>'Provider is not primary care physician',
196 '50'=>'Provider ineligible for inquiries',
197 '51'=>'Provider not on file',
198 '52'=>'Service dates not within provider plan enrollment',
199 '56'=>'Inappropriate date',
200 '57'=>'Invalid/Missing dates of service',
201 '58'=>'Invalid/Missing date of birth',
202 '60'=>'Date of birth follows date of service',
203 '61'=>'Date of death preceeds dates of service',
204 '62'=>'Date of service not within allowable inquiry period',
205 '63'=>'Date of service in future',
206 '71'=>'Patient birth date does not match that for the parient in the database',
207 '72'=>'Invalid/Missing subscriber/insured ID',
208 '73'=>'Invalid/Missing subscriber/insured name',
209 '74'=>'Invalid/Missing subscriber/insured gender code',
210 '75'=>'Subscriber/Insured not found',
211 '76'=>'Duplicate Subscriber/Insured ID number',
212 '78'=>'Subscriber/Insured not in Group/Plan identified',
213 '79'=>'Invalid participant identification',
214 '97'=>'invalid or missing provider address',
215 'T4'=>'Payer name or identifier missing',
216 '80'=>'No response received by clearinghouse',
217 'C'=>'Please correct and resubmit',
218 'N'=>'Resubmission not allowed',
219 'P'=>'Please resubmit original transaction',
220 'R'=>'Resubmission allowed',
221 'S'=>'Do not resubmit; Inquiry initiated to a third party',
222 'W'=>'Please wait 30 days and resubmit',
223 'X'=>'Please wait 10 days and resubmit',
224 'Y'=>'Do not resubmit; We will hold your request and respond again shortly'
228 // provider PRV codes
229 $code271['PRV'] = array(
230 'AD'=>'Admitting',
231 'AT'=>'Attending',
232 'BI'=>'Billing',
233 'CO'=>'Consulting',
234 'CV'=>'Covering',
235 'H'=>'Hospital',
236 'HH'=>'Home Health Care',
237 'LA'=>'Laboratory',
238 'OT'=>'Other Physician',
239 'P1'=>'Pharmacy',
240 'PC'=>'Primary Care Physician',
241 'PE'=>'Performing',
242 'R'=>'Rural Health Clinic',
243 'RF'=>'Referring',
244 'SB'=>'Sunmitting',
245 'SK'=>'Skilled Nursing Facility',
246 'SU'=>'Supervising'
249 //REF codes
250 $code271['REF'] = array(
251 '18'=>'Plan Number',
252 '1L'=>'Group or Policy number',
253 '1W'=>'Member identification number',
254 '3H'=>'Case number',
255 '49'=>'Family unit number',
256 '6P'=>'Group number',
257 'CE'=>'Class of contract code',
258 'CT'=>'Provider contract number',
259 'EA'=>'Medical record identification number',
260 'EJ'=>'Patient account number',
261 'F6'=>'Health insurance claim (HIC) number',
262 'GH'=>'Identification card serial number',
263 'HJ'=>'Identity card number',
264 'IF'=>'Issue number',
265 'IG'=>'Insurance policy number',
266 'N6'=>'Plan network identification number',
267 'NQ'=>'Medicaid recipient identification number',
268 'Q4'=>'Prior identifier number',
269 'SY'=>'Social security number',
270 'Y4'=>'Agency claim number'
273 // DTP date qualifiers
274 $code271['DTP'] = array(
275 '096'=>'Discharge',
276 '102'=>'Issue',
277 '152'=>'Effective date of change',
278 '291'=>'Plan',
279 '307'=>'Eligibility',
280 '318'=>'Added',
281 '340'=>'COBRA begin',
282 '341'=>'COBRA end',
283 '342'=>'Premium paid to date begin',
284 '343'=>'Premium paid to date end',
285 '346'=>'Plan begin',
286 '347'=>'Plan end',
287 '356'=>'Eligibility begin',
288 '357'=>'Eligibility end',
289 '382'=>'Enrollment',
290 '435'=>'Admission',
291 '442'=>'Date of death',
292 '458'=>'Certification',
293 '472'=>'Service',
294 '539'=>'Policy effective',
295 '540'=>'Policy expiration',
296 '636'=>'Date of last update',
297 '771'=>'Status'
301 //entity identifier code --code source 237
302 $code271['NM101'] = array(
303 '03'=>'Dependent',
304 '13'=>'Contracted Service Provider',
305 '1I'=>'Preferred Provider Organization (PPO)',
306 '1P'=>'Provider',
307 '2B'=>'Third-Party Administrator',
308 '36'=>'Employer',
309 '70'=>'Prior Incorrect Insured',
310 '71'=>'Attending Physician',
311 '72'=>'Operating Physician',
312 '73'=>'Other Physician',
313 '74'=>'Corrected Insured',
314 '75'=>'Participant',
315 'EXS'=>'Ex-spouse',
316 'FA'=>'Facility',
317 'GM'=>'Spouse Insured',
318 'GP'=>'Gateway Provider',
319 'GW'=>'Group',
320 'HF'=>'HPSA Facility',
321 'HH'=>'Home Health Agency',
322 'I3'=>'Independent Physicians Association (IPA)',
323 'IL'=>'Insured or Subscriber',
324 'IR'=>'Self Insured',
325 'LR'=>'Legal Representative',
326 'NZ'=>'Primary Physician',
327 'OC'=>'Origin Carrier',
328 'P2'=>'Primary Insured or Subscriber',
329 'P3'=>'Primary Care Provider',
330 'P4'=>'Prior Insurance Carrier',
331 'P5'=>'Plan Sponsor',
332 'PR'=>'Payer',
333 'SEP'=>'Secondary Payer',
334 'TTP'=>'Tertiary Payer',
335 'VER'=>'Party Performing Verification',
336 'VN'=>'Vendor',
337 'VY'=>'Organization Completing Configuration Change',
338 'X3'=>'Utilization Management Organization',
339 'X4'=>'Spouse',
340 'Y2'=>'Managed Care Organization',
341 'AAG'=>'Ground Ambulance Services',
342 'AAK'=>'Primary Surgeon',
343 'AAL'=>'Medical Nurse',
344 'AAM'=>'Cardiac Rehabilitation Services',
345 'AAN'=>'Skilled Nursing Services',
346 'AAO'=>'Observation Room Services',
347 'AAQ'=>'Anesthesiology Services',
348 'NCT'=>'Name Changed To',
349 'ORI'=>'Original Name',
350 '5T'=>'X-Ray Radiation Therapy Unit',
351 '5U'=>'CT Scanner Unit',
352 '5V'=>'Diagnostic Radioisotope Facility',
353 '5W'=>'Magnetic Resonance Imaging (MRI) Facility',
354 '5X'=>'Ultrasound Unit',
355 '5Y'=>'Rehabilitation Inpatient Unit',
356 '5Z'=>'Rehabilitation Outpatient Services'
359 // Name -- entity relationship code
360 $code271['NM110'] = array(
361 '01'=>'Parent',
362 '02'=>'Child',
363 '27'=>'Domestic Partner',
364 '41'=>'Spouse',
365 '48'=>'Employee',
366 '65'=>'Other',
367 '72'=>'Unknown'
370 // MPI qualifiers
371 // the MPI03 Service affiliation qualifiers have 'SB' prepended
372 $code271['MPI'] = array(
373 'A'=>'Partial',
374 'C'=>'Current',
375 'L'=>'Latest',
376 'O'=>'Oldest',
377 'P'=>'Prior',
378 'S'=>'Second most current',
379 'T'=>'Third most current',
380 'AE'=>'Active reserve',
381 'AO'=>'Active military - overseas',
382 'AS'=>'Academy student',
383 'AT'=>'Presidential appointee',
384 'CC'=>'Contractor',
385 'DD'=>'Dishonorably discharges',
386 'HD'=>'Honorably discharges',
387 'IR'=>'Inactive reserve',
388 'LX'=>'Leave of absence: military',
389 'PE'=>'Plan to enlist',
390 'RE'=>'REcommissioned',
391 'RM'=>'Retired military - overseas',
392 'RR'=>'Retired without recall',
393 'RU'=>'REtired military - USA',
394 'SBA'=>'Air Force',
395 'SBB'=>'Air Force Reserves',
396 'SBC'=>'Army',
397 'SBD'=>'Army Reserves',
398 'SBE'=>'Coast Guard',
399 'SBF'=>'Marine Corps',
400 'SBG'=>'Marine Corps Reserves',
401 'SBH'=>'National Guard',
402 'SBI'=>'Navy',
403 'SBJ'=>'Navy Reserves',
404 'SBK'=>'Other',
405 'SBL'=>'Peace Corp',
406 'SBM'=>'Regular Armed Forces',
407 'SBN'=>'Reserves',
408 'SBO'=>'U.S. Public Health Service',
409 'SBQ'=>'Foreign Military',
410 'SBR'=>'American Red Cross',
411 'SBS'=>'Department of Defvense',
412 'SBU'=>'Unites Services Organization',
413 'SBW'=>'Military Sealift Command',
414 'A1'=>'Admiral',
415 'A2'=>'Airman',
416 'A3'=>'Airman First Class',
417 'B1'=>'Basic Airman',
418 'B2'=>'Brigadier General',
419 'C1'=>'Captain',
420 'C2'=>'Chief Master Sergeant',
421 'C3'=>'Chief Petty Officer',
422 'C4'=>'Chief Warrant',
423 'C5'=>'Colonel',
424 'C6'=>'Commander',
425 'C7'=>'Commodore',
426 'C8'=>'Corporal',
427 'C9'=>'Corporal Specialist 4',
428 'E1'=>'Ensign',
429 'F1'=>'First Lieutenant',
430 'F2'=>'First Sergeant',
431 'F3'=>'First Sergeant-Master Sergeant',
432 'F4'=>'Fleet Admiral',
433 'G1'=>'General',
434 'G4'=>'Gunnery Sergeant',
435 'L1'=>'Lance Corporal',
436 'L2'=>'Lieutenant',
437 'L3'=>'Lieutenant Colonel',
438 'L4'=>'Lieutenant Commander',
439 'L5'=>'Lieutenant General',
440 'L6'=>'Lieutenant Junior Grade',
441 'M1'=>'Major',
442 'M2'=>'Major General',
443 'M3'=>'Master Chief Petty Officer',
444 'M4'=>'Master Gunnery Sergeant Major',
445 'M5'=>'Master Sergeant',
446 'M6'=>'Master Sergeant Specialist 8',
447 'P1'=>'Petty Officer First Class',
448 'P2'=>'Petty Officer Second Class',
449 'P3'=>'Petty Officer Third Class',
450 'P4'=>'Private',
451 'P5'=>'Private First Class',
452 'R1'=>'Rear Admiral',
453 'R2'=>'Recruit',
454 'S1'=>'Seaman',
455 'S2'=>'Seaman Apprentice',
456 'S3'=>'Seaman Recruit',
457 'S4'=>'Second Lieutenant',
458 'S5'=>'Senior Chief Petty Officer',
459 'S6'=>'Senior Master Sergeant',
460 'S7'=>'Sergeant',
461 'S8'=>'Sergeant First Class Specialist 7',
462 'S9'=>'Sergeant Major Specialist 9',
463 'SA'=>'Sergeant Specialist 5',
464 'SB'=>'Staff Sergeant',
465 'SC'=>'Staff Sergeant Specialist 6',
466 'T1'=>'Technical Sergeant',
467 'V1'=>'Vice Admiral',
468 'W1'=>'Warrant Officer'
471 // eligibility or benifit information code
472 $code271['EB01'] = array(
473 '1'=>'Active Coverage',
474 '2'=>'Active - Full Risk Capitation',
475 '3'=>'Active - Services Capitated',
476 '4'=>'Active - Services Capitated to Primary Care Physician',
477 '5'=>'Active - Pending Investigation',
478 '6'=>'Inactive',
479 '7'=>'Inactive - Pending Eligibility Update',
480 '8'=>'Inactive - Pending Investigation',
481 'A'=>'Co-Insurance',
482 'B'=>'Co-Payment',
483 'C'=>'Deductible',
484 'D'=>'Benefit Description',
485 'E'=>'Exclusions',
486 'F'=>'Limitations',
487 'G'=>'Out of Pocket (Stop Loss)',
488 'H'=>'Unlimited',
489 'I'=>'Non-Covered',
490 'J'=>'Cost Containment',
491 'K'=>'Reserve',
492 'L'=>'Primary Care Provider',
493 'M'=>'Pre-existing Condition',
494 'N'=>'Services Restricted to Following Provider',
495 'O'=>'Not Deemed a Medical Necessity',
496 'P'=>'Benefit Disclaimer',
497 'Q'=>'Second Surgical Opinion Required',
498 'R'=>'Other or Additional Payor',
499 'S'=>'Prior Year(s) History',
500 'T'=>'Card(s) Reported Lost/Stolen',
501 'U'=>'Contact Following Entity for Eligibility or Benefit Information',
502 'V'=>'Cannot Process',
503 'W'=>'Other Source of Data',
504 'X'=>'Health Care Facility',
505 'Y'=>'Spend Down',
506 'CB'=>'Coverage Basis',
507 'MC'=>'Managed Care Coordinator'
510 // coverage level code
511 $code271['EB02'] = array(
512 'CHD'=>'Children Only',
513 'DEP'=>'Dependents Only',
514 'E1D'=>'Employee and One Dependent',
515 'E2D'=>'Employee and Two Dependents',
516 'E3D'=>'Employee and Three Dependents',
517 'E5D'=>'Employee and One or More Dependents',
518 'E6D'=>'Employee and Two or More Dependents',
519 'E7D'=>'Employee and Three or More Dependents',
520 'E8D'=>'Employee and Four or More Dependents',
521 'E9D'=>'Employee and Five or More Dependents',
522 'ECH'=>'Employee and Children',
523 'EMP'=>'Employee Only',
524 'ESP'=>'Employee and Spouse',
525 'FAM'=>'Family',
526 'IND'=>'Individual',
527 'SPC'=>'Spouse and Children',
528 'SPO'=>'Spouse Only',
529 'TWO'=>'Two Party'
532 // service type code
533 $code271['EB03'] = array(
534 '1'=>'Medical Care',
535 '2'=>'Surgical',
536 '3'=>'Consultation',
537 '4'=>'Diagnostic X-Ray',
538 '5'=>'Diagnostic Lab',
539 '6'=>'Radiation Therapy',
540 '7'=>'Anesthesia',
541 '8'=>'Surgical Assistance',
542 '10'=>'Blood',
543 '11'=>'Durable Medical Equipment Used',
544 '12'=>'Durable Medical Equipment Purchased',
545 '14'=>'Renal Supplies',
546 '17'=>'Pre-Admission Testing',
547 '18'=>'Durable Medical Equipment Rental',
548 '19'=>'Pneumonia Vaccine',
549 '20'=>'Second Surgical Opinion',
550 '21'=>'Third Surgical Opinion',
551 '22'=>'Social Work',
552 '23'=>'Diagnostic Dental',
553 '24'=>'Periodontics',
554 '25'=>'Restorative',
555 '26'=>'Endodontics',
556 '27'=>'Maxillofacial Prosthetics',
557 '28'=>'Adjunctive Dental Services',
558 '30'=>'Health Benefit Plan Coverage',
559 '32'=>'Plan Waiting Period',
560 '33'=>'Chiropractic',
561 '34'=>'Chiropractic Modality',
562 '35'=>'Dental Care',
563 '36'=>'Dental Crowns',
564 '37'=>'Dental Accident',
565 '38'=>'Orthodontics',
566 '39'=>'Prosthodontics',
567 '40'=>'Oral Surgery',
568 '41'=>'Preventive Dental',
569 '42'=>'Home Health Care',
570 '43'=>'Home Health Prescriptions',
571 '45'=>'Hospice',
572 '46'=>'Respite Care',
573 '47'=>'Hospitalization',
574 '49'=>'Hospital - Room and Board',
575 '54'=>'Long Term Care',
576 '55'=>'Major Medical',
577 '56'=>'Medically Related Transportation',
578 '60'=>'General Benefits',
579 '61'=>'In-vitro Fertilization',
580 '62'=>'MRI Scan',
581 '63'=>'Donor Procedures',
582 '64'=>'Acupuncture',
583 '65'=>'Newborn Care',
584 '66'=>'Pathology',
585 '67'=>'Smoking Cessation',
586 '68'=>'Well Baby Care',
587 '69'=>'Maternity',
588 '70'=>'Transplants',
589 '71'=>'Audiology',
590 '72'=>'Inhalation Therapy',
591 '73'=>'Diagnostic Medical',
592 '74'=>'Private Duty Nursing',
593 '75'=>'Prosthetic Device',
594 '76'=>'Dialysis',
595 '77'=>'Otology',
596 '78'=>'Chemotherapy',
597 '79'=>'Allergy Testing',
598 '80'=>'Immunizations',
599 '81'=>'Routine Physical',
600 '82'=>'Family Planning',
601 '83'=>'Infertility',
602 '84'=>'Abortion',
603 '85'=>'HIV - AIDS Treatment',
604 '86'=>'Emergency Services',
605 '87'=>'Cancer Treatment',
606 '88'=>'Pharmacy',
607 '89'=>'Free Standing Prescription Drug',
608 '90'=>'Mail Order Prescription Drug',
609 '91'=>'Brand Name Prescription Drug',
610 '92'=>'Generic Prescription Drug',
611 '93'=>'Podiatry',
612 '94'=>'Podiatry - Office Visits',
613 '95'=>'Podiatry - Nursing Home Visits',
614 '96'=>'Professional (Physician)',
615 '97'=>'Anesthesiologist',
616 '98'=>'Professional (Physician) Visit - Office',
617 '99'=>'Professional (Physician) Visit - Inpatient',
618 'A0'=>'Professional (Physician) Visit - Outpatient',
619 'A1'=>'Professional (Physician) Visit - Nursing Home',
620 'A2'=>'Professional (Physician) Visit - Skilled Nursing Facility',
621 'A3'=>'Professional (Physician) Visit - Home',
622 'A4'=>'Psychiatric',
623 'A5'=>'Psychiatric - Room and Board',
624 'A6'=>'Psychotherapy',
625 'A7'=>'Psychiatric - Inpatient',
626 'A8'=>'Psychiatric - Outpatient',
627 'A9'=>'Rehabilitation',
628 'AB'=>'Rehabilitation - Inpatient',
629 'AC'=>'Rehabilitation - Outpatient',
630 'AD'=>'Occupational Therapy',
631 'AE'=>'Physical Medicine',
632 'AF'=>'Speech Therapy',
633 'AG'=>'Skilled Nursing Care',
634 'AI'=>'Substance Abuse',
635 'AJ'=>'Alcoholism Treatment',
636 'AK'=>'Drug Addiction',
637 'AL'=>'Optometry',
638 'AM'=>'Frames',
639 'AO'=>'Lenses',
640 'AP'=>'Routine Eye Exam',
641 'AQ'=>'Nonmedically Necessary Physical (e.g. insurance app, pilot license, employment, or school)',
642 'AR'=>'Experimental Drug Therapy',
643 'B1'=>'Burn Care',
644 'B2'=>'Brand Name Prescription Drug - Formulary',
645 'B3'=>'Brand Name Prescription Drug - Non-Formulary',
646 'BA'=>'Independent Medical Evaluation',
647 'BB'=>'Psychiatric Treatment Partial Hospitalization',
648 'BC'=>'Day Care (Psychiatric)',
649 'BD'=>'Cognitive Therapy',
650 'BE'=>'Massage Therapy',
651 'BF'=>'Pulmonary Rehabilitation',
652 'BG'=>'Cardiac Rehabilitation',
653 'BH'=>'Pediatric',
654 'BI'=>'Nursery Room and Board',
655 'BK'=>'Orthopedic',
656 'BL'=>'Cardiac',
657 'BM'=>'Lymphatic',
658 'BN'=>'Gastrointestinal',
659 'BP'=>'Endocrine',
660 'BQ'=>'Neurology',
661 'BR'=>'Eye',
662 'BS'=>'Invasive Procedures',
663 'BT'=>'Gynecological',
664 'BU'=>'Obstetrical',
665 'BV'=>'Obstetrical/Gynecological',
666 'BW'=>'Mail Order Prescription Drug: Brand Name',
667 'BX'=>'Mail Order Prescription Drug: Generic',
668 'BY'=>'Physician Visit - Sick',
669 'BZ'=>'Physician Visit - Well',
670 'C1'=>'Coronary Care',
671 'CA'=>'Private Duty Nursing - Inpatient',
672 'CB'=>'Private Duty Nursing - Home',
673 'CC'=>'Surgical Benefits - Professional (Physician)',
674 'CD'=>'Surgical Benefits - Facility',
675 'CE'=>'Mental Health Provider - Inpatient',
676 'CF'=>'Mental Health Provider - Home',
677 'CG'=>'Mental Health Facility - Inpatient',
678 'CH'=>'Mental Health Facility - Outpatient',
679 'CI'=>'Substance Abuse Facility - Inpatient',
680 'CJ'=>'Substance Abuse Facility - Outpatient',
681 'CK'=>'Screening X-ray',
682 'CL'=>'Screening laboratory',
683 'CM'=>'Mammogram, High Risk Patient',
684 'CN'=>'Mammogram, Low Risk Patient',
685 'CO'=>'Flu Vaccination',
686 'CP'=>'Eyewear and Eyewear Accessories',
687 'CQ'=>'Case Management',
688 'DG'=>'Dermatology',
689 'DM'=>'Durable Medical Equipment',
690 'DS'=>'Diabetic Supplies',
691 'E0'=>'Allied Behavioral Analysis Therapy',
692 'E1'=>'Non-Medical Equipment (non DME)',
693 'E2'=>'Psychiatric Emergency',
694 'E3'=>'Step Down Unit',
695 'E4'=>'Skilled Nursing Facility Head Level of Care',
696 'E5'=>'Skilled Nursing Facility Ventilator Level of Care',
697 'E6'=>'Level of Care 1',
698 'E7'=>'Level of Care 2',
699 'E8'=>'Level of Care 3',
700 'E9'=>'Level of Care 4',
701 'E10'=>'Radiographs',
702 'E11'=>'Diagnostic Imaging',
703 'E12'=>'Basic Restorative - Dental',
704 'E13'=>'Major Restorative - Dental',
705 'E14'=>'Fixed Prosthodontics',
706 'E15'=>'Removable Prosthodontics',
707 'E16'=>'Intraoral Images - Complete Series',
708 'E17'=>'Oral Evaluation',
709 'E18'=>'Dental Prophylaxis',
710 'E19'=>'Panoramic Images',
711 'E20'=>'Sealants',
712 'E21'=>'Flouride Treatments',
713 'E22'=>'Dental Implants',
714 'E23'=>'Temporomandibular Joint Dysfunction',
715 'E24'=>'Retail Pharmacy Prescription Drug',
716 'E25'=>'Long Term Care Pharmacy',
717 'E26'=>'Comprehensive Medication Therapy Management Review',
718 'E27'=>'Targeted Medication Therapy Management Review',
719 'E28'=>'Dietary/Nutritional Services',
720 'EA'=>'Preventive Services',
721 'EB'=>'Specialty Pharmacy',
722 'EC'=>'Durable Medical Equipment New',
723 'ED'=>'CAT Scan',
724 'EE'=>'Ophthalmology',
725 'EF'=>'Contact Lenses',
726 'GF'=>'Generic Prescription Drug - Formulary',
727 'GN'=>'Generic Prescription Drug - Non-Formulary',
728 'GY'=>'Allergy',
729 'IC'=>'Intensive Care',
730 'MH'=>'Mental Health',
731 'NI'=>'Neonatal Intensive Care',
732 'ON'=>'Oncology',
733 'PE'=>'Positron Emission Tomography (PET) Scan',
734 'PT'=>'Physical Therapy',
735 'PU'=>'Pulmonary',
736 'RN'=>'Renal',
737 'RT'=>'Residential Psychiatric Treatment',
738 'SMH'=>'Serious Mental Health',
739 'TC'=>'Transitional Care',
740 'TN'=>'Transitional Nursery Care',
741 'UC'=>'Urgent Care'
744 // insurance type codes
745 $code271['EB04'] = array(
746 'D'=>'Disability',
747 '12'=>'Medicare Secondary Working Aged Beneficiary or Spouse with Employer Group Health Plan',
748 '13'=>'Medicare Secondary End-Stage Renal Disease Beneficiary in the 12 month coordination period with an employer\'s group health plan',
749 '14'=>'Medicare Secondary, No-fault Insurance including Auto is Primary',
750 '15'=>'Medicare Secondary Worker\'s Compensation',
751 '16'=>'Medicare Secondary Public Health Service (PHS)or Other Federal Agency',
752 '41'=>'Medicare Secondary Black Lung',
753 '42'=>'Medicare Secondary Veteran\'s Administration',
754 '43'=>'Medicare Secondary Disabled Beneficiary Under Age 65 with Large Group Health Plan (LGHP)',
755 '47'=>'Medicare Secondary, Other Liability Insurance is Primary',
756 'AP'=>'Auto Insurance Policy',
757 'C1'=>'Commercial',
758 'CO'=>'Consolidated Omnibus Budget Reconciliation Act (COBRA)',
759 'CP'=>'Medicare Conditionally Primary',
760 'DB'=>'Disability Benefits',
761 'EP'=>'Exclusive Provider Organization',
762 'FF'=>'Family or Friends',
763 'GP'=>'Group Policy',
764 'HM'=>'Health Maintenance Organization (HMO)',
765 'HN'=>'Health Maintenance Organization (HMO) - Medicare Risk',
766 'HS'=>'Special Low Income Medicare Beneficiary',
767 'IN'=>'Indemnity',
768 'IP'=>'Individual Policy',
769 'LC'=>'Long Term Care',
770 'LD'=>'Long Term Policy',
771 'LI'=>'Life Insurance',
772 'LT'=>'Litigation',
773 'MA'=>'Medicare Part A',
774 'MB'=>'Medicare Part B',
775 'MC'=>'Medicaid',
776 'MH'=>'Medigap Part A',
777 'MI'=>'Medigap Part B',
778 'MP'=>'Medicare Primary',
779 'OT'=>'Other',
780 'PE'=>'Property Insurance - Personal',
781 'PL'=>'Personal',
782 'PP'=>'Personal Payment (Cash - No Insurance)',
783 'PR'=>'Preferred Provider Organization (PPO)',
784 'PS'=>'Point of Service (POS)',
785 'QM'=>'Qualified Medicare Beneficiary',
786 'RP'=>'Property Insurance - Real',
787 'SP'=>'Supplemental Policy',
788 'TF'=>'Tax Equity Fiscal Responsibility Act (TEFRA)',
789 'WC'=>'Workers Compensation',
790 'WU'=>'Wrap Up Policy'
793 // time period qualifier
794 $code271['EB06'] = array(
795 '1'=>'Month',
796 '2'=>'Year',
797 '6'=>'Hour',
798 '7'=>'Day',
799 '21'=>'Years',
800 '22'=>'Service Year',
801 '23'=>'Calendar Year',
802 '24'=>'Year to Date',
803 '25'=>'Contract',
804 '26'=>'Episode',
805 '27'=>'Visit',
806 '28'=>'Outlier',
807 '29'=>'Remaining',
808 '30'=>'Exceeded',
809 '31'=>'Not Exceeded',
810 '33'=>'Lifetime Remaining',
811 '34'=>'Month',
812 '35'=>'Week',
813 '36'=>'Admission',
814 'A'=>'Hourly Appurtenance Units (Hours of Enhancement/Addition to Equipment)',
815 'D'=>'Daily Time Units',
816 'H'=>'Hourly Time Units',
817 'O'=>'Other Time Units'
820 // quantity type qualifier
821 $code271['EB09'] = array(
822 '8H'=>'Minimum',
823 '99'=>'Quantity Used',
824 'CA'=>'Covered - Actual',
825 'CE'=>'Covered - Estimated',
826 'D3'=>'Number of Co-insurance Days',
827 'DB'=>'Deductible Blood Units',
828 'DY'=>'Days',
829 'HS'=>'Hours',
830 'LA'=>'Life-time Reserve - Actual',
831 'LE'=>'Life-time Reserve - Estimated',
832 'M2'=>'Maximum',
833 'MN'=>'Month',
834 'P6'=>'Number of Services or Procedures',
835 'QA'=>'Quantity Approved',
836 'S7'=>'Age, High Value',
837 'S8'=>'Age, Low Value',
838 'VS'=>'Visits',
839 'YY'=>'Years'
842 // product/service id qualifier
843 $code271['EB13'] = array(
844 'AD'=>'American Dental Association Codes',
845 'CJ'=>'CPT Codes',
846 'HC'=>'HCPCS Codes',
847 'ID'=>'ICD-9-CM - Procedure',
848 'IV'=>'Home Infusion EDI Coalition (HIEC) Product/Service Code',
849 'N4'=>'National Drug Code in 5-4-2 Format',
850 'ZZ'=>'Mutually Defined'
853 // quantity qualifier - unit or basis copde
854 $code271['HSD'] = array(
855 'DY'=>'Days',
856 'FL'=>'Units',
857 'HS'=>'Hours',
858 'MN'=>'Month',
859 'VS'=>'Visit',
860 'DA'=>'Days',
861 'MO'=>'Months',
862 'WK'=>'Week',
863 'YR'=>'Years'
866 // delivery frequency code
867 $code271['HSD07'] = array(
868 '1'=>'1st Week of the Month',
869 '2'=>'2nd Week of the Month',
870 '3'=>'3rd Week of the Month',
871 '4'=>'4th Week of the Month',
872 '5'=>'5th Week of the Month',
873 '6'=>'1st & 3rd Weeks of the Month',
874 '7'=>'2nd & 4th Weeks of the Month',
875 '8'=>'1st Working Day of Period',
876 '9'=>'Last Working Day of Period',
877 'A'=>'Monday through Friday',
878 'B'=>'Monday through Saturday',
879 'C'=>'Monday through Sunday',
880 'D'=>'Monday',
881 'E'=>'Tuesday',
882 'F'=>'Wednesday',
883 'G'=>'Thursday',
884 'H'=>'Friday',
885 'J'=>'Saturday',
886 'K'=>'Sunday',
887 'L'=>'Monday through Thursday',
888 'M'=>'Immediately',
889 'N'=>'As Directed',
890 'O'=>'Daily Mon. through Fri.',
891 'P'=>'1/2 Mon. & 1/2 Thurs.',
892 'Q'=>'1/2 Tues. & 1/2 Thurs.',
893 'R'=>'1/2 Wed. & 1/2 Fri.',
894 'S'=>'Once Anytime Mon. through Fri.',
895 'T'=>'1/2 Tue. & 1/2 Fri.',
896 'U'=>'1/2 Mon. & 1/2 Wed.',
897 'V'=>'1/3 Mon., 1/3 Wed., 1/3 Fri.',
898 'W'=>'Whenever Necessary',
899 'X'=>'1/2 By Wed., Bal. By Fri.',
900 'Y'=>'None (Also Used to Cancel or Override a Previous Pattern)',
901 'Z'=>'Mutually Defined',
902 'SA'=>'Sunday, Monday, Thursday, Friday, Saturday',
903 'SB'=>'Tuesday through Saturday',
904 'SC'=>'Sunday, Wednesday, Thursday, Friday, Saturday',
905 'SD'=>'Monday, Wednesday, Thursday, Friday, Saturday',
906 'SG'=>'Tuesday through Friday',
907 'SL'=>'Monday, Tuesday and Thursday',
908 'SP'=>'Monday, Tuesday and Friday',
909 'SX'=>'Wednesday and Thursday',
910 'SY'=>'Monday, Wednesday and Thursday',
911 'SZ'=>'Tuesday, Thursday and Friday',
914 // Ship/Delivery Pattern Time Code
915 $code271['HSD08'] = array(
916 'A'=>'1st Shift (Normal Working Hours)',
917 'B'=>'2nd Shift',
918 'C'=>'3rd Shift',
919 'D'=>'A.M.',
920 'E'=>'P.M.',
921 'F'=>'As Directed',
922 'G'=>'Any Shift',
923 'Y'=>'None (Also Cancel or Override Previous)',
924 'Z'=>'Mutually Defined'
927 //place of service --code source 237
928 $code271['POS'] = array(
929 '01'=>'Pharmacy',
930 '02'=>'Unassigned',
931 '03'=>'School',
932 '04'=>'Homeless Shelter',
933 '05'=>'Indian Health Service Free-standing Facility',
934 '06'=>'Indian Health Service Provider-based Facility',
935 '07'=>'Tribal 638 Free-standing Facility',
936 '08'=>'Tribal 638 Provider-based Facility',
937 '09'=>'Prison/Correctional Facility',
938 '11'=>'Office',
939 '12'=>'Home ',
940 '13'=>'Assisted Living Facility',
941 '14'=>'Group Home',
942 '15'=>'Mobile Unit',
943 '16'=>'Temporary Lodging',
944 '17'=>'Walk-in Retail Health Clinic',
945 '20'=>'Urgent Care Facility',
946 '21'=>'Inpatient Hospital',
947 '22'=>'Outpatient Hospital',
948 '23'=>'Emergency Room - Hospital',
949 '24'=>'Ambulatory Surgical Center',
950 '25'=>'Birthing Center',
951 '26'=>'Military Treatment Facility',
952 '31'=>'Skilled Nursing Facility',
953 '32'=>'Nursing Facility',
954 '33'=>'Custodial Care Facility',
955 '34'=>'Hospice',
956 '41'=>'Ambulance - Land',
957 '42'=>'Ambulance - Air or Water',
958 '49'=>'Independent Clinic',
959 '50'=>'Federally Qualified Health Center',
960 '51'=>'Inpatient Psychiatric Facility',
961 '52'=>'Psychiatric Facility-Partial Hospitalization',
962 '53'=>'Community Mental Health Center',
963 '54'=>'Intermediate Care Facility/Mentally Retarded',
964 '55'=>'Residential Substance Abuse Treatment Facility',
965 '56'=>'Psychiatric Residential Treatment Center',
966 '57'=>'Non-residential Substance Abuse Treatment Facility',
967 '60'=>'Mass Immunization Center',
968 '61'=>'Comprehensive Inpatient Rehabilitation Facility',
969 '62'=>'Comprehensive Outpatient Rehabilitation Facility',
970 '71'=>'Public Health Clinic',
971 '72'=>'Rural Health Clinic',
972 '81'=>'Independent Laboratory',
973 '99'=>'Other Place of Service'
978 // insurance relationship code
979 $code271['INS02'] = array(
980 '18'=>'self',
981 '01'=>'spouse',
982 '19'=>'child',
983 '20'=>'employee',
984 '21'=>'unknown'
987 if ( array_key_exists($segment_id, $code271) ) {
988 $val = (isset($code271[$segment_id][$code]) ) ? $code271[$segment_id][$code] : "code $code not found";
989 } else {
990 $val = "segment $segment_id codes ($code) not available";
993 return $val;
999 function ibr_271_toarray($ar_segments) {
1000 // @param array $ar_segments -- array produced by csv_x12segments()
1002 if (is_array($ar_segments) && count($ar_segments['segments']) ) {
1003 $fdir = dirname($ar_segments['path']);
1004 $fname = basename($ar_segments['path']);
1005 $fmtime = date('Ymd', filemtime($ar_segments['path']) );
1007 $ar_271segs = $ar_segments['segments'];
1009 $elem_d = $ar_segments['delimiters']['e'];
1010 $rep_d = $ar_segments['delimiters']['r'];
1011 $sub_d = $ar_segments['delimiters']['s'];
1012 } else {
1013 csv_edihist_log("ibr_271toarray: error invalid segments array");
1014 return FALSE;
1016 // loop 0 ST BHT
1017 // loop 2000A HL AAA
1018 // loop 2100A NM1 PER AAA
1019 // loop 2000B HL
1020 // loop 2100B NM1 REF N3 N4 AAA PRV
1021 // loop 2000C HL TRN
1022 // loop 2100C NM1 REF N3 N4 AAA PRV DMG INS HI DTP MPI
1023 // loop 2110C EB HSD REF DTP AAA MSG
1024 // loop 2115C III LS
1025 // loop 2120C NM1 N3 N4 PER PRV LE
1026 // loop 2000D HL TRN
1027 // loop 2100D NM1 REF N3 N4 AAA PRV DMG INS HI DTP MPI
1028 // loop 2110D EB HSD REF DTP AAA MSG
1029 // loop 2115D III LS
1030 // loop 2120D NM1 N3 N4 PER PRV LE
1031 // loop trailer SE
1033 $ar_elig = array();
1034 $B = -1;
1036 foreach($ar_271segs as $seg_str) {
1037 $seg = explode($elem_d, $seg_str);
1038 $st_ct++;
1040 // expectation is multiple ST-SE with a one or more BHT in each, so index on BHT instead of ST
1041 // if multiple ISA--IEA blocks, then an $I for ISA index may need to be inserted, with a transaction number
1043 // identify loops
1044 if ($seg[0]=="ST") { $loopid = "0"; $st_ct=1; }
1045 if ($seg[0]=="BHT") { $loopid = "0"; $B++; $hl_ct = 0; }
1046 if ($seg[0]=="HL") {
1047 //if ($seg[1] == '0022' && ($seg[2]=='06' || $seg[2]=='11')) { $loopid = "2000A"; }
1048 if ($seg[3] == '20') { $loopid = "2000A"; }
1049 if ($seg[3] == '21') { $loopid = "2000B"; }
1050 if ($seg[3] == '22') { $loopid = "2000C"; }
1051 if ($seg[1] == '23') { $loopid = "2000D"; }
1053 $haschild = ($seg[4]=="1") ? TRUE : FALSE;
1054 $hl_ct++;
1057 if ($seg[0]=="NM1") {
1058 // 1P Provider 2B Third-Party Administrator 36 Employer 80 Hospital FA Facility GP Gateway Provider P5 Pan Sponsor PR Payer
1059 //if (strpos("1P|2B|36|80|FA|GP|P5|PR", $seg[1]) { $loopid = "2100B"; } // information receiver name
1060 if ($loopid == "2000A") { $loopid = "2100A"; }
1061 if ($loopid == "2000B") { $loopid = "2100B"; }
1062 // allow for repeat loops
1063 if (($loopid == "2000C" || $loopid = "2100C") && $seg[1] == "IL") { $loopid = "2100C"; $eb_2110C_ct = 0; }
1064 if (($loopid == "2000D" || $loopid = "2100D") && $seg[1] == "03") { $loopid = "2100D"; $eb_2110D_ct = 0; }
1065 // EB III or LS should occur before this, so this should never apply
1066 if ($loopid == "2110D" &&
1067 strpos("|13|1I|1P|2B|36|73|FA|GP|GW|I3|IL|LR|OC|P3|P4|P5|PR|PRP|SEP|TTP|VER|VN|VY|X3|Y2", $seg[1]) ) { $loopid = "2120D"; }
1070 if ($seg[0]=="EB") { $loopid = "2110" . substr($loopid, -1); } // loopid should now be 2110C or 2110D
1071 if ($seg[0]=="III") { $loopid = "2115" . substr($loopid, -1); }
1072 if ($seg[0]=="LS") { $loopid = $seg[1] . substr($loopid, -1); } // LS begins inner loop 2120C or 2120D
1073 if ($seg[0]=="LE") { $loopid = "2110" . substr($loopid, -1); }
1075 // loops are identified, now arrange the data into an array -- concept is [BHT][idx][loop]
1077 $ar_elig['BHT'][$B] = array();
1078 $L = $loopid;
1079 if ( !array_key_exists($L, $ar_elig['BHT'][$B]) ) { $ar_elig['BHT'][$B][$L] = array(); }
1082 if ($seg[0]=="ST") {
1083 $ar_elig['BHT'][$B] = array();
1084 $ar_elig['BHT'][$B]['ST01'] = $seg[1];
1085 $ar_elig['BHT'][$B]['FILE'] = $fname;
1086 continue;
1089 if ($seg[0]=="BHT") {
1090 // begin heirarchical transaction -- basics: purpose, referenceID, date, time ['ST01'] ['BHT01']['BHT02']['BHT03']['BHT04']['BHT05']
1091 $ar_elig['BHT'][$B]['BHT01'] = $seg[1]; // expect '0022' for normal response
1092 $ar_elig['BHT'][$B]['BHT02'] = $seg[2]; // purpose code '06' confirmation '11' response
1093 $ar_elig['BHT'][$B]['BHT03'] = $seg[3]; // reference ID
1094 $ar_elig['BHT'][$B]['BHT04'] = $seg[4]; // date CCYYMMDD
1095 $ar_elig['BHT'][$B]['BHT05'] = $seg[5]; // time HHMMSSDD
1096 //$ar_elig['BHT'][$B]['BHT06'] = $seg[6]; // transaction type -- not used
1098 continue;
1101 if ($seg[0]=="GS") {
1102 $ar_elig['BHT'][$B]['GS04'] = $seg[4]; // 271 response date CCYYMMDD
1103 continue;
1106 if ($seg[0]=="AAA") {
1107 // AAA segment is returned in case of errors
1108 $rej_str = $seg[1] . ': ' . ibr_271_codes('AAA', $seg[3]) . ' -- ' . ibr_271_codes('AAA', $seg[4]);
1109 if ($loopid == "2000A" || $loopid == "2100A" ) {
1110 $ar_elig['BHT'][$B]['AAA'] = $rej_str;
1111 } else {
1112 $ar_elig['BHT'][$B][$L]['AAA'] = $rej_str;
1115 continue;
1118 if ($seg[0]=="NM1") {
1119 if ($loopid == "2100A") {
1120 // information source name
1121 $ar_elig['BHT'][$B][$L]['NM101'] = ibr_271_codes('NM101', $seg[1]);
1122 $ar_elig['BHT'][$B][$L]['NM103'] = ($seg[2] == "2") ? $seg[3] : $seg[3] .', ' . $seg[4];
1123 $ar_elig['BHT'][$B][$L]['NM109'] = isset($seg[9]) ? $seg[9] : '';
1124 } elseif ($loopid == "2100B") {
1125 $ar_elig['BHT'][$B][$L]['NM103'] = ($seg[2] == "2") ? $seg[3] : $seg[3] .', ' . $seg[4];
1126 $ar_elig['BHT'][$B][$L]['NM109'] = isset($seg[9]) ? $seg[9] : '';
1127 } elseif ($loopid == "2100C" || $loopid == "2100D") {
1128 $ar_elig['BHT'][$B][$L]['NM103'] = ($seg[2] == "2") ? $seg[3] : $seg[3] .', ' . $seg[4];
1129 if ( isset($seg[9]) ) { $ar_elig['BHT'][$B][$L]['NM109'] = $seg[8] .': ' .$seg[9]; } // policy or patient id
1130 if ( isset($seg[10]) ) { $ar_elig['BHT'][$B][$L]['NM110'] = ibr_271_codes('NM110', $seg[10]); } // relationship
1131 } elseif ($loopid == "2120C" || $loopid == "2120D" ) {
1132 // person (provider) involved in the eligibility
1133 $ar_elig['BHT'][$B][$L]['NM101'] = ibr_271_codes("NM101", $seg[1]);
1134 $ar_elig['BHT'][$B][$L]['NM103'] = ($seg[2] == "2") ? $seg[3] : $seg[3] .', ' . $seg[4];
1135 if ( isset($seg[9]) ) { $ar_elig['BHT'][$B][$L]['NM109'] = $seg[8] .': ' .$seg[9]; } // policy or patient id
1136 if ( isset($seg[10]) ) { $ar_elig['BHT'][$B][$L]['NM110'] = ibr_271_codes('NM110', $seg[10]); } // relationship
1139 continue;
1142 if ($seg[0]=="PER" && $loopid == "2100A") {
1143 $ar_elig['BHT'][$B][$L]['PER02'] = isset($seg[2]) ? $seg[2] : '';
1144 $ar_elig['BHT'][$B][$L]['PER03'] = isset($seg[3]) ? $seg[3] : '';
1145 $ar_elig['BHT'][$B][$L]['PER04'] = isset($seg[4]) ? $seg[4] : '';
1147 continue;
1150 if ($seg[0] == "REF") {
1151 // since this segment can repeat, create a subarray under the 'REF' key
1152 $ref_str = ibr_271_codes("REF", $seg[1]);
1153 $ar_elig['BHT'][$B][$L]['REF'][] = $seg[2] . ' ' . $ref_str;
1154 continue;
1157 if ($seg[0] == "TRN") {
1158 // TRN in loop 2000C or 2000D, not both
1159 // trace numbers can be tricky. If TRN01 == 2, the original 270 trace number is returned
1160 // do we have an originating company id? if so,it distinguishes TRN segments
1161 // if ($seg[3] == "originating company id") -- expect our trace in TRN02
1162 // likewise, if ($seg[3] == "clearinghouse id") -- clearinghouse trace in TRN02
1163 $ar_elig['BHT'][$B][$L]['TRN01'] = $seg[1];
1164 if ($seg[1] == "2") {
1165 $ar_elig['BHT'][$B][$L]['TRN02'] = $seg[2]; // TRN02 TRACE holds the id number originally sent
1166 // department or subdivision
1167 if ( isset($seg[4]) ) { $ar_elig['BHT'][$B][$L]['TRN04'] = $seg[4]; }
1168 } else {
1169 $ar_elig['BHT'][$B][$L]['TRN02'] = $seg[2]; // TRN02 holds a number by the sender/clearinghouse
1171 $ar_elig['BHT'][$B][$L]['TRN03'] = isset($seg[3]) ? $seg[3] : '';
1172 continue;
1175 if ($seg[0] == "N3") {
1176 // loop 2100C subscriber is patient, ins co uses address, or there is a rejection due to incorrect address information
1177 $ar_elig['BHT'][$B][$L]['N301'] = $seg[1];
1178 if ( isset($seg[2]) ) { $ar_elig['BHT'][$B][$L]['N302'] = $seg[2]; }
1179 continue;
1182 if ($seg[0] == "N4") {
1183 //loop 2100C subscriber is patient, ins co uses address, or there is a rejection due to incorrect address information
1185 $ar_elig['BHT'][$B][$L]['N401'] = $seg[1];
1186 $ar_elig['BHT'][$B][$L]['N402'] = $seg[2];
1187 $ar_elig['BHT'][$B][$L]['N403'] = $seg[3];
1188 continue;
1191 if ($seg[0] == "PRV") {
1192 $ar_elig['BHT'][$B][$L]['PRV01'] = ibr_271_codes("PRV", $seg[1]);
1193 if ( isset($seg[2]) ) {
1194 // if PRV02 then PRV03
1195 $ar_elig['BHT'][$B][$L]['PRV02'] = $seg[2];
1196 $ar_elig['BHT'][$B][$L]['PRV03'] = $seg[3];
1198 continue;
1201 if ($seg[0] == "DMG") {
1202 $ar_elig['BHT'][$B][$L]['DMG01'] = $seg[1];
1203 $ar_elig['BHT'][$B][$L]['DMG02'] = $seg[2];
1204 $ar_elig['BHT'][$B][$L]['DMG03'] = $seg[3];
1205 continue;
1208 if ($seg[0] == "INS") {
1209 $ar_elig['BHT'][$B][$L]['INS01'] = $seg[1]; // Y/N Yes/No whether subscriber
1210 // 18 self 01 spouse 19 child 20 employee 21 unknown
1211 $ar_elig['BHT'][$B][$L]['INS02'] = ibr_271_codes("INS02", $seg[2]); // individual relationship code
1212 if ( isset($seg[3]) ) {
1213 // possibly create some type of alert to show that returned information is different from what was submitted
1214 $ar_elig['BHT'][$B][$L]['INS03'] = $seg[3]; // maintenance type code 001
1215 $ar_elig['BHT'][$B][$L]['INS04'] = $seg[4]; // maintenance reason code 25 change in identifying details
1217 // birth order if twins, triplets, etc.
1218 if ( isset($seg[17]) ) { $ar_elig['BHT'][$B][$L]['INS17'] = $seg[17]; }
1219 continue;
1222 if ($seg[0] == "HI") {
1223 $hi_str = "";
1224 for ($i=0; $i<count($seg); $i++) {
1225 // could go on to HI08 ex: BK:40101*BF:2724
1226 $dt = substr($seg[$i], 0, strpos($seg[$i]), $sub_d);
1227 $dc = substr($seg[$i], strpos($seg[$i], $sub_d)+1);
1228 $hi_str .= $dt . $sub_d . sprintf("%1$ 3d.%2$02d", substr($dc,0,3), substr($dc,3)) .' ';
1230 $ar_elig['BHT'][$B][$L]['HI'] = $hi_str;
1232 continue;
1235 if ($seg[0] == "DTP") {
1236 // segment can repeat, set up an indexed key
1237 $dtp_str = ibr_271_codes("DTP", $seg[1]);
1238 $dtp_str .= ' ' . $seg[3];
1240 $ar_elig['BHT'][$B][$L]['DTP'][] = $dtp_str;
1241 continue;
1244 if ($seg[0] == "MPI") {
1245 if (isset($seg[1])) { $ar_elig['BHT'][$B][$L]['MPI01'] = ibr_271_codes("MPI", $seg[1]); }
1246 if (isset($seg[2])) { $ar_elig['BHT'][$B][$L]['MPI02'] = ibr_271_codes("MPI", $seg[2]); }
1247 // prepended 'SB' to service affiliation codes for uniqueness
1248 if (isset($seg[3])) { $ar_elig['BHT'][$B][$L]['MPI03'] = ibr_271_codes("MPI", 'SB'.$seg[3]); }
1249 if (isset($seg[4])) { $ar_elig['BHT'][$B][$L]['MPI04'] = $seg[4]; }
1250 if (isset($seg[5])) { $ar_elig['BHT'][$B][$L]['MPI05'] = ibr_271_codes("MPI", $seg[5]); }
1252 if (isset($seg[7])) { $ar_elig['BHT'][$B][$L]['MPI07'] = $seg[7]; }
1253 continue;
1256 if ($seg[0] == "EB") {
1257 // this one is complicated -- repetitions, code references, and subelements, references to subordinate loops
1258 // create a concatenated string of the descriptions and a subarray under the 'EB' key
1259 // this may not really be adequate, but after testing a better layout should be apparent
1260 // if loop 2100C subscriber is patient
1261 $strcov = "";
1262 $strplan = "";
1263 $strfin = "";
1264 $strauth = "";
1265 $strmed = "";
1267 $ebarr = array();
1268 if (isset($seg[1])) { $strcov .= ibr_271_codes("EB01", $seg[1]); } // eligibility or benefit information code
1269 if (isset($seg[2])) { $strcov .= ' | ' . ibr_271_codes("EB02", $seg[2]); } // coverage level i.e. individual, family, etc
1270 $ebarr['COV'] = $strcov;
1272 if (isset($seg[3])) {
1273 // here we have a possibly long list of repetitions of different service type codes
1274 // we are probably interested in code 1 "medical care" and codes 98-A3, BY, BZ, "physician visit" 4, 5 are x-ray and lab
1275 /* ********* important *****************************************************************
1276 * This filter needs to be checked in practice so that necessary information is not lost
1277 * perhaps the filter should not be used at all, but it can shorten output to relevant applicable benefit listing
1278 * this filter does not affect other elements in the segment
1279 * ********* */
1280 if ( strpos($seg[3], $rep_d) ) {
1281 $relevant = array('1', '96', '4', '5', '98', '99', 'A0', 'A1', 'A2', 'A3', 'BY','BZ');
1282 $eb03 = explode($rep_d, $seg[3]);
1283 if ( is_array($eb03) ) {
1284 foreach($eb03 as $st) {
1285 if (in_array($st, $relevant)) {
1286 $ebarr['EB03'][] = ibr_271_codes("EB03", $st);
1290 } else {
1291 $ebarr['EB03'][] = ibr_271_codes("EB03", $seg[3]);
1295 if (isset($seg[5])) { $strplan .= $seg[5] . ' '; } // plan description e.g. "Super-Duper NadaDinero"
1296 if (isset($seg[4])) { $strplan .= ibr_271_codes("EB04", $seg[4]) . ' '; } // insurance type
1297 $ebarr['PLAN'] = $strplan;
1299 if (isset($seg[6])) { $strfin .= ibr_271_codes("EB06", $seg[6]) . ' '; } // time period e.r. Visit, "Calendar Year", "Lifetime"
1300 if (isset($seg[7])) { $strfin .= sprintf("%01.2f", $seg[7]) . ' '; } // dollar amount
1301 if (isset($seg[8])) { $strfin .= sprintf("% 1.0f%%", $seg[8]) . ' '; } // percentage
1302 if (isset($seg[9])) { $stfinr .= ibr_271_codes("EB09", $seg[9]) . ' '; } // quantity qualifier e.g. days, visits, lifetime reserve,
1303 if (isset($seg[10])) { $strfin .= $seg[10] . ' '; } // quantity for eb09
1304 $ebarr['FIN'] = $strfin;
1306 // authorization required ?
1307 if (isset($seg[11])) {
1308 if ($seg[11] == "Y") {
1309 $strauth .= 'auth/cert required';
1310 } elseif ($seg[11] == "N") {
1311 $strauth .= 'auth/cert not required';
1312 } else {
1313 $strauth .= 'auth/cert requirement unknown';
1316 // difference for in or out of network
1317 if (isset($seg[12])) {
1318 if ($seg[12] == "Y") {
1319 $strauth .= ' In-Plan-Network';
1320 } elseif ($seg[12] == "N") {
1321 $strauth .= ' Out-Of-Plan-Network';
1322 } elseif ($seg[12] == "W") {
1323 $strauth .= ' Same for In or Out of Plan-Network';
1324 } else {
1325 $strauth .= ' Unknown for Plan-Network';
1328 $ebarr['AUTH'] = $strauth;
1330 // EB13 is used only when EB03 is empty -- composit medical procedure identifier
1331 // expect a list of eligible procedures (repetitions of composite elements, with up to 8 parts in the composition),
1332 // but treat it as a string, extracting the code type for labeling (CPT, ICD-9), and concatenate
1333 if (isset($seg[13])) {
1334 if ( strpos($seg[13], $rep_d) ) {
1335 $eb13 = explode($rep_d, $seg[13]);
1336 if ( is_array($eb13) ) {
1337 foreach($eb13 as $sv) {
1338 if (strpos($sv, $sub_d)) {
1339 $strmed .= ibr_271_codes("EB13", substr($sv, 0, strpos($sv, $sub_d)-1));
1340 $strmed .= ' ' . substr($sv, strpos($sv, $sub_d)+1) . ' ' ;
1341 } else {
1342 $strmed .= $sv .' ';
1345 $strmed .= trim($strmed);
1347 } else {
1348 // no repetitions of the element
1349 $strmed .= ibr_271_codes("EB13", substr($sv, 0, strpos($sv, $sub_d))) . ' ' . substr($sv, strpos($sv, $sub_d)+1);
1352 // diagnosis code pointers -- the index position of the HI segment in loop 2100C or 2100D
1353 if (isset($seg[14])) {
1354 $strmed = "Diagnosis Code Pointers: " . $seg[14];
1356 $ebarr['MED'] = $strmed;
1358 /* ********* using concatenated strings per information topics instead of segment id *************
1359 if (isset($seg[4]) { $ebarr['EB04'] = ibr_271_codes("EB04", $seg[4]); } // insurance type
1360 if (isset($seg[5]) { $ebarr['EB05'] = $seg[5]; } // plan description e.g. "Super-Duper NadaDinero"
1361 if (isset($seg[6]) { $ebarr['EB06'] = ibr_271_codes("EB06", $seg[6]); } // time period e.r. Visit, "Calendar Year", "Lifetime"
1362 if (isset($seg[7]) { $ebarr['EB07'] = sprintf("%01.2f", $seg[7]); } // dollar amount
1363 if (isset($seg[8]) { $ebarr['EB08'] = sprintf("% 1.0f%%", $seg[8]); } // percentage
1364 if (isset($seg[9]) { $ebarr['EB09'] = ibr_271_codes("EB09", $seg[9]); } // quantity qualifier e.g. days, visits, lifetime reserve,
1365 if (isset($seg[10]) { $ebarr['EB10'] = $seg[10]; } // quantity for eb09
1366 // authorization required ?
1367 if (isset($seg[11]) {
1368 if ($seg[11] == "Y") {
1369 $ebarr['EB11'] = 'auth/cert required';
1370 } elseif ($seg[11] == "N") {
1371 $ebarr['EB11'] = 'auth/cert not required';
1372 } else {
1373 $ebarr['EB11'] = 'auth/cert requirement unknown';
1376 // difference for in or out of network
1377 if (isset($seg[12]) {
1378 if ($seg[12] == "Y") {
1379 $ebarr['EB12'] = 'In-Plan-Network';
1380 } elseif ($seg[12] == "N") {
1381 $ebarr['EB12'] = 'Out-Of-Plan-Network';
1382 } elseif ($seg[12] == "W") {
1383 $ebarr['EB12'] = 'Same for In/Out of Plan-Network';
1384 } else {
1385 $ebarr['EB12'] = 'Unknown for In/Out of Plan-Network';
1388 // EB13 is used only when EB03 is empty -- composit medical procedure identifier
1389 // expect a list of eligible procedures (repetitions of composite elements),
1390 // but treat it as a string, extracting the code type for labeling (CPT, ICD-9), and concatenate
1391 if (isset($seg[13]) {
1392 if ( strpos($seg[13], $rep_d) ) {
1393 $eb13 = explode($rep_d, $seg[13]);
1394 if ( is_array($eb13) ) {
1395 foreach($eb13 as $sv) {
1396 if (strpos($sv, $sub_d) {
1397 $str_eb .= ibr_271_codes("EB13", substr($sv, 0, strpos($sv, $sub_d)-1));
1398 $str_eb .= ' ' . substr($sv, strpos($sv, $sub_d)+1) . ' ' ;
1399 } else {
1400 $str_eb .= $sv .' ';
1403 $ebarr['EB13'] = trim($str_eb);
1405 } else {
1406 $ebarr['EB13'] = ibr_271_codes("EB13", substr($sv, 0, strpos($sv, $sub_d)-1)) . ' ' . substr($sv, strpos($sv, $sub_d)+1);
1409 // diagnosis code pointers -- the index position of the HI segment in loop 2100C or 2100D
1410 if (isset($seg[14]) {
1411 $ebarr['EB14'] = "Diagnisis Code Pointers: " . $seg[14];
1413 * **************************** */
1415 // OK, we have the EB segment safely lodged in $ebarr, so add it as a subarray of 'EB'
1416 $ar_elig['BHT'][$B][$L]['EB'][] = $ebarr;
1418 continue;
1420 } // end if ($seg[0] == 'EB')
1423 if ($seg[0] == "HSD") {
1424 // health care services delivery
1425 // qualifier followed by count
1426 // create a concatenated string
1428 $str_hsd = "";
1429 if (isset($seg[2])) { $str_hsd .= $seg[2] . ' ' . ibr_271_codes("HSD", $seg[1]); }
1430 if (isset($seg[4])) { $str_hsd .= ' ' . $seg[4] . ' per ' . ibr_271_codes("EB06", $seg[3]); }
1431 if (isset($seg[6])) { $str_hsd .= ' for ' . $seg[6] . ' ' . ibr_271_codes("EB06", $seg[5]); }
1432 if (isset($seg[7])) { $str_hsd .= ' ' . ibr_271_codes("HSD07", $seg[7]); }
1433 if (isset($seg[8])) { $str_hsd .= ' ' . ibr_271_codes("HSD08", $seg[8]); }
1435 $ar_elig['BHT'][$B][$L]['HSD'] = $str_hsd;
1437 continue;
1440 if ($seg[0] == "MSG") {
1441 if (isset($seg[1])) { $ar_elig['BHT'][$B][$L]['MSG'] = $seg[2]; }
1442 continue;
1445 if ($seg[0] == "III") {
1446 // the "nature of injury" codes are reported here if used in the request, codes not available
1447 // service location information can also be reported
1448 // again, create a concatenated string
1449 $iii_str = "";
1450 if (isset($seg[1]) && $seg[1]=="ZZ") {
1451 $iii_str .= ibr_271_codes("POS", $seg[2]);
1452 } elseif (isset($seg[1])) {
1453 $iii_str .= $seg[1] . ' ' . $seg[2];
1455 if (isset($seg[3])) { $iii_str .= ' ' . $seg[3]; }
1456 if (isset($seg[4])) { $iii_str .= ' ' . $seg[4]; }
1458 $ar_elig['BHT'][$B][$L]['III'] = $iii_str;
1459 continue;
1464 return $ar_elig;
1468 function ibr_271_csv_data($ar_277_vals) {
1469 // @param array $ar_277_vals -- the array produced by ibr_277_toarray()
1471 // we will take the bare minimum for a 'claim' type record
1472 // patient name, trace number (pid -- or something), ST number, payer_name, file trace, file name, error message
1473 // concept is to point to a rendition of the file rather than try to distill 271 response
1475 // files csv will also be minimal record
1478 /* *** code goes here **** */
1479 $csv271['file']['filename'] = $ar_elig['BHT']['FILE'];
1480 $ar_elig['BHT']['controlnum'] =
1487 function ibr_271html($ar_271) {
1488 // @param array $ar_271vals -- the multi-dimensional array from ibr_271toarray()
1490 // render the array into an html table
1492 if ( !isarray($ar_271) ) { return false; }
1494 // expect array like $ar_271vals['BHT'][$i][$loop][keys]
1496 // table
1497 // row 1: if (isset($ar_271vals['BHT']['2000A']['AAA']) -- rejected
1498 // loop 0 ST BHT
1499 // loop 2000A HL AAA
1500 // loop 2100A NM1 PER AAA
1501 // loop 2000B HL
1502 // loop 2100B NM1 REF N3 N4 AAA PRV
1503 // loop 2000C HL TRN
1504 // loop 2100C NM1 REF N3 N4 AAA PRV DMG INS HI DTP MPI
1505 // loop 2110C EB HSD REF DTP AAA MSG
1506 // loop 2115C III LS
1507 // loop 2120C NM1 N3 N4 PER PRV LE
1508 // loop 2000D HL TRN
1509 // loop 2100D NM1 REF N3 N4 AAA PRV DMG INS HI DTP MPI
1510 // loop 2110D EB HSD REF DTP AAA MSG
1511 // loop 2115D III LS
1512 // loop 2120D NM1 N3 N4 PER PRV LE
1513 // loop trailer SE
1515 $html_str = "";
1517 // header lables here (6 columns)
1518 $hd_str = "";
1521 $idx = 0;
1522 foreach ($ar_271['BHT'] as $b) {
1524 if (isset($b['ST01'])) {
1525 // basic information basics: purpose, referenceID, date, time ['ST01'] ['BHT01']['BHT02']['BHT03']['BHT04']['BHT05']
1526 $html_str .= "<tr>
1528 $html_str .= "<td>{$b['ST01']}</td>";
1529 $html_str .= "<td>{$b['BHT01']}</td>";
1530 $html_str .= "<td>{$b['BHT02']}</td>";
1531 $html_str .= "<td>{$b['BHT03']}</td>";
1532 $html_str .= "<td>{$b['BHT04']}</td>";
1533 $html_str .= "<td>{$b['BHT05']}</td>";
1534 $html_str .= "
1535 <tr>";
1538 if (isset($b['2000A']['AAA'])){
1539 // error in 270 request ISA06, ISA08, GS02, or GS03
1540 $html_str .= "<tr>
1542 $html_str .= "<td colspan=6>{$b['2000A']['AAA']}</td>";
1543 $html_str .= "
1544 <tr>";
1547 if (isset($b['2100A'])) {
1548 // information sender -- clearinghouse or payer?
1549 $html_str .= "<tr>
1551 $html_str .= "<td>{$b['2100A']['NM101']}</td>";
1552 $html_str .= "<td>{$b['2100A']['NM103']}</td>";
1553 $html_str .= "<td>{$b['2100A']['NM109']}</td>";
1554 $html_str .= "<td>{$b['2100A']['PER02']}</td>";
1555 $html_str .= "<td colspan=2>{$b['2100A']['PER03']}" . " {$b['2100A']['PER04']}</td>";
1556 $html_str .= "
1557 </tr>";
1558 // error in 270 request loop 2100A or in 271 sender's system
1559 $html_str .= isset($b['2100A']['AAA']) ? "<tr>
1560 <td colspan=6>{$b['2100A']['AAA']}</td>
1561 </tr>" : "";
1565 if (isset($b['2100B'])) {
1566 // inforamtion receiver -- practice
1567 $html_str .= "<tr>
1569 $html_str .= "<td>{$b['2100B']['NM103']}</td>";
1570 $html_str .= "<td>{$b['2100B']['NM109']}</td>";
1571 $html_str .= isset($b['2100B']['PRV']) ? "<td>{$b['2100B']['REF']}</td>" : "<td>&nbsp</td>";
1572 if ( isset($b['2100B']['REF']) ) {
1573 $ref_str = "";
1574 foreach($b['2100B']['REF'] as $r) { $ref_str .= $r . " "; }
1575 $html_str .= "<td colspan =2>$ref_str</td>";
1576 $ref_str = "";
1577 } else {
1578 $html_str .= "<td colspan=2>&nbsp</td>";
1580 $html_str .= "
1581 </tr>";
1582 if ( isset($b['2100B']['AAA']) ) {
1583 // error in 270 request loop 2100B
1584 $html_str .= "<tr>
1585 <td colspan=6>{$b['2100B']['AAA']}</td>
1586 </tr>";
1590 if ( isset($b['2000C']['TRN01']) ){
1591 // expect sunscriber identification here
1592 $html_str .= "<tr>
1594 $html_str .= ($b['2000C']['TRN01'] == "1") ? "<td>current</td>" : "<td>referenced</td>";
1595 $html_str .= "<td>{$b['2000C']['TRN02']}</td>";
1596 $html_str .= "<td>{$b['2000C']['TRN03']}</td>";
1597 $html_str .= "<td>{$b['2000C']['TRN04']}</td>";
1598 $html_str .= "<td colspan=2>&nbsp</td>";
1599 $html_str .= "
1600 </tr>";
1603 /* ********************************************************
1604 * the 2100C and 2100D loops are practically identical and one or the other is expected
1605 * but it may be that there is a small amount of subscriber information, followed by
1606 * detailed patient /dependent information
1607 * thus, at this point, we have redundant code
1608 * ******************************************************** */
1609 if ( isset($b['2100C']) ) {
1610 // subscriber information
1611 $html_str .= "<tr>
1613 $html_str .= "<td>{$b['2100C']['NM103']}</td>";
1614 $html_str .= "<td>{$b['2100C']['NM109']}</td>";
1615 $html_str .= "<td>{$b['2100C']['NM110']}</td>";
1616 $html_str .= isset($b['2100C']['DMG03']) ? "<td>{$b['2100C']['DMG03']}</td>" : "<td>&nbsp</td>";
1618 // put the relationship in this row, if available
1619 if (isset($b['2100C']['INS01']) ) {
1620 $ins_str = $b['2100C']['INS01'] . " " . $b['2100C']['INS02'];
1621 $ins_str .= isset($b['2100C']['INS03']) ? $b['2100C']['INS04'] . " " . $b['2100C']['INS04'] : "";
1622 $ins_str .= isset($b['2100C']['INS17']) ? $b['2100C']['INS17'] : "";
1623 $html_str .= "<td colspan=2>$ins_str</td>";
1625 $html_str .= "
1626 </tr>";
1629 if ( isset($b['2100C']['N3']) ) {
1630 // subscriber address
1631 $html_str .= "<tr>
1633 $html_str .= "<td>{$b['2100C']['N301']}</td>";
1634 $html_str .= "<td>{$b['2100C']['N302']}</td>";
1635 $html_str .= isset($b['2100C']['N401']) ? "<td>{$b['2100C']['N401']}</td>" : "<td>&nbsp</td>";
1636 $html_str .= isset($b['2100C']['N402']) ? "<td>{$b['2100C']['N402']}</td>" : "<td>&nbsp</td>";
1637 $html_str .= isset($b['2100C']['N403']) ? "<td>{$b['2100C']['N403']}</td>" : "<td>&nbsp</td>";
1638 $html_str .= isset($b['2100C']['N404']) ? "<td>{$b['2100C']['N404']}</td>" : "<td>&nbsp</td>";
1639 $html_str .= "
1640 </tr>";
1643 if (isset($b['2100C']['AAA'])) {
1644 // error in 270 request subscriber information
1645 $html_str .= "<tr>
1647 $html_str .= "<td colspan=6>{$b['2100C']['AAA']}</td>";
1648 $html_str .= "
1649 </tr>";
1652 if (isset($b['2100C']['MPI01'])) {
1653 // military personnell information
1654 $html_str .= "<tr>
1656 $html_str .= "<td>{$b['2100C']['MPI01']}</td>";
1657 $html_str .= "<td>{$b['2100C']['MPI02']}</td>";
1658 $html_str .= "<td>{$b['2100C']['MPI03']}</td>";
1659 $html_str .= "<td>{$b['2100C']['MPI04']}</td>";
1660 $html_str .= "<td>{$b['2100C']['MPI05']}</td>";
1661 $html_str .= "<td>{$b['2100C']['MPI07']}</td>";
1662 $html_str .= "
1663 </tr>";
1667 if ( isset($b['2100C']['DTP']) ) {
1668 // dates such as eligibility, termnation, authorization, etc
1669 // made into a subarray of strings e.g. "eligibility 20110501"
1670 $dct = 0;
1671 $html_str .= "<tr>
1673 foreach($b['2100C']['DTP'] as $d) {
1674 $dct++;
1675 $html_str .= "<td colspan=2>$d</td>";
1676 if ($dct % 3 == 0) {
1677 $html_str .= "</tr>
1678 <tr>";
1681 if ($dct % 3 > 0) {
1682 $cs = 2*(3 - ($dct % 3));
1683 "<td colspan=$cs>&nbsp</td>"; }
1684 $html_str .= "
1685 </tr>";
1688 if ( isset($b['2100C']['PRV01']) ) {
1689 // provider information, which will be combined with diagnosis codes if present
1690 $html_str .= "<tr>
1692 $html_str .= "<td>{$b['2100C']['PRV01']}</td>";
1693 $html_str .= "<td>{$b['2100C']['PRV02']}</td>";
1694 $html_str .= "<td>{$b['2100C']['PRV03']}</td>";
1696 $html_str .= isset($b['2100C']['HI']) ? "<td colspan=2>{$b['2100C']['HI']}</td>" : "<td colspan=2>&nbsp</td>";
1697 $html_str .= "
1698 </tr>tr>";
1701 // EB segment is most difficult one
1702 if ( isset($b['2110C']['EB']) && count($b['2110C']['EB']) > 0 ) {
1703 // eligibility / benefits detail
1704 // this is an array which is indexed under 'EB' ['EB03'] and ['COV']['PLAN']['FIN'] ['AUTH']['MED']
1705 foreach($b['2110C']['EB'] as $eb) {
1706 // first issue is 'EB03' -- an array of service types
1707 if (isset($eb['EB03']) && count($eb['EB03']) > 0 ) {
1708 $ebct = 0;
1709 $html_str .= "<tr>
1711 foreach($eb['EB03'] as $st) {
1712 $html_str .= "<td>$st</td>";
1713 if ($dct % 6 == 0) {
1714 $html_str .= "</tr>
1715 <tr>";
1718 $html_str .= "
1719 </tr>";
1721 $html_str .= "<tr>
1723 if (isset($eb['PLAN']) ) {
1724 $html_str .= "<tr>
1725 <td colspan=6>{$eb['PLAN']}</td>
1726 </tr>";
1728 if (isset($eb['COV']) ) {
1729 $html_str .= "<tr>
1730 <td colspan=6>{$eb['COV']}</td>
1731 </tr>";
1733 if ( isset($eb['FIN']) ) {
1734 $html_str .= "<tr>
1735 <td colspan=6>{$eb['FIN']}</td>
1736 </tr>";
1738 if ( isset($eb['AUTH']) ) {
1739 $html_str .= "<tr>
1740 <td colspan=6>{$eb['AUTH']}</td>
1741 </tr>";
1743 if ( isset($eb['MED']) ) {
1744 $html_str .= "<tr>
1745 <td colspan=6>{$eb['MED']}</td>
1746 </tr>";
1750 } // end if ( isset($b['2110C']['EB'])
1753 if ( isset($b['2110C']['DTP']) ) {
1754 // dates such as eligibility, termnation, authorization, etc
1755 // DTP in loop 2110C when the specific benefit has a different date than in loop 2100C
1756 $html_str .= "<tr>
1758 // made into a subarray of strings e.g. "eligibility 20110501"
1759 $dct = 0;
1760 foreach($b['2110C']['DTP'] as $d) {
1761 $dct++;
1762 $html_str .= "<td colspan=2>$d</td>";
1763 if ($dct % 3 == 0) {
1764 $html_str .= "</tr>
1765 <tr>";
1768 if ($dct % 3 > 0) { "<td colspan={2*(3 - $dct % 3)}>&nbsp</td>"; }
1769 $html_str .= "
1770 </tr>";
1773 if (isset($b['2110C']['AAA'])) {
1774 // error in 270 request or in regards to specific benefit
1775 $html_str .= "<tr>
1777 $html_str .= "<td colspan=6>{$b['2110C']['AAA']}</td>";
1778 $html_str .= "
1779 </tr>";
1782 if (isset($b['2110C']['MSG'])) {
1783 // free form text messaget
1784 $html_str .= "<tr>
1786 $html_str .= "<td colspan=6>{$b['2110C']['MSG']}</td>";
1787 $html_str .= "
1788 </tr>";
1791 if (isset($b['2115C']['III'])) {
1792 // added information regarding eligibility or benefits in the 2110C loop
1793 $html_str .= "<tr>
1795 $html_str .= "<td colspan=6>{$b['2115C']['III']}</td>";
1796 $html_str .= "
1797 </tr>";
1800 if (isset($b['2120C']['NM101'])) {
1801 // subscriber benefit related entity
1802 $html_str .= "<tr>
1804 $html_str .= "<td colspan=2>{$b['2100C']['NM101']}</td>";
1805 $html_str .= "<td>{$b['2100C']['NM103']}</td>";
1806 $html_str .= "<td>{$b['2100C']['NM109']}</td>";
1807 $html_str .= "<td colspan=2>{$b['2100C']['NM110']}</td>";
1808 $html_str .= "
1809 </tr>";
1812 if (isset($b['2120C']['N301'])) {
1813 $html_str .= "<tr>
1815 $html_str .= "<td>{$b['2120C']['N301']}</td>";
1816 $html_str .= "<td>{$b['2120C']['N302']}</td>";
1817 $html_str .= isset($b['2120C']['N401']) ? "<td>{$b['2100C']['N401']}</td>" : "<td>&nbsp</td>";
1818 $html_str .= isset($b['2120C']['N402']) ? "<td>{$b['2100C']['N402']}</td>" : "<td>&nbsp</td>";
1819 $html_str .= isset($b['2120C']['N403']) ? "<td>{$b['2100C']['N403']}</td>" : "<td>&nbsp</td>";
1820 $html_str .= isset($b['2120C']['N404']) ? "<td>{$b['2100C']['N404']}</td>" : "<td>&nbsp</td>";
1821 $html_str .= "
1822 </tr>";
1825 if (isset($b['2120C']['PRV01'])) {
1826 $html_str .= "<tr>
1828 $html_str .= "<td colspan=2>{$b['2120C']['PRV01']} </td>";
1829 $html_str .= "<td>{$b['2120C']['PRV02']} </td>";
1830 $html_str .= "<td>{$b['2120C']['PRV03']} </td>";
1831 $html_str .= "<td colspan=2>&nbsp </td>";
1832 $html_str .= "
1833 </tr>";
1836 if (isset($b['2120C']['PER02'])) {
1837 $html_str .= "<tr>
1839 $html_str .= "<td>{$b['2120C']['PER02']} </td>";
1840 $html_str .= "<td colspan=2>{$b['2120C']['PER03']}" . " {$b['2120C']['PER04']}</td>";
1841 $html_str .= "<td colspan=3>&nbsp </td>";
1843 $html_str .= "
1844 </tr>";
1847 /* *************
1848 * now repeat the above code, but for the 2100D loop
1849 * ************* */
1850 if ( isset($b['2100D']) ) {
1851 // subscriber information
1852 $html_str .= "<tr>
1854 $html_str .= "<td>{$b['2100D']['NM103']}</td>";
1855 $html_str .= "<td>{$b['2100D']['NM109']}</td>";
1856 $html_str .= "<td>{$b['2100D']['NM110']}</td>";
1857 $html_str .= isset($b['2100D']['DMG03']) ? "<td>{$b['2100D']['DMG03']}</td>" : "<td>&nbsp</td>";
1859 // put the relationship in this row, if available
1860 if (isset($b['2100D']['INS01']) ) {
1861 $ins_str = $b['2100D']['INS01'] . " " . $b['2100D']['INS02'];
1862 $ins_str .= isset($b['2100D']['INS03']) ? $b['2100D']['INS04'] . " " . $b['2100D']['INS04'] : "";
1863 $ins_str .= isset($b['2100D']['INS17']) ? $b['2100D']['INS17'] : "";
1864 $html_str .= "<td colspan=2>$ins_str</td>";
1866 $html_str .= "
1867 </tr>";
1870 if ( isset($b['2100D']['N3']) ) {
1871 // subscriber address
1872 $html_str .= "<tr>
1874 $html_str .= "<td>{$b['2100D']['N301']}</td>";
1875 $html_str .= "<td>{$b['2100D']['N302']}</td>";
1876 $html_str .= isset($b['2100D']['N401']) ? "<td>{$b['2100D']['N401']}</td>" : "<td>&nbsp</td>";
1877 $html_str .= isset($b['2100D']['N402']) ? "<td>{$b['2100D']['N402']}</td>" : "<td>&nbsp</td>";
1878 $html_str .= isset($b['2100D']['N403']) ? "<td>{$b['2100D']['N403']}</td>" : "<td>&nbsp</td>";
1879 $html_str .= isset($b['2100D']['N404']) ? "<td>{$b['2100D']['N404']}</td>" : "<td>&nbsp</td>";
1880 $html_str .= "
1881 </tr>";
1884 if (isset($b['2100D']['AAA'])) {
1885 // error in 270 request subscriber information
1886 $html_str .= "<tr>
1888 $html_str .= "<td colspan=6>{$b['2100D']['AAA']}</td>";
1889 $html_str .= "
1890 </tr>";
1893 if (isset($b['2100D']['MPI01'])) {
1894 // military personnell information
1895 $html_str .= "<tr>
1897 $html_str .= "<td>{$b['2100D']['MPI01']}</td>";
1898 $html_str .= "<td>{$b['2100D']['MPI02']}</td>";
1899 $html_str .= "<td>{$b['2100D']['MPI03']}</td>";
1900 $html_str .= "<td>{$b['2100D']['MPI04']}</td>";
1901 $html_str .= "<td>{$b['2100D']['MPI05']}</td>";
1902 $html_str .= "<td>{$b['2100D']['MPI07']}</td>";
1903 $html_str .= "
1904 </tr>";
1908 if ( isset($b['2100D']['DTP']) ) {
1909 // dates such as eligibility, termnation, authorization, etc
1910 $html_str .= "<tr>
1912 // made into a subarray of strings e.g. "eligibility 20110501"
1913 $dct = 0;
1914 foreach($b['2100D']['DTP'] as $d) {
1915 $dct++;
1916 $html_str .= "<td colspan=2>$d</td>";
1917 if ($dct % 3 == 0) {
1918 $html_str .= "</tr>
1919 <tr>";
1922 if ($dct % 3 > 0) { "<td colspan={2*(3 - $dct % 3)}>&nbsp</td>"; }
1923 $html_str .= "
1924 </tr>";
1927 if ( isset($b['2100D']['PRV01']) ) {
1928 // provider information, which will be combined with diagnosis codes if present
1929 $html_str .= "<tr>
1931 $html_str .= "<td>{$b['2100D']['PRV01']}</td>";
1932 $html_str .= "<td>{$b['2100D']['PRV02']}</td>";
1933 $html_str .= "<td>{$b['2100D']['PRV03']}</td>";
1935 $html_str .= isset($b['2100D']['HI']) ? "<td colspan=2>{$b['2100D']['HI']}</td>" : "<td colspan=2>&nbsp</td>";
1936 $html_str .= "
1937 </tr>tr>";
1940 // EB segment is most difficult one
1941 if ( isset($b['2110D']['EB']) && count($b['2110D']['EB']) > 0 ) {
1942 // eligibility / benefits detail
1943 // this is an array which is indexed under 'EB' ['EB03'] and ['COV']['PLAN']['FIN'] ['AUTH']['MED']
1944 foreach($b['2110D']['EB'] as $eb) {
1945 // first issue is 'EB03' -- an array of service types
1946 if (isset($eb['EB03']) && count($eb['EB03']) > 0 ) {
1947 $ebct = 0;
1948 $html_str .= "<tr>
1950 foreach($eb['EB03'] as $st) {
1951 $html_str .= "<td>$st</td>";
1952 if ($dct % 6 == 0) {
1953 $html_str .= "</tr>
1954 <tr>";
1957 $html_str .= "
1958 </tr>";
1960 $html_str .= "<tr>
1962 if (isset($eb['PLAN']) ) {
1963 $html_str .= "<tr>
1964 <td colspan=6>{$eb['PLAN']}</td>
1965 </tr>";
1967 if (isset($eb['COV']) ) {
1968 $html_str .= "<tr>
1969 <td colspan=6>{$eb['COV']}</td>
1970 </tr>";
1972 if ( isset($eb['FIN']) ) {
1973 $html_str .= "<tr>
1974 <td colspan=6>{$eb['FIN']}</td>
1975 </tr>";
1977 if ( isset($eb['AUTH']) ) {
1978 $html_str .= "<tr>
1979 <td colspan=6>{$eb['AUTH']}</td>
1980 </tr>";
1982 if ( isset($eb['MED']) ) {
1983 $html_str .= "<tr>
1984 <td colspan=6>{$eb['MED']}</td>
1985 </tr>";
1989 } // end if ( isset($b['2110D']['EB'])
1992 if ( isset($b['2110D']['DTP']) ) {
1993 // dates such as eligibility, termnation, authorization, etc
1994 // DTP in loop 2110C when the specific benefit has a different date than in loop 2100C
1995 $html_str .= "<tr>
1997 // made into a subarray of strings e.g. "eligibility 20110501"
1998 $dct = 0;
1999 foreach($b['2110D']['DTP'] as $d) {
2000 $dct++;
2001 $html_str .= "<td colspan=2>$d</td>";
2002 if ($dct % 3 == 0) {
2003 $html_str .= "</tr>
2004 <tr>";
2007 if ($dct % 3 > 0) {
2008 $cs = 2*(3 - ($dct % 3));
2009 $html_str .= "<td colspan=$cs>&nbsp</td>";
2011 $html_str .= "
2012 </tr>";
2015 if (isset($b['2110D']['AAA'])) {
2016 // error in 270 request or in regards to specific benefit
2017 $html_str .= "<tr>
2019 $html_str .= "<td colspan=6>{$b['2110D']['AAA']}</td>";
2020 $html_str .= "
2021 </tr>";
2024 if (isset($b['2110D']['MSG'])) {
2025 // free form text messaget
2026 $html_str .= "<tr>
2028 $html_str .= "<td colspan=6>{$b['2110D']['MSG']}</td>";
2029 $html_str .= "
2030 </tr>";
2033 if (isset($b['2115D']['III'])) {
2034 // added information regarding eligibility or benefits in the 2110C loop
2035 $html_str .= "<tr>
2037 $html_str .= "<td colspan=6>{$b['2115D']['III']}</td>";
2038 $html_str .= "
2039 </tr>";
2042 if (isset($b['2120D']['NM101'])) {
2043 // subscriber benefit related entity
2044 $html_str .= "<tr>
2046 $html_str .= "<td colspan=2>{$b['2100D']['NM101']}</td>";
2047 $html_str .= "<td>{$b['2100D']['NM103']}</td>";
2048 $html_str .= "<td>{$b['2100D']['NM109']}</td>";
2049 $html_str .= "<td colspan=2>{$b['2100D']['NM110']}</td>";
2050 $html_str .= "
2051 </tr>";
2054 if (isset($b['2120D']['N301'])) {
2055 $html_str .= "<tr>
2057 $html_str .= "<td>{$b['2120D']['N301']}</td>";
2058 $html_str .= "<td>{$b['2120D']['N302']}</td>";
2059 $html_str .= isset($b['2120D']['N401']) ? "<td>{$b['2100D']['N401']}</td>" : "<td>&nbsp</td>";
2060 $html_str .= isset($b['2120D']['N402']) ? "<td>{$b['2100D']['N402']}</td>" : "<td>&nbsp</td>";
2061 $html_str .= isset($b['2120D']['N403']) ? "<td>{$b['2100D']['N403']}</td>" : "<td>&nbsp</td>";
2062 $html_str .= isset($b['2120D']['N404']) ? "<td>{$b['2100D']['N404']}</td>" : "<td>&nbsp</td>";
2063 $html_str .= "
2064 </tr>";
2067 if (isset($b['2120D']['PRV01'])) {
2068 $html_str .= "<tr>
2070 $html_str .= "<td colspan=2>{$b['2120D']['PRV01']} </td>";
2071 $html_str .= "<td>{$b['2120D']['PRV02']} </td>";
2072 $html_str .= "<td>{$b['2120D']['PRV03']} </td>";
2073 $html_str .= "<td colspan=2>&nbsp </td>";
2074 $html_str .= "
2075 </tr>";
2078 if (isset($b['2120D']['PER02'])) {
2079 $html_str .= "<tr>
2081 $html_str .= "<td>{$b['2120D']['PER02']} </td>";
2082 $html_str .= "<td colspan=2>{$b['2120D']['PER03']}" . " {$b['2120D']['PER04']}</td>";
2083 $html_str .= "<td colspan=3>&nbsp </td>";
2085 $html_str .= "
2086 </tr>";
2095 function ibr_271_new_files($files_ar = NULL, $html_out = FALSE, $err_only = TRUE) {
2096 // @param bool $html_out -- whether to return html output
2097 // @param bool $err_only -- only list claims with errors in output
2098 // @param array $files_ar -- list of new files from upload script
2099 // otherwise the 271/ directory is scanned and files in directory that
2100 // are not in the 271_files.csv record are treated as "new" files
2102 // get the new files in an array
2103 if ( is_array($files_ar) && count($files_ar) ) {
2104 $ar_files = $files_ar;
2105 $need_dir = FALSE;
2106 } else {
2107 $ar_files = csv_newfile_list("f271");
2108 $need_dir = TRUE;
2109 $p = csv_parameters("f271");
2110 $dir = dirname(__FILE__).$p['directory'];
2113 if (!is_array($ar_files) || count($ar_files) == 0 ) {
2114 $html_str = "ibr_271_new_files: no new f271 (eligibility) files found <br />" . PHP_EOL;
2115 return $html_str;
2117 // OK, we have some new files
2118 $html_str = "";
2119 $idx = 0;
2120 $chr_c = 0;
2121 $chr_f = 0;
2123 foreach ($ar_files as $file_271) {
2124 // debug
2125 //echo "ibr_277_process_new: $file_277 <br />";
2126 $path_271 = ($need_dir) ? $dir.DIRECTORY_SEPARATOR.$file_271 : $file_271;
2128 $ar_seg = csv_x12_segments($path_277, "277", FALSE);
2130 if (is_array($ar_seg) && count($ar_seg['segments']) ) {
2131 $ar_271_vals = ibr_271_toarray($ar_seg);
2132 if (!$ar_271_vals) {
2133 $html_str .= "failed to get segments for $file_271 <br />" .PHP_EOL;
2134 continue;
2136 } else {
2137 $html_str .= "failed to get segments for $file_271 <br />" .PHP_EOL;
2138 continue;
2140 //$ar_277_vals = ($need_dir) ? ibr_277_parse($dir . $file_277) : $file_277;
2142 // debug
2143 //echo "ar_277_vals count " . count($ar_277_vals) . "<br />";
2144 //var_dump(array_keys($ar_277_vals));
2145 //var_dump($ar_277_vals['file']);
2147 $ar_csvc = ibr_271_csv_data($ar_277_vals);
2149 //$chr_f = ibr_277_write_csv ($ar_277_vals['file'], "file");
2150 //$chr_c = ibr_277_write_csv ($ar_csvc, "claim");
2152 $chr_f += csv_write_record($ar_277_vals['file'], "f277", "file");
2153 $chr_c += csv_write_record($ar_csvc, "f277", "claim");
2155 if ($html_out) {
2156 // store the data arrays so they are html'ized at once
2157 $ar_h[$idx]['file'] = $ar_277_vals['file'];
2158 $ar_h[$idx]['claim'] = $ar_csvc;
2159 $idx++;
2163 } // end foreach ($ar_files as $file_277)
2165 if ($html_out) {
2166 $html_str .= ibr_277_html($ar_h, $err_only);
2167 } else {
2168 $html_str .= "ibr_277_process_new: wrote $chr_c characters claims and $chr_f characters files <br />". PHP_EOL;
2170 csv_edihist_log("ibr_277_process_new: $chr_f characters written to files_277.csv");
2171 csv_edihist_log("ibr_277_process_new: $chr_c characters written to claims_277.csv");
2172 // var_dump ($ar_277_vals);
2174 return $html_str;