aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/xyz/driver/pdsuidomain/formats/json/eligibilityarm.scala
blob: 5827f626596a97e4ae149815868f1d708e852c25 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package xyz.driver.pdsuidomain.formats.json

import spray.json._
import xyz.driver.entities.patient.CancerType
import xyz.driver.formats.json.patient._
import xyz.driver.pdsuicommon.domain.{LongId, StringId}
import xyz.driver.pdsuidomain.entities._

object eligibilityarm {

  import DefaultJsonProtocol._
  import common._

  private def deserializationErrorFieldMessage(field: String, json: JsValue)(implicit className: String) = {
    deserializationError(s"$className json object do not contain '$field' field: $json")
  }

  private def deserializationErrorEntityMessage(json: JsValue)(implicit className: String) = {
    deserializationError(s"Expected Json Object as $className, but got $json")
  }

  implicit def eligibilityArmWithDiseasesWriter: RootJsonWriter[EligibilityArmWithDiseases] =
    new RootJsonWriter[EligibilityArmWithDiseases] {
      override def write(obj: EligibilityArmWithDiseases): JsValue = {
        JsObject(
          "id"           -> obj.eligibilityArm.id.toJson,
          "name"         -> obj.eligibilityArm.name.toJson,
          "originalName" -> obj.eligibilityArm.originalName.toJson,
          "trialId"      -> obj.eligibilityArm.trialId.toJson,
          "diseases"     -> obj.eligibilityArmDiseases.map(_.disease.toJson).toJson
        )
      }
    }

  implicit def eligibilityArmWithDiseasesReader: RootJsonReader[EligibilityArmWithDiseases] = {
    new RootJsonReader[EligibilityArmWithDiseases] {
      implicit val className: String = "create EligibilityArmWithDiseases"

      override def read(json: JsValue): EligibilityArmWithDiseases = {
        json match {
          case JsObject(fields) =>
            val id = fields
              .get("id")
              .flatMap(_.convertTo[Option[LongId[EligibilityArm]]])

            val name = fields
              .get("name")
              .map(_.convertTo[String])
              .getOrElse(deserializationErrorFieldMessage("name", json))

            val trialId = fields
              .get("trialId")
              .map(_.convertTo[StringId[Trial]])
              .getOrElse(deserializationErrorFieldMessage("trialId", json))

            val diseases = fields
              .get("diseases")
              .map(_.convertTo[Seq[String]])
              .getOrElse(deserializationErrorFieldMessage("diseases", json))

            val eligibilityArm = EligibilityArm(
              id = id.getOrElse(LongId(0)),
              name = name,
              trialId = trialId,
              originalName = name
            )

            EligibilityArmWithDiseases(
              eligibilityArm,
              diseases.map { disease =>
                val condition = CancerType
                  .fromString(disease)
                  .getOrElse(throw new NoSuchElementException(s"unknown condition $disease"))
                EligibilityArmDisease(eligibilityArm.id, condition)
              }
            )
          case _ => deserializationErrorEntityMessage(json)
        }
      }
    }
  }

  def applyUpdateToEligibilityArmWithDiseases(json: JsValue,
                                              orig: EligibilityArmWithDiseases): EligibilityArmWithDiseases = {
    implicit val className: String = "update EligibilityArmWithDiseases"
    json match {
      case JsObject(fields) =>
        val name = fields
          .get("name")
          .map(_.convertTo[String])
          .getOrElse(orig.eligibilityArm.name)

        val diseases = fields
          .get("diseases")
          .map(_.convertTo[Seq[CancerType]].map(x => EligibilityArmDisease(orig.eligibilityArm.id, x)))
          .getOrElse(orig.eligibilityArmDiseases)

        orig.copy(
          eligibilityArm = orig.eligibilityArm
            .copy(name = name),
          eligibilityArmDiseases = diseases
        )

      case _ => deserializationErrorEntityMessage(json)
    }
  }
}