Search in sources :

Example 21 with ClaimType

use of org.hl7.fhir.r4.model.codesystems.ClaimType in project beneficiary-fhir-data by CMSgov.

the class R4ExplanationOfBenefitResourceProviderIT method searchForNonSamhsaEobsWithExcludeSamhsaTrue.

/**
 * Verifies that {@link
 * gov.cms.bfd.server.war.r4.providers.R4ExplanationOfBenefitResourceProvider#findByPatient} with
 * <code>excludeSAMHSA=true</code> properly returns claims that are not SAMHSA-related.
 *
 * @throws FHIRException (indicates test failure)
 */
@Test
public void searchForNonSamhsaEobsWithExcludeSamhsaTrue() throws FHIRException {
    // Load the SAMPLE_A resources normally.
    Beneficiary beneficiary = loadSampleA();
    IGenericClient fhirClient = ServerTestUtils.get().createFhirClientV2();
    Bundle searchResults = fhirClient.search().forResource(ExplanationOfBenefit.class).where(ExplanationOfBenefit.PATIENT.hasId(TransformerUtilsV2.buildPatientId(beneficiary.getBeneficiaryId()))).and(new StringClientParam(EXCLUDE_SAMHSA_PARAM).matches().value("true")).returnBundle(Bundle.class).execute();
    assertNotNull(searchResults);
    for (ClaimTypeV2 claimType : ClaimTypeV2.values()) {
        // None of the claims are SAMHSA so we expect one record per claim type in the results.
        assertEquals(1, filterToClaimType(searchResults, claimType).size(), String.format("Verify claims of type '%s' are present", claimType));
    }
}
Also used : StringClientParam(ca.uhn.fhir.rest.gclient.StringClientParam) IGenericClient(ca.uhn.fhir.rest.client.api.IGenericClient) IBaseBundle(org.hl7.fhir.instance.model.api.IBaseBundle) Bundle(org.hl7.fhir.r4.model.Bundle) Beneficiary(gov.cms.bfd.model.rif.Beneficiary) Stu3EobSamhsaMatcherTest(gov.cms.bfd.server.war.stu3.providers.Stu3EobSamhsaMatcherTest) Test(org.junit.jupiter.api.Test)

Example 22 with ClaimType

use of org.hl7.fhir.r4.model.codesystems.ClaimType in project beneficiary-fhir-data by CMSgov.

the class R4ExplanationOfBenefitResourceProviderIT method searchForNonSamhsaEobsWithExcludeSamhsaFalse.

/**
 * Verifies that {@link
 * gov.cms.bfd.server.war.r4.providers.R4ExplanationOfBenefitResourceProvider#findByPatient} with
 * <code>excludeSAMHSA=false</code> properly returns claims that are not SAMHSA-related.
 *
 * @throws FHIRException (indicates test failure)
 */
@Test
public void searchForNonSamhsaEobsWithExcludeSamhsaFalse() throws FHIRException {
    // Load the SAMPLE_A resources normally.
    Beneficiary beneficiary = loadSampleA();
    IGenericClient fhirClient = ServerTestUtils.get().createFhirClientV2();
    Bundle searchResults = fhirClient.search().forResource(ExplanationOfBenefit.class).where(ExplanationOfBenefit.PATIENT.hasId(TransformerUtilsV2.buildPatientId(beneficiary.getBeneficiaryId()))).and(new StringClientParam(EXCLUDE_SAMHSA_PARAM).matches().value("false")).returnBundle(Bundle.class).execute();
    assertNotNull(searchResults);
    for (ClaimTypeV2 claimType : ClaimTypeV2.values()) {
        // None of the claims are SAMHSA so we expect one record per claim type in the results.
        assertEquals(1, filterToClaimType(searchResults, claimType).size(), String.format("Verify claims of type '%s' are present", claimType));
    }
}
Also used : StringClientParam(ca.uhn.fhir.rest.gclient.StringClientParam) IGenericClient(ca.uhn.fhir.rest.client.api.IGenericClient) IBaseBundle(org.hl7.fhir.instance.model.api.IBaseBundle) Bundle(org.hl7.fhir.r4.model.Bundle) Beneficiary(gov.cms.bfd.model.rif.Beneficiary) Stu3EobSamhsaMatcherTest(gov.cms.bfd.server.war.stu3.providers.Stu3EobSamhsaMatcherTest) Test(org.junit.jupiter.api.Test)

Example 23 with ClaimType

use of org.hl7.fhir.r4.model.codesystems.ClaimType in project beneficiary-fhir-data by CMSgov.

the class R4ExplanationOfBenefitResourceProviderIT method searchForSamhsaEobsWithExcludeSamhsaFalse.

/**
 * Verifies that {@link
 * gov.cms.bfd.server.war.r4.providers.R4ExplanationOfBenefitResourceProvider#findByPatient} with
 * <code>excludeSAMHSA=false</code> does not filter out SAMHSA-related claims.
 *
 * @throws FHIRException (indicates test failure)
 */
@Test
public void searchForSamhsaEobsWithExcludeSamhsaFalse() throws FHIRException {
    Beneficiary beneficiary = loadSampleAWithSamhsa();
    IGenericClient fhirClient = ServerTestUtils.get().createFhirClientV2();
    Bundle searchResults = fhirClient.search().forResource(ExplanationOfBenefit.class).where(ExplanationOfBenefit.PATIENT.hasId(TransformerUtilsV2.buildPatientId(beneficiary.getBeneficiaryId()))).and(new StringClientParam(EXCLUDE_SAMHSA_PARAM).matches().value("false")).returnBundle(Bundle.class).execute();
    assertNotNull(searchResults);
    for (ClaimTypeV2 claimType : ClaimTypeV2.values()) {
        // Without filtering we expect one claim for each claim type.
        assertEquals(1, filterToClaimType(searchResults, claimType).size());
    }
}
Also used : StringClientParam(ca.uhn.fhir.rest.gclient.StringClientParam) IGenericClient(ca.uhn.fhir.rest.client.api.IGenericClient) IBaseBundle(org.hl7.fhir.instance.model.api.IBaseBundle) Bundle(org.hl7.fhir.r4.model.Bundle) Beneficiary(gov.cms.bfd.model.rif.Beneficiary) Stu3EobSamhsaMatcherTest(gov.cms.bfd.server.war.stu3.providers.Stu3EobSamhsaMatcherTest) Test(org.junit.jupiter.api.Test)

Example 24 with ClaimType

use of org.hl7.fhir.r4.model.codesystems.ClaimType in project beneficiary-fhir-data by CMSgov.

the class PartDEventTransformerTest method assertMatches.

/**
 * Verifies that the {@link ExplanationOfBenefit} "looks like" it should, if it were produced from
 * the specified {@link PartDEvent}.
 *
 * @param claim the {@link PartDEvent} that the {@link ExplanationOfBenefit} was generated from
 * @param eob the {@link ExplanationOfBenefit} that was generated from the specified {@link
 *     PartDEvent}
 * @throws FHIRException (indicates test failure)
 */
static void assertMatches(PartDEvent claim, ExplanationOfBenefit eob) throws FHIRException {
    // Test to ensure group level fields between all claim types match
    TransformerTestUtils.assertEobCommonClaimHeaderData(eob, claim.getEventId(), claim.getBeneficiaryId(), ClaimType.PDE, claim.getClaimGroupId().toPlainString(), MedicareSegment.PART_D, Optional.of(claim.getPrescriptionFillDate()), Optional.of(claim.getPrescriptionFillDate()), Optional.empty(), claim.getFinalAction());
    TransformerTestUtils.assertExtensionIdentifierEquals(CcwCodebookVariable.PLAN_CNTRCT_REC_ID, claim.getPlanContractId(), eob.getInsurance().getCoverage());
    TransformerTestUtils.assertExtensionIdentifierEquals(CcwCodebookVariable.PLAN_PBP_REC_NUM, claim.getPlanBenefitPackageId(), eob.getInsurance().getCoverage());
    assertEquals("01", claim.getServiceProviderIdQualiferCode());
    assertEquals("01", claim.getPrescriberIdQualifierCode());
    ItemComponent rxItem = eob.getItem().stream().filter(i -> i.getSequence() == 1).findAny().get();
    TransformerTestUtils.assertHasCoding(TransformerConstants.CODING_NDC, null, TransformerUtils.retrieveFDADrugCodeDisplay(claim.getNationalDrugCode()), claim.getNationalDrugCode(), rxItem.getService().getCoding());
    TransformerTestUtils.assertHasCoding(V3ActCode.RXDINV.getSystem(), V3ActCode.RXDINV.toCode(), rxItem.getDetail().get(0).getType().getCoding());
    assertEquals(Date.valueOf(claim.getPrescriptionFillDate()), rxItem.getServicedDateType().getValue());
    TransformerTestUtils.assertReferenceEquals(TransformerConstants.CODING_NPI_US, claim.getServiceProviderId(), eob.getOrganization());
    TransformerTestUtils.assertReferenceEquals(TransformerConstants.CODING_NPI_US, claim.getServiceProviderId(), eob.getFacility());
    TransformerTestUtils.assertExtensionCodingEquals(CcwCodebookVariable.PHRMCY_SRVC_TYPE_CD, claim.getPharmacyTypeCode(), eob.getFacility());
    if (claim.getDrugCoverageStatusCode() == 'C')
        TransformerTestUtils.assertAdjudicationAmountEquals(CcwCodebookVariable.CVRD_D_PLAN_PD_AMT, claim.getPartDPlanCoveredPaidAmount(), rxItem.getAdjudication());
    else
        TransformerTestUtils.assertAdjudicationAmountEquals(CcwCodebookVariable.NCVRD_PLAN_PD_AMT, claim.getPartDPlanCoveredPaidAmount(), rxItem.getAdjudication());
    TransformerTestUtils.assertAdjudicationAmountEquals(CcwCodebookVariable.PTNT_PAY_AMT, claim.getPatientPaidAmount(), rxItem.getAdjudication());
    TransformerTestUtils.assertAdjudicationAmountEquals(CcwCodebookVariable.OTHR_TROOP_AMT, claim.getOtherTrueOutOfPocketPaidAmount(), rxItem.getAdjudication());
    TransformerTestUtils.assertAdjudicationAmountEquals(CcwCodebookVariable.LICS_AMT, claim.getLowIncomeSubsidyPaidAmount(), rxItem.getAdjudication());
    TransformerTestUtils.assertAdjudicationAmountEquals(CcwCodebookVariable.PLRO_AMT, claim.getPatientLiabilityReductionOtherPaidAmount(), rxItem.getAdjudication());
    TransformerTestUtils.assertAdjudicationAmountEquals(CcwCodebookVariable.TOT_RX_CST_AMT, claim.getTotalPrescriptionCost(), rxItem.getAdjudication());
    TransformerTestUtils.assertAdjudicationAmountEquals(CcwCodebookVariable.RPTD_GAP_DSCNT_NUM, claim.getGapDiscountAmount(), rxItem.getAdjudication());
    TransformerTestUtils.assertExtensionQuantityEquals(CcwCodebookVariable.FILL_NUM, claim.getFillNumber(), rxItem.getQuantity());
    TransformerTestUtils.assertExtensionQuantityEquals(CcwCodebookVariable.DAYS_SUPLY_NUM, claim.getDaysSupply(), rxItem.getQuantity());
    // verify {@link
    // TransformerUtils#mapEobType(CodeableConcept,ClaimType,Optional,Optional)}
    // method worked as expected for this claim type
    TransformerTestUtils.assertMapEobType(eob.getType(), ClaimType.PDE, Optional.of(org.hl7.fhir.dstu3.model.codesystems.ClaimType.PHARMACY), Optional.empty(), Optional.empty());
    TransformerTestUtils.assertInfoWithCodeEquals(CcwCodebookVariable.DAW_PROD_SLCTN_CD, CcwCodebookVariable.DAW_PROD_SLCTN_CD, claim.getDispenseAsWrittenProductSelectionCode(), eob);
    if (claim.getDispensingStatusCode().isPresent())
        TransformerTestUtils.assertInfoWithCodeEquals(CcwCodebookVariable.DSPNSNG_STUS_CD, CcwCodebookVariable.DSPNSNG_STUS_CD, claim.getDispensingStatusCode(), eob);
    TransformerTestUtils.assertInfoWithCodeEquals(CcwCodebookVariable.DRUG_CVRG_STUS_CD, CcwCodebookVariable.DRUG_CVRG_STUS_CD, claim.getDrugCoverageStatusCode(), eob);
    if (claim.getAdjustmentDeletionCode().isPresent())
        TransformerTestUtils.assertInfoWithCodeEquals(CcwCodebookVariable.ADJSTMT_DLTN_CD, CcwCodebookVariable.ADJSTMT_DLTN_CD, claim.getAdjustmentDeletionCode(), eob);
    if (claim.getNonstandardFormatCode().isPresent())
        TransformerTestUtils.assertInfoWithCodeEquals(CcwCodebookVariable.NSTD_FRMT_CD, CcwCodebookVariable.NSTD_FRMT_CD, claim.getNonstandardFormatCode(), eob);
    if (claim.getPricingExceptionCode().isPresent())
        TransformerTestUtils.assertInfoWithCodeEquals(CcwCodebookVariable.PRCNG_EXCPTN_CD, CcwCodebookVariable.PRCNG_EXCPTN_CD, claim.getPricingExceptionCode(), eob);
    if (claim.getCatastrophicCoverageCode().isPresent())
        TransformerTestUtils.assertInfoWithCodeEquals(CcwCodebookVariable.CTSTRPHC_CVRG_CD, CcwCodebookVariable.CTSTRPHC_CVRG_CD, claim.getCatastrophicCoverageCode(), eob);
    if (claim.getPrescriptionOriginationCode().isPresent())
        TransformerTestUtils.assertInfoWithCodeEquals(CcwCodebookVariable.RX_ORGN_CD, CcwCodebookVariable.RX_ORGN_CD, claim.getPrescriptionOriginationCode(), eob);
    if (claim.getBrandGenericCode().isPresent())
        TransformerTestUtils.assertInfoWithCodeEquals(CcwCodebookVariable.BRND_GNRC_CD, CcwCodebookVariable.BRND_GNRC_CD, claim.getBrandGenericCode(), eob);
    TransformerTestUtils.assertInfoWithCodeEquals(CcwCodebookVariable.PHRMCY_SRVC_TYPE_CD, CcwCodebookVariable.PHRMCY_SRVC_TYPE_CD, claim.getPharmacyTypeCode(), eob);
    TransformerTestUtils.assertInfoWithCodeEquals(CcwCodebookVariable.PTNT_RSDNC_CD, CcwCodebookVariable.PTNT_RSDNC_CD, claim.getPatientResidenceCode(), eob);
    if (claim.getSubmissionClarificationCode().isPresent())
        TransformerTestUtils.assertInfoWithCodeEquals(CcwCodebookVariable.SUBMSN_CLR_CD, CcwCodebookVariable.SUBMSN_CLR_CD, claim.getSubmissionClarificationCode(), eob);
    TransformerTestUtils.assertLastUpdatedEquals(claim.getLastUpdated(), eob);
    try {
        TransformerTestUtils.assertFDADrugCodeDisplayEquals(claim.getNationalDrugCode(), "ACETAMINOPHEN AND CODEINE PHOSPHATE - ACETAMINOPHEN; CODEINE PHOSPHATE");
    } catch (IOException e) {
        throw new UncheckedIOException(e);
    }
    try {
        TransformerTestUtils.assertNPICodeDisplayEquals(claim.getPrescriberId(), "DR. ROBERT BISBEE MD");
    } catch (IOException e) {
        throw new UncheckedIOException(e);
    }
}
Also used : ItemComponent(org.hl7.fhir.dstu3.model.ExplanationOfBenefit.ItemComponent) UncheckedIOException(java.io.UncheckedIOException) IOException(java.io.IOException) UncheckedIOException(java.io.UncheckedIOException)

Example 25 with ClaimType

use of org.hl7.fhir.r4.model.codesystems.ClaimType in project beneficiary-fhir-data by CMSgov.

the class SNFClaimTransformerTest method assertMatches.

/**
 * Verifies that the {@link ExplanationOfBenefit} "looks like" it should, if it were produced from
 * the specified {@link SNFClaim}.
 *
 * @param claim the {@link SNFClaim} that the {@link ExplanationOfBenefit} was generated from
 * @param eob the {@link ExplanationOfBenefit} that was generated from the specified {@link
 *     SNFClaim}
 * @throws FHIRException (indicates test failure)
 */
static void assertMatches(SNFClaim claim, ExplanationOfBenefit eob) throws FHIRException {
    // Test to ensure group level fields between all claim types match
    TransformerTestUtils.assertEobCommonClaimHeaderData(eob, claim.getClaimId(), claim.getBeneficiaryId(), ClaimType.SNF, claim.getClaimGroupId().toPlainString(), MedicareSegment.PART_A, Optional.of(claim.getDateFrom()), Optional.of(claim.getDateThrough()), Optional.of(claim.getPaymentAmount()), claim.getFinalAction());
    // test the common field provider number is set as expected in the EOB
    TransformerTestUtils.assertProviderNumber(eob, claim.getProviderNumber());
    // test common benefit components between SNF and Inpatient claims are set as expected
    TransformerTestUtils.assertCommonGroupInpatientSNF(eob, claim.getCoinsuranceDayCount(), claim.getNonUtilizationDayCount(), claim.getDeductibleAmount(), claim.getPartACoinsuranceLiabilityAmount(), claim.getBloodPintsFurnishedQty(), claim.getNoncoveredCharge(), claim.getTotalDeductionAmount(), claim.getClaimPPSCapitalDisproportionateShareAmt(), claim.getClaimPPSCapitalExceptionAmount(), claim.getClaimPPSCapitalFSPAmount(), claim.getClaimPPSCapitalIMEAmount(), claim.getClaimPPSCapitalOutlierAmount(), claim.getClaimPPSOldCapitalHoldHarmlessAmount());
    if (claim.getQualifiedStayFromDate().isPresent() || claim.getQualifiedStayThroughDate().isPresent()) {
        SupportingInformationComponent nchQlyfdStayInfo = TransformerTestUtils.assertHasInfo(CcwCodebookVariable.NCH_QLFYD_STAY_FROM_DT, eob);
        TransformerTestUtils.assertPeriodEquals(claim.getQualifiedStayFromDate(), claim.getQualifiedStayThroughDate(), (Period) nchQlyfdStayInfo.getTiming());
    }
    // test common eob information between SNF and Inpatient claims are set as expected
    TransformerTestUtils.assertCommonEobInformationInpatientSNF(eob, claim.getNoncoveredStayFromDate(), claim.getNoncoveredStayThroughDate(), claim.getCoveredCareThroughDate(), claim.getMedicareBenefitsExhaustedDate(), claim.getDiagnosisRelatedGroupCd());
    TransformerTestUtils.assertDateEquals(claim.getClaimAdmissionDate().get(), eob.getHospitalization().getStartElement());
    TransformerTestUtils.assertDateEquals(claim.getBeneficiaryDischargeDate().get(), eob.getHospitalization().getEndElement());
    // test common eob information between Inpatient, HHA, Hospice and SNF claims are set as
    // expected
    TransformerTestUtils.assertEobCommonGroupInpHHAHospiceSNFEquals(eob, claim.getClaimAdmissionDate(), claim.getBeneficiaryDischargeDate(), Optional.of(claim.getUtilizationDayCount()));
    // Test to ensure common group fields between Inpatient, Outpatient and SNF
    TransformerTestUtils.assertEobCommonGroupInpOutSNFEquals(eob, claim.getBloodDeductibleLiabilityAmount(), claim.getOperatingPhysicianNpi(), claim.getOtherPhysicianNpi(), claim.getClaimQueryCode(), claim.getMcoPaidSw());
    // Test to ensure common group fields between Inpatient, Outpatient HHA, Hospice
    // and SNF match
    TransformerTestUtils.assertEobCommonGroupInpOutHHAHospiceSNFEquals(eob, claim.getOrganizationNpi(), claim.getClaimFacilityTypeCode(), claim.getClaimFrequencyCode(), claim.getClaimNonPaymentReasonCode(), claim.getPatientDischargeStatusCode(), claim.getClaimServiceClassificationTypeCode(), claim.getClaimPrimaryPayerCode(), claim.getAttendingPhysicianNpi(), claim.getTotalChargeAmount(), claim.getPrimaryPayerPaidAmount(), claim.getFiscalIntermediaryNumber(), claim.getFiDocumentClaimControlNumber(), claim.getFiOriginalClaimControlNumber());
    assertEquals(6, eob.getDiagnosis().size());
    CCWProcedure ccwProcedure = new CCWProcedure(claim.getProcedure1Code(), claim.getProcedure1CodeVersion(), claim.getProcedure1Date());
    TransformerTestUtils.assertHasCoding(ccwProcedure.getFhirSystem().toString(), claim.getProcedure1Code().get(), eob.getProcedure().get(0).getProcedureCodeableConcept().getCoding());
    assertEquals(TransformerUtils.convertToDate(claim.getProcedure1Date().get()), eob.getProcedure().get(0).getDate());
    assertEquals(1, eob.getItem().size());
    SNFClaimLine claimLine1 = claim.getLines().get(0);
    ItemComponent eobItem0 = eob.getItem().get(0);
    assertEquals(claimLine1.getLineNumber(), new BigDecimal(eobItem0.getSequence()));
    assertEquals(claim.getProviderStateCode(), eobItem0.getLocationAddress().getState());
    TransformerTestUtils.assertHasCoding(CcwCodebookVariable.REV_CNTR, claimLine1.getRevenueCenter(), eobItem0.getRevenue());
    TransformerTestUtils.assertHcpcsCodes(eobItem0, claimLine1.getHcpcsCode(), Optional.empty(), Optional.empty(), Optional.empty(), 0);
    // Test to ensure common group field coinsurance between Inpatient, HHA, Hospice and SNF match
    TransformerTestUtils.assertEobCommonGroupInpHHAHospiceSNFCoinsuranceEquals(eobItem0, claimLine1.getDeductibleCoinsuranceCd());
    String claimControlNumber = "0000000000";
    // Test to ensure item level fields between Inpatient, Outpatient, HHA, Hopsice
    // and SNF match
    TransformerTestUtils.assertEobCommonItemRevenueEquals(eobItem0, eob, claimLine1.getRevenueCenter(), claimLine1.getRateAmount(), claimLine1.getTotalChargeAmount(), claimLine1.getNonCoveredChargeAmount(), BigDecimal.valueOf(claimLine1.getUnitCount()), claimControlNumber, claimLine1.getNationalDrugCodeQuantity(), claimLine1.getNationalDrugCodeQualifierCode(), claimLine1.getRevenueCenterRenderingPhysicianNPI(), 1);
    // verify {@link
    // TransformerUtils#mapEobType(CodeableConcept,ClaimType,Optional,Optional)}
    // method worked as expected for this claim type
    TransformerTestUtils.assertMapEobType(eob.getType(), ClaimType.SNF, Optional.of(org.hl7.fhir.dstu3.model.codesystems.ClaimType.INSTITUTIONAL), Optional.of(claim.getNearLineRecordIdCode()), Optional.of(claim.getClaimTypeCode()));
    // Test lastUpdated
    TransformerTestUtils.assertLastUpdatedEquals(claim.getLastUpdated(), eob);
}
Also used : SupportingInformationComponent(org.hl7.fhir.dstu3.model.ExplanationOfBenefit.SupportingInformationComponent) SNFClaimLine(gov.cms.bfd.model.rif.SNFClaimLine) CCWProcedure(gov.cms.bfd.server.war.commons.CCWProcedure) ItemComponent(org.hl7.fhir.dstu3.model.ExplanationOfBenefit.ItemComponent) BigDecimal(java.math.BigDecimal)

Aggregations

Beneficiary (gov.cms.bfd.model.rif.Beneficiary)10 IGenericClient (ca.uhn.fhir.rest.client.api.IGenericClient)8 StringClientParam (ca.uhn.fhir.rest.gclient.StringClientParam)8 ItemComponent (org.hl7.fhir.dstu3.model.ExplanationOfBenefit.ItemComponent)8 IBaseBundle (org.hl7.fhir.instance.model.api.IBaseBundle)8 Test (org.junit.jupiter.api.Test)8 ArrayList (java.util.ArrayList)6 BigDecimal (java.math.BigDecimal)5 Bundle (org.hl7.fhir.dstu3.model.Bundle)5 Trace (com.newrelic.api.agent.Trace)4 Operation (gov.cms.bfd.server.war.Operation)4 BadCodeMonkeyException (gov.cms.bfd.sharedutils.exceptions.BadCodeMonkeyException)4 HashSet (java.util.HashSet)4 List (java.util.List)4 Optional (java.util.Optional)4 Set (java.util.Set)4 Collectors (java.util.stream.Collectors)4 Bundle (org.hl7.fhir.r4.model.Bundle)4 Logger (org.slf4j.Logger)4 LoggerFactory (org.slf4j.LoggerFactory)4