Search in sources :

Example 1 with FhirComponents

use of org.hl7.davinci.r4.FhirComponents in project CRD by HL7-DaVinci.

the class CardBuilder method createSuggestionWithNote.

public static Suggestion createSuggestionWithNote(Card card, IBaseResource request, FhirComponentsT fhirComponents, String label, String description, boolean isRecommended, CoverageGuidance coverageGuidance) {
    Date now = new Date();
    Suggestion requestWithNoteSuggestion = new Suggestion();
    requestWithNoteSuggestion.setLabel(label);
    requestWithNoteSuggestion.setIsRecommended(isRecommended);
    List<Action> actionList = new ArrayList<>();
    // build the Annotation
    Annotation annotation = new Annotation();
    StringType author = new StringType();
    author.setValue(card.getSource().getLabel());
    annotation.setAuthor(author);
    String text = card.getSummary() + ": " + card.getDetail();
    annotation.setText(text);
    // set the date and time to now
    annotation.setTime(now);
    IBaseResource resource = FhirRequestProcessor.addNoteToRequest(request, annotation);
    try {
        // build the Extension with the coverage information
        Extension extension = new Extension();
        extension.setUrl("http://hl7.org/fhir/us/davinci-crd/StructureDefinition/ext-coverage-information");
        Extension coverageInfo = new Extension();
        coverageInfo.setUrl("coverageInfo").setValue(coverageGuidance.getCoding());
        extension.addExtension(coverageInfo);
        Extension coverageExtension = new Extension();
        Reference coverageReference = new Reference();
        // TODO: get the coverage from the prefetch and pass it into here instead of retrieving it from the request
        coverageReference.setReference(FhirRequestProcessor.getCoverageFromRequest(request).getReference());
        coverageExtension.setUrl("coverage").setValue(coverageReference);
        extension.addExtension(coverageExtension);
        Extension date = new Extension();
        date.setUrl("date").setValue(new DateType().setValue(now));
        extension.addExtension(date);
        Extension identifier = new Extension();
        String id = UUID.randomUUID().toString();
        identifier.setUrl("identifier").setValue(new StringType(id));
        extension.addExtension(identifier);
        resource = FhirRequestProcessor.addExtensionToRequest(resource, extension);
    } catch (NoCoverageException e) {
        logger.warn("No Coverage, discrete coverage extension will not be included: " + e.getMessage());
    }
    Action updateAction = new Action(fhirComponents);
    updateAction.setType(Action.TypeEnum.update);
    updateAction.setDescription(description);
    updateAction.setResource(resource);
    actionList.add(updateAction);
    requestWithNoteSuggestion.setActions(actionList);
    return requestWithNoteSuggestion;
}
Also used : NoCoverageException(org.hl7.davinci.endpoint.cdshooks.services.crd.r4.NoCoverageException) Extension(org.hl7.fhir.r4.model.Extension) IBaseResource(org.hl7.fhir.instance.model.api.IBaseResource)

Example 2 with FhirComponents

use of org.hl7.davinci.r4.FhirComponents in project CRD by HL7-DaVinci.

the class JacksonBundleDeserializer method deserialize.

@Override
public Bundle deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
    FhirComponents fhirComponents = new FhirComponents();
    ObjectMapper mapper = (ObjectMapper) p.getCodec();
    JsonNode node = mapper.readTree(p);
    IBaseResource parsedResource = fhirComponents.getJsonParser().parseResource(mapper.writeValueAsString(node));
    return (Bundle) parsedResource;
}
Also used : Bundle(org.hl7.fhir.r4.model.Bundle) JsonNode(com.fasterxml.jackson.databind.JsonNode) IBaseResource(org.hl7.fhir.instance.model.api.IBaseResource) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper)

Example 3 with FhirComponents

use of org.hl7.davinci.r4.FhirComponents in project CRD by HL7-DaVinci.

the class CdsConnectFileStore method processFhirFiles.

private void processFhirFiles(List<CdsConnectFile> files, String topic) {
    // process the fhir resource files
    // setup the proper FHIR Context for the version of FHIR we are dealing with
    FhirContext r4ctx = new org.hl7.davinci.r4.FhirComponents().getFhirContext();
    IParser r4parser = r4ctx.newJsonParser();
    // suppress the unknown element warnings
    r4parser.setParserErrorHandler(new SuppressParserErrorHandler());
    // process all of the files found within the topic/artifact
    for (CdsConnectFile file : files) {
        String path = file.getPath();
        String filename = file.getFilename();
        if (filename.endsWith(".json")) {
            logger.info("        process: FHIR Resource: " + filename);
            String[] parts = filename.split("-");
            if (parts.length > 2) {
                // String resourceType = parts[0];
                String fhirVersion = parts[1];
                String name = parts[2];
                IBaseResource baseResource = null;
                byte[] fileContents = file.getCqlBundle();
                if (fhirVersion.equalsIgnoreCase("R4")) {
                    baseResource = r4parser.parseResource(new ByteArrayInputStream(fileContents));
                }
                processFhirResource(baseResource, path, filename, fhirVersion, topic);
            }
        }
    }
}
Also used : FhirContext(ca.uhn.fhir.context.FhirContext) SuppressParserErrorHandler(org.hl7.davinci.SuppressParserErrorHandler) IBaseResource(org.hl7.fhir.instance.model.api.IBaseResource) IParser(ca.uhn.fhir.parser.IParser)

Example 4 with FhirComponents

use of org.hl7.davinci.r4.FhirComponents in project CRD by HL7-DaVinci.

the class GitHubFileStore method processFhirFolder.

private void processFhirFolder(String topic, String fhirVersion, String fhirPath) {
    fhirVersion = fhirVersion.toUpperCase();
    logger.info("      GitHubFileStore::processFhirFolder(): " + fhirVersion + ": " + fhirPath);
    // setup the proper FHIR Context for the version of FHIR we are dealing with
    FhirContext ctx = null;
    if (fhirVersion.equalsIgnoreCase("R4")) {
        ctx = new org.hl7.davinci.r4.FhirComponents().getFhirContext();
    } else {
        logger.warn("unsupported FHIR version: " + fhirVersion + ", skipping folder");
        return;
    }
    IParser parser = ctx.newJsonParser();
    // suppress the unknown element warnings
    parser.setParserErrorHandler(new SuppressParserErrorHandler());
    for (String folder : connection.getDirectory(fhirPath)) {
        if (folder.equalsIgnoreCase("resources")) {
            String fullFolderPath = fhirPath + "/" + folder;
            for (String resource : connection.getDirectory(fullFolderPath)) {
                String filename = resource;
                String fullFilePath = fullFolderPath + "/" + filename;
                logger.info("        process: FHIR Resource: " + filename);
                String[] parts = filename.split("-");
                if (parts.length > 2) {
                    // = parts[0];
                    String resourceType;
                    if (!parts[1].equalsIgnoreCase(fhirVersion)) {
                        logger.warn("GitHubFileStore::processFhirFolder() warning: FhirVersion doesn't match!");
                        continue;
                    }
                    InputStream inputStream = connection.getFile(fullFilePath);
                    if (inputStream != null) {
                        IBaseResource baseResource = parser.parseResource(inputStream);
                        processFhirResource(baseResource, filename, filename, fhirVersion, topic);
                    } else {
                        logger.warn("could not find file: " + fullFilePath);
                        continue;
                    }
                }
            }
        }
    }
}
Also used : FhirContext(ca.uhn.fhir.context.FhirContext) SuppressParserErrorHandler(org.hl7.davinci.SuppressParserErrorHandler) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) IBaseResource(org.hl7.fhir.instance.model.api.IBaseResource) IParser(ca.uhn.fhir.parser.IParser)

Example 5 with FhirComponents

use of org.hl7.davinci.r4.FhirComponents in project CRD by HL7-DaVinci.

the class CdsService method handleRequest.

/**
 * Performs generic operations for incoming requests of any type.
 *
 * @param request the generically typed incoming request
 * @return The response from the server
 */
public CdsResponse handleRequest(@Valid @RequestBody requestTypeT request, URL applicationBaseUrl) {
    // create the RequestLog
    RequestLog requestLog = new RequestLog(request, new Date().getTime(), this.fhirComponents.getFhirVersion().toString(), this.id, requestService, 5);
    // Parsed request
    requestLog.advanceTimeline(requestService);
    PrefetchHydrator prefetchHydrator = new PrefetchHydrator(this, request, this.fhirComponents);
    prefetchHydrator.hydrate();
    // hydrated
    requestLog.advanceTimeline(requestService);
    // Attempt a Query Batch Request to backfill missing attributes.
    if (myConfig.isQueryBatchRequest()) {
        QueryBatchRequest qbr = new QueryBatchRequest(this.fhirComponents);
        this.attempQueryBatchRequest(request, qbr);
    }
    logger.info("***** ***** request from requestLog: " + requestLog.toString());
    CdsResponse response = new CdsResponse();
    Gson gson = new Gson();
    final String jsonObject = gson.toJson(request.getPrefetch());
    logger.info("Final populated CRDPrefetch: " + jsonObject);
    // CQL Fetched
    List<CoverageRequirementRuleResult> lookupResults;
    try {
        lookupResults = this.createCqlExecutionContexts(request, fileStore, applicationBaseUrl.toString() + "/");
        requestLog.advanceTimeline(requestService);
    } catch (RequestIncompleteException e) {
        logger.warn("RequestIncompleteException " + request);
        logger.warn(e.getMessage() + "; summary card sent to client");
        response.addCard(CardBuilder.summaryCard(CardTypes.COVERAGE, e.getMessage()));
        requestLog.setCardListFromCards(response.getCards());
        requestLog.setResults(e.getMessage());
        requestService.edit(requestLog);
        return response;
    }
    // process the extension for the configuration
    // load hook configuration with default values
    Configuration hookConfiguration = new Configuration();
    Extension extension = request.getExtension();
    if (extension != null) {
        if (extension.getConfiguration() != null) {
            hookConfiguration = extension.getConfiguration();
        }
    }
    boolean errorCardOnEmpty = !(request instanceof OrderSelectRequest);
    // no error cards on empty when order-select request
    boolean foundApplicableRule = false;
    for (CoverageRequirementRuleResult lookupResult : lookupResults) {
        requestLog.addTopic(requestService, lookupResult.getTopic());
        CqlResultsForCard results = executeCqlAndGetRelevantResults(lookupResult.getContext(), lookupResult.getTopic());
        CoverageRequirements coverageRequirements = results.getCoverageRequirements();
        if (results.ruleApplies()) {
            foundApplicableRule = true;
            if (results.getCoverageRequirements().getApplies()) {
                // if prior auth already approved
                if (coverageRequirements.isPriorAuthApproved()) {
                    response.addCard(CardBuilder.priorAuthCard(results, results.getRequest(), fhirComponents, coverageRequirements.getPriorAuthId(), request.getContext().getPatientId(), lookupResult.getCriteria().getPayorId(), request.getContext().getUserId(), applicationBaseUrl.toString() + "/fhir/" + fhirComponents.getFhirVersion().toString(), fhirResourceRepository));
                } else if (coverageRequirements.isDocumentationRequired() || coverageRequirements.isPriorAuthRequired()) {
                    if (StringUtils.isNotEmpty(coverageRequirements.getQuestionnaireOrderUri()) || StringUtils.isNotEmpty(coverageRequirements.getQuestionnaireFaceToFaceUri()) || StringUtils.isNotEmpty(coverageRequirements.getQuestionnaireLabUri()) || StringUtils.isNotEmpty(coverageRequirements.getQuestionnaireProgressNoteUri()) || StringUtils.isNotEmpty(coverageRequirements.getQuestionnairePARequestUri()) || StringUtils.isNotEmpty(coverageRequirements.getQuestionnairePlanOfCareUri()) || StringUtils.isNotEmpty(coverageRequirements.getQuestionnaireDispenseUri()) || StringUtils.isNotEmpty(coverageRequirements.getQuestionnaireAdditionalUri())) {
                        List<Link> smartAppLinks = createQuestionnaireLinks(request, applicationBaseUrl, lookupResult, results);
                        if (coverageRequirements.isPriorAuthRequired()) {
                            Card card = CardBuilder.transform(CardTypes.PRIOR_AUTH, results, smartAppLinks);
                            card.addSuggestionsItem(CardBuilder.createSuggestionWithNote(card, results.getRequest(), fhirComponents, "Save Update To EHR", "Update original " + results.getRequest().fhirType() + " to add note", true, CoverageGuidance.ADMIN));
                            response.addCard(card);
                        } else if (coverageRequirements.isDocumentationRequired()) {
                            Card card = CardBuilder.transform(CardTypes.DTR_CLIN, results, smartAppLinks);
                            card.addSuggestionsItem(CardBuilder.createSuggestionWithNote(card, results.getRequest(), fhirComponents, "Save Update To EHR", "Update original " + results.getRequest().fhirType() + " to add note", true, CoverageGuidance.CLINICAL));
                            response.addCard(card);
                        }
                        // add a card for an alternative therapy if there is one
                        if (results.getAlternativeTherapy().getApplies() && hookConfiguration.getAlternativeTherapy()) {
                            try {
                                response.addCard(CardBuilder.alternativeTherapyCard(results.getAlternativeTherapy(), results.getRequest(), fhirComponents));
                            } catch (RuntimeException e) {
                                logger.warn("Failed to process alternative therapy: " + e.getMessage());
                            }
                        }
                    } else {
                        logger.warn("Unspecified Questionnaire URI; summary card sent to client");
                        response.addCard(CardBuilder.transform(CardTypes.COVERAGE, results));
                    }
                } else {
                    // no prior auth or documentation required
                    logger.info("Add the no doc or prior auth required card");
                    Card card = CardBuilder.transform(CardTypes.COVERAGE, results);
                    card.addSuggestionsItem(CardBuilder.createSuggestionWithNote(card, results.getRequest(), fhirComponents, "Save Update To EHR", "Update original " + results.getRequest().fhirType() + " to add note", true, CoverageGuidance.COVERED));
                    card.setSelectionBehavior(Card.SelectionBehaviorEnum.ANY);
                    response.addCard(card);
                }
            }
            // apply the DrugInteractions
            if (results.getDrugInteraction().getApplies()) {
                response.addCard(CardBuilder.drugInteractionCard(results.getDrugInteraction(), results.getRequest()));
            }
        }
    }
    // CQL Executed
    requestLog.advanceTimeline(requestService);
    if (errorCardOnEmpty) {
        if (!foundApplicableRule) {
            String msg = "No documentation rules found";
            logger.warn(msg + "; summary card sent to client");
            response.addCard(CardBuilder.summaryCard(CardTypes.COVERAGE, msg));
        }
        CardBuilder.errorCardIfNonePresent(CardTypes.COVERAGE, response);
    }
    // Ading card to requestLog
    requestLog.setCardListFromCards(response.getCards());
    requestService.edit(requestLog);
    return response;
}
Also used : CqlResultsForCard(org.hl7.davinci.endpoint.components.CardBuilder.CqlResultsForCard) OrderSelectRequest(org.hl7.davinci.r4.crdhook.orderselect.OrderSelectRequest) PrefetchHydrator(org.hl7.davinci.endpoint.components.PrefetchHydrator) Gson(com.google.gson.Gson) Date(java.util.Date) CqlResultsForCard(org.hl7.davinci.endpoint.components.CardBuilder.CqlResultsForCard) DiscoveryExtension(org.hl7.davinci.r4.crdhook.DiscoveryExtension) RequestLog(org.hl7.davinci.endpoint.database.RequestLog) RequestIncompleteException(org.hl7.davinci.RequestIncompleteException) CoverageRequirementRuleResult(org.hl7.davinci.endpoint.rules.CoverageRequirementRuleResult) ArrayList(java.util.ArrayList) List(java.util.List) QueryBatchRequest(org.hl7.davinci.endpoint.components.QueryBatchRequest)

Aggregations

IBaseResource (org.hl7.fhir.instance.model.api.IBaseResource)7 FhirContext (ca.uhn.fhir.context.FhirContext)5 IParser (ca.uhn.fhir.parser.IParser)5 ArrayList (java.util.ArrayList)3 SuppressParserErrorHandler (org.hl7.davinci.SuppressParserErrorHandler)3 DataFormatException (ca.uhn.fhir.parser.DataFormatException)2 List (java.util.List)2 FatalRequestIncompleteException (org.hl7.davinci.FatalRequestIncompleteException)2 Bundle (org.hl7.fhir.r4.model.Bundle)2 Questionnaire (org.hl7.fhir.r4.model.Questionnaire)2 Resource (org.hl7.fhir.r4.model.Resource)2 HttpEntity (org.springframework.http.HttpEntity)2 HttpHeaders (org.springframework.http.HttpHeaders)2 JsonNode (com.fasterxml.jackson.databind.JsonNode)1 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 Gson (com.google.gson.Gson)1 FileInputStream (java.io.FileInputStream)1 FileNotFoundException (java.io.FileNotFoundException)1 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1