diff --git a/core/app/models/spree/fulfilment_changer.rb b/core/app/models/spree/fulfilment_changer.rb index 61a4234716..1178c08f8e 100644 --- a/core/app/models/spree/fulfilment_changer.rb +++ b/core/app/models/spree/fulfilment_changer.rb @@ -86,9 +86,9 @@ def run! # we can take from the desired location, we could end up with some items being backordered. def run_tracking_inventory # 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 - + available_quantity = get_available_quantity new_on_hand_quantity = [available_quantity, quantity].min + backordered_quantity = get_backordered_quantity(available_quantity, new_on_hand_quantity) unstock_quantity = desired_shipment.stock_location.backorderable?(variant) ? quantity : new_on_hand_quantity ActiveRecord::Base.transaction do @@ -105,19 +105,21 @@ def run_tracking_inventory # 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'`. + # We start to move the new actual backordered quantity, so the remaining + # quantity can be set to on_hand state. 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) + limit(backordered_quantity). + update_all(shipment_id: desired_shipment.id, state: :backordered) 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) + limit(quantity - backordered_quantity). + update_all(shipment_id: desired_shipment.id, state: :on_hand) end end @@ -141,11 +143,22 @@ def handle_stock_counts? current_shipment.order.completed? && current_stock_location != desired_stock_location end - def default_on_hand_quantity + def get_available_quantity + if current_stock_location != desired_stock_location + desired_location_quantifier.positive_stock + else + sl_availability = current_location_quantifier.positive_stock + shipment_availability = current_shipment.inventory_units.where(variant: variant).on_hand.count + sl_availability + shipment_availability + end + end + + def get_backordered_quantity(available_quantity, new_on_hand_quantity) if current_stock_location != desired_stock_location - 0 + quantity - new_on_hand_quantity else - current_shipment.inventory_units.where(variant: variant).on_hand.count + shipment_quantity = current_shipment.inventory_units.where(variant: variant).size + shipment_quantity - available_quantity end end @@ -156,11 +169,19 @@ def current_shipment_not_already_shipped end def enough_stock_at_desired_location - unless Spree::Stock::Quantifier.new(variant, desired_stock_location).can_supply?(quantity) + unless desired_location_quantifier.can_supply?(quantity) errors.add(:desired_shipment, :not_enough_stock_at_desired_location) end end + def desired_location_quantifier + @desired_location_quantifier ||= Spree::Stock::Quantifier.new(variant, desired_stock_location) + end + + def current_location_quantifier + @current_location_quantifier ||= Spree::Stock::Quantifier.new(variant, current_stock_location) + end + def desired_shipment_different_from_current if desired_shipment.id == current_shipment.id errors.add(:desired_shipment, :can_not_transfer_within_same_shipment)