Module: Straight::OrderModule::Prependable

Defined in:
lib/straight/order.rb

Overview

If you are defining methods in this module, it means you most likely want to call super() somehwere inside those methods. An example would be the #status= setter. We do our thing, then call super() so that the class this module is prepended to could do its thing. For instance, if we included it into ActiveRecord, then after #status= is executed, it would call ActiveRecord model setter #status=

In short, the idea is to let the class we’re being prepended to do its magic after out methods are finished.

Instance Method Summary collapse

Instance Method Details

#get_transaction_status(reload: false) ⇒ Object



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/straight/order.rb', line 114

def get_transaction_status(reload: false)
  t = transaction(reload: reload)
  
  return STATUSES[:new] if t.nil?
  return STATUSES[:unconfirmed] if status_unconfirmed?(t[:confirmations])

  set_amount_paid(t)
  if t[:total_amount] == amount
    STATUSES[:paid]
  elsif t[:total_amount] < amount
    STATUSES[:underpaid]
  else
    STATUSES[:overpaid]
  end
end

#set_amount_paid(transaction) ⇒ Object



110
111
112
# File 'lib/straight/order.rb', line 110

def set_amount_paid(transaction)
  self.amount_paid = transaction[:total_amount]
end

#status(as_sym: false, reload: false) ⇒ Object

Checks #transaction and returns one of the STATUSES based on the meaning of each status and the contents of transaction If as_sym is set to true, then each status is returned as Symbol, otherwise an equivalent Integer from STATUSES is returned.



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/straight/order.rb', line 66

def status(as_sym: false, reload: false)

  if defined?(super)
    begin
      @status = super
    # if no method with arguments found in the class
    # we're prepending to, then let's use a standard getter
    # with no argument.
    rescue ArgumentError
      @status = super()
    end
  end

  # Prohibit status update if the order was paid in some way.
  # This is just a caching workaround so we don't query
  # the blockchain needlessly. The actual safety switch is in the setter.
  if (reload || @status.nil?) && !status_locked?
    self.status = get_transaction_status(reload: reload)
  end

  as_sym ? STATUSES.invert[@status] : @status
end

#status=(new_status) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/straight/order.rb', line 89

def status=(new_status)
  # Prohibit status update if the order was paid in some way,
  # so statuses above 1 are in fact immutable.
  return false if status_locked?

  self.tid = transaction[:tid] if transaction

  # Pay special attention to the order of these statements. If you place
  # the assignment @status = new_status below the callback call,
  # you may get a "Stack level too deep" error if the callback checks
  # for the status and it's nil (therefore, force reload and the cycle continues).
  #
  # The order in which these statements currently are prevents that error, because
  # by the time a callback checks the status it's already set.
  @status_changed = (@status != new_status)
  @old_status     = @status
  @status         = new_status
  gateway.order_status_changed(self) if status_changed?
  super if defined?(super)
end

#status_changed?Boolean

Returns:

  • (Boolean)


138
139
140
# File 'lib/straight/order.rb', line 138

def status_changed?
  @status_changed
end

#status_locked?Boolean

Returns:

  • (Boolean)


134
135
136
# File 'lib/straight/order.rb', line 134

def status_locked?
  @status && @status > 1
end

#status_unconfirmed?(confirmations) ⇒ Boolean

Returns:

  • (Boolean)


130
131
132
# File 'lib/straight/order.rb', line 130

def status_unconfirmed?(confirmations)
  confirmations < gateway.confirmations_required
end