Update X12_5010_837P.php (#2599)
[openemr.git] / src / Billing / HCFA_1500.php
bloba6c7549daccf6bbeacfd2136cd79f723650a6d7d
1 <?php
2 /* HCFA_1500 Class
4 * This program creates the HCFA 1500 claim form.
6 * @package OpenEMR
7 * @author Rod Roark <rod@sunsetsystems.com>
8 * @author Stephen Waite <stephen.waite@cmsvt.com>
9 * @copyright Copyright (c) 2011 Rod Roark <rod@sunsetsystems.com>
10 * @copyright Copyright (C) 2018 Stephen Waite <stephen.waite@cmsvt.com>
11 * @link https://www.open-emr.org
12 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
15 namespace OpenEMR\Billing;
17 require_once(dirname(__FILE__) . "/../../library/invoice_summary.inc.php");
19 use OpenEMR\Billing\Claim;
20 use OpenEMR\Billing\HCFA_Info;
22 class HCFA_1500
24 protected $hcfa_curr_line;
25 protected $hcfa_curr_col;
26 protected $hcfa_data;
27 protected $hcfa_proc_index;
28 /**
29 * HCFA_1500 constructor.
30 * @param int $hcfa_curr_line
31 * @param int $hcfa_curr_col
32 * @param type $hcfa_data
33 * @param int $hcfa_proc_index
35 public function __construct()
37 $this->hcfa_curr_line = 1;
38 $this->hcfa_curr_col = 1;
39 $this->hcfa_data = '';
40 $this->hcfa_proc_index = 0;
43 /**
44 * take the data element and place it at the correct coordinates on the page
46 * @global int $hcfa_curr_line
47 * @global int $hcfa_curr_col
48 * @global type $hcfa_data
49 * @param type $line
50 * @param type $col
51 * @param type $maxlen
52 * @param type $data
53 * @param type $strip regular expression for what to strip from the data. period and has are the defaults
54 * 02/12 version needs to include periods in the diagnoses hence the need to override
56 private function put_hcfa($line, $col, $maxlen, $data, $strip = '/[.#]/')
58 if ($line < $this->hcfa_curr_line) {
59 die("Data item at ($line, $col) precedes current line $this->hcfa_curr_line and $data");
62 while ($this->hcfa_curr_line < $line) {
63 $this->hcfa_data .= "\n";
64 ++$this->hcfa_curr_line;
65 $this->hcfa_curr_col = 1;
68 if ($col < $this->hcfa_curr_col) {
69 die("Data item at ($line, $col) precedes current column.");
72 while ($this->hcfa_curr_col < $col) {
73 $this->hcfa_data .= " ";
74 ++$this->hcfa_curr_col;
77 $data = preg_replace($strip, '', strtoupper($data));
78 $len = min(strlen($data), $maxlen);
79 $this->hcfa_data .= substr($data, 0, $len);
80 $this->hcfa_curr_col += $len;
83 /**
84 * Process the diagnoses for a given claim. log any errors
86 * @param type $claim
87 * @param string $log
89 private function process_diagnoses_02_12($claim, &$log)
91 $hcfa_entries=array();
92 $diags = $claim->diagArray(false);
93 if ($claim->diagtype=='ICD10') {
94 $icd_indicator='0';
95 } else {
96 $icd_indicator='9';
99 $hcfa_entries[]=new HCFA_Info(37, 42, 1, $icd_indicator);
101 // Box 22. Medicaid Resubmission Code and Original Ref. No.
102 $hcfa_entries[]=new HCFA_Info(38, 50, 10, $claim->medicaidResubmissionCode());
103 $hcfa_entries[]=new HCFA_Info(38, 62, 15, $claim->medicaidOriginalReference());
105 // Box 23. Prior Authorization Number
106 $hcfa_entries[]=new HCFA_Info(40, 50, 28, $claim->priorAuth());
108 $diag_count=0;
109 foreach ($diags as $diag) {
110 if ($diag_count<12) {
111 $this->add_diagnosis($hcfa_entries, $diag_count, $diag);
112 } else {
113 $log.= "***Too many diagnoses ".($diag_count+1).":".$diag;
116 $diag_count++;
118 // Sort the entries to put them in the page base sequence.
119 usort($hcfa_entries, array('OpenEMR\Billing\HCFA_Info', 'cmp_hcfa_info'));
121 foreach ($hcfa_entries as $hcfa_entry) {
122 $this->put_hcfa($hcfa_entry->getRow(), $hcfa_entry->getColumn(), $hcfa_entry->getWidth(), $hcfa_entry->getInfo(), '/#/');
126 * calculate where on the form a given diagnosis belongs and add it to the entries
128 * @param array $hcfa_entries
129 * @param type $number
130 * @param type $diag
132 private function add_diagnosis(&$hcfa_entries, $number, $diag)
135 * The diagnoses go across the page.
136 * Positioned
137 * A B C D
138 * E F G H
139 * I J K L
141 $column_num = ($number%4);
142 $row_num = (int)($number / 4);
144 // First column is at location 3, each column is 13 wide
145 $col_pos=3+13*$column_num;
147 // First diagnosis row is 38
148 $strip='/[.#]/';
149 $diag = preg_replace($strip, '', strtoupper($diag));
150 $row_pos=38+$row_num;
151 $hcfa_entries[]=new HCFA_Info($row_pos, $col_pos, 8, $diag);
154 public function gen_hcfa_1500($pid, $encounter, &$log)
156 $this->hcfa_data = '';
157 $this->hcfa_proc_index = 0;
159 $today = time();
161 $claim = new Claim($pid, $encounter);
163 $log .= "Generating HCFA claim $pid-$encounter for " .
164 $claim->patientFirstName() . ' ' .
165 $claim->patientMiddleName() . ' ' .
166 $claim->patientLastName() . ' on ' .
167 date('Y-m-d H:i', $today) . ".\n";
169 while ($this->hcfa_proc_index < $claim->procCount()) {
170 if ($this->hcfa_proc_index) {
171 $this->hcfa_data .= "\014"; // append form feed for new page
174 $this->gen_hcfa_1500_page($pid, $encounter, $log, $claim);
177 $log .= "\n";
178 return $this->hcfa_data;
181 private function gen_hcfa_1500_page($pid, $encounter, &$log, $claim)
184 $this->hcfa_curr_line = 1;
185 $this->hcfa_curr_col = 1;
187 // According to:
188 // https://www.ngsmedicare.com/NGSMedicare/PartB/EducationandSupport/ToolsandMaterials/CMS_ClaimFormInst.aspx
189 // Medicare interprets sections 9 and 11 of the claim form in its own
190 // special way. This flag tells us to do that. However I'm not 100%
191 // sure that it applies nationwide, and if you find that it is not right
192 // for you then set it to false. -- Rod 2009-03-26
193 $new_medicare_logic = $claim->claimType() == 'MB';
195 // Payer name, attn, street.
196 $this->put_hcfa(2, 41, 31, $claim->payerName());
197 $this->put_hcfa(3, 41, 31, $claim->payerAttn());
198 $this->put_hcfa(4, 41, 31, $claim->payerStreet());
200 // Payer city, state, zip.
201 $tmp = $claim->payerCity() ? ($claim->payerCity() . ', ') : '';
202 $this->put_hcfa(5, 41, 31, $tmp . $claim->payerState() . ' ' . $claim->payerZip());
204 // Box 1. Insurance Type
205 // claimTypeRaw() gets the integer value from insurance_companies.ins_type_code.
206 // Previous version of this code called claimType() which maps ins_type_code to
207 // a 2-character code and that was not specific enough.
208 $ct = $claim->claimTypeRaw();
209 $tmpcol = 45; // Other
210 if ($ct == 2) {
211 $tmpcol = 1; // Medicare
212 } else if ($ct == 3) {
213 $tmpcol = 8; // Medicaid
214 } else if ($ct == 5) {
215 $tmpcol = 15; // TriCare (formerly CHAMPUS)
216 } else if ($ct == 4) {
217 $tmpcol = 24; // Champus VA
218 } else if ($ct == 6) {
219 $tmpcol = 31; // Group Health Plan (only BCBS?)
220 } else if ($ct == 7) {
221 $tmpcol = 39; // FECA
224 $this->put_hcfa(8, $tmpcol, 1, 'X');
226 // Box 1a. Insured's ID Number
227 $this->put_hcfa(8, 50, 17, $claim->policyNumber());
229 // Box 2. Patient's Name
230 $tmp = $claim->patientLastName() . ', ' . $claim->patientFirstName();
231 if ($claim->patientMiddleName()) {
232 $tmp .= ', ' . substr($claim->patientMiddleName(), 0, 1);
235 $this->put_hcfa(10, 1, 28, $tmp);
237 // Box 3. Patient's Birth Date and Sex
238 $tmp = $claim->patientDOB();
239 $this->put_hcfa(10, 31, 2, substr($tmp, 4, 2));
240 $this->put_hcfa(10, 34, 2, substr($tmp, 6, 2));
241 $this->put_hcfa(10, 37, 4, substr($tmp, 0, 4));
242 $this->put_hcfa(10, $claim->patientSex() == 'M' ? 42 : 47, 1, 'X');
244 // Box 4. Insured's Name
245 $tmp = $claim->insuredLastName() . ', ' . $claim->insuredFirstName();
246 if ($claim->insuredMiddleName()) {
247 $tmp .= ', ' . substr($claim->insuredMiddleName(), 0, 1);
250 $this->put_hcfa(10, 50, 28, $tmp);
252 // Box 5. Patient's Address
253 $this->put_hcfa(12, 1, 28, $claim->patientStreet());
255 // Box 6. Patient Relationship to Insured
256 $tmp = $claim->insuredRelationship();
257 $tmpcol = 47; // Other
258 if ($tmp === '18') {
259 $tmpcol = 33; // self
260 } else if ($tmp === '01') {
261 $tmpcol = 38; // spouse
262 } else if ($tmp === '19') {
263 $tmpcol = 42; // child
266 $this->put_hcfa(12, $tmpcol, 1, 'X');
268 // Box 7. Insured's Address
269 $this->put_hcfa(12, 50, 28, $claim->insuredStreet());
271 // Box 5 continued. Patient's City and State
272 $this->put_hcfa(14, 1, 20, $claim->patientCity());
273 $this->put_hcfa(14, 26, 2, $claim->patientState());
275 // Box 8. Reserved for NUCC Use in 02/12
277 // Box 7 continued. Insured's City and State
278 $this->put_hcfa(14, 50, 20, $claim->insuredCity());
279 $this->put_hcfa(14, 74, 2, $claim->insuredState());
281 // Box 5 continued. Patient's Zip Code and Telephone
282 $this->put_hcfa(16, 1, 10, $claim->patientZip());
283 $tmp = $claim->patientPhone();
284 $this->put_hcfa(16, 15, 3, substr($tmp, 0, 3));
285 $this->put_hcfa(16, 19, 7, substr($tmp, 3));
287 // Box 7 continued. Insured's Zip Code and Telephone
288 $this->put_hcfa(16, 50, 10, $claim->insuredZip());
289 $tmp = $claim->insuredPhone();
290 $this->put_hcfa(16, 65, 3, substr($tmp, 0, 3));
291 $this->put_hcfa(16, 69, 7, substr($tmp, 3));
293 // Box 9. Other Insured's Name
294 if ($new_medicare_logic) {
295 // TBD: Medigap stuff? How do we know if this is a Medigap transfer?
296 } else {
297 if ($claim->payerCount() > 1) {
298 $tmp = $claim->insuredLastName(1) . ', ' . $claim->insuredFirstName(1);
299 if ($claim->insuredMiddleName(1)) {
300 $tmp .= ', ' . substr($claim->insuredMiddleName(1), 0, 1);
303 $this->put_hcfa(18, 1, 28, $tmp);
307 // Box 11. Insured's Group Number
308 if ($new_medicare_logic) {
309 // If this is Medicare secondary then we need the primary's policy number
310 // here, otherwise the word "NONE".
311 $tmp = $claim->payerSequence() == 'P' ? 'NONE' : $claim->policyNumber(1);
312 } else {
313 $tmp = $claim->groupNumber();
316 $this->put_hcfa(18, 50, 30, $tmp);
318 // Box 9a. Other Insured's Policy or Group Number
319 if ($new_medicare_logic) {
320 // TBD: Medigap stuff?
321 } else {
322 if ($claim->payerCount() > 1) {
323 $this->put_hcfa(20, 1, 28, $claim->policyNumber(1));
327 // Box 10a. Employment Related
328 $this->put_hcfa(20, $claim->isRelatedEmployment() ? 35 : 41, 1, 'X');
330 // Box 11a. Insured's Birth Date and Sex
331 if ($new_medicare_logic) {
332 $tmpdob = $tmpsex = '';
333 if ($claim->payerSequence() != 'P') {
334 $tmpdob = $claim->insuredDOB(1);
335 $tmpsex = $claim->insuredSex(1);
337 } else {
338 $tmpdob = $claim->insuredDOB();
339 $tmpsex = $claim->insuredSex();
342 if ($tmpdob) {
343 $this->put_hcfa(20, 53, 2, substr($tmpdob, 4, 2));
344 $this->put_hcfa(20, 56, 2, substr($tmpdob, 6, 2));
345 $this->put_hcfa(20, 59, 4, substr($tmpdob, 0, 4));
348 if ($tmpsex) {
349 $this->put_hcfa(20, $tmpsex == 'M' ? 68 : 75, 1, 'X');
352 // Box 9b. Reserved for NUCC Use in 02/12
354 // Box 10b. Auto Accident
355 $this->put_hcfa(22, $claim->isRelatedAuto() ? 35 : 41, 1, 'X');
356 if ($claim->isRelatedAuto()) {
357 $this->put_hcfa(22, 45, 2, $claim->autoAccidentState());
360 // Box 11b. Insured's Employer/School Name
361 if ($new_medicare_logic) {
362 $tmp = $claim->payerSequence() == 'P' ? '' : $claim->groupName(1);
363 } else {
364 $tmp = $claim->groupName();
367 $this->put_hcfa(22, 50, 30, $tmp);
369 // Box 9c. Reserved for NUCC Use in 02/12
371 // Box 10c. Other Accident
372 $this->put_hcfa(24, $claim->isRelatedOther() ? 35 : 41, 1, 'X');
374 // Box 11c. Insurance Plan Name or Program Name
375 if ($new_medicare_logic) {
376 $tmp = '';
377 if ($claim->payerSequence() != 'P') {
378 $tmp = $claim->planName(1);
379 if (!$tmp) {
380 $tmp = $claim->payerName(1);
383 } else {
384 $tmp = $claim->planName();
387 $this->put_hcfa(24, 50, 30, $tmp);
389 // Box 9d. Other Insurance Plan Name or Program Name
390 if ($new_medicare_logic) {
391 // TBD: Medigap stuff?
392 } else {
393 if ($claim->payerCount() > 1) {
394 $this->put_hcfa(26, 1, 28, $claim->planName(1));
398 // Box 10d. Claim Codes medicaid_referral_code
400 if ($claim->epsdtFlag()) {
401 $this->put_hcfa(26, 34, 2, $claim->medicaidReferralCode());
404 // Box 11d. Is There Another Health Benefit Plan
406 if (!$new_medicare_logic) {
407 $this->put_hcfa(26, $claim->payerCount() > 1 ? 52 : 57, 1, 'X');
410 // Box 12. Patient's or Authorized Person's Signature
411 $this->put_hcfa(29, 7, 17, 'Signature on File');
412 // Note: Date does not apply unless the person physically signs the form.
414 // Box 13. Insured's or Authorized Person's Signature
415 $this->put_hcfa(29, 55, 17, 'Signature on File');
417 // Box 14. Date of Current Illness/Injury/Pregnancy
418 // this will cause onsetDate in Encounter summary to override misc billing so not perfect yet but fine for now
419 $tmp = ($claim->onsetDate()) ? $claim->onsetDate() : $claim->miscOnsetDate();
420 if (!empty($tmp)) {
421 $this->put_hcfa(32, 2, 2, substr($tmp, 4, 2));
422 $this->put_hcfa(32, 5, 2, substr($tmp, 6, 2));
423 $this->put_hcfa(32, 8, 4, substr($tmp, 0, 4));
424 // Include Box 14 Qualifier
425 $this->put_hcfa(32, 16, 3, $claim->box14Qualifier());
428 // Box 15. First Date of Same or Similar Illness, if applicable
429 $tmp = $claim->dateInitialTreatment();
430 if (!empty($tmp)) {
431 // Only include the Box 15 qualifier if using version 02/12 and there is a Box 15 date.
432 $this->put_hcfa(32, 31, 3, $claim->box15Qualifier());
435 $this->put_hcfa(32, 37, 2, substr($tmp, 4, 2));
436 $this->put_hcfa(32, 40, 2, substr($tmp, 6, 2));
437 $this->put_hcfa(32, 43, 4, substr($tmp, 0, 4));
439 // Box 16. Dates Patient Unable to Work in Current Occupation
440 if ($claim->isUnableToWork()) {
441 $tmp = $claim->offWorkFrom();
442 $this->put_hcfa(32, 54, 2, substr($tmp, 4, 2));
443 $this->put_hcfa(32, 57, 2, substr($tmp, 6, 2));
444 $this->put_hcfa(32, 60, 4, substr($tmp, 0, 4));
445 $tmp = $claim->offWorkTo();
446 $this->put_hcfa(32, 68, 2, substr($tmp, 4, 2));
447 $this->put_hcfa(32, 71, 2, substr($tmp, 6, 2));
448 $this->put_hcfa(32, 74, 4, substr($tmp, 0, 4));
451 // Referring provider stuff. Reports are that for primary care providers,
452 // Medicare forbids an entry here and other payers require one.
453 // There is still confusion over this.
454 if ($claim->referrerLastName() || $claim->billingProviderLastName() &&
455 (empty($GLOBALS['MedicareReferrerIsRenderer']) || $claim->claimType() != 'MB')) {
456 // Box 17a. Referring Provider Alternate Identifier
457 // Commented this out because UPINs are obsolete, leaving the code as an
458 // example in case some other identifier needs to be supported.
459 /*****************************************************************
460 * if ($claim->referrerUPIN() && $claim->claimType() != 'MB') {
461 * $this->put_hcfa(33, 30, 2, '1G');
462 * $this->put_hcfa(33, 33, 15, $claim->referrerUPIN());
464 *****************************************************************/
465 if ($claim->claimType() == 'MC') {
466 $this->put_hcfa(33, 30, 2, 'ZZ');
467 $this->put_hcfa(33, 33, 14, $claim->referrerTaxonomy());
470 // Box 17. Name of Referring Provider or Other Source
471 if (strlen($claim->billingProviderLastName()) != 0) {
472 $tmp2 = $claim->billingProviderLastName() . ', ' . $claim->billingProviderFirstName();
473 if ($claim->billingProviderMiddleName()) {
474 $tmp2 .= ', ' . substr($claim->billingProviderMiddleName(), 0, 1);
477 $this->put_hcfa(34, 1, 3, $claim->billing_options['provider_qualifier_code']);
478 $this->put_hcfa(34, 4, 25, $tmp2);
479 if ($claim->billingProviderNPI()) {
480 $this->put_hcfa(34, 33, 15, $claim->billingProviderNPI());
482 } else {
483 $tmp = $claim->referrerLastName() . ', ' . $claim->referrerFirstName();
484 if ($claim->referrerMiddleName()) {
485 $tmp .= ', ' . substr($claim->referrerMiddleName(), 0, 1);
488 $this->put_hcfa(34, 1, 3, 'DN');
489 $this->put_hcfa(34, 4, 25, $tmp);
490 if ($claim->referrerNPI()) {
491 $this->put_hcfa(34, 33, 15, $claim->referrerNPI());
496 // Box 18. Hospitalization Dates Related to Current Services
497 if ($claim->isHospitalized()) {
498 $tmp = $claim->hospitalizedFrom();
499 $this->put_hcfa(34, 54, 2, substr($tmp, 4, 2));
500 $this->put_hcfa(34, 57, 2, substr($tmp, 6, 2));
501 $this->put_hcfa(34, 60, 4, substr($tmp, 0, 4));
502 $tmp = $claim->hospitalizedTo();
503 $this->put_hcfa(34, 68, 2, substr($tmp, 4, 2));
504 $this->put_hcfa(34, 71, 2, substr($tmp, 6, 2));
505 $this->put_hcfa(34, 74, 4, substr($tmp, 0, 4));
508 // Box 19. Reserved for Local Use
509 $this->put_hcfa(36, 1, 48, $claim->additionalNotes());
511 // Box 20. Outside Lab
512 $this->put_hcfa(36, $claim->isOutsideLab() ? 52 : 57, 1, 'X');
513 if ($claim->isOutsideLab()) {
514 // Note here that $this->put_hcfa strips the decimal point, as required.
515 // We right-justify this amount (ending in col. 69).
516 $this->put_hcfa(36, 63, 8, sprintf('%8s', $claim->outsideLabAmount()));
519 // Box 21. Diagnoses
520 $this->process_diagnoses_02_12($claim, $log);
522 $proccount = $claim->procCount(); // number of procedures
524 // Charges, adjustments and payments are accumulated by line item so that
525 // each page of a multi-page claim will stand alone. Payments include the
526 // co-pay for the first page only.
527 $clm_total_charges = 0;
528 $clm_amount_adjusted = 0;
529 $clm_amount_paid = $this->hcfa_proc_index ? 0 : $claim->patientPaidAmount();
531 // Procedure loop starts here.
532 for ($svccount = 0; $svccount < 6 && $this->hcfa_proc_index < $proccount; ++$this->hcfa_proc_index) {
533 $dia = $claim->diagIndexArray($this->hcfa_proc_index);
535 if (!$claim->cptCharges($this->hcfa_proc_index)) {
536 $log .= "*** Procedure '" . $claim->cptKey($this->hcfa_proc_index) .
537 "' has no charges!\n";
540 if (empty($dia)) {
541 $log .= "*** Procedure '" . $claim->cptKey($this->hcfa_proc_index) .
542 "' is not justified!\n";
545 $clm_total_charges += floatval($claim->cptCharges($this->hcfa_proc_index));
547 // Compute prior payments and "hard" adjustments.
548 for ($ins = 1; $ins < $claim->payerCount(); ++$ins) {
549 if ($claim->payerSequence($ins) > $claim->payerSequence()) {
550 continue; // skip future payers
553 $payerpaid = $claim->payerTotals($ins, $claim->cptKey($this->hcfa_proc_index));
554 $clm_amount_paid += $payerpaid[1];
555 $clm_amount_adjusted += $payerpaid[2];
558 ++$svccount;
559 $lino = $svccount * 2 + 41;
561 // Drug Information. Medicaid insurers want this with HCPCS codes.
563 $ndc = $claim->cptNDCID($this->hcfa_proc_index);
564 if ($ndc) {
565 if (preg_match('/^(\d\d\d\d\d)-(\d\d\d\d)-(\d\d)$/', $ndc, $tmp)) {
566 $ndc = $tmp[1] . $tmp[2] . $tmp[3];
567 } else if (preg_match('/^\d{11}$/', $ndc)) {
568 } else {
569 $log .= "*** NDC code '$ndc' has invalid format!\n";
572 $this->put_hcfa($lino, 1, 50, "N4$ndc " . $claim->cptNDCUOM($this->hcfa_proc_index) .
573 $claim->cptNDCQuantity($this->hcfa_proc_index));
576 //Note Codes.
577 $this->put_hcfa($lino, 25, 7, $claim->cptNotecodes($this->hcfa_proc_index));
579 // 24i and 24j Top. ID Qualifier and Rendering Provider ID
580 if ($claim->supervisorNumber()) {
581 // If there is a supervising provider and that person has a
582 // payer-specific provider number, then we assume that the SP
583 // must be identified on the claim and this is how we do it
584 // (but the NPI of the actual rendering provider appears below).
585 // BCBS of TN indicated they want it this way. YMMV. -- Rod
586 $this->put_hcfa($lino, 65, 2, $claim->supervisorNumberType());
587 $this->put_hcfa($lino, 68, 10, $claim->supervisorNumber());
588 } else if ($claim->providerNumber($this->hcfa_proc_index)) {
589 $this->put_hcfa($lino, 65, 2, $claim->providerNumberType($this->hcfa_proc_index));
590 $this->put_hcfa($lino, 68, 10, $claim->providerNumber($this->hcfa_proc_index));
591 } else if ($claim->claimType() == 'MC') {
592 $this->put_hcfa($lino, 65, 2, 'ZZ');
593 $this->put_hcfa($lino, 68, 14, $claim->providerTaxonomy());
596 ++$lino;
598 // 24a. Date of Service
599 $tmp = $claim->serviceDate();
600 $this->put_hcfa($lino, 1, 2, substr($tmp, 4, 2));
601 $this->put_hcfa($lino, 4, 2, substr($tmp, 6, 2));
602 $this->put_hcfa($lino, 7, 2, substr($tmp, 2, 2));
603 $this->put_hcfa($lino, 10, 2, substr($tmp, 4, 2));
604 $this->put_hcfa($lino, 13, 2, substr($tmp, 6, 2));
605 $this->put_hcfa($lino, 16, 2, substr($tmp, 2, 2));
607 // 24b. Place of Service
608 $this->put_hcfa($lino, 19, 2, $claim->facilityPOS());
610 // 24c. EMG
611 // Not currently supported.
613 // 24d. Procedures, Services or Supplies
614 $this->put_hcfa($lino, 25, 7, $claim->cptCode($this->hcfa_proc_index));
615 // replace colon with space for printing
616 $this->put_hcfa($lino, 33, 12, str_replace(':', ' ', $claim->cptModifier($this->hcfa_proc_index)));
618 // 24e. Diagnosis Pointer
619 $tmp = '';
620 foreach ($claim->diagIndexArray($this->hcfa_proc_index) as $value) {
621 $value = chr($value + 64);
622 $tmp .= $value;
625 $this->put_hcfa($lino, 45, 4, $tmp);
627 // 24f. Charges
628 $this->put_hcfa($lino, 50, 8, str_replace(
629 '.',
630 ' ',
631 sprintf('%8.2f', $claim->cptCharges($this->hcfa_proc_index))
634 // 24g. Days or Units
635 $this->put_hcfa($lino, 59, 3, $claim->cptUnits($this->hcfa_proc_index));
637 // 24h. EPSDT Family Plan
639 if ($claim->epsdtFlag()) {
640 $this->put_hcfa($lino, 63, 2, '03');
643 // 24j. Rendering Provider NPI
644 $this->put_hcfa($lino, 68, 10, $claim->providerNPI($this->hcfa_proc_index));
647 // 25. Federal Tax ID Number
648 $this->put_hcfa(56, 1, 15, $claim->billingFacilityETIN());
649 if ($claim->federalIdType() == 'SY') {
650 $this->put_hcfa(56, 17, 1, 'X'); // The SSN checkbox
651 } else {
652 $this->put_hcfa(56, 19, 1, 'X'); // The EIN checkbox
655 // 26. Patient's Account No.
656 // Instructions say hyphens are not allowed.
657 $this->put_hcfa(56, 23, 15, "$pid-$encounter");
659 // 27. Accept Assignment
660 $this->put_hcfa(56, $claim->billingFacilityAssignment() ? 38 : 43, 1, 'X');
662 // 28. Total Charge
663 $this->put_hcfa(56, 52, 8, str_replace('.', ' ', sprintf('%8.2f', $clm_total_charges)));
664 if (!$clm_total_charges) {
665 $log .= "*** This claim has no charges!\n";
668 // 29. Amount Paid
669 $this->put_hcfa(56, 62, 8, str_replace('.', ' ', sprintf('%8.2f', $clm_amount_paid)));
671 // 30. Reserved for NUCC use.
673 // 33. Billing Provider: Phone Number
674 $tmp = $claim->billingContactPhone();
675 $this->put_hcfa(57, 66, 3, substr($tmp, 0, 3));
676 $this->put_hcfa(57, 70, 3, substr($tmp, 3)); // slight adjustment for better look smw 030315
677 $this->put_hcfa(57, 73, 1, '-');
678 $this->put_hcfa(57, 74, 4, substr($tmp, 6));
680 // 32. Service Facility Location Information: Name
681 $this->put_hcfa(58, 23, 25, $claim->facilityName());
683 // 33. Billing Provider: Name
684 if ($claim->federalIdType() == "SY") { // check entity type for NM*102 1 == person, 2 == non-person entity
685 $firstName = $claim->providerFirstName();
686 $lastName = $claim->providerLastName();
687 $middleName = $claim->providerMiddleName();
688 $suffixName = $claim->providerSuffixName();
689 $billingProviderName = $lastName . ", " . $firstName . ", " . $middleName . ", " . $suffixName;
690 $this->put_hcfa(58, 50, 25, $billingProviderName);
691 } else {
692 $this->put_hcfa(58, 50, 25, $claim->billingFacilityName());
695 // 32. Service Facility Location Information: Street
696 $this->put_hcfa(59, 23, 25, $claim->facilityStreet());
698 // 33. Billing Provider: Name
699 $this->put_hcfa(59, 50, 25, $claim->billingFacilityStreet());
701 // 31. Signature of Physician or Supplier
703 if ($GLOBALS['cms_1500_box_31_format'] == 0) {
704 $this->put_hcfa(60, 1, 20, 'Signature on File');
705 } else if ($GLOBALS['cms_1500_box_31_format'] == 1) {
706 $this->put_hcfa(60, 1, 22, $claim->providerFirstName() . " " . $claim->providerLastName());
709 // 32. Service Facility Location Information: City State Zip
710 $tmp = $claim->facilityCity() ? ($claim->facilityCity() . ' ') : '';
711 $this->put_hcfa(60, 23, 27, $tmp . $claim->facilityState() . ' ' .
712 $claim->facilityZip());
714 // 33. Billing Provider: City State Zip
715 $tmp = $claim->billingFacilityCity() ? ($claim->billingFacilityCity() . ' ') : '';
716 $this->put_hcfa(60, 50, 27, $tmp . $claim->billingFacilityState() . ' ' .
717 $claim->billingFacilityZip());
719 // 31. Signature of Physician or Supplier: Date
720 if ($GLOBALS['cms_1500_box_31_date'] > 0) {
721 if ($GLOBALS['cms_1500_box_31_date'] == 1) {
722 $date_of_service = $claim->serviceDate();
723 $MDY = substr($date_of_service, 4, 2) . " " . substr($date_of_service, 6, 2) . " " . substr($date_of_service, 2, 2);
724 } else if ($GLOBALS['cms_1500_box_31_date'] == 2) {
725 $MDY = date("m/d/y");
728 $this->put_hcfa(61, 6, 10, $MDY);
731 // 32a. Service Facility NPI
732 $this->put_hcfa(61, 23, 10, $claim->facilityNPI());
734 // 32b. Service Facility Other ID
735 // Note that Medicare does NOT want this any more.
736 if ($claim->providerGroupNumber()) {
737 $this->put_hcfa(61, 36, 2, $claim->providerNumberType());
738 $this->put_hcfa(61, 38, 11, $claim->providerGroupNumber());
741 // 33a. Billing Facility NPI
742 $this->put_hcfa(61, 50, 10, $claim->billingFacilityNPI());
744 // 33b. Billing Facility Other ID
745 // Note that Medicare does NOT want this any more.
746 if ($claim->claimType() == 'MC') {
747 $this->put_hcfa(61, 63, 2, 'ZZ');
748 $this->put_hcfa(61, 65, 14, $claim->providerTaxonomy());
749 } elseif ($claim->providerGroupNumber() && $claim->claimType() != 'MB') {
750 $this->put_hcfa(61, 63, 2, $claim->providerNumberType());
751 $this->put_hcfa(61, 65, 14, $claim->providerGroupNumber());
754 // Put an extra line here for compatibility with old hcfa text generated form
755 $this->put_hcfa(62, 1, 1, ' ');
756 // put a couple more in so that multiple claims correctly print through the text file download
757 $this->put_hcfa(63, 1, 1, ' ');
758 $this->put_hcfa(64, 1, 1, ' ');
759 return;