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



145
146
147
148
149
150
151
# File 'app/models/gold/machine.rb', line 145

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.



126
127
128
129
130
# File 'app/models/gold/machine.rb', line 126

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



138
139
140
141
142
# File 'app/models/gold/machine.rb', line 138

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



132
133
134
135
136
# File 'app/models/gold/machine.rb', line 132

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.



155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'app/models/gold/machine.rb', line 155

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)


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

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

#current_stateObject



119
120
121
# File 'app/models/gold/machine.rb', line 119

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.



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

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



326
327
328
# File 'app/models/gold/machine.rb', line 326

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



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

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