From 72d033c6483658aac533daa28bc590d7faabcb73 Mon Sep 17 00:00:00 2001 From: Thomas Leishman Date: Tue, 21 Mar 2017 22:43:06 -0600 Subject: [PATCH 1/4] Add new Project selector option to mimic Redmines Email Notification: Only for things I watch or I'm involved in --- app/models/digest_rule.rb | 5 ++-- config/locales/en.yml | 2 ++ lib/redmine_digest/digest.rb | 31 +++++++++++++++++++++---- test/unit/redmine_digest/digest_test.rb | 15 ++++++++++++ 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/app/models/digest_rule.rb b/app/models/digest_rule.rb index 1fcc876..2f7dc26 100644 --- a/app/models/digest_rule.rb +++ b/app/models/digest_rule.rb @@ -4,7 +4,8 @@ class DigestRule < ActiveRecord::Base NOT_SELECTED = 'not_selected' MEMBER = 'member' MEMBER_NOT_SELECTED = 'member_not_selected' - PROJECT_SELECTOR_VALUES = [ALL, SELECTED, NOT_SELECTED, MEMBER, MEMBER_NOT_SELECTED] + ALL_INVOLVED = 'all_involved' + PROJECT_SELECTOR_VALUES = [ALL, SELECTED, NOT_SELECTED, MEMBER, MEMBER_NOT_SELECTED, ALL_INVOLVED] NOTIFY_AND_DIGEST = 'all' NOTIFY_ONLY = 'notify' @@ -151,7 +152,7 @@ def event_for_journal_detail(journal, jdetail) def get_projects_scope case project_selector - when ALL + when ALL, ALL_INVOLVED nil when SELECTED ['projects.id in (?)', project_ids] diff --git a/config/locales/en.yml b/config/locales/en.yml index 62aa083..4f6ce3e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -29,6 +29,7 @@ en: not_selected: "For any issue update except for the selected projects" member: "For any update on all projects I am a member of" member_not_selected: "For any update on projects I am a member of, except for the selected projects" + all_involved: "For any update to issues I watch or I'm involved in for all projects" project_selector_short: all: "All projects" @@ -36,6 +37,7 @@ en: not_selected: "Except for the selected projects" member: "Projects I am a member of" member_not_selected: "Projects I am a member of, except for the selected projects" + all_involved: "All projects I watch or I'm involved in" notify_options: all: "Send notifications about an event and include it in the digest" diff --git a/lib/redmine_digest/digest.rb b/lib/redmine_digest/digest.rb index 0af9db4..7be3188 100644 --- a/lib/redmine_digest/digest.rb +++ b/lib/redmine_digest/digest.rb @@ -172,15 +172,16 @@ def get_time_to end def get_changed_issue_ids - Journal.joins(:issue).where('issues.project_id in (?)', project_ids). + get_journal_scope. where('journals.created_on >= ? and journals.created_on < ?', time_from, time_to). uniq.pluck(:journalized_id) end def get_created_issue_ids - Issue.where('issues.project_id in (?)', project_ids). - where('issues.created_on >= ? and issues.created_on < ?', time_from, time_to). - uniq.pluck(:id) + issues = Issue.where('issues.project_id in (?)', project_ids). + where('issues.created_on >= ? and issues.created_on < ?', time_from, time_to) + issues.where('(issues.assigned_to_id = ? OR issues.author_id = ?)', user.id, user.id) if all_involved_only? + issues.uniq.pluck(:id) end def get_issues_scope(issue_ids) @@ -189,6 +190,28 @@ def get_issues_scope(issue_ids) where(Issue.visible_condition(user)) end + def get_journal_scope + if all_involved_only? + get_journal_all_involved_scope + else + Journal.joins(:issue).where('issues.project_id in (?)', project_ids) + end + end + + def get_journal_all_involved_scope + Journal.joins(:issue). + joins("LEFT JOIN journal_details ON journals.id = journal_details.journal_id AND property = 'attr' AND prop_key = 'assigned_to_id'"). + joins("LEFT JOIN watchers ON watchers.watchable_type='Issue' AND watchers.watchable_id = issues.id"). + where('watchers.user_id = ? OR issues.author_id = ? OR issues.assigned_to_id = ? OR + journal_details.old_value = ? OR journal_details.value = ? OR journals.user_id = ?', + user.id, user.id, user.id, user.id, user.id, user.id) + + end + + def all_involved_only? + project_selector == DigestRule::ALL_INVOLVED + end + def project_ids @project_ids ||= digest_rule.affected_project_ids end diff --git a/test/unit/redmine_digest/digest_test.rb b/test/unit/redmine_digest/digest_test.rb index 6c1e967..1ee0b3a 100644 --- a/test/unit/redmine_digest/digest_test.rb +++ b/test/unit/redmine_digest/digest_test.rb @@ -126,6 +126,21 @@ def test_member_not_selected_projects assert_equal exp_ids, issue_ids end + def test_all_involved + user = User.find(2) + rule = user.digest_rules.create( + name: 'test', + recurrent: DigestRule::MONTHLY, + project_selector: DigestRule::ALL_INVOLVED, + event_ids: DigestEvent::TYPES + ) + time_to = Journal.last.created_on + 1.hour + digest = RedmineDigest::Digest.new(rule, time_to) + exp_ids = [1, 2, 4, 6, 7, 8, 11, 12, 14] + issue_ids = digest.issues.map(&:id).sort + assert_equal exp_ids, issue_ids + end + def test_time_zone Time.use_zone('UTC') do # leave only ane issue at midnight UTC From 458fac9c65f34e463c125f3c75f977afabcf82e5 Mon Sep 17 00:00:00 2001 From: Thomas Leishman Date: Wed, 22 Mar 2017 07:27:31 -0600 Subject: [PATCH 2/4] Refactor all_involved_only? method into DigestRule class --- app/models/digest_rule.rb | 4 ++++ lib/redmine_digest/digest.rb | 6 +----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/models/digest_rule.rb b/app/models/digest_rule.rb index 2f7dc26..d675f63 100644 --- a/app/models/digest_rule.rb +++ b/app/models/digest_rule.rb @@ -129,6 +129,10 @@ def digest_only? notify == DIGEST_ONLY end + def all_involved_only? + project_selector == ALL_INVOLVED + end + private def event_for_journal_detail(journal, jdetail) diff --git a/lib/redmine_digest/digest.rb b/lib/redmine_digest/digest.rb index 7be3188..cbac8ce 100644 --- a/lib/redmine_digest/digest.rb +++ b/lib/redmine_digest/digest.rb @@ -5,7 +5,7 @@ class Digest attr_reader :digest_rule, :time_to - delegate :name, :user, :recurrent, :project_selector, + delegate :name, :user, :recurrent, :project_selector, :all_involved_only?, to: :digest_rule, allow_nil: true def initialize(digest_rule, time_to = nil, issue_limit = nil) @@ -208,10 +208,6 @@ def get_journal_all_involved_scope end - def all_involved_only? - project_selector == DigestRule::ALL_INVOLVED - end - def project_ids @project_ids ||= digest_rule.affected_project_ids end From 917281770f2dc0865fd5e6af0bb738f9be4d1217 Mon Sep 17 00:00:00 2001 From: Thomas Leishman Date: Wed, 22 Mar 2017 22:58:19 -0600 Subject: [PATCH 3/4] correct scope in Digest#get_created_issue_ids --- lib/redmine_digest/digest.rb | 2 +- test/unit/redmine_digest/digest_test.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/redmine_digest/digest.rb b/lib/redmine_digest/digest.rb index cbac8ce..5752bd6 100644 --- a/lib/redmine_digest/digest.rb +++ b/lib/redmine_digest/digest.rb @@ -180,7 +180,7 @@ def get_changed_issue_ids def get_created_issue_ids issues = Issue.where('issues.project_id in (?)', project_ids). where('issues.created_on >= ? and issues.created_on < ?', time_from, time_to) - issues.where('(issues.assigned_to_id = ? OR issues.author_id = ?)', user.id, user.id) if all_involved_only? + issues = issues.where('(issues.assigned_to_id = ? OR issues.author_id = ?)', user.id, user.id) if all_involved_only? issues.uniq.pluck(:id) end diff --git a/test/unit/redmine_digest/digest_test.rb b/test/unit/redmine_digest/digest_test.rb index 1ee0b3a..5271c53 100644 --- a/test/unit/redmine_digest/digest_test.rb +++ b/test/unit/redmine_digest/digest_test.rb @@ -136,7 +136,7 @@ def test_all_involved ) time_to = Journal.last.created_on + 1.hour digest = RedmineDigest::Digest.new(rule, time_to) - exp_ids = [1, 2, 4, 6, 7, 8, 11, 12, 14] + exp_ids = [1, 2, 4, 6, 7, 8, 11, 14] issue_ids = digest.issues.map(&:id).sort assert_equal exp_ids, issue_ids end From 4d1e4216fe28bff58504a6f73f53416235f74811 Mon Sep 17 00:00:00 2001 From: Thomas Leishman Date: Wed, 22 Mar 2017 23:39:24 -0600 Subject: [PATCH 4/4] simplify queries --- lib/redmine_digest/digest.rb | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/redmine_digest/digest.rb b/lib/redmine_digest/digest.rb index 5752bd6..abd6f65 100644 --- a/lib/redmine_digest/digest.rb +++ b/lib/redmine_digest/digest.rb @@ -178,10 +178,14 @@ def get_changed_issue_ids end def get_created_issue_ids - issues = Issue.where('issues.project_id in (?)', project_ids). - where('issues.created_on >= ? and issues.created_on < ?', time_from, time_to) - issues = issues.where('(issues.assigned_to_id = ? OR issues.author_id = ?)', user.id, user.id) if all_involved_only? - issues.uniq.pluck(:id) + Issue.where('issues.project_id in (?)', project_ids). + where('issues.created_on >= ? and issues.created_on < ?', time_from, time_to). + where(user_is_involved_in_issues). + uniq.pluck(:id) + end + + def user_is_involved_in_issues + ['issues.assigned_to_id = :user_id OR issues.author_id = :user_id', {user_id: user.id}] if all_involved_only? end def get_issues_scope(issue_ids) @@ -202,9 +206,9 @@ def get_journal_all_involved_scope Journal.joins(:issue). joins("LEFT JOIN journal_details ON journals.id = journal_details.journal_id AND property = 'attr' AND prop_key = 'assigned_to_id'"). joins("LEFT JOIN watchers ON watchers.watchable_type='Issue' AND watchers.watchable_id = issues.id"). - where('watchers.user_id = ? OR issues.author_id = ? OR issues.assigned_to_id = ? OR - journal_details.old_value = ? OR journal_details.value = ? OR journals.user_id = ?', - user.id, user.id, user.id, user.id, user.id, user.id) + where('watchers.user_id = :user_id OR issues.author_id = :user_id OR issues.assigned_to_id = :user_id OR + journal_details.old_value = :user_id OR journal_details.value = :user_id OR journals.user_id = :user_id', + {user_id: user.id}) end