aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/xyz/driver/pdsuidomain/entities
diff options
context:
space:
mode:
authorvlad <vlad@driver.xyz>2017-06-30 19:38:37 -0700
committervlad <vlad@driver.xyz>2017-06-30 19:38:37 -0700
commit96d81a36286e41035ff4068859a3b0f9da924fbc (patch)
tree8d9f0014140d1f07ca449b56adaba8ccb3d2fc59 /src/main/scala/xyz/driver/pdsuidomain/entities
parenta997aa6539d1f0af4ab4fc395ff2033335da312a (diff)
downloadrest-query-96d81a36286e41035ff4068859a3b0f9da924fbc.tar.gz
rest-query-96d81a36286e41035ff4068859a3b0f9da924fbc.tar.bz2
rest-query-96d81a36286e41035ff4068859a3b0f9da924fbc.zip
Latest PDS UI utils including all the domain stuffv0.1.12
Diffstat (limited to 'src/main/scala/xyz/driver/pdsuidomain/entities')
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/Document.scala167
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/ExtractedData.scala1
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/Intervention.scala1
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/LinkedPatient.scala16
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/MedicalRecord.scala4
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/Patient.scala3
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/PatientEligibleTrial.scala39
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/PatientLabelEvidenceView.scala28
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/RawTrialLabel.scala3
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/Trial.scala5
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/UserHistory.scala156
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/export/patient/ExportPatientLabel.scala30
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/export/patient/ExportPatientLabelEvidence.scala32
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/export/patient/ExportPatientLabelEvidenceDocument.scala30
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/export/patient/ExportPatientWithLabels.scala26
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrial.scala27
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialArm.scala15
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialLabelCriterion.scala32
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialWithLabels.scala52
19 files changed, 627 insertions, 40 deletions
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/Document.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/Document.scala
index 5af00bc..5c957fb 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/entities/Document.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/Document.scala
@@ -1,6 +1,6 @@
package xyz.driver.pdsuidomain.entities
-import java.time.{LocalDate, LocalDateTime}
+import java.time.{LocalDate, LocalDateTime, ZoneId}
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
import com.fasterxml.jackson.core.{JsonGenerator, JsonParser}
@@ -17,6 +17,72 @@ import xyz.driver.pdsuicommon.compat.Implicits._
final case class ProviderType(id: LongId[ProviderType], name: String)
object ProviderType {
+ sealed trait ProviderTypeName
+ case object MedicalOncology extends ProviderTypeName
+ case object Surgery extends ProviderTypeName
+ case object Pathology extends ProviderTypeName
+ case object MolecularPathology extends ProviderTypeName
+ case object LaboratoryMedicine extends ProviderTypeName
+ case object Radiology extends ProviderTypeName
+ case object InterventionalRadiology extends ProviderTypeName
+ case object RadiationOncology extends ProviderTypeName
+ case object PrimaryCare extends ProviderTypeName
+ case object Cardiology extends ProviderTypeName
+ case object Dermatology extends ProviderTypeName
+ case object Ophthalmology extends ProviderTypeName
+ case object Gastroenterology extends ProviderTypeName
+ case object Neurology extends ProviderTypeName
+ case object Psychiatry extends ProviderTypeName
+ case object Gynecology extends ProviderTypeName
+ case object InfectiousDisease extends ProviderTypeName
+ case object Immunology extends ProviderTypeName
+ case object Nephrology extends ProviderTypeName
+ case object Rheumatology extends ProviderTypeName
+ case object Cytology extends ProviderTypeName
+ case object Otolaryngology extends ProviderTypeName
+ case object Anesthesiology extends ProviderTypeName
+ case object Urology extends ProviderTypeName
+ case object PalliativeCare extends ProviderTypeName
+ case object EmergencyMedicine extends ProviderTypeName
+ case object SocialWork extends ProviderTypeName
+ case object NA extends ProviderTypeName
+ case object Other extends ProviderTypeName
+
+ def fromString(txt: String): Option[ProviderTypeName] = {
+ txt match {
+ case "Medical Oncology" => Some(MedicalOncology)
+ case "Surgery" => Some(Surgery)
+ case "Pathology" => Some(Pathology)
+ case "Molecular Pathology" => Some(MolecularPathology)
+ case "LaboratoryMedicine" => Some(LaboratoryMedicine)
+ case "Radiology" => Some(Radiology)
+ case "Interventional Radiology" => Some(InterventionalRadiology)
+ case "Radiation Oncology" => Some(RadiationOncology)
+ case "Primary Care" => Some(PrimaryCare)
+ case "Cardiology" => Some(Cardiology)
+ case "Dermatology" => Some(Dermatology)
+ case "Ophthalmology" => Some(Ophthalmology)
+ case "Gastroenterology" => Some(Gastroenterology)
+ case "Neurology" => Some(Neurology)
+ case "Psychiatry" => Some(Psychiatry)
+ case "Gynecology" => Some(Gynecology)
+ case "Infectious Disease" => Some(InfectiousDisease)
+ case "Immunology" => Some(Immunology)
+ case "Nephrology" => Some(Nephrology)
+ case "Rheumatology" => Some(Rheumatology)
+ case "Cytology" => Some(Cytology)
+ case "Otolaryngology" => Some(Otolaryngology)
+ case "Anesthesiology" => Some(Anesthesiology)
+ case "Urology" => Some(Urology)
+ case "Palliative Care" => Some(PalliativeCare)
+ case "Emergency Medicine" => Some(EmergencyMedicine)
+ case "Social Work" => Some(SocialWork)
+ case "N/A" => Some(NA)
+ case "Other" => Some(Other)
+ case _ => None
+ }
+ }
+
implicit def toPhiString(x: ProviderType): PhiString = {
import x._
phi"ProviderType(id=$id, category=${Unsafe(name)})"
@@ -26,6 +92,38 @@ object ProviderType {
final case class DocumentType(id: LongId[DocumentType], name: String)
object DocumentType {
+ sealed trait DocumentTypeName
+ case object OutpatientPhysicianNote extends DocumentTypeName
+ case object DischargeNote extends DocumentTypeName
+ case object LaboratoryReport extends DocumentTypeName
+ case object MedicationList extends DocumentTypeName
+ case object HospitalizationNote extends DocumentTypeName
+ case object PathologyReport extends DocumentTypeName
+ case object RadiologyReport extends DocumentTypeName
+ case object OperativeProcedureReport extends DocumentTypeName
+ case object MedicationAdministration extends DocumentTypeName
+ case object SocialWorkCaseManagementNote extends DocumentTypeName
+ case object NonPhysicianProviderNote extends DocumentTypeName
+ case object Administrative extends DocumentTypeName
+
+ def fromString(txt: String): Option[DocumentTypeName] = {
+ txt match {
+ case "Outpatient Physician Note" => Some(OutpatientPhysicianNote)
+ case "Discharge Note" => Some(DischargeNote)
+ case "Laboratory Report" => Some(LaboratoryReport)
+ case "Medication List" => Some(MedicationList)
+ case "Hospitalization Note" => Some(HospitalizationNote)
+ case "Pathology Report" => Some(PathologyReport)
+ case "Radiology Report" => Some(RadiologyReport)
+ case "Operative/Procedure Report" => Some(OperativeProcedureReport)
+ case "Medication Administration" => Some(MedicationAdministration)
+ case "Social Work/Case Management Note" => Some(SocialWorkCaseManagementNote)
+ case "Non-physician Provider Note" => Some(NonPhysicianProviderNote)
+ case "Administrative" => Some(Administrative)
+ case _ => None
+ }
+ }
+
implicit def toPhiString(x: DocumentType): PhiString = {
import x._
phi"DocumentType(id=$id, name=${Unsafe(name)})"
@@ -71,6 +169,7 @@ object Document {
def oneOf(xs: Set[Status]): Boolean = xs.contains(this)
}
+
object Status {
case object New extends Status
case object Organized extends Status
@@ -82,12 +181,58 @@ object Document {
val All = Set[Status](New, Organized, Extracted, Done, Flagged, Archived)
val AllPrevious = Set[Status](Organized, Extracted)
+ val fromString: PartialFunction[String, Status] = {
+ case "New" => Status.New
+ case "Organized" => Status.Organized
+ case "Extracted" => Status.Extracted
+ case "Done" => Status.Done
+ case "Flagged" => Status.Flagged
+ case "Archived" => Status.Archived
+ }
+
+ def statusToString(x: Status): String = x match {
+ case Status.New => "New"
+ case Status.Organized => "Organized"
+ case Status.Extracted => "Extracted"
+ case Status.Done => "Done"
+ case Status.Flagged => "Flagged"
+ case Status.Archived => "Archived"
+ }
+
implicit def toPhiString(x: Status): PhiString = Unsafe(Utils.getClassSimpleName(x.getClass))
}
+ sealed trait RequiredType extends Product with Serializable {
+
+ def oneOf(xs: RequiredType*): Boolean = xs.contains(this)
+
+ def oneOf(xs: Set[RequiredType]): Boolean = xs.contains(this)
+
+ }
+
+ object RequiredType {
+ case object OPN extends RequiredType
+ case object PN extends RequiredType
+
+ val All = Set[RequiredType](OPN, PN)
+
+ val fromString: PartialFunction[String, RequiredType] = {
+ case "OPN" => RequiredType.OPN
+ case "PN" => RequiredType.PN
+ }
+
+ def requiredTypeToString(x: RequiredType): String = x match {
+ case RequiredType.OPN => "OPN"
+ case RequiredType.PN => "PN"
+ }
+
+ implicit def toPhiString(x: RequiredType): PhiString = Unsafe(Utils.getClassSimpleName(x.getClass))
+ }
+
implicit def toPhiString(x: Document): PhiString = {
import x._
- phi"Document(id=$id, status=$status, assignee=$assignee, previousAssignee=$previousAssignee, recordId=$recordId)"
+ phi"Document(id=$id, status=$status, assignee=$assignee, " +
+ phi"previousAssignee=$previousAssignee, lastActiveUserId=$lastActiveUserId, recordId=$recordId)"
}
val validator: Validator[Document, Document] = { input =>
@@ -126,11 +271,13 @@ final case class Document(id: LongId[Document] = LongId(0L),
previousStatus: Option[Document.Status],
assignee: Option[LongId[User]],
previousAssignee: Option[LongId[User]],
+ lastActiveUserId: Option[LongId[User]],
recordId: LongId[MedicalRecord],
physician: Option[String],
typeId: Option[LongId[DocumentType]], // not null
providerName: Option[String], // not null
providerTypeId: Option[LongId[ProviderType]], // not null
+ requiredType: Option[Document.RequiredType],
meta: Option[TextJson[Meta]], // not null
startDate: Option[LocalDate], // not null
endDate: Option[LocalDate],
@@ -142,6 +289,22 @@ final case class Document(id: LongId[Document] = LongId(0L),
assert(AllPrevious.contains(previousStatus.get), s"Previous status has invalid value: ${previousStatus.get}")
}
+ def getRequiredType(documentTypeName: String, providerTypeName: String): Option[Document.RequiredType] = {
+ import DocumentType.{OutpatientPhysicianNote, PathologyReport}
+ import ProviderType.MedicalOncology
+
+ (DocumentType.fromString(documentTypeName), ProviderType.fromString(providerTypeName), startDate) match {
+ case (Some(OutpatientPhysicianNote), Some(MedicalOncology), Some(date))
+ if !(date.isAfter(LocalDate.now(ZoneId.of("Z"))) || date.isBefore(
+ LocalDate.now(ZoneId.of("Z")).minusMonths(6))) =>
+ Some(Document.RequiredType.OPN)
+
+ case (Some(PathologyReport), _, _) => Some(Document.RequiredType.PN)
+
+ case _ => None
+ }
+ }
+
// TODO: with the current business logic code this constraint sometimes harmful
// require(status match {
// case Document.Status.New if assignee.isDefined => false
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/ExtractedData.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/ExtractedData.scala
index 9972142..32258dc 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/entities/ExtractedData.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/ExtractedData.scala
@@ -19,7 +19,6 @@ object ExtractedData {
final case class Meta(keyword: Meta.Keyword, evidence: Meta.Evidence)
object Meta {
-
final case class Evidence(pageRatio: Double, start: TextLayerPosition, end: TextLayerPosition)
final case class TextLayerPosition(page: Integer, index: Integer, offset: Integer)
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/Intervention.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/Intervention.scala
index dc82050..e691547 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/entities/Intervention.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/Intervention.scala
@@ -28,6 +28,7 @@ final case class Intervention(id: LongId[Intervention],
typeId: Option[LongId[InterventionType]],
originalType: Option[String],
description: String,
+ originalDescription: String,
isActive: Boolean)
object Intervention {
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/LinkedPatient.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/LinkedPatient.scala
new file mode 100644
index 0000000..e82bcc3
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/LinkedPatient.scala
@@ -0,0 +1,16 @@
+package xyz.driver.pdsuidomain.entities
+
+import xyz.driver.pdsuicommon.domain._
+import xyz.driver.pdsuicommon.logging._
+
+object LinkedPatient {
+
+ implicit def toPhiString(x: LinkedPatient): PhiString = {
+ import x._
+ phi"LinkedPatient(userId=$userId, patientId=$patientId, trialId=$trialId)"
+ }
+}
+
+case class LinkedPatient(userId: LongId[User],
+ patientId: UuidId[Patient],
+ trialId: StringId[Trial])
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/MedicalRecord.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/MedicalRecord.scala
index 17de7de..0e30fa0 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/entities/MedicalRecord.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/MedicalRecord.scala
@@ -134,7 +134,8 @@ object MedicalRecord {
implicit def toPhiString(x: MedicalRecord): PhiString = {
import x._
- phi"MedicalRecord(id=$id, status=$status, assignee=$assignee, previousAssignee=$previousAssignee)"
+ phi"MedicalRecord(id=$id, status=$status, assignee=$assignee, " +
+ phi"previousAssignee=$previousAssignee, lastActiveUserId=$lastActiveUserId)"
}
}
@@ -143,6 +144,7 @@ case class MedicalRecord(id: LongId[MedicalRecord],
previousStatus: Option[MedicalRecord.Status],
assignee: Option[LongId[User]],
previousAssignee: Option[LongId[User]],
+ lastActiveUserId: Option[LongId[User]],
patientId: UuidId[Patient],
requestId: RecordRequestId,
disease: String,
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/Patient.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/Patient.scala
index 93262a4..695245c 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/entities/Patient.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/Patient.scala
@@ -45,7 +45,7 @@ object Patient {
implicit def toPhiString(x: Patient): PhiString = {
import x._
- phi"Patient(id=$id, status=$status, previousStatus=$previousStatus, " +
+ phi"Patient(id=$id, status=$status, previousStatus=$previousStatus, lastActiveUserId=$lastActiveUserId" +
phi"assignee=$assignee, previousAssignee=$previousAssignee)"
}
}
@@ -57,6 +57,7 @@ final case class Patient(id: UuidId[Patient],
assignee: Option[LongId[User]],
previousStatus: Option[Patient.Status],
previousAssignee: Option[LongId[User]],
+ lastActiveUserId: Option[LongId[User]],
isUpdateRequired: Boolean,
condition: String,
orderId: PatientOrderId,
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/PatientEligibleTrial.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/PatientEligibleTrial.scala
index 8084884..e16c324 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/entities/PatientEligibleTrial.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/PatientEligibleTrial.scala
@@ -82,35 +82,8 @@ object PatientTrialArmGroup {
implicit def toPhiString(x: PatientTrialArmGroup): PhiString = {
import x._
phi"PatientTrialArmGroup(id=$id, eligibleTrialId=$eligibleTrialId, " +
- phi"eligibilityStatus=${Unsafe(eligibilityStatus)}, isVerified=$isVerified)"
- }
-
- /**
- * @see https://driverinc.atlassian.net/wiki/display/DMPD/EV+Business+Process
- */
- def getEligibilityStatusForEvToRc(criterionList: List[(Option[Boolean], Option[FuzzyValue])]): Option[FuzzyValue] = {
- def isEligible = {
- // Eligible, if for all (verified for EV) label-criteria eligibilityStatus=NULL or YES and at least one has status=YES
- // If method executes from PatientService (when EV submit patient) need to check value PatientCriterion.isVerified
- val verifiedList = criterionList.filter { case (isVerifiedOpt, _) => isVerifiedOpt.isEmpty || isVerifiedOpt.get }
- verifiedList.forall {
- case (_, eligibilityStatus) =>
- eligibilityStatus.isEmpty || eligibilityStatus.contains(FuzzyValue.Yes)
- } && verifiedList.exists { case (_, eligibilityStatus) => eligibilityStatus.contains(FuzzyValue.Yes) }
- }
-
- if (criterionList.exists {
- case (isVerified, eligibilityStatus) =>
- eligibilityStatus.contains(FuzzyValue.No) && (isVerified.isEmpty || isVerified.get)
- }) { Some(FuzzyValue.No) } else if (criterionList.forall {
- case (_, eligibilityStatus) => eligibilityStatus.isEmpty
- }) {
- None
- } else if (isEligible) {
- Some(FuzzyValue.Yes)
- } else {
- Some(FuzzyValue.Maybe)
- }
+ phi"eligibilityStatus=${Unsafe(eligibilityStatus)}, " +
+ phi"verifiedEligibilityStatus=${Unsafe(verifiedEligibilityStatus)}, isVerified=$isVerified)"
}
/**
@@ -131,14 +104,16 @@ object PatientTrialArmGroup {
final case class PatientTrialArmGroup(id: LongId[PatientTrialArmGroup],
eligibleTrialId: UuidId[PatientEligibleTrial],
eligibilityStatus: Option[FuzzyValue],
+ verifiedEligibilityStatus: Option[FuzzyValue],
isVerified: Boolean)
object PatientTrialArmGroupView {
implicit def toPhiString(x: PatientTrialArmGroupView): PhiString = {
import x._
- phi"PatientTrialArmGroupView(id=$id, patientId=$patientId, trialId=$trialId, hypothesisId=$hypothesisId, " +
- phi"eligibilityStatus=${Unsafe(eligibilityStatus)}, isVerified=$isVerified)"
+ phi"PatientTrialArmGroupView(id=$id, patientId=$patientId, trialId=$trialId, " +
+ phi"hypothesisId=$hypothesisId, eligibilityStatus=${Unsafe(eligibilityStatus)}, " +
+ phi"verifiedEligibilityStatus=${Unsafe(verifiedEligibilityStatus)}, isVerified=$isVerified)"
}
}
@@ -147,11 +122,13 @@ final case class PatientTrialArmGroupView(id: LongId[PatientTrialArmGroup],
trialId: StringId[Trial],
hypothesisId: UuidId[Hypothesis],
eligibilityStatus: Option[FuzzyValue],
+ verifiedEligibilityStatus: Option[FuzzyValue],
isVerified: Boolean) {
def applyTo(trialArmGroup: PatientTrialArmGroup) = {
trialArmGroup.copy(
eligibilityStatus = this.eligibilityStatus,
+ verifiedEligibilityStatus = this.verifiedEligibilityStatus,
isVerified = this.isVerified
)
}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/PatientLabelEvidenceView.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/PatientLabelEvidenceView.scala
new file mode 100644
index 0000000..60298b9
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/PatientLabelEvidenceView.scala
@@ -0,0 +1,28 @@
+package xyz.driver.pdsuidomain.entities
+
+import java.time.LocalDate
+
+import xyz.driver.pdsuicommon.domain._
+import xyz.driver.pdsuicommon.logging._
+
+object PatientLabelEvidenceView {
+ implicit def toPhiString(x: PatientLabelEvidenceView): PhiString = {
+ import x._
+ phi"PatientLabelEvidenceViewRepository.Row(id=$id, value=$value, documentId=$documentId, " +
+ phi"evidenceId=$evidenceId, reportId=$reportId, patientId=$patientId, labelId=$labelId, " +
+ phi"isImplicitMatch=$isImplicitMatch)"
+ }
+}
+
+final case class PatientLabelEvidenceView(id: LongId[PatientLabelEvidence],
+ value: FuzzyValue,
+ evidenceText: String,
+ documentId: Option[LongId[Document]],
+ evidenceId: Option[LongId[ExtractedData]],
+ reportId: Option[UuidId[DirectReport]],
+ documentType: String,
+ date: Option[LocalDate], // Document.startDate is optional
+ providerType: String,
+ patientId: UuidId[Patient],
+ labelId: LongId[Label],
+ isImplicitMatch: Boolean)
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/RawTrialLabel.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/RawTrialLabel.scala
index e3b323f..82204c2 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/entities/RawTrialLabel.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/RawTrialLabel.scala
@@ -12,7 +12,6 @@ case class RawTrialLabel(nctId: StringId[Trial],
armName: String,
armId: LongId[Arm],
labelId: LongId[Label],
- label: String,
value: Option[Boolean],
criterionId: LongId[Criterion],
criteria: String,
@@ -25,7 +24,7 @@ object RawTrialLabel {
implicit def toPhiString(x: RawTrialLabel): PhiString = {
import x._
phi"RawTrialLabel(nctId=$nctId, trialId=$trialId, condition=${Unsafe(condition)}, lastReviewed=$lastReviewed, " +
- phi"armId=$armId, armName=${Unsafe(armName)}, labelId=$labelId, label=${Unsafe(label)}, value=$value, " +
+ phi"armId=$armId, armName=${Unsafe(armName)}, labelId=$labelId, value=$value, " +
phi"criterionId=$criterionId, criteria=${Unsafe(criteria)}, criterionArmId=$criterionArmId, " +
phi"isCompound=$isCompound, isDefining=$isDefining)"
}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/Trial.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/Trial.scala
index f5ab3cb..0f478ca 100644
--- a/src/main/scala/xyz/driver/pdsuidomain/entities/Trial.scala
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/Trial.scala
@@ -57,8 +57,8 @@ object Trial {
implicit def toPhiString(x: Trial): PhiString = {
import x._
phi"Trial(id=$id, externalId=$externalId, status=$status, previousStatus=$previousStatus, " +
- phi"assignee=$assignee, previousAssignee=$previousAssignee, isSummaryReviewed=$isSummaryReviewed, " +
- phi"isCriteriaReviewed=$isCriteriaReviewed)"
+ phi"lastActiveUserId=$lastActiveUserId, assignee=$assignee, previousAssignee=$previousAssignee, " +
+ phi"isSummaryReviewed=$isSummaryReviewed, isCriteriaReviewed=$isCriteriaReviewed)"
}
case class Locations(locations: List[String])
@@ -81,6 +81,7 @@ final case class Trial(id: StringId[Trial],
assignee: Option[LongId[User]],
previousStatus: Option[Status],
previousAssignee: Option[LongId[User]],
+ lastActiveUserId: Option[LongId[User]],
lastUpdate: LocalDateTime,
condition: Condition,
phase: String,
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/UserHistory.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/UserHistory.scala
new file mode 100644
index 0000000..b55369e
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/UserHistory.scala
@@ -0,0 +1,156 @@
+package xyz.driver.pdsuidomain.entities
+
+import java.time.{LocalDateTime, ZoneId}
+
+import xyz.driver.pdsuicommon.domain._
+import xyz.driver.pdsuicommon.logging._
+import xyz.driver.pdsuicommon.utils.Utils
+
+final case class UserHistory(id: LongId[UserHistory],
+ executor: LongId[User],
+ recordId: Option[LongId[MedicalRecord]] = None,
+ documentId: Option[LongId[Document]] = None,
+ trialId: Option[StringId[Trial]] = None,
+ patientId: Option[UuidId[Patient]] = None,
+ state: UserHistory.State,
+ action: UserHistory.Action,
+ created: LocalDateTime = LocalDateTime.now(ZoneId.of("Z")))
+
+object UserHistory {
+
+ def forDocument(executor: LongId[User],
+ documentId: LongId[Document],
+ state: UserHistory.State,
+ action: UserHistory.Action): UserHistory = UserHistory (
+ id = LongId(0L),
+ executor = executor,
+ documentId = Some(documentId),
+ state = state,
+ action = action
+ )
+
+ def forRecord(executor: LongId[User],
+ recordId: LongId[MedicalRecord],
+ state: UserHistory.State,
+ action: UserHistory.Action): UserHistory = UserHistory (
+ id = LongId(0L),
+ executor = executor,
+ recordId = Some(recordId),
+ state = state,
+ action = action
+ )
+
+ def forTrial(executor: LongId[User],
+ trialId: StringId[Trial],
+ state: UserHistory.State,
+ action: UserHistory.Action): UserHistory = UserHistory (
+ id = LongId(0L),
+ executor = executor,
+ trialId = Some(trialId),
+ state = state,
+ action = action
+ )
+
+ def forPatient(executor: LongId[User],
+ patientId: UuidId[Patient],
+ state: UserHistory.State,
+ action: UserHistory.Action): UserHistory = UserHistory (
+ id = LongId(0L),
+ executor = executor,
+ patientId = Some(patientId),
+ state = state,
+ action = action
+ )
+
+ sealed trait State extends Product with Serializable {
+
+ def oneOf(xs: State*): Boolean = xs.contains(this)
+
+ def oneOf(xs: Set[State]): Boolean = xs.contains(this)
+ }
+
+ object State {
+ case object Clean extends State
+ case object Organize extends State
+ case object Extract extends State
+ case object Summarize extends State
+ case object Criteriarize extends State
+ case object Verify extends State
+ case object Curate extends State
+ case object Review extends State
+ case object Flag extends State
+
+ val All: Set[State] = Set[State](Clean, Organize, Extract, Summarize, Criteriarize, Verify, Curate, Review, Flag)
+
+ val fromString: PartialFunction[String, State] = {
+ case "Clean" => State.Clean
+ case "Organize" => State.Organize
+ case "Extract" => State.Extract
+ case "Summarize" => State.Summarize
+ case "Criteriarize" => State.Criteriarize
+ case "Verify" => State.Verify
+ case "Curate" => State.Curate
+ case "Review" => State.Review
+ case "Flag" => State.Flag
+ }
+
+ def stateToString(x: State): String = x match {
+ case State.Clean => "Clean"
+ case State.Organize => "Organize"
+ case State.Extract => "Extract"
+ case State.Summarize => "Summarize"
+ case State.Criteriarize => "Criteriarize"
+ case State.Verify => "Verify"
+ case State.Curate => "Curate"
+ case State.Review => "Review"
+ case State.Flag => "Flag"
+ }
+
+ implicit def toPhiString(x: State): PhiString = Unsafe(Utils.getClassSimpleName(x.getClass))
+ }
+
+ sealed trait Action extends Product with Serializable {
+
+ def oneOf(xs: Action*): Boolean = xs.contains(this)
+
+ def oneOf(xs: Set[Action]): Boolean = xs.contains(this)
+ }
+
+ object Action {
+ case object Start extends Action
+ case object Submit extends Action
+ case object Unassign extends Action
+ case object Resolve extends Action
+ case object Flag extends Action
+ case object Archive extends Action
+
+ val All: Set[Action] = Set[Action](Start, Submit, Unassign, Resolve, Flag, Archive)
+
+ val fromString: PartialFunction[String, Action] = {
+ case "Start" => Action.Start
+ case "Submit" => Action.Submit
+ case "Unassign" => Action.Unassign
+ case "Resolve" => Action.Resolve
+ case "Flag" => Action.Flag
+ case "Archive" => Action.Archive
+ }
+
+ def actionToString(x: Action): String = x match {
+ case Action.Start => "Start"
+ case Action.Submit => "Submit"
+ case Action.Unassign => "Unassign"
+ case Action.Resolve => "Resolve"
+ case Action.Flag => "Flag"
+ case Action.Archive => "Archive"
+ }
+
+ implicit def toPhiString(x: Action): PhiString = Unsafe(Utils.getClassSimpleName(x.getClass))
+ }
+
+ implicit def toPhiString(x: UserHistory): PhiString = {
+ import x._
+ phi"UserHistory(id=$id, executor=$executor, recordId=$recordId, " +
+ phi"documentId=$documentId, trialId=$trialId, patientId=$patientId, " +
+ phi"state=$state, action=$action, created=$created)"
+ }
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/export/patient/ExportPatientLabel.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/export/patient/ExportPatientLabel.scala
new file mode 100644
index 0000000..5474413
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/export/patient/ExportPatientLabel.scala
@@ -0,0 +1,30 @@
+package xyz.driver.pdsuidomain.entities.export.patient
+
+import xyz.driver.pdsuicommon.domain.LongId
+import xyz.driver.pdsuicommon.logging._
+import xyz.driver.pdsuidomain.entities.{Label, RawPatientLabel}
+
+final case class ExportPatientLabel(id: LongId[Label],
+ name: String,
+ evidences: List[ExportPatientLabelEvidence])
+
+object ExportPatientLabel extends PhiLogging {
+
+ implicit def toPhiString(x: ExportPatientLabel): PhiString = {
+ import x._
+ phi"ExportPatientLabel(id=$id, evidences=$evidences)"
+ }
+
+ def fromRaw(labelId: LongId[Label], rawPatientLabels: List[RawPatientLabel]): ExportPatientLabel = {
+ val firstLabel = rawPatientLabels.headOption
+ if (firstLabel.isEmpty) {
+ logger.warn(phi"rawPatientLabels is empty, labelId: $labelId")
+ }
+
+ ExportPatientLabel(
+ id = labelId,
+ name = firstLabel.map(_.label).getOrElse(""),
+ evidences = rawPatientLabels.map(ExportPatientLabelEvidence.fromRaw)
+ )
+ }
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/export/patient/ExportPatientLabelEvidence.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/export/patient/ExportPatientLabelEvidence.scala
new file mode 100644
index 0000000..fb40339
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/export/patient/ExportPatientLabelEvidence.scala
@@ -0,0 +1,32 @@
+package xyz.driver.pdsuidomain.entities.export.patient
+
+import xyz.driver.pdsuicommon.domain._
+import xyz.driver.pdsuicommon.logging._
+import xyz.driver.pdsuidomain.entities.{ExtractedData, RawPatientLabel}
+
+final case class ExportPatientLabelEvidence(id: LongId[ExtractedData],
+ value: FuzzyValue,
+ evidenceText: String,
+ document: ExportPatientLabelEvidenceDocument)
+
+object ExportPatientLabelEvidence {
+
+ implicit def toPhiString(x: ExportPatientLabelEvidence): PhiString = {
+ import x._
+ phi"ExportPatientLabelEvidence(id=${Unsafe(id)}, value=$value, " +
+ phi"evidenceText=${Unsafe(evidenceText)}, document=$document)"
+ }
+
+ def fromRaw(x: RawPatientLabel) = ExportPatientLabelEvidence(
+ id = x.evidenceId,
+ value = x.value,
+ evidenceText = x.evidenceText,
+ document = ExportPatientLabelEvidenceDocument(
+ x.documentId,
+ x.requestId,
+ x.documentType,
+ x.providerType,
+ x.startDate
+ )
+ )
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/export/patient/ExportPatientLabelEvidenceDocument.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/export/patient/ExportPatientLabelEvidenceDocument.scala
new file mode 100644
index 0000000..99912bc
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/export/patient/ExportPatientLabelEvidenceDocument.scala
@@ -0,0 +1,30 @@
+package xyz.driver.pdsuidomain.entities.export.patient
+
+import java.time.LocalDate
+
+import xyz.driver.pdsuicommon.domain._
+import xyz.driver.pdsuicommon.logging._
+import xyz.driver.pdsuidomain.entities.{Document, RawPatientLabel, RecordRequestId}
+
+final case class ExportPatientLabelEvidenceDocument(documentId: LongId[Document],
+ requestId: RecordRequestId,
+ documentType: String,
+ providerType: String,
+ date: LocalDate)
+
+object ExportPatientLabelEvidenceDocument extends PhiLogging {
+
+ implicit def toPhiString(x: ExportPatientLabelEvidenceDocument): PhiString = {
+ import x._
+ phi"ExportPatientLabelEvidenceDocument(documentId=$documentId, requestId=$requestId, " +
+ phi"documentType=${Unsafe(documentType)}, providerType=${Unsafe(providerType)}, date=$date)"
+ }
+
+ def fromRaw(x: RawPatientLabel) = ExportPatientLabelEvidenceDocument(
+ documentId = x.documentId,
+ requestId = x.requestId,
+ documentType = x.documentType,
+ providerType = x.providerType,
+ date = x.startDate
+ )
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/export/patient/ExportPatientWithLabels.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/export/patient/ExportPatientWithLabels.scala
new file mode 100644
index 0000000..e6262ed
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/export/patient/ExportPatientWithLabels.scala
@@ -0,0 +1,26 @@
+package xyz.driver.pdsuidomain.entities.export.patient
+
+import xyz.driver.pdsuicommon.domain._
+import xyz.driver.pdsuicommon.logging._
+import xyz.driver.pdsuidomain.entities.{Patient, RawPatientLabel}
+
+import scala.collection.breakOut
+
+final case class ExportPatientWithLabels(patientId: UuidId[Patient], labelVersion: Long, labels: List[ExportPatientLabel])
+
+object ExportPatientWithLabels {
+
+ implicit def toPhiString(x: ExportPatientWithLabels): PhiString = {
+ import x._
+ phi"ExportPatientWithLabels(patientId=$patientId, version=${Unsafe(labelVersion)}, labels=$labels)"
+ }
+
+ def fromRaw(patientId: UuidId[Patient],
+ rawPatientRefs: List[RawPatientLabel]) = ExportPatientWithLabels(
+ patientId = patientId,
+ labelVersion = 1L, // TODO It is needed to replace this mock label version.
+ labels = rawPatientRefs
+ .groupBy(_.labelId)
+ .map(Function.tupled(ExportPatientLabel.fromRaw))(breakOut)
+ )
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrial.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrial.scala
new file mode 100644
index 0000000..1aed121
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrial.scala
@@ -0,0 +1,27 @@
+package xyz.driver.pdsuidomain.entities.export.trial
+
+import java.time.LocalDateTime
+
+import xyz.driver.pdsuicommon.domain._
+import xyz.driver.pdsuicommon.logging._
+import xyz.driver.pdsuidomain.entities.Trial
+
+final case class ExportTrial(nctId: StringId[Trial],
+ trialId: UuidId[Trial],
+ condition: Trial.Condition,
+ lastReviewed: LocalDateTime)
+
+object ExportTrial {
+
+ implicit def toPhiString(x: ExportTrial): PhiString = {
+ import x._
+ phi"ExportTrial(nctId=$nctId, trialId=$trialId, condition=${Unsafe(condition)}, lastReviewed=$lastReviewed)"
+ }
+
+ def fromDomain(x: Trial) = ExportTrial(
+ nctId = x.id,
+ trialId = x.externalId,
+ condition = x.condition,
+ lastReviewed = x.lastUpdate
+ )
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialArm.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialArm.scala
new file mode 100644
index 0000000..5a9a406
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialArm.scala
@@ -0,0 +1,15 @@
+package xyz.driver.pdsuidomain.entities.export.trial
+
+import xyz.driver.pdsuicommon.domain._
+import xyz.driver.pdsuicommon.logging._
+import xyz.driver.pdsuidomain.entities.Arm
+
+final case class ExportTrialArm(armId: LongId[Arm], armName: String)
+
+object ExportTrialArm {
+
+ implicit def toPhiString(x: ExportTrialArm): PhiString = {
+ import x._
+ phi"ExportTrialArm(armId=$armId, armName=${Unsafe(armName)})"
+ }
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialLabelCriterion.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialLabelCriterion.scala
new file mode 100644
index 0000000..7bff22c
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialLabelCriterion.scala
@@ -0,0 +1,32 @@
+package xyz.driver.pdsuidomain.entities.export.trial
+
+import xyz.driver.pdsuicommon.domain._
+import xyz.driver.pdsuicommon.logging._
+import xyz.driver.pdsuidomain.entities.{Arm, Criterion, Label, RawTrialLabel}
+
+final case class ExportTrialLabelCriterion(criterionId: LongId[Criterion],
+ value: Option[Boolean],
+ labelId: LongId[Label],
+ armIds: Set[LongId[Arm]],
+ criteria: String,
+ isCompound: Boolean,
+ isDefining: Boolean)
+
+object ExportTrialLabelCriterion {
+
+ implicit def toPhiString(x: ExportTrialLabelCriterion): PhiString = {
+ import x._
+ phi"TrialLabelCriterion(criterionId=$criterionId, value=$value, labelId=$labelId, " +
+ phi"criteria=${Unsafe(criteria)}, isCompound=$isCompound, isDefining=$isDefining)"
+ }
+
+ def fromRaw(x: RawTrialLabel, armIds: Set[LongId[Arm]]) = ExportTrialLabelCriterion(
+ criterionId = x.criterionId,
+ value = x.value,
+ labelId = x.labelId,
+ armIds = armIds,
+ criteria = x.criteria,
+ isCompound = x.isCompound,
+ isDefining = x.isDefining
+ )
+}
diff --git a/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialWithLabels.scala b/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialWithLabels.scala
new file mode 100644
index 0000000..1655a88
--- /dev/null
+++ b/src/main/scala/xyz/driver/pdsuidomain/entities/export/trial/ExportTrialWithLabels.scala
@@ -0,0 +1,52 @@
+package xyz.driver.pdsuidomain.entities.export.trial
+
+import java.time.LocalDateTime
+
+import xyz.driver.pdsuicommon.domain._
+import xyz.driver.pdsuicommon.logging._
+import xyz.driver.pdsuidomain.entities.{RawTrialLabel, Trial}
+
+import scala.collection.breakOut
+
+final case class ExportTrialWithLabels(nctId: StringId[Trial],
+ trialId: UuidId[Trial],
+ condition: String,
+ lastReviewed: LocalDateTime,
+ labelVersion: Long,
+ arms: List[ExportTrialArm],
+ criteria: List[ExportTrialLabelCriterion])
+
+object ExportTrialWithLabels {
+
+ implicit def toPhiString(x: ExportTrialWithLabels): PhiString = {
+ import x._
+ phi"TrialWithLabels(nctId=$nctId, trialId=$trialId, condition=${Unsafe(condition)}, " +
+ phi"lastReviewed=$lastReviewed, labelVersion=${Unsafe(labelVersion)}, arms=$arms, criteria=$criteria)"
+ }
+
+ def fromRaw(rawData: List[RawTrialLabel]): ExportTrialWithLabels = {
+ val trials: Set[StringId[Trial]] = rawData.map(_.nctId)(breakOut)
+
+ assert(trials.size == 1, "There are more than one trials in the rawData")
+ val trial = rawData.head
+
+ ExportTrialWithLabels(
+ nctId = trial.nctId,
+ trialId = trial.trialId,
+ condition = trial.condition,
+ lastReviewed = trial.lastReviewed,
+ labelVersion = 1, // TODO It is needed to replace this mock label version.
+ arms = rawData.groupBy(_.armId).map { case (armId, rawTrials) =>
+ ExportTrialArm(armId, rawTrials.head.armName)
+ }(breakOut),
+ criteria = rawData.groupBy { x =>
+ (x.criterionId, x.labelId)
+ }.map {
+ case (_, rawTrialLabels) =>
+ val armIds = rawTrialLabels.map(_.criterionArmId).toSet
+ ExportTrialLabelCriterion.fromRaw(rawTrialLabels.head, armIds)
+ }(breakOut)
+ )
+ }
+
+}