Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pull] main from solidusio:main #409

Merged
merged 14 commits into from
May 23, 2024
Merged
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
2 changes: 1 addition & 1 deletion .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,7 @@ Style/OptionalBooleanParameter:
- "core/app/mailers/spree/reimbursement_mailer.rb"
- "core/app/models/concerns/spree/user_address_book.rb"
- "core/app/models/spree/order.rb"
- "core/app/models/spree/order_contents.rb"
- "core/app/models/spree/simple_order_contents.rb"
- "core/app/models/spree/stock/estimator.rb"

# Offense count: 4
Expand Down
9 changes: 2 additions & 7 deletions core/app/models/spree/order.rb
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ def empty!
line_items.destroy_all
adjustments.destroy_all
shipments.destroy_all
order_promotions.destroy_all
Spree::Bus.publish :order_emptied, order: self

recalculate
end
Expand Down Expand Up @@ -508,11 +508,6 @@ def create_shipments_for_line_item(line_item)
end
end

def apply_shipping_promotions
Spree::Config.promotions.shipping_promotion_handler_class.new(self).activate
recalculate
end

# Clean shipments and make order back to address state (or to whatever state
# is set by restart_checkout_flow in case of state machine modifications)
def check_shipments_and_restart_checkout
Expand Down Expand Up @@ -799,7 +794,7 @@ def ensure_inventory_units
end

def ensure_promotions_eligible
Spree::Config.promotions.promotion_adjuster_class.new(self).call
Spree::Config.promotions.order_adjuster_class.new(self).call

if promo_total_changed?
restart_checkout_flow
Expand Down
101 changes: 5 additions & 96 deletions core/app/models/spree/order_contents.rb
Original file line number Diff line number Diff line change
@@ -1,39 +1,9 @@
# frozen_string_literal: true

module Spree
class OrderContents
attr_accessor :order

def initialize(order)
@order = order
end

# Add a line items to the order if there is inventory to do so
# and populate Promotions
#
# @param [Spree::Variant] variant The variant the line_item should
# be associated with
# @param [Integer] quantity The line_item quantity
# @param [Hash] options Options for the adding proccess
# Valid options:
# shipment: [Spree::Shipment] LineItem target shipment
#
# @return [Spree::LineItem]
def add(variant, quantity = 1, options = {})
line_item = add_to_line_item(variant, quantity, options)
after_add_or_remove(line_item, options)
end

def remove(variant, quantity = 1, options = {})
line_item = remove_from_line_item(variant, quantity, options)
after_add_or_remove(line_item, options)
end

def remove_line_item(line_item, options = {})
order.line_items.destroy(line_item)
after_add_or_remove(line_item, options)
end

class OrderContents < Spree::SimpleOrderContents
# Updates the order's line items with the params passed in.
# Also runs the PromotionHandler::Cart.
def update_cart(params)
if order.update(params)
unless order.completed?
Expand All @@ -43,7 +13,7 @@ def update_cart(params)
# promotion rules would not be triggered.
reload_totals
order.check_shipments_and_restart_checkout
PromotionHandler::Cart.new(order).activate
::Spree::PromotionHandler::Cart.new(order).activate
end
reload_totals
true
Expand All @@ -52,76 +22,15 @@ def update_cart(params)
end
end

def advance
while @order.next; end
end

def approve(user: nil, name: nil)
if user.blank? && name.blank?
raise ArgumentError, 'user or name must be specified'
end

order.update!(
approver: user,
approver_name: name,
approved_at: Time.current
)
end

private

def after_add_or_remove(line_item, options = {})
reload_totals
shipment = options[:shipment]
shipment.present? ? shipment.update_amounts : order.check_shipments_and_restart_checkout
PromotionHandler::Cart.new(order, line_item).activate
::Spree::PromotionHandler::Cart.new(order, line_item).activate
reload_totals
line_item
end

def reload_totals
@order.recalculate
end

def add_to_line_item(variant, quantity, options = {})
line_item = grab_line_item_by_variant(variant, false, options)

line_item ||= order.line_items.new(
quantity: 0,
variant: variant,
adjustments: [],
)

line_item.quantity += quantity.to_i
line_item.options = ActionController::Parameters.new(options).permit(PermittedAttributes.line_item_attributes).to_h

line_item.target_shipment = options[:shipment]
line_item.save!
line_item
end

def remove_from_line_item(variant, quantity, options = {})
line_item = grab_line_item_by_variant(variant, true, options)
line_item.quantity -= quantity
line_item.target_shipment = options[:shipment]

if line_item.quantity <= 0
order.line_items.destroy(line_item)
else
line_item.save!
end

line_item
end

def grab_line_item_by_variant(variant, raise_error = false, options = {})
line_item = order.find_line_item_by_variant(variant, options)

if !line_item.present? && raise_error
raise ActiveRecord::RecordNotFound, "Line item not found for variant #{variant.sku}"
end

line_item
end
end
end
2 changes: 1 addition & 1 deletion core/app/models/spree/order_updater.rb
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ def log_state_change(name)
end

def update_promotions
Spree::Config.promotions.promotion_adjuster_class.new(order).call
Spree::Config.promotions.order_adjuster_class.new(order).call
end

def update_taxes
Expand Down
120 changes: 120 additions & 0 deletions core/app/models/spree/simple_order_contents.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# frozen_string_literal: true

module Spree
class SimpleOrderContents
attr_accessor :order

def initialize(order)
@order = order
end

# Add a line items to the order if there is inventory to do so
# and populate Promotions
#
# @param [Spree::Variant] variant The variant the line_item should
# be associated with
# @param [Integer] quantity The line_item quantity
# @param [Hash] options Options for the adding proccess
# Valid options:
# shipment: [Spree::Shipment] LineItem target shipment
#
# @return [Spree::LineItem]
def add(variant, quantity = 1, options = {})
line_item = add_to_line_item(variant, quantity, options)
after_add_or_remove(line_item, options)
end

def remove(variant, quantity = 1, options = {})
line_item = remove_from_line_item(variant, quantity, options)
after_add_or_remove(line_item, options)
end

def remove_line_item(line_item, options = {})
order.line_items.destroy(line_item)
after_add_or_remove(line_item, options)
end

def update_cart(params)
if order.update(params)
unless order.completed?
order.line_items = order.line_items.select { |li| li.quantity > 0 }
order.check_shipments_and_restart_checkout
end
reload_totals
true
else
false
end
end

def advance
while @order.next; end
end

def approve(user: nil, name: nil)
if user.blank? && name.blank?
raise ArgumentError, 'user or name must be specified'
end

order.update!(
approver: user,
approver_name: name,
approved_at: Time.current
)
end

private

def after_add_or_remove(line_item, options = {})
shipment = options[:shipment]
shipment.present? ? shipment.update_amounts : order.check_shipments_and_restart_checkout
reload_totals
line_item
end

def reload_totals
@order.recalculate
end

def add_to_line_item(variant, quantity, options = {})
line_item = grab_line_item_by_variant(variant, false, options)

line_item ||= order.line_items.new(
quantity: 0,
variant: variant,
adjustments: []
)

line_item.quantity += quantity.to_i
line_item.options = ActionController::Parameters.new(options).permit(PermittedAttributes.line_item_attributes).to_h

line_item.target_shipment = options[:shipment]
line_item.save!
line_item
end

def remove_from_line_item(variant, quantity, options = {})
line_item = grab_line_item_by_variant(variant, true, options)
line_item.quantity -= quantity
line_item.target_shipment = options[:shipment]

if line_item.quantity <= 0
order.line_items.destroy(line_item)
else
line_item.save!
end

line_item
end

def grab_line_item_by_variant(variant, raise_error = false, options = {})
line_item = order.find_line_item_by_variant(variant, options)

if line_item.blank? && raise_error
raise ActiveRecord::RecordNotFound, "Line item not found for variant #{variant.sku}"
end

line_item
end
end
end
16 changes: 11 additions & 5 deletions core/lib/spree/app_configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -600,15 +600,21 @@ def promotions
class << self
private

def promotions_deprecation_message(method)
def promotions_deprecation_message(method, new_method_name = nil)
"The `Spree::Config.#{method}` preference is deprecated and will be removed in Solidus 5.0. " \
"Use `Spree::Config.promotions.#{method}` instead"
"Use `Spree::Config.promotions.#{new_method_name || method}` instead"
end
end

delegate :promotion_adjuster_class, :promotion_adjuster_class=, to: :promotions
deprecate promotion_adjuster_class: promotions_deprecation_message("promotion_adjuster_class"), deprecator: Spree.deprecator
deprecate "promotion_adjuster_class=": promotions_deprecation_message("promotion_adjuster_class="), deprecator: Spree.deprecator
def promotion_adjuster_class
promotions.order_adjuster_class
end

def promotion_adjuster_class=(klass)
promotions.order_adjuster_class = klass
end
deprecate promotion_adjuster_class: promotions_deprecation_message("promotion_adjuster_class", "order_adjuster_class"), deprecator: Spree.deprecator
deprecate "promotion_adjuster_class=": promotions_deprecation_message("promotion_adjuster_class=", "order_adjuster_class="), deprecator: Spree.deprecator

delegate :promotion_chooser_class, :promotion_chooser_class=, to: :promotions
deprecate promotion_chooser_class: promotions_deprecation_message("promotion_chooser_class"), deprecator: Spree.deprecator
Expand Down
1 change: 1 addition & 0 deletions core/lib/spree/core/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class Engine < ::Rails::Engine
Spree::Bus.clear

%i[
order_emptied
order_finalized
order_recalculated
reimbursement_reimbursed
Expand Down
6 changes: 4 additions & 2 deletions core/lib/spree/core/null_promotion_configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
module Spree
module Core
class NullPromotionConfiguration < Spree::Preferences::Configuration
# promotion_adjuster_class allows extensions to provide their own Promotion Adjuster
class_name_attribute :promotion_adjuster_class, default: 'Spree::NullPromotionAdjuster'
# order_adjuster_class allows extensions to provide their own Order Adjuster
class_name_attribute :order_adjuster_class, default: 'Spree::NullPromotionAdjuster'

# Allows providing a different coupon code handler.
# @!attribute [rw] coupon_code_handler_class
Expand All @@ -29,6 +29,8 @@ class NullPromotionConfiguration < Spree::Preferences::Configuration
# the standard promotion finder class
# Spree::NullPromotionHandler.
class_name_attribute :shipping_promotion_handler_class, default: 'Spree::NullPromotionHandler'
deprecate :shipping_promotion_handler_class, deprecator: Spree.deprecator
deprecate :shipping_promotion_handler_class=, deprecator: Spree.deprecator

# Allows providing a different promotion advertiser.
# @!attribute [rw] advertiser_class
Expand Down
4 changes: 2 additions & 2 deletions core/lib/spree/core/promotion_configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ class PromotionConfiguration < Spree::Preferences::Configuration
# promotion_chooser_class allows extensions to provide their own PromotionChooser
class_name_attribute :promotion_chooser_class, default: 'Spree::PromotionChooser'

# promotion_adjuster_class allows extensions to provide their own Promotion Adjuster
class_name_attribute :promotion_adjuster_class, default: 'Spree::Promotion::OrderAdjustmentsRecalculator'
# order_adjuster_class allows extensions to provide their own Order Adjuster
class_name_attribute :order_adjuster_class, default: 'Spree::Promotion::OrderAdjustmentsRecalculator'

# promotion_finder_class allows extensions to provide their own Promotion Finder
class_name_attribute :promotion_finder_class, default: 'Spree::PromotionFinder'
Expand Down
1 change: 0 additions & 1 deletion core/lib/spree/core/state_machines/order.rb
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ def define_state_machine!
before_transition to: :delivery, do: :ensure_shipping_address
before_transition to: :delivery, do: :create_proposed_shipments
before_transition to: :delivery, do: :ensure_available_shipping_rates
before_transition from: :delivery, do: :apply_shipping_promotions
end

before_transition to: :resumed, do: :ensure_line_item_variants_are_not_deleted
Expand Down
6 changes: 4 additions & 2 deletions core/spec/lib/spree/core/null_promotion_configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
subject(:config) { described_class.new }

it "uses the null promotion adjuster class by default" do
expect(config.promotion_adjuster_class).to eq Spree::NullPromotionAdjuster
expect(config.order_adjuster_class).to eq Spree::NullPromotionAdjuster
end

it "uses the null coupon code handler class by default" do
Expand All @@ -18,7 +18,9 @@
end

it "uses the null promotion handler as the shipping promo handler" do
expect(config.shipping_promotion_handler_class).to eq Spree::NullPromotionHandler
Spree.deprecator.silence do
expect(config.shipping_promotion_handler_class).to eq Spree::NullPromotionHandler
end
end

it "uses the null promotion advertiser class by default" do
Expand Down
Loading
Loading