Class: SegmentGenerator

Inherits:
Object
  • Object
show all
Includes:
Utils
Defined in:
lib/ez7gen/service/segment_generator.rb

Constant Summary collapse

@@maxReps =
2
@@random =
Random.new
@@BASE_VER =
{'2.4'=>'2.4','vaz2.4'=>'2.4'}
@@SET_ID_PIECE =
1

Constants included from Utils

Utils::BASE, Utils::BASE_INDICATOR, Utils::DATA_LOOKUP_MIS, Utils::PRIMARY

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Utils

#blank?, #get_name_without_base, #get_segment_name, #get_type_by_name, #has_html_encoded_ch?, #is_number?, #num_to_nil, #safe_len, #sample_index

Constructor Details

#initialize(version, event, pp) ⇒ SegmentGenerator

constructor



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/ez7gen/service/segment_generator.rb', line 22

def initialize(version, event, pp)
  @version = version
  @event = event

  #If there are multiple profile parsers, instantiate a generators for each
  @fieldGenerators = {}
  pp.each{|profileName, parser|
    # helper parser for lookup in the other schema
    # when generating segments for custom (not base) ex VAZ2.4 the field generator will have to look in both schemas
    # to resolve types and coded tables value.
    # we will assign the other schema parser as a helper parser
    helper_parser = pp.select{|key, value| key != profileName}
    helper_parser = (helper_parser.empty?) ? nil: helper_parser.values.first

    # starting with 2.5 use schema and version specific type generator.
    @fieldGenerators[profileName] = get_field_generator(parser, helper_parser)
  }
  # p @fieldGenerators
end

Instance Attribute Details

#versionObject

TODO: do I need accessors for version and event? refactor.



19
20
21
# File 'lib/ez7gen/service/segment_generator.rb', line 19

def version
  @version
end

Instance Method Details

#add_field(attributes) ⇒ Object

adds a generated field based on data type



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/ez7gen/service/segment_generator.rb', line 196

def add_field(attributes)

  type = get_type_by_name(attributes[:datatype])

  if(blank?(type)) #safe handle missing data typetype
    attributes[:datatype] = 'ID'
    type = get_type_by_name(attributes[:datatype])
  end

  fieldGenerator= @fieldGenerators[type]
  data_type = get_name_without_base(attributes[:datatype])

  # puts Utils.blank?(dt)?'~~~~~~~~~> data type is missing': dt
  if(['CK'].include?(data_type))
    return nil
  else
    # fld = blank?(dt)?nil :fieldGenerator.method(dt).call(attributes)
    fld = blank?(data_type)?nil :fieldGenerator.dt(data_type, attributes)
  end

end

#generate(message, segment, parsers, isGroup = false) ⇒ Object

refactoring



101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/ez7gen/service/segment_generator.rb', line 101

def generate(message, segment, parsers, isGroup=false)
  if(segment.kind_of?(Array))
    # handle group
    generate_group(message, segment, parsers)
  else
    # build_segment
    choiceParser = parsers[get_type_by_name(segment)]
    attributes = choiceParser.get_segment_structure(get_name_without_base(segment))
    generate_segment_in_context(message, segment, attributes, isGroup)

  end
end

#generate_group(message, group, parsers) ⇒ Object

generate a group of segments in test message segment using metadata



115
116
117
118
119
120
121
122
123
# File 'lib/ez7gen/service/segment_generator.rb', line 115

def generate_group( message,  group,  parsers)
  # generate each segment in the group
  totalReps = (group.instance_of?(RepeatingGroup))? (1..@@maxReps).to_a.sample: 1
  totalReps.times do |i|
    group.each{|seg| generate(message, seg, parsers, true) }
  end

  return message
end

#generate_segment(segmentName, attributes, idx = nil) ⇒ Object

generate a segment using Ensemble schema



158
159
160
161
162
163
164
165
# File 'lib/ez7gen/service/segment_generator.rb', line 158

def generate_segment(segmentName, attributes, idx=nil)
  elements = generate_segment_elements(segmentName, attributes)
  # overrite ids for sequential repeating segments
  elements[@@SET_ID_PIECE] = handle_set_id(segmentName, attributes, idx) || elements[@@SET_ID_PIECE]

  #generate segment using elements
  HL7::Message::Segment::Default.new(elements)
end

#generate_segment_elements(segmentName, attributes) ⇒ Object

use attributes to generate contents of a specific segment



181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/ez7gen/service/segment_generator.rb', line 181

def generate_segment_elements(segmentName, attributes)

  fields =[]
  total = attributes.size()
  # type = get_type_by_name(segmentName)
  # generate segment attributes
  total.times do |i|
    fields << add_field(attributes[i])
  end

  # add segment name to the beginning of the array
  fields.unshift(get_name_without_base(segmentName))
end

#generate_segment_in_context(message, segment, attributes, isGroup = false) ⇒ Object

generate test message segment using metadata



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/ez7gen/service/segment_generator.rb', line 128

def generate_segment_in_context(message, segment, attributes, isGroup=false)
  isRep = is_segment_repeating?(segment)
  segmentName = get_segment_name(segment)

  # decide if segment needs to repeat and how many times
  # totalReps = (isRep)? @@random.rand(1.. @@maxReps) : 1 # between 1 and maxReps
  totalReps = (isRep)? (1..@@maxReps).to_a.sample: 1

  totalReps.times do |i|
    # seg = (isRep)?message."get$segmentName"(i) :message."get$segmentName"()
    #groupId = (totalReps>1)?i+1 :((isGroup)?1:nil)
    sharedGroupId = (isGroup)? i+1: nil
    message << generate_segment(segmentName, attributes, sharedGroupId)
  end

  return message
end

#get_field_generator(parser, helper_parser) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/ez7gen/service/segment_generator.rb', line 42

def get_field_generator(parser, helper_parser)
  gen = nil
  begin
    require_relative "../../ez7gen/service/#{version}/field_generator"
    gen = FieldGenerator.new( parser, helper_parser)
  rescue => e
    # p e
    $log.error("#{self.class.to_s}:#{__method__.to_s}") { e.message }
    # @fieldGenerators[profileName] = TypeAwareFieldGenerator.new( parser, helper_parser)
  end
  return gen
end

#handle_set_id(segmentName, attributes, idx) ⇒ Object



167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/ez7gen/service/segment_generator.rb', line 167

def handle_set_id( segmentName, attributes, idx)

  #set-id field sometimes set to specific non numeric value, keep it, otherwise override if needed
  is_from_codetable = attributes.find { |p| p[:piece] == @@SET_ID_PIECE.to_s }[:codetable]
  if(!is_from_codetable) # ignore any value that generated using codetable
    #Set ID field in PID.1, AL1.1, DG1.1 etc. should have number 1 for the first occurrence of the segment.
    (idx) ? idx.to_s : (['PID', 'AL1', 'DG1'].include?(segmentName))? '1' :nil
  else
    nil
  end

end

#init_mshObject

initialize msh segment



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/ez7gen/service/segment_generator.rb', line 56

def init_msh
  # create a MSH segment
  msh = HL7::Message::Segment::MSH.new

  #pick a field generator
  fieldGenerator = @fieldGenerators['primary']

  msh.enc_chars ='^~\&'
  # msh.sending_app = fieldGenerator.HD({:codetable =>'361', :required =>'R'})
  msh.sending_app = fieldGenerator.dt('HD',{:codetable =>'361', :required =>'R'})
  # msh.sending_facility = fieldGenerator.HD({:codetable => '362', :required =>'R'})
  msh.sending_facility = fieldGenerator.dt('HD',{:codetable => '362', :required =>'R'})
  msh.recv_app = fieldGenerator.dt('HD',{:codetable => '361', :required =>'R'})
  msh.recv_facility = fieldGenerator.dt('HD',{:codetable => '362', :required =>'R'})
  msh.processing_id = 'P'#@fieldGenerators['primary'].ID({},true)
  #Per Galina, set version to 2.4 for all of vaz
  # msh.version_id = @@BASE_VER[@version]
  msh.version_id = @version
  msh.security = fieldGenerator.dt('ID',{:required =>'O'})

  # Per Galina's requirement, fix for validation failure.
  # MSH.9.3 needs to be populated with the correct Message Structure values for those messages
  # that are the “copies” of the “original” messages.
  structType = fieldGenerator.pp.get_message_structure(@event)
  msh.message_type = @event.sub('_','^')<<'^'<<structType

  msh.time =  DateTime.now.strftime('%Y%m%d%H%M%S.%L')
  msh.message_control_id = fieldGenerator.dt('ID',{:required =>'R'})
  msh.seq = fieldGenerator.dt('ID',{:required=>'O'})
  msh.continue_ptr = fieldGenerator.dt('ID',{:required=>'O'})
  msh.accept_ack_type = fieldGenerator.dt('ID',{:required=>'R', :codetable=>'155'})
  msh.app_ack_type = fieldGenerator.dt('ID',{:required=>'R', :codetable=>'155'})
  msh.country_code = fieldGenerator.dt('ID',{:required=>'R', :codetable=>'399'})
  # msh.charset = @fieldGenerators['primary'].ID({:required=>'R', :codetable=>'211'})
  msh.charset = 'ASCII' # default value from codetable, change causes problems in validating messages in Ensemble
  #Table 296 Primary Language has no suggested values.  The field will be populated with values from the Primary Language table in the properties file. Example value: EN^English
  msh.principal_language_of_message ='EN^English'
  msh.alternate_character_set_handling_scheme = fieldGenerator.dt('ID',{:required=>'O', :codetable=>'356'})
  # 21	Conformance Statement ID
  msh.e20 =  fieldGenerator.dt('ID',{:required=>'O', :codetable=>'449'})

  return msh
end

#is_segment_repeating?(segment) ⇒ Boolean

#generate_segment_in_context test message using def generateSegmentFields( segment, attributes)

segmentName = Utils.get_segment_name(segment)
generate_segment(segmentName, attributes)

end

Returns:

  • (Boolean)


153
154
155
# File 'lib/ez7gen/service/segment_generator.rb', line 153

def is_segment_repeating?(segment)
  segment.include?("~{")
end