Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CFRID_635 #298

Merged
merged 2 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ allprojects {
maven { url 'https://oss.sonatype.org/service/local/repositories/snapshots/content' }
maven { url "https://jitpack.io" }
jcenter()
maven { url 'https://repo.jenkins-ci.org/public'}
}


Expand Down
2 changes: 2 additions & 0 deletions resources/src/main/java/org/cdshooks/Hook.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ public enum Hook {
ORDER_SELECT("order-select"),
ORDER_SIGN("order-sign"),
APPOINTMENT_BOOK("appointment-book"),
ENCOUNTER_START("encounter-start"),
ORDER_DISPATCH("order-dispatch");


private String value;

Hook(String value) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.hl7.davinci.r4.crdhook.encounterstart;

import org.hl7.davinci.PrefetchTemplateElement;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Patient;



/**
* Class that contains the different prefetch template elements used in crd requests.
* The templates are based on https://build.fhir.org/ig/HL7/davinci-crd/hooks.html#prefetch
*/

public class CrdPrefetchTemplateElements {

public static final PrefetchTemplateElement PATIENT = new PrefetchTemplateElement(
"patient",
Patient.class,
"Patient/{{context.patientId}}");

public static final PrefetchTemplateElement COVERAGE_REQUEST_BUNDLE = new PrefetchTemplateElement(
"coverageBundle",
Bundle.class,
"Coverage?patient={{context.patientId}}");

public static final PrefetchTemplateElement ENCOUNTER_BUNDLE = new PrefetchTemplateElement(
"encounterBundle",
Bundle.class,
"Encounter?_id={{context.encounterId}}"
+ "&_include=Encounter:patient"
+ "&_include=Encounter:service-provider"
+ "&_include=Encounter:practitioner"
+ "&_include=Encounter:location");


}

Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package org.hl7.davinci.r4.crdhook.encounterstart;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.hl7.davinci.r4.JacksonBundleDeserializer;
import org.hl7.davinci.r4.JacksonHapiSerializer;
import org.hl7.davinci.r4.crdhook.ServiceContext;
import org.hl7.fhir.r4.model.Bundle;
import javax.validation.constraints.NotNull;


public class EncounterStartContext extends ServiceContext {

/** The FHIR Practictioner.id of the current practitioner in context. REQUIRED */
@NotNull
private String userId = null;

/** The FHIR Patient.id of the current patient in context. REQUIRED */
@NotNull
private String patientId;

/** The FHIR Encounter.id of the current encounter in context. OPTIONAL */
private String encounterId;


@JsonSerialize(using = JacksonHapiSerializer.class)
@JsonDeserialize(using = JacksonBundleDeserializer.class)
private Bundle draftOrders;

public String getUserId() { return userId; }

public void setUserId(String userId) { this.userId = userId; }

public String getPatientId() { return patientId; }

public void setPatientId(String patientId) { this.patientId = patientId; }

public String getEncounterId() { return encounterId; }

public void setEncounterId(String encounterId) { this.encounterId = encounterId; }

public Bundle getDraftOrders() {
return draftOrders;
}

public void setDraftOrders(Bundle draftOrders) {
this.draftOrders = draftOrders;
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.hl7.davinci.r4.crdhook.encounterstart;

import org.cdshooks.CdsRequest;
import org.hl7.davinci.r4.Utilities;
import org.hl7.davinci.r4.crdhook.CrdPrefetch;
import org.hl7.davinci.r4.crdhook.appointmentbook.AppointmentBookContext;

import java.util.HashMap;

public class EncounterStartRequest extends CdsRequest<CrdPrefetch, EncounterStartContext> {

private HashMap<String, Object> mapForPrefetchTemplates = null;

@Override
public Object getDataForPrefetchToken() {
if (mapForPrefetchTemplates != null) {
return mapForPrefetchTemplates;
}
mapForPrefetchTemplates = new HashMap<>();

HashMap<String, Object> contextMap = new HashMap<>();
contextMap.put("userId", getContext().getUserId());
contextMap.put("patientId", getContext().getPatientId());
contextMap.put("encounterId", getContext().getEncounterId());
mapForPrefetchTemplates.put("context", contextMap);

return mapForPrefetchTemplates;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package org.hl7.davinci.endpoint.cdshooks.services.crd.r4;

import org.cdshooks.Hook;
import org.hl7.davinci.PrefetchTemplateElement;
import org.hl7.davinci.RequestIncompleteException;
import org.hl7.davinci.endpoint.cdshooks.services.crd.CdsService;
import org.hl7.davinci.endpoint.components.CardBuilder;
import org.hl7.davinci.endpoint.components.QueryBatchRequest;
import org.hl7.davinci.endpoint.files.FileStore;
import org.hl7.davinci.endpoint.rules.CoverageRequirementRuleResult;
import org.hl7.davinci.r4.FhirComponents;
import org.hl7.davinci.r4.crdhook.ConfigurationOption;
import org.hl7.davinci.r4.crdhook.CrdPrefetch;
import org.hl7.davinci.r4.crdhook.DiscoveryExtension;
import org.hl7.davinci.r4.crdhook.appointmentbook.CrdExtensionConfigurationOptions;
import org.hl7.davinci.r4.crdhook.appointmentbook.CrdPrefetchTemplateElements;
import org.hl7.davinci.r4.crdhook.encounterstart.EncounterStartRequest;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.opencds.cqf.cql.engine.execution.Context;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;

@Component("r4_EncounterStartService")
public class EncounterStartService extends CdsService<EncounterStartRequest> {

public static final String ID = "encounter-start-crd";
public static final String TITLE = "encounter-start Coverage Requirements Discovery";
public static final Hook HOOK = Hook.APPOINTMENT_BOOK;
public static final String DESCRIPTION =
"Get information regarding the coverage requirements for encounters";
public static final List<PrefetchTemplateElement> PREFETCH_ELEMENTS = Arrays.asList(
CrdPrefetchTemplateElements.COVERAGE_REQUEST_BUNDLE,
CrdPrefetchTemplateElements.PATIENT,
CrdPrefetchTemplateElements.ENCOUNTER_BUNDLE);
public static final FhirComponents FHIRCOMPONENTS = new FhirComponents();
public static final List<ConfigurationOption> CONFIGURATION_OPTIONS = Arrays.asList(
CrdExtensionConfigurationOptions.COVERAGE,
CrdExtensionConfigurationOptions.MAX_CARDS
);
public static final DiscoveryExtension EXTENSION = new DiscoveryExtension(CONFIGURATION_OPTIONS);

public EncounterStartService() { super(ID, HOOK, TITLE, DESCRIPTION, PREFETCH_ELEMENTS, FHIRCOMPONENTS, EXTENSION);}

@Override
public List<CoverageRequirementRuleResult> createCqlExecutionContexts(EncounterStartRequest request, FileStore fileStore, String baseUrl) throws RequestIncompleteException {
// List<String> selections = Arrays.asList(request.getContext().getSelections());
List<String> selections = null;

FhirBundleProcessor fhirBundleProcessor = new FhirBundleProcessor(fileStore, baseUrl, selections);
CrdPrefetch prefetch = request.getPrefetch();
//It should be safe to cast these as Bundles as any OperationOutcome's found in the prefetch that could not get resolved would have thrown an exception
List<CoverageRequirementRuleResult> results = fhirBundleProcessor.getResults();

if (results.isEmpty()) {
throw RequestIncompleteException.NoSupportedBundlesFound();
}
return results;
}

@Override
protected CardBuilder.CqlResultsForCard executeCqlAndGetRelevantResults(Context context, String topic) {
CardBuilder.CqlResultsForCard cardResult = new CardBuilder.CqlResultsForCard();
cardResult.setRequest((IBaseResource)context);
return cardResult;
}

@Override
protected void attemptQueryBatchRequest(EncounterStartRequest request, QueryBatchRequest qbr) {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@
import org.cdshooks.CdsResponse;
import org.hl7.davinci.endpoint.Utils;
import org.hl7.davinci.endpoint.cdshooks.services.crd.CdsServiceInformation;
import org.hl7.davinci.endpoint.cdshooks.services.crd.r4.AppointmentBookService;
import org.hl7.davinci.endpoint.cdshooks.services.crd.r4.OrderSelectService;
import org.hl7.davinci.endpoint.cdshooks.services.crd.r4.OrderSignService;
import org.hl7.davinci.endpoint.cdshooks.services.crd.r4.OrderDispatchService;
import org.hl7.davinci.endpoint.cdshooks.services.crd.r4.*;
import org.hl7.davinci.r4.crdhook.CrdPrefetch;
import org.hl7.davinci.r4.crdhook.appointmentbook.AppointmentBookRequest;
import org.hl7.davinci.r4.crdhook.encounterstart.EncounterStartRequest;
import org.hl7.davinci.r4.crdhook.orderselect.OrderSelectRequest;
import org.hl7.davinci.r4.crdhook.ordersign.OrderSignRequest;
import org.hl7.davinci.r4.crdhook.orderdispatch.OrderDispatchRequest;
Expand All @@ -36,6 +34,7 @@ public class CdsHooksController {
@Autowired private OrderSignService orderSignService;
@Autowired private AppointmentBookService appointmentBookService;
@Autowired private OrderDispatchService orderDispatchService;
@Autowired private EncounterStartService encounterStartService;

/**
* The FHIR r4 services discovery endpoint.
Expand Down Expand Up @@ -101,12 +100,22 @@ public CdsResponse handleAppointmentBook(@Valid @RequestBody AppointmentBookRequ
}
return appointmentBookService.handleRequest(request, Utils.getApplicationBaseUrl(httpServletRequest));
}

@CrossOrigin
@PostMapping(value = FHIR_RELEASE + URL_BASE + "/" + EncounterStartService.ID,
consumes = "application/json;charset=UTF-8")
public CdsResponse handleEncounterStart(@Valid @RequestBody EncounterStartRequest request, final HttpServletRequest httpServletRequest) {
logger.info("r4/handleEncounterStart");
if (request.getPrefetch() == null) {
request.setPrefetch(new CrdPrefetch());
}
return encounterStartService.handleRequest(request, Utils.getApplicationBaseUrl(httpServletRequest));
}



/**
* The coverage requirement discovery endpoint for the appointment-book hook.
* @param request An appointment-book triggered cds request
* @return The card response
*/
@CrossOrigin
Expand Down Expand Up @@ -134,3 +143,5 @@ public CdsResponse handleOrderDispatch(@Valid @RequestBody OrderDispatchRequest
return orderDispatchService.handleRequest(request, Utils.getApplicationBaseUrl(httpServletRequest));
}
}


Loading