eancom 0.1.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +190 -5
  3. data/.gitlab-ci.yml +25 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile.lock +22 -18
  6. data/README.md +46 -0
  7. data/bin/console +3 -2
  8. data/definitions/desadv/d01b.rb +251 -0
  9. data/definitions/desadv/d96a.rb +208 -87
  10. data/definitions/invoic/d01b.rb +559 -0
  11. data/definitions/invoic/d96a.rb +389 -0
  12. data/definitions/invrpt/d01b.rb +134 -0
  13. data/definitions/invrpt/d96a.rb +125 -0
  14. data/definitions/orders/d01b.rb +182 -0
  15. data/definitions/orders/d96b.rb +198 -0
  16. data/definitions/ordrsp/d01b.rb +251 -0
  17. data/definitions/ordrsp/d96b.rb +226 -0
  18. data/definitions/pricat/d01b.rb +225 -0
  19. data/definitions/pricat/d96b.rb +207 -0
  20. data/definitions/retann/d01b.rb +172 -0
  21. data/definitions/retann/d96b.rb +221 -0
  22. data/definitions/segments/ajt.rb +47 -0
  23. data/definitions/segments/alc.rb +328 -0
  24. data/definitions/segments/ali.rb +93 -0
  25. data/definitions/segments/bgm.rb +395 -0
  26. data/definitions/segments/cav.rb +122 -0
  27. data/definitions/segments/cci.rb +136 -0
  28. data/definitions/segments/cdi.rb +39 -0
  29. data/definitions/segments/cnt.rb +82 -0
  30. data/definitions/segments/cps.rb +76 -0
  31. data/definitions/segments/cta.rb +89 -0
  32. data/definitions/segments/cux.rb +174 -0
  33. data/definitions/segments/dgs.rb +34 -0
  34. data/definitions/segments/doc.rb +45 -0
  35. data/definitions/segments/dtm.rb +243 -0
  36. data/definitions/segments/efi.rb +67 -0
  37. data/definitions/segments/eqd.rb +37 -0
  38. data/definitions/segments/ftx.rb +165 -0
  39. data/definitions/segments/gin.rb +113 -0
  40. data/definitions/segments/imd.rb +360 -0
  41. data/definitions/segments/inv.rb +94 -0
  42. data/definitions/segments/lin.rb +133 -0
  43. data/definitions/segments/loc.rb +137 -0
  44. data/definitions/segments/mea.rb +189 -0
  45. data/definitions/segments/moa.rb +228 -0
  46. data/definitions/segments/nad.rb +314 -0
  47. data/definitions/segments/pac.rb +262 -0
  48. data/definitions/segments/pat.rb +171 -0
  49. data/definitions/segments/pcd.rb +72 -0
  50. data/definitions/segments/pci.rb +110 -0
  51. data/definitions/segments/pgi.rb +152 -0
  52. data/definitions/segments/pia.rb +501 -0
  53. data/definitions/segments/pri.rb +208 -0
  54. data/definitions/segments/qty.rb +293 -0
  55. data/definitions/segments/rff.rb +210 -0
  56. data/definitions/segments/rte.rb +52 -0
  57. data/definitions/segments/tax.rb +266 -0
  58. data/definitions/segments/tdt.rb +278 -0
  59. data/definitions/segments/tod.rb +64 -0
  60. data/definitions/segments/tru.rb +34 -0
  61. data/definitions/segments/una.rb +85 -0
  62. data/definitions/segments/unb.rb +284 -0
  63. data/definitions/segments/unh.rb +183 -0
  64. data/definitions/segments/uns.rb +40 -0
  65. data/definitions/segments/unt.rb +48 -0
  66. data/definitions/segments/unz.rb +48 -0
  67. data/definitions/slsrpt/d01b.rb +206 -0
  68. data/definitions/slsrpt/d96a.rb +199 -0
  69. data/eancom.gemspec +2 -1
  70. data/lib/eancom.rb +61 -16
  71. data/lib/eancom/definition.rb +1 -1
  72. data/lib/eancom/edifact.rb +60 -13
  73. data/lib/eancom/edifact/body.rb +63 -0
  74. data/lib/eancom/edifact/composite.rb +38 -0
  75. data/lib/eancom/edifact/data.rb +108 -0
  76. data/lib/eancom/edifact/document.rb +43 -11
  77. data/lib/eancom/edifact/document_element.rb +26 -0
  78. data/lib/eancom/edifact/footer.rb +7 -0
  79. data/lib/eancom/edifact/header.rb +15 -0
  80. data/lib/eancom/edifact/item.rb +40 -0
  81. data/lib/eancom/edifact/message.rb +24 -16
  82. data/lib/eancom/edifact/segment.rb +131 -12
  83. data/lib/eancom/edifact/segments/ajt.rb +32 -0
  84. data/lib/eancom/edifact/segments/alc.rb +61 -0
  85. data/lib/eancom/edifact/segments/ali.rb +50 -0
  86. data/lib/eancom/edifact/segments/bgm.rb +46 -0
  87. data/lib/eancom/edifact/segments/cav.rb +47 -0
  88. data/lib/eancom/edifact/segments/cci.rb +53 -0
  89. data/lib/eancom/edifact/segments/cdi.rb +30 -0
  90. data/lib/eancom/edifact/segments/cnt.rb +40 -0
  91. data/lib/eancom/edifact/segments/cps.rb +33 -0
  92. data/lib/eancom/edifact/segments/cta.rb +30 -0
  93. data/lib/eancom/edifact/segments/cux.rb +60 -0
  94. data/lib/eancom/edifact/segments/dgs.rb +31 -0
  95. data/lib/eancom/edifact/segments/doc.rb +30 -0
  96. data/lib/eancom/edifact/segments/dtm.rb +47 -0
  97. data/lib/eancom/edifact/segments/efi.rb +38 -0
  98. data/lib/eancom/edifact/segments/eqd.rb +30 -0
  99. data/lib/eancom/edifact/segments/ftx.rb +63 -0
  100. data/lib/eancom/edifact/segments/gin.rb +45 -0
  101. data/lib/eancom/edifact/segments/imd.rb +69 -0
  102. data/lib/eancom/edifact/segments/inv.rb +43 -0
  103. data/lib/eancom/edifact/segments/lin.rb +47 -0
  104. data/lib/eancom/edifact/segments/loc.rb +46 -0
  105. data/lib/eancom/edifact/segments/mea.rb +54 -0
  106. data/lib/eancom/edifact/segments/moa.rb +45 -0
  107. data/lib/eancom/edifact/segments/nad.rb +112 -0
  108. data/lib/eancom/edifact/segments/pac.rb +56 -0
  109. data/lib/eancom/edifact/segments/pat.rb +37 -0
  110. data/lib/eancom/edifact/segments/pcd.rb +33 -0
  111. data/lib/eancom/edifact/segments/pci.rb +40 -0
  112. data/lib/eancom/edifact/segments/pgi.rb +45 -0
  113. data/lib/eancom/edifact/segments/pia.rb +108 -0
  114. data/lib/eancom/edifact/segments/pri.rb +53 -0
  115. data/lib/eancom/edifact/segments/qty.rb +44 -0
  116. data/lib/eancom/edifact/segments/rff.rb +47 -0
  117. data/lib/eancom/edifact/segments/rte.rb +33 -0
  118. data/lib/eancom/edifact/segments/tax.rb +78 -0
  119. data/lib/eancom/edifact/segments/tdt.rb +57 -0
  120. data/lib/eancom/edifact/segments/tod.rb +33 -0
  121. data/lib/eancom/edifact/segments/tru.rb +31 -0
  122. data/lib/eancom/edifact/segments/una.rb +52 -0
  123. data/lib/eancom/edifact/segments/unb.rb +68 -0
  124. data/lib/eancom/edifact/segments/unh.rb +50 -0
  125. data/lib/eancom/edifact/segments/uns.rb +32 -0
  126. data/lib/eancom/edifact/segments/unt.rb +28 -0
  127. data/lib/eancom/edifact/segments/unz.rb +28 -0
  128. data/lib/eancom/edifact/structure.rb +90 -0
  129. data/lib/eancom/factory.rb +9 -8
  130. data/lib/eancom/parser.rb +7 -0
  131. data/lib/eancom/parser/document.rb +60 -0
  132. data/lib/eancom/parser/segment.rb +71 -0
  133. data/lib/eancom/version.rb +1 -1
  134. data/pricat.json +1 -0
  135. metadata +141 -9
  136. data/lib/eancom/edifact/element.rb +0 -16
  137. data/lib/eancom/edifact/envelope.rb +0 -24
@@ -0,0 +1,26 @@
1
+ module Eancom
2
+ module Edifact
3
+
4
+ class DocumentElement
5
+
6
+ attr_accessor :segments
7
+
8
+ def initialize
9
+ @segments = []
10
+ end
11
+
12
+ def segment(segment)
13
+ segments << segment
14
+ end
15
+
16
+ def to_s(debug: false)
17
+ stream = ""
18
+ segments.each do |segment|
19
+ stream << segment.to_edi
20
+ stream << "\n" if debug
21
+ end
22
+ stream
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,7 @@
1
+ module Eancom
2
+ module Edifact
3
+ class Footer < DocumentElement
4
+ # Why is this module empty?
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ module Eancom
2
+ module Edifact
3
+ class Header < DocumentElement
4
+
5
+ def to_json_hash
6
+ hash = {}
7
+ hash[:header] = {}
8
+ @segments.each do |segment|
9
+ hash[:header].merge! segment.to_json_hash
10
+ end
11
+ hash
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,40 @@
1
+ module Eancom
2
+ module Edifact
3
+ class Item
4
+
5
+ attr_accessor :hash
6
+
7
+ def initialize()
8
+ @hash = {}
9
+ end
10
+
11
+ def << (segment)
12
+ if name = group_name(segment)
13
+ @hash[name] = [] if @hash[name].nil?
14
+ @hash[name] << segment.to_json_hash
15
+ else
16
+ @hash.merge!(segment.to_json_hash)
17
+ end
18
+ end
19
+
20
+ def to_json_hash
21
+ @hash
22
+ end
23
+
24
+ def empty?
25
+ @hash.empty?
26
+ end
27
+
28
+ private
29
+
30
+ def group_name(segment)
31
+ if segment.item_group_name
32
+ segment.item_group_name
33
+ else
34
+ segment.group_name
35
+ end
36
+ end
37
+
38
+ end
39
+ end
40
+ end
@@ -1,31 +1,39 @@
1
1
  module Eancom
2
2
  module Edifact
3
- class Message < Element
3
+ class Message
4
+
5
+ attr_accessor :items, :hash
4
6
 
5
7
  def initialize()
6
- @me = Segment.new
7
- @segments = [@me]
8
+ @items = []
9
+ @hash = {}
8
10
  end
9
11
 
10
- def add_segment(segment)
11
- @segments << segment
12
+ def add_item(item)
13
+ @items << item
12
14
  end
13
15
 
14
- def composite(composite)
15
- @me.composite(composite)
16
+ def << (segment)
17
+ if name = group_name(segment)
18
+ @hash[name] = [] if @hash[name].nil?
19
+ @hash[name] << segment.to_json_hash
20
+ else
21
+ @hash.merge!(segment.to_json_hash)
22
+ end
16
23
  end
17
24
 
18
- def name=(name)
19
- @me.name = name
25
+ def to_json_hash
26
+ message_hash = {}
27
+ items_hash = { items: @items }
28
+ message_hash.merge!(@hash)
29
+ message_hash.merge!(items_hash)
30
+ message_hash
20
31
  end
21
32
 
22
- def to_s
23
- stream = ""
24
- @segments.each do |segment|
25
- stream << segment.to_s
26
- stream << DELIMITERS[:segment]
27
- end
28
- stream
33
+ private
34
+
35
+ def group_name(segment)
36
+ segment.group_name
29
37
  end
30
38
 
31
39
  end
@@ -1,26 +1,145 @@
1
1
  module Eancom
2
2
  module Edifact
3
3
  class Segment
4
- attr_accessor :name, :composites
4
+ attr_accessor :tag
5
5
 
6
- def initialize(name = "")
7
- @name = name
8
- @composites = []
6
+ class SegmentParserError < StandardError; end
7
+
8
+ def initialize(tag:)
9
+ @tag = tag
10
+ validate_structure
11
+ end
12
+
13
+ def self.initialize_by_components(structure, array)
14
+ begin
15
+ new(**structure.build_hash(array))
16
+ rescue StandardError => e
17
+ raise SegmentParserError.new(
18
+ "'Parser Error in structure #{structure.tag} with array #{array}.\n \
19
+ 'Inside Structure: \n \ '#{structure.to_s}.\n \
20
+ 'Error:\n \
21
+ '#{e}"
22
+ )
23
+ end
24
+ end
25
+
26
+ def validate_structure
27
+ attributes.each do |key, value|
28
+ next if value.nil?
29
+ structure.validate!(key, value)
30
+ end
9
31
  end
10
32
 
11
- def composite(content = "")
12
- @composites << content
33
+ def array
34
+ @array ||= structure.build_array(to_hash)
35
+ end
36
+
37
+ def structure
38
+ @structure ||= Eancom.find_structure(tag: tag)
13
39
  end
14
40
 
15
41
  def to_s
16
- stream = ""
17
- stream << name
18
- @composites.each do |composite|
19
- stream << DELIMITERS[:data]
20
- stream << composite
42
+ string = array.map do |e|
43
+ e = e.compact
44
+ next if e.empty?
45
+ [e.join(component_delimiter)]
46
+ end.join(data_delimiter)
47
+ clean_end_string(string)
48
+ string << segment_delimiter
49
+ string
50
+ end
51
+
52
+ def to_edi
53
+ to_s
54
+ end
55
+
56
+ def to_json_hash
57
+ raise NotImplementedError
58
+ end
59
+
60
+ def segment_type
61
+ raise NotImplementedError
62
+ end
63
+
64
+ def to_hash
65
+ attributes
66
+ end
67
+
68
+ def is_header?
69
+ segment_type == :header
70
+ end
71
+
72
+ def is_body?
73
+ segment_type == :body
74
+ end
75
+
76
+ def is_footer?
77
+ segment_type == :footer
78
+ end
79
+
80
+ def tag?(other)
81
+ tag == other
82
+ end
83
+
84
+ def starts_message?
85
+ false
86
+ end
87
+
88
+ def starts_item?
89
+ false
90
+ end
91
+
92
+ def group_name
93
+ nil
94
+ end
95
+
96
+ def item_group_name
97
+ nil
98
+ end
99
+
100
+ private
101
+
102
+ def data_delimiter
103
+ DELIMITERS[:data]
104
+ end
105
+
106
+ def component_delimiter
107
+ DELIMITERS[:component]
108
+ end
109
+
110
+ def segment_delimiter
111
+ DELIMITERS[:segment]
112
+ end
113
+
114
+ def attributes
115
+ hash = {}
116
+ instance_variables.each do |var|
117
+ key = var.to_s.delete('@').to_sym
118
+ next if key == :structure
119
+ next if key == :array
120
+ value = instance_variable_get(var)
121
+ hash[key] = value
122
+ end
123
+ hash
124
+ end
125
+
126
+ def find_identifier(key)
127
+ dictionary = structure.find(key).dictionary
128
+ var = instance_variable_get('@' + key.to_s)
129
+ if dictionary[var]
130
+ dictionary[var][:identifier]
131
+ else
132
+ var
133
+ end
134
+ end
135
+
136
+ def clean_end_string(string)
137
+ while (string[-1] == data_delimiter)
138
+ string.chop!
21
139
  end
22
- stream
140
+ string
23
141
  end
142
+
24
143
  end
25
144
  end
26
145
  end
@@ -0,0 +1,32 @@
1
+ module Eancom
2
+ module Edifact
3
+ class AJT < Segment
4
+ TAG = 'AJT'.freeze
5
+ TYPE = :body.freeze
6
+
7
+ attr_reader :segment_type
8
+
9
+ def initialize(
10
+ tag: nil,
11
+ adjustment_reason_description:
12
+ )
13
+ @tag = tag
14
+ @adjustment_reason_description = adjustment_reason_description
15
+
16
+ super(tag: tag || TAG)
17
+ end
18
+
19
+ def to_json_hash
20
+ hash = {}
21
+ if @adjustment_reason_description
22
+ hash.merge!(adjustment_reason_description: find_identifier(:adjustment_reason_description))
23
+ end
24
+ hash
25
+ end
26
+
27
+ def segment_type
28
+ TYPE
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,61 @@
1
+ module Eancom
2
+ module Edifact
3
+ class ALC < Segment
4
+ TAG = 'ALC'.freeze
5
+ TYPE = :body.freeze
6
+
7
+ attr_reader :segment_type
8
+
9
+ def initialize(
10
+ tag: nil,
11
+ allowance_or_charge_code_qualifier:,
12
+ allowance_or_charge_identifier: nil,
13
+ allowance_or_charge_identification_code: nil,
14
+ settlement_mean_code: nil,
15
+ calculation_sequence_code: nil,
16
+ special_service_description_code: nil,
17
+ code_list_identification_code: nil,
18
+ code_list_responsible_agency_code: nil,
19
+ special_service_description_1: nil,
20
+ special_service_description_2: nil
21
+ )
22
+ @tag = tag
23
+ @allowance_or_charge_code_qualifier = allowance_or_charge_code_qualifier
24
+ @allowance_or_charge_identifier = allowance_or_charge_identifier
25
+ @allowance_or_charge_identification_code = allowance_or_charge_identification_code
26
+ @settlement_mean_code = settlement_mean_code
27
+ @calculation_sequence_code = calculation_sequence_code
28
+ @special_service_description_code = special_service_description_code
29
+ @code_list_identification_code = code_list_identification_code
30
+ @code_list_responsible_agency_code = code_list_responsible_agency_code
31
+ @special_service_description_1 = special_service_description_1
32
+ @special_service_description_2 = special_service_description_2
33
+ super(tag: tag || TAG)
34
+ end
35
+
36
+ def to_json_hash
37
+ hash = {}
38
+ hash.merge!(allowance_or_charge_code_qualifier: find_identifier(:allowance_or_charge_code_qualifier)) if @allowance_or_charge_code_qualifier
39
+ hash.merge!(allowance_or_charge_identifier: @allowance_or_charge_identifier) if @allowance_or_charge_identifier
40
+ hash.merge!(allowance_or_charge_identification_code: find_identifier(:allowance_or_charge_identification_code)) if @allowance_or_charge_identification_code
41
+ hash.merge!(settlement_mean_code: find_identifier(:settlement_mean_code)) if @settlement_mean_code
42
+ hash.merge!(calculation_sequence_code: find_identifier(:calculation_sequence_code)) if @calculation_sequence_code
43
+ hash.merge!(special_service_description_code: find_identifier(:special_service_description_code)) if @special_service_description_code
44
+ hash.merge!(code_list_identification_code: @code_list_identification_code) if @code_list_identification_code
45
+ hash.merge!(code_list_responsible_agency_code: find_identifier(:code_list_responsible_agency_code)) if @code_list_responsible_agency_code
46
+ hash.merge!(special_service_description_1: @special_service_description_1) if @special_service_description_1
47
+ hash.merge!(special_service_description_2: @special_service_description_2) if @special_service_description_2
48
+ hash
49
+ end
50
+
51
+ def group_name
52
+ 'allowances_or_charges'
53
+ end
54
+
55
+ def segment_type
56
+ TYPE
57
+ end
58
+
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,50 @@
1
+ module Eancom
2
+ module Edifact
3
+ class ALI < Segment
4
+ TAG = 'ALI'.freeze
5
+ TYPE = :body
6
+
7
+ attr_reader :segment_type
8
+
9
+ def initialize(
10
+ tag: nil,
11
+ country_of_origin_name_code: nil,
12
+ duty_regime_type_code: nil,
13
+ special_condition_code_1: nil,
14
+ special_condition_code_2: nil,
15
+ special_condition_code_3: nil,
16
+ special_condition_code_4: nil,
17
+ special_condition_code_5: nil
18
+ )
19
+ @tag = tag
20
+ @country_of_origin_name_code = country_of_origin_name_code
21
+ @duty_regime_type_code = duty_regime_type_code
22
+ @special_condition_code_1 = special_condition_code_1
23
+ @special_condition_code_2 = special_condition_code_2
24
+ @special_condition_code_3 = special_condition_code_3
25
+ @special_condition_code_4 = special_condition_code_4
26
+ @special_condition_code_5 = special_condition_code_5
27
+
28
+ super(tag: tag || TAG)
29
+ end
30
+
31
+ def to_json_hash
32
+ hash = {}
33
+ hash.merge!(country_of_origin_name_code: @country_of_origin_name_code) if @country_of_origin_name_code
34
+ hash.merge!(duty_regime_type_code: @duty_regime_type_code) if @duty_regime_type_code
35
+ hash.merge!(special_condition_code_1: find_identifier(:special_condition_code_1)) if @special_condition_code_1
36
+ hash.merge!(special_condition_code_2: find_identifier(:special_condition_code_2)) if @special_condition_code_2
37
+ hash.merge!(special_condition_code_3: find_identifier(:special_condition_code_3)) if @special_condition_code_3
38
+ hash.merge!(special_condition_code_4: find_identifier(:special_condition_code_4)) if @special_condition_code_4
39
+ hash.merge!(special_condition_code_5: find_identifier(:special_condition_code_5)) if @special_condition_code_5
40
+ outer_hash = {}
41
+ outer_hash.merge!(additional_information: hash)
42
+ outer_hash
43
+ end
44
+
45
+ def segment_type
46
+ TYPE
47
+ end
48
+ end
49
+ end
50
+ end