From 8c79f696684c1bdb456ae32ae99d2a8d9d627dd3 Mon Sep 17 00:00:00 2001 From: Logan Mitchell Date: Thu, 4 Jan 2024 13:16:35 -0800 Subject: [PATCH] BFD-3164: Bugfix for SAMHSA filter not filtering illegal DRG codes for V2 (SNF/Inpatient) (#2130) --- .../war/adapters/SupportingInfoComponent.java | 15 +++++++++ .../r4/ExplanationOfBenefitAdapter.java | 31 +++++++++++++++++++ .../stu3/ExplanationOfBenefitAdapter.java | 8 +++++ .../war/commons/AbstractSamhsaMatcher.java | 31 +++++++++++++++++++ .../war/r4/providers/R4EobSamhsaMatcher.java | 4 ++- 5 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 apps/bfd-server/bfd-server-war/src/main/java/gov/cms/bfd/server/war/adapters/SupportingInfoComponent.java diff --git a/apps/bfd-server/bfd-server-war/src/main/java/gov/cms/bfd/server/war/adapters/SupportingInfoComponent.java b/apps/bfd-server/bfd-server-war/src/main/java/gov/cms/bfd/server/war/adapters/SupportingInfoComponent.java new file mode 100644 index 0000000000..f422bcfc43 --- /dev/null +++ b/apps/bfd-server/bfd-server-war/src/main/java/gov/cms/bfd/server/war/adapters/SupportingInfoComponent.java @@ -0,0 +1,15 @@ +package gov.cms.bfd.server.war.adapters; + +/** + * Interface for creating SupportingInfoComponent wrapper implementations for different FHIR + * resource implementations. + */ +public interface SupportingInfoComponent { + + /** + * Gets the supporting info codeable concept. + * + * @return the supporting info codeable concept + */ + CodeableConcept getSupportingInfoCodeableConcept(); +} diff --git a/apps/bfd-server/bfd-server-war/src/main/java/gov/cms/bfd/server/war/adapters/r4/ExplanationOfBenefitAdapter.java b/apps/bfd-server/bfd-server-war/src/main/java/gov/cms/bfd/server/war/adapters/r4/ExplanationOfBenefitAdapter.java index ec4b0ea21a..37614ddd58 100644 --- a/apps/bfd-server/bfd-server-war/src/main/java/gov/cms/bfd/server/war/adapters/r4/ExplanationOfBenefitAdapter.java +++ b/apps/bfd-server/bfd-server-war/src/main/java/gov/cms/bfd/server/war/adapters/r4/ExplanationOfBenefitAdapter.java @@ -6,6 +6,7 @@ import gov.cms.bfd.server.war.adapters.FhirResource; import gov.cms.bfd.server.war.adapters.ItemComponent; import gov.cms.bfd.server.war.adapters.ProcedureComponent; +import gov.cms.bfd.server.war.adapters.SupportingInfoComponent; import java.util.List; import java.util.stream.Collectors; import org.hl7.fhir.r4.model.ExplanationOfBenefit; @@ -47,6 +48,36 @@ public List getItem() { return eob.getItem().stream().map(ItemComponentAdapter::new).collect(Collectors.toList()); } + /** {@inheritDoc} */ + public List getSupportingInfo() { + return eob.getSupportingInfo().stream() + .map(SupportingInfoAdapter::new) + .collect(Collectors.toList()); + } + + /** Adapter for creating R4 FHIR supporting info components. */ + public static class SupportingInfoAdapter implements SupportingInfoComponent { + + /** The eob's supporting information component. */ + private final ExplanationOfBenefit.SupportingInformationComponent supportingInfoComponent; + + /** + * Instantiates a new SupportingInfo component adapter. + * + * @param supportingInfoComponent the supporting info component + */ + public SupportingInfoAdapter( + ExplanationOfBenefit.SupportingInformationComponent supportingInfoComponent) { + this.supportingInfoComponent = supportingInfoComponent; + } + + /** {@inheritDoc} */ + @Override + public CodeableConcept getSupportingInfoCodeableConcept() { + return new CodeableConceptAdapter(supportingInfoComponent.getCode()); + } + } + /** Adapter for creating R4 FHIR procedure components. */ public static class ProcedureComponentAdapter implements ProcedureComponent { diff --git a/apps/bfd-server/bfd-server-war/src/main/java/gov/cms/bfd/server/war/adapters/stu3/ExplanationOfBenefitAdapter.java b/apps/bfd-server/bfd-server-war/src/main/java/gov/cms/bfd/server/war/adapters/stu3/ExplanationOfBenefitAdapter.java index be3f26ef6b..4a758ca5a0 100644 --- a/apps/bfd-server/bfd-server-war/src/main/java/gov/cms/bfd/server/war/adapters/stu3/ExplanationOfBenefitAdapter.java +++ b/apps/bfd-server/bfd-server-war/src/main/java/gov/cms/bfd/server/war/adapters/stu3/ExplanationOfBenefitAdapter.java @@ -6,6 +6,8 @@ import gov.cms.bfd.server.war.adapters.FhirResource; import gov.cms.bfd.server.war.adapters.ItemComponent; import gov.cms.bfd.server.war.adapters.ProcedureComponent; +import gov.cms.bfd.server.war.adapters.SupportingInfoComponent; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import org.hl7.fhir.dstu3.model.ExplanationOfBenefit; @@ -50,6 +52,12 @@ public List getItem() { return eob.getItem().stream().map(ItemComponentAdapter::new).collect(Collectors.toList()); } + /** {@inheritDoc} */ + public List getSupportingInfo() { + // V1 doesn't have supportingInfo, so return an empty list + return new ArrayList<>(); + } + /** Adapter for creating stu3 FHIR procedure components. */ public static class ProcedureComponentAdapter implements ProcedureComponent { diff --git a/apps/bfd-server/bfd-server-war/src/main/java/gov/cms/bfd/server/war/commons/AbstractSamhsaMatcher.java b/apps/bfd-server/bfd-server-war/src/main/java/gov/cms/bfd/server/war/commons/AbstractSamhsaMatcher.java index 098fe29cfb..abb8300d8d 100644 --- a/apps/bfd-server/bfd-server-war/src/main/java/gov/cms/bfd/server/war/commons/AbstractSamhsaMatcher.java +++ b/apps/bfd-server/bfd-server-war/src/main/java/gov/cms/bfd/server/war/commons/AbstractSamhsaMatcher.java @@ -7,6 +7,7 @@ import gov.cms.bfd.server.war.adapters.DiagnosisComponent; import gov.cms.bfd.server.war.adapters.ItemComponent; import gov.cms.bfd.server.war.adapters.ProcedureComponent; +import gov.cms.bfd.server.war.adapters.SupportingInfoComponent; import gov.cms.bfd.sharedutils.exceptions.BadCodeMonkeyException; import java.io.IOException; import java.io.InputStream; @@ -156,6 +157,18 @@ protected boolean containsSamhsaIcdProcedureCode(List proced return procedure.stream().anyMatch(this::isSamhsaIcdProcedure); } + /** + * Checks if the given {@link SupportingInfoComponent} list contains any SAMHSA data. + * + * @param supportingInformationComponents the supporting information components + * @return {@code true} if any of the specified {@link SupportingInfoComponent}s match any of the + * {@link AbstractSamhsaMatcher#drgCodes}, {@code false} if they all do not + */ + protected boolean containsSamhsaSupportingInfo( + List supportingInformationComponents) { + return supportingInformationComponents.stream().anyMatch(this::isSamhsaSupportingInfo); + } + /** * Checks if the given {@link DiagnosisComponent} list contains any SAMHSA data. * @@ -224,6 +237,24 @@ boolean isSamhsaDiagnosis(DiagnosisComponent diagnosis) { } } + /** + * Checks if the given {@link SupportingInfoComponent} contains SAMHSA data. + * + * @param supportingInfo the {@link SupportingInfoComponent} to check + * @return {@code true} if the specified {@link SupportingInfoComponent} matches one of the {@link + * AbstractSamhsaMatcher#drgCodes} entries, false if it does not + */ + @VisibleForTesting + boolean isSamhsaSupportingInfo(SupportingInfoComponent supportingInfo) { + try { + return supportingInfo.getSupportingInfoCodeableConcept().getCoding().stream() + .filter(s -> s.getSystem().equals(AbstractSamhsaMatcher.DRG)) + .anyMatch(this::isSamhsaDrgCode); + } catch (FHIRException e) { + throw new BadCodeMonkeyException(e); + } + } + /** * Checks that for the specified {@link CodeableConcept}, the Codings (if any) within, contain a * blacklisted SAMHSA procedure code. If any of the systems within the {@link CodeableConcept} are diff --git a/apps/bfd-server/bfd-server-war/src/main/java/gov/cms/bfd/server/war/r4/providers/R4EobSamhsaMatcher.java b/apps/bfd-server/bfd-server-war/src/main/java/gov/cms/bfd/server/war/r4/providers/R4EobSamhsaMatcher.java index 0ed39f313e..7a520857fe 100644 --- a/apps/bfd-server/bfd-server-war/src/main/java/gov/cms/bfd/server/war/r4/providers/R4EobSamhsaMatcher.java +++ b/apps/bfd-server/bfd-server-war/src/main/java/gov/cms/bfd/server/war/r4/providers/R4EobSamhsaMatcher.java @@ -55,7 +55,9 @@ public boolean test(ExplanationOfBenefit eob) { case INPATIENT: case OUTPATIENT: case SNF: - containsSamhsa = containsSamhsaIcdProcedureCode(adapter.getProcedure()); + containsSamhsa = + containsSamhsaIcdProcedureCode(adapter.getProcedure()) + || containsSamhsaSupportingInfo(adapter.getSupportingInfo()); case CARRIER: case DME: case HHA: