allscripts_api 0.4.0 → 0.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 315aedfaf84044bf6676dba411e2c73f5693aa0e
4
- data.tar.gz: 4d37e4ebba1d080edb9766e80dbb672dae232fd8
3
+ metadata.gz: e7f2c6194381fdaa1b4069b22120b15d035333e2
4
+ data.tar.gz: 01520fdc6872cfefe47c6844cf3067ee075095c3
5
5
  SHA512:
6
- metadata.gz: 1215aeb29079a1a44e68c07762cb52f2e3132e0d57666574d30a43a49f04dd015c2833157eecfda9e9f964cfc06125b6b82ffd4cf55e7cfcc45c300734db3bae
7
- data.tar.gz: 2a12b36abd1eca7dddef706a0fdd96726c4500c4ee55af2e166a43aadfc3e3e0f4e650ac576dbbb359a74f759b5520ce1ae2622677c19c2e8fb78709251bc826
6
+ metadata.gz: edfadd90b79088c4de35c34a0884e2d11bd7946e50b2ce6409197e793175e28ce97e00b55c69ce5b0e224d3cd578bf09f2d5e23bf08955c0bab775fc4227dc07
7
+ data.tar.gz: e87bb431c75c9cd005bd147a8c0043444cbc73181bef5b323d099660fe12c90a51dd7315a08d2da4458d8c570a1267ba026b662303dae09a9d5240a818137b40
data/.pryrc CHANGED
@@ -1,6 +1,7 @@
1
1
  require "allscripts_api"
2
2
  require "yaml"
3
3
  require "awesome_print"
4
+ require "base64"
4
5
  AwesomePrint.pry!
5
6
  AwesomePrint.defaults = { raw: true }
6
7
 
@@ -24,4 +25,26 @@ def bc
24
25
  client.get_user_authentication("jmedici", "password01")
25
26
 
26
27
  client
27
- end
28
+ end
29
+
30
+ def document_params
31
+ {
32
+ bytes_read: "0",
33
+ b_done_upload: false,
34
+ document_var: "",
35
+ patient_id: 19,
36
+ owner_code: "TW0001",
37
+ first_name: "Allison",
38
+ last_name: "Allscripts",
39
+ document_type: "sEKG", #document_type_de.entrycode value GetDictionary
40
+ organization_name: "New World Health"
41
+ }
42
+ end
43
+
44
+ def pdf
45
+ File.open("spec/fixtures/hba1c_sample.pdf").read
46
+ end
47
+
48
+ def encoded_pdf
49
+ Base64.encode64(pdf)
50
+ end
@@ -2,7 +2,7 @@ AllCops:
2
2
  Exclude:
3
3
  - "bin/*"
4
4
  - .pryrc
5
- - "spec/*"
5
+ - "spec/**/*"
6
6
 
7
7
  Style/StringLiterals:
8
8
  EnforcedStyle: double_quotes
@@ -19,10 +19,20 @@ Metrics/MethodLength:
19
19
  Max: 15
20
20
  Exclude:
21
21
  - "lib/allscripts_api/order.rb"
22
+ - "lib/allscripts_api/documents/document.rb"
22
23
  # Bumbing the max from 5 to 7 allows magic params to work nicely
23
24
  Metrics/ParameterLists:
24
25
  Max: 7
25
26
 
26
27
  Metrics/AbcSize:
27
28
  Exclude:
28
- - "lib/allscripts_api/order.rb"
29
+ - "lib/allscripts_api/order.rb"
30
+ - "lib/allscripts_api/documents/document.rb"
31
+
32
+ Metrics/BlockLength:
33
+ Exclude:
34
+ -
35
+ - "lib/allscripts_api/documents/document.rb"
36
+
37
+ Metrics/LineLength:
38
+ Max: 90
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- allscripts_api (0.4.0)
4
+ allscripts_api (0.5.0)
5
5
  faraday (>= 0.12.2)
6
6
 
7
7
  GEM
@@ -1,10 +1,13 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "nokogiri"
3
4
  require "allscripts_api/configuration"
5
+ require "allscripts_api/utilities/validator"
4
6
  require "allscripts_api/magic_params"
5
7
  require "allscripts_api/named_magic_methods"
6
8
  require "allscripts_api/ordering_methods"
7
9
  require "allscripts_api/order"
10
+ require "allscripts_api/documents"
8
11
  require "allscripts_api/client"
9
12
  require "allscripts_api/version"
10
13
 
@@ -18,6 +21,10 @@ module AllscriptsApi
18
21
  class GetTokenError < RuntimeError
19
22
  end
20
23
 
24
+ # Error raised when required params are missing.
25
+ class MissingRequiredParamsError < RuntimeError
26
+ end
27
+
21
28
  # Error raised if AllscriptsApi.connect is called without configuring
22
29
  # the gem first
23
30
  class NoConfigurationError < RuntimeError
@@ -7,6 +7,7 @@ module AllscriptsApi
7
7
  class Client
8
8
  include AllscriptsApi::NamedMagicMethods
9
9
  include AllscriptsApi::OrderingMethods
10
+ include AllscriptsApi::Documents::DocumentMethods
10
11
  attr_reader :adapter, :unity_url, :app_name, :token
11
12
  attr_writer :sso_token
12
13
 
@@ -4,12 +4,12 @@ module AllscriptsApi
4
4
  # Configuration class to allow configuration on application
5
5
  # initialization. Configuration should look like the following.
6
6
  #
7
- # AllscriptsApi.configure do |config|
8
- # config.app_name = 'YOUR_APP_NAME_HERE'
9
- # config.app_username = 'YOUR_APP_USERNAME_HERE'
10
- # config.app_password = 'YOUR_APP_PASSWORD_HERE'
11
- # config.faraday_adapter = Faraday.some_adapter # default = Faraday.default_adapter
12
- # end
7
+ # AllscriptsApi.configure do |config|
8
+ # config.app_name = 'YOUR_APP_NAME_HERE'
9
+ # config.app_username = 'YOUR_APP_USERNAME_HERE'
10
+ # config.app_password = 'YOUR_APP_PASSWORD_HERE'
11
+ # config.faraday_adapter = Faraday.some_adapter # default = Faraday.default_adapter
12
+ # end
13
13
  class Configuration
14
14
  attr_accessor :app_name, :app_password, :app_username, :faraday_adapter
15
15
  # The initialize method may be passed a block, but defaults to fetching
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "allscripts_api/documents/document_methods"
4
+ require "allscripts_api/documents/document"
5
+ require "allscripts_api/documents/document_sender"
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AllscriptsApi
4
+ module Documents
5
+ # A value object wrapped around a Nokogiri::XML::Builder
6
+ # DSL that builds properly formatted XML for
7
+ # {AllscriptsApi::OrderingMethods.save_document_image}
8
+ # @see https://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/Builder
9
+ class Document
10
+ # rubocop:disable LineLength
11
+ # required parameters for building the XML, omitting any raises {MissingRequiredParamsError}
12
+ REQUIRED_PARAMS =
13
+ %i[bytes_read document_type first_name last_name
14
+ organization_name owner_code].freeze
15
+ # Builder method for returning XML needed to save document images
16
+ #
17
+ # @param file_name [String] name of the file you wish to save
18
+ # @param command [String] i for insert, e for delete (entered in error), u for update
19
+ # @param params [Hash] any other params you may wish to pass to the api
20
+ # params may look like the following, all of which are required:
21
+ # @option params [String] :bytes_read number of bytes in the chunk (use 0 for 1 big chunk)
22
+ # @option params [String] :b_done_upload should be passed in as false,
23
+ # @option params [String] :document_var should be empty unless you are saving or updating
24
+ # @option params [String] :patient_id
25
+ # @option params [String] :owner_code EntryCode value from GetProvider
26
+ # @option params [String] :first_name patient first name
27
+ # @option params [String] :last_name patient last name
28
+ # @option params [String] :document_type document_type_de entrycode from value GetDictionary, for example, "sEKG"
29
+ # @option params [String] :organization_name the org's name, e.g. "New World Health"
30
+ # @option params [String] :encounter_id defaults to 0 to open a new encounter
31
+ # @option params [String] :orientation defaults to 1. 1=No Rotation, 2=Rot 90 deg, 3=Rot 180 Deg, 4=Rot 270 Deg
32
+ # @see The '.pryrc' file for an example params hash
33
+ # @return [String] xml formatted for {AllscriptsApi::OrderingMethods#save_document_image}
34
+ # on required and optional params
35
+ # rubocop:enable LineLength
36
+ def self.build_xml(file_name, command = "i", params)
37
+ Utilities::Validator.validate_params(REQUIRED_PARAMS, params)
38
+ encounter_date_time = DateTime.now.strftime("%Y-%m-%d %H:%m:%S")
39
+ builder = Nokogiri::XML::Builder.new
40
+ builder.document do
41
+ # i for insert, e for delete (entered in error), u for update
42
+ builder.item("name" => "documentCommand",
43
+ "value" => command)
44
+ # document_type_de.entrycode value GetDictionary
45
+ builder.item("name" => "documentType",
46
+ "value" => params[:document_type])
47
+ # file offset of the current chunk to upload
48
+ # not yet supported by allscripts_api gem
49
+ builder.item("name" => "offset",
50
+ "value" => "0")
51
+ # how many bytes in current chunk
52
+ builder.item("name" => "bytesRead", "value" => params[:bytes_read])
53
+ # false until the last chunk, then call SaveDocumentImage
54
+ # once more with true
55
+ builder.item("name" => "bDoneUpload",
56
+ "value" => params[:b_done_upload] || "false")
57
+ # empty for first chunk, which will then return the GUID to use for
58
+ # subsequent calls
59
+ builder.item("name" => "documentVar",
60
+ "value" => params[:document_var] || "")
61
+ # documentid only applies to updates
62
+ # not yet supported by allscripts_api gem
63
+ builder.item("name" => "documentID",
64
+ "value" => "0")
65
+ # actual file name
66
+ builder.item("name" => "vendorFileName", "value" => file_name)
67
+ # Valid encounterID from GetEncounter Set to "0" to create encounter
68
+ # based on ahsEncounterDDTM value
69
+ builder.item("name" => "ahsEncounterDTTM",
70
+ "value" => params[:encounter_time] ||
71
+ encounter_date_time)
72
+ builder.item("name" => "ahsEncounterID",
73
+ "value" => params[:encounter_id] || "0")
74
+ # EntryCode value from GetProvider
75
+ builder.item("name" => "ownerCode", "value" => params[:owner_code])
76
+ # required to ensure the proper patient is identified
77
+ builder.item("name" => "organizationName",
78
+ "value" => params[:organization_name])
79
+ # required for event table entries, audit
80
+ builder.item("name" => "patientFirstName",
81
+ "value" => params[:first_name])
82
+ builder.item("name" => "patientLastName",
83
+ "value" => params[:last_name])
84
+ # Indicate how to display in TouchWorks EHR UI:
85
+ # 1=No Rotation, 2=Rot 90 deg, 3=Rot 180 Deg, 4=Rot 270 Deg
86
+ builder.item("name" => "Orientation",
87
+ "value" => params[:orientation] || "1")
88
+ builder.item("name" => "auditCCDASummary",
89
+ "value" => "N")
90
+ end
91
+ # This is a hack to get around Nokogiri choking on
92
+ # {Nokogiri::XML::Builder.doc}
93
+ builder.to_xml.gsub("document>", "doc>")
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AllscriptsApi
4
+ module Documents
5
+ # A collection of named convenience methods that map
6
+ # to Allscripts magic actions related to documents.
7
+ # These methods are included in {AllscriptsApi::Client}
8
+ # and can be accessed from instances of that class.
9
+ module DocumentMethods
10
+ # rubocop:disable LineLength
11
+ # a wrapper around SaveDocumentImage, which saves pdfs to Allscripts
12
+ #
13
+ # @param patient_id [String] patient id
14
+ # @param document_params [String] XML produced by {AllscriptsApi::Documents::Document.build_xml}
15
+ # @param document_buffer [String] a byte array of document data for the current chunk.
16
+ # @param base_64_data [String] Alternative to using the Data parameter. If Data parameter is empty/null, Unity will check for presence of content in Base64Data. Note: In the Parameter1 XML, bytesRead is still the number of document bytes and not the base-64 string length.
17
+ # @return [Hash, MagicError] a confirmation or error
18
+ # rubocop:Enable LineLength
19
+ def save_document_image(patient_id, document_params,
20
+ document_buffer = nil, base_64_data = nil)
21
+ params =
22
+ MagicParams.format(
23
+ user_id: @allscripts_username,
24
+ patient_id: patient_id,
25
+ parameter1: document_params,
26
+ parameter6: base_64_data,
27
+ data: document_buffer
28
+ )
29
+ results = magic("SaveDocumentImage", magic_params: params)
30
+ results["savedocumentimageinfo"]
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AllscriptsApi
4
+ module Documents
5
+ # Wraps {AllscriptsApi::Documents::Document.build_xml} and
6
+ # {AllscriptsApi::Documents::DocumentMethods#save_document_image}
7
+ # to handle the 2 step document image saving process
8
+ class DocumentSender
9
+ # rubocop:disable LineLength
10
+ # The new method sets up eerything needed to run {#send_document}
11
+ #
12
+ # @example Usage Example
13
+ # document_params =
14
+ # {
15
+ # bytes_read: "0",
16
+ # b_done_upload: false,
17
+ # document_var: "",
18
+ # patient_id: 19,
19
+ # owner_code: "TW0001",
20
+ # first_name: "Allison",
21
+ # last_name: "Allscripts",
22
+ # document_type: "sEKG",
23
+ # organization_name: "New World Health"
24
+ # }
25
+ # ds = AllscriptsApi::Documents::DocumentSender.new(client, pdf, "test.pdf", document_params)
26
+ # ds.send_document
27
+ #
28
+ # @param client [AllscriptsApi::Client] pass in an authorized client
29
+ # @param document [String] the string contents of the pdf to be saved
30
+ # @param file_name [String] the name of the file to be saved, usually ending in .pdf
31
+ # @param params [Hash] a hash of params for use in saving a document
32
+ # @see {AllscriptsApi::Dpcuments::DocumentSender} for details
33
+ # @return [AllscriptsApi::Documents::DocumentSender]
34
+ # rubocop:enable LineLength
35
+ def initialize(client, document, file_name, params)
36
+ @params = params
37
+ @patient_id = @params[:patient_id]
38
+ raise MissingRequiredParamsError, "patient_id required" unless @patient_id
39
+ @client = client
40
+ @document = Base64.encode64(document)
41
+ @file_name = file_name
42
+ end
43
+
44
+ # Sends the document in 2 steps, first the doc itself, then
45
+ # a confirmation that it is done and ready to be saved.
46
+ # @return [Hash, MagicError] a confirmation or error
47
+ def send_document
48
+ @params[:b_done_upload] = "false"
49
+ first_step_xml =
50
+ Documents::Document.build_xml(@file_name, "i", @params)
51
+ results =
52
+ @client.save_document_image(@patient_id,
53
+ first_step_xml, @document)
54
+ @params[:b_done_upload] = "true"
55
+ @params[:document_var] = results[0]["documentVar"]
56
+ second_step_xml =
57
+ Documents::Document.build_xml(@file_name, "i", @params)
58
+ @client.save_document_image(@patient_id,
59
+ second_step_xml, @document)
60
+ end
61
+ end
62
+ end
63
+ end
@@ -105,12 +105,12 @@ module AllscriptsApi
105
105
  end
106
106
 
107
107
  # gets patient's demographic info, insurance, guarantor, and PCP info
108
- # Note that this method is litely to return blank data sets
108
+ # Note that this method is litely to return blank data sets
109
109
  # for invalid IDs rather than raising an error
110
110
  #
111
111
  # @param patient_id [String] patient id
112
112
  # @param mrn [String|nil] medical record number, if patient id is unknown
113
- # @parma order_id [String|nil] optionally used to get info for a secific
113
+ # @param order_id [String|nil] optionally used to get info for a secific
114
114
  # patient order
115
115
  # @return [String, AllscriptsApi::MagicError] patient demographics
116
116
  def get_patient_full(patient_id, mrn = nil, order_id = nil)
@@ -159,8 +159,7 @@ module AllscriptsApi
159
159
  #
160
160
  # @param start_date [Date] start date inclusive
161
161
  # @param end_date [Date] end date inclusive
162
- # @return [Array<Hash>, Array, MagicError] a list of scheduled appointments,
163
- # an empty array, or an error
162
+ # @return [Array<Hash>, Array, MagicError] a list of scheduled appointments, an empty array, or an error
164
163
  def get_schedule(start_date, end_date)
165
164
  params =
166
165
  MagicParams.format(
@@ -171,6 +170,15 @@ module AllscriptsApi
171
170
  results["getscheduleinfo"]
172
171
  end
173
172
 
173
+ # a wrapper around GetEncounterList
174
+ #
175
+ # @param patient_id [String] patient id
176
+ # @param encounter_type [String] encounter type to filter on from Encounter_Type_DE
177
+ # @param when_or_limit [String] filter by specified date
178
+ # @param nostradamus [String] how many days to look into the future. Defaults to 0.
179
+ # @param show_past_flag [String] show previous encounters, "Y" or "N". Defaults to Y
180
+ # @param billing_provider_user_name [String] filter by user name (if specified)
181
+ # @return [Array<Hash>, Array, MagicError] a list of encounters
174
182
  def get_encounter_list(patient_id = "", encounter_type = "",
175
183
  when_or_limit = "", nostradamus = 0,
176
184
  show_past_flag = "Y",
@@ -1,8 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AllscriptsApi
4
- # A value object wrapped around a `Nokogiri::XML::Builder` DSL that builds
5
- # properly formatted XML for `AllscriptsApi::OrderingMEthods.save_order`
4
+ # A value object wrapped around a Nokogiri::XML::Builder DSL that builds
5
+ # properly formatted XML for {AllscriptsApi::OrderingMethods#save_order}
6
+ # @see https://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/Builder
6
7
  class Order
7
8
  # Builder method for returning XML
8
9
  #
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AllscriptsApi
4
+ module Utilities
5
+ # Simple module that provides `validate_params`
6
+ # which raises {MissingRequiredParamsError} if
7
+ # if required params are missing.
8
+ module Validator
9
+ # Raises and error if required params are missing
10
+ # @param required_params [Array<Symbol>]
11
+ # @param params [Hash] params to be validated
12
+ def self.validate_params(required_params, params)
13
+ # TODO: describe why this works
14
+ missing_keys = required_params - params.keys
15
+ unless missing_keys.empty?
16
+ raise MissingRequiredParamsError,
17
+ "The key(s) #{missing_keys} is/are required for this method."
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module AllscriptsApi
4
4
  # gem version declaration
5
- VERSION = "0.4.0".freeze
5
+ VERSION = "0.5.0".freeze
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: allscripts_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chase
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-05-04 00:00:00.000000000 Z
11
+ date: 2018-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -247,10 +247,15 @@ files:
247
247
  - lib/allscripts_api.rb
248
248
  - lib/allscripts_api/client.rb
249
249
  - lib/allscripts_api/configuration.rb
250
+ - lib/allscripts_api/documents.rb
251
+ - lib/allscripts_api/documents/document.rb
252
+ - lib/allscripts_api/documents/document_methods.rb
253
+ - lib/allscripts_api/documents/document_sender.rb
250
254
  - lib/allscripts_api/magic_params.rb
251
255
  - lib/allscripts_api/named_magic_methods.rb
252
256
  - lib/allscripts_api/order.rb
253
257
  - lib/allscripts_api/ordering_methods.rb
258
+ - lib/allscripts_api/utilities/validator.rb
254
259
  - lib/allscripts_api/version.rb
255
260
  homepage: https://github.com/Avhana/allscripts_api
256
261
  licenses: []