From aa50004591b9a383b66f4c95bcb78229a36a9290 Mon Sep 17 00:00:00 2001 From: Volker Schmidt Date: Tue, 13 Aug 2019 17:33:14 +0200 Subject: [PATCH] Adds support for optional program stage metadata. Tests are still missing. --- .../Dstu3ProgramStageFhirRestAppTest.java | 21 +++--- .../r4/R4ProgramStageFhirRestAppTest.java | 29 ++++---- .../dhis/tracker/program/EventService.java | 3 +- .../program/impl/EventServiceImpl.java | 23 +++++-- .../fhir/metadata/model/ProgramStageRule.java | 41 ++++++------ ...reCreateSaveProgramStageRuleValidator.java | 4 -- .../impl/MetadataExportServiceImpl.java | 2 +- .../PreparedProgramStageToFhirSearch.java | 14 +++- .../ProgramStageToFhirDataProvider.java | 66 +++++++++++++------ .../ProgramStageToFhirSearchState.java | 6 +- .../ProgramStageToFhirTransformer.java | 5 ++ .../FhirToProgramStageTransformer.java | 6 ++ .../V1.1.0.45_0_0__Care_Resources_Read.sql | 2 + 13 files changed, 141 insertions(+), 81 deletions(-) diff --git a/app/src/test/java/org/dhis2/fhir/adapter/fhir/server/dstu3/Dstu3ProgramStageFhirRestAppTest.java b/app/src/test/java/org/dhis2/fhir/adapter/fhir/server/dstu3/Dstu3ProgramStageFhirRestAppTest.java index 0e9b8d48..2bf7448b 100644 --- a/app/src/test/java/org/dhis2/fhir/adapter/fhir/server/dstu3/Dstu3ProgramStageFhirRestAppTest.java +++ b/app/src/test/java/org/dhis2/fhir/adapter/fhir/server/dstu3/Dstu3ProgramStageFhirRestAppTest.java @@ -137,8 +137,9 @@ public void searchObservationInvalidAuthorization() throws Exception { expectProgramStageMetadataRequests(); userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6aW52YWxpZF8x" ) ) - .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?skipPaging=false&page=1&pageSize=10&program=EPDyQuoRnXk&programStage=qowTSevVSkd&ouMode=ACCESSIBLE&" + - "fields=deleted,event,orgUnit,program,enrollment,trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D" ) ) + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?skipPaging=false&page=1&pageSize=10&ouMode=ACCESSIBLE&" + + "fields=deleted,event,orgUnit,program,enrollment,trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D" + + "&program=EPDyQuoRnXk&programStage=qowTSevVSkd" ) ) .andRespond( withStatus( HttpStatus.UNAUTHORIZED ) ); final IGenericClient client = createGenericClient(); @@ -160,12 +161,12 @@ private void searchObservation() throws Exception expectProgramStageMetadataRequests(); userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6Zmhpcl9jbGllbnRfMQ==" ) ) - .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?skipPaging=false&page=1&pageSize=10&program=EPDyQuoRnXk&programStage=qowTSevVSkd&ouMode=ACCESSIBLE&fields=deleted,event,orgUnit,program,enrollment," + - "trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D" ) ) + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?skipPaging=false&page=1&pageSize=10&ouMode=ACCESSIBLE&fields=deleted,event,orgUnit,program,enrollment," + + "trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D&program=EPDyQuoRnXk&programStage=qowTSevVSkd" ) ) .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/default-event-70-get.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6Zmhpcl9jbGllbnRfMQ==" ) ) - .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?skipPaging=false&page=1&pageSize=9&program=EPDyQuoRnXk&programStage=MsWxkiY6tMS&ouMode=ACCESSIBLE&fields=deleted,event,orgUnit,program,enrollment," + - "trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D" ) ) + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?skipPaging=false&page=1&pageSize=9&ouMode=ACCESSIBLE&fields=deleted,event,orgUnit,program,enrollment," + + "trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D&program=EPDyQuoRnXk&programStage=MsWxkiY6tMS" ) ) .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/default-event-71-only-get.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); systemDhis2Server.expect( ExpectedCount.between( 0, 1 ), method( HttpMethod.GET ) ).andExpect( header( "Authorization", testConfiguration.getDhis2SystemAuthorization() ) ) .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/organisationUnits/ldXIdLNUNEp.json?fields=lastUpdated,id,code,name,shortName,displayName,level,openingDate,closedDate,coordinates,leaf,parent%5Bid%5D" ) ) @@ -189,12 +190,12 @@ public void searchObservationPatient() throws Exception { expectProgramStageMetadataRequests(); userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6Zmhpcl9jbGllbnRfMQ==" ) ) - .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?trackedEntityInstance=JeR2Ul4mZfx&skipPaging=false&page=1&pageSize=10&program=EPDyQuoRnXk&programStage=qowTSevVSkd&ouMode=ACCESSIBLE&fields=deleted,event,orgUnit," + - "program,enrollment,trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D" ) ) + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?trackedEntityInstance=JeR2Ul4mZfx&skipPaging=false&page=1&pageSize=10&ouMode=ACCESSIBLE&fields=deleted,event,orgUnit," + + "program,enrollment,trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D&program=EPDyQuoRnXk&programStage=qowTSevVSkd" ) ) .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/default-event-70-get.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6Zmhpcl9jbGllbnRfMQ==" ) ) - .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?trackedEntityInstance=JeR2Ul4mZfx&skipPaging=false&page=1&pageSize=9&program=EPDyQuoRnXk&programStage=MsWxkiY6tMS&ouMode=ACCESSIBLE&fields=deleted,event,orgUnit," + - "program,enrollment,trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D" ) ) + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?trackedEntityInstance=JeR2Ul4mZfx&skipPaging=false&page=1&pageSize=9&ouMode=ACCESSIBLE&fields=deleted,event,orgUnit," + + "program,enrollment,trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D&program=EPDyQuoRnXk&programStage=MsWxkiY6tMS" ) ) .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/default-event-71-only-get.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); systemDhis2Server.expect( ExpectedCount.between( 0, 1 ), method( HttpMethod.GET ) ).andExpect( header( "Authorization", testConfiguration.getDhis2SystemAuthorization() ) ) .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/organisationUnits/ldXIdLNUNEp.json?fields=lastUpdated,id,code,name,shortName,displayName,level,openingDate,closedDate,coordinates,leaf,parent%5Bid%5D" ) ) diff --git a/app/src/test/java/org/dhis2/fhir/adapter/fhir/server/r4/R4ProgramStageFhirRestAppTest.java b/app/src/test/java/org/dhis2/fhir/adapter/fhir/server/r4/R4ProgramStageFhirRestAppTest.java index 4a0a1801..0de029e9 100644 --- a/app/src/test/java/org/dhis2/fhir/adapter/fhir/server/r4/R4ProgramStageFhirRestAppTest.java +++ b/app/src/test/java/org/dhis2/fhir/adapter/fhir/server/r4/R4ProgramStageFhirRestAppTest.java @@ -138,8 +138,9 @@ public void searchObservationInvalidAuthorization() throws Exception { expectProgramStageMetadataRequests(); userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6aW52YWxpZF8x" ) ) - .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?skipPaging=false&page=1&pageSize=10&program=EPDyQuoRnXk&programStage=qowTSevVSkd&ouMode=ACCESSIBLE&" + - "fields=deleted,event,orgUnit,program,enrollment,trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D" ) ) + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?skipPaging=false&page=1&pageSize=10&ouMode=ACCESSIBLE&" + + "fields=deleted,event,orgUnit,program,enrollment,trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D" + + "&program=EPDyQuoRnXk&programStage=qowTSevVSkd" ) ) .andRespond( withStatus( HttpStatus.UNAUTHORIZED ) ); final IGenericClient client = createGenericClient(); @@ -161,12 +162,12 @@ private void searchObservation() throws Exception expectProgramStageMetadataRequests(); userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6Zmhpcl9jbGllbnRfMQ==" ) ) - .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?skipPaging=false&page=1&pageSize=10&program=EPDyQuoRnXk&programStage=qowTSevVSkd&ouMode=ACCESSIBLE&fields=deleted,event,orgUnit,program,enrollment," + - "trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D" ) ) + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?skipPaging=false&page=1&pageSize=10&ouMode=ACCESSIBLE&fields=deleted,event,orgUnit,program,enrollment," + + "trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D&program=EPDyQuoRnXk&programStage=qowTSevVSkd" ) ) .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/default-event-70-get.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6Zmhpcl9jbGllbnRfMQ==" ) ) - .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?skipPaging=false&page=1&pageSize=9&program=EPDyQuoRnXk&programStage=MsWxkiY6tMS&ouMode=ACCESSIBLE&fields=deleted,event,orgUnit,program,enrollment," + - "trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D" ) ) + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?skipPaging=false&page=1&pageSize=9&ouMode=ACCESSIBLE&fields=deleted,event,orgUnit,program,enrollment," + + "trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D&program=EPDyQuoRnXk&programStage=MsWxkiY6tMS" ) ) .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/default-event-71-only-get.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); systemDhis2Server.expect( ExpectedCount.between( 0, 1 ), method( HttpMethod.GET ) ).andExpect( header( "Authorization", testConfiguration.getDhis2SystemAuthorization() ) ) .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/organisationUnits/ldXIdLNUNEp.json?fields=lastUpdated,id,code,name,shortName,displayName,level,openingDate,closedDate,coordinates,leaf,parent%5Bid%5D" ) ) @@ -190,12 +191,12 @@ public void searchObservationPatient() throws Exception { expectProgramStageMetadataRequests(); userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6Zmhpcl9jbGllbnRfMQ==" ) ) - .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?trackedEntityInstance=JeR2Ul4mZfx&skipPaging=false&page=1&pageSize=10&program=EPDyQuoRnXk&programStage=qowTSevVSkd&ouMode=ACCESSIBLE&fields=deleted,event,orgUnit," + - "program,enrollment,trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D" ) ) + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?trackedEntityInstance=JeR2Ul4mZfx&skipPaging=false&page=1&pageSize=10&ouMode=ACCESSIBLE&fields=deleted,event,orgUnit," + + "program,enrollment,trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D&program=EPDyQuoRnXk&programStage=qowTSevVSkd" ) ) .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/default-event-70-get.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6Zmhpcl9jbGllbnRfMQ==" ) ) - .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?trackedEntityInstance=JeR2Ul4mZfx&skipPaging=false&page=1&pageSize=9&program=EPDyQuoRnXk&programStage=MsWxkiY6tMS&ouMode=ACCESSIBLE&fields=deleted,event,orgUnit," + - "program,enrollment,trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D" ) ) + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?trackedEntityInstance=JeR2Ul4mZfx&skipPaging=false&page=1&pageSize=9&ouMode=ACCESSIBLE&fields=deleted,event,orgUnit," + + "program,enrollment,trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D&program=EPDyQuoRnXk&programStage=MsWxkiY6tMS" ) ) .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/default-event-71-only-get.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); systemDhis2Server.expect( ExpectedCount.between( 0, 1 ), method( HttpMethod.GET ) ).andExpect( header( "Authorization", testConfiguration.getDhis2SystemAuthorization() ) ) .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/organisationUnits/ldXIdLNUNEp.json?fields=lastUpdated,id,code,name,shortName,displayName,level,openingDate,closedDate,coordinates,leaf,parent%5Bid%5D" ) ) @@ -219,12 +220,12 @@ public void searchObservationEncounter() throws Exception { expectProgramStageMetadataRequests(); userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6Zmhpcl9jbGllbnRfMQ==" ) ) - .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?event=deR4kl4mnf7&skipPaging=false&page=1&pageSize=10&program=EPDyQuoRnXk&programStage=qowTSevVSkd&ouMode=ACCESSIBLE&fields=deleted,event,orgUnit," + - "program,enrollment,trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D" ) ) + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?event=deR4kl4mnf7&skipPaging=false&page=1&pageSize=10&ouMode=ACCESSIBLE&fields=deleted,event,orgUnit," + + "program,enrollment,trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D&program=EPDyQuoRnXk&programStage=qowTSevVSkd" ) ) .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/default-event-70-get.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6Zmhpcl9jbGllbnRfMQ==" ) ) - .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?event=deR4kl4mnf7&skipPaging=false&page=1&pageSize=9&program=EPDyQuoRnXk&programStage=MsWxkiY6tMS&ouMode=ACCESSIBLE&fields=deleted,event,orgUnit,program,enrollment," + - "trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D" ) ) + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/events.json?event=deR4kl4mnf7&skipPaging=false&page=1&pageSize=9&ouMode=ACCESSIBLE&fields=deleted,event,orgUnit,program,enrollment," + + "trackedEntityInstance,programStage,status,eventDate,dueDate,coordinate,lastUpdated,dataValues%5BdataElement,value,providedElsewhere,lastUpdated,storedBy%5D&program=EPDyQuoRnXk&programStage=MsWxkiY6tMS" ) ) .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/default-event-71-only-get.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); systemDhis2Server.expect( ExpectedCount.between( 0, 1 ), method( HttpMethod.GET ) ).andExpect( header( "Authorization", testConfiguration.getDhis2SystemAuthorization() ) ) .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/organisationUnits/ldXIdLNUNEp.json?fields=lastUpdated,id,code,name,shortName,displayName,level,openingDate,closedDate,coordinates,leaf,parent%5Bid%5D" ) ) diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/EventService.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/EventService.java index 80215e74..b57ac84f 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/EventService.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/EventService.java @@ -34,6 +34,7 @@ import org.dhis2.fhir.adapter.dhis.service.DhisService; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.util.Collection; import java.util.Optional; @@ -65,5 +66,5 @@ Collection find( @Nonnull String programId, @Nonnull String programStageI boolean delete( @Nonnull String eventId ); @Nonnull - DhisResourceResult find( @Nonnull String programId, @Nonnull String programStageId, @Nonnull UriFilterApplier uriFilterApplier, int from, int max ); + DhisResourceResult find( @Nullable String programId, @Nullable String programStageId, @Nonnull UriFilterApplier uriFilterApplier, int from, int max ); } diff --git a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/EventServiceImpl.java b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/EventServiceImpl.java index 437e279a..c85cc24b 100644 --- a/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/EventServiceImpl.java +++ b/dhis/src/main/java/org/dhis2/fhir/adapter/dhis/tracker/program/impl/EventServiceImpl.java @@ -450,19 +450,30 @@ protected Event update( @Nonnull Event event ) @HystrixCommand( ignoreExceptions = { UnauthorizedException.class, DhisFindException.class } ) @Nonnull @Override - public DhisResourceResult find( @Nonnull String programId, @Nonnull String programStageId, @Nonnull UriFilterApplier uriFilterApplier, int from, int max ) + public DhisResourceResult find( @Nullable String programId, @Nullable String programStageId, @Nonnull UriFilterApplier uriFilterApplier, int from, int max ) { final DhisPagingQuery pagingQuery = DhisPagingUtils.createPagingQuery( from, max ); final List variables = new ArrayList<>(); - final String uri = uriFilterApplier.add( UriComponentsBuilder.newInstance(), variables ).path( "/events.json" ) + + UriComponentsBuilder builder = uriFilterApplier.add( UriComponentsBuilder.newInstance(), variables ).path( "/events.json" ) .queryParam( "skipPaging", "false" ).queryParam( "page", pagingQuery.getPage() ).queryParam( "pageSize", pagingQuery.getPageSize() ) - .queryParam( "program", programId ).queryParam( "programStage", programStageId ) .queryParam( "ouMode", uriFilterApplier.containsQueryParam( "orgUnit" ) ? "SELECTED" : "ACCESSIBLE" ) - .queryParam( "fields", FIELDS ).build().toString(); + .queryParam( "fields", FIELDS ); + + if ( programId != null ) + { + builder = builder.queryParam( "program", programId ); + } + + if ( programStageId != null ) + { + builder = builder.queryParam( "programStage", programStageId ); + } + final ResponseEntity result; try { - result = restTemplate.getForEntity( uri, DhisEvents.class, variables.toArray() ); + result = restTemplate.getForEntity( builder.build().toString(), DhisEvents.class, variables.toArray() ); } catch ( HttpClientErrorException e ) { @@ -470,8 +481,10 @@ public DhisResourceResult find( @Nonnull String programId, @Nonnull Strin { throw new DhisFindException( e.getMessage(), e ); } + throw e; } + final DhisEvents events = Objects.requireNonNull( result.getBody() ); return new DhisResourceResult<>( (events.getEvents().size() > pagingQuery.getResultOffset()) ? diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/ProgramStageRule.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/ProgramStageRule.java index a4fec076..f7045bbb 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/ProgramStageRule.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/ProgramStageRule.java @@ -49,6 +49,7 @@ import javax.persistence.NamedQuery; import javax.persistence.Table; import javax.persistence.Transient; +import java.util.Objects; /** * AbstractRule for program stage that defines also if and how to enroll into a program. @@ -60,17 +61,15 @@ @DiscriminatorValue( "PROGRAM_STAGE_EVENT" ) @NamedQueries( { @NamedQuery( name = ProgramStageRule.FIND_ALL_EXP_NAMED_QUERY, - query = "SELECT psr FROM ProgramStageRule psr JOIN psr.programStage ps JOIN ps.program p WHERE " + - "psr.enabled=true AND psr.expEnabled=true AND (psr.fhirCreateEnabled=true OR psr.fhirUpdateEnabled=true) AND psr.transformExpScript IS NOT NULL AND " + - "ps.enabled=true AND ps.expEnabled=true AND (ps.fhirCreateEnabled=true OR ps.fhirUpdateEnabled=true) AND " + - "p.enabled=true AND p.expEnabled=true AND (p.fhirCreateEnabled=true OR p.fhirUpdateEnabled=true) AND " + - "p.programReference IN (:programReferences) AND ps.programStageReference IN (:programStageReferences)" ), + query = "SELECT psr FROM ProgramStageRule psr " + + "LEFT JOIN psr.programStage ps ON (ps.enabled=true AND ps.expEnabled=true AND (ps.fhirCreateEnabled=true OR ps.fhirUpdateEnabled=true) AND ps.programStageReference IN (:programStageReferences)) " + + "LEFT JOIN ps.program p ON (p.enabled=true AND p.expEnabled=true AND (p.fhirCreateEnabled=true OR p.fhirUpdateEnabled=true) AND p.programReference IN (:programReferences)) WHERE " + + "psr.enabled=true AND psr.expEnabled=true AND (psr.fhirCreateEnabled=true OR psr.fhirUpdateEnabled=true) AND psr.transformExpScript IS NOT NULL" ), @NamedQuery( name = ProgramStageRule.FIND_ALL_EXP_BY_DATA_REF_NAMED_QUERY, - query = "SELECT psr FROM ProgramStageRule psr JOIN psr.programStage ps JOIN ps.program p WHERE " + + query = "SELECT psr FROM ProgramStageRule psr " + + "LEFT JOIN psr.programStage ps ON (ps.enabled=true AND ps.expEnabled=true AND (ps.fhirCreateEnabled=true OR ps.fhirUpdateEnabled=true) AND ps.programStageReference IN (:programStageReferences)) " + + "LEFT JOIN ps.program p ON (p.enabled=true AND p.expEnabled=true AND (p.fhirCreateEnabled=true OR p.fhirUpdateEnabled=true) AND p.programReference IN (:programReferences)) WHERE " + "psr.enabled=true AND psr.expEnabled=true AND (psr.fhirCreateEnabled=true OR psr.fhirUpdateEnabled=true) AND psr.transformExpScript IS NOT NULL AND " + - "ps.enabled=true AND ps.expEnabled=true AND (ps.fhirCreateEnabled=true OR ps.fhirUpdateEnabled=true) AND " + - "p.enabled=true AND p.expEnabled=true AND (p.fhirCreateEnabled=true OR p.fhirUpdateEnabled=true) AND " + - "p.programReference IN (:programReferences) AND ps.programStageReference IN (:programStageReferences) AND " + "EXISTS (SELECT 1 FROM RuleDhisDataReference edr WHERE edr.rule=psr AND edr.dataReference IN (:dataReferences))" ) } ) @Relation( value = "rule", collectionRelation = "rules" ) @@ -154,9 +153,8 @@ public void setUpdateEventDate( boolean updateEventDate ) this.updateEventDate = updateEventDate; } - - @ManyToOne( optional = false ) - @JoinColumn( name = "program_stage_id", referencedColumnName = "id", nullable = false ) + @ManyToOne + @JoinColumn( name = "program_stage_id", referencedColumnName = "id" ) public MappedTrackerProgramStage getProgramStage() { return programStage; @@ -265,28 +263,28 @@ public void setExpDeleteEvaluateScript( ExecutableScript expDeleteEvaluateScript @Transient public EventPeriodDayType getResultingBeforePeriodDayType() { - return (getBeforePeriodDayType() == null) ? getProgramStage().getBeforePeriodDayType() : getBeforePeriodDayType(); + return getBeforePeriodDayType() == null && getProgramStage() != null ? getProgramStage().getBeforePeriodDayType() : getBeforePeriodDayType(); } @JsonIgnore @Transient public int getResultingBeforePeriodDays() { - return (getBeforePeriodDays() == null) ? getProgramStage().getBeforePeriodDays() : getBeforePeriodDays(); + return getBeforePeriodDays() == null && getProgramStage() != null ? getProgramStage().getBeforePeriodDays() : getBeforePeriodDays(); } @JsonIgnore @Transient public EventPeriodDayType getResultingAfterPeriodDayType() { - return (getAfterPeriodDayType() == null) ? getProgramStage().getAfterPeriodDayType() : getAfterPeriodDayType(); + return getAfterPeriodDayType() == null && getProgramStage() != null ? getProgramStage().getAfterPeriodDayType() : getAfterPeriodDayType(); } @JsonIgnore @Transient public int getResultingAfterPeriodDays() { - return (getAfterPeriodDays() == null) ? getProgramStage().getAfterPeriodDays() : getAfterPeriodDays(); + return getAfterPeriodDays() == null && getProgramStage() != null ? getProgramStage().getAfterPeriodDays() : getAfterPeriodDays(); } @Override @@ -294,7 +292,7 @@ public int getResultingAfterPeriodDays() @JsonIgnore public boolean isEffectiveFhirCreateEnable() { - return isExpEnabled() && isFhirCreateEnabled() && getProgramStage().isExpEnabled() && getProgramStage().isEffectiveFhirCreateEnabled(); + return isExpEnabled() && isFhirCreateEnabled() && ( getProgramStage() == null || ( getProgramStage().isExpEnabled() && getProgramStage().isEffectiveFhirCreateEnabled() ) ); } @Override @@ -302,7 +300,7 @@ public boolean isEffectiveFhirCreateEnable() @JsonIgnore public boolean isEffectiveFhirUpdateEnable() { - return isExpEnabled() && isFhirUpdateEnabled() && getProgramStage().isExpEnabled() && getProgramStage().isEffectiveFhirUpdateEnabled(); + return isExpEnabled() && isFhirUpdateEnabled() && ( getProgramStage() == null || ( getProgramStage().isExpEnabled() && getProgramStage().isEffectiveFhirUpdateEnabled() ) ); } @Override @@ -310,13 +308,14 @@ public boolean isEffectiveFhirUpdateEnable() @JsonIgnore public boolean isEffectiveFhirDeleteEnable() { - return isExpEnabled() && isFhirDeleteEnabled() && getProgramStage().isExpEnabled() && getProgramStage().isEffectiveFhirDeleteEnabled(); + return isExpEnabled() && isFhirDeleteEnabled() && ( getProgramStage() == null || ( getProgramStage().isExpEnabled() && getProgramStage().isEffectiveFhirDeleteEnabled() ) ); } @Override public boolean coversExecutedRule( @Nonnull AbstractRule executedRule ) { - return executedRule instanceof ProgramStageRule && ( (ProgramStageRule) executedRule ) - .getProgramStage().getId().equals( getProgramStage().getId() ); + return executedRule instanceof ProgramStageRule && Objects.equals( + ( (ProgramStageRule) executedRule ).getProgramStage() == null ? null : ( (ProgramStageRule) executedRule ).getProgramStage().getId(), + getProgramStage() == null ? null : getProgramStage().getId() ); } } diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveProgramStageRuleValidator.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveProgramStageRuleValidator.java index 4efbebf7..68c06ac6 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveProgramStageRuleValidator.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveProgramStageRuleValidator.java @@ -69,9 +69,5 @@ public void doValidate( @Nonnull ProgramStageRule rule, @Nonnull Errors errors ) { rule.setEventStatusUpdate( new EventStatusUpdate() ); } - if ( rule.getProgramStage() == null ) - { - errors.rejectValue( "programStage", "ProgramStageRule.programStage.null", "Program stage is mandatory." ); - } } } diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/service/impl/MetadataExportServiceImpl.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/service/impl/MetadataExportServiceImpl.java index 7222dc08..cfd50c9b 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/service/impl/MetadataExportServiceImpl.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/service/impl/MetadataExportServiceImpl.java @@ -211,7 +211,7 @@ protected void processFhirResourceTypes( @Nonnull TypedMetadataObjectContainer t { final Map> fhirResourceMappingKeys = new HashMap<>(); - typedContainer.getContainer( ProgramStageRule.class ).getObjects().stream().map( r -> (ProgramStageRule) r ).forEach( r -> + typedContainer.getContainer( ProgramStageRule.class ).getObjects().stream().map( r -> (ProgramStageRule) r ).filter( r -> r.getProgramStage() != null ).forEach( r -> fhirResourceMappingKeys.computeIfAbsent( r.getProgramStage().getProgram().getTrackedEntityFhirResourceType(), resourceType -> new HashSet<>( Collections.singleton( resourceType ) ) ).add( r.getFhirResourceType() ) ); diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/PreparedProgramStageToFhirSearch.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/PreparedProgramStageToFhirSearch.java index b0189d80..a1e6b657 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/PreparedProgramStageToFhirSearch.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/PreparedProgramStageToFhirSearch.java @@ -33,6 +33,7 @@ import org.dhis2.fhir.adapter.fhir.metadata.model.ProgramStageRule; import org.dhis2.fhir.adapter.fhir.metadata.model.RuleInfo; import org.dhis2.fhir.adapter.fhir.model.FhirVersion; +import org.dhis2.fhir.adapter.fhir.transform.FatalTransformerException; import org.dhis2.fhir.adapter.fhir.transform.dhis.PreparedDhisToFhirSearch; import org.dhis2.fhir.adapter.fhir.transform.dhis.impl.AbstractPreparedDhisToFhirSearch; @@ -51,15 +52,26 @@ public class PreparedProgramStageToFhirSearch extends AbstractPreparedDhisToFhir private final List programStageIds; public PreparedProgramStageToFhirSearch( @Nonnull FhirVersion fhirVersion, @Nonnull List> ruleInfos, @Nullable Map> filter, @Nullable DateRangeParam lastUpdatedDateRange, int count, - @Nonnull List programStageIds ) + @Nullable List programStageIds ) { super( fhirVersion, ruleInfos, filter, lastUpdatedDateRange, count ); + this.programStageIds = programStageIds; } + public boolean isProgramStageRestricted() + { + return programStageIds != null; + } + @Nullable public ProgramStageId getNextProgramStageId( @Nullable ProgramStageId previousProgramStageId ) { + if ( programStageIds == null ) + { + throw new FatalTransformerException( "No program stages have been selected." ); + } + if ( previousProgramStageId == null ) { return programStageIds.get( 0 ); diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirDataProvider.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirDataProvider.java index 6143ba7e..148cdd34 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirDataProvider.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirDataProvider.java @@ -56,8 +56,6 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -117,18 +115,26 @@ public DhisResource findByDhisFhirIdentifier( @Nonnull FhirClient fhirClient, @N @Override public PreparedDhisToFhirSearch prepareSearch( @Nonnull FhirVersion fhirVersion, @Nonnull List> ruleInfos, @Nullable Map> filter, @Nullable DateRangeParam lastUpdatedDateRange, int count ) throws DhisToFhirDataProviderException { - final Set refs = ruleInfos.stream() - .filter( ri -> ri.getRule().getProgramStage().isEnabled() && ri.getRule().getProgramStage().isExpEnabled() && ri.getRule().getProgramStage().getProgram().isEnabled() && ri.getRule().getProgramStage().getProgram().isExpEnabled() ) - .map( ri -> new ReferenceTuple( ri.getRule().getProgramStage().getProgram().getProgramReference(), ri.getRule().getProgramStage().getProgramStageReference() ) ) - .collect( Collectors.toCollection( TreeSet::new ) ); - final Set programStageIds = refs.stream().map( ref -> { - final Program program = metadataService.findMetadataByReference( ref.getProgramReference() ) - .orElseThrow( () -> new TransformerMappingException( "Program does not exist: " + ref.getProgramReference() ) ); - final ProgramStage programStage = program.getOptionalStage( ref.getProgramStageReference() ) - .orElseThrow( () -> new TransformerMappingException( "Program stage does not exist: " + ref.getProgramStageReference() ) ); - return new ProgramStageId( program.getId(), programStage.getId() ); - } ).collect( Collectors.toCollection( LinkedHashSet::new ) ); - return new PreparedProgramStageToFhirSearch( fhirVersion, ruleInfos, filter, lastUpdatedDateRange, count, new ArrayList<>( programStageIds ) ); + List programStageIds = null; + + if ( ruleInfos.stream().noneMatch( ri -> ri.getRule().getProgramStage() == null ) ) + { + final Set refs = ruleInfos.stream() + .filter( ri -> ri.getRule().getProgramStage().isEnabled() && ri.getRule().getProgramStage().isExpEnabled() && ri.getRule().getProgramStage().getProgram().isEnabled() && ri.getRule().getProgramStage().getProgram().isExpEnabled() ) + .map( ri -> new ReferenceTuple( ri.getRule().getProgramStage().getProgram().getProgramReference(), ri.getRule().getProgramStage().getProgramStageReference() ) ) + .collect( Collectors.toCollection( TreeSet::new ) ); + + programStageIds = refs.stream().map( ref -> { + final Program program = metadataService.findMetadataByReference( ref.getProgramReference() ) + .orElseThrow( () -> new TransformerMappingException( "Program does not exist: " + ref.getProgramReference() ) ); + final ProgramStage programStage = program.getOptionalStage( ref.getProgramStageReference() ) + .orElseThrow( () -> new TransformerMappingException( "Program stage does not exist: " + ref.getProgramStageReference() ) ); + + return new ProgramStageId( program.getId(), programStage.getId() ); + } ).distinct().collect( Collectors.toList() ); + } + + return new PreparedProgramStageToFhirSearch( fhirVersion, ruleInfos, filter, lastUpdatedDateRange, count, programStageIds ); } @Nullable @@ -140,13 +146,27 @@ public DhisToFhirSearchResult search( @Nonnull PreparedD final ProgramStageId programStageId; final int from; - if ( (ss == null) || !ss.isMore() ) + + if ( ss == null || !ss.isMore() ) { - programStageId = ps.getNextProgramStageId( (ss == null) ? null : ss.getProgramStageId() ); - if ( programStageId == null ) + if ( ps.isProgramStageRestricted() ) + { + programStageId = ps.getNextProgramStageId( ss == null ? null : ss.getProgramStageId() ); + + if ( programStageId == null ) + { + return null; + } + } + else if ( ss == null ) + { + programStageId = null; + } + else { return null; } + from = 0; // may be filtered by ID of program stage @@ -162,15 +182,17 @@ public DhisToFhirSearchResult search( @Nonnull PreparedD try { result = eventService.find( - programStageId.getProgramId(), programStageId.getProgramStageId(), ps, from, max ); + programStageId == null ? null : programStageId.getProgramId(), + programStageId == null ? null : programStageId.getProgramStageId(), + ps, from, max ); } catch ( DhisFindException e ) { throw new DhisToFhirDataProviderException( e.getMessage(), e ); } - return new DhisToFhirSearchResult<>( result.getResources(), - new ProgramStageToFhirSearchState( programStageId, from + result.getResources().size(), - !result.getResources().isEmpty() && result.isMore() ) ); + + return new DhisToFhirSearchResult<>( result.getResources(), new ProgramStageToFhirSearchState( programStageId, from + result.getResources().size(), + !result.getResources().isEmpty() && result.isMore() ) ); } public static class ReferenceTuple implements Comparable @@ -217,10 +239,12 @@ public int hashCode() public int compareTo( @Nonnull ReferenceTuple o ) { int value = programReference.compareTo( o.programReference ); + if ( value != 0 ) { return value; } + return programStageReference.compareTo( o.programStageReference ); } } diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirSearchState.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirSearchState.java index 88986e32..4990612e 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirSearchState.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirSearchState.java @@ -31,7 +31,7 @@ import org.dhis2.fhir.adapter.dhis.tracker.program.ProgramStageId; import org.dhis2.fhir.adapter.fhir.transform.dhis.DhisToFhirSearchState; -import javax.annotation.Nonnull; +import javax.annotation.Nullable; /** * Implementation of {@link DhisToFhirSearchState} for program stages. @@ -46,14 +46,14 @@ public class ProgramStageToFhirSearchState implements DhisToFhirSearchState private final boolean more; - public ProgramStageToFhirSearchState( @Nonnull ProgramStageId programStageId, int from, boolean more ) + public ProgramStageToFhirSearchState( @Nullable ProgramStageId programStageId, int from, boolean more ) { this.programStageId = programStageId; this.from = from; this.more = more; } - @Nonnull + @Nullable public ProgramStageId getProgramStageId() { return programStageId; diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirTransformer.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirTransformer.java index bbb65b92..abc32a65 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirTransformer.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirTransformer.java @@ -124,6 +124,11 @@ public DhisToFhirTransformOutcome transform( @Nonnull FhirClient fhirClient, @Nonnull DhisToFhirTransformerContext context, @Nonnull ScriptedEvent input, @Nonnull RuleInfo ruleInfo, @Nonnull Map scriptVariables ) throws TransformerException { + if ( ruleInfo.getRule().getProgramStage() == null ) + { + return null; + } + final Map variables = new HashMap<>( scriptVariables ); if ( !addScriptVariables( variables, input ) ) diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/program/FhirToProgramStageTransformer.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/program/FhirToProgramStageTransformer.java index 5ecb19fa..28850c15 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/program/FhirToProgramStageTransformer.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/fhir/impl/program/FhirToProgramStageTransformer.java @@ -188,10 +188,16 @@ public Class getRuleClass() public FhirToDhisTransformOutcome transform( @Nonnull FhirClientResource fhirClientResource, @Nonnull FhirToDhisTransformerContext context, @Nonnull IBaseResource input, @Nonnull RuleInfo ruleInfo, @Nonnull Map scriptVariables ) throws TransformerException { + if ( ruleInfo.getRule().getProgramStage() == null ) + { + return null; + } + if ( !ruleInfo.getRule().getProgramStage().isEnabled() || !ruleInfo.getRule().getProgramStage().getProgram().isEnabled() ) { logger.debug( "Ignoring not enabled program stage \"{}\" of program \"{}\".", ruleInfo.getRule().getProgramStage().getName(), ruleInfo.getRule().getProgramStage().getProgram().getName() ); + return null; } diff --git a/fhir/src/main/resources/db/migration/production/V1.1.0.45_0_0__Care_Resources_Read.sql b/fhir/src/main/resources/db/migration/production/V1.1.0.45_0_0__Care_Resources_Read.sql index e649d714..4c62666f 100644 --- a/fhir/src/main/resources/db/migration/production/V1.1.0.45_0_0__Care_Resources_Read.sql +++ b/fhir/src/main/resources/db/migration/production/V1.1.0.45_0_0__Care_Resources_Read.sql @@ -28,3 +28,5 @@ -- @formatter:off UPDATE fhir_rule SET exp_enabled=TRUE WHERE id='c4e17e7d-880e-45b5-9bc5-568da8c79742'; + +ALTER TABLE fhir_program_stage_rule ALTER COLUMN program_stage_id DROP NOT NULL;