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;
}
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;
}
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);
}
}
}
}
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;
}
}
}
}
}
}
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;
}
Aggregations