cqm-models 0.7.2

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.
Files changed (178) hide show
  1. checksums.yaml +7 -0
  2. data/.eslintignore +1 -0
  3. data/.eslintrc.json +26 -0
  4. data/.github/PULL_REQUEST_TEMPLATE.md +32 -0
  5. data/.gitignore +21 -0
  6. data/.rspec +2 -0
  7. data/.rubocop.yml +42 -0
  8. data/.travis.yml +21 -0
  9. data/Gemfile +5 -0
  10. data/LICENSE.txt +201 -0
  11. data/README.md +26 -0
  12. data/Rakefile +12 -0
  13. data/app/assets/javascripts/AdverseEvent.js +27 -0
  14. data/app/assets/javascripts/AllDataElements.js +120 -0
  15. data/app/assets/javascripts/AllergyIntolerance.js +27 -0
  16. data/app/assets/javascripts/AssessmentPerformed.js +30 -0
  17. data/app/assets/javascripts/AssessmentRecommended.js +27 -0
  18. data/app/assets/javascripts/CareGoal.js +25 -0
  19. data/app/assets/javascripts/CommunicationFromPatientToProvider.js +26 -0
  20. data/app/assets/javascripts/CommunicationFromProviderToPatient.js +26 -0
  21. data/app/assets/javascripts/CommunicationFromProviderToProvider.js +26 -0
  22. data/app/assets/javascripts/Component.js +22 -0
  23. data/app/assets/javascripts/Concept.js +14 -0
  24. data/app/assets/javascripts/DeviceApplied.js +29 -0
  25. data/app/assets/javascripts/DeviceOrder.js +26 -0
  26. data/app/assets/javascripts/DeviceRecommended.js +26 -0
  27. data/app/assets/javascripts/Diagnosis.js +27 -0
  28. data/app/assets/javascripts/DiagnosticStudyOrder.js +27 -0
  29. data/app/assets/javascripts/DiagnosticStudyPerformed.js +33 -0
  30. data/app/assets/javascripts/DiagnosticStudyRecommended.js +27 -0
  31. data/app/assets/javascripts/EncounterOrder.js +27 -0
  32. data/app/assets/javascripts/EncounterPerformed.js +32 -0
  33. data/app/assets/javascripts/EncounterRecommended.js +27 -0
  34. data/app/assets/javascripts/FacilityLocation.js +22 -0
  35. data/app/assets/javascripts/FamilyHistory.js +25 -0
  36. data/app/assets/javascripts/Id.js +22 -0
  37. data/app/assets/javascripts/ImmunizationAdministered.js +30 -0
  38. data/app/assets/javascripts/ImmunizationOrder.js +30 -0
  39. data/app/assets/javascripts/InterventionOrder.js +26 -0
  40. data/app/assets/javascripts/InterventionPerformed.js +29 -0
  41. data/app/assets/javascripts/InterventionRecommended.js +26 -0
  42. data/app/assets/javascripts/LaboratoryTestOrder.js +27 -0
  43. data/app/assets/javascripts/LaboratoryTestPerformed.js +33 -0
  44. data/app/assets/javascripts/LaboratoryTestRecommended.js +27 -0
  45. data/app/assets/javascripts/Measure.js +76 -0
  46. data/app/assets/javascripts/MeasurePackage.js +20 -0
  47. data/app/assets/javascripts/MedicationActive.js +28 -0
  48. data/app/assets/javascripts/MedicationAdministered.js +31 -0
  49. data/app/assets/javascripts/MedicationDischarge.js +30 -0
  50. data/app/assets/javascripts/MedicationDispensed.js +31 -0
  51. data/app/assets/javascripts/MedicationOrder.js +34 -0
  52. data/app/assets/javascripts/Participation.js +21 -0
  53. data/app/assets/javascripts/Patient.js +248 -0
  54. data/app/assets/javascripts/PatientCareExperience.js +23 -0
  55. data/app/assets/javascripts/PatientCharacteristic.js +23 -0
  56. data/app/assets/javascripts/PatientCharacteristicBirthdate.js +24 -0
  57. data/app/assets/javascripts/PatientCharacteristicClinicalTrialParticipant.js +26 -0
  58. data/app/assets/javascripts/PatientCharacteristicEthnicity.js +23 -0
  59. data/app/assets/javascripts/PatientCharacteristicExpired.js +25 -0
  60. data/app/assets/javascripts/PatientCharacteristicPayer.js +24 -0
  61. data/app/assets/javascripts/PatientCharacteristicRace.js +23 -0
  62. data/app/assets/javascripts/PatientCharacteristicSex.js +23 -0
  63. data/app/assets/javascripts/PhysicalExamOrder.js +28 -0
  64. data/app/assets/javascripts/PhysicalExamPerformed.js +31 -0
  65. data/app/assets/javascripts/PhysicalExamRecommended.js +28 -0
  66. data/app/assets/javascripts/ProcedureOrder.js +30 -0
  67. data/app/assets/javascripts/ProcedurePerformed.js +35 -0
  68. data/app/assets/javascripts/ProcedureRecommended.js +30 -0
  69. data/app/assets/javascripts/ProviderCareExperience.js +23 -0
  70. data/app/assets/javascripts/ProviderCharacteristic.js +23 -0
  71. data/app/assets/javascripts/Ratio.js +22 -0
  72. data/app/assets/javascripts/Result.js +28 -0
  73. data/app/assets/javascripts/ResultComponent.js +21 -0
  74. data/app/assets/javascripts/SubstanceAdministered.js +30 -0
  75. data/app/assets/javascripts/SubstanceOrder.js +32 -0
  76. data/app/assets/javascripts/SubstanceRecommended.js +32 -0
  77. data/app/assets/javascripts/Symptom.js +25 -0
  78. data/app/assets/javascripts/ValueSet.js +30 -0
  79. data/app/assets/javascripts/basetypes/Code.js +25 -0
  80. data/app/assets/javascripts/basetypes/DataElement.js +36 -0
  81. data/app/assets/javascripts/basetypes/DateTime.js +18 -0
  82. data/app/assets/javascripts/basetypes/Interval.js +35 -0
  83. data/app/assets/javascripts/basetypes/Quantity.js +20 -0
  84. data/app/assets/javascripts/index.js +12 -0
  85. data/app/models/models.rb +78 -0
  86. data/app/models/qdm/adverse_event.rb +15 -0
  87. data/app/models/qdm/allergy_intolerance.rb +15 -0
  88. data/app/models/qdm/assessment_performed.rb +18 -0
  89. data/app/models/qdm/assessment_recommended.rb +15 -0
  90. data/app/models/qdm/basetypes/code.rb +56 -0
  91. data/app/models/qdm/basetypes/data_element.rb +42 -0
  92. data/app/models/qdm/basetypes/interval.rb +54 -0
  93. data/app/models/qdm/basetypes/quantity.rb +52 -0
  94. data/app/models/qdm/care_goal.rb +13 -0
  95. data/app/models/qdm/communication_from_patient_to_provider.rb +14 -0
  96. data/app/models/qdm/communication_from_provider_to_patient.rb +14 -0
  97. data/app/models/qdm/communication_from_provider_to_provider.rb +14 -0
  98. data/app/models/qdm/component.rb +10 -0
  99. data/app/models/qdm/device_applied.rb +17 -0
  100. data/app/models/qdm/device_order.rb +14 -0
  101. data/app/models/qdm/device_recommended.rb +14 -0
  102. data/app/models/qdm/diagnosis.rb +15 -0
  103. data/app/models/qdm/diagnostic_study_order.rb +15 -0
  104. data/app/models/qdm/diagnostic_study_performed.rb +21 -0
  105. data/app/models/qdm/diagnostic_study_recommended.rb +15 -0
  106. data/app/models/qdm/encounter_order.rb +15 -0
  107. data/app/models/qdm/encounter_performed.rb +20 -0
  108. data/app/models/qdm/encounter_recommended.rb +15 -0
  109. data/app/models/qdm/facility_location.rb +10 -0
  110. data/app/models/qdm/family_history.rb +13 -0
  111. data/app/models/qdm/id.rb +10 -0
  112. data/app/models/qdm/immunization_administered.rb +18 -0
  113. data/app/models/qdm/immunization_order.rb +18 -0
  114. data/app/models/qdm/intervention_order.rb +14 -0
  115. data/app/models/qdm/intervention_performed.rb +17 -0
  116. data/app/models/qdm/intervention_recommended.rb +14 -0
  117. data/app/models/qdm/laboratory_test_order.rb +15 -0
  118. data/app/models/qdm/laboratory_test_performed.rb +21 -0
  119. data/app/models/qdm/laboratory_test_recommended.rb +15 -0
  120. data/app/models/qdm/medication_active.rb +16 -0
  121. data/app/models/qdm/medication_administered.rb +19 -0
  122. data/app/models/qdm/medication_discharge.rb +18 -0
  123. data/app/models/qdm/medication_dispensed.rb +19 -0
  124. data/app/models/qdm/medication_order.rb +22 -0
  125. data/app/models/qdm/participation.rb +9 -0
  126. data/app/models/qdm/patient.rb +201 -0
  127. data/app/models/qdm/patient_care_experience.rb +11 -0
  128. data/app/models/qdm/patient_characteristic.rb +11 -0
  129. data/app/models/qdm/patient_characteristic_birthdate.rb +12 -0
  130. data/app/models/qdm/patient_characteristic_clinical_trial_participant.rb +14 -0
  131. data/app/models/qdm/patient_characteristic_ethnicity.rb +11 -0
  132. data/app/models/qdm/patient_characteristic_expired.rb +13 -0
  133. data/app/models/qdm/patient_characteristic_payer.rb +12 -0
  134. data/app/models/qdm/patient_characteristic_race.rb +11 -0
  135. data/app/models/qdm/patient_characteristic_sex.rb +11 -0
  136. data/app/models/qdm/physical_exam_order.rb +16 -0
  137. data/app/models/qdm/physical_exam_performed.rb +19 -0
  138. data/app/models/qdm/physical_exam_recommended.rb +16 -0
  139. data/app/models/qdm/procedure_order.rb +18 -0
  140. data/app/models/qdm/procedure_performed.rb +23 -0
  141. data/app/models/qdm/procedure_recommended.rb +18 -0
  142. data/app/models/qdm/provider_care_experience.rb +11 -0
  143. data/app/models/qdm/provider_characteristic.rb +11 -0
  144. data/app/models/qdm/ratio.rb +10 -0
  145. data/app/models/qdm/result_component.rb +9 -0
  146. data/app/models/qdm/substance_administered.rb +18 -0
  147. data/app/models/qdm/substance_order.rb +20 -0
  148. data/app/models/qdm/substance_recommended.rb +20 -0
  149. data/app/models/qdm/symptom.rb +13 -0
  150. data/app/models/qdm/tacoma/concept.rb +14 -0
  151. data/app/models/qdm/tacoma/measure.rb +172 -0
  152. data/app/models/qdm/tacoma/measure_package.rb +10 -0
  153. data/app/models/qdm/tacoma/valueset.rb +68 -0
  154. data/bin/console +14 -0
  155. data/bin/setup +8 -0
  156. data/bin/validate_dist.sh +17 -0
  157. data/config/mongoid.yml +6 -0
  158. data/cqm-models.gemspec +29 -0
  159. data/data/oids.json +584 -0
  160. data/dist/index.js +157647 -0
  161. data/lib/cqm/models.rb +1 -0
  162. data/lib/generate_models.rb +330 -0
  163. data/modelinfo/qdm-modelinfo-4.2.xml +515 -0
  164. data/modelinfo/qdm-modelinfo-4.3.xml +521 -0
  165. data/modelinfo/qdm-modelinfo-5.0.1.xml +436 -0
  166. data/modelinfo/qdm-modelinfo-5.0.2.xml +445 -0
  167. data/modelinfo/qdm-modelinfo-5.0.xml +429 -0
  168. data/modelinfo/qdm-modelinfo-5.3.xml +524 -0
  169. data/package.json +34 -0
  170. data/templates/all_data_elements_template.js.erb +4 -0
  171. data/templates/index_template.js.erb +12 -0
  172. data/templates/models_template.rb.erb +21 -0
  173. data/templates/mongoose_template.js.erb +20 -0
  174. data/templates/patient_extension.rb.erb +194 -0
  175. data/templates/patient_template.js.erb +247 -0
  176. data/tmp/.keep +0 -0
  177. data/yarn.lock +1901 -0
  178. metadata +320 -0
data/lib/cqm/models.rb ADDED
@@ -0,0 +1 @@
1
+ require_relative '../../app/models/models'
@@ -0,0 +1,330 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require 'nokogiri'
4
+ require 'active_support/all'
5
+ require 'rails/generators'
6
+ require 'erb'
7
+ require 'json'
8
+
9
+ ###############################################################################
10
+ # Helpers
11
+ ###############################################################################
12
+
13
+ # Lookups for modelinfo 'element types' to Ruby+Mongoid types.
14
+ TYPE_LOOKUP_RB = {
15
+ 'System.DateTime': 'DateTime',
16
+ 'System.Integer': 'Integer',
17
+ 'System.Quantity': 'Quantity',
18
+ 'System.Code': 'Code',
19
+ 'System.Any': 'Any',
20
+ 'interval<System.DateTime>': 'Interval',
21
+ 'interval<System.Quantity>': 'Interval',
22
+ 'list<QDM.Component>': 'Array',
23
+ 'System.String': 'String',
24
+ 'list<QDM.Id>': 'Array',
25
+ 'list<QDM.ResultComponent>': 'Array',
26
+ 'list<QDM.FacilityLocation>': 'Array',
27
+ 'list<System.Code>': 'Array',
28
+ 'QDM.Id': 'String',
29
+ 'System.Decimal': 'Float',
30
+ 'System.Time': 'Time',
31
+ 'System.Concept': 'Any'
32
+ }.stringify_keys!
33
+
34
+ # Lookups for modelinfo 'element types' to JavaScript+Mongoose types.
35
+ TYPE_LOOKUP_JS = {
36
+ 'System.DateTime': 'DateTime',
37
+ 'System.Integer': 'Number',
38
+ 'System.Quantity': 'Quantity',
39
+ 'System.Code': 'Code',
40
+ 'System.Any': '{}',
41
+ 'interval<System.DateTime>': 'Interval',
42
+ 'interval<System.Quantity>': 'Interval',
43
+ 'list<QDM.Component>': '[]',
44
+ 'System.String': 'String',
45
+ 'list<QDM.Id>': '[String]',
46
+ 'list<QDM.ResultComponent>': '[]',
47
+ 'list<QDM.FacilityLocation>': '[]',
48
+ 'list<System.Code>': '[Code]',
49
+ 'QDM.Id': 'String',
50
+ 'System.Decimal': 'Number',
51
+ 'System.Time': 'DateTime',
52
+ 'System.Concept': '{}'
53
+ }.stringify_keys!
54
+
55
+ ###############################################################################
56
+ # Start of modelinfo file parsing
57
+ ###############################################################################
58
+
59
+ puts 'Parsing modelinfo file...'
60
+
61
+ Dir.chdir ENV['TRAVIS_BUILD_DIR'] if ENV['CI']
62
+ puts Dir.pwd
63
+ puts Dir.entries('.')
64
+
65
+ # Open specified modelinfo file
66
+ modelinfo_file = ARGV[0]
67
+ raise 'Please provide a valid modelinfo file path and name.' if modelinfo_file.blank? || !File.file?(modelinfo_file)
68
+ modelinfo = File.open(modelinfo_file) { |f| Nokogiri::XML(f) }
69
+
70
+ # Open specified HQMF oid file
71
+ oids_file = ARGV[1]
72
+ raise 'Please provide a valid HQMF oid file path and name.' if oids_file.blank? || !File.file?(oids_file)
73
+ oids = JSON.parse(File.read(oids_file))
74
+
75
+ # If this script was run with a third parameter of 'TEST', then generate the models in a
76
+ # not standard location. This helps with testing.
77
+ IS_TEST = (ARGV[2] == 'TEST')
78
+
79
+ # Grab QDM version as defined in the modelinfo file
80
+ qdm_version = modelinfo.xpath('//ns4:modelInfo').first.attributes['version'].value
81
+
82
+ # Datatypes (keys are the datatype name, values are the datatype attributes)
83
+ datatypes = {}
84
+
85
+ # Loop through each typeInfo node (each of these is a QDM datatype)
86
+ modelinfo.xpath('//ns4:typeInfo').each do |type|
87
+ # Grab the name of this QDM datatype
88
+ datatype_name = type.attributes['name'].value.split('.').last
89
+
90
+ # Grab the QDM attributes for this datatype
91
+ attributes = []
92
+ type.xpath('./ns4:element').each do |attribute|
93
+ # Grab the name of this QDM datatype attribute
94
+ attribute_name = attribute.attributes['name'].value
95
+
96
+ # Grab the type of this QDM datatype attribute
97
+ attribute_type = if attribute.attributes['type']
98
+ attribute.attributes['type'].value
99
+ else
100
+ 'System.Any'
101
+ end
102
+
103
+ next if attribute_name.blank? || attribute_type.blank?
104
+
105
+ # Store name and type
106
+ attributes << { name: attribute_name, type: attribute_type }
107
+ end
108
+
109
+ # Store datatype and its attributes (reject irrelevant datatypes)
110
+ next if datatype_name.include?('Negative') || datatype_name.include?('Positive') || datatype_name.include?('QDMBaseType')
111
+ datatypes[datatype_name] = attributes
112
+ end
113
+
114
+ ###############################################################################
115
+ # Start of model generation
116
+ ###############################################################################
117
+
118
+ puts 'Generating Ruby models...'
119
+
120
+ # Do a quick sanity check on attribute types
121
+ datatypes.each do |datatype, attributes|
122
+ attributes.each do |attribute|
123
+ raise 'Unsupported type from modelinfo file for Ruby types: ' + attribute[:type] + 'from: ' + datatype if TYPE_LOOKUP_RB[attribute[:type]].blank?
124
+ raise 'Unsupported type from modelinfo file for JavaScript types: ' + attribute[:type] + 'from: ' + datatype if TYPE_LOOKUP_JS[attribute[:type]].blank?
125
+ end
126
+ end
127
+
128
+ # Create Ruby models
129
+ extra_fields_rb = [
130
+ 'hqmfOid:String',
131
+ 'qrdaOid:String',
132
+ 'category:String',
133
+ 'qdmStatus:String',
134
+ 'qdmVersion:String'
135
+ ]
136
+ base_module = 'QDM::'
137
+ base_module = 'Test::QDM::' if IS_TEST
138
+ datatypes.each do |datatype, attributes|
139
+ Rails::Generators.invoke('mongoid:model', [base_module + datatype] + attributes.collect { |attribute| attribute[:name] + ':' + TYPE_LOOKUP_RB[attribute[:type]] } + extra_fields_rb)
140
+ end
141
+
142
+ # Create require file (if not in test mode)
143
+ unless IS_TEST
144
+ model_template = File.read('templates/models_template.rb.erb')
145
+ renderer = ERB.new(model_template, nil, '-')
146
+ file_path = 'app/models/models.rb'
147
+ File.open(file_path, 'w') { |file| file.puts renderer.result(binding) }
148
+ end
149
+
150
+ puts 'Generating JavaScript models...'
151
+
152
+ # Create JavaScript models
153
+ template = File.read('templates/mongoose_template.js.erb')
154
+ renderer = ERB.new(template, nil, '-')
155
+ file_path = 'app/assets/javascripts/'
156
+ file_path = 'tmp/' if IS_TEST
157
+ extra_fields_js = [
158
+ { name: 'hqmfOid', type: 'System.String' },
159
+ { name: 'qrdaOid', type: 'System.String' },
160
+ { name: 'category', type: 'System.String' },
161
+ { name: 'qdmStatus', type: 'System.String' },
162
+ { name: 'qdmVersion', type: 'System.String' },
163
+ { name: '_type', type: 'System.String' }
164
+ ]
165
+ datatypes.each do |datatype, attributes|
166
+ if datatype == 'Patient'
167
+ # Handle Patient as its own special case, with its own template.
168
+ patient_template = File.read('templates/patient_template.js.erb')
169
+ patient_renderer = ERB.new(patient_template, nil, '-')
170
+ attrs_with_extras = attributes + extra_fields_js
171
+ puts ' ' + file_path + datatype + '.js'
172
+ File.open(file_path + datatype + '.js', 'w') { |file| file.puts patient_renderer.result(binding) }
173
+ else
174
+ attrs_with_extras = attributes + extra_fields_js
175
+ puts ' ' + file_path + datatype + '.js'
176
+ File.open(file_path + datatype + '.js', 'w') { |file| file.puts renderer.result(binding) }
177
+ end
178
+ end
179
+
180
+ # Create require file (if not in test mode)
181
+ unless IS_TEST
182
+ indtemplate = File.read('templates/index_template.js.erb')
183
+ renderer = ERB.new(indtemplate, nil, '-')
184
+ file_path = 'app/assets/javascripts/index.js'
185
+ File.open(file_path, 'w') { |file| file.puts renderer.result(binding) }
186
+
187
+ alltemplate = File.read('templates/all_data_elements_template.js.erb')
188
+ renderer = ERB.new(alltemplate, nil, '-')
189
+ file_path = 'app/assets/javascripts/AllDataElements.js'
190
+ File.open(file_path, 'w') { |file| file.puts renderer.result(binding) }
191
+ end
192
+
193
+ ###############################################################################
194
+ # Model post processing
195
+ ###############################################################################
196
+
197
+ puts 'Post processing...'
198
+
199
+ # Ruby post processing
200
+ ruby_models_path = 'app/models/qdm/'
201
+ ruby_models_path = 'app/models/test/qdm/' if IS_TEST
202
+ Dir.glob(ruby_models_path + '*.rb').each do |file_name|
203
+ contents = File.read(file_name)
204
+
205
+ # Cut out the 'Any' type placeholder (these attributes could point to anything).
206
+ contents.gsub!(/, type: Any/, '')
207
+
208
+ # Add QDM version
209
+ contents.gsub!(/field :qdmVersion, type: String/, "field :qdmVersion, type: String, default: '#{qdm_version}'")
210
+
211
+ # Add HQMF oid (if it exists in the given HQMF oid mapping file)
212
+ dc_name = File.basename(file_name, '.*')
213
+ if oids[dc_name].present? && oids[dc_name]['hqmf_oid'].present?
214
+ contents.gsub!(/ field :hqmfOid, type: String\n/, " field :hqmfOid, type: String, default: '#{oids[dc_name]['hqmf_oid']}'\n")
215
+ else
216
+ contents.gsub!(/ field :hqmfOid, type: String\n/, '') # Don't include this field
217
+ end
218
+
219
+ # Add QRDA oid (if it exists in the given QRDA oid mapping file)
220
+ if oids[dc_name].present? && oids[dc_name]['qrda_oid'].present?
221
+ contents.gsub!(/ field :qrdaOid, type: String\n/, " field :qrdaOid, type: String, default: '#{oids[dc_name]['qrda_oid']}'\n")
222
+ else
223
+ contents.gsub!(/ field :qrdaOid, type: String\n/, '') # Don't include this field
224
+ end
225
+
226
+ # Add category
227
+ if oids[dc_name].present? && oids[dc_name]['category'].present?
228
+ contents.gsub!(/ field :category, type: String\n/, " field :category, type: String, default: '#{oids[dc_name]['category']}'\n")
229
+ else
230
+ contents.gsub!(/ field :category, type: String\n/, '') # Don't include this field
231
+ end
232
+
233
+ # Add status
234
+ if oids[dc_name].present? && oids[dc_name]['status'].present?
235
+ contents.gsub!(/ field :qdmStatus, type: String\n/, " field :qdmStatus, type: String, default: '#{oids[dc_name]['status']}'\n")
236
+ else
237
+ contents.gsub!(/ field :qdmStatus, type: String\n/, '') # Don't include this field
238
+ end
239
+
240
+ File.open(file_name, 'w') { |file| file.puts contents }
241
+ end
242
+
243
+ # JavaScript post processing
244
+ js_models_path = 'app/assets/javascripts/'
245
+ js_models_path = 'tmp/' if IS_TEST
246
+ files = Dir.glob(js_models_path + '*.js').each do |file_name|
247
+ contents = File.read(file_name)
248
+
249
+ # Replace 'Any' type placeholder (these attributes could point to anything).
250
+ contents.gsub!(/: Any/, ': {}')
251
+
252
+ # Add QDM version
253
+ contents.gsub!(/qdmVersion: String/, "qdmVersion: { type: String, default: '#{qdm_version}' }")
254
+
255
+ # Add HQMF oid (if it exists in the given HQMF oid mapping file)
256
+ dc_name = File.basename(file_name.underscore, '.*')
257
+ if oids[dc_name].present? && oids[dc_name]['hqmf_oid'].present?
258
+ contents.gsub!(/ hqmfOid: String,\n/, " hqmfOid: { type: String, default: '#{oids[dc_name]['hqmf_oid']}' },\n")
259
+ else
260
+ contents.gsub!(/ hqmfOid: String,\n/, '') # Don't include this field
261
+ end
262
+
263
+ # Add QRDA oid (if it exists in the given QRDA oid mapping file)
264
+ if oids[dc_name].present? && oids[dc_name]['qrda_oid'].present?
265
+ contents.gsub!(/ qrdaOid: String,\n/, " qrdaOid: { type: String, default: '#{oids[dc_name]['qrda_oid']}' },\n")
266
+ else
267
+ contents.gsub!(/ qrdaOid: String,\n/, '') # Don't include this field
268
+ end
269
+
270
+ # Add category
271
+ if oids[dc_name].present? && oids[dc_name]['category'].present?
272
+ contents.gsub!(/ category: String,\n/, " category: { type: String, default: '#{oids[dc_name]['category']}' },\n")
273
+ else
274
+ contents.gsub!(/ category: String,\n/, '') # Don't include this field
275
+ end
276
+
277
+ # Add status
278
+ if oids[dc_name].present? && oids[dc_name]['status'].present?
279
+ contents.gsub!(/ qdmStatus: String,\n/, " qdmStatus: { type: String, default: '#{oids[dc_name]['status']}' },\n")
280
+ else
281
+ contents.gsub!(/ qdmStatus: String,\n/, '') # Don't include this field
282
+ end
283
+
284
+ # Add class
285
+ contents.gsub!(/ _type: String,\n/, " _type: { type: String, default: '#{dc_name.camelize}' },\n")
286
+
287
+ File.open(file_name, 'w') { |file| file.puts contents }
288
+ end
289
+
290
+ # Inject Ruby Patient model extensions
291
+ template = File.read('templates/patient_extension.rb.erb')
292
+ renderer = ERB.new(template, nil, '-')
293
+ rb_patient = File.read(ruby_models_path + 'patient.rb')
294
+ rb_patient.gsub!(/end/, renderer.result(binding))
295
+ File.open(ruby_models_path + 'patient.rb', 'w') { |file| file.write(rb_patient) }
296
+
297
+ # Make sure Ruby models are in the correct module
298
+ ruby_models_path = 'app/models/qdm/'
299
+ ruby_models_path = 'app/models/test/qdm/' if IS_TEST
300
+ Dir.glob(ruby_models_path + '*.rb').each do |file_name|
301
+ contents = File.read(file_name)
302
+ contents.gsub!('Qdm', 'QDM')
303
+ contents.gsub!('Code', 'QDM::Code')
304
+ contents.gsub!('Interval', 'QDM::Interval')
305
+ contents.gsub!('Quantity', 'QDM::Quantity')
306
+ File.open(file_name, 'w') { |file| file.puts contents }
307
+ end
308
+
309
+ # Set embedded in for datatypes
310
+ Dir.glob(ruby_models_path + '*.rb').each do |file_name|
311
+ contents = File.read(file_name)
312
+ next if File.basename(file_name) == 'patient.rb'
313
+ contents.gsub!(/ include Mongoid::Document\n/, " include Mongoid::Document\n embedded_in :patient\n")
314
+ File.open(file_name, 'w') { |file| file.puts contents }
315
+ end
316
+
317
+ # Make sure Ruby datatypes models have the correct inheritance
318
+ Dir.glob(ruby_models_path + '*.rb').each do |file_name|
319
+ contents = ''
320
+ File.open(file_name).each_line.with_index do |line, index|
321
+ line.gsub!("\n", " < DataElement\n") if index.zero? && !file_name.include?('/patient.rb')
322
+ contents += "module QDM\n # #{file_name}\n #{line.gsub('QDM::', '')}" if index.zero?
323
+ contents += ' ' unless index.zero? || line.blank?
324
+ contents += line unless index.zero?
325
+ end
326
+ contents += 'end'
327
+ File.open(file_name, 'w') { |file| file.puts contents }
328
+ end
329
+
330
+ puts 'Done.'