diff --git a/app/jobs/scheduled/mark_as_solution.rb b/app/jobs/scheduled/mark_as_solution.rb index 63cabd3..00b8c6c 100644 --- a/app/jobs/scheduled/mark_as_solution.rb +++ b/app/jobs/scheduled/mark_as_solution.rb @@ -2,53 +2,52 @@ module Jobs class MarkAsSolution < ::Jobs::Scheduled - every 14.days + every 1.day def execute(_args = nil) - return false unless SiteSetting.solved_enabled - return false unless SiteSetting.solved_reminders_plugin_enabled + return false unless SiteSetting.solved_enabled && SiteSetting.solved_reminders_plugin_enabled Rails.logger.warn("Running scheduled job to send notifications to mark a post a solution.") - unsolved_topic_ids = [] + base_query = + Topic + .listable_topics + .where(closed: false, archived: false, visible: true) + .where("posts_count > 0") + .where("last_post_user_id <> user_id") + .where("last_posted_at > ?", SiteSetting.remind_mark_solution_last_post_age.days.ago) + .where( + "NOT EXISTS (SELECT 1 FROM discourse_solved_solved_topics dsst WHERE dsst.topic_id = topics.id)", + ) - if SiteSetting.allow_solved_on_all_topics - unsolved_topic_ids = unsolved_topic_ids.push(*Topic.pluck(:id)) - else + if !SiteSetting.allow_solved_on_all_topics category_ids = - CategoryCustomField.where(name: "enable_accepted_answers", value: "true").pluck( + CategoryCustomField.where(name: "enable_accepted_answers", value: "true").select( :category_id, ) - unsolved_topic_ids = - unsolved_topic_ids.push(*Topic.where(category_id: category_ids).pluck(:id)) - - if SiteSetting.enable_solved_tags.present? - allowed_tags_ids = Tag.where_name(SiteSetting.enable_solved_tags.split("|")).pluck(:id) - unsolved_topic_ids = - unsolved_topic_ids.push( - *TopicTag.where(tag_id: allowed_tags_ids).distinct.pluck(:topic_id), - ) - end + tag_topic_ids = + if SiteSetting.enable_solved_tags.present? + TopicTag.where( + tag_id: Tag.where_name(SiteSetting.enable_solved_tags.split("|")).select(:id), + ).select(:topic_id) + end + + base_query = + if tag_topic_ids + base_query.where("category_id IN (?) OR id IN (?)", category_ids, tag_topic_ids) + else + base_query.where(category_id: category_ids) + end end - solved_topic_ids = TopicCustomField.where(name: "accepted_answer_post_id").pluck(:topic_id) - unsolved_topic_ids = unsolved_topic_ids - solved_topic_ids if solved_topic_ids.present? + cutoff_date = SiteSetting.remind_mark_solution_after_days.days.ago - unsolved_topics = - Topic - .listable_topics - .where(id: unsolved_topic_ids) - .where(closed: false, archived: false, visible: true) - .where("posts_count > 0") - .where("last_post_user_id <> user_id") - .where("last_posted_at > ?", SiteSetting.remind_mark_solution_last_post_age.days.ago) - - unsolved_topics.each do |topic| - if (topic&.last_posted_at || Date.today) < - SiteSetting.remind_mark_solution_after_days.days.ago - # create a new reminder PM + discobot = User.find(-2) + base_query + .where("COALESCE(last_posted_at, current_date) < ?", cutoff_date) + .find_each do |topic| PostCreator.create!( - User.find(-2), + discobot, title: I18n.t("mark_as_solution.title"), raw: "#{I18n.t("mark_as_solution.message")}\n\n#{topic.url}", archetype: Archetype.private_message, @@ -56,7 +55,6 @@ def execute(_args = nil) skip_validations: true, ) end - end end end end diff --git a/spec/jobs/mark_as_solution_spec.rb b/spec/jobs/mark_as_solution_spec.rb index da38623..f6825ca 100644 --- a/spec/jobs/mark_as_solution_spec.rb +++ b/spec/jobs/mark_as_solution_spec.rb @@ -16,7 +16,9 @@ context "when the topic is not solved" do it "should send the PM to user to mark a post as solution" do - expect { described_class.new.execute({}) }.to change { Topic.count }.by(1) + expect { described_class.new.execute({}) }.to change { + Topic.where(archetype: Archetype.private_message).count + }.by(1) expect(Topic.last.title).to eq(I18n.t("mark_as_solution.title")) end end @@ -25,14 +27,18 @@ before { DiscourseSolved.accept_answer!(post, Discourse.system_user) } it "should not send the PM to user" do - expect { described_class.new.execute({}) }.to not_change { Topic.count } + expect { described_class.new.execute({}) }.to not_change { + Topic.where(archetype: Archetype.private_message).count + } end end context "when the plugin is disabled" do it "should not send the PM to user" do SiteSetting.solved_reminders_plugin_enabled = false - expect { described_class.new.execute({}) }.to not_change { Topic.count } + expect { described_class.new.execute({}) }.to not_change { + Topic.where(archetype: Archetype.private_message).count + } end end end