huginn_bigcommerce_product_agent 1.0.2 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d6b3753b33f18dcebc855995dd0a0933264939bfbcdb43e3a85782e6c9fe6491
4
- data.tar.gz: 61f18e0d600dca9c000757263ce85402fc8f873c4b0ece8b4eccf32a369a8863
3
+ metadata.gz: fc1f86e4140f0ea64f918029089504724d3fe118af99ff9058520b5443635080
4
+ data.tar.gz: 5e276b0de209730cb1435efd7afe43429bb616b5db1632da8ac6f579fe7f4d34
5
5
  SHA512:
6
- metadata.gz: da2ca4d9e10b4c0fcb386e356559308531dcaafc158ac9c0d2e7839dce7d49f40124f8c7818c70199b22bd7726dffaaaaf8a7597ed588e4108e83be4bf55b7a6
7
- data.tar.gz: e8da778b8ef5a95862ceb721a1e10f27abd11926eb242b1eb2f46266c05698bdbd2d6dfd94439140ebd2892c9da2c4dacca3fb725fe972640e1da43bf9e840dd
6
+ metadata.gz: 3abfde4474f27ea44e964897fb98b689cd15d2b3f502a0a41442ed767a6c93756ce45ad4f888452edf406a0f670dd6e5138cf49d88736610deb4bb7dec867f95
7
+ data.tar.gz: fe9a2d303d6259f58f4d9536cbbf6ff53f7141ecb31a9841b78191acfc0cae9b35eaccfb61aa1adb60005618f87e95e4ebd1a507135fe84e4a82c9305cc3901a
@@ -0,0 +1,49 @@
1
+ module BigcommerceProductAgent
2
+ module Client
3
+ class MetaField < AbstractClient
4
+ @uri_base = 'catalog/products/:product_id/metafields/:meta_field_id'
5
+
6
+ def get_for_product(product_id)
7
+ return [] if product_id.blank?
8
+
9
+ response = client.get(uri(product_id: product_id))
10
+ return response.body['data']
11
+ end
12
+
13
+ def create(meta_field)
14
+ response = client.post(
15
+ uri(product_id: meta_field[:resource_id]),
16
+ meta_field.to_json
17
+ )
18
+
19
+ return response.body['data']
20
+ end
21
+
22
+ def update(meta_field)
23
+ response = client.put(
24
+ uri(product_id: meta_field[:resource_id], meta_field_id: meta_field[:id]),
25
+ meta_field.to_json
26
+ )
27
+
28
+ return response.body['data']
29
+ end
30
+
31
+ def upsert(meta_field)
32
+ begin
33
+ if meta_field[:id]
34
+ return update(meta_field)
35
+ else
36
+ return create(meta_field)
37
+ end
38
+ rescue Faraday::Error::ClientError => e
39
+ puts e.inspect
40
+ raise e
41
+ end
42
+ end
43
+
44
+ def delete(product_id, meta_field_id)
45
+ client.delete(uri(product_id: product_id, meta_field_id: meta_field_id))
46
+ end
47
+ end
48
+ end
49
+ end
@@ -20,6 +20,8 @@ module Agents
20
20
  'client_id' => '',
21
21
  'access_token' => '',
22
22
  'custom_fields_map' => {},
23
+ 'meta_fields_map' => {},
24
+ 'meta_fields_namespace' => '',
23
25
  }
24
26
  end
25
27
 
@@ -39,6 +41,14 @@ module Agents
39
41
  unless options['custom_fields_map'].is_a?(Hash)
40
42
  errors.add(:base, "if provided, custom_fields_map must be a hash")
41
43
  end
44
+
45
+ unless options['meta_fields_map'].is_a?(Hash)
46
+ errors.add(:base, "if provided, meta_fields_map must be a hash")
47
+ end
48
+
49
+ if options['meta_fields_map']
50
+ errors.add(:base, "if meta_fields_map is provided, meta_fields_namespace is required") if options['meta_fields_namespace'].blank?
51
+ end
42
52
  end
43
53
 
44
54
  def working?
@@ -68,10 +78,15 @@ module Agents
68
78
  # upsert child products
69
79
  bc_children = []
70
80
  custom_fields_delete = []
81
+ meta_fields_upsert = []
82
+ meta_fields_delete = []
83
+
71
84
  skus.each do |sku|
72
85
  bc_product = bc_products[sku]
73
86
  result = upsert(sku, product, bc_product)
74
87
  custom_fields_delete += result[:custom_fields_delete]
88
+ meta_fields_upsert += result[:meta_fields_upsert]
89
+ meta_fields_delete += result[:meta_fields_delete]
75
90
  bc_children.push(result[:product])
76
91
  end
77
92
 
@@ -79,6 +94,8 @@ module Agents
79
94
  bc_wrapper_product = bc_products[wrapper_sku]
80
95
  result = upsert(wrapper_sku, product, bc_wrapper_product)
81
96
  custom_fields_delete += result[:custom_fields_delete]
97
+ meta_fields_upsert += result[:meta_fields_upsert]
98
+ meta_fields_delete += result[:meta_fields_delete]
82
99
 
83
100
  # update modifier
84
101
  sku_option_map = ::BigcommerceProductAgent::Mapper::ProductMapper.get_sku_option_label_map(product)
@@ -91,7 +108,9 @@ module Agents
91
108
 
92
109
  clean_up_custom_fields(custom_fields_delete)
93
110
  clean_up_modifier_values(modifier_updates[:delete])
111
+ meta_fields = update_meta_fields(meta_fields_upsert, meta_fields_delete)
94
112
 
113
+ product['meta_fields'] = meta_fields
95
114
  product['modifiers'] = modifier_updates[:upsert]
96
115
  create_event payload: {
97
116
  product: product,
@@ -115,6 +134,12 @@ module Agents
115
134
  interpolated['access_token']
116
135
  )
117
136
 
137
+ @meta_field = ::BigcommerceProductAgent::Client::MetaField.new(
138
+ interpolated['store_hash'],
139
+ interpolated['client_id'],
140
+ interpolated['access_token']
141
+ )
142
+
118
143
  @modifier = ::BigcommerceProductAgent::Client::Modifier.new(
119
144
  interpolated['store_hash'],
120
145
  interpolated['client_id'],
@@ -136,6 +161,7 @@ module Agents
136
161
  )
137
162
 
138
163
  product_id = bc_product['id'] unless bc_product.nil?
164
+
139
165
  payload = ::BigcommerceProductAgent::Mapper::ProductMapper.payload(
140
166
  sku,
141
167
  product,
@@ -145,9 +171,21 @@ module Agents
145
171
 
146
172
  bc_product = @product.upsert(payload)
147
173
 
174
+ # Metafields need to be managed separately. Intentionally get them _AFTER_
175
+ # the upsert so that we have the necessary resource_id (bc_product.id)
176
+ meta_fields_updates = ::BigcommerceProductAgent::Mapper::MetaFieldMapper.map(
177
+ interpolated['meta_fields_map'],
178
+ product,
179
+ bc_product,
180
+ @meta_field.get_for_product(bc_product['id']),
181
+ interpolated['meta_fields_namespace']
182
+ )
183
+
148
184
  return {
149
185
  product: bc_product,
150
186
  custom_fields_delete: custom_fields_updates[:delete],
187
+ meta_fields_upsert: meta_fields_updates[:upsert],
188
+ meta_fields_delete: meta_fields_updates[:delete],
151
189
  }
152
190
  end
153
191
 
@@ -162,5 +200,19 @@ module Agents
162
200
  @modifier_value.delete(field[:product_id], field[:modifier_id], field[:value_id])
163
201
  end
164
202
  end
203
+
204
+ def update_meta_fields(upsert_fields, delete_fields)
205
+ meta_fields = []
206
+
207
+ upsert_fields.each do |field|
208
+ meta_fields << @meta_field.upsert(field)
209
+ end
210
+
211
+ delete_fields.each do |field|
212
+ @meta_field.delete(field[:resource_id], field[:id])
213
+ end
214
+
215
+ return meta_fields
216
+ end
165
217
  end
166
218
  end
@@ -0,0 +1,100 @@
1
+ module BigcommerceProductAgent
2
+ module Mapper
3
+ class MetaFieldMapper
4
+
5
+ def self.map(field_map, product, bc_product, meta_fields, namespace)
6
+ fields = {
7
+ upsert: [],
8
+ delete: [],
9
+ }
10
+
11
+ existing_fields = {}
12
+
13
+ if bc_product
14
+ meta_fields.each do |mf|
15
+
16
+ unless mf['namespace'] != namespace
17
+ # Only delete meta fields managed by this sync
18
+ existing_fields[mf['key'].to_s] = mf
19
+ end
20
+ end
21
+ end
22
+
23
+ if field_map && field_map['additionalProperty']
24
+ field_map['additionalProperty'].each do |key, val|
25
+ field = self.from_additional_property(product, existing_fields, key, val, namespace, bc_product)
26
+ fields[:upsert].push(field) unless field.nil?
27
+ end
28
+ end
29
+
30
+ if field_map
31
+ field_map.each do |key, val|
32
+ if key == 'additionalProperty'
33
+ next
34
+ end
35
+
36
+ field = self.from_property(product, existing_fields, key, val, namespace, bc_product)
37
+ fields[:upsert].push(field) unless field.nil?
38
+ end
39
+ end
40
+
41
+ # return values that need deleted
42
+ fields[:delete] = existing_fields.values
43
+ return fields
44
+ end
45
+
46
+ private
47
+
48
+ def self.from_property(product, existing_fields, from_key, to_key, namespace, bc_product)
49
+
50
+ if !product[from_key].nil?
51
+ field = {
52
+ namespace: namespace,
53
+ permission_set: 'write',
54
+ resource_type: 'product',
55
+ key: to_key,
56
+ value: product[from_key]
57
+ }
58
+
59
+ if bc_product
60
+ field[:resource_id] = bc_product['id']
61
+ end
62
+
63
+ if existing_fields[to_key]
64
+ field[:id] = existing_fields[to_key]['id']
65
+ existing_fields.delete(to_key)
66
+ end
67
+
68
+ return field
69
+ end
70
+ end
71
+
72
+ def self.from_additional_property(product, existing_fields, from_key, to_key, namespace, bc_product)
73
+
74
+ item = product['additionalProperty'].select {|p| p['propertyID'] == from_key}.first
75
+ if !item.nil?
76
+
77
+ field = {
78
+ namespace: namespace,
79
+ permission_set: 'write',
80
+ resource_type: 'product',
81
+ key: to_key,
82
+ value: item['value']
83
+ }
84
+
85
+ if bc_product
86
+ field[:resource_id] = bc_product['id']
87
+ end
88
+
89
+ if existing_fields[to_key]
90
+ field[:id] = existing_fields[to_key]['id']
91
+ existing_fields.delete(to_key)
92
+ end
93
+
94
+ return field
95
+ end
96
+ end
97
+
98
+ end
99
+ end
100
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: huginn_bigcommerce_product_agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.0
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-03-06 00:00:00.000000000 Z
11
+ date: 2020-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -62,12 +62,14 @@ extra_rdoc_files: []
62
62
  files:
63
63
  - lib/abstract_client.rb
64
64
  - lib/client/custom_field.rb
65
+ - lib/client/meta_field.rb
65
66
  - lib/client/modifier.rb
66
67
  - lib/client/modifier_value.rb
67
68
  - lib/client/product.rb
68
69
  - lib/huginn_bigcommerce_product_agent.rb
69
70
  - lib/huginn_bigcommerce_product_agent/bigcommerce_product_agent.rb
70
71
  - lib/mapper/custom_field_mapper.rb
72
+ - lib/mapper/meta_field_mapper.rb
71
73
  - lib/mapper/modifier_mapper.rb
72
74
  - lib/mapper/product_mapper.rb
73
75
  - spec/bigcommerce_product_agent_spec.rb