Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions core/app/models/spree/line_item.rb
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,15 @@ def options=(options = {})
end
end

# Recalculate the price using the pricing options for this line item.
# Useful for making sure carts are up-to-date when prices change.
# Will not make changes to completed orders.
#
def recalculate_price
return if order.completed?
self.money_price = variant.price_for_options(pricing_options)&.money
end

def pricing_options
Spree::Config.pricing_options_class.from_line_item(self)
end
Expand Down
7 changes: 7 additions & 0 deletions core/app/models/spree/order_updater.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def initialize(order)
# associations try to save and then in turn try to call +update!+ again.)
def recalculate
order.transaction do
recalculate_line_item_prices
recalculate_item_count
update_shipment_amounts
update_totals
Expand Down Expand Up @@ -240,5 +241,11 @@ def recalculate_item_totals
)
end
end

def recalculate_line_item_prices
if Spree::Config.recalculate_cart_prices
line_items.each(&:recalculate_price)
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ Spree.config do |config|
config.image_attachment_module = 'Spree::Image::ActiveStorageAttachment'
config.taxon_attachment_module = 'Spree::Taxon::ActiveStorageAttachment'

# Uncomment to recalculate cart prices when the cart changes
# config.recalculate_cart_prices = true

# Defaults
# Permission Sets:

Expand Down
4 changes: 4 additions & 0 deletions core/lib/spree/app_configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,10 @@ class AppConfiguration < Preferences::Configuration
# @return [Integer] Products to show per-page in the frontend (default: +12+)
preference :products_per_page, :integer, default: 12

# @!attribute [rw] recalculate_cart_prices
# @return [Boolean] Whether to recalculate cart prices when recalculating (default: +false+)
versioned_preference :recalculate_cart_prices, :boolean, initial_value: false, boundaries: { "5.0.0.alpha" => true }

# @!attribute [rw] require_master_price
# @return [Boolean] Require a price on the master variant of a product (default: +true+)
preference :require_master_price, :boolean, default: true
Expand Down
14 changes: 14 additions & 0 deletions core/spec/lib/spree/app_configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -248,4 +248,18 @@ class DummyClass; end;
expect(prefs[:meta_data_max_value_length]).to eq(256)
end
end

describe "#recalculate_cart_prices" do
subject { prefs[:recalculate_cart_prices] }

it { is_expected.to be false }

context "if solidus version is 5.0" do
before do
prefs.load_defaults "5.0"
end

it { is_expected.to be true }
end
end
end
20 changes: 20 additions & 0 deletions core/spec/models/spree/line_item_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -184,5 +184,25 @@
end
end

describe "#recalculate_price" do
let(:order) { create(:order) }
let(:variant) { create(:variant, price: 14.99) }
let(:line_item) { build(:line_item, order:, variant:, price: 13.39) }

subject { line_item.recalculate_price }

it "updates the price of the line item" do
expect { subject }.to change { line_item.price }.from(13.39).to(14.99)
end

context "if order is completed" do
let(:order) { create(:order, completed_at: 1.hour.ago) }

it "does not update line item prices" do
expect { subject }.not_to change { line_item.price }.from(13.39)
end
end
end

it_behaves_like "customer and admin metadata fields: storage and validation", :line_item
end
33 changes: 33 additions & 0 deletions core/spec/models/spree/order_updater_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,39 @@ module Spree
end
end

describe "price recalculation" do
let(:variant) { create(:variant, price: 98) }
let!(:order) { create(:order_with_line_items, line_items_attributes: [{ variant:, price: 98 }]) }

subject { updater.recalculate }

before do
variant.price = 100
variant.save!
order.reload
end

context "when recalculate_cart_prices is true" do
before do
stub_spree_preferences(recalculate_cart_prices: true)
end

it "sets prices to the currently active price" do
expect { subject }.to change { order.line_items.first.price }.from(98).to(100)
end
end

context "when recalculate_cart_prices is false" do
before do
stub_spree_preferences(recalculate_cart_prices: false)
end

it "does not recalculate prices" do
expect { subject }.not_to change { order.line_items.first.price }.from(98)
end
end
end

context "updating shipment state" do
let(:order) { create :order_with_line_items }

Expand Down
Loading