Skip to content

Commit

Permalink
add location stock resource type (#129)
Browse files Browse the repository at this point in the history
* add locatio stock resource type

* add test for PhysicalLocationAndStocks

* update snapshot version

* add properties file and updated tests
  • Loading branch information
bennsimon committed Jun 24, 2021
1 parent 55d893d commit 2b3f89e
Show file tree
Hide file tree
Showing 11 changed files with 275 additions and 63 deletions.
2 changes: 2 additions & 0 deletions application.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fhir.server=https://fhir.smartregister.org
hl7.terminology.url=http://terminology.hl7.org
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<artifactId>opensrp-plan-evaluator</artifactId>
<packaging>jar</packaging>
<version>1.5.1-SNAPSHOT</version>
<version>1.6.0-SNAPSHOT</version>
<name>OpenSRP Plan Evaluator</name>
<description>OpenSRP Plan Evaluator Library</description>
<url>https://github.com/OpenSRP/opensrp-plan-evaluator</url>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.smartregister.converters;

import com.ibm.fhir.model.resource.Bundle;
import com.ibm.fhir.model.resource.Location;
import com.ibm.fhir.model.type.code.BundleType;
import org.smartregister.domain.PhysicalLocationAndStocks;
import org.smartregister.domain.Stock;
import org.smartregister.domain.StockAndProductDetails;

import java.util.ArrayList;
import java.util.List;

public class PhysicalLocationAndStocksConverter {

public static Bundle convertLocationAndStocksToBundleResource(PhysicalLocationAndStocks physicalLocationAndStocks) {
Location location = LocationConverter.convertPhysicalLocationToLocationResource(physicalLocationAndStocks);
Bundle.Builder bundleBuilder = Bundle.builder();
bundleBuilder.id(physicalLocationAndStocks.getId());

List<Bundle.Entry> entries = new ArrayList<>();
entries.add(Bundle.Entry.builder().resource(location).build());
for (Stock stock : physicalLocationAndStocks.getStocks()) {
Bundle.Entry entry = StockConverter
.createBundleEntryFromStockAndProduct(new StockAndProductDetails(stock, null));
entries.add(entry);
}
bundleBuilder.entry(entries);

return bundleBuilder.type(BundleType.COLLECTION).build();
}

}
165 changes: 107 additions & 58 deletions src/main/java/org/smartregister/converters/StockConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,70 @@
import com.ibm.fhir.model.resource.Bundle;
import com.ibm.fhir.model.resource.Device;
import com.ibm.fhir.model.resource.SupplyDelivery;
import com.ibm.fhir.model.type.*;
import com.ibm.fhir.model.type.Code;
import com.ibm.fhir.model.type.CodeableConcept;
import com.ibm.fhir.model.type.Coding;
import com.ibm.fhir.model.type.DateTime;
import com.ibm.fhir.model.type.Decimal;
import com.ibm.fhir.model.type.Element;
import com.ibm.fhir.model.type.Identifier;
import com.ibm.fhir.model.type.Reference;
import com.ibm.fhir.model.type.SimpleQuantity;
import com.ibm.fhir.model.type.String;
import com.ibm.fhir.model.type.Uri;
import com.ibm.fhir.model.type.code.BundleType;
import com.ibm.fhir.model.type.code.FHIRDeviceStatus;
import com.ibm.fhir.model.type.code.SupplyDeliveryStatus;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.format.ISODateTimeFormat;
import org.smartregister.domain.StockAndProductDetails;
import org.smartregister.utils.ApplicationConstants;
import org.smartregister.utils.ApplicationProperties;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class StockConverter {

private static final java.lang.String PO_NUMBER = "PO Number";

private static final java.lang.String DEVICE = "device";

private static final java.lang.String UNICEF_SECTION = "UNICEF section";

private static final java.lang.String SUPPLY_DELIVERY = "supplyDelivery";

private static final java.lang.String CODE_SYSTEM = "CodeSystem";

private static final java.lang.String SUPPLY_ITEM_TYPE = "supply-item-type";

private static final java.lang.String ORGANIZATION = "Organization";

private static final java.lang.String LOCATION = "Location";

public static Bundle convertStockToBundleResource(StockAndProductDetails stockAndProductDetails) {

Bundle.Builder bundleBuilder = Bundle.builder();

Code deviceItemCode;
Coding deviceItemCoding;
Element deviceItemElement = null;
Identifier poNumberIdentifier = null;
Reference supplier = null;
java.lang.String deliveryDateInString;
Element occurrenceDateTime;

Device.Builder deviceBuilder = Device.builder();
if (stockAndProductDetails != null && stockAndProductDetails.getStock() != null) {
deviceBuilder.id(stockAndProductDetails.getStock().getId());
}

java.lang.String unicefSection = stockAndProductDetails.getStock() != null
&& stockAndProductDetails.getStock().getCustomProperties() != null ?
stockAndProductDetails.getStock().getCustomProperties().get("UNICEF section") : "";
stockAndProductDetails.getStock().getCustomProperties().get(UNICEF_SECTION) : "";

java.lang.String locationId = stockAndProductDetails != null && stockAndProductDetails.getStock() != null &&
stockAndProductDetails.getStock().getLocationId() != null ?
stockAndProductDetails.getStock().getLocationId() :
"";

Reference owner = Reference.builder().reference(String.of("Organization/" + unicefSection)).build();
Reference location = Reference.builder().reference(String.of("Location/" + locationId)).build();
Reference owner = Reference.builder().reference(String.of(
java.lang.String.format("%s/%s", ORGANIZATION, unicefSection))).build();
Reference location = Reference.builder().reference(String.of(
java.lang.String.format("%s/%s", LOCATION, locationId))).build();

String serialNumber = stockAndProductDetails != null && stockAndProductDetails.getStock() != null &&
StringUtils.isNotBlank(stockAndProductDetails.getStock().getSerialNumber()) ?
Expand All @@ -54,46 +75,59 @@ public static Bundle convertStockToBundleResource(StockAndProductDetails stockAn
deviceBuilder.owner(owner).location(location).serialNumber(serialNumber)
.status(fhirDeviceStatus);

SupplyDelivery.Builder supplyDeliveryBuilder = SupplyDelivery.builder();
Decimal decimal = Decimal.builder().value(java.lang.String.valueOf(stockAndProductDetails.getStock().getValue()))
.build();
SimpleQuantity simpleQuantity = SimpleQuantity.builder().value(decimal).build();
List<Bundle.Entry> entryList = new ArrayList<>();
java.lang.String productId =
stockAndProductDetails != null && stockAndProductDetails.getProductCatalogue() != null &&
stockAndProductDetails.getProductCatalogue().getUniqueId() != null ?
java.lang.String.valueOf(stockAndProductDetails.getProductCatalogue().getUniqueId()) : "";

if (stockAndProductDetails != null && stockAndProductDetails.getProductCatalogue() != null &&
stockAndProductDetails.getProductCatalogue().getProductName() != null) {
deviceItemCode = Code.builder().value(stockAndProductDetails.getProductCatalogue().getProductName())
.build();
deviceItemCoding = Coding.builder().code(deviceItemCode)
.display(String.of(stockAndProductDetails.getProductCatalogue().getProductName())).build();
deviceItemElement = CodeableConcept.builder().coding(deviceItemCoding).build();
java.lang.String deviceUriString = java.lang.String.format("%s/%s/%s",
ApplicationProperties.getInstance().getProperty(ApplicationConstants.PropertiesConstants.FHIR_SERVER_URL),
DEVICE, productId);
Uri deviceUri = Uri.builder().value(deviceUriString).build();
Bundle.Entry deviceEntry = Bundle.Entry.builder().fullUrl(deviceUri).resource(deviceBuilder.build()).build();
entryList.add(deviceEntry);
entryList.add(createBundleEntryFromStockAndProduct(stockAndProductDetails));
if (stockAndProductDetails != null && stockAndProductDetails.getStock() != null) {
bundleBuilder.id(stockAndProductDetails.getStock().getId());
}
SupplyDelivery.SuppliedItem suppliedItem = SupplyDelivery.SuppliedItem.builder().quantity(simpleQuantity)
.item(deviceItemElement).build();

java.lang.String poNumber = stockAndProductDetails.getStock() != null
&& stockAndProductDetails.getStock().getCustomProperties() != null ?
stockAndProductDetails.getStock().getCustomProperties().get("PO Number") : "";
return bundleBuilder.type(BundleType.COLLECTION).entry(entryList).build();
}

String poNumberString = poNumber != null ? String.of(poNumber) : null;
if (poNumberString != null) {
poNumberIdentifier = Identifier.builder().value(poNumberString).build();
}
public static Bundle.Entry createBundleEntryFromStockAndProduct(StockAndProductDetails stockAndProductDetails) {
Identifier poNumberIdentifier = null;
Reference supplier = null;
Element deviceItemElement = null;
java.lang.String deliveryDateInString;
Element occurrenceDateTime;

Code deviceItemCode;
Coding deviceItemCoding;
Uri system = Uri.builder().value(java.lang.String.format("%s/%s/%s", ApplicationProperties.getInstance().getProperty(
ApplicationConstants.PropertiesConstants.HL7_TERMINOLOGY_URL), CODE_SYSTEM, SUPPLY_ITEM_TYPE)).build();
Code deviceCode = Code.builder().value(DEVICE).build();
Coding coding = Coding.builder().code(deviceCode).system(system).build();
CodeableConcept typeCodeableConcept = CodeableConcept.builder().coding(coding).build();
SupplyDelivery.Builder supplyDeliveryBuilder = SupplyDelivery.builder();
Decimal decimal = Decimal.builder().value(java.lang.String.valueOf(
stockAndProductDetails != null && stockAndProductDetails.getStock() != null ?
stockAndProductDetails.getStock().getValue() :
"0.0"))
.build();

java.lang.String donor = stockAndProductDetails != null && stockAndProductDetails.getStock() != null &&
stockAndProductDetails.getStock().getDonor() != null ?
"Organization/" + stockAndProductDetails.getStock().getDonor() :
java.lang.String.format("%s/%s", ORGANIZATION, stockAndProductDetails.getStock().getDonor()) :
null;

String donorString = donor != null ? String.of(donor) : null;

if (donorString != null) {
supplier = Reference.builder().reference(donorString)
.display(donorString).build();
}

Code deviceCode = Code.builder().value("device").build();
Uri system = Uri.builder().value("http://terminology.hl7.org/CodeSystem/supply-item-type").build();
Coding coding = Coding.builder().code(deviceCode).system(system).build();
CodeableConcept typeCodeableConcept = CodeableConcept.builder().coding(coding).build();

Date deliveryDate = stockAndProductDetails != null && stockAndProductDetails.getStock() != null
&& stockAndProductDetails.getStock().getDeliveryDate() != null ?
stockAndProductDetails.getStock().getDeliveryDate() :
Expand All @@ -102,36 +136,51 @@ public static Bundle convertStockToBundleResource(StockAndProductDetails stockAn
deliveryDateInString = deliveryDate != null ? ISODateTimeFormat.date().print(deliveryDate.getTime()) : null;
occurrenceDateTime = deliveryDateInString != null ? DateTime.builder().value(deliveryDateInString).build() : null;

if (stockAndProductDetails != null && stockAndProductDetails.getProductCatalogue() != null &&
stockAndProductDetails.getProductCatalogue().getProductName() != null) {
deviceItemCode = Code.builder().value(stockAndProductDetails.getProductCatalogue().getProductName())
.build();
deviceItemCoding = Coding.builder().code(deviceItemCode)
.display(String.of(stockAndProductDetails.getProductCatalogue().getProductName())).build();
deviceItemElement = CodeableConcept.builder().coding(deviceItemCoding).build();
}

SimpleQuantity simpleQuantity = SimpleQuantity.builder().value(decimal).build();

SupplyDelivery.SuppliedItem suppliedItem = SupplyDelivery.SuppliedItem.builder().quantity(simpleQuantity)
.item(deviceItemElement).build();

java.lang.String poNumber = stockAndProductDetails.getStock() != null
&& stockAndProductDetails.getStock().getCustomProperties() != null ?
stockAndProductDetails.getStock().getCustomProperties().get(PO_NUMBER) : "";

String poNumberString = poNumber != null ? String.of(poNumber) : null;

if (poNumberString != null) {
poNumberIdentifier = Identifier.builder().value(poNumberString).build();
}

if (poNumberIdentifier != null) {
supplyDeliveryBuilder.identifier(poNumberIdentifier);
}
supplyDeliveryBuilder.suppliedItem(suppliedItem).status(SupplyDeliveryStatus.COMPLETED)
.supplier(supplier).type(typeCodeableConcept).occurrence(occurrenceDateTime).build();

List<Bundle.Entry> entryList = new ArrayList<>();
java.lang.String productId =
stockAndProductDetails != null && stockAndProductDetails.getProductCatalogue() != null &&
stockAndProductDetails.getProductCatalogue().getUniqueId() != null ?
java.lang.String.valueOf(stockAndProductDetails.getProductCatalogue().getUniqueId()) : "";

java.lang.String deviceUriString = "https://fhir.smartregister.org/device/" + productId;
Uri deviceUri = Uri.builder().value(deviceUriString).build();
Bundle.Entry deviceEntry = Bundle.Entry.builder().fullUrl(deviceUri).resource(deviceBuilder.build()).build();
java.lang.String stockId = stockAndProductDetails != null && stockAndProductDetails.getStock() != null &&
stockAndProductDetails.getStock().getId() != null ?
java.lang.String.valueOf(stockAndProductDetails.getStock().getId()) :
"";
java.lang.String supplyDeliveryUriString = "https://fhir.smartregister.org/supplyDelivery/" + stockId;

SupplyDelivery supplyDelivery = supplyDeliveryBuilder.id(stockId).suppliedItem(suppliedItem)
.status(SupplyDeliveryStatus.COMPLETED)
.supplier(supplier).type(typeCodeableConcept).occurrence(occurrenceDateTime).build();

java.lang.String supplyDeliveryUriString = java.lang.String.format("%s/%s/%s",
ApplicationProperties.getInstance().getProperty(ApplicationConstants.PropertiesConstants.FHIR_SERVER_URL),
SUPPLY_DELIVERY, stockId);

Uri supplyDeliveryUri = Uri.builder().value(supplyDeliveryUriString).build();
Bundle.Entry supplyDeliveryEntry = Bundle.Entry.builder().fullUrl(supplyDeliveryUri)
.resource(supplyDeliveryBuilder.build()).build();
entryList.add(deviceEntry);
entryList.add(supplyDeliveryEntry);
if (stockAndProductDetails != null && stockAndProductDetails.getStock() != null) {
bundleBuilder.id(stockAndProductDetails.getStock().getId());
}

return bundleBuilder.type(BundleType.COLLECTION).entry(entryList).build();
return Bundle.Entry.builder().fullUrl(supplyDeliveryUri)
.resource(supplyDelivery).build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.smartregister.domain;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.List;

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class PhysicalLocationAndStocks extends PhysicalLocation {

private static final long serialVersionUID = 1L;

private List<Stock> stocks;

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
*
*
*/
package org.smartregister.pathevaluator;

Expand All @@ -9,7 +9,7 @@
* @author Samuel Githengi created on 06/15/20
*/
public enum ResourceType {

JURISDICTION("Jurisdiction"),
LOCATION("Location"),
FAMILY("Family"),
Expand All @@ -18,7 +18,8 @@ public enum ResourceType {
QUESTIONAIRRE_RESPONSE("QuestionnaireResponse"),
GLOBAL_TASK("Global.Task"),
JURISDICTIONAL_TASK("Jurisdictional.Task"),
DEVICE("Device");
DEVICE("Device"),
LOCATION_STOCK("Location.Stock");

private String value;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ public List<? extends Resource> getSubjectResources(Action action, Jurisdiction
case QUESTIONAIRRE_RESPONSE:
return eventDao.findEventsByJurisdictionIdAndPlan(jurisdiction.getCode(), planIdentifier);

case LOCATION_STOCK:
return locationDao.findLocationAndStocksByJurisdiction(jurisdiction.getCode());

default:
logger.log(Level.WARNING,"unmapped resource type "+resourceType);
return Collections.emptyList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import java.util.List;

import com.ibm.fhir.model.resource.Bundle;
import com.ibm.fhir.model.resource.Location;

/**
Expand Down Expand Up @@ -37,5 +38,11 @@ public interface LocationDao {
List<Location> findLocationByJurisdiction(String jurisdiction);

List<String> findChildLocationByJurisdiction(String id);


/**
* Gets the locations/structures with its stock in a particular jurisdiction
* @param jurisdiction the jurisdiction Id
* @return a Bundle
*/
List<Bundle> findLocationAndStocksByJurisdiction(String jurisdiction);
}
11 changes: 11 additions & 0 deletions src/main/java/org/smartregister/utils/ApplicationConstants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.smartregister.utils;

public interface ApplicationConstants {

interface PropertiesConstants {

String FHIR_SERVER_URL = "fhir.server";
String HL7_TERMINOLOGY_URL = "hl7.terminology.url";
}

}
Loading

0 comments on commit 2b3f89e

Please sign in to comment.