-
Notifications
You must be signed in to change notification settings - Fork 1
/
R01Model.cls
199 lines (159 loc) · 5.98 KB
/
R01Model.cls
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
Class sdf.connectors.interop.datapipe.model.R01Model Extends (%RegisteredObject, %XML.Adaptor, %JSON.Adaptor, DataPipe.Model)
{
Property MsgId As %String;
Property PatientId As %String;
Property Name As %String;
Property Surname1 As %String;
Property Surname2 As %String;
Property DOB As %Date;
Property AdministrativeSex As %String;
Property SSN As %String;
Property ObxValues As %ArrayOfDataTypes;
Property ObxUnits As %ArrayOfDataTypes;
Property ObxDateTime As %ArrayOfDataTypes;
Property ObxDataType As %ArrayOfDataTypes;
/// Serialize to json
Method Serialize(Output stream) As %Status
{
set ret = $$$OK
try {
// serialize to json
$$$ThrowOnError(..%JSONExportToStream(.tmpStream))
// format json
set formatter = ##class(%JSON.Formatter).%New()
$$$ThrowOnError(formatter.FormatToStream(tmpStream, .stream))
} catch ex {
set ret = ex.AsStatus()
}
quit ret
}
ClassMethod Deserialize(stream As %Stream.Object, Output obj) As %Status
{
set ret = $$$OK
try {
set obj = ..%New()
$$$ThrowOnError(obj.%JSONImport(stream, .obj))
} catch ex {
set ret = ex.AsStatus()
}
quit ret
}
Method Normalize(Output obj As DataPipe.Model) As %Status
{
set ret = $$$OK
try {
// call normalizaton data transform
set sc = $classmethod("sdf.connectors.interop.datapipe.dt.R01Normalize", "Transform", $this, .obj)
$$$ThrowOnError(sc)
} catch ex {
set ret = ex.AsStatus()
}
quit ret
}
/// Validate model
Method Validate(Output errorList As %List) As %Status
{
#define AddError(%list, %code, %desc) set error = ##class(DataPipe.Data.ErrorInfo).%New() set error.Code=%code set error.Desc=%desc do %list.Insert(error)
set ret = $$$OK
try {
set errorList = ##class(%ListOfObjects).%New()
// administrative sex
if ..AdministrativeSex="" $$$AddError(errorList, "VGEN", "AdministrativeSex required")
// date of birth
if ..DOB="" {
$$$AddError(errorList, "V001", "DOB required")
}
else {
set yearDOB = $extract($zdate(..DOB,8),1,4)
if (yearDOB < 1930) $$$AddError(errorList, "V002", "DOB must be greater than 1930")
if (yearDOB < 1983) $$$AddError(errorList, "W083", "Warning! Older than 1983")
}
// model is invalid if errors (not warnings) found
for i=1:1:errorList.Count() {
set error = errorList.GetAt(i)
set errorCode = error.Code
// in this sample model, all warnings start with "W"
if errorCode'["W" {
$$$ThrowStatus($$$ERROR($$$GeneralError, "Invalid"))
}
}
} catch ex {
set ret = ex.AsStatus()
}
quit ret
}
/// Return the Business Operation name that will run the operation with the model
/// Each Business Operation can be used to hold different queues
Method GetOperation() As %Status
{
quit "R01 Operation"
}
/// Run final operation with the model
/// This method can be used to persit data from the model to an operational data store
Method RunOperation(Output errorList As %List, Output log As %Stream.Object, bOperation As Ens.BusinessOperation = "") As %Status
{
#define AddError(%list, %code, %desc) set error = ##class(DataPipe.Data.ErrorInfo).%New() set error.Code=%code set error.Desc=%desc do %list.Insert(error)
#define AddLog(%log, %msg) do %log.WriteLine("["_$zdt($h,3)_"] "_%msg)
set errorList = ##class(%ListOfObjects).%New()
set log = ##class(%Stream.GlobalCharacter).%New()
set ret = $$$OK
try {
TSTART
$$$AddLog(log, "Transaction Started")
// patient
$$$ThrowOnError(##class(sdf.data.Patient).GetByIdentifier(..PatientId, .patientObj))
if '$isobject(patientObj) {
$$$AddLog(log, "Patient "_..PatientId_" does not exist. Creating patient")
set patientObj = ##class(sdf.data.Patient).%New()
}
set patientObj.Identifier = ..PatientId
set patientObj.FirstName = ..Name
set patientObj.AdministrativeSex = ..AdministrativeSex
set patientObj.LastName = ..Surname1
set patientObj.BirthDate = ..DOB
// observations
set obxCode=""
for {
set obxValue = ..ObxValues.GetNext(.obxCode)
quit:obxCode=""
set obxUnits = ..ObxUnits.GetAt(obxCode)
set obxDateTime = ..ObxDateTime.GetAt(obxCode)
set obxDataType = ..ObxDataType.GetAt(obxCode)
set obxObj = ##class(sdf.data.Observation).%New()
set obxObj.Code = obxCode
set obxObj.Status = "F"
if obxDataType = "NM" {
set obxObj.ValueNM = obxValue
} else {
set obxObj.ValueST = obxValue
}
set obxObj.Units = obxUnits
set obxObj.TimeStamp = obxDateTime
do patientObj.Observations.Insert(obxObj)
$$$AddLog(log, "Adding ("_obxCode_") observation")
}
$$$ThrowOnError(patientObj.%Save(1))
TCOMMIT
$$$AddLog(log, "Transaction Commited")
/*
// you can send messages to other production components (while you are not on an open transaction)
if $isobject(bOperation) {
set req = ##class(sdf.connectors.interop.msg.TelegramMsgReq).%New()
set req.text = "Patient ("_..PatientId_") ingested! 🌡️ "_$number(..ObxValues.GetAt("BodyTemp"),2)_" "_..ObxUnits.GetAt("BodyTemp")
$$$ThrowOnError(bOperation.SendRequestAsync("TelegramSendMessage", req))
}
*/
} catch ex {
TROLLBACK
$$$AddLog(log, "Rollback!")
set ret = ex.AsStatus()
$$$AddLog(log, "Error catched: "_$system.Status.GetOneStatusText(ret))
// include exception errors into errorList
do $system.Status.DecomposeStatus(ret, .errors)
for i=1:1:errors {
$$$AddError(errorList, "Exception", errors(i))
}
}
quit ret
}
}