class EDI::A::DE
Class EDI::A::DE
This class implements ANSI X12 data elements 1004, 2005 etc., including the service DEs I01, …, I16
For internal use only.
Public Class Methods
new( p, name, status, fmt )
click to toggle source
Calls superclass method
EDI::DE::new
# File lib/edi4r/ansi_x12.rb, line 1051 def initialize( p, name, status, fmt ) super( p, name, status, fmt ) raise "Illegal DE name: #{name}" unless name =~ /\d{1,4}/ # check if supported format syntax # check if supported status value end
Public Instance Methods
parse( buf, already_escaped=false )
click to toggle source
Generate the DE
content from the given string representation. buf
contains a single DE
string
# File lib/edi4r/ansi_x12.rb, line 1062 def parse( buf, already_escaped=false ) # 2nd par is a dummy for X12 return nil unless buf return @value = nil if buf.empty? self.value = buf # if format[0] == ?n # # Select appropriate Numeric, FIXME: Also match exponents! # self.value = @value=~/\d+\.\d+/ ? @value.to_f : @value.to_i # end @value end
to_s( no_escape=false )
click to toggle source
# File lib/edi4r/ansi_x12.rb, line 1074 def to_s( no_escape=false ) # Parameter is a dummy for X12 location = "DE #{parent.name}/#{@name}" if @format =~ /^(AN|B|DT|ID|N\d+?|R|TM|XX) (\d+)\/(\d+)$/ _type, min_size, max_size = $1, $2.to_i, $3.to_i else raise "#{location}: Illegal format #{format}" end case _type when 'AN', 'ID', 'DT', 'TM' if empty? then return( required? ? ' '* min_size : '' ) end str = @value.to_s; fixlen = str.length return @value.to_s[0,max_size] if fixlen > max_size # Truncate if too long fixlen < min_size ? str + ' ' * (min_size - fixlen) : str # Right-pad with blanks if too short when /N(\d+)/ x = @value.to_f $1.to_i.times { x *= 10 } str = (x+0.0001).to_i.to_s; fixlen = str.length raise "#{location}: '#{value}' too long (#{fixlen}) for fmt #{format}" if fixlen > max_size return '0' * (min_size - fixlen) + str if fixlen < min_size # Left-pad with zeroes str when 'R' @value.to_s # FIXME: Add length control! when 'XX' # @value.to_s @value else raise "#{location}: Format #{format} not supported" end end
validate( err_count=0, fmt=@format )
click to toggle source
Performs various validation checks and returns the number of issues found (plus the value of err_count
):
-
empty while mandatory?
-
character set limitations violated?
-
various format restrictions violated?
Note: X12 comes with its own format definitions, so we overwrite
validate() of the base class here entirely.
# File lib/edi4r/ansi_x12.rb, line 1157 def validate( err_count=0, fmt=@format ) location = "DE #{parent.name}/#{@name}" if empty? if required? EDI::logger.warn "#{location}: Empty though mandatory!" err_count += 1 end else # # Charset check # if (pos = (value =~ root.illegal_charset_pattern)) # != nil EDI::logger.warn "#{location}: Illegal character: #{value[pos].chr} (#{value[pos]})" err_count += 1 end # # Format check, raise error if not consistent! # if fmt =~ /^(AN|B|DT|ID|N\d|R|TM|XX) (\d+)\/(\d+)$/ _type, min_size, max_size = $1, $2.to_i, $3.to_i case _type when 'R' strval = value.to_s re = Regexp.new('^(-)?(\d+)(\.\d+)?$') md = re.match strval if md.nil? raise "#{location}: '#{strval}' - not matching format #{fmt}" # warn "#{strval} - not matching format #{fmt}" # err_count += 1 end len = strval.length # Sign char does not go into length count: len -= 1 if md[1]=='-' # Decimal char does not go into length count: len -= 1 if not md[3].nil? # break if not required? and len == 0 if required? or len != 0 if len > max_size.to_i # if _upto.nil? and len != _size.to_i or len > _size.to_i EDI::logger.warn "Context in #{location}: #{_type}, #{min_size}, #{max_size}; #{md[1]}, #{md[2]}, #{md[3]}" EDI::logger.warn "Max length exceeded in #{location}: #{len} vs. #{max_size}" err_count += 1 # warn " (strval was: '#{strval}')" end if md[1] =~/^0+/ EDI::logger.warn "#{strval} contains leading zeroes" err_count += 1 end if md[3] and md[3]=~ /.0+$/ EDI::logger.warn "#{strval} contains trailing decimal sign/zeroes" err_count += 1 end end when /N\d+/ len = (str=value.to_s).length len -= 1 if str[0]==?- # Don't count sign in length if len > max_size # len < min_size is ok, would be left-padded EDI::logger.warn "#{@name}: Value is '#{value}'" EDI::logger.warn "Length mismatch in #{location}: #{len} vs. #{min_size}/#{max_size}" err_count += 1 end when 'AN' len = value.to_s.length if len > max_size EDI::logger.warn "#{@name}: Value is '#{value}'" EDI::logger.warn "Length mismatch in #{location}: #{len} vs. #{min_size}/#{max_size} - content will be truncated!" err_count += 1 elsif len < min_size EDI::logger.warn "#{@name}: Value is '#{value}'" EDI::logger.warn "Length mismatch in #{location}: #{len} vs. #{min_size}/#{max_size} (content will be right-padded)" # err_count += 1 end when 'ID', 'DT', 'TM' len = value.to_s.length unless len.between?( min_size, max_size ) EDI::logger.warn "#{@name}: Value is '#{value}'" EDI::logger.warn "Length mismatch in #{location}: #{len} vs. #{min_size}/#{max_size}" err_count += 1 end when 'XX' # Currently, this case only affects I15, which is a Fixnum, # but represents a character if RUBY_VERSION < '1.9' x_from, x_to = 1, 255 else x_from, x_to = "\001", "\377" end unless value.between?(x_from, x_to) EDI::logger.warn "#{@name}: Value is '#{value}'" EDI::logger.warn "Cannot be encoded as a character!" err_count += 1 end else raise "#{location}: Illegal format prefix #{_type}" # err_count += 1 end else EDI::logger.warn "#{location}: Illegal format: #{fmt}!" err_count += 1 end end err_count end
value=( val )
click to toggle source
The proper method to assign values to a DE
. The passed value must respond to to_i
.
Calls superclass method
# File lib/edi4r/ansi_x12.rb, line 1108 def value=( val ) if @format =~ /^(AN|B|DT|ID|N\d+?|R|TM|XX) (\d+)\/(\d+)$/ _type, min_size, max_size = $1, $2.to_i, $3.to_i else location = "DE #{parent.name}/#{@name}" raise "#{location}: Illegal format #{format}" end case _type when 'AN', 'ID', 'DT', 'TM' # super when 'R' val = val.to_f when /N(\d+)/ if $1==0 val = val.to_i else val = val.to_f $1.to_i.times { val /= 10.0 } end when 'XX' # p "case XX: name, val = ", name, val val = val[0] if val.is_a?(String) # raise "#{location}: Illegal value #{val} for format XX" unless val.is_a? Fixnum # return super else location = "DE #{parent.name}/#{@name}" raise "#{location}: Format #{format} not supported" end # Suppress trailing decimal part if Integer value if val.is_a? Float ival = val.to_i val = ival if val == ival end EDI::logger.info "***** I15='#{val}'" if name == 'I15' && val.is_a?(String) && val.size > 1 super end