cxml-ruby 0.5.0 → 0.8.1

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 (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
  ]