huginn_acumen_product_agent 1.6.0 → 1.7.3
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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1025b857902f5c14f649104a892ec5d882201920933ca4f010b45cab3a25f480
|
4
|
+
data.tar.gz: 999d68b437f373c47b70f69f5d884c52a30c6788f46262beb226b24c2200bba0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 46ea5a9bd225a32c1af84c9a14becb87b71a4c01038a85199e6dfc9bdea0f1073fef090738839f4d2cbc2a5d3b3b81e2d13da67cc9f6952dbd9542b7647a3014
|
7
|
+
data.tar.gz: c08f0f45ed92defb6704b6b821053859c959c0a4061c5f58b094bac7c5bb5ca3c7e1bf0bda93ff2117d11134533945d00a6b65df1a6ed1214c2ac242a88c2782
|
@@ -95,6 +95,8 @@ class AcumenClient
|
|
95
95
|
<column_name>Inv_Product.Category</column_name>
|
96
96
|
<column_name>Inv_Product.Next_Release</column_name>
|
97
97
|
<column_name>Inv_Product.BO_Reason</column_name>
|
98
|
+
<column_name>Inv_Product.Not_On_Website</column_name>
|
99
|
+
<column_name>Inv_Product.Not_Active</column_name>
|
98
100
|
</requested_output>
|
99
101
|
</acusoapRequest>
|
100
102
|
XML
|
@@ -11,7 +11,28 @@ module Agents
|
|
11
11
|
default_schedule 'never'
|
12
12
|
|
13
13
|
description <<-MD
|
14
|
-
Huginn agent for sane ACUMEN product data.
|
14
|
+
Huginn agent for retrieving sane ACUMEN product data.
|
15
|
+
|
16
|
+
## Agent Options
|
17
|
+
The following outlines the available options in this agent
|
18
|
+
|
19
|
+
### Acumen Connection
|
20
|
+
* endpoint: The root URL for the Acumen API
|
21
|
+
* site_code: The site code from Acumen
|
22
|
+
* password: The Acumen API password
|
23
|
+
|
24
|
+
### Variant Settings
|
25
|
+
* physical_formats: A list of the formats associated with a physical product
|
26
|
+
* digital_formats: A list of the formats associated with a digital product
|
27
|
+
|
28
|
+
### Product Attributes
|
29
|
+
* attribute_to_property: An optional map linking Acumen attributes to Schema.org
|
30
|
+
product properties.
|
31
|
+
|
32
|
+
### Other Options
|
33
|
+
* ignore_skus: An optional array of Acumen product skus that will be intentionally
|
34
|
+
excluded from any output.
|
35
|
+
|
15
36
|
MD
|
16
37
|
|
17
38
|
def default_options
|
@@ -22,7 +43,6 @@ module Agents
|
|
22
43
|
'physical_formats' => [],
|
23
44
|
'digital_formats' => [],
|
24
45
|
'attribute_to_property' => {},
|
25
|
-
'contributor_types_map' => {},
|
26
46
|
}
|
27
47
|
end
|
28
48
|
|
@@ -51,10 +71,6 @@ module Agents
|
|
51
71
|
errors.add(:base, "if provided, attribute_to_property must be a hash")
|
52
72
|
end
|
53
73
|
|
54
|
-
unless options['contributor_types_map'].is_a?(Hash)
|
55
|
-
errors.add(:base, "if provided, contributor_types_map must be a hash")
|
56
|
-
end
|
57
|
-
|
58
74
|
if options['ignore_skus']
|
59
75
|
unless options['ignore_skus'].is_a?(Array)
|
60
76
|
errors.add(:base, "if provided, ignore_skus must be an array")
|
@@ -96,6 +112,7 @@ module Agents
|
|
96
112
|
ids = event.payload['ids']
|
97
113
|
products = get_products_by_ids(client, ids)
|
98
114
|
products = get_product_variants(client, products, physical_formats, digital_formats)
|
115
|
+
products = get_master_products_by_id(client, products)
|
99
116
|
products = get_product_categories(client, products)
|
100
117
|
products = get_product_contributors(client, products)
|
101
118
|
|
@@ -10,6 +10,8 @@ module AcumenProductQueryConcern
|
|
10
10
|
|
11
11
|
def get_products_by_ids(acumen_client, ids)
|
12
12
|
response = acumen_client.get_products(ids)
|
13
|
+
products = []
|
14
|
+
|
13
15
|
products = parse_product_request(response)
|
14
16
|
|
15
17
|
response = acumen_client.get_products_marketing(ids)
|
@@ -69,6 +71,35 @@ module AcumenProductQueryConcern
|
|
69
71
|
products
|
70
72
|
end
|
71
73
|
|
74
|
+
def get_master_products_by_id(client, products)
|
75
|
+
master_products = []
|
76
|
+
|
77
|
+
products.each do |product|
|
78
|
+
wrapper_id = product['identifier']
|
79
|
+
master_id = 0
|
80
|
+
product['model'].each do |variant|
|
81
|
+
if variant['acumenAttributes']['is_master'] && variant['isAvailableForPurchase']
|
82
|
+
master_id = variant['identifier']
|
83
|
+
end
|
84
|
+
end
|
85
|
+
if wrapper_id == master_id || master_id == 0
|
86
|
+
master_products.push(product)
|
87
|
+
else
|
88
|
+
if (master_products.find { |p| p['identifier'] == master_id }).nil?
|
89
|
+
reloaded_product = get_products_by_ids(client, [master_id.to_s])[0]
|
90
|
+
|
91
|
+
unless reloaded_product.nil?
|
92
|
+
reloaded_product['model'] = product['model']
|
93
|
+
reloaded_product['additionalProperty'].push(product['additionalProperty'].select { |m| m['propertyID'] == 'baseSku'}[0])
|
94
|
+
master_products.push(reloaded_product)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
master_products
|
101
|
+
end
|
102
|
+
|
72
103
|
def get_product_variants(acumen_client, products, physical_formats, digital_formats)
|
73
104
|
ids = products.map { |product| product['identifier'] }
|
74
105
|
# fetch product/variant relationships
|
@@ -86,20 +117,27 @@ module AcumenProductQueryConcern
|
|
86
117
|
|
87
118
|
def get_product_categories(acumen_client, products)
|
88
119
|
# fetch categories
|
89
|
-
|
90
|
-
|
91
|
-
|
120
|
+
categories_map = {}
|
121
|
+
|
122
|
+
skus = products.map { |product| product['model'].map { |m| m['sku'] } }
|
123
|
+
skus.each do |sku_set|
|
124
|
+
sku_set.each do |sku|
|
125
|
+
response = acumen_client.get_product_categories([sku])
|
126
|
+
categories = process_product_categories_query(response)
|
127
|
+
categories_map[sku] = categories != {} ? categories[sku] : []
|
128
|
+
end
|
129
|
+
end
|
92
130
|
|
93
131
|
# map categories to products
|
94
132
|
products.each do |product|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
133
|
+
product['model'].each do |variant|
|
134
|
+
variant['categories'] = []
|
135
|
+
categories = categories_map[variant['sku']].select { |c| c['inactive'] == '0' }
|
136
|
+
categories.map do |c|
|
137
|
+
variant['categories'].push({
|
138
|
+
'@type' => 'Thing',
|
139
|
+
'identifier' => c['category_id']
|
140
|
+
})
|
103
141
|
end
|
104
142
|
end
|
105
143
|
end
|
@@ -120,6 +158,7 @@ module AcumenProductQueryConcern
|
|
120
158
|
variant['@type'] = 'ProductModel'
|
121
159
|
variant['isDefault'] = false
|
122
160
|
variant['isTaxable'] = field_value(p, 'Inv_Product.Taxable') == '1'
|
161
|
+
variant['isAvailableForPurchase'] = field_value(p, 'Inv_Product.Not_On_Website') == '0'
|
123
162
|
variant['acumenAttributes'] = {
|
124
163
|
'is_master' => field_value(p, 'Inv_Product.OnWeb_LinkOnly') == '0'
|
125
164
|
}
|
@@ -154,6 +193,7 @@ module AcumenProductQueryConcern
|
|
154
193
|
'info_alpha_1' => field_value(p, 'Inv_Product.Info_Alpha_1'),
|
155
194
|
'info_boolean_1' => field_value(p, 'Inv_Product.Info_Boolean_1'),
|
156
195
|
},
|
196
|
+
'isAvailableForPurchase' => field_value(p, variant['isAvailableForPurchase']),
|
157
197
|
}
|
158
198
|
|
159
199
|
category = field_value(p, 'Inv_Product.Category')
|
@@ -397,6 +437,7 @@ module AcumenProductQueryConcern
|
|
397
437
|
result.each do |product|
|
398
438
|
if product['model'].length == 1
|
399
439
|
product['model'][0]['isDefault'] = true
|
440
|
+
set_base_sku(product, product['model'][0]['sku'])
|
400
441
|
next
|
401
442
|
else
|
402
443
|
physical_formats.each do |val|
|
@@ -417,6 +458,17 @@ module AcumenProductQueryConcern
|
|
417
458
|
end
|
418
459
|
end
|
419
460
|
end
|
461
|
+
|
462
|
+
model_ids = product['model'].map { |m| m['identifier'] }
|
463
|
+
primary_variant = product['model'].select { |m| m['identifier'] == model_ids.min }.first
|
464
|
+
|
465
|
+
# Set the base SKU to the SKU of the oldest record.
|
466
|
+
# The base_sku property is designed to be a system value specific to the inegration using this agent.
|
467
|
+
# As a result, we don't particularly care what that value is so long as we can retrieve it consistently
|
468
|
+
# across executions. If a paperback product is created first, this will always return that product's SKU
|
469
|
+
# as the base. This gives us a consistent way to link Acumen products to an external system where database
|
470
|
+
# IDs may not match.
|
471
|
+
set_base_sku(product, primary_variant ? primary_variant['sku'] : product['model'][0]['sku'])
|
420
472
|
end
|
421
473
|
result
|
422
474
|
end
|
@@ -436,6 +488,18 @@ module AcumenProductQueryConcern
|
|
436
488
|
field[key]['__content__'] if field[key]
|
437
489
|
end
|
438
490
|
|
491
|
+
def set_base_sku(product, sku)
|
492
|
+
|
493
|
+
product['additionalProperty'].push({
|
494
|
+
'@type' => 'PropertyValue',
|
495
|
+
'propertyID' => 'baseSku',
|
496
|
+
'name' => 'Base SKU',
|
497
|
+
'value' => sku,
|
498
|
+
})
|
499
|
+
|
500
|
+
product
|
501
|
+
end
|
502
|
+
|
439
503
|
def quantitative_value(value, unit)
|
440
504
|
{
|
441
505
|
'@type' => 'QuantitativeValue',
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: huginn_acumen_product_agent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jacob Spizziri
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|