lib/hqmf-parser/2.0/precondition.rb in health-data-standards-3.6.1 vs lib/hqmf-parser/2.0/precondition.rb in health-data-standards-3.7.0
- old
+ new
@@ -1,47 +1,73 @@
module HQMF2
-
+ # Represents the logic that defines grouping of criteria and actions done on it.
class Precondition
-
include HQMF2::Utilities
-
- attr_reader :preconditions, :reference
-
- def initialize(entry, doc)
- @doc = doc
- @entry = entry
- @preconditions = @entry.xpath('./*/cda:precondition', HQMF2::Document::NAMESPACES).collect do |precondition|
- Precondition.new(precondition, @doc)
+
+ attr_reader :preconditions, :reference, :conjunction, :id
+
+ def self.parse(entry, doc, id_generator)
+ doc = doc
+ entry = entry
+ aggregation = entry.at_xpath('./cda:allTrue | ./cda:atLeastOneTrue | ./cda:allFalse | ./cda:atLeastOneFalse',
+ HQMF2::Document::NAMESPACES)
+
+ # Sets the reference criteria for the precondition (if it exists)
+ reference_def = entry.at_xpath('./*/cda:id', HQMF2::Document::NAMESPACES)
+ reference_def ||= entry.at_xpath('./cda:join/cda:templateId/cda:item', HQMF2::Document::NAMESPACES)
+ reference = Reference.new(reference_def) if reference_def
+
+ # Unless there is an aggregator, no further actions are necessary.
+ return new(id_generator.next_id, nil, [], false, reference) unless aggregation
+
+ precondition_entries = entry.xpath('./*/cda:precondition', HQMF2::Document::NAMESPACES)
+ preconditions = precondition_entries.collect do |precondition|
+ precondition = Precondition.parse(precondition, doc, id_generator)
+ # There are cases where a precondition may contain no references or preconditions, and should be ignored.
+ precondition.reference.nil? && precondition.preconditions.empty? ? nil : precondition
end
- reference_def = @entry.at_xpath('./*/cda:id', HQMF2::Document::NAMESPACES)
- if !reference_def
- reference_def = @entry.at_xpath('./cda:join/cda:templateId/cda:item', HQMF2::Document::NAMESPACES)
- end
- if reference_def
- @reference = Reference.new(reference_def)
- end
+ preconditions.compact!
+ handle_aggregation(id_generator, reference, preconditions, aggregation)
end
-
- # Return true of this precondition represents a conjunction with nested preconditions
- # or false of this precondition is a reference to a data criteria
- def conjunction?
- @preconditions.length>0
- end
-
- # Get the conjunction code, e.g. allTrue, allFalse
- # @return [String] conjunction code
- def conjunction_code
- if conjunction?
- @entry.at_xpath('./*[1]', HQMF2::Document::NAMESPACES).name
+
+ # "False" aggregators exist, and require special handling, so this manages that and returns the
+ # proper precondition.
+ def self.handle_aggregation(id_generator, reference, preconditions, aggregation, conjunction = nil)
+ negation = false
+ conjunction = aggregation.name
+ case conjunction
+ # DeMorgan's law is used to handle negated caes: e.g. to find if all are false, negate the "at least one true"
+ # check.
+ when 'allFalse'
+ negation = true
+ conjunction = 'atLeastOneTrue'
+ when 'atLeastOneFalse'
+ negation = true
+ conjunction = 'allTrue'
+ end
+ # Return the proper precondition given if a negation exists
+ if negation
+ # Wrap the negation in a seperate precondition which this will reference
+ precondition_wrapper = new(id_generator.next_id, conjunction, preconditions, true, reference)
+ new(id_generator.next_id, conjunction, [precondition_wrapper])
else
- nil
+ new(id_generator.next_id, conjunction, preconditions, false, reference)
end
end
-
+
+ def initialize(id, conjunction, preconditions = [], negation = false, reference = nil)
+ @preconditions = preconditions || []
+ @conjunction = conjunction
+ @reference = reference
+ @negation = negation
+ @id = id
+ end
+
+ # Generates this classes hqmf-model equivalent
def to_model
- pcs = preconditions.collect {|p| p.to_model}
- mr = reference ? reference.to_model : nil
- HQMF::Precondition.new(nil, pcs, mr, conjunction_code, false)
+ pcs = @preconditions.collect(&:to_model)
+ mr = @reference ? @reference.to_model : nil
+ cc = @conjunction
+ HQMF::Precondition.new(@id, pcs, mr, cc, @negation)
end
end
-
end