lib/hqmf-parser/1.0/restriction.rb
module HQMF1
# Represents a restriction on the allowable values of a data item
class Restriction
include HQMF1::Utilities
attr_reader :range, :comparison, :restrictions, :subset, :preconditions, :expression
attr_accessor :from_parent
def initialize(entry, parent, doc)
@doc = doc
@entry = entry
@restrictions = []
range_def = @entry.at_xpath('./cda:pauseQuantity')
if range_def
@range = Range.new(range_def)
end
local_restrictions = @entry.xpath('./*/cda:sourceOf[@typeCode!="PRCN" and @typeCode!="COMP"]').collect do |entry|
Restriction.new(entry, self, @doc)
end
@restrictions.concat(local_restrictions)
local_subset = attr_val('./cda:subsetCode/@code')
if local_subset
@subset = local_subset
end
if @entry.at_xpath('./*/cda:derivationExpr')
@expression = Expression.new(@entry)
end
comparison_def = @entry.at_xpath('./*/cda:sourceOf[@typeCode="COMP"]')
if comparison_def
data_criteria_id = attr_val('./*/cda:id/@root')
data_criteria_id = comparison_def.at_xpath('./*/cda:id/@root').value if (data_criteria_id.nil? and comparison_def.at_xpath('./*/cda:id/@root'))
@comparison = Comparison.new(data_criteria_id, comparison_def, self, @doc)
end
@preconditions = @entry.xpath('./*/cda:sourceOf[@typeCode="PRCN"]').collect do |entry|
# create a dummy parent with a single restriction copied from self minus the
# nested preconditions to avoid an infinite loop
prior_comparison = nil
if parent.class==HQMF1::Precondition
prior_comparison = parent.first_comparison
else
prior_comparison = @comparsion
end
current_restriction = OpenStruct.new(
'range' => @range,
'comparison' => prior_comparison,
'restrictions' => [],
'preconditions' => [],
'subset' => @subset,
'type' => type,
'target_id' => target_id,
'field' => field,
'field_code' => field_code,
'field_time' => field_time,
'value' => value)
all_restrictions = []
all_restrictions.concat @restrictions
all_restrictions << current_restriction
parent = OpenStruct.new(
'restrictions' => all_restrictions,
'subset' => @subset
)
p = Precondition.new(entry, parent, @doc)
end
check_nil_conjunction_on_child
end
# The type of restriction, e.g. SBS, SBE etc
def type
attr_val('./@typeCode')
end
# is this type negated? true or false
def negation
attr_val('./@inversionInd') == "true"
end
# The id of the data criteria or measurement property that the value
# will be compared against
def target_id
attr_val('./*/cda:id/@root')
end
def field
attr_val('./cda:observation/cda:code/@displayName')
end
def field_code
attr_val('./cda:observation/cda:code/@code') || attr_val('./cda:encounter/cda:participant/cda:roleParticipant/@classCode')
end
def field_time
effectiveTime = @entry.at_xpath('./cda:observation/cda:effectiveTime') || @entry.at_xpath('./cda:encounter/cda:participant/cda:roleParticipant/cda:effectiveTime')
time = nil
if effectiveTime
time = :start if effectiveTime.at_xpath('./cda:low')
time = :end if effectiveTime.at_xpath('./cda:high')
end
time
end
def value
value = nil
type = attr_val('./cda:observation/cda:value/@xsi:type') || 'CD'
case type
when 'IVL_PQ'
value = HQMF1::Range.new(@entry.xpath('./cda:observation/cda:value'))
when 'PQ'
value = HQMF1::Value.new(@entry.xpath('./cda:observation/cda:value'))
when 'CD'
if field && field.downcase == 'status'
code = attr_val('./cda:observation/cda:value/@displayName').downcase
value = HQMF::Coded.for_single_code('status',code,code)
elsif attr_val('./cda:observation/cda:value/@code')
oid = attr_val('./cda:observation/cda:value/@code')
title = attr_val('./cda:observation/cda:value/@displayName')
value = HQMF::Coded.for_code_list(oid,title)
elsif attr_val('./cda:encounter/cda:participant/cda:roleParticipant/cda:code/@code')
oid = attr_val('./cda:encounter/cda:participant/cda:roleParticipant/cda:code/@code')
title = attr_val('./cda:encounter/cda:participant/cda:roleParticipant/cda:code/@displayName')
value = HQMF::Coded.for_code_list(oid,title)
end
when 'ANYNonNull'
value = HQMF::AnyValue.new
else
raise "Unknown restriction value type #{type}"
end if type
value
end
def to_json
return nil if from_parent
json = build_hash(self, [:subset,:type,:target_id,:field,:field_code,:from_parent, :negation, :field_time])
json[:range] = range.to_json if range
if value
if value.is_a? String
json[:value] = value
else
json[:value] = value.to_json
end
end
json[:comparison] = comparison.to_json if comparison
json[:restrictions] = json_array(self.restrictions)
json[:preconditions] = json_array(self.preconditions)
json[:expression] = self.expression.to_json if self.expression
json
end
end
end