Module: Spree::Order::GiftCard

Extended by:
ActiveSupport::Concern
Included in:
Spree::Order
Defined in:
app/models/spree/order/gift_card.rb

Instance Method Summary collapse

Instance Method Details

#apply_gift_card(gift_card) ⇒ Spree::Order

Applies a gift card to the order

Parameters:

Returns:



27
28
29
# File 'app/models/spree/order/gift_card.rb', line 27

def apply_gift_card(gift_card)
  Spree.gift_card_apply_service.call(gift_card: gift_card, order: self)
end

#gift_card_totalDecimal

Returns the total amount of the gift card applied to the order

Returns:

  • (Decimal)


15
16
17
18
19
20
21
22
# File 'app/models/spree/order/gift_card.rb', line 15

def gift_card_total
  return 0.to_d unless gift_card.present?

  store_credit_ids = payments.store_credits.valid.pluck(:source_id)
  store_credits = Spree::StoreCredit.where(id: store_credit_ids, originator: gift_card)

  store_credits.sum(:amount)
end

#recalculate_gift_cardObject

Recalculates the gift card payment amount based on the current order total. Updates the existing payment in place instead of remove + re-apply to avoid creating unnecessary invalid payment records.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'app/models/spree/order/gift_card.rb', line 40

def recalculate_gift_card
  return unless gift_card.present?

  payment = payments.checkout.store_credits.where(source: gift_card.store_credits).first
  return unless payment

  # with_lock acquires a row lock and wraps in a transaction.
  # The entire read-compute-write must be inside the lock to prevent
  # stale amount_remaining from concurrent requests.
  gift_card.with_lock do
    new_amount = [gift_card.amount_remaining + payment.amount, total].min
    next if payment.amount == new_amount

    difference = new_amount - payment.amount
    # Uses update_column to bypass Payment#max_amount validation which
    # can fail during recalculation due to stale in-memory order state.
    # Bounds are enforced via min() above.
    payment.update_column(:amount, new_amount)
    payment.source.update_column(:amount, new_amount)
    gift_card.amount_used += difference
    gift_card.save!
  end
end

#redeem_gift_cardObject



64
65
66
67
68
# File 'app/models/spree/order/gift_card.rb', line 64

def redeem_gift_card
  return unless gift_card.present?

  Spree.gift_card_redeem_service.call(gift_card: gift_card)
end

#remove_gift_cardSpree::Order

Removes a gift card from the order

Returns:



33
34
35
# File 'app/models/spree/order/gift_card.rb', line 33

def remove_gift_card
  Spree.gift_card_remove_service.call(order: self)
end