Skip to content

Commit

Permalink
Merge pull request solidusio#5755 from mamhoff/simple-order-contents
Browse files Browse the repository at this point in the history
Create Spree::SimpleOrderContents
  • Loading branch information
tvdeyen authored May 23, 2024
2 parents 098260d + 6415b7f commit ffbb2d2
Show file tree
Hide file tree
Showing 6 changed files with 483 additions and 356 deletions.
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
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
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
Loading

0 comments on commit ffbb2d2

Please sign in to comment.