healthcare_phony 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitattributes +1 -0
- data/.github/workflows/gem-push.yml +42 -0
- data/.github/workflows/ruby.yml +33 -0
- data/.gitignore +64 -0
- data/.rdoc_options +23 -0
- data/.rubocop.yml +10 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +21 -0
- data/README.md +285 -0
- data/Rakefile +12 -0
- data/VERSION +1 -0
- data/healthcare_phony.gemspec +36 -0
- data/lib/healthcare_phony.rb +88 -0
- data/lib/healthcare_phony/address.rb +89 -0
- data/lib/healthcare_phony/assigning_authority.rb +6 -0
- data/lib/healthcare_phony/cell_phone_number.rb +20 -0
- data/lib/healthcare_phony/data_files/address_type.yml +7 -0
- data/lib/healthcare_phony/data_files/adt_event_types.yml +59 -0
- data/lib/healthcare_phony/data_files/degree.yml +9 -0
- data/lib/healthcare_phony/data_files/discharge_disposition.yml +15 -0
- data/lib/healthcare_phony/data_files/ethnic_group.yml +10 -0
- data/lib/healthcare_phony/data_files/hl7_message_types.yml +4 -0
- data/lib/healthcare_phony/data_files/language.yml +7 -0
- data/lib/healthcare_phony/data_files/marital_status.yml +49 -0
- data/lib/healthcare_phony/data_files/mdm_event_types.yml +12 -0
- data/lib/healthcare_phony/data_files/oru_event_types.yml +2 -0
- data/lib/healthcare_phony/data_files/race.yml +13 -0
- data/lib/healthcare_phony/data_files/religion.yml +250 -0
- data/lib/healthcare_phony/data_files/tele_equipment_type.yml +10 -0
- data/lib/healthcare_phony/data_files/tele_use_code.yml +9 -0
- data/lib/healthcare_phony/diagnosis.rb +12 -0
- data/lib/healthcare_phony/doctor.rb +25 -0
- data/lib/healthcare_phony/email.rb +25 -0
- data/lib/healthcare_phony/ethnic_group.rb +34 -0
- data/lib/healthcare_phony/gender.rb +22 -0
- data/lib/healthcare_phony/helper.rb +72 -0
- data/lib/healthcare_phony/hl7_message.rb +136 -0
- data/lib/healthcare_phony/home_phone_number.rb +20 -0
- data/lib/healthcare_phony/identifier.rb +23 -0
- data/lib/healthcare_phony/insurance.rb +6 -0
- data/lib/healthcare_phony/language.rb +30 -0
- data/lib/healthcare_phony/marital_status.rb +31 -0
- data/lib/healthcare_phony/patient.rb +114 -0
- data/lib/healthcare_phony/patient_visit.rb +96 -0
- data/lib/healthcare_phony/person_name.rb +104 -0
- data/lib/healthcare_phony/phone_number.rb +85 -0
- data/lib/healthcare_phony/procedure.rb +6 -0
- data/lib/healthcare_phony/race.rb +30 -0
- data/lib/healthcare_phony/religion.rb +32 -0
- data/lib/healthcare_phony/templates/adt_example.erb +6 -0
- data/lib/healthcare_phony/templates/csv_example.erb +4 -0
- data/lib/healthcare_phony/version.rb +5 -0
- data/lib/healthcare_phony/visit_admission.rb +53 -0
- data/lib/healthcare_phony/visit_discharge.rb +62 -0
- data/lib/healthcare_phony/visit_doctors.rb +19 -0
- data/lib/healthcare_phony/visit_location.rb +106 -0
- data/lib/healthcare_phony/work_phone_number.rb +20 -0
- metadata +185 -0
data/Rakefile
ADDED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.0
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'healthcare_phony/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'healthcare_phony'
|
9
|
+
spec.version = HealthcarePhony::VERSION
|
10
|
+
spec.authors = ['Austin Moody']
|
11
|
+
spec.email = ['austin.moody@hey.com']
|
12
|
+
|
13
|
+
spec.summary = 'A utility to create fake data and files for healthcare integration testing'
|
14
|
+
spec.homepage = 'http://github.com/austinmoody/healthcare_phony'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
# Specify which files should be added to the gem when it is released.
|
18
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
19
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
20
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
21
|
+
end
|
22
|
+
spec.bindir = 'exe'
|
23
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
|
+
spec.require_paths = ['lib']
|
25
|
+
|
26
|
+
spec.add_development_dependency 'bundler', '~> 2.2'
|
27
|
+
spec.add_development_dependency 'minitest', '~> 5.0'
|
28
|
+
spec.add_development_dependency 'rake', '~> 12.3.3'
|
29
|
+
|
30
|
+
spec.required_ruby_version = '>= 2.6'
|
31
|
+
spec.required_rubygems_version = '>= 2.6.10'
|
32
|
+
|
33
|
+
spec.add_dependency 'faker', '~> 2.13.0'
|
34
|
+
spec.add_dependency 'psych', '~> 3.1.0'
|
35
|
+
spec.add_dependency 'regexp-examples', '~> 1.5.1'
|
36
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'erb'
|
4
|
+
require 'faker'
|
5
|
+
require 'psych'
|
6
|
+
require 'regexp-examples'
|
7
|
+
|
8
|
+
Dir[File.join(__dir__, 'healthcare_phony', '*.rb')].sort.each { |file| require file }
|
9
|
+
|
10
|
+
Faker::Config.locale = 'en-US'
|
11
|
+
|
12
|
+
module HealthcarePhony
|
13
|
+
class Adt
|
14
|
+
attr_reader :template_file
|
15
|
+
|
16
|
+
def initialize(template_file = nil)
|
17
|
+
@template_file = if template_file.nil?
|
18
|
+
File.join(File.dirname(__FILE__), 'healthcare_phony', 'templates', 'adt_example.erb')
|
19
|
+
else
|
20
|
+
template_file
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
template = ERB.new(File.read(@template_file))
|
26
|
+
message = Hl7Message.new
|
27
|
+
patient = Patient.new
|
28
|
+
visit = PatientVisit.new
|
29
|
+
template.result_with_hash({ patient: patient, hl7: message, visit: visit })
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class CsvFile
|
34
|
+
attr_reader :template_file, :number_of_rows
|
35
|
+
|
36
|
+
def initialize(number_of_rows, template_file = nil)
|
37
|
+
@template_file = if template_file.nil?
|
38
|
+
File.join(File.dirname(__FILE__), 'healthcare_phony', 'templates', 'csv_example.erb')
|
39
|
+
else
|
40
|
+
template_file
|
41
|
+
end
|
42
|
+
@number_of_rows = number_of_rows
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_s
|
46
|
+
template = ERB.new(File.read(@template_file), trim_mode: '<>')
|
47
|
+
counter = 0
|
48
|
+
output_string = ''
|
49
|
+
while counter < @number_of_rows
|
50
|
+
output_string += template.result_with_hash({ patient: Patient.new, write_header: counter == 0 }) + "\n"
|
51
|
+
counter += 1
|
52
|
+
end
|
53
|
+
output_string
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class String
|
59
|
+
def to_hl7date
|
60
|
+
self
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_hl7datetime
|
64
|
+
self
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class Date
|
69
|
+
def to_hl7date
|
70
|
+
strftime('%Y%m%d')
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class Time
|
75
|
+
def to_hl7datetime
|
76
|
+
strftime('%Y%m%d%H%M%S')
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class NilClass
|
81
|
+
def to_hl7datetime
|
82
|
+
''
|
83
|
+
end
|
84
|
+
|
85
|
+
def to_hl7date
|
86
|
+
''
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module HealthcarePhony
|
4
|
+
# Public: Generates a fake Address
|
5
|
+
class Address
|
6
|
+
attr_accessor :address_line1, :address_line2, :city, :state, :postal_code, :country, :address_type
|
7
|
+
|
8
|
+
# Public: Initializes an Address. Pass in hash of different parameters, currently this includes:
|
9
|
+
# blank - An integer representing the % of times Address components should be blank.
|
10
|
+
# state - Allows specification of the Address state instead of randomly being chosen.
|
11
|
+
# country - Allows specification of the Address country. Is blank by default.
|
12
|
+
# address_type - Allows specification of the Address type.
|
13
|
+
# address_type_data_file - YAML file containing address types to randomly choose from if different options than
|
14
|
+
# those that come with gem are desired.
|
15
|
+
# See {address_type.yml}[https://github.com/austinmoody/healthcare_phony/blob/main/lib/healthcare_phony/data_files/address_type.yml]
|
16
|
+
def initialize(**init_args)
|
17
|
+
@set_blank = !init_args[:blank].nil? && Helper.random_with_blank('X', init_args[:blank]) == ''
|
18
|
+
@state = init_args[:state]
|
19
|
+
@country = init_args[:country]
|
20
|
+
@address_type_data_file = init_args[:address_type_data_file]
|
21
|
+
@address_type = init_args[:address_type]
|
22
|
+
define_address_line1
|
23
|
+
define_address_line2
|
24
|
+
define_city
|
25
|
+
define_state
|
26
|
+
define_postal_code
|
27
|
+
define_country
|
28
|
+
define_address_type
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# Private: Boolean set during initialization if Address components should be set to blank.
|
34
|
+
attr_accessor :set_blank
|
35
|
+
# Private: File containing address types to randomly choose from.
|
36
|
+
attr_accessor :address_type_data_file
|
37
|
+
|
38
|
+
# Private: Randomly generates the street address (address_line1)
|
39
|
+
def define_address_line1
|
40
|
+
@address_line1 = Faker::Address.street_address
|
41
|
+
@address_line1 = '' unless @set_blank == false
|
42
|
+
end
|
43
|
+
|
44
|
+
# Private: Randomly generates a second part of the street address (address_line2)
|
45
|
+
def define_address_line2
|
46
|
+
@address_line2 = Faker::Address.secondary_address
|
47
|
+
@address_line2 = '' unless @set_blank == false
|
48
|
+
end
|
49
|
+
|
50
|
+
# Private: Randomly generates the city.
|
51
|
+
def define_city
|
52
|
+
@city = Faker::Address.city
|
53
|
+
@city = '' unless @set_blank == false
|
54
|
+
end
|
55
|
+
|
56
|
+
# Private: Randomly generates the state unless state was specified during initialization.
|
57
|
+
def define_state
|
58
|
+
@state = Faker::Address.state_abbr if @state.nil?
|
59
|
+
@state = '' unless @set_blank == false
|
60
|
+
end
|
61
|
+
|
62
|
+
# Private: Randomly generates the postal/zip code.
|
63
|
+
def define_postal_code
|
64
|
+
@postal_code = Faker::Address.zip_code(state_abbreviation: @state)
|
65
|
+
@postal_code = '' unless @set_blank == false
|
66
|
+
end
|
67
|
+
|
68
|
+
def define_country
|
69
|
+
@country = '' if @country.nil?
|
70
|
+
@country = '' unless @set_blank == false
|
71
|
+
end
|
72
|
+
|
73
|
+
# Private: Sets the address type, either by the address type specified during initialization, by randomly choosing
|
74
|
+
# a value from the address_type.yml file, or by a random value from a file specified by address_type_data_file
|
75
|
+
# during initialization.
|
76
|
+
def define_address_type
|
77
|
+
if @address_type.nil?
|
78
|
+
data_file = if !@address_type_data_file.nil?
|
79
|
+
@address_type_data_file
|
80
|
+
else
|
81
|
+
"#{::File.expand_path(::File.join("..", "data_files"), __FILE__)}/address_type.yml"
|
82
|
+
end
|
83
|
+
address_types = Psych.load_file(data_file)
|
84
|
+
@address_type = address_types.sample unless address_types.nil?
|
85
|
+
end
|
86
|
+
@address_type = '' unless @set_blank == false
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require File.expand_path('phone_number', __dir__)
|
4
|
+
|
5
|
+
module HealthcarePhony
|
6
|
+
# Public: Generates a fake cell phone number
|
7
|
+
class CellPhoneNumber < PhoneNumber
|
8
|
+
# Public: Initializes a cell phone number. Pass in hash of different parameters, currently this includes:
|
9
|
+
# blank - An integer representing the % of times phone number components should be blank.
|
10
|
+
# use_code - Allows specification of the phone use code (PID.13.2)
|
11
|
+
# equipment_type - Allows specification of the phone equipment type (PID.13.3)
|
12
|
+
def initialize(**init_args)
|
13
|
+
super(init_args)
|
14
|
+
@use_code = init_args[:use_code].nil? ? 'ORN' : init_args[:use_code]
|
15
|
+
@use_code = '' unless @set_blank == false
|
16
|
+
@equipment_type = init_args[:equipment_type].nil? ? 'CP' : init_args[:equipment_type]
|
17
|
+
@equipment_type = '' unless @set_blank == false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
---
|
2
|
+
- A01
|
3
|
+
- A02
|
4
|
+
- A03
|
5
|
+
- A04
|
6
|
+
- A05
|
7
|
+
- A06
|
8
|
+
- A07
|
9
|
+
- A08
|
10
|
+
- A09
|
11
|
+
- A10
|
12
|
+
- A11
|
13
|
+
- A12
|
14
|
+
- A13
|
15
|
+
- A14
|
16
|
+
- A15
|
17
|
+
- A16
|
18
|
+
- A17
|
19
|
+
- A18
|
20
|
+
- A19
|
21
|
+
- A20
|
22
|
+
- A21
|
23
|
+
- A22
|
24
|
+
- A23
|
25
|
+
- A24
|
26
|
+
- A25
|
27
|
+
- A26
|
28
|
+
- A27
|
29
|
+
- A28
|
30
|
+
- A29
|
31
|
+
- A30
|
32
|
+
- A31
|
33
|
+
- A32
|
34
|
+
- A33
|
35
|
+
- A34
|
36
|
+
- A35
|
37
|
+
- A36
|
38
|
+
- A37
|
39
|
+
- A38
|
40
|
+
- A39
|
41
|
+
- A40
|
42
|
+
- A41
|
43
|
+
- A42
|
44
|
+
- A43
|
45
|
+
- A44
|
46
|
+
- A45
|
47
|
+
- A46
|
48
|
+
- A47
|
49
|
+
- A48
|
50
|
+
- A49
|
51
|
+
- A50
|
52
|
+
- A51
|
53
|
+
- A52
|
54
|
+
- A53
|
55
|
+
- A54
|
56
|
+
- A55
|
57
|
+
- A60
|
58
|
+
- A61
|
59
|
+
- A62
|
@@ -0,0 +1,49 @@
|
|
1
|
+
---
|
2
|
+
- :code: A
|
3
|
+
:description: Separated
|
4
|
+
:coding_system: HL70002
|
5
|
+
- :code: B
|
6
|
+
:description: Unmarried
|
7
|
+
:coding_system: HL70002
|
8
|
+
- :code: C
|
9
|
+
:description: Common Law
|
10
|
+
:coding_system: HL70002
|
11
|
+
- :code: D
|
12
|
+
:description: Divorced
|
13
|
+
:coding_system: HL70002
|
14
|
+
- :code: E
|
15
|
+
:description: Legally Separated
|
16
|
+
:coding_system: HL70002
|
17
|
+
- :code: G
|
18
|
+
:description: Living Together
|
19
|
+
:coding_system: HL70002
|
20
|
+
- :code: I
|
21
|
+
:description: Interlocutory
|
22
|
+
:coding_system: HL70002
|
23
|
+
- :code: M
|
24
|
+
:description: Married
|
25
|
+
:coding_system: HL70002
|
26
|
+
- :code: N
|
27
|
+
:description: Annulled
|
28
|
+
:coding_system: HL70002
|
29
|
+
- :code: O
|
30
|
+
:description: Other
|
31
|
+
:coding_system: HL70002
|
32
|
+
- :code: P
|
33
|
+
:description: Domestic Partner
|
34
|
+
:coding_system: HL70002
|
35
|
+
- :code: R
|
36
|
+
:description: Registered Domestic Partner
|
37
|
+
:coding_system: HL70002
|
38
|
+
- :code: S
|
39
|
+
:description: Single
|
40
|
+
:coding_system: HL70002
|
41
|
+
- :code: T
|
42
|
+
:description: Unreported
|
43
|
+
:coding_system: HL70002
|
44
|
+
- :code: U
|
45
|
+
:description: Unknown
|
46
|
+
:coding_system: HL70002
|
47
|
+
- :code: W
|
48
|
+
:description: Widowed
|
49
|
+
:coding_system: HL70002
|