Skip to content

Commit

Permalink
Add OptionValues processor
Browse files Browse the repository at this point in the history
Shopify allows a maximum of three key,value options to define product
attributes (I don't know if premium shop permits more options)

We map these values into into Spree::OptionValue

NOTE: according to https://help.shopify.com/en/manual/products/import-export
when `Option Value1` is equal to 'Default Title`, means that product has no
variants.
  • Loading branch information
Flavio Auciello committed Apr 10, 2020
1 parent 0efd197 commit 3951aa1
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/solidus_importer/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class Configuration < Spree::Preferences::Configuration
SolidusImporter::Processors::Product,
SolidusImporter::Processors::Variant,
SolidusImporter::Processors::OptionTypes,
SolidusImporter::Processors::OptionValues,
SolidusImporter::Processors::ProductImages,
SolidusImporter::Processors::VariantImages,
SolidusImporter::Processors::Log
Expand Down
49 changes: 49 additions & 0 deletions lib/solidus_importer/processors/option_values.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# frozen_string_literal: true

module SolidusImporter
module Processors
class OptionValues < Base
attr_accessor :option_types, :variant

def call(context)
@data = context.fetch(:data)
return unless option_values?

self.variant = context.fetch(:variant)
process_option_values
end

private

def process_option_values
option_value_names.each_with_index do |name, i|
option_value = Spree::OptionValue.find_or_initialize_by(
option_type: option_type(i),
name: name
)
option_value.presentation = name
variant.option_values << option_value
end
end

def option_type(index)
variant.product.option_types.find { |ot| ot.position == index + 1 }
end

def option_value_names
@option_value_names ||= @data.values_at(
'Option1 Value',
'Option2 Value',
'Option3 Value'
).compact
end

def option_values?
# NOTE: according to https://help.shopify.com/en/manual/products/import-export
# when `Option Value1` is equal to 'Default Title`, means that product has no
# variants.
(@data['Option1 Value'] != 'Default Title') && option_value_names.any?
end
end
end
end
2 changes: 2 additions & 0 deletions spec/features/solidus_importer/import_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
expect(import.state).to eq('completed')
expect(product.images).not_to be_empty
expect(product.option_types.count).to eq 2
expect(product.variants.sample.option_values.count).to eq 2
expect(product.variants.sample.images).not_to be_empty
expect(Spree::Product.last.images).not_to be_empty
expect(Spree::Variant.last.images).not_to be_empty
expect(Spree::LogEntry).to have_received(:create!).exactly(csv_file_rows).times
Expand Down
43 changes: 43 additions & 0 deletions spec/lib/solidus_importer/processors/option_values_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe SolidusImporter::Processors::OptionValues do
describe '#call' do
subject(:described_method) { described_class.call(context) }

let(:context) { { data: data, variant: variant } }
let(:variant) { create :base_variant }
let(:product) { variant.product }
let(:color) { create :option_type, presentation: 'Color' }
let(:size) { create :option_type, presentation: 'Size' }
let(:data) do
{
'Option1 Name' => 'Size',
'Option1 Value' => 'L',
'Option2 Name' => 'Color',
'Option2 Value' => 'Black'
}
end

before { product.option_types << size << color }

context 'when "Option(1,2,3) Value" are present' do
it 'create option values for variant in row' do
expect { described_method }.to change(variant.option_values, :count).from(0).to(2)
expect(variant.option_values.first.presentation).to eq 'L'
expect(variant.option_values.first.name).to eq 'L'
expect(variant.option_values.last.presentation).to eq 'Black'
expect(variant.option_values.last.name).to eq 'Black'
end

it 'creates "Black" option value for related "Color" option type' do
described_method
black = variant.option_values.find_by(presentation: 'Black')
l = variant.option_values.find_by(presentation: 'L')
expect(black.option_type).to eq color
expect(l.option_type).to eq size
end
end
end
end

0 comments on commit 3951aa1

Please sign in to comment.