Skip to content

Commit

Permalink
WIP: refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
Flink committed Nov 16, 2023
1 parent 07ba320 commit 039ca40
Showing 1 changed file with 105 additions and 69 deletions.
174 changes: 105 additions & 69 deletions lib/random_assign_utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,84 +29,21 @@ def initialize(context, fields, automation)
end

def automation_script!
min_hours = fields.dig("minimum_time_between_assignments", "value").presence
if min_hours &&
TopicCustomField
.where(name: "assigned_to_id", topic: topic)
.where("created_at < ?", min_hours.to_i.hours.ago)
.exists?
log_info("Topic(#{topic.id}) has already been assigned recently")
return
end

assignable_user_ids = User.assign_allowed.pluck(:id)
users_on_holiday =
Set.new(
User.where(
id: UserCustomField.where(name: "on_holiday", value: "t").select(:user_id),
).pluck(:id),
)

group_users = group.group_users.joins(:user)
if skip_new_users_for_days = fields.dig("skip_new_users_for_days", "value").presence
group_users = group_users.where("users.created_at < ?", skip_new_users_for_days.to_i.days.ago)
end

group_users_ids =
group_users
.pluck("users.id")
.filter { |user_id| assignable_user_ids.include?(user_id) }
.reject { |user_id| users_on_holiday.include?(user_id) }

return no_one! if group_users_ids.empty?

max_recently_assigned_days =
(fields.dig("max_recently_assigned_days", "value").presence || 180).to_i.days.ago
last_assignees_ids = recently_assigned_users_ids(max_recently_assigned_days)
users_ids = group_users_ids - last_assignees_ids
if users_ids.blank?
min_recently_assigned_days =
(fields.dig("min_recently_assigned_days", "value").presence || 14).to_i.days.ago
recently_assigned_users_ids = recently_assigned_users_ids(min_recently_assigned_days)
users_ids = group_users_ids - recently_assigned_users_ids
end

users_ids << last_assignees_ids.last if users_ids.blank?

if fields.dig("in_working_hours", "value")
assign_to_user_id = users_ids.shuffle.detect { |user_id| in_working_hours?(user_id) }
end
assign_to_user_id ||= users_ids.sample

assign_to = User.find(assign_to_user_id)
result = nil
if raw = fields.dig("post_template", "value").presence
post =
PostCreator.new(
Discourse.system_user,
raw: raw,
skip_validations: true,
topic_id: topic.id,
).create!

result = Assigner.new(post, Discourse.system_user).assign(assign_to)

PostDestroyer.new(Discourse.system_user, post).destroy if !result[:success]
else
result = Assigner.new(topic, Discourse.system_user).assign(assign_to)
end

no_one! if !result[:success]
return log_info("Topic(#{topic.id}) has already been assigned recently") if assigned_recently?
return no_one! unless assigned_user
assign_user!
end

def recently_assigned_users_ids(from)
posts =
Post
.select(:id)
.joins(:user)
.where(topic: topic, action_code: %w[assigned reassigned assigned_to_post])
.where("posts.created_at > ?", from)
.order(created_at: :desc)
usernames = posts.map { _1.custom_fields[:action_code_who] }.uniq
usernames =
Post.custom_fields_for_ids(posts, [:action_code_who]).map { |_, v| v["action_code_who"] }.uniq
User
.where(username: usernames)
.joins(
Expand Down Expand Up @@ -135,6 +72,28 @@ def no_one!
)
end

def assigned_user
@assigned_user ||=
begin
group_users_ids = group_users.pluck(:id)
return if group_users_ids.empty?

last_assignees_ids = recently_assigned_users_ids(max_recently_assigned_days)
users_ids = group_users_ids - last_assignees_ids
if users_ids.blank?
recently_assigned_users_ids = recently_assigned_users_ids(min_recently_assigned_days)
users_ids = group_users_ids - recently_assigned_users_ids
end
users_ids << last_assignees_ids.last if users_ids.blank?
if fields.dig("in_working_hours", "value")
assign_to_user_id = users_ids.shuffle.detect { |user_id| in_working_hours?(user_id) }
end
assign_to_user_id ||= users_ids.sample

User.find(assign_to_user_id)
end
end

def in_working_hours?(user_id)
tzinfo = user_tzinfo(user_id)
tztime = tzinfo.now
Expand All @@ -158,4 +117,81 @@ def user_tzinfo(user_id)

tzinfo
end

def min_hours
hours = fields.dig("minimum_time_between_assignments", "value").presence
return unless hours
hours.to_i.hours.ago
end

def assigned_recently?
return unless min_hours
TopicCustomField
.where(name: "assigned_to_id", topic: topic)
.where("created_at < ?", min_hours)
.exists?
end

def skip_new_users_for_days
days = fields.dig("skip_new_users_for_days", "value").presence
return unless days
days.to_i.days.ago
end

def group_users
users =
group
.users
.where(id: User.assign_allowed.select(:id))
.where.not(
id:
User
.joins(:_custom_fields)
.where(user_custom_fields: { name: "on_holiday", value: "t" })
.select(:id),
)
return users unless skip_new_users_for_days
users.where("users.created_at < ?", skip_new_users_for_days)
end

def max_recently_assigned_days
@max_days ||= (fields.dig("max_recently_assigned_days", "value").presence || 180).to_i.days.ago
end

def min_recently_assigned_days
@min_days ||= (fields.dig("min_recently_assigned_days", "value").presence || 14).to_i.days.ago
end

def post_template
@post_template ||= fields.dig("post_template", "value").presence
end

def create_post_template
post =
PostCreator.new(
Discourse.system_user,
raw: post_template,
skip_validations: true,
topic_id: topic.id,
).create!
Assigner
.new(post, Discourse.system_user)
.assign(assigned_user)
.then do |result|
next if result[:success]
PostDestroyer.new(Discourse.system_user, post).destroy
no_one!
end
end

def assign_user!
return create_post_template if post_template
Assigner
.new(topic, Discourse.system_user)
.assign(assigned_user)
.then do |result|
next if result[:success]
no_one!
end
end
end

0 comments on commit 039ca40

Please sign in to comment.