Class: SpreeCmCommissioner::InventoryItems::Reset
- Inherits:
-
Object
- Object
- SpreeCmCommissioner::InventoryItems::Reset
- Extended by:
- ServiceModuleThrowable
- Includes:
- Spree::ServiceModule::Base
- Defined in:
- app/services/spree_cm_commissioner/inventory_items/reset.rb
Instance Method Summary collapse
- #call(inventory_item:) ⇒ Object
- #variant_total_inventory(inventory_item) ⇒ Object
-
#variant_total_on_hold(inventory_item) ⇒ Object
[public_on_hold, locked_on_hold] — SPLIT BY POOL.
- #variant_total_purchases(inventory_item) ⇒ Object
Methods included from ServiceModuleThrowable
Instance Method Details
#call(inventory_item:) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'app/services/spree_cm_commissioner/inventory_items/reset.rb', line 7 def call(inventory_item:) max_capacity = variant_total_inventory(inventory_item) total_purchases = variant_total_purchases(inventory_item) # Everything an operator has taken off public sale, by either mechanism: one ReservedBlock per # seat for seat-selection products, and quantity_locked for everything else. Both must be # subtracted or a reset hands withheld units straight back to the public. # # locked_count is self-healing because the rows ARE the record of what was deducted. # quantity_locked is not — it is a counter with no rows behind it, so a reset preserves it # rather than recomputing it. It is deliberately left out of the update below. total_locked = inventory_item.locked_count + inventory_item.quantity_locked quantity_available = [max_capacity - total_purchases - total_locked, 0].max quantity_on_hold, quantity_locked_on_hold = variant_total_on_hold(inventory_item) updated = inventory_item.update( max_capacity: max_capacity, quantity_available: quantity_available, quantity_on_hold: quantity_on_hold, quantity_locked_on_hold: quantity_locked_on_hold ) return failure(nil, :failed_to_update_inventory_item) unless updated reset_redis_inventory(inventory_item) success(nil) end |
#variant_total_inventory(inventory_item) ⇒ Object
34 35 36 37 38 39 40 41 42 |
# File 'app/services/spree_cm_commissioner/inventory_items/reset.rb', line 34 def variant_total_inventory(inventory_item) # for shipment, total_on_hand is not orignal stock. shipment does subtract the stock. # to get desire result, we need to add to total_purchase. if inventory_item.variant.delivery_required? inventory_item.variant.total_on_hand.to_i + variant_total_purchases(inventory_item) else inventory_item.variant.total_on_hand.to_i end end |
#variant_total_on_hold(inventory_item) ⇒ Object
[public_on_hold, locked_on_hold] — SPLIT BY POOL.
A locked-stock line holds against the locked counter, so counting it here would inflate the public one and under-report public availability: exactly the drift this service exists to correct.
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'app/services/spree_cm_commissioner/inventory_items/reset.rb', line 59 def variant_total_on_hold(inventory_item) active_hold_order_ids = SpreeCmCommissioner::InventoryHold.active_or_payment_locked.pluck(:order_id) return [0, 0] if active_hold_order_ids.empty? scope = Spree::LineItem .where(order_id: active_hold_order_ids) .joins(variant: :inventory_items) .where(cm_inventory_items: { id: inventory_item.id }) if inventory_item.permanent_stock? scope = scope.where('? BETWEEN spree_line_items.from_date AND spree_line_items.to_date', inventory_item.inventory_date) end # Partitioned in Ruby, not SQL. StoreMetadata's coder does JSON.dump on the whole hash, so the # jsonb column holds a JSON *string* rather than an object — `private_metadata ->> 'locked_stock'` # returns NULL for every row. Reset is a maintenance pass over one inventory item, so loading # its held lines is cheap. totals = { false => 0, true => 0 } scope.find_each { |line_item| totals[line_item.locked_stock?] += line_item.quantity } [totals[false], totals[true]] end |
#variant_total_purchases(inventory_item) ⇒ Object
44 45 46 47 48 49 50 51 52 |
# File 'app/services/spree_cm_commissioner/inventory_items/reset.rb', line 44 def variant_total_purchases(inventory_item) scope = inventory_item.variant.line_items.affecting_inventory if inventory_item.permanent_stock? scope.where('? BETWEEN from_date AND to_date', inventory_item.inventory_date).sum(:quantity).to_i else scope.sum(:quantity).to_i end end |