Class: Spree::StoreCredit

Inherits:
Base
  • Object
show all
Defined in:
app/models/spree/store_credit.rb

Constant Summary collapse

VOID_ACTION =
'void'.freeze
CANCEL_ACTION =
'cancel'.freeze
CREDIT_ACTION =
'credit'.freeze
CAPTURE_ACTION =
'capture'.freeze
ELIGIBLE_ACTION =
'eligible'.freeze
AUTHORIZE_ACTION =
'authorize'.freeze
ALLOCATION_ACTION =
'allocation'.freeze
DEFAULT_CREATED_BY_EMAIL =
'[email protected]'.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

belongs_to_required_by_default, page, spree_base_scopes

Methods included from Preferences::Preferable

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

Instance Attribute Details

#actionObject

Returns the value of attribute action


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

def action
  @action
end

#action_amountObject

Returns the value of attribute action_amount


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

def action_amount
  @action_amount
end

#action_authorization_codeObject

Returns the value of attribute action_authorization_code


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

def action_authorization_code
  @action_authorization_code
end

#action_originatorObject

Returns the value of attribute action_originator


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

def action_originator
  @action_originator
end

Class Method Details

.default_created_byObject


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

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

Instance Method Details

#actionsObject


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

def actions
  [CAPTURE_ACTION, VOID_ACTION, CREDIT_ACTION]
end

#amount_remainingObject


46
47
48
# File 'app/models/spree/store_credit.rb', line 46

def amount_remaining
  amount - amount_used - amount_authorized
end

#authorize(amount, order_currency, options = {}) ⇒ Object


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

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_payment_method.insufficient_authorized_amount'))
    false
  end
end

#can_capture?(payment) ⇒ Boolean


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

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

#can_credit?(payment) ⇒ Boolean


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

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

#can_void?(payment) ⇒ Boolean


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

def can_void?(payment)
  payment.pending? || (payment.checkout? && !payment.order.completed?)
end

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


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 85

def capture(amount, authorization_code, order_currency, options = {})
  return false unless authorize(amount, order_currency, action_authorization_code: authorization_code)

  if amount <= amount_authorized
    if currency != order_currency
      errors.add(:base, Spree.t('store_credit_payment_method.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 - amount
      )
      authorization_code
    end
  else
    errors.add(:base, Spree.t('store_credit_payment_method.insufficient_authorized_amount'))
    false
  end
end

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


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

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_payment_method.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_payment_method.unable_to_credit', auth_code: authorization_code))
    false
  end
end

#display_amountObject


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

def display_amount
  Spree::Money.new(amount)
end

#display_amount_usedObject


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

def display_amount_used
  Spree::Money.new(amount_used)
end

#generate_authorization_codeObject


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

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

#validate_authorization(amount, order_currency) ⇒ Object


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

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

#void(authorization_code, options = {}) ⇒ Object


109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# 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_payment_method.unable_to_void', auth_code: authorization_code))
    false
  end
end