Skip to content

Instantly share code, notes, and snippets.

@linqing
Created December 29, 2011 15:30
Show Gist options
  • Save linqing/1534581 to your computer and use it in GitHub Desktop.
Save linqing/1534581 to your computer and use it in GitHub Desktop.
workflow engine ruby version
class WfEntry < ActiveRecord::Base
has_many :history_steps, :foreign_key => :entry_id, :class_name => 'WfHistoryStep', :dependent => :destroy
has_many :current_steps, :foreign_key => :entry_id, :class_name => 'WfCurrentStep', :dependent => :destroy
has_many :comments, :as => :container, :dependent => :destroy
belongs_to :document, :polymorphic => true
named_scope :todo_of_workflow_name_and_owner, lambda { |workflow_name, owner_name|
{:include => :current_steps,
:conditions =>["name = ? and #{WfCurrentStep.table_name}.owner = ?", workflow_name, owner_name ]}
}
named_scope :draft_of_workflow_name_and_owner, lambda { |workflow_name|
{:include => :current_steps,
:conditions =>["name = ? and #{WfCurrentStep.table_name}.previous_id is ?", workflow_name, nil ]}
}
named_scope :draft_of_workflow_name_and_owner, lambda { |workflow_name|
{:include => :current_steps,
:conditions =>["name = ? and #{WfCurrentStep.table_name}.previous_id is ?", workflow_name, nil ]}
}
named_scope :in_process_of_workflow_name_and_owner, lambda { |workflow_name|
{:include => :current_steps,
:conditions =>["name = ? and #{WfCurrentStep.table_name}.step_id <> ? and #{WfCurrentStep.table_name}.step_id <> ? ", workflow_name, "900", "100" ]}
}
named_scope :completed_of_workflow_name_and_owner, lambda { |workflow_name|
{:include => :current_steps,
:conditions =>["name = ? and #{WfCurrentStep.table_name}.step_id = ?", workflow_name, "900" ]}
}
named_scope :all_of_workflow_name_and_owner, lambda { |workflow_name|
{:include => :current_steps,
:conditions =>["name = ? ", workflow_name ]}
}
named_scope :rejected_of_workflow_name_and_owner, lambda { |workflow_name|
{:include => :current_steps,
:conditions =>["name = ? and #{WfCurrentStep.table_name}.step_id = ?", workflow_name, "800" ]}
}
named_scope :document_with_text, lambda { |text|
{:include => :current_steps,
:conditions =>["exists(select document_id from full_texts where full_texts.document_type = wf_entries.document_type and full_texts.document_id = wf_entries.document_id and full_texts.full_text like ?)", "%#{text}%" ]}
}
def temp_comment
comments.find_by_comment_key("temp") || comments.create(:comment_key => "temp")
end
def subject
'The subject of the document'
end
def initialize_workflow(action_id, params = {})
wf = eval(name).new
action = wf.initial_actions.find { |a| a[:action_id] == action_id }
transition_workflow(action, params)
end
def do_action(action_id, params = { })
action_id = action_id.to_sym
action = config.steps["S#{current_steps[0].step_id}".to_sym][:actions][action_id]
if action[:before_action_script]
return false unless eval(action[:before_action_script])
end
transition_workflow(action, params)
eval(action[:post_action_script]) if action[:post_action_script]
# record comment
if params[:comment]
params[:comment][:author] = User.current.login
comments.create(params[:comment])
temp_comment.destroy
end
return true
end
def transition_workflow(action, params = { })
old_step = self.current_steps.length > 0 ? self.current_steps[0]: nil
history_step = self.history_steps.create!(:entry => self,
:step_id => old_step.step_id,
:owner => old_step.owner,
:caller => User.current.login,
:action_id => action[:action_id].to_s[1..3].to_i,
:start_date => old_step.start_date,
:finish_date => Time.now) if old_step
current_step = self.current_steps.create(:entry => self,
:step_id => action[:to_step_id].to_s[1..10].to_i,
:owner => eval(action[:owner]),
:start_date => Time.now)
current_step.previous = history_step if history_step
current_step.due_date = current_step.step_def[:due_days].to_i.days.from_now if current_step.step_def[:due_days]
current_step.save!
self.current_steps.delete(old_step) if old_step
end
def config
@wf_config ||= eval(name).new
end
def current_step
return current_steps[0] if current_steps.length > 0
nil
end
def available_actions(username, parameters = { })
step = current_step
return [] unless is_current_step_owner(username)
step_id = step.step_id
config.steps["S#{step_id.to_s.rjust(3, '0')}".to_sym][:actions]
end
def is_document_owner(username)
return false if current_step[:owner].blank?
if history_steps.blank?
return true
else
return history_steps.first.owner.grep(/#{username}/).length > 0
end
end
def is_current_step_owner(username)
return false if current_step[:owner].blank?
current_step[:owner].grep(/#{username}/).length > 0
end
def is_editable(username)
is_document_owner(username) && is_current_step_owner(username)
end
def current_comment_key
config.steps["S#{current_step.step_id}".to_sym][:comment_key]
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment