change_healthcare 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,88 @@
1
+ # https://cli-cert.emdeon.com/api/cert/order.html
2
+ class ChangeHealthcare::Order < ChangeHealthcare::BaseApiObject
3
+ def self.attributes
4
+ [
5
+ :actalink_user_name, :age, :age_type, :anonymous_flag, :aoe_validation_failed,
6
+ :beacon_case_number, :bed, :bill_type, :billingcaregiver, :cached_requisition,
7
+ :callback_phone_area_code, :callback_phone_number, :cg_first_name, :cg_last_name,
8
+ :cg_middle_name, :collection_datetime, :created_by, :date, :description, :document,
9
+ :expected_coll_datetime, :fasting_hours, :faxback_phone_area_code, :faxback_phone_number,
10
+ :first_name, :guarantor, :guarantor_address_1, :guarantor_address_2, :guarantor_city,
11
+ :guarantor_first_name, :guarantor_home_phone, :guarantor_last_name, :guarantor_middle_name,
12
+ :guarantor_relationship, :guarantor_sex, :guarantor_state, :guarantor_suffix, :guarantor_zip,
13
+ :home_phone_area_code, :home_phone_number, :hospital_id, :hsilabel, :icd_10_cm_code,
14
+ :icd_9_cm_code, :icd_lab_accepts, :icd_validation_failed, :include_in_manifest,
15
+ :is_split, :lab, :lab_instruction, :lab_logo_location, :lab_name, :lab_reference,
16
+ :last_name, :master_placer_order_number, :middle_name, :nurse_unit, :order, :order_code,
17
+ :order_comment, :order_diag_description, :order_status, :order_type, :ordering_cg_id,
18
+ :orderingorganization, :organization_counter, :orig_organization_name, :originalorder,
19
+ :origorderingorganization, :pan_indicator, :parentorder, :patient_id, :person,
20
+ :person_address_1, :person_address_2, :person_city, :person_dob, :person_first_name,
21
+ :person_home_phone_area_code, :person_home_phone_number, :person_hsi_value,
22
+ :person_last_name, :person_middle_name, :person_sex, :person_ssn, :person_state,
23
+ :person_suffix, :person_zip, :personhsi, :phone_result_flag, :placer_order_number,
24
+ :prepaid_amount, :primaryorderingcaregiver, :ref_cg_fname, :ref_cg_lname, :ref_cg_mname,
25
+ :ref_cg_npi, :ref_cg_suffix, :ref_cg_upin, :referring_cg_id, :referringcaregiver,
26
+ :request_date, :room, :seconds_since_transmit, :sex, :stat_flag, :submission_date,
27
+ :suffix, :transmission_date, :username, :work_phone_area_code, :work_phone_ext, :work_phone_number
28
+ ]
29
+ end
30
+
31
+ attr_accessor(*self.attributes)
32
+
33
+ def self.chc_object_name
34
+ "order"
35
+ end
36
+
37
+ # https://cli-cert.emdeon.com/api/cert/order.html#generate_order_number
38
+ # params = { lab: "1502191", orderingorganization: #{facility} }
39
+ def self.generate_order_number(params={})
40
+ resp = call_api(__method__.to_s, params, false)
41
+ response_to_list(resp)
42
+ end
43
+
44
+ # https://cli-cert.emdeon.com/api/cert/order.html#search_by_order_info
45
+ # params = { placer_order_number: "76047", orderingorganization: #{facility} }
46
+ def self.search_by_order_info(params={})
47
+ resp = call_api(__method__.to_s, params, false)
48
+ response_to_list(resp)
49
+ end
50
+
51
+ # https://cli-cert.emdeon.com/api/cert/order.html#get
52
+ # params = { order: "3004834610" }
53
+ def self.get(params={})
54
+ resp = call_api(__method__.to_s, params, false)
55
+ response_to_list(resp)
56
+ end
57
+
58
+ def self.e_order_summary_link(params)
59
+ base = {
60
+ "userid" => configuration.user_id,
61
+ "PW" => configuration.password,
62
+ "hdnBusiness" => configuration.facility,
63
+ "target" => "jsp/lab/order/ESummaryOrder.jsp",
64
+ "actionCommand" => "EOrderSummary",
65
+ "summary" => "true",
66
+ "apilogon" => "true",
67
+ }
68
+ params.merge!(base)
69
+
70
+ return "#{configuration.portal_url}?#{params.to_query}"
71
+ end
72
+
73
+
74
+ #{order_id: XXXXXXXXXXX}
75
+ def self.e_order_html_link(params)
76
+ base = {
77
+ "userid" => configuration.user_id,
78
+ "PW" => configuration.password,
79
+ "hdnBusiness" => configuration.facility,
80
+ "apiLogin" => "true",
81
+ "target" => "servlet/servlets.apiOrderServlet?",
82
+ "actionCommand" => "print",
83
+ "apiuserid" => configuration.user_id
84
+ }
85
+ params.merge!(base)
86
+ return "#{configuration.portal_url}?#{params.to_query}"
87
+ end
88
+ end
@@ -0,0 +1,59 @@
1
+ module ChangeHealthcare
2
+ class OrderDiagnosis < ChangeHealthcare::BaseApiObject
3
+ def self.attributes
4
+ %i[
5
+ name
6
+ op
7
+ date
8
+ clientid
9
+ split_code
10
+ orderable
11
+ description
12
+ exclusive_flag
13
+ cpp_count
14
+ expiration_date
15
+ orderdiagnosis
16
+ orderable_type
17
+ special_test_flag
18
+ ordertest
19
+ specimen
20
+ clearance
21
+ freq_abn
22
+ icd_10_cm_code
23
+ order_diag_description
24
+ has_aoe
25
+ order
26
+ icd_9_cm_code
27
+ placer_order_number
28
+ orderable_description
29
+ ownerid
30
+ created_by
31
+ lcp_fda_flag
32
+ order_code
33
+ sequence
34
+ estimated_cost
35
+ category
36
+ user_description
37
+ ]
38
+ end
39
+
40
+ attr_accessor(*attributes)
41
+
42
+ def self.chc_object_name
43
+ 'orderdiagnosis'
44
+ end
45
+
46
+ # https://cli-cert.emdeon.com/api/cert/orderdiagnosis.html#get
47
+ # params = {orderdiagnosis: xxxxxxxxxx} or {order: xxxxxxxxxx}
48
+ def self.get(params)
49
+ # if orderdiagnosis reference is passed in use default orderdiagnosis.get call
50
+ if params[:orderdiagnosis].present?
51
+ resp = call_api(__method__.to_s, params, false)
52
+ response_to_list(resp)
53
+ # if order reference is passed in use servlet.apiOrderServlet to grab all order details and fetch orderdiagnosis info
54
+ elsif params[:order].present?
55
+ Servlet.api_order_servlet(params)['orderdiagnosis'].map { |diagnosis| new(diagnosis) }
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,25 @@
1
+ # https://cli-cert.emdeon.com/api/cert/organizationlab.htm
2
+ class ChangeHealthcare::OrganizationLab < ChangeHealthcare::BaseApiObject
3
+ def self.attributes
4
+ [
5
+ :address_1, :address_2, :can_order_thru, :city, :clia_number,
6
+ :discrete_result, :enable_irbcl, :is_beacon, :is_default,
7
+ :lab, :lab_code, :lab_name, :organization, :organizationlab,
8
+ :parent_lab_code, :parent_lab_name, :parentlab, :payer_priority,
9
+ :sequence, :state, :transfer_id, :transmission_mode, :zip
10
+ ]
11
+ end
12
+
13
+ attr_accessor(*self.attributes)
14
+
15
+ def self.chc_object_name
16
+ "organizationlab"
17
+ end
18
+
19
+ #https://cli-cert.emdeon.com/api/cert/organizationlab.html#search_orderable_labs
20
+ #sample params: {can_order_thru: "Y", child_only: "Y"}
21
+ def self.search_orderable_labs(params={})
22
+ resp = call_api(__method__.to_s, params)
23
+ response_to_list(resp)
24
+ end
25
+ end
@@ -0,0 +1,48 @@
1
+ # https://cli-cert.emdeon.com/api/cert/person.html
2
+ class ChangeHealthcare::Person < ChangeHealthcare::BaseApiObject
3
+ def self.attributes
4
+ [
5
+ :address_1, :address_2, :age, :age_type, :allergy_status, :bill_type,
6
+ :birth_date, :city, :country, :county, :date, :fav_pharm_name,
7
+ :favorite_pharmacy, :first_name, :formu_groupid, :formu_orgid,
8
+ :guarantor, :height, :home_phone_area_code, :home_phone_number,
9
+ :hsi_value, :hsilabel, :insurance, :is_active, :isp_address_1,
10
+ :isp_city, :isp_hsi_value, :isp_name, :isp_state, :isp_zip, :lab,
11
+ :lab_name, :label_name, :last_name, :last_name_soundex, :leadperson,
12
+ :middle_name, :mother_name, :mothers_maiden_name, :name_prefix,
13
+ :organization, :payer_identifier, :person, :person_hsi, :placer_order_number,
14
+ :plan_identifier, :prim_cg_fname, :prim_cg_lname, :prim_cg_mname,
15
+ :primarycaregiver, :providercaregiver, :record_date, :sec_insurance,
16
+ :sec_isp_address_1, :sec_isp_city, :sec_isp_hsi_value, :sec_isp_name,
17
+ :sec_isp_state, :sec_isp_zip, :sex, :soundex_flag, :ssn, :state, :status,
18
+ :suffix, :ter_insurance, :ter_isp_address_1, :ter_isp_city, :ter_isp_hsi_value,
19
+ :ter_isp_name, :ter_isp_state, :ter_isp_zip, :title, :transmission_mode, :weight,
20
+ :work_phone_area_code, :work_phone_ext, :work_phone_number, :zip
21
+ ]
22
+ end
23
+
24
+ attr_accessor(*self.attributes)
25
+
26
+ def self.chc_object_name
27
+ "person"
28
+ end
29
+
30
+ # https://cli-cert.emdeon.com/api/cert/person.html#search_hsi
31
+ # Search by patient id
32
+ # params = {hsi_value: "PATIENT_ID"}
33
+ def self.search_hsi(params={})
34
+ resp = call_api(__method__.to_s, params, true)
35
+ response_to_list(resp)
36
+ end
37
+
38
+ # https://cli-cert.emdeon.com/api/cert/person.html#put_partial
39
+ # Create Patient
40
+ # params = {birth_date: "10/27/1924", first_name: "Florence",
41
+ # last_name: "Edwards", middle_name: "E", address_1: "2401 N Abram Rd 85",
42
+ # city: "Mission", state: "TX", sex: "F", zip: "78572", hsi_value: "955001",
43
+ # hsilabel: "7930723", home_phone_area_code: "956", home_phone_number: "5856449"}
44
+ def self.put_partial(params={})
45
+ resp = call_api(__method__.to_s, params, false)
46
+ response_to_list(resp)
47
+ end
48
+ end
@@ -0,0 +1,33 @@
1
+ # https://cli-cert.emdeon.com/api/cert/providercaregiver.html
2
+ class ChangeHealthcare::ProviderCaregiver < ChangeHealthcare::BaseApiObject
3
+ def self.attributes
4
+ [
5
+ :appuser, :reference, :caregiver, :caregiver_type,
6
+ :cg_birth_date, :cg_dea_number, :cg_first_name,
7
+ :cg_is_epcs_enabled, :cg_last_name, :cg_middle_name,
8
+ :cg_npi, :cg_patmsg_id, :cg_prefix, :cg_sex,:cg_ssn,
9
+ :cg_suffix, :cg_type, :cg_upin, :dea_number, :enable_epcs,
10
+ :enable_refill, :is_active, :is_erx_registered, :organization,
11
+ :provider, :provider_address_1, :provider_city, :provider_fed_tax_id,
12
+ :provider_name, :provider_npi, :provider_state, :provider_type,
13
+ :provider_zip, :providercaregiver, :toggle_epcs_for_approval, :update
14
+ ]
15
+ end
16
+
17
+ attr_accessor(*self.attributes)
18
+ def self.chc_object_name
19
+ "providercaregiver"
20
+ end
21
+ # https://cli-cert.emdeon.com/api/cert/providercaregiver.html#search_provcg_and_cgpref
22
+ def self.search_provcg_and_cgpref
23
+ resp = call_api(__method__.to_s)
24
+ response_to_list(resp)
25
+ end
26
+
27
+ # https://cli-cert.emdeon.com/api/cert/providercaregiver.html#put_no_update
28
+ # params = {caregiver: "3004219964", provider: #{facility}}
29
+ def self.put_no_update(params={})
30
+ resp = call_api(__method__.to_s, params, false)
31
+ response_to_list(resp)
32
+ end
33
+ end
@@ -0,0 +1,139 @@
1
+ # Not a object on the API
2
+ class ChangeHealthcare::Report < ChangeHealthcare::BaseApiObject
3
+
4
+
5
+ # params = {
6
+ # "reportTypes" => "LABRES",
7
+ # "EMR" => "y",
8
+ # "autoPrint" => "true",
9
+ # "batchDownload" => "true",
10
+ # "CreationDateFrom" => "03/01/2014",
11
+ # "CreationDateTo" => "03/08/2014",
12
+ # }
13
+ # yields a hash with all the file data
14
+ def self.download_reports(params)
15
+ raise "Block needed to handle results" unless block_given?
16
+ r1 = RestClient.get(search_downloadable_reports(params))
17
+ cookies = r1.cookies
18
+
19
+ loop do
20
+ r2 = RestClient.get(number_of_files_to_download, cookies: cookies)
21
+ #cookies = r2.cookies
22
+
23
+ files_to_dowload_data = r2.body.match("<--BEGIN NUMBER OF DOCS>(?<data>.*)<--END NUMBER OF DOCS>")[:data]
24
+ number, error_code, report_unique_id, _ = files_to_dowload_data.split(";")
25
+ number = number.to_i
26
+
27
+ break if number == -1
28
+
29
+ i=0
30
+ while i < number do
31
+ r3 = RestClient.get(retrieve_document_information, cookies: cookies)
32
+ doc_info = r3.body
33
+ doc_data = r3.body.match("<--BEGIN FILE INFO>(?<data>.*)<--END FILE INFO>")[:data]
34
+
35
+ sponsor_name, report_type, receiving_client_id,
36
+ account_no_last_name_first_name, document_unique_id, mime_type,
37
+ special, request_or_service_date, sponsor_code,
38
+ caregiver_id, account, first_name, last_name, report_service_date,
39
+ practice_id, report_subject, report_status = doc_data.split(";")
40
+
41
+ r4 = RestClient.get(download_document, cookies: cookies)
42
+ doc_content = r4.body
43
+
44
+ yield({
45
+ report_unique_id: report_unique_id,
46
+ document_unique_id: document_unique_id,
47
+ last_name: last_name,
48
+ first_name: first_name,
49
+ sponsor_name: sponsor_name,
50
+ report_type: report_type,
51
+ receiving_client_id: receiving_client_id,
52
+ account_no_last_name_first_name: account_no_last_name_first_name,
53
+ mime_type: mime_type,
54
+ special: special,
55
+ request_or_service_date: request_or_service_date,
56
+ sponsor_code: sponsor_code,
57
+ caregiver_id: caregiver_id,
58
+ account: account,
59
+ report_service_date: report_service_date,
60
+ practice_id: practice_id,
61
+ report_subject: report_subject,
62
+ report_status: report_status,
63
+ doc_content: doc_content,
64
+ cookies: cookies
65
+ })
66
+
67
+ i+=1
68
+ end
69
+ end
70
+ end
71
+
72
+ # params = {
73
+ # "reportTypes" => "LABRES",
74
+ # "EMR" => "y",
75
+ # "autoPrint" => "true",
76
+ # "batchDownload" => "true",
77
+ # "CreationDateFrom" => "03/01/2014",
78
+ # "CreationDateTo" => "03/08/2014",
79
+ # }
80
+ def self.search_downloadable_reports(params)
81
+ base = {
82
+ "userid" => configuration.user_id,
83
+ "PW" => configuration.password,
84
+ "hdnBusiness" => configuration.facility,
85
+ "apiLogin" => "true",
86
+ "target" => "jsp/lab/results/FDC.jsp",
87
+ "actionCommand" => "startDownload"
88
+ }
89
+ params.merge!(base)
90
+
91
+ return "#{configuration.portal_url}?#{params.to_query}"
92
+ end
93
+
94
+ # Needs to be chained through session to previous call
95
+ def self.number_of_files_to_download
96
+ params = {
97
+ "actionCommand" => "NextFile",
98
+ "batchDownload" => "true",
99
+ "fdcuserid" => configuration.user_id
100
+ }
101
+ return "#{lab_portal_url}?#{params.to_query}"
102
+ end
103
+
104
+ # Needs to be chained through session to previous call
105
+ def self.retrieve_document_information
106
+ params = {
107
+ "actionCommand" => "GetFileInfo",
108
+ "fdcuserid" => configuration.user_id
109
+ }
110
+ return "#{lab_portal_url}?#{params.to_query}"
111
+ end
112
+
113
+ # Needs to be chained through session to previous call
114
+ def self.download_document
115
+ params = {
116
+ "actionCommand" => "DownloadFile",
117
+ "fdcuserid" => configuration.user_id
118
+ }
119
+ return "#{lab_portal_url}?#{params.to_query}"
120
+ end
121
+
122
+
123
+ # Needs to be chained through session to previous call
124
+ def self.mark_as_downloaded
125
+ params = {
126
+ "actionCommand" => "MarkAsDownloaded",
127
+ "fdcuserid" => configuration.user_id
128
+ }
129
+ return "#{lab_portal_url}?#{params.to_query}"
130
+ end
131
+
132
+ private
133
+
134
+ def self.lab_portal_url
135
+ path = configuration.portal_url.dup
136
+ path["DxLogin"] = "lab.results.fdcServlet"
137
+ path
138
+ end
139
+ end
@@ -0,0 +1,50 @@
1
+ # https://cli-cert.emdeon.com/api/Change%20Healthcare%20Clinical%20Exchange%20Channel%20Partner%20API%20v2.4.pdf
2
+
3
+ module ChangeHealthcare
4
+ class Servlet < ChangeHealthcare::BaseApiObject
5
+ def self.chc_object_name
6
+ 'servlets'
7
+ end
8
+
9
+ def self.api_order_servlet(params)
10
+ resp = call_api(__method__.to_s.camelize(:lower), params)
11
+ data_nodes = resp.xml.root.children.map { |node| Hash.from_xml(node.to_s)['OBJECT'] }
12
+ data_nodes.each_with_object({}) do |node, hsh|
13
+ hsh[node['name']] ||= []
14
+ hsh[node['name']] << node
15
+ end
16
+ end
17
+
18
+ class << self
19
+ private
20
+
21
+ def call_api(name, params = {})
22
+ formatted_params = base_api_params.merge(params)
23
+ response = RestClient.get(url(name, formatted_params), cookies: login.cookies)
24
+ ChangeHealthcare::XmlResponse.new(response)
25
+ end
26
+
27
+ def base_api_params
28
+ {
29
+ apiuserid: configuration.user_id,
30
+ actionCommand: 'xml'
31
+ }
32
+ end
33
+
34
+ def login
35
+ params = {
36
+ userid: configuration.user_id,
37
+ PW: configuration.password,
38
+ hdnBusiness: configuration.facility,
39
+ apiLogin: true,
40
+ actionCommand: 'xml'
41
+ }
42
+ RestClient.get("#{configuration.portal_url}?#{params.to_query}")
43
+ end
44
+
45
+ def url(name, params)
46
+ "#{configuration.base_api_url}/#{chc_object_name}.#{name}?#{params.to_query}"
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,3 @@
1
+ module ChangeHealthcare
2
+ VERSION = '1.0.1'.freeze
3
+ end
@@ -0,0 +1,13 @@
1
+ module ChangeHealthcare
2
+ class XmlResponse
3
+ attr_reader :xml, :response
4
+ def initialize(response)
5
+ @response = response
6
+ @xml = Nokogiri::XML(response.body)
7
+ end
8
+
9
+ def method_missing(m, *args, &block)
10
+ response.send(m, *args, &block)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,45 @@
1
+ require "rest_client"
2
+ require "nokogiri"
3
+
4
+ require "active_support"
5
+ require 'active_support/core_ext'
6
+ require "singleton"
7
+
8
+ require "change_healthcare/version"
9
+ require "change_healthcare/error"
10
+ require "change_healthcare/api_client"
11
+ require "change_healthcare/base_api_object"
12
+ require "change_healthcare/xml_response"
13
+ require "change_healthcare/caregiver"
14
+ require "change_healthcare/hsi_label"
15
+ require "change_healthcare/lab_system_code"
16
+ require "change_healthcare/organization_lab"
17
+ require "change_healthcare/provider_caregiver"
18
+ require "change_healthcare/client_id"
19
+ require "change_healthcare/lab_config"
20
+ require "change_healthcare/order"
21
+ require "change_healthcare/person"
22
+ require "change_healthcare/object_doc"
23
+ require "change_healthcare/report"
24
+ require "change_healthcare/clinical_report"
25
+ require "change_healthcare/servlet"
26
+ require "change_healthcare/order_diagnosis"
27
+
28
+
29
+ module ChangeHealthcare
30
+ class Error < StandardError; end
31
+
32
+ class << self
33
+ attr_accessor :configuration
34
+ end
35
+
36
+ def self.configure
37
+ self.configuration ||= Configuration.new
38
+ yield(configuration) if block_given?
39
+ configuration
40
+ end
41
+
42
+ class Configuration
43
+ attr_accessor :base_url, :base_api_url, :portal_url, :user_id, :password, :facility
44
+ end
45
+ end