adf_builder 1.0.0 → 1.1.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 +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +17 -1
- data/Gemfile.lock +1 -1
- data/lib/adf_builder/nodes/customer.rb +32 -32
- data/lib/adf_builder/nodes/node.rb +7 -2
- data/lib/adf_builder/nodes/prospect.rb +12 -0
- data/lib/adf_builder/nodes/provider.rb +48 -0
- data/lib/adf_builder/nodes/shared.rb +91 -0
- data/lib/adf_builder/nodes/vehicle.rb +56 -6
- data/lib/adf_builder/nodes/vehicle_nodes.rb +137 -0
- data/lib/adf_builder/nodes/vendor.rb +33 -0
- data/lib/adf_builder/serializer.rb +5 -2
- data/lib/adf_builder/version.rb +1 -1
- data/lib/adf_builder.rb +8 -150
- metadata +5 -13
- data/lib/adf_builder/base/base.rb +0 -13
- data/lib/adf_builder/base/prospect.rb +0 -34
- data/lib/adf_builder/base/request_date.rb +0 -22
- data/lib/adf_builder/customer/customer.rb +0 -50
- data/lib/adf_builder/customer/timeframe.rb +0 -44
- data/lib/adf_builder/provider/provider.rb +0 -53
- data/lib/adf_builder/shared/contact.rb +0 -44
- data/lib/adf_builder/shared/id.rb +0 -18
- data/lib/adf_builder/vehicles/colorcombinations.rb +0 -30
- data/lib/adf_builder/vehicles/price.rb +0 -43
- data/lib/adf_builder/vehicles/vehicles.rb +0 -123
- data/lib/adf_builder/vendor/vendor.rb +0 -31
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ded72167a643d102957459b6d439bbaae8f01833303a3eca082ce4a6f0e264dd
|
|
4
|
+
data.tar.gz: 64486e697bd4feefa5fdbc8c6cbe01d3d0492878225748ffdf3c8ed1650b8b09
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b868564c56972b958839382c2d5c5706ce1b7864ea13e2c7eb38dddccb82f6481a66bc471f679f79589533a8fa9fd29897a387d53d4426ee8bc5490242912b45
|
|
7
|
+
data.tar.gz: 0c25a32fec2c3015e402fdbe26e0c2af23a2a91ea64840097a7a86acd7c88c4e89a809362b1ea35b8eebaa112dc130534b82f1a3647173ab5f0d1f3aa2b19fa0
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,20 @@
|
|
|
1
|
-
## [
|
|
1
|
+
## [1.1.0] - 2026-01-19
|
|
2
|
+
- **Feature Complete**: Implemented all ADF 1.0 nodes and attributes including `Vendor`, `Provider`, and complex `Vehicle` tags (`Finance`, `Option`, `Odometer`, `ColorCombination`, `ImageTag`, `Price`).
|
|
3
|
+
- **Singular Field logic**: Methods for singular fields (e.g. `vehicle.year`) now correctly replace existing values instead of appending.
|
|
4
|
+
- **Removed Legacy Code**: Cleaned up deprecated legacy implementation directories.
|
|
5
|
+
|
|
6
|
+
## [1.0.0] - 2026-01-19
|
|
7
|
+
- **MAJOR OVERHAUL**: Complete rewrtie of the library architecture.
|
|
8
|
+
- **New Block-based DSL**: Intuitive API for building ADF documents (`AdfBuilder.build { vehicle { ... } }`).
|
|
9
|
+
- **Validation**: Strict enforcement of ADF enumerations and structure (e.g. `vehicle status: :new`).
|
|
10
|
+
- **Editing**: New `AdfBuilder.tree` method for programmatic modifications after construction.
|
|
11
|
+
- **Robustness**: Complete rewrite of XML generation using robust heuristics and strict `Ox` serialization.
|
|
12
|
+
- **Compatibility**: Verified for Ruby 3.4.x.
|
|
13
|
+
- **Features**:
|
|
14
|
+
- Support for multiple vehicles/customers.
|
|
15
|
+
- Support for singular vs multiple item logic.
|
|
16
|
+
- Dynamic support for arbitrary/custom tags (`method_missing`).
|
|
17
|
+
- Automatic handling of XML attributes vs simple elements.
|
|
2
18
|
|
|
3
19
|
## [0.4.0] - 2026-01-19
|
|
4
20
|
- Modernized dependencies
|
data/Gemfile.lock
CHANGED
|
@@ -3,56 +3,56 @@
|
|
|
3
3
|
module AdfBuilder
|
|
4
4
|
module Nodes
|
|
5
5
|
class Customer < Node
|
|
6
|
+
def initialize
|
|
7
|
+
super
|
|
8
|
+
@tag_name = :customer
|
|
9
|
+
end
|
|
10
|
+
|
|
6
11
|
def contact(&block)
|
|
12
|
+
remove_children(:contact)
|
|
7
13
|
contact = Contact.new
|
|
8
14
|
contact.instance_eval(&block) if block_given?
|
|
9
15
|
add_child(contact)
|
|
10
16
|
end
|
|
11
|
-
end
|
|
12
17
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
add_child(name_node)
|
|
18
|
+
def id(value, sequence: nil, source: nil)
|
|
19
|
+
# id* is multiple
|
|
20
|
+
add_child(Id.new(value, sequence: sequence, source: source))
|
|
17
21
|
end
|
|
18
22
|
|
|
19
|
-
def
|
|
20
|
-
|
|
23
|
+
def timeframe(&block)
|
|
24
|
+
remove_children(:timeframe)
|
|
25
|
+
tf = Timeframe.new
|
|
26
|
+
tf.instance_eval(&block) if block_given?
|
|
27
|
+
add_child(tf)
|
|
21
28
|
end
|
|
22
29
|
|
|
23
|
-
def
|
|
24
|
-
|
|
25
|
-
add_child(
|
|
30
|
+
def comments(value)
|
|
31
|
+
remove_children(:comments)
|
|
32
|
+
add_child(GenericNode.new(:comments, {}, value))
|
|
26
33
|
end
|
|
27
34
|
end
|
|
28
35
|
|
|
29
|
-
class
|
|
30
|
-
def initialize
|
|
31
|
-
super
|
|
32
|
-
@
|
|
33
|
-
@attributes[:part] = part if part
|
|
34
|
-
@attributes[:type] = type if type
|
|
36
|
+
class Timeframe < Node
|
|
37
|
+
def initialize
|
|
38
|
+
super
|
|
39
|
+
@tag_name = :timeframe
|
|
35
40
|
end
|
|
36
|
-
attr_reader :value
|
|
37
|
-
end
|
|
38
41
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
def description(value)
|
|
43
|
+
remove_children(:description)
|
|
44
|
+
add_child(GenericNode.new(:description, {}, value))
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def earliestdate(value)
|
|
48
|
+
remove_children(:earliestdate)
|
|
49
|
+
add_child(GenericNode.new(:earliestdate, {}, value))
|
|
44
50
|
end
|
|
45
|
-
attr_reader :value
|
|
46
|
-
end
|
|
47
51
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
super()
|
|
52
|
-
@tag_name = tag_name
|
|
53
|
-
@value = value
|
|
52
|
+
def latestdate(value)
|
|
53
|
+
remove_children(:latestdate)
|
|
54
|
+
add_child(GenericNode.new(:latestdate, {}, value))
|
|
54
55
|
end
|
|
55
|
-
attr_reader :value, :tag_name
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
58
|
end
|
|
@@ -5,17 +5,23 @@ module AdfBuilder
|
|
|
5
5
|
class Node
|
|
6
6
|
include AdfBuilder::Validations
|
|
7
7
|
|
|
8
|
-
attr_reader :children, :attributes
|
|
8
|
+
attr_reader :children, :attributes, :value, :tag_name
|
|
9
9
|
|
|
10
10
|
def initialize
|
|
11
11
|
@children = []
|
|
12
12
|
@attributes = {}
|
|
13
|
+
@value = nil
|
|
14
|
+
@tag_name = nil
|
|
13
15
|
end
|
|
14
16
|
|
|
15
17
|
def add_child(node)
|
|
16
18
|
@children << node
|
|
17
19
|
end
|
|
18
20
|
|
|
21
|
+
def remove_children(tag_name)
|
|
22
|
+
@children.reject! { |c| c.tag_name == tag_name }
|
|
23
|
+
end
|
|
24
|
+
|
|
19
25
|
def to_xml
|
|
20
26
|
Serializer.to_xml(self)
|
|
21
27
|
end
|
|
@@ -57,7 +63,6 @@ module AdfBuilder
|
|
|
57
63
|
@attributes = attributes
|
|
58
64
|
@value = value
|
|
59
65
|
end
|
|
60
|
-
attr_reader :tag_name, :value
|
|
61
66
|
end
|
|
62
67
|
|
|
63
68
|
class Root < Node
|
|
@@ -19,6 +19,18 @@ module AdfBuilder
|
|
|
19
19
|
add_child(customer)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
def vendor(&block)
|
|
23
|
+
vendor = Vendor.new
|
|
24
|
+
vendor.instance_eval(&block) if block_given?
|
|
25
|
+
add_child(vendor)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def provider(&block)
|
|
29
|
+
provider = Provider.new
|
|
30
|
+
provider.instance_eval(&block) if block_given?
|
|
31
|
+
add_child(provider)
|
|
32
|
+
end
|
|
33
|
+
|
|
22
34
|
# Helpers for Editing
|
|
23
35
|
def vehicles
|
|
24
36
|
@children.select { |c| c.is_a?(Vehicle) }
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AdfBuilder
|
|
4
|
+
module Nodes
|
|
5
|
+
class Provider < Node
|
|
6
|
+
def initialize
|
|
7
|
+
super
|
|
8
|
+
@tag_name = :provider
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def id(value, sequence: nil, source: nil)
|
|
12
|
+
add_child(Id.new(value, sequence: sequence, source: source))
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def name(value, part: nil, type: nil)
|
|
16
|
+
remove_children(:name)
|
|
17
|
+
add_child(Name.new(value, part: part, type: type))
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def service(value)
|
|
21
|
+
remove_children(:service)
|
|
22
|
+
add_child(GenericNode.new(:service, {}, value))
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def url(value)
|
|
26
|
+
remove_children(:url)
|
|
27
|
+
add_child(GenericNode.new(:url, {}, value))
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def email(value, preferredcontact: nil)
|
|
31
|
+
remove_children(:email)
|
|
32
|
+
add_child(Email.new(value, preferredcontact: preferredcontact))
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def phone(value, type: nil, time: nil, preferredcontact: nil)
|
|
36
|
+
remove_children(:phone)
|
|
37
|
+
add_child(Phone.new(value, type: type, time: time, preferredcontact: preferredcontact))
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def contact(primary_contact: false, &block)
|
|
41
|
+
remove_children(:contact)
|
|
42
|
+
contact = Contact.new(primary_contact: primary_contact)
|
|
43
|
+
contact.instance_eval(&block) if block_given?
|
|
44
|
+
add_child(contact)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AdfBuilder
|
|
4
|
+
module Nodes
|
|
5
|
+
class Id < Node
|
|
6
|
+
def initialize(value, sequence: nil, source: nil)
|
|
7
|
+
super()
|
|
8
|
+
@tag_name = :id
|
|
9
|
+
@value = value
|
|
10
|
+
@attributes[:sequence] = sequence if sequence
|
|
11
|
+
@attributes[:source] = source if source
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class Phone < Node
|
|
16
|
+
def initialize(value, type: nil, time: nil, preferredcontact: nil)
|
|
17
|
+
super()
|
|
18
|
+
@tag_name = :phone
|
|
19
|
+
@value = value
|
|
20
|
+
@attributes[:type] = type if type
|
|
21
|
+
@attributes[:time] = time if time
|
|
22
|
+
@attributes[:preferredcontact] = preferredcontact if preferredcontact
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class Email < Node
|
|
27
|
+
def initialize(value, preferredcontact: nil)
|
|
28
|
+
super()
|
|
29
|
+
@tag_name = :email
|
|
30
|
+
@value = value
|
|
31
|
+
@attributes[:preferredcontact] = preferredcontact if preferredcontact
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
class Name < Node
|
|
36
|
+
def initialize(value, part: nil, type: nil)
|
|
37
|
+
super()
|
|
38
|
+
@tag_name = :name
|
|
39
|
+
@value = value
|
|
40
|
+
@attributes[:part] = part if part
|
|
41
|
+
@attributes[:type] = type if type
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
class Address < Node
|
|
46
|
+
def initialize(type: nil)
|
|
47
|
+
super()
|
|
48
|
+
@tag_name = :address
|
|
49
|
+
@attributes[:type] = type if type
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def street(value, line: nil)
|
|
53
|
+
node = GenericNode.new(:street, { line: line }.compact, value)
|
|
54
|
+
add_child(node)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Simple elements
|
|
58
|
+
%i[apartment city regioncode postalcode country].each do |tag|
|
|
59
|
+
define_method(tag) do |value|
|
|
60
|
+
add_child(GenericNode.new(tag, {}, value))
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
class Contact < Node
|
|
66
|
+
def initialize(primary_contact: false)
|
|
67
|
+
super()
|
|
68
|
+
@tag_name = :contact
|
|
69
|
+
# primary_contact might be useful for logic but not an attribute
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def name(value, part: nil, type: nil)
|
|
73
|
+
add_child(Name.new(value, part: part, type: type))
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def email(value, preferredcontact: nil)
|
|
77
|
+
add_child(Email.new(value, preferredcontact: preferredcontact))
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def phone(value, type: nil, time: nil, preferredcontact: nil)
|
|
81
|
+
add_child(Phone.new(value, type: type, time: time, preferredcontact: preferredcontact))
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def address(type: nil, &block)
|
|
85
|
+
addr = Address.new(type: type)
|
|
86
|
+
addr.instance_eval(&block) if block_given?
|
|
87
|
+
add_child(addr)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -4,22 +4,72 @@ module AdfBuilder
|
|
|
4
4
|
module Nodes
|
|
5
5
|
class Vehicle < Node
|
|
6
6
|
validates_inclusion_of :status, in: %i[new used]
|
|
7
|
+
validates_inclusion_of :interest, in: %i[buy lease sell trade-in test-drive]
|
|
7
8
|
|
|
8
|
-
def
|
|
9
|
-
|
|
9
|
+
def initialize
|
|
10
|
+
super
|
|
11
|
+
@tag_name = :vehicle
|
|
12
|
+
@attributes[:status] = :new
|
|
13
|
+
@attributes[:interest] = :buy
|
|
10
14
|
end
|
|
11
15
|
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
# Simple Text Elements (Singular)
|
|
17
|
+
%i[year make model vin stock trim doors bodystyle transmission condition pricecomments comments].each do |tag|
|
|
18
|
+
define_method(tag) do |value|
|
|
19
|
+
remove_children(tag)
|
|
20
|
+
add_child(GenericNode.new(tag, {}, value))
|
|
21
|
+
end
|
|
14
22
|
end
|
|
15
23
|
|
|
16
|
-
def
|
|
17
|
-
@attributes[:
|
|
24
|
+
def interest(value)
|
|
25
|
+
@attributes[:interest] = value
|
|
18
26
|
end
|
|
19
27
|
|
|
20
28
|
def status(value)
|
|
21
29
|
@attributes[:status] = value
|
|
22
30
|
end
|
|
31
|
+
|
|
32
|
+
# Complex Elements
|
|
33
|
+
def id(value, sequence: nil, source: nil)
|
|
34
|
+
# id* is multiple, so just add
|
|
35
|
+
add_child(Id.new(value, sequence: sequence, source: source))
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def odometer(value, status: nil, units: nil)
|
|
39
|
+
remove_children(:odometer)
|
|
40
|
+
add_child(Odometer.new(value, status: status, units: units))
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def imagetag(value, width: nil, height: nil, alttext: nil)
|
|
44
|
+
remove_children(:imagetag)
|
|
45
|
+
add_child(ImageTag.new(value, width: width, height: height, alttext: alttext))
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def price(value, **attrs)
|
|
49
|
+
remove_children(:price)
|
|
50
|
+
add_child(Price.new(value, **attrs))
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def option(&block)
|
|
54
|
+
# option* is multiple
|
|
55
|
+
opt = Option.new
|
|
56
|
+
opt.instance_eval(&block) if block_given?
|
|
57
|
+
add_child(opt)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def finance(&block)
|
|
61
|
+
remove_children(:finance)
|
|
62
|
+
fin = Finance.new
|
|
63
|
+
fin.instance_eval(&block) if block_given?
|
|
64
|
+
add_child(fin)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def colorcombination(&block)
|
|
68
|
+
# colorcombination* is multiple
|
|
69
|
+
cc = ColorCombination.new
|
|
70
|
+
cc.instance_eval(&block) if block_given?
|
|
71
|
+
add_child(cc)
|
|
72
|
+
end
|
|
23
73
|
end
|
|
24
74
|
end
|
|
25
75
|
end
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AdfBuilder
|
|
4
|
+
module Nodes
|
|
5
|
+
class Odometer < Node
|
|
6
|
+
validates_inclusion_of :status, in: %i[unknown rolledover replaced original]
|
|
7
|
+
validates_inclusion_of :units, in: %i[km mi]
|
|
8
|
+
|
|
9
|
+
def initialize(value, status: nil, units: nil)
|
|
10
|
+
super()
|
|
11
|
+
@tag_name = :odometer
|
|
12
|
+
@value = value
|
|
13
|
+
@attributes[:status] = status if status
|
|
14
|
+
@attributes[:units] = units if units
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class ImageTag < Node
|
|
19
|
+
def initialize(value, width: nil, height: nil, alttext: nil)
|
|
20
|
+
super()
|
|
21
|
+
@tag_name = :imagetag
|
|
22
|
+
@value = value
|
|
23
|
+
@attributes[:width] = width if width
|
|
24
|
+
@attributes[:height] = height if height
|
|
25
|
+
@attributes[:alttext] = alttext if alttext
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class Price < Node
|
|
30
|
+
validates_inclusion_of :type, in: %i[quote offer msrp invoice call appraisal asking]
|
|
31
|
+
validates_inclusion_of :delta, in: %i[absolute relative percentage]
|
|
32
|
+
validates_inclusion_of :relativeto, in: %i[msrp invoice]
|
|
33
|
+
|
|
34
|
+
def initialize(value, type: :quote, currency: nil, delta: nil, relativeto: nil, source: nil)
|
|
35
|
+
super()
|
|
36
|
+
@tag_name = :price
|
|
37
|
+
@value = value
|
|
38
|
+
@attributes[:type] = type
|
|
39
|
+
@attributes[:currency] = currency if currency
|
|
40
|
+
@attributes[:delta] = delta if delta
|
|
41
|
+
@attributes[:relativeto] = relativeto if relativeto
|
|
42
|
+
@attributes[:source] = source if source
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
class Amount < Node
|
|
47
|
+
validates_inclusion_of :type, in: %i[downpayment monthly total]
|
|
48
|
+
validates_inclusion_of :limit, in: %i[maximum minimum exact]
|
|
49
|
+
|
|
50
|
+
def initialize(value, type: :total, limit: :maximum, currency: nil)
|
|
51
|
+
super()
|
|
52
|
+
@tag_name = :amount
|
|
53
|
+
@value = value
|
|
54
|
+
@attributes[:type] = type
|
|
55
|
+
@attributes[:limit] = limit
|
|
56
|
+
@attributes[:currency] = currency if currency
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
class Balance < Node
|
|
61
|
+
validates_inclusion_of :type, in: %i[finance residual]
|
|
62
|
+
|
|
63
|
+
def initialize(value, type: :finance, currency: nil)
|
|
64
|
+
super()
|
|
65
|
+
@tag_name = :balance
|
|
66
|
+
@value = value
|
|
67
|
+
@attributes[:type] = type
|
|
68
|
+
@attributes[:currency] = currency if currency
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
class Finance < Node
|
|
73
|
+
def initialize
|
|
74
|
+
super
|
|
75
|
+
@tag_name = :finance
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def method(value)
|
|
79
|
+
add_child(GenericNode.new(:method, {}, value))
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def amount(value, type: :total, limit: :maximum, currency: nil)
|
|
83
|
+
add_child(Amount.new(value, type: type, limit: limit, currency: currency))
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def balance(value, type: :finance, currency: nil)
|
|
87
|
+
add_child(Balance.new(value, type: type, currency: currency))
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
class Option < Node
|
|
92
|
+
def initialize
|
|
93
|
+
super
|
|
94
|
+
@tag_name = :option
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def optionname(value)
|
|
98
|
+
add_child(GenericNode.new(:optionname, {}, value))
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def manufacturercode(value)
|
|
102
|
+
add_child(GenericNode.new(:manufacturercode, {}, value))
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def stock(value)
|
|
106
|
+
add_child(GenericNode.new(:stock, {}, value))
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def weighting(value)
|
|
110
|
+
add_child(GenericNode.new(:weighting, {}, value))
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def price(value, **attrs)
|
|
114
|
+
add_child(Price.new(value, **attrs))
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
class ColorCombination < Node
|
|
119
|
+
def initialize
|
|
120
|
+
super
|
|
121
|
+
@tag_name = :colorcombination
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def interiorcolor(value)
|
|
125
|
+
add_child(GenericNode.new(:interiorcolor, {}, value))
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def exteriorcolor(value)
|
|
129
|
+
add_child(GenericNode.new(:exteriorcolor, {}, value))
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def preference(value)
|
|
133
|
+
add_child(GenericNode.new(:preference, {}, value))
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AdfBuilder
|
|
4
|
+
module Nodes
|
|
5
|
+
class Vendor < Node
|
|
6
|
+
def initialize
|
|
7
|
+
super
|
|
8
|
+
@tag_name = :vendor
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def id(value, sequence: nil, source: nil)
|
|
12
|
+
add_child(Id.new(value, sequence: sequence, source: source))
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def vendorname(value)
|
|
16
|
+
remove_children(:vendorname)
|
|
17
|
+
add_child(GenericNode.new(:vendorname, {}, value))
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def url(value)
|
|
21
|
+
remove_children(:url)
|
|
22
|
+
add_child(GenericNode.new(:url, {}, value))
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def contact(primary_contact: false, &block)
|
|
26
|
+
remove_children(:contact)
|
|
27
|
+
contact = Contact.new(primary_contact: primary_contact)
|
|
28
|
+
contact.instance_eval(&block) if block_given?
|
|
29
|
+
add_child(contact)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -41,7 +41,7 @@ module AdfBuilder
|
|
|
41
41
|
def serialize_node(node, parent_element)
|
|
42
42
|
# Determine element name using tag_name to avoid conflict with DSL methods like 'name'
|
|
43
43
|
# Safest check: Does it have the instance variable set?
|
|
44
|
-
element_name = if node.instance_variable_defined?(:@tag_name)
|
|
44
|
+
element_name = if node.instance_variable_defined?(:@tag_name) && node.instance_variable_get(:@tag_name)
|
|
45
45
|
node.instance_variable_get(:@tag_name).to_s
|
|
46
46
|
else
|
|
47
47
|
node.class.name.split("::").last.downcase
|
|
@@ -75,7 +75,10 @@ module AdfBuilder
|
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
def attribute?(key)
|
|
78
|
-
%i[
|
|
78
|
+
%i[
|
|
79
|
+
part type status sequence source id valid preferredcontact time
|
|
80
|
+
interest units width height alttext limit currency delta relativeto line
|
|
81
|
+
].include?(key)
|
|
79
82
|
end
|
|
80
83
|
end
|
|
81
84
|
end
|
data/lib/adf_builder/version.rb
CHANGED
data/lib/adf_builder.rb
CHANGED
|
@@ -4,164 +4,22 @@ require "ox"
|
|
|
4
4
|
require "json"
|
|
5
5
|
|
|
6
6
|
require_relative "adf_builder/version"
|
|
7
|
-
|
|
8
|
-
# CUSTOMER
|
|
9
|
-
require_relative "adf_builder/customer/customer"
|
|
10
|
-
require_relative "adf_builder/customer/timeframe"
|
|
11
|
-
|
|
12
|
-
# BASE
|
|
13
|
-
require_relative "adf_builder/base/base"
|
|
14
|
-
require_relative "adf_builder/base/prospect"
|
|
15
|
-
require_relative "adf_builder/base/request_date"
|
|
16
|
-
|
|
17
|
-
# PROVIDER
|
|
18
|
-
require_relative "adf_builder/provider/provider"
|
|
19
|
-
|
|
20
|
-
# SHARED
|
|
21
|
-
require_relative "adf_builder/shared/id"
|
|
22
|
-
require_relative "adf_builder/shared/contact"
|
|
23
|
-
|
|
24
|
-
# VEHICLES
|
|
25
|
-
require_relative "adf_builder/vehicles/vehicles"
|
|
26
|
-
require_relative "adf_builder/vehicles/colorcombinations"
|
|
27
|
-
require_relative "adf_builder/vehicles/price"
|
|
28
|
-
|
|
29
|
-
# VENDOR
|
|
30
|
-
require_relative "adf_builder/vendor/vendor"
|
|
31
|
-
|
|
32
|
-
# v1.0 DSL
|
|
33
|
-
# v1.0 DSL
|
|
34
7
|
require_relative "adf_builder/validations"
|
|
8
|
+
|
|
9
|
+
# Nodes
|
|
35
10
|
require_relative "adf_builder/nodes/node"
|
|
36
11
|
require_relative "adf_builder/nodes/prospect"
|
|
12
|
+
require_relative "adf_builder/nodes/shared"
|
|
37
13
|
require_relative "adf_builder/nodes/vehicle"
|
|
14
|
+
require_relative "adf_builder/nodes/vehicle_nodes"
|
|
38
15
|
require_relative "adf_builder/nodes/customer"
|
|
16
|
+
require_relative "adf_builder/nodes/vendor"
|
|
17
|
+
require_relative "adf_builder/nodes/provider"
|
|
18
|
+
|
|
19
|
+
# Core
|
|
39
20
|
require_relative "adf_builder/serializer"
|
|
40
21
|
require_relative "adf_builder/dsl"
|
|
41
22
|
|
|
42
23
|
module AdfBuilder
|
|
43
24
|
class Error < StandardError; end
|
|
44
|
-
|
|
45
|
-
class Builder
|
|
46
|
-
def initialize
|
|
47
|
-
@doc = init_doc
|
|
48
|
-
@base = Base.new(@doc)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def prospect
|
|
52
|
-
@base.prospect
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
# output the XML
|
|
56
|
-
def to_xml
|
|
57
|
-
Ox.dump(@doc, {})
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
# def an example of minimal XML taken from ADF spec file http://adfxml.info/adf_spec.pdf
|
|
61
|
-
def minimal_lead
|
|
62
|
-
prospect = Ox::Element.new("prospect")
|
|
63
|
-
|
|
64
|
-
request_date = Ox::Element.new("requestdate")
|
|
65
|
-
request_date << "2000-03-30T15:30:20-08:00"
|
|
66
|
-
|
|
67
|
-
vehicle = Ox::Element.new("vehicle")
|
|
68
|
-
year = Ox::Element.new("year")
|
|
69
|
-
year << "1999"
|
|
70
|
-
|
|
71
|
-
make = Ox::Element.new("make")
|
|
72
|
-
make << "Chevrolet"
|
|
73
|
-
|
|
74
|
-
model = Ox::Element.new("model")
|
|
75
|
-
model << "Blazer"
|
|
76
|
-
|
|
77
|
-
vehicle << year << make << model
|
|
78
|
-
|
|
79
|
-
customer = Ox::Element.new("customer")
|
|
80
|
-
|
|
81
|
-
contact = Ox::Element.new("contact")
|
|
82
|
-
|
|
83
|
-
name = Ox::Element.new("name")
|
|
84
|
-
name[:part] = "full"
|
|
85
|
-
name << "John Doe"
|
|
86
|
-
|
|
87
|
-
phone = Ox::Element.new("phone")
|
|
88
|
-
phone << "393-999-3922"
|
|
89
|
-
|
|
90
|
-
contact << name << phone
|
|
91
|
-
customer << contact
|
|
92
|
-
|
|
93
|
-
vendor = Ox::Element.new("vendor")
|
|
94
|
-
|
|
95
|
-
contact = Ox::Element.new("contact")
|
|
96
|
-
name = Ox::Element.new("name")
|
|
97
|
-
name[:part] = "full"
|
|
98
|
-
name << "Acura of Bellevue"
|
|
99
|
-
|
|
100
|
-
contact << name
|
|
101
|
-
vendor << contact
|
|
102
|
-
|
|
103
|
-
prospect << request_date << vehicle << customer << vendor
|
|
104
|
-
@doc.remove_children_by_path("adf/prospect")
|
|
105
|
-
@doc.adf << prospect
|
|
106
|
-
Ox.dump(@doc, {})
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
# go back to the initial structure
|
|
110
|
-
def reset_doc
|
|
111
|
-
@doc.adf.prospect.remove_children_by_path("*")
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
# all the files will start with this same header
|
|
115
|
-
def init_doc
|
|
116
|
-
doc = Ox::Document.new
|
|
117
|
-
instruct = Ox::Instruct.new(:xml)
|
|
118
|
-
instruct[:version] = "1.0"
|
|
119
|
-
doc << instruct
|
|
120
|
-
doc << Ox::Raw.new("")
|
|
121
|
-
instruct = Ox::Instruct.new("ADF")
|
|
122
|
-
instruct[:version] = "1.0"
|
|
123
|
-
doc << instruct
|
|
124
|
-
adf = Ox::Element.new("adf")
|
|
125
|
-
doc << adf
|
|
126
|
-
doc
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
# we will either create a new node with the value or replace the one if it is available
|
|
130
|
-
def self.update_node(parent_node, key, value, params = {})
|
|
131
|
-
key = key.to_s
|
|
132
|
-
value = value.to_s
|
|
133
|
-
if parent_node.locate(key).size.positive?
|
|
134
|
-
node = parent_node.locate(key).first
|
|
135
|
-
node.replace_text(value)
|
|
136
|
-
else
|
|
137
|
-
node = (Ox::Element.new(key) << value)
|
|
138
|
-
parent_node << node
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
AdfBuilder::Builder.update_params(node, key, params)
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
# update the params by first checking if they are valid params and then checking if the values are valid if necessary
|
|
145
|
-
def self.update_params(node, key, params)
|
|
146
|
-
return true if params.empty?
|
|
147
|
-
|
|
148
|
-
key = key.to_sym
|
|
149
|
-
valid_values = params[:valid_values]
|
|
150
|
-
valid_parameters = params[:valid_parameters]
|
|
151
|
-
_params = AdfBuilder::Builder.whitelabel_params(params, valid_parameters, key)
|
|
152
|
-
_params.each do |k, v|
|
|
153
|
-
node[k] = v if (valid_values[key][k] == true) || valid_values[key][k].include?(v.to_s)
|
|
154
|
-
end
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
# clear out the opts that don't match valid keys
|
|
158
|
-
def self.whitelabel_params(opts, valid_parameters, key)
|
|
159
|
-
opts.slice(*valid_parameters[key])
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
def self.valid_child?(parent, tag_name, index)
|
|
163
|
-
child = parent.locate(tag_name)[index]
|
|
164
|
-
[!child.nil?, child]
|
|
165
|
-
end
|
|
166
|
-
end
|
|
167
25
|
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.
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- marcus.salinas
|
|
@@ -100,26 +100,18 @@ files:
|
|
|
100
100
|
- bin/console
|
|
101
101
|
- bin/setup
|
|
102
102
|
- lib/adf_builder.rb
|
|
103
|
-
- lib/adf_builder/base/base.rb
|
|
104
|
-
- lib/adf_builder/base/prospect.rb
|
|
105
|
-
- lib/adf_builder/base/request_date.rb
|
|
106
|
-
- lib/adf_builder/customer/customer.rb
|
|
107
|
-
- lib/adf_builder/customer/timeframe.rb
|
|
108
103
|
- lib/adf_builder/data/iso-4217-currency-codes.json
|
|
109
104
|
- lib/adf_builder/dsl.rb
|
|
110
105
|
- lib/adf_builder/nodes/customer.rb
|
|
111
106
|
- lib/adf_builder/nodes/node.rb
|
|
112
107
|
- lib/adf_builder/nodes/prospect.rb
|
|
108
|
+
- lib/adf_builder/nodes/provider.rb
|
|
109
|
+
- lib/adf_builder/nodes/shared.rb
|
|
113
110
|
- lib/adf_builder/nodes/vehicle.rb
|
|
114
|
-
- lib/adf_builder/
|
|
111
|
+
- lib/adf_builder/nodes/vehicle_nodes.rb
|
|
112
|
+
- lib/adf_builder/nodes/vendor.rb
|
|
115
113
|
- lib/adf_builder/serializer.rb
|
|
116
|
-
- lib/adf_builder/shared/contact.rb
|
|
117
|
-
- lib/adf_builder/shared/id.rb
|
|
118
114
|
- lib/adf_builder/validations.rb
|
|
119
|
-
- lib/adf_builder/vehicles/colorcombinations.rb
|
|
120
|
-
- lib/adf_builder/vehicles/price.rb
|
|
121
|
-
- lib/adf_builder/vehicles/vehicles.rb
|
|
122
|
-
- lib/adf_builder/vendor/vendor.rb
|
|
123
115
|
- lib/adf_builder/version.rb
|
|
124
116
|
homepage: https://github.com/jippylong12/adf_builder
|
|
125
117
|
licenses:
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module AdfBuilder
|
|
4
|
-
class Prospect
|
|
5
|
-
STATUSES = {
|
|
6
|
-
new: :new,
|
|
7
|
-
resend: :resend
|
|
8
|
-
}.freeze
|
|
9
|
-
|
|
10
|
-
def initialize(doc)
|
|
11
|
-
@doc = doc
|
|
12
|
-
@doc.adf << Ox::Element.new("prospect")
|
|
13
|
-
@prospect = @doc.adf.prospect
|
|
14
|
-
@prospect[:status] = STATUSES[:new]
|
|
15
|
-
|
|
16
|
-
@request_date = RequestDate.new(@prospect)
|
|
17
|
-
@vehicles = Vehicles.new(@prospect)
|
|
18
|
-
@customer = Customer.new(@prospect)
|
|
19
|
-
@vendor = Vendor.new(@prospect)
|
|
20
|
-
@provider = Provider.new(@prospect)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
attr_reader :request_date, :vehicles, :customer, :vendor, :provider
|
|
24
|
-
|
|
25
|
-
# set status to renew
|
|
26
|
-
def set_renew
|
|
27
|
-
@prospect[:status] = STATUSES[:resend]
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def add_id(value, source = nil, sequence = 1)
|
|
31
|
-
Id.new.add(@prospect, value, source, sequence)
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module AdfBuilder
|
|
4
|
-
class RequestDate
|
|
5
|
-
WITH_SYMBOLS = "%FT%T%:z"
|
|
6
|
-
WITHOUT_SYMBOLS = "%Y%m%dT%H%M%S%z"
|
|
7
|
-
|
|
8
|
-
def initialize(prospect_node)
|
|
9
|
-
@request_date_node = Ox::Element.new("requestdate")
|
|
10
|
-
@request_date_node << DateTime.now.strftime("%FT%T%:z")
|
|
11
|
-
prospect_node << @request_date_node
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def update_val(datetime_value, format = 1)
|
|
15
|
-
if format == 1
|
|
16
|
-
@request_date_node.replace_text(datetime_value.strftime(WITH_SYMBOLS))
|
|
17
|
-
elsif format == 2
|
|
18
|
-
@request_date_node.replace_text(datetime_value.strftime(WITHOUT_SYMBOLS))
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module AdfBuilder
|
|
4
|
-
class Customer
|
|
5
|
-
def initialize(prospect)
|
|
6
|
-
@customer = Ox::Element.new("customer")
|
|
7
|
-
@contact = nil
|
|
8
|
-
@timeframe = nil
|
|
9
|
-
|
|
10
|
-
prospect << @customer
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
attr_reader :contact, :timeframe
|
|
14
|
-
|
|
15
|
-
def add(name, opts = {})
|
|
16
|
-
@contact = Contact.new(@customer, name, opts)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def add_id(index, value, source = nil, sequence = 1)
|
|
20
|
-
if @prospect.locate("customer").empty?
|
|
21
|
-
false
|
|
22
|
-
else
|
|
23
|
-
Id.new.add(@prospect.customer(index), value, source, sequence)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# @param descriptin [String] - Description of customer’s timing intention.
|
|
28
|
-
# @param earliest_date [DateTime] - Earliest date customer is interested in. If timeframe tag
|
|
29
|
-
# is present, it is required to specify earliestdate and/or
|
|
30
|
-
# latestdate
|
|
31
|
-
# @param latest_date [DateTime] - Latest date customer is interested in. If timeframe tag
|
|
32
|
-
# is present, it is required to specify earliestdate and/or
|
|
33
|
-
# latestdate
|
|
34
|
-
def add_timeframe(description, earliest_date = nil, latest_date = nil)
|
|
35
|
-
return false if earliest_date.nil? && latest_date.nil?
|
|
36
|
-
|
|
37
|
-
return false if earliest_date && (earliest_date.class != DateTime)
|
|
38
|
-
|
|
39
|
-
return false if latest_date && (latest_date.class != DateTime)
|
|
40
|
-
|
|
41
|
-
@timeframe = Timeframe.new(@customer, description, earliest_date, latest_date) if @timeframe.nil?
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def update_comments(comments)
|
|
45
|
-
return false if comments.class != String
|
|
46
|
-
|
|
47
|
-
AdfBuilder::Builder.update_node(@customer, :comments, comments)
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module AdfBuilder
|
|
4
|
-
class Timeframe
|
|
5
|
-
def initialize(customer, description, earliest_date, latest_date)
|
|
6
|
-
begin
|
|
7
|
-
earliest_date = earliest_date.strftime("%FT%T%:z") if earliest_date
|
|
8
|
-
latest_date = latest_date.strftime("%FT%T%:z") if latest_date
|
|
9
|
-
rescue StandardError
|
|
10
|
-
return nil
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
@timeframe = Ox::Element.new("timeframe")
|
|
14
|
-
|
|
15
|
-
@timeframe << (Ox::Element.new("description") << description)
|
|
16
|
-
@timeframe << (Ox::Element.new("earliestdate") << earliest_date) if earliest_date
|
|
17
|
-
@timeframe << (Ox::Element.new("latestdate") << latest_date) if latest_date
|
|
18
|
-
customer << @timeframe
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def update_description(description)
|
|
22
|
-
AdfBuilder::Builder.update_node(@timeframe, :description, description)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def update_earliest_date(date)
|
|
26
|
-
begin
|
|
27
|
-
date = date.strftime("%FT%T%:z")
|
|
28
|
-
rescue StandardError
|
|
29
|
-
return false
|
|
30
|
-
end
|
|
31
|
-
AdfBuilder::Builder.update_node(@timeframe, :earliestdate, date)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def update_latest_date(date)
|
|
35
|
-
begin
|
|
36
|
-
date = date.strftime("%FT%T%:z")
|
|
37
|
-
rescue StandardError
|
|
38
|
-
return false
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
AdfBuilder::Builder.update_node(@timeframe, :latestdate, date)
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module AdfBuilder
|
|
4
|
-
class Provider
|
|
5
|
-
FREE_TEXT_OPTIONAL_TAGS = %i[service url].freeze
|
|
6
|
-
|
|
7
|
-
def initialize(prospect)
|
|
8
|
-
@prospect = prospect
|
|
9
|
-
@provider = nil
|
|
10
|
-
@contact = nil
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
attr_reader :contact
|
|
14
|
-
|
|
15
|
-
def add(name, params = {})
|
|
16
|
-
@provider = Ox::Element.new("provider")
|
|
17
|
-
params.merge!({ valid_values: AdfBuilder::Contact::VALID_VALUES,
|
|
18
|
-
valid_parameters: AdfBuilder::Contact::VALID_PARAMETERS })
|
|
19
|
-
AdfBuilder::Builder.update_node(@provider, :name, name, params)
|
|
20
|
-
@prospect << @provider
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def add_contact(name, opts = {})
|
|
24
|
-
@contact = Contact.new(@provider, name, opts)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def add_phone(phone, params = {})
|
|
28
|
-
params.merge!({ valid_values: AdfBuilder::Contact::VALID_VALUES,
|
|
29
|
-
valid_parameters: AdfBuilder::Contact::VALID_PARAMETERS })
|
|
30
|
-
AdfBuilder::Builder.update_node(@provider, :phone, phone, params)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def add_email(email, params = {})
|
|
34
|
-
params.merge!({ valid_values: AdfBuilder::Contact::VALID_VALUES,
|
|
35
|
-
valid_parameters: AdfBuilder::Contact::VALID_PARAMETERS })
|
|
36
|
-
AdfBuilder::Builder.update_node(@provider, :email, email, params)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def update_tags_with_free_text(tags)
|
|
40
|
-
tags.each do |key, value|
|
|
41
|
-
AdfBuilder::Builder.update_node(@provider, key, value) if FREE_TEXT_OPTIONAL_TAGS.include? key.to_sym
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def add_id(index, value, source = nil, sequence = 1)
|
|
46
|
-
if @prospect.locate("provider").empty?
|
|
47
|
-
false
|
|
48
|
-
else
|
|
49
|
-
Id.new.add(@prospect.provider(index), value, source, sequence)
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module AdfBuilder
|
|
4
|
-
class Contact
|
|
5
|
-
VALID_PARAMETERS = {
|
|
6
|
-
name: %i[part type primarycontact],
|
|
7
|
-
email: [:preferredcontact],
|
|
8
|
-
phone: %i[type time preferredcontact]
|
|
9
|
-
}.freeze
|
|
10
|
-
|
|
11
|
-
VALID_VALUES = {
|
|
12
|
-
name: {
|
|
13
|
-
part: %w[first middle suffix last full],
|
|
14
|
-
type: %w[individual business],
|
|
15
|
-
primarycontact: %w[0 1]
|
|
16
|
-
},
|
|
17
|
-
email: {
|
|
18
|
-
preferredcontact: %w[0 1]
|
|
19
|
-
},
|
|
20
|
-
phone: {
|
|
21
|
-
preferredcontact: %w[0 1],
|
|
22
|
-
type: %w[phone fax cellphone pager],
|
|
23
|
-
time: %w[morning afternoon evening nopreference day]
|
|
24
|
-
}
|
|
25
|
-
}.freeze
|
|
26
|
-
|
|
27
|
-
def initialize(parent_node, name, params = {})
|
|
28
|
-
@contact = Ox::Element.new("contact")
|
|
29
|
-
params.merge!({ valid_values: VALID_VALUES, valid_parameters: VALID_PARAMETERS })
|
|
30
|
-
AdfBuilder::Builder.update_node(@contact, :name, name, params)
|
|
31
|
-
parent_node << @contact
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def add_phone(phone, params = {})
|
|
35
|
-
params.merge!({ valid_values: VALID_VALUES, valid_parameters: VALID_PARAMETERS })
|
|
36
|
-
AdfBuilder::Builder.update_node(@contact, :phone, phone, params)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def add_email(email, params = {})
|
|
40
|
-
params.merge!({ valid_values: VALID_VALUES, valid_parameters: VALID_PARAMETERS })
|
|
41
|
-
AdfBuilder::Builder.update_node(@contact, :email, email, params)
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module AdfBuilder
|
|
4
|
-
class Id
|
|
5
|
-
def initialize; end
|
|
6
|
-
|
|
7
|
-
# add id tag to the form
|
|
8
|
-
def add(parent_node, value, source = nil, sequence = 1)
|
|
9
|
-
id_node = Ox::Element.new("id")
|
|
10
|
-
id_node << value
|
|
11
|
-
id_node[:sequence] = sequence
|
|
12
|
-
|
|
13
|
-
id_node[:source] = source if source
|
|
14
|
-
|
|
15
|
-
parent_node.prepend_child(id_node)
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module AdfBuilder
|
|
4
|
-
class ColorCombinations
|
|
5
|
-
FREE_TEXT_OPTIONAL_TAGS = %i[interiorcolor exteriorcolor preference].freeze
|
|
6
|
-
|
|
7
|
-
def initialize(vehicle)
|
|
8
|
-
@vehicle = vehicle
|
|
9
|
-
@color_combination = nil
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def add(interior_color, exterior_color, preference)
|
|
13
|
-
@color_combination = Ox::Element.new("colorcombination")
|
|
14
|
-
@color_combination <<
|
|
15
|
-
(Ox::Element.new("interiorcolor") << interior_color) <<
|
|
16
|
-
(Ox::Element.new("exteriorcolor") << exterior_color) <<
|
|
17
|
-
(Ox::Element.new("preference") << preference.to_s)
|
|
18
|
-
@vehicle << @color_combination
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def update_tags(index, tags)
|
|
22
|
-
valid, vehicle = AdfBuilder::Builder.valid_child?(@vehicle, "colorcombination", index)
|
|
23
|
-
return unless valid
|
|
24
|
-
|
|
25
|
-
tags.each do |key, value|
|
|
26
|
-
AdfBuilder::Builder.update_node(vehicle, key, value) if FREE_TEXT_OPTIONAL_TAGS.include? key.to_sym
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module AdfBuilder
|
|
4
|
-
class Price
|
|
5
|
-
VALID_PARAMETERS = {
|
|
6
|
-
price: %i[type currency delta relativeto source]
|
|
7
|
-
}.freeze
|
|
8
|
-
|
|
9
|
-
VALID_VALUES = {
|
|
10
|
-
price: {
|
|
11
|
-
type: %w[quote offer msrp invoice call appraisal asking],
|
|
12
|
-
currency: true,
|
|
13
|
-
delta: %w[absolute relative percentage],
|
|
14
|
-
relativeto: %w[msrp invoice],
|
|
15
|
-
source: true
|
|
16
|
-
}
|
|
17
|
-
}.freeze
|
|
18
|
-
|
|
19
|
-
def initialize(parent_node, value, params = {})
|
|
20
|
-
@parent_node = parent_node
|
|
21
|
-
params.merge!({ valid_values: VALID_VALUES, valid_parameters: VALID_PARAMETERS })
|
|
22
|
-
validate_currency(params)
|
|
23
|
-
AdfBuilder::Builder.update_node(@parent_node, :price, value, params)
|
|
24
|
-
@price = @parent_node.price
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def update(value, params = {})
|
|
28
|
-
params.merge!({ valid_values: VALID_VALUES, valid_parameters: VALID_PARAMETERS })
|
|
29
|
-
AdfBuilder::Builder.update_node(@parent_node, :price, value, params)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def validate_currency(params)
|
|
33
|
-
code = params[:currency]
|
|
34
|
-
return unless code
|
|
35
|
-
|
|
36
|
-
json = JSON.parse(File.read("./lib/adf_builder/data/iso-4217-currency-codes.json"))
|
|
37
|
-
codes = json.map { |j| j["Alphabetic_Code"] }.reject(&:nil?)
|
|
38
|
-
return if codes.include? code
|
|
39
|
-
|
|
40
|
-
params.delete(:currency)
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module AdfBuilder
|
|
4
|
-
class Vehicles
|
|
5
|
-
VALID_PARAMETERS = {
|
|
6
|
-
vehicle: %i[interest status],
|
|
7
|
-
odometer: %i[status units],
|
|
8
|
-
imagetag: %i[width height alttext]
|
|
9
|
-
}.freeze
|
|
10
|
-
|
|
11
|
-
VALID_VALUES = {
|
|
12
|
-
vehicle: {
|
|
13
|
-
interest: %w[buy lease sell trade-in test-drive],
|
|
14
|
-
status: %w[new used]
|
|
15
|
-
},
|
|
16
|
-
odometer: {
|
|
17
|
-
status: %w[unknown rolledover replaced original],
|
|
18
|
-
units: %w[km mi]
|
|
19
|
-
},
|
|
20
|
-
imagetag: {
|
|
21
|
-
width: true,
|
|
22
|
-
height: true,
|
|
23
|
-
alttext: true
|
|
24
|
-
}
|
|
25
|
-
}.freeze
|
|
26
|
-
|
|
27
|
-
FREE_TEXT_OPTIONAL_TAGS = %i[year make model vin stock
|
|
28
|
-
trim doors bodystyle transmission pricecomments comments].freeze
|
|
29
|
-
|
|
30
|
-
CONDITIONS = %w[excellent good fair poor unknown].freeze
|
|
31
|
-
|
|
32
|
-
def initialize(prospect)
|
|
33
|
-
@prospect = prospect
|
|
34
|
-
@color_combinations = []
|
|
35
|
-
@prices = []
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def add_color_combination(v_index, interior_color, exterior_color, preference)
|
|
39
|
-
valid, vehicle = AdfBuilder::Builder.valid_child?(@prospect, "vehicle", v_index)
|
|
40
|
-
return unless valid
|
|
41
|
-
|
|
42
|
-
cc = ColorCombinations.new(vehicle)
|
|
43
|
-
cc.add(interior_color, exterior_color, preference)
|
|
44
|
-
@color_combinations.push(cc)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def color_combination(index)
|
|
48
|
-
@color_combinations[index]
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def price(index)
|
|
52
|
-
@prices[index]
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def add(year, make, model, params = {})
|
|
56
|
-
vehicle = Ox::Element.new("vehicle")
|
|
57
|
-
|
|
58
|
-
params.merge!({ valid_values: VALID_VALUES, valid_parameters: VALID_PARAMETERS })
|
|
59
|
-
AdfBuilder::Builder.update_params(vehicle, :vehicle, params)
|
|
60
|
-
|
|
61
|
-
vehicle << (Ox::Element.new("year") << year.to_s)
|
|
62
|
-
vehicle << (Ox::Element.new("make") << make)
|
|
63
|
-
vehicle << (Ox::Element.new("model") << model)
|
|
64
|
-
|
|
65
|
-
@prospect << vehicle
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def update_odometer(index, value, params = {})
|
|
69
|
-
valid, vehicle = AdfBuilder::Builder.valid_child?(@prospect, "vehicle", index)
|
|
70
|
-
return unless valid
|
|
71
|
-
|
|
72
|
-
params.merge!({ valid_values: VALID_VALUES, valid_parameters: VALID_PARAMETERS })
|
|
73
|
-
AdfBuilder::Builder.update_node(vehicle, "odometer", value, params)
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def update_condition(index, value)
|
|
77
|
-
valid, vehicle = AdfBuilder::Builder.valid_child?(@prospect, "vehicle", index)
|
|
78
|
-
return unless valid && CONDITIONS.include?(value)
|
|
79
|
-
|
|
80
|
-
AdfBuilder::Builder.update_node(vehicle, "condition", value)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def update_imagetag(index, value, params = {})
|
|
84
|
-
valid, vehicle = AdfBuilder::Builder.valid_child?(@prospect, "vehicle", index)
|
|
85
|
-
return unless valid
|
|
86
|
-
|
|
87
|
-
params.merge!({ valid_values: VALID_VALUES, valid_parameters: VALID_PARAMETERS })
|
|
88
|
-
AdfBuilder::Builder.update_node(vehicle, "imagetag", value, params)
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def update_tags_with_free_text(index, tags)
|
|
92
|
-
valid, vehicle = AdfBuilder::Builder.valid_child?(@prospect, "vehicle", index)
|
|
93
|
-
return unless valid
|
|
94
|
-
|
|
95
|
-
tags.each do |key, value|
|
|
96
|
-
AdfBuilder::Builder.update_node(vehicle, key, value) if FREE_TEXT_OPTIONAL_TAGS.include? key.to_sym
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def add_id(index, value, source = nil, sequence = 1)
|
|
101
|
-
if @prospect.locate("vehicle").empty? || @prospect.vehicle(index).nil?
|
|
102
|
-
false
|
|
103
|
-
else
|
|
104
|
-
Id.new.add(@prospect.vehicle(index), value, source, sequence)
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
def add_price(index, value, params = {})
|
|
109
|
-
valid, vehicle = AdfBuilder::Builder.valid_child?(@prospect, "vehicle", index)
|
|
110
|
-
return unless valid
|
|
111
|
-
|
|
112
|
-
price = Price.new(vehicle, value, params)
|
|
113
|
-
@prices.push(price)
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
def add_comments(index, value)
|
|
117
|
-
valid, vehicle = AdfBuilder::Builder.valid_child?(@prospect, "vehicle", index)
|
|
118
|
-
return unless valid
|
|
119
|
-
|
|
120
|
-
AdfBuilder::Builder.update_node(vehicle, "comments", value)
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
end
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module AdfBuilder
|
|
4
|
-
class Vendor
|
|
5
|
-
def initialize(prospect)
|
|
6
|
-
@vendor = Ox::Element.new("vendor")
|
|
7
|
-
@contact = nil
|
|
8
|
-
prospect << @vendor
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
attr_reader :contact
|
|
12
|
-
|
|
13
|
-
def add(name, contact_name, opts = {})
|
|
14
|
-
@vendor << (Ox::Element.new("vendorname") << name)
|
|
15
|
-
@contact = Contact.new(@vendor, contact_name, opts)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def add_url(url)
|
|
19
|
-
@vendor.remove_children(@vendor.url) if @vendor.locate("url").size.positive?
|
|
20
|
-
@vendor << (Ox::Element.new("url") << url)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def add_id(index, value, source = nil, sequence = 1)
|
|
24
|
-
if @prospect.locate("vendor").empty?
|
|
25
|
-
false
|
|
26
|
-
else
|
|
27
|
-
Id.new.add(@prospect.vendor(index), value, source, sequence)
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|