{"action":"opened","issue":{"url":"https://api.github.com/repos/spree/spree/issues/6469","labels_url":"https://api.github.com/repos/spree/spree/issues/6469/labels{/name}","comments_url":"https://api.github.com/repos/spree/spree/issues/6469/comments","events_url":"https://api.github.com/repos/spree/spree/issues/6469/events","html_url":"https://github.com/spree/spree/issues/6469","id":86122267,"number":6469,"title":"Migrate old Spree::Calculator::PerItem calculators","user":{"login":"mvz","id":10898,"avatar_url":"https://avatars.githubusercontent.com/u/10898?v=3","gravatar_id":"","url":"https://api.github.com/users/mvz","html_url":"https://github.com/mvz","followers_url":"https://api.github.com/users/mvz/followers","following_url":"https://api.github.com/users/mvz/following{/other_user}","gists_url":"https://api.github.com/users/mvz/gists{/gist_id}","starred_url":"https://api.github.com/users/mvz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mvz/subscriptions","organizations_url":"https://api.github.com/users/mvz/orgs","repos_url":"https://api.github.com/users/mvz/repos","events_url":"https://api.github.com/users/mvz/events{/privacy}","received_events_url":"https://api.github.com/users/mvz/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-06-08T10:35:43Z","updated_at":"2015-06-08T10:35:43Z","closed_at":null,"body":"`Spree::Calculator::PerItem` calculators are not adjusted when migrating to Spree 2.2 and up, causing data loss in the promotions, and failures in the `MigrateOldPreferences` migration. I have worked around this in an ad-hoc fashion by adjusting `MigrateOldPreferences` as follows:\r\n\r\n```ruby\r\nclass MigrateOldPreferences < ActiveRecord::Migration\r\n  def up\r\n    adjust_calculators\r\n    migrate_preferences(Spree::Calculator)\r\n    migrate_preferences(Spree::PaymentMethod)\r\n    migrate_preferences(Spree::PromotionRule)\r\n  end\r\n\r\n  def down\r\n  end\r\n\r\n  private\r\n\r\n  def adjust_calculators\r\n    Spree::Calculator.reset_column_information\r\n    Spree::PromotionAction.reset_column_information\r\n\r\n    Spree::Calculator.inheritance_column = :foo\r\n    Spree::PromotionAction.inheritance_column = :foo\r\n\r\n    Spree::Calculator.where(type: 'Spree::Calculator::PerItem').find_each do |record|\r\n      unless record.calculable_type == 'Spree::PromotionAction'\r\n        raise \"Unexpected calculable #{record.calculable_type}\"\r\n      end\r\n\r\n      calculable = record.calculable\r\n\r\n      unless calculable.type == 'Spree::Promotion::Actions::CreateAdjustment'\r\n        raise \"Unexpected calculable #{calculable.type}\"\r\n      end\r\n\r\n      Spree::Calculator.transaction do\r\n        calculable.type = 'Spree::Promotion::Actions::CreateItemAdjustments'\r\n        calculable.save!\r\n\r\n        prefs = Spree::Preference.\r\n          where(\"spree_preference.key like 'spree/calculator/per_item/%/#{record.id}'\")\r\n        prefs.each do |pref|\r\n          pref.key = pref.key.sub(/per_item/, 'flat_rate')\r\n          pref.save!\r\n        end\r\n\r\n        record.type = 'Spree::Calculator::FlatRate'\r\n        record.save!\r\n      end\r\n    end\r\n\r\n    Spree::Calculator.inheritance_column = :type\r\n    Spree::PromotionAction.inheritance_column = :type\r\n  end\r\n\r\n  # This is the same as before\r\n  def migrate_preferences klass\r\n    klass.reset_column_information\r\n    klass.find_each do |record|\r\n      store = Spree::Preferences::ScopedStore.new(record.class.name.underscore, record.id)\r\n      record.defined_preferences.each do |key|\r\n        value = store.fetch(key){}\r\n        record.preferences[key] = value unless value.nil?\r\n      end\r\n      record.save!\r\n    end\r\n  end\r\nend\r\n```\r\n\r\nI'm not creating a PR yet, since I don't know if there are any uses of `Spree::Calculator::PerItem` that my fix doesn't cover."}}