engines/order_management/app/services/order_management/stock/estimator.rb
# frozen_string_literal: true
module OrderManagement
module Stock
class Estimator
attr_reader :order, :currency
def initialize(order)
@order = order
@currency = order.currency
end
def shipping_rates(package, frontend_only = true)
shipping_rates = []
shipping_methods = shipping_methods(package)
return [] unless shipping_methods
shipping_methods.each do |shipping_method|
cost = calculate_cost(shipping_method, package)
shipping_rates << shipping_method.shipping_rates.new(cost:) unless cost.nil?
end
shipping_rates.sort_by! { |r| r.cost || 0 }
unless shipping_rates.empty? || order.manual_shipping_selection
select_first_shipping_method(shipping_rates, frontend_only)
end
shipping_rates
end
def calculate_cost(shipping_method, package)
shipping_method.calculator.compute(package)
end
private
# Sets the first available shipping method to "selected".
# Note: seems like a hangover from Spree, we can probably just remove this at some point.
def select_first_shipping_method(shipping_rates, frontend_only)
if frontend_only
shipping_rates.each do |rate|
if rate.shipping_method.frontend?
rate.selected = true
break
end
end
else
shipping_rates.first.selected = true
end
end
def shipping_methods(package)
shipping_methods = package.shipping_methods
shipping_methods.delete_if { |ship_method| !ship_method.calculator.available?(package) }
shipping_methods.delete_if { |ship_method| !ship_method.delivers_to?(order.ship_address) }
shipping_methods.delete_if { |ship_method|
!(ship_method.calculator.preferences[:currency].nil? ||
ship_method.calculator.preferences[:currency] == currency)
}
shipping_methods
end
end
end
end