package xyz.driver.pdsuidomain.entities import xyz.driver.pdsuicommon.domain.{LongId, StringId} import xyz.driver.pdsuicommon.logging._ import xyz.driver.pdsuidomain.entities.InterventionType.DeliveryMethod import xyz.driver.pdsuidomain.entities.InterventionType.DeliveryMethod._ import scalaz.syntax.equal._ import scalaz.Scalaz.stringInstance sealed trait InterventionType { val id: LongId[InterventionType] val name: String val deliveryMethods: Set[DeliveryMethod] } object InterventionType { final case object Chemotherapy extends InterventionType { val id: LongId[InterventionType] = LongId[InterventionType](2) val name: String = "Chemotherapy" val deliveryMethods: Set[DeliveryMethod] = commonMethods } final case object TargetedTherapy extends InterventionType { val id: LongId[InterventionType] = LongId[InterventionType](3) val name: String = "Targeted therapy" val deliveryMethods: Set[DeliveryMethod] = commonMethods } final case object Immunotherapy extends InterventionType { val id: LongId[InterventionType] = LongId[InterventionType](4) val name: String = "Immunotherapy" val deliveryMethods: Set[DeliveryMethod] = commonMethods } final case object HormoneTherapy extends InterventionType { val id: LongId[InterventionType] = LongId[InterventionType](6) val name: String = "Hormone therapy" val deliveryMethods: Set[DeliveryMethod] = commonMethods } final case object Other extends InterventionType { val id: LongId[InterventionType] = LongId[InterventionType](7) val name: String = "Other" val deliveryMethods: Set[DeliveryMethod] = commonMethods } final case object Radiation extends InterventionType { val id: LongId[InterventionType] = LongId[InterventionType](8) val name: String = "Radiation" val deliveryMethods: Set[DeliveryMethod] = Set( ExternalRadiationTherapy, Brachytherapy, SystemicRadiationTherapyIV, SystemicRadiationTherapyOral, ProtonBeamTherapy ) } final case object SurgeryProcedure extends InterventionType { val id: LongId[InterventionType] = LongId[InterventionType](9) val name: String = "Surgery/Procedure" val deliveryMethods: Set[DeliveryMethod] = Set( RadioFrequencyAblationRFA, Cryoablation, TherapeuticConventionalSurgery, RoboticAssistedLaparoscopicSurgery ) } def typeFromString(txt: String): Option[InterventionType] = { All.values.find(_.name === txt) } sealed trait DeliveryMethod object DeliveryMethod { case object IntravenousInfusionIV extends DeliveryMethod case object IntramuscularInjection extends DeliveryMethod case object SubcutaneousInjection extends DeliveryMethod case object IntradermalInjection extends DeliveryMethod case object SpinalInjection extends DeliveryMethod case object Oral extends DeliveryMethod case object Topical extends DeliveryMethod case object TransdermalPatch extends DeliveryMethod case object Inhalation extends DeliveryMethod case object Rectal extends DeliveryMethod case object ExternalRadiationTherapy extends DeliveryMethod case object Brachytherapy extends DeliveryMethod case object SystemicRadiationTherapyIV extends DeliveryMethod case object SystemicRadiationTherapyOral extends DeliveryMethod case object ProtonBeamTherapy extends DeliveryMethod case object RadioFrequencyAblationRFA extends DeliveryMethod case object Cryoablation extends DeliveryMethod case object TherapeuticConventionalSurgery extends DeliveryMethod case object RoboticAssistedLaparoscopicSurgery extends DeliveryMethod def fromString: PartialFunction[String, DeliveryMethod] = { case "Intravenous Infusion (IV)" => IntravenousInfusionIV case "Intramuscular Injection" => IntramuscularInjection case "Subcutaneous Injection" => SubcutaneousInjection case "Intradermal Injection" => IntradermalInjection case "Spinal Injection" => SpinalInjection case "Oral" => Oral case "Topical" => Topical case "Transdermal Patch" => TransdermalPatch case "Inhalation" => Inhalation case "Rectal" => Rectal case "External Radiation Therapy" => ExternalRadiationTherapy case "Brachytherapy" => Brachytherapy case "Systemic Radiation Therapy (IV)" => SystemicRadiationTherapyIV case "Systemic Radiation Therapy (Oral)" => SystemicRadiationTherapyOral case "Proton Beam Therapy" => ProtonBeamTherapy case "Radio-Frequency Ablation (RFA)" => RadioFrequencyAblationRFA case "Cryoablation" => Cryoablation case "Therapeutic Conventional Surgery" => TherapeuticConventionalSurgery case "Robotic Assisted Laparoscopic Surgery" => RoboticAssistedLaparoscopicSurgery } def methodToString(x: DeliveryMethod): String = x match { case IntravenousInfusionIV => "Intravenous Infusion (IV)" case IntramuscularInjection => "Intramuscular Injection" case SubcutaneousInjection => "Subcutaneous Injection" case IntradermalInjection => "Intradermal Injection" case SpinalInjection => "Spinal Injection" case Oral => "Oral" case Topical => "Topical" case TransdermalPatch => "Transdermal Patch" case Inhalation => "Inhalation" case Rectal => "Rectal" case ExternalRadiationTherapy => "External Radiation Therapy" case Brachytherapy => "Brachytherapy" case SystemicRadiationTherapyIV => "Systemic Radiation Therapy (IV)" case SystemicRadiationTherapyOral => "Systemic Radiation Therapy (Oral)" case ProtonBeamTherapy => "Proton Beam Therapy" case RadioFrequencyAblationRFA => "Radio-Frequency Ablation (RFA)" case Cryoablation => "Cryoablation" case TherapeuticConventionalSurgery => "Therapeutic Conventional Surgery" case RoboticAssistedLaparoscopicSurgery => "Robotic Assisted Laparoscopic Surgery" } } val commonMethods: Set[DeliveryMethod] = Set[DeliveryMethod]( IntravenousInfusionIV, IntramuscularInjection, SubcutaneousInjection, IntradermalInjection, SpinalInjection, Oral, Topical, TransdermalPatch, Inhalation, Rectal ) val All: Map[LongId[InterventionType], InterventionType] = Map[LongId[InterventionType], InterventionType]( LongId[InterventionType](2) -> Chemotherapy, LongId[InterventionType](3) -> TargetedTherapy, LongId[InterventionType](4) -> Immunotherapy, LongId[InterventionType](6) -> HormoneTherapy, LongId[InterventionType](7) -> Other, LongId[InterventionType](8) -> Radiation, LongId[InterventionType](9) -> SurgeryProcedure ) implicit def toPhiString(x: InterventionType): PhiString = { import x._ phi"InterventionType(id=$id, name=${Unsafe(name)})" } } final case class InterventionArm(armId: LongId[SlotArm], interventionId: LongId[Intervention]) object InterventionArm { implicit def toPhiString(x: InterventionArm): PhiString = { import x._ phi"InterventionArm(armId=$armId, interventionId=$interventionId)" } } final case class Intervention(id: LongId[Intervention], trialId: StringId[Trial], name: String, originalName: String, typeId: Option[LongId[InterventionType]], originalType: Option[String], dosage: String, originalDosage: String, isActive: Boolean, deliveryMethod: Option[String]) { def deliveryMethodIsCorrect: Boolean = { if (this.typeId.nonEmpty && this.deliveryMethod.nonEmpty) { InterventionType.All .getOrElse(this.typeId.get, throw new IllegalArgumentException(s"Not found Intervention type ${this.typeId}")) .deliveryMethods .contains(DeliveryMethod.fromString(this.deliveryMethod.get)) } else true } } object Intervention { implicit def toPhiString(x: Intervention): PhiString = { import x._ phi"Intervention(id=$id, trialId=$trialId, name=${Unsafe(name)}, typeId=$typeId, isActive=$isActive, deliveryMethod=${Unsafe(deliveryMethod)})" } } final case class InterventionWithArms(intervention: Intervention, arms: List[InterventionArm]) object InterventionWithArms { implicit def toPhiString(x: InterventionWithArms): PhiString = { import x._ phi"InterventionWithArms(intervention=$intervention, arms=$arms)" } }