Cache result of insufficient_stock_lines so that it is not called for every single line item rendered on the cart page
Delete all inventory units (rather than destroy)

When a shipment was previously destroyed, it would call destroy on each InventoryUnit object. This took a long time if there were a lot of inventory units. There's no need to call destroy, as there's no callbacks in this model for destroy. All shipment needs to do is *DELETE ALL* its inventory units, and so this is what's going to happen now.
Only call update_order + update_inventory callbacks for LineItem if is destroyed or changed
Delete all shipping adjustments immediately prior to deleting all shipments in Order#create_proposed_shipments

What would happen before is that each shipment would find its adjustments and call destroy on them. We don't necessarily care about all that happening because once the new adjustments have been created then the order will be updated correctly.
When a shipment is destroyed, delete all shipping rates in one query, rather than 1 query per shipping rate
Check if a stock location has any of a variant in stock by using an exists? query, which is faster than Ruby
Handle 404 responses from alerts.spreecommerce.com

Fixes #3716