-
-
Save benolee/9414161 to your computer and use it in GitHub Desktop.
This file contains 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 characters
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 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 characters
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 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 characters
#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 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 characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment