package edu.gatech.i3l.fhir.dstu2.entities; import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.validation.constraints.NotNull; import org.hibernate.envers.Audited; import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt; import ca.uhn.fhir.model.dstu2.composite.CodingDt; import ca.uhn.fhir.model.dstu2.composite.PeriodDt; import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt; import ca.uhn.fhir.model.dstu2.composite.SimpleQuantityDt; import ca.uhn.fhir.model.dstu2.resource.MedicationAdministration; import ca.uhn.fhir.model.dstu2.resource.MedicationAdministration.Dosage; import ca.uhn.fhir.model.dstu2.resource.MedicationDispense; import ca.uhn.fhir.model.dstu2.valueset.MedicationAdministrationStatusEnum; import ca.uhn.fhir.model.primitive.DateTimeDt; import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.InstantDt; import edu.gatech.i3l.fhir.jpa.entity.IResourceEntity; @Entity @Audited @DiscriminatorValue("DrugAdministration") public final class DrugExposureAdministration extends DrugExposure { public static final String RES_TYPE = "MedicationAdministration"; @ManyToOne(cascade={CascadeType.MERGE}) @JoinColumn(name="drug_type_concept_id", nullable=false) @NotNull private Concept drugExposureType; @ManyToOne(fetch=FetchType.LAZY,cascade={CascadeType.MERGE}) @JoinColumn(name="person_id", nullable=false) @NotNull private Person person; @Column(name="drug_exposure_start_date", nullable=false) @NotNull private Date startDate; @Column(name="drug_exposure_end_date", nullable=false) private Date endDate; @Column(name="stop_reason") private String stopReason; @Column(name="quantity") private Double quantity; @Column(name="days_supply") private Integer daysSupply; @ManyToOne(cascade={CascadeType.MERGE}) @JoinColumn(name="drug_concept_id") @NotNull private Concept medication; public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } public String getStopReason() { return stopReason; } public void setStopReason(String stopReason) { this.stopReason = stopReason; } public Double getQuantity() { return quantity; } public void setQuantity(Double quantity) { this.quantity = quantity; } public Integer getDaysSupply() { return daysSupply; } public void setDaysSupply(Integer daysSupply) { this.daysSupply = daysSupply; } public Concept getMedication() { return medication; } public void setMedication(Concept medication) { this.medication = medication; } public Concept getDrugExposureType() { return drugExposureType; } public void setDrugExposureType(Concept drugExposureType) { this.drugExposureType = drugExposureType; } public Date getStartDate() { return startDate; } public void setStartDate(Date startDate) { this.startDate = startDate; } public Date getEndDate() { return endDate; } public void setEndDate(Date endDate) { this.endDate = endDate; } @Override public FhirVersionEnum getFhirVersion() { return FhirVersionEnum.DSTU2; } @Override public String getResourceType() { return RES_TYPE; } @Override public InstantDt getUpdated() { // TODO Auto-generated method stub return null; } @Override public String translateSearchParam(String theSearchParam) { switch (theSearchParam) { case MedicationDispense.SP_PATIENT: return "person"; case MedicationDispense.SP_MEDICATION: return "medication"; default: break; } return theSearchParam; } @Override public IResource getRelatedResource() { MedicationAdministration resource = new MedicationAdministration(); resource.setId(this.getIdDt()); resource.setPatient(new ResourceReferenceDt(new IdDt(Person.RES_TYPE, this.person.getId()))); // Adding medication to Contained. CodingDt medCoding = new CodingDt(this.getMedication().getVocabulary().getSystemUri(), this.getMedication().getConceptCode()); medCoding.setDisplay(this.getMedication().getName()); List<CodingDt> codingList = new ArrayList<CodingDt>(); codingList.add(medCoding); CodeableConceptDt codeDt = new CodeableConceptDt(); codeDt.setCoding(codingList); resource.setMedication(codeDt); // Medication medResource = new Medication(); // // No ID set // medResource.setCode(codeDt); // // // Medication reference. This should point to the contained resource. // ResourceReferenceDt medRefDt = new ResourceReferenceDt(); // medRefDt.setDisplay(this.getMedication().getName()); // // Resource reference set, but no ID // medRefDt.setResource(medResource); // // resource.setMedication(medRefDt); // End of contained medication. Double doseValue = this.getEffectiveDrugDose(); if (doseValue == null || doseValue <= 0.0) { // If effective Drug Dose is not provided, then check if we have quantity. doseValue = this.getQuantity(); } if (doseValue != null && doseValue >= 0.0) { Dosage dosage = new Dosage(); SimpleQuantityDt dose = new SimpleQuantityDt(); dose.setValue(doseValue); Concept myDoseUnitConcept = this.getDoseUnitConcept(); if (myDoseUnitConcept != null) { dose.setUnit(myDoseUnitConcept.getConceptCode()); } dosage.setQuantity(dose); resource.setDosage(dosage); } // DrugExposureComplement f_drug = this.getComplement(); // if (f_drug != null) { // Dosage dosage = new Dosage(); // SimpleQuantityDt dose = new SimpleQuantityDt(); // if (f_drug.getDose() != null && Pattern.matches(StaticVariables.fpRegex, f_drug.getDose())) { // Double doseValue = Double.valueOf(f_drug.getDose()); // Will not throw NumberFormatException // dose.setValue(doseValue); // dose.setUnit(this.getComplement().getUnit()); // dosage.setQuantity(dose); // resource.setDosage(dosage); // } // } // Calendar c = Calendar.getInstance(); // c.setTime(this.startDate); if (this.endDate != null) { // c.setTime(this.endDate); PeriodDt period = new PeriodDt(); // period.setStart(new DateTimeDt(c.getTime())); // period.setEnd(new DateTimeDt(c.getTime())); period.setStart(new DateTimeDt(this.startDate)); period.setEnd(new DateTimeDt(this.endDate)); resource.setEffectiveTime(period); } else { resource.setEffectiveTime(new DateTimeDt(this.startDate)); } // Set the status. First check if we have anything in the stop_reason column if (getStopReason() != null && !getStopReason().isEmpty()) { resource.setStatus(MedicationAdministrationStatusEnum.STOPPED); } else { // We have no stop reason. Check the effective time range. // If today falls within this range, we set status to in-progress. // If future, we set status to on-hold. // If past, we set status to completed. Date now = new Date(); if (this.startDate.getTime() > now.getTime()) { resource.setStatus(MedicationAdministrationStatusEnum.ON_HOLD); } else { if (this.endDate != null) { if (now.getTime() < this.endDate.getTime()) { resource.setStatus(MedicationAdministrationStatusEnum.IN_PROGRESS); } else { resource.setStatus(MedicationAdministrationStatusEnum.COMPLETED); } } else { // Administration should have start and end. But, if stop is null // but start is not null, then we may have this drug still in progress. resource.setStatus(MedicationAdministrationStatusEnum.IN_PROGRESS); } } } return resource; } @Override public IResourceEntity constructEntityFromResource(IResource resource) { // TODO Auto-generated method stub return null; } }