Class: Spree::FulfilmentChanger
- Inherits:
-
Object
- Object
- Spree::FulfilmentChanger
- Includes:
- ActiveModel::Validations
- Defined in:
- app/models/spree/fulfilment_changer.rb
Overview
Service class to change fulfilment of inventory units of a particular variant to another shipment. The other shipment would typically have a different shipping method, stock location or delivery date, such that we actually change the planned fulfilment for the items in question.
Can be used to merge shipments by moving all items to another shipment, because this class will delete any empty original shipment.
Instance Attribute Summary collapse
-
#current_shipment ⇒ Spree::Shipment
The shipment we transfer units from.
-
#current_stock_location ⇒ Spree::StockLocation
The stock location of the current shipment.
-
#desired_shipment ⇒ Spree::Shipment
The shipment we want to move units onto.
-
#desired_stock_location ⇒ Spree::StockLocation
The stock location of the desired shipment.
-
#quantity ⇒ Integer
How many units we want to move.
-
#variant ⇒ Spree::Variant
We only move units that represent this variant.
Instance Method Summary collapse
-
#initialize(current_shipment:, desired_shipment:, variant:, quantity:) ⇒ FulfilmentChanger
constructor
A new instance of FulfilmentChanger.
-
#run! ⇒ true, false
Performs the change of fulfilment.
Constructor Details
#initialize(current_shipment:, desired_shipment:, variant:, quantity:) ⇒ FulfilmentChanger
Returns a new instance of FulfilmentChanger.
25 26 27 28 29 30 31 32 |
# File 'app/models/spree/fulfilment_changer.rb', line 25 def initialize(current_shipment:, desired_shipment:, variant:, quantity:) @current_shipment = current_shipment @desired_shipment = desired_shipment @current_stock_location = current_shipment.stock_location @desired_stock_location = desired_shipment.stock_location @variant = variant @quantity = quantity end |
Instance Attribute Details
#current_shipment ⇒ Spree::Shipment
The shipment we transfer units from
19 20 21 |
# File 'app/models/spree/fulfilment_changer.rb', line 19 def current_shipment @current_shipment end |
#current_stock_location ⇒ Spree::StockLocation
The stock location of the current shipment
19 20 21 |
# File 'app/models/spree/fulfilment_changer.rb', line 19 def current_stock_location @current_stock_location end |
#desired_shipment ⇒ Spree::Shipment
The shipment we want to move units onto
19 20 21 |
# File 'app/models/spree/fulfilment_changer.rb', line 19 def desired_shipment @desired_shipment end |
#desired_stock_location ⇒ Spree::StockLocation
The stock location of the desired shipment
19 20 21 |
# File 'app/models/spree/fulfilment_changer.rb', line 19 def desired_stock_location @desired_stock_location end |
#quantity ⇒ Integer
How many units we want to move
19 20 21 |
# File 'app/models/spree/fulfilment_changer.rb', line 19 def quantity @quantity end |
#variant ⇒ Spree::Variant
We only move units that represent this variant
19 20 21 |
# File 'app/models/spree/fulfilment_changer.rb', line 19 def variant @variant end |
Instance Method Details
#run! ⇒ true, false
Performs the change of fulfilment
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'app/models/spree/fulfilment_changer.rb', line 42 def run! # Validations here are intended to catch all necessary prerequisites. # We return early so all checks have happened already. return false if invalid? desired_shipment.save! if desired_shipment.new_record? # Retrieve how many on hand items we can take from desired stock location available_quantity = [desired_shipment.stock_location.count_on_hand(variant), default_on_hand_quantity].max new_on_hand_quantity = [available_quantity, quantity].min unstock_quantity = desired_shipment.stock_location.backorderable?(variant) ? quantity : new_on_hand_quantity ActiveRecord::Base.transaction do if handle_stock_counts? # We only run this query if we need it. current_on_hand_quantity = [current_shipment.inventory_units.pre_shipment.size, quantity].min # Restock things we will not fulfil from the current shipment anymore current_stock_location.restock(variant, current_on_hand_quantity, current_shipment) # Unstock what we will fulfil with the new shipment desired_stock_location.unstock(variant, unstock_quantity, desired_shipment) end # These two statements are the heart of this class. We change the number # of inventory units requested from one shipment to the other. # We order by state, because `'backordered' < 'on_hand'`. current_shipment. inventory_units. where(variant: variant). order(state: :asc). limit(new_on_hand_quantity). update_all(shipment_id: desired_shipment.id, state: :on_hand) current_shipment. inventory_units. where(variant: variant). order(state: :asc). limit(quantity - new_on_hand_quantity). update_all(shipment_id: desired_shipment.id, state: :backordered) end # We modified the inventory units at the database level for speed reasons. # The downside of that is that we need to reload the associations. current_shipment.inventory_units.reload desired_shipment.inventory_units.reload # If the current shipment now has no inventory units left, we won't need it any longer. if current_shipment.inventory_units.length.zero? current_shipment.destroy! else # The current shipment has changed, so we need to make sure that shipping rates # have the correct amount. current_shipment.refresh_rates end # The desired shipment has also change, so we need to make sure shipping rates # are up-to-date, too. desired_shipment.refresh_rates # In order to reflect the changes in the order totals desired_shipment.order.reload desired_shipment.order.recalculate true end |