ez7gen 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/ez7gen +6 -0
- data/lib/ez7gen.rb +23 -0
- data/lib/ez7gen/config/schema/2.4/2.4.HL7.xml +13904 -0
- data/lib/ez7gen/config/schema/2.4/VAZ2.4.HL7.xml +3085 -0
- data/lib/ez7gen/config/schema/2.4/added/coded-tables.xml +730 -0
- data/lib/ez7gen/config/schema/2.4/rules/2.4.HL7.yml +4 -0
- data/lib/ez7gen/config/schema/2.4/rules/VAZ2.4.HL7.yml +6 -0
- data/lib/ez7gen/config/schema/2.5/2.5.HL7.xml +10008 -0
- data/lib/ez7gen/config/schema/2.5/VAZ2.5.HL7.xml +7 -0
- data/lib/ez7gen/config/schema/2.5/added/coded-tables.xml +549 -0
- data/lib/ez7gen/config/schema/readme.txt +0 -0
- data/lib/ez7gen/config/templates/2.4/eiv table update-mfn_m01 20151201.xml +416 -0
- data/lib/ez7gen/config/templates/2.4/eiv table update-mfn_y01.xml +416 -0
- data/lib/ez7gen/config/templates/2.4/eiv-ec-MFN_X01_reg request 20160126.xml +659 -0
- data/lib/ez7gen/config/templates/2.4/examples/ADT_A60.txt +69 -0
- data/lib/ez7gen/config/templates/2.4/examples/eiv table update-mfn_m01 20151201.txt +21 -0
- data/lib/ez7gen/config/templates/2.4/examples/mhvsm_dss_units-query_qbp_q13-qbp_q13.txt +26 -0
- data/lib/ez7gen/config/templates/2.4/examples/mhvsm_ecs_procedures_query_qbp_q13-qbp_q13.txt +26 -0
- data/lib/ez7gen/config/templates/2.4/examples/mhvsm_patient eligibility_response-rsp_k11-080714.txt +44 -0
- data/lib/ez7gen/config/templates/2.4/examples/mhvsm_standardhl7lib_diagnosis_query_qbp_q11-qbp_q11.txt +21 -0
- data/lib/ez7gen/config/templates/2.4/examples/mhvsm_standardhl7lib_diagnosis_response_rsp_k11-rsp_k11.txt +42 -0
- data/lib/ez7gen/config/templates/2.4/examples/mhvsm_standardhl7lib_dss_units_response_rtb_k13-rtb_k13.txt +49 -0
- data/lib/ez7gen/config/templates/2.4/examples/mhvsm_standardhl7lib_ecs_filer_request_dft_p03-dft_p03-080714.txt +31 -0
- data/lib/ez7gen/config/templates/2.4/examples/mhvsm_standardhl7lib_ecs_filer_response_ack_p03-ack_p03.txt +21 -0
- data/lib/ez7gen/config/templates/2.4/examples/mhvsm_standardhl7lib_esc_procedures_response_rtb_k13-rtb_k13.txt +40 -0
- data/lib/ez7gen/config/templates/2.4/examples/mhvsm_standardhl7lib_patient_eclass_query_qbp_q11-qbp_q11.txt +21 -0
- data/lib/ez7gen/config/templates/2.4/examples/mhvsm_standardhl7lib_patient_problems_query_qbp_q11-qbp_q11.txt +21 -0
- data/lib/ez7gen/config/templates/2.4/examples/mhvsm_standardhl7lib_patinet_problems_response_rsp_k11-rsp_k11.txt +33 -0
- data/lib/ez7gen/config/templates/2.4/examples/orur01rvbecv2.txt +31 -0
- data/lib/ez7gen/config/templates/2.4/examples/sqwm vitals-oru_ro1.txt +52 -0
- data/lib/ez7gen/config/templates/2.4/examples/vista sqwm-adt_a60.txt +40 -0
- data/lib/ez7gen/config/templates/2.4/mhvsm_dss_units_query_qbp_q13-qbp_q13.xml +312 -0
- data/lib/ez7gen/config/templates/2.4/mhvsm_ecs_procedures_query_qbp_q13-qbp_q13.xml +314 -0
- data/lib/ez7gen/config/templates/2.4/mhvsm_patient eligibility_response-rsp_k11-080714.xml +640 -0
- data/lib/ez7gen/config/templates/2.4/mhvsm_standardhl7lib_diagnosis_query_qbp_q11-qbp_q11.xml +284 -0
- data/lib/ez7gen/config/templates/2.4/mhvsm_standardhl7lib_diagnosis_response_rsp_k11-rsp_k11-rsp_k11.xml +563 -0
- data/lib/ez7gen/config/templates/2.4/mhvsm_standardhl7lib_dss_units_response_rtb_k13-rtb_k13-rtb_k13.xml +365 -0
- data/lib/ez7gen/config/templates/2.4/mhvsm_standardhl7lib_ecs_filer_request_dft_p03-dft_p03-080714.xml +2172 -0
- data/lib/ez7gen/config/templates/2.4/mhvsm_standardhl7lib_ecs_filer_response_ack_p03-ack_p03.xml +269 -0
- data/lib/ez7gen/config/templates/2.4/mhvsm_standardhl7lib_ecs_procedures_response_rtb_k13-rtb_k13-rtb_k13.xml +354 -0
- data/lib/ez7gen/config/templates/2.4/mhvsm_standardhl7lib_patient_eclass_query_qbp_q11-qbp_q11.xml +284 -0
- data/lib/ez7gen/config/templates/2.4/mhvsm_standardhl7lib_patient_problems_query_qbp_q11-qbp_q11.xml +282 -0
- data/lib/ez7gen/config/templates/2.4/mhvsm_standardhl7lib_patient_problems_response_rsp_k11-rsp_k11-rsp_k11.xml +565 -0
- data/lib/ez7gen/config/templates/2.4/orur01rvbecv2.xml +1529 -0
- data/lib/ez7gen/config/templates/2.4/sqwm vitals-oru_r01.xml +2975 -0
- data/lib/ez7gen/config/templates/2.4/vista sqwm-adt_a60.xml +1360 -0
- data/lib/ez7gen/message_factory.rb +142 -0
- data/lib/ez7gen/msg_error_handler.rb +33 -0
- data/lib/ez7gen/profile_parser.rb +321 -0
- data/lib/ez7gen/resources/properties-with-comments.yml +51 -0
- data/lib/ez7gen/resources/properties.yml +325 -0
- data/lib/ez7gen/service/2.4/dynamic_field_generator.rb +45 -0
- data/lib/ez7gen/service/2.4/field_generator.rb +1586 -0
- data/lib/ez7gen/service/2.5/field_generator.rb +75 -0
- data/lib/ez7gen/service/base_field_generator.rb +451 -0
- data/lib/ez7gen/service/segment_generator.rb +218 -0
- data/lib/ez7gen/service/segment_picker.rb +147 -0
- data/lib/ez7gen/service/template_generator.rb +213 -0
- data/lib/ez7gen/service/type_aware_field_generator.rb +1583 -0
- data/lib/ez7gen/service/utils.rb +75 -0
- data/lib/ez7gen/structure_parser.rb +331 -0
- data/lib/ez7gen/version.rb +38 -0
- data/test/Additional Tables with values_v1.1.txt +1653 -0
- data/test/added_shema_test.rb +143 -0
- data/test/app-tmp.rb +225 -0
- data/test/at.txt +1 -0
- data/test/backburner.zip +0 -0
- data/test/codes.txt +262 -0
- data/test/codes1.txt +1240 -0
- data/test/data_types_exploration_test.rb +213 -0
- data/test/dynamic_field_generated_test.rb +292 -0
- data/test/message_factory_24_custom_test.rb +648 -0
- data/test/message_factory_25_test.rb +50 -0
- data/test/message_factory_adm_test.rb +558 -0
- data/test/message_factory_gen_test.rb +63 -0
- data/test/message_factory_lab_test.rb +107 -0
- data/test/message_factory_pharm_test.rb +121 -0
- data/test/message_factory_template_24_test.rb +730 -0
- data/test/message_factory_test.rb +220 -0
- data/test/msg_error_handler_test.rb +59 -0
- data/test/profile_parser_test.rb +542 -0
- data/test/quick_run.rb +880 -0
- data/test/segment_generator_test.rb +656 -0
- data/test/segment_picker_test.rb +279 -0
- data/test/structrure_parser_test.rb +355 -0
- data/test/template_generator_test.rb +164 -0
- data/test/type_aware_field_generator_test.rb +582 -0
- data/test/utils_test.rb +97 -0
- metadata +215 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#web.install.dir: "/Users/romansova/RubymineProjects/ez7gen-staged/"
|
|
2
|
+
#web.install.dir: C:/Web-Ez7Gen/ez7gen-web
|
|
3
|
+
person.names.first: [Odysseus,Xander,Jameson,Brian,Yoshio,Connor,Kasper,Macon,Mannix,Cyrus,Jeremy,Channing,Raja,Daniel,Roth,Ezekiel,Martin,Cameron,Elmo,Omar,Holmes,Ulric,Nissim,Colton,Herman,Luke,Thaddeus,Leroy,Baxter,Tanner,Caleb,Salvador,Adrian,Reuben,Ronan,Burton,Kermit,Kareem,Tobias,Cedric,Flynn,Uriel,Barry,Amal,Orson,Arsenio,Vladimir,Thane,Nissim,Alden,Stewart,Plato,Prescott,Xenos,David,Castor,Carson,Brian,Jarrod,Stuart,Herman,Tobias,Lucius,Fitzgerald,Malachi,Theodore,Eaton,Arsenio,Gannon,Burton,Zahir,Caleb,Preston,Ivor,Martin,Aidan,Octavius,Ali,Aristotle,Ivor,Chadwick,Hilel,Octavius,Victor,Noah,Leo,Cameron,Ross,Lionel,Howard,Armand,Solomon,Darius,Edan,Tad,Forrest,Allen,Macon,Kasimir,Brian]
|
|
4
|
+
person.names.last: [Daugherty,Small,Webster,Reilly,Key,Velazquez,Holder,Larson,Watkins,Holden,Davenport,Kirkland,Decker,Pate,Shepherd,Love,Robles,Strong,Mitchell,Burgess,Hewitt,Rush,Watkins,Merritt,Howell,Munoz,Zimmerman,Hammond,Hickman,Wilkinson,Lane,Koch,Hoover,Stevens,Stephens,Woodward,Blanchard,Vinson,Rodriquez,Oneal,Blake,Pennington,Pittman,Mills,Byers,Gilliam,Browning,Thompson,Patrick,Potts,Zimmerman,Larson,Bullock,Rocha,Prince,Kaufman,Obrien,Bauer,Calderon,Vance,Castillo,Flores,Ford,Mcgee,Leon,Mckee,Carver,Hardy,Mcmillan,Strong,Franks,Cooke,Boyer,Meyer,Gates,Madden,William,Riggs,Walker,Rosa,Simmons,Dunlap,Acosta,Espinoza,Beasley,Ramirez,Farrell,Ratliff,Caldwell,Harper,Wiley,Mendoza,Cain,Blankenship,Buck,Marquez,Stevenson,Gates,Carpenter,Fletcher]
|
|
5
|
+
dmgr.gender: [M,F]
|
|
6
|
+
address.streetNames: [504 Honey Elk Wynd,7608 Silent Glen,7741 Foggy Pond Jetty,7061 Iron Blossom Ridge,5777 Fallen Panda Expressway]
|
|
7
|
+
address.cities: [Oatmeal,Owl,Dollar Settlement,Saint-Quentin,Ragtown]
|
|
8
|
+
address.states: [TN,MS,TN,MS,GA]
|
|
9
|
+
address.states.all: [AL,AK,AZ,AR,CA,CO,CT,DE,FL,GA,HI,ID,IL,IN,IA,KS,KY,LA,ME,MD,MA,MI,MN,MS,MO,MT,NE,NV,NH,NJ,NM,NY,NC,ND,OH,OK,OR,PA,RI,SC,SD,TN,TX,UT,VT,VA,WA,WV,WI,WY]
|
|
10
|
+
address.zips: [37166-9572,38889-6760,37326-6978,39377-7406,39833-8563]
|
|
11
|
+
address.countries: [USA,USA,USA,USA,USA]
|
|
12
|
+
address.phones: [(931)872-7634,(601)110-8688,(731)538-7434,(662)120-6474,(470)446-7282]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
#job Titles []Accountant, Application Developer, Attorney, Engineer, Dentist,Nurse Practitioner, Paramedic, Pharmacist, Physician] CT1.49 Job Title
|
|
16
|
+
#Person Class Codes 193200000X Multi-specialty,193400000X Single specialty,208D00000X General practice,207R00000X Internal medicine,208600000X Surgery #ROL.9 Provider Type (both the code and the description need to be populated)
|
|
17
|
+
|
|
18
|
+
#ICD 10 Observation Codes
|
|
19
|
+
#R71.8 Other abnormality of red blood cells,
|
|
20
|
+
#R82.8 Abnormal findings on cytological and histological examination of urine,
|
|
21
|
+
#R81 Glycosuria,
|
|
22
|
+
#R82.99 Other abnormal findings in urine,
|
|
23
|
+
#R79.0 Abnormal level of blood mineral,
|
|
24
|
+
#R03.1 Nonspecific low blood-pressure reading,
|
|
25
|
+
#R78.79 Finding of abnormal level of heavy metals in blood
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
#OBX.3 Observation Identifier (both the code and the description need to be populated)
|
|
29
|
+
#ICD 10 Allergen Codes
|
|
30
|
+
codes.allergens.icd10:
|
|
31
|
+
T78.40XA: Allergy unspecified initial encounter
|
|
32
|
+
T78.40XD: Allergy unspecified subsequent encounter
|
|
33
|
+
Z91.048: Other nonmedicinal substance allergy status
|
|
34
|
+
Z91.09: Other allergy status, other than to drugs and biological substances
|
|
35
|
+
Z91.013: Allergy to seafood
|
|
36
|
+
Z91.010: Allergy to peanuts
|
|
37
|
+
Z88.0: Allergy status to penicillin
|
|
38
|
+
Z91.038: Other insect allergy status
|
|
39
|
+
Z91.030: Bee Allergy status
|
|
40
|
+
|
|
41
|
+
#AL1.3 Allergen Code/Mnemonic/ Description (both the code and the description need to be populated)
|
|
42
|
+
codes.allergens:
|
|
43
|
+
#ICD 10: Allergy Reaction Codes
|
|
44
|
+
L50.0: Hives
|
|
45
|
+
R11.2: Nausea with vomiting
|
|
46
|
+
R68.2: Dry mouth
|
|
47
|
+
K52.2: Diarrhea
|
|
48
|
+
J30.9: Itching
|
|
49
|
+
#AL1.5 Allergy Reaction Code #(just the code)
|
|
50
|
+
allergens.yn: [Y,N]
|
|
51
|
+
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
---
|
|
2
|
+
web.install.dir: "../resources"
|
|
3
|
+
logger.level: 2
|
|
4
|
+
logger.comments: "DEBUG = 0; INFO = 1; WARN = 2; ERROR = 3; FATAL = 4; UNKNOWN = 5"
|
|
5
|
+
person.names.first:
|
|
6
|
+
- Odysseus
|
|
7
|
+
- Xander
|
|
8
|
+
- Jameson
|
|
9
|
+
- Brian
|
|
10
|
+
- Yoshio
|
|
11
|
+
- Connor
|
|
12
|
+
- Kasper
|
|
13
|
+
- Macon
|
|
14
|
+
- Mannix
|
|
15
|
+
- Cyrus
|
|
16
|
+
- Jeremy
|
|
17
|
+
- Channing
|
|
18
|
+
- Raja
|
|
19
|
+
- Daniel
|
|
20
|
+
- Roth
|
|
21
|
+
- Ezekiel
|
|
22
|
+
- Martin
|
|
23
|
+
- Cameron
|
|
24
|
+
- Elmo
|
|
25
|
+
- Omar
|
|
26
|
+
- Holmes
|
|
27
|
+
- Ulric
|
|
28
|
+
- Nissim
|
|
29
|
+
- Colton
|
|
30
|
+
- Herman
|
|
31
|
+
- Luke
|
|
32
|
+
- Thaddeus
|
|
33
|
+
- Leroy
|
|
34
|
+
- Baxter
|
|
35
|
+
- Tanner
|
|
36
|
+
- Caleb
|
|
37
|
+
- Salvador
|
|
38
|
+
- Adrian
|
|
39
|
+
- Reuben
|
|
40
|
+
- Ronan
|
|
41
|
+
- Burton
|
|
42
|
+
- Kermit
|
|
43
|
+
- Kareem
|
|
44
|
+
- Tobias
|
|
45
|
+
- Cedric
|
|
46
|
+
- Flynn
|
|
47
|
+
- Uriel
|
|
48
|
+
- Barry
|
|
49
|
+
- Amal
|
|
50
|
+
- Orson
|
|
51
|
+
- Arsenio
|
|
52
|
+
- Vladimir
|
|
53
|
+
- Thane
|
|
54
|
+
- Nissim
|
|
55
|
+
- Alden
|
|
56
|
+
- Stewart
|
|
57
|
+
- Plato
|
|
58
|
+
- Prescott
|
|
59
|
+
- Xenos
|
|
60
|
+
- David
|
|
61
|
+
- Castor
|
|
62
|
+
- Carson
|
|
63
|
+
- Brian
|
|
64
|
+
- Jarrod
|
|
65
|
+
- Stuart
|
|
66
|
+
- Herman
|
|
67
|
+
- Tobias
|
|
68
|
+
- Lucius
|
|
69
|
+
- Fitzgerald
|
|
70
|
+
- Malachi
|
|
71
|
+
- Theodore
|
|
72
|
+
- Eaton
|
|
73
|
+
- Arsenio
|
|
74
|
+
- Gannon
|
|
75
|
+
- Burton
|
|
76
|
+
- Zahir
|
|
77
|
+
- Caleb
|
|
78
|
+
- Preston
|
|
79
|
+
- Ivor
|
|
80
|
+
- Martin
|
|
81
|
+
- Aidan
|
|
82
|
+
- Octavius
|
|
83
|
+
- Ali
|
|
84
|
+
- Aristotle
|
|
85
|
+
- Ivor
|
|
86
|
+
- Chadwick
|
|
87
|
+
- Hilel
|
|
88
|
+
- Octavius
|
|
89
|
+
- Victor
|
|
90
|
+
- Noah
|
|
91
|
+
- Leo
|
|
92
|
+
- Cameron
|
|
93
|
+
- Ross
|
|
94
|
+
- Lionel
|
|
95
|
+
- Howard
|
|
96
|
+
- Armand
|
|
97
|
+
- Solomon
|
|
98
|
+
- Darius
|
|
99
|
+
- Edan
|
|
100
|
+
- Tad
|
|
101
|
+
- Forrest
|
|
102
|
+
- Allen
|
|
103
|
+
- Macon
|
|
104
|
+
- Kasimir
|
|
105
|
+
- Brian
|
|
106
|
+
person.names.last:
|
|
107
|
+
- Daugherty
|
|
108
|
+
- Small
|
|
109
|
+
- Webster
|
|
110
|
+
- Reilly
|
|
111
|
+
- Key
|
|
112
|
+
- Velazquez
|
|
113
|
+
- Holder
|
|
114
|
+
- Larson
|
|
115
|
+
- Watkins
|
|
116
|
+
- Holden
|
|
117
|
+
- Davenport
|
|
118
|
+
- Kirkland
|
|
119
|
+
- Decker
|
|
120
|
+
- Pate
|
|
121
|
+
- Shepherd
|
|
122
|
+
- Love
|
|
123
|
+
- Robles
|
|
124
|
+
- Strong
|
|
125
|
+
- Mitchell
|
|
126
|
+
- Burgess
|
|
127
|
+
- Hewitt
|
|
128
|
+
- Rush
|
|
129
|
+
- Watkins
|
|
130
|
+
- Merritt
|
|
131
|
+
- Howell
|
|
132
|
+
- Munoz
|
|
133
|
+
- Zimmerman
|
|
134
|
+
- Hammond
|
|
135
|
+
- Hickman
|
|
136
|
+
- Wilkinson
|
|
137
|
+
- Lane
|
|
138
|
+
- Koch
|
|
139
|
+
- Hoover
|
|
140
|
+
- Stevens
|
|
141
|
+
- Stephens
|
|
142
|
+
- Woodward
|
|
143
|
+
- Blanchard
|
|
144
|
+
- Vinson
|
|
145
|
+
- Rodriquez
|
|
146
|
+
- Oneal
|
|
147
|
+
- Blake
|
|
148
|
+
- Pennington
|
|
149
|
+
- Pittman
|
|
150
|
+
- Mills
|
|
151
|
+
- Byers
|
|
152
|
+
- Gilliam
|
|
153
|
+
- Browning
|
|
154
|
+
- Thompson
|
|
155
|
+
- Patrick
|
|
156
|
+
- Potts
|
|
157
|
+
- Zimmerman
|
|
158
|
+
- Larson
|
|
159
|
+
- Bullock
|
|
160
|
+
- Rocha
|
|
161
|
+
- Prince
|
|
162
|
+
- Kaufman
|
|
163
|
+
- Obrien
|
|
164
|
+
- Bauer
|
|
165
|
+
- Calderon
|
|
166
|
+
- Vance
|
|
167
|
+
- Castillo
|
|
168
|
+
- Flores
|
|
169
|
+
- Ford
|
|
170
|
+
- Mcgee
|
|
171
|
+
- Leon
|
|
172
|
+
- Mckee
|
|
173
|
+
- Carver
|
|
174
|
+
- Hardy
|
|
175
|
+
- Mcmillan
|
|
176
|
+
- Strong
|
|
177
|
+
- Franks
|
|
178
|
+
- Cooke
|
|
179
|
+
- Boyer
|
|
180
|
+
- Meyer
|
|
181
|
+
- Gates
|
|
182
|
+
- Madden
|
|
183
|
+
- William
|
|
184
|
+
- Riggs
|
|
185
|
+
- Walker
|
|
186
|
+
- Rosa
|
|
187
|
+
- Simmons
|
|
188
|
+
- Dunlap
|
|
189
|
+
- Acosta
|
|
190
|
+
- Espinoza
|
|
191
|
+
- Beasley
|
|
192
|
+
- Ramirez
|
|
193
|
+
- Farrell
|
|
194
|
+
- Ratliff
|
|
195
|
+
- Caldwell
|
|
196
|
+
- Harper
|
|
197
|
+
- Wiley
|
|
198
|
+
- Mendoza
|
|
199
|
+
- Cain
|
|
200
|
+
- Blankenship
|
|
201
|
+
- Buck
|
|
202
|
+
- Marquez
|
|
203
|
+
- Stevenson
|
|
204
|
+
- Gates
|
|
205
|
+
- Carpenter
|
|
206
|
+
- Fletcher
|
|
207
|
+
person.suffix:
|
|
208
|
+
- JR
|
|
209
|
+
- SR
|
|
210
|
+
- RET
|
|
211
|
+
- ESQ
|
|
212
|
+
person.prefix:
|
|
213
|
+
- DR
|
|
214
|
+
- PROF
|
|
215
|
+
- HON
|
|
216
|
+
- ATTY
|
|
217
|
+
dmgr.gender:
|
|
218
|
+
- M
|
|
219
|
+
- F
|
|
220
|
+
address.streetNames:
|
|
221
|
+
- 504 Honey Elk Wynd
|
|
222
|
+
- 7608 Silent Glen
|
|
223
|
+
- 7741 Foggy Pond Jetty
|
|
224
|
+
- 7061 Iron Blossom Ridge
|
|
225
|
+
- 5777 Fallen Panda Expressway
|
|
226
|
+
address.cities:
|
|
227
|
+
- Oatmeal
|
|
228
|
+
- Owl
|
|
229
|
+
- Dollar Settlement
|
|
230
|
+
- Saint-Quentin
|
|
231
|
+
- Ragtown
|
|
232
|
+
address.states:
|
|
233
|
+
- TN
|
|
234
|
+
- MS
|
|
235
|
+
- TN
|
|
236
|
+
- MS
|
|
237
|
+
- GA
|
|
238
|
+
address.states.all:
|
|
239
|
+
- AL
|
|
240
|
+
- AK
|
|
241
|
+
- AZ
|
|
242
|
+
- AR
|
|
243
|
+
- CA
|
|
244
|
+
- CO
|
|
245
|
+
- CT
|
|
246
|
+
- DE
|
|
247
|
+
- FL
|
|
248
|
+
- GA
|
|
249
|
+
- HI
|
|
250
|
+
- ID
|
|
251
|
+
- IL
|
|
252
|
+
- IN
|
|
253
|
+
- IA
|
|
254
|
+
- KS
|
|
255
|
+
- KY
|
|
256
|
+
- LA
|
|
257
|
+
- ME
|
|
258
|
+
- MD
|
|
259
|
+
- MA
|
|
260
|
+
- MI
|
|
261
|
+
- MN
|
|
262
|
+
- MS
|
|
263
|
+
- MO
|
|
264
|
+
- MT
|
|
265
|
+
- NE
|
|
266
|
+
- NV
|
|
267
|
+
- NH
|
|
268
|
+
- NJ
|
|
269
|
+
- NM
|
|
270
|
+
- NY
|
|
271
|
+
- NC
|
|
272
|
+
- ND
|
|
273
|
+
- OH
|
|
274
|
+
- OK
|
|
275
|
+
- OR
|
|
276
|
+
- PA
|
|
277
|
+
- RI
|
|
278
|
+
- SC
|
|
279
|
+
- SD
|
|
280
|
+
- TN
|
|
281
|
+
- TX
|
|
282
|
+
- UT
|
|
283
|
+
- VT
|
|
284
|
+
- VA
|
|
285
|
+
- WA
|
|
286
|
+
- WV
|
|
287
|
+
- WI
|
|
288
|
+
- WY
|
|
289
|
+
address.zips:
|
|
290
|
+
- 37166-9572
|
|
291
|
+
- 38889-6760
|
|
292
|
+
- 37326-6978
|
|
293
|
+
- 39377-7406
|
|
294
|
+
- 39833-8563
|
|
295
|
+
address.countries:
|
|
296
|
+
- USA
|
|
297
|
+
- USA
|
|
298
|
+
- USA
|
|
299
|
+
- USA
|
|
300
|
+
- USA
|
|
301
|
+
address.phones:
|
|
302
|
+
- "(931)872-7634"
|
|
303
|
+
- "(601)110-8688"
|
|
304
|
+
- "(731)538-7434"
|
|
305
|
+
- "(662)120-6474"
|
|
306
|
+
- "(470)446-7282"
|
|
307
|
+
codes.allergens.icd10:
|
|
308
|
+
T78.40XA: Allergy unspecified initial encounter
|
|
309
|
+
T78.40XD: Allergy unspecified subsequent encounter
|
|
310
|
+
Z91.048: Other nonmedicinal substance allergy status
|
|
311
|
+
Z91.09: Other allergy status, other than to drugs and biological substances
|
|
312
|
+
Z91.013: Allergy to seafood
|
|
313
|
+
Z91.010: Allergy to peanuts
|
|
314
|
+
Z88.0: Allergy status to penicillin
|
|
315
|
+
Z91.038: Other insect allergy status
|
|
316
|
+
Z91.030: Bee Allergy status
|
|
317
|
+
codes.allergens:
|
|
318
|
+
L50.0: Hives
|
|
319
|
+
R11.2: Nausea with vomiting
|
|
320
|
+
R68.2: Dry mouth
|
|
321
|
+
K52.2: Diarrhea
|
|
322
|
+
J30.9: Itching
|
|
323
|
+
allergens.yn:
|
|
324
|
+
- Y
|
|
325
|
+
- N
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
require_relative '../../profile_parser'
|
|
3
|
+
require_relative '../base_field_generator'
|
|
4
|
+
|
|
5
|
+
class DynamicFieldGenerator < BaseFieldGenerator
|
|
6
|
+
include Utils
|
|
7
|
+
|
|
8
|
+
# constructor
|
|
9
|
+
def initialize(pp)
|
|
10
|
+
super pp
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# base data types ["DT", "FT", "ID", "IS", "NM", "SI", "ST", "TM", "TN", "TX"]
|
|
14
|
+
|
|
15
|
+
def dynamic(name, map, force=false)
|
|
16
|
+
#check if the field is optional and randomly generate it of skip
|
|
17
|
+
return '' if(!generate?(map, force))
|
|
18
|
+
sub_types = []
|
|
19
|
+
value = []
|
|
20
|
+
|
|
21
|
+
@pp.xml.Export.Document.Category.locate('DataType').select{|it| it.attributes[:name] == name}.first.locate('DataSubType').each{ |it| sub_types << it.attributes}
|
|
22
|
+
|
|
23
|
+
sub_types.each{ |sub_type|
|
|
24
|
+
# check if field is required
|
|
25
|
+
begin
|
|
26
|
+
value << method(sub_type[:datatype]).call(sub_type,true)
|
|
27
|
+
rescue NameError => e
|
|
28
|
+
# puts e
|
|
29
|
+
$log.error("#{self.class.to_s}:#{__method__.to_s}") { e.message }
|
|
30
|
+
sub_values = dynamic(sub_type[:datatype], sub_type, true)
|
|
31
|
+
|
|
32
|
+
# TODO :remove trailing empty fields
|
|
33
|
+
# TODO: handle fields and subfields if it deeper then 3 levels in DR : "761&663^753&799"
|
|
34
|
+
value << sub_values.gsub(@@HAT,@@SUB)
|
|
35
|
+
puts sub_values
|
|
36
|
+
end
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return value.join(@@HAT)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
#
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
end
|
|
@@ -0,0 +1,1586 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
require_relative '../../profile_parser'
|
|
3
|
+
|
|
4
|
+
class FieldGenerator
|
|
5
|
+
# class TypeAwareFieldGenerator
|
|
6
|
+
include Utils
|
|
7
|
+
|
|
8
|
+
attr_accessor :yml,:pp
|
|
9
|
+
# @@UP_TO_3_DGTS = 1000 # up to 3 digits
|
|
10
|
+
@@REQ_LEN_3_DGTS = 3 #up to 3 digits
|
|
11
|
+
@@RANGE_INDICATOR = '...'
|
|
12
|
+
@@HAT = '^' # Component separator, aka hat
|
|
13
|
+
@@SUB ='&' # Subcomponent separator
|
|
14
|
+
# @@MONEY_FORMAT_INDICATORS = ['Money', 'Balance', 'Charge', 'Adjustment', 'Income', 'Amount', 'Payment','Cost']
|
|
15
|
+
# @@MONEY_FORMAT_REGEX = /\bMoney\b|\bBalance\b|\bCharge|\bAdjustment\b|\bIncome\b|\bAmount\b|\bPayment\b|\bCost\b|\bPercentage\b/
|
|
16
|
+
@@MONEY_FORMAT_REGEX = /\bMoney\b|\bBalance\b|\bCharge|\bAdjustment\b|\bIncome\b|\bAmount\b|\bPayment\b|\bCost\b/
|
|
17
|
+
@@PERCENT_FORMAT_REGEX = /\bPercentage\b|%/
|
|
18
|
+
@@INITIALS = ('A'..'Z').to_a
|
|
19
|
+
@@GENERAL_TEXT = 'Notes'
|
|
20
|
+
|
|
21
|
+
@@random = Random.new
|
|
22
|
+
|
|
23
|
+
# constructor
|
|
24
|
+
def initialize(parser, helper_parser=nil)
|
|
25
|
+
@pp = parser
|
|
26
|
+
# Coded table value lookup profiler. Only set for custom schemas.
|
|
27
|
+
# Custom schema has types which coming from the base schema but using coded tables from primary schema.
|
|
28
|
+
# Also primary schemas use base type coded tables.
|
|
29
|
+
@hp = helper_parser
|
|
30
|
+
|
|
31
|
+
# dirname = File.join(File.dirname(File.expand_path(__FILE__)),'../../resources/properties.yml')
|
|
32
|
+
propertiesFile = File.expand_path('../../../resources/properties.yml', __FILE__)
|
|
33
|
+
@yml = YAML.load_file propertiesFile
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# This method common for all field generators
|
|
37
|
+
def dt (dt, attrs)
|
|
38
|
+
self.method(dt).call(attrs)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
#Generate HL7 AD (address) data type.
|
|
42
|
+
def AD(map, force=false)
|
|
43
|
+
#check if the field is optional and randomly generate it of skip
|
|
44
|
+
return '' if(!generate?(map, force))
|
|
45
|
+
|
|
46
|
+
# match cities, states and zips
|
|
47
|
+
sample = @yml['address.states'].sample
|
|
48
|
+
idx = @yml['address.states'].index(sample) #index of random element
|
|
49
|
+
|
|
50
|
+
val=[]
|
|
51
|
+
#street address (ST) (ST)
|
|
52
|
+
val << @yml['address.streetNames'].sample
|
|
53
|
+
#other designation (ST)
|
|
54
|
+
val <<''
|
|
55
|
+
#city (ST)
|
|
56
|
+
val << @yml['address.cities'].at(idx)
|
|
57
|
+
#state or province (ST)
|
|
58
|
+
val << @yml['address.states'].at(idx)
|
|
59
|
+
#zip or postal code (ST)
|
|
60
|
+
val << @yml['address.zips'].at(idx)
|
|
61
|
+
#country (ID)
|
|
62
|
+
val << @yml['address.countries'].at(idx)
|
|
63
|
+
# address type (ID)
|
|
64
|
+
# ot5 her geographic designation (ST)
|
|
65
|
+
|
|
66
|
+
val.join(@@HAT)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Authorization information
|
|
70
|
+
def AUI(map, force=false)
|
|
71
|
+
#check if the field is optional and randomly generate it of skip
|
|
72
|
+
return '' if(!generate?(map, force))
|
|
73
|
+
|
|
74
|
+
# authorization number (ST)
|
|
75
|
+
ST(map, true)
|
|
76
|
+
# date (DT)
|
|
77
|
+
# source (ST)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
#Charge time
|
|
81
|
+
def CCD(map, force=false)
|
|
82
|
+
#check if the field is optional and randomly generate it of skip
|
|
83
|
+
return '' if(!generate?(map, force))
|
|
84
|
+
|
|
85
|
+
#<when to charge code (ID)>
|
|
86
|
+
ID(map, force=false)
|
|
87
|
+
# <date/time (TS)>
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
#Channel calibration parameters
|
|
91
|
+
def CCP(map, force=false)
|
|
92
|
+
#check if the field is optional and randomly generate it of skip
|
|
93
|
+
return '' if(!generate?(map, force))
|
|
94
|
+
|
|
95
|
+
# <channel calibration sensitivity correction (NM)>
|
|
96
|
+
NM(map,true)
|
|
97
|
+
# <channel calibration baseline (NM)>
|
|
98
|
+
# <channel calibration time skew (NM)>
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Channel definition
|
|
102
|
+
def CD(map, force=false)
|
|
103
|
+
# check if the field is optional and randomly generate it of skip
|
|
104
|
+
return '' if(!generate?(map, force))
|
|
105
|
+
|
|
106
|
+
#<channel identifier (WVI)>
|
|
107
|
+
WVI(map, force=true)
|
|
108
|
+
#<waveform source (WVS)>
|
|
109
|
+
# <channel sensitivity/units (SCU)>
|
|
110
|
+
#<channel calibration parameters (CCP)>
|
|
111
|
+
# <sampling frequency (NM)>
|
|
112
|
+
# <minimum/maximum data values (NR)>
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Generate HL7 CE (coded element) data type
|
|
116
|
+
def CE(map, force=false)
|
|
117
|
+
#check if the field is optional and randomly generate it of skip
|
|
118
|
+
return '' if(!generate?(map, force))
|
|
119
|
+
|
|
120
|
+
if(map[:max_length] && map[:max_length].to_i <3)
|
|
121
|
+
# if CE Element has lenght of 2 or less use only value
|
|
122
|
+
return ID(map, true)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
#TODO: Refactor this method
|
|
126
|
+
if (map[:description] == 'Role Action Reason' || map[:description] == 'Species Code' || map[:description] == 'Breed Code' || map[:description] == 'Production Class Code')
|
|
127
|
+
return '' #Per requirement, PID.35 – PID.38
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
val = []
|
|
131
|
+
# CE ce = (CE) map?.fld
|
|
132
|
+
codes = get_coded_map(map)
|
|
133
|
+
if(blank?(codes))
|
|
134
|
+
case map[:description]
|
|
135
|
+
when 'Allergen Code/Mnemonic/Description'
|
|
136
|
+
pair = yml['codes.allergens.icd10'].to_a.sample(1).to_h.first # randomly pick a pair
|
|
137
|
+
val<<pair.first
|
|
138
|
+
val<<pair.last
|
|
139
|
+
|
|
140
|
+
else
|
|
141
|
+
# TODO: only for elements that don't have look up table set the id randomly
|
|
142
|
+
# if codetable is empty
|
|
143
|
+
val << ((blank?(map[:codetable])) ? ID(map, true) : '')
|
|
144
|
+
end
|
|
145
|
+
else
|
|
146
|
+
#identifier (ST) (ST)
|
|
147
|
+
val<<codes[:value]
|
|
148
|
+
#text (ST)
|
|
149
|
+
val<<codes[:description]
|
|
150
|
+
#name of coding system (IS)
|
|
151
|
+
#alternate identifier (ST) (ST)
|
|
152
|
+
#alternate text (ST)
|
|
153
|
+
#name of alternate coding system (IS)
|
|
154
|
+
end
|
|
155
|
+
return val.join(@@HAT)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Coded element with formatted values
|
|
159
|
+
def CF(map, force=false)
|
|
160
|
+
#check if the field is optional and randomly generate it of skip
|
|
161
|
+
return '' if(!generate?(map, force))
|
|
162
|
+
|
|
163
|
+
# <identifier (ID)>
|
|
164
|
+
ID(map, true)
|
|
165
|
+
# <formatted text (FT)>
|
|
166
|
+
# <name of coding system (IS)>
|
|
167
|
+
# <alternate identifier (ID)>
|
|
168
|
+
# <alternate formatted text (FT)>
|
|
169
|
+
# <name of alternate coding system (IS)>
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
#Composite ID with check digit
|
|
173
|
+
def CK(map, force=false)
|
|
174
|
+
#check if the field is optional and randomly generate it of skip
|
|
175
|
+
return '' if(!generate?(map, force))
|
|
176
|
+
# <ID number (NM)>
|
|
177
|
+
NM(map,true)
|
|
178
|
+
# <check digit (NM)>
|
|
179
|
+
# <code identifying the check digit scheme employed (ID)>
|
|
180
|
+
# < assigning authority (HD)>
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
#Composite
|
|
184
|
+
def CM(map, force=false)
|
|
185
|
+
#check if the field is optional and randomly generate it of skip
|
|
186
|
+
return '' if(!generate?(map, force))
|
|
187
|
+
|
|
188
|
+
val=[]
|
|
189
|
+
# <penalty type (IS)>
|
|
190
|
+
val=IS(map,true)
|
|
191
|
+
# <penalty amount (NM)>
|
|
192
|
+
val<<NM({},true)
|
|
193
|
+
val.join(@@HAT)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# CN Composite ID number and name
|
|
197
|
+
# "<ID number (ST)> ^ <family name (FN)> ^ <given name (ST)> ^ < second and further given names or initials thereof (ST)> ^ <suffix (e.g., JR or III) (ST)> ^ <prefix (e.g. DR) (ST)> ^ <degree (e.g., MD) (IS)> ^ <source table (IS)> ^ <assigning authority(HD)>
|
|
198
|
+
# Replaced by XCN data type as of v 2.3"
|
|
199
|
+
|
|
200
|
+
# CNE Coded with no exceptions
|
|
201
|
+
def CNE(map, force=false)
|
|
202
|
+
#check if the field is optional and randomly generate it of skip
|
|
203
|
+
return '' if(!generate?(map, force))
|
|
204
|
+
|
|
205
|
+
# <identifier (ST)> ^ <text (ST)>
|
|
206
|
+
ST(map, true)
|
|
207
|
+
# <name of coding system (IS)>
|
|
208
|
+
# <alternate identifier(ST)>
|
|
209
|
+
# <alternate text (ST)>
|
|
210
|
+
# <name of alternate coding system (IS)>
|
|
211
|
+
# <coding system version ID (ST)>
|
|
212
|
+
# alternate coding system version ID (ST)>
|
|
213
|
+
# <original text (ST)>
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# Composite ID number and name (special DT for NDL)
|
|
217
|
+
def CNN(map, force=false)
|
|
218
|
+
#check if the field is optional and randomly generate it of skip
|
|
219
|
+
return '' if(!generate?(map, force))
|
|
220
|
+
|
|
221
|
+
# ID number (ST) (ST)
|
|
222
|
+
|
|
223
|
+
# val << ID(map, true)
|
|
224
|
+
# family name (FN), used for ST
|
|
225
|
+
# val << FN(map, true)
|
|
226
|
+
# given name (ST)
|
|
227
|
+
# val << @yml['person.names.first'].sample
|
|
228
|
+
# second and further given names or initials thereof (ST)
|
|
229
|
+
# val << @@INITIALS.to_a.sample
|
|
230
|
+
# < suffix (e.g., JR or III) (ST)> ^ < prefix (e.g., DR) (ST)>
|
|
231
|
+
# < degree (e.g., MD) (IS)> ^ < source table (IS)>
|
|
232
|
+
PN(map, true)
|
|
233
|
+
|
|
234
|
+
# < assigning authority namespace ID (IS)>
|
|
235
|
+
# < assigning authority universal ID (ST)>
|
|
236
|
+
# < assigning authority universal ID type (ID)>
|
|
237
|
+
# val.join(@@SUB)
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def CP(map, force=false)
|
|
241
|
+
#check if the field is optional and randomly generate it of skip
|
|
242
|
+
return '' if(!generate?(map, force))
|
|
243
|
+
|
|
244
|
+
#price (MO)
|
|
245
|
+
MO(map,true)
|
|
246
|
+
#price type (ID)
|
|
247
|
+
#from value (NM)
|
|
248
|
+
#to value (NM)
|
|
249
|
+
#range units (CE)
|
|
250
|
+
#range type (ID)
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
# Composite quantity with units
|
|
254
|
+
def CQ(map, force=false)
|
|
255
|
+
#check if the field is optional and randomly generate it of skip
|
|
256
|
+
return '' if(!generate?(map, force))
|
|
257
|
+
# val =[]
|
|
258
|
+
# <quantity (NM)>
|
|
259
|
+
NM({},true)
|
|
260
|
+
|
|
261
|
+
# val<<NM({},true)
|
|
262
|
+
# <units (CE)>
|
|
263
|
+
# val<<CE(map,true) # Per request with QBP_Q21 issue
|
|
264
|
+
# CE always get values from code table 335, schema does not always specify it.
|
|
265
|
+
# only ID part from CE is used for this data type
|
|
266
|
+
# val<<ID(reset_map_attr(map, :codetable, '335'), true)
|
|
267
|
+
# val<<ID(map,true)
|
|
268
|
+
# val.join(@@HAT)
|
|
269
|
+
# val.join(@@SUB)
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
#Channel sensitivity/units
|
|
273
|
+
def CSU(map, force=false)
|
|
274
|
+
#check if the field is optional and randomly generate it of skip
|
|
275
|
+
return '' if(!generate?(map, force))
|
|
276
|
+
|
|
277
|
+
# < channel sensitivity (NM)>
|
|
278
|
+
NM(map,true)
|
|
279
|
+
# < unit of measure identifier (ST)>
|
|
280
|
+
# < unit of measure description (ST)>
|
|
281
|
+
# < unit of measure coding system (IS)>
|
|
282
|
+
# < alternate unit of measure identifier (ST)>
|
|
283
|
+
# < alternate unit of measure description (ST)>
|
|
284
|
+
# < alternate unit of measure coding system (IS)>
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
#Coded with exceptions
|
|
288
|
+
def CWE(map, force=false)
|
|
289
|
+
#check if the field is optional and randomly generate it of skip
|
|
290
|
+
return '' if(!generate?(map, force))
|
|
291
|
+
# <identifier (ST)>
|
|
292
|
+
# <text (ST)> ^ <name of coding system (IS)> ^ <alternate identifier(ST)> ^ <alternate text (ST)> ^ <name of alternate coding system (IS)> ^ <coding system version ID (ST)> ^ alternate coding system version ID (ST)> ^ <original text (ST)>
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
#Generate HL7 CX (extended composite ID with check digit) data type.
|
|
296
|
+
def CX(map, force=false)
|
|
297
|
+
#check if the field is optional and randomly generate it of skip
|
|
298
|
+
return '' if(!generate?(map, force))
|
|
299
|
+
|
|
300
|
+
#ID (ST)
|
|
301
|
+
ST(reset_map_attr(map, :description, 'Number'), true)
|
|
302
|
+
#check digit (ST) (ST)
|
|
303
|
+
#code identifying the check digit scheme employed (ID)
|
|
304
|
+
#assigning authority (HD)
|
|
305
|
+
#identifier type code (ID) (ID)
|
|
306
|
+
#assigning facility (HD)
|
|
307
|
+
#effective date (DT) (DT)
|
|
308
|
+
#expiration date (DT)
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
# Daily deductible
|
|
312
|
+
def DDI(map, force=false)
|
|
313
|
+
#check if the field is optional and randomly generate it of skip
|
|
314
|
+
return '' if(!generate?(map, force))
|
|
315
|
+
|
|
316
|
+
# < delay days (NM)>
|
|
317
|
+
# < amount (NM)>
|
|
318
|
+
NM(map,true)
|
|
319
|
+
# < number of days (NM)>
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
# Activation date
|
|
323
|
+
def DIN(map, force=false)
|
|
324
|
+
#check if the field is optional and randomly generate it of skip
|
|
325
|
+
return '' if(!generate?(map, force))
|
|
326
|
+
# date < date (TS)>
|
|
327
|
+
TS(map,true)
|
|
328
|
+
# <institution name (CE)>
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
#Generate HL7 DLD (discharge location) data type. This type consists of the following components=>
|
|
332
|
+
def DLD(map, force=false)
|
|
333
|
+
#check if the field is optional and randomly generate it of skip
|
|
334
|
+
return '' if(!generate?(map, force))
|
|
335
|
+
|
|
336
|
+
val=[]
|
|
337
|
+
#discharge location (ID)
|
|
338
|
+
val<<ID(map, true)
|
|
339
|
+
#effective date (TS)
|
|
340
|
+
val<<TS({},true)
|
|
341
|
+
val.join(@@HAT)
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
#Generate HHL7 DLN (driver's license number) data type
|
|
345
|
+
def DLN(map, force=false)
|
|
346
|
+
#check if the field is optional and randomly generate it of skip
|
|
347
|
+
return '' if(!generate?(map, force))
|
|
348
|
+
val=[]
|
|
349
|
+
# DLN dln = (DLN) map.fld
|
|
350
|
+
#Driver´s License Number (ST)
|
|
351
|
+
val << generate_length_bound_id(10) # 10 vs 7 Numeric, as for some states in real life
|
|
352
|
+
#Issuing State, province, country (IS)
|
|
353
|
+
#is(['fld'=>dln.getIssuingStateProvinceCountry(), 'required'=>'R','codetable'=>map.codetable])
|
|
354
|
+
#dln.getIssuingStateProvinceCountry().setValue(allStates.get(Math.abs(random.nextInt()%allStates.size())))
|
|
355
|
+
# val << @yml['address.states'].sample # pick a state
|
|
356
|
+
val << IS({:codetable =>'333'},true) # pick a state
|
|
357
|
+
#expiration date (DT)
|
|
358
|
+
val << DT(reset_map_attr(map, :description, 'End'), true)
|
|
359
|
+
val.join(@@HAT)
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
# Delta check
|
|
364
|
+
def DLT(map, force=false)
|
|
365
|
+
#check if the field is optional and randomly generate it of skip
|
|
366
|
+
return '' if(!generate?(map, force))
|
|
367
|
+
# <range (NR)>
|
|
368
|
+
NR(map,true)
|
|
369
|
+
# <numeric threshold (NM)>
|
|
370
|
+
# <change computation (ST)>
|
|
371
|
+
# <length of time-days (NM)>
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
#Generates HL7 DR (date/time range) data type.
|
|
375
|
+
def DR(map, force=false)
|
|
376
|
+
#check if the field is optional and randomly generate it of skip
|
|
377
|
+
return '' if(!generate?(map, force))
|
|
378
|
+
val=[]
|
|
379
|
+
#range start date/time (TS)
|
|
380
|
+
val<<TS(map,true)
|
|
381
|
+
#range end date/time (TS)
|
|
382
|
+
val<<TS(reset_map_attr(map, :description, 'End'), true)
|
|
383
|
+
val.join(@@HAT)
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
#Generates an HL7 DT (date) datatype.
|
|
387
|
+
def DT(map, force=false)
|
|
388
|
+
#check if the field is optional and randomly generate it of skip
|
|
389
|
+
return '' if(!generate?(map, force))
|
|
390
|
+
|
|
391
|
+
is_year_only = (map[:max_length]) ? map[:max_length].to_i == 4 : false
|
|
392
|
+
# #time of an event (TSComponentOne)
|
|
393
|
+
(is_year_only)? to_datetime(map).strftime('%Y') : to_datetime(map).strftime('%Y%m%d') #format('YYYYMMdd.SSS')Date.iso8601
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
# Day Type and Number
|
|
397
|
+
def DTN(map, force=false)
|
|
398
|
+
#check if the field is optional and randomly generate it of skip
|
|
399
|
+
return '' if(!generate?(map, force))
|
|
400
|
+
|
|
401
|
+
# val=[]
|
|
402
|
+
# # <day type (IS)>
|
|
403
|
+
# val<<IS(map,true)
|
|
404
|
+
# per Galina request: Ensemble limits the length of IN3.11 to 3. So, we need to remove the second component from being populated ...
|
|
405
|
+
IS(map,true)
|
|
406
|
+
# # <number of days (NM)>
|
|
407
|
+
# val<<NM({},true)
|
|
408
|
+
# val.join(@@HAT)
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
# Encapsulated data
|
|
412
|
+
def ED(map, force=false)
|
|
413
|
+
#check if the field is optional and randomly generate it of skip
|
|
414
|
+
return '' if(!generate?(map, force))
|
|
415
|
+
# <source application (HD) >
|
|
416
|
+
HD(map, true)
|
|
417
|
+
# <type of data (ID)>
|
|
418
|
+
# <data subtype (ID)>
|
|
419
|
+
# <encoding (ID)>
|
|
420
|
+
# <data (ST)>
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
# Entity identifier
|
|
424
|
+
def EI(map, force=false)
|
|
425
|
+
#check if the field is optional and randomly generate it of skip
|
|
426
|
+
return '' if(!generate?(map, force))
|
|
427
|
+
# <entity identifier (ST)>
|
|
428
|
+
ST(map,true)
|
|
429
|
+
# <namespace ID (IS)>
|
|
430
|
+
# <universal ID (ST)>
|
|
431
|
+
# < universal ID type (ID)>
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
# Parent order
|
|
435
|
+
def EIP(map, force=false)
|
|
436
|
+
#check if the field is optional and randomly generate it of skip
|
|
437
|
+
return '' if(!generate?(map, force))
|
|
438
|
+
|
|
439
|
+
# <parent’s placer order number (EI)>
|
|
440
|
+
EI(map,true)
|
|
441
|
+
# <parent’s filler order number (EI)>
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
# Error segment
|
|
445
|
+
def ELD(map, force=false)
|
|
446
|
+
#check if the field is optional and randomly generate it of skip
|
|
447
|
+
return '' if(!generate?(map, force))
|
|
448
|
+
val = []
|
|
449
|
+
# <segment ID (ST)>
|
|
450
|
+
val<<''
|
|
451
|
+
# <sequence (NM)>
|
|
452
|
+
val<<''
|
|
453
|
+
# <field position (NM)>
|
|
454
|
+
val<<''
|
|
455
|
+
# <code identifying error (CE)>
|
|
456
|
+
val<<CE(map,true)
|
|
457
|
+
val.join(@@HAT)
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
#Generates HL7 FC (financial class) data type.
|
|
461
|
+
def FC(map, force=false)
|
|
462
|
+
#check if the field is optional and randomly generate it of skip
|
|
463
|
+
return '' if(!generate?(map, force))
|
|
464
|
+
|
|
465
|
+
val = []
|
|
466
|
+
#Financial Class (IS)
|
|
467
|
+
val << IS(map, true)
|
|
468
|
+
#Effective Date (TS) (TS)
|
|
469
|
+
val << TS(map, true)
|
|
470
|
+
val.join(@@HAT)
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
#Generates an HL7 FN (familiy name) data type.
|
|
474
|
+
def FN(map, force=false)
|
|
475
|
+
#check if the field is optional and randomly generate it of skip
|
|
476
|
+
return '' if(!generate?(map, force))
|
|
477
|
+
|
|
478
|
+
#surname (ST)
|
|
479
|
+
@yml['person.names.last'].sample
|
|
480
|
+
#own surname prefix (ST)
|
|
481
|
+
#own surname (ST)
|
|
482
|
+
#surname prefix from partner/spouse (ST)
|
|
483
|
+
#surname from partner/spouse (ST)
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
# Formatted text data.
|
|
487
|
+
# The FT field is of arbitrary length (up to 64k) and may contain formatting commands enclosed in escape characters.
|
|
488
|
+
def FT(map, force=false)
|
|
489
|
+
#check if the field is optional and randomly generate it of skip
|
|
490
|
+
return '' if(!generate?(map, force))
|
|
491
|
+
|
|
492
|
+
ID(map, true)
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
#Generates HL7 HD (hierarchic designator) data type
|
|
497
|
+
def HD(map, force=false)
|
|
498
|
+
#check if the field is optional and randomly generate it of skip
|
|
499
|
+
return '' if(!generate?(map, force))
|
|
500
|
+
|
|
501
|
+
#namespace ID (IS)
|
|
502
|
+
IS(map, true)
|
|
503
|
+
#universal ID (ST)
|
|
504
|
+
#universal ID type (ID)
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
# Generate HL7 ID, usually using value from code table
|
|
509
|
+
def ID(map, force=false)
|
|
510
|
+
#check if the field is optional and randomly generate it of skip
|
|
511
|
+
return '' if(!generate?(map, force))
|
|
512
|
+
|
|
513
|
+
#value only
|
|
514
|
+
#Case when max_len overrides requirements
|
|
515
|
+
len = safe_len(map[:max_length], @@REQ_LEN_3_DGTS)
|
|
516
|
+
(!blank?(map[:codetable]))? get_coded_value(map): generate_length_bound_id(len)
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
#Generates HL7 IS (namespace id) data type
|
|
520
|
+
def IS(map, force=false)
|
|
521
|
+
#check if the field is optional and randomly generate it of skip
|
|
522
|
+
return '' if(!generate?(map, force))
|
|
523
|
+
|
|
524
|
+
#TODO: same as ID?
|
|
525
|
+
ID(map,true)
|
|
526
|
+
end
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
#Generates HL7 JCC (job code/class) data type.
|
|
530
|
+
def JCC(map, force=false)
|
|
531
|
+
#check if the field is optional and randomly generate it of skip
|
|
532
|
+
return '' if(!generate?(map, force))
|
|
533
|
+
|
|
534
|
+
val=[]
|
|
535
|
+
#job code (IS)
|
|
536
|
+
# is(['fld'=>jcc.getComponent(0), 'required'=>'R', 'codetable'=>map.codetable])
|
|
537
|
+
val << IS(map, true)
|
|
538
|
+
#job class (IS)
|
|
539
|
+
val << IS(map, true)
|
|
540
|
+
# is(['fld'=>jcc.getComponent(1), 'required'=>'R'])
|
|
541
|
+
val.join(@@HAT)
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
# Location with address information (variant 1)
|
|
545
|
+
def LA1(map, force=false)
|
|
546
|
+
#check if the field is optional and randomly generate it of skip
|
|
547
|
+
return '' if(!generate?(map, force))
|
|
548
|
+
val =[]
|
|
549
|
+
# <point of care (IS)>
|
|
550
|
+
val<<IS(map,true)
|
|
551
|
+
# <room (IS) >
|
|
552
|
+
val<<IS({:codetable =>'303'},true)
|
|
553
|
+
# <bed (IS)>
|
|
554
|
+
val<<IS({:codetable =>'304'},true)
|
|
555
|
+
# <facility (HD) >
|
|
556
|
+
val<<HD({},true)
|
|
557
|
+
# <location status (IS)
|
|
558
|
+
val<<''
|
|
559
|
+
# <patient location type (IS)>
|
|
560
|
+
val<<''
|
|
561
|
+
# <building (IS)>
|
|
562
|
+
val<<IS({:codetable =>'307'},true)
|
|
563
|
+
# <floor (IS)>
|
|
564
|
+
# <address(AD)>
|
|
565
|
+
val.join(@@HAT)
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
# Location with address information (variant 2)
|
|
569
|
+
def LA2(map, force=false)
|
|
570
|
+
#check if the field is optional and randomly generate it of skip
|
|
571
|
+
return '' if(!generate?(map, force))
|
|
572
|
+
|
|
573
|
+
val =[]
|
|
574
|
+
# <point of care (IS)>
|
|
575
|
+
val<<IS(map,true)
|
|
576
|
+
# <room (IS)
|
|
577
|
+
val<<IS({:codetable =>'303'},true)
|
|
578
|
+
# <bed (IS)>
|
|
579
|
+
val<<IS({:codetable =>'304'},true)
|
|
580
|
+
# <facility (HD) >
|
|
581
|
+
val<<HD({},true)
|
|
582
|
+
# <location status (IS)
|
|
583
|
+
val<<''
|
|
584
|
+
# <patient location type (IS)>
|
|
585
|
+
val<<''
|
|
586
|
+
# <building (IS)>
|
|
587
|
+
val<<IS({:codetable =>'307'},true)
|
|
588
|
+
# <floor (IS)>
|
|
589
|
+
# < street address (ST)>
|
|
590
|
+
# <other designation (ST)>
|
|
591
|
+
# <city (ST)>
|
|
592
|
+
# <state or province (ST)>
|
|
593
|
+
# <zip or postal code (ST)>
|
|
594
|
+
# <country (ID)>
|
|
595
|
+
# <address type (ID)>
|
|
596
|
+
# <other geographic designation (ST)>
|
|
597
|
+
val.join(@@HAT)
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
#MA segment
|
|
601
|
+
def MA(map, force=false)
|
|
602
|
+
#check if the field is optional and randomly generate it of skip
|
|
603
|
+
return '' if(!generate?(map, force))
|
|
604
|
+
|
|
605
|
+
# <sample 1 from channel 1 (NM)>
|
|
606
|
+
NM(map,true)
|
|
607
|
+
# <sample 1 from channel 2 (NM)>
|
|
608
|
+
# <sample 1 from channel 3 (NM)>
|
|
609
|
+
# <sample 2 from channel 1 (NM)>
|
|
610
|
+
# <sample 2 from channel 2 (NM)>
|
|
611
|
+
# <sample 2 from channel 3 (NM)>
|
|
612
|
+
end
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
#Generates an HL7 MO (money) data type.
|
|
616
|
+
def MO(map, force=false)
|
|
617
|
+
#check if the field is optional and randomly generate it of skip
|
|
618
|
+
return '' if(!generate?(map, force))
|
|
619
|
+
# val = []
|
|
620
|
+
#quantity (NM)Guarantor Household Annual Income
|
|
621
|
+
# val << NM(reset_map_attr(map,:description,'Money'),true)
|
|
622
|
+
#val << NM(map,true)
|
|
623
|
+
NM(map,true)
|
|
624
|
+
#denomination (ID)
|
|
625
|
+
# val << 'USD' # Per request.
|
|
626
|
+
# return val.join(@@SUB)
|
|
627
|
+
end
|
|
628
|
+
|
|
629
|
+
# Charge to practice
|
|
630
|
+
def MOC(map, force=false)
|
|
631
|
+
#check if the field is optional and randomly generate it of skip
|
|
632
|
+
return '' if(!generate?(map, force))
|
|
633
|
+
|
|
634
|
+
# <dollar amount (MO)>
|
|
635
|
+
MO(map,true)
|
|
636
|
+
# <charge code (CE)>
|
|
637
|
+
end
|
|
638
|
+
|
|
639
|
+
# Money or percentage
|
|
640
|
+
def MOP(map, force=false)
|
|
641
|
+
#check if the field is optional and randomly generate it of skip
|
|
642
|
+
return '' if(!generate?(map, force))
|
|
643
|
+
val=[]
|
|
644
|
+
# <money or percentage indicator (IS)>
|
|
645
|
+
val<<IS({:codetable =>'148'},true)
|
|
646
|
+
# <money or percentage quantity (NM)>
|
|
647
|
+
val<<NM({:description =>'Percentage'},true)
|
|
648
|
+
val.join(@@HAT)
|
|
649
|
+
end
|
|
650
|
+
|
|
651
|
+
# MSG segment
|
|
652
|
+
def MSG(map, force=false)
|
|
653
|
+
#check if the field is optional and randomly generate it of skip
|
|
654
|
+
return '' if(!generate?(map, force))
|
|
655
|
+
val=[]
|
|
656
|
+
# <message type (ID)>
|
|
657
|
+
val<<IS({:codetable =>'76'},true)
|
|
658
|
+
# <trigger event (ID)>
|
|
659
|
+
val<<IS({:codetable =>'3'},true)
|
|
660
|
+
# <message structure (ID)>
|
|
661
|
+
val<<IS({:codetable =>'354'},true)
|
|
662
|
+
val.join(@@HAT)
|
|
663
|
+
end
|
|
664
|
+
|
|
665
|
+
#Generates HL7 MSG (Message Type) data type.
|
|
666
|
+
def MSH(map, force=false)
|
|
667
|
+
#Message type set while initializing MSH segment, do nothing.
|
|
668
|
+
|
|
669
|
+
#message type (ID)
|
|
670
|
+
#trigger event (ID)
|
|
671
|
+
#message structure (ID)
|
|
672
|
+
end
|
|
673
|
+
|
|
674
|
+
|
|
675
|
+
# Numeric Array
|
|
676
|
+
def NA(map, force=false)
|
|
677
|
+
#check if the field is optional and randomly generate it of skip
|
|
678
|
+
return '' if(!generate?(map, force))
|
|
679
|
+
# <value1 (NM)>
|
|
680
|
+
NM(map,true)
|
|
681
|
+
# <value2 (NM)>
|
|
682
|
+
# <value3 (NM)>
|
|
683
|
+
# <value4 (NM)>
|
|
684
|
+
end
|
|
685
|
+
|
|
686
|
+
# Observing practitioner
|
|
687
|
+
def NDL(map, force=false)
|
|
688
|
+
#check if the field is optional and randomly generate it of skip
|
|
689
|
+
return '' if(!generate?(map, force))
|
|
690
|
+
# <name (CNN)>
|
|
691
|
+
CNN(map,true)
|
|
692
|
+
# <start date/time (TS)>
|
|
693
|
+
# <end date/time (TS)>
|
|
694
|
+
# <point of care (IS)>
|
|
695
|
+
# <room (IS)>
|
|
696
|
+
# <bed (IS)>
|
|
697
|
+
# <facility (HD)>
|
|
698
|
+
# <location status (IS)>
|
|
699
|
+
# <person location type (IS)>
|
|
700
|
+
# <building (IS)>
|
|
701
|
+
# <floor (IS)>
|
|
702
|
+
end
|
|
703
|
+
|
|
704
|
+
#Generates an HL7 NM (numeric) data type. A NM contains a single String value.
|
|
705
|
+
def NM(map, force=false)
|
|
706
|
+
#check if the field is optional and randomly generate it of skip
|
|
707
|
+
return '' if(!generate?(map, force))
|
|
708
|
+
val = 0
|
|
709
|
+
case map[:description]
|
|
710
|
+
when'Guarantor Household Size','Birth Order'
|
|
711
|
+
val = generate_length_bound_id(1)
|
|
712
|
+
when 'Guarantor Household Annual Income'
|
|
713
|
+
val = '%.2f' % generate_length_bound_id(5)
|
|
714
|
+
when @@MONEY_FORMAT_REGEX
|
|
715
|
+
val = '%.2f' % ID(map,true)
|
|
716
|
+
when @@PERCENT_FORMAT_REGEX
|
|
717
|
+
val = @@random.rand(0..100) # generate proper % value < 100
|
|
718
|
+
else
|
|
719
|
+
val = ID(map,true) # general rule for a number
|
|
720
|
+
if (map[:datatype] == 'CP' || map[:datatype] == 'MO') # money
|
|
721
|
+
val = '%.2f' % val
|
|
722
|
+
end
|
|
723
|
+
end
|
|
724
|
+
# #money
|
|
725
|
+
# if (!Utils.blank?(map[:description]) && @@MONEY_FORMAT_INDICATORS.index{|it| map[:description].include?(it)}) #check for specific numeric for money
|
|
726
|
+
# val = '%.2f' % @@random.rand(@@UP_TO_3_DGTS) #under $1,000
|
|
727
|
+
# else #quantity (NM)
|
|
728
|
+
# val = @@random.rand(@@UP_TO_3_DGTS).to_s #under 20
|
|
729
|
+
# end
|
|
730
|
+
return val
|
|
731
|
+
end
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
#Numeric Range
|
|
735
|
+
def NR(map, force=false)
|
|
736
|
+
#check if the field is optional and randomly generate it of skip
|
|
737
|
+
return '' if(!generate?(map, force))
|
|
738
|
+
val=[]
|
|
739
|
+
# Low Value (NM)
|
|
740
|
+
val=NM(map,true)
|
|
741
|
+
# High Value (NM)
|
|
742
|
+
val<<''
|
|
743
|
+
val.join(@@SUB)
|
|
744
|
+
end
|
|
745
|
+
|
|
746
|
+
#Generates an HL7 OCD (occurence) data type.
|
|
747
|
+
#The code and associated date defining a significant event relating to a bill that may affect payer processing
|
|
748
|
+
def OCD(map, force=false)
|
|
749
|
+
#check if the field is optional and randomly generate it of skip
|
|
750
|
+
return '' if(!generate?(map, force))
|
|
751
|
+
val = []
|
|
752
|
+
#occurrence code (IS)
|
|
753
|
+
val << IS(map, true)
|
|
754
|
+
# is(['fld'=>ocd.getComponent(0), 'required'=>'R', 'codetable'=>map.codetable])
|
|
755
|
+
#occurrence date (DT)
|
|
756
|
+
#dt(['fld'=>ocd.getComponent(1), 'required'=>'R'])
|
|
757
|
+
val << DT(map, true)
|
|
758
|
+
val.join(@@HAT)
|
|
759
|
+
end
|
|
760
|
+
|
|
761
|
+
# Order sequence
|
|
762
|
+
def OSD(map, force=false)
|
|
763
|
+
#check if the field is optional and randomly generate it of skip
|
|
764
|
+
return '' if(!generate?(map, force))
|
|
765
|
+
|
|
766
|
+
# <sequence/results flag (ID)>
|
|
767
|
+
ID(map, force)
|
|
768
|
+
# <placer order number: entity identifier (ST)>
|
|
769
|
+
# <placer order number: namespace ID (IS)>
|
|
770
|
+
# <filler order number: entity identifier (ST)>
|
|
771
|
+
# <filler order number: namespace ID (IS)>
|
|
772
|
+
# <sequence condition value (ST)>
|
|
773
|
+
# <maximum number of repeats (NM)>
|
|
774
|
+
# <placer order number: universal ID (ST)>
|
|
775
|
+
# <placer order number; universal ID type (ID)>
|
|
776
|
+
# <filler order number: universal ID (ST)>
|
|
777
|
+
# <filler order number: universal ID type (ID)>
|
|
778
|
+
end
|
|
779
|
+
|
|
780
|
+
#Generate an HL7 OSP (occurence span) data type.
|
|
781
|
+
def OSP(map, force=false)
|
|
782
|
+
#check if the field is optional and randomly generate it of skip
|
|
783
|
+
return '' if(!generate?(map, force))
|
|
784
|
+
val = []
|
|
785
|
+
|
|
786
|
+
#occurrence span code (CE)
|
|
787
|
+
# val << CE(map, true) # Per request with ADT_A05 and ADT_A06 issues
|
|
788
|
+
val << ID(map, true)
|
|
789
|
+
#occurrence span start date (DT)
|
|
790
|
+
val << DT({},true)
|
|
791
|
+
#occurrence span stop date (DT)
|
|
792
|
+
val << DT(reset_map_attr(map, :description, 'End'), true)
|
|
793
|
+
val.join(@@HAT)
|
|
794
|
+
end
|
|
795
|
+
|
|
796
|
+
# Pre-certification required
|
|
797
|
+
def PCF(map, force=false)
|
|
798
|
+
#check if the field is optional and randomly generate it of skip
|
|
799
|
+
return '' if(!generate?(map, force))
|
|
800
|
+
|
|
801
|
+
# <pre-certification patient type (IS)>
|
|
802
|
+
IS({:codetable =>'150'},true)
|
|
803
|
+
# <pre-certification required>
|
|
804
|
+
# <pre-certification window>
|
|
805
|
+
end
|
|
806
|
+
|
|
807
|
+
# Person identifier
|
|
808
|
+
def PI(map, force=false)
|
|
809
|
+
#check if the field is optional and randomly generate it of skip
|
|
810
|
+
return '' if(!generate?(map, force))
|
|
811
|
+
# <ID number (ST)>
|
|
812
|
+
ST(map,true)
|
|
813
|
+
# <type of ID number>
|
|
814
|
+
# <other qualifying info>
|
|
815
|
+
end
|
|
816
|
+
|
|
817
|
+
# Privileges
|
|
818
|
+
def PIP(map, force=false)
|
|
819
|
+
#check if the field is optional and randomly generate it of skip
|
|
820
|
+
return '' if(!generate?(map, force))
|
|
821
|
+
|
|
822
|
+
# <privilege (CE)>
|
|
823
|
+
IS(map,true)
|
|
824
|
+
# <privilege class (CE)>
|
|
825
|
+
# <expiration date (DT)>
|
|
826
|
+
# <activation date (DT)>
|
|
827
|
+
# <facility (EI)>
|
|
828
|
+
end
|
|
829
|
+
|
|
830
|
+
|
|
831
|
+
#Generate an HL7 PL (person location) data type.
|
|
832
|
+
def PL(map, force=false)
|
|
833
|
+
#check if the field is optional and randomly generate it of skip
|
|
834
|
+
return '' if(!generate?(map, force))
|
|
835
|
+
val = []
|
|
836
|
+
#point of care (IS)
|
|
837
|
+
val<<IS({:codetable =>'302'},true)
|
|
838
|
+
#room (IS)
|
|
839
|
+
val<<IS({:codetable =>'303'},true)
|
|
840
|
+
#bed (IS)
|
|
841
|
+
val<<IS({:codetable =>'304'},true)
|
|
842
|
+
#facility (HD) (HD)
|
|
843
|
+
val << HD({:codetable =>'300'}, true)
|
|
844
|
+
#location status (IS)
|
|
845
|
+
val << ''
|
|
846
|
+
#person location type (IS)
|
|
847
|
+
val << ''
|
|
848
|
+
#building (IS)
|
|
849
|
+
val<<IS({:codetable =>'307'},true)
|
|
850
|
+
#floor (IS)
|
|
851
|
+
#Location description (ST)
|
|
852
|
+
val.join(@@HAT)
|
|
853
|
+
end
|
|
854
|
+
|
|
855
|
+
# Practitioner ID Numbers
|
|
856
|
+
def PLN(map, force=false)
|
|
857
|
+
#check if the field is optional and randomly generate it of skip
|
|
858
|
+
return '' if(!generate?(map, force))
|
|
859
|
+
|
|
860
|
+
# <ID number (ST)>
|
|
861
|
+
ST(map,true)
|
|
862
|
+
# <type of ID number (IS)>
|
|
863
|
+
# <state/other qualifying info (ST)>
|
|
864
|
+
# <expiration date (DT)>
|
|
865
|
+
end
|
|
866
|
+
|
|
867
|
+
# Person name
|
|
868
|
+
def PN(map, force=false)
|
|
869
|
+
#check if the field is optional and randomly generate it of skip
|
|
870
|
+
return '' if(!generate?(map, force))
|
|
871
|
+
val=[]
|
|
872
|
+
# family name (FN)
|
|
873
|
+
val << FN(map, true)
|
|
874
|
+
# given name (ST)
|
|
875
|
+
val << @yml['person.names.first'].sample
|
|
876
|
+
# second and further given names or initials thereof (ST)
|
|
877
|
+
val << @@INITIALS.to_a.sample
|
|
878
|
+
# suffix (e.g., JR or III) (ST)
|
|
879
|
+
# prefix (e.g., DR) (ST)
|
|
880
|
+
# degree (e.g., MD) (IS)
|
|
881
|
+
val.join(@@HAT)
|
|
882
|
+
end
|
|
883
|
+
|
|
884
|
+
# Performing person time stamp
|
|
885
|
+
def PPN(map, force=false)
|
|
886
|
+
# check if the field is optional and randomly generate it of skip
|
|
887
|
+
return '' if(!generate?(map, force))
|
|
888
|
+
val = []
|
|
889
|
+
# <ID number (ST)>
|
|
890
|
+
val << ST(map,true)
|
|
891
|
+
|
|
892
|
+
# PN will work for the subset of fields used below
|
|
893
|
+
val << PN({},true)
|
|
894
|
+
# <family name (FN)>
|
|
895
|
+
# <given name (ST)>
|
|
896
|
+
# <second and further given names or initials thereof (ST)>
|
|
897
|
+
# <suffix (e.g., JR or III) (ST)>
|
|
898
|
+
# <prefix (e.g., DR) (ST)>
|
|
899
|
+
# <degree (e.g., MD) (IS)>
|
|
900
|
+
# <source table (IS)>
|
|
901
|
+
# <assigning authority (HD)>
|
|
902
|
+
# <name type code(ID)>
|
|
903
|
+
# <identifier check digit (ST)>
|
|
904
|
+
# <code identifying the check digit scheme employed (ID )>
|
|
905
|
+
# <identifier type code (IS)>
|
|
906
|
+
# <assigning facility (HD)>
|
|
907
|
+
# < date/time action performed (TS)>
|
|
908
|
+
# <name representation code (ID)>
|
|
909
|
+
# <name context (CE)>
|
|
910
|
+
# <name validity range (DR)>
|
|
911
|
+
# <name assembly order (ID)>
|
|
912
|
+
|
|
913
|
+
val.join(@@HAT)
|
|
914
|
+
end
|
|
915
|
+
|
|
916
|
+
# Parent result link
|
|
917
|
+
def PRL(map, force=false)
|
|
918
|
+
#check if the field is optional and randomly generate it of skip
|
|
919
|
+
return '' if(!generate?(map, force))
|
|
920
|
+
|
|
921
|
+
# <OBX-3-observation identifier of parent result (CE)>
|
|
922
|
+
CE(map,true)
|
|
923
|
+
# <OBX-4-sub-ID of parent result(ST)>
|
|
924
|
+
# <part of OBX-5 observation result from parent (TX)see discussion>
|
|
925
|
+
end
|
|
926
|
+
|
|
927
|
+
#Generate HL7 S PT (processing type) data type.
|
|
928
|
+
def PT(map, force=false)
|
|
929
|
+
#check if the field is optional and randomly generate it of skip
|
|
930
|
+
return '' if(!generate?(map, force))
|
|
931
|
+
|
|
932
|
+
#map.maxlen
|
|
933
|
+
# PT pt = (PT) map.fld
|
|
934
|
+
# Map mp = map.clone()
|
|
935
|
+
# mp.fld = pt.getComponent(0)
|
|
936
|
+
# mp.required = 'R'
|
|
937
|
+
ID(map, true)
|
|
938
|
+
#processing ID (ID)
|
|
939
|
+
#processing mode (ID)
|
|
940
|
+
end
|
|
941
|
+
|
|
942
|
+
# Processing type
|
|
943
|
+
def PTA(map, force=false)
|
|
944
|
+
#check if the field is optional and randomly generate it of skip
|
|
945
|
+
return '' if(!generate?(map, force))
|
|
946
|
+
|
|
947
|
+
# <processing ID (ID)>
|
|
948
|
+
ID(map, true)
|
|
949
|
+
# <processing mode (ID)>
|
|
950
|
+
# <processing ID (ID)>
|
|
951
|
+
end
|
|
952
|
+
|
|
953
|
+
# Query input parameter list
|
|
954
|
+
def OIP(map, force=false)
|
|
955
|
+
#check if the field is optional and randomly generate it of skip
|
|
956
|
+
return '' if(!generate?(map, force))
|
|
957
|
+
|
|
958
|
+
# <segment field name (ST) >
|
|
959
|
+
# <value1 (ST) & value2 (ST) & value3 (ST) ...>
|
|
960
|
+
#Example: |@PID.5.1^EVANS|
|
|
961
|
+
#TBD
|
|
962
|
+
''
|
|
963
|
+
end
|
|
964
|
+
|
|
965
|
+
# QSC Query selection criteria
|
|
966
|
+
def QSC(map, force=false)
|
|
967
|
+
#check if the field is optional and randomly generate it of skip
|
|
968
|
+
return '' if(!generate?(map, force))
|
|
969
|
+
|
|
970
|
+
# <segment field name(ST)>
|
|
971
|
+
# <relational operator (ID)>
|
|
972
|
+
# <value (ST)> <relational conjunction (ID)>
|
|
973
|
+
# Example: |@PID.5.1^EQ^EVANS|"
|
|
974
|
+
#TBD
|
|
975
|
+
''
|
|
976
|
+
end
|
|
977
|
+
|
|
978
|
+
# RCD Row column definition
|
|
979
|
+
def RCD(map, force=false)
|
|
980
|
+
#check if the field is optional and randomly generate it of skip
|
|
981
|
+
return '' if(!generate?(map, force))
|
|
982
|
+
|
|
983
|
+
# <segment field name (ST)>
|
|
984
|
+
ST(reset_map_attr(map,:codetable, '440'),true)
|
|
985
|
+
# <HL7 data type (ID)>
|
|
986
|
+
# <maximum column width (NM)>
|
|
987
|
+
# Example: |@PID.5.1^ST^20|"
|
|
988
|
+
#TBD
|
|
989
|
+
# ''
|
|
990
|
+
end
|
|
991
|
+
|
|
992
|
+
# RDF Table row definition
|
|
993
|
+
def RDT(map, force=false)
|
|
994
|
+
#check if the field is optional and randomly generate it of skip
|
|
995
|
+
return '' if(!generate?(map, force))
|
|
996
|
+
val = []
|
|
997
|
+
# <parameter class (IS)>
|
|
998
|
+
# randomly generated 3-digit number
|
|
999
|
+
# v << generate_length_bound_id(@@REQ_LEN_3_DGTS)
|
|
1000
|
+
ID({},true)
|
|
1001
|
+
end
|
|
1002
|
+
|
|
1003
|
+
# Reference range
|
|
1004
|
+
def RFR(map, force=false)
|
|
1005
|
+
#check if the field is optional and randomly generate it of skip
|
|
1006
|
+
return '' if(!generate?(map, force))
|
|
1007
|
+
|
|
1008
|
+
# <numeric range (NR)>
|
|
1009
|
+
NR(map, true)
|
|
1010
|
+
# <administrative sex (IS)
|
|
1011
|
+
# <age range (NR)>
|
|
1012
|
+
# <gestational range (NR)>
|
|
1013
|
+
# <species (TX)>
|
|
1014
|
+
# <race/subspecies (ST)>
|
|
1015
|
+
# <conditions (TX)>
|
|
1016
|
+
end
|
|
1017
|
+
|
|
1018
|
+
# Repeat interval
|
|
1019
|
+
def RI(map, force=false)
|
|
1020
|
+
#check if the field is optional and randomly generate it of skip
|
|
1021
|
+
return '' if(!generate?(map, force))
|
|
1022
|
+
# <repeat pattern (IS)>
|
|
1023
|
+
# IS(map,true)
|
|
1024
|
+
IS(reset_map_attr(map, :codetable, '335'), true)
|
|
1025
|
+
# <explicit time interval (ST)>
|
|
1026
|
+
end
|
|
1027
|
+
|
|
1028
|
+
# Room coverage
|
|
1029
|
+
def RMC(map, force=false)
|
|
1030
|
+
#check if the field is optional and randomly generate it of skip
|
|
1031
|
+
return '' if(!generate?(map, force))
|
|
1032
|
+
|
|
1033
|
+
# <room type> (IS)
|
|
1034
|
+
IS(map,true)
|
|
1035
|
+
# <amount type>
|
|
1036
|
+
# <coverage amount>
|
|
1037
|
+
end
|
|
1038
|
+
|
|
1039
|
+
# Reference pointer
|
|
1040
|
+
def PR(map, force=false)
|
|
1041
|
+
#check if the field is optional and randomly generate it of skip
|
|
1042
|
+
return '' if(!generate?(map, force))
|
|
1043
|
+
|
|
1044
|
+
# <pointer (ST) >
|
|
1045
|
+
ST(map,true)
|
|
1046
|
+
# < application ID (HD)>
|
|
1047
|
+
# <type of data (ID)>
|
|
1048
|
+
# <subtype (ID)>
|
|
1049
|
+
end
|
|
1050
|
+
|
|
1051
|
+
# Street address
|
|
1052
|
+
# Appears ONLY in the XAD data type.
|
|
1053
|
+
# TODO: Future refactoring, handled in XAD.
|
|
1054
|
+
# def SAD(map, force=false)
|
|
1055
|
+
# #check if the field is optional and randomly generate it of skip
|
|
1056
|
+
# return '' if(!autoGenerate?(map,force))
|
|
1057
|
+
#
|
|
1058
|
+
# # <street or mailing address (ST)>
|
|
1059
|
+
# # <street name (ST)>
|
|
1060
|
+
# # <dwelling number (ST)>
|
|
1061
|
+
# end
|
|
1062
|
+
|
|
1063
|
+
# SCV Scheduling class value pair
|
|
1064
|
+
def SCV(map, force=false)
|
|
1065
|
+
#check if the field is optional and randomly generate it of skip
|
|
1066
|
+
return '' if(!generate?(map, force))
|
|
1067
|
+
|
|
1068
|
+
val = []
|
|
1069
|
+
# <parameter class (IS)>
|
|
1070
|
+
val<<''
|
|
1071
|
+
# <parameter value (ST)>
|
|
1072
|
+
# val<<ST(map,true)
|
|
1073
|
+
val<<ST(reset_map_attr(map,:codetable, '294'),true)
|
|
1074
|
+
val.join(@@HAT)
|
|
1075
|
+
end
|
|
1076
|
+
|
|
1077
|
+
#Generate HL7 SI (sequence ID) data type. A SI contains a single String value.
|
|
1078
|
+
def SI(map, force=false)
|
|
1079
|
+
#check if the field is optional and randomly generate it of skip
|
|
1080
|
+
return '' if(!generate?(map, force))
|
|
1081
|
+
|
|
1082
|
+
#SI pt = (SI) map.fld
|
|
1083
|
+
#pt.setValue(generate_length_bound_id((map.max_length)?map.max_length.toInteger():1))
|
|
1084
|
+
len = (!blank?(map[:max_length]))?map[:max_length].to_i : 1
|
|
1085
|
+
# per Galina: - the set IDs should be max 4 digits, please remove all the zeros.
|
|
1086
|
+
len = (len >4 )? 4 :len
|
|
1087
|
+
generate_length_bound_id(len)
|
|
1088
|
+
end
|
|
1089
|
+
|
|
1090
|
+
# Structured numeric
|
|
1091
|
+
def SN(map, force=false)
|
|
1092
|
+
#check if the field is optional and randomly generate it of skip
|
|
1093
|
+
return '' if(!generate?(map, force))
|
|
1094
|
+
val = []
|
|
1095
|
+
# <comparator (ST)>
|
|
1096
|
+
val << ''
|
|
1097
|
+
# <num1 (NM)>
|
|
1098
|
+
val << NM(map,true)
|
|
1099
|
+
# <separator/suffix (ST)>
|
|
1100
|
+
# <num2 (NM)>
|
|
1101
|
+
val.join(@@HAT)
|
|
1102
|
+
end
|
|
1103
|
+
|
|
1104
|
+
# Specialty
|
|
1105
|
+
def SPD(map, force=false)
|
|
1106
|
+
#check if the field is optional and randomly generate it of skip
|
|
1107
|
+
return '' if(!generate?(map, force))
|
|
1108
|
+
|
|
1109
|
+
# <specialty name (ST)>
|
|
1110
|
+
ST(map,true)
|
|
1111
|
+
# <governing board (ST)>
|
|
1112
|
+
# <eligible or certified (ID)>
|
|
1113
|
+
# <date of certification (DT)>
|
|
1114
|
+
end
|
|
1115
|
+
|
|
1116
|
+
# Specimen source
|
|
1117
|
+
def SPS(map, force=false)
|
|
1118
|
+
#check if the field is optional and randomly generate it of skip
|
|
1119
|
+
return '' if(!generate?(map, force))
|
|
1120
|
+
|
|
1121
|
+
#<specimen source name or code (CE)>
|
|
1122
|
+
CE(map,true)
|
|
1123
|
+
# <additives (TX)>
|
|
1124
|
+
# <freetext (TX)>
|
|
1125
|
+
# <body site (CE)>
|
|
1126
|
+
# <site modifier (CE)>
|
|
1127
|
+
# <collection modifier method code (CE)>
|
|
1128
|
+
# <specimen role (CE)>
|
|
1129
|
+
end
|
|
1130
|
+
|
|
1131
|
+
#Sort order
|
|
1132
|
+
def SRT(map, force=false)
|
|
1133
|
+
#check if the field is optional and randomly generate it of skip
|
|
1134
|
+
return '' if(!generate?(map, force))
|
|
1135
|
+
|
|
1136
|
+
# <sort-by field (ST)>
|
|
1137
|
+
# <sequencing (ID)>
|
|
1138
|
+
ID(map,true)
|
|
1139
|
+
end
|
|
1140
|
+
|
|
1141
|
+
#Generate HL7 ST (string data) data type. A ST contains a single String value.
|
|
1142
|
+
def ST(map, force=false)
|
|
1143
|
+
#check if the field is optional and randomly generate it of skip
|
|
1144
|
+
return '' if(!generate?(map, force))
|
|
1145
|
+
|
|
1146
|
+
# TODO add provider type ln 840 ROL
|
|
1147
|
+
case map[:description]
|
|
1148
|
+
when 'Guarantor SSN','Insured’s Social Security Number','Medicare health ins Card Number','Military ID Number', 'Contact Person Social Security Number'
|
|
1149
|
+
generate_length_bound_id(9)
|
|
1150
|
+
when 'Allergy Reaction Code'
|
|
1151
|
+
yml['codes.allergens'].keys.sample()
|
|
1152
|
+
when 'Strain'
|
|
1153
|
+
#PID.35 – PID.38 should be always blank, as they deal with animals, not humans.
|
|
1154
|
+
when 'AGENT ORANGE EXPOSURE LOCATION'
|
|
1155
|
+
#ZEL.29 should be 1 digit integer.
|
|
1156
|
+
generate_length_bound_id(1)
|
|
1157
|
+
else
|
|
1158
|
+
#Case when max_len overrides requirements
|
|
1159
|
+
len = safe_len(map[:max_length], @@REQ_LEN_3_DGTS)
|
|
1160
|
+
(!blank?(map[:codetable]))? get_coded_value(map): generate_length_bound_id(len)
|
|
1161
|
+
end
|
|
1162
|
+
|
|
1163
|
+
end
|
|
1164
|
+
|
|
1165
|
+
# An Elementary Data Type Format: HH[MM[SS[.S[S[S[S]]]]]][+/-ZZZZ]
|
|
1166
|
+
# EX: 160140.761
|
|
1167
|
+
def TM(map, force=false)
|
|
1168
|
+
#check if the field is optional and randomly generate it of skip
|
|
1169
|
+
return '' if(!generate?(map, force))
|
|
1170
|
+
to_datetime(map).strftime('%H%M%S.%L')
|
|
1171
|
+
end
|
|
1172
|
+
|
|
1173
|
+
#Generate an HL7 TN (telephone number) data type. A TN contains a single String value.
|
|
1174
|
+
def TN(map, force=false)
|
|
1175
|
+
#check if the field is optional and randomly generate it of skip
|
|
1176
|
+
return '' if(!generate?(map, force))
|
|
1177
|
+
|
|
1178
|
+
# TN tn = (TN) map.fld
|
|
1179
|
+
# tn.setValue(phones.getAt(Math.abs(random.nextInt()%phones.size())))
|
|
1180
|
+
@yml['address.phones'].sample # pick a phone
|
|
1181
|
+
end
|
|
1182
|
+
|
|
1183
|
+
# Timing quantity
|
|
1184
|
+
def TQ(map, force=false)
|
|
1185
|
+
#check if the field is optional and randomly generate it of skip
|
|
1186
|
+
return '' if(!generate?(map, force))
|
|
1187
|
+
|
|
1188
|
+
# <quantity (CQ)>
|
|
1189
|
+
# CQ(reset_map_attr(map, :codetable, '335'), true)
|
|
1190
|
+
CQ(map,true)
|
|
1191
|
+
# <interval (RI)
|
|
1192
|
+
# < duration (ST)>
|
|
1193
|
+
# <start date/time (TS)>
|
|
1194
|
+
# <end date/time (TS)>
|
|
1195
|
+
# <priority (ST)>
|
|
1196
|
+
# <condition (ST)>
|
|
1197
|
+
# <text (TX)>
|
|
1198
|
+
# <conjunction component (ID)>
|
|
1199
|
+
# <order sequencing (OSD)>
|
|
1200
|
+
# <occurrence duration (CE)>
|
|
1201
|
+
# <total occurrences (NM)>
|
|
1202
|
+
end
|
|
1203
|
+
|
|
1204
|
+
#Generate HL7 TS (time stamp), within number of weeks in the future or past
|
|
1205
|
+
def TS(map, force=false)
|
|
1206
|
+
#check if the field is optional and randomly generate it of skip
|
|
1207
|
+
return '' if(!generate?(map, force))
|
|
1208
|
+
|
|
1209
|
+
#time of an event (TSComponentOne)
|
|
1210
|
+
ts = to_datetime(map).strftime('%Y%m%d%H%M%S.%L') #format('YYYYMMDDHHSS.SSS')Date.iso8601
|
|
1211
|
+
# TS is lenght sensetive, check max_len and trim appropriate
|
|
1212
|
+
if (ts.size > (maxlen = (map[:max_length]) ? map[:max_length].to_i : ts.size))
|
|
1213
|
+
# puts ts
|
|
1214
|
+
# ts = ts[0,maxlen]
|
|
1215
|
+
ts = ts.slice(0...maxlen)
|
|
1216
|
+
end
|
|
1217
|
+
return ts
|
|
1218
|
+
end
|
|
1219
|
+
|
|
1220
|
+
#Generate HL7 TX (text data) data type. A TX contains a single String value.
|
|
1221
|
+
def TX(map, force=false)
|
|
1222
|
+
#check if the field is optional and randomly generate it of skip
|
|
1223
|
+
return '' if(!generate?(map, force))
|
|
1224
|
+
# @@GENERAL_TEXT
|
|
1225
|
+
ID(map,true)
|
|
1226
|
+
end
|
|
1227
|
+
|
|
1228
|
+
#Generate an HL7 UVC (Value code and amount) data type.
|
|
1229
|
+
def UVC(map, force=false)
|
|
1230
|
+
#check if the field is optional and randomly generate it of skip
|
|
1231
|
+
return '' if(!generate?(map, force))
|
|
1232
|
+
val =[]
|
|
1233
|
+
# UVC uvc = ((UVC)map.fld)
|
|
1234
|
+
#value code (IS)
|
|
1235
|
+
val << IS(map, true)
|
|
1236
|
+
# is(['fld'=>uvc.getComponent(0), 'required'=>'R', 'codetable'=>map.codetable])
|
|
1237
|
+
#value amount (NM)
|
|
1238
|
+
# nm(['fld'=>uvc.getComponent(1), 'required'=>'R'])
|
|
1239
|
+
val << NM({},true)# description confuses NM generator
|
|
1240
|
+
val.join(@@HAT)
|
|
1241
|
+
end
|
|
1242
|
+
|
|
1243
|
+
# Visiting hours
|
|
1244
|
+
def VH(map, force=false)
|
|
1245
|
+
#check if the field is optional and randomly generate it of skip
|
|
1246
|
+
return '' if(!generate?(map, force))
|
|
1247
|
+
|
|
1248
|
+
val =[]
|
|
1249
|
+
# <start day range (ID)>
|
|
1250
|
+
val << ID(map,true)
|
|
1251
|
+
# <end day range (ID)>
|
|
1252
|
+
val << ID(map,true)
|
|
1253
|
+
# <start hour range (TM)>
|
|
1254
|
+
# <end hour range (TM)>
|
|
1255
|
+
val.join(@@HAT)
|
|
1256
|
+
end
|
|
1257
|
+
|
|
1258
|
+
#Generate an HL7 VID (version identifier) data type.
|
|
1259
|
+
def VID(map, force=false)
|
|
1260
|
+
#check if the field is optional and randomly generate it of skip
|
|
1261
|
+
return '' if(!generate?(map, force))
|
|
1262
|
+
|
|
1263
|
+
# VID vid = ((VID)map.fld)
|
|
1264
|
+
#version ID (ID)
|
|
1265
|
+
ID(map, true)
|
|
1266
|
+
#id(['fld'=>vid.getComponent(0), 'required'=>'R', 'codetable'=>map.codetable])
|
|
1267
|
+
|
|
1268
|
+
# internationalization code (CE)
|
|
1269
|
+
# international version ID (CE)
|
|
1270
|
+
end
|
|
1271
|
+
|
|
1272
|
+
# Value qualifier
|
|
1273
|
+
def VR(map, force=false)
|
|
1274
|
+
#check if the field is optional and randomly generate it of skip
|
|
1275
|
+
return '' if(!generate?(map, force))
|
|
1276
|
+
# <first data code value (ST)>
|
|
1277
|
+
ST(map,true)
|
|
1278
|
+
# <Last data code value (ST)>
|
|
1279
|
+
end
|
|
1280
|
+
|
|
1281
|
+
#Channel identifier
|
|
1282
|
+
def WVI(map, force=true)
|
|
1283
|
+
#check if the field is optional and randomly generate it of skip
|
|
1284
|
+
return '' if(!generate?(map, force))
|
|
1285
|
+
|
|
1286
|
+
# <channel number (NM)>
|
|
1287
|
+
NM(map, true)
|
|
1288
|
+
# <channel name (ST)>
|
|
1289
|
+
end
|
|
1290
|
+
|
|
1291
|
+
|
|
1292
|
+
# def WVS(map, force=false)
|
|
1293
|
+
# #check if the field is optional and randomly generate it of skip
|
|
1294
|
+
# return '' if(!autoGenerate?(map,force))
|
|
1295
|
+
# end
|
|
1296
|
+
|
|
1297
|
+
#Generate HL7 XAD (extended address)
|
|
1298
|
+
def XAD(map, force=false)
|
|
1299
|
+
#check if the field is optional and randomly generate it of skip
|
|
1300
|
+
return '' if(!generate?(map, force))
|
|
1301
|
+
|
|
1302
|
+
# same as address AD
|
|
1303
|
+
AD(map,true)
|
|
1304
|
+
#street address (SAD) (SAD)
|
|
1305
|
+
#other designation (ST)
|
|
1306
|
+
#city (ST)
|
|
1307
|
+
#state or province (ST)
|
|
1308
|
+
#zip or postal code (ST)
|
|
1309
|
+
#country (ID)
|
|
1310
|
+
#address type (ID)
|
|
1311
|
+
#other geographic designation (ST)
|
|
1312
|
+
#county/parish code (IS)
|
|
1313
|
+
#census tract (IS)
|
|
1314
|
+
#address representation code (ID)
|
|
1315
|
+
#address validity range (DR)
|
|
1316
|
+
end
|
|
1317
|
+
|
|
1318
|
+
# Generate HL7 XCN (extended composite ID number and name for persons)
|
|
1319
|
+
def XCN(map, force=false)
|
|
1320
|
+
#check if the field is optional and randomly generate it of skip
|
|
1321
|
+
return '' if(!generate?(map, force))
|
|
1322
|
+
|
|
1323
|
+
val=[]
|
|
1324
|
+
# XCN xcn = (XCN) map.fld
|
|
1325
|
+
# ID number (ST) (ST)
|
|
1326
|
+
val << ID(map, true)
|
|
1327
|
+
# xcn.getIDNumber().setValue(Math.abs(random.nextInt() % 300).toString())
|
|
1328
|
+
|
|
1329
|
+
val << PN(map, true)
|
|
1330
|
+
# family name (FN)
|
|
1331
|
+
# val << FN(map, true)
|
|
1332
|
+
# given name (ST)
|
|
1333
|
+
# val << @yml['person.names.first'].sample
|
|
1334
|
+
# second and further given names or initials thereof (ST)
|
|
1335
|
+
# val << @@INITIALS.to_a.sample
|
|
1336
|
+
# suffix (e.g., JR or III) (ST)
|
|
1337
|
+
# prefix (e.g., DR) (ST)
|
|
1338
|
+
# degree (e.g., MD) (IS)
|
|
1339
|
+
|
|
1340
|
+
# source table (IS)
|
|
1341
|
+
# assigning authority (HD)
|
|
1342
|
+
# name type code (ID)
|
|
1343
|
+
# identifier check digit (ST)
|
|
1344
|
+
# code identifying the check digit scheme employed (ID)
|
|
1345
|
+
# identifier type code (IS) (IS)
|
|
1346
|
+
# assigning facility (HD)
|
|
1347
|
+
# Name Representation code (ID)
|
|
1348
|
+
# name context (CE)
|
|
1349
|
+
# name validity range (DR)
|
|
1350
|
+
# name assembly order (ID)
|
|
1351
|
+
val.join(@@HAT)
|
|
1352
|
+
end
|
|
1353
|
+
|
|
1354
|
+
#Generate an HL7 XON (extended composite name and identification number for organizations) data type.
|
|
1355
|
+
def XON(map, force=false)
|
|
1356
|
+
#check if the field is optional and randomly generate it of skip
|
|
1357
|
+
return '' if(!generate?(map, force))
|
|
1358
|
+
|
|
1359
|
+
# XON xtn = (XON) map.fld
|
|
1360
|
+
val=[]
|
|
1361
|
+
#organization name (ST)
|
|
1362
|
+
val << ST(map, true)
|
|
1363
|
+
# st(['fld'=>xtn.getComponent(0), 'required'=>'R', 'codetable'=>map.codetable])
|
|
1364
|
+
#organization name type code (IS)
|
|
1365
|
+
val << ''
|
|
1366
|
+
#ID number (NM) (NM)
|
|
1367
|
+
val << NM(map, true)
|
|
1368
|
+
#nm(['fld'=>xtn.getComponent(2), 'required'=>'R'])
|
|
1369
|
+
#check digit (NM) (ST)
|
|
1370
|
+
#code identifying the check digit scheme employed (ID)
|
|
1371
|
+
#assigning authority (HD)
|
|
1372
|
+
#identifier type code (IS) (IS)
|
|
1373
|
+
#assigning facility ID (HD)
|
|
1374
|
+
#Name Representation code (ID)
|
|
1375
|
+
val.join(@@HAT)
|
|
1376
|
+
end
|
|
1377
|
+
|
|
1378
|
+
#Generate an HL7 XPN (extended person name) data type. This type consists of the following components=>
|
|
1379
|
+
def XPN(map, force=false)
|
|
1380
|
+
#check if the field is optional and randomly generate it of skip
|
|
1381
|
+
return '' if(!generate?(map, force))
|
|
1382
|
+
|
|
1383
|
+
# val=[]
|
|
1384
|
+
#family name (FN)
|
|
1385
|
+
# val << FN(map, true)
|
|
1386
|
+
# fn(['fld'=> xpn.getComponent(0),'required'=>'R'])
|
|
1387
|
+
#given name (ST)
|
|
1388
|
+
# val << @yml['person.names.first'].sample
|
|
1389
|
+
#xpn.givenName.setValue(firstNames.getAt(Math.abs(random.nextInt()%firstNames.size())));
|
|
1390
|
+
#xpn.getComponent(1).setValue(firstNames.getAt(Math.abs(random.nextInt()%firstNames.size())))
|
|
1391
|
+
#second and further given names or initials thereof (ST)
|
|
1392
|
+
# val << @@INITIALS.to_a.sample
|
|
1393
|
+
#xpn.secondAndFurtherGivenNamesOrInitialsThereof.setValue('ABCDEFGHIJKLMNOPQRSTUVWXYZ'.getAt(Math.abs(random.nextInt()%26)))
|
|
1394
|
+
#suffix (e.g., JR or III) (ST)
|
|
1395
|
+
#prefix (e.g., DR) (ST)
|
|
1396
|
+
#degree (e.g., MD) (IS)
|
|
1397
|
+
PN(map,true)
|
|
1398
|
+
|
|
1399
|
+
#name type code (ID)
|
|
1400
|
+
# val.join(@@HAT)
|
|
1401
|
+
|
|
1402
|
+
end
|
|
1403
|
+
|
|
1404
|
+
#Generate HL7 XTN (extended telecommunication number)
|
|
1405
|
+
def XTN(map, force=false)
|
|
1406
|
+
#check if the field is optional and randomly generate it of skip
|
|
1407
|
+
return '' if(!generate?(map, force))
|
|
1408
|
+
|
|
1409
|
+
#[(999)] 999-9999 [X99999][C any text] (TN)
|
|
1410
|
+
TN(map, true)
|
|
1411
|
+
#xtn.get9999999X99999CAnyText().setValue(phones.getAt(Math.abs(random.nextInt()%phones.size())))
|
|
1412
|
+
# telecommunication use code (ID)
|
|
1413
|
+
# telecommunication equipment type (ID) (ID)
|
|
1414
|
+
# Email address (ST)
|
|
1415
|
+
# Country Code (NM)
|
|
1416
|
+
# Area/city code (NM)
|
|
1417
|
+
# Phone number (NM)
|
|
1418
|
+
# Extension (NM)
|
|
1419
|
+
# any text (ST)
|
|
1420
|
+
end
|
|
1421
|
+
|
|
1422
|
+
# def xx(map, force=false)
|
|
1423
|
+
# #check if the field is optional and randomly generate it of skip
|
|
1424
|
+
# return '' if(!autoGenerate?(map,force))
|
|
1425
|
+
# end
|
|
1426
|
+
|
|
1427
|
+
# End of Data Types #
|
|
1428
|
+
|
|
1429
|
+
# Value of coded table returned as as single value
|
|
1430
|
+
def get_coded_value(attributes)
|
|
1431
|
+
codes = get_code_table(attributes)
|
|
1432
|
+
|
|
1433
|
+
# puts codes
|
|
1434
|
+
#Apply rules to find a value and description
|
|
1435
|
+
map = apply_rules(codes, attributes)
|
|
1436
|
+
#Return value only
|
|
1437
|
+
return map[:value]
|
|
1438
|
+
end
|
|
1439
|
+
|
|
1440
|
+
# Values and Description from code table returned as a pair.
|
|
1441
|
+
def get_coded_map(attributes)
|
|
1442
|
+
codes = get_code_table(attributes)
|
|
1443
|
+
|
|
1444
|
+
# puts codes
|
|
1445
|
+
#Apply rules to find a value and description
|
|
1446
|
+
#Returns map with code and description
|
|
1447
|
+
apply_rules(codes, attributes)
|
|
1448
|
+
end
|
|
1449
|
+
|
|
1450
|
+
def get_code_table(attributes)
|
|
1451
|
+
codeTable = get_name_without_base(attributes[:codetable])
|
|
1452
|
+
codes = @pp.get_code_table(codeTable)
|
|
1453
|
+
# Case when we are looking for code values defined in base schema for types
|
|
1454
|
+
# which are in custom/primary schema or the othere way around.
|
|
1455
|
+
if(@hp && (codes.first == Utils::DATA_LOOKUP_MIS))
|
|
1456
|
+
codes = @hp.get_code_table(codeTable)
|
|
1457
|
+
end
|
|
1458
|
+
return codes
|
|
1459
|
+
end
|
|
1460
|
+
|
|
1461
|
+
# Handle range values specified by '...' sequence, including empty range
|
|
1462
|
+
#TODO refactor candidate
|
|
1463
|
+
def apply_rules(codes, attributes)
|
|
1464
|
+
#safety check, no codes returns an empty map
|
|
1465
|
+
return {} if blank?(codes)
|
|
1466
|
+
|
|
1467
|
+
#index of random element
|
|
1468
|
+
idx = sample_index(codes.size)
|
|
1469
|
+
code = codes[idx][:value]
|
|
1470
|
+
description = codes[idx][:description]
|
|
1471
|
+
|
|
1472
|
+
if (code.include?(@@RANGE_INDICATOR))
|
|
1473
|
+
code = handle_ranges(code)
|
|
1474
|
+
end
|
|
1475
|
+
|
|
1476
|
+
if (code.size > (maxlen = (attributes[:max_length]) ? attributes[:max_length].to_i : code.size))
|
|
1477
|
+
#remove all codes wich values violate
|
|
1478
|
+
#codes.select! {|it| it[:value].size <= maxlen }
|
|
1479
|
+
code, description = handle_length(codes, maxlen)
|
|
1480
|
+
end
|
|
1481
|
+
|
|
1482
|
+
# got to have code, get an id, most basic - TODO: verify this.
|
|
1483
|
+
# if(Utils.blank?(code))
|
|
1484
|
+
# code, description = ID({},true), ''
|
|
1485
|
+
# end
|
|
1486
|
+
# return code, description
|
|
1487
|
+
|
|
1488
|
+
# puts code + ', ' + description
|
|
1489
|
+
return {:value => code, :description => description}
|
|
1490
|
+
end
|
|
1491
|
+
|
|
1492
|
+
def handle_length(codes, maxlen)
|
|
1493
|
+
idx = codes.find_index { |it| it[:value].size <= maxlen }
|
|
1494
|
+
|
|
1495
|
+
if (!idx)
|
|
1496
|
+
code, description = '', ''
|
|
1497
|
+
else
|
|
1498
|
+
# puts codes
|
|
1499
|
+
code = codes[idx][:value]
|
|
1500
|
+
description = codes[idx][:description]
|
|
1501
|
+
end
|
|
1502
|
+
return code, description
|
|
1503
|
+
end
|
|
1504
|
+
|
|
1505
|
+
def handle_ranges(code)
|
|
1506
|
+
# if (code.include?(@@RANGE_INDICATOR))
|
|
1507
|
+
ends = code.delete(' ').split('...').map { |it| it }
|
|
1508
|
+
if (ends.empty?) # This is indication that codetable does not have any values
|
|
1509
|
+
code = ''
|
|
1510
|
+
else #Handle range values, build range and pick random value
|
|
1511
|
+
# range = ends.first..ends.last
|
|
1512
|
+
# code = range.to_a.sample
|
|
1513
|
+
|
|
1514
|
+
# per Galina: Invalid value 'Q8' appears in segment 4:PD1, field 20, repetition 1, component 1, subcomponent 1,
|
|
1515
|
+
# but does not appear in code table 2.4:141.
|
|
1516
|
+
# I think you had to fix this one before to pull only the first and the last values from each row.
|
|
1517
|
+
code = ends.sample
|
|
1518
|
+
end
|
|
1519
|
+
return code
|
|
1520
|
+
end
|
|
1521
|
+
|
|
1522
|
+
# Returns randomly generated Id of required length, of single digit id
|
|
1523
|
+
def generate_length_bound_id(maxlen, str=@@random.rand(100000000).to_s)
|
|
1524
|
+
idx = maxlen
|
|
1525
|
+
if(maxlen > str.size)
|
|
1526
|
+
str = str.ljust(maxlen,'0')
|
|
1527
|
+
idx = str.size
|
|
1528
|
+
end
|
|
1529
|
+
#safe fail
|
|
1530
|
+
#this handles case when maxlen is less then 1
|
|
1531
|
+
idx = [0,idx-1].max
|
|
1532
|
+
return str[0..idx]
|
|
1533
|
+
end
|
|
1534
|
+
|
|
1535
|
+
|
|
1536
|
+
# # Returns randomly generated Id of required length, of single digit id
|
|
1537
|
+
# def generateLengthBoundId1(map, str=@@random.rand(100000000).to_s)
|
|
1538
|
+
# (!Utils.blank?(map[:codetable]))? get_coded_value(map): @@random.rand(@@UP_TO_3_DGTS).to_s
|
|
1539
|
+
#
|
|
1540
|
+
# map[:maxlen]
|
|
1541
|
+
# end
|
|
1542
|
+
|
|
1543
|
+
# If field are X,W,B (Not Supported, Withdrawn Fields or Backward Compatible) returns false.
|
|
1544
|
+
# Conditional (C) ?
|
|
1545
|
+
# For Optional field (O) makes random choice
|
|
1546
|
+
# R - Required returns true
|
|
1547
|
+
# def autoGenerate?(map, force=false)
|
|
1548
|
+
def generate?(map, force=false)
|
|
1549
|
+
# return true
|
|
1550
|
+
return true if(force) #forced generation, ignore mappings
|
|
1551
|
+
|
|
1552
|
+
#look up in the mapping
|
|
1553
|
+
case map[:required]
|
|
1554
|
+
when 'X','W','B' then false;
|
|
1555
|
+
when 'R' then true;
|
|
1556
|
+
when 'O' then [true,false].sample();
|
|
1557
|
+
else false ;
|
|
1558
|
+
end
|
|
1559
|
+
# if(['X','W','B'].include?(map[:required]))then return false end
|
|
1560
|
+
# if(map[:required] =='R') then return true end
|
|
1561
|
+
# if(map[:required] == 'O') then return true end #random boolean
|
|
1562
|
+
end
|
|
1563
|
+
|
|
1564
|
+
# @return DateTime generated with consideration of description string for dates in the future
|
|
1565
|
+
def to_datetime(map)
|
|
1566
|
+
#for Time Stamp one way to figure out if event is in the future of in the past to look for key words in description
|
|
1567
|
+
isFutureEvent = !blank?(map[:description])&& map[:description].include?('End') #so 'Role End Date/Time'
|
|
1568
|
+
seed = 365 #seed bounds duration of time to a year
|
|
1569
|
+
days = @@random.rand(seed)
|
|
1570
|
+
|
|
1571
|
+
if(map[:description]=='Date/Time Of Birth')
|
|
1572
|
+
isFutureEvent = false
|
|
1573
|
+
years = rand(30..50)
|
|
1574
|
+
days = days + 365*years # make a person 30 years old
|
|
1575
|
+
end
|
|
1576
|
+
|
|
1577
|
+
(isFutureEvent) ? DateTime.now().next_day(days) : DateTime.now().prev_day(days)
|
|
1578
|
+
end
|
|
1579
|
+
|
|
1580
|
+
# convention method to modify values of attirbutes
|
|
1581
|
+
def reset_map_attr(map, key, value)
|
|
1582
|
+
map[key.to_sym]=value
|
|
1583
|
+
return map
|
|
1584
|
+
end
|
|
1585
|
+
|
|
1586
|
+
end
|