diff --git a/app/models/concerns/csv_uploader.rb b/app/models/concerns/csv_uploader.rb new file mode 100644 index 00000000..6f4b8f51 --- /dev/null +++ b/app/models/concerns/csv_uploader.rb @@ -0,0 +1,44 @@ +# 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.upload_csv(file_path, title, rows_content) + DIRECTORY.files.create( + key: file_path, + body: create_csv(title, rows_content), + public: false + ) + end + + def self.download_url(file_path, filename) + DIRECTORY.files.head(file_path).url( + Time.now.to_i + 18_000, + query: { "response-content-disposition": "attachment; filename=#{filename}.csv" } + ) + end + + def self.create_csv(title, rows_content) + CSV.generate do |csv| + csv << Array(title) + rows_content.each do |row_content| + csv << Array(row_content) + end + end + end + private_class_method :method + + def self.file_csv?(file) + ['text/csv', 'application/vnd.ms-excel'].include?(file.content_type) && + File.extname(file.original_filename.downcase) == '.csv' + end + + def upload(base_file_path) + CSVUploader.upload_csv("#{base_file_path}/#{@filename}", @file_content[0], @file_content[1..-1]) + @filename + end +end 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