diff --git a/app/models/spree/price_decorator.rb b/app/models/spree/price_decorator.rb index 00219eeedd..036daae4de 100644 --- a/app/models/spree/price_decorator.rb +++ b/app/models/spree/price_decorator.rb @@ -1,7 +1,14 @@ module Spree Price.class_eval do + acts_as_paranoid without_default_scope: true + after_save :refresh_products_cache + # Allow prices to access associated soft-deleted variants. + def variant + Spree::Variant.unscoped { super } + end + private def check_price diff --git a/app/models/spree/variant_decorator.rb b/app/models/spree/variant_decorator.rb index 4c6691b65f..83c89122e6 100644 --- a/app/models/spree/variant_decorator.rb +++ b/app/models/spree/variant_decorator.rb @@ -91,6 +91,11 @@ Spree::Variant.class_eval do can_supply?(quantity) end + # Allow variant to access associated soft-deleted prices. + def default_price + Spree::Price.unscoped { super } + end + def price_with_fees(distributor, order_cycle) price + fees_for(distributor, order_cycle) end diff --git a/db/migrate/20190830134723_add_deleted_at_to_spree_prices.rb b/db/migrate/20190830134723_add_deleted_at_to_spree_prices.rb new file mode 100644 index 0000000000..886569dcff --- /dev/null +++ b/db/migrate/20190830134723_add_deleted_at_to_spree_prices.rb @@ -0,0 +1,6 @@ +class AddDeletedAtToSpreePrices < ActiveRecord::Migration + def change + add_column :spree_prices, :deleted_at, :datetime + add_index :spree_prices, :deleted_at + end +end diff --git a/db/schema.rb b/db/schema.rb index 843eb9d18a..db6e9a8ffc 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20190701002454) do +ActiveRecord::Schema.define(:version => 20190830134723) do create_table "adjustment_metadata", :force => true do |t| t.integer "adjustment_id" @@ -649,9 +649,10 @@ ActiveRecord::Schema.define(:version => 20190701002454) do add_index "spree_preferences", ["key"], :name => "index_spree_preferences_on_key", :unique => true create_table "spree_prices", :force => true do |t| - t.integer "variant_id", :null => false - t.decimal "amount", :precision => 8, :scale => 2 - t.string "currency" + t.integer "variant_id", :null => false + t.decimal "amount", :precision => 8, :scale => 2 + t.string "currency" + t.datetime "deleted_at" end add_index "spree_prices", ["variant_id"], :name => "index_spree_prices_on_variant_id" diff --git a/spec/features/consumer/shopping/cart_spec.rb b/spec/features/consumer/shopping/cart_spec.rb index d6a15263ea..138c6de022 100644 --- a/spec/features/consumer/shopping/cart_spec.rb +++ b/spec/features/consumer/shopping/cart_spec.rb @@ -28,6 +28,17 @@ feature "full-page cart", js: true do end end + describe "when a product is soft-deleted" do + it "shows the cart without errors" do + add_product_to_cart order, product_with_tax, quantity: 1 + add_product_to_cart order, product_with_fee, quantity: 2 + product_with_fee.destroy + + visit main_app.cart_path + expect(page).to have_selector '.cart-item-price' + end + end + describe "percentage fees" do let(:percentage_fee) { create(:enterprise_fee, calculator: Calculator::FlatPercentPerItem.new(preferred_flat_percent: 20)) } diff --git a/spec/models/spree/price_spec.rb b/spec/models/spree/price_spec.rb index 5d48afd95b..c44a361fb5 100644 --- a/spec/models/spree/price_spec.rb +++ b/spec/models/spree/price_spec.rb @@ -2,10 +2,10 @@ require 'spec_helper' module Spree describe Price do - describe "callbacks" do - let(:variant) { create(:variant) } - let(:price) { variant.default_price } + let(:variant) { create(:variant) } + let(:price) { variant.default_price } + describe "callbacks" do it "refreshes the products cache on change" do expect(OpenFoodNetwork::ProductsCache).to receive(:variant_changed).with(variant) price.amount = 123 @@ -21,5 +21,15 @@ module Spree expect(OpenFoodNetwork::ProductsCache).to receive(:variant_changed).never end end + + context "when variant is soft-deleted" do + before do + variant.destroy + end + + it "can access the variant" do + expect(price.variant).to eq variant + end + end end end diff --git a/spec/models/variant_override_spec.rb b/spec/models/variant_override_spec.rb index c93a8bd3c7..98f10b5d7f 100644 --- a/spec/models/variant_override_spec.rb +++ b/spec/models/variant_override_spec.rb @@ -128,6 +128,26 @@ describe VariantOverride do end end + describe "delegated price" do + let!(:variant_with_price) { create(:variant, price: 123.45) } + let(:price_object) { variant_with_price.default_price } + + context "when variant is soft-deleted" do + before do + variant_with_price.destroy + end + + it "soft-deletes the price" do + expect(price_object.deleted_at).to_not be_nil + end + + it "can access the soft-deleted price" do + expect(variant_with_price.default_price).to eq price_object + expect(variant_with_price.price).to eq 123.45 + end + end + end + describe "with price" do let(:variant_override) { create(:variant_override, variant: variant, hub: hub, price: 12.34) }