Skip to content

Commit

Permalink
Implemented read access to care plan.
Browse files Browse the repository at this point in the history
Test are missing and will be added later.
  • Loading branch information
volsch committed Aug 18, 2019
1 parent df95c8d commit b05c0eb
Show file tree
Hide file tree
Showing 36 changed files with 1,747 additions and 219 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,12 @@ public Optional<T> findMetadataRefreshedByReference( @Nonnull Reference referenc
@HystrixCommand( ignoreExceptions = UnauthorizedException.class )
@Nonnull
@Override
@CachePut( cacheResolver = "dhisMetadataCacheResolver", unless = "#result==null" )
public Optional<T> findOneByReference( @Nonnull Reference reference )
{
return findOneByReference( userRestTemplate, reference );
}

@HystrixCommand( ignoreExceptions = UnauthorizedException.class )
@HystrixCommand( ignoreExceptions = { UnauthorizedException.class, DhisFindException.class } )
@Nonnull
@Override
public DhisResourceResult<T> find( @Nonnull UriFilterApplier uriFilterApplier, int from, int max )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import org.dhis2.fhir.adapter.dhis.model.DhisResourceResult;
import org.dhis2.fhir.adapter.dhis.model.UriFilterApplier;
import org.dhis2.fhir.adapter.dhis.service.DhisService;

import javax.annotation.Nonnull;
Expand Down Expand Up @@ -55,4 +57,7 @@ public interface EnrollmentService extends DhisService<Enrollment>
Enrollment createOrUpdate( @Nonnull Enrollment enrollment );

boolean delete( @Nonnull String enrollmentId );

@Nonnull
DhisResourceResult<Enrollment> find( @Nonnull UriFilterApplier uriFilterApplier, int from, int max );
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,29 @@
import org.dhis2.fhir.adapter.auth.UnauthorizedException;
import org.dhis2.fhir.adapter.cache.RequestCacheService;
import org.dhis2.fhir.adapter.dhis.DhisConflictException;
import org.dhis2.fhir.adapter.dhis.DhisFindException;
import org.dhis2.fhir.adapter.dhis.DhisImportUnsuccessfulException;
import org.dhis2.fhir.adapter.dhis.local.LocalDhisRepositoryPersistCallback;
import org.dhis2.fhir.adapter.dhis.local.LocalDhisRepositoryPersistResult;
import org.dhis2.fhir.adapter.dhis.local.LocalDhisRepositoryPersistStatus;
import org.dhis2.fhir.adapter.dhis.local.LocalDhisResourceRepositoryTemplate;
import org.dhis2.fhir.adapter.dhis.model.DhisResourceComparator;
import org.dhis2.fhir.adapter.dhis.model.DhisResourceResult;
import org.dhis2.fhir.adapter.dhis.model.DhisResourceType;
import org.dhis2.fhir.adapter.dhis.model.ImportStatus;
import org.dhis2.fhir.adapter.dhis.model.ImportSummaries;
import org.dhis2.fhir.adapter.dhis.model.ImportSummariesWebMessage;
import org.dhis2.fhir.adapter.dhis.model.ImportSummary;
import org.dhis2.fhir.adapter.dhis.model.Status;
import org.dhis2.fhir.adapter.dhis.model.UriFilterApplier;
import org.dhis2.fhir.adapter.dhis.tracker.program.Enrollment;
import org.dhis2.fhir.adapter.dhis.tracker.program.EnrollmentService;
import org.dhis2.fhir.adapter.dhis.tracker.program.EnrollmentStatus;
import org.dhis2.fhir.adapter.dhis.tracker.program.Event;
import org.dhis2.fhir.adapter.dhis.tracker.program.EventService;
import org.dhis2.fhir.adapter.dhis.util.CodeGenerator;
import org.dhis2.fhir.adapter.dhis.util.DhisPagingQuery;
import org.dhis2.fhir.adapter.dhis.util.DhisPagingUtils;
import org.dhis2.fhir.adapter.rest.RestTemplateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
Expand All @@ -64,9 +69,11 @@
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
Expand Down Expand Up @@ -125,6 +132,37 @@ public DhisResourceType getDhisResourceType()
return DhisResourceType.ENROLLMENT;
}

@HystrixCommand( ignoreExceptions = { UnauthorizedException.class, DhisFindException.class } )
@Nonnull
@Override
public DhisResourceResult<Enrollment> find( @Nonnull UriFilterApplier uriFilterApplier, int from, int max )
{
final DhisPagingQuery pagingQuery = DhisPagingUtils.createPagingQuery( from, max );
final List<String> variables = new ArrayList<>();
final String uri = uriFilterApplier.add( UriComponentsBuilder.newInstance(), variables ).path( "/enrollments.json" )
.queryParam( "skipPaging", "false" ).queryParam( "page", pagingQuery.getPage() ).queryParam( "pageSize", pagingQuery.getPageSize() )
.queryParam( "ouMode", uriFilterApplier.containsQueryParam( "ou" ) ? "SELECTED" : "ACCESSIBLE" )
.queryParam( "fields", ":all" ).build().toString();
final ResponseEntity<DhisEnrollments> result;
try
{
result = restTemplate.getForEntity( uri, DhisEnrollments.class, variables.toArray() );
}
catch ( HttpClientErrorException e )
{
if ( e.getStatusCode() == HttpStatus.BAD_REQUEST || e.getStatusCode() == HttpStatus.CONFLICT )
{
throw new DhisFindException( e.getMessage(), e );
}
throw e;
}
final DhisEnrollments enrollments = Objects.requireNonNull( result.getBody() );

return new DhisResourceResult<>( ( enrollments.getEnrollments().size() > pagingQuery.getResultOffset() ) ?
enrollments.getEnrollments().subList( pagingQuery.getResultOffset(), enrollments.getEnrollments().size() ) : Collections.emptyList(),
( enrollments.getEnrollments().size() >= pagingQuery.getPageSize() ) );
}

@HystrixCommand( ignoreExceptions = UnauthorizedException.class )
@Nonnull
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ protected Event update( @Nonnull Event event )
return event;
}

@HystrixCommand( ignoreExceptions = UnauthorizedException.class )
@HystrixCommand( ignoreExceptions = { UnauthorizedException.class, DhisFindException.class } )
@Nonnull
@Override
public DhisResourceResult<Event> find( @Nonnull String programId, @Nonnull String programStageId, @Nonnull UriFilterApplier uriFilterApplier, int from, int max )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ public boolean persistDeleteById( @Nonnull String id )
return _delete( id );
}

@HystrixCommand( ignoreExceptions = UnauthorizedException.class )
@HystrixCommand( ignoreExceptions = { UnauthorizedException.class, DhisFindException.class } )
@Nonnull
@Override
public DhisResourceResult<TrackedEntityInstance> find( @Nonnull String trackedEntityTypeId, @Nonnull UriFilterApplier uriFilterApplier, int from, int max )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
<label value="Incident date" />
<short value="Incident date of enrollment" />
<definition value="The incident date of the enrollment." />
<max value="1" />
<type>
<code value="Extension" />
<profile value="http://www.dhis2.org/dhis2-fhir-adapter/extensions/incident-date" />
Expand Down Expand Up @@ -145,8 +146,8 @@
</element>
<element id="CarePlan.status">
<path value="CarePlan.status" />
<short value="active | completed | cancelled" />
<definition value="active | completed | cancelled" />
<short value="active | completed | revoked" />
<definition value="active | completed | revoked (cancelled)" />
</element>
<element id="CarePlan.intent">
<path value="CarePlan.intent" />
Expand Down Expand Up @@ -227,6 +228,10 @@
<path value="CarePlan.goal" />
<max value="0" />
</element>
<element id="CarePlan.activity">
<path value="CarePlan.activity" />
<max value="0" />
</element>
<element id="CarePlan.activity.outcomeCodeableConcept">
<path value="CarePlan.activity.outcomeCodeableConcept" />
<max value="0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ protected Object convert( @Nullable IBaseDatatype fhirValue, @Nonnull ValueType
case INTEGER_POSITIVE:
case INTEGER_NEGATIVE:
case INTEGER_ZERO_OR_POSITIVE:
if ( fhirValue.isEmpty() )
{
return null;
}

if ( fhirValue instanceof IPrimitiveType && ( (IPrimitiveType) fhirValue ).getValue() instanceof Integer )
{
return ( (IPrimitiveType) fhirValue ).getValueAsString();
Expand All @@ -118,6 +123,11 @@ protected Object convert( @Nullable IBaseDatatype fhirValue, @Nonnull ValueType
case NUMBER:
case PERCENTAGE:
case UNIT_INTERVAL:
if ( fhirValue.isEmpty() )
{
return null;
}

if ( fhirValue instanceof IPrimitiveType && ( (IPrimitiveType) fhirValue ).getValue() instanceof Number )
{
return ( (IPrimitiveType) fhirValue ).getValueAsString();
Expand All @@ -127,6 +137,11 @@ protected Object convert( @Nullable IBaseDatatype fhirValue, @Nonnull ValueType
case DATETIME:
case DATE:
case AGE:
if ( fhirValue.isEmpty() )
{
return null;
}

if ( fhirValue instanceof DateTimeType )
{
return DateTimeFormatter.ISO_LOCAL_DATE_TIME
Expand All @@ -143,6 +158,11 @@ protected Object convert( @Nullable IBaseDatatype fhirValue, @Nonnull ValueType
break;
case BOOLEAN:
case TRUE_ONLY:
if ( fhirValue.isEmpty() )
{
return null;
}

if ( fhirValue instanceof IPrimitiveType && ( (IPrimitiveType) fhirValue ).getValue() instanceof Boolean )
{
return ( (IPrimitiveType) fhirValue ).getValueAsString();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package org.dhis2.fhir.adapter.fhir.transform.dhis.impl.enrollment.r4;

/*
* Copyright (c) 2004-2019, University of Oslo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither the name of the HISP project nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import org.dhis2.fhir.adapter.dhis.tracker.program.Enrollment;
import org.dhis2.fhir.adapter.dhis.tracker.program.EnrollmentStatus;
import org.dhis2.fhir.adapter.dhis.tracker.program.ProgramMetadataService;
import org.dhis2.fhir.adapter.dhis.tracker.trackedentity.TrackedEntityMetadataService;
import org.dhis2.fhir.adapter.fhir.data.repository.FhirDhisAssignmentRepository;
import org.dhis2.fhir.adapter.fhir.extension.IncidentDateExtensionUtils;
import org.dhis2.fhir.adapter.fhir.extension.LocationExtensionUtils;
import org.dhis2.fhir.adapter.fhir.metadata.model.EnrollmentRule;
import org.dhis2.fhir.adapter.fhir.metadata.model.FhirClient;
import org.dhis2.fhir.adapter.fhir.metadata.model.FhirResourceType;
import org.dhis2.fhir.adapter.fhir.metadata.model.RuleInfo;
import org.dhis2.fhir.adapter.fhir.metadata.repository.FhirResourceMappingRepository;
import org.dhis2.fhir.adapter.fhir.metadata.repository.SystemRepository;
import org.dhis2.fhir.adapter.fhir.metadata.repository.TrackedEntityRuleRepository;
import org.dhis2.fhir.adapter.fhir.model.FhirVersion;
import org.dhis2.fhir.adapter.fhir.repository.FhirResourceRepository;
import org.dhis2.fhir.adapter.fhir.script.ScriptExecutor;
import org.dhis2.fhir.adapter.fhir.transform.dhis.DhisToFhirTransformerContext;
import org.dhis2.fhir.adapter.fhir.transform.dhis.impl.enrollment.AbstractEnrollmentToCarePlanFhirTransformer;
import org.dhis2.fhir.adapter.fhir.transform.scripted.ScriptedEnrollment;
import org.dhis2.fhir.adapter.lock.LockManager;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.CanonicalType;
import org.hl7.fhir.r4.model.CarePlan;
import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.ResourceFactory;
import org.hl7.fhir.r4.model.UriType;
import org.springframework.stereotype.Component;

import javax.annotation.Nonnull;
import java.sql.Date;
import java.util.Collections;
import java.util.Map;
import java.util.Set;

/**
* R4 specific implementation of {@link AbstractEnrollmentToCarePlanFhirTransformer}.
*
* @author volsch
*/
@Component
public class R4EnrollmentToCarePlanFhirTransformer extends AbstractEnrollmentToCarePlanFhirTransformer
{
public R4EnrollmentToCarePlanFhirTransformer( @Nonnull ScriptExecutor scriptExecutor, @Nonnull LockManager lockManager, @Nonnull SystemRepository systemRepository, @Nonnull FhirResourceRepository fhirResourceRepository,
@Nonnull FhirResourceMappingRepository resourceMappingRepository, @Nonnull FhirDhisAssignmentRepository fhirDhisAssignmentRepository, @Nonnull TrackedEntityMetadataService trackedEntityMetadataService,
@Nonnull TrackedEntityRuleRepository trackedEntityRuleRepository, @Nonnull ProgramMetadataService programMetadataService )
{
super( scriptExecutor, lockManager, systemRepository, fhirResourceRepository, resourceMappingRepository, fhirDhisAssignmentRepository, trackedEntityMetadataService, trackedEntityRuleRepository, programMetadataService );
}

@Nonnull
@Override
public Set<FhirVersion> getFhirVersions()
{
return FhirVersion.R4_ONLY;
}

@Override
protected boolean transformInternal( @Nonnull FhirClient fhirClient, @Nonnull DhisToFhirTransformerContext context, @Nonnull RuleInfo<EnrollmentRule> ruleInfo, @Nonnull Map<String, Object> scriptVariables,
@Nonnull ScriptedEnrollment input, @Nonnull IBaseResource output, @Nonnull IBaseResource trackedEntityResource )
{
final Enrollment enrollment = (Enrollment) input.getDhisResource();
final CarePlan fhirCarePlan = (CarePlan) output;
final String planDefinitionUri = FhirResourceType.PLAN_DEFINITION.withId( enrollment.getProgramId() );

fhirCarePlan.setInstantiatesUri( Collections.singletonList( new UriType( planDefinitionUri ) ) );
fhirCarePlan.setInstantiatesCanonical( Collections.singletonList( new CanonicalType( planDefinitionUri ) ) );

fhirCarePlan.setIntent( CarePlan.CarePlanIntent.PLAN );
fhirCarePlan.setStatus( convertStatus( enrollment.getStatus() ) );

LocationExtensionUtils.setValue( fhirCarePlan,
new Reference( FhirResourceType.LOCATION.withId( enrollment.getOrgUnitId() ) ) );
fhirCarePlan.setSubject( new Reference( trackedEntityResource.getIdElement() ) );

fhirCarePlan.setPeriod( null );
fhirCarePlan.getPeriod().setStart( Date.from( enrollment.getEnrollmentDate().toInstant() ) );
IncidentDateExtensionUtils.setValue( fhirCarePlan, enrollment.getIncidentDate() == null ? null :
Date.from( enrollment.getIncidentDate().toInstant() ), ResourceFactory::createType );

return true;
}

@Nonnull
protected CarePlan.CarePlanStatus convertStatus( @Nonnull EnrollmentStatus enrollmentStatus )
{
switch ( enrollmentStatus )
{
case ACTIVE:
return CarePlan.CarePlanStatus.ACTIVE;
case COMPLETED:
return CarePlan.CarePlanStatus.COMPLETED;
case CANCELLED:
return CarePlan.CarePlanStatus.REVOKED;
default:
throw new AssertionError( "Invalid enrollment status: " + enrollmentStatus );
}
}
}
Loading

0 comments on commit b05c0eb

Please sign in to comment.