adf_builder 1.2.2 → 1.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/Gemfile.lock +1 -1
- data/lib/adf_builder/nodes/customer.rb +21 -0
- data/lib/adf_builder/nodes/shared.rb +43 -2
- data/lib/adf_builder/validations.rb +5 -1
- data/lib/adf_builder/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c0e75f097adeb0e0f73541ee79c693ae5de334a55b9330eb49130037fd6fbbe5
|
|
4
|
+
data.tar.gz: 78c32bb06e602c81270ce30b97ed526fb9449d9bc5aa6b6ddf19ac22593c8596
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c00a8c760bac13e7347f7a365e9598f6c2993ccf72c3adeaf1ef498e3092b6eab70bcd65b8c31e5bc0594014c012339b2653d4017b09716e20fc5364f174d587
|
|
7
|
+
data.tar.gz: 1c2a4588b945d2cc5275e1a583dea5da1fffc6fa7c6d9004c3466bf984d905bbc9bdfe49496073191a025f5c99efbc0ba503042ce587e2cf97380290336869bb
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
## [1.3.1] - 2026-01-19
|
|
2
|
+
- **Validation Refinement**: `Address` now strictly enforces 1 to 5 `street` lines.
|
|
3
|
+
|
|
4
|
+
## [1.3.0] - 2026-01-19
|
|
5
|
+
- **Customer & Contact Validations**:
|
|
6
|
+
- `Contact`: Requires Name and at least one Phone or Email.
|
|
7
|
+
- `Address`: Validates Country against ISO 3166-1 alpha-2 codes.
|
|
8
|
+
- `Timeframe`: Validates ISO 8601 dates and requires earliest/latest date if present.
|
|
9
|
+
- `Phone/Email`: Enforces valid types and preference flags.
|
|
10
|
+
|
|
1
11
|
## [1.2.2] - 2026-01-19
|
|
2
12
|
- **Strict Validations**: Added ISO 4217 currency validation for `Price`, `Amount`, and `Balance`.
|
|
3
13
|
|
data/Gemfile.lock
CHANGED
|
@@ -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,12 +57,24 @@ 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
|
|
51
66
|
@attributes[:type] = type if type
|
|
52
67
|
end
|
|
53
68
|
|
|
69
|
+
def validate!
|
|
70
|
+
super
|
|
71
|
+
streets = @children.select { |c| c.tag_name == :street }
|
|
72
|
+
raise AdfBuilder::Error, "Address must have at least one street line" if streets.empty?
|
|
73
|
+
return unless streets.size > 5
|
|
74
|
+
|
|
75
|
+
raise AdfBuilder::Error, "Address can have at most 5 street lines"
|
|
76
|
+
end
|
|
77
|
+
|
|
54
78
|
def street(value, line: nil)
|
|
55
79
|
node = GenericNode.new(:street, { line: line }.compact, value)
|
|
56
80
|
add_child(node)
|
|
@@ -59,16 +83,33 @@ module AdfBuilder
|
|
|
59
83
|
# Simple elements
|
|
60
84
|
%i[apartment city regioncode postalcode country].each do |tag|
|
|
61
85
|
define_method(tag) do |value|
|
|
86
|
+
if tag == :country && !ISO_3166.include?(value.to_s.upcase)
|
|
87
|
+
raise AdfBuilder::Error, "Invalid country code: #{value}"
|
|
88
|
+
end
|
|
89
|
+
|
|
62
90
|
add_child(GenericNode.new(tag, {}, value))
|
|
63
91
|
end
|
|
64
92
|
end
|
|
65
93
|
end
|
|
66
94
|
|
|
67
95
|
class Contact < Node
|
|
68
|
-
|
|
96
|
+
validates_inclusion_of :primarycontact, in: [0, 1, "0", "1"]
|
|
97
|
+
|
|
98
|
+
def initialize(primary_contact: nil)
|
|
69
99
|
super()
|
|
70
100
|
@tag_name = :contact
|
|
71
|
-
|
|
101
|
+
@attributes[:primarycontact] = primary_contact if primary_contact
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def validate!
|
|
105
|
+
super
|
|
106
|
+
# Custom Validation: Name is required
|
|
107
|
+
raise AdfBuilder::Error, "Contact must have a Name" unless @children.any? { |c| c.tag_name == :name }
|
|
108
|
+
|
|
109
|
+
# Custom Validation: At least one Phone OR Email
|
|
110
|
+
return if @children.any? { |c| %i[phone email].include?(c.tag_name) }
|
|
111
|
+
|
|
112
|
+
raise AdfBuilder::Error, "Contact must have at least one Phone or Email"
|
|
72
113
|
end
|
|
73
114
|
|
|
74
115
|
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
|
-
|
|
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
|
data/lib/adf_builder/version.rb
CHANGED