# frozen_string_literal: true require_dependency 'email/sender' class ::TopicAssigner ASSIGNED_TO_ID = 'assigned_to_id' ASSIGNED_BY_ID = 'assigned_by_id' def self.backfill_auto_assign staff_mention = User.where('moderator OR admin') .pluck('username') .map { |name| "p.cooked ILIKE '%mention%@#{name}%'" } .join(' OR ') sql = < assign_to.username } ) if @assigned_by.id != assign_to.id Notification.create!( notification_type: Notification.types[:custom], user_id: assign_to.id, topic_id: @topic.id, post_number: 1, data: { message: 'discourse_assign.assign_notification', display_username: @assigned_by.username, topic_title: @topic.title }.to_json ) end end # we got to send a push notification as well # what we created here is a whisper and notification will not raise a push alerter = PostAlerter.new(first_post) # TODO: remove June 2019 if alerter.respond_to?(:create_notification_alert) && @assigned_by.id != assign_to.id alerter.create_notification_alert( user: assign_to, post: first_post, username: @assigned_by.username, notification_type: Notification.types[:custom], excerpt: I18n.t("discourse_assign.topic_assigned_excerpt", title: @topic.title) ) end { success: true } end def unassign(silent: false) if assigned_to_id = @topic.custom_fields[ASSIGNED_TO_ID] # TODO core needs an API for this stuff badly # currently there is no 100% surefire way of deleting a custom field TopicCustomField.where( topic_id: @topic.id ).where( 'name in (?)', [ASSIGNED_BY_ID, ASSIGNED_TO_ID] ).destroy_all if Array === assigned_to_id # more custom field mess, try to recover assigned_to_id = assigned_to_id.first end # clean up in memory object @topic.custom_fields[ASSIGNED_TO_ID] = nil @topic.custom_fields[ASSIGNED_BY_ID] = nil if !assigned_to_id # nothing to do here return end post = @topic.posts.where(post_number: 1).first return unless post.present? post.publish_change_to_clients!(:revised, reload_topic: true) if TopicUser.exists?( user_id: assigned_to_id, topic: @topic, notification_level: TopicUser.notification_levels[:watching], notifications_reason_id: TopicUser.notification_reasons[:plugin_changed] ) TopicUser.change( assigned_to_id, @topic.id, notification_level: TopicUser.notification_levels[:tracking], notifications_reason_id: TopicUser.notification_reasons[:plugin_changed] ) end assigned_user = User.find_by(id: assigned_to_id) MessageBus.publish( "/staff/topic-assignment", { type: 'unassigned', topic_id: @topic.id, }, user_ids: staff_ids ) publish_topic_tracking_state(@topic, assigned_user.id) UserAction.where( action_type: UserAction::ASSIGNED, target_post_id: post.id ).destroy_all # yank notification Notification.where( notification_type: Notification.types[:custom], user_id: assigned_user.try(:id), topic_id: @topic.id, post_number: 1 ).where("data like '%discourse_assign.assign_notification%'").destroy_all if SiteSetting.unassign_creates_tracking_post && !silent post_type = SiteSetting.assigns_public ? Post.types[:small_action] : Post.types[:whisper] @topic.add_moderator_post( @assigned_by, nil, bump: false, post_type: post_type, custom_fields: { "action_code_who" => assigned_user&.username }, action_code: "unassigned" ) end end end private def publish_topic_tracking_state(topic, user_id) if topic.private_message? MessageBus.publish( "/private-messages/assigned", { topic_id: topic.id }, user_ids: [user_id] ) end end end