solidus_datashift 0.1.0 → 1.0.0.pre.alpha
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 +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +5 -0
- data/.travis.yml +2 -0
- data/Gemfile +2 -2
- data/README.md +13 -13
- data/lib/solidus_datashift.rb +3 -1
- data/lib/solidus_datashift/importer.rb +21 -0
- data/lib/solidus_datashift/importer/product.rb +21 -0
- data/lib/solidus_datashift/importer/variant.rb +20 -0
- data/lib/solidus_datashift/populator.rb +9 -0
- data/lib/solidus_datashift/populator/product.rb +101 -0
- data/lib/solidus_datashift/populator/variant.rb +29 -0
- data/lib/solidus_datashift/utils.rb +64 -0
- data/lib/solidus_datashift/version.rb +1 -1
- data/lib/tasks/solidus_datashift.rake +6 -1
- data/solidus_datashift.gemspec +4 -1
- data/spec/fixtures/spree_products.csv +4 -4
- data/spec/fixtures/spree_products.xls +0 -0
- data/spec/fixtures/spree_variants.csv +3 -0
- data/spec/fixtures/spree_variants_multiple_locations.csv +3 -0
- data/spec/solidus_datashift/product_importer_spec.rb +63 -2
- data/spec/solidus_datashift/variant_importer_spec.rb +78 -0
- data/spec/spec_helper.rb +3 -1
- metadata +56 -5
- data/lib/solidus_datashift/product_importer.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f14fbdd695b3d332226f2fe075e282f6d29e07f5
|
4
|
+
data.tar.gz: ead11b53fb4445a9cab2aadb12aa557aafb999e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 890fbf3a9b74de7f2f0c15d3d5c6901bacca6d41e3f5e00d60258a1cb7a72eda4701f4b549f85c8b0e0aae33608bcf28c1d9d552ec4f39e5bd228e76a011abf4
|
7
|
+
data.tar.gz: 05d7b3f468c4ec7e02bf2620f588f0f6f4b7b82faf56673b7d2ef1a97bebcc497fae297b78332c18807dfce8e2fc2eeb46552a5b35e1a546316de842326200a9
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
@@ -18,6 +18,7 @@ env:
|
|
18
18
|
- SOLIDUS_BRANCH=v2.2 DB=postgres
|
19
19
|
- SOLIDUS_BRANCH=v2.3 DB=postgres
|
20
20
|
- SOLIDUS_BRANCH=v2.4 DB=postgres
|
21
|
+
- SOLIDUS_BRANCH=v2.5 DB=postgres
|
21
22
|
- SOLIDUS_BRANCH=master DB=postgres
|
22
23
|
- SOLIDUS_BRANCH=v1.0 DB=mysql
|
23
24
|
- SOLIDUS_BRANCH=v1.1 DB=mysql
|
@@ -29,4 +30,5 @@ env:
|
|
29
30
|
- SOLIDUS_BRANCH=v2.2 DB=mysql
|
30
31
|
- SOLIDUS_BRANCH=v2.3 DB=mysql
|
31
32
|
- SOLIDUS_BRANCH=v2.4 DB=mysql
|
33
|
+
- SOLIDUS_BRANCH=v2.5 DB=mysql
|
32
34
|
- SOLIDUS_BRANCH=master DB=mysql
|
data/Gemfile
CHANGED
@@ -7,6 +7,6 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}.git" }
|
|
7
7
|
branch = ENV.fetch('SOLIDUS_BRANCH', 'master')
|
8
8
|
gem 'solidus', github: 'solidusio/solidus', branch: branch
|
9
9
|
|
10
|
-
gem 'datashift', github: 'ccarruitero/datashift', branch: 'fix_delegator_2.4'
|
11
|
-
|
12
10
|
gemspec
|
11
|
+
|
12
|
+
gem 'solidus_multi_domain', github: 'solidusio/solidus_multi_domain'
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
SolidusDatashift
|
2
2
|
================
|
3
3
|
|
4
|
-
|
4
|
+
Allow import data to your solidus store
|
5
5
|
|
6
6
|
Installation
|
7
7
|
------------
|
@@ -12,28 +12,28 @@ Add solidus_datashift to your Gemfile:
|
|
12
12
|
gem 'solidus_datashift'
|
13
13
|
```
|
14
14
|
|
15
|
-
Bundle your dependencies
|
15
|
+
Bundle your dependencies
|
16
16
|
|
17
17
|
```shell
|
18
18
|
bundle
|
19
|
-
bundle exec rails g solidus_datashift:install
|
20
19
|
```
|
21
20
|
|
22
|
-
|
23
|
-
|
21
|
+
Usage
|
22
|
+
-----
|
24
23
|
|
25
|
-
|
24
|
+
This gem include some rake tasks, namespaced into `solidus_datashift`, that let
|
25
|
+
you import data to your project.
|
26
|
+
|
27
|
+
For example for import products you should use the following command
|
26
28
|
|
27
|
-
```
|
28
|
-
|
29
|
-
bundle exec rake
|
29
|
+
```
|
30
|
+
rake solidus_datashift:product_import[your_file_name]
|
30
31
|
```
|
31
32
|
|
32
|
-
|
33
|
-
Simply add this require statement to your spec_helper:
|
33
|
+
You can check all available importer tasks by running
|
34
34
|
|
35
|
-
```
|
36
|
-
|
35
|
+
```
|
36
|
+
rake -T
|
37
37
|
```
|
38
38
|
|
39
39
|
Copyright (c) 2018 [César Carruitero](https://github.com/ccarruitero), released under MIT License
|
data/lib/solidus_datashift.rb
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SolidusDataShift
|
4
|
+
class Importer
|
5
|
+
def initialize(file_name)
|
6
|
+
# TODO: allow receive StringIO
|
7
|
+
@file_name = file_name
|
8
|
+
@datashift_loader = DataShift::Loader::Factory.get_loader(file_name)
|
9
|
+
end
|
10
|
+
|
11
|
+
def importer_populator; end
|
12
|
+
|
13
|
+
def inclusion_columns; end
|
14
|
+
|
15
|
+
def run
|
16
|
+
DataShift::PopulatorFactory.global_populator_class = importer_populator if importer_populator
|
17
|
+
DataShift::Configuration.call.force_inclusion_of_columns = inclusion_columns if inclusion_columns
|
18
|
+
@datashift_loader.run(@file_name, importer_model)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'solidus_datashift/importer'
|
4
|
+
require 'solidus_datashift/populator/product'
|
5
|
+
|
6
|
+
module SolidusDataShift
|
7
|
+
class Importer::Product < Importer
|
8
|
+
def inclusion_columns
|
9
|
+
%w[ cost_price images price shipping_category sku stock_items
|
10
|
+
count_on_hand taxons]
|
11
|
+
end
|
12
|
+
|
13
|
+
def importer_model
|
14
|
+
Spree::Product
|
15
|
+
end
|
16
|
+
|
17
|
+
def importer_populator
|
18
|
+
Populator::Product
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'solidus_datashift/importer'
|
4
|
+
require 'solidus_datashift/populator/variant'
|
5
|
+
|
6
|
+
module SolidusDataShift
|
7
|
+
class Importer::Variant < Importer
|
8
|
+
def inclusion_columns
|
9
|
+
%w[product_sku price count_on_hand]
|
10
|
+
end
|
11
|
+
|
12
|
+
def importer_model
|
13
|
+
Spree::Variant
|
14
|
+
end
|
15
|
+
|
16
|
+
def importer_populator
|
17
|
+
Populator::Variant
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'solidus_datashift/populator'
|
4
|
+
|
5
|
+
module SolidusDataShift
|
6
|
+
class Populator::Product < Populator
|
7
|
+
def prepare_and_assign_method_binding(method_binding, record, data)
|
8
|
+
prepare_data(method_binding, data)
|
9
|
+
if method_binding.operator?('count_on_hand')
|
10
|
+
setup_stock(record, data)
|
11
|
+
elsif method_binding.operator?('product_properties')
|
12
|
+
setup_product_properties(record, data)
|
13
|
+
elsif method_binding.operator?('taxons')
|
14
|
+
setup_taxons(record, data)
|
15
|
+
elsif method_binding.operator?('stores')
|
16
|
+
setup_stores(record, data)
|
17
|
+
elsif method_binding.operator?('option_types')
|
18
|
+
setup_option_types(record, data)
|
19
|
+
elsif method_binding.operator?('images')
|
20
|
+
setup_images(record.master, data)
|
21
|
+
else
|
22
|
+
assign(method_binding, record)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
# Expect taxon's names separated by `|`. Also, could define taxon's childs
|
29
|
+
# separeted by `>`.
|
30
|
+
# Ex: name|other_name>child>child|an_other_name
|
31
|
+
def setup_taxons(record, data)
|
32
|
+
taxon_list = split_data(data)
|
33
|
+
|
34
|
+
taxon_list.each do |taxon_str|
|
35
|
+
taxon_names = taxon_str.split(/\s*>\s*/)
|
36
|
+
taxonomy = Spree::Taxonomy.find_or_create_by(name: taxon_names.shift)
|
37
|
+
parent = taxonomy.root
|
38
|
+
associate_to_product(record, 'taxons', parent)
|
39
|
+
|
40
|
+
taxon_names.each do |taxon_name|
|
41
|
+
taxon = Spree::Taxon.find_or_create_by(name: taxon_name,
|
42
|
+
taxonomy: taxonomy,
|
43
|
+
parent: parent)
|
44
|
+
associate_to_product(record, 'taxons', taxon)
|
45
|
+
parent = taxon
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def setup_stores(record, data)
|
51
|
+
if record.respond_to?('stores')
|
52
|
+
store_names = split_data(data)
|
53
|
+
store_names.each do |store_name|
|
54
|
+
store = Spree::Store.find_or_create_by(name: store_name) do |obj|
|
55
|
+
obj.code = store_name
|
56
|
+
obj.url = "#{store_name}.example.com"
|
57
|
+
obj.mail_from_address = 'mail@example.com'
|
58
|
+
end
|
59
|
+
|
60
|
+
associate_to_product(record, 'stores', store)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def setup_product_properties(record, data)
|
66
|
+
properties_names = split_data(data)
|
67
|
+
|
68
|
+
properties_names.each do |property_name|
|
69
|
+
property = Spree::Property.find_or_create_by(name: property_name) do |obj|
|
70
|
+
obj.presentation = property_name
|
71
|
+
end
|
72
|
+
|
73
|
+
associate_to_product(record, 'properties', property)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def setup_option_types(record, data)
|
78
|
+
type_list = split_data(data)
|
79
|
+
|
80
|
+
type_list.each do |type_str|
|
81
|
+
name, values = type_str.split(':')
|
82
|
+
option_type = Spree::OptionType.find_or_create_by(name: name) do |obj|
|
83
|
+
obj.presentation = name
|
84
|
+
end
|
85
|
+
|
86
|
+
values.split(',').map(&:strip).each do |value|
|
87
|
+
option_type.option_values.find_or_create_by(name: value) do |obj|
|
88
|
+
obj.presentation = value
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
associate_to_product(record, 'option_types', option_type)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def associate_to_product(product, association_name, item)
|
97
|
+
association = product.send(association_name)
|
98
|
+
association << item unless association.include?(item)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'solidus_datashift/populator'
|
4
|
+
|
5
|
+
module SolidusDataShift
|
6
|
+
class Populator::Variant < Populator
|
7
|
+
def prepare_and_assign_method_binding(method_binding, record, data)
|
8
|
+
prepare_data(method_binding, data)
|
9
|
+
if method_binding.operator?('product_sku')
|
10
|
+
setup_product(method_binding, record, data)
|
11
|
+
elsif method_binding.operator?('count_on_hand')
|
12
|
+
setup_stock(record, data)
|
13
|
+
elsif method_binding.operator?('images')
|
14
|
+
setup_images(record, data)
|
15
|
+
else
|
16
|
+
assign(method_binding, record)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def setup_product(method_binding, record, data)
|
23
|
+
return unless method_binding.operator?('product_sku') && data.present?
|
24
|
+
|
25
|
+
master = Spree::Variant.find_by(sku: data)
|
26
|
+
record.product = master.product
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mechanize'
|
4
|
+
|
5
|
+
module SolidusDataShift
|
6
|
+
module Utils
|
7
|
+
# for count_on_hand we expect two kind of values:
|
8
|
+
# * An integer (Ex: 30)
|
9
|
+
# In this case all stock locations are populated with the received value
|
10
|
+
#
|
11
|
+
# * A list of stock locations with stock values
|
12
|
+
# (Ex: foo_warehouse:20|bar_warehouse:10)
|
13
|
+
# In this case we attempt to find a stock location by name and populate
|
14
|
+
# with the asociated value
|
15
|
+
def setup_stock(record, data)
|
16
|
+
inventory = split_data(data)
|
17
|
+
|
18
|
+
if inventory.size > 1
|
19
|
+
inventory.each do |stock_hash|
|
20
|
+
name, stock = stock_hash.split(':')
|
21
|
+
stock_location = Spree::StockLocation.where('name LIKE ?', name)
|
22
|
+
.first_or_create(name: name)
|
23
|
+
populate_stock(stock_location, record, stock)
|
24
|
+
end
|
25
|
+
else
|
26
|
+
Spree::StockLocation.all.each do |stock_location|
|
27
|
+
populate_stock(stock_location, record, inventory.first)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def setup_images(record, data)
|
33
|
+
images = split_data(data)
|
34
|
+
images.each do |image_url|
|
35
|
+
agent = Mechanize.new
|
36
|
+
image_file = agent.get(image_url)
|
37
|
+
name, extension = image_file.filename.split('.')
|
38
|
+
temp_file = Tempfile.new([name, ".#{extension}"], encoding: 'ascii-8bit')
|
39
|
+
begin
|
40
|
+
temp_file.write image_file.body_io.string
|
41
|
+
temp_file.rewind
|
42
|
+
image = Spree::Image.create(attachment: temp_file)
|
43
|
+
record.images << image
|
44
|
+
ensure
|
45
|
+
temp_file.close
|
46
|
+
temp_file.unlink
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def populate_stock(stock_location, variant, count)
|
52
|
+
variant.save unless variant.persisted?
|
53
|
+
stock_item = Spree::StockItem.find_or_create_by(
|
54
|
+
stock_location_id: stock_location.id,
|
55
|
+
variant_id: variant.id
|
56
|
+
)
|
57
|
+
stock_item.set_count_on_hand(count)
|
58
|
+
end
|
59
|
+
|
60
|
+
def split_data(data)
|
61
|
+
data.to_s.split('|')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -3,6 +3,11 @@
|
|
3
3
|
namespace :solidus_datashift do
|
4
4
|
desc 'import product to Solidus'
|
5
5
|
task :product_import, [:file] => :environment do |_t, args|
|
6
|
-
|
6
|
+
SolidusDataShift::Importer::Product.new(args[:file]).run
|
7
|
+
end
|
8
|
+
|
9
|
+
desc 'import variants to Solidus'
|
10
|
+
task :variant_import, [:file] => :environment do |_t, args|
|
11
|
+
SolidusDataShift::Importer::Variant.new(args[:file]).run
|
7
12
|
end
|
8
13
|
end
|
data/solidus_datashift.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
$:.push File.expand_path('
|
3
|
+
$:.push File.expand_path('lib', __dir__)
|
4
4
|
require 'solidus_datashift/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
@@ -18,11 +18,13 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
19
|
|
20
20
|
s.add_dependency 'datashift', '~> 0.40'
|
21
|
+
s.add_dependency 'mechanize'
|
21
22
|
s.add_dependency 'solidus_core'
|
22
23
|
s.add_dependency 'solidus_support'
|
23
24
|
|
24
25
|
s.add_development_dependency 'capybara'
|
25
26
|
s.add_development_dependency 'database_cleaner'
|
27
|
+
s.add_development_dependency 'factory_bot'
|
26
28
|
s.add_development_dependency 'ffaker'
|
27
29
|
s.add_development_dependency 'mysql2'
|
28
30
|
s.add_development_dependency 'pg'
|
@@ -31,5 +33,6 @@ Gem::Specification.new do |s|
|
|
31
33
|
s.add_development_dependency 'rspec-rails'
|
32
34
|
s.add_development_dependency 'rubocop'
|
33
35
|
s.add_development_dependency 'simplecov'
|
36
|
+
s.add_development_dependency 'solidus_multi_domain'
|
34
37
|
s.add_development_dependency 'sqlite3'
|
35
38
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
SKU,Name,Description,Available On, Price,cost_price, ShippingCategory,product_properties,Taxons,OptionTypes,
|
2
|
-
DEMO_001,Demo Product for AR Loader,blah blah,2011-02-14,399.99,320
|
3
|
-
DEMO_002,Demo Excel Load via Jruby,less blah,2011-05-14,100
|
4
|
-
DEMO_003,Demo third row in future,more blah blah,2012-07-01,50.34,23.34,:name => “Small”,test_pp_002|test_pp_003:Example free value|yet_another_property,Drawings|Paintings>Landscape
|
1
|
+
SKU,Name,Description,Available On, Price,cost_price, ShippingCategory,product_properties,Taxons,OptionTypes,count_on_hand,stores,images
|
2
|
+
DEMO_001,Demo Product for AR Loader,blah blah,2011-02-14,399.99,320,small,test_pp_001,Paintings|WaterColour,"mime_type:jpeg,PDF,PNG",foo:12|bar:6|baz:7,default,http://rubyonrails.org/images/imagine.png
|
3
|
+
DEMO_002,Demo Excel Load via Jruby,less blah,2011-05-14,100,30,small,test_pp_003,Paintings|Oils|Paintings>Nature>Seascape,"mime_type:jpeg, PDF,PNG",foo:5|bar:4|baz:2,default|new_store,
|
4
|
+
DEMO_003,Demo third row in future,more blah blah,2012-07-01,50.34,23.34,:name => “Small”,test_pp_002|test_pp_003:Example free value|yet_another_property,Drawings|Paintings>Landscape,"mime_type:jpeg,PDF,PNG|print_type:black_white,colour",10,,
|
Binary file
|
@@ -2,16 +2,77 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe
|
5
|
+
describe SolidusDataShift::Importer::Product do
|
6
6
|
context 'with csv file' do
|
7
7
|
let(:importer) { described_class.new(fixture_file('spree_products.csv')) }
|
8
8
|
|
9
9
|
it 'should successfull upload products' do
|
10
10
|
expect { importer.run }.to change { Spree::Product.count }.by(3)
|
11
11
|
end
|
12
|
+
|
13
|
+
context 'after run importer' do
|
14
|
+
before do
|
15
|
+
importer.run
|
16
|
+
@product = Spree::Product.first
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'has correct name' do
|
20
|
+
expect(@product.name).to eq('Demo Product for AR Loader')
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'has correct sku' do
|
24
|
+
expect(@product.sku).to eq('DEMO_001')
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'has correct price' do
|
28
|
+
expect(@product.price.to_s).to eq('399.99')
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'has correct cost_price' do
|
32
|
+
expect(@product.cost_price.to_s).to eq('320.0')
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'has correct shipping_category' do
|
36
|
+
expect(@product.shipping_category.name).to eq('small')
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'has correct taxons' do
|
40
|
+
expect(@product.taxons.count).to eq(2)
|
41
|
+
expect(@product.taxons.pluck(:name)).to eq(['Paintings', 'WaterColour'])
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'has correct product properties' do
|
45
|
+
expect(@product.product_properties.count).to eq(1)
|
46
|
+
first_property = @product.product_properties.first.property
|
47
|
+
expect(first_property.name).to eq('test_pp_001')
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'has correct option types' do
|
51
|
+
expect(@product.option_types.count).to eq(1)
|
52
|
+
|
53
|
+
option_type = @product.option_types.first
|
54
|
+
expect(option_type.option_values.count).to eq(3)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'has correct count_on_hand' do
|
58
|
+
expect(Spree::StockLocation.count).to eq(3)
|
59
|
+
first_location = Spree::StockLocation.first
|
60
|
+
first_stock_item = @product.stock_items.first
|
61
|
+
expect(first_stock_item.stock_location).to eq(first_location)
|
62
|
+
expect(first_stock_item.count_on_hand).to eq(12)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'allow associate stores to product' do
|
66
|
+
expect(@product.stores.count).to eq(1) if @product.respond_to?('stores')
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'allow image' do
|
70
|
+
expect(@product.images.count).to eq(1)
|
71
|
+
end
|
72
|
+
end
|
12
73
|
end
|
13
74
|
|
14
|
-
context 'with
|
75
|
+
context 'with xls file' do
|
15
76
|
let(:importer) { described_class.new(fixture_file('spree_products.xls')) }
|
16
77
|
|
17
78
|
it 'should successfull upload products' do
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe SolidusDataShift::Importer::Variant do
|
6
|
+
context 'with csv file' do
|
7
|
+
let(:importer) { described_class.new(fixture_file('spree_variants.csv')) }
|
8
|
+
let(:product) { create(:product) }
|
9
|
+
|
10
|
+
before do
|
11
|
+
@variant_data = CSV.read(fixture_file('spree_variants.csv'))[1]
|
12
|
+
master_sku = @variant_data[0]
|
13
|
+
product.master.update(sku: master_sku)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should upload variants' do
|
17
|
+
expect { importer.run }.to change { Spree::Variant.count }.by(2)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should associate variant with product' do
|
21
|
+
expect { importer.run }.to change { product.variants.count }.by(2)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should store data price correctly' do
|
25
|
+
importer.run
|
26
|
+
variant = product.variants.find_by(sku: @variant_data[1])
|
27
|
+
expect(variant.price.to_f).to eq(@variant_data[2].to_f)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should populate stock item' do
|
31
|
+
importer.run
|
32
|
+
variant = product.variants.find_by(sku: @variant_data[1])
|
33
|
+
expect(variant.stock_items.first.count_on_hand).to eq(@variant_data[3].to_i)
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'with multiple stock locations' do
|
37
|
+
let!(:stock_location) { create(:stock_location, name: 'CA Warehouse') }
|
38
|
+
|
39
|
+
context 'with count_on_hand like integer' do
|
40
|
+
it 'should populate stock item in all stock locations' do
|
41
|
+
importer.run
|
42
|
+
variant = product.variants.find_by(sku: @variant_data[1])
|
43
|
+
expect(variant.stock_items.count).to eq(2)
|
44
|
+
|
45
|
+
variant.stock_items.each do |stock_item|
|
46
|
+
expect(stock_item.count_on_hand).to eq(@variant_data[3].to_i)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'with stock_locations list' do
|
52
|
+
let(:stock_importer) { described_class.new(fixture_file('spree_variants_multiple_locations.csv')) }
|
53
|
+
|
54
|
+
before do
|
55
|
+
@variant_stock_data = CSV.read(fixture_file('spree_variants_multiple_locations.csv'))[1]
|
56
|
+
master_sku = @variant_stock_data[0]
|
57
|
+
product.master.update(sku: master_sku)
|
58
|
+
stock_importer.run
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should associate variant with product' do
|
62
|
+
expect(product.variants.count).to eq(2)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should populate stock item accordingly' do
|
66
|
+
variant = product.variants.find_by(sku: @variant_stock_data[1])
|
67
|
+
ny_location = Spree::StockLocation.find_by(name: 'NY Warehouse')
|
68
|
+
ny_item = Spree::StockItem.find_by(variant_id: variant.id, stock_location_id: ny_location.id)
|
69
|
+
expect(ny_item.count_on_hand).to eq(5)
|
70
|
+
|
71
|
+
ca_location = Spree::StockLocation.find_by(name: 'CA Warehouse')
|
72
|
+
ca_item = Spree::StockItem.find_by(variant_id: variant.id, stock_location_id: ca_location.id)
|
73
|
+
expect(ca_item.count_on_hand).to eq(15)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -15,7 +15,7 @@ end
|
|
15
15
|
# Configure Rails Environment
|
16
16
|
ENV['RAILS_ENV'] = 'test'
|
17
17
|
|
18
|
-
require File.expand_path('
|
18
|
+
require File.expand_path('dummy/config/environment.rb', __dir__)
|
19
19
|
|
20
20
|
require 'rspec/rails'
|
21
21
|
require 'database_cleaner'
|
@@ -31,6 +31,7 @@ require 'spree/testing_support/authorization_helpers'
|
|
31
31
|
require 'spree/testing_support/capybara_ext'
|
32
32
|
require 'spree/testing_support/controller_requests'
|
33
33
|
require 'spree/testing_support/url_helpers'
|
34
|
+
require 'spree/testing_support/factories'
|
34
35
|
|
35
36
|
RSpec.configure do |config|
|
36
37
|
# Infer an example group's spec type from the file location.
|
@@ -42,6 +43,7 @@ RSpec.configure do |config|
|
|
42
43
|
#
|
43
44
|
# visit spree.admin_path
|
44
45
|
# current_path.should eql(spree.products_path)
|
46
|
+
config.include FactoryBot::Syntax::Methods
|
45
47
|
config.include Spree::TestingSupport::UrlHelpers
|
46
48
|
config.include FileHelpers
|
47
49
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: solidus_datashift
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.pre.alpha
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- César Carruitero
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-04-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: datashift
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0.40'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: mechanize
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: solidus_core
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +94,20 @@ dependencies:
|
|
80
94
|
- - ">="
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: factory_bot
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
83
111
|
- !ruby/object:Gem::Dependency
|
84
112
|
name: ffaker
|
85
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -192,6 +220,20 @@ dependencies:
|
|
192
220
|
- - ">="
|
193
221
|
- !ruby/object:Gem::Version
|
194
222
|
version: '0'
|
223
|
+
- !ruby/object:Gem::Dependency
|
224
|
+
name: solidus_multi_domain
|
225
|
+
requirement: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - ">="
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: '0'
|
230
|
+
type: :development
|
231
|
+
prerelease: false
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
233
|
+
requirements:
|
234
|
+
- - ">="
|
235
|
+
- !ruby/object:Gem::Version
|
236
|
+
version: '0'
|
195
237
|
- !ruby/object:Gem::Dependency
|
196
238
|
name: sqlite3
|
197
239
|
requirement: !ruby/object:Gem::Requirement
|
@@ -225,13 +267,22 @@ files:
|
|
225
267
|
- config/locales/en.yml
|
226
268
|
- lib/solidus_datashift.rb
|
227
269
|
- lib/solidus_datashift/engine.rb
|
228
|
-
- lib/solidus_datashift/
|
270
|
+
- lib/solidus_datashift/importer.rb
|
271
|
+
- lib/solidus_datashift/importer/product.rb
|
272
|
+
- lib/solidus_datashift/importer/variant.rb
|
273
|
+
- lib/solidus_datashift/populator.rb
|
274
|
+
- lib/solidus_datashift/populator/product.rb
|
275
|
+
- lib/solidus_datashift/populator/variant.rb
|
276
|
+
- lib/solidus_datashift/utils.rb
|
229
277
|
- lib/solidus_datashift/version.rb
|
230
278
|
- lib/tasks/solidus_datashift.rake
|
231
279
|
- solidus_datashift.gemspec
|
232
280
|
- spec/fixtures/spree_products.csv
|
233
281
|
- spec/fixtures/spree_products.xls
|
282
|
+
- spec/fixtures/spree_variants.csv
|
283
|
+
- spec/fixtures/spree_variants_multiple_locations.csv
|
234
284
|
- spec/solidus_datashift/product_importer_spec.rb
|
285
|
+
- spec/solidus_datashift/variant_importer_spec.rb
|
235
286
|
- spec/spec_helper.rb
|
236
287
|
- spec/support/file_helpers.rb
|
237
288
|
homepage: https://github.com/ccarruitero/solidus_datashift
|
@@ -249,9 +300,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
249
300
|
version: '0'
|
250
301
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
251
302
|
requirements:
|
252
|
-
- - "
|
303
|
+
- - ">"
|
253
304
|
- !ruby/object:Gem::Version
|
254
|
-
version:
|
305
|
+
version: 1.3.1
|
255
306
|
requirements: []
|
256
307
|
rubyforge_project:
|
257
308
|
rubygems_version: 2.6.13
|
@@ -1,22 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'datashift'
|
4
|
-
|
5
|
-
module SolidusDatashift
|
6
|
-
class ProductImporter
|
7
|
-
def initialize(file_name)
|
8
|
-
@file_name = file_name
|
9
|
-
@datashift_loader = DataShift::Loader::Factory.get_loader(file_name)
|
10
|
-
end
|
11
|
-
|
12
|
-
def inclusion_columns
|
13
|
-
%w[ cost_price images price shipping_category sku stock_items variant_sku
|
14
|
-
variant_cost_price variant_price variant_images]
|
15
|
-
end
|
16
|
-
|
17
|
-
def run
|
18
|
-
DataShift::Configuration.call.force_inclusion_of_columns = inclusion_columns
|
19
|
-
@datashift_loader.run(@file_name, Spree::Product)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|