Class: Journal

Inherits:
ActiveRecord::Base
  • Object
show all
Includes:
Redmine::SafeAttributes
Defined in:
app/models/journal.rb

Overview

Redmine - project management software Copyright (C) 2006-2016 Jean-Philippe Lang

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Redmine::SafeAttributes

#delete_unsafe_attributes, included, #safe_attribute?, #safe_attribute_names, #safe_attributes=

Constructor Details

#initialize(*args) ⇒ Journal

Returns a new instance of Journal



60
61
62
63
64
65
66
67
68
69
# File 'app/models/journal.rb', line 60

def initialize(*args)
  super
  if journalized
    if journalized.new_record?
      self.notify = false
    else
      start
    end
  end
end

Instance Attribute Details

#indiceObject

Returns the value of attribute indice



28
29
30
# File 'app/models/journal.rb', line 28

def indice
  @indice
end

Class Method Details

.preload_journals_details_custom_fields(journals) ⇒ Object

Sets @custom_field instance variable on journals details using a single query



173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'app/models/journal.rb', line 173

def self.preload_journals_details_custom_fields(journals)
  field_ids = journals.map(&:details).flatten.select {|d| d.property == 'cf'}.map(&:prop_key).uniq
  if field_ids.any?
    fields_by_id = CustomField.where(:id => field_ids).inject({}) {|h, f| h[f.id] = f; h}
    journals.each do |journal|
      journal.details.each do |detail|
        if detail.property == 'cf'
          detail.instance_variable_set "@custom_field", fields_by_id[detail.prop_key.to_i]
        end
      end
    end
  end
  journals
end

Instance Method Details

#attachmentsObject



127
128
129
# File 'app/models/journal.rb', line 127

def attachments
  journalized.respond_to?(:attachments) ? journalized.attachments : []
end

#css_classesObject

Returns a string of css classes



132
133
134
135
136
137
138
# File 'app/models/journal.rb', line 132

def css_classes
  s = 'journal'
  s << ' has-notes' unless notes.blank?
  s << ' has-details' unless details.blank?
  s << ' private-notes' if private_notes?
  s
end

#detail_for_attribute(attribute) ⇒ Object

Returns the JournalDetail for the given attribute, or nil if the attribute was not updated



105
106
107
# File 'app/models/journal.rb', line 105

def detail_for_attribute(attribute)
  details.detect {|detail| detail.prop_key == attribute}
end

#each_notification(users, &block) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
# File 'app/models/journal.rb', line 90

def each_notification(users, &block)
  if users.any?
    users_by_details_visibility = users.group_by do |user|
      visible_details(user)
    end
    users_by_details_visibility.each do |visible_details, users|
      if notes? || visible_details.any?
        yield(users)
      end
    end
  end
end

#editable_by?(usr) ⇒ Boolean

Returns:

  • (Boolean)


119
120
121
# File 'app/models/journal.rb', line 119

def editable_by?(usr)
  usr && usr.logged? && (usr.allowed_to?(:edit_issue_notes, project) || (self.user == usr && usr.allowed_to?(:edit_own_issue_notes, project)))
end

#journalize_attachment(attachment, added_or_removed) ⇒ Object

Adds a journal detail for an attachment that was added or removed



204
205
206
207
208
209
210
211
# File 'app/models/journal.rb', line 204

def journalize_attachment(attachment, added_or_removed)
  key = (added_or_removed == :removed ? :old_value : :value)
  details << JournalDetail.new(
      :property => 'attachment',
      :prop_key => attachment.id,
      key => attachment.filename
    )
end

#journalize_relation(relation, added_or_removed) ⇒ Object

Adds a journal detail for an issue relation that was added or removed



214
215
216
217
218
219
220
221
# File 'app/models/journal.rb', line 214

def journalize_relation(relation, added_or_removed)
  key = (added_or_removed == :removed ? :old_value : :value)
  details << JournalDetail.new(
      :property  => 'relation',
      :prop_key  => relation.relation_type_for(journalized),
      key => relation.other_issue(journalized).try(:id)
    )
end

#new_statusObject

Returns the new status if the journal contains a status change, otherwise nil



110
111
112
113
# File 'app/models/journal.rb', line 110

def new_status
  s = new_value_for('status_id')
  s ? IssueStatus.find_by_id(s.to_i) : nil
end

#new_value_for(prop) ⇒ Object



115
116
117
# File 'app/models/journal.rb', line 115

def new_value_for(prop)
  detail_for_attribute(prop).try(:value)
end

#notified_usersObject



148
149
150
151
152
153
154
# File 'app/models/journal.rb', line 148

def notified_users
  notified = journalized.notified_users
  if private_notes?
    notified = notified.select {|user| user.allowed_to?(:view_private_notes, journalized.project)}
  end
  notified
end

#notified_watchersObject



160
161
162
163
164
165
166
# File 'app/models/journal.rb', line 160

def notified_watchers
  notified = journalized.notified_watchers
  if private_notes?
    notified = notified.select {|user| user.allowed_to?(:view_private_notes, journalized.project)}
  end
  notified
end

#notify=(arg) ⇒ Object



144
145
146
# File 'app/models/journal.rb', line 144

def notify=(arg)
  @notify = arg
end

#notify?Boolean

Returns:

  • (Boolean)


140
141
142
# File 'app/models/journal.rb', line 140

def notify?
  @notify != false
end

#projectObject



123
124
125
# File 'app/models/journal.rb', line 123

def project
  journalized.respond_to?(:project) ? journalized.project : nil
end

#recipientsObject



156
157
158
# File 'app/models/journal.rb', line 156

def recipients
  notified_users.map(&:mail)
end

#save(*args) ⇒ Object



71
72
73
74
75
# File 'app/models/journal.rb', line 71

def save(*args)
  journalize_changes
  # Do not save an empty journal
  (details.empty? && notes.blank?) ? false : super
end

#startObject

Stores the values of the attributes and custom fields of the journalized object



189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'app/models/journal.rb', line 189

def start
  if journalized
    @attributes_before_change = journalized.journalized_attribute_names.inject({}) do |h, attribute|
      h[attribute] = journalized.send(attribute)
      h
    end
    @custom_values_before_change = journalized.custom_field_values.inject({}) do |h, c|
      h[c.custom_field_id] = c.value
      h
    end
  end
  self
end

#visible_details(user = User.current) ⇒ Object

Returns journal details that are visible to user



78
79
80
81
82
83
84
85
86
87
88
# File 'app/models/journal.rb', line 78

def visible_details(user=User.current)
  details.select do |detail|
    if detail.property == 'cf'
      detail.custom_field && detail.custom_field.visible_by?(project, user)
    elsif detail.property == 'relation'
      Issue.find_by_id(detail.value || detail.old_value).try(:visible?, user)
    else
      true
    end
  end
end

#watcher_recipientsObject



168
169
170
# File 'app/models/journal.rb', line 168

def watcher_recipients
  notified_watchers.map(&:mail)
end