From 352aa3cc1a9e33bae6e12ac0b08a082e3d758aea Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 11 Mar 2021 13:39:29 -0300 Subject: [PATCH 01/10] [DL-82] Adding new service to import HS code from hs10 endpoint as well as a little spec to test happy path --- app/models/spree/flow_io_order_decorator.rb | 8 +++ app/models/spree/flow_io_variant_decorator.rb | 13 ++++ .../import_items_hs_codes.rb | 62 +++++++++++++++++++ spec/factories/flow_io/hs_code.rb | 18 ++++++ spec/service/import_items_hs_codes_spec.rb | 24 +++++++ 5 files changed, 125 insertions(+) create mode 100644 app/services/flowcommerce_spree/import_items_hs_codes.rb create mode 100644 spec/factories/flow_io/hs_code.rb create mode 100644 spec/service/import_items_hs_codes_spec.rb diff --git a/app/models/spree/flow_io_order_decorator.rb b/app/models/spree/flow_io_order_decorator.rb index 9eda86b3..eac24f12 100644 --- a/app/models/spree/flow_io_order_decorator.rb +++ b/app/models/spree/flow_io_order_decorator.rb @@ -23,6 +23,14 @@ def flow_order flow_data&.[]('order') end + def flow_order? + payment = payments.completed.first + return payment.payment_method.type == 'Spree::Gateway::FlowIo' if payment + return zone.flow_io_active_experience? if zone + + flow_data.present? + end + # accepts line item, usually called from views def flow_line_item_price(line_item, total = false) result = if (order = flow_order) diff --git a/app/models/spree/flow_io_variant_decorator.rb b/app/models/spree/flow_io_variant_decorator.rb index e931188d..9366e2c1 100644 --- a/app/models/spree/flow_io_variant_decorator.rb +++ b/app/models/spree/flow_io_variant_decorator.rb @@ -12,6 +12,8 @@ def self.prepended(base) # after every save we sync product we generate sh1 checksums to update only when change happend base.after_save :sync_product_to_flow + + base.after_save :sync_classification end def experiences @@ -200,6 +202,17 @@ def flow_import_item(item_hash, experience_key: nil) update_column(:meta, meta.to_json) end + def sync_classification + return unless meta_changed? + + meta_changes = changes['meta'] + old_hs_code = meta_changes[0]&.[]('flow_data')&.[]('hs_code') + new_hs_code = meta_changes[1]&.[]('flow_data')&.[]('hs_code') + return if old_hs_code == new_hs_code + + VariantService.new.update_classification(self) + end + Spree::Variant.prepend(self) if Spree::Variant.included_modules.exclude?(self) end end diff --git a/app/services/flowcommerce_spree/import_items_hs_codes.rb b/app/services/flowcommerce_spree/import_items_hs_codes.rb new file mode 100644 index 00000000..f68b722b --- /dev/null +++ b/app/services/flowcommerce_spree/import_items_hs_codes.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +module FlowcommerceSpree + # A service object to import the data for product variants belonging to a flow.io Experience + class ImportItemsHsCodes + def self.run(zone, client: FlowcommerceSpree.client, organization: ORGANIZATION) + new(zone, client: client, organization: organization).run + end + + def run + page_size = 100 + offset = 0 + items = [] + total = 0 + + while offset == 0 || items.length != 0 + # show current list size + @logger.info "\nGetting items: #{@experience_key.green}, rows #{offset} - #{offset + page_size}" + + begin + items = @client.hs10.get(@organization, limit: page_size, offset: offset) + rescue Io::Flow::V0::HttpClient::PreconditionException => e + @logger.info "flow.io API error: #{e.message}" + break + end + + offset += page_size + log_str = +'' + + items.group_by { |hs_code| hs_code.item.number }.each do |item| + total += 1 + + variant_sku = item.first + next unless (variant = Spree::Variant.find_by(sku: variant_sku)) + + hs_code_data_list = item.last + hs_code = hs_code_data_list&.first&.code&.[](0..5) + variant.flow_data ||= {} + variant.flow_data['hs_code'] = hs_code + variant.update_column(:meta, variant.meta.to_json) + log_str << "#{variant.sku}, " + end + @logger.info log_str + end + + # @logger.info "\nUpdating Fulfil: #{@experience_key.green}" + # VariantService.new.update_classification + + @logger.info "\nData for #{total.to_s.green} products was imported." + end + + private + + def initialize(zone, client:, organization:) + @client = client + @experience_key = zone.flow_io_experience + @logger = client.instance_variable_get(:@http_handler).logger + @organization = organization + @zone = zone + end + end +end diff --git a/spec/factories/flow_io/hs_code.rb b/spec/factories/flow_io/hs_code.rb new file mode 100644 index 00000000..5fbd8ed0 --- /dev/null +++ b/spec/factories/flow_io/hs_code.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :flow_hs_code, class: Io::Flow::V0::Models::Hs10 do + id { Faker::Guid.guid } + origin { 'CAN' } + destination { 'DEU' } + code { '71131910' } + item do + Io::Flow::V0::Models::HarmonizedItemReference.new( + description: 'jewellery precious_metal', + id: 'cit-b1d68224735e4828a51b0be90ad37c6f', + number: Spree::Variant.first&.sku || create(:base_variant).sku + ) + end + initialize_with { new(**attributes) } + end +end diff --git a/spec/service/import_items_hs_codes_spec.rb b/spec/service/import_items_hs_codes_spec.rb new file mode 100644 index 00000000..c887e24b --- /dev/null +++ b/spec/service/import_items_hs_codes_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'colorize' + +module FlowcommerceSpree + RSpec.describe ImportItemsHsCodes do + let(:zone) { create(:germany_zone, :with_flow_data) } + let(:hs_code_data) { build(:flow_hs_code) } + + before do + allow_any_instance_of(Io::Flow::V0::Clients::Hs10) + .to(receive(:get).with('mejuridevs', { limit: 100, offset: 0 }).and_return([hs_code_data])) + allow_any_instance_of(Io::Flow::V0::Clients::Hs10) + .to(receive(:get).with('mejuridevs', { limit: 100, offset: 100 }).and_return([])) + end + + it 'Update variant HS code' do + FlowcommerceSpree::ImportItemsHsCodes.run(zone) + variant = Spree::Variant.find_by(sku: hs_code_data.item.number) + expect(variant.flow_data['hs_code']).to(eq(hs_code_data.code[0..5])) + end + end +end From 73e90f339b63e0d84f3328eb564f26a03dee80e9 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 22 Mar 2021 09:11:48 -0300 Subject: [PATCH 02/10] [DL-82] Adding specs associated to task for import HS codes from flow using CSV file. --- app/models/spree/flow_io_variant_decorator.rb | 2 +- .../import_items_hs_codes.rb | 3 -- lib/tasks/spree_variant.rake | 31 +++++++++++++ spec/rails_helper.rb | 1 + spec/support/tasks.rb | 35 +++++++++++++++ spec/tasks/spree_variant_spec.rb | 43 +++++++++++++++++++ 6 files changed, 111 insertions(+), 4 deletions(-) create mode 100644 lib/tasks/spree_variant.rake create mode 100644 spec/support/tasks.rb create mode 100644 spec/tasks/spree_variant_spec.rb diff --git a/app/models/spree/flow_io_variant_decorator.rb b/app/models/spree/flow_io_variant_decorator.rb index 9366e2c1..8c626ff1 100644 --- a/app/models/spree/flow_io_variant_decorator.rb +++ b/app/models/spree/flow_io_variant_decorator.rb @@ -210,7 +210,7 @@ def sync_classification new_hs_code = meta_changes[1]&.[]('flow_data')&.[]('hs_code') return if old_hs_code == new_hs_code - VariantService.new.update_classification(self) + VariantService.new.update_classification([self]) end Spree::Variant.prepend(self) if Spree::Variant.included_modules.exclude?(self) diff --git a/app/services/flowcommerce_spree/import_items_hs_codes.rb b/app/services/flowcommerce_spree/import_items_hs_codes.rb index f68b722b..af28bdb7 100644 --- a/app/services/flowcommerce_spree/import_items_hs_codes.rb +++ b/app/services/flowcommerce_spree/import_items_hs_codes.rb @@ -43,9 +43,6 @@ def run @logger.info log_str end - # @logger.info "\nUpdating Fulfil: #{@experience_key.green}" - # VariantService.new.update_classification - @logger.info "\nData for #{total.to_s.green} products was imported." end diff --git a/lib/tasks/spree_variant.rake b/lib/tasks/spree_variant.rake new file mode 100644 index 00000000..24250f3c --- /dev/null +++ b/lib/tasks/spree_variant.rake @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +namespace :spree_variant do + desc 'Import Flow Hs Codes from CSV' + task import_flow_hs_code_from_csv: :environment do |t| + s3_file_path = CSVUploader.download_url('script/flow_hs_codes.csv', 'flow_hs_code') + csv = CSV.new(URI.parse(s3_file_path).open, headers: true, col_sep: ',') + + not_found = [] + updated_count = [] + + csv.each do |row| + hs_code = row['hs6'] + next if hs_code.blank? + + sku = row['item_number'] + next not_found << sku unless (variant = Spree::Variant.find_by(sku: row['item_number'])) + + variant.flow_data ||= {} + variant.flow_data['hs_code'] = hs_code + variant.update_column(:meta, variant.meta.to_json) + updated_count << sku + end + + puts "\n#{Time.zone.now} | Not found in the DB #{not_found.size}." + puts not_found.inspect + + puts "\n#{Time.zone.now} | Updated #{updated_count.size}." + puts "Updated #{updated_count} variants." + end +end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 14f82eeb..2a521431 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -17,6 +17,7 @@ require 'support/database_cleaner.rb' require 'support/flow.rb' require 'support/controller_requests.rb' +require 'support/tasks.rb' # Add additional requires below this line. Rails is not loaded until this point! diff --git a/spec/support/tasks.rb b/spec/support/tasks.rb new file mode 100644 index 00000000..ff645b49 --- /dev/null +++ b/spec/support/tasks.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require 'rake' + +# Task names should be used in the top-level describe, with an optional +# "rake "-prefix for better documentation. Both of these will work: +# +# 1) describe "foo:bar" do ... end +# +# 2) describe "rake foo:bar" do ... end +# +# Favor including "rake "-prefix as in the 2nd example above as it produces +# doc output that makes it clear a rake task is under test and how it is +# invoked. +module TaskFormat + extend ActiveSupport::Concern + + included do + let(:task_name) { self.class.top_level_description.sub(/\Arake /, '') } + let(:tasks) { Rake::Task } # Make the Rake task available as `task` in your examples: + subject(:task) { tasks[task_name] } + end +end + +RSpec.configure do |config| # Tag Rake specs with `:task` metadata or put them in the spec/tasks dir + config.define_derived_metadata(file_path: %r{/spec/tasks/}) do |metadata| + metadata[:type] = :task + end + + config.include TaskFormat, type: :task + + config.before(:suite) do + Rails.application.load_tasks + end +end diff --git a/spec/tasks/spree_variant_spec.rb b/spec/tasks/spree_variant_spec.rb new file mode 100644 index 00000000..b9dac2b2 --- /dev/null +++ b/spec/tasks/spree_variant_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'csv' +# require 'tasks/tasks_helper' + +describe 'rake products:turn_on_version_for_region', type: :task do + let(:variant) { create(:base_variant, :with_flow_data) } + + describe 'import_flow_hs_code_from_csv' do + let(:hs_code) { '711319' } + let(:stubed_csv_content) { [variant.sku, hs_code, variant.product.id, variant.product.name] } + let(:stubed_csv) { CSV.new("item_number,hs6,product_id,item_name\n#{stubed_csv_content.join(',')}", headers: true) } + let(:run_codes_rake_task) do + Rake::Task['spree_variant:import_flow_hs_code_from_csv'].reenable + Rake.application.invoke_task('spree_variant:import_flow_hs_code_from_csv') + end + + before(:each) do + allow(CSVUploader).to(receive(:download_url).and_return('https://s3.amazonaws.com/test/script/flow_hs_codes.csv')) + allow_any_instance_of(URI::HTTPS).to(receive(:open)) + + # stubed_csv = CSV.new("#{title.join(',')}\n#{content.join(',')}", headers: true) + allow(CSV).to(receive(:new).and_return(stubed_csv)) + end + + it 'updates variant`s flow data with the hs_code' do + expect(variant.flow_data['hs_code']).to(be_blank) + run_codes_rake_task + expect(variant.reload.flow_data['hs_code']).to(eq(hs_code)) + end + + context 'when csv does not have hs_code from flow' do + let(:stubed_csv_content) { [variant.sku, '', variant.product.id, variant.product.name] } + + it 'does not update variant`s flow hs_code' do + expect(variant.flow_data['hs_code']).to(be_blank) + run_codes_rake_task + expect(variant.reload.flow_data['hs_code']).to(be_blank) + end + end + end +end From 9cc520d6af4a44bacc4dc3d980387f8189f79f59 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 22 Mar 2021 11:48:03 -0300 Subject: [PATCH 03/10] [Dl-82] Adding small rubocop improvemeents alonside some more general improvements --- app/models/spree/flow_io_order_decorator.rb | 8 -------- app/models/spree/flow_io_variant_decorator.rb | 2 +- .../flowcommerce_spree/import_items_hs_codes.rb | 16 +++++++++------- lib/tasks/spree_variant.rake | 17 ++++++++++++----- spec/dummy/app/models/concerns/csv_uploader.rb | 11 +++++++++++ spec/dummy/app/services/variant_service.rb | 10 ++++++++++ spec/service/import_items_hs_codes_spec.rb | 7 +++---- 7 files changed, 46 insertions(+), 25 deletions(-) create mode 100644 spec/dummy/app/models/concerns/csv_uploader.rb create mode 100644 spec/dummy/app/services/variant_service.rb diff --git a/app/models/spree/flow_io_order_decorator.rb b/app/models/spree/flow_io_order_decorator.rb index eac24f12..9eda86b3 100644 --- a/app/models/spree/flow_io_order_decorator.rb +++ b/app/models/spree/flow_io_order_decorator.rb @@ -23,14 +23,6 @@ def flow_order flow_data&.[]('order') end - def flow_order? - payment = payments.completed.first - return payment.payment_method.type == 'Spree::Gateway::FlowIo' if payment - return zone.flow_io_active_experience? if zone - - flow_data.present? - end - # accepts line item, usually called from views def flow_line_item_price(line_item, total = false) result = if (order = flow_order) diff --git a/app/models/spree/flow_io_variant_decorator.rb b/app/models/spree/flow_io_variant_decorator.rb index 8c626ff1..4c33ac0e 100644 --- a/app/models/spree/flow_io_variant_decorator.rb +++ b/app/models/spree/flow_io_variant_decorator.rb @@ -210,7 +210,7 @@ def sync_classification new_hs_code = meta_changes[1]&.[]('flow_data')&.[]('hs_code') return if old_hs_code == new_hs_code - VariantService.new.update_classification([self]) + VariantService.new.update_classification([sku]) end Spree::Variant.prepend(self) if Spree::Variant.included_modules.exclude?(self) diff --git a/app/services/flowcommerce_spree/import_items_hs_codes.rb b/app/services/flowcommerce_spree/import_items_hs_codes.rb index af28bdb7..774ce3c3 100644 --- a/app/services/flowcommerce_spree/import_items_hs_codes.rb +++ b/app/services/flowcommerce_spree/import_items_hs_codes.rb @@ -3,19 +3,20 @@ module FlowcommerceSpree # A service object to import the data for product variants belonging to a flow.io Experience class ImportItemsHsCodes - def self.run(zone, client: FlowcommerceSpree.client, organization: ORGANIZATION) - new(zone, client: client, organization: organization).run + def self.run(client: FlowcommerceSpree.client, organization: ORGANIZATION) + new(client: client, organization: organization).run end - def run + def run # rubocop:disable Metrics/MethodLength, Metrics/AbcSize page_size = 100 offset = 0 items = [] + updated = [] total = 0 while offset == 0 || items.length != 0 # show current list size - @logger.info "\nGetting items: #{@experience_key.green}, rows #{offset} - #{offset + page_size}" + @logger.info "\nGetting items: rows #{offset} - #{offset + page_size}" begin items = @client.hs10.get(@organization, limit: page_size, offset: offset) @@ -39,21 +40,22 @@ def run variant.flow_data['hs_code'] = hs_code variant.update_column(:meta, variant.meta.to_json) log_str << "#{variant.sku}, " + updated << variant.sku end @logger.info log_str end + VariantService.new.update_classification(updated) + @logger.info "\nData for #{total.to_s.green} products was imported." end private - def initialize(zone, client:, organization:) + def initialize(client:, organization:) @client = client - @experience_key = zone.flow_io_experience @logger = client.instance_variable_get(:@http_handler).logger @organization = organization - @zone = zone end end end diff --git a/lib/tasks/spree_variant.rake b/lib/tasks/spree_variant.rake index 24250f3c..36509166 100644 --- a/lib/tasks/spree_variant.rake +++ b/lib/tasks/spree_variant.rake @@ -2,12 +2,12 @@ namespace :spree_variant do desc 'Import Flow Hs Codes from CSV' - task import_flow_hs_code_from_csv: :environment do |t| + task import_flow_hs_code_from_csv: :environment do s3_file_path = CSVUploader.download_url('script/flow_hs_codes.csv', 'flow_hs_code') csv = CSV.new(URI.parse(s3_file_path).open, headers: true, col_sep: ',') not_found = [] - updated_count = [] + updated = [] csv.each do |row| hs_code = row['hs6'] @@ -19,13 +19,20 @@ namespace :spree_variant do variant.flow_data ||= {} variant.flow_data['hs_code'] = hs_code variant.update_column(:meta, variant.meta.to_json) - updated_count << sku + updated << sku end + VariantService.new.update_classification(updated) + puts "\n#{Time.zone.now} | Not found in the DB #{not_found.size}." puts not_found.inspect - puts "\n#{Time.zone.now} | Updated #{updated_count.size}." - puts "Updated #{updated_count} variants." + puts "\n#{Time.zone.now} | Updated #{updated.size}." + puts "Updated #{updated} variants." + end + + desc 'Import Flow Hs Codes from Api' + task import_flow_hs_code: :environment do + FlowcommerceSpree::ImportItemsHsCodes.run(with_items: true, client: client, refresher: refresher) end end diff --git a/spec/dummy/app/models/concerns/csv_uploader.rb b/spec/dummy/app/models/concerns/csv_uploader.rb new file mode 100644 index 00000000..77cc8cef --- /dev/null +++ b/spec/dummy/app/models/concerns/csv_uploader.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class CSVUploader + def initialize(file) + timestamp = Time.current.strftime('%Y%m%d%H%M%S') + @filename = "#{timestamp}_#{file.original_filename}" + @file_content = CSV.parse(file.read) + end + + def self.download_url(file_path, filename); end +end diff --git a/spec/dummy/app/services/variant_service.rb b/spec/dummy/app/services/variant_service.rb new file mode 100644 index 00000000..26edbf10 --- /dev/null +++ b/spec/dummy/app/services/variant_service.rb @@ -0,0 +1,10 @@ +class VariantService + attr_accessor :variant + + def initialize(variant = nil) + @variant = variant + @bom_stock = {} + end + + def update_classification(variant_skus = []); end +end diff --git a/spec/service/import_items_hs_codes_spec.rb b/spec/service/import_items_hs_codes_spec.rb index c887e24b..fd8933e2 100644 --- a/spec/service/import_items_hs_codes_spec.rb +++ b/spec/service/import_items_hs_codes_spec.rb @@ -5,18 +5,17 @@ module FlowcommerceSpree RSpec.describe ImportItemsHsCodes do - let(:zone) { create(:germany_zone, :with_flow_data) } let(:hs_code_data) { build(:flow_hs_code) } before do allow_any_instance_of(Io::Flow::V0::Clients::Hs10) - .to(receive(:get).with('mejuridevs', { limit: 100, offset: 0 }).and_return([hs_code_data])) + .to(receive(:get).with('mejuridevs', limit: 100, offset: 0).and_return([hs_code_data])) allow_any_instance_of(Io::Flow::V0::Clients::Hs10) - .to(receive(:get).with('mejuridevs', { limit: 100, offset: 100 }).and_return([])) + .to(receive(:get).with('mejuridevs', limit: 100, offset: 100).and_return([])) end it 'Update variant HS code' do - FlowcommerceSpree::ImportItemsHsCodes.run(zone) + FlowcommerceSpree::ImportItemsHsCodes.run variant = Spree::Variant.find_by(sku: hs_code_data.item.number) expect(variant.flow_data['hs_code']).to(eq(hs_code_data.code[0..5])) end From be52565a8ba78c624460504309ea93ea75c75d29 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 22 Mar 2021 16:06:04 -0300 Subject: [PATCH 04/10] [DL-82] Adding small rubocop changes and improvements to code related to hs code handling --- spec/dummy/app/services/variant_service.rb | 3 ++- spec/tasks/spree_variant_spec.rb | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/dummy/app/services/variant_service.rb b/spec/dummy/app/services/variant_service.rb index 26edbf10..9c1bac91 100644 --- a/spec/dummy/app/services/variant_service.rb +++ b/spec/dummy/app/services/variant_service.rb @@ -1,9 +1,10 @@ +# frozen_string_literal: true + class VariantService attr_accessor :variant def initialize(variant = nil) @variant = variant - @bom_stock = {} end def update_classification(variant_skus = []); end diff --git a/spec/tasks/spree_variant_spec.rb b/spec/tasks/spree_variant_spec.rb index b9dac2b2..b28ebce0 100644 --- a/spec/tasks/spree_variant_spec.rb +++ b/spec/tasks/spree_variant_spec.rb @@ -20,7 +20,6 @@ allow(CSVUploader).to(receive(:download_url).and_return('https://s3.amazonaws.com/test/script/flow_hs_codes.csv')) allow_any_instance_of(URI::HTTPS).to(receive(:open)) - # stubed_csv = CSV.new("#{title.join(',')}\n#{content.join(',')}", headers: true) allow(CSV).to(receive(:new).and_return(stubed_csv)) end From 4d965d324509ea4156ec823d38a374d77630d497 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 22 Mar 2021 18:57:15 -0300 Subject: [PATCH 05/10] [DL-82] Adding small code improvements for Flow HS code handling --- app/models/spree/flow_io_variant_decorator.rb | 16 ---------------- lib/tasks/spree_variant.rake | 2 -- spec/service/import_items_hs_codes_spec.rb | 6 ++++++ spec/tasks/spree_variant_spec.rb | 12 +++--------- 4 files changed, 9 insertions(+), 27 deletions(-) diff --git a/app/models/spree/flow_io_variant_decorator.rb b/app/models/spree/flow_io_variant_decorator.rb index 4c33ac0e..d536a40c 100644 --- a/app/models/spree/flow_io_variant_decorator.rb +++ b/app/models/spree/flow_io_variant_decorator.rb @@ -9,11 +9,6 @@ def self.prepended(base) base.serialize :meta, ActiveRecord::Coders::JSON.new(symbolize_keys: true) base.store_accessor :meta, :flow_data - - # after every save we sync product we generate sh1 checksums to update only when change happend - base.after_save :sync_product_to_flow - - base.after_save :sync_classification end def experiences @@ -202,17 +197,6 @@ def flow_import_item(item_hash, experience_key: nil) update_column(:meta, meta.to_json) end - def sync_classification - return unless meta_changed? - - meta_changes = changes['meta'] - old_hs_code = meta_changes[0]&.[]('flow_data')&.[]('hs_code') - new_hs_code = meta_changes[1]&.[]('flow_data')&.[]('hs_code') - return if old_hs_code == new_hs_code - - VariantService.new.update_classification([sku]) - end - Spree::Variant.prepend(self) if Spree::Variant.included_modules.exclude?(self) end end diff --git a/lib/tasks/spree_variant.rake b/lib/tasks/spree_variant.rake index 36509166..a8b65723 100644 --- a/lib/tasks/spree_variant.rake +++ b/lib/tasks/spree_variant.rake @@ -11,8 +11,6 @@ namespace :spree_variant do csv.each do |row| hs_code = row['hs6'] - next if hs_code.blank? - sku = row['item_number'] next not_found << sku unless (variant = Spree::Variant.find_by(sku: row['item_number'])) diff --git a/spec/service/import_items_hs_codes_spec.rb b/spec/service/import_items_hs_codes_spec.rb index fd8933e2..dedd38a4 100644 --- a/spec/service/import_items_hs_codes_spec.rb +++ b/spec/service/import_items_hs_codes_spec.rb @@ -19,5 +19,11 @@ module FlowcommerceSpree variant = Spree::Variant.find_by(sku: hs_code_data.item.number) expect(variant.flow_data['hs_code']).to(eq(hs_code_data.code[0..5])) end + + it 'Calls VariantService#update_classification method' do + expect_any_instance_of(VariantService).to(receive(:update_classification) + .with([hs_code_data.item.number])) + FlowcommerceSpree::ImportItemsHsCodes.run + end end end diff --git a/spec/tasks/spree_variant_spec.rb b/spec/tasks/spree_variant_spec.rb index b28ebce0..0fa8d9a1 100644 --- a/spec/tasks/spree_variant_spec.rb +++ b/spec/tasks/spree_variant_spec.rb @@ -2,7 +2,6 @@ require 'rails_helper' require 'csv' -# require 'tasks/tasks_helper' describe 'rake products:turn_on_version_for_region', type: :task do let(:variant) { create(:base_variant, :with_flow_data) } @@ -29,14 +28,9 @@ expect(variant.reload.flow_data['hs_code']).to(eq(hs_code)) end - context 'when csv does not have hs_code from flow' do - let(:stubed_csv_content) { [variant.sku, '', variant.product.id, variant.product.name] } - - it 'does not update variant`s flow hs_code' do - expect(variant.flow_data['hs_code']).to(be_blank) - run_codes_rake_task - expect(variant.reload.flow_data['hs_code']).to(be_blank) - end + it 'Calls VariantService#update_classification method' do + expect_any_instance_of(VariantService).to(receive(:update_classification).with([variant.sku])) + run_codes_rake_task end end end From cea6ef45992787b4ed8ca940e18f5dc647c0d816 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 22 Mar 2021 18:59:37 -0300 Subject: [PATCH 06/10] [DL-82] Adding small code improvements for Flow HS code handling --- app/models/spree/flow_io_variant_decorator.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/models/spree/flow_io_variant_decorator.rb b/app/models/spree/flow_io_variant_decorator.rb index d536a40c..e931188d 100644 --- a/app/models/spree/flow_io_variant_decorator.rb +++ b/app/models/spree/flow_io_variant_decorator.rb @@ -9,6 +9,9 @@ def self.prepended(base) base.serialize :meta, ActiveRecord::Coders::JSON.new(symbolize_keys: true) base.store_accessor :meta, :flow_data + + # after every save we sync product we generate sh1 checksums to update only when change happend + base.after_save :sync_product_to_flow end def experiences From 0fd667cad83d0b44a20b2119f7a3cbe1f20bc6c1 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 23 Mar 2021 10:40:28 -0300 Subject: [PATCH 07/10] [DL-82] Slightly change in method name to make it more undertandable and adding errors count to Flow HS code importing methods --- .../import_items_hs_codes.rb | 34 +++++++++++-------- lib/tasks/spree_variant.rake | 26 +++++++++----- spec/dummy/app/services/variant_service.rb | 2 +- spec/service/import_items_hs_codes_spec.rb | 4 +-- spec/tasks/spree_variant_spec.rb | 4 +-- 5 files changed, 41 insertions(+), 29 deletions(-) diff --git a/app/services/flowcommerce_spree/import_items_hs_codes.rb b/app/services/flowcommerce_spree/import_items_hs_codes.rb index 774ce3c3..68c0fa45 100644 --- a/app/services/flowcommerce_spree/import_items_hs_codes.rb +++ b/app/services/flowcommerce_spree/import_items_hs_codes.rb @@ -8,10 +8,11 @@ def self.run(client: FlowcommerceSpree.client, organization: ORGANIZATION) end def run # rubocop:disable Metrics/MethodLength, Metrics/AbcSize - page_size = 100 - offset = 0 - items = [] - updated = [] + page_size = 100 + offset = 0 + items = [] + updated = [] + with_errors = [] total = 0 while offset == 0 || items.length != 0 @@ -30,22 +31,25 @@ def run # rubocop:disable Metrics/MethodLength, Metrics/AbcSize items.group_by { |hs_code| hs_code.item.number }.each do |item| total += 1 + begin + variant_sku = item.first + next unless (variant = Spree::Variant.find_by(sku: variant_sku)) - variant_sku = item.first - next unless (variant = Spree::Variant.find_by(sku: variant_sku)) - - hs_code_data_list = item.last - hs_code = hs_code_data_list&.first&.code&.[](0..5) - variant.flow_data ||= {} - variant.flow_data['hs_code'] = hs_code - variant.update_column(:meta, variant.meta.to_json) - log_str << "#{variant.sku}, " - updated << variant.sku + hs_code_data_list = item.last + hs_code = hs_code_data_list&.first&.code&.[](0..5) + variant.flow_data ||= {} + variant.flow_data['hs_code'] = hs_code + variant.update_column(:meta, variant.meta.to_json) + log_str << "#{variant.sku}, " + updated << variant.sku + rescue StandardError + with_errors = variant.sku + end end @logger.info log_str end - VariantService.new.update_classification(updated) + VariantService.new.update_flow_classification(updated) @logger.info "\nData for #{total.to_s.green} products was imported." end diff --git a/lib/tasks/spree_variant.rake b/lib/tasks/spree_variant.rake index a8b65723..acc4d085 100644 --- a/lib/tasks/spree_variant.rake +++ b/lib/tasks/spree_variant.rake @@ -8,23 +8,31 @@ namespace :spree_variant do not_found = [] updated = [] + with_errors = [] csv.each do |row| - hs_code = row['hs6'] - sku = row['item_number'] - next not_found << sku unless (variant = Spree::Variant.find_by(sku: row['item_number'])) - - variant.flow_data ||= {} - variant.flow_data['hs_code'] = hs_code - variant.update_column(:meta, variant.meta.to_json) - updated << sku + begin + hs_code = row['hs6'] + sku = row['item_number'] + next not_found << sku unless (variant = Spree::Variant.find_by(sku: row['item_number'])) + + variant.flow_data ||= {} + variant.flow_data['hs_code'] = hs_code + variant.update_column(:meta, variant.meta.to_json) + updated << sku + rescue StandardError + with_errors << sku + end end - VariantService.new.update_classification(updated) + VariantService.new.update_flow_classification(updated) puts "\n#{Time.zone.now} | Not found in the DB #{not_found.size}." puts not_found.inspect + puts "\n#{Time.zone.now} | Unexpected errors while updating #{with_errors.size}." + puts with_errors.inspect + puts "\n#{Time.zone.now} | Updated #{updated.size}." puts "Updated #{updated} variants." end diff --git a/spec/dummy/app/services/variant_service.rb b/spec/dummy/app/services/variant_service.rb index 9c1bac91..25e2edd4 100644 --- a/spec/dummy/app/services/variant_service.rb +++ b/spec/dummy/app/services/variant_service.rb @@ -7,5 +7,5 @@ def initialize(variant = nil) @variant = variant end - def update_classification(variant_skus = []); end + def update_flow_classification(variant_skus = []); end end diff --git a/spec/service/import_items_hs_codes_spec.rb b/spec/service/import_items_hs_codes_spec.rb index dedd38a4..8d00b070 100644 --- a/spec/service/import_items_hs_codes_spec.rb +++ b/spec/service/import_items_hs_codes_spec.rb @@ -20,8 +20,8 @@ module FlowcommerceSpree expect(variant.flow_data['hs_code']).to(eq(hs_code_data.code[0..5])) end - it 'Calls VariantService#update_classification method' do - expect_any_instance_of(VariantService).to(receive(:update_classification) + it 'Calls VariantService#update_flow_classification method' do + expect_any_instance_of(VariantService).to(receive(:update_flow_classification) .with([hs_code_data.item.number])) FlowcommerceSpree::ImportItemsHsCodes.run end diff --git a/spec/tasks/spree_variant_spec.rb b/spec/tasks/spree_variant_spec.rb index 0fa8d9a1..bcae8c50 100644 --- a/spec/tasks/spree_variant_spec.rb +++ b/spec/tasks/spree_variant_spec.rb @@ -28,8 +28,8 @@ expect(variant.reload.flow_data['hs_code']).to(eq(hs_code)) end - it 'Calls VariantService#update_classification method' do - expect_any_instance_of(VariantService).to(receive(:update_classification).with([variant.sku])) + it 'Calls VariantService#update_flow_classification method' do + expect_any_instance_of(VariantService).to(receive(:update_flow_classification).with([variant.sku])) run_codes_rake_task end end From ce179bd99c0d5a322e4a1ab82b30e182ebcee23e Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 25 Mar 2021 13:30:48 -0300 Subject: [PATCH 08/10] [DL-82] Updating flowcommerce_spree hs_code import scripts --- lib/tasks/spree_variant.rake | 2 +- spec/tasks/spree_variant_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/tasks/spree_variant.rake b/lib/tasks/spree_variant.rake index acc4d085..709f71a0 100644 --- a/lib/tasks/spree_variant.rake +++ b/lib/tasks/spree_variant.rake @@ -39,6 +39,6 @@ namespace :spree_variant do desc 'Import Flow Hs Codes from Api' task import_flow_hs_code: :environment do - FlowcommerceSpree::ImportItemsHsCodes.run(with_items: true, client: client, refresher: refresher) + FlowcommerceSpree::ImportItemsHsCodes.run end end diff --git a/spec/tasks/spree_variant_spec.rb b/spec/tasks/spree_variant_spec.rb index bcae8c50..3b6de3b8 100644 --- a/spec/tasks/spree_variant_spec.rb +++ b/spec/tasks/spree_variant_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' require 'csv' -describe 'rake products:turn_on_version_for_region', type: :task do +describe 'rake spree_variants', type: :task do let(:variant) { create(:base_variant, :with_flow_data) } describe 'import_flow_hs_code_from_csv' do From ea87a66640e3698c5c8a66f0f1b88a91499b2960 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 25 Mar 2021 17:25:18 -0300 Subject: [PATCH 09/10] [DL-82] Small improvement to avoid updating hs_code from flow when no hs_code is provided within csv --- lib/tasks/spree_variant.rake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/tasks/spree_variant.rake b/lib/tasks/spree_variant.rake index 709f71a0..f67c37fd 100644 --- a/lib/tasks/spree_variant.rake +++ b/lib/tasks/spree_variant.rake @@ -13,6 +13,8 @@ namespace :spree_variant do csv.each do |row| begin hs_code = row['hs6'] + next unless hs_code.present? + sku = row['item_number'] next not_found << sku unless (variant = Spree::Variant.find_by(sku: row['item_number'])) From 74cda06bfa588b5df581623d873e93ec501a63ca Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 26 Mar 2021 10:56:08 -0300 Subject: [PATCH 10/10] [DL-82] Adding small test and message to rake task to import flow hs_code --- lib/tasks/spree_variant.rake | 2 ++ spec/tasks/spree_variant_spec.rb | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/lib/tasks/spree_variant.rake b/lib/tasks/spree_variant.rake index f67c37fd..f7ecce9a 100644 --- a/lib/tasks/spree_variant.rake +++ b/lib/tasks/spree_variant.rake @@ -37,6 +37,8 @@ namespace :spree_variant do puts "\n#{Time.zone.now} | Updated #{updated.size}." puts "Updated #{updated} variants." + + puts '[Important] Review task output to see if all products where properly synchronized with Fulfil.' end desc 'Import Flow Hs Codes from Api' diff --git a/spec/tasks/spree_variant_spec.rb b/spec/tasks/spree_variant_spec.rb index 3b6de3b8..a2ced0fe 100644 --- a/spec/tasks/spree_variant_spec.rb +++ b/spec/tasks/spree_variant_spec.rb @@ -32,5 +32,14 @@ expect_any_instance_of(VariantService).to(receive(:update_flow_classification).with([variant.sku])) run_codes_rake_task end + + context 'when no hs_code is present' do + let(:stubed_csv_content) { [variant.sku, '', variant.product.id, variant.product.name] } + + it 'does not update variant' do + run_codes_rake_task + expect(variant.reload.flow_data['hs_code']).to(be_blank) + end + end end end