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: '039c056f31f39d29c6dd956c1eea702c9719ee62c1549d1ee5eba1f7154aabcc'
4
- data.tar.gz: 11cde731d4163bc95d8ea9b154171d8c1be4998812fdfa1c7bf9d3e78a77fd07
3
+ metadata.gz: 1025b857902f5c14f649104a892ec5d882201920933ca4f010b45cab3a25f480
4
+ data.tar.gz: 999d68b437f373c47b70f69f5d884c52a30c6788f46262beb226b24c2200bba0
5
5
  SHA512:
6
- metadata.gz: ffe42c8cb2135556c76c64ee241b59256632196ef38ce920c365f6e501eab321d300142d41ed04eff1da9a6a98af8498cf683488408db113f1322916774b9b1f
7
- data.tar.gz: 1ef83798e88e33c4a275dd298a0d6abb5cf48a920903ea7086838634d04226023e6be25f7c54b769d31b158c71326cf8d3ddc1aee5af8ba1b292dd1b7ffeb63a
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
- skus = products.map { |product| product['sku'] }
90
- response = acumen_client.get_product_categories(skus)
91
- categories = process_product_categories_query(response)
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
- sku = product['sku']
96
- if categories[sku]
97
- active = categories[sku].select { |c| c['inactive'] == '0' }
98
- product['categories'] = active.map do |category|
99
- {
100
- '@type' => 'Thing',
101
- 'identifier' => category['category_id']
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.6.0
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-10-12 00:00:00.000000000 Z
11
+ date: 2020-12-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler