diff --git a/app/models/digest_rule.rb b/app/models/digest_rule.rb index 1fcc876..d675f63 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' @@ -128,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) @@ -151,7 +156,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..abd6f65 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) @@ -172,7 +172,7 @@ 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 @@ -180,15 +180,38 @@ def get_changed_issue_ids 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). + 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) Issue.joins(:project).includes(:author, :project, journals: [:user, :details]). where('issues.id in (?)', 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 = :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 + 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..5271c53 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, 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