Skip to content

Commit 6ba088d

Browse files
committed
BFD-4203: V3 EOB bugs fix
1 parent 779d635 commit 6ba088d

16 files changed

Lines changed: 812 additions & 984 deletions

File tree

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
BENE_SK,BENE_XREF_EFCTV_SK,BENE_MBI_ID,BENE_LAST_NAME,BENE_1ST_NAME,BENE_MIDL_NAME,BENE_BRTH_DT,BENE_DEATH_DT,BENE_VRFY_DEATH_DAY_SW,BENE_SEX_CD,BENE_RACE_CD,BENE_LINE_1_ADR,BENE_LINE_2_ADR,BENE_LINE_3_ADR,BENE_LINE_4_ADR,BENE_LINE_5_ADR,BENE_LINE_6_ADR,GEO_ZIP_PLC_NAME,GEO_ZIP5_CD,GEO_USPS_STATE_CD,CNTCT_LANG_CD,IDR_TRANS_EFCTV_TS,IDR_UPDT_TS,IDR_TRANS_OBSLT_TS
2-
181968400,405764107,8Z73WV0QC20,Erdapfel,Bluey,Caroline,1967-03-19,,~,2,2,1970 S University Blvd,,,,,,Mobile,36609,AL,SPA,2023-08-15 15:47:22.203391,2024-01-12 02:41:38.810329,9999-12-31 00:00:00.000000
3-
405764107,405764107,8Z73WV0QC20,Erdapfel,Bluey,Caroline,1967-03-19,,~,2,2,1970 S University Blvd,,,,,,Mobile,36609,AL,SPA,2024-03-30 06:52:39.094875,2024-05-28 20:14:30.616999,9999-12-31 00:00:00.000000
4-
517782585,517782585,2B19C89AA35,Heeler,Alex,Joey,1959-03-14,,~,1,4,14152 ND-27,,,,,,Lisbon,58054,ND,~,2024-06-12 01:06:49.588129,2024-11-05 18:51:29.174693,9999-12-31 00:00:00.000000
5-
848484848,517782585,2B19C89AA35,Heeler,Alex,Joey,1959-03-14,,~,1,4,14152 ND-27,,,,,,Lisbon,58054,ND,~,2024-06-12 01:06:49.588129,2024-11-05 18:51:29.174693,9999-12-31 00:00:00.000000
6-
121212121,517782585,2B19C89AA35,Heeler,Alex,Joey,1959-03-14,,~,1,4,14152 ND-27,,,,,,Lisbon,58054,ND,~,2024-06-12 01:06:49.588129,2024-11-05 18:51:29.174693,9999-12-31 00:00:00.000000
7-
878934873,178083966,9OJ2CG2UC85,Jones,Abby,,1922-04-01,,~,1,6,2904 61st,,,,,,Galveston,77551,TX,~,2024-06-04 18:32:49.034231,2024-12-10 12:27:50.972975,9999-12-31T00:00:00.000000+0000
8-
792872340,178083966,9OJ2CG2UC85,Jones,Abby,,1922-04-01,,~,1,6,2904 61st,,,,,,Galveston,77551,TX,~,2024-06-04 18:32:49.034231,2024-12-10 12:27:50.972975,9999-12-31T00:00:00.000000+0000
9-
178083966,178083966,9OJ2CG2UC85,Jones,Abby,,1922-04-01,,~,1,6,2904 61st,,,,,,Galveston,77551,TX,~,2023-09-12 01:53:35.572554,2025-04-26 14:53:59.117910,9999-12-31T00:00:00.000000+0000
1+
BENE_SK,BENE_XREF_EFCTV_SK,BENE_MBI_ID,BENE_LAST_NAME,BENE_1ST_NAME,BENE_MIDL_NAME,BENE_BRTH_DT,BENE_DEATH_DT,BENE_VRFY_DEATH_DAY_SW,BENE_SEX_CD,BENE_RACE_CD,BENE_LINE_1_ADR,BENE_LINE_2_ADR,BENE_LINE_3_ADR,BENE_LINE_4_ADR,BENE_LINE_5_ADR,BENE_LINE_6_ADR,GEO_ZIP_PLC_NAME,GEO_ZIP5_CD,GEO_USPS_STATE_CD,CNTCT_LANG_CD,IDR_TRANS_EFCTV_TS,IDR_UPDT_TS,IDR_TRANS_OBSLT_TS,IDR_INSRT_TS
2+
181968400,405764107,8Z73WV0QC20,Erdapfel,Bluey,Caroline,3/19/67,,~,2,2,1970 S University Blvd,,,,,,Mobile,36609,AL,SPA,2017-10-16T00:00:00.000000+0000,2017-10-16T00:00:00.000000+0000,9999-12-31T00:00:00.000000+0000,2017-10-16T00:00:00.000000+0000
3+
405764107,405764107,8Z73WV0QC20,Erdapfel,Bluey,Caroline,3/19/67,,~,2,2,1970 S University Blvd,,,,,,Mobile,36609,AL,SPA,2017-10-16T00:00:00.000000+0000,2017-10-16T00:00:00.000000+0000,9999-12-31T00:00:00.000000+0000,2017-10-16T00:00:00.000000+0000
4+
517782585,517782585,2B19C89AA35,Heeler,Alex,Joey,3/14/59,,~,1,4,14152 ND-27,,,,,,Lisbon,58054,ND,~,2017-10-16T00:00:00.000000+0000,2017-10-16T00:00:00.000000+0000,9999-12-31T00:00:00.000000+0000,2017-10-16T00:00:00.000000+0000
5+
848484848,517782585,2B19C89AA35,Heeler,Alex,Joey,3/14/59,,~,1,4,14152 ND-27,,,,,,Lisbon,58054,ND,~,2017-10-16T00:00:00.000000+0000,2017-10-16T00:00:00.000000+0000,9999-12-31T00:00:00.000000+0000,2017-10-16T00:00:00.000000+0000
6+
121212121,517782585,2B19C89AA35,Heeler,Alex,Joey,3/14/59,,~,1,4,14152 ND-27,,,,,,Lisbon,58054,ND,~,2017-10-16T00:00:00.000000+0000,2017-10-16T00:00:00.000000+0000,9999-12-31T00:00:00.000000+0000,2017-10-16T00:00:00.000000+0000
7+
878934873,178083966,9OJ2CG2UC85,Jones,Abby,,4/1/22,,~,1,6,2904 61st,,,,,,Galveston,77551,TX,~,2017-10-16T00:00:00.000000+0000,2017-10-16T00:00:00.000000+0000,9999-12-31T00:00:00.000000+0000,2017-10-16T00:00:00.000000+0000
8+
792872340,178083966,9OJ2CG2UC85,Jones,Abby,,4/1/22,,~,1,6,2904 61st,,,,,,Galveston,77551,TX,~,2017-10-16T00:00:00.000000+0000,2017-10-16T00:00:00.000000+0000,9999-12-31T00:00:00.000000+0000,2017-10-16T00:00:00.000000+0000
9+
178083966,178083966,9OJ2CG2UC85,Jones,Abby,,4/1/22,,~,1,6,2904 61st,,,,,,Galveston,77551,TX,~,2017-10-16T00:00:00.000000+0000,2017-10-16T00:00:00.000000+0000,9999-12-31T00:00:00.000000+0000,2017-10-16T00:00:00.000000+0000
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
BENE_SK,BENE_XREF_EFCTV_SK,BENE_MBI_ID,IDR_TRANS_EFCTV_TS,IDR_UPDT_TS,IDR_TRANS_OBSLT_TS
2-
405764107,405764107,8Z73WV0QC20,2024-03-22 07:54:19.747237,2024-08-29 11:13:59.468894,9999-12-31 00:00:00.000000
1+
BENE_SK,BENE_XREF_EFCTV_SK,BENE_MBI_ID,IDR_TRANS_EFCTV_TS,IDR_UPDT_TS,IDR_TRANS_OBSLT_TS,IDR_INSRT_TS
2+
405764107,405764107,8Z73WV0QC20,2017-10-16T00:00:00.000000+0000,2017-10-16T00:00:00.000000+0000,9999-12-31T00:00:00.000000+0000,2017-10-16T00:00:00.000000+0000
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
BENE_MBI_ID,BENE_MBI_EFCTV_DT,BENE_MBI_OBSLT_DT,IDR_TRANS_EFCTV_TS,IDR_UPDT_TS,IDR_TRANS_OBSLT_TS
2-
8Z73WV0QC20,2020-04-21,2020-05-25,2022-07-10 09:11:52.588300,2023-05-07 17:37:59.821448,9999-12-31 00:00:00.000000
1+
BENE_MBI_ID,BENE_MBI_EFCTV_DT,BENE_MBI_OBSLT_DT,IDR_TRANS_EFCTV_TS,IDR_UPDT_TS,IDR_TRANS_OBSLT_TS,IDR_INSRT_TS
2+
8Z73WV0QC20,4/21/20,5/25/20,2017-10-16T00:00:00.000000+0000,2017-10-16T00:00:00.000000+0000,9999-12-31T00:00:00.000000+0000,2017-10-16T00:00:00.000000+0000

apps/bfd-server-ng/src/main/java/gov/cms/bfd/server/ng/SystemUrls.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,10 @@ public class SystemUrls {
251251
public static final String HL7_BENEFIT_CATEGORY =
252252
"http://terminology.hl7.org/CodeSystem/ex-benefitcategory";
253253

254+
/** URL. */
255+
public static final String HL7_ADJUDICATION_CATEGORY =
256+
"http://terminology.hl7.org/CodeSystem/adjudication";
257+
254258
// US Core
255259
/**
256260
* <a href="https://hl7.org/fhir/us/core/STU7/StructureDefinition-us-core-ethnicity.html">US Core
@@ -303,6 +307,10 @@ public class SystemUrls {
303307
public static final String CARIN_CODE_SYSTEM_CLAIM_PROCEDURE_TYPE =
304308
"http://hl7.org/fhir/us/carin-bb/CodeSystem/C4BBClaimProcedureType";
305309

310+
/** URL. */
311+
public static final String POA_CODING =
312+
"https://www.cms.gov/Medicare/Medicare-Fee-for-Service-Payment/HospitalAcqCond/Coding";
313+
306314
/** URL. */
307315
public static final String CARIN_CODE_SYSTEM_DIAGNOSIS_TYPE =
308316
"http://hl7.org/fhir/us/carin-bb/CodeSystem/C4BBClaimDiagnosisType";
@@ -358,7 +366,7 @@ public class SystemUrls {
358366

359367
/** URL. */
360368
public static final String BLUE_BUTTON_CODE_SYSTEM_CLAIM_CONTRACTOR_NUMBER =
361-
"https://bluebutton.cms.gov/CodeSystem/CLM-CNTRCTR-NUM";
369+
"https://bluebutton.cms.gov/fhir/CodeSystem/CLM-CNTRCTR-NUM";
362370

363371
/** URL. */
364372
public static final String BLUE_BUTTON_STRUCTURE_DEFINITION_CLAIM_RECORD_TYPE =
@@ -424,6 +432,10 @@ public class SystemUrls {
424432
public static final String BLUE_BUTTON_CODE_SYSTEM_CLAIM_DEDUCTIBLE_COINSURANCE_CODE =
425433
"https://bluebutton.cms.gov/fhir/CodeSystem/CLM-DDCTBL-COINSRNC-CD";
426434

435+
/** URL. */
436+
public static final String BLUE_BUTTON_CODE_SYSTEM_ADJUDICATION_SYSTEM =
437+
"https://bluebutton.cms.gov/fhir/CodeSystem/Adjudication";
438+
427439
/** URL. */
428440
public static final String BLUE_BUTTON_STRUCTURE_DEFINITION_PPS_DRG_WEIGHT_NUMBER =
429441
"https://bluebutton.cms.gov/fhir/StructureDefinition/CLM-MDCR-IP-PPS-DRG-WT-NUM";

apps/bfd-server-ng/src/main/java/gov/cms/bfd/server/ng/claim/model/AdjudicationCharge.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class AdjudicationCharge {
99
@Column(name = "clm_sbmt_chrg_amt")
1010
private float submittedChargeAmount;
1111

12-
ExplanationOfBenefit.AdjudicationComponent toFhir() {
13-
return AdjudicationChargeType.SUBMITTED_CHARGE_AMOUNT.toFhir(submittedChargeAmount);
12+
ExplanationOfBenefit.TotalComponent toFhir() {
13+
return AdjudicationChargeType.SUBMITTED_CHARGE_AMOUNT.toFhirTotal(submittedChargeAmount);
1414
}
1515
}

apps/bfd-server-ng/src/main/java/gov/cms/bfd/server/ng/claim/model/AdjudicationChargeType.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,21 @@ ExplanationOfBenefit.AdjudicationComponent toFhir(double value) {
123123
.setDisplay(coding2Display)))
124124
.setAmount(USD.toFhir(value));
125125
}
126+
127+
ExplanationOfBenefit.TotalComponent toFhirTotal(double value) {
128+
return new ExplanationOfBenefit.TotalComponent()
129+
.setCategory(
130+
new CodeableConcept()
131+
.addCoding(
132+
new Coding()
133+
.setSystem(coding1System)
134+
.setCode(coding1Code)
135+
.setDisplay(coding1Display))
136+
.addCoding(
137+
new Coding()
138+
.setSystem(SystemUrls.BLUE_BUTTON_CODE_SYSTEM_ADJUDICATION)
139+
.setCode(coding2Code)
140+
.setDisplay(coding2Display)))
141+
.setAmount(USD.toFhir(value));
142+
}
126143
}

apps/bfd-server-ng/src/main/java/gov/cms/bfd/server/ng/claim/model/Claim.java

Lines changed: 70 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@
1212
import jakarta.persistence.OneToOne;
1313
import jakarta.persistence.Table;
1414
import java.time.LocalDate;
15+
import java.util.ArrayList;
1516
import java.util.Collection;
17+
import java.util.Comparator;
1618
import java.util.List;
1719
import java.util.Optional;
1820
import java.util.Set;
21+
import java.util.stream.Collectors;
1922
import java.util.stream.Stream;
2023
import lombok.Getter;
2124
import org.hl7.fhir.r4.model.ExplanationOfBenefit;
@@ -51,6 +54,7 @@ public class Claim {
5154
@Embedded private CareTeam careTeam;
5255
@Embedded private BenefitBalance benefitBalance;
5356
@Embedded private AdjudicationCharge adjudicationCharge;
57+
@Embedded private ClaimPaymentAmount claimPaymentAmount;
5458

5559
@OneToOne
5660
@JoinColumn(name = "bene_sk")
@@ -114,10 +118,17 @@ public ExplanationOfBenefit toFhir() {
114118
.flatMap(Collection::stream)
115119
.forEach(eob::addExtension);
116120

117-
for (var procedure : claimProcedures) {
118-
procedure.toFhirProcedure().ifPresent(eob::addProcedure);
119-
procedure.toFhirDiagnosis().ifPresent(eob::addDiagnosis);
120-
}
121+
eob.setProcedure(
122+
transformOptionalAndSort(
123+
claimProcedures,
124+
ClaimProcedure::toFhirProcedure,
125+
ExplanationOfBenefit.ProcedureComponent::getSequence));
126+
127+
eob.setDiagnosis(
128+
transformOptionalAndSort(
129+
claimProcedures,
130+
ClaimProcedure::toFhirDiagnosis,
131+
ExplanationOfBenefit.DiagnosisComponent::getSequence));
121132

122133
billingProvider
123134
.toFhir(claimTypeCode)
@@ -128,28 +139,32 @@ public ExplanationOfBenefit toFhir() {
128139
});
129140

130141
var supportingInfoFactory = new SupportingInfoFactory();
131-
var initialSupportingInfo =
132-
List.of(
133-
bloodPints.toFhir(supportingInfoFactory),
134-
nchPrimaryPayorCode.toFhir(supportingInfoFactory),
135-
typeOfBillCode.toFhir(supportingInfoFactory));
136-
Stream.of(
137-
initialSupportingInfo,
138-
claimDateSignature.getSupportingInfo().toFhir(supportingInfoFactory),
139-
institutional
140-
.map(i -> i.getSupportingInfo().toFhir(supportingInfoFactory))
141-
.orElse(List.of()))
142-
.flatMap(Collection::stream)
143-
.forEach(eob::addSupportingInfo);
144-
145-
claimLines.stream().map(ClaimLine::toFhir).forEach(eob::addItem);
146-
careTeam
147-
.toFhir()
142+
List<ExplanationOfBenefit.SupportingInformationComponent> supportingInfoList =
143+
Stream.of(
144+
List.of(
145+
bloodPints.toFhir(supportingInfoFactory),
146+
nchPrimaryPayorCode.toFhir(supportingInfoFactory),
147+
typeOfBillCode.toFhir(supportingInfoFactory)),
148+
claimDateSignature.getSupportingInfo().toFhir(supportingInfoFactory),
149+
institutional
150+
.map(i -> i.getSupportingInfo().toFhir(supportingInfoFactory))
151+
.orElse(List.of()))
152+
.flatMap(Collection::stream)
153+
.collect(Collectors.toList());
154+
155+
eob.setSupportingInfo(supportingInfoList);
156+
157+
eob.setItem(
158+
transformAndSort(
159+
claimLines, ClaimLine::toFhir, ExplanationOfBenefit.ItemComponent::getSequence));
160+
161+
transformAndSort(careTeam.toFhir(), pair -> pair, pair -> pair.careTeam().getSequence())
148162
.forEach(
149-
c -> {
150-
eob.addCareTeam(c.careTeam());
151-
eob.addContained(c.practitioner());
163+
sortedPair -> {
164+
eob.addCareTeam(sortedPair.careTeam());
165+
eob.addContained(sortedPair.practitioner());
152166
});
167+
153168
institutional.ifPresent(
154169
i -> {
155170
eob.addAdjudication(i.getPpsDrgWeight().toFhir());
@@ -158,7 +173,37 @@ public ExplanationOfBenefit toFhir() {
158173
});
159174

160175
claimTypeCode.toFhirInsurance().ifPresent(eob::addInsurance);
161-
eob.addAdjudication(adjudicationCharge.toFhir());
176+
eob.addTotal(adjudicationCharge.toFhir());
177+
eob.setPayment(claimPaymentAmount.toFhir());
178+
162179
return eob;
163180
}
181+
182+
private <S, T> List<T> transformAndSort(
183+
Collection<S> source,
184+
java.util.function.Function<S, T> transformer,
185+
java.util.function.Function<T, Integer> sequenceExtractor) {
186+
if (source == null || source.isEmpty()) {
187+
return new ArrayList<>();
188+
}
189+
return source.stream()
190+
.map(transformer)
191+
.sorted(Comparator.comparing(sequenceExtractor))
192+
.collect(Collectors.toList());
193+
}
194+
195+
private <S, T> List<T> transformOptionalAndSort(
196+
Collection<S> source,
197+
java.util.function.Function<S, Optional<T>> transformer,
198+
java.util.function.Function<T, Integer> sequenceExtractor) {
199+
if (source == null || source.isEmpty()) {
200+
return new ArrayList<>();
201+
}
202+
return source.stream()
203+
.map(transformer)
204+
.filter(Optional::isPresent)
205+
.map(Optional::get)
206+
.sorted(Comparator.comparing(sequenceExtractor))
207+
.collect(Collectors.toList());
208+
}
164209
}

apps/bfd-server-ng/src/main/java/gov/cms/bfd/server/ng/claim/model/ClaimFinalActionCode.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import gov.cms.bfd.server.ng.SystemUrls;
44
import jakarta.persistence.Column;
55
import java.util.Optional;
6-
import org.hl7.fhir.r4.model.CodeableConcept;
76
import org.hl7.fhir.r4.model.Coding;
87
import org.hl7.fhir.r4.model.Extension;
98

@@ -17,9 +16,8 @@ Optional<Extension> toFhir() {
1716
new Extension()
1817
.setUrl(SystemUrls.BLUE_BUTTON_STRUCTURE_DEFINITION_FINAL_ACTION_CODE)
1918
.setValue(
20-
new CodeableConcept(
21-
new Coding()
22-
.setSystem(SystemUrls.BLUE_BUTTON_CODE_SYSTEM_FINAL_ACTION_CODE)
23-
.setCode(s))));
19+
new Coding()
20+
.setSystem(SystemUrls.BLUE_BUTTON_CODE_SYSTEM_FINAL_ACTION_CODE)
21+
.setCode(s)));
2422
}
2523
}

apps/bfd-server-ng/src/main/java/gov/cms/bfd/server/ng/claim/model/ClaimLineAdjudicationCharge.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ List<ExplanationOfBenefit.AdjudicationComponent> toFhir() {
3535
return List.of(
3636
AdjudicationChargeType.NONCOVERED_CHARGE_AMOUNT.toFhir(noncoveredChargeAmount),
3737
AdjudicationChargeType.ALLOWED_CHARGE_AMOUNT.toFhir(allowedChargeAmount),
38-
AdjudicationChargeType.SUBMITTED_CHARGE_AMOUNT.toFhir(submittedChargeAmount),
3938
AdjudicationChargeType.PROVIDER_PAYMENT_AMOUNT.toFhir(providerPaymentAmount),
4039
AdjudicationChargeType.BENE_PAYMENT_AMOUNT.toFhir(benePaymentAmount),
4140
AdjudicationChargeType.BENE_PAID_AMOUNT.toFhir(benePaidAmount),

apps/bfd-server-ng/src/main/java/gov/cms/bfd/server/ng/claim/model/ClaimNonpaymentReasonCode.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import gov.cms.bfd.server.ng.SystemUrls;
44
import jakarta.persistence.Column;
55
import java.util.Optional;
6-
import org.hl7.fhir.r4.model.CodeableConcept;
76
import org.hl7.fhir.r4.model.Coding;
87
import org.hl7.fhir.r4.model.Extension;
98

@@ -17,9 +16,8 @@ Optional<Extension> toFhir() {
1716
new Extension()
1817
.setUrl(SystemUrls.BLUE_BUTTON_STRUCTURE_DEFINITION_NONPAYMENT_REASON_CODE)
1918
.setValue(
20-
new CodeableConcept(
21-
new Coding()
22-
.setSystem(SystemUrls.BLUE_BUTTON_CODE_SYSTEM_NONPAYMENT_REASON_CODE)
23-
.setCode(s))));
19+
new Coding()
20+
.setSystem(SystemUrls.BLUE_BUTTON_CODE_SYSTEM_NONPAYMENT_REASON_CODE)
21+
.setCode(s)));
2422
}
2523
}

0 commit comments

Comments
 (0)