From b5da163a061cc00650d0c5a50c922e2218e70589 Mon Sep 17 00:00:00 2001 From: stephen waite Date: Sun, 6 May 2018 23:37:42 -0400 Subject: [PATCH] begin to support DME billing from misc_billing_options form (#1607) --- library/billing/src/Claim.php | 43 ++++++++++++++++--- library/gen_x12_837.inc.php | 99 ++++++++++++++++++++++++++++++------------- 2 files changed, 108 insertions(+), 34 deletions(-) diff --git a/library/billing/src/Claim.php b/library/billing/src/Claim.php index 2dec006cc..b41d31bd8 100644 --- a/library/billing/src/Claim.php +++ b/library/billing/src/Claim.php @@ -38,7 +38,7 @@ class Claim public $invoice; // result from get_invoice_summary() public $payers; // array of arrays, for all payers public $copay; // total of copays from the ar_activity table - public $facilityService; + public $facilityService; // via matthew.vita orm work :) // This enforces the X12 Basic Character Set. Page A2. private function x12Clean($str) @@ -218,7 +218,7 @@ class Claim $this->facility = $this->facilityService->getById($this->encounter['facility_id']); /***************************************************************** - $provider_id = $this->procs[0]['provider_id']; + $provider_id = $this->procs[0]['provider_id']; *****************************************************************/ $provider_id = $this->encounter['provider_id']; $sql = "SELECT * FROM users WHERE id = '$provider_id'"; @@ -1368,15 +1368,24 @@ class Claim { // If no box qualifier specified use "431" indicating Onset return empty($this->billing_options['box_14_date_qual']) ? '431' : - $this->billing_options['box_14_date_qual']; + $this->billing_options['box_14_date_qual']; } public function box15Qualifier() { // If no box qualifier specified use "454" indicating Initial Treatment return empty($this->billing_options['box_15_date_qual']) ? '454' : - $this->billing_options['box_15_date_qual']; + $this->billing_options['box_15_date_qual']; } + + public function box17Qualifier() + { + //If no box qualifier specified use "DK" for ordering provider + //someday might make mbo form the place to set referring instead of demographics under choices + return empty($this->billing_options['provider_qualifier_code']) ? 'DK' : + $this->billing_options['provider_qualifier_code']; + } + // Returns an array of unique diagnoses. Periods are stripped by default // Option to keep periods is to support HCFA 1500 02/12 version public function diagArray($strip_periods = true) @@ -1687,7 +1696,31 @@ class Claim if (empty($this->billing_prov_id['taxonomy'])) { return '207Q00000X'; } - return $this->x12Clean(trim($this->billing_prov_id['taxonomy'])); } + + public function billingProviderStreet() + { + return $this->x12Clean(trim($this->billing_prov_id['street'])); + } + + public function billingProviderStreetB() + { + return $this->x12Clean(trim($this->billing_prov_id['streetb'])); + } + + public function billingProviderCity() + { + return $this->x12Clean(trim($this->billing_prov_id['city'])); + } + + public function billingProviderState() + { + return $this->x12Clean(trim($this->billing_prov_id['state'])); + } + + public function billingProviderZip() + { + return $this->x12Clean(trim($this->billing_prov_id['zip'])); + } } diff --git a/library/gen_x12_837.inc.php b/library/gen_x12_837.inc.php index fc5de14c9..96583dd60 100644 --- a/library/gen_x12_837.inc.php +++ b/library/gen_x12_837.inc.php @@ -469,14 +469,13 @@ function gen_x12_837($pid, $encounter, &$log, $encounter_claim = false) if ($claim->miscOnsetDate() && ($claim->box14Qualifier()) && ($claim->miscOnsetDateValid())) { ++$edicount; - $out .= "DTP" . // Date Last Seen + $out .= "DTP" . "*" . $claim->box14Qualifier() . "*" . "D8" . "*" . $claim->miscOnsetDate() . "~\n"; } - // Segment DTP*454 (Initial Treatment Date) // Segment DTP*304 (Last Seen Date) // Segment DTP*453 (Acute Manifestation Date) // Segment DTP*439 (Accident Date) @@ -488,6 +487,8 @@ function gen_x12_837($pid, $encounter, &$log, $encounter_claim = false) // Segment DTP*297 (Last Worked Date) // Segment DTP*296 (Authorized Return to Work Date) + // Segment DTP*454 (Initial Treatment Date) + if ($claim->dateInitialTreatment() && ($claim->box15Qualifier()) && ($claim->dateInitialTreatmentValid())) { ++$edicount; $out .= "DTP" . // Date Last Seen @@ -760,8 +761,8 @@ function gen_x12_837($pid, $encounter, &$log, $encounter_claim = false) // Segment REF (Service Facility Location Secondary Identification) omitted. // Segment PER (Service Facility Contact Information) omitted. - // Loop 2310E, Supervising Provider - if ($claim->supervisorLastName()) { + // Loop 2310D, Supervising Provider + if (! empty($claim->supervisorLastName())) { ++$edicount; $out .= "NM1" . "*" . "DQ" . // Supervising Physician @@ -788,7 +789,7 @@ function gen_x12_837($pid, $encounter, &$log, $encounter_claim = false) "~\n"; } } else { - $log .= "*** Supervising provider has invalid last name.\n"; + $log .= "*** Supervising provider is empty.\n"; } // Segments NM1*PW, N3, N4 (Ambulance Pick-Up Location) omitted. @@ -945,16 +946,18 @@ function gen_x12_837($pid, $encounter, &$log, $encounter_claim = false) $loopcount = 0; - // Procedure loop starts here. + // Loop 2400 Procedure Loop. + // + for ($prockey = 0; $prockey < $proccount; ++$prockey) { ++$loopcount; ++$edicount; - $out .= "LX" . // Loop 2400 LX Service Line. Page 398. + $out .= "LX" . // Segment LX, Service Line. Page 398. "*" . $loopcount . "~\n"; ++$edicount; - $out .= "SV1" . // Professional Service. Page 400. + $out .= "SV1" . // Segment SV1, Professional Service. Page 400. "*" . "HC:" . $claim->cptKey($prockey) . "*" . sprintf('%.2f', $claim->cptCharges($prockey)) . "*" . "UN" . @@ -995,8 +998,7 @@ function gen_x12_837($pid, $encounter, &$log, $encounter_claim = false) } // Segment SV5 (Durable Medical Equipment Service) omitted. - // Segment PWK (Line Supplemental Information) omitted. - // Segment PWK (Durable Medical Equipment Certificate of Medical Necessity Indicator) omitted. + // Segment PWK01 (Line Supplemental Information) omitted. // Segment CR1 (Ambulance Transport Information) omitted. // Segment CR3 (Durable Medical Equipment Certification) omitted. // Segment CRC (Ambulance Certification) omitted. @@ -1076,14 +1078,15 @@ function gen_x12_837($pid, $encounter, &$log, $encounter_claim = false) "*" . $claim->cptNDCUOM($prockey) . // Note: 5010 documents "ME" (Milligrams) as an additional unit of measure. "~\n"; + + // Segment REF (Prescription or Compound Drug Association Number) omitted. } - // Segment REF (Prescription or Compound Drug Association Number) omitted. // Loop 2420A, Rendering Provider (service-specific). // Used if the rendering provider for this service line is different // from that in loop 2310B. - // + if ($claim->providerNPI() != $claim->providerNPI($prockey)) { ++$edicount; $out .= "NM1" . // Loop 2420A Rendering Provider @@ -1114,21 +1117,7 @@ function gen_x12_837($pid, $encounter, &$log, $encounter_claim = false) "~\n"; } - // Segment REF (Rendering Provider Secondary Identification) omitted. - // Segment NM1 (Purchased Service Provider Name) omitted. - // Segment REF (Purchased Service Provider Secondary Identification) omitted. - // Segment NM1,N3,N4 (Service Facility Location) omitted. - // Segment REF (Service Facility Location Secondary Identification) omitted. - // Segment NM1 (Supervising Provider Name) omitted. - // Segment REF (Supervising Provider Secondary Identification) omitted. - // Segment NM1,N3,N4 (Ordering Provider) omitted. - // Segment REF (Ordering Provider Secondary Identification) omitted. - // Segment PER (Ordering Provider Contact Information) omitted. - // Segment NM1 (Referring Provider Name) omitted. - // Segment REF (Referring Provider Secondary Identification) omitted. - // Segments NM1*PW, N3, N4 (Ambulance Pick-Up Location) omitted. - // Segments NM1*45, N3, N4 (Ambulance Drop-Off Location) omitted. - + // Segment REF (Rendering Provider Secondary Identification). // REF*1C is required here for the Medicare provider number if NPI was // specified in NM109. Not sure if other payers require anything here. @@ -1138,8 +1127,60 @@ function gen_x12_837($pid, $encounter, &$log, $encounter_claim = false) } } // end provider exception - // Loop 2430, adjudication by previous payers. - // + // Segment NM1 (Loop 2420B Purchased Service Provider Name) omitted. + // Segment REF (Loop 2420B Purchased Service Provider Secondary Identification) omitted. + // Segment NM1,N3,N4 (Loop 2420C Service Facility Location) omitted. + // Segment REF (Loop 2420C Service Facility Location Secondary Identification) omitted. + // Segment NM1 (Loop 2420D Supervising Provider Name) omitted. + // Segment REF (Loop 2420D Supervising Provider Secondary Identification) omitted. + + // Loop 2420E, Ordering Provider. + // for Medicare DME claims esp @joe on chat.open-emr.org :) + + if ($claim->Box17Qualifier() == "DK" && ($claim->claimType() === 'MB')) { + ++$edicount; + $out .= "NM1" . + "*" . $claim->Box17Qualifier() . + "*" . "1" . + "*" . $claim->billingProviderLastName() . + "*" . $claim->billingProviderFirstName() . + "*" . $claim->billingProviderMiddleName() . + "*" . + "*"; + if ($claim->billingProviderNPI()) { + $out .= + "*" . "XX" . + "*" . $claim->billingProviderNPI(); + } else { + $log .= "*** Ordering provider has no NPI.\n"; + } + $out .= "~\n"; + + ++$edicount; + $out .= "N3" . + "*" . $claim->billingProviderStreet() . + "*" . $claim->billingProviderStreetB() . + "~\n"; + + ++$edicount; + $out .= "N4" . + "*" . $claim->billingProviderCity() . + "*" . $claim->billingProviderState() . + "*" . stripZipCode($claim->billingProviderZip()) . + "~\n"; + // Segment REF (Ordering Provider Secondary Identification) omitted. + // Segment PER (Ordering Provider Contact Information) omitted. + } + + + // Segment NM1 (Referring Provider Name) omitted. + // Segment REF (Referring Provider Secondary Identification) omitted. + // Segments NM1*PW, N3, N4 (Ambulance Pick-Up Location) omitted. + // Segments NM1*45, N3, N4 (Ambulance Drop-Off Location) omitted. + + // Loop 2430, adjudication by previous payers. + // + for ($ins = 1; $ins < $claim->payerCount(); ++$ins) { if ($claim->payerSequence($ins) > $claim->payerSequence()) { continue; // payer is future, not previous -- 2.11.4.GIT