[open-ils-commits] r812 - in acq_edi/trunk: lib/edi test (mbklein)
svn at svn.open-ils.org
svn at svn.open-ils.org
Wed Mar 3 16:22:58 EST 2010
Author: mbklein
Date: 2010-03-03 16:22:53 -0500 (Wed, 03 Mar 2010)
New Revision: 812
Modified:
acq_edi/trunk/lib/edi/edi2json.rb
acq_edi/trunk/lib/edi/mapper.rb
acq_edi/trunk/test/map_spec.rb
acq_edi/trunk/test/openils_map_spec.rb
Log:
Fixed round-tripping of JSON<->EDI; slightly changed JSON format again
Modified: acq_edi/trunk/lib/edi/edi2json.rb
===================================================================
--- acq_edi/trunk/lib/edi/edi2json.rb 2010-03-02 21:42:25 UTC (rev 811)
+++ acq_edi/trunk/lib/edi/edi2json.rb 2010-03-03 21:22:53 UTC (rev 812)
@@ -9,22 +9,39 @@
result = {}
self.each { |child|
+ if self[child.name].length > 1 and result[child.name].nil?
+ result[child.name] = []
+ end
if child.is_a?(Collection)
+ # Data elements first
hash = child.to_hash
- result[child.name] = hash unless hash.empty?
- unless self.children.empty?
- segments = []
- self.children.each { |segment|
- segments << [segment.name, segment.to_hash]
- }
- result[self.sg_name] = segments
+ unless hash.empty?
+ if result[child.name].is_a?(Array)
+ result[child.name] << hash
+ else
+ result[child.name] = hash
+ end
end
else
unless child.value.nil?
- result[child.name] = child.value
+ if result[child.name].is_a?(Array)
+ result[child.name] << child.value
+ else
+ result[child.name] = child.value
+ end
end
end
}
+
+ # Segment groups last
+ if self.respond_to?(:children) and (self.children.empty? == false)
+ segments = []
+ self.children.each { |segment|
+ segments << [segment.name, segment.to_hash]
+ }
+ result[self.sg_name] = segments
+ end
+
result
end
@@ -40,14 +57,18 @@
messages = []
self.each { |message|
- messages << [message.name, message.to_hash]
+ messages << {message.name => message.to_hash}
}
{
- 'UNA' => self.una.to_s,
- 'header' => [self.header.name, self.header.to_hash],
- 'body' => messages,
- 'trailer' => [self.trailer.name, self.trailer.to_hash]
+ 'UNA' => self.una.to_hash,
+ 'sender' => self.header.cS002.d0004,
+ 'sender_qual' => self.header.cS002.d0007,
+ 'recipient' => self.header.cS003.d0010,
+ 'recipient_qual' => self.header.cS003.d0007,
+ 'header' => [self.header.name, self.header.to_hash],
+ 'body' => messages,
+ 'trailer' => [self.trailer.name, self.trailer.to_hash]
}
end
@@ -57,20 +78,26 @@
def to_hash
segments = []
-
+ segments << [self.header.name, self.header.to_hash]
self.find_all { |segment|
segment.level < 2
}.each { |segment|
segments << [segment.name, segment.to_hash]
}
segments << [self.trailer.name, self.trailer.to_hash]
- {
- 'header' => [self.header.name, self.header.to_hash],
- 'body' => segments,
- 'trailer' => [self.trailer.name, self.trailer.to_hash]
- }
+ segments
end
end
+class E::UNA
+ def to_hash
+ result = {}
+ [:ce_sep,:de_sep,:decimal_sign,:esc_char,:rep_sep,:seg_term].each { |field|
+ result[field.to_s] = self.send(field).chr
+ }
+ result
+ end
+end
+
end
\ No newline at end of file
Modified: acq_edi/trunk/lib/edi/mapper.rb
===================================================================
--- acq_edi/trunk/lib/edi/mapper.rb 2010-03-02 21:42:25 UTC (rev 811)
+++ acq_edi/trunk/lib/edi/mapper.rb 2010-03-03 21:22:53 UTC (rev 812)
@@ -22,14 +22,14 @@
class Mapper
extend Forwardable
- attr :message
+ attr :message, :ic
attr_accessor :defaults
- def_delegators :@ic, :charset, :empty?, :groups_created, :header,
- :illegal_charset_pattern, :inspect, :is_iedi?, :messages_created,
- :output_mode, :output_mode=, :show_una, :show_una=, :syntax, :to_s,
- :to_xml, :to_xml_header, :to_xml_trailer, :trailer, :una, :validate,
- :version
-
+# def_delegators :@ic, :charset, :empty?, :groups_created, :header,
+# :illegal_charset_pattern, :inspect, :is_iedi?, :messages_created,
+# :output_mode, :output_mode=, :show_una, :show_una=, :syntax, :to_s,
+# :to_xml, :to_xml_header, :to_xml_trailer, :trailer, :una, :validate,
+# :version
+
class << self
def defaults
@defaults || {}
@@ -106,19 +106,46 @@
struct['msg_opts'].each_pair { |k,v| json_msg_opts[k.to_sym] = v }
end
- result = self.new(struct['msg_type'], json_msg_opts, ic_opts.merge(json_opts))
- result.add(struct['msg'])
+ result = self.new(ic_opts.merge(json_opts))
+
+ ['header','trailer'].each { |envseg|
+ if struct[envseg]
+ target = result.send(envseg.to_sym)
+ struct[envseg].last.each_pair { |de,val|
+ if val.is_a?(Hash)
+ val.each_pair { |cde,sval|
+ target[de][0][cde][0].value = sval
+ }
+ else
+ target[de][0].value = val
+ end
+ }
+ end
+ }
+
+ struct['body'].each { |msg_def|
+ msg_def.each_pair { |msg_type, msg_body|
+ if unh = msg_body.find { |s| s[0] == 'UNH' }
+ version_info = unh[1]['S009']
+ json_msg_opts[:resp_agency] = version_info['0051']
+ json_msg_opts[:version] = version_info['0052']
+ json_msg_opts[:release] = version_info['0054']
+ end
+ result.add_message(msg_type, json_msg_opts)
+ result.add(msg_body)
+ }
+ }
result.finalize
end
- def initialize(msg_type, msg_opts = {}, ic_opts = {})
+ def initialize(ic_opts = {})
# Bug in edi4r 0.9 -- sometimes :recipient is used; sometimes :recip. It doesn't
# work. We'll override it.
local_ic_opts = ic_opts.reject { |k,v| [:sender,:sender_qual,:recipient,:recipient_qual].include?(k) }
@ic = EDI::E::Interchange.new(local_ic_opts || {})
# Apply any envelope defaults.
- ['UNA','UNB','UNZ'].each { |seg|
+ ['UNB','UNZ'].each { |seg|
seg_defs = self.class.defaults[seg]
if seg_defs
seg_defs.each_pair { |cde,defs|
@@ -136,7 +163,9 @@
@ic.header.cS002.d0007 = ic_opts[:sender_qual] unless ic_opts[:sender_qual].nil?
@ic.header.cS003.d0010 = ic_opts[:recipient] unless ic_opts[:recipient].nil?
@ic.header.cS003.d0007 = ic_opts[:recipient_qual] unless ic_opts[:recipient_qual].nil?
-
+ end
+
+ def add_message(msg_type, msg_opts = {})
@message = @ic.new_message( { :msg_type => msg_type, :version => 'D', :release => '96A', :resp_agency => 'UN' }.merge(msg_opts || {}) )
@ic.add(@message,false)
end
@@ -166,16 +195,26 @@
@ic.to_s
end
+ def method_missing(sym, *args)
+ if @ic.respond_to?(sym)
+ @ic.send(sym, *args)
+ else
+ super(sym, *args)
+ end
+ end
+
private
def add_segment(seg_name, value)
if seg_name =~ /^[A-Z]{3}$/
- seg = @message.new_segment(seg_name)
- @message.add(seg)
- default = self.class.defaults[seg_name]
- data = default.nil? ? value : default.merge(value)
- data.each_pair { |de,val|
- add_element(seg,de,val,default)
- }
+ if seg_name !~ /^UN[HT]$/
+ seg = @message.new_segment(seg_name)
+ @message.add(seg)
+ default = self.class.defaults[seg_name]
+ data = default.nil? ? value : default.merge(value)
+ data.each_pair { |de,val|
+ add_element(seg,de,val,default)
+ }
+ end
else
apply_mapping(seg_name, value)
end
@@ -184,7 +223,9 @@
def add_element(parent, de, value, default)
default = default[de] unless default.nil?
- if value.is_a?(Hash)
+ if de =~ /^SG[0-9]+$/
+ value.each { |v| self.add(*v) }
+ elsif value.is_a?(Hash)
new_parent = parent.send("c#{de}")
data = default.nil? ? value : default.merge(value)
data.each_pair { |k,v| add_element(new_parent,k,v,default) }
Modified: acq_edi/trunk/test/map_spec.rb
===================================================================
--- acq_edi/trunk/test/map_spec.rb 2010-03-02 21:42:25 UTC (rev 811)
+++ acq_edi/trunk/test/map_spec.rb 2010-03-03 21:22:53 UTC (rev 812)
@@ -5,7 +5,8 @@
describe EDI::E::Mapper do
before(:each) do
- @map = EDI::E::Mapper.new('ORDERS')
+ @map = EDI::E::Mapper.new
+ @map.add_message('ORDERS')
end
it "should chunk text" do
@@ -42,7 +43,8 @@
end
it "should properly fill in interchange envelope defaults" do
- map = EDI::E::Mapper.new('ORDERS', nil, {:sender => '123456', :recipient => '654321'})
+ map = EDI::E::Mapper.new({:sender => '123456', :recipient => '654321'})
+ map.add_message('ORDERS')
map.to_s.should =~ /UNA:\+\.\? 'UNB\+UNOB:3\+123456\+654321\+[0-9]{6}:[0-9]{4}\+1'UNH\+1\+ORDERS:D:96A:UN'UNT\+2\+1'UNZ\+1\+1'/
end
@@ -112,7 +114,7 @@
}
# Can't compare everything because of timestamping, so we'll just compare
# the bodies for a high degree of confidence
- interchange.to_hash['body'].should == [["ORDERS", {"trailer"=>["UNT", {"0074"=>33, "0062"=>"1"}], "body"=>[["BGM", {"C002"=>{"1001"=>"220"}, "1225"=>"9", "1004"=>"2"}], ["DTM", {"C507"=>{"2005"=>"137", "2380"=>"20090331", "2379"=>"102"}}], ["NAD", {"C082"=>{"3039"=>"3472205", "3055"=>"91"}, "SG2"=>[["RFF", {"C506"=>{"1153"=>"API", "1154"=>"3472205 0001"}}]], "3035"=>"BY"}], ["NAD", {"C082"=>{"3039"=>"3472205", "3055"=>"31B"}, "SG2"=>[["RFF", {"C506"=>{"1153"=>"API", "1154"=>"3472205 0001"}}]], "3035"=>"BY"}], ["NAD", {"C082"=>{"3039"=>"1556150", "3055"=>"31B"}, "3035"=>"SU"}], ["NAD", {"C082"=>{"3039"=>"1556150", "3055"=>"91"}, "SG2"=>[["RFF", {"C506"=>{"1153"=>"IA", "1154"=>"1865"}}]], "3035"=>"SU"}], ["CUX", {"C504"=>{"6345"=>"USD", "6347"=>"2", "6343"=>"9"}}], ["LIN", {"SG25"=>[["PIA", {"C212"=>{"7140"=>"03-0010837", "7143"=>"SA"}, "4347"=>"5"}], ["IMD", {"C273"=>{"7008"=>"Discernment"}, "7077"=>"F", "7081"=>"BTI"}], ["IMD", {"C273"=>{"7008"=>"Concord Records,"}, "7077"=>"F", "7081"=>"BPU"}], ["IMD", {"C273"=>{"7008"=>"1986."}, "7077"=>"F", "7081"=>"BPD"}], ["IMD", {"C273"=>{"7008"=>"1 sound disc :"}, "7077"=>"F", "7081"=>"BPH"}], ["QTY", {"C186"=>{"6060"=>2, "6063"=>"21"}}], ["PRI", {"C509"=>{"5125"=>"AAB", "5118"=>35.95}}], ["RFF", {"C506"=>{"1153"=>"LI", "1154"=>"2/1"}}]], "1082"=>1}], ["LIN", {"SG25"=>[["PIA", {"C212"=>{"7140"=>"03-0010840", "7143"=>"SA"}, "4347"=>"5"}], ["IMD", {"C273"=>{"7008"=>"The inner source"}, "7077"=>"F", "7081"=>"BTI"}], ["IMD", {"C273"=>{"7008"=>"Duke, George, 1946-"}, "7077"=>"F", "7081"=>"BAU"}], ["IMD", {"C273"=>{"7008"=>"MPS Records,"}, "7077"=>"F", "7081"=>"BPU"}], ["IMD", {"C273"=>{"7008"=>"1973."}, "7077"=>"F", "7081"=>"BPD"}], ["IMD", {"C273"=>{"7008"=>"2 sound discs :"}, "7077"=>"F", "7081"=>"BPH"}], ["QTY", {"C186"=>{"6060"=>1, "6063"=>"21"}}], ["PRI", {"C509"=>{"5125"=>"AAB", "5118"=>28.95}}], ["RFF", {"C506"=>{"1153"=>"LI", "1154"=>"2/2"}}]], "1082"=>2}], ["UNS", {"0081"=>"S"}], ["CNT", {"C270"=>{"6069"=>"2", "6066"=>2}}], ["UNT", {"0074"=>33, "0062"=>"1"}]], "header"=>["UNH", {"S009"=>{"0052"=>"D", "0065"=>"ORDERS", "0054"=>"96A", "0051"=>"UN"}, "0062"=>"1"}]}]]
+ interchange.to_hash['body'].should == [{"ORDERS"=>[["UNH", {"S009"=>{"0052"=>"D", "0054"=>"96A", "0065"=>"ORDERS", "0051"=>"UN"}, "0062"=>"1"}], ["BGM", {"1225"=>"9", "C002"=>{"1001"=>"220"}, "1004"=>"2"}], ["DTM", {"C507"=>{"2379"=>"102", "2380"=>"20090331", "2005"=>"137"}}], ["NAD", {"C080"=>{"3036"=>[]}, "C058"=>{"3124"=>[]}, "C059"=>{"3042"=>[]}, "C082"=>{"3039"=>"3472205", "3055"=>"91"}, "SG2"=>[["RFF", {"C506"=>{"1153"=>"API", "1154"=>"3472205 0001"}}]], "3035"=>"BY"}], ["NAD", {"C080"=>{"3036"=>[]}, "C058"=>{"3124"=>[]}, "C059"=>{"3042"=>[]}, "C082"=>{"3039"=>"3472205", "3055"=>"31B"}, "SG2"=>[["RFF", {"C506"=>{"1153"=>"API", "1154"=>"3472205 0001"}}]], "3035"=>"BY"}], ["NAD", {"C080"=>{"3036"=>[]}, "C058"=>{"3124"=>[]}, "C059"=>{"3042"=>[]}, "C082"=>{"3039"=>"1556150", "3055"=>"31B"}, "3035"=>"SU"}], ["NAD", {"C080"=>{"3036"=>[]}, "C058"=>{"3124"=>[]}, "C059"=>{"3042"=>[]}, "C082"=>{"3039"=>"1556150", "3055"=>"91"}, "SG2"=>[["RFF", {"C506"=>{"1153"=>"IA", "1154"=>"1865"}}]], "3035"=>"SU"}], ["CUX", {"C504"=>[{"6345"=>"USD", "6347"=>"2", "6343"=>"9"}]}], ["LIN", {"SG25"=>[["PIA", {"C212"=>[{"7140"=>"03-0010837", "7143"=>"SA"}], "4347"=>"5"}], ["IMD", {"C273"=>{"7008"=>["Discernment"]}, "7077"=>"F", "7081"=>"BTI"}], ["IMD", {"C273"=>{"7008"=>["Concord Records,"]}, "7077"=>"F", "7081"=>"BPU"}], ["IMD", {"C273"=>{"7008"=>["1986."]}, "7077"=>"F", "7081"=>"BPD"}], ["IMD", {"C273"=>{"7008"=>["1 sound disc :"]}, "7077"=>"F", "7081"=>"BPH"}], ["QTY", {"C186"=>{"6060"=>2, "6063"=>"21"}}], ["PRI", {"C509"=>{"5125"=>"AAB", "5118"=>35.95}}], ["RFF", {"C506"=>{"1153"=>"LI", "1154"=>"2/1"}}]], "1082"=>1}], ["LIN", {"SG25"=>[["PIA", {"C212"=>[{"7140"=>"03-0010840", "7143"=>"SA"}], "4347"=>"5"}], ["IMD", {"C273"=>{"7008"=>["The inner source"]}, "7077"=>"F", "7081"=>"BTI"}], ["IMD", {"C273"=>{"7008"=>["Duke, George, 1946-"]}, "7077"=>"F", "7081"=>"BAU"}], ["IMD", {"C273"=>{"7008"=>["MPS Records,"]}, "7077"=>"F", "7081"=>"BPU"}], ["IMD", {"C273"=>{"7008"=>["1973."]}, "7077"=>"F", "7081"=>"BPD"}], ["IMD", {"C273"=>{"7008"=>["2 sound discs :"]}, "7077"=>"F", "7081"=>"BPH"}], ["QTY", {"C186"=>{"6060"=>1, "6063"=>"21"}}], ["PRI", {"C509"=>{"5125"=>"AAB", "5118"=>28.95}}], ["RFF", {"C506"=>{"1153"=>"LI", "1154"=>"2/2"}}]], "1082"=>2}], ["UNS", {"0081"=>"S"}], ["CNT", {"C270"=>{"6069"=>"2", "6066"=>2}}], ["UNT", {"0074"=>33, "0062"=>"1"}]]}]
end
end
\ No newline at end of file
Modified: acq_edi/trunk/test/openils_map_spec.rb
===================================================================
--- acq_edi/trunk/test/openils_map_spec.rb 2010-03-02 21:42:25 UTC (rev 811)
+++ acq_edi/trunk/test/openils_map_spec.rb 2010-03-03 21:22:53 UTC (rev 812)
@@ -3,7 +3,8 @@
describe OpenILS::Mapper do
before(:each) do
- @map = OpenILS::Mapper.new('ORDERS')
+ @map = OpenILS::Mapper.new
+ @map.add_message('ORDERS')
end
it "should add both qualified and unqualified buyer/vendor fields" do
@@ -32,7 +33,7 @@
it "should create a message from high-level JEDI input" do
json = File.read(File.join(File.dirname(__FILE__), 'test_po.json'))
- @map = OpenILS::Mapper.from_json(%{{ "msg_type": "ORDERS", "msg": #{json}, "sender": "123456", "recipient": {"id": "999999999", "id-qualifier": "1"}}})
+ @map = OpenILS::Mapper.from_json(%{{ "body": [{ "ORDERS": #{json}}], "sender": "123456", "recipient": {"id": "999999999", "id-qualifier": "1"}}})
@map.message.to_s.should == "UNH+1+ORDERS:D:96A:UN'BGM+220+2+9'DTM+137:20090331:102'NAD+BY+3472205::91'RFF+API:3472205 0001'NAD+BY+3472205::31B'RFF+API:3472205 0001'NAD+SU+1556150::31B'NAD+SU+1556150::91'RFF+IA:1865'CUX+2:USD:9'LIN+1'PIA+5+03-0010837:SA'IMD+F+BTI+:::Discernment'IMD+F+BPU+:::Concord Records,'IMD+F+BPD+:::1986.'IMD+F+BPH+:::1 sound disc ?:'QTY+21:2'PRI+AAB:35.95'RFF+LI:2/1'LIN+2'PIA+5+03-0010840:SA'IMD+F+BTI+:::The inner source'IMD+F+BAU+:::Duke, George, 1946-'IMD+F+BPU+:::MPS Records,'IMD+F+BPD+:::1973.'IMD+F+BPH+:::2 sound discs ?:'QTY+21:1'PRI+AAB:28.95'RFF+LI:2/2'UNS+S'CNT+2:2'UNT+33+1'"
@map.header.cS002.to_s.should == "123456:31B"
@map.header.cS003.to_s.should == "999999999:1"
More information about the open-ils-commits
mailing list