Module: Models::InventoryCommittable

Extended by:
ActiveSupport::Concern
Included in:
LineItem, Order
Defined in:
app/concerns/models/inventory_committable.rb

Overview

Inventory commit/uncommit behavior for orders, quotes, and line items.

Constant Summary collapse

STATES_WITH_NO_EXPIRATION =

States with no expiration.

%i[in_cr_hold crm_back_order pending_release_authorization processing_deliveries in_management_hold pre_pack request_carrier_assignment awaiting_carrier_assignment].freeze

Instance Method Summary collapse

Instance Method Details

#can_be_committed?(expires_on = nil) ⇒ Boolean?

Whether this record's inventory may be committed.

Parameters:

  • expires_on (Date, nil) (defaults to: nil)

    expiration date commits must not already use

Returns:

  • (Boolean, nil)

    true when commitable; nil for unsupported types



27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'app/concerns/models/inventory_committable.rb', line 27

def can_be_committed?(expires_on = nil)
  if instance_of?(Order)
    %w[SO TO MO].include?(order_type) &&
      %w[cart awaiting_deliveries shipped invoiced cancelled fraudulent].exclude?(state)
  elsif instance_of?(Quote)
    state != 'cancelled' &&
      orders.empty?
  elsif instance_of?(LineItem)
    # if there are no commits or any of the commits have a different expiry date
    # and the resource (Order/Quote) can be committed
    inventory_commits.where(expires_on:).empty? && resource.can_be_committed?
  end
end

#can_be_uncommitted?Boolean?

Whether this record has inventory commits that may be reversed.

Returns:

  • (Boolean, nil)

    true when commits exist; nil for unsupported types



44
45
46
47
48
49
50
# File 'app/concerns/models/inventory_committable.rb', line 44

def can_be_uncommitted?
  if instance_of?(Order) || instance_of?(Quote)
    InventoryCommit.where(line_item_id: line_items.pluck(:id)).any?
  elsif instance_of?(LineItem)
    inventory_commits.any?
  end
end

#commit_line_items(expires_on = nil) ⇒ Boolean?

Commit inventory for this record's line items.

Parameters:

  • expires_on (Date, nil) (defaults to: nil)

    expiration date for the new commits

Returns:

  • (Boolean, nil)

    false when the record cannot be committed,
    otherwise the committer's result



57
58
59
60
61
62
63
64
65
# File 'app/concerns/models/inventory_committable.rb', line 57

def commit_line_items(expires_on = nil)
  return false unless can_be_committed?(expires_on)

  if instance_of?(Order) || instance_of?(Quote)
    Item::InventoryCommitter.crm_commit(line_items, expires_on:)
  elsif instance_of?(LineItem)
    commit_line_item(self, expires_on)
  end
end

#determine_commit_expiration_dateDate?

Compute the expiration date for new inventory commits.

Returns:

  • (Date, nil)

    the line item's own commit expiration date, nil for
    states that never expire, or three working days from today otherwise



17
18
19
20
21
# File 'app/concerns/models/inventory_committable.rb', line 17

def determine_commit_expiration_date
  return itemizable.commit_expiration_date if instance_of?(LineItem)

  STATES_WITH_NO_EXPIRATION.include?(state.to_sym) ? nil : 3.working.days.since(Date.current)
end

#has_committed_line_items?Boolean?

Whether any line items of this record currently have inventory commits.

Returns:

  • (Boolean, nil)

    true when commits exist; nil for unsupported types



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'app/concerns/models/inventory_committable.rb', line 84

def has_committed_line_items?
  if instance_of?(Order) || instance_of?(Quote)
    InventoryCommit.joins(:line_item).merge(line_items).exists?
  elsif instance_of?(LineItem)
    # When inventory_commits is already preloaded (e.g. via includes in a collection
    # render), use the in-memory array to avoid a per-row EXISTS query.
    # The kit_line_item_id branch only applies to kit parent items which are rare,
    # so the occasional miss is acceptable in exchange for eliminating the N+1.
    if inventory_commits.loaded?
      inventory_commits.any?
    else
      InventoryCommit.where('line_item_id = :id or kit_line_item_id = :id', { id: }).any?
    end
  end
end

#uncommit_line_itemsBoolean?

Reverse this record's inventory commits.

Returns:

  • (Boolean, nil)

    false when nothing can be uncommitted,
    otherwise the committer's result



71
72
73
74
75
76
77
78
79
# File 'app/concerns/models/inventory_committable.rb', line 71

def uncommit_line_items
  return false unless can_be_uncommitted?

  if instance_of?(Order) || instance_of?(Quote)
    Item::InventoryCommitter.crm_uncommit(line_items)
  elsif instance_of?(LineItem)
    uncommit_line_item(self)
  end
end