cxml-ruby 0.5.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +1 -0
  3. data/.rubocop.yml +4 -0
  4. data/CHANGELOG.md +22 -0
  5. data/cxml-ruby.gemspec +1 -0
  6. data/lib/cxml-ruby.rb +1 -1
  7. data/lib/cxml/address.rb +4 -1
  8. data/lib/cxml/comment.rb +9 -0
  9. data/lib/cxml/contact.rb +4 -1
  10. data/lib/cxml/country_code.rb +9 -0
  11. data/lib/cxml/credential.rb +1 -1
  12. data/lib/cxml/deposit_amount.rb +9 -0
  13. data/lib/cxml/document.rb +4 -4
  14. data/lib/cxml/document_node.rb +11 -5
  15. data/lib/cxml/invoice_detail_item.rb +11 -11
  16. data/lib/cxml/invoice_detail_item_reference.rb +3 -1
  17. data/lib/cxml/invoice_detail_request_header.rb +5 -5
  18. data/lib/cxml/invoice_detail_summary.rb +6 -4
  19. data/lib/cxml/item_detail.rb +5 -1
  20. data/lib/cxml/order_request_header.rb +11 -10
  21. data/lib/cxml/parser.rb +7 -2
  22. data/lib/cxml/phone.rb +13 -0
  23. data/lib/cxml/postal_address.rb +1 -1
  24. data/lib/cxml/punch_out_setup_request.rb +3 -2
  25. data/lib/cxml/telephone_number.rb +11 -0
  26. data/lib/cxml/version.rb +1 -1
  27. data/spec/document_spec.rb +39 -1
  28. data/spec/fixtures/1.2.014-cXML.dtd +4184 -0
  29. data/spec/fixtures/1.2.020-InvoiceDetail.dtd +4590 -0
  30. data/spec/fixtures/1.2.020-cXML.dtd +4917 -0
  31. data/spec/fixtures/1.2.037-InvoiceDetail.dtd +7287 -0
  32. data/spec/fixtures/document_node_with_unknown_attribute.xml +7 -0
  33. data/spec/fixtures/invoice_taxes_at_line_multiple_taxes.xml +1 -3
  34. data/spec/fixtures/item_in.xml +2 -1
  35. data/spec/fixtures/{order_request.cxml → order_request.xml} +0 -0
  36. data/spec/fixtures/punch_out_order_message_doc.xml +1 -1
  37. data/spec/fixtures/punch_out_setup_request_doc_with_ship_to.xml +7 -0
  38. data/spec/fixtures/response_status_200.xml +1 -1
  39. data/spec/fixtures/response_status_400.xml +2 -2
  40. data/spec/invoice_detail_request_spec.rb +21 -1
  41. data/spec/item_in_spec.rb +5 -0
  42. data/spec/output/.gitkeep +0 -0
  43. data/spec/punch_out_order_message_spec.rb +5 -0
  44. data/spec/punch_out_setup_request_spec.rb +2 -0
  45. data/spec/purchase_order_request_spec.rb +6 -1
  46. data/spec/sender_spec.rb +6 -0
  47. data/spec/spec_helper.rb +27 -0
  48. metadata +22 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a5aed2303e25923bfa9f60fc5f0156f277df0f08a4f5d2c1f86598f762d273f6
4
- data.tar.gz: 3a613e2eb5e2a6873e861624942ea04242f25f61ef883c5ab05925e16f4a7659
3
+ metadata.gz: 8fe5e0c45372ed39797b5501ba49e8339fad0728a574ccf74fce1c23629e2c72
4
+ data.tar.gz: f9512d489f5f1bcaa21dfe5d7b230c7c75d9e546e8c1f97e2b351f6a76b2428d
5
5
  SHA512:
6
- metadata.gz: a6a49b19ccd68bf63238deae57a4b07df188458bdb5684064d2f0bb5d8c4be7e98bb281dbab6a0660a4e41e462a80e620887df43e27691d8ea87d5e410bc4c54
7
- data.tar.gz: bd436f24c35a1fe90ebfc9ca83d5544b3341c604a73faf3381783ecf32b9d2755bcd2fdb0115c30f3d0fe1fc9442cd55da44f4e4a7dec040551319a1eedf6d4c
6
+ metadata.gz: 11c6f9f315eddf474decf57927b675b638a55dcc32d574831ce1a9dc7ba10b0af12af3d92636b112a7cb7a69de64c3284629c30f45177f8bf25afacc7c218670
7
+ data.tar.gz: c304d098c3605d2818953608e29656ce1c289f505b7b14824e7d1c8cc871860ac89aea9a32158491baa254adf4000c8c9e754268e77c91e665d0114c0bc7c259
@@ -15,6 +15,7 @@ jobs:
15
15
  ruby-version: 2.6.x
16
16
  - name: Test with Rake
17
17
  run: |
18
+ sudo apt-get install libxml2-utils
18
19
  gem install bundler
19
20
  bundle install --jobs 4 --retry 3
20
21
  bundle exec rake
data/.rubocop.yml CHANGED
@@ -2,6 +2,7 @@ AllCops:
2
2
  Exclude:
3
3
  - Gemfile
4
4
  - vendor/**/*
5
+ NewCops: enable
5
6
 
6
7
  # # Disable checking for block length
7
8
  Metrics/BlockLength:
@@ -54,6 +55,9 @@ Style/Documentation:
54
55
  Style/ClassAndModuleChildren:
55
56
  Enabled: false
56
57
 
58
+ Style/ArrayCoercion:
59
+ Enabled: false
60
+
57
61
  Style/HashEachMethods:
58
62
  Enabled: true
59
63
 
data/CHANGELOG.md CHANGED
@@ -14,6 +14,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
14
14
 
15
15
  ---
16
16
 
17
+ ## [0.8.1] - 2021-05-24
18
+ ### Fixed
19
+ - Reorder the attributes output for `PunchoutSetupRequest`.
20
+
21
+ ## [0.8.0] - 2021-04-25
22
+ ### Changed
23
+ - Support continued parsing of child nodes if unknown attribute is encountered with `raise_unknown_elements` set to `false`.
24
+
25
+ ## [0.7.0] - 2021-01-12
26
+ ### Added
27
+ - Support parsing Phone tags.
28
+
29
+ ## [0.6.1] - 2020-09-04
30
+ ### Fixed
31
+ - Handle parsing CDATA tags in cXML content (Thanks @CRiva!).
32
+
33
+ ## [0.6.0] - 2020-05-01
34
+ ### Fixed
35
+ - Conform to cXML DTD spec for ordered output of child nodes.
36
+ ### Added
37
+ - Support parsing and validating output against DTDs in specs.
38
+
17
39
  ## [0.5.0] - 2020-04-30
18
40
  ### Added
19
41
  - Support parsing and specifying different DTDs.
data/cxml-ruby.gemspec CHANGED
@@ -12,6 +12,7 @@ Gem::Specification.new do |s|
12
12
  s.authors = ['Josh Beckman', 'Eleni Chappen']
13
13
  s.email = ['josh@officeluv.com', 'eleni@officeluv.com']
14
14
 
15
+ s.required_ruby_version = '>= 2.4'
15
16
  s.add_dependency('ox', '~> 2.13')
16
17
 
17
18
  s.add_development_dependency('pry', '~> 0.12')
data/lib/cxml-ruby.rb CHANGED
@@ -26,7 +26,7 @@ module CXML
26
26
  def self.logger
27
27
  return @logger if @logger
28
28
 
29
- @logger ||= Logger.new(STDOUT, level: :warn)
29
+ @logger ||= Logger.new($stdout, level: :warn)
30
30
  end
31
31
 
32
32
  def self.logger=(new_logger)
data/lib/cxml/address.rb CHANGED
@@ -8,9 +8,12 @@ module CXML
8
8
  iso_country_code
9
9
  ]
10
10
  accessible_nodes %i[
11
- email
12
11
  name
13
12
  postal_address
13
+ email
14
+ phone
15
+ fax
16
+ url
14
17
  ]
15
18
  end
16
19
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class Comments < DocumentNode
5
+ accessible_attributes %i[
6
+ xml_lang
7
+ ]
8
+ end
9
+ end
data/lib/cxml/contact.rb CHANGED
@@ -8,9 +8,12 @@ module CXML
8
8
  address_id
9
9
  ]
10
10
  accessible_nodes %i[
11
- email
12
11
  name
13
12
  postal_address
13
+ email
14
+ phone
15
+ fax
16
+ url
14
17
  ]
15
18
  end
16
19
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class CountryCode < DocumentNode
5
+ accessible_attributes %i[
6
+ iso_country_code
7
+ ]
8
+ end
9
+ end
@@ -41,8 +41,8 @@ module CXML
41
41
  type
42
42
  ]
43
43
  accessible_nodes %i[
44
- shared_secret
45
44
  identity
45
+ shared_secret
46
46
  credential_mac
47
47
  ]
48
48
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class DepositAmount < DocumentNode
5
+ accessible_nodes %i[
6
+ money
7
+ ]
8
+ end
9
+ end
data/lib/cxml/document.rb CHANGED
@@ -2,8 +2,9 @@
2
2
 
3
3
  module CXML
4
4
  class Document < DocumentNode
5
+ attr_writer :dtd
6
+
5
7
  accessible_attributes %i[
6
- dtd
7
8
  payload_id
8
9
  timestamp
9
10
  version
@@ -64,18 +65,17 @@ module CXML
64
65
  'cXML'
65
66
  end
66
67
 
67
- private
68
-
69
68
  def dtd_url
70
69
  "http://xml.cxml.org/schemas/cXML/#{version}/#{dtd}.dtd"
71
70
  end
72
71
 
72
+ private
73
+
73
74
  def ox_doc
74
75
  doc = Ox::Document.new
75
76
  instruct = Ox::Instruct.new(:xml)
76
77
  instruct[:version] = '1.0'
77
78
  instruct[:encoding] = 'UTF-8'
78
- instruct[:standalone] = 'yes'
79
79
  doc << instruct
80
80
  doc << Ox::DocType.new("cXML SYSTEM \"#{dtd_url}\"")
81
81
  doc
@@ -108,7 +108,7 @@ module CXML
108
108
  string_attr = if attr.to_sym == :xml_lang
109
109
  'xml:lang'
110
110
  else
111
- camelize(attr, false)
111
+ camelize(attr, uppercase_first_letter: false)
112
112
  end
113
113
  obj[string_attr] = value
114
114
  end
@@ -121,9 +121,7 @@ module CXML
121
121
  klass = "CXML::#{camelize(key)}"
122
122
  send("#{key}=", Object.const_get(klass).new(val))
123
123
  rescue NoMethodError => e
124
- raise(UnknownAttributeError, e) if CXML.raise_unknown_elements
125
-
126
- CXML.logger.warn(e)
124
+ handle_unknown_elements_error(e)
127
125
  rescue NameError => e
128
126
  raise(e) unless e.to_s.match?(klass)
129
127
 
@@ -136,9 +134,11 @@ module CXML
136
134
  else
137
135
  send("#{key}=", val)
138
136
  end
137
+ rescue NoMethodError => e
138
+ handle_unknown_elements_error(e)
139
139
  end
140
140
 
141
- def camelize(string, uppercase_first_letter = true)
141
+ def camelize(string, uppercase_first_letter: true)
142
142
  string = if uppercase_first_letter
143
143
  string.to_s.sub(/^[a-z\d]*/, &:capitalize)
144
144
  else
@@ -150,5 +150,11 @@ module CXML
150
150
  "#{Regexp.last_match(1)}#{Regexp.last_match(2).capitalize}"
151
151
  end.gsub('/', '::')
152
152
  end
153
+
154
+ def handle_unknown_elements_error(error)
155
+ raise(UnknownAttributeError, error) if CXML.raise_unknown_elements
156
+
157
+ CXML.logger.warn(error)
158
+ end
153
159
  end
154
160
  end
@@ -14,28 +14,28 @@ module CXML
14
14
  reference_date
15
15
  ]
16
16
  accessible_nodes %i[
17
- comments
18
- distribution
19
- extrinsics
17
+ unit_of_measure
18
+ unit_price
19
+ invoice_detail_item_reference
20
+ subtotal_amount
21
+ tax
22
+ invoice_detail_line_special_handling
23
+ invoice_detail_line_shipping
20
24
  gross_amount
21
25
  invoice_detail_discount
26
+ net_amount
27
+ distribution
28
+ comments
29
+ extrinsics
22
30
  invoice_detail_item_industry
23
- invoice_detail_item_reference
24
- invoice_detail_line_shipping
25
- invoice_detail_line_special_handling
26
31
  invoice_item_modifications
27
- net_amount
28
32
  packaging
29
33
  price_basis_quantity
30
34
  ship_notice_id_info
31
35
  ship_notice_line_item_reference
32
- subtotal_amount
33
- tax
34
36
  total_allowances
35
37
  total_amount_without_tax
36
38
  total_charges
37
- unit_of_measure
38
- unit_price
39
39
  ]
40
40
 
41
41
  def initialize_extrinsic(value)
@@ -6,12 +6,14 @@ module CXML
6
6
  line_number
7
7
  ]
8
8
  accessible_nodes %i[
9
- description
10
9
  item_id
10
+ description
11
11
  classification
12
12
  manufacturer_part_id
13
13
  manufacturer_name
14
14
  country
15
+ serial_number
16
+ supplier_batch_id
15
17
  ]
16
18
  end
17
19
  end
@@ -11,16 +11,16 @@ module CXML
11
11
  purpose
12
12
  ]
13
13
  accessible_nodes %i[
14
- comments
15
- document_reference
16
- extrinsics
17
14
  invoice_detail_header_indicator
18
15
  invoice_detail_line_indicator
19
- invoice_detail_shipping
20
- invoice_id_info
21
16
  invoice_partners
17
+ document_reference
18
+ invoice_id_info
19
+ invoice_detail_shipping
22
20
  payment_term
23
21
  period
22
+ comments
23
+ extrinsics
24
24
  ]
25
25
 
26
26
  def initialize_invoice_partner(value)
@@ -3,13 +3,15 @@
3
3
  module CXML
4
4
  class InvoiceDetailSummary < DocumentNode
5
5
  accessible_nodes %i[
6
+ subtotal_amount
7
+ tax
8
+ special_handling_amount
9
+ shipping_amount
6
10
  gross_amount
7
11
  invoice_detail_discount
8
12
  net_amount
9
- shipping_amount
10
- special_handling_amount
11
- subtotal_amount
12
- tax
13
+ deposit_amount
14
+ due_amount
13
15
  total_allowances
14
16
  total_amount_without_tax
15
17
  total_charges
@@ -3,10 +3,14 @@
3
3
  module CXML
4
4
  class ItemDetail < DocumentNode
5
5
  accessible_nodes %i[
6
+ unit_price
6
7
  description
7
8
  unit_of_measure
8
- unit_price
9
9
  classification
10
+ manufacturer_part_id
11
+ manufacturer_name
12
+ url
13
+ lead_time
10
14
  extrinsics
11
15
  ]
12
16
 
@@ -23,26 +23,27 @@ module CXML
23
23
  type
24
24
  ]
25
25
  accessible_nodes %i[
26
+ total
27
+ ship_to
26
28
  bill_to
27
- comments
29
+ shipping
30
+ tax
31
+ payment
32
+ payment_term
28
33
  contact
29
- control_keys
30
- delivery_period
34
+ comments
35
+ followup
31
36
  document_reference
37
+ supplier_order_info
32
38
  extrinsics
39
+ control_keys
40
+ delivery_period
33
41
  followup
34
42
  id_reference
35
43
  legal_identity
36
44
  order_request_header_industry
37
45
  organizational_unit
38
- payment
39
- payment_term
40
- ship_to
41
- shipping
42
- supplier_order_info
43
- tax
44
46
  terms_of_delivery
45
- total
46
47
  ]
47
48
 
48
49
  def type
data/lib/cxml/parser.rb CHANGED
@@ -44,17 +44,22 @@ module CXML
44
44
 
45
45
  private
46
46
 
47
- def node_to_hash(node) # rubocop:disable Metrics/AbcSize
47
+ def node_to_hash(node)
48
+ return node.value if node.is_a?(Ox::CData)
48
49
  return node if node.is_a? String
49
50
  return node.nodes.first if node.nodes.all?(String) && node.attributes.empty?
50
51
 
52
+ transform_node_to_hash node
53
+ end
54
+
55
+ def transform_node_to_hash(node)
51
56
  hash = node.attributes
52
57
  hash.transform_keys!(&method(:underscore_key))
53
58
  node.nodes.reduce(hash) do |acc, child_node|
54
59
  next acc if child_node.is_a?(Ox::Comment)
55
60
 
56
61
  node_hash = {}
57
- name = child_node.is_a?(String) ? :content : child_node.value
62
+ name = child_node.is_a?(String) || child_node.is_a?(Ox::CData) ? :content : child_node.value
58
63
  node_hash[underscore_key(name)] = node_to_hash(child_node)
59
64
  acc.merge(node_hash) do |_key, val1, val2|
60
65
  [val1, val2].flatten
data/lib/cxml/phone.rb ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class Phone < DocumentNode
5
+ accessible_attributes %i[
6
+ name
7
+ ]
8
+
9
+ accessible_nodes %i[
10
+ telephone_number
11
+ ]
12
+ end
13
+ end
@@ -8,10 +8,10 @@ module CXML
8
8
  ]
9
9
  accessible_nodes %i[
10
10
  deliver_to
11
- state
12
11
  street
13
12
  municipality
14
13
  city
14
+ state
15
15
  postal_code
16
16
  country
17
17
  ]