Improved Code Sniffing (#928)
[openemr.git] / library / gen_hcfa_1500.inc.php
bloba844cb0b43930f9911b1e7f1d361e2723c999874
1 <?php
2 /*
3 * This program creates the HCFA 1500 claim form.
5 * @package OpenEMR
6 * @author Rod Roark <rod@sunsetsystems.com>
7 * @author Stephen Waite <stephen.waite@cmsvt.com>
8 * @copyright Copyright (c) 2011 Rod Roark <rod@sunsetsystems.com>
9 * @copyright Copyright (C) 2017 Stephen Waite <stephen.waite@cmsvt.com>
10 * @link http://www.open-emr.org
11 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
14 require_once("Claim.class.php");
15 require_once("gen_hcfa_1500_02_12.inc.php");
17 $hcfa_curr_line = 1;
18 $hcfa_curr_col = 1;
19 $hcfa_data = '';
20 $hcfa_proc_index = 0;
23 /**
24 * take the data element and place it at the correct coordinates on the page
26 * @global int $hcfa_curr_line
27 * @global type $hcfa_curr_col
28 * @global type $hcfa_data
29 * @param type $line
30 * @param type $col
31 * @param type $maxlen
32 * @param type $data
33 * @param type $strip regular expression for what to strip from the data. period and has are the defaults
34 * 02/12 version needs to include periods in the diagnoses hence the need to override
36 function put_hcfa($line, $col, $maxlen, $data,$strip='/[.#]/')
38 global $hcfa_curr_line, $hcfa_curr_col, $hcfa_data;
39 if ($line < $hcfa_curr_line)
40 die("Data item at ($line, $col) precedes current line.");
41 while ($hcfa_curr_line < $line) {
42 $hcfa_data .= "\n";
43 ++$hcfa_curr_line;
44 $hcfa_curr_col = 1;
46 if ($col < $hcfa_curr_col)
47 die("Data item at ($line, $col) precedes current column.");
48 while ($hcfa_curr_col < $col) {
49 $hcfa_data .= " ";
50 ++$hcfa_curr_col;
52 $data = preg_replace($strip, '', strtoupper($data));
53 $len = min(strlen($data), $maxlen);
54 $hcfa_data .= substr($data, 0, $len);
55 $hcfa_curr_col += $len;
58 function gen_hcfa_1500($pid, $encounter, &$log)
60 global $hcfa_data, $hcfa_proc_index;
62 $hcfa_data = '';
63 $hcfa_proc_index = 0;
65 $today = time();
66 $claim = new Claim($pid, $encounter);
68 $log .= "Generating HCFA claim $pid-$encounter for " .
69 $claim->patientFirstName() . ' ' .
70 $claim->patientMiddleName() . ' ' .
71 $claim->patientLastName() . ' on ' .
72 date('Y-m-d H:i', $today) . ".\n";
74 while ($hcfa_proc_index < $claim->procCount()) {
75 if ($hcfa_proc_index) $hcfa_data .= "\014"; // append form feed for new page
76 gen_hcfa_1500_page($pid, $encounter, $log, $claim);
79 $log .= "\n";
80 return $hcfa_data;
83 function gen_hcfa_1500_page($pid, $encounter, &$log, &$claim)
85 global $hcfa_curr_line, $hcfa_curr_col, $hcfa_data, $hcfa_proc_index;
87 $hcfa_curr_line = 1;
88 $hcfa_curr_col = 1;
90 // According to:
91 // http://www.ngsmedicare.com/NGSMedicare/PartB/EducationandSupport/ToolsandMaterials/CMS_ClaimFormInst.aspx
92 // Medicare interprets sections 9 and 11 of the claim form in its own
93 // special way. This flag tells us to do that. However I'm not 100%
94 // sure that it applies nationwide, and if you find that it is not right
95 // for you then set it to false. -- Rod 2009-03-26
96 $new_medicare_logic = $claim->claimType() == 'MB';
98 // Payer name, attn, street.
99 put_hcfa(2, 41, 31, $claim->payerName());
100 put_hcfa(3, 41, 31, $claim->payerAttn());
101 put_hcfa(4, 41, 31, $claim->payerStreet());
103 // Payer city, state, zip.
104 $tmp = $claim->payerCity() ? ($claim->payerCity() . ', ') : '';
105 put_hcfa(5, 41, 31, $tmp . $claim->payerState() . ' ' . $claim->payerZip());
107 // Box 1. Insurance Type
108 // claimTypeRaw() gets the integer value from insurance_companies.ins_type_code.
109 // Previous version of this code called claimType() which maps ins_type_code to
110 // a 2-character code and that was not specific enough.
111 $ct = $claim->claimTypeRaw();
112 $tmpcol = 45; // Other
113 if ($ct == 2) $tmpcol = 1; // Medicare
114 else if ($ct == 3) $tmpcol = 8; // Medicaid
115 else if ($ct == 5) $tmpcol = 15; // TriCare (formerly CHAMPUS)
116 else if ($ct == 4) $tmpcol = 24; // Champus VA
117 else if ($ct == 6) $tmpcol = 31; // Group Health Plan (only BCBS?)
118 else if ($ct == 7) $tmpcol = 39; // FECA
119 put_hcfa(8, $tmpcol, 1, 'X');
121 // Box 1a. Insured's ID Number
122 put_hcfa(8, 50, 17, $claim->policyNumber());
124 // Box 2. Patient's Name
125 $tmp = $claim->patientLastName() . ', ' . $claim->patientFirstName();
126 if ($claim->patientMiddleName())
127 $tmp .= ', ' . substr($claim->patientMiddleName(),0,1);
128 put_hcfa(10, 1, 28, $tmp);
130 // Box 3. Patient's Birth Date and Sex
131 $tmp = $claim->patientDOB();
132 put_hcfa(10, 31, 2, substr($tmp,4,2));
133 put_hcfa(10, 34, 2, substr($tmp,6,2));
134 put_hcfa(10, 37, 4, substr($tmp,0,4));
135 put_hcfa(10, $claim->patientSex() == 'M' ? 42 : 47, 1, 'X');
137 // Box 4. Insured's Name
138 $tmp = $claim->insuredLastName() . ', ' . $claim->insuredFirstName();
139 if ($claim->insuredMiddleName())
140 $tmp .= ', ' . substr($claim->insuredMiddleName(),0,1);
141 put_hcfa(10, 50, 28, $tmp);
143 // Box 5. Patient's Address
144 put_hcfa(12, 1, 28, $claim->patientStreet());
146 // Box 6. Patient Relationship to Insured
147 $tmp = $claim->insuredRelationship();
148 $tmpcol = 47; // Other
149 if ($tmp === '18') $tmpcol = 33; // self
150 else if ($tmp === '01') $tmpcol = 38; // spouse
151 else if ($tmp === '19') $tmpcol = 42; // child
152 put_hcfa(12, $tmpcol, 1, 'X');
154 // Box 7. Insured's Address
155 put_hcfa(12, 50, 28, $claim->insuredStreet());
157 // Box 5 continued. Patient's City and State
158 put_hcfa(14, 1, 20, $claim->patientCity());
159 put_hcfa(14, 26, 2, $claim->patientState());
161 // Box 8. Patient (Marital) Status
162 if(!hcfa_1500_version_02_12()) // Box 8 Reserved for NUCC Use in 02/12
164 $tmp = $claim->patientStatus();
165 $tmpcol = 47; // Other
166 if ($tmp === 'S') $tmpcol = 35; // Single
167 else if ($tmp === 'M') $tmpcol = 41; // Married
168 put_hcfa(14, $tmpcol, 1, 'X');
171 // Box 7 continued. Insured's City and State
172 put_hcfa(14, 50, 20, $claim->insuredCity());
173 put_hcfa(14, 74, 2, $claim->insuredState());
175 // Box 5 continued. Patient's Zip Code and Telephone
176 put_hcfa(16, 1, 10, $claim->patientZip());
177 $tmp = $claim->patientPhone();
178 put_hcfa(16, 15, 3, substr($tmp,0,3));
179 put_hcfa(16, 19, 7, substr($tmp,3));
181 // Box 8 continued. Patient (Employment) Status
182 if(!hcfa_1500_version_02_12()) // Box 8 Reserved for NUCC Use in 02/12
184 $tmp = $claim->patientOccupation();
185 if ($tmp === 'STUDENT' ) put_hcfa(16, 41, 1, 'X');
186 else if ($tmp === 'PT STUDENT') put_hcfa(16, 47, 1, 'X');
187 else if ($tmp !== 'UNEMPLOYED') put_hcfa(16, 35, 1, 'X');
190 // Box 7 continued. Insured's Zip Code and Telephone
191 put_hcfa(16, 50, 10, $claim->insuredZip());
192 $tmp = $claim->insuredPhone();
193 put_hcfa(16, 65, 3, substr($tmp,0,3));
194 put_hcfa(16, 69, 7, substr($tmp,3));
196 // Box 9. Other Insured's Name
197 if ($new_medicare_logic) {
198 // TBD: Medigap stuff? How do we know if this is a Medigap transfer?
200 else {
201 if ($claim->payerCount() > 1) {
202 $tmp = $claim->insuredLastName(1) . ', ' . $claim->insuredFirstName(1);
203 if ($claim->insuredMiddleName(1))
204 $tmp .= ', ' . substr($claim->insuredMiddleName(1),0,1);
205 put_hcfa(18, 1, 28, $tmp);
209 // Box 11. Insured's Group Number
210 if ($new_medicare_logic) {
211 // If this is Medicare secondary then we need the primary's policy number
212 // here, otherwise the word "NONE".
213 $tmp = $claim->payerSequence() == 'P' ? 'NONE' : $claim->policyNumber(1);
215 else {
216 $tmp = $claim->groupNumber();
218 put_hcfa(18, 50, 30, $tmp);
220 // Box 9a. Other Insured's Policy or Group Number
221 if ($new_medicare_logic) {
222 // TBD: Medigap stuff?
224 else {
225 if ($claim->payerCount() > 1) {
226 put_hcfa(20, 1, 28, $claim->policyNumber(1));
230 // Box 10a. Employment Related
231 put_hcfa(20, $claim->isRelatedEmployment() ? 35 : 41, 1, 'X');
233 // Box 11a. Insured's Birth Date and Sex
234 if ($new_medicare_logic) {
235 $tmpdob = $tmpsex = '';
236 if ($claim->payerSequence() != 'P') {
237 $tmpdob = $claim->insuredDOB(1);
238 $tmpsex = $claim->insuredSex(1);
241 else {
242 $tmpdob = $claim->insuredDOB();
243 $tmpsex = $claim->insuredSex();
245 if ($tmpdob) {
246 put_hcfa(20, 53, 2, substr($tmpdob,4,2));
247 put_hcfa(20, 56, 2, substr($tmpdob,6,2));
248 put_hcfa(20, 59, 4, substr($tmpdob,0,4));
250 if ($tmpsex) {
251 put_hcfa(20, $tmpsex == 'M' ? 68 : 75, 1, 'X');
254 // Box 9b. Other Insured's Birth Date and Sex
255 if(!hcfa_1500_version_02_12()) // Box 9b Reserved for NUCC Use in 02/12
257 if ($new_medicare_logic) {
258 // TBD: Medigap stuff?
260 else {
261 if ($claim->payerCount() > 1) {
262 $tmp = $claim->insuredDOB(1);
263 put_hcfa(22, 2, 2, substr($tmp,4,2));
264 put_hcfa(22, 5, 2, substr($tmp,6,2));
265 put_hcfa(22, 8, 4, substr($tmp,0,4));
266 put_hcfa(22, $claim->insuredSex(1) == 'M' ? 18 : 24, 1, 'X');
271 // Box 10b. Auto Accident
272 put_hcfa(22, $claim->isRelatedAuto() ? 35 : 41, 1, 'X');
273 if ($claim->isRelatedAuto())
274 put_hcfa(22, 45, 2, $claim->autoAccidentState());
276 // Box 11b. Insured's Employer/School Name
277 if ($new_medicare_logic) {
278 $tmp = $claim->payerSequence() == 'P' ? '' : $claim->groupName(1);
280 else {
281 $tmp = $claim->groupName();
283 put_hcfa(22, 50, 30, $tmp);
285 // Box 9c. Other Insured's Employer/School Name
286 if(!hcfa_1500_version_02_12()) // Box 9c Reserved for NUCC Use in 02/12
288 if ($new_medicare_logic) {
289 // TBD: Medigap stuff?
291 else {
292 if ($claim->payerCount() > 1) {
293 put_hcfa(24, 1, 28, $claim->groupName(1));
298 // Box 10c. Other Accident
299 put_hcfa(24, $claim->isRelatedOther() ? 35 : 41, 1, 'X');
301 // Box 11c. Insurance Plan Name or Program Name
302 if ($new_medicare_logic) {
303 $tmp = '';
304 if ($claim->payerSequence() != 'P') {
305 $tmp = $claim->planName(1);
306 if (!$tmp) $tmp = $claim->payerName(1);
309 else {
310 $tmp = $claim->planName();
312 put_hcfa(24, 50, 30, $tmp);
314 // Box 9d. Other Insurance Plan Name or Program Name
315 if ($new_medicare_logic) {
316 // TBD: Medigap stuff?
318 else {
319 if ($claim->payerCount() > 1) {
320 put_hcfa(26, 1, 28, $claim->planName(1));
324 // Box 10d. Claim Codes medicaid_referral_code
326 if($claim->epsdtFlag()) {
327 put_hcfa(26, 34, 2, $claim->medicaidReferralCode());
330 // Box 11d. Is There Another Health Benefit Plan
332 if (!$new_medicare_logic) {
333 put_hcfa(26, $claim->payerCount() > 1 ? 52 : 57, 1, 'X');
336 // Box 12. Patient's or Authorized Person's Signature
337 put_hcfa(29, 7, 17, 'Signature on File');
338 // Note: Date does not apply unless the person physically signs the form.
340 // Box 13. Insured's or Authorized Person's Signature
341 put_hcfa(29, 55, 17, 'Signature on File');
343 // Box 14. Date of Current Illness/Injury/Pregnancy
344 $tmp = $claim->miscOnsetDate();
345 put_hcfa(32, 2, 2, substr($tmp,4,2));
346 put_hcfa(32, 5, 2, substr($tmp,6,2));
347 put_hcfa(32, 8, 4, substr($tmp,0,4));
349 if(hcfa_1500_version_02_12() && !empty($tmp))
351 // Only include the Box 14 qualifier if using version 02/12 and there is a Box 14 date.
352 put_hcfa(32, 16, 3, $claim->box14Qualifier());
355 // Box 15. First Date of Same or Similar Illness, if applicable
356 $tmp = $claim->dateInitialTreatment();
357 if(hcfa_1500_version_02_12() && !empty($tmp))
359 // Only include the Box 15 qualifier if using version 02/12 and there is a Box 15 date.
360 put_hcfa(32, 31, 3, $claim->box15Qualifier());
363 put_hcfa(32,37, 2, substr($tmp,4,2));
364 put_hcfa(32,40, 2, substr($tmp,6,2));
365 put_hcfa(32,43, 4, substr($tmp,0,4));
367 // Box 16. Dates Patient Unable to Work in Current Occupation
368 if ($claim->isUnableToWork()) {
369 $tmp = $claim->offWorkFrom();
370 put_hcfa(32, 54, 2, substr($tmp,4,2));
371 put_hcfa(32, 57, 2, substr($tmp,6,2));
372 put_hcfa(32, 60, 4, substr($tmp,0,4));
373 $tmp = $claim->offWorkTo();
374 put_hcfa(32, 68, 2, substr($tmp,4,2));
375 put_hcfa(32, 71, 2, substr($tmp,6,2));
376 put_hcfa(32, 74, 4, substr($tmp,0,4));
379 // Referring provider stuff. Reports are that for primary care doctors,
380 // Medicare forbids an entry here and other payers require one.
381 // There is still confusion over this.
383 if ($claim->referrerLastName() || $claim->billingProviderLastName() &&
384 (empty($GLOBALS['MedicareReferrerIsRenderer']) || $claim->claimType() != 'MB'))
386 // Box 17a. Referring Provider Alternate Identifier
387 // Commented this out because UPINs are obsolete, leaving the code as an
388 // example in case some other identifier needs to be supported.
389 /*****************************************************************
390 if ($claim->referrerUPIN() && $claim->claimType() != 'MB') {
391 put_hcfa(33, 30, 2, '1G');
392 put_hcfa(33, 33, 15, $claim->referrerUPIN());
394 *****************************************************************/
395 if ($claim->claimType() == 'MC') {
396 put_hcfa(33, 30, 2, 'ZZ');
397 put_hcfa(33, 33, 14, $claim->referrerTaxonomy());
399 // Box 17. Name of Referring Provider or Other Source leave it like it is just check if there is info in misc_billing the use it provider_qualifier_code
400 # Changed to look first at the misc hcfa billing form to complete this box if nothing on misc hcfa form use referrer
401 if (strlen($claim->billingProviderLastName()) !=0) {
402 $tmp2 = $claim->billingProviderLastName() . ', ' . $claim->billingProviderFirstName();
403 if ($claim->billingProviderMiddleName())
404 $tmp2 .= ', ' . substr($claim->billingProviderMiddleName(),0,1);
405 put_hcfa(34, 1, 3, $claim->billing_options['provider_qualifier_code']);
406 put_hcfa(34, 4, 25, $tmp2);
407 if ($claim->billingProviderNPI()) {
408 put_hcfa(34, 33, 15, $claim->billingProviderNPI());
411 else
413 $tmp = $claim->referrerLastName() . ', ' . $claim->referrerFirstName();
414 if ($claim->referrerMiddleName())
415 $tmp .= ', ' . substr($claim->referrerMiddleName(),0,1);
416 put_hcfa(34, 1, 3, 'DN');
417 put_hcfa(34, 4, 25, $tmp);
418 if ($claim->referrerNPI()) {
419 put_hcfa(34, 33, 15, $claim->referrerNPI());
424 // Box 18. Hospitalization Dates Related to Current Services
425 if ($claim->isHospitalized()) {
426 $tmp = $claim->hospitalizedFrom();
427 put_hcfa(34, 54, 2, substr($tmp,4,2));
428 put_hcfa(34, 57, 2, substr($tmp,6,2));
429 put_hcfa(34, 60, 4, substr($tmp,0,4));
430 $tmp = $claim->hospitalizedTo();
431 put_hcfa(34, 68, 2, substr($tmp,4,2));
432 put_hcfa(34, 71, 2, substr($tmp,6,2));
433 put_hcfa(34, 74, 4, substr($tmp,0,4));
436 // Box 19. Reserved for Local Use
437 put_hcfa(36, 1, 48, $claim->additionalNotes());
439 // Box 20. Outside Lab
440 put_hcfa(36, $claim->isOutsideLab() ? 52 : 57, 1, 'X');
441 if ($claim->isOutsideLab()) {
442 // Note here that put_hcfa strips the decimal point, as required.
443 // We right-justify this amount (ending in col. 69).
444 put_hcfa(36, 63, 8, sprintf('%8s', $claim->outsideLabAmount()));
447 if(hcfa_1500_version_02_12())
449 process_diagnoses_02_12($claim,$log);
451 else
453 // Box 21. Diagnoses
454 $tmp = $claim->diagArray();
455 $diags = array();
456 foreach ($tmp as $diag) $diags[] = $diag;
457 if (!empty($diags[0])) {
458 put_hcfa(38, 3, 3, substr($diags[0], 0, 3));
459 put_hcfa(38, 7, 2, substr($diags[0], 3));
461 if (!empty($diags[2])) {
462 put_hcfa(38, 30, 3, substr($diags[2], 0, 3));
463 put_hcfa(38, 34, 2, substr($diags[2], 3));
466 // Box 22. Medicaid Resubmission Code and Original Ref. No.
467 put_hcfa(38, 50, 10, $claim->medicaidResubmissionCode());
468 put_hcfa(38, 62, 15, $claim->medicaidOriginalReference());
470 // Box 21 continued. Diagnoses
471 if (!empty($diags[1])) {
472 put_hcfa(40, 3, 3, substr($diags[1], 0, 3));
473 put_hcfa(40, 7, 2, substr($diags[1], 3));
475 if (!empty($diags[3])) {
476 put_hcfa(40, 30, 3, substr($diags[3], 0, 3));
477 put_hcfa(40, 34, 2, substr($diags[3], 3));
480 // Box 23. Prior Authorization Number
481 put_hcfa(40, 50, 28, $claim->priorAuth());
483 $proccount = $claim->procCount(); // number of procedures
485 // Charges, adjustments and payments are accumulated by line item so that
486 // each page of a multi-page claim will stand alone. Payments include the
487 // co-pay for the first page only.
488 $clm_total_charges = 0;
489 $clm_amount_adjusted = 0;
490 $clm_amount_paid = $hcfa_proc_index ? 0 : $claim->patientPaidAmount();
492 // Procedure loop starts here.
494 for ($svccount = 0; $svccount < 6 && $hcfa_proc_index < $proccount; ++$hcfa_proc_index) {
495 $dia = $claim->diagIndexArray($hcfa_proc_index);
497 if (!$claim->cptCharges($hcfa_proc_index)) {
498 $log .= "*** Procedure '" . $claim->cptKey($hcfa_proc_index) .
499 "' has no charges!\n";
502 if (empty($dia)) {
503 $log .= "*** Procedure '" . $claim->cptKey($hcfa_proc_index) .
504 "' is not justified!\n";
507 $clm_total_charges += $claim->cptCharges($hcfa_proc_index);
509 // Compute prior payments and "hard" adjustments.
510 for ($ins = 1; $ins < $claim->payerCount(); ++$ins) {
511 if ($claim->payerSequence($ins) > $claim->payerSequence())
512 continue; // skip future payers
513 $payerpaid = $claim->payerTotals($ins, $claim->cptKey($hcfa_proc_index));
514 $clm_amount_paid += $payerpaid[1];
515 $clm_amount_adjusted += $payerpaid[2];
518 ++$svccount;
519 $lino = $svccount * 2 + 41;
521 // Drug Information. Medicaid insurers want this with HCPCS codes.
523 $ndc = $claim->cptNDCID($hcfa_proc_index);
524 if ($ndc) {
525 if (preg_match('/^(\d\d\d\d\d)-(\d\d\d\d)-(\d\d)$/', $ndc, $tmp)) {
526 $ndc = $tmp[1] . $tmp[2] . $tmp[3];
528 else if(preg_match('/^\d{11}$/', $ndc)){
531 else {
532 $log .= "*** NDC code '$ndc' has invalid format!\n";
534 put_hcfa($lino, 1, 50, "N4$ndc " . $claim->cptNDCUOM($hcfa_proc_index) .
535 $claim->cptNDCQuantity($hcfa_proc_index));
538 //Note Codes.
539 put_hcfa($lino, 25, 7, $claim->cptNotecodes($hcfa_proc_index));
541 // 24i and 24j Top. ID Qualifier and Rendering Provider ID
542 if ($claim->supervisorNumber()) {
543 // If there is a supervising provider and that person has a
544 // payer-specific provider number, then we assume that the SP
545 // must be identified on the claim and this is how we do it
546 // (but the NPI of the actual rendering provider appears below).
547 // BCBS of TN indicated they want it this way. YMMV. -- Rod
548 put_hcfa($lino, 65, 2, $claim->supervisorNumberType());
549 put_hcfa($lino, 68, 10, $claim->supervisorNumber());
551 else if ($claim->providerNumber($hcfa_proc_index)) {
552 put_hcfa($lino, 65, 2, $claim->providerNumberType($hcfa_proc_index));
553 put_hcfa($lino, 68, 10, $claim->providerNumber($hcfa_proc_index));
555 else if ($claim->claimType() == 'MC') {
556 put_hcfa($lino, 65, 2, 'ZZ');
557 put_hcfa($lino, 68, 14, $claim->providerTaxonomy());
560 ++$lino;
562 // 24a. Date of Service
563 $tmp = $claim->serviceDate();
564 put_hcfa($lino, 1, 2, substr($tmp,4,2));
565 put_hcfa($lino, 4, 2, substr($tmp,6,2));
566 put_hcfa($lino, 7, 2, substr($tmp,2,2));
567 put_hcfa($lino,10, 2, substr($tmp,4,2));
568 put_hcfa($lino,13, 2, substr($tmp,6,2));
569 put_hcfa($lino,16, 2, substr($tmp,2,2));
571 // 24b. Place of Service
572 put_hcfa($lino, 19, 2, $claim->facilityPOS());
574 // 24c. EMG
575 // Not currently supported.
577 // 24d. Procedures, Services or Supplies
578 put_hcfa($lino, 25, 7, $claim->cptCode($hcfa_proc_index));
579 // replace colon with space for printing
580 put_hcfa($lino, 33, 12, str_replace(':', ' ', $claim->cptModifier($hcfa_proc_index)));
582 // 24e. Diagnosis Pointer
583 $tmp = '';
584 foreach ($claim->diagIndexArray($hcfa_proc_index) as $value)
586 if(hcfa_1500_version_02_12())// For 02/12 Version convert number to letter.
588 // ASCII A is 65, since diagIndexArray is ones based, this will make 1->A, 2->B...
589 $value=chr($value+64);
591 $tmp .= $value;
593 put_hcfa($lino, 45, 4, $tmp);
595 // 24f. Charges
596 put_hcfa($lino, 50, 8, str_replace('.', ' ',
597 sprintf('%8.2f', $claim->cptCharges($hcfa_proc_index))));
599 // 24g. Days or Units
600 put_hcfa($lino, 59, 3, $claim->cptUnits($hcfa_proc_index));
602 // 24h. EPSDT Family Plan
604 if($claim->epsdtFlag()) {
605 put_hcfa($lino, 63, 2, '03');
608 // 24j. Rendering Provider NPI
609 put_hcfa($lino, 68, 10, $claim->providerNPI($hcfa_proc_index));
612 // 25. Federal Tax ID Number
613 // FrreB hard coded EIN. Changed it to included SSN as well.
614 put_hcfa(56, 1, 15, $claim->billingFacilityETIN());
615 if($claim->federalIdType()=='SY'){
616 put_hcfa(56, 17, 1, 'X'); // The SSN checkbox
618 else{
619 put_hcfa(56, 19, 1, 'X'); // The EIN checkbox
622 // 26. Patient's Account No.
623 // Instructions say hyphens are not allowed.
624 put_hcfa(56, 23, 15, "$pid-$encounter");
626 // 27. Accept Assignment
627 put_hcfa(56, $claim->billingFacilityAssignment() ? 38 : 43, 1, 'X');
629 // 28. Total Charge
630 put_hcfa(56, 52, 8, str_replace('.',' ',sprintf('%8.2f',$clm_total_charges)));
631 if (!$clm_total_charges) {
632 $log .= "*** This claim has no charges!\n";
635 // 29. Amount Paid
636 put_hcfa(56, 62, 8, str_replace('.',' ',sprintf('%8.2f',$clm_amount_paid)));
638 // 30. Balance Due
639 // For secondary payers this reflects primary "contracted rate" adjustments,
640 // so in general box 30 will not equal box 28 minus box 29.
641 if(!hcfa_1500_version_02_12()) // Box 30 Reserved for NUCC Use in 02/12
643 put_hcfa(56, 71, 8, str_replace('.',' ',sprintf('%8.2f',
644 $clm_total_charges - $clm_amount_paid - $clm_amount_adjusted)));
647 // 33. Billing Provider: Phone Number
648 $tmp = $claim->billingContactPhone();
649 put_hcfa(57, 66, 3, substr($tmp,0,3));
650 put_hcfa(57, 70, 3, substr($tmp,3)); // slight adjustment for better look smw 030315
651 put_hcfa(57, 73, 1, '-');
652 put_hcfa(57, 74, 4, substr($tmp,6));
654 // 32. Service Facility Location Information: Name
655 put_hcfa(58, 23, 25, $claim->facilityName());
657 // 33. Billing Provider: Name
658 if($claim->federalIdType()=='SY'){
659 $tempName = $claim->billingFacilityName();
660 $partsName = explode(' ', $tempName);// entity == person
661 $num_parts = count($partsName);
662 switch ($num_parts) {
663 case "2":
664 $firstName = $partsName[0];
665 $lastName = $partsName[1];
666 $billingProviderName = $lastName . ", " . $firstName;
667 break;
668 case "3":
669 $firstName = $partsName[0];
670 $middleName = $partsName[1];
671 $lastName = $partsName[2];
672 $billingProviderName = $lastName . ", " . $firstName. ", " . $middleName;
673 break;
674 case "4":
675 $firstName = $partsName[0];
676 $middleName = $partsName[1];
677 $lastName = $partsName[2];
678 $suffixName = $partsName[3];
679 $billingProviderName = $lastName . ", " . $firstName. ", " . $middleName. ", " . $suffixName;
680 break;
681 default:
682 $log .= "*** individual name has more than 4 parts and may not be desirable on the claim form\n";
683 $firstName = $partsName[0];
684 $middleName = $partsName[1];
685 $lastName = $partsName[2];
686 $suffixName = $partsName[3];
687 $billingProviderName = $lastName . ", " . $firstName. ", " . $middleName. ", " . $suffixName;
689 put_hcfa(58, 50, 25, $billingProviderName);
691 else {
692 put_hcfa(58, 50, 25, $claim->billingFacilityName());
694 // 32. Service Facility Location Information: Street
695 put_hcfa(59, 23, 25, $claim->facilityStreet());
697 // 33. Billing Provider: Name
698 put_hcfa(59, 50, 25, $claim->billingFacilityStreet());
700 // 31. Signature of Physician or Supplier
702 if($GLOBALS['cms_1500_box_31_format']==0)
704 put_hcfa(60, 1, 20, 'Signature on File');
706 else if($GLOBALS['cms_1500_box_31_format']==1)
708 put_hcfa(60, 1, 22, $claim->providerFirstName()." ".$claim->providerLastName());
711 // $tmp = $claim->providerFirstName();
712 // if ($claim->providerMiddleName()) $tmp .= ' ' . substr($claim->providerMiddleName(),0,1);
713 // put_hcfa(60, 1, 20, $tmp . ' ' . $claim->providerLastName());
715 // 32. Service Facility Location Information: City State Zip
716 $tmp = $claim->facilityCity() ? ($claim->facilityCity() . ' ') : '';
717 put_hcfa(60, 23, 27, $tmp . $claim->facilityState() . ' ' .
718 $claim->facilityZip());
720 // 33. Billing Provider: City State Zip
721 $tmp = $claim->billingFacilityCity() ? ($claim->billingFacilityCity() . ' ') : '';
722 put_hcfa(60, 50, 27, $tmp . $claim->billingFacilityState() . ' ' .
723 $claim->billingFacilityZip());
725 // 31. Signature of Physician or Supplier: Date
726 if($GLOBALS['cms_1500_box_31_date']>0)
728 if($GLOBALS['cms_1500_box_31_date']==1)
730 $date_of_service= $claim->serviceDate();
731 $MDY=substr($date_of_service,4,2)." ".substr($date_of_service,6,2)." ".substr($date_of_service,2,2);
733 else if($GLOBALS['cms_1500_box_31_date']==2)
735 $MDY=date("m/d/y");
737 put_hcfa(61,6,10,$MDY);
740 // 32a. Service Facility NPI
741 put_hcfa(61, 23, 10, $claim->facilityNPI());
743 // 32b. Service Facility Other ID
744 // Note that Medicare does NOT want this any more.
745 if ($claim->providerGroupNumber()) {
746 put_hcfa(61, 36, 2, $claim->providerNumberType());
747 put_hcfa(61, 38, 11, $claim->providerGroupNumber());
750 // 33a. Billing Facility NPI
751 put_hcfa(61, 50, 10, $claim->billingFacilityNPI());
753 // 33b. Billing Facility Other ID
754 // Note that Medicare does NOT want this any more.
755 if ($claim->claimType() == 'MC') {
756 put_hcfa(61, 63, 2, 'ZZ');
757 put_hcfa(61, 65, 14, $claim->providerTaxonomy());
758 } elseif ($claim->providerGroupNumber() && $claim->claimType() != 'MB') {
759 put_hcfa(61, 63, 2, $claim->providerNumberType());
760 put_hcfa(61, 65, 14, $claim->providerGroupNumber());
763 // Put an extra line here for compatibility with old hcfa text generated form
764 put_hcfa(62, 1, 1, ' ');
765 // put a couple more in so that multiple claims correctly print through the text file download
766 put_hcfa(63, 1, 1, ' ');
767 put_hcfa(64, 1, 1, ' ');
768 return;