solidus_importer 0.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 +7 -0
- data/.circleci/config.yml +35 -0
- data/.gem_release.yml +5 -0
- data/.github/stale.yml +17 -0
- data/.gitignore +20 -0
- data/.hound.yml +8 -0
- data/.rspec +2 -0
- data/.rubocop.yml +2 -0
- data/Gemfile +33 -0
- data/LICENSE +26 -0
- data/README.md +170 -0
- data/Rakefile +6 -0
- data/app/assets/javascripts/spree/backend/solidus_importer.js +2 -0
- data/app/assets/javascripts/spree/frontend/solidus_importer.js +2 -0
- data/app/assets/stylesheets/spree/backend/solidus_importer.css +16 -0
- data/app/assets/stylesheets/spree/frontend/solidus_importer.css +4 -0
- data/app/controllers/spree/admin/solidus_importer/import_rows_controller.rb +24 -0
- data/app/controllers/spree/admin/solidus_importer/imports_controller.rb +44 -0
- data/app/jobs/solidus_importer/import_job.rb +30 -0
- data/app/models/solidus_importer/import.rb +48 -0
- data/app/models/solidus_importer/row.rb +26 -0
- data/app/views/spree/admin/solidus_importer/import_rows/show.html.erb +46 -0
- data/app/views/spree/admin/solidus_importer/imports/_form.html.erb +14 -0
- data/app/views/spree/admin/solidus_importer/imports/index.html.erb +80 -0
- data/app/views/spree/admin/solidus_importer/imports/new.html.erb +13 -0
- data/app/views/spree/admin/solidus_importer/imports/show.html.erb +87 -0
- data/bin/console +17 -0
- data/bin/rails +7 -0
- data/bin/rails-engine +13 -0
- data/bin/rails-sandbox +16 -0
- data/bin/rake +7 -0
- data/bin/sandbox +84 -0
- data/bin/setup +8 -0
- data/config/initializers/spree.rb +11 -0
- data/config/locales/en.yml +28 -0
- data/config/routes.rb +11 -0
- data/db/migrate/20191216101011_create_solidus_importer_imports.rb +19 -0
- data/db/migrate/20191216101012_create_solidus_importer_rows.rb +14 -0
- data/examples/importers/custom_importer.rb +20 -0
- data/examples/processors/notify_on_failure.rb +22 -0
- data/lib/generators/solidus_importer/install/install_generator.rb +22 -0
- data/lib/solidus_importer.rb +25 -0
- data/lib/solidus_importer/base_importer.rb +26 -0
- data/lib/solidus_importer/configuration.rb +39 -0
- data/lib/solidus_importer/engine.rb +23 -0
- data/lib/solidus_importer/exception.rb +5 -0
- data/lib/solidus_importer/factories.rb +4 -0
- data/lib/solidus_importer/process_import.rb +88 -0
- data/lib/solidus_importer/process_row.rb +46 -0
- data/lib/solidus_importer/processors/address.rb +47 -0
- data/lib/solidus_importer/processors/base.rb +15 -0
- data/lib/solidus_importer/processors/customer.rb +41 -0
- data/lib/solidus_importer/processors/log.rb +15 -0
- data/lib/solidus_importer/processors/option_types.rb +43 -0
- data/lib/solidus_importer/processors/option_values.rb +49 -0
- data/lib/solidus_importer/processors/order.rb +40 -0
- data/lib/solidus_importer/processors/product.rb +51 -0
- data/lib/solidus_importer/processors/product_images.rb +30 -0
- data/lib/solidus_importer/processors/taxon.rb +52 -0
- data/lib/solidus_importer/processors/variant.rb +51 -0
- data/lib/solidus_importer/processors/variant_images.rb +30 -0
- data/lib/solidus_importer/version.rb +5 -0
- data/solidus_importer.gemspec +36 -0
- data/spec/factories/solidus_importer_imports.rb +27 -0
- data/spec/factories/solidus_importer_rows.rb +82 -0
- data/spec/features/admin/solidus_importer/import_rows_spec.rb +30 -0
- data/spec/features/admin/solidus_importer/imports_spec.rb +121 -0
- data/spec/features/solidus_importer/import_spec.rb +138 -0
- data/spec/features/solidus_importer/processors_spec.rb +53 -0
- data/spec/fixtures/solidus_importer/apparel.csv +23 -0
- data/spec/fixtures/solidus_importer/customers.csv +3 -0
- data/spec/fixtures/solidus_importer/home-and-garden.csv +22 -0
- data/spec/fixtures/solidus_importer/invalid_headers.csv +3 -0
- data/spec/fixtures/solidus_importer/invalid_product.csv +2 -0
- data/spec/fixtures/solidus_importer/jewelery.csv +55 -0
- data/spec/fixtures/solidus_importer/orders.csv +5 -0
- data/spec/fixtures/solidus_importer/products.csv +8 -0
- data/spec/fixtures/solidus_importer/thinking-cat.jpg +0 -0
- data/spec/jobs/solidus_importer/import_job_spec.rb +54 -0
- data/spec/lib/solidus_importer/base_importer_spec.rb +23 -0
- data/spec/lib/solidus_importer/process_import_spec.rb +74 -0
- data/spec/lib/solidus_importer/process_row_spec.rb +24 -0
- data/spec/lib/solidus_importer/processors/address_spec.rb +18 -0
- data/spec/lib/solidus_importer/processors/base_spec.rb +9 -0
- data/spec/lib/solidus_importer/processors/customer_spec.rb +65 -0
- data/spec/lib/solidus_importer/processors/log_spec.rb +18 -0
- data/spec/lib/solidus_importer/processors/option_types_spec.rb +38 -0
- data/spec/lib/solidus_importer/processors/option_values_spec.rb +43 -0
- data/spec/lib/solidus_importer/processors/order_spec.rb +56 -0
- data/spec/lib/solidus_importer/processors/product_images_spec.rb +42 -0
- data/spec/lib/solidus_importer/processors/product_spec.rb +66 -0
- data/spec/lib/solidus_importer/processors/taxon_spec.rb +33 -0
- data/spec/lib/solidus_importer/processors/variant_images_spec.rb +44 -0
- data/spec/lib/solidus_importer/processors/variant_spec.rb +86 -0
- data/spec/lib/solidus_importer_spec.rb +14 -0
- data/spec/models/solidus_importer/import_spec.rb +60 -0
- data/spec/models/solidus_importer/row_spec.rb +18 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/support/solidus_importer_helpers.rb +13 -0
- metadata +227 -0
data/bin/setup
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Spree::Backend::Config.configure do |config|
|
|
4
|
+
config.menu_items << config.class::MenuItem.new(
|
|
5
|
+
:imports,
|
|
6
|
+
'download',
|
|
7
|
+
condition: -> { can?(:admin, Spree::Product) },
|
|
8
|
+
label: :importer,
|
|
9
|
+
url: :admin_solidus_importer_imports_path
|
|
10
|
+
)
|
|
11
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
en:
|
|
2
|
+
spree:
|
|
3
|
+
solidus_importer:
|
|
4
|
+
created_at: Created at
|
|
5
|
+
data: Data
|
|
6
|
+
import: Import
|
|
7
|
+
imports: Imports
|
|
8
|
+
import_rows: Import rows
|
|
9
|
+
log_entry: Log information
|
|
10
|
+
messages: Messages
|
|
11
|
+
target_entity: Target entity
|
|
12
|
+
title: &solidus_importer_title
|
|
13
|
+
Importer
|
|
14
|
+
updated_at: Updated at
|
|
15
|
+
updated_at_from: 'Updated at: start date'
|
|
16
|
+
updated_at_to: 'Updated at: end date'
|
|
17
|
+
import_type: Import Type
|
|
18
|
+
import_types:
|
|
19
|
+
customers: Customers
|
|
20
|
+
orders: Orders
|
|
21
|
+
products: Products
|
|
22
|
+
|
|
23
|
+
admin:
|
|
24
|
+
tab:
|
|
25
|
+
importer: *solidus_importer_title
|
|
26
|
+
solidus_importer:
|
|
27
|
+
create: Import!
|
|
28
|
+
new: New import
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class CreateSolidusImporterImports < ActiveRecord::Migration[5.2]
|
|
4
|
+
def change
|
|
5
|
+
create_table :solidus_importer_imports do |t|
|
|
6
|
+
t.string :import_type
|
|
7
|
+
t.string :state, null: false, default: 'created', limit: 32
|
|
8
|
+
t.string :file, null: false, default: '', limit: 1024
|
|
9
|
+
t.text :messages
|
|
10
|
+
|
|
11
|
+
t.timestamps null: false
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
reversible do |dir|
|
|
15
|
+
dir.up { add_attachment :solidus_importer_imports, :file }
|
|
16
|
+
dir.down { remove_attachment :solidus_importer_imports, :file }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class CreateSolidusImporterRows < ActiveRecord::Migration[5.2]
|
|
4
|
+
def change
|
|
5
|
+
create_table :solidus_importer_rows do |t|
|
|
6
|
+
t.belongs_to :import
|
|
7
|
+
t.string :state, null: false, default: 'created', limit: 32
|
|
8
|
+
t.text :data
|
|
9
|
+
t.text :messages
|
|
10
|
+
|
|
11
|
+
t.timestamps null: false
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SolidusImporter
|
|
4
|
+
module Importers
|
|
5
|
+
##
|
|
6
|
+
# This importer sends an email when the import process is finished.
|
|
7
|
+
#
|
|
8
|
+
# Install: set the class as importer in solidus_importer configuration
|
|
9
|
+
class CustomImporter < ::SolidusImporter::BaseImporter
|
|
10
|
+
def after_import(context)
|
|
11
|
+
ActionMailer::Base.mail(
|
|
12
|
+
from: 'some_email',
|
|
13
|
+
to: 'some_email_2',
|
|
14
|
+
subject: 'Import finished',
|
|
15
|
+
body: "Ending context:\n#{context.to_json}"
|
|
16
|
+
).deliver_now
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SolidusImporter
|
|
4
|
+
module Processors
|
|
5
|
+
##
|
|
6
|
+
# This processor sends an email if the process of a single row is failing.
|
|
7
|
+
#
|
|
8
|
+
# Install: add the class to processors in solidus_importer configuration
|
|
9
|
+
class NotifyOnFailure < Base
|
|
10
|
+
def call(context)
|
|
11
|
+
return if context[:success]
|
|
12
|
+
|
|
13
|
+
ActionMailer::Base.mail(
|
|
14
|
+
from: 'some_email',
|
|
15
|
+
to: 'some_email_2',
|
|
16
|
+
subject: 'Row process error',
|
|
17
|
+
body: "Row context:\n#{context.to_json}"
|
|
18
|
+
).deliver_now
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SolidusImporter
|
|
4
|
+
module Generators
|
|
5
|
+
class InstallGenerator < Rails::Generators::Base
|
|
6
|
+
class_option :auto_run_migrations, type: :boolean, default: false
|
|
7
|
+
|
|
8
|
+
def add_migrations
|
|
9
|
+
run 'bin/rails railties:install:migrations FROM=solidus_importer'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def run_migrations
|
|
13
|
+
run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask('Would you like to run the migrations now? [Y/n]')) # rubocop:disable Metrics/LineLength
|
|
14
|
+
if run_migrations
|
|
15
|
+
run 'bin/rails db:migrate'
|
|
16
|
+
else
|
|
17
|
+
puts 'Skipping bin/rails db:migrate, don\'t forget to run it!' # rubocop:disable Rails/Output
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'solidus_core'
|
|
4
|
+
require 'solidus_support'
|
|
5
|
+
|
|
6
|
+
require 'solidus_importer/version'
|
|
7
|
+
require 'solidus_importer/exception'
|
|
8
|
+
require 'solidus_importer/base_importer'
|
|
9
|
+
|
|
10
|
+
require 'solidus_importer/processors/base'
|
|
11
|
+
processors = File.join(__dir__, 'solidus_importer/processors/*.rb')
|
|
12
|
+
Dir[processors].each { |file| require file }
|
|
13
|
+
|
|
14
|
+
require 'solidus_importer/configuration'
|
|
15
|
+
require 'solidus_importer/engine'
|
|
16
|
+
require 'solidus_importer/process_import'
|
|
17
|
+
require 'solidus_importer/process_row'
|
|
18
|
+
|
|
19
|
+
module SolidusImporter
|
|
20
|
+
class << self
|
|
21
|
+
def import!(import_path, type:)
|
|
22
|
+
ProcessImport.import_from_file(import_path, type.to_sym)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SolidusImporter
|
|
4
|
+
class BaseImporter
|
|
5
|
+
def initialize(options)
|
|
6
|
+
@options = options
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def processors
|
|
10
|
+
@options[:processors] || []
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
##
|
|
14
|
+
# Defines a method called before the import process is started.
|
|
15
|
+
# Remember to always return a context with `success` key.
|
|
16
|
+
#
|
|
17
|
+
# - initial_context: context used process the rows, example: `{ success: true }`
|
|
18
|
+
def before_import(initial_context)
|
|
19
|
+
initial_context
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
##
|
|
23
|
+
# Defines a method called after the import process is started
|
|
24
|
+
def after_import(_ending_context); end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SolidusImporter
|
|
4
|
+
class Configuration < Spree::Preferences::Configuration
|
|
5
|
+
preference :solidus_importer, :hash, default: {
|
|
6
|
+
customers: {
|
|
7
|
+
importer: SolidusImporter::BaseImporter,
|
|
8
|
+
processors: [
|
|
9
|
+
SolidusImporter::Processors::Address,
|
|
10
|
+
SolidusImporter::Processors::Customer,
|
|
11
|
+
SolidusImporter::Processors::Log
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
orders: {
|
|
15
|
+
importer: SolidusImporter::BaseImporter,
|
|
16
|
+
processors: [
|
|
17
|
+
SolidusImporter::Processors::Order,
|
|
18
|
+
SolidusImporter::Processors::Log
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
products: {
|
|
22
|
+
importer: SolidusImporter::BaseImporter,
|
|
23
|
+
processors: [
|
|
24
|
+
SolidusImporter::Processors::Product,
|
|
25
|
+
SolidusImporter::Processors::Variant,
|
|
26
|
+
SolidusImporter::Processors::OptionTypes,
|
|
27
|
+
SolidusImporter::Processors::OptionValues,
|
|
28
|
+
SolidusImporter::Processors::ProductImages,
|
|
29
|
+
SolidusImporter::Processors::VariantImages,
|
|
30
|
+
SolidusImporter::Processors::Log
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
def available_types
|
|
36
|
+
solidus_importer.keys
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spree/core'
|
|
4
|
+
require 'solidus_importer'
|
|
5
|
+
|
|
6
|
+
module SolidusImporter
|
|
7
|
+
class Engine < Rails::Engine
|
|
8
|
+
include SolidusSupport::EngineExtensions
|
|
9
|
+
|
|
10
|
+
isolate_namespace ::Spree
|
|
11
|
+
|
|
12
|
+
engine_name 'solidus_importer'
|
|
13
|
+
|
|
14
|
+
initializer 'solidus_importer.environment', before: :load_config_initializers do |_app|
|
|
15
|
+
SolidusImporter::Config = SolidusImporter::Configuration.new
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# use rspec for tests
|
|
19
|
+
config.generators do |g|
|
|
20
|
+
g.test_framework :rspec
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'csv'
|
|
4
|
+
|
|
5
|
+
module SolidusImporter
|
|
6
|
+
##
|
|
7
|
+
# This class parse the source file and create the rows (scan). Then it asks to
|
|
8
|
+
# Process Row to process each one.
|
|
9
|
+
class ProcessImport
|
|
10
|
+
attr_reader :importer
|
|
11
|
+
|
|
12
|
+
def initialize(import, importer_options: nil)
|
|
13
|
+
@import = import
|
|
14
|
+
options = importer_options || ::SolidusImporter::Config.solidus_importer[@import.import_type.to_sym]
|
|
15
|
+
@importer = options[:importer].new(options)
|
|
16
|
+
@import.importer = @importer
|
|
17
|
+
validate!
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def process(force_scan: nil)
|
|
21
|
+
return @import unless @import.created_or_failed?
|
|
22
|
+
|
|
23
|
+
scan_required = force_scan.nil? ? @import.created? : force_scan
|
|
24
|
+
@import.update(state: :processing)
|
|
25
|
+
initial_context = scan_required ? scan : { success: true }
|
|
26
|
+
initial_context = @importer.before_import(initial_context)
|
|
27
|
+
unless @import.failed?
|
|
28
|
+
rows = process_rows(initial_context)
|
|
29
|
+
@import.update(state: :completed) if rows.zero?
|
|
30
|
+
end
|
|
31
|
+
@import
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class << self
|
|
35
|
+
def import_from_file(import_path, import_type)
|
|
36
|
+
import = ::SolidusImporter::Import.new(import_type: import_type)
|
|
37
|
+
import.import_file = import_path
|
|
38
|
+
import.save!
|
|
39
|
+
new(import).process
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def scan
|
|
46
|
+
data = CSV.parse(
|
|
47
|
+
File.read(@import.file.path),
|
|
48
|
+
headers: true,
|
|
49
|
+
encoding: 'UTF-8',
|
|
50
|
+
header_converters: ->(h) { h.strip }
|
|
51
|
+
)
|
|
52
|
+
prepare_rows(data)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def check_data(data)
|
|
56
|
+
messages = []
|
|
57
|
+
headers = data.headers
|
|
58
|
+
messages << 'Invalid headers' if headers.blank? || !headers.exclude?(nil)
|
|
59
|
+
messages
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def prepare_rows(data)
|
|
63
|
+
messages = check_data(data)
|
|
64
|
+
if messages.empty?
|
|
65
|
+
data.each do |row|
|
|
66
|
+
@import.rows << ::SolidusImporter::Row.new(data: row.to_h)
|
|
67
|
+
end
|
|
68
|
+
{ success: true }
|
|
69
|
+
else
|
|
70
|
+
@import.update(state: :failed, messages: messages.join(', '))
|
|
71
|
+
{ success: false, messages: messages.join(', ') }
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def process_rows(initial_context)
|
|
76
|
+
rows = @import.rows.created_or_failed.order(id: :asc)
|
|
77
|
+
rows.each do |row|
|
|
78
|
+
::SolidusImporter::ProcessRow.new(@importer, row).process(initial_context)
|
|
79
|
+
end
|
|
80
|
+
rows.size
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def validate!
|
|
84
|
+
raise ::SolidusImporter::Exception, 'Valid import entity required' if !@import || !@import.valid?
|
|
85
|
+
raise ::SolidusImporter::Exception, "No importer found for #{@import.import_type} type" if !@importer
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SolidusImporter
|
|
4
|
+
##
|
|
5
|
+
# This class process a single row of an import running the configured
|
|
6
|
+
# processor in chain.
|
|
7
|
+
class ProcessRow
|
|
8
|
+
def initialize(importer, row)
|
|
9
|
+
@importer = importer
|
|
10
|
+
@row = row
|
|
11
|
+
validate!
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def process(initial_context)
|
|
15
|
+
context = initial_context.dup.merge!(row_id: @row.id, importer: @importer, data: @row.data)
|
|
16
|
+
@importer.processors.each do |processor|
|
|
17
|
+
begin
|
|
18
|
+
processor.call(context)
|
|
19
|
+
rescue StandardError => e
|
|
20
|
+
context.merge!(success: false, messages: e.message) # rubocop:disable Performance/RedundantMerge
|
|
21
|
+
break
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
@row.update!(
|
|
25
|
+
state: context[:success] ? :completed : :failed,
|
|
26
|
+
messages: context[:messages]
|
|
27
|
+
)
|
|
28
|
+
check_import_finished(context)
|
|
29
|
+
context
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def check_import_finished(context)
|
|
35
|
+
return unless @row.import.finished?
|
|
36
|
+
|
|
37
|
+
@importer.after_import(context)
|
|
38
|
+
@row.import.update!(state: (@row.import.rows.failed.any? ? :failed : :completed))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def validate!
|
|
42
|
+
raise SolidusImporter::Exception, 'No importer defined' if !@importer
|
|
43
|
+
raise SolidusImporter::Exception, 'Invalid row type' if !@row || !@row.is_a?(SolidusImporter::Row)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SolidusImporter
|
|
4
|
+
module Processors
|
|
5
|
+
class Address < Base
|
|
6
|
+
def call(context)
|
|
7
|
+
@data = context.fetch(:data)
|
|
8
|
+
|
|
9
|
+
return unless address?
|
|
10
|
+
|
|
11
|
+
context.merge!(address: process_address)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def process_address
|
|
17
|
+
prepare_address.tap(&:save)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def prepare_address
|
|
21
|
+
Spree::Address.new(
|
|
22
|
+
firstname: @data['First Name'],
|
|
23
|
+
lastname: @data['Last Name'],
|
|
24
|
+
address1: @data['Address1'],
|
|
25
|
+
address2: @data['Address2'],
|
|
26
|
+
city: @data['City'],
|
|
27
|
+
zipcode: @data['Zip'],
|
|
28
|
+
phone: @data['Phone'],
|
|
29
|
+
country: extract_country(@data['Country Code']),
|
|
30
|
+
state: extract_state(@data['Province Code'])
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def extract_country(iso)
|
|
35
|
+
Spree::Country.find_by(iso: iso)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def extract_state(iso)
|
|
39
|
+
Spree::State.find_by(abbr: iso) || Spree::State.find_by(name: iso)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def address?
|
|
43
|
+
@data['Address1'].present?
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|