Merge pull request #956 to fix therapy groups permissions
[openemr.git] / library / gen_x12_837.inc.php
blobbbaff846ba2151d29b0f19adea650d29a1365dbf
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];
122 $out .= "NM1" . // Loop 1000A Submitter
123 "*41" .
124 "*1" .
125 "*" . $lastName .
126 "*" . $firstName .
127 "*" . $middleName .
128 "*" . // Name Prefix not used
129 "*" . // Name Suffix not used
130 "*46";
131 } else { //Field length is limited to 35. See nucc dataset page 63 www.nucc.org
132 $billingFacilityName = substr($claim->billingFacilityName(), 0, $CMS_5010 ? 60 : 35);
133 if ($billingFacilityName == '') {
134 $log .= "*** billing facility name in 1000A loop is empty\n";
137 $out .= "NM1" .
138 "*41" .
139 "*2" .
140 "*" . $billingFacilityName .
141 "*" .
142 "*" .
143 "*" .
144 "*" .
145 "*46";
148 if (trim($claim->x12gsreceiverid()) == '470819582') { // if ECLAIMS EDI
149 $out .= "*" . $claim->clearingHouseETIN();
150 } else {
151 $out .= "*" . $claim->billingFacilityETIN();
154 $out .= "~\n";
156 ++$edicount;
157 $out .= "PER" .
158 "*IC" .
159 "*" . $claim->billingContactName() .
160 "*TE" .
161 "*" . $claim->billingContactPhone();
162 if (!$CMS_5010 && $claim->x12gsper06()) {
163 $out .= "*ED*" . $claim->x12gsper06();
166 $out .= "~\n";
168 ++$edicount;
169 $out .= "NM1" . // Loop 1000B Receiver
170 "*40" .
171 "*2" .
172 "*" . $claim->clearingHouseName() .
173 "*" .
174 "*" .
175 "*" .
176 "*" .
177 "*46" .
178 "*" . $claim->clearingHouseETIN() .
179 "~\n";
181 $HLcount = 1;
183 ++$edicount;
184 $out .= "HL" . // Loop 2000A Billing/Pay-To Provider HL Loop
185 "*$HLcount" .
186 "*" .
187 "*20" .
188 "*1" . // 1 indicates there are child segments
189 "~\n";
191 $HLBillingPayToProvider = $HLcount++;
193 // Situational PRV segment for provider taxonomy code for Medicaid.
194 if ($claim->claimType() == 'MC') {
195 ++$edicount;
196 $out .= "PRV*BI*ZZ" .
197 "*" . $claim->providerTaxonomy() .
198 "~\n";
201 // Situational CUR segment (foreign currency information) omitted here.
203 ++$edicount;
204 //Field length is limited to 35. See nucc dataset page 63 www.nucc.org
205 if ($claim->federalIdType() == "SY") { // check for entity type like in 1000A
206 $tempName = $claim->billingFacilityName();
207 $partsName = explode(' ', $tempName);// Loop 2010AA Billing Provider entity == person
208 $num_parts = count($partsName);
209 switch ($num_parts) {
210 case "2":
211 $firstName = $partsName[0];
212 $middleName = '';
213 $lastName = $partsName[1];
214 $suffixName = '';
215 break;
216 case "3":
217 $firstName = $partsName[0];
218 $middleName = $partsName[1];
219 $lastName = $partsName[2];
220 $suffixName = '';
221 break;
222 case "4":
223 $firstName = $partsName[0];
224 $middleName = $partsName[1];
225 $lastName = $partsName[2];
226 $suffixName = $partsName[3];
227 break;
228 default:
229 $log .= "*** billing provider name in 2010AA loop has more than 4 parts, may not be desirable\n";
230 $firstName = $partsName[0];
231 $middleName = $partsName[1];
232 $lastName = $partsName[2];
233 $suffixName = $partsName[3];
236 $out .= "NM1" .
237 "*85" .
238 "*1" .
239 "*" . $lastName .
240 "*" . $firstName .
241 "*" . $middleName .
242 "*" . // Name Prefix not used
243 "*" . $suffixName;
244 } else {
245 $billingFacilityName = substr($claim->billingFacilityName(), 0, $CMS_5010 ? 60 : 35);
246 if ($billingFacilityName == '') {
247 $log .= "*** billing facility name in 2010A loop is empty\n";
250 $out .= "NM1" . // Loop 2010AA Billing Provider
251 "*85" .
252 "*2" .
253 "*" . $billingFacilityName .
254 "*" .
255 "*" .
256 "*" .
257 "*";
260 if ($claim->billingFacilityNPI()) {
261 $out .= "*XX*" . $claim->billingFacilityNPI();
262 } else {
263 $log .= "*** Billing facility has no NPI.\n";
264 if ($CMS_5010) {
265 $out .= "*XX*";
266 } else {
267 $out .= "*24*" . $claim->billingFacilityETIN();
271 $out .= "~\n";
273 ++$edicount;
274 $out .= "N3" .
275 "*" . $claim->billingFacilityStreet() .
276 "~\n";
278 ++$edicount;
279 $out .= "N4" .
280 "*" . $claim->billingFacilityCity() .
281 "*" . $claim->billingFacilityState() .
282 "*" . stripZipCode($claim->billingFacilityZip()) .
283 "~\n";
285 if ($CMS_5010 || ($claim->billingFacilityNPI() && $claim->billingFacilityETIN())) {
286 ++$edicount;
287 $out .= "REF" ;
288 if ($claim->federalIdType()) {
289 $out .= "*" . $claim->federalIdType();
290 } else {
291 $out .= "*EI"; // For dealing with the situation before adding TaxId type In facility.
294 $out .= "*" . $claim->billingFacilityETIN() .
295 "~\n";
298 if ($claim->providerNumberType() && $claim->providerNumber() &&
299 !($CMS_5010 && $claim->billingFacilityNPI())) {
300 ++$edicount;
301 $out .= "REF" .
302 "*" . $claim->providerNumberType() .
303 "*" . $claim->providerNumber() .
304 "~\n";
305 } else if ($claim->providerNumber() && !$claim->providerNumberType()) {
306 $log .= "*** Payer-specific provider insurance number is present but has no type assigned.\n";
309 // Situational PER*1C segment omitted.
311 // Pay-To Address defaults to billing provider and is no longer required in 5010.
312 if (!$CMS_5010) {
313 ++$edicount;
314 // Field length is limited to 35. See nucc dataset page 63 www.nucc.org
315 $billingFacilityName = substr($claim->billingFacilityName(), 0, $CMS_5010 ? 60 : 35);
316 $out .= "NM1" . // Loop 2010AB Pay-To Provider
317 "*87" .
318 "*2" .
319 "*" . $billingFacilityName .
320 "*" .
321 "*" .
322 "*" .
323 "*";
324 if ($claim->billingFacilityNPI()) {
325 $out .= "*XX*" . $claim->billingFacilityNPI();
326 } else {
327 $out .= "*24*" . $claim->billingFacilityETIN();
330 $out .= "~\n";
332 ++$edicount;
333 $out .= "N3" .
334 "*" . $claim->billingFacilityStreet() .
335 "~\n";
337 ++$edicount;
338 $out .= "N4" .
339 "*" . $claim->billingFacilityCity() .
340 "*" . $claim->billingFacilityState() .
341 "*" . stripZipCode($claim->billingFacilityZip()) .
342 "~\n";
344 if ($claim->billingFacilityNPI() && $claim->billingFacilityETIN()) {
345 ++$edicount;
346 $out .= "REF" .
347 "*EI" .
348 "*" . $claim->billingFacilityETIN() .
349 "~\n";
353 // Loop 2010AC Pay-To Plan Name omitted. Includes:
354 // NM1*PE, N3, N4, REF*2U, REF*EI
356 $PatientHL = $claim->isSelfOfInsured() ? 0 : 1;
357 $HLSubscriber = $HLcount++;
359 ++$edicount;
360 $out .= "HL" . // Loop 2000B Subscriber HL Loop
361 "*$HLSubscriber" .
362 "*$HLBillingPayToProvider" .
363 "*22" .
364 "*$PatientHL" .
365 "~\n";
367 if (!$claim->payerSequence()) {
368 $log .= "*** Error: Insurance information is missing!\n";
371 ++$edicount;
372 $out .= "SBR" . // Subscriber Information
373 "*" . $claim->payerSequence() .
374 "*" . ($claim->isSelfOfInsured() ? '18' : '') .
375 "*" . $claim->groupNumber() .
376 "*" . (($CMS_5010 && $claim->groupNumber()) ? '' : $claim->groupName()) .
377 "*" . $claim->insuredTypeCode() . // applies for secondary medicare
378 "*" .
379 "*" .
380 "*" .
381 "*" . $claim->claimType() . // Zirmed replaces this
382 "~\n";
384 // Segment PAT omitted.
386 ++$edicount;
387 $out .= "NM1" . // Loop 2010BA Subscriber
388 "*IL" .
389 "*1" . // 1 = person, 2 = non-person
390 "*" . $claim->insuredLastName() .
391 "*" . $claim->insuredFirstName() .
392 "*" . $claim->insuredMiddleName() .
393 "*" .
394 "*" . // Name Suffix
395 "*MI" .
396 // "MI" = Member Identification Number
397 // "II" = Standard Unique Health Identifier, "Required if the
398 // HIPAA Individual Patient Identifier is mandated use."
399 // Here we presume that is not true yet.
400 "*" . $claim->policyNumber() .
401 "~\n";
403 // For 5010, further subscriber info is sent only if they are the patient.
404 if (!$CMS_5010 || $claim->isSelfOfInsured()) {
405 ++$edicount;
406 $out .= "N3" .
407 "*" . $claim->insuredStreet() .
408 "~\n";
410 ++$edicount;
411 $out .= "N4" .
412 "*" . $claim->insuredCity() .
413 "*" . $claim->insuredState() .
414 "*" . stripZipCode($claim->insuredZip()) .
415 "~\n";
417 ++$edicount;
418 $out .= "DMG" .
419 "*D8" .
420 "*" . $claim->insuredDOB() .
421 "*" . $claim->insuredSex() .
422 "~\n";
425 // Segment REF*SY (Subscriber Secondary Identification) omitted.
426 // Segment REF*Y4 (Property and Casualty Claim Number) omitted.
427 // Segment PER*IC (Property and Casualty Subscriber Contact Information) omitted.
429 ++$edicount;
430 //Field length is limited to 35. See nucc dataset page 81 www.nucc.org
431 $payerName = substr($claim->payerName(), 0, $CMS_5010 ? 60 : 35);
432 $out .= "NM1" . // Loop 2010BB Payer
433 "*PR" .
434 "*2" .
435 "*" . $payerName .
436 "*" .
437 "*" .
438 "*" .
439 "*" .
440 // The 5010 spec says:
441 // "On or after the mandated implementation date for the HIPAA
442 // National Plan Identifier (National Plan ID), XV must be sent.
443 // Prior to the mandated implementation date and prior to any phase-
444 // in period identified by Federal regulation, PI must be sent."
445 // *************** Anybody know what that date is? ***************
446 // August 2011 - Publish interim final rule
447 // October 1, 2012-March 31, 2013 - Enumeration
448 // April 1, 2013-September 30, 2013 - Testing
449 // October 1, 2013 - Implementation
451 "*PI" .
452 // Zirmed ignores this if using payer name matching:
453 "*" . ($encounter_claim ? $claim->payerAltID() : $claim->payerID()) .
454 "~\n";
456 // if (!$claim->payerID()) {
457 // $log .= "*** CMS ID is missing for payer '" . $claim->payerName() . "'.\n";
458 // }
460 if (true) { // !$CMS_5010
461 // The 5010 spec says:
462 // "Required when the payer address is available and the submitter intends
463 // for the claim to be printed on paper at the next EDI location (for example, a
464 // clearinghouse). If not required by this implementation guide, do not send."
466 ++$edicount;
467 $out .= "N3" .
468 "*" . $claim->payerStreet() .
469 "~\n";
471 ++$edicount;
472 $out .= "N4" .
473 "*" . $claim->payerCity() .
474 "*" . $claim->payerState() .
475 "*" . stripZipCode($claim->payerZip()) .
476 "~\n";
479 // Segment REF (Payer Secondary Identification) omitted.
480 // Segment REF (Billing Provider Secondary Identification) omitted.
482 if (! $claim->isSelfOfInsured()) {
483 ++$edicount;
484 $out .= "HL" . // Loop 2000C Patient Information
485 "*$HLcount" .
486 "*$HLSubscriber" .
487 "*23" .
488 "*0" .
489 "~\n";
491 $HLcount++;
493 ++$edicount;
494 $out .= "PAT" .
495 "*" . $claim->insuredRelationship() .
496 "~\n";
498 ++$edicount;
499 $out .= "NM1" . // Loop 2010CA Patient
500 "*QC" .
501 "*1" .
502 "*" . $claim->patientLastName() .
503 "*" . $claim->patientFirstName();
504 if ($claim->patientMiddleName() !== '') {
505 $out .= "*"
506 . $claim->patientMiddleName();
509 $out .= "~\n";
511 ++$edicount;
512 $out .= "N3" .
513 "*" . $claim->patientStreet() .
514 "~\n";
516 ++$edicount;
517 $out .= "N4" .
518 "*" . $claim->patientCity() .
519 "*" . $claim->patientState() .
520 "*" . stripZipCode($claim->patientZip()) .
521 "~\n";
523 ++$edicount;
524 $out .= "DMG" .
525 "*D8" .
526 "*" . $claim->patientDOB() .
527 "*" . $claim->patientSex() .
528 "~\n";
530 // Segment REF*Y4 (Property and Casualty Claim Number) omitted.
531 // Segment REF (Property and Casualty Patient Identifier) omitted.
532 // Segment PER (Property and Casualty Patient Contact Information) omitted.
533 } // end of patient different from insured
535 $proccount = $claim->procCount();
537 $clm_total_charges = 0;
538 for ($prockey = 0; $prockey < $proccount; ++$prockey) {
539 $clm_total_charges += $claim->cptCharges($prockey);
542 if (!$clm_total_charges) {
543 $log .= "*** This claim has no charges!\n";
546 ++$edicount;
547 $out .= "CLM" . // Loop 2300 Claim
548 "*$pid-$encounter" .
549 "*" . sprintf("%.2f", $clm_total_charges) . // Zirmed computes and replaces this
550 "*" .
551 "*" .
552 "*" . sprintf('%02d', $claim->facilityPOS()) . ":" .
553 ($CMS_5010 ? "B" : "") . ":" .
554 $claim->frequencyTypeCode() . // Changed to correct single digit output
555 "*Y" .
556 "*A" .
557 "*" . ($claim->billingFacilityAssignment() ? 'Y' : 'N') .
558 "*Y" .
559 ($CMS_5010 ? "" : "*C") .
560 "~\n";
562 if ($claim->onsetDate() &&
563 ($claim->onsetDate()!== $claim->serviceDate()) &&
564 ($claim->onsetDateValid())
566 ++$edicount;
567 $out .= "DTP" . // Date of Onset
568 "*431" .
569 "*D8" .
570 "*" . $claim->onsetDate() .
571 "~\n";
574 // above is for historical use of encounter onset date, now in misc_billing_options
575 // Segment DTP*431 (Onset of Current Symptoms or Illness)
576 // Segment DTP*484 (Last Menstrual Period Date)
578 if ($claim->miscOnsetDate() &&
579 ($claim->box14Qualifier()) &&
580 ($claim->miscOnsetDateValid())) {
581 ++$edicount;
582 $out .= "DTP" . // Date Last Seen
583 "*" . $claim->box14Qualifier() .
584 "*D8" .
585 "*" . $claim->miscOnsetDate() .
586 "~\n";
589 // Segment DTP*454 (Initial Treatment Date)
590 // Segment DTP*304 (Last Seen Date)
591 // Segment DTP*453 (Acute Manifestation Date)
592 // Segment DTP*439 (Accident Date)
593 // Segment DTP*455 (Last X-Ray Date)
594 // Segment DTP*471 (Hearing and Vision Prescription Date)
595 // Segment DTP*314 (Disability) omitted.
596 // Segment DTP*360 (Initial Disability Period Start) omitted.
597 // Segment DTP*361 (Initial Disability Period End) omitted.
598 // Segment DTP*297 (Last Worked Date)
599 // Segment DTP*296 (Authorized Return to Work Date)
601 if ($claim->dateInitialTreatment() &&
602 ($claim->box15Qualifier()) &&
603 ($claim->dateInitialTreatmentValid())) {
604 ++$edicount;
605 $out .= "DTP" . // Date Last Seen
606 "*" . $claim->box15Qualifier() .
607 "*D8" .
608 "*" . $claim->dateInitialTreatment() .
609 "~\n";
612 if (strcmp($claim->facilityPOS(), '21') == 0 && $claim->onsetDateValid()) {
613 ++$edicount;
614 $out .= "DTP" . // Date of Hospitalization
615 "*435" .
616 "*D8" .
617 "*" . $claim->onsetDate() .
618 "~\n";
621 // above is for historical use of encounter onset date, now in misc_billing_options
622 if (strcmp($claim->facilityPOS(), '21') == 0 && $claim->hospitalizedFromDateValid()) {
623 ++$edicount;
624 $out .= "DTP" . // Date of Admission
625 "*435" .
626 "*D8" .
627 "*" . $claim->hospitalizedFrom() .
628 "~\n";
631 // Segment DTP*096 (Discharge Date)
632 if (strcmp($claim->facilityPOS(), '21') == 0 && $claim->hospitalizedToDateValid()) {
633 ++$edicount;
634 $out .= "DTP" . // Date of Discharge
635 "*96" .
636 "*D8" .
637 "*" . $claim->hospitalizedTo() .
638 "~\n";
641 // Segments DTP (Assumed and Relinquished Care Dates) omitted.
642 // Segment DTP*444 (Property and Casualty Date of First Contact) omitted.
643 // Segment DTP*050 (Repricer Received Date) omitted.
644 // Segment PWK (Claim Supplemental Information) omitted.
645 // Segment CN1 (Contract Information) omitted.
647 $patientpaid = $claim->patientPaidAmount();
648 if ($patientpaid != 0) {
649 ++$edicount;
650 $out .= "AMT" . // Patient paid amount. Page 190/220.
651 "*F5" .
652 "*" . $patientpaid .
653 "~\n";
656 // Segment REF*4N (Service Authorization Exception Code) omitted.
657 // Segment REF*F5 (Mandatory Medicare Crossover Indicator) omitted.
658 // Segment REF*EW (Mammography Certification Number) omitted.
659 // Segment REF*9F (Referral Number) omitted.
661 if ($claim->priorAuth()) {
662 ++$edicount;
663 $out .= "REF" . // Prior Authorization Number
664 "*G1" .
665 "*" . $claim->priorAuth() .
666 "~\n";
669 // Segment REF*F8 Payer Claim Control Number for claim re-submission.icn_resubmission_number
671 #if($claim->billing_options['replacement_claim'] == '1'){
672 if (trim($claim->billing_options['icn_resubmission_number']) > 3) {
673 ++$edicount;
674 error_log("Method 1: ".$claim->billing_options['icn_resubmission_number'], 0);
675 $out .= "REF" .
676 "*F8" .
677 "*" . $claim->icnResubmissionNumber() .
678 "~\n";
682 if ($claim->cliaCode() && ($CMS_5010 || $claim->claimType() === 'MB')) {
683 // Required by Medicare when in-house labs are done.
684 ++$edicount;
685 $out .= "REF" . // Clinical Laboratory Improvement Amendment Number
686 "*X4" .
687 "*" . $claim->cliaCode() .
688 "~\n";
691 // Segment REF*9A (Repriced Claim Number) omitted.
692 // Segment REF*9C (Adjusted Repriced Claim Number) omitted.
693 // Segment REF*LX (Investigational Device Exemption Number) omitted.
694 // Segment REF*D9 (Claim Identifier for Transmission Intermediaries) omitted.
695 // Segment REF*EA (Medical Record Number) omitted.
696 // Segment REF*P4 (Demonstration Project Identifier) omitted.
697 // Segment REF*1J (Care Plan Oversight) omitted.
698 // Segment K3 (File Information) omitted.
700 if ($claim->additionalNotes()) {
701 // Claim note.
702 ++$edicount;
703 $out .= "NTE" . // comments box 19
704 "*" . ($CMS_5010 ? "ADD" : "") .
705 "*" . $claim->additionalNotes() .
706 "~\n";
709 // Segment CR1 (Ambulance Transport Information) omitted.
710 // Segment CR2 (Spinal Manipulation Service Information) omitted.
711 // Segment CRC (Ambulance Certification) omitted.
712 // Segment CRC (Patient Condition Information: Vision) omitted.
713 // Segment CRC (Homebound Indicator) omitted.
715 // Segment CRC (EPSDT Referral).
716 if ($claim->epsdtFlag()) {
717 ++$edicount;
718 $out .= "CRC" .
719 "*ZZ" .
720 "*Y" .
721 "*" . $claim->medicaidReferralCode() .
722 "~\n";
725 // Diagnoses, up to $max_per_seg per HI segment.
726 $max_per_seg = $CMS_5010 ? 12 : 8;
727 $da = $claim->diagArray();
728 if ($claim->diagtype == "ICD9") {
729 $diag_type_code = 'BK';
730 } else {
731 $diag_type_code = 'ABK';
734 $tmp = 0;
735 foreach ($da as $diag) {
736 if ($tmp % $max_per_seg == 0) {
737 if ($tmp) {
738 $out .= "~\n";
741 ++$edicount;
742 $out .= "HI"; // Health Diagnosis Codes
745 $out .= "*$diag_type_code:" . $diag;
746 if ($claim->diagtype == "ICD9") {
747 $diag_type_code = 'BF';
748 } else {
749 $diag_type_code = 'ABF';
752 ++$tmp;
755 if ($tmp) {
756 $out .= "~\n";
759 // Segment HI*BP (Anesthesia Related Procedure) omitted.
760 // Segment HI*BG (Condition Information) omitted.
761 // Segment HCP (Claim Pricing/Repricing Information) omitted.
763 if ($claim->referrerLastName()) {
764 // Medicare requires referring provider's name and UPIN.
765 ++$edicount;
766 $out .= "NM1" . // Loop 2310A Referring Provider
767 "*DN" .
768 "*1" .
769 "*" . $claim->referrerLastName() .
770 "*" . $claim->referrerFirstName() .
771 "*" . $claim->referrerMiddleName() .
772 "*" .
773 "*";
774 if ($CMS_5010 || $claim->referrerNPI()) {
775 $out .=
776 "*XX" .
777 "*" . $claim->referrerNPI();
778 } else {
779 $out .=
780 "*34" . // not allowed for 5010
781 "*" . $claim->referrerSSN();
784 $out .= "~\n";
786 if (!$CMS_5010 && $claim->referrerTaxonomy()) {
787 ++$edicount;
788 $out .= "PRV" .
789 "*RF" . // ReFerring provider
790 "*ZZ" .
791 "*" . $claim->referrerTaxonomy() .
792 "~\n";
795 if (!CMS_5010 && $claim->referrerUPIN()) {
796 ++$edicount;
797 $out .= "REF" . // Referring Provider Secondary Identification
798 "*1G" .
799 "*" . $claim->referrerUPIN() .
800 "~\n";
805 /* Per the implementation guide lines, only include this information if it is different
806 * than the Loop 2010AA information
808 if (!$CMS_5010 ||
809 ($claim->providerNPIValid() &&
810 $claim->billingFacilityNPI() !== $claim->providerNPI() )) {
811 ++$edicount;
812 $out .= "NM1" . // Loop 2310B Rendering Provider
813 "*82" .
814 "*1" .
815 "*" . $claim->providerLastName() .
816 "*" . $claim->providerFirstName() .
817 "*" . $claim->providerMiddleName() .
818 "*" .
819 "*";
820 if ($CMS_5010 || $claim->providerNPI()) {
821 $out .=
822 "*XX" .
823 "*" . $claim->providerNPI();
824 } else {
825 $out .=
826 "*34" . // not allowed for 5010
827 "*" . $claim->providerSSN();
828 $log .= "*** Rendering provider has no NPI.\n";
831 $out .= "~\n";
833 if ($claim->providerTaxonomy()) {
834 ++$edicount;
835 $out .= "PRV" .
836 "*PE" . // Performing provider
837 "*" .($claim->claimType() != 'MC' ? "PXC" : "ZZ") .
838 "*" . $claim->providerTaxonomy() .
839 "~\n";
842 // End of Loop 2310B
843 } else {
844 // This loop can only get skipped if we are generating a 5010 claim
845 if (!($claim->providerNPIValid())) {
846 /* If the loop was skipped because the provider NPI was invalid, generate
847 * a warning for the log.*/
848 $log.="*** Skipping 2310B because ".$claim->providerLastName() ."," . $claim->providerFirstName() . " has invalid NPI.\n";
851 /* Skipping this segment because the providerNPI and the billingFacilityNPI are identical
852 * is a normal condition, so no need to warn.
856 // 4010: REF*1C is required here for the Medicare provider number if NPI was
857 // specified in NM109. Not sure if other payers require anything here.
858 // --- apparently ECLAIMS, INC wants the data in 2010 but NOT in 2310B - tony@mi-squared.com
860 // 5010 spec says nothing here if NPI was specified.
862 if (($CMS_5010 && !$claim->providerNPI() && in_array($claim->providerNumberType(), array('0B','1G','G2','LU')))
863 || (!$CMS_5010 && trim($claim->x12gsreceiverid()) != '470819582')) { // if NOT ECLAIMS EDI
864 if ($claim->providerNumber()) {
865 ++$edicount;
866 $out .= "REF" .
867 "*" . $claim->providerNumberType() .
868 "*" . $claim->providerNumber() .
869 "~\n";
873 // Loop 2310D is omitted in the case of home visits (POS=12).
874 if ($claim->facilityPOS() != 12 && (!$CMS_5010 ||
875 ($claim->facilityNPI() != $claim->billingFacilityNPI() ||
876 ($claim->facilityNPI() == $claim->billingFacilityNPI() &&
877 $claim->facilityStreet() != $claim->billingFacilityStreet())))) {
878 ++$edicount;
879 $out .= "NM1" . // Loop 2310D Service Location
880 "*77" .
881 "*2";
882 //Field length is limited to 35. See nucc dataset page 77 www.nucc.org
883 $facilityName = substr($claim->facilityName(), 0, $CMS_5010 ? 60 : 35);
884 if ($claim->facilityName() || $claim->facilityNPI() || $claim->facilityETIN()) {
885 $out .=
886 "*" . $facilityName;
889 if ($claim->facilityNPI() || $claim->facilityETIN()) {
890 $out .=
891 "*" .
892 "*" .
893 "*" .
894 "*";
895 if ($CMS_5010 || $claim->facilityNPI()) {
896 $out .=
897 "*XX*" . $claim->facilityNPI();
898 } else {
899 $out .=
900 "*24*" . $claim->facilityETIN();
903 if (!$claim->facilityNPI()) {
904 $log .= "*** Service location has no NPI.\n";
908 $out .= "~\n";
909 if ($claim->facilityStreet()) {
910 ++$edicount;
911 $out .= "N3" .
912 "*" . $claim->facilityStreet() .
913 "~\n";
916 if ($claim->facilityState()) {
917 ++$edicount;
918 $out .= "N4" .
919 "*" . $claim->facilityCity() .
920 "*" . $claim->facilityState() .
921 "*" . stripZipCode($claim->facilityZip()) .
922 "~\n";
926 // Segment REF (Service Facility Location Secondary Identification) omitted.
927 // Segment PER (Service Facility Contact Information) omitted.
929 // Loop 2310E, Supervising Provider
931 if ($claim->supervisorLastName()) {
932 ++$edicount;
933 $out .= "NM1" .
934 "*DQ" . // Supervising Physician
935 "*1" . // Person
936 "*" . $claim->supervisorLastName() .
937 "*" . $claim->supervisorFirstName() .
938 "*" . $claim->supervisorMiddleName() .
939 "*" . // NM106 not used
940 "*"; // Name Suffix
941 if ($CMS_5010 || $claim->supervisorNPI()) {
942 $out .=
943 "*XX" .
944 "*" . $claim->supervisorNPI();
945 } else {
946 $out .=
947 "*34" .
948 "*" . $claim->supervisorSSN();
951 if (!$claim->supervisorNPI()) {
952 $log .= "*** Supervising Provider has no NPI.\n";
955 $out .= "~\n";
957 if ($claim->supervisorNumber()) {
958 ++$edicount;
959 $out .= "REF" .
960 "*" . $claim->supervisorNumberType() .
961 "*" . $claim->supervisorNumber() .
962 "~\n";
966 // Segments NM1*PW, N3, N4 (Ambulance Pick-Up Location) omitted.
967 // Segments NM1*45, N3, N4 (Ambulance Drop-Off Location) omitted.
969 $prev_pt_resp = $clm_total_charges; // for computation below
971 // Loops 2320 and 2330*, other subscriber/payer information.
972 // Remember that insurance index 0 is always for the payer being billed
973 // by this claim, and 1 and above are always for the "other" payers.
975 for ($ins = 1; $ins < $claim->payerCount(); ++$ins) {
976 $tmp1 = $claim->claimType($ins);
977 $tmp2 = 'C1'; // Here a kludge. See page 321.
978 if ($tmp1 === 'CI') {
979 $tmp2 = 'C1';
982 if ($tmp1 === 'AM') {
983 $tmp2 = 'AP';
986 if ($tmp1 === 'HM') {
987 $tmp2 = 'HM';
990 if ($tmp1 === 'MB') {
991 $tmp2 = 'MB';
994 if ($tmp1 === 'MC') {
995 $tmp2 = 'MC';
998 if ($tmp1 === '09') {
999 $tmp2 = 'PP';
1002 ++$edicount;
1003 $out .= "SBR" . // Loop 2320, Subscriber Information - page 297/318
1004 "*" . $claim->payerSequence($ins) .
1005 "*" . $claim->insuredRelationship($ins) .
1006 "*" . $claim->groupNumber($ins) .
1007 "*" . (($CMS_5010 && $claim->groupNumber($ins)) ? '' : $claim->groupName($ins)) .
1008 "*" . ($CMS_5010 ? $claim->insuredTypeCode($ins) : $tmp2) .
1009 "*" .
1010 "*" .
1011 "*" .
1012 "*" . $claim->claimType($ins) .
1013 "~\n";
1015 // Things that apply only to previous payers, not future payers.
1017 if ($claim->payerSequence($ins) < $claim->payerSequence()) {
1018 // Generate claim-level adjustments.
1019 $aarr = $claim->payerAdjustments($ins);
1020 foreach ($aarr as $a) {
1021 ++$edicount;
1022 $out .= "CAS" . // Previous payer's claim-level adjustments. Page 301/323.
1023 "*" . $a[1] .
1024 "*" . $a[2] .
1025 "*" . $a[3] .
1026 "~\n";
1029 $payerpaid = $claim->payerTotals($ins);
1030 ++$edicount;
1031 $out .= "AMT" . // Previous payer's paid amount. Page 307/332.
1032 "*D" .
1033 "*" . $payerpaid[1] .
1034 "~\n";
1036 // Segment AMT*A8 (COB Total Non-Covered Amount) omitted.
1037 // Segment AMT*EAF (Remaining Patient Liability) omitted.
1039 if (!$CMS_5010) {
1040 // Patient responsibility amount as of this previous payer.
1041 $prev_pt_resp -= $payerpaid[1]; // reduce by payments
1042 $prev_pt_resp -= $payerpaid[2]; // reduce by adjustments
1044 ++$edicount;
1045 $out .= "AMT" . // Allowed amount per previous payer. Page 334.
1046 "*B6" .
1047 "*" . sprintf('%.2f', $payerpaid[1] + $prev_pt_resp) .
1048 "~\n";
1050 ++$edicount;
1051 $out .= "AMT" . // Patient responsibility amount per previous payer. Page 335.
1052 "*F2" .
1053 "*" . sprintf('%.2f', $prev_pt_resp) .
1054 "~\n";
1056 } // End of things that apply only to previous payers.
1058 if (!$CMS_5010) {
1059 ++$edicount;
1060 $out .= "DMG" . // Other subscriber demographic information. Page 342.
1061 "*D8" .
1062 "*" . $claim->insuredDOB($ins) .
1063 "*" . $claim->insuredSex($ins) .
1064 "~\n";
1067 ++$edicount;
1068 $out .= "OI" . // Other Insurance Coverage Information. Page 310/344.
1069 "*" .
1070 "*" .
1071 "*" . ($claim->billingFacilityAssignment($ins) ? 'Y' : 'N') .
1072 // For this next item, the 5010 example in the spec does not match its
1073 // description. So this might be wrong.
1074 "*" . ($CMS_5010 ? '' : 'B') .
1075 "*" .
1076 "*Y" .
1077 "~\n";
1079 // Segment MOA (Medicare Outpatient Adjudication) omitted.
1081 ++$edicount;
1082 $out .= "NM1" . // Loop 2330A Subscriber info for other insco. Page 315/350.
1083 "*IL" .
1084 "*1" .
1085 "*" . $claim->insuredLastName($ins) .
1086 "*" . $claim->insuredFirstName($ins) .
1087 "*" . $claim->insuredMiddleName($ins) .
1088 "*" .
1089 "*" .
1090 "*MI" .
1091 "*" . $claim->policyNumber($ins) .
1092 "~\n";
1094 ++$edicount;
1095 $out .= "N3" .
1096 "*" . $claim->insuredStreet($ins) .
1097 "~\n";
1099 ++$edicount;
1100 $out .= "N4" .
1101 "*" . $claim->insuredCity($ins) .
1102 "*" . $claim->insuredState($ins) .
1103 "*" . stripZipCode($claim->insuredZip($ins)) .
1104 "~\n";
1106 // Segment REF (Other Subscriber Secondary Identification) omitted.
1108 ++$edicount;
1109 //Field length is limited to 35. See nucc dataset page 81 www.nucc.org
1110 $payerName = substr($claim->payerName($ins), 0, $CMS_5010 ? 60 : 35);
1111 $out .= "NM1" . // Loop 2330B Payer info for other insco. Page 322/359.
1112 "*PR" .
1113 "*2" .
1114 "*" . $payerName .
1115 "*" .
1116 "*" .
1117 "*" .
1118 "*" .
1119 "*PI" .
1120 "*" . $claim->payerID($ins) .
1121 "~\n";
1123 // if (!$claim->payerID($ins)) {
1124 // $log .= "*** CMS ID is missing for payer '" . $claim->payerName($ins) . "'.\n";
1125 // }
1127 // Payer address (N3 and N4) are added below so that Gateway EDI can
1128 // auto-generate secondary claims. These do NOT appear in my copy of
1129 // the spec! -- Rod 2008-06-12
1131 if ($CMS_5010 || trim($claim->x12gsreceiverid()) == '431420764') { // if Gateway EDI
1132 ++$edicount;
1133 $out .= "N3" .
1134 "*" . $claim->payerStreet($ins) .
1135 "~\n";
1137 ++$edicount;
1138 $out .= "N4" .
1139 "*" . $claim->payerCity($ins) .
1140 "*" . $claim->payerState($ins) .
1141 "*" . stripZipCode($claim->payerZip($ins)) .
1142 "~\n";
1143 } // end Gateway EDI
1145 // Segment DTP*573 (Claim Check or Remittance Date) omitted.
1146 // Segment REF (Other Payer Secondary Identifier) omitted.
1147 // Segment REF*G1 (Other Payer Prior Authorization Number) omitted.
1148 // Segment REF*9F (Other Payer Referral Number) omitted.
1149 // Segment REF*T4 (Other Payer Claim Adjustment Indicator) omitted.
1150 // Segment REF*F8 (Other Payer Claim Control Number) omitted.
1151 // Segment NM1 (Other Payer Referring Provider) omitted.
1152 // Segment REF (Other Payer Referring Provider Secondary Identification) omitted.
1153 // Segment NM1 (Other Payer Rendering Provider) omitted.
1154 // Segment REF (Other Payer Rendering Provider Secondary Identification) omitted.
1155 // Segment NM1 (Other Payer Service Facility Location) omitted.
1156 // Segment REF (Other Payer Service Facility Location Secondary Identification) omitted.
1157 // Segment NM1 (Other Payer Supervising Provider) omitted.
1158 // Segment REF (Other Payer Supervising Provider Secondary Identification) omitted.
1159 // Segment NM1 (Other Payer Billing Provider) omitted.
1160 // Segment REF (Other Payer Billing Provider Secondary Identification) omitted.
1161 } // End loops 2320/2330*.
1163 $loopcount = 0;
1165 // Procedure loop starts here.
1167 for ($prockey = 0; $prockey < $proccount; ++$prockey) {
1168 ++$loopcount;
1170 ++$edicount;
1171 $out .= "LX" . // Loop 2400 LX Service Line. Page 398.
1172 "*$loopcount" .
1173 "~\n";
1175 ++$edicount;
1176 $out .= "SV1" . // Professional Service. Page 400.
1177 "*HC:" . $claim->cptKey($prockey) .
1178 "*" . sprintf('%.2f', $claim->cptCharges($prockey)) .
1179 "*UN" .
1180 "*" . $claim->cptUnits($prockey) .
1181 "*" .
1182 "*" .
1183 "*";
1184 $dia = $claim->diagIndexArray($prockey);
1185 $i = 0;
1186 foreach ($dia as $dindex) {
1187 if ($i) {
1188 $out .= ':';
1191 $out .= $dindex;
1192 if (++$i >= 4) {
1193 break;
1197 # needed for epstd
1198 if ($claim->epsdtFlag()) {
1199 $out .= "*" .
1200 "*" .
1201 "*" .
1202 "*Y" .
1203 "~\n";
1204 } else {
1205 $out .= "~\n";
1208 if (!$claim->cptCharges($prockey)) {
1209 $log .= "*** Procedure '" . $claim->cptKey($prockey) . "' has no charges!\n";
1212 if (empty($dia)) {
1213 $log .= "*** Procedure '" . $claim->cptKey($prockey) . "' is not justified!\n";
1216 // Segment SV5 (Durable Medical Equipment Service) omitted.
1217 // Segment PWK (Line Supplemental Information) omitted.
1218 // Segment PWK (Durable Medical Equipment Certificate of Medical Necessity Indicator) omitted.
1219 // Segment CR1 (Ambulance Transport Information) omitted.
1220 // Segment CR3 (Durable Medical Equipment Certification) omitted.
1221 // Segment CRC (Ambulance Certification) omitted.
1222 // Segment CRC (Hospice Employee Indicator) omitted.
1223 // Segment CRC (Condition Indicator / Durable Medical Equipment) omitted.
1225 ++$edicount;
1226 $out .= "DTP" . // Date of Service. Page 435.
1227 "*472" .
1228 "*D8" .
1229 "*" . $claim->serviceDate() .
1230 "~\n";
1232 $testnote = rtrim($claim->cptNotecodes($prockey));
1233 if (!empty($testnote)) {
1234 ++$edicount;
1235 $out .= "NTE" . // Explain Unusual Circumstances.
1236 "*ADD" .
1237 "*" . $claim->cptNotecodes($prockey) .
1238 "~\n";
1241 // Segment DTP*471 (Prescription Date) omitted.
1242 // Segment DTP*607 (Revision/Recertification Date) omitted.
1243 // Segment DTP*463 (Begin Therapy Date) omitted.
1244 // Segment DTP*461 (Last Certification Date) omitted.
1245 // Segment DTP*304 (Last Seen Date) omitted.
1246 // Segment DTP (Test Date) omitted.
1247 // Segment DTP*011 (Shipped Date) omitted.
1248 // Segment DTP*455 (Last X-Ray Date) omitted.
1249 // Segment DTP*454 (Initial Treatment Date) omitted.
1250 // Segment QTY (Ambulance Patient Count) omitted.
1251 // Segment QTY (Obstetric Anesthesia Additional Units) omitted.
1252 // Segment MEA (Test Result) omitted.
1253 // Segment CN1 (Contract Information) omitted.
1254 // Segment REF*9B (Repriced Line Item Reference Number) omitted.
1255 // Segment REF*9D (Adjusted Repriced Line Item Reference Number) omitted.
1256 // Segment REF*G1 (Prior Authorization) omitted.
1257 // Segment REF*6R (Line Item Control Number) omitted.
1258 // (Really oughta have this for robust 835 posting!)
1259 // Segment REF*EW (Mammography Certification Number) omitted.
1260 // Segment REF*X4 (CLIA Number) omitted.
1261 // Segment REF*F4 (Referring CLIA Facility Identification) omitted.
1262 // Segment REF*BT (Immunization Batch Number) omitted.
1263 // Segment REF*9F (Referral Number) omitted.
1264 // Segment AMT*T (Sales Tax Amount) omitted.
1265 // Segment AMT*F4 (Postage Claimed Amount) omitted.
1266 // Segment K3 (File Information) omitted.
1267 // Segment NTE (Line Note) omitted.
1268 // Segment NTE (Third Party Organization Notes) omitted.
1269 // Segment PS1 (Purchased Service Information) omitted.
1270 // Segment HCP (Line Pricing/Repricing Information) omitted.
1272 if (!$CMS_5010) {
1273 // This segment was deleted for 5010.
1275 // AMT*AAE segment for Approved Amount from previous payer.
1276 // Medicare secondaries seem to require this.
1278 for ($ins = $claim->payerCount() - 1; $ins > 0; --$ins) {
1279 if ($claim->payerSequence($ins) > $claim->payerSequence()) {
1280 continue; // payer is future, not previous
1283 $payerpaid = $claim->payerTotals($ins, $claim->cptKey($prockey));
1284 ++$edicount;
1285 $out .= "AMT" . // Approved amount per previous payer. Page 485.
1286 "*AAE" .
1287 "*" . sprintf('%.2f', $claim->cptCharges($prockey) - $payerpaid[2]) .
1288 "~\n";
1289 break;
1293 // Loop 2410, Drug Information. Medicaid insurers seem to want this
1294 // with HCPCS codes.
1296 $ndc = $claim->cptNDCID($prockey);
1297 if ($ndc) {
1298 ++$edicount;
1299 $out .= "LIN" . // Drug Identification. Page 500+ (Addendum pg 71).
1300 "*" . // Per addendum, LIN01 is not used.
1301 "*N4" .
1302 "*" . $ndc .
1303 "~\n";
1305 if (!preg_match('/^\d\d\d\d\d-\d\d\d\d-\d\d$/', $ndc, $tmp) && !preg_match('/^\d{11}$/', $ndc)) {
1306 $log .= "*** NDC code '$ndc' has invalid format!\n";
1309 ++$edicount;
1310 $tmpunits = $claim->cptNDCQuantity($prockey) * $claim->cptUnits($prockey);
1311 if (!$tmpunits) {
1312 $tmpunits = 1;
1315 $out .= "CTP" . // Drug Pricing. Page 500+ (Addendum pg 74).
1316 "*" .
1317 "*" .
1318 "*" . ($CMS_5010 ? '' : sprintf('%.2f', $claim->cptCharges($prockey) / $tmpunits)) .
1319 "*" . $claim->cptNDCQuantity($prockey) .
1320 "*" . $claim->cptNDCUOM($prockey) .
1321 // Note: 5010 documents "ME" (Milligrams) as an additional unit of measure.
1322 "~\n";
1325 // Segment REF (Prescription or Compound Drug Association Number) omitted.
1327 // Loop 2420A, Rendering Provider (service-specific).
1328 // Used if the rendering provider for this service line is different
1329 // from that in loop 2310B.
1331 if ($claim->providerNPI() != $claim->providerNPI($prockey)) {
1332 ++$edicount;
1333 $out .= "NM1" . // Loop 2310B Rendering Provider
1334 "*82" .
1335 "*1" .
1336 "*" . $claim->providerLastName($prockey) .
1337 "*" . $claim->providerFirstName($prockey) .
1338 "*" . $claim->providerMiddleName($prockey) .
1339 "*" .
1340 "*";
1341 if ($CMS_5010 || $claim->providerNPI($prockey)) {
1342 $out .=
1343 "*XX" .
1344 "*" . $claim->providerNPI($prockey);
1345 } else {
1346 $out .=
1347 "*34" . // Not allowed for 5010
1348 "*" . $claim->providerSSN($prockey);
1351 if (!$claim->providerNPI($prockey)) {
1352 $log .= "*** Rendering provider has no NPI.\n";
1355 $out .= "~\n";
1357 if ($claim->providerTaxonomy($prockey)) {
1358 ++$edicount;
1359 $out .= "PRV" .
1360 "*PE" . // PErforming provider
1361 "*" . ($CMS_5010 ? "PXC" : "ZZ") .
1362 "*" . $claim->providerTaxonomy($prockey) .
1363 "~\n";
1366 // Segment PRV*PE (Rendering Provider Specialty Information) omitted.
1367 // Segment REF (Rendering Provider Secondary Identification) omitted.
1368 // Segment NM1 (Purchased Service Provider Name) omitted.
1369 // Segment REF (Purchased Service Provider Secondary Identification) omitted.
1370 // Segment NM1,N3,N4 (Service Facility Location) omitted.
1371 // Segment REF (Service Facility Location Secondary Identification) omitted.
1372 // Segment NM1 (Supervising Provider Name) omitted.
1373 // Segment REF (Supervising Provider Secondary Identification) omitted.
1374 // Segment NM1,N3,N4 (Ordering Provider) omitted.
1375 // Segment REF (Ordering Provider Secondary Identification) omitted.
1376 // Segment PER (Ordering Provider Contact Information) omitted.
1377 // Segment NM1 (Referring Provider Name) omitted.
1378 // Segment REF (Referring Provider Secondary Identification) omitted.
1379 // Segments NM1*PW, N3, N4 (Ambulance Pick-Up Location) omitted.
1380 // Segments NM1*45, N3, N4 (Ambulance Drop-Off Location) omitted.
1382 // REF*1C is required here for the Medicare provider number if NPI was
1383 // specified in NM109. Not sure if other payers require anything here.
1384 if (!$CMS_5010 && $claim->providerNumber($prockey)) {
1385 ++$edicount;
1386 $out .= "REF" .
1387 "*" . $claim->providerNumberType($prockey) .
1388 // Note: 5010 documents that type 1D (Medicaid) is changed to G2.
1389 "*" . $claim->providerNumber($prockey) .
1390 "~\n";
1394 // Loop 2430, adjudication by previous payers.
1396 for ($ins = 1; $ins < $claim->payerCount(); ++$ins) {
1397 if ($claim->payerSequence($ins) > $claim->payerSequence()) {
1398 continue; // payer is future, not previous
1401 $payerpaid = $claim->payerTotals($ins, $claim->cptKey($prockey));
1402 $aarr = $claim->payerAdjustments($ins, $claim->cptKey($prockey));
1404 if ($payerpaid[1] == 0 && !count($aarr)) {
1405 $log .= "*** Procedure '" . $claim->cptKey($prockey) .
1406 "' has no payments or adjustments from previous payer!\n";
1407 continue;
1410 ++$edicount;
1411 $out .= "SVD" . // Service line adjudication. Page 554.
1412 "*" . $claim->payerID($ins) .
1413 "*" . $payerpaid[1] .
1414 "*HC:" . $claim->cptKey($prockey) .
1415 "*" .
1416 "*" . $claim->cptUnits($prockey) .
1417 "~\n";
1419 $tmpdate = $payerpaid[0];
1420 foreach ($aarr as $a) {
1421 ++$edicount;
1422 $out .= "CAS" . // Previous payer's line level adjustments. Page 558.
1423 "*" . $a[1] .
1424 "*" . $a[2] .
1425 "*" . $a[3] .
1426 "~\n";
1427 if (!$tmpdate) {
1428 $tmpdate = $a[0];
1431 // WTH is this??
1432 /*************************************************************
1433 if ( isset($a[4]) &&
1434 $a[4] != null ) {
1435 $out .= "CAS02" . // Previous payer's adjustment reason
1436 "*" . $a[4] .
1437 "~\n";
1439 *************************************************************/
1442 if ($tmpdate) {
1443 ++$edicount;
1444 $out .= "DTP" . // Previous payer's line adjustment date. Page 493/566.
1445 "*573" .
1446 "*D8" .
1447 "*$tmpdate" .
1448 "~\n";
1451 // Segment AMT*EAF (Remaining Patient Liability) omitted.
1452 // Segment LQ (Form Identification Code) omitted.
1453 // Segment FRM (Supporting Documentation) omitted.
1454 } // end loop 2430
1455 } // end this procedure
1457 ++$edicount;
1458 $out .= "SE" . // SE Trailer
1459 "*$edicount" .
1460 "*0021" .
1461 "~\n";
1463 $out .= "GE" . // GE Trailer
1464 "*1" .
1465 "*1" .
1466 "~\n";
1468 $out .= "IEA" . // IEA Trailer
1469 "*1" .
1470 "*000000001" .
1471 "~\n";
1473 // Remove any trailing empty fields (delimiters) from each segment.
1474 $out = preg_replace('/\*+~/', '~', $out);
1476 $log .= "\n";
1477 return $out;