Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@
/spec/reports/
/tmp/
Gemfile.lock
/*.gem
/standard/*.pdf
134 changes: 134 additions & 0 deletions bin/generate_code.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#! /usr/bin/env ruby
# frozen_string_literal: true

# Script to generate pipehat classes for types/segments
#
# This went throughs several iterations of trying to parse this data from the
# PDF versions of the HL7 standard but it was too tricky. So now we're storing
# the data in manually maintained CSV files.

require "csv"
require "bundler/setup"
require "pry"

class CodeGenerator
def generate!
generate_types
generate_segments
end

# Given a name/description, convert it into a string suitable to use as a
# method name in ruby
def self.normalise(name)
name
.downcase
.gsub(/\(.*\)$/, "")
.gsub(/['’]s/, "s")
.gsub(/\(s\)/, "s")
.gsub(/[^a-z0-9]/, " ")
.strip
.squeeze(" ")
.gsub(" ", "_")
end

private

Component = Struct.new(:type, :name) do
def method_name
CodeGenerator.normalise(name)
end
end

Type = Struct.new(:name, :description, :components) do
def filename
"lib/pipehat/types/#{name.downcase}.rb"
end
end

Field = Component

Segment = Struct.new(:name, :description, :fields) do
def filename
"lib/pipehat/segment/#{name.downcase}.rb"
end
end

def generate_types
type = nil
CSV.new(File.read("standard/datatypes.csv")).each do |row|
if row[0]
write_type_definition(type) if type
type = Type.new(row[0], row[1], [])
end
type.components << Component.new(row[2], row[3]) if row[2]
end
write_type_definition(type)
end

def write_type_definition(type)
puts "Writing #{type.filename} ..."

maxlen = type.components.map(&:method_name).map(&:length).max

File.open(type.filename, "w") do |file|
file.puts "# frozen_string_literal: true"
file.puts
file.puts "# #{type.description}"
if type.components.any?
file.puts "Pipehat.define_type :#{type.name} do"
type.components.each do |comp|
file.puts " add_component :#{"#{comp.method_name},".ljust(maxlen + 1)} :#{comp.type}"
end
file.puts "end"
else
file.puts "Pipehat.define_type :#{type.name}"
end
end
end

def generate_segments
segment = nil
CSV.new(File.read("standard/segments.csv")).each do |row|
if row[0]
write_segment_class(segment) if segment
segment = Segment.new(row[0], row[1], [])
end
segment.fields << Field.new(row[2], row[3]) if row[2]
end
write_segment_class(segment)
end

def write_segment_class(segment)
puts "Writing #{segment.filename}"

maxlen = segment.fields.map(&:method_name).map(&:length).max
parent = %w[BHS FHS MSH].include?(segment.name) ? "Header" : "Base"

File.open(segment.filename, "w") do |file|
file.puts <<~RUBY
# frozen_string_literal: true

module Pipehat
module Segment
# #{segment.description}
class #{segment.name} < #{parent}
RUBY
segment.fields.each do |field|
options = ""
if parent == "Header" &&
(field.name.end_with?("Field Separator") || field.name.end_with?("Encoding Characters"))
# special case for field sep and encoding chats in header segments
options = ", setter: false"
end
file.puts " add_field :#{"#{field.method_name},".ljust(maxlen + 1)} :#{field.type}#{options}"
end
file.puts <<~RUBY
end
end
end
RUBY
end
end
end

CodeGenerator.new.generate!
3 changes: 3 additions & 0 deletions lib/pipehat.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require "pipehat/version"

module Pipehat
Expand All @@ -6,6 +8,7 @@ class Error < StandardError; end

require "pipehat/parser"
require "pipehat/segment/base"
require "pipehat/segment/header"
require "pipehat/node"
require "pipehat/field/base"
require "pipehat/repeat/base"
Expand Down
23 changes: 23 additions & 0 deletions lib/pipehat/segment/abs.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

module Pipehat
module Segment
# Abstract
class ABS < Base
add_field :discharge_care_provider, :XCN
add_field :transfer_medical_service_code, :CWE
add_field :severity_of_illness_code, :CWE
add_field :date_time_of_attestation, :DTM
add_field :attested_by, :XCN
add_field :triage_code, :CWE
add_field :abstract_completion_date_time, :DTM
add_field :abstracted_by, :XCN
add_field :case_category_code, :CWE
add_field :caesarian_section_indicator, :ID
add_field :gestation_category_code, :CWE
add_field :gestation_period_weeks, :NM
add_field :newborn_code, :CWE
add_field :stillborn_indicator, :ID
end
end
end
22 changes: 22 additions & 0 deletions lib/pipehat/segment/acc.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

module Pipehat
module Segment
# Accident
class ACC < Base
add_field :accident_date_time, :DTM
add_field :accident_code, :CWE
add_field :accident_location, :ST
add_field :auto_accident_state, :CWE
add_field :accident_job_related_indicator, :ID
add_field :accident_death_indicator, :ID
add_field :entered_by, :XCN
add_field :accident_description, :ST
add_field :brought_in_by, :ST
add_field :police_notified_indicator, :ID
add_field :accident_address, :XAD
add_field :degree_of_patient_liability, :NM
add_field :accident_identifier, :EI
end
end
end
10 changes: 10 additions & 0 deletions lib/pipehat/segment/add.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

module Pipehat
module Segment
# Addendum
class ADD < Base
add_field :addendum_continuation_pointer, :ST
end
end
end
14 changes: 14 additions & 0 deletions lib/pipehat/segment/aff.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

module Pipehat
module Segment
# Professional Affiliation
class AFF < Base
add_field :set_id, :SI
add_field :professional_organization, :XON
add_field :professional_organization_address, :XAD
add_field :professional_organization_affiliation_date_range, :DR
add_field :professional_affiliation_additional_information, :ST
end
end
end
23 changes: 23 additions & 0 deletions lib/pipehat/segment/aig.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

module Pipehat
module Segment
# Appointment Information – General Resource
class AIG < Base
add_field :set_id, :SI
add_field :segment_action_code, :ID
add_field :resource_id, :CWE
add_field :resource_type, :CWE
add_field :resource_group, :CWE
add_field :resource_quantity, :NM
add_field :resource_quantity_units, :CNE
add_field :start_date_time, :DTM
add_field :start_date_time_offset, :NM
add_field :start_date_time_offset_units, :CNE
add_field :duration, :NM
add_field :duration_units, :CNE
add_field :allow_substitution_code, :CWE
add_field :filler_status_code, :CWE
end
end
end
21 changes: 21 additions & 0 deletions lib/pipehat/segment/ail.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

module Pipehat
module Segment
# Appointment Information – Location Resource
class AIL < Base
add_field :set_id, :SI
add_field :segment_action_code, :ID
add_field :location_resource_id, :PL
add_field :location_type, :CWE
add_field :location_group, :CWE
add_field :start_date_time, :DTM
add_field :start_date_time_offset, :NM
add_field :start_date_time_offset_units, :CNE
add_field :duration, :NM
add_field :duration_units, :CNE
add_field :allow_substitution_code, :CWE
add_field :filler_status_code, :CWE
end
end
end
26 changes: 13 additions & 13 deletions lib/pipehat/segment/aip.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@

module Pipehat
module Segment
# Appointment Information - Personnel Resource
# Appointment Information Personnel Resource
class AIP < Base
add_field :set_id, :SI
add_field :segment_action_code, :ID
add_field :personnel_resource_id, :XCN
add_field :resource_type, :CWE
add_field :resource_group, :CWE
add_field :start_date_time, :DTM
add_field :start_date_time_offset, :NM
add_field :start_date_time_offset_units, :CNE
add_field :duration, :NM
add_field :duration_units, :CNE
add_field :allow_substitution_code, :CWE
add_field :filler_status_code, :CWE
add_field :set_id, :SI
add_field :segment_action_code, :ID
add_field :personnel_resource_id, :XCN
add_field :resource_type, :CWE
add_field :resource_group, :CWE
add_field :start_date_time, :DTM
add_field :start_date_time_offset, :NM
add_field :start_date_time_offset_units, :CNE
add_field :duration, :NM
add_field :duration_units, :CNE
add_field :allow_substitution_code, :CWE
add_field :filler_status_code, :CWE
end
end
end
12 changes: 6 additions & 6 deletions lib/pipehat/segment/al1.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ module Pipehat
module Segment
# Patient Allergy Information
class AL1 < Base
add_field :set_id, :SI
add_field :allergen_type_code, :CE
add_field :allergen_code, :CE
add_field :allergy_severity_code, :CE
add_field :allergy_reaction_code, :ST
add_field :identification_date, :DT
add_field :set_id, :SI
add_field :allergen_type_code, :CWE
add_field :allergen_code_mnemonic_description, :CWE
add_field :allergy_severity_code, :CWE
add_field :allergy_reaction_code, :ST
add_field :identification_date, :DT
end
end
end
14 changes: 14 additions & 0 deletions lib/pipehat/segment/apr.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

module Pipehat
module Segment
# Appointment Preferences
class APR < Base
add_field :time_selection_criteria, :SCV
add_field :resource_selection_criteria, :SCV
add_field :location_selection_criteria, :SCV
add_field :slot_spacing_criteria, :NM
add_field :filler_override_criteria, :SCV
end
end
end
35 changes: 35 additions & 0 deletions lib/pipehat/segment/arq.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# frozen_string_literal: true

module Pipehat
module Segment
# Appointment Request
class ARQ < Base
add_field :placer_appointment_id, :EI
add_field :filler_appointment_id, :EI
add_field :occurrence_number, :NM
add_field :placer_order_group_number, :EI
add_field :schedule_id, :CWE
add_field :request_event_reason, :CWE
add_field :appointment_reason, :CWE
add_field :appointment_type, :CWE
add_field :appointment_duration, :NM
add_field :appointment_duration_units, :CNE
add_field :requested_start_date_time_range, :DR
add_field :priority_arq, :ST
add_field :repeating_interval, :RI
add_field :repeating_interval_duration, :ST
add_field :placer_contact_person, :XCN
add_field :placer_contact_phone_number, :XTN
add_field :placer_contact_address, :XAD
add_field :placer_contact_location, :PL
add_field :entered_by_person, :XCN
add_field :entered_by_phone_number, :XTN
add_field :entered_by_location, :PL
add_field :parent_placer_appointment_id, :EI
add_field :parent_filler_appointment_id, :EI
add_field :placer_order_number, :EI
add_field :filler_order_number, :EI
add_field :alternate_placer_order_group_number, :EIP
end
end
end
19 changes: 19 additions & 0 deletions lib/pipehat/segment/arv.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

module Pipehat
module Segment
# Access Restriction
class ARV < Base
add_field :set_id, :SI
add_field :access_restriction_action_code, :CNE
add_field :access_restriction_value, :CWE
add_field :access_restriction_reason, :CWE
add_field :special_access_restriction_instructions, :ST
add_field :access_restriction_date_range, :DR
add_field :security_classification_tag, :CWE
add_field :security_handling_instructions, :CWE
add_field :access_restriction_message_location, :ERL
add_field :access_restriction_instance_identifier, :EI
end
end
end
Loading