Class: SpreeLoyalty::Accrual

Inherits:
Object
  • Object
show all
Defined in:
app/services/spree_loyalty/accrual.rb

Overview

Awards loyalty points for a completed order. Guest checkouts (no order.user) don't earn — loyalty requires an account, same reasoning Square Loyalty itself uses (it identifies customers by phone number to accrue points; an anonymous sale earns nothing there either). No retroactive guest-to-account linking in this version — a guest who creates an account later doesn't get past orders' points backfilled.

Points accrue on order.item_total, not order.total — a restaurant loyalty program crediting points for the DoorDash delivery fee would be an unstated, arguably wrong default; this makes the choice explicit.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.callObject



13
# File 'app/services/spree_loyalty/accrual.rb', line 13

def self.call(...) = new.call(...)

Instance Method Details

#call(order) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'app/services/spree_loyalty/accrual.rb', line 15

def call(order)
  return if order.user.blank?

  points = (order.item_total * SpreeLoyalty::Config.points_per_dollar).floor
  return unless points.positive?

   = SpreeLoyalty::Account.find_or_create_by!(user: order.user, store: order.store)

  SpreeLoyalty::Account.transaction do
    .transactions.create!(
      points: points,
      kind: SpreeLoyalty::Transaction::EARNED,
      source: order
    )
    .update!(
      points_balance: .points_balance + points,
      lifetime_points_earned: .lifetime_points_earned + points
    )
  end

  
end