Created
March 3, 2014 21:10
-
-
Save BiggerNoise/9334673 to your computer and use it in GitHub Desktop.
Revisions
-
BiggerNoise created this gist
Mar 3, 2014 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,60 @@ class AssignCaseCommand < Command attribute :case, Case attribute :owner, User attribute :created_by, User attribute :comments, String attribute :distribute_at, DateTime attribute :distribute_rule_name, String attribute :require_initial, Boolean validates :case, :owner, presence: true def initialize(params) self.attributes = { case: params[:case] || Case.find(params[:case_id]), owner: params[:owner] || (params[:owner_id] && User.find(params[:owner_id])), created_by: params[:created_by] || (params[:created_by_id] && User.find(params[:created_by_id])), comments: params[:comments], distribute_at: params[:distribute_at], distribute_rule_name: params[:distribute_rule_name], require_initial: params.has_key?(:require_initial) ? params[:require_initial] : false } end protected def execute_self return false unless valid? @previous_owner = self.case.owner self.case.owner = owner self.case.distribute_at = distribute_at self.case.distribute_rule_name = distribute_rule_name self.case.save end def format_activity_comment result = "Case assigned to #{owner.full_name}" result << "; #{comments}" if comments end def prepare_sub_commands sub_commands = [] sub_commands << CreateActivityCommand.new(case: self.case, created_by: created_by, comments: format_activity_comment, activity_type: 'CASEASSIGNED') # All non-closed tasks for the current owner of the case are assigned to the new owner of the case open_tasks_for_current_owner = self.case.tasks.select { |t| t.owner == @previous_owner && t.status != TaskStatus::CLOSED } unless @previous_owner.nil? open_tasks_for_current_owner.each { |t| sub_commands.push AssignTaskCommand.new(task: t, owner: owner, created_by: created_by, comments: comments) } end # if there wasn't an initial contact task, create one if require_initial == true if require_initial && !open_tasks_for_current_owner.any? { |t| t.task_type == Task::INITIAL_TASK_TYPE } sub_commands.push CreateTaskCommand.new(case: self.case, owner: owner, task_type: Task::INITIAL_TASK_TYPE, created_by: created_by, comments: comments) end sub_commands end end This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,57 @@ class AssignTaskCommand < Command attribute :task, Task attribute :owner, User attribute :due_at, DateTime attribute :created_by, User attribute :comments, String attribute :distribute_at, DateTime attribute :distribute_rule_name, String attribute :assign_case, Integer validates :task, :owner, presence: true def initialize(params) self.attributes = { task: params[:task] || (params.has_key?(:task_id) && Task.find(params[:task_id])), owner: params[:owner] || (params.has_key?(:owner_id) && User.find(params[:owner_id])), due_at: params[:due_at] || Task.default_due_date, created_by: params[:created_by] || (params[:created_by_id] && User.find(params[:created_by_id])), distribute_at: params[:distribute_at], distribute_rule_name: params[:distribute_rule_name], comments: params[:comments], assign_case: params[:assign_case] } end protected def format_activity_comment result = "Task assigned to #{owner.full_name}" result << "; #{comments}" if comments end def format_case_assignment_comment result = 'Case assignment followed task assignment' result << "; #{comments}" if comments end def execute_self @previous_owner = task.owner task.owner = owner task.due_at = due_at if task.due_at.nil? || due_at.nil? || due_at > task.due_at self.task.distribute_at = distribute_at self.task.distribute_rule_name = distribute_rule_name task.save end def prepare_sub_commands cmds = [CreateActivityCommand.new(case: task.case, task: task, created_by: created_by, activity_type: 'TASKASSIGNED', comments: format_activity_comment)] case when assign_case == AssignCase::UNASSIGNED && task.case.owner.nil? cmds << AssignCaseCommand.new(case: task.case, owner: owner, comments: format_case_assignment_comment) when assign_case == AssignCase::ALWAYS cmds << AssignCaseCommand.new(case: task.case, owner: owner, comments: format_case_assignment_comment) end cmds end end This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,39 @@ #implement execute_self which returns true/false for success. Do not throw. # optionally implement prepare_sub_commands and return an array of subcommands class Command include ActiveModel::Validations include ActiveRecord::Serialization include Virtus def execute return false unless valid? && execute_self !!execute_sub_commands(prepare_sub_commands) end def execute! (valid? && execute_self) || raise(ActiveRecord::RecordInvalid.new(self)) execute_sub_commands!(prepare_sub_commands) end def attributes_except(*exclusions) attr = attributes.dup exclusions.flatten.each { |e| attr.delete(e) } attr end protected def prepare_sub_commands [] end def execute_sub_commands(sub_commands) sub_commands.each do |c| break nil unless c.execute end end def execute_sub_commands!(sub_commands) sub_commands.each { |c| c.execute! } end end This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,108 @@ class CreateActivityCommand < Command attr_reader :activity attribute :created_by, User attribute :parent_activity, Activity attribute :member, Case attribute :case, Case attribute :task, Task attribute :activity_type, String attribute :comments, String attribute :case_closed, Boolean attribute :task_closed, Boolean attribute :due_at, DateTime attribute :allow_closed_case_activity, Boolean attribute :allow_closed_task_activity, Boolean validates :member, :activity_type, presence: true validate :case_cannot_be_closed, :task_cannot_be_closed def initialize(params = {}) self.created_by = params[:created_by] || User.where(id: params[:created_by_id]).first self.parent_activity = params[:parent_activity] # Lookups do not make sense here self.member = params[:member] || Member.where(id: params[:member_id]).first self.case = params[:case] || Case.where(id: params[:case_id]).first self.task = params[:task] || Task.where(id: params[:task_id]).first self.activity_type = params[:activity_type] || params[:activity_type_code] self.comments = params[:comments] self.case_closed = !!params[:case_closed] self.task_closed = !!params[:task_closed] self.due_at = params[:due_at] && params[:due_at].to_datetime self.allow_closed_case_activity = params.has_key?(:allow_closed_case_activity) ? params[:allow_closed_case_activity] : false self.allow_closed_task_activity = params.has_key?(:allow_closed_task_activity) ? params[:allow_closed_task_activity] : false self.member ||= (self.case && self.case.member) end def execute_self return false if invalid? create_activity self.case.last_activity = @activity if self.case self.task.last_activity = self.case.last_activity if self.task if case_closed && self.case close_case self.case elsif task_closed && self.task close_task self.task elsif task && due_at && due_at != task.due_at postpone_task task end # Task may already be saved by close/postpone self.task.save! if task && task.changed? self.case.save! if self.case true end private STORED_ATTRIBUTES = [:member, :case, :task, :activity_type, :created_by, :parent_activity, :comments, :task_closed, :case_closed] def create_activity @activity = Activity.create!(attributes.select {|a,_| STORED_ATTRIBUTES.include?(a)}) end def close_case(c) close_open_tasks c c.closed_at = Time.current c.closed_by = created_by c.status = CaseStatus::CLOSED c.save! end def close_open_tasks(c) c.tasks.find_all { |t| t.status != TaskStatus::CLOSED }.each { |t| close_task t } end def close_task(t) return unless t t.closed_at = Time.current t.closed_by = created_by t.status = TaskStatus::CLOSED t.save! end def postpone_task(t) return unless t && due_at t.due_at = due_at t.save! end def case_cannot_be_closed if self.case and !allow_closed_case_activity and self.case.status == CaseStatus::CLOSED errors.add :case_id, 'cannot have new activity when its closed' end end def task_cannot_be_closed if self.task and !allow_closed_task_activity and self.task.status == TaskStatus::CLOSED errors.add :task_id, 'cannot have new activity when its closed' end end def persisted? false end end