generated from StanfordSpezi/SpeziTemplateApplication
-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Updated Medications View + Adding to Environment Variable (#51)
# Working Medications View with Sample Patient Data and Updating Global Environment Variable ## ♻️ Current situation & Problem #21 Previously, the medications view would only pull the display name from the medications fhir resource. This was problematic in several ways--the UI was not developed, patient medications could be added that weren't accurate, and there was no additional information beyond the display name. ## ⚙️ Release Notes - Updated the patient medication data to be filtered by only including outpatient and activate medications (like from llmonfhir) - Modified existing code from SpeziMedications to create structs specific to Intake such as IntakeMedications and IntakeDosage - Updated medicationOptions to represent some of the top mock patient medications - Updated a MedicationSettingsViewModel to initialize with existing mock patient medications including dosage, intake method, and dose frequency - Added compatibility to global variable ## 📚 Documentation *Please ensure that you properly document any additions in conformance to [Spezi Documentation Guide](https://github.com/StanfordSpezi/.github/blob/main/DOCUMENTATIONGUIDE.md).* *You can use this section to describe your solution, but we encourage contributors to document your reasoning and changes using in-line documentation.* ## ✅ Testing *Please ensure that the PR meets the testing requirements set by CodeCov and that new functionality is appropriately tested.* *This section describes important information about the tests and why some elements might not be testable.* ## 📝 Code of Conduct & Contributing Guidelines By submitting creating this pull request, you agree to follow our [Code of Conduct](https://github.com/CS342/.github/blob/main/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/CS342/.github/blob/main/CONTRIBUTING.md): - [x ] I agree to follow the [Code of Conduct](https://github.com/CS342/.github/blob/main/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/CS342/.github/blob/main/CONTRIBUTING.md).
- Loading branch information
Showing
12 changed files
with
342 additions
and
191 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// | ||
// IntakeDosage.swift | ||
// Intake | ||
// | ||
// Created by Kate Callon on 2/17/24. | ||
// | ||
// | ||
// This source file is part of the Intake based on the Stanford Spezi Template Medication project | ||
// | ||
// SPDX-FileCopyrightText: 2023 Stanford University | ||
// | ||
// SPDX-License-Identifier: MIT | ||
// | ||
|
||
import Foundation | ||
import SpeziMedication | ||
|
||
struct IntakeDosage: Dosage { | ||
var localizedDescription: String | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// | ||
// IntakeMedication.swift | ||
// Intake | ||
// | ||
// Created by Kate Callon on 2/17/24. | ||
// | ||
// | ||
// This source file is part of the Intake based on the Stanford Spezi Medication Application project | ||
// | ||
// SPDX-FileCopyrightText: 2023 Stanford University | ||
// | ||
// SPDX-License-Identifier: MIT | ||
// | ||
|
||
import Foundation | ||
import SpeziMedication | ||
|
||
struct IntakeMedication: Medication, Comparable { | ||
var localizedDescription: String | ||
var dosages: [IntakeDosage] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// | ||
// IntakeMedicationInstance.swift | ||
// Intake | ||
// | ||
// Created by Kate Callon on 2/17/24. | ||
// | ||
// | ||
// This source file is part of the Intake based on the Stanford Spezi Template Medication project | ||
// | ||
// SPDX-FileCopyrightText: 2023 Stanford University | ||
// | ||
// SPDX-License-Identifier: MIT | ||
// | ||
|
||
import Foundation | ||
import SpeziMedication | ||
|
||
struct IntakeMedicationInstance: MedicationInstance, MedicationInstanceInitializable { | ||
let id: UUID | ||
let type: IntakeMedication | ||
var dosage: IntakeDosage | ||
var schedule: Schedule | ||
|
||
init(type: IntakeMedication, dosage: IntakeDosage, schedule: Schedule) { | ||
self.id = UUID() | ||
self.type = type | ||
self.dosage = dosage | ||
self.schedule = schedule | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
// | ||
// IntakeMedicationViewModel.swift | ||
// Intake | ||
// | ||
// Created by Kate Callon on 2/17/24. | ||
// | ||
// | ||
// This source file is part of the Intake based on the Stanford Spezi Template Medication project | ||
// | ||
// SPDX-FileCopyrightText: 2023 Stanford University | ||
// | ||
// SPDX-License-Identifier: MIT | ||
// | ||
|
||
import Foundation | ||
import class ModelsR4.MedicationRequest | ||
import Spezi | ||
import SpeziFHIR | ||
import SpeziMedication | ||
import SwiftUI | ||
|
||
@Observable | ||
class IntakeMedicationSettingsViewModel: Module, MedicationSettingsViewModel, CustomStringConvertible { | ||
var medicationInstances: Set<IntakeMedicationInstance> = [] | ||
let medicationOptions: Set<IntakeMedication> | ||
|
||
var description: String { | ||
guard !medicationInstances.isEmpty else { | ||
return "No Medications" | ||
} | ||
|
||
return medicationInstances | ||
.map { medicationInstance in | ||
let scheduleDescription: String | ||
switch medicationInstance.schedule.frequency { | ||
case let .regularDayIntervals(dayInterval): | ||
scheduleDescription = "RegularDayIntervals: \(dayInterval)" | ||
case let .specificDaysOfWeek(weekdays): | ||
scheduleDescription = "SpecificDaysOfWeek: \(weekdays)" | ||
case .asNeeded: | ||
scheduleDescription = "AsNeeded" | ||
} | ||
|
||
return "\(medicationInstance.type.localizedDescription) - \(medicationInstance.dosage.localizedDescription) - \(scheduleDescription)" | ||
} | ||
.joined(separator: ", ") | ||
} | ||
|
||
init(existingMedications: [FHIRResource]) { // swiftlint:disable:this function_body_length | ||
self.medicationOptions = [ | ||
IntakeMedication( | ||
localizedDescription: "Hydrochlorothiazide 25 MG Oral Tablet", | ||
dosages: [ | ||
IntakeDosage(localizedDescription: "25 MG") | ||
] | ||
), | ||
IntakeMedication( | ||
localizedDescription: "Acetaminophen 160 MG Chewable Tablet", | ||
dosages: [ | ||
IntakeDosage(localizedDescription: "160 MG") | ||
] | ||
), | ||
IntakeMedication( | ||
localizedDescription: "Fexofenadine hydrochloride 30 MG Oral Tablet", | ||
dosages: [ | ||
IntakeDosage(localizedDescription: "30 MG") | ||
] | ||
), | ||
IntakeMedication( | ||
localizedDescription: "NDA020800 0.3 ML Epinephrine 1 MG/ML Auto-Injector", | ||
dosages: [ | ||
IntakeDosage(localizedDescription: "0.3ML / 1 MG/ML") | ||
] | ||
) | ||
] | ||
|
||
var foundMedications: [IntakeMedicationInstance] = [] | ||
if !existingMedications.isEmpty { | ||
for medication in existingMedications { | ||
for option in medicationOptions where option.localizedDescription == medication.displayName { | ||
var medSchedule: SpeziMedication.Schedule | ||
let medRequest = medicationRequest(resource: medication) | ||
if case .boolean(let asNeeded) = medRequest?.dosageInstruction?.first?.asNeeded { | ||
if let asNeededbool = asNeeded.value?.bool { | ||
if asNeededbool { | ||
medSchedule = SpeziMedication.Schedule(frequency: .asNeeded) | ||
} else { | ||
let intValue: Int | ||
let interval = medRequest?.dosageInstruction?.first?.timing?.repeat?.period?.value?.decimal | ||
if let interval = interval { | ||
intValue = interval.int | ||
} else { | ||
continue | ||
} | ||
medSchedule = Schedule(frequency: .regularDayIntervals(intValue)) | ||
} | ||
|
||
guard let firstDosage = option.dosages.first else { | ||
continue | ||
} | ||
|
||
let intakeMedicationInstance = IntakeMedicationInstance( | ||
type: option, | ||
dosage: firstDosage, | ||
schedule: medSchedule | ||
) | ||
foundMedications.append(intakeMedicationInstance) | ||
} | ||
} | ||
} | ||
} | ||
self.medicationInstances = Set(foundMedications) | ||
} | ||
} | ||
func persist(medicationInstances: Set<IntakeMedicationInstance>) async throws { | ||
self.medicationInstances = medicationInstances | ||
} | ||
|
||
func medicationRequest(resource: FHIRResource) -> MedicationRequest? { | ||
guard case let .r4(resource) = resource.versionedResource, | ||
let medicationRequest = resource as? ModelsR4.MedicationRequest else { | ||
return nil | ||
} | ||
return medicationRequest | ||
} | ||
} | ||
|
||
extension Decimal { | ||
var int: Int { | ||
let intVal = NSDecimalNumber(decimal: self).intValue // swiftlint:disable:this legacy_objc_type | ||
return intVal | ||
} | ||
} |
Oops, something went wrong.