Class: Gemgento::Adapter::Shopify::Product

Inherits:
Object
  • Object
show all
Defined in:
app/models/gemgento/adapter/shopify/product.rb

Class Method Summary collapse

Class Method Details

.create_assets(product, base_image, images) ⇒ Gemgento::Product

Create the assets for a product.

Parameters:

  • product (Gemgento::Product)
  • base_image (ShopifyAPI::Image)
  • images (Array(ShopifyAPI::Image))

Returns:



292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
# File 'app/models/gemgento/adapter/shopify/product.rb', line 292

def self.create_assets(product, base_image, images)
  images.each do |image|
    asset_file = nil

    product.stores.each do |store|
      asset = Gemgento::Asset.find_or_initialize_by(product: product, label: image.id)
      asset.asset_types << Gemgento::AssetType.find_by(code: 'image') if image == base_image
      asset.store = store
      asset.position = image.position
      asset.set_file(URI.parse(image.src))
      asset.sync_needed = false
      asset.save

      asset.sync_needed = true
      asset.save

      asset_file = asset.asset_file
    end

    Gemgento::Adapter::ShopifyAdapter.create_association(asset_file, image) unless asset_file.nil?
  end

  return product
end

.create_configurable_product(base_product, simple_products) ⇒ Gemgento::Product

Create a simple product from Shopify product data.

Parameters:

Returns:



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'app/models/gemgento/adapter/shopify/product.rb', line 112

def self.create_configurable_product(base_product, simple_products)
  product = initialize_product(base_product, base_product, "#{simple_products.first.sku}_base", 'configurable', true, !base_product.published_at.nil?)

  product.set_attribute_value('barcode', simple_products.first.barcode)
  product.set_attribute_value('compare_at_price', simple_products.first.compare_at_price)
  product.set_attribute_value('fulfillment_service', simple_products.first.fulfillment_service)      
  product.set_attribute_value('weight', simple_products.first.weight)
  product.set_attribute_value('price', simple_products.first.price)
  product.set_attribute_value('name', base_product.title)
  if base_product.published_at.blank?
    product.set_attribute_value('status', 'enabled')
  else
    product.set_attribute_value('status', 'disabled')
  end

  product.sync_needed = false
  product.save

  product = set_configurable_attributes(product, base_product, base_product.variants.first)
  #product = set_categories(product, base_product.id)

  simple_products.uniq.each do |simple_product|
    simple_product.configurable_products << product unless simple_product.configurable_products.include? product
    simple_product.sync_needed
    simple_product.save
  end

  product.sync_needed = true
  product.save

  Gemgento::Adapter::ShopifyAdapter.create_association(product, base_product) if product.shopify_adapter.nil?

  # begin
  #   product = create_assets(product, base_product.image, base_product.images)
  # rescue => e
  #   Rails.logger.warn "Unable to create assets, will ignore: #{e}"
  # end

  # create_tags(product, base_product.tags)

  return product
end

.create_inventory(product, variant) ⇒ Object

Create the inventory for the product.

Parameters:



321
322
323
324
325
326
327
328
329
330
# File 'app/models/gemgento/adapter/shopify/product.rb', line 321

def self.create_inventory(product, variant)
  product.stores.each do |store|
    inventory = Gemgento::Inventory.find_or_initialize_by(product: product, store: store)
    inventory.quantity = variant.inventory_quantity
    inventory.is_in_stock = (inventory.quantity > 0 || variant.inventory_policy == 'continue')
    inventory.backorders = variant.inventory_policy == 'continue' ? 1 : 0
    inventory.sync_needed = inventory.new_record? || inventory.changed?
    inventory.save
  end
end

.create_simple_product(base_product, variant, is_catalog_visible) ⇒ Gemgento::Product

Create a simple product from Shopify product data.

Parameters:

  • base_product (ShopifyAPI::Product)
  • variant (ShopifyAPI::Variant)
  • is_catalog_visible (Boolean)

Returns:



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'app/models/gemgento/adapter/shopify/product.rb', line 66

def self.create_simple_product(base_product, variant, is_catalog_visible)
  product = initialize_product(variant, base_product, variant.sku, 'simple', is_catalog_visible, !base_product.published_at.nil?)

  product.set_attribute_value('barcode', variant.barcode)
  product.set_attribute_value('compare_at_price', variant.compare_at_price)
  product.set_attribute_value('fulfillment_service', variant.fulfillment_service)
  product.set_attribute_value('weight', variant.grams)
  product.set_attribute_value('price', variant.price)      
  #product.set_attribute_value('size', variant.size)

  if base_product.published_at.blank?
    product.set_attribute_value('status', 'enabled')
  else
    product.set_attribute_value('status', 'disabled')
  end
  if is_catalog_visible # catalog visible simple products are not part of a configurable
    product.set_attribute_value('name', base_product.title)
  else
    product.set_attribute_value('name', "#{base_product.title} - #{variant.title}")
  end

  product = set_option_values(product, base_product, variant)
  #product = set_categories(product, base_product.id)

  product.sync_needed = true
  product.save

  Gemgento::Adapter::ShopifyAdapter.create_association(product, variant) if product.shopify_adapter.nil?

  # begin
  #   product = create_assets(product, base_product.image, base_product.images)
  # rescue => e
  #   Rails.logger.warn "Unable to create assets, will ignore: #{e}"
  # end

  # create_tags(product, base_product.tags)
  create_inventory(product, variant)

  return product
end

.create_tags(product, tags) ⇒ Void

Create and associate product with tags.

Parameters:

Returns:

  • (Void)


337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
# File 'app/models/gemgento/adapter/shopify/product.rb', line 337

def self.create_tags(product, tags)
  tags.split(',').each do |tag_name|
    tag = Gemgento::Tag.find_or_initialize_by(name: tag_name.strip)
    tag.status = 1
    tag.sync_needed = false
    tag.save

    Gemgento::Store.where.not(code: 'admin').each do |store|
      next if tag.stores.include? store
      
      tag.store_tags.create(store: store)
    end

    tag.products << product unless tag.products.include? product
    tag.sync_needed = false
    tag.save
  end
end

.get_option_attribute_code(base_product, option_code) ⇒ Object

Get the Gemgento::Attribute.code relate to an Shopify option code.

Parameters:

  • base_product (ShopifyAPI::Product)
  • option_code (String)


219
220
221
222
223
# File 'app/models/gemgento/adapter/shopify/product.rb', line 219

def self.get_option_attribute_code(base_product, option_code)
  index = option_code.to_s.gsub('option', '').to_i - 1
  return nil if index >= base_product.options.length
  return base_product.options[index].name.downcase
end

.import(skip_existing = false) ⇒ void

This method returns an undefined value.

Import products from Shopify to Gemgento.

Parameters:

  • skip_existing (Boolean) (defaults to: false)


18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'app/models/gemgento/adapter/shopify/product.rb', line 18

def self.import(skip_existing = false)
  page = 1
  ShopifyAPI::Base.site = Gemgento::Adapter::ShopifyAdapter.api_url
  shopify_products = ShopifyAPI::Product.where(limit: 250, page: page)

  while shopify_products.any?

    shopify_products.each do |product|
      simple_products = []

      if product.variants.count > 1 && !skip?(skip_existing, product)
        product.variants.each do |variant|
          if skip?(skip_existing, variant)
            simple_products << Gemgento::Adapter::ShopifyAdapter.find_by_shopify_model(variant).gemgento_model
          else
            simple_products << create_simple_product(product, variant, false)
          end
        end

        create_configurable_product(product, simple_products)
      else
        create_simple_product(product, product.variants.first, true) unless skip?(skip_existing, product.variants.first)
      end
    end

    page = page + 1
    shopify_products = ShopifyAPI::Product.where(limit: 250, page: page)
  end

  push_tags
end

.initialize_product(shopify_model, base_product, sku, magento_type, is_catalog_visible, status) ⇒ Gemgento::Product

Initialize a Gemgento::Product given some basic data form Shopify product.

Parameters:

  • shopify_model (Object)

    the shopify model that the product will be associated with through Gemgento::Adapter::ShopifyAdapter

  • base_product (ShopifyAPI::Product)
  • sku (String)
  • magento_type (String)
  • is_catalog_visible (Boolean)
  • status (Boolean)

Returns:



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'app/models/gemgento/adapter/shopify/product.rb', line 164

def self.initialize_product(shopify_model, base_product, sku, magento_type, is_catalog_visible, status)
  if shopify_adapter = Gemgento::Adapter::ShopifyAdapter.find_by_shopify_model(shopify_model)
    product = shopify_adapter.gemgento_model
  else
    product = Gemgento::Product.not_deleted.find_or_initialize_by(sku: normalize_sku(sku, base_product, base_product.variants.first))
  end

  product.magento_type = magento_type
  product.visibility = is_catalog_visible ? 4 : 1
  product.product_attribute_set = Gemgento::ProductAttributeSet.first
  product.status = status
  product.sync_needed = false
  product.save

  product.set_attribute_value('url_key', base_product.handle)
  product.set_attribute_value('name', base_product.title)
  product.set_attribute_value('description', base_product.body_html)
  product.set_attribute_value('vendor', base_product.vendor)
  product.set_attribute_value('udropship_vendor', base_product.vendor)
  product.set_attribute_value('meta-keywords', base_product.tags)
  product.stores = Gemgento::Store.all

  puts 'PRODUCT ID: '+product.id.to_s+ '  DESCRIPTION: '+product.description

  return product
end

.is_configurable_attribute_used(product, attribute) ⇒ Boolean

Check if a configurable attribute is actually being used to differentiate simples.

Parameters:

Returns:

  • (Boolean)


278
279
280
281
282
283
284
# File 'app/models/gemgento/adapter/shopify/product.rb', line 278

def self.is_configurable_attribute_used(product, attribute)
  product.simple_products.each do |simple_product|
    return false unless simple_product.product_attribute_values.exists?(product_attribute: attribute)
  end

  return true
end

.normalize_sku(sku, base_product, variant) ⇒ String

Normalize the sku.

Parameters:

  • sku (String)
  • base_product (ShopifyAPI::Product)
  • variant (ShopifyAPI::ProductVariant)

Returns:

  • (String)


372
373
374
# File 'app/models/gemgento/adapter/shopify/product.rb', line 372

def self.normalize_sku(sku, base_product, variant)
  return sku
end

.push_tagsVoid

Push all tags to Magento.

Returns:

  • (Void)


359
360
361
362
363
364
# File 'app/models/gemgento/adapter/shopify/product.rb', line 359

def self.push_tags
  Gemgento::Tag.all.each do |tag|
    tag.sync_needed = true
    tag.save
  end
end

.set_categories(product, shopify_id) ⇒ Gemgento::Product

Associate product with categories based on Shopify collections.

Parameters:

Returns:



230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'app/models/gemgento/adapter/shopify/product.rb', line 230

def self.set_categories(product, shopify_id)
  collections = ShopifyAPI::CustomCollection.where(product_id: shopify_id)

  Gemgento::Adapter::ShopifyAdapter.where(shopify_model_type: collections.first.class, shopify_model_id: collections.map(&:id)).each do |shopify_adapter|
    category = shopify_adapter.gemgento_model

    Gemgento::Store.all.each do |store|
      product_category = Gemgento::ProductCategory.find_or_initialize_by(product: product, category: category, store: store)
      product_category.sync_needed = false
      product_category.save
    end
  end

  product.product_categories.reload

  return product
end

.set_configurable_attributes(product, base_product, variant) ⇒ Gemgento::Product

Define the configurable attributes for a configurable product.

Parameters:

  • product (Gemgento::Product)
  • base_product (ShopifyAPI::Product)
  • variant (ShopifyAPI::Variant)

Returns:



254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
# File 'app/models/gemgento/adapter/shopify/product.rb', line 254

def self.set_configurable_attributes(product, base_product, variant)
  variant.attributes.each do |key, value|
    if key.to_s.include? 'option'
      code = get_option_attribute_code(base_product, key)
      next if code.nil?
      attribute = Gemgento::ProductAttribute.find_by(code: code)

      if attribute && attribute.is_configurable && is_configurable_attribute_used(product, attribute)
        product.configurable_attributes << attribute unless product.configurable_attributes.include? attribute
      end
    end
  end

  product.sync_needed = false
  product.save

  return product
end

.set_option_values(product, base_product, variant) ⇒ Gemgento::Product

Set product attribute values that have options.

Parameters:

  • product (Gemgento::Product)
  • base_product (ShopifyAPI::Product)
  • variant (ShopifyAPI::Variant)

Returns:



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'app/models/gemgento/adapter/shopify/product.rb', line 197

def self.set_option_values(product, base_product, variant)
  variant.attributes.each do |key, value|
    if key.to_s.include? 'option'
      code = get_option_attribute_code(base_product, key)
      next if code.nil?
      Rails.logger.warn  'ATTRIBUTE CODE: '+code
      value = 'N/A' if value.blank?
      product.set_attribute_value(code, value)
      Rails.logger.warn  'ATTRIBUTE VALUE: '+value
    end
  end

  product.sync_needed = false
  product.save

  return product
end

.skip?(skip_existing, shopify_model) ⇒ Boolean

Determine if product import can be skipped.

Parameters:

  • skip_existing (Boolean)
  • shopify_model (Object)

Returns:

  • (Boolean)


55
56
57
58
# File 'app/models/gemgento/adapter/shopify/product.rb', line 55

def self.skip?(skip_existing, shopify_model)
  shopify_adapter = Gemgento::Adapter::ShopifyAdapter.find_by_shopify_model(shopify_model)
  return skip_existing && (shopify_adapter && !shopify_adapter.gemgento_model.magento_id.nil?)
end