Improved Code Sniffing (#928)
[openemr.git] / library / gen_x12_837.inc.php
blob21d25a628d1329a8713fe41501ec52356236463f
1 <?php
2 /** @package OpenEMR
3 * @link http://www.open-emr.org
4 * @author Rod Roark <rod@sunsetsystems.com>
5 * @copyright Copyright (c) 2009 Rod Roark <rod@sunsetsystems.com>
6 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
7 */
9 require_once("Claim.class.php");
10 function stripZipCode($zip)
12 return preg_replace('/[-\s]*/','',$zip);
14 function gen_x12_837($pid, $encounter, &$log, $encounter_claim=false)
17 $today = time();
18 $out = '';
19 $claim = new Claim($pid, $encounter);
20 $edicount = 0;
22 // This is true for the 5010 standard, false for 4010.
23 // x12gsversionstring() should be "005010X222A1" or "004010X098A1".
24 $CMS_5010 = strpos($claim->x12gsversionstring(), '5010') !== false;
26 $log .= "Generating claim $pid-$encounter for " .
27 $claim->patientFirstName() . ' ' .
28 $claim->patientMiddleName() . ' ' .
29 $claim->patientLastName() . ' on ' .
30 date('Y-m-d H:i', $today) . ".\n";
32 $out .= "ISA" .
33 "*" . $claim->x12gsisa01() .
34 "*" . $claim->x12gsisa02() .
35 "*" . $claim->x12gsisa03() .
36 "*" . $claim->x12gsisa04() .
37 "*" . $claim->x12gsisa05() .
38 "*" . $claim->x12gssenderid() .
39 "*" . $claim->x12gsisa07() .
40 "*" . $claim->x12gsreceiverid() .
41 "*030911" .
42 "*1630" .
43 "*" . ($CMS_5010 ? "^" : "U" ) .
44 "*" . ($CMS_5010 ? "00501" : "00401") .
45 "*000000001" .
46 "*" . $claim->x12gsisa14() .
47 "*" . $claim->x12gsisa15() .
48 "*:" .
49 "~\n";
51 $out .= "GS" .
52 "*HC" .
53 "*" . $claim->x12gsgs02() .
54 "*" . trim($claim->x12gs03()) .
55 "*" . date('Ymd', $today) .
56 "*" . date('Hi', $today) .
57 "*1" .
58 "*X" .
59 "*" . $claim->x12gsversionstring() .
60 "~\n";
62 ++$edicount;
63 $out .= "ST" .
64 "*837" .
65 "*0021" .
66 // Spec says the following is optional, so should be able to leave it out.
67 ($CMS_5010 ? ("*" . $claim->x12gsversionstring()) : "") .
68 "~\n";
70 ++$edicount;
71 $out .= "BHT" .
72 "*0019" . // 0019 is required here
73 "*00" . // 00 = original transmission
74 "*0123" . // reference identification
75 "*" . date('Ymd', $today) . // transaction creation date
76 "*" . date('Hi', $today) . // transaction creation time
77 ($encounter_claim ? "*RP" : "*CH") . // RP = reporting, CH = chargeable
78 "~\n";
80 if (!$CMS_5010) {
81 // This segment was deleted for 5010.
82 ++$edicount;
83 $out .= "REF" .
84 "*87" .
85 "*" . $claim->x12gsversionstring() .
86 "~\n";
89 ++$edicount;
91 if ($claim->federalIdType() == "SY") { // check entity type for NM*102 1 == person, 2 == non-person entity
92 $tempName = $claim->billingFacilityName();
93 $partsName = explode(' ', $tempName);// Loop 1000A submitter entity == person
94 $num_parts = count($partsName);
95 switch ($num_parts) {
96 case "2":
97 $firstName = $partsName[0];
98 $middleName = '';
99 $lastName = $partsName[1];
100 $suffixName = '';
101 break;
102 case "3":
103 $firstName = $partsName[0];
104 $middleName = $partsName[1];
105 $lastName = $partsName[2];
106 $suffixName = '';
107 break;
108 case "4":
109 $firstName = $partsName[0];
110 $middleName = $partsName[1];
111 $lastName = $partsName[2];
112 $suffixName = $partsName[3];
113 break;
114 default:
115 $log .= "*** submitter name in 1000A loop has more than 4 parts, may not be desirable\n";
116 $firstName = $partsName[0];
117 $middleName = $partsName[1];
118 $lastName = $partsName[2];
119 $suffixName = $partsName[3];
121 $out .= "NM1" . // Loop 1000A Submitter
122 "*41" .
123 "*1" .
124 "*" . $lastName .
125 "*" . $firstName .
126 "*" . $middleName .
127 "*" . // Name Prefix not used
128 "*" . // Name Suffix not used
129 "*46";
130 } else { //Field length is limited to 35. See nucc dataset page 63 www.nucc.org
131 $billingFacilityName = substr($claim->billingFacilityName(), 0, $CMS_5010 ? 60 : 35);
132 if ($billingFacilityName == '') $log .= "*** billing facility name in 1000A loop is empty\n";
133 $out .= "NM1" .
134 "*41" .
135 "*2" .
136 "*" . $billingFacilityName .
137 "*" .
138 "*" .
139 "*" .
140 "*" .
141 "*46";
144 if (trim($claim->x12gsreceiverid()) == '470819582') { // if ECLAIMS EDI
145 $out .= "*" . $claim->clearingHouseETIN();
146 } else {
147 $out .= "*" . $claim->billingFacilityETIN();
149 $out .= "~\n";
151 ++$edicount;
152 $out .= "PER" .
153 "*IC" .
154 "*" . $claim->billingContactName() .
155 "*TE" .
156 "*" . $claim->billingContactPhone();
157 if (!$CMS_5010 && $claim->x12gsper06()) {
158 $out .= "*ED*" . $claim->x12gsper06();
160 $out .= "~\n";
162 ++$edicount;
163 $out .= "NM1" . // Loop 1000B Receiver
164 "*40" .
165 "*2" .
166 "*" . $claim->clearingHouseName() .
167 "*" .
168 "*" .
169 "*" .
170 "*" .
171 "*46" .
172 "*" . $claim->clearingHouseETIN() .
173 "~\n";
175 $HLcount = 1;
177 ++$edicount;
178 $out .= "HL" . // Loop 2000A Billing/Pay-To Provider HL Loop
179 "*$HLcount" .
180 "*" .
181 "*20" .
182 "*1" . // 1 indicates there are child segments
183 "~\n";
185 $HLBillingPayToProvider = $HLcount++;
187 // Situational PRV segment for provider taxonomy code for Medicaid.
188 if ($claim->claimType() == 'MC') {
189 ++$edicount;
190 $out .= "PRV*BI*ZZ" .
191 "*" . $claim->providerTaxonomy() .
192 "~\n";
195 // Situational CUR segment (foreign currency information) omitted here.
197 ++$edicount;
198 //Field length is limited to 35. See nucc dataset page 63 www.nucc.org
199 if ($claim->federalIdType() == "SY") { // check for entity type like in 1000A
200 $tempName = $claim->billingFacilityName();
201 $partsName = explode(' ', $tempName);// Loop 2010AA Billing Provider entity == person
202 $num_parts = count($partsName);
203 switch ($num_parts) {
204 case "2":
205 $firstName = $partsName[0];
206 $middleName = '';
207 $lastName = $partsName[1];
208 $suffixName = '';
209 break;
210 case "3":
211 $firstName = $partsName[0];
212 $middleName = $partsName[1];
213 $lastName = $partsName[2];
214 $suffixName = '';
215 break;
216 case "4":
217 $firstName = $partsName[0];
218 $middleName = $partsName[1];
219 $lastName = $partsName[2];
220 $suffixName = $partsName[3];
221 break;
222 default:
223 $log .= "*** billing provider name in 2010AA loop has more than 4 parts, may not be desirable\n";
224 $firstName = $partsName[0];
225 $middleName = $partsName[1];
226 $lastName = $partsName[2];
227 $suffixName = $partsName[3];
229 $out .= "NM1" .
230 "*85" .
231 "*1" .
232 "*" . $lastName .
233 "*" . $firstName .
234 "*" . $middleName .
235 "*" . // Name Prefix not used
236 "*" . $suffixName;
238 else {
239 $billingFacilityName = substr($claim->billingFacilityName(), 0, $CMS_5010 ? 60 : 35);
240 if ($billingFacilityName == '') $log .= "*** billing facility name in 2010A loop is empty\n";
241 $out .= "NM1" . // Loop 2010AA Billing Provider
242 "*85" .
243 "*2" .
244 "*" . $billingFacilityName .
245 "*" .
246 "*" .
247 "*" .
248 "*";
250 if ($claim->billingFacilityNPI()) {
251 $out .= "*XX*" . $claim->billingFacilityNPI();
253 else {
254 $log .= "*** Billing facility has no NPI.\n";
255 if ($CMS_5010) {
256 $out .= "*XX*";
258 else {
259 $out .= "*24*" . $claim->billingFacilityETIN();
262 $out .= "~\n";
264 ++$edicount;
265 $out .= "N3" .
266 "*" . $claim->billingFacilityStreet() .
267 "~\n";
269 ++$edicount;
270 $out .= "N4" .
271 "*" . $claim->billingFacilityCity() .
272 "*" . $claim->billingFacilityState() .
273 "*" . stripZipCode($claim->billingFacilityZip()) .
274 "~\n";
276 if ($CMS_5010 || ($claim->billingFacilityNPI() && $claim->billingFacilityETIN())) {
277 ++$edicount;
278 $out .= "REF" ;
279 if($claim->federalIdType()){
280 $out .= "*" . $claim->federalIdType();
282 else{
283 $out .= "*EI"; // For dealing with the situation before adding TaxId type In facility.
285 $out .= "*" . $claim->billingFacilityETIN() .
286 "~\n";
289 if ($claim->providerNumberType() && $claim->providerNumber() &&
290 !($CMS_5010 && $claim->billingFacilityNPI()))
292 ++$edicount;
293 $out .= "REF" .
294 "*" . $claim->providerNumberType() .
295 "*" . $claim->providerNumber() .
296 "~\n";
298 else if ($claim->providerNumber() && !$claim->providerNumberType()) {
299 $log .= "*** Payer-specific provider insurance number is present but has no type assigned.\n";
302 // Situational PER*1C segment omitted.
304 // Pay-To Address defaults to billing provider and is no longer required in 5010.
305 if (!$CMS_5010) {
306 ++$edicount;
307 // Field length is limited to 35. See nucc dataset page 63 www.nucc.org
308 $billingFacilityName = substr($claim->billingFacilityName(), 0, $CMS_5010 ? 60 : 35);
309 $out .= "NM1" . // Loop 2010AB Pay-To Provider
310 "*87" .
311 "*2" .
312 "*" . $billingFacilityName .
313 "*" .
314 "*" .
315 "*" .
316 "*";
317 if ($claim->billingFacilityNPI())
318 $out .= "*XX*" . $claim->billingFacilityNPI();
319 else
320 $out .= "*24*" . $claim->billingFacilityETIN();
321 $out .= "~\n";
323 ++$edicount;
324 $out .= "N3" .
325 "*" . $claim->billingFacilityStreet() .
326 "~\n";
328 ++$edicount;
329 $out .= "N4" .
330 "*" . $claim->billingFacilityCity() .
331 "*" . $claim->billingFacilityState() .
332 "*" . stripZipCode($claim->billingFacilityZip()) .
333 "~\n";
335 if ($claim->billingFacilityNPI() && $claim->billingFacilityETIN()) {
336 ++$edicount;
337 $out .= "REF" .
338 "*EI" .
339 "*" . $claim->billingFacilityETIN() .
340 "~\n";
344 // Loop 2010AC Pay-To Plan Name omitted. Includes:
345 // NM1*PE, N3, N4, REF*2U, REF*EI
347 $PatientHL = $claim->isSelfOfInsured() ? 0 : 1;
348 $HLSubscriber = $HLcount++;
350 ++$edicount;
351 $out .= "HL" . // Loop 2000B Subscriber HL Loop
352 "*$HLSubscriber" .
353 "*$HLBillingPayToProvider" .
354 "*22" .
355 "*$PatientHL" .
356 "~\n";
358 if (!$claim->payerSequence()) {
359 $log .= "*** Error: Insurance information is missing!\n";
362 ++$edicount;
363 $out .= "SBR" . // Subscriber Information
364 "*" . $claim->payerSequence() .
365 "*" . ($claim->isSelfOfInsured() ? '18' : '') .
366 "*" . $claim->groupNumber() .
367 "*" . (($CMS_5010 && $claim->groupNumber()) ? '' : $claim->groupName()) .
368 "*" . $claim->insuredTypeCode() . // applies for secondary medicare
369 "*" .
370 "*" .
371 "*" .
372 "*" . $claim->claimType() . // Zirmed replaces this
373 "~\n";
375 // Segment PAT omitted.
377 ++$edicount;
378 $out .= "NM1" . // Loop 2010BA Subscriber
379 "*IL" .
380 "*1" . // 1 = person, 2 = non-person
381 "*" . $claim->insuredLastName() .
382 "*" . $claim->insuredFirstName() .
383 "*" . $claim->insuredMiddleName() .
384 "*" .
385 "*" . // Name Suffix
386 "*MI" .
387 // "MI" = Member Identification Number
388 // "II" = Standard Unique Health Identifier, "Required if the
389 // HIPAA Individual Patient Identifier is mandated use."
390 // Here we presume that is not true yet.
391 "*" . $claim->policyNumber() .
392 "~\n";
394 // For 5010, further subscriber info is sent only if they are the patient.
395 if (!$CMS_5010 || $claim->isSelfOfInsured()) {
396 ++$edicount;
397 $out .= "N3" .
398 "*" . $claim->insuredStreet() .
399 "~\n";
401 ++$edicount;
402 $out .= "N4" .
403 "*" . $claim->insuredCity() .
404 "*" . $claim->insuredState() .
405 "*" . stripZipCode($claim->insuredZip()) .
406 "~\n";
408 ++$edicount;
409 $out .= "DMG" .
410 "*D8" .
411 "*" . $claim->insuredDOB() .
412 "*" . $claim->insuredSex() .
413 "~\n";
416 // Segment REF*SY (Subscriber Secondary Identification) omitted.
417 // Segment REF*Y4 (Property and Casualty Claim Number) omitted.
418 // Segment PER*IC (Property and Casualty Subscriber Contact Information) omitted.
420 ++$edicount;
421 //Field length is limited to 35. See nucc dataset page 81 www.nucc.org
422 $payerName = substr($claim->payerName(), 0, $CMS_5010 ? 60 : 35);
423 $out .= "NM1" . // Loop 2010BB Payer
424 "*PR" .
425 "*2" .
426 "*" . $payerName .
427 "*" .
428 "*" .
429 "*" .
430 "*" .
431 // The 5010 spec says:
432 // "On or after the mandated implementation date for the HIPAA
433 // National Plan Identifier (National Plan ID), XV must be sent.
434 // Prior to the mandated implementation date and prior to any phase-
435 // in period identified by Federal regulation, PI must be sent."
436 // *************** Anybody know what that date is? ***************
437 // August 2011 - Publish interim final rule
438 // October 1, 2012-March 31, 2013 - Enumeration
439 // April 1, 2013-September 30, 2013 - Testing
440 // October 1, 2013 - Implementation
442 "*PI" .
443 // Zirmed ignores this if using payer name matching:
444 "*" . ($encounter_claim ? $claim->payerAltID() : $claim->payerID()) .
445 "~\n";
447 // if (!$claim->payerID()) {
448 // $log .= "*** CMS ID is missing for payer '" . $claim->payerName() . "'.\n";
449 // }
451 if (true) { // !$CMS_5010
452 // The 5010 spec says:
453 // "Required when the payer address is available and the submitter intends
454 // for the claim to be printed on paper at the next EDI location (for example, a
455 // clearinghouse). If not required by this implementation guide, do not send."
457 ++$edicount;
458 $out .= "N3" .
459 "*" . $claim->payerStreet() .
460 "~\n";
462 ++$edicount;
463 $out .= "N4" .
464 "*" . $claim->payerCity() .
465 "*" . $claim->payerState() .
466 "*" . stripZipCode($claim->payerZip()) .
467 "~\n";
470 // Segment REF (Payer Secondary Identification) omitted.
471 // Segment REF (Billing Provider Secondary Identification) omitted.
473 if (! $claim->isSelfOfInsured()) {
474 ++$edicount;
475 $out .= "HL" . // Loop 2000C Patient Information
476 "*$HLcount" .
477 "*$HLSubscriber" .
478 "*23" .
479 "*0" .
480 "~\n";
482 $HLcount++;
484 ++$edicount;
485 $out .= "PAT" .
486 "*" . $claim->insuredRelationship() .
487 "~\n";
489 ++$edicount;
490 $out .= "NM1" . // Loop 2010CA Patient
491 "*QC" .
492 "*1" .
493 "*" . $claim->patientLastName() .
494 "*" . $claim->patientFirstName();
495 if ($claim->patientMiddleName() !== '') $out .= "*"
496 . $claim->patientMiddleName();
497 $out .= "~\n";
499 ++$edicount;
500 $out .= "N3" .
501 "*" . $claim->patientStreet() .
502 "~\n";
504 ++$edicount;
505 $out .= "N4" .
506 "*" . $claim->patientCity() .
507 "*" . $claim->patientState() .
508 "*" . stripZipCode($claim->patientZip()) .
509 "~\n";
511 ++$edicount;
512 $out .= "DMG" .
513 "*D8" .
514 "*" . $claim->patientDOB() .
515 "*" . $claim->patientSex() .
516 "~\n";
518 // Segment REF*Y4 (Property and Casualty Claim Number) omitted.
519 // Segment REF (Property and Casualty Patient Identifier) omitted.
520 // Segment PER (Property and Casualty Patient Contact Information) omitted.
522 } // end of patient different from insured
524 $proccount = $claim->procCount();
526 $clm_total_charges = 0;
527 for ($prockey = 0; $prockey < $proccount; ++$prockey) {
528 $clm_total_charges += $claim->cptCharges($prockey);
531 if (!$clm_total_charges) {
532 $log .= "*** This claim has no charges!\n";
535 ++$edicount;
536 $out .= "CLM" . // Loop 2300 Claim
537 "*$pid-$encounter" .
538 "*" . sprintf("%.2f",$clm_total_charges) . // Zirmed computes and replaces this
539 "*" .
540 "*" .
541 "*" . sprintf('%02d', $claim->facilityPOS()) . ":" .
542 ($CMS_5010 ? "B" : "") . ":" .
543 $claim->frequencyTypeCode() . // Changed to correct single digit output
544 "*Y" .
545 "*A" .
546 "*" . ($claim->billingFacilityAssignment() ? 'Y' : 'N') .
547 "*Y" .
548 ($CMS_5010 ? "" : "*C") .
549 "~\n";
551 if ($claim->onsetDate() &&
552 ($claim->onsetDate()!== $claim->serviceDate()) &&
553 ($claim->onsetDateValid())
555 ++$edicount;
556 $out .= "DTP" . // Date of Onset
557 "*431" .
558 "*D8" .
559 "*" . $claim->onsetDate() .
560 "~\n";
563 // above is for historical use of encounter onset date, now in misc_billing_options
564 // Segment DTP*431 (Onset of Current Symptoms or Illness)
565 // Segment DTP*484 (Last Menstrual Period Date)
567 if ($claim->miscOnsetDate() &&
568 ($claim->box14Qualifier()) &&
569 ($claim->miscOnsetDateValid())) {
570 ++$edicount;
571 $out .= "DTP" . // Date Last Seen
572 "*" . $claim->box14Qualifier() .
573 "*D8" .
574 "*" . $claim->miscOnsetDate() .
575 "~\n";
578 // Segment DTP*454 (Initial Treatment Date)
579 // Segment DTP*304 (Last Seen Date)
580 // Segment DTP*453 (Acute Manifestation Date)
581 // Segment DTP*439 (Accident Date)
582 // Segment DTP*455 (Last X-Ray Date)
583 // Segment DTP*471 (Hearing and Vision Prescription Date)
584 // Segment DTP*314 (Disability) omitted.
585 // Segment DTP*360 (Initial Disability Period Start) omitted.
586 // Segment DTP*361 (Initial Disability Period End) omitted.
587 // Segment DTP*297 (Last Worked Date)
588 // Segment DTP*296 (Authorized Return to Work Date)
590 if ($claim->dateInitialTreatment() &&
591 ($claim->box15Qualifier()) &&
592 ($claim->dateInitialTreatmentValid())){
593 ++$edicount;
594 $out .= "DTP" . // Date Last Seen
595 "*" . $claim->box15Qualifier() .
596 "*D8" .
597 "*" . $claim->dateInitialTreatment() .
598 "~\n";
601 if (strcmp($claim->facilityPOS(),'21') == 0 && $claim->onsetDateValid() ) {
602 ++$edicount;
603 $out .= "DTP" . // Date of Hospitalization
604 "*435" .
605 "*D8" .
606 "*" . $claim->onsetDate() .
607 "~\n";
610 // above is for historical use of encounter onset date, now in misc_billing_options
611 if (strcmp($claim->facilityPOS(),'21') == 0 && $claim->hospitalizedFromDateValid() ) {
612 ++$edicount;
613 $out .= "DTP" . // Date of Admission
614 "*435" .
615 "*D8" .
616 "*" . $claim->hospitalizedFrom() .
617 "~\n";
620 // Segment DTP*096 (Discharge Date)
621 if (strcmp($claim->facilityPOS(),'21') == 0 && $claim->hospitalizedToDateValid() ) {
622 ++$edicount;
623 $out .= "DTP" . // Date of Discharge
624 "*96" .
625 "*D8" .
626 "*" . $claim->hospitalizedTo() .
627 "~\n";
630 // Segments DTP (Assumed and Relinquished Care Dates) omitted.
631 // Segment DTP*444 (Property and Casualty Date of First Contact) omitted.
632 // Segment DTP*050 (Repricer Received Date) omitted.
633 // Segment PWK (Claim Supplemental Information) omitted.
634 // Segment CN1 (Contract Information) omitted.
636 $patientpaid = $claim->patientPaidAmount();
637 if ($patientpaid != 0) {
638 ++$edicount;
639 $out .= "AMT" . // Patient paid amount. Page 190/220.
640 "*F5" .
641 "*" . $patientpaid .
642 "~\n";
645 // Segment REF*4N (Service Authorization Exception Code) omitted.
646 // Segment REF*F5 (Mandatory Medicare Crossover Indicator) omitted.
647 // Segment REF*EW (Mammography Certification Number) omitted.
648 // Segment REF*9F (Referral Number) omitted.
650 if ($claim->priorAuth()) {
651 ++$edicount;
652 $out .= "REF" . // Prior Authorization Number
653 "*G1" .
654 "*" . $claim->priorAuth() .
655 "~\n";
658 // Segment REF*F8 Payer Claim Control Number for claim re-submission.icn_resubmission_number
660 #if($claim->billing_options['replacement_claim'] == '1'){
661 if(trim($claim->billing_options['icn_resubmission_number']) > 3){
662 ++$edicount;
663 error_log("Method 1: ".$claim->billing_options['icn_resubmission_number'], 0);
664 $out .= "REF" .
665 "*F8" .
666 "*" . $claim->icnResubmissionNumber() .
667 "~\n";
671 if ($claim->cliaCode() && ($CMS_5010 || $claim->claimType() === 'MB')) {
672 // Required by Medicare when in-house labs are done.
673 ++$edicount;
674 $out .= "REF" . // Clinical Laboratory Improvement Amendment Number
675 "*X4" .
676 "*" . $claim->cliaCode() .
677 "~\n";
680 // Segment REF*9A (Repriced Claim Number) omitted.
681 // Segment REF*9C (Adjusted Repriced Claim Number) omitted.
682 // Segment REF*LX (Investigational Device Exemption Number) omitted.
683 // Segment REF*D9 (Claim Identifier for Transmission Intermediaries) omitted.
684 // Segment REF*EA (Medical Record Number) omitted.
685 // Segment REF*P4 (Demonstration Project Identifier) omitted.
686 // Segment REF*1J (Care Plan Oversight) omitted.
687 // Segment K3 (File Information) omitted.
689 if ($claim->additionalNotes()) {
690 // Claim note.
691 ++$edicount;
692 $out .= "NTE" . // comments box 19
693 "*" . ($CMS_5010 ? "ADD" : "") .
694 "*" . $claim->additionalNotes() .
695 "~\n";
698 // Segment CR1 (Ambulance Transport Information) omitted.
699 // Segment CR2 (Spinal Manipulation Service Information) omitted.
700 // Segment CRC (Ambulance Certification) omitted.
701 // Segment CRC (Patient Condition Information: Vision) omitted.
702 // Segment CRC (Homebound Indicator) omitted.
704 // Segment CRC (EPSDT Referral).
705 if($claim->epsdtFlag()) {
706 ++$edicount;
707 $out .= "CRC" .
708 "*ZZ" .
709 "*Y" .
710 "*" . $claim->medicaidReferralCode() .
711 "~\n";
714 // Diagnoses, up to $max_per_seg per HI segment.
715 $max_per_seg = $CMS_5010 ? 12 : 8;
716 $da = $claim->diagArray();
717 if ($claim->diagtype == "ICD9") {
718 $diag_type_code = 'BK';
720 else
722 $diag_type_code = 'ABK';
724 $tmp = 0;
725 foreach ($da as $diag) {
726 if ($tmp % $max_per_seg == 0) {
727 if ($tmp) $out .= "~\n";
728 ++$edicount;
729 $out .= "HI"; // Health Diagnosis Codes
731 $out .= "*$diag_type_code:" . $diag;
732 if ($claim->diagtype == "ICD9") {
733 $diag_type_code = 'BF';
735 else
737 $diag_type_code = 'ABF';
739 ++$tmp;
741 if ($tmp) $out .= "~\n";
743 // Segment HI*BP (Anesthesia Related Procedure) omitted.
744 // Segment HI*BG (Condition Information) omitted.
745 // Segment HCP (Claim Pricing/Repricing Information) omitted.
747 if ($claim->referrerLastName()) {
748 // Medicare requires referring provider's name and UPIN.
749 ++$edicount;
750 $out .= "NM1" . // Loop 2310A Referring Provider
751 "*DN" .
752 "*1" .
753 "*" . $claim->referrerLastName() .
754 "*" . $claim->referrerFirstName() .
755 "*" . $claim->referrerMiddleName() .
756 "*" .
757 "*";
758 if ($CMS_5010 || $claim->referrerNPI()) { $out .=
759 "*XX" .
760 "*" . $claim->referrerNPI();
761 } else { $out .=
762 "*34" . // not allowed for 5010
763 "*" . $claim->referrerSSN();
765 $out .= "~\n";
767 if (!$CMS_5010 && $claim->referrerTaxonomy()) {
768 ++$edicount;
769 $out .= "PRV" .
770 "*RF" . // ReFerring provider
771 "*ZZ" .
772 "*" . $claim->referrerTaxonomy() .
773 "~\n";
776 if (!CMS_5010 && $claim->referrerUPIN()) {
777 ++$edicount;
778 $out .= "REF" . // Referring Provider Secondary Identification
779 "*1G" .
780 "*" . $claim->referrerUPIN() .
781 "~\n";
786 /* Per the implementation guide lines, only include this information if it is different
787 * than the Loop 2010AA information
789 if(!$CMS_5010 ||
790 ($claim->providerNPIValid() &&
791 $claim->billingFacilityNPI() !== $claim->providerNPI() ))
793 ++$edicount;
794 $out .= "NM1" . // Loop 2310B Rendering Provider
795 "*82" .
796 "*1" .
797 "*" . $claim->providerLastName() .
798 "*" . $claim->providerFirstName() .
799 "*" . $claim->providerMiddleName() .
800 "*" .
801 "*";
802 if ($CMS_5010 || $claim->providerNPI()) { $out .=
803 "*XX" .
804 "*" . $claim->providerNPI();
805 } else { $out .=
806 "*34" . // not allowed for 5010
807 "*" . $claim->providerSSN();
808 $log .= "*** Rendering provider has no NPI.\n";
810 $out .= "~\n";
812 if ($claim->providerTaxonomy()) {
813 ++$edicount;
814 $out .= "PRV" .
815 "*PE" . // Performing provider
816 "*" .($claim->claimType() != 'MC' ? "PXC" : "ZZ") .
817 "*" . $claim->providerTaxonomy() .
818 "~\n";
820 // End of Loop 2310B
822 else
824 // This loop can only get skipped if we are generating a 5010 claim
825 if(!($claim->providerNPIValid()))
827 /* If the loop was skipped because the provider NPI was invalid, generate
828 * a warning for the log.*/
829 $log.="*** Skipping 2310B because ".$claim->providerLastName() ."," . $claim->providerFirstName() . " has invalid NPI.\n";
831 /* Skipping this segment because the providerNPI and the billingFacilityNPI are identical
832 * is a normal condition, so no need to warn.
837 // 4010: REF*1C is required here for the Medicare provider number if NPI was
838 // specified in NM109. Not sure if other payers require anything here.
839 // --- apparently ECLAIMS, INC wants the data in 2010 but NOT in 2310B - tony@mi-squared.com
841 // 5010 spec says nothing here if NPI was specified.
843 if (($CMS_5010 && !$claim->providerNPI() && in_array($claim->providerNumberType(), array('0B','1G','G2','LU')))
844 || (!$CMS_5010 && trim($claim->x12gsreceiverid()) != '470819582')) // if NOT ECLAIMS EDI
846 if ($claim->providerNumber()) {
847 ++$edicount;
848 $out .= "REF" .
849 "*" . $claim->providerNumberType() .
850 "*" . $claim->providerNumber() .
851 "~\n";
855 // Loop 2310D is omitted in the case of home visits (POS=12).
856 if ($claim->facilityPOS() != 12 && (!$CMS_5010 ||
857 ($claim->facilityNPI() != $claim->billingFacilityNPI() ||
858 ($claim->facilityNPI() == $claim->billingFacilityNPI() &&
859 $claim->facilityStreet() != $claim->billingFacilityStreet()))))
861 ++$edicount;
862 $out .= "NM1" . // Loop 2310D Service Location
863 "*77" .
864 "*2";
865 //Field length is limited to 35. See nucc dataset page 77 www.nucc.org
866 $facilityName = substr($claim->facilityName(), 0, $CMS_5010 ? 60 : 35);
867 if ($claim->facilityName() || $claim->facilityNPI() || $claim->facilityETIN()) { $out .=
868 "*" . $facilityName;
870 if ($claim->facilityNPI() || $claim->facilityETIN()) { $out .=
871 "*" .
872 "*" .
873 "*" .
874 "*";
875 if ($CMS_5010 || $claim->facilityNPI()) { $out .=
876 "*XX*" . $claim->facilityNPI();
877 } else { $out .=
878 "*24*" . $claim->facilityETIN();
880 if (!$claim->facilityNPI()) {
881 $log .= "*** Service location has no NPI.\n";
884 $out .= "~\n";
885 if ($claim->facilityStreet()) {
886 ++$edicount;
887 $out .= "N3" .
888 "*" . $claim->facilityStreet() .
889 "~\n";
891 if ($claim->facilityState()) {
892 ++$edicount;
893 $out .= "N4" .
894 "*" . $claim->facilityCity() .
895 "*" . $claim->facilityState() .
896 "*" . stripZipCode($claim->facilityZip()) .
897 "~\n";
901 // Segment REF (Service Facility Location Secondary Identification) omitted.
902 // Segment PER (Service Facility Contact Information) omitted.
904 // Loop 2310E, Supervising Provider
906 if ($claim->supervisorLastName()) {
907 ++$edicount;
908 $out .= "NM1" .
909 "*DQ" . // Supervising Physician
910 "*1" . // Person
911 "*" . $claim->supervisorLastName() .
912 "*" . $claim->supervisorFirstName() .
913 "*" . $claim->supervisorMiddleName() .
914 "*" . // NM106 not used
915 "*"; // Name Suffix
916 if ($CMS_5010 || $claim->supervisorNPI()) { $out .=
917 "*XX" .
918 "*" . $claim->supervisorNPI();
919 } else { $out .=
920 "*34" .
921 "*" . $claim->supervisorSSN();
923 if (!$claim->supervisorNPI()) {
924 $log .= "*** Supervising Provider has no NPI.\n";
926 $out .= "~\n";
928 if ($claim->supervisorNumber()) {
929 ++$edicount;
930 $out .= "REF" .
931 "*" . $claim->supervisorNumberType() .
932 "*" . $claim->supervisorNumber() .
933 "~\n";
937 // Segments NM1*PW, N3, N4 (Ambulance Pick-Up Location) omitted.
938 // Segments NM1*45, N3, N4 (Ambulance Drop-Off Location) omitted.
940 $prev_pt_resp = $clm_total_charges; // for computation below
942 // Loops 2320 and 2330*, other subscriber/payer information.
943 // Remember that insurance index 0 is always for the payer being billed
944 // by this claim, and 1 and above are always for the "other" payers.
946 for ($ins = 1; $ins < $claim->payerCount(); ++$ins) {
948 $tmp1 = $claim->claimType($ins);
949 $tmp2 = 'C1'; // Here a kludge. See page 321.
950 if ($tmp1 === 'CI') $tmp2 = 'C1';
951 if ($tmp1 === 'AM') $tmp2 = 'AP';
952 if ($tmp1 === 'HM') $tmp2 = 'HM';
953 if ($tmp1 === 'MB') $tmp2 = 'MB';
954 if ($tmp1 === 'MC') $tmp2 = 'MC';
955 if ($tmp1 === '09') $tmp2 = 'PP';
956 ++$edicount;
957 $out .= "SBR" . // Loop 2320, Subscriber Information - page 297/318
958 "*" . $claim->payerSequence($ins) .
959 "*" . $claim->insuredRelationship($ins) .
960 "*" . $claim->groupNumber($ins) .
961 "*" . (($CMS_5010 && $claim->groupNumber($ins)) ? '' : $claim->groupName($ins)) .
962 "*" . ($CMS_5010 ? $claim->insuredTypeCode($ins) : $tmp2) .
963 "*" .
964 "*" .
965 "*" .
966 "*" . $claim->claimType($ins) .
967 "~\n";
969 // Things that apply only to previous payers, not future payers.
971 if ($claim->payerSequence($ins) < $claim->payerSequence()) {
973 // Generate claim-level adjustments.
974 $aarr = $claim->payerAdjustments($ins);
975 foreach ($aarr as $a) {
976 ++$edicount;
977 $out .= "CAS" . // Previous payer's claim-level adjustments. Page 301/323.
978 "*" . $a[1] .
979 "*" . $a[2] .
980 "*" . $a[3] .
981 "~\n";
984 $payerpaid = $claim->payerTotals($ins);
985 ++$edicount;
986 $out .= "AMT" . // Previous payer's paid amount. Page 307/332.
987 "*D" .
988 "*" . $payerpaid[1] .
989 "~\n";
991 // Segment AMT*A8 (COB Total Non-Covered Amount) omitted.
992 // Segment AMT*EAF (Remaining Patient Liability) omitted.
994 if (!$CMS_5010) {
995 // Patient responsibility amount as of this previous payer.
996 $prev_pt_resp -= $payerpaid[1]; // reduce by payments
997 $prev_pt_resp -= $payerpaid[2]; // reduce by adjustments
999 ++$edicount;
1000 $out .= "AMT" . // Allowed amount per previous payer. Page 334.
1001 "*B6" .
1002 "*" . sprintf('%.2f', $payerpaid[1] + $prev_pt_resp) .
1003 "~\n";
1005 ++$edicount;
1006 $out .= "AMT" . // Patient responsibility amount per previous payer. Page 335.
1007 "*F2" .
1008 "*" . sprintf('%.2f', $prev_pt_resp) .
1009 "~\n";
1011 } // End of things that apply only to previous payers.
1013 if (!$CMS_5010) {
1014 ++$edicount;
1015 $out .= "DMG" . // Other subscriber demographic information. Page 342.
1016 "*D8" .
1017 "*" . $claim->insuredDOB($ins) .
1018 "*" . $claim->insuredSex($ins) .
1019 "~\n";
1022 ++$edicount;
1023 $out .= "OI" . // Other Insurance Coverage Information. Page 310/344.
1024 "*" .
1025 "*" .
1026 "*" . ($claim->billingFacilityAssignment($ins) ? 'Y' : 'N') .
1027 // For this next item, the 5010 example in the spec does not match its
1028 // description. So this might be wrong.
1029 "*" . ($CMS_5010 ? '' : 'B') .
1030 "*" .
1031 "*Y" .
1032 "~\n";
1034 // Segment MOA (Medicare Outpatient Adjudication) omitted.
1036 ++$edicount;
1037 $out .= "NM1" . // Loop 2330A Subscriber info for other insco. Page 315/350.
1038 "*IL" .
1039 "*1" .
1040 "*" . $claim->insuredLastName($ins) .
1041 "*" . $claim->insuredFirstName($ins) .
1042 "*" . $claim->insuredMiddleName($ins) .
1043 "*" .
1044 "*" .
1045 "*MI" .
1046 "*" . $claim->policyNumber($ins) .
1047 "~\n";
1049 ++$edicount;
1050 $out .= "N3" .
1051 "*" . $claim->insuredStreet($ins) .
1052 "~\n";
1054 ++$edicount;
1055 $out .= "N4" .
1056 "*" . $claim->insuredCity($ins) .
1057 "*" . $claim->insuredState($ins) .
1058 "*" . stripZipCode($claim->insuredZip($ins)) .
1059 "~\n";
1061 // Segment REF (Other Subscriber Secondary Identification) omitted.
1063 ++$edicount;
1064 //Field length is limited to 35. See nucc dataset page 81 www.nucc.org
1065 $payerName = substr($claim->payerName($ins), 0, $CMS_5010 ? 60 : 35);
1066 $out .= "NM1" . // Loop 2330B Payer info for other insco. Page 322/359.
1067 "*PR" .
1068 "*2" .
1069 "*" . $payerName .
1070 "*" .
1071 "*" .
1072 "*" .
1073 "*" .
1074 "*PI" .
1075 "*" . $claim->payerID($ins) .
1076 "~\n";
1078 // if (!$claim->payerID($ins)) {
1079 // $log .= "*** CMS ID is missing for payer '" . $claim->payerName($ins) . "'.\n";
1080 // }
1082 // Payer address (N3 and N4) are added below so that Gateway EDI can
1083 // auto-generate secondary claims. These do NOT appear in my copy of
1084 // the spec! -- Rod 2008-06-12
1086 if ($CMS_5010 || trim($claim->x12gsreceiverid()) == '431420764') { // if Gateway EDI
1087 ++$edicount;
1088 $out .= "N3" .
1089 "*" . $claim->payerStreet($ins) .
1090 "~\n";
1092 ++$edicount;
1093 $out .= "N4" .
1094 "*" . $claim->payerCity($ins) .
1095 "*" . $claim->payerState($ins) .
1096 "*" . stripZipCode($claim->payerZip($ins)) .
1097 "~\n";
1098 } // end Gateway EDI
1100 // Segment DTP*573 (Claim Check or Remittance Date) omitted.
1101 // Segment REF (Other Payer Secondary Identifier) omitted.
1102 // Segment REF*G1 (Other Payer Prior Authorization Number) omitted.
1103 // Segment REF*9F (Other Payer Referral Number) omitted.
1104 // Segment REF*T4 (Other Payer Claim Adjustment Indicator) omitted.
1105 // Segment REF*F8 (Other Payer Claim Control Number) omitted.
1106 // Segment NM1 (Other Payer Referring Provider) omitted.
1107 // Segment REF (Other Payer Referring Provider Secondary Identification) omitted.
1108 // Segment NM1 (Other Payer Rendering Provider) omitted.
1109 // Segment REF (Other Payer Rendering Provider Secondary Identification) omitted.
1110 // Segment NM1 (Other Payer Service Facility Location) omitted.
1111 // Segment REF (Other Payer Service Facility Location Secondary Identification) omitted.
1112 // Segment NM1 (Other Payer Supervising Provider) omitted.
1113 // Segment REF (Other Payer Supervising Provider Secondary Identification) omitted.
1114 // Segment NM1 (Other Payer Billing Provider) omitted.
1115 // Segment REF (Other Payer Billing Provider Secondary Identification) omitted.
1117 } // End loops 2320/2330*.
1119 $loopcount = 0;
1121 // Procedure loop starts here.
1123 for ($prockey = 0; $prockey < $proccount; ++$prockey) {
1124 ++$loopcount;
1126 ++$edicount;
1127 $out .= "LX" . // Loop 2400 LX Service Line. Page 398.
1128 "*$loopcount" .
1129 "~\n";
1131 ++$edicount;
1132 $out .= "SV1" . // Professional Service. Page 400.
1133 "*HC:" . $claim->cptKey($prockey) .
1134 "*" . sprintf('%.2f', $claim->cptCharges($prockey)) .
1135 "*UN" .
1136 "*" . $claim->cptUnits($prockey) .
1137 "*" .
1138 "*" .
1139 "*";
1140 $dia = $claim->diagIndexArray($prockey);
1141 $i = 0;
1142 foreach ($dia as $dindex) {
1143 if ($i) $out .= ':';
1144 $out .= $dindex;
1145 if (++$i >= 4) break;
1147 # needed for epstd
1148 if($claim->epsdtFlag()) {
1149 $out .= "*" .
1150 "*" .
1151 "*" .
1152 "*Y" .
1153 "~\n";
1155 else
1157 $out .= "~\n";
1160 if (!$claim->cptCharges($prockey)) {
1161 $log .= "*** Procedure '" . $claim->cptKey($prockey) . "' has no charges!\n";
1164 if (empty($dia)) {
1165 $log .= "*** Procedure '" . $claim->cptKey($prockey) . "' is not justified!\n";
1168 // Segment SV5 (Durable Medical Equipment Service) omitted.
1169 // Segment PWK (Line Supplemental Information) omitted.
1170 // Segment PWK (Durable Medical Equipment Certificate of Medical Necessity Indicator) omitted.
1171 // Segment CR1 (Ambulance Transport Information) omitted.
1172 // Segment CR3 (Durable Medical Equipment Certification) omitted.
1173 // Segment CRC (Ambulance Certification) omitted.
1174 // Segment CRC (Hospice Employee Indicator) omitted.
1175 // Segment CRC (Condition Indicator / Durable Medical Equipment) omitted.
1177 ++$edicount;
1178 $out .= "DTP" . // Date of Service. Page 435.
1179 "*472" .
1180 "*D8" .
1181 "*" . $claim->serviceDate() .
1182 "~\n";
1184 $testnote = rtrim($claim->cptNotecodes($prockey));
1185 if (!empty($testnote)) {
1186 ++$edicount;
1187 $out .= "NTE" . // Explain Unusual Circumstances.
1188 "*ADD" .
1189 "*" . $claim->cptNotecodes($prockey) .
1190 "~\n";
1193 // Segment DTP*471 (Prescription Date) omitted.
1194 // Segment DTP*607 (Revision/Recertification Date) omitted.
1195 // Segment DTP*463 (Begin Therapy Date) omitted.
1196 // Segment DTP*461 (Last Certification Date) omitted.
1197 // Segment DTP*304 (Last Seen Date) omitted.
1198 // Segment DTP (Test Date) omitted.
1199 // Segment DTP*011 (Shipped Date) omitted.
1200 // Segment DTP*455 (Last X-Ray Date) omitted.
1201 // Segment DTP*454 (Initial Treatment Date) omitted.
1202 // Segment QTY (Ambulance Patient Count) omitted.
1203 // Segment QTY (Obstetric Anesthesia Additional Units) omitted.
1204 // Segment MEA (Test Result) omitted.
1205 // Segment CN1 (Contract Information) omitted.
1206 // Segment REF*9B (Repriced Line Item Reference Number) omitted.
1207 // Segment REF*9D (Adjusted Repriced Line Item Reference Number) omitted.
1208 // Segment REF*G1 (Prior Authorization) omitted.
1209 // Segment REF*6R (Line Item Control Number) omitted.
1210 // (Really oughta have this for robust 835 posting!)
1211 // Segment REF*EW (Mammography Certification Number) omitted.
1212 // Segment REF*X4 (CLIA Number) omitted.
1213 // Segment REF*F4 (Referring CLIA Facility Identification) omitted.
1214 // Segment REF*BT (Immunization Batch Number) omitted.
1215 // Segment REF*9F (Referral Number) omitted.
1216 // Segment AMT*T (Sales Tax Amount) omitted.
1217 // Segment AMT*F4 (Postage Claimed Amount) omitted.
1218 // Segment K3 (File Information) omitted.
1219 // Segment NTE (Line Note) omitted.
1220 // Segment NTE (Third Party Organization Notes) omitted.
1221 // Segment PS1 (Purchased Service Information) omitted.
1222 // Segment HCP (Line Pricing/Repricing Information) omitted.
1224 if (!$CMS_5010) {
1225 // This segment was deleted for 5010.
1227 // AMT*AAE segment for Approved Amount from previous payer.
1228 // Medicare secondaries seem to require this.
1230 for ($ins = $claim->payerCount() - 1; $ins > 0; --$ins) {
1231 if ($claim->payerSequence($ins) > $claim->payerSequence())
1232 continue; // payer is future, not previous
1233 $payerpaid = $claim->payerTotals($ins, $claim->cptKey($prockey));
1234 ++$edicount;
1235 $out .= "AMT" . // Approved amount per previous payer. Page 485.
1236 "*AAE" .
1237 "*" . sprintf('%.2f', $claim->cptCharges($prockey) - $payerpaid[2]) .
1238 "~\n";
1239 break;
1243 // Loop 2410, Drug Information. Medicaid insurers seem to want this
1244 // with HCPCS codes.
1246 $ndc = $claim->cptNDCID($prockey);
1247 if ($ndc) {
1248 ++$edicount;
1249 $out .= "LIN" . // Drug Identification. Page 500+ (Addendum pg 71).
1250 "*" . // Per addendum, LIN01 is not used.
1251 "*N4" .
1252 "*" . $ndc .
1253 "~\n";
1255 if (!preg_match('/^\d\d\d\d\d-\d\d\d\d-\d\d$/', $ndc, $tmp) && !preg_match('/^\d{11}$/', $ndc)) {
1256 $log .= "*** NDC code '$ndc' has invalid format!\n";
1259 ++$edicount;
1260 $tmpunits = $claim->cptNDCQuantity($prockey) * $claim->cptUnits($prockey);
1261 if (!$tmpunits) $tmpunits = 1;
1262 $out .= "CTP" . // Drug Pricing. Page 500+ (Addendum pg 74).
1263 "*" .
1264 "*" .
1265 "*" . ($CMS_5010 ? '' : sprintf('%.2f', $claim->cptCharges($prockey) / $tmpunits)) .
1266 "*" . $claim->cptNDCQuantity($prockey) .
1267 "*" . $claim->cptNDCUOM($prockey) .
1268 // Note: 5010 documents "ME" (Milligrams) as an additional unit of measure.
1269 "~\n";
1272 // Segment REF (Prescription or Compound Drug Association Number) omitted.
1274 // Loop 2420A, Rendering Provider (service-specific).
1275 // Used if the rendering provider for this service line is different
1276 // from that in loop 2310B.
1278 if ($claim->providerNPI() != $claim->providerNPI($prockey)) {
1279 ++$edicount;
1280 $out .= "NM1" . // Loop 2310B Rendering Provider
1281 "*82" .
1282 "*1" .
1283 "*" . $claim->providerLastName($prockey) .
1284 "*" . $claim->providerFirstName($prockey) .
1285 "*" . $claim->providerMiddleName($prockey) .
1286 "*" .
1287 "*";
1288 if ($CMS_5010 || $claim->providerNPI($prockey)) { $out .=
1289 "*XX" .
1290 "*" . $claim->providerNPI($prockey);
1291 } else { $out .=
1292 "*34" . // Not allowed for 5010
1293 "*" . $claim->providerSSN($prockey);
1295 if (!$claim->providerNPI($prockey)) {
1296 $log .= "*** Rendering provider has no NPI.\n";
1298 $out .= "~\n";
1300 if ($claim->providerTaxonomy($prockey)) {
1301 ++$edicount;
1302 $out .= "PRV" .
1303 "*PE" . // PErforming provider
1304 "*" . ($CMS_5010 ? "PXC" : "ZZ") .
1305 "*" . $claim->providerTaxonomy($prockey) .
1306 "~\n";
1309 // Segment PRV*PE (Rendering Provider Specialty Information) omitted.
1310 // Segment REF (Rendering Provider Secondary Identification) omitted.
1311 // Segment NM1 (Purchased Service Provider Name) omitted.
1312 // Segment REF (Purchased Service Provider Secondary Identification) omitted.
1313 // Segment NM1,N3,N4 (Service Facility Location) omitted.
1314 // Segment REF (Service Facility Location Secondary Identification) omitted.
1315 // Segment NM1 (Supervising Provider Name) omitted.
1316 // Segment REF (Supervising Provider Secondary Identification) omitted.
1317 // Segment NM1,N3,N4 (Ordering Provider) omitted.
1318 // Segment REF (Ordering Provider Secondary Identification) omitted.
1319 // Segment PER (Ordering Provider Contact Information) omitted.
1320 // Segment NM1 (Referring Provider Name) omitted.
1321 // Segment REF (Referring Provider Secondary Identification) omitted.
1322 // Segments NM1*PW, N3, N4 (Ambulance Pick-Up Location) omitted.
1323 // Segments NM1*45, N3, N4 (Ambulance Drop-Off Location) omitted.
1325 // REF*1C is required here for the Medicare provider number if NPI was
1326 // specified in NM109. Not sure if other payers require anything here.
1327 if (!$CMS_5010 && $claim->providerNumber($prockey)) {
1328 ++$edicount;
1329 $out .= "REF" .
1330 "*" . $claim->providerNumberType($prockey) .
1331 // Note: 5010 documents that type 1D (Medicaid) is changed to G2.
1332 "*" . $claim->providerNumber($prockey) .
1333 "~\n";
1337 // Loop 2430, adjudication by previous payers.
1339 for ($ins = 1; $ins < $claim->payerCount(); ++$ins) {
1340 if ($claim->payerSequence($ins) > $claim->payerSequence())
1341 continue; // payer is future, not previous
1343 $payerpaid = $claim->payerTotals($ins, $claim->cptKey($prockey));
1344 $aarr = $claim->payerAdjustments($ins, $claim->cptKey($prockey));
1346 if ($payerpaid[1] == 0 && !count($aarr)) {
1347 $log .= "*** Procedure '" . $claim->cptKey($prockey) .
1348 "' has no payments or adjustments from previous payer!\n";
1349 continue;
1352 ++$edicount;
1353 $out .= "SVD" . // Service line adjudication. Page 554.
1354 "*" . $claim->payerID($ins) .
1355 "*" . $payerpaid[1] .
1356 "*HC:" . $claim->cptKey($prockey) .
1357 "*" .
1358 "*" . $claim->cptUnits($prockey) .
1359 "~\n";
1361 $tmpdate = $payerpaid[0];
1362 foreach ($aarr as $a) {
1363 ++$edicount;
1364 $out .= "CAS" . // Previous payer's line level adjustments. Page 558.
1365 "*" . $a[1] .
1366 "*" . $a[2] .
1367 "*" . $a[3] .
1368 "~\n";
1369 if (!$tmpdate) $tmpdate = $a[0];
1371 // WTH is this??
1372 /*************************************************************
1373 if ( isset($a[4]) &&
1374 $a[4] != null ) {
1375 $out .= "CAS02" . // Previous payer's adjustment reason
1376 "*" . $a[4] .
1377 "~\n";
1379 *************************************************************/
1382 if ($tmpdate) {
1383 ++$edicount;
1384 $out .= "DTP" . // Previous payer's line adjustment date. Page 493/566.
1385 "*573" .
1386 "*D8" .
1387 "*$tmpdate" .
1388 "~\n";
1391 // Segment AMT*EAF (Remaining Patient Liability) omitted.
1392 // Segment LQ (Form Identification Code) omitted.
1393 // Segment FRM (Supporting Documentation) omitted.
1395 } // end loop 2430
1396 } // end this procedure
1398 ++$edicount;
1399 $out .= "SE" . // SE Trailer
1400 "*$edicount" .
1401 "*0021" .
1402 "~\n";
1404 $out .= "GE" . // GE Trailer
1405 "*1" .
1406 "*1" .
1407 "~\n";
1409 $out .= "IEA" . // IEA Trailer
1410 "*1" .
1411 "*000000001" .
1412 "~\n";
1414 // Remove any trailing empty fields (delimiters) from each segment.
1415 $out = preg_replace('/\*+~/', '~', $out);
1417 $log .= "\n";
1418 return $out;