-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathReportBundle.swift
143 lines (110 loc) · 3.93 KB
/
ReportBundle.swift
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//
// InstrumentResult.swift
// SMARTMarkers
//
// Created by raheel on 4/4/24.
// Copyright © 2024 Boston Children's Hospital. All rights reserved.
//
import Foundation
import SMART
/**
SubmissionBundle holds newly created reports for submission to the FHIR
One `InstrumentResult` created for each PGHD task session
*/
public class InstrumentResult {
public enum ResultStatus: String, CustomStringConvertible {
public var description: String {
get {
switch self {
case .readyToSubmit:
return "Ready"
case .submitted:
return "Submitted"
case .failedToSubmit:
return "Failed to Submit"
case .discarded:
return "Discarded"
}
}
}
case readyToSubmit
case submitted
case failedToSubmit
case discarded
}
/// User session task identifier
public final let taskId: String
/// `SMART.Bundle` generated from the task session
public final var bundle: SMART.Bundle?
/// Associated request identifier; (if any)
public final let requestId: String?
/// Boolean to indicate if "ok" to submit
public var canSubmit: Bool = false
/// Metrics (start time, end time and conclusion
public var metric: TaskAttempt
/// Submission status
public var status: ResultStatus {
for resource in resources() ?? [] {
if resource.id == nil {
return .readyToSubmit
}
}
return .submitted
}
/**
Designated Initializer
- parameter taskId: User task session identifier
- parameter bundle: `SMART.Bundle` generated from the task session
- parameter requestId: Optional request identifier
*/
public init(taskId: String, bundle: SMART.Bundle?, metric: TaskAttempt, requestId: String? = nil) {
self.taskId = taskId
self.bundle = bundle
self.requestId = requestId
self.metric = metric
}
/**
Convinience methods
*/
public func reports() -> [Report]? {
bundle?.entry?.compactMap({ $0.resource as? Report })
}
public func resources() -> [DomainResource]? {
bundle?.entry?.compactMap({ $0.resource as? DomainResource })
}
convenience public init?(serialized: [String: Any]) throws {
guard
let taskId = serialized["taskId"] as? String,
let metricsJson = serialized["metric"] as? [String: Any] else {
throw SMError.undefined(description: "InstrumentResult cannot be initialized; invalid format")
}
let metr = try TaskAttempt(serialized: metricsJson)
var context = FHIRInstantiationContext(strict: false)
var bundl: SMART.Bundle?
if let gD = serialized["generatedData"] as? [[String: Any]] {
let generatedData = gD.compactMap({ (json) -> DomainResource? in
FHIRAbstractResource.instantiate(from: json, owner: nil, context: &context) as? DomainResource
})
if !generatedData.isEmpty {
bundl = SMART.Bundle.sm_with(generatedData)
}
}
self.init(
taskId: taskId,
bundle: bundl,
metric: metr,
requestId: nil)
}
public func serialize(errors: inout [Error]?) -> [String: Any]? {
var json: [String: Any] = [
"taskId": self.taskId
]
var errors = [FHIRValidationError]()
if let resources = self.resources()?
.compactMap ({ $0.asJSON(errors: &errors) }) {
json["generatedData"] = resources
}
json["metric"] = metric.serialize()
return json
}
}