module Eddy module Models # Base class for EDI Transaction Sets. class TransactionSet # @return [Integer] ID = nil # @return [String] NAME = nil # @return [String] FUNCTIONAL_GROUP = nil # @return [Array] attr_accessor :components # Container used to distribute state throughout an Interchange. # @return [Eddy::Data::Store] attr_accessor :store # A unique control number for the Transaction Set. # @return [Integer] attr_accessor :control_number # @param store [Eddy::Data::Store] # @param components [Array] # @return [void] def initialize(store, *components) self.store = store components.flatten! self.components = components || [] self.control_number = Eddy::Data.new_transaction_set_control_number(self.id) end # @return [String] def id return self.class::ID end # @return [String] def self.id return self::ID end # @return [String] def functional_group return self.class::FUNCTIONAL_GROUP end # @return [String] def self.functional_group return self::FUNCTIONAL_GROUP end # @return [String] def name return self.class::NAME end # @return [String] def self.name return self::NAME end # Add `ST` and `SE` segments to the `components` array. # # @return [void] def add_envelope() st = Eddy::Segments::ST.new(self.store) st.TransactionSetIdentifierCode = self.id st.TransactionSetControlNumber = self.control_number se = Eddy::Segments::SE.new(self.store) se.NumberOfIncludedSegments = self.number_of_included_segments() se.TransactionSetControlNumber = self.control_number self.components.unshift(st) self.components.push(se) end # This shouldn't be used. # An Interchange or FunctionalGroup should call `all_components` and render those itself. # # @param s_sep [String] (self.store.segment_separator) # @return [String] def render(s_sep = self.store.segment_separator) add_envelope() return self.all_components.map { |s| s.render(self.store.element_separator) }.compact.join(s_sep).rstrip() end # Return the count of Segments in the Transaction Set where `skip` is false, # plus 2 for `ST` and `SE`. # # @return [Integer] def number_of_included_segments() return (self.all_components.reject(&:skip).length + 2) end # Return all contained Segments in a single, flattened array. # # @return [Array] def all_components() comps = self.components.map do |c| if c.is_a?(Eddy::Models::Loop::Base) c.all_contents() elsif c.is_a?(Eddy::Models::Segment) c else raise Eddy::Errors::RenderError end end return comps.flatten end end end end