aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/xyz/driver/pdsuidomain/entities/Document.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/xyz/driver/pdsuidomain/entities/Document.scala')
-rw-r--r--src/main/scala/xyz/driver/pdsuidomain/entities/Document.scala167
1 files changed, 165 insertions, 2 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