Class: Gold::Machine

Inherits:
Object
  • Object
show all
Includes:
Statesman::Machine
Defined in:
app/models/gold/machine.rb

Overview

This is the finite state machine specification that governs how shops may transition from one state to another.

Constant Summary collapse

ACCEPTANCE_STATES =

These are stable states that a store can be in for an indefinite amount of time. Any watchdog task should ignore these states.

%i[affiliate billing done staff].freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.ensure_min_days_in_state(duration_in_days) ⇒ Object

Ensure that a shop has been in a current state for longer than number of days



142
143
144
145
146
147
148
# File 'app/models/gold/machine.rb', line 142

def self.ensure_min_days_in_state(duration_in_days)
  test = proc { |billing|
    billing.state_machine.last_transition.updated_at < duration_in_days.days.ago
  }
  test.define_singleton_method(:to_s) { "After #{duration_in_days} days?" }
  test
end

.ensure_plan_is(query_method) ⇒ Object

Ensure that a shop has a certain type of plan before allowing a transition.



123
124
125
126
127
# File 'app/models/gold/machine.rb', line 123

def self.ensure_plan_is(query_method)
  test = proc { |billing| billing.shopify_plan.send(query_method) }
  test.define_singleton_method(:to_s) { "Billing is #{query_method}?" }
  test
end

.ensure_tier_is_freeObject



135
136
137
138
139
# File 'app/models/gold/machine.rb', line 135

def self.ensure_tier_is_free
  test = proc { |billing| billing.tier&.free? }
  test.define_singleton_method(:to_s) { "Tier is free?" }
  test
end

.ensure_tier_is_not_freeObject



129
130
131
132
133
# File 'app/models/gold/machine.rb', line 129

def self.ensure_tier_is_not_free
  test = proc { |billing| !billing.tier&.free? }
  test.define_singleton_method(:to_s) { "Tier is not free?" }
  test
end

.require_metadata(*properties) ⇒ Object

Ensure that certain metadata properties are set before allowing a transition.



152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'app/models/gold/machine.rb', line 152

def self.(*properties)
  proc do |_, transition|
    properties.each do |property|
      # rubocop:disable Style/Next
      unless transition..key?(property.to_sym) ||
             transition..key?(property.to_s)
        message = "Transition to #{transition.to_state} needs to have #{property} set"
        raise Gold::Exceptions::MetadataMissing, message
      end
      # rubocop:enable Style/Next
    end
  end
end

Instance Method Details

#accepted?Boolean

Whether this state machine is currently in an acceptance state.

Returns:

  • (Boolean)


112
113
114
# File 'app/models/gold/machine.rb', line 112

def accepted?
  ACCEPTANCE_STATES.include?(current_state.to_sym)
end

#current_stateObject



116
117
118
# File 'app/models/gold/machine.rb', line 116

def current_state
  super.to_sym
end

#last_transition_to(*states) ⇒ Object

Like ‘last_transition` but returns the last transition to one of the states provided as arguments. Returns nil if no transitions match.



312
313
314
# File 'app/models/gold/machine.rb', line 312

def last_transition_to(*states)
  history.reverse.find { |t| states.include?(t.to_state.to_sym) }
end

#transition_to_or_stay_in(state, metadata = nil) ⇒ Object

Soft transition only if different from the current state



322
323
324
# File 'app/models/gold/machine.rb', line 322

def transition_to_or_stay_in(state,  = nil)
  current_state == state ? true : transition_to(state, )
end

#transition_to_or_stay_in!(state, metadata = nil) ⇒ Object

Transition only if different from the current state



317
318
319
# File 'app/models/gold/machine.rb', line 317

def transition_to_or_stay_in!(state,  = nil)
  transition_to!(state, ) unless current_state == state
end