Class: Spree::StoreCredit

Inherits:
PaymentSource show all
Extended by:
DisplayMoney
Defined in:
app/models/spree/store_credit.rb

Constant Summary

VOID_ACTION =
'void'
CREDIT_ACTION =
'credit'
CAPTURE_ACTION =
'capture'
ELIGIBLE_ACTION =
'eligible'
AUTHORIZE_ACTION =
'authorize'
ALLOCATION_ACTION =
'allocation'
ADJUSTMENT_ACTION =
'adjustment'
INVALIDATE_ACTION =
'invalidate'
DEFAULT_CREATED_BY_EMAIL =
"spree@example.com"

Instance Attribute Summary (collapse)

Attributes inherited from PaymentSource

#imported

Class Method Summary (collapse)

Instance Method Summary (collapse)

Methods included from DisplayMoney

money_methods

Methods inherited from PaymentSource

#reusable?

Methods inherited from Base

display_includes, #initialize_preference_defaults, page, preference

Methods included from Preferences::Preferable

#default_preferences, #defined_preferences, #get_preference, #has_preference!, #has_preference?, #preference_default, #preference_type, #set_preference

Instance Attribute Details

- (Object) action

Returns the value of attribute action



37
38
39
# File 'app/models/spree/store_credit.rb', line 37

def action
  @action
end

- (Object) action_amount

Returns the value of attribute action_amount



37
38
39
# File 'app/models/spree/store_credit.rb', line 37

def action_amount
  @action_amount
end

- (Object) action_authorization_code

Returns the value of attribute action_authorization_code



37
38
39
# File 'app/models/spree/store_credit.rb', line 37

def action_authorization_code
  @action_authorization_code
end

- (Object) action_originator

Returns the value of attribute action_originator



37
38
39
# File 'app/models/spree/store_credit.rb', line 37

def action_originator
  @action_originator
end

- (Object) update_reason

Returns the value of attribute update_reason



37
38
39
# File 'app/models/spree/store_credit.rb', line 37

def update_reason
  @update_reason
end

Class Method Details

+ (Object) default_created_by



204
205
206
# File 'app/models/spree/store_credit.rb', line 204

def default_created_by
  Spree.user_class.find_by(email: DEFAULT_CREATED_BY_EMAIL)
end

Instance Method Details

- (Object) actions



148
149
150
# File 'app/models/spree/store_credit.rb', line 148

def actions
  [CAPTURE_ACTION, VOID_ACTION, CREDIT_ACTION]
end

- (Object) amount_remaining



42
43
44
45
# File 'app/models/spree/store_credit.rb', line 42

def amount_remaining
  return 0.0.to_d if invalidated?
  amount - amount_used - amount_authorized
end

- (Object) authorize(amount, order_currency, options = {})



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'app/models/spree/store_credit.rb', line 47

def authorize(amount, order_currency, options = {})
  authorization_code = options[:action_authorization_code]
  if authorization_code
    if store_credit_events.find_by(action: AUTHORIZE_ACTION, authorization_code: authorization_code)
      # Don't authorize again on capture
      return true
    end
  else
    authorization_code = generate_authorization_code
  end

  if validate_authorization(amount, order_currency)
    update_attributes!({
      action: AUTHORIZE_ACTION,
      action_amount: amount,
      action_originator: options[:action_originator],
      action_authorization_code: authorization_code,

      amount_authorized: amount_authorized + amount
    })
    authorization_code
  else
    errors.add(:base, Spree.t('store_credit.insufficient_authorized_amount'))
    false
  end
end

- (Boolean) can_capture?(payment)

Returns:

  • (Boolean)


152
153
154
# File 'app/models/spree/store_credit.rb', line 152

def can_capture?(payment)
  payment.pending? || payment.checkout?
end

- (Boolean) can_credit?(payment)

Returns:

  • (Boolean)


160
161
162
# File 'app/models/spree/store_credit.rb', line 160

def can_credit?(payment)
  payment.completed? && payment.credit_allowed > 0
end

- (Boolean) can_void?(payment)

Returns:

  • (Boolean)


156
157
158
# File 'app/models/spree/store_credit.rb', line 156

def can_void?(payment)
  payment.pending?
end

- (Object) capture(amount, authorization_code, order_currency, options = {})



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'app/models/spree/store_credit.rb', line 83

def capture(amount, authorization_code, order_currency, options = {})
  return false unless authorize(amount, order_currency, action_authorization_code: authorization_code)
  auth_event = store_credit_events.find_by!(action: AUTHORIZE_ACTION, authorization_code: authorization_code)

  if amount <= auth_event.amount
    if currency != order_currency
      errors.add(:base, Spree.t('store_credit.currency_mismatch'))
      false
    else
      update_attributes!({
        action: CAPTURE_ACTION,
        action_amount: amount,
        action_originator: options[:action_originator],
        action_authorization_code: authorization_code,

        amount_used: amount_used + amount,
        amount_authorized: amount_authorized - auth_event.amount
      })
      authorization_code
    end
  else
    errors.add(:base, Spree.t('store_credit.insufficient_authorized_amount'))
    false
  end
end

- (Object) credit(amount, authorization_code, order_currency, options = {})



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'app/models/spree/store_credit.rb', line 126

def credit(amount, authorization_code, order_currency, options = {})
  # Find the amount related to this authorization_code in order to add the store credit back
  capture_event = store_credit_events.find_by(action: CAPTURE_ACTION, authorization_code: authorization_code)

  if currency != order_currency # sanity check to make sure the order currency hasn't changed since the auth
    errors.add(:base, Spree.t('store_credit.currency_mismatch'))
    false
  elsif capture_event && amount <= capture_event.amount
    action_attributes = {
      action: CREDIT_ACTION,
      action_amount: amount,
      action_originator: options[:action_originator],
      action_authorization_code: authorization_code
    }
    create_credit_record(amount, action_attributes)
    true
  else
    errors.add(:base, Spree.t('store_credit.unable_to_credit', auth_code: authorization_code))
    false
  end
end

- (Boolean) editable?

Returns:

  • (Boolean)


168
169
170
# File 'app/models/spree/store_credit.rb', line 168

def editable?
  !amount_remaining.zero?
end

- (Object) generate_authorization_code



164
165
166
# File 'app/models/spree/store_credit.rb', line 164

def generate_authorization_code
  "#{id}-SC-#{Time.current.utc.strftime('%Y%m%d%H%M%S%6N')}"
end

- (Object) invalidate(reason, user_performing_invalidation)



190
191
192
193
194
195
196
197
198
199
200
201
# File 'app/models/spree/store_credit.rb', line 190

def invalidate(reason, user_performing_invalidation)
  if invalidateable?
    self.action = INVALIDATE_ACTION
    self.update_reason = reason
    self.action_originator = user_performing_invalidation
    self.invalidated_at = Time.current
    save
  else
    errors.add(:invalidated_at, Spree.t("store_credit.errors.cannot_invalidate_uncaptured_authorization"))
    return false
  end
end

- (Boolean) invalidateable?

Returns:

  • (Boolean)


172
173
174
# File 'app/models/spree/store_credit.rb', line 172

def invalidateable?
  !invalidated? && amount_authorized.zero?
end

- (Boolean) invalidated?

Returns:

  • (Boolean)


176
177
178
# File 'app/models/spree/store_credit.rb', line 176

def invalidated?
  !!invalidated_at
end

- (Object) update_amount(amount, reason, user_performing_update)



180
181
182
183
184
185
186
187
188
# File 'app/models/spree/store_credit.rb', line 180

def update_amount(amount, reason, user_performing_update)
  previous_amount = self.amount
  self.amount = amount
  self.action_amount = self.amount - previous_amount
  self.action = ADJUSTMENT_ACTION
  self.update_reason = reason
  self.action_originator = user_performing_update
  save
end

- (Object) validate_authorization(amount, order_currency)



74
75
76
77
78
79
80
81
# File 'app/models/spree/store_credit.rb', line 74

def validate_authorization(amount, order_currency)
  if amount_remaining.to_d < amount.to_d
    errors.add(:base, Spree.t('store_credit.insufficient_funds'))
  elsif currency != order_currency
    errors.add(:base, Spree.t('store_credit.currency_mismatch'))
  end
  errors.blank?
end

- (Object) void(authorization_code, options = {})



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'app/models/spree/store_credit.rb', line 109

def void(authorization_code, options = {})
  if auth_event = store_credit_events.find_by(action: AUTHORIZE_ACTION, authorization_code: authorization_code)
    update_attributes!({
      action: VOID_ACTION,
      action_amount: auth_event.amount,
      action_authorization_code: authorization_code,
      action_originator: options[:action_originator],

      amount_authorized: amount_authorized - auth_event.amount
    })
    true
  else
    errors.add(:base, Spree.t('store_credit.unable_to_void', auth_code: authorization_code))
    false
  end
end