healthcare_phony 0.7s.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/gem-push.yml +42 -42
  3. data/.github/workflows/ruby.yml +33 -33
  4. data/.gitignore +63 -63
  5. data/.rdoc_options +23 -23
  6. data/.rubocop.yml +10 -10
  7. data/CODE_OF_CONDUCT.md +84 -84
  8. data/Gemfile +8 -8
  9. data/LICENSE.txt +21 -21
  10. data/README.md +365 -365
  11. data/Rakefile +12 -12
  12. data/VERSION +1 -1
  13. data/examples/bigger_csv_example.erb +3 -3
  14. data/examples/phony_adt_sender.rb +111 -111
  15. data/examples/phony_adt_sender.yml +11 -11
  16. data/examples/phony_csv.yml +4 -4
  17. data/healthcare_phony.gemspec +36 -36
  18. data/lib/healthcare_phony.rb +138 -139
  19. data/lib/healthcare_phony/address.rb +89 -89
  20. data/lib/healthcare_phony/assigning_authority.rb +6 -6
  21. data/lib/healthcare_phony/cell_phone_number.rb +20 -20
  22. data/lib/healthcare_phony/data_files/address_type.yml +7 -7
  23. data/lib/healthcare_phony/data_files/adt_event_types.yml +59 -59
  24. data/lib/healthcare_phony/data_files/degree.yml +9 -9
  25. data/lib/healthcare_phony/data_files/discharge_disposition.yml +15 -15
  26. data/lib/healthcare_phony/data_files/ethnic_group.yml +9 -9
  27. data/lib/healthcare_phony/data_files/hl7_message_types.yml +4 -4
  28. data/lib/healthcare_phony/data_files/language.yml +7 -7
  29. data/lib/healthcare_phony/data_files/marital_status.yml +49 -49
  30. data/lib/healthcare_phony/data_files/mdm_event_types.yml +12 -12
  31. data/lib/healthcare_phony/data_files/oru_event_types.yml +2 -2
  32. data/lib/healthcare_phony/data_files/race.yml +13 -13
  33. data/lib/healthcare_phony/data_files/religion.yml +250 -250
  34. data/lib/healthcare_phony/data_files/tele_equipment_type.yml +10 -10
  35. data/lib/healthcare_phony/data_files/tele_use_code.yml +9 -9
  36. data/lib/healthcare_phony/diagnosis.rb +12 -12
  37. data/lib/healthcare_phony/doctor.rb +26 -26
  38. data/lib/healthcare_phony/email.rb +25 -25
  39. data/lib/healthcare_phony/ethnic_group.rb +34 -34
  40. data/lib/healthcare_phony/gender.rb +22 -22
  41. data/lib/healthcare_phony/helper.rb +72 -72
  42. data/lib/healthcare_phony/hl7_message.rb +159 -159
  43. data/lib/healthcare_phony/home_phone_number.rb +20 -20
  44. data/lib/healthcare_phony/identifier.rb +23 -23
  45. data/lib/healthcare_phony/insurance.rb +6 -6
  46. data/lib/healthcare_phony/language.rb +30 -30
  47. data/lib/healthcare_phony/marital_status.rb +31 -31
  48. data/lib/healthcare_phony/patient.rb +114 -114
  49. data/lib/healthcare_phony/patient_visit.rb +97 -97
  50. data/lib/healthcare_phony/person_name.rb +104 -104
  51. data/lib/healthcare_phony/phone_number.rb +85 -85
  52. data/lib/healthcare_phony/procedure.rb +6 -6
  53. data/lib/healthcare_phony/race.rb +31 -31
  54. data/lib/healthcare_phony/religion.rb +32 -32
  55. data/lib/healthcare_phony/templates/csv_example.erb +3 -3
  56. data/lib/healthcare_phony/version.rb +5 -5
  57. data/lib/healthcare_phony/visit_admission.rb +53 -53
  58. data/lib/healthcare_phony/visit_discharge.rb +62 -62
  59. data/lib/healthcare_phony/visit_doctors.rb +19 -19
  60. data/lib/healthcare_phony/visit_location.rb +106 -106
  61. data/lib/healthcare_phony/visit_type.rb +8 -8
  62. data/lib/healthcare_phony/work_phone_number.rb +20 -20
  63. metadata +5 -5
@@ -1,10 +1,10 @@
1
- ---
2
- - BP
3
- - CP
4
- - FX
5
- - Internet
6
- - MD
7
- - PH
8
- - TDD
9
- - TTY
10
- - X.400
1
+ ---
2
+ - BP
3
+ - CP
4
+ - FX
5
+ - Internet
6
+ - MD
7
+ - PH
8
+ - TDD
9
+ - TTY
10
+ - X.400
@@ -1,9 +1,9 @@
1
- ---
2
- - ASN
3
- - BPN
4
- - EMR
5
- - NET
6
- - ORN
7
- - PRN
8
- - VHN
9
- - WPN
1
+ ---
2
+ - ASN
3
+ - BPN
4
+ - EMR
5
+ - NET
6
+ - ORN
7
+ - PRN
8
+ - VHN
9
+ - WPN
@@ -1,12 +1,12 @@
1
- # frozen_string_literal: true
2
-
3
- module HealthcarePhony
4
- class Diagnosis
5
- attr_accessor :coding_method,
6
- :code,
7
- :description,
8
- :coding_system,
9
- :date_time,
10
- :type
11
- end
12
- end
1
+ # frozen_string_literal: true
2
+
3
+ module HealthcarePhony
4
+ class Diagnosis
5
+ attr_accessor :coding_method,
6
+ :code,
7
+ :description,
8
+ :coding_system,
9
+ :date_time,
10
+ :type
11
+ end
12
+ end
@@ -1,26 +1,26 @@
1
- # frozen_string_literal: true
2
-
3
- module HealthcarePhony
4
- # Public: Generates a fake Doctor
5
- class Doctor
6
- # Public: Gets/Sets the String identifier of the doctor.
7
- attr_accessor :identifier
8
- # Public: Gets/Sets the PersonName name of the doctor.
9
- attr_accessor :name
10
-
11
- # Public: Initialize a Doctor. Pass in hash of different parameters, currently this includes:
12
- #
13
- # identifier - Allows you to specify an identifier for this Doctor instead of having it randomly generated.
14
- def initialize(init_args = {})
15
- @identifier = if !init_args[:identifier].nil?
16
- init_args[:identifier]
17
- else
18
- pre_check_npi = /1[0-9]{8}/.random_example.to_i
19
- (pre_check_npi.to_s + Helper.get_npi_check_digit(pre_check_npi).to_s).to_i
20
- end
21
-
22
- init_args[:degree] = 'MD,DO'
23
- @name = PersonName.new(init_args)
24
- end
25
- end
26
- end
1
+ # frozen_string_literal: true
2
+
3
+ module HealthcarePhony
4
+ # Public: Generates a fake Doctor
5
+ class Doctor
6
+ # Public: Gets/Sets the String identifier of the doctor.
7
+ attr_accessor :identifier
8
+ # Public: Gets/Sets the PersonName name of the doctor.
9
+ attr_accessor :name
10
+
11
+ # Public: Initialize a Doctor. Pass in hash of different parameters, currently this includes:
12
+ #
13
+ # identifier - Allows you to specify an identifier for this Doctor instead of having it randomly generated.
14
+ def initialize(init_args = {})
15
+ @identifier = if !init_args[:identifier].nil?
16
+ init_args[:identifier]
17
+ else
18
+ pre_check_npi = /1[0-9]{8}/.random_example.to_i
19
+ (pre_check_npi.to_s + Helper.get_npi_check_digit(pre_check_npi).to_s).to_i
20
+ end
21
+
22
+ init_args[:degree] = 'MD,DO'
23
+ @name = PersonName.new(init_args)
24
+ end
25
+ end
26
+ end
@@ -1,25 +1,25 @@
1
- # frozen_string_literal: true
2
-
3
- module HealthcarePhony
4
- # Public: Generate a fake email address
5
- class Email
6
- attr_accessor :email_address,
7
- :use_code,
8
- :equipment_type
9
-
10
- def initialize(init_args = {})
11
- @set_blank = !init_args[:blank].nil? && Helper.random_with_blank('X', init_args[:blank]) == ''
12
- @email_address = Faker::Internet.email
13
- @email_address = '' unless @set_blank == false
14
- @use_code = @email_address == '' ? '' : 'NET'
15
- @use_code = '' unless @set_blank == false
16
- @equipment_type = @email_address == '' ? '' : 'X.400'
17
- @equipment_type = '' unless @set_blank == false
18
- end
19
-
20
- private
21
-
22
- # Private: Boolean set during initialization if Address components should be set to blank.
23
- attr_accessor :set_blank
24
- end
25
- end
1
+ # frozen_string_literal: true
2
+
3
+ module HealthcarePhony
4
+ # Public: Generate a fake email address
5
+ class Email
6
+ attr_accessor :email_address,
7
+ :use_code,
8
+ :equipment_type
9
+
10
+ def initialize(init_args = {})
11
+ @set_blank = !init_args[:blank].nil? && Helper.random_with_blank('X', init_args[:blank]) == ''
12
+ @email_address = Faker::Internet.email
13
+ @email_address = '' unless @set_blank == false
14
+ @use_code = @email_address == '' ? '' : 'NET'
15
+ @use_code = '' unless @set_blank == false
16
+ @equipment_type = @email_address == '' ? '' : 'X.400'
17
+ @equipment_type = '' unless @set_blank == false
18
+ end
19
+
20
+ private
21
+
22
+ # Private: Boolean set during initialization if Address components should be set to blank.
23
+ attr_accessor :set_blank
24
+ end
25
+ end
@@ -1,34 +1,34 @@
1
- # frozen_string_literal: true
2
-
3
- module HealthcarePhony
4
- # Public: Randomly generates an ethnic group
5
- class EthnicGroup
6
- attr_accessor :code,
7
- :description,
8
- :coding_system
9
-
10
- # Public: Initializes an EthnicGroup. Pass in hash of different parameters, currently this includes:
11
- # blank - An integer representing the % of times EthnicGroup components should be blank.
12
- # ethnic_group_data_file - YAML file containing ethnic group information to randomly choose from if different options than
13
- # those that come with gem are desired. See {ethnic_group.yml}[https://github.com/austinmoody/healthcare_phony/blob/main/lib/healthcare_phony/data_files/ethnic_group.yml]
14
- # for default values.
15
- def initialize(init_args = {})
16
- @set_blank = !init_args[:blank].nil? && Helper.random_with_blank('X', init_args[:blank]) == ''
17
- data_file = if !init_args[:ethnic_group_data_file].nil?
18
- init_args[:ethnic_group_data_file]
19
- else
20
- "#{::File.expand_path(::File.join("..", "data_files"), __FILE__)}/ethnic_group.yml"
21
- end
22
- e_array = Psych.load_file(data_file)
23
- random_ethnic = e_array.nil? ? '' : e_array.sample
24
- @code = @set_blank == true ? '' : random_ethnic[:code]
25
- @description = @set_blank == true ? '' : random_ethnic[:description]
26
- @coding_system = @set_blank == true ? '' : random_ethnic[:coding_system]
27
- end
28
-
29
- private
30
-
31
- # Private: Boolean set during initialization if Address components should be set to blank.
32
- attr_accessor :set_blank
33
- end
34
- end
1
+ # frozen_string_literal: true
2
+
3
+ module HealthcarePhony
4
+ # Public: Randomly generates an ethnic group
5
+ class EthnicGroup
6
+ attr_accessor :code,
7
+ :description,
8
+ :coding_system
9
+
10
+ # Public: Initializes an EthnicGroup. Pass in hash of different parameters, currently this includes:
11
+ # blank - An integer representing the % of times EthnicGroup components should be blank.
12
+ # ethnic_group_data_file - YAML file containing ethnic group information to randomly choose from if different options than
13
+ # those that come with gem are desired. See {ethnic_group.yml}[https://github.com/austinmoody/healthcare_phony/blob/main/lib/healthcare_phony/data_files/ethnic_group.yml]
14
+ # for default values.
15
+ def initialize(init_args = {})
16
+ @set_blank = !init_args[:blank].nil? && Helper.random_with_blank('X', init_args[:blank]) == ''
17
+ data_file = if !init_args[:ethnic_group_data_file].nil?
18
+ init_args[:ethnic_group_data_file]
19
+ else
20
+ "#{::File.expand_path(::File.join("..", "data_files"), __FILE__)}/ethnic_group.yml"
21
+ end
22
+ e_array = Psych.load_file(data_file)
23
+ random_ethnic = e_array.nil? ? '' : e_array.sample
24
+ @code = @set_blank == true ? '' : random_ethnic[:code]
25
+ @description = @set_blank == true ? '' : random_ethnic[:description]
26
+ @coding_system = @set_blank == true ? '' : random_ethnic[:coding_system]
27
+ end
28
+
29
+ private
30
+
31
+ # Private: Boolean set during initialization if Address components should be set to blank.
32
+ attr_accessor :set_blank
33
+ end
34
+ end
@@ -1,22 +1,22 @@
1
- # frozen_string_literal: true
2
-
3
- module HealthcarePhony
4
- # Public: Randomly generates a Gender.
5
- class Gender
6
- attr_accessor :code,
7
- :description
8
-
9
- # Public: Initializes a Gender. Pass in hash of different parameters, currently this includes:
10
- # blank - An integer representing the % of times Address components should be blank.
11
- def initialize(init_args = {})
12
- @description = %w[Female Male Unknown].sample
13
-
14
- @description = if !init_args[:blank].nil?
15
- Helper.random_with_blank(@description, init_args[:blank])
16
- else
17
- @description
18
- end
19
- @code = @description == '' ? '' : @description[0]
20
- end
21
- end
22
- end
1
+ # frozen_string_literal: true
2
+
3
+ module HealthcarePhony
4
+ # Public: Randomly generates a Gender.
5
+ class Gender
6
+ attr_accessor :code,
7
+ :description
8
+
9
+ # Public: Initializes a Gender. Pass in hash of different parameters, currently this includes:
10
+ # blank - An integer representing the % of times Address components should be blank.
11
+ def initialize(init_args = {})
12
+ @description = %w[Female Male Unknown].sample
13
+
14
+ @description = if !init_args[:blank].nil?
15
+ Helper.random_with_blank(@description, init_args[:blank])
16
+ else
17
+ @description
18
+ end
19
+ @code = @description == '' ? '' : @description[0]
20
+ end
21
+ end
22
+ end
@@ -1,72 +1,72 @@
1
- # frozen_string_literal: true
2
-
3
- module HealthcarePhony
4
- class Helper
5
- class << self
6
- def random_with_blank(non_blank_value, blank_percentage)
7
- b_array = [[non_blank_value, (100 - blank_percentage)], ['', blank_percentage]]
8
- b_array.max_by { |_, weight| rand**100.fdiv(weight) }[0]
9
- end
10
-
11
- def get_array(input_argument)
12
- return_array = []
13
-
14
- if !input_argument.nil? && input_argument.instance_of?(Array)
15
- return_array = input_argument
16
- elsif !input_argument.nil? && input_argument.instance_of?(String)
17
- return_array = input_argument.split(',')
18
- end
19
-
20
- return_array
21
- end
22
-
23
- def npi_step_one(input)
24
- # Step 1: Double the value of alternate digits, beginning with the rightmost digit.
25
- npi = []
26
- input.to_s.split('').reverse.each_with_index do |n, i|
27
- npi.push((n.to_i * 2).to_s) if (i + 1).odd?
28
- end
29
- npi.reverse!
30
- total = 0
31
- npi.join('').split('').each do |x|
32
- total += x.to_i
33
- end
34
- total
35
- end
36
-
37
- def npi_step_two(input, step_one_total)
38
- # Step 2: Add constant 24, to account for the 80840 prefix that would be present on a card issuer identifier,
39
- # plus the individual digits of products of doubling, plus unaffected digits.
40
- (24 + step_one_total + double_alternate_digits(input))
41
- end
42
-
43
- def next_number_end_with_zero(input)
44
- input += 1 while input.to_s[-1] != '0'
45
- input
46
- end
47
-
48
- def double_alternate_digits(npi)
49
- a_total = 0
50
- counter = 1
51
- npi.to_s.split('').each do |n|
52
- a_total += n.to_i if counter.even?
53
- counter += 1
54
- end
55
- a_total
56
- end
57
-
58
- def get_npi_check_digit(npi)
59
- step_one = npi_step_one(npi)
60
-
61
- # Add totals from above two steps + 24
62
- # c_total = 24 + a_total + b_total
63
- step_two = npi_step_two(npi, step_one)
64
-
65
- next_high = next_number_end_with_zero(step_two)
66
-
67
- # Step 3: Subtract from next higher number ending in zero.
68
- (next_high - step_two)
69
- end
70
- end
71
- end
72
- end
1
+ # frozen_string_literal: true
2
+
3
+ module HealthcarePhony
4
+ class Helper
5
+ class << self
6
+ def random_with_blank(non_blank_value, blank_percentage)
7
+ b_array = [[non_blank_value, (100 - blank_percentage)], ['', blank_percentage]]
8
+ b_array.max_by { |_, weight| rand**100.fdiv(weight) }[0]
9
+ end
10
+
11
+ def get_array(input_argument)
12
+ return_array = []
13
+
14
+ if !input_argument.nil? && input_argument.instance_of?(Array)
15
+ return_array = input_argument
16
+ elsif !input_argument.nil? && input_argument.instance_of?(String)
17
+ return_array = input_argument.split(',')
18
+ end
19
+
20
+ return_array
21
+ end
22
+
23
+ def npi_step_one(input)
24
+ # Step 1: Double the value of alternate digits, beginning with the rightmost digit.
25
+ npi = []
26
+ input.to_s.split('').reverse.each_with_index do |n, i|
27
+ npi.push((n.to_i * 2).to_s) if (i + 1).odd?
28
+ end
29
+ npi.reverse!
30
+ total = 0
31
+ npi.join('').split('').each do |x|
32
+ total += x.to_i
33
+ end
34
+ total
35
+ end
36
+
37
+ def npi_step_two(input, step_one_total)
38
+ # Step 2: Add constant 24, to account for the 80840 prefix that would be present on a card issuer identifier,
39
+ # plus the individual digits of products of doubling, plus unaffected digits.
40
+ (24 + step_one_total + double_alternate_digits(input))
41
+ end
42
+
43
+ def next_number_end_with_zero(input)
44
+ input += 1 while input.to_s[-1] != '0'
45
+ input
46
+ end
47
+
48
+ def double_alternate_digits(npi)
49
+ a_total = 0
50
+ counter = 1
51
+ npi.to_s.split('').each do |n|
52
+ a_total += n.to_i if counter.even?
53
+ counter += 1
54
+ end
55
+ a_total
56
+ end
57
+
58
+ def get_npi_check_digit(npi)
59
+ step_one = npi_step_one(npi)
60
+
61
+ # Add totals from above two steps + 24
62
+ # c_total = 24 + a_total + b_total
63
+ step_two = npi_step_two(npi, step_one)
64
+
65
+ next_high = next_number_end_with_zero(step_two)
66
+
67
+ # Step 3: Subtract from next higher number ending in zero.
68
+ (next_high - step_two)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -1,159 +1,159 @@
1
- # frozen_string_literal: true
2
-
3
- module HealthcarePhony
4
- # Public: Generates information needed to build an HL7v2 message
5
- class Hl7Message
6
- attr_accessor :message_type,
7
- :trigger_event,
8
- :message_control_id,
9
- :version,
10
- :sending_application,
11
- :sending_facility,
12
- :receiving_application,
13
- :receiving_facility,
14
- :message_datetime,
15
- :processing_id
16
-
17
- # Public: Initializes an Address. Pass in hash of different parameters, currently this includes:
18
- # message_version - HL7v2 version (MSH.12)
19
- # message_processing_id - Typically P or T (MSH.11)
20
- # message_types - Array of Message Types (MSH.9.1) to randomly choose from. Specified as comma separated String or
21
- # Ruby array.
22
- # message_type_file - Location of file containing Message Types (MSH.9.1). If not specified then included
23
- # {hl7_message_types.yml}[https://github.com/austinmoody/healthcare_phony/blob/main/lib/healthcare_phony/data_files/hl7_message_types.yml] file will be used.
24
- # message_events - Generic array of Trigger Events (MSH.9.2) to randomly choose from. Specified as command
25
- # separated String or Ruby array.
26
- # adt_events - Array of ADT Trigger Events (MSH.9.2) to randomly choose from. Used (if specified) if the Message
27
- # type for the message is ADT. ADT events from {adt_event_types.yml}[https://github.com/austinmoody/healthcare_phony/blob/main/lib/healthcare_phony/data_files/adt_event_types.yml]
28
- # will be used by default.
29
- # oru_events - Array of ORU Trigger Events (MSH.9.2) to randomly choose from. Used (if specified) if the Message
30
- # type for the message is ORU. ORU events from {oru_event_types.yml}[https://github.com/austinmoody/healthcare_phony/blob/main/lib/healthcare_phony/data_files/adt_event_types.yml]
31
- # will be used by default.
32
- # mdm_events - Array of MDM Trigger Events (MSH.9.2) to randomly choose from. Used (if speciifed) if the Message
33
- # type for the message is MDM. MDM events from {mdm_event_types.yml}[https://github.com/austinmoody/healthcare_phony/blob/main/lib/healthcare_phony/data_files/adt_event_types.yml]
34
- # will be used by default.
35
- # message_control_id_pattern - Regex pattern used to randomly generate MSH.10 values. Default is PHONY\d{10} which will
36
- # generate a value like: PHONY6850295805
37
- # message_sending_facility - Array of Sending Facilities (MSH.4) to randomly choose from. Specified as comma separated
38
- # String or Ruby Array.
39
- # message_sending_application - Array of Sending Applications (MSH.3) to randomly choose from. Specified as comma
40
- # separated String or Ruby Array.
41
- # message_receiving_application - Array of Receiving Applications (MSH.5) to randomly choose from. Specified as comma
42
- # separated String or Ruby Array.
43
- # message_receiving_facility - Array of Receiving Facilities (MSH.6) to randomly choose from. Specified as comma separated
44
- # String or Ruby Array.
45
- def initialize(init_args)
46
- define_message_type(init_args)
47
- define_trigger_event(init_args)
48
- define_control_id(init_args)
49
- @version = init_args[:message_version].nil? ? '2.5.1' : init_args[:message_version]
50
- define_sending_facility(init_args)
51
- define_sending_application(init_args)
52
- define_receiving_application(init_args)
53
- define_receiving_facility(init_args)
54
-
55
- # Potential use case to allow you to provide begin/end date?
56
- @message_datetime = Time.now
57
-
58
- @processing_id = init_args[:message_processing_id].nil? ? 'P' : init_args[:message_processing_id]
59
- end
60
-
61
- private
62
-
63
- def define_message_type(init_args = {})
64
- file_name = "#{::File.expand_path(::File.join("..", "data_files"), __FILE__)}/hl7_message_types.yml"
65
- file_name = init_args[:message_type_file] unless init_args[:message_type_file].nil?
66
- hl7_message_types = if !init_args[:message_types].nil?
67
- Helper.get_array(init_args[:message_types])
68
- else
69
- Psych.load_file(file_name)
70
- end
71
- @message_type = hl7_message_types.nil? ? '' : hl7_message_types.sample
72
- end
73
-
74
- def define_trigger_event(init_args = {})
75
- @trigger_event = Helper.get_array(init_args[:message_events]).sample
76
- return unless @trigger_event.nil?
77
-
78
- case @message_type
79
- when 'ADT'
80
- @trigger_event = define_adt_trigger_event(init_args)
81
- when 'ORU'
82
- @trigger_event = define_oru_trigger_event(init_args)
83
- when 'MDM'
84
- @trigger_event = define_mdm_trigger_event(init_args)
85
- end
86
- end
87
-
88
- def define_adt_trigger_event(init_args = {})
89
- event_types = get_adt_events(init_args)
90
- event_types&.sample
91
- end
92
-
93
- def define_oru_trigger_event(init_args = {})
94
- event_types = get_oru_events(init_args)
95
- event_types&.sample
96
- end
97
-
98
- def define_mdm_trigger_event(init_args = {})
99
- event_types = get_mdm_events(init_args)
100
- event_types&.sample
101
- end
102
-
103
- def get_adt_events(init_args = {})
104
- file_name = "#{::File.expand_path(::File.join("..", "data_files"), __FILE__)}/adt_event_types.yml"
105
- if init_args[:adt_events].nil?
106
- Psych.load_file(file_name)
107
- else
108
- Helper.get_array(init_args[:adt_events])
109
- end
110
- end
111
-
112
- def get_oru_events(init_args = {})
113
- file_name = "#{::File.expand_path(::File.join("..", "data_files"), __FILE__)}/oru_event_types.yml"
114
- if init_args[:oru_events].nil?
115
- Psych.load_file(file_name)
116
- else
117
- Helper.get_array(init_args[:oru_events])
118
- end
119
- end
120
-
121
- def get_mdm_events(init_args = {})
122
- file_name = "#{::File.expand_path(::File.join("..", "data_files"), __FILE__)}/mdm_event_types.yml"
123
- if init_args[:mdm_events].nil?
124
- Psych.load_file(file_name)
125
- else
126
- Helper.get_array(init_args[:mdm_events])
127
- end
128
- end
129
-
130
- def define_control_id(init_args = {})
131
- control_id_pattern = if init_args[:message_control_id_pattern].nil?
132
- 'PHONY\d{10}'
133
- else
134
- init_args[:message_control_id_pattern]
135
- end
136
- @message_control_id = Regexp.new(control_id_pattern).random_example
137
- end
138
-
139
- def define_sending_facility(init_args = {})
140
- sf_choices = Helper.get_array(init_args[:message_sending_facility])
141
- @sending_facility = !sf_choices.empty? ? sf_choices.sample : ''
142
- end
143
-
144
- def define_sending_application(init_args = {})
145
- sa_choices = Helper.get_array(init_args[:message_sending_application])
146
- @sending_application = !sa_choices.empty? ? sa_choices.sample : ''
147
- end
148
-
149
- def define_receiving_application(init_args = {})
150
- ra_choices = Helper.get_array(init_args[:message_receiving_application])
151
- @receiving_application = !ra_choices.empty? ? ra_choices.sample : ''
152
- end
153
-
154
- def define_receiving_facility(init_args = {})
155
- rf_choices = Helper.get_array(init_args[:message_receiving_facility])
156
- @receiving_facility = !rf_choices.empty? ? rf_choices.sample : ''
157
- end
158
- end
159
- end
1
+ # frozen_string_literal: true
2
+
3
+ module HealthcarePhony
4
+ # Public: Generates information needed to build an HL7v2 message
5
+ class Hl7Message
6
+ attr_accessor :message_type,
7
+ :trigger_event,
8
+ :message_control_id,
9
+ :version,
10
+ :sending_application,
11
+ :sending_facility,
12
+ :receiving_application,
13
+ :receiving_facility,
14
+ :message_datetime,
15
+ :processing_id
16
+
17
+ # Public: Initializes an Address. Pass in hash of different parameters, currently this includes:
18
+ # message_version - HL7v2 version (MSH.12)
19
+ # message_processing_id - Typically P or T (MSH.11)
20
+ # message_types - Array of Message Types (MSH.9.1) to randomly choose from. Specified as comma separated String or
21
+ # Ruby array.
22
+ # message_type_file - Location of file containing Message Types (MSH.9.1). If not specified then included
23
+ # {hl7_message_types.yml}[https://github.com/austinmoody/healthcare_phony/blob/main/lib/healthcare_phony/data_files/hl7_message_types.yml] file will be used.
24
+ # message_events - Generic array of Trigger Events (MSH.9.2) to randomly choose from. Specified as command
25
+ # separated String or Ruby array.
26
+ # adt_events - Array of ADT Trigger Events (MSH.9.2) to randomly choose from. Used (if specified) if the Message
27
+ # type for the message is ADT. ADT events from {adt_event_types.yml}[https://github.com/austinmoody/healthcare_phony/blob/main/lib/healthcare_phony/data_files/adt_event_types.yml]
28
+ # will be used by default.
29
+ # oru_events - Array of ORU Trigger Events (MSH.9.2) to randomly choose from. Used (if specified) if the Message
30
+ # type for the message is ORU. ORU events from {oru_event_types.yml}[https://github.com/austinmoody/healthcare_phony/blob/main/lib/healthcare_phony/data_files/adt_event_types.yml]
31
+ # will be used by default.
32
+ # mdm_events - Array of MDM Trigger Events (MSH.9.2) to randomly choose from. Used (if speciifed) if the Message
33
+ # type for the message is MDM. MDM events from {mdm_event_types.yml}[https://github.com/austinmoody/healthcare_phony/blob/main/lib/healthcare_phony/data_files/adt_event_types.yml]
34
+ # will be used by default.
35
+ # message_control_id_pattern - Regex pattern used to randomly generate MSH.10 values. Default is PHONY\d{10} which will
36
+ # generate a value like: PHONY6850295805
37
+ # message_sending_facility - Array of Sending Facilities (MSH.4) to randomly choose from. Specified as comma separated
38
+ # String or Ruby Array.
39
+ # message_sending_application - Array of Sending Applications (MSH.3) to randomly choose from. Specified as comma
40
+ # separated String or Ruby Array.
41
+ # message_receiving_application - Array of Receiving Applications (MSH.5) to randomly choose from. Specified as comma
42
+ # separated String or Ruby Array.
43
+ # message_receiving_facility - Array of Receiving Facilities (MSH.6) to randomly choose from. Specified as comma separated
44
+ # String or Ruby Array.
45
+ def initialize(init_args)
46
+ define_message_type(init_args)
47
+ define_trigger_event(init_args)
48
+ define_control_id(init_args)
49
+ @version = init_args[:message_version].nil? ? '2.5.1' : init_args[:message_version]
50
+ define_sending_facility(init_args)
51
+ define_sending_application(init_args)
52
+ define_receiving_application(init_args)
53
+ define_receiving_facility(init_args)
54
+
55
+ # Potential use case to allow you to provide begin/end date?
56
+ @message_datetime = Time.now
57
+
58
+ @processing_id = init_args[:message_processing_id].nil? ? 'P' : init_args[:message_processing_id]
59
+ end
60
+
61
+ private
62
+
63
+ def define_message_type(init_args = {})
64
+ file_name = "#{::File.expand_path(::File.join("..", "data_files"), __FILE__)}/hl7_message_types.yml"
65
+ file_name = init_args[:message_type_file] unless init_args[:message_type_file].nil?
66
+ hl7_message_types = if !init_args[:message_types].nil?
67
+ Helper.get_array(init_args[:message_types])
68
+ else
69
+ Psych.load_file(file_name)
70
+ end
71
+ @message_type = hl7_message_types.nil? ? '' : hl7_message_types.sample
72
+ end
73
+
74
+ def define_trigger_event(init_args = {})
75
+ @trigger_event = Helper.get_array(init_args[:message_events]).sample
76
+ return unless @trigger_event.nil?
77
+
78
+ case @message_type
79
+ when 'ADT'
80
+ @trigger_event = define_adt_trigger_event(init_args)
81
+ when 'ORU'
82
+ @trigger_event = define_oru_trigger_event(init_args)
83
+ when 'MDM'
84
+ @trigger_event = define_mdm_trigger_event(init_args)
85
+ end
86
+ end
87
+
88
+ def define_adt_trigger_event(init_args = {})
89
+ event_types = get_adt_events(init_args)
90
+ event_types&.sample
91
+ end
92
+
93
+ def define_oru_trigger_event(init_args = {})
94
+ event_types = get_oru_events(init_args)
95
+ event_types&.sample
96
+ end
97
+
98
+ def define_mdm_trigger_event(init_args = {})
99
+ event_types = get_mdm_events(init_args)
100
+ event_types&.sample
101
+ end
102
+
103
+ def get_adt_events(init_args = {})
104
+ file_name = "#{::File.expand_path(::File.join("..", "data_files"), __FILE__)}/adt_event_types.yml"
105
+ if init_args[:adt_events].nil?
106
+ Psych.load_file(file_name)
107
+ else
108
+ Helper.get_array(init_args[:adt_events])
109
+ end
110
+ end
111
+
112
+ def get_oru_events(init_args = {})
113
+ file_name = "#{::File.expand_path(::File.join("..", "data_files"), __FILE__)}/oru_event_types.yml"
114
+ if init_args[:oru_events].nil?
115
+ Psych.load_file(file_name)
116
+ else
117
+ Helper.get_array(init_args[:oru_events])
118
+ end
119
+ end
120
+
121
+ def get_mdm_events(init_args = {})
122
+ file_name = "#{::File.expand_path(::File.join("..", "data_files"), __FILE__)}/mdm_event_types.yml"
123
+ if init_args[:mdm_events].nil?
124
+ Psych.load_file(file_name)
125
+ else
126
+ Helper.get_array(init_args[:mdm_events])
127
+ end
128
+ end
129
+
130
+ def define_control_id(init_args = {})
131
+ control_id_pattern = if init_args[:message_control_id_pattern].nil?
132
+ 'PHONY\d{10}'
133
+ else
134
+ init_args[:message_control_id_pattern]
135
+ end
136
+ @message_control_id = Regexp.new(control_id_pattern).random_example
137
+ end
138
+
139
+ def define_sending_facility(init_args = {})
140
+ sf_choices = Helper.get_array(init_args[:message_sending_facility])
141
+ @sending_facility = !sf_choices.empty? ? sf_choices.sample : ''
142
+ end
143
+
144
+ def define_sending_application(init_args = {})
145
+ sa_choices = Helper.get_array(init_args[:message_sending_application])
146
+ @sending_application = !sa_choices.empty? ? sa_choices.sample : ''
147
+ end
148
+
149
+ def define_receiving_application(init_args = {})
150
+ ra_choices = Helper.get_array(init_args[:message_receiving_application])
151
+ @receiving_application = !ra_choices.empty? ? ra_choices.sample : ''
152
+ end
153
+
154
+ def define_receiving_facility(init_args = {})
155
+ rf_choices = Helper.get_array(init_args[:message_receiving_facility])
156
+ @receiving_facility = !rf_choices.empty? ? rf_choices.sample : ''
157
+ end
158
+ end
159
+ end