spree/spree — pull request #5163 by IrvinFan (2014-08-07 21:08:39+00:00)
Title: Correctly fill backorders when there are multiple inventory_units

Steps to reproduce the issue:

1. Place an order that has two inventory units in backordered state.
2. Increase inventory by at least 2 to fullfill the order.

Expect the order is changed to READY. But it's still in BACKORDER. Even worse, it's stuck in that state no matter how many inventory we can increase. It works fine if there is only one inventory unit.

The cause for this is this code https://github.com/spree/spree/blob/2-2-stable/core/app/models/spree/stock_item.rb#L69-L71 where we iterate through inventory units and call fill_backorder on each one. Each unit is transited from backordered to on_hand and trigger call to order.update! https://github.com/spree/spree/blob/2-2-stable/core/app/models/spree/inventory_unit.rb#L24

The problem is that order.update! will eventually check all inventory_units to see if any of them is in backordered state https://github.com/spree/spree/blob/2-2-stable/core/app/models/spree/shipment.rb#L80. After the call fill_backorder on the first unit all other units are loaded in memory as well. Subsequent calls on other units don't have the latest status. That's why this only works when there is one inventory unit.

The fix proposed in this PR is simple. Just reload the inventory unit itself before call order.update!

I understand that eventually this is not needed once https://github.com/spree/spree/pull/4741 is done. This is a quick fix in the meantime for annoying customer issue.