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,54 @@
1
+ module Services
2
+
3
+ class SltcApiException < StandardError
4
+
5
+ attr_reader :inner_exception
6
+ attr_reader :raw_json, :error_code, :error_message, :error_response
7
+
8
+ def initialize(exception)
9
+ @inner_exception = exception
10
+ @raw_json = exception.response if exception && exception.respond_to?(:response)
11
+ @error_code = -1
12
+ super format_exception_message
13
+ end
14
+
15
+ def http_code
16
+ inner_exception.http_code if inner_exception && inner_exception.respond_to?(:http_code)
17
+ end
18
+
19
+ def http_message
20
+ inner_exception.message if inner_exception && inner_exception.respond_to?(:message)
21
+ end
22
+
23
+ private
24
+
25
+ def format_exception_message
26
+ return "Unknown SimpleLTC API Error (#{basic_message_fmt})" if raw_json.nil?
27
+
28
+ extract_sltc_error_information
29
+ end
30
+
31
+ def extract_sltc_error_information
32
+ @error_response = JSON.parse(raw_json)
33
+
34
+ return "No error message in SimpleLTC error response (#{raw_json}) (#{basic_message_fmt})" unless @error_response.is_a?(Hash) && @error_response.has_key?('Message')
35
+
36
+ @error_message = @error_response['Message']
37
+ @error_code = @error_response['ErrorCode']
38
+
39
+ "SimpleLTC error response: (#{@error_code.present? ? @error_code : 'N/A'}) #{@error_message} (#{basic_message_fmt})"
40
+ rescue Exception => ex
41
+ "Error parsing SimpleLTC API Error JSON (#{raw_json}): #{ex.message} (#{basic_message_fmt})"
42
+ end
43
+
44
+ def basic_message_fmt
45
+ if http_code.present?
46
+ "#{http_code}: #{http_message}"
47
+ else
48
+ "no http_code associated with inner exception"
49
+ end
50
+ end
51
+ end
52
+
53
+ end
54
+
@@ -0,0 +1,230 @@
1
+ module Services
2
+
3
+ class SltcMdsPull < MdsPull
4
+ include FileUtils
5
+
6
+ #
7
+ # Overridden from MdsPull
8
+ #
9
+ def identify_providers(configured_account)
10
+ api = api_impl(configured_account)
11
+ provider_list = api.list_providers
12
+ process_provider_list(configured_account, provider_list)
13
+ end
14
+
15
+ #
16
+ # Overridden from MdsPull
17
+ #
18
+ def request_assessments(configured_account)
19
+ enabled_providers = providers_for_account(configured_account)
20
+
21
+ enabled_providers.each do | provider_id |
22
+ request_assessments_to_pull(configured_account, provider_id)
23
+ end
24
+ end
25
+
26
+ def providers_for_account(configured_account)
27
+ enabled_facility_ids = ApplicationApi.api_impl.enabled_facilities_for_account_id(configured_account.account_id).pluck(:id)
28
+ FacilityMapping.
29
+ joins('LEFT OUTER JOIN services_configured_facilities ON services_configured_facilities.facility_id = services_facility_mappings.facility_id').
30
+ where('services_facility_mappings.facility_id IN (?) AND services_configured_facilities.enabled = 1', enabled_facility_ids).
31
+ pluck(:facility_code)
32
+ end
33
+
34
+ def list_available_files(configured_account)
35
+ api = api_impl(configured_account)
36
+
37
+ list_available_assessment_requests api, configured_account
38
+ end
39
+
40
+ def list_available_assessment_requests(api, configured_account)
41
+ assessment_request_ids = []
42
+ enabled_providers = providers_for_account(configured_account)
43
+
44
+ AssessmentRequest.available.where(facility_code: enabled_providers).each do | assessment_request |
45
+ status_response = api.assessment_request_status(assessment_request.request_id)
46
+ case status_response['status']
47
+ when 'Complete'
48
+ assessment_request_ids << [ assessment_request.request_id, "#{assessment_request.request_id}.zip" ]
49
+ assessment_request.update_attribute :status, AssessmentRequest::STATUS_COMPLETED
50
+ when 'Empty'
51
+ assessment_request.update_attribute :status, AssessmentRequest::STATUS_EMPTY
52
+ when 'Error'
53
+ assessment_request.update_attribute :status, AssessmentRequest::STATUS_ERROR
54
+ else
55
+ # Do nothing ... Must be processing so we leave the status as 'Active'
56
+ end
57
+ end
58
+
59
+ assessment_request_ids
60
+ end
61
+
62
+ def perform_file_downloads(configured_account, files_to_download)
63
+ api = api_impl(configured_account)
64
+ downloaded_files = []
65
+ files_to_download.each do | available_file |
66
+ downloaded_files << download_file(api, available_file)
67
+ end
68
+ downloaded_files.compact
69
+ end
70
+
71
+ def perform_cleanup_on_remote_server(configured_account)
72
+ configured_account.available_files.deleted.pluck(:id)
73
+ end
74
+
75
+ def download_file(api, available_file)
76
+ mkdir_p available_file.download_path
77
+ File.open(available_file.downloaded_file_path, "wb") do |f|
78
+ f.write(api.download_assessment_request(available_file.request_id))
79
+ end
80
+ available_file.id
81
+ end
82
+
83
+ def request_baseline(configured_account, provider_id, uploaded_after, uploaded_before)
84
+ api = api_impl(configured_account)
85
+ result = api.assessment_request(provider_id, uploaded_after, uploaded_before, 'Accepted')
86
+ Rails.logger.info "Response from baseline request: #{result.inspect}"
87
+ request_id = result['requestId']
88
+ # Create a new row in the assessment request table
89
+ AssessmentRequest.create!(request_id: request_id,
90
+ facility_code: provider_id,
91
+ pull_from: uploaded_after,
92
+ pull_to: uploaded_before,
93
+ status: AssessmentRequest::STATUS_AVAILABLE)
94
+ request_id
95
+ end
96
+
97
+ def api_impl(configured_account)
98
+ SltcApi.for_configured_account(configured_account)
99
+ end
100
+
101
+ def process_provider_list(configured_account, provider_list)
102
+ # The provider Ids need to be converted to strings because we store
103
+ # the provider_codes as strings in the db.
104
+ sltc_provider_ids = provider_list.map { | provider_info | provider_info['id'].to_s }
105
+ # Get the provider ids that are currently enabled for this account
106
+ mapped_facility_ids = providers_for_account(configured_account)
107
+
108
+ facilities_removed = mapped_facility_ids - sltc_provider_ids
109
+ facilities_added = sltc_provider_ids - mapped_facility_ids
110
+
111
+ added_facility_info = provider_list.select { | provider | facilities_added.include?(provider['id'].to_s) }
112
+
113
+ still_to_add = facilities_added - ProviderChange.
114
+ added_providers(configured_account.id, facilities_added).
115
+ pluck(:facility_code)
116
+
117
+ register_provider_deltas configured_account, provider_list.select { |p| still_to_add.include?(p['id'].to_s) }, ProviderChange::VERB_ADD
118
+
119
+ still_to_remove = facilities_removed - ProviderChange.
120
+ deleted_providers(configured_account.id, facilities_removed).
121
+ pluck(:facility_code)
122
+
123
+ mappings = FacilityMapping.sltc_provider_mappings(still_to_remove).
124
+ map do | fm |
125
+ facility = fm.facility
126
+ {
127
+ 'id' => fm.facility_code,
128
+ 'name' => facility.name,
129
+ 'state' => facility.state,
130
+ 'npi' => facility.npi,
131
+ 'ccn' => facility.govid,
132
+ 'mdsFacilityId' => facility.fac_id
133
+ }
134
+ end
135
+
136
+ register_provider_deltas configured_account, mappings, ProviderChange::VERB_DELETE
137
+
138
+ disable_removed_facilities(facilities_removed) unless facilities_removed.empty?
139
+ configure_added_facilities(added_facility_info)
140
+ end
141
+
142
+ def register_provider_deltas(configured_account, provider_list, verb)
143
+ provider_list.each do |pi|
144
+ ProviderChange.create!(configured_account_id: configured_account.id,
145
+ facility_code: pi['id'],
146
+ name: pi['name'],
147
+ state: pi['state'],
148
+ npi: pi['npi'],
149
+ ccn: pi['ccn'],
150
+ fac_id: pi['mdsFacilityId'],
151
+ verb: verb)
152
+ end
153
+ end
154
+
155
+ def disable_removed_facilities(facility_codes)
156
+ fac_mappings = FacilityMapping.
157
+ sltc_provider_mappings(facility_codes)
158
+
159
+ facility_ids = fac_mappings.pluck(:facility_id)
160
+ mapping_ids = fac_mappings.pluck(:id)
161
+
162
+ # Delete all the facility configuration entries
163
+ ConfiguredFacility.where(facility_id: facility_ids).destroy_all
164
+
165
+ # Remove all the facility mappings
166
+ FacilityMapping.where(id: mapping_ids).destroy_all
167
+ end
168
+
169
+ def configure_added_facilities(added_facility_info)
170
+ configure_existing_enabled_facilities(added_facility_info)
171
+
172
+ # We will not be creating new facilities based on the information from
173
+ # SLTC. It will only configure existing, enabled facilities that have
174
+ # not yet been configured
175
+ end
176
+
177
+ def configure_existing_enabled_facilities(added_facility_info)
178
+ govids = added_facility_info.map { | facility_info | facility_info['ccn'] }
179
+ facilities = ApplicationApi.api_impl.enabled_facilities_with_govids(govids)
180
+ facilities.each do | facility |
181
+ facility_info = added_facility_info.detect { | fi | fi['ccn'] == facility.govid }
182
+ # Set the state code/fac_id if not already set.
183
+ if facility.state != facility_info['state'] ||
184
+ facility.fac_id != facility_info['mdsFacilityId']
185
+ facility.update_attributes(fac_id: facility_info['mdsFacilityId'],
186
+ state: facility_info['state'])
187
+ end
188
+ # Create the facility mappings we need
189
+ FacilityMapping.create!(third_party_id: service_definition.third_party_id,
190
+ facility_id: facility.id,
191
+ facility_code: facility_info['id'],
192
+ top_level: false)
193
+
194
+ # Create the configured facility we need
195
+ ConfiguredFacility.create!(service_definition_id: service_definition.id,
196
+ facility_id: facility.id,
197
+ enabled: true)
198
+ end
199
+ end
200
+
201
+ def request_assessments_to_pull(configured_account, provider_code)
202
+ # Find the latest assessment request that we pulled to. We do this because
203
+ # we want to know from when to start our requested range.
204
+ latest_assessment_request = AssessmentRequest.
205
+ where(facility_code: provider_code).
206
+ order('pull_to DESC').
207
+ limit(1).
208
+ first
209
+
210
+ # Set the date range for the request
211
+ pull_to = Time.now
212
+ pull_from = latest_assessment_request.present? ? latest_assessment_request.pull_to - 1.second : Time.now - 24.hours
213
+
214
+ api = api_impl(configured_account)
215
+ response = api.assessment_request(provider_code,
216
+ pull_from,
217
+ pull_to,
218
+ 'Accepted')
219
+
220
+ # Register that we made the request
221
+ AssessmentRequest.create(facility_code: provider_code,
222
+ request_id: response['requestId'],
223
+ pull_from: pull_from,
224
+ pull_to: pull_to,
225
+ status: AssessmentRequest::STATUS_AVAILABLE)
226
+ end
227
+
228
+ end
229
+
230
+ end
@@ -0,0 +1,23 @@
1
+ module Services
2
+
3
+ class SltcRegistration < ActiveRecord::Base
4
+
5
+ STATUS_NEW = 0
6
+ STATUS_REGISTERED = 1
7
+
8
+ validates :company_name, presence: true, length: { maximum: 255 }, allow_nil: true, allow_blank: true
9
+ validates :initiated_by, presence: true, length: { maximum: 255 }, allow_nil: true, allow_blank: true
10
+
11
+ attr_encrypted :auth_password, :auth_username
12
+
13
+ def account_code
14
+ auth_username.split('@').last if auth_username.present?
15
+ end
16
+
17
+ def username
18
+ auth_username.split('@').first if auth_username.present?
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,18 @@
1
+ module Services
2
+
3
+ class ThirdParty < ActiveRecord::Base
4
+ has_many :account_mappings, dependent: :destroy
5
+ has_many :facility_mappings, dependent: :destroy
6
+ has_many :service_definitions, dependent: :destroy
7
+
8
+ PROVIDIGM = 'pvdgm'
9
+ POINTCLICKCARE = 'pcc'
10
+ SLTC = 'sltc'
11
+
12
+ validates :name, presence: true, uniqueness: true, length: { maximum: 255 }
13
+ validates :key, presence: true, uniqueness: true, length: { maximum: 255 }
14
+ validates :contact_email, presence: true, length: { maximum: 255 }
15
+
16
+ end
17
+
18
+ end
@@ -0,0 +1,13 @@
1
+ module Services
2
+
3
+ module AccountMappingCreator
4
+
5
+ def create(params)
6
+ account_mappings.new(params).tap do | account_mapping |
7
+ account_mapping.save if account_mapping.valid?
8
+ end
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,12 @@
1
+ module Services
2
+
3
+ module AccountMappingUpdator
4
+
5
+ def update(params)
6
+ update_attributes(params)
7
+ self
8
+ end
9
+
10
+ end
11
+
12
+ end
@@ -0,0 +1,13 @@
1
+ module Services
2
+
3
+ module ConfiguredAccountCreator
4
+
5
+ def create(params)
6
+ configured_accounts.new(params).tap do | configured_account |
7
+ configured_account.save if configured_account.valid?
8
+ end
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,12 @@
1
+ module Services
2
+
3
+ module ConfiguredAccountUpdater
4
+
5
+ def update(params)
6
+ update_attributes(params)
7
+ self
8
+ end
9
+
10
+ end
11
+
12
+ end
@@ -0,0 +1,13 @@
1
+ module Services
2
+
3
+ module ConfiguredFacilityCreator
4
+
5
+ def create(params)
6
+ configured_facilities.new(params).tap do | configured_facility |
7
+ configured_facility.save if configured_facility.valid?
8
+ end
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,12 @@
1
+ module Services
2
+
3
+ module ConfiguredFacilityUpdater
4
+
5
+ def update(params)
6
+ update_attributes(params)
7
+ self
8
+ end
9
+
10
+ end
11
+
12
+ end
@@ -0,0 +1,11 @@
1
+ module Services
2
+
3
+ module CredentialCreator
4
+
5
+ def add_credential(params)
6
+ credentials << Services::Credential.new(params)
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,20 @@
1
+ module Services
2
+
3
+ module CredentialUpdater
4
+
5
+ def update_credential(params)
6
+ credential = credentials.first
7
+ if credential.present?
8
+ if params.present?
9
+ credential.update_attributes(params)
10
+ else
11
+ credential.destroy
12
+ end
13
+ elsif params.present?
14
+ credentials << Credential.new(params)
15
+ end
16
+ end
17
+
18
+ end
19
+
20
+ end
@@ -0,0 +1,13 @@
1
+ module Services
2
+
3
+ module FacilityMappingCreator
4
+
5
+ def create(params)
6
+ facility_mappings.new(params).tap do | facility_mapping |
7
+ facility_mapping.save if facility_mapping.valid?
8
+ end
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,11 @@
1
+ module Services
2
+
3
+ module FacilityMappingUpdater
4
+
5
+ def update(params)
6
+ update_attributes(params)
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,15 @@
1
+ module Services
2
+
3
+ module Hl7AdtMessageSaver
4
+
5
+ def persist(message_type, message_body)
6
+ Services::Hl7Message.new.tap do | msg |
7
+ msg.message_type = message_type
8
+ msg.message = message_body
9
+ msg.save if msg.valid?
10
+ end
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,14 @@
1
+ module Services
2
+
3
+ module Hl7MessageTrimmer
4
+
5
+ def trim_messages
6
+ Hl7Message.
7
+ where(status: Hl7Message::STATUS_PROCESSED).
8
+ where("updated_at < ?", Time.now - 30.days).
9
+ destroy_all
10
+ end
11
+
12
+ end
13
+
14
+ end
@@ -0,0 +1,71 @@
1
+ module Services
2
+
3
+ module MdsAssessmentCategorizer
4
+
5
+ def significant_correction_assessment?
6
+ responses.present? && %w{ 05 06 }.include?(a0310a)
7
+ end
8
+
9
+ def admission_assessment?
10
+ a0310a.to_i == 1
11
+ end
12
+
13
+ def any_type_of_correction_assessment?
14
+ significant_correction_assessment? || correction_record?
15
+ end
16
+
17
+ def correction_record?
18
+ responses.present? && version == MdsAssessment::VERSION1_0 ? x0100 == "2" : a0050 == "2"
19
+ end
20
+
21
+ def correction_applied?
22
+ responses.present? && prior_isc_cd.present?
23
+ end
24
+
25
+ def inactivated?
26
+ responses.present? && (corrected? && prior_isc_cd.blank?)
27
+ end
28
+
29
+ def entry_assessment?
30
+ responses.present? && a0310f.to_i == 1
31
+ end
32
+
33
+ def discharge_assessment?
34
+ responses.present? && a0310f.to_i == 10 || a0310f.to_i == 11
35
+ end
36
+
37
+ def death_assessment?
38
+ responses.present? && a0310f.to_i == 12
39
+ end
40
+
41
+ def discharge_or_death_assessment?
42
+ discharge_assessment? || death_assessment?
43
+ end
44
+
45
+ def tracking_assessment?
46
+ responses.present? && %w{ NT ST }.include?(itm_sbst_cd)
47
+ end
48
+
49
+ def quarterly?
50
+ responses.present? && a0310a == "02"
51
+ end
52
+
53
+ def ninety_day?
54
+ responses.present? && a0310b == "05"
55
+ end
56
+
57
+ def inactivation_assessment?
58
+ responses.present? && itm_sbst_cd == IscCode.inactivation_code
59
+ end
60
+
61
+ def entered_from_hospital?
62
+ responses.present? && a1800 == "03"
63
+ end
64
+
65
+ def a0310f_99?
66
+ responses.present? && a0310f == "99"
67
+ end
68
+
69
+ end
70
+
71
+ end
@@ -0,0 +1,86 @@
1
+ module Services
2
+
3
+ module MdsFileProcessor
4
+ PCC_METADATA_FILE_RE = %r{PCC_.+_metadata.xml\z}
5
+
6
+ # So, the work we're going to do here is to crack open the
7
+ # MDS file and save each of the assessments to the MDS
8
+ # assessments table. We won't process it any further at this
9
+ # point.
10
+ def process
11
+ # Do nothing if we dont' have a status of NEW
12
+ return unless self.status == MdsUpload::NEW
13
+ return unless self.mds_content.present?
14
+
15
+ start_time = Time.now
16
+ num_records = 0
17
+ num_duplicated = 0
18
+ num_rejected = 0
19
+
20
+ # Loop over all the files in the upload file
21
+ self.mds_content.each_entry do | entry, relative_path |
22
+
23
+ next if File.directory?(entry)
24
+ basename = File.basename(entry)
25
+ next if basename =~ PCC_METADATA_FILE_RE
26
+
27
+ num_records += 1
28
+
29
+ parser = MdsXmlFileParser.new(entry)
30
+ assessment_data = parser.parse
31
+
32
+ if assessment_data.blank?
33
+ num_rejected += 1
34
+ self.file_errors.merge!(parser.file_errors) if parser.file_errors.present?
35
+ else
36
+ # We use the relative_path to the file from the extration
37
+ # directory so that the error report will properly show
38
+ # the path to the file with the problem, even if the file
39
+ # was located in an embedded zip file.
40
+ begin
41
+ mds = create_assessment(relative_path, assessment_data)
42
+ if mds.blank?
43
+ num_duplicated += 1
44
+ add_file_errors(relative_path, "Duplicate assessment")
45
+ elsif !mds.valid?
46
+ num_rejected += 1
47
+ add_file_errors(relative_path, mds.errors.values.flatten)
48
+ end
49
+ rescue => ex
50
+ num_rejected += 1
51
+ add_file_errors(relative_path, ex.message)
52
+ end
53
+ end
54
+ end
55
+
56
+ # Need to save any errors
57
+ update_attributes(status: MdsUpload::ASSESSMENTS_LOADED,
58
+ num_records: num_records,
59
+ num_duplicated: num_duplicated,
60
+ num_rejected: num_rejected,
61
+ parse_time: ((Time.now - start_time) * 1000).round)
62
+ rescue => ex
63
+ Rails.logger.error("#{ex.message}\n#{ex.backtrace.join("\n")}")
64
+ update_attribute(:fatal_error, "#{ex.message}\n#{ex.backtrace.join("\n")}")
65
+ end
66
+
67
+ private
68
+
69
+ def create_assessment(filename, assessment_data)
70
+ # Don't bother with duplicates
71
+ md5_checksum = Digest::MD5.hexdigest(assessment_data.to_s)
72
+ return if MdsAssessment.where(md5_checksum: md5_checksum).count > 0
73
+
74
+ mds_assessment = MdsAssessment.new(mds_upload: self,
75
+ md5_checksum: md5_checksum,
76
+ filename: filename,
77
+ responses: assessment_data)
78
+ if mds_assessment.valid?
79
+ mds_assessment.save
80
+ end
81
+ mds_assessment
82
+ end
83
+
84
+ end
85
+
86
+ end