allscripts_api 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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: []