adf_builder 1.2.2 → 1.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f5c6497310cd559356bd6e358243d2dd2ed5d2a859330fe403ae959b32592b0b
4
- data.tar.gz: 77e66f74d658adc2022d401d85a037549f8f92c91d984c265db337a33c05353c
3
+ metadata.gz: d362b1ad0b8a252bd6e941a5c1c2572b098d1b0fb98da0eed415fa3074297fff
4
+ data.tar.gz: 8319bcc2fd7289ac3e0dfd46be7deb46166b1b2b1cbea247ad1b5eeac2f86b87
5
5
  SHA512:
6
- metadata.gz: 8aba468994e77c3af346c7f6dccbdd4eed16fd858ccf6206226c90d97a5e1126d75bc5083440d40ce1ac3233d2b6f0395b899fcce70afc76ccba7691867e779f
7
- data.tar.gz: 215970d63f001f71e21c55651368c9ebab28dafd9e5f26d19519dbff6c897ed4859443623f01d3a99a5c014743d00f8e74b351eda0b371d28e578edc744d5582
6
+ metadata.gz: f49bb434697231563e420d4da2123b38370b61ac8b83ae5e6e6d7ad3517c6308acdd7a4db70e7a3866f5c578c4f2bd012a7830d94a69dc0ca8aacd6c941f9dbc
7
+ data.tar.gz: 5441957e0585459da711b7943e8e5d0eca3b4d596c54159178a71656c6a532c185dcf5395765eae75dbe46c3a6df5d8c80eb02a8e9101f1cc25b09698c32549f
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## [1.3.0] - 2026-01-19
2
+ - **Customer & Contact Validations**:
3
+ - `Contact`: Requires Name and at least one Phone or Email.
4
+ - `Address`: Validates Country against ISO 3166-1 alpha-2 codes.
5
+ - `Timeframe`: Validates ISO 8601 dates and requires earliest/latest date if present.
6
+ - `Phone/Email`: Enforces valid types and preference flags.
7
+
1
8
  ## [1.2.2] - 2026-01-19
2
9
  - **Strict Validations**: Added ISO 4217 currency validation for `Price`, `Amount`, and `Balance`.
3
10
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- adf_builder (1.2.1)
4
+ adf_builder (1.2.2)
5
5
  ox (~> 2.14)
6
6
 
7
7
  GEM
@@ -39,20 +39,41 @@ module AdfBuilder
39
39
  @tag_name = :timeframe
40
40
  end
41
41
 
42
+ def validate!
43
+ super
44
+ # If timeframe is present, earliestdate or latestdate is required
45
+ return if @children.any? { |c| %i[earliestdate latestdate].include?(c.tag_name) }
46
+
47
+ raise AdfBuilder::Error, "Timeframe must have at least one of earliestdate or latestdate"
48
+ end
49
+
42
50
  def description(value)
43
51
  remove_children(:description)
44
52
  add_child(GenericNode.new(:description, {}, value))
45
53
  end
46
54
 
47
55
  def earliestdate(value)
56
+ validate_iso8601(value)
48
57
  remove_children(:earliestdate)
49
58
  add_child(GenericNode.new(:earliestdate, {}, value))
50
59
  end
51
60
 
52
61
  def latestdate(value)
62
+ validate_iso8601(value)
53
63
  remove_children(:latestdate)
54
64
  add_child(GenericNode.new(:latestdate, {}, value))
55
65
  end
66
+
67
+ private
68
+
69
+ def validate_iso8601(value)
70
+ # Simple ISO 8601 check (YYYY-MM-DDT...)
71
+ # Using a basic regex for now or standard library
72
+ require "date"
73
+ Date.iso8601(value.to_s)
74
+ rescue ArgumentError
75
+ raise AdfBuilder::Error, "Invalid ISO 8601 date: #{value}"
76
+ end
56
77
  end
57
78
  end
58
79
  end
@@ -14,7 +14,14 @@ module AdfBuilder
14
14
  end
15
15
  end
16
16
 
17
+ # Common ISO 3166-1 alpha-2 codes
18
+ ISO_3166 = %w[US CA MX GB DE FR GR IT ES JP CN IN BR RU ZA AU NZ KR SE NO FI DK NL BE CH].freeze
19
+
17
20
  class Phone < Node
21
+ validates_inclusion_of :type, in: %i[phone fax cellphone pager]
22
+ validates_inclusion_of :time, in: %i[morning afternoon evening nopreference day]
23
+ validates_inclusion_of :preferredcontact, in: [0, 1, "0", "1"]
24
+
18
25
  def initialize(value, type: nil, time: nil, preferredcontact: nil)
19
26
  super()
20
27
  @tag_name = :phone
@@ -26,6 +33,8 @@ module AdfBuilder
26
33
  end
27
34
 
28
35
  class Email < Node
36
+ validates_inclusion_of :preferredcontact, in: [0, 1, "0", "1"]
37
+
29
38
  def initialize(value, preferredcontact: nil)
30
39
  super()
31
40
  @tag_name = :email
@@ -35,6 +44,9 @@ module AdfBuilder
35
44
  end
36
45
 
37
46
  class Name < Node
47
+ validates_inclusion_of :part, in: %i[first middle suffix last full]
48
+ validates_inclusion_of :type, in: %i[individual business]
49
+
38
50
  def initialize(value, part: nil, type: nil)
39
51
  super()
40
52
  @tag_name = :name
@@ -45,6 +57,9 @@ module AdfBuilder
45
57
  end
46
58
 
47
59
  class Address < Node
60
+ validates_inclusion_of :type, in: %i[work home delivery]
61
+ validates_inclusion_of :country, in: ISO_3166
62
+
48
63
  def initialize(type: nil)
49
64
  super()
50
65
  @tag_name = :address
@@ -52,6 +67,9 @@ module AdfBuilder
52
67
  end
53
68
 
54
69
  def street(value, line: nil)
70
+ # Line validation 1-5
71
+ raise AdfBuilder::Error, "Street line must be 1-5" if line && !line.to_s.match?(/^[1-5]$/)
72
+
55
73
  node = GenericNode.new(:street, { line: line }.compact, value)
56
74
  add_child(node)
57
75
  end
@@ -59,16 +77,33 @@ module AdfBuilder
59
77
  # Simple elements
60
78
  %i[apartment city regioncode postalcode country].each do |tag|
61
79
  define_method(tag) do |value|
80
+ if tag == :country && !ISO_3166.include?(value.to_s.upcase)
81
+ raise AdfBuilder::Error, "Invalid country code: #{value}"
82
+ end
83
+
62
84
  add_child(GenericNode.new(tag, {}, value))
63
85
  end
64
86
  end
65
87
  end
66
88
 
67
89
  class Contact < Node
68
- def initialize(primary_contact: false)
90
+ validates_inclusion_of :primarycontact, in: [0, 1, "0", "1"]
91
+
92
+ def initialize(primary_contact: nil)
69
93
  super()
70
94
  @tag_name = :contact
71
- # primary_contact might be useful for logic but not an attribute
95
+ @attributes[:primarycontact] = primary_contact if primary_contact
96
+ end
97
+
98
+ def validate!
99
+ super
100
+ # Custom Validation: Name is required
101
+ raise AdfBuilder::Error, "Contact must have a Name" unless @children.any? { |c| c.tag_name == :name }
102
+
103
+ # Custom Validation: At least one Phone OR Email
104
+ return if @children.any? { |c| %i[phone email].include?(c.tag_name) }
105
+
106
+ raise AdfBuilder::Error, "Contact must have at least one Phone or Email"
72
107
  end
73
108
 
74
109
  def name(value, part: nil, type: nil)
@@ -31,7 +31,11 @@ module AdfBuilder
31
31
  next if value.nil?
32
32
 
33
33
  allowed = validation[:in]
34
- unless allowed.include?(value)
34
+ # Normalize for comparison (allow string/symbol interchangeably)
35
+ value_s = value.to_s
36
+ allowed_s = allowed.map(&:to_s)
37
+
38
+ unless allowed_s.include?(value_s)
35
39
  raise AdfBuilder::Error,
36
40
  "Invalid value for #{validation[:attribute]}: #{value}. Allowed: #{allowed.join(", ")}"
37
41
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AdfBuilder
4
- VERSION = "1.2.2"
4
+ VERSION = "1.3.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: adf_builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - marcus.salinas