workflower-1/lib/workflower/acts_as_workflower.rb

113 lines
4.0 KiB
Ruby

require "active_support"
module Workflower
mattr_accessor :workflower_state_column_name, :default_workflow_id
module ActsAsWorkflower
extend ActiveSupport::Concern
module InstanceMethods
# mattr_accessor :workflower_base
attr_accessor :possible_events, :allowed_events, :allowed_transitions, :workflow_transition_event_name, :workflow_transition_flow
def set_initial_state
write_attribute self.class.workflower_state_column_name, workflower_initial_state
end
def workflower_initial_state
workflower_base.set_initial_state
end
def workflower_base
@workflower_base
end
def source_workflow
@source_workflow_instance ||= source.new(self)
@source_workflow_instance.get_workflows_for_workflow_id(workflow_id)
end
def workflower_initializer
@source_workflow_instance ||= source.new(self)
@workflower_base ||= Workflower::Manager.new(self, @source_workflow_instance)
@workflower_base.allowed_transitions.each do |flow|
define_singleton_method flow.trigger_action_name.to_s do
@workflow_transition_event_name = flow.event
@workflow_transition_flow = flow
@workflower_base.process_transition!(flow)
end
define_singleton_method flow.boolean_action_name.to_s do
@workflower_base.transition_possible?(flow)
end
end
@possible_events ||= @workflower_base.events
@allowed_events ||= @workflower_base.allowed_events
@allowed_transitions ||= @workflower_base.allowed_transitions
end
def workflower_uninitializer(reset_source_workflow_instance: false)
@workflower_base.uninitialize
@workflower_base = nil
@source_workflow_instance = nil if reset_source_workflow_instance
@possible_events = nil
@allowed_events = nil
@allowed_transitions = nil
end
def initialize(*)
super
write_attribute :workflow_id, default_workflow_id if workflow_id.blank?
workflower_initializer
end
end
module ClassMethods
def workflower(default_workflow_id:, source:, workflower_state_column_name: "workflow_state", skip_setting_initial_state: false)
raise Workflower::WorkflowerError, "Options can't be blank" if source.blank? || default_workflow_id.blank?
cattr_accessor :source, default: source
cattr_accessor :workflower_state_column_name, default: workflower_state_column_name
cattr_accessor :default_workflow_id, default: default_workflow_id
self.workflower_state_column_name = workflower_state_column_name
self.source = source
self.default_workflow_id = default_workflow_id
# self.validates "#{workflow_model.tableize.singularize}_id", presence: true
before_create :set_initial_state unless skip_setting_initial_state
end
def workflower_abilities(workflow_selector: nil)
# workflow_selector helps dynamic transition selection when we have multiple workflows that needs to change depending on the workflow_selector.
load = source.new(new).get_workflows.values.flatten.uniq unless workflow_selector.present?
load = source.new(workflow_selector.to_sym).get_workflows.values.flatten.uniq if workflow_selector.present?
unless load.blank?
# transitions = load.transitions.where("(metadata->>'roles') IS NOT NULL")
transitions = load.select { |item| item.try(:[], :metadata).try(:key?, :roles) }
roles = transitions.map { |item| item[:metadata][:roles] }.flatten.uniq
roles_hash = {}
roles.each do |role|
roles_hash[role] = transitions.select { |trans| trans[:metadata][:roles].to_a.include?(role) }.map { |item| item[:event] }.uniq
end
roles_hash
end
end
end
def self.included(base)
base.send :include, InstanceMethods
base.extend(ClassMethods)
end
end
end