diff --git a/core/db/migrate/20150313201503_copy_shipped_shipments_to_cartons.rb b/core/db/migrate/20150313201503_copy_shipped_shipments_to_cartons.rb deleted file mode 100644 index 2610f9ca6d8..00000000000 --- a/core/db/migrate/20150313201503_copy_shipped_shipments_to_cartons.rb +++ /dev/null @@ -1,12 +0,0 @@ -class CopyShippedShipmentsToCartons < ActiveRecord::Migration[4.2] - # Prevent everything from running in one giant transaction in postrgres. - disable_ddl_transaction! - - def up - Rake::Task["spree:migrations:copy_shipped_shipments_to_cartons:up"].invoke - end - - def down - Rake::Task["spree:migrations:copy_shipped_shipments_to_cartons:down"].invoke - end -end diff --git a/core/lib/tasks/migrations/copy_shipped_shipments_to_cartons.rake b/core/lib/tasks/migrations/copy_shipped_shipments_to_cartons.rake deleted file mode 100644 index e4324758e49..00000000000 --- a/core/lib/tasks/migrations/copy_shipped_shipments_to_cartons.rake +++ /dev/null @@ -1,172 +0,0 @@ -namespace 'spree:migrations:copy_shipped_shipments_to_cartons' do - # This copies data from shipments into cartons from previous versions of - # Spree. - - # Used in the migration CopyShippedShipmentsToCartons and made available as a - # rake task to allow running it a second time after deploying the new code, in - # case some shipment->carton data was missed between the time that the - # migration was run and the application servers were restarted with the new - # code. - - # This task should be safe to run multiple times. - - # We're doing these via SQL because for large stores with lots of shipments - # and lots of inventory units this would take excessively long to do via - # ActiveRecord one at a time. Also, these queries can take a long time for - # large stores so we do them in batches. - - task up: :environment do - bad_shipping_rate = Spree::ShippingRate. - select(:shipment_id). - where(selected: true). - group(:shipment_id). - having("count(0) > 1"). - limit(1).to_a.first - - if bad_shipping_rate - # This would end up generating multiple cartons for a single shipment - raise(<<-TEXT.squish) - Error: You have shipments with more than one 'selected' shipping rate, - such as shipment #{bad_shipping_rate.shipment_id}. This code will not - work correctly. - TEXT - end - - say_with_time 'generating cartons' do - last_id = Spree::Shipment.last.try!(:id) || 0 - - in_batches(last_id: last_id) do |start_id, end_id| - say_with_time "processing shipment #{start_id} to #{end_id}" do - Spree::Carton.connection.execute(<<-SQL.strip_heredoc) - insert into spree_cartons - ( - number, imported_from_shipment_id, stock_location_id, - address_id, shipping_method_id, tracking, shipped_at, - created_at, updated_at - ) - select - -- create the carton number as 'C'+shipment number: - #{db_concat("'C'", 'spree_shipments.number')}, -- number - spree_shipments.id, -- imported_from_shipment_id - spree_shipments.stock_location_id, - spree_orders.ship_address_id, - spree_shipping_rates.shipping_method_id, - spree_shipments.tracking, - spree_shipments.shipped_at, - '#{Time.current.to_s(:db)}', -- created_at - '#{Time.current.to_s(:db)}' -- updated_at - from spree_shipments - left join spree_orders - on spree_orders.id = spree_shipments.order_id - left join spree_shipping_rates - on spree_shipping_rates.shipment_id = spree_shipments.id - and spree_shipping_rates.selected = #{Spree::Carton.connection.quoted_true} - left join spree_inventory_units - on spree_inventory_units.shipment_id = spree_shipments.id - and spree_inventory_units.carton_id is not null - where spree_shipments.shipped_at is not null - -- must have at least one inventory unit - and exists ( - select 1 - from spree_inventory_units iu - where iu.shipment_id = spree_shipments.id - ) - -- if *any* inventory units are connected to cartons then we assume - -- the entire shipment has been either already migrated or handled - -- by the new code - and spree_inventory_units.id is null - and spree_shipments.id >= #{start_id} - and spree_shipments.id <= #{end_id} - SQL - end - end - end - - say_with_time 'linking inventory units to cartons' do - last_id = Spree::InventoryUnit.last.try!(:id) || 0 - - in_batches(last_id: last_id) do |start_id, end_id| - say_with_time "processing inventory units #{start_id} to #{end_id}" do - Spree::InventoryUnit.connection.execute(<<-SQL.strip_heredoc) - update spree_inventory_units - set carton_id = ( - select spree_cartons.id - from spree_shipments - inner join spree_cartons - on spree_cartons.imported_from_shipment_id = spree_shipments.id - where spree_shipments.id = spree_inventory_units.shipment_id - ) - where spree_inventory_units.carton_id is null - and spree_inventory_units.shipment_id is not null - and spree_inventory_units.id >= #{start_id} - and spree_inventory_units.id <= #{end_id} - SQL - end - end - end - end - - task down: :environment do - last_id = Spree::InventoryUnit.last.try!(:id) || 0 - - say_with_time 'unlinking inventory units from cartons' do - in_batches(last_id: last_id) do |start_id, end_id| - say_with_time "processing inventory units #{start_id} to #{end_id}" do - Spree::InventoryUnit.connection.execute(<<-SQL.strip_heredoc) - update spree_inventory_units - set carton_id = null - where carton_id is not null - and exists ( - select 1 - from spree_cartons - where spree_cartons.id = spree_inventory_units.carton_id - and spree_cartons.imported_from_shipment_id is not null - ) - and spree_inventory_units.id >= #{start_id} - and spree_inventory_units.id <= #{end_id} - SQL - end - end - end - - say_with_time "clearing carton imported_from_shipment_ids" do - Spree::Carton.where.not(imported_from_shipment_id: nil).delete_all - end - end - - def db_concat(*args) - case Spree::Shipment.connection.adapter_name - when /mysql/i - "concat(#{args.join(', ')})" - else - args.join(' || ') - end - end - - def say_with_time(message) - say message - ms = Benchmark.ms { yield } - say "(#{ms.round}ms)" - end - - def say(message) - if Rails.env.test? - Rails.logger.info message - else - puts message - end - end - - def in_batches(last_id:) - start_id = 1 - batch_size = 10_000 - - while start_id <= last_id - end_id = start_id + batch_size - 1 - - yield start_id, end_id - - start_id += batch_size - end - end -end diff --git a/core/spec/lib/tasks/migrations/copy_shipped_shipments_to_cartons_spec.rb b/core/spec/lib/tasks/migrations/copy_shipped_shipments_to_cartons_spec.rb deleted file mode 100644 index a481e2b4ea6..00000000000 --- a/core/spec/lib/tasks/migrations/copy_shipped_shipments_to_cartons_spec.rb +++ /dev/null @@ -1,111 +0,0 @@ -require 'rails_helper' - -describe 'spree:migrations:copy_shipped_shipments_to_cartons' do - include_context( - 'rake', - task_name: 'spree:migrations:copy_shipped_shipments_to_cartons:up', - task_path: Spree::Core::Engine.root.join('lib/tasks/migrations/copy_shipped_shipments_to_cartons.rake'), - ) - - describe 'up' do - # should generate a carton - let!(:shipped_shipment) { shipped_order.shipments.first } - # should not generate a carton because it's not shipped - let!(:unshipped_shipment) { create(:shipment) } - # should not generate a carton because it has no inventory units - let!(:shipped_shipment_without_units) do - shipped_order_without_units.shipments.first - end - # should not generate a carton because it already has a carton - let!(:shipped_and_cartonized_shipment) do - shipped_and_cartonized_order.shipments.first - end - - let(:shipped_order) { create(:shipped_order, line_items_count: 1, with_cartons: false) } - - let(:shipped_order_without_units) do - create(:shipped_order, line_items_count: 1) do |order| - order.inventory_units.delete_all - end - end - - let(:shipped_and_cartonized_order) do - create(:order_ready_to_ship, line_items_count: 1).tap do |order| - order.shipping.ship_shipment(order.shipments.first) - end - end - - it 'creates the expected carton' do - expect { - task.invoke - }.to change { Spree::Carton.count }.by(1) - - carton = Spree::Carton.last - - expect(carton).to be_valid - - expect(carton.imported_from_shipment_id).to eq shipped_shipment.id - expect(carton.orders).to eq [shipped_order] - - expect(carton.number).to eq "C#{shipped_shipment.number}" - expect(carton.stock_location).to eq shipped_shipment.stock_location - expect(carton.address).to eq shipped_shipment.order.ship_address - expect(carton.shipping_method).to eq shipped_shipment.shipping_method - expect(carton.tracking).to eq shipped_shipment.tracking - expect(carton.shipped_at).to eq shipped_shipment.shipped_at - expect(carton.created_at).to be_present - expect(carton.updated_at).to be_present - - expect(carton.inventory_units).to match_array shipped_shipment.inventory_units - end - - describe 'when run a second time' do - before do - task.invoke - task.reenable - end - - let!(:second_shipped_shipment) { second_shipped_order.shipments.first } - - let(:second_shipped_order) { create(:shipped_order, line_items_count: 1, with_cartons: false) } - - it 'creates only a carton for the second shipment' do - expect { - task.invoke - }.to change { Spree::Carton.count }.by(1) - - carton = Spree::Carton.last - - expect(carton.imported_from_shipment_id).to eq second_shipped_shipment.id - expect(carton.orders).to eq [second_shipped_order] - end - end - end - - describe 'down' do - let(:task) do - Rake::Task['spree:migrations:copy_shipped_shipments_to_cartons:down'] - end - - let!(:migrated_carton) { create(:carton) } - let!(:preexisting_carton) { create(:carton) } - - let!(:migrated_carton_inventory_units) { migrated_carton.inventory_units.to_a } - let!(:preexisting_carton_inventory_units) { preexisting_carton.inventory_units.to_a } - - before do - migrated_carton.update!(imported_from_shipment_id: migrated_carton.inventory_units.first.shipment_id) - end - - it 'clears out the correct carton' do - expect { - task.invoke - }.to change { Spree::Carton.count }.by(-1) - - expect(Spree::Carton.find_by(id: migrated_carton.id)).to be_nil - - expect(migrated_carton_inventory_units.map(&:reload).map(&:carton_id)).to all(be_nil) - expect(preexisting_carton_inventory_units.map(&:reload).map(&:carton_id)).to all(eq preexisting_carton.id) - end - end -end