diff --git a/core/app/models/spree/fulfilment_changer.rb b/core/app/models/spree/fulfilment_changer.rb index 61a4234716f..0884fa14096 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,20 +105,22 @@ 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 remainder + # 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) + end 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 + limit(quantity - backordered_quantity). + update_all(shipment_id: desired_shipment.id, state: :on_hand) end # When we don't track inventory, we can just move the inventory units from one shipment @@ -141,11 +143,27 @@ def handle_stock_counts? current_shipment.order.completed? && current_stock_location != desired_stock_location end - def default_on_hand_quantity + def get_available_quantity + positive_stock = -> (shipment) do + on_hand = shipment.stock_location.count_on_hand(variant) + on_hand.positive? ? on_hand : 0 + end + + if current_stock_location != desired_stock_location + positive_stock.call(desired_shipment) + else + sl_availability = positive_stock.call(current_shipment) + 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