Class: EDI::E::MsgGroup

Inherits:
MsgGroup show all
Defined in:
lib/edi4r/edifact.rb

Overview

Class EDI::E::MsgGroup

This class implements a group of business documents of the same type Its header unites features from UNB as well as from UNH.

Constant Summary collapse

@@msggroup_defaults =
{
  :msg_type => 'ORDERS', :version => 'D', :release => '96A',
  :resp_agency => 'UN', :assigned_code => nil # e.g. 'EAN008'
}
@@msggroup_default_keys =

e.g. 'EAN008'

@@msggroup_defaults.keys

Instance Attribute Summary collapse

Attributes inherited from Collection_HT

#header, #trailer

Attributes inherited from Object

#name, #parent, #root

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from MsgGroup

#each_BCDS, #fmt_of_DE, parse_xml

Methods inherited from Collection_HT

#empty?, #root=, #to_din16557_4, #to_xml, #to_xml_header, #to_xml_trailer

Methods inherited from Collection

#==, #[], #each, #find_all, #first, #index, #inspect, #last, #length, #map, #names, #normalized_class_name, #root=, #size

Constructor Details

#initialize(p, user_par = {}) ⇒ MsgGroup

Creates an empty UN/EDIFACT message group Don't use directly - use new_msggroup of class Interchange instead!

First parameter

This is always the parent object (an interchange object). Use method new_msggroup in the corresponding object instead of creating message groups unattended - the parent reference will be accounted for automatically.

Second parameter

List of supported hash keys:

UNG presets for your convenience, may be changed later

:msg_type

Sets DE 0038, default = 'INVOIC'

:resp_agency

Sets DE 0051, default = 'UN'

:version

Sets S008.0052, default = 'D'

:release

Sets S008.0054, default = '96A'

Optional parameters, required depending upon use case

:assigned_code

Sets S008.0057 (subset), default = nil

:sender

Presets DE S006/0040, default = nil

:recipient

Presets DE S007/0044, default = nil

:group_reference

Presets DE 0048, auto-incremented

Notes

  • The functional group reference number in UNG and UNE (0048) is set automatically to a number that is unique for this message group and the running process (auto-increment).

  • The counter in UNG (0060) is set automatically to the number of included messages.

  • The trailer segment (UNE) is generated automatically.

  • Whenever possible, avoid writing to the counters of the message header or trailer segments!


888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
# File 'lib/edi4r/edifact.rb', line 888

def initialize( p, user_par={} )
  super( p, user_par )
  @messages_created = 0

  if user_par.is_a? Hash
    preset_group( user_par )
    @header = new_segment('UNG')
    @trailer = new_segment('UNE')
    @trailer.d0060 = 0

    @header.d0038 = @name
    @header.d0051 = @resp_agency
    cde = @header.cS008
    cde.d0052 = @version
    cde.d0054 = @release
    cde.d0057 = @subset

    @header.cS006.d0040 = user_par[:sender]    || root.header.cS002.d0004
    @header.cS007.d0044 = user_par[:recipient] || root.header.cS003.d0010
    @header.d0048 = user_par[:group_reference] || p.groups_created
    #      @trailer.d0048 = @header.d0048

    t = Time.now
    @header.cS004.d0017 = t.strftime(p.version==4 ? '%Y%m%d':'%y%m%d')
    @header.cS004.d0019 = t.strftime("%H%M")

  elsif user_par.is_a? Segment

    @header = user_par
    raise "UNG expected, #{@header.name} found!" if @header.name != 'UNG'
    @header.parent = self
    @header.root = self.root

    # Assign a temporary UNE segment
    de_sep = root.una.de_sep
    @trailer = Segment.parse(root, 'UNE' << de_sep << '0' << de_sep << '0')

    s008 = @header.cS008
    @name = @header.d0038
    @version = s008.d0052
    @release = s008.d0054
    @resp_agency = @header.d0051
    @subset = s008.d0057
  else
    raise "First parameter: Illegal type!"
  end

end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class EDI::Collection

Instance Attribute Details

#messages_createdObject (readonly)

Returns the value of attribute messages_created


841
842
843
# File 'lib/edi4r/edifact.rb', line 841

def messages_created
  @messages_created
end

Class Method Details

.parse(p, segment_list) ⇒ Object

List of segments


959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
# File 'lib/edi4r/edifact.rb', line 959

def MsgGroup.parse (p, segment_list) # List of segments
  grp = p.new_msggroup(:msg_type => 'DUMMY')

  # We now expect a sequence of segments that comprises one group,
  # starting with UNG and ending with UNE, and with messages in between.
  # We process the UNG/UNE envelope separately, then work on the content.

  header  = grp.parse_segment(segment_list.shift, 'UNG')
  trailer = grp.parse_segment(segment_list.pop,   'UNE')

  init_seg = Regexp.new('^UNH')
  exit_seg = Regexp.new('^UNT')

  while segbuf = segment_list.shift
    case segbuf

    when init_seg
      sub_list = Array.new
      sub_list.push segbuf

    when exit_seg
      sub_list.push segbuf
      grp.add grp.parse_message(sub_list)

    else
      sub_list.push segbuf
    end
  end

  grp.header  = header
  grp.trailer = trailer
  grp
end

Instance Method Details

#add(msg) ⇒ Object


1013
1014
1015
1016
1017
# File 'lib/edi4r/edifact.rb', line 1013

def add( msg )
  super
  @trailer.d0060 = @trailer.d0060.to_i if @trailer.d0060.is_a? String
  @trailer.d0060 += 1
end

#new_message(params = {}) ⇒ Object


994
995
996
997
# File 'lib/edi4r/edifact.rb', line 994

def new_message(params={})
  @messages_created += 1
  Message.new(self, params)
end

#new_segment(tag) ⇒ Object

:nodoc:


999
1000
1001
# File 'lib/edi4r/edifact.rb', line 999

def new_segment(tag) # :nodoc:
  Segment.new(self, tag)
end

#parse_message(list) ⇒ Object

:nodoc:


1004
1005
1006
# File 'lib/edi4r/edifact.rb', line 1004

def parse_message(list) # :nodoc:
  Message.parse(self, list)
end

#parse_segment(buf, tag) ⇒ Object

:nodoc:


1008
1009
1010
# File 'lib/edi4r/edifact.rb', line 1008

def parse_segment(buf, tag) # :nodoc:
  Segment.parse(self, buf, tag)
end

#preset_group(user_par) ⇒ Object

Internal use only!


940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
# File 'lib/edi4r/edifact.rb', line 940

def preset_group(user_par) # :nodoc:
  if (illegal_keys = user_par.keys - @@msggroup_default_keys) != []
    msg = "Illegal parameter(s) found: #{illegal_keys.join(', ')}\n"
    msg += "Valid param keys (symbols): #{@@msggroup_default_keys.join(', ')}"
    raise ArgumentError, msg
  end
  par = @@msggroup_defaults.merge( user_par )

  @name = par[:msg_type]
  @version = par[:version]
  @release = par[:release]
  @resp_agency = par[:resp_agency]
  @subset = par[:assigned_code]
  # FIXME: Eliminate use of @version, @release, @resp_agency, @subset
  #        They get outdated whenever their UNG counterparts are changed
  #        Try to keep @name updated, or pass it a generic name
end

#to_sObject


1020
1021
1022
1023
# File 'lib/edi4r/edifact.rb', line 1020

def to_s
  postfix = '' << root.una.seg_term << root.e_linebreak
  super( postfix )
end

#validate(err_count = 0) ⇒ Object


1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
# File 'lib/edi4r/edifact.rb', line 1026

def validate( err_count=0 )

  # Consistency checks

  if (a=@trailer.d0060) != (b=self.size)
    warn "UNE: DE 0060 (#{a}) does not match number of messages (#{b})"
    err_count += 1
  end
  a, b = @trailer.d0048, @header.d0048
  if a != b
    warn "UNE: DE 0048 (#{a}) does not match reference in UNG (#{b})"
    err_count += 1
  end

  # FIXME: Check if messages are uniquely numbered

  super
end