Class: SpreeCmCommissioner::InventoryItems::BulkAdjustQuantitiesOnConvert

Inherits:
Object
  • Object
show all
Extended by:
ServiceModuleThrowable
Includes:
Spree::ServiceModule::Base
Defined in:
app/services/spree_cm_commissioner/inventory_items/bulk_adjust_quantities_on_convert.rb

Overview

DB mirror of InventoryHolds::Convert#convert_hold_redis!: applies the same delta to quantity_on_hold and quantity_available together, under ONE row lock per inventory item. Doing this as two separate jobs (BulkAdjustQuantitiesOnHoldJob + BulkAdjustQuantitiesJob), each locking and saving independently, left a window between the two locks where a reader could see one column updated and the other not yet — the same class of gap that made the Redis side non-atomic. One lock, one update, removes that window on the DB side too.

Instance Method Summary collapse

Methods included from ServiceModuleThrowable

call!

Instance Method Details

#call(inventory_id_and_quantities:, caller_source: nil) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'app/services/spree_cm_commissioner/inventory_items/bulk_adjust_quantities_on_convert.rb', line 13

def call(inventory_id_and_quantities:, caller_source: nil)
  CmAppLogger.log(
    label: "#{self.class.name}#call started",
    data: { caller_source: caller_source, inventory_id_and_quantities: inventory_id_and_quantities }
  )

  ActiveRecord::Base.transaction do
    items_by_id = inventory_items(inventory_id_and_quantities).index_by(&:id)

    grouped_deltas(inventory_id_and_quantities).each do |(inventory_id, locked), quantity|
      inventory_item = items_by_id[inventory_id]
      next if inventory_item.nil?

      adjust_quantities(inventory_item, quantity, caller_source, locked: locked)
    end
  end

  success(nil)
end