To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.
root / .svn / pristine / 29 / 298be127abf8c78d6ccda6e13729844112a36c53.svn-base @ 1298:4f746d8966dd
History | View | Annotate | Download (4.53 KB)
| 1 |
# Redmine - project management software |
|---|---|
| 2 |
# Copyright (C) 2006-2012 Jean-Philippe Lang |
| 3 |
# |
| 4 |
# This program is free software; you can redistribute it and/or |
| 5 |
# modify it under the terms of the GNU General Public License |
| 6 |
# as published by the Free Software Foundation; either version 2 |
| 7 |
# of the License, or (at your option) any later version. |
| 8 |
# |
| 9 |
# This program is distributed in the hope that it will be useful, |
| 10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 |
# GNU General Public License for more details. |
| 13 |
# |
| 14 |
# You should have received a copy of the GNU General Public License |
| 15 |
# along with this program; if not, write to the Free Software |
| 16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 17 |
|
| 18 |
class Journal < ActiveRecord::Base |
| 19 |
belongs_to :journalized, :polymorphic => true |
| 20 |
# added as a quick fix to allow eager loading of the polymorphic association |
| 21 |
# since always associated to an issue, for now |
| 22 |
belongs_to :issue, :foreign_key => :journalized_id |
| 23 |
|
| 24 |
belongs_to :user |
| 25 |
has_many :details, :class_name => "JournalDetail", :dependent => :delete_all |
| 26 |
attr_accessor :indice |
| 27 |
|
| 28 |
acts_as_event :title => Proc.new {|o| status = ((s = o.new_status) ? " (#{s})" : nil); "#{o.issue.tracker} ##{o.issue.id}#{status}: #{o.issue.subject}" },
|
| 29 |
:description => :notes, |
| 30 |
:author => :user, |
| 31 |
:type => Proc.new {|o| (s = o.new_status) ? (s.is_closed? ? 'issue-closed' : 'issue-edit') : 'issue-note' },
|
| 32 |
:url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.issue.id, :anchor => "change-#{o.id}"}}
|
| 33 |
|
| 34 |
acts_as_activity_provider :type => 'issues', |
| 35 |
:author_key => :user_id, |
| 36 |
:find_options => {:include => [{:issue => :project}, :details, :user],
|
| 37 |
:conditions => "#{Journal.table_name}.journalized_type = 'Issue' AND" +
|
| 38 |
" (#{JournalDetail.table_name}.prop_key = 'status_id' OR #{Journal.table_name}.notes <> '')"}
|
| 39 |
|
| 40 |
before_create :split_private_notes |
| 41 |
|
| 42 |
scope :visible, lambda {|*args|
|
| 43 |
user = args.shift || User.current |
| 44 |
|
| 45 |
includes(:issue => :project). |
| 46 |
where(Issue.visible_condition(user, *args)). |
| 47 |
where("(#{Journal.table_name}.private_notes = ? OR (#{Project.allowed_to_condition(user, :view_private_notes, *args)}))", false)
|
| 48 |
} |
| 49 |
|
| 50 |
def save(*args) |
| 51 |
# Do not save an empty journal |
| 52 |
(details.empty? && notes.blank?) ? false : super |
| 53 |
end |
| 54 |
|
| 55 |
# Returns the new status if the journal contains a status change, otherwise nil |
| 56 |
def new_status |
| 57 |
c = details.detect {|detail| detail.prop_key == 'status_id'}
|
| 58 |
(c && c.value) ? IssueStatus.find_by_id(c.value.to_i) : nil |
| 59 |
end |
| 60 |
|
| 61 |
def new_value_for(prop) |
| 62 |
c = details.detect {|detail| detail.prop_key == prop}
|
| 63 |
c ? c.value : nil |
| 64 |
end |
| 65 |
|
| 66 |
def editable_by?(usr) |
| 67 |
usr && usr.logged? && (usr.allowed_to?(:edit_issue_notes, project) || (self.user == usr && usr.allowed_to?(:edit_own_issue_notes, project))) |
| 68 |
end |
| 69 |
|
| 70 |
def project |
| 71 |
journalized.respond_to?(:project) ? journalized.project : nil |
| 72 |
end |
| 73 |
|
| 74 |
def attachments |
| 75 |
journalized.respond_to?(:attachments) ? journalized.attachments : nil |
| 76 |
end |
| 77 |
|
| 78 |
# Returns a string of css classes |
| 79 |
def css_classes |
| 80 |
s = 'journal' |
| 81 |
s << ' has-notes' unless notes.blank? |
| 82 |
s << ' has-details' unless details.blank? |
| 83 |
s << ' private-notes' if private_notes? |
| 84 |
s |
| 85 |
end |
| 86 |
|
| 87 |
def notify? |
| 88 |
@notify != false |
| 89 |
end |
| 90 |
|
| 91 |
def notify=(arg) |
| 92 |
@notify = arg |
| 93 |
end |
| 94 |
|
| 95 |
def recipients |
| 96 |
notified = journalized.notified_users |
| 97 |
if private_notes? |
| 98 |
notified = notified.select {|user| user.allowed_to?(:view_private_notes, journalized.project)}
|
| 99 |
end |
| 100 |
notified.map(&:mail) |
| 101 |
end |
| 102 |
|
| 103 |
def watcher_recipients |
| 104 |
notified = journalized.notified_watchers |
| 105 |
if private_notes? |
| 106 |
notified = notified.select {|user| user.allowed_to?(:view_private_notes, journalized.project)}
|
| 107 |
end |
| 108 |
notified.map(&:mail) |
| 109 |
end |
| 110 |
|
| 111 |
private |
| 112 |
|
| 113 |
def split_private_notes |
| 114 |
if private_notes? |
| 115 |
if notes.present? |
| 116 |
if details.any? |
| 117 |
# Split the journal (notes/changes) so we don't have half-private journals |
| 118 |
journal = Journal.new(:journalized => journalized, :user => user, :notes => nil, :private_notes => false) |
| 119 |
journal.details = details |
| 120 |
journal.save |
| 121 |
self.details = [] |
| 122 |
self.created_on = journal.created_on |
| 123 |
end |
| 124 |
else |
| 125 |
# Blank notes should not be private |
| 126 |
self.private_notes = false |
| 127 |
end |
| 128 |
end |
| 129 |
true |
| 130 |
end |
| 131 |
end |