Skip to content
Draft
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
33 changes: 33 additions & 0 deletions app/decorators/models/solidus_easypost/spree/shipment_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,41 @@ def easypost_postage_label_url
easypost_shipment&.postage_label&.label_url
end

def select_shipping_method(shipping_method)
# Selects the specified shipping method for the shipment.
# This method fetches available shipping rates using the estimator and
# marks the selected shipping rate while deselecting all others.
estimator = ::Spree::Config.stock.estimator_class.new
rates = estimator.shipping_rates(to_package, false)

# Find the rate that matches the provided shipping method
rate = rates.detect { |detected| detected.shipping_method_id == shipping_method.id }

# Mark the selected shipping method as true and deselect others
deselect_other_shipping_rates(rate.id)
rate.update(selected: true)
end

def update_amounts
# NOTE: Reload the shipment to reflect any updates to the selected shipping rate.
# Updates the shipment amounts by reloading the selected shipping rate.
# This ensures that the shipment cost is recalculated based on the latest
# selected shipping rate.
reload

# Call the parent method from solidus_core to ensure proper cost recalculations.
super
end

private

def deselect_other_shipping_rates(selected_rate_id)
# Deselects all shipping rates except the one selected by the user.
# This ensures that only one shipping rate remains marked as selected.
# Update all other shipping rates, setting `selected` to false.
shipping_rates.where.not(id: selected_rate_id).update_all(selected: false)
end

def buy_easypost_rate
# Skip label purchase if tracking information already exists.
return if tracking
Expand Down
20 changes: 16 additions & 4 deletions lib/solidus_easypost/estimator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,22 @@
module SolidusEasypost
class Estimator
def shipping_rates(package, _frontend_only = true)
easypost_rates = ShipmentBuilder.from_package(package).rates.sort_by(&:rate)

shipping_rates = easypost_rates.map { |rate| build_shipping_rate(rate) }.compact
shipping_rates.min_by(&:cost)&.selected = true
# NOTE: The easypost_shipments were being created again when retrieving shipping_rates
# Hence this method has been updated to check if an EasyPost shipment has already been created for the shipment.
# If it exists, it fetches the stored shipping rates instead of creating a new EasyPost shipment.
shipment = package.shipment

if shipment.easypost_shipment
shipping_rates = shipment.shipping_rates
else
easypost_rates = ShipmentBuilder.from_package(package).rates.sort_by(&:rate)

# Build shipping rate objects from EasyPost rates.
shipping_rates = easypost_rates.map { |rate| build_shipping_rate(rate) }.compact

# Automatically select the shipping rate with the lowest cost.
shipping_rates.min_by(&:cost)&.selected = true
end

shipping_rates
end
Expand Down
Loading