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,44 @@
1
+ module Services
2
+
3
+ module MdsNotifications
4
+
5
+ def handle_mds_notifications
6
+ logger.info "Fixing to notify the uploader: #{notify_the_uploader?}"
7
+ self.send_upload_confirmation if notify_the_uploader?
8
+
9
+ notification_type = self.account.mds_notification_type
10
+ return if notification_type == MdsNotification::NOTIFY_NONE
11
+
12
+ if notification_type == MdsNotification::NOTIFY_WHEN_UPLOADED
13
+ logger.info "Notifying for all uploads"
14
+ self.send_upload_confirmation(self.account.mds_notification_email)
15
+ else
16
+ # DS: Notice that an immediate account email will be sent out even if the notification
17
+ # type is set to NOTIFY_DAILY_DIGEST. THERE IS A REASON FOR THIS. Most accounts do not
18
+ # want to wait for the digest to be sent out to learn that there was an MDS upload error.
19
+ # These things don't happen very often, so it shouldn't be a major imposition to recieve
20
+ # these error emails.
21
+ #
22
+ # SO. DON'T CHANGE THIS UNLESS YOU HAVE BEEN EXPLICITLY ASKED TO CHANGE IT. I may have
23
+ # made a mistake here, but it was an _intentional_ mistake.
24
+ #
25
+ # Enjoy the rest of your day.
26
+ logger.info "Notifying for error uploads"
27
+ self.send_upload_confirmation(self.account.mds_notification_email) if has_errors?
28
+ end
29
+
30
+ end
31
+
32
+ def notify_the_uploader?
33
+ self.notify_uploader? &&
34
+ self.upload_user.present? &&
35
+ self.upload_user.email.present?
36
+ end
37
+
38
+ def send_upload_confirmation(notification_email=nil)
39
+ MDS_NOTIFICATION_MAILER.notify_mds_uploaded(self, notification_email).deliver
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,19 @@
1
+ module Services
2
+
3
+ module MonthlyServiceTableCleaner
4
+
5
+ def clean_up_service_tables
6
+ Services::AssessmentRequest.destroy_all where_clause(Services::AssessmentRequest::STATUS_COMPLETED)
7
+ Services::AvailableFile.destroy_all where_clause(Services::AvailableFile::STATUS_CLEARED)
8
+ Services::MdsPullAccount.destroy_all where_clause(Services::MdsPullAccount::STATUS_REMOTE_CLEAN)
9
+ end
10
+
11
+ private
12
+
13
+ def where_clause(status)
14
+ "DATEDIFF(CURRENT_DATE, created_at) > 30 AND status = #{status}"
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,11 @@
1
+ module Services
2
+
3
+ module NewRegistrationNotifier
4
+
5
+ def notify
6
+ ServicesMailer.notify_sltc_client_registration(self).deliver
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,14 @@
1
+ module Services
2
+
3
+ module PublicKeyCreator
4
+
5
+ def create(params)
6
+ key = params[:key_file].read
7
+ PublicKey.new(params.slice(:name, :valid_until).merge(key: key)).tap do | pk |
8
+ pk.save if pk.valid?
9
+ end
10
+ end
11
+
12
+ end
13
+
14
+ end
@@ -0,0 +1,12 @@
1
+ module Services
2
+
3
+ module PublicKeyUpdater
4
+
5
+ def update(params)
6
+ key = params[:key_file].read
7
+ self.tap { | pk | pk.update_attributes(params.slice(:name, :valid_until).merge(key: key)) }
8
+ end
9
+
10
+ end
11
+
12
+ end
@@ -0,0 +1,13 @@
1
+ module Services
2
+
3
+ module ServiceCreator
4
+
5
+ def create(params)
6
+ Service.new(params).tap do | svc |
7
+ svc.save if svc.valid?
8
+ end
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,13 @@
1
+ module Services
2
+
3
+ module ServiceDefinitionCreator
4
+
5
+ def create(params)
6
+ service_definitions.new(params).tap do | service_definition |
7
+ service_definition.save if service_definition.valid?
8
+ end
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,12 @@
1
+ module Services
2
+
3
+ module ServiceDefinitionUpdater
4
+
5
+ def update(params)
6
+ update_attributes(params)
7
+ self
8
+ end
9
+
10
+ end
11
+
12
+ end
@@ -0,0 +1,25 @@
1
+ module Services
2
+
3
+ module ServiceInvoker
4
+
5
+ #
6
+ # The async configuration options
7
+ #
8
+ ASYNC_SEND_OPTS = {
9
+ :priority => 100, # Pretty high priority; higher than MDS for sure
10
+ :time_to_run => 3600 # GIve it an hour
11
+ }
12
+
13
+ def invoke
14
+ service_definitions.each do | service_definition |
15
+
16
+ # Each service implementation is handled in a separate
17
+ # worker
18
+ service_definition.ayl_send_opts(:invoke, ASYNC_SEND_OPTS)
19
+
20
+ end
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,11 @@
1
+ module Services
2
+
3
+ module ServiceUpdater
4
+
5
+ def update(params)
6
+ self.tap { | svc | svc.update_attributes(params) }
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,19 @@
1
+ module Services
2
+
3
+ module SltcBaselineRequestor
4
+
5
+ def request_baseline(params)
6
+ provider_id = params[:provider_id]
7
+ uploaded_before = Time.parse(params[:uploaded_before])
8
+ uploaded_after = Time.parse(params[:uploaded_after])
9
+
10
+ sd = service_definition
11
+
12
+ si = sd.service_implementation
13
+
14
+ si.request_baseline(self, provider_id, uploaded_after, uploaded_before)
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,25 @@
1
+ module Services
2
+
3
+ module SltcProviderChangeNotifier
4
+
5
+ def notify
6
+ requiring_notification = ProviderChange.
7
+ where(status: ProviderChange::STATUS_NEW).
8
+ order("configured_account_id ASC, verb ASC")
9
+
10
+ return if requiring_notification.empty?
11
+
12
+ ServicesMailer.notify_sltc_provider_changes(requiring_notification).deliver
13
+
14
+ ids = requiring_notification.pluck(:id)
15
+
16
+ # Mark these guys as reported
17
+ ProviderChange.
18
+ connection.
19
+ execute("UPDATE services_provider_changes SET status = #{Services::ProviderChange::STATUS_REPORTED} WHERE id IN (#{ids.join(',')})")
20
+
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,13 @@
1
+ module Services
2
+
3
+ module SltcProviderLister
4
+
5
+ def list_providers
6
+ si = service_definition.service_implementation
7
+ api = si.api_impl(self)
8
+ api.list_providers
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,81 @@
1
+ module Services
2
+
3
+ module SltcRegistrationCompleter
4
+
5
+ def complete(params)
6
+ configure_only = params[:configure_only].present? && params[:configure_only] == 'true'
7
+
8
+ am = find_or_create_account_mapping(params[:third_party_id], params[:account_id])
9
+
10
+ ca = find_or_create_configured_account(params[:service_definition_id], params[:account_id], configure_only)
11
+
12
+ # The requestor only wants the account configured for operations. Does NOT
13
+ # want to process the registration any further at this time. The 'complete' method
14
+ # is re-entrant in that it will continue even if the account stuff has already been
15
+ # configured.
16
+ return if configure_only
17
+
18
+ si = ca.service_definition.service_implementation
19
+
20
+ # Take care of configuring all the facilities for the new account
21
+ si.identify_providers(ca)
22
+
23
+ # Now, request baselines for all the configured facilities
24
+ uploaded_before = Time.now
25
+ uploaded_after = uploaded_before - (params[:baseline_days].present? ? params[:baseline_days].to_i : 90).days
26
+
27
+ abaqis_facility_ids = ApplicationApi.api_impl.enabled_facilities_for_account_id(params[:account_id]).pluck(:id)
28
+
29
+ ca.service_definition.third_party.facility_mappings.where(facility_id: abaqis_facility_ids).each do | facility_mapping |
30
+ si.request_baseline(ca, facility_mapping.facility_code, uploaded_after, uploaded_before)
31
+ end
32
+
33
+ update_attributes(status: Services::SltcRegistration::STATUS_REGISTERED)
34
+
35
+ end
36
+
37
+ private
38
+
39
+ def find_or_create_account_mapping(third_party_id, account_id)
40
+ am = AccountMapping.where(third_party_id: third_party_id,
41
+ account_id: account_id,
42
+ account_code: account_code).first
43
+ unless am.present?
44
+ am = AccountMapping.create!(third_party_id: third_party_id,
45
+ account_id: account_id,
46
+ account_code: account_code)
47
+
48
+ end
49
+ am
50
+ end
51
+
52
+ def find_or_create_configured_account(service_definition_id, account_id, configure_only=false)
53
+ ca = ConfiguredAccount.where(service_definition_id: service_definition_id,
54
+ account_id: account_id).first
55
+
56
+ account_enabled = configure_only ? false : true
57
+
58
+ if ca.present?
59
+
60
+ # Force the enabled flag to the correct value
61
+ ca.update_attribute(:enabled, account_enabled)
62
+
63
+ cred = ca.credentials.first
64
+ if cred.present?
65
+ cred.update_attributes(password: auth_password)
66
+ else
67
+ ca.credentials << Credential.new(password: auth_password)
68
+ end
69
+ else
70
+ ca = ConfiguredAccount.create!(service_definition_id: service_definition_id,
71
+ account_id: account_id,
72
+ enabled: account_enabled,
73
+ username: username)
74
+ ca.credentials << Credential.new(password: auth_password)
75
+ end
76
+ ca
77
+ end
78
+
79
+ end
80
+
81
+ end
@@ -0,0 +1,13 @@
1
+ module Services
2
+
3
+ module SltcRegistrationSaver
4
+
5
+ def save_registration(params)
6
+ Services::SltcRegistration.new(params).tap do | registration |
7
+ registration.save if registration.valid?
8
+ end
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,28 @@
1
+ module Services
2
+
3
+ module SubmitMdsFileForProcessing
4
+ TIME_TO_RUN = 36000
5
+ PRIORITY = 500
6
+ ASYNC_SEND_OPTIONS = { :priority => PRIORITY, :time_to_run => TIME_TO_RUN }
7
+
8
+ def submit_uploaded_file
9
+ errors = []
10
+ mds_upload = MdsUpload.new(:account => account,
11
+ :mds_file => uploaded_file,
12
+ :status => MdsUpload::NEW,
13
+ :upload_user => upload_user,
14
+ :file_errors => {},
15
+ :notify_uploader => notify_uploader)
16
+
17
+ if mds_upload.valid?
18
+ mds_upload.save!
19
+ MdsFileProcessingContext.ayl_send_opts(:call, ASYNC_SEND_OPTIONS, mds_upload)
20
+ else
21
+ errors.concat(mds_upload.errors[:mds_file])
22
+ end
23
+ errors
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,13 @@
1
+ module Services
2
+
3
+ module ThirdPartyCreator
4
+
5
+ def create(params)
6
+ ThirdParty.new(params).tap do | tp |
7
+ tp.save if tp.valid?
8
+ end
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,12 @@
1
+ module Services
2
+
3
+ module ThirdPartyUpdater
4
+
5
+ def update(params)
6
+ update_attributes(params)
7
+ self
8
+ end
9
+
10
+ end
11
+
12
+ end
@@ -0,0 +1,33 @@
1
+ #
2
+ # A mixin for controllers that want to clean out temporary files created
3
+ # for file uploads.
4
+ #
5
+ # Typically used as follows:
6
+ #
7
+ # class MyController < ApplicationController
8
+ # include FileUploadHandler
9
+ #
10
+ # after_filter :clear_temporary_files
11
+ #
12
+ # ...
13
+ #
14
+ # end
15
+ #
16
+ module Services
17
+
18
+ module FileUploadHandler
19
+
20
+ def clear_temporary_files(hash=params)
21
+ return if hash.nil?
22
+ hash.values.each do |v|
23
+ if v.is_a?(Hash)
24
+ clear_temporary_files(v)
25
+ elsif v.respond_to?(:path)
26
+ File.unlink(v.path) if File.exists?(v.path)
27
+ end
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,26 @@
1
+ module Services
2
+
3
+ module MdsUploadFilters
4
+
5
+ def must_have_uploaded_file
6
+ @uploaded_file = params[:composite_file]
7
+ if @uploaded_file.blank?
8
+ @errors = [ "Please select an MDS file for upload." ]
9
+ render action: :create
10
+ end
11
+ end
12
+
13
+ def must_be_valid_mds_file
14
+ uv = UnzipmeValidator.new(@uploaded_file.path)
15
+
16
+ if ! uv.valid_zip?
17
+ @errors = [ "You have uploaded an invalid MDS 3.0 or MDS 3.0 Composite file." ]
18
+ error_stickie(@errors.first)
19
+ redirect_to stagei_mds_uploads_path
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,104 @@
1
+ require 'libxml'
2
+
3
+ module Services
4
+
5
+ class MdsXmlFileParser
6
+ include LibXML
7
+
8
+ attr_reader :assessment_file, :file_errors
9
+
10
+ ROOT_NODE = "ASSESSMENT"
11
+
12
+ def initialize(assessment_file)
13
+ @assessment_file = assessment_file
14
+ @base_name = File.basename(assessment_file)
15
+ @file_errors = { @base_name => [] }
16
+ end
17
+
18
+ def parse
19
+
20
+ begin
21
+ sax_handler = MdsSaxHandler.new
22
+ File.open(assessment_file, "r") do | f |
23
+ parser = LibXML::XML::SaxParser.io(f)
24
+ parser.callbacks = sax_handler
25
+ parser.parse
26
+ end
27
+
28
+ rescue LibXML::XML::Error
29
+ add_error "XML root element ASSESSMENT not found."
30
+ return
31
+ rescue
32
+ add_error "There was a problem parsing this file. Please ensure that it has the correct MDS 3.0 XML format."
33
+ return
34
+ end
35
+
36
+ add_error(sax_handler.errors) if sax_handler.errors.present?
37
+ return if has_errors?
38
+
39
+ add_error("XML data elements were not found.") if sax_handler.assessment_hash.empty?
40
+ return if has_errors?
41
+
42
+ sax_handler.assessment_hash
43
+ end
44
+
45
+ private
46
+
47
+ def add_error(error)
48
+ if error.is_a?(Array)
49
+ @file_errors[@base_name].concat(error)
50
+ else
51
+ @file_errors[@base_name] << error
52
+ end
53
+ end
54
+
55
+ def has_errors?
56
+ @file_errors[@base_name].present?
57
+ end
58
+
59
+ end
60
+
61
+ # ----------------------------------------------------------------------------#
62
+ # Using LibXML with SAX API for performance reasons. #
63
+ # ----------------------------------------------------------------------------#
64
+
65
+ class MdsSaxHandler
66
+ include LibXML::XML::SaxParser::Callbacks
67
+
68
+ attr_reader :assessment_hash, :errors
69
+
70
+ ROOT_NESTING_LEVEL = 0
71
+ ATTRIBUTE_NESTING_LEVEL = 1
72
+ TEXT_NESTING_LEVEL = 2
73
+
74
+ def initialize
75
+ @assessment_hash = {}
76
+ @file_errors = []
77
+ @xml_nesting_level = ROOT_NESTING_LEVEL
78
+ @element_text = nil
79
+ end
80
+
81
+ def on_start_element(element_name, attributes)
82
+ if @xml_nesting_level == ROOT_NESTING_LEVEL
83
+ @file_errors << "XML root element ASSESSMENT not found." unless element_name == "ASSESSMENT"
84
+ end
85
+ @xml_nesting_level += 1
86
+ @element_text = ''
87
+ end
88
+
89
+ def on_characters(text)
90
+ @element_text << text if @xml_nesting_level == TEXT_NESTING_LEVEL
91
+ end
92
+
93
+ def on_end_element(element_name)
94
+ @assessment_hash[element_name.downcase] = @element_text.strip if !@element_text.nil? && @xml_nesting_level == TEXT_NESTING_LEVEL
95
+ @xml_nesting_level -= 1
96
+ end
97
+
98
+ def on_error(error)
99
+ @file_errors << error.message
100
+ end
101
+
102
+ end
103
+
104
+ end
@@ -0,0 +1,13 @@
1
+ module Services
2
+
3
+ class UploadFile < File
4
+ attr_reader :original_filename, :content_type
5
+
6
+ def initialize(filename)
7
+ super(filename, "rb")
8
+ @original_filename = File.basename(filename)
9
+ @content_type = "application/zip"
10
+ end
11
+ end
12
+
13
+ end
@@ -0,0 +1,42 @@
1
+
2
+ class IscCodeValidator < ActiveModel::EachValidator
3
+
4
+ def validate_each(object, attribute, value)
5
+ isc_lookup = Services::IscCodeLookup.new(object)
6
+ object.errors[attribute] << "The ISC Code provided: #{isc_lookup.isc_provided_value} is incorrect for this assessment." unless isc_lookup.valid_isc_value?
7
+ end
8
+
9
+
10
+
11
+ #-----------------------------------------------------------------#
12
+ # Removing the custom message below for performance reasons #
13
+ #-----------------------------------------------------------------#
14
+ def build_error_message(object, isc_lookup)
15
+ message = "The ISC value in this file (#{isc_lookup.isc_provided_value}), "
16
+ message += cms_table_message(isc_lookup)
17
+ message += "Please ensure these values are correct: "
18
+ message += attribute_message(isc_lookup, object)
19
+ message
20
+ end
21
+
22
+
23
+ def cms_table_message(isc_lookup)
24
+ if isc_lookup.isc_lookup_value.nil?
25
+ message = "does not match any value provided in the CMS lookup table. "
26
+ else
27
+ message = "does not match the value provided in the CMS lookup table (#{isc_lookup.isc_lookup_value}). "
28
+ end
29
+ message
30
+ end
31
+
32
+ def attribute_message(isc_lookup, object)
33
+ if isc_lookup.isc_lookup_value == IscCode.inactivation_code
34
+ message = "x0100 => #{object.x0100} "
35
+ else
36
+ message = "a0200 => #{object.a0200}, a0310a => #{object.a0310a}, a0310b => #{object.a0310b}, a0310c => #{object.a0310c}, a0310d => #{object.a0310d}, a0310f => #{object.a0310f}."
37
+ end
38
+ message
39
+ end
40
+
41
+
42
+ end
@@ -0,0 +1,37 @@
1
+ class MdsBirthdateValidator < ActiveModel::EachValidator
2
+
3
+ def validate_each(record, attribute, value)
4
+ return true if record.send("clean_#{attribute}").blank?
5
+ # return true if value.blank? || Resident.missing_attribute_values.include?(value)
6
+ record.errors[attribute] << "Invalid birth date entered in #{attribute}. Birth date may contain only numbers." and return if value =~ /\D/
7
+ record.errors[attribute] << "Invalid birth date entered in #{attribute}. Birth date must be formatted as YYYYMMDD, YYYYMM or YYYY." and return unless birthdate_correct_length?(value)
8
+ record.errors[attribute] << "Invalid birth date entered in #{attribute}. Birth date is not valid." unless birthdate_ymd_valid?(value)
9
+ end
10
+
11
+
12
+ private
13
+
14
+ def birthdate_correct_length?(birthdate)
15
+ return true if birthdate.blank?
16
+ return true if [4, 6, 8].include?(birthdate.length)
17
+ false
18
+ end
19
+
20
+ #----------------------------------------------------#
21
+ # If it gets here, then it is of correct length #
22
+ #----------------------------------------------------#
23
+ def birthdate_ymd_valid?(birthdate)
24
+ return true if birthdate.blank?
25
+ year, month, day = birthdate.slice(0,4), birthdate.slice(4,2), birthdate.slice(6,2)
26
+ year_valid?(year) && month_valid?(month) && day_valid?(day)
27
+ end
28
+
29
+ def year_valid?(year) year =~ /\A(18|19|20)\d\d/; end
30
+
31
+ def month_valid?(month) return true if month.blank?; month =~ /\A(0[1-9]|1[012])/; end
32
+
33
+ def day_valid?(day) return true if day.blank?; day =~ /\A(0[1-9]|[12][0-9]|3[01])/; end
34
+
35
+
36
+ end
37
+
@@ -0,0 +1,8 @@
1
+ class MdsDateValidator < ActiveModel::EachValidator
2
+
3
+ def validate_each(record, attribute, value)
4
+ return if value.is_a?(Date) # We store dates as Date's; don't validate if it is already a date.
5
+ record.errors[attribute] << "A valid date in item #{attribute} is required for this assessment type." if Date.safe_parse(value).blank?
6
+ end
7
+
8
+ end