pvdgm_services 0.1.0

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 (256) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +29 -0
  3. data/Rakefile +40 -0
  4. data/app/contexts/services/accept_hl7_message_context.rb +32 -0
  5. data/app/contexts/services/application_mds_context.rb +21 -0
  6. data/app/contexts/services/complete_sltc_registration_process_context.rb +23 -0
  7. data/app/contexts/services/create_account_mapping_context.rb +23 -0
  8. data/app/contexts/services/create_configured_account_context.rb +26 -0
  9. data/app/contexts/services/create_configured_facility_context.rb +26 -0
  10. data/app/contexts/services/create_credential_context.rb +23 -0
  11. data/app/contexts/services/create_facility_mapping_context.rb +23 -0
  12. data/app/contexts/services/create_public_key_context.rb +22 -0
  13. data/app/contexts/services/create_service_context.rb +22 -0
  14. data/app/contexts/services/create_service_definition_context.rb +26 -0
  15. data/app/contexts/services/create_sltc_registration_context.rb +24 -0
  16. data/app/contexts/services/create_third_party_context.rb +22 -0
  17. data/app/contexts/services/hl7_message_trimming_context.rb +19 -0
  18. data/app/contexts/services/invoke_service_context.rb +21 -0
  19. data/app/contexts/services/list_sltc_providers_context.rb +22 -0
  20. data/app/contexts/services/mds_file_processing_context.rb +27 -0
  21. data/app/contexts/services/mds_file_upload_context.rb +25 -0
  22. data/app/contexts/services/mds_pull_context.rb +21 -0
  23. data/app/contexts/services/monthly_service_table_cleanup_context.rb +19 -0
  24. data/app/contexts/services/notify_new_registration_context.rb +22 -0
  25. data/app/contexts/services/notify_sltc_provider_change_context.rb +19 -0
  26. data/app/contexts/services/request_sltc_baseline_context.rb +23 -0
  27. data/app/contexts/services/update_account_mapping_context.rb +23 -0
  28. data/app/contexts/services/update_configured_account_context.rb +26 -0
  29. data/app/contexts/services/update_configured_facility_context.rb +26 -0
  30. data/app/contexts/services/update_credential_context.rb +23 -0
  31. data/app/contexts/services/update_facility_mapping_context.rb +23 -0
  32. data/app/contexts/services/update_public_key_context.rb +23 -0
  33. data/app/contexts/services/update_service_context.rb +23 -0
  34. data/app/contexts/services/update_service_definition_context.rb +26 -0
  35. data/app/contexts/services/update_third_party_context.rb +23 -0
  36. data/app/controllers/services/account_mappings_controller.rb +54 -0
  37. data/app/controllers/services/adts_controller.rb +35 -0
  38. data/app/controllers/services/application_controller.rb +17 -0
  39. data/app/controllers/services/assessment_requests_controller.rb +48 -0
  40. data/app/controllers/services/available_files_controller.rb +19 -0
  41. data/app/controllers/services/configured_account_base_controller.rb +17 -0
  42. data/app/controllers/services/configured_accounts_controller.rb +59 -0
  43. data/app/controllers/services/configured_facilities_controller.rb +65 -0
  44. data/app/controllers/services/facility_mappings_controller.rb +58 -0
  45. data/app/controllers/services/mds_files_controller.rb +75 -0
  46. data/app/controllers/services/mds_pull_accounts_controller.rb +57 -0
  47. data/app/controllers/services/public_keys_controller.rb +50 -0
  48. data/app/controllers/services/service_base_controller.rb +18 -0
  49. data/app/controllers/services/service_definition_base_controller.rb +31 -0
  50. data/app/controllers/services/service_definitions_controller.rb +59 -0
  51. data/app/controllers/services/services_controller.rb +56 -0
  52. data/app/controllers/services/sltc_providers_controller.rb +15 -0
  53. data/app/controllers/services/sltc_registrations_controller.rb +74 -0
  54. data/app/controllers/services/status_masking.rb +17 -0
  55. data/app/controllers/services/third_parties_controller.rb +47 -0
  56. data/app/controllers/services/third_party_base_controller.rb +17 -0
  57. data/app/controllers/services/validation_controller.rb +17 -0
  58. data/app/helpers/services/application_helper.rb +8 -0
  59. data/app/helpers/services/assessment_request_helper.rb +19 -0
  60. data/app/helpers/services/available_files_helper.rb +27 -0
  61. data/app/helpers/services/mds_pull_accounts_helper.rb +27 -0
  62. data/app/helpers/services/sltc_registrations_helper.rb +15 -0
  63. data/app/mailers/services_mailer.rb +57 -0
  64. data/app/models/services/abaqis_mds_push.rb +51 -0
  65. data/app/models/services/account_mapping.rb +10 -0
  66. data/app/models/services/application_api.rb +19 -0
  67. data/app/models/services/assessment_request.rb +18 -0
  68. data/app/models/services/available_file.rb +73 -0
  69. data/app/models/services/configured_account.rb +26 -0
  70. data/app/models/services/configured_facility.rb +16 -0
  71. data/app/models/services/credential.rb +9 -0
  72. data/app/models/services/facility_mapping.rb +12 -0
  73. data/app/models/services/ftp_server.rb +69 -0
  74. data/app/models/services/hl7_inbound_service.rb +47 -0
  75. data/app/models/services/hl7_message.rb +27 -0
  76. data/app/models/services/isc_code.rb +15 -0
  77. data/app/models/services/isc_code_lookup.rb +75 -0
  78. data/app/models/services/mds_assessment.rb +371 -0
  79. data/app/models/services/mds_content.rb +55 -0
  80. data/app/models/services/mds_pull.rb +41 -0
  81. data/app/models/services/mds_pull_account.rb +192 -0
  82. data/app/models/services/mds_push.rb +24 -0
  83. data/app/models/services/mds_upload.rb +64 -0
  84. data/app/models/services/mds_upload_content.rb +148 -0
  85. data/app/models/services/mds_ws_response.rb +21 -0
  86. data/app/models/services/mds_ws_response_handler.rb +31 -0
  87. data/app/models/services/pcc_mds_pull.rb +77 -0
  88. data/app/models/services/provider_change.rb +26 -0
  89. data/app/models/services/public_key.rb +11 -0
  90. data/app/models/services/service.rb +20 -0
  91. data/app/models/services/service_definition.rb +37 -0
  92. data/app/models/services/service_implementation.rb +29 -0
  93. data/app/models/services/sltc_api.rb +179 -0
  94. data/app/models/services/sltc_api_exception.rb +54 -0
  95. data/app/models/services/sltc_mds_pull.rb +230 -0
  96. data/app/models/services/sltc_registration.rb +23 -0
  97. data/app/models/services/third_party.rb +18 -0
  98. data/app/roles/services/account_mapping_creator.rb +13 -0
  99. data/app/roles/services/account_mapping_updator.rb +12 -0
  100. data/app/roles/services/configured_account_creator.rb +13 -0
  101. data/app/roles/services/configured_account_updater.rb +12 -0
  102. data/app/roles/services/configured_facility_creator.rb +13 -0
  103. data/app/roles/services/configured_facility_updater.rb +12 -0
  104. data/app/roles/services/credential_creator.rb +11 -0
  105. data/app/roles/services/credential_updater.rb +20 -0
  106. data/app/roles/services/facility_mapping_creator.rb +13 -0
  107. data/app/roles/services/facility_mapping_updater.rb +11 -0
  108. data/app/roles/services/hl7_adt_message_saver.rb +15 -0
  109. data/app/roles/services/hl7_message_trimmer.rb +14 -0
  110. data/app/roles/services/mds_assessment_categorizer.rb +71 -0
  111. data/app/roles/services/mds_file_processor.rb +86 -0
  112. data/app/roles/services/mds_notifications.rb +44 -0
  113. data/app/roles/services/monthly_service_table_cleaner.rb +19 -0
  114. data/app/roles/services/new_registration_notifier.rb +11 -0
  115. data/app/roles/services/public_key_creator.rb +14 -0
  116. data/app/roles/services/public_key_updater.rb +12 -0
  117. data/app/roles/services/service_creator.rb +13 -0
  118. data/app/roles/services/service_definition_creator.rb +13 -0
  119. data/app/roles/services/service_definition_updater.rb +12 -0
  120. data/app/roles/services/service_invoker.rb +25 -0
  121. data/app/roles/services/service_updater.rb +11 -0
  122. data/app/roles/services/sltc_baseline_requestor.rb +19 -0
  123. data/app/roles/services/sltc_provider_change_notifier.rb +25 -0
  124. data/app/roles/services/sltc_provider_lister.rb +13 -0
  125. data/app/roles/services/sltc_registration_completer.rb +81 -0
  126. data/app/roles/services/sltc_registration_saver.rb +13 -0
  127. data/app/roles/services/submit_mds_file_for_processing.rb +28 -0
  128. data/app/roles/services/third_party_creator.rb +13 -0
  129. data/app/roles/services/third_party_updater.rb +12 -0
  130. data/app/utils/services/file_upload_handler.rb +33 -0
  131. data/app/utils/services/mds_upload_filters.rb +26 -0
  132. data/app/utils/services/mds_xml_file_parser.rb +104 -0
  133. data/app/utils/services/upload_file.rb +13 -0
  134. data/app/validators/isc_code_validator.rb +42 -0
  135. data/app/validators/mds_birthdate_validator.rb +37 -0
  136. data/app/validators/mds_date_validator.rb +8 -0
  137. data/app/validators/mds_integer_validator.rb +15 -0
  138. data/app/validators/mds_version_validator.rb +16 -0
  139. data/app/validators/state_code_validator.rb +9 -0
  140. data/app/views/layouts/services/application.html.erb +14 -0
  141. data/app/views/services/account_mappings/index.json.jbuilder +9 -0
  142. data/app/views/services/account_mappings/show.json.jbuilder +7 -0
  143. data/app/views/services/assessment_requests/index.json.jbuilder +11 -0
  144. data/app/views/services/available_files/index.json.jbuilder +13 -0
  145. data/app/views/services/configured_accounts/index.json.jbuilder +13 -0
  146. data/app/views/services/configured_accounts/show.json.jbuilder +11 -0
  147. data/app/views/services/configured_facilities/index.json.jbuilder +13 -0
  148. data/app/views/services/configured_facilities/show.json.jbuilder +11 -0
  149. data/app/views/services/facility_mappings/index.json.jbuilder +10 -0
  150. data/app/views/services/facility_mappings/show.json.jbuilder +8 -0
  151. data/app/views/services/mds_files/create.builder +10 -0
  152. data/app/views/services/mds_pull_accounts/index.json.jbuilder +11 -0
  153. data/app/views/services/public_keys/index.json.jbuilder +8 -0
  154. data/app/views/services/public_keys/show.json.jbuilder +6 -0
  155. data/app/views/services/service_definitions/index.json.jbuilder +17 -0
  156. data/app/views/services/service_definitions/show.json.jbuilder +16 -0
  157. data/app/views/services/services/index.json.jbuilder +6 -0
  158. data/app/views/services/services/show.json.jbuilder +4 -0
  159. data/app/views/services/sltc_providers/index.json.jbuilder +10 -0
  160. data/app/views/services/sltc_registrations/index.json.jbuilder +10 -0
  161. data/app/views/services/third_parties/index.json.jbuilder +7 -0
  162. data/app/views/services/third_parties/show.json.jbuilder +5 -0
  163. data/app/views/services_mailer/burying_job.html.erb +20 -0
  164. data/app/views/services_mailer/delaying_job.html.erb +20 -0
  165. data/app/views/services_mailer/notify_sltc_client_registration.html.erb +39 -0
  166. data/app/views/services_mailer/notify_sltc_client_registration_invalid_request_type.html.erb +8 -0
  167. data/app/views/services_mailer/notify_sltc_client_registration_request_invalid.html.erb +10 -0
  168. data/app/views/services_mailer/notify_sltc_client_registration_validation_errors.html.erb +13 -0
  169. data/app/views/services_mailer/notify_sltc_provider_changes.html.erb +26 -0
  170. data/app/views/services_mailer/notify_support_about_no_mds_pull.html.erb +6 -0
  171. data/config/routes.rb +48 -0
  172. data/db/migrate/20140102000000_create_services_engine_tables.rb +131 -0
  173. data/db/migrate/20140517184450_new_services_columns.rb +24 -0
  174. data/db/migrate/20140525142842_new_configured_provider_table.rb +18 -0
  175. data/db/migrate/20140714172442_add_error_column_to_hl7_messages.rb +5 -0
  176. data/db/migrate/20140730164152_mds_upload_tables.rb +78 -0
  177. data/db/sql_data/service_data_setup.sql +24 -0
  178. data/lib/services/engine.rb +40 -0
  179. data/lib/services/version.rb +3 -0
  180. data/lib/services.rb +4 -0
  181. data/lib/tasks/services_tasks.rake +40 -0
  182. data/spec/dummy/README.rdoc +261 -0
  183. data/spec/dummy/Rakefile +7 -0
  184. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  185. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  186. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  187. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  188. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  189. data/spec/dummy/config/application.rb +60 -0
  190. data/spec/dummy/config/boot.rb +10 -0
  191. data/spec/dummy/config/database.yml +29 -0
  192. data/spec/dummy/config/environment.rb +5 -0
  193. data/spec/dummy/config/environments/development.rb +35 -0
  194. data/spec/dummy/config/environments/production.rb +68 -0
  195. data/spec/dummy/config/environments/test.rb +32 -0
  196. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  197. data/spec/dummy/config/initializers/email.rb +1 -0
  198. data/spec/dummy/config/initializers/inflections.rb +15 -0
  199. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  200. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  201. data/spec/dummy/config/initializers/session_store.rb +8 -0
  202. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  203. data/spec/dummy/config/locales/en.yml +5 -0
  204. data/spec/dummy/config/routes.rb +4 -0
  205. data/spec/dummy/config.ru +4 -0
  206. data/spec/dummy/db/schema.rb +237 -0
  207. data/spec/dummy/db/sql_data/services_isc_codes.sql +878 -0
  208. data/spec/dummy/log/test.log +3498 -0
  209. data/spec/dummy/public/404.html +26 -0
  210. data/spec/dummy/public/422.html +26 -0
  211. data/spec/dummy/public/500.html +25 -0
  212. data/spec/dummy/public/favicon.ico +0 -0
  213. data/spec/dummy/script/rails +6 -0
  214. data/spec/models/abaqis_mds_push_spec.rb +120 -0
  215. data/spec/models/available_file_spec.rb +234 -0
  216. data/spec/models/configured_account_spec.rb +39 -0
  217. data/spec/models/ftp_server_spec.rb +221 -0
  218. data/spec/models/isc_code_lookup_spec.rb +125 -0
  219. data/spec/models/isc_code_spec.rb +5 -0
  220. data/spec/models/mds_assessment_spec.rb +1070 -0
  221. data/spec/models/mds_pull_account_spec.rb +468 -0
  222. data/spec/models/mds_pull_spec.rb +48 -0
  223. data/spec/models/mds_push_spec.rb +43 -0
  224. data/spec/models/mds_ws_response_spec.rb +54 -0
  225. data/spec/models/pcc_mds_pull_spec.rb +273 -0
  226. data/spec/models/service_implementation_spec.rb +88 -0
  227. data/spec/models/sltc_api_exception_spec.rb +136 -0
  228. data/spec/models/sltc_api_spec.rb +192 -0
  229. data/spec/models/sltc_mds_pull_spec.rb +776 -0
  230. data/spec/roles/account_mapping_creator_spec.rb +40 -0
  231. data/spec/roles/account_mapping_updator_spec.rb +16 -0
  232. data/spec/roles/configured_account_creator_spec.rb +40 -0
  233. data/spec/roles/configured_account_updater_spec.rb +16 -0
  234. data/spec/roles/configured_facility_creator_spec.rb +40 -0
  235. data/spec/roles/configured_facility_updater_spec.rb +16 -0
  236. data/spec/roles/credential_creator_spec.rb +23 -0
  237. data/spec/roles/credential_updater_spec.rb +38 -0
  238. data/spec/roles/facility_mapping_creator_spec.rb +40 -0
  239. data/spec/roles/facility_mapping_updater_spec.rb +16 -0
  240. data/spec/roles/hl7_adt_message_saver_spec.rb +35 -0
  241. data/spec/roles/hl7_message_trimmer_spec.rb +31 -0
  242. data/spec/roles/monthly_service_table_cleaner_spec.rb +27 -0
  243. data/spec/roles/new_registration_notifier_spec.rb +18 -0
  244. data/spec/roles/service_ceator_spec.rb +34 -0
  245. data/spec/roles/service_definition_creator_spec.rb +40 -0
  246. data/spec/roles/service_definition_updater_spec.rb +16 -0
  247. data/spec/roles/service_invoker_spec.rb +22 -0
  248. data/spec/roles/service_updater_spec.rb +17 -0
  249. data/spec/roles/sltc_baseline_requestor_spec.rb +30 -0
  250. data/spec/roles/sltc_provider_lister_spec.rb +27 -0
  251. data/spec/roles/sltc_registration_completer_spec.rb +187 -0
  252. data/spec/roles/sltc_registration_saver_spec.rb +34 -0
  253. data/spec/roles/third_party_creator_spec.rb +34 -0
  254. data/spec/roles/third_party_updater_spec.rb +17 -0
  255. data/spec/spec_helper.rb +72 -0
  256. metadata +581 -0
@@ -0,0 +1,73 @@
1
+ module Services
2
+
3
+ class AvailableFile < ActiveRecord::Base
4
+ belongs_to :configured_account
5
+
6
+ STATUS_AVAILABLE = 0
7
+ STATUS_DOWNLOADED = 1
8
+ STATUS_INVALID = 2
9
+ STATUS_MISSING = 3
10
+ STATUS_UPLOADED = 4
11
+ STATUS_UPLOAD_ERROR = 5
12
+ STATUS_DELETED = 6
13
+ STATUS_CLEARED = 7 # Final status
14
+
15
+ validates :request_id, presence: true, length: { maximum: 255 }
16
+ validates :filename, presence: true, length: { maximum: 255 }
17
+ validates :status, presence: true, inclusion: { in: [ STATUS_AVAILABLE,
18
+ STATUS_DOWNLOADED,
19
+ STATUS_INVALID,
20
+ STATUS_MISSING,
21
+ STATUS_UPLOADED,
22
+ STATUS_UPLOAD_ERROR,
23
+ STATUS_DELETED,
24
+ STATUS_CLEARED
25
+ ] }
26
+ validates :composite_file_name, length: { minimum: 0, maximum: 255 }, allow_blank: true, allow_nil: true
27
+ validates :error, length: { minimum: 0, maximum: 255 }, allow_blank: true, allow_nil: true
28
+
29
+ scope :available, -> { where(status: STATUS_AVAILABLE) }
30
+ scope :downloaded, -> { where(status: STATUS_DOWNLOADED) }
31
+ scope :cleared, -> { where(status: STATUS_CLEARED) }
32
+ scope :uploaded, -> { where(status: STATUS_UPLOADED) }
33
+ scope :invalid, -> { where(status: STATUS_INVALID) }
34
+ scope :missing, -> { where(status: STATUS_MISSING) }
35
+ scope :upload_error, -> { where(status: STATUS_UPLOAD_ERROR) }
36
+ scope :deleted, -> { where(status: STATUS_DELETED) }
37
+ scope :with_status, ->(status) { where(status: status) }
38
+
39
+ def downloaded_file_path
40
+ File.join(download_path, filename)
41
+ end
42
+
43
+ def download_path
44
+ Rails.root.join("tmp", "available_file_#{id}").to_s
45
+ end
46
+
47
+ def split_path
48
+ File.join(download_path, 'split')
49
+ end
50
+
51
+ def composite_path
52
+ File.join(split_path, 'MdsFileUtils::ZipSplitter', composite_file_name)
53
+ end
54
+
55
+ def actual_file_path
56
+ composite_file_name.nil? ? downloaded_file_path : composite_path
57
+ end
58
+
59
+ def downloaded_file_exists?
60
+ File.exists?(downloaded_file_path)
61
+ end
62
+
63
+ def mds_analyzer
64
+ @mds_analyzer ||= MdsFileUtils::ZipAnalyzer.new(downloaded_file_path)
65
+ end
66
+
67
+ def valid_mds_file?
68
+ mds_analyzer.valid_zip?
69
+ end
70
+
71
+ end
72
+
73
+ end
@@ -0,0 +1,26 @@
1
+ module Services
2
+
3
+ class ConfiguredAccount < ActiveRecord::Base
4
+ belongs_to :service_definition
5
+ belongs_to :account
6
+
7
+ has_many :credentials, as: :credentialled, dependent: :destroy
8
+ has_many :available_files, dependent: :destroy
9
+ has_many :mds_pull_accounts, dependent: :destroy
10
+
11
+ validates :username, length: { minimum: 0, maximum: 255 }, allow_blank: true, allow_nil: true
12
+
13
+ scope :for_service, ->(service_id) { joins(:service_definition).where(services_service_definitions: { service_id: service_id }) }
14
+
15
+ scope :enabled, -> { where(enabled: true) }
16
+
17
+ def application_account
18
+ ApplicationApi.api_impl.account_by_id(self.account_id)
19
+ end
20
+
21
+ def account_mapping
22
+ service_definition.third_party.account_mappings.where(account_id: account_id).first
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,16 @@
1
+ module Services
2
+
3
+ class ConfiguredFacility < ActiveRecord::Base
4
+ belongs_to :service_definition
5
+ belongs_to :facility
6
+
7
+ has_many :credentials, as: :credentialled, dependent: :destroy
8
+
9
+ validates :username, length: { minimum: 0, maximum: 255 }, allow_nil: true, allow_blank: true
10
+
11
+ scope :for_service, ->(service_id) { joins(:service_definition).where(services_service_definitions: { service_id: service_id }) }
12
+
13
+ scope :enabled, -> { where(enabled: true) }
14
+ end
15
+
16
+ end
@@ -0,0 +1,9 @@
1
+ module Services
2
+ class Credential < ActiveRecord::Base
3
+ belongs_to :credentialled, polymorphic: true
4
+
5
+ validates :credentialled_type, presence: true, length: { maximum: 255 }
6
+
7
+ attr_encrypted :password, :token
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ module Services
2
+
3
+ class FacilityMapping < ActiveRecord::Base
4
+ belongs_to :third_party
5
+ belongs_to :facility
6
+
7
+ validates :facility_code, presence: true, length: { maximum: 255 }
8
+
9
+ scope :sltc_provider_mappings, ->(facility_codes) { select("services_facility_mappings.*").joins(:third_party).where("`key` = ? AND facility_code IN (?)", ThirdParty::SLTC, facility_codes ) }
10
+ end
11
+
12
+ end
@@ -0,0 +1,69 @@
1
+ module Services
2
+
3
+ class FtpServer
4
+ include FileUtils
5
+
6
+ # Allow the private key path to be overridden. The default
7
+ # is the production location
8
+ PRIVATE_KEY_FILE = defined?(SSH_PRIVATE_KEY) ? SSH_PRIVATE_KEY : '/etc/pki/abaqis/abaqis_rsa'
9
+
10
+ def initialize(hostname, username, password, base_directory='/')
11
+ @hostname = hostname
12
+ @username = username
13
+ @password = password
14
+ @base_directory = base_directory
15
+ end
16
+
17
+ def connect
18
+
19
+ options = {
20
+ password: @password,
21
+ auth_methods: %w{ publickey password }
22
+ }
23
+ # Add the private key to the list if available
24
+ options[:keys] = PRIVATE_KEY_FILE if File.exists?(PRIVATE_KEY_FILE)
25
+
26
+ Net::SFTP.start(@hostname, @username, options) do | sftp |
27
+ @sftp = sftp
28
+ begin
29
+ yield self
30
+ ensure
31
+ @sftp = nil
32
+ end
33
+ end
34
+ end
35
+
36
+ def path(subdir, file_name=nil)
37
+ parameters = [ @base_directory, @username, subdir ]
38
+ parameters << file_name unless file_name.nil?
39
+ File.join(*parameters)
40
+ end
41
+
42
+ def file_list(in_dir, with_glob='*')
43
+ raise "Must be called within the block of a connect!" if @sftp.nil?
44
+ dir = path(in_dir)
45
+ @sftp.dir.glob(dir, with_glob).select { | entry | entry.file? }.map { | entry | entry.name }
46
+ end
47
+
48
+ def download_files(from_dir, files, to_directory)
49
+ files.each { | file | download_file from_dir, file, to_directory }
50
+ end
51
+
52
+ def download_file(from_dir, file, to_directory)
53
+ raise "Must be called within the block of a connect!" if @sftp.nil?
54
+ mkdir_p to_directory
55
+ @sftp.download! path(from_dir, file), File.join(to_directory, file)
56
+ end
57
+
58
+ def remove_files(from_dir, files)
59
+ files.each { | file | remove_file from_dir, file } unless files.nil?
60
+ end
61
+
62
+ def remove_file(from_dir, file)
63
+ raise "Must be called within the block of a connect!" if @sftp.nil?
64
+ @sftp.remove! path(from_dir, file)
65
+ end
66
+
67
+ end
68
+
69
+ end
@@ -0,0 +1,47 @@
1
+ module Services
2
+
3
+ class Hl7InboundService < ServiceImplementation
4
+
5
+ #
6
+ # Invoke, in this case will create the service loop on the socket server
7
+ # port and just hang out and handle the stuff
8
+ #
9
+ def invoke
10
+ server = TCPServer.open(service_definition.hostname, service_definition.port)
11
+ loop do # Servers run forever
12
+ #
13
+ # We put the accepted client in a separate thread to manage a high volume of
14
+ # calls better. The AcceptHl7MessageContext call saves the Hl7Message
15
+ # and puts the processing into beanstalk, so we shouldn't be in this
16
+ # separate thread for long.
17
+ #
18
+ # Note that we fail fast if the message coming in doesn't have the
19
+ # API key we are expecting. We don't save the incoming message in that
20
+ # case because we don't know what we're getting. Could be evil.
21
+ #
22
+ Thread.start(server.accept) do |client|
23
+ begin
24
+ key = client.gets('|').chop # Don't want the last character '|'
25
+ creds = service_definition.credentials.last
26
+ if creds.present? && creds.token == key
27
+ message_type = client.gets('|').chop
28
+ raw_message = client.gets('|').chop
29
+ AcceptHl7MessageContext.call(message_type, raw_message)
30
+ client.puts( { status: 'accepted' }.to_json )
31
+ else
32
+ client.puts({ status: 'error', message: 'invalid key' }.to_json )
33
+ end
34
+ rescue Exception => ex
35
+ puts ex.inspect
36
+ client.puts( { status: 'error', errors: [ ex.message ] } )
37
+ ensure
38
+ client.close # Disconnect from the client
39
+ end
40
+ end
41
+ end
42
+
43
+ end
44
+
45
+ end
46
+
47
+ end
@@ -0,0 +1,27 @@
1
+ module Services
2
+
3
+ class Hl7Message < ActiveRecord::Base
4
+
5
+ STATUS_RECEIVED = 0
6
+ STATUS_PROCESSED = 1
7
+ STATUS_ERRORED = 2
8
+
9
+ attr_encrypted :message
10
+
11
+ belongs_to :facility
12
+ belongs_to :resident
13
+
14
+ validates :message_type, presence: true, length: { maximum: 255 }
15
+
16
+ def message_as_hash
17
+ message.empty? ? {} : ActiveSupport::HashWithIndifferentAccess.new(JSON.parse(message))
18
+ end
19
+
20
+ def raw_hl7_message
21
+ raw_data = message_as_hash['rawData']
22
+ Base64.urlsafe_decode64(raw_data) if raw_data.present?
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,15 @@
1
+ module Services
2
+
3
+ class IscCode < ActiveRecord::Base
4
+
5
+ has_many :isc_code_lookups
6
+
7
+ INACTIVATION_CODE = "XX"
8
+
9
+ def self.inactivation_code
10
+ INACTIVATION_CODE
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,75 @@
1
+ module Services
2
+
3
+ class IscCodeLookup < ActiveRecord::Base
4
+
5
+ belongs_to :isc_code
6
+
7
+ scope :isc_lookup, ->(assessment) {
8
+ joins(:isc_code).
9
+ where(a0200: assessment.a0200,
10
+ a0310a: assessment.a0310a,
11
+ a0310b: assessment.a0310b,
12
+ a0310c: assessment.a0310c,
13
+ a0310d: assessment.a0310d,
14
+ a0310f: assessment.a0310f)
15
+
16
+ }
17
+
18
+ attr_reader :isc_provided_value, :isc_lookup_value
19
+
20
+ #------------------------------------------------------------------#
21
+ # Raises an ArgumentError if itm_sbst_cd (provided isc value) #
22
+ # does not exist. since this class depends on the comparison #
23
+ # between the calculated isc and the provided isc values. #
24
+ #------------------------------------------------------------------#
25
+ def initialize(assessment)
26
+ raise(ArgumentError, "The attribute 'itm_sbst_cd' does not exist") unless assessment.respond_to?("itm_sbst_cd")
27
+ @isc_provided_value = assessment.itm_sbst_cd
28
+ @isc_lookup_value = find_isc_value(assessment)
29
+ end
30
+
31
+ #------------------------------------------------------------------#
32
+ # Finds and returns the actual isc code (eg: "NC") #
33
+ # Returns nil if: #
34
+ # 1) any of the attributes required for isc calculation are nil #
35
+ # 2) isc code is not found due to an invalid combination of #
36
+ # required attributes #
37
+ #------------------------------------------------------------------#
38
+ def find_isc_value(assessment)
39
+ return Services::IscCode.inactivation_code if inactivation_isc?(assessment)
40
+
41
+ if all_lookup_attributes_exist?(assessment)
42
+ isc_lookup = self.class.isc_lookup(assessment).first
43
+ isc_lookup.isc_code.code if isc_lookup
44
+ end
45
+ end
46
+
47
+ #----------------------------------------------------------------#
48
+ # Returns whether the calculated isc code is the same as #
49
+ # the provided isc code #
50
+ #----------------------------------------------------------------#
51
+ def valid_isc_value?()
52
+ return if @isc_provided_value.nil?
53
+ @isc_lookup_value == @isc_provided_value
54
+ end
55
+
56
+
57
+ private
58
+
59
+ def all_lookup_attributes_exist?(assessment)
60
+ assessment.a0200.present? &&
61
+ assessment.a0310a.present? &&
62
+ assessment.a0310b.present? &&
63
+ assessment.a0310c.present? &&
64
+ assessment.a0310d.present? &&
65
+ assessment.a0310f.present?
66
+ # !attributes["a0200"].nil? && !attributes["a0310a"].nil? && !attributes["a0310b"].nil? && !attributes["a0310c"].nil? && !attributes["a0310d"].nil? && !attributes["a0310f"].nil?
67
+ end
68
+
69
+ def inactivation_isc?(assessment)
70
+ assessment.type_of_record == 3
71
+ end
72
+
73
+ end
74
+
75
+ end