Class: Journal

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

Overview

Redmine - project management software Copyright (C) 2006-2014 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

Constructor Details

#initialize(*args) ⇒ Journal

Returns a new instance of Journal



53
54
55
56
57
58
59
60
61
62
# File 'app/models/journal.rb', line 53

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



26
27
28
# File 'app/models/journal.rb', line 26

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



166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'app/models/journal.rb', line 166

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



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

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

#css_classesObject

Returns a string of css classes



125
126
127
128
129
130
131
# File 'app/models/journal.rb', line 125

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



98
99
100
# File 'app/models/journal.rb', line 98

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

#each_notification(users, &block) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
# File 'app/models/journal.rb', line 83

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)


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

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



197
198
199
200
201
202
203
204
# File 'app/models/journal.rb', line 197

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



207
208
209
210
211
212
213
214
# File 'app/models/journal.rb', line 207

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



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

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

#new_value_for(prop) ⇒ Object



108
109
110
# File 'app/models/journal.rb', line 108

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

#notified_usersObject



141
142
143
144
145
146
147
# File 'app/models/journal.rb', line 141

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



153
154
155
156
157
158
159
# File 'app/models/journal.rb', line 153

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



137
138
139
# File 'app/models/journal.rb', line 137

def notify=(arg)
  @notify = arg
end

#notify?Boolean

Returns:

  • (Boolean)


133
134
135
# File 'app/models/journal.rb', line 133

def notify?
  @notify != false
end

#projectObject



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

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

#recipientsObject



149
150
151
# File 'app/models/journal.rb', line 149

def recipients
  notified_users.map(&:mail)
end

#save(*args) ⇒ Object



64
65
66
67
68
# File 'app/models/journal.rb', line 64

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



182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'app/models/journal.rb', line 182

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



71
72
73
74
75
76
77
78
79
80
81
# File 'app/models/journal.rb', line 71

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



161
162
163
# File 'app/models/journal.rb', line 161

def watcher_recipients
  notified_watchers.map(&:mail)
end