Project

General

Profile

Feature #2477 ยป 2477-reminder-to-watchers.diff

patch against the current trunk (3.3.2.devel.16172) - Go MAEDA, 2017-01-12 15:23

View differences:

app/models/mailer.rb (working copy)
376 376
  # * :project  => id or identifier of project to process (defaults to all projects)
377 377
  # * :users    => array of user/group ids who should be reminded
378 378
  # * :version  => name of target version for filtering issues (defaults to none)
379
  # * :recipients => array of recipient types (available values are :assignee and :watcher, default to :assignee)
379 380
  def self.reminders(options={})
380 381
    days = options[:days] || 7
381 382
    project = options[:project] ? Project.find(options[:project]) : nil
......
385 386
      raise ActiveRecord::RecordNotFound.new("Couldn't find Version with named #{options[:version]}")
386 387
    end
387 388
    user_ids = options[:users]
389
    recipients = options[:recipients]
390
    recipients = [:assignee] if recipients.blank?
388 391

  
389
    scope = Issue.open.where("#{Issue.table_name}.assigned_to_id IS NOT NULL" +
390
      " AND #{Project.table_name}.status = #{Project::STATUS_ACTIVE}" +
392
    scope = Issue.open.where(
393
      "#{Project.table_name}.status = #{Project::STATUS_ACTIVE}" +
391 394
      " AND #{Issue.table_name}.due_date <= ?", days.day.from_now.to_date
392 395
    )
393 396
    scope = scope.where(:assigned_to_id => user_ids) if user_ids.present?
394 397
    scope = scope.where(:project_id => project.id) if project
395 398
    scope = scope.where(:fixed_version_id => target_version_id) if target_version_id.present?
396 399
    scope = scope.where(:tracker_id => tracker.id) if tracker
397
    issues_by_assignee = scope.includes(:status, :assigned_to, :project, :tracker).
398
                              group_by(&:assigned_to)
399
    issues_by_assignee.keys.each do |assignee|
400
      if assignee.is_a?(Group)
401
        assignee.users.each do |user|
402
          issues_by_assignee[user] ||= []
403
          issues_by_assignee[user] += issues_by_assignee[assignee]
400
    issues = scope.includes(:status, :assigned_to, :project, :tracker)
401
    issues_by_recipient = {}
402

  
403
    if recipients.include?(:assignee)
404
      issues_by_recipient =
405
        issues.where('assigned_to_id IS NOT NULL').group_by(&:assigned_to)
406
      issues_by_recipient.keys.each do |assignee|
407
        if assignee.is_a?(Group)
408
          assignee.users.each do |user|
409
            issues_by_recipient[user] ||= []
410
            issues_by_recipient[user] += issues_by_recipient[assignee]
411
          end
404 412
        end
405 413
      end
406 414
    end
407

  
408
    issues_by_assignee.each do |assignee, issues|
409
      reminder(assignee, issues, days).deliver if assignee.is_a?(User) && assignee.active?
415
    if recipients.include?(:watcher)
416
      issues.each do |issue|
417
        issue.notified_watchers.each do |watcher|
418
          issues_by_recipient[watcher] ||= []
419
          issues_by_recipient[watcher] |= [issue]
420
        end
421
      end
410 422
    end
423
    issues_by_recipient.each do |recipient, issues|
424
      reminder(recipient, issues, days).deliver if recipient.is_a?(User) && recipient.active?
425
    end
411 426
  end
412 427

  
413 428
  # Activates/desactivates email deliveries during +block+
lib/tasks/reminder.rake (working copy)
24 24
  * project  => id or identifier of project (defaults to all projects)
25 25
  * users    => comma separated list of user/group ids who should be reminded
26 26
  * version  => name of target version for filtering issues (defaults to none)
27
  * recipients => comma separated list of recipient types
28
    (default to 'assignee', available values are 'assignee' and 'watcher')
27 29

  
28 30
Example:
29 31
  rake redmine:send_reminders days=7 users="1,23, 56" RAILS_ENV="production"
......
36 38
    options[:project] = ENV['project'] if ENV['project']
37 39
    options[:tracker] = ENV['tracker'].to_i if ENV['tracker']
38 40
    options[:users] = (ENV['users'] || '').split(',').each(&:strip!)
39
    options[:version] = ENV['version'] if ENV['version'] 
41
    options[:version] = ENV['version'] if ENV['version']
42
    options[:recipients] =
43
      ENV['recipients'].to_s.downcase.split(',').map(&:strip).map(&:to_sym) &
44
      [:assignee, :watcher]
40 45

  
41 46
    Mailer.with_synched_deliveries do
42 47
      Mailer.reminders(options)
test/unit/mailer_test.rb (working copy)
663 663
    end
664 664
  end
665 665

  
666
  def test_reminders_with_recipient_option
667
    with_settings :default_language => 'en' do
668
      # assigned to dlopper, watched by jsmith
669
      issues(:issues_003).add_watcher(users(:users_002))
670
      # assigned to nobody, watched by jsmith
671
      Issue.generate!(:assigned_to => nil, :due_date => 5.days.from_now, :subject => 'Assigned to nobody').add_watcher(users(:users_002))
672
      ActionMailer::Base.deliveries.clear
673

  
674
      Mailer.reminders(:days => 42, :recipients => [:assignee])
675
      assert_equal 1, ActionMailer::Base.deliveries.size
676
      assert last_email.bcc.include?('dlopper@somenet.foo')
677
      ActionMailer::Base.deliveries.clear
678

  
679
      Mailer.reminders(:days => 42, :recipients => [:watcher])
680
      assert_equal 1, ActionMailer::Base.deliveries.size
681
      mail = last_email
682
      assert mail.bcc.include?('jsmith@somenet.foo')
683
      assert_mail_body_match 'Bug #3: Error 281 when updating a recipe', mail
684
      assert_mail_body_match 'Assigned to nobody', mail
685
      ActionMailer::Base.deliveries.clear
686

  
687
      Mailer.reminders(:days => 42, :recipients => [:assignee, :watcher])
688
      assert_equal 2, ActionMailer::Base.deliveries.size
689
      assert_equal %w(dlopper@somenet.foo jsmith@somenet.foo), ActionMailer::Base.deliveries.map(&:bcc).flatten.sort
690
    end
691
  end
692

  
666 693
  def test_security_notification
667 694
    set_language_if_valid User.find(1).language
668 695
    with_settings :emails_footer => "footer without link" do
    (1-1/1)