1
|
# Redmine - project management software
|
2
|
# Copyright (C) 2006-2014 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 Mailer < ActionMailer::Base
|
19
|
layout 'mailer'
|
20
|
helper :application
|
21
|
helper :issues
|
22
|
helper :custom_fields
|
23
|
|
24
|
include Redmine::I18n
|
25
|
|
26
|
#antropoff begin
|
27
|
TYPE_REJECT = 1
|
28
|
TYPE_CREATE = 2
|
29
|
TYPE_NOTE = 3
|
30
|
TYPE_CLOSE = 4
|
31
|
TYPE_CANCEL = 5
|
32
|
TYPE_ANALYSIS = 6
|
33
|
TYPE_WORK = 7
|
34
|
TYPE_REJECT2 = 8
|
35
|
|
36
|
TRACK_SUPPORT = 3
|
37
|
#antropoff end
|
38
|
|
39
|
def self.default_url_options
|
40
|
{ :host => Setting.host_name, :protocol => Setting.protocol }
|
41
|
end
|
42
|
|
43
|
# Builds a mail for notifying to_users and cc_users about a new issue
|
44
|
def issue_add(issue, to_users, cc_users)
|
45
|
#antropoff begin
|
46
|
if (issue.tracker_id==TRACK_SUPPORT)
|
47
|
to_users = support_send_to_users(issue, to_users, TYPE_CREATE)
|
48
|
cc_users = support_send_to_users(issue, cc_users, TYPE_CREATE)
|
49
|
end
|
50
|
#antropoff end
|
51
|
redmine_headers 'Project' => issue.project.identifier,
|
52
|
'Issue-Id' => issue.id,
|
53
|
'Issue-Author' => issue.author.login
|
54
|
redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
|
55
|
message_id issue
|
56
|
references issue
|
57
|
@author = issue.author
|
58
|
@issue = issue
|
59
|
@users = to_users + cc_users
|
60
|
@issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue)
|
61
|
mail :to => to_users.map(&:mail),
|
62
|
:cc => cc_users.map(&:mail),
|
63
|
:subject => "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] (#{issue.status.name}) #{issue.subject}"
|
64
|
end
|
65
|
|
66
|
# Notifies users about a new issue
|
67
|
def self.deliver_issue_add(issue)
|
68
|
to = issue.notified_users
|
69
|
#antropoff begin
|
70
|
if (issue.tracker_id==TRACK_SUPPORT)
|
71
|
Rails.logger.info "deliver_issue_add: to=[#{to}] (before)"
|
72
|
Rails.logger.info "deliver_issue_add: issue.project.members=[#{issue.project.members}]"
|
73
|
issue.project.members.each do |mem|
|
74
|
usr = User.find_by_id(mem.user_id)
|
75
|
Rails.logger.info "deliver_issue_add: mem=[#{usr}]"
|
76
|
if usr.is_support?(issue.project)
|
77
|
Rails.logger.info "deliver_issue_add: >>>added support member!"
|
78
|
to << usr
|
79
|
end
|
80
|
end
|
81
|
to.uniq!
|
82
|
Rails.logger.info "deliver_issue_add: to=[#{to}] (after)"
|
83
|
end
|
84
|
#antropoff end
|
85
|
cc = issue.notified_watchers - to
|
86
|
issue.each_notification(to + cc) do |users|
|
87
|
Mailer.issue_add(issue, to & users, cc & users).deliver
|
88
|
end
|
89
|
end
|
90
|
|
91
|
# Builds a mail for notifying to_users and cc_users about an issue update
|
92
|
def issue_edit(journal, to_users, cc_users)
|
93
|
issue = journal.journalized
|
94
|
#antropoff begin
|
95
|
if (issue.tracker_id==TRACK_SUPPORT)
|
96
|
Rails.logger.info "issue_edit: journal.notes=[#{journal.notes}]"
|
97
|
Rails.logger.info "issue_edit: journal.attachments=[#{journal.attachments}]"
|
98
|
Rails.logger.info "issue_edit: journal.new_value_for('status_id')=[#{journal.new_value_for('status_id')}]"
|
99
|
|
100
|
the_notes = ""
|
101
|
if journal.notes && journal.notes.to_s.strip!=""
|
102
|
the_notes = journal.notes
|
103
|
end
|
104
|
attchs = nil
|
105
|
if journal.attachments && journal.attachments.length>0
|
106
|
attchs = journal.attachments
|
107
|
end
|
108
|
|
109
|
Rails.logger.info "issue_edit: attachments=[#{attachments}]"
|
110
|
Rails.logger.info "issue_edit: attchs=[#{attchs}]"
|
111
|
if (attchs && attchs.size > 0)
|
112
|
attchs.each do |att|
|
113
|
fnam = att['filename']
|
114
|
dnam = att['disk_filename']
|
115
|
ddir = att['disk_directory']
|
116
|
full = "c:/Ruby193/apps/redmine-2.5.2/files/"+ddir+"/"+dnam
|
117
|
Rails.logger.info ">>>file: filename=[#{fnam}] diskname=[#{dnam}] ddir=[#{ddir}] full=[#{full}]"
|
118
|
if (File.exists?(full))
|
119
|
# attachments[File.basename(full)] = File.read(full, mode: 'rb')
|
120
|
attachments[fnam] = File.read(full, mode: 'rb')
|
121
|
end
|
122
|
end
|
123
|
end
|
124
|
Rails.logger.info "issue_edit: attachments=[#{attachments}] (count: #{attachments.size})"
|
125
|
|
126
|
if journal.new_value_for('status_id')
|
127
|
case issue.status.id
|
128
|
when 2 #work
|
129
|
support_send_to_users(issue, to_users, TYPE_WORK, the_notes, journal)
|
130
|
support_send_to_users(issue, cc_users, TYPE_WORK, the_notes, journal)
|
131
|
when 5 #closed
|
132
|
support_send_to_users(issue, to_users, TYPE_CLOSE, the_notes, journal)
|
133
|
support_send_to_users(issue, cc_users, TYPE_CLOSE, the_notes, journal)
|
134
|
when 6 #canceled
|
135
|
support_send_to_users(issue, to_users, TYPE_CANCEL, the_notes, journal)
|
136
|
support_send_to_users(issue, cc_users, TYPE_CANCEL, the_notes, journal)
|
137
|
when 10 #analysis
|
138
|
support_send_to_users(issue, to_users, TYPE_ANALYSIS, the_notes, journal)
|
139
|
support_send_to_users(issue, cc_users, TYPE_ANALYSIS, the_notes, journal)
|
140
|
else
|
141
|
if (the_notes.strip!="")
|
142
|
support_send_to_users(issue, to_users, TYPE_NOTE, the_notes, journal)
|
143
|
support_send_to_users(issue, cc_users, TYPE_NOTE, the_notes, journal)
|
144
|
end
|
145
|
end
|
146
|
else
|
147
|
if (the_notes.strip!="")
|
148
|
support_send_to_users(issue, to_users, TYPE_NOTE, the_notes, journal)
|
149
|
support_send_to_users(issue, cc_users, TYPE_NOTE, the_notes, journal)
|
150
|
end
|
151
|
end
|
152
|
to_users.reject! {|usr| usr.is_support?(issue.project)}
|
153
|
to_users.compact!
|
154
|
cc_users.reject! {|usr| usr.is_support?(issue.project)}
|
155
|
cc_users.compact!
|
156
|
end
|
157
|
#antropoff end
|
158
|
redmine_headers 'Project' => issue.project.identifier,
|
159
|
'Issue-Id' => issue.id,
|
160
|
'Issue-Author' => issue.author.login
|
161
|
redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
|
162
|
message_id journal
|
163
|
references issue
|
164
|
@author = journal.user
|
165
|
s = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] "
|
166
|
s << "(#{issue.status.name}) " if journal.new_value_for('status_id')
|
167
|
s << issue.subject
|
168
|
@issue = issue
|
169
|
@users = to_users + cc_users
|
170
|
@journal = journal
|
171
|
@journal_details = journal.visible_details(@users.first)
|
172
|
@issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue, :anchor => "change-#{journal.id}")
|
173
|
mail :to => to_users.map(&:mail),
|
174
|
:cc => cc_users.map(&:mail),
|
175
|
:subject => s
|
176
|
end
|
177
|
|
178
|
# Notifies users about an issue update
|
179
|
def self.deliver_issue_edit(journal)
|
180
|
issue = journal.journalized.reload
|
181
|
to = journal.notified_users
|
182
|
#antropoff begin
|
183
|
if (issue.tracker_id==TRACK_SUPPORT)
|
184
|
Rails.logger.info "deliver_issue_edit: to=[#{to}] (before)"
|
185
|
Rails.logger.info "deliver_issue_edit: issue.project.members=[#{issue.project.members}]"
|
186
|
issue.project.members.each do |mem|
|
187
|
usr = User.find_by_id(mem.user_id)
|
188
|
Rails.logger.info "deliver_issue_edit: mem=[#{usr}]"
|
189
|
if usr.is_support?(issue.project)
|
190
|
Rails.logger.info "deliver_issue_edit: >>>added support member!"
|
191
|
to << usr
|
192
|
end
|
193
|
end
|
194
|
to.uniq!
|
195
|
Rails.logger.info "deliver_issue_edit: to=[#{to}] (after)"
|
196
|
end
|
197
|
#antropoff end
|
198
|
|
199
|
cc = journal.notified_watchers - to
|
200
|
journal.each_notification(to + cc) do |users|
|
201
|
issue.each_notification(users) do |users2|
|
202
|
Mailer.issue_edit(journal, to & users2, cc & users2).deliver
|
203
|
end
|
204
|
end
|
205
|
end
|
206
|
|
207
|
def reminder(user, issues, days)
|
208
|
set_language_if_valid user.language
|
209
|
@issues = issues
|
210
|
@days = days
|
211
|
@issues_url = url_for(:controller => 'issues', :action => 'index',
|
212
|
:set_filter => 1, :assigned_to_id => user.id,
|
213
|
:sort => 'due_date:asc')
|
214
|
mail :to => user.mail,
|
215
|
:subject => l(:mail_subject_reminder, :count => issues.size, :days => days)
|
216
|
end
|
217
|
|
218
|
# Builds a Mail::Message object used to email users belonging to the added document's project.
|
219
|
#
|
220
|
# Example:
|
221
|
# document_added(document) => Mail::Message object
|
222
|
# Mailer.document_added(document).deliver => sends an email to the document's project recipients
|
223
|
def document_added(document)
|
224
|
redmine_headers 'Project' => document.project.identifier
|
225
|
@author = User.current
|
226
|
@document = document
|
227
|
@document_url = url_for(:controller => 'documents', :action => 'show', :id => document)
|
228
|
mail :to => document.recipients,
|
229
|
:subject => "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
|
230
|
end
|
231
|
|
232
|
# Builds a Mail::Message object used to email recipients of a project when an attachements are added.
|
233
|
#
|
234
|
# Example:
|
235
|
# attachments_added(attachments) => Mail::Message object
|
236
|
# Mailer.attachments_added(attachments).deliver => sends an email to the project's recipients
|
237
|
def attachments_added(attachments)
|
238
|
Rails.logger.info "attachments_added: attachments=[#{attachments}]"
|
239
|
container = attachments.first.container
|
240
|
added_to = ''
|
241
|
added_to_url = ''
|
242
|
@author = attachments.first.author
|
243
|
case container.class.name
|
244
|
when 'Project'
|
245
|
added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container)
|
246
|
added_to = "#{l(:label_project)}: #{container}"
|
247
|
recipients = container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}.collect {|u| u.mail}
|
248
|
when 'Version'
|
249
|
added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container.project)
|
250
|
added_to = "#{l(:label_version)}: #{container.name}"
|
251
|
recipients = container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}.collect {|u| u.mail}
|
252
|
when 'Document'
|
253
|
added_to_url = url_for(:controller => 'documents', :action => 'show', :id => container.id)
|
254
|
added_to = "#{l(:label_document)}: #{container.title}"
|
255
|
recipients = container.recipients
|
256
|
end
|
257
|
redmine_headers 'Project' => container.project.identifier
|
258
|
@attachments = attachments
|
259
|
@added_to = added_to
|
260
|
@added_to_url = added_to_url
|
261
|
mail :to => recipients,
|
262
|
:subject => "[#{container.project.name}] #{l(:label_attachment_new)}"
|
263
|
end
|
264
|
|
265
|
# Builds a Mail::Message object used to email recipients of a news' project when a news item is added.
|
266
|
#
|
267
|
# Example:
|
268
|
# news_added(news) => Mail::Message object
|
269
|
# Mailer.news_added(news).deliver => sends an email to the news' project recipients
|
270
|
def news_added(news)
|
271
|
redmine_headers 'Project' => news.project.identifier
|
272
|
@author = news.author
|
273
|
message_id news
|
274
|
references news
|
275
|
@news = news
|
276
|
@news_url = url_for(:controller => 'news', :action => 'show', :id => news)
|
277
|
mail :to => news.recipients,
|
278
|
:cc => news.cc_for_added_news,
|
279
|
:subject => "[#{news.project.name}] #{l(:label_news)}: #{news.title}"
|
280
|
end
|
281
|
|
282
|
# Builds a Mail::Message object used to email recipients of a news' project when a news comment is added.
|
283
|
#
|
284
|
# Example:
|
285
|
# news_comment_added(comment) => Mail::Message object
|
286
|
# Mailer.news_comment_added(comment) => sends an email to the news' project recipients
|
287
|
def news_comment_added(comment)
|
288
|
news = comment.commented
|
289
|
redmine_headers 'Project' => news.project.identifier
|
290
|
@author = comment.author
|
291
|
message_id comment
|
292
|
references news
|
293
|
@news = news
|
294
|
@comment = comment
|
295
|
@news_url = url_for(:controller => 'news', :action => 'show', :id => news)
|
296
|
mail :to => news.recipients,
|
297
|
:cc => news.watcher_recipients,
|
298
|
:subject => "Re: [#{news.project.name}] #{l(:label_news)}: #{news.title}"
|
299
|
end
|
300
|
|
301
|
# Builds a Mail::Message object used to email the recipients of the specified message that was posted.
|
302
|
#
|
303
|
# Example:
|
304
|
# message_posted(message) => Mail::Message object
|
305
|
# Mailer.message_posted(message).deliver => sends an email to the recipients
|
306
|
def message_posted(message)
|
307
|
redmine_headers 'Project' => message.project.identifier,
|
308
|
'Topic-Id' => (message.parent_id || message.id)
|
309
|
@author = message.author
|
310
|
message_id message
|
311
|
references message.root
|
312
|
recipients = message.recipients
|
313
|
cc = ((message.root.watcher_recipients + message.board.watcher_recipients).uniq - recipients)
|
314
|
@message = message
|
315
|
@message_url = url_for(message.event_url)
|
316
|
mail :to => recipients,
|
317
|
:cc => cc,
|
318
|
:subject => "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] #{message.subject}"
|
319
|
end
|
320
|
|
321
|
# Builds a Mail::Message object used to email the recipients of a project of the specified wiki content was added.
|
322
|
#
|
323
|
# Example:
|
324
|
# wiki_content_added(wiki_content) => Mail::Message object
|
325
|
# Mailer.wiki_content_added(wiki_content).deliver => sends an email to the project's recipients
|
326
|
def wiki_content_added(wiki_content)
|
327
|
redmine_headers 'Project' => wiki_content.project.identifier,
|
328
|
'Wiki-Page-Id' => wiki_content.page.id
|
329
|
@author = wiki_content.author
|
330
|
message_id wiki_content
|
331
|
recipients = wiki_content.recipients
|
332
|
cc = wiki_content.page.wiki.watcher_recipients - recipients
|
333
|
@wiki_content = wiki_content
|
334
|
@wiki_content_url = url_for(:controller => 'wiki', :action => 'show',
|
335
|
:project_id => wiki_content.project,
|
336
|
:id => wiki_content.page.title)
|
337
|
mail :to => recipients,
|
338
|
:cc => cc,
|
339
|
:subject => "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_added, :id => wiki_content.page.pretty_title)}"
|
340
|
end
|
341
|
|
342
|
# Builds a Mail::Message object used to email the recipients of a project of the specified wiki content was updated.
|
343
|
#
|
344
|
# Example:
|
345
|
# wiki_content_updated(wiki_content) => Mail::Message object
|
346
|
# Mailer.wiki_content_updated(wiki_content).deliver => sends an email to the project's recipients
|
347
|
def wiki_content_updated(wiki_content)
|
348
|
redmine_headers 'Project' => wiki_content.project.identifier,
|
349
|
'Wiki-Page-Id' => wiki_content.page.id
|
350
|
@author = wiki_content.author
|
351
|
message_id wiki_content
|
352
|
recipients = wiki_content.recipients
|
353
|
cc = wiki_content.page.wiki.watcher_recipients + wiki_content.page.watcher_recipients - recipients
|
354
|
@wiki_content = wiki_content
|
355
|
@wiki_content_url = url_for(:controller => 'wiki', :action => 'show',
|
356
|
:project_id => wiki_content.project,
|
357
|
:id => wiki_content.page.title)
|
358
|
@wiki_diff_url = url_for(:controller => 'wiki', :action => 'diff',
|
359
|
:project_id => wiki_content.project, :id => wiki_content.page.title,
|
360
|
:version => wiki_content.version)
|
361
|
mail :to => recipients,
|
362
|
:cc => cc,
|
363
|
:subject => "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_updated, :id => wiki_content.page.pretty_title)}"
|
364
|
end
|
365
|
|
366
|
# Builds a Mail::Message object used to email the specified user their account information.
|
367
|
#
|
368
|
# Example:
|
369
|
# account_information(user, password) => Mail::Message object
|
370
|
# Mailer.account_information(user, password).deliver => sends account information to the user
|
371
|
def account_information(user, password)
|
372
|
set_language_if_valid user.language
|
373
|
@user = user
|
374
|
@password = password
|
375
|
@login_url = url_for(:controller => 'account', :action => 'login')
|
376
|
mail :to => user.mail,
|
377
|
:subject => l(:mail_subject_register, Setting.app_title)
|
378
|
end
|
379
|
|
380
|
# Builds a Mail::Message object used to email all active administrators of an account activation request.
|
381
|
#
|
382
|
# Example:
|
383
|
# account_activation_request(user) => Mail::Message object
|
384
|
# Mailer.account_activation_request(user).deliver => sends an email to all active administrators
|
385
|
def account_activation_request(user)
|
386
|
# Send the email to all active administrators
|
387
|
recipients = User.active.where(:admin => true).collect { |u| u.mail }.compact
|
388
|
@user = user
|
389
|
@url = url_for(:controller => 'users', :action => 'index',
|
390
|
:status => User::STATUS_REGISTERED,
|
391
|
:sort_key => 'created_on', :sort_order => 'desc')
|
392
|
mail :to => recipients,
|
393
|
:subject => l(:mail_subject_account_activation_request, Setting.app_title)
|
394
|
end
|
395
|
|
396
|
# Builds a Mail::Message object used to email the specified user that their account was activated by an administrator.
|
397
|
#
|
398
|
# Example:
|
399
|
# account_activated(user) => Mail::Message object
|
400
|
# Mailer.account_activated(user).deliver => sends an email to the registered user
|
401
|
def account_activated(user)
|
402
|
set_language_if_valid user.language
|
403
|
@user = user
|
404
|
@login_url = url_for(:controller => 'account', :action => 'login')
|
405
|
mail :to => user.mail,
|
406
|
:subject => l(:mail_subject_register, Setting.app_title)
|
407
|
end
|
408
|
|
409
|
def lost_password(token)
|
410
|
set_language_if_valid(token.user.language)
|
411
|
@token = token
|
412
|
@url = url_for(:controller => 'account', :action => 'lost_password', :token => token.value)
|
413
|
mail :to => token.user.mail,
|
414
|
:subject => l(:mail_subject_lost_password, Setting.app_title)
|
415
|
end
|
416
|
|
417
|
def register(token)
|
418
|
set_language_if_valid(token.user.language)
|
419
|
@token = token
|
420
|
@url = url_for(:controller => 'account', :action => 'activate', :token => token.value)
|
421
|
mail :to => token.user.mail,
|
422
|
:subject => l(:mail_subject_register, Setting.app_title)
|
423
|
end
|
424
|
|
425
|
def test_email(user)
|
426
|
set_language_if_valid(user.language)
|
427
|
@url = url_for(:controller => 'welcome')
|
428
|
mail :to => user.mail,
|
429
|
:subject => 'Redmine test'
|
430
|
end
|
431
|
|
432
|
#antropoff begin
|
433
|
def support_reject(user,subj,msg)
|
434
|
set_language_if_valid(user.language)
|
435
|
@pre = l(:support_mail_reject_pre)
|
436
|
@subj = subj
|
437
|
@post = l(:support_mail_reject_post)
|
438
|
if (msg && msg.strip!="")
|
439
|
@txt = l(:support_mail_reject_txt)
|
440
|
@msg = msg
|
441
|
end
|
442
|
mail :to => user.mail, :subject => l(:support_mail_reject_subj), 'NeedChangeFrom' => true
|
443
|
end
|
444
|
|
445
|
def support_reject2(user,issue)
|
446
|
set_language_if_valid(user.language)
|
447
|
@pre = l(:support_mail_reject2_pre)
|
448
|
@iid = "#"+issue.id.to_s
|
449
|
@post = l(:support_mail_reject2_post)
|
450
|
mail :to => user.mail, :subject => l(:support_mail_reject2_subj), 'NeedChangeFrom' => true
|
451
|
end
|
452
|
|
453
|
def support_create(user,issue)
|
454
|
set_language_if_valid(user.language)
|
455
|
@iid = "#"+issue.id.to_s
|
456
|
@pre = l(:support_mail_create_pre)
|
457
|
@subj = issue.subject
|
458
|
@post = l(:support_mail_create_post)
|
459
|
@avt = "#{l(:support_mail_create_avt)}: #{issue.author}"
|
460
|
@txt = l(:support_mail_create_txt)
|
461
|
mail :to => user.mail, :subject => "##{issue.id.to_s}: #{l(:support_mail_create_subj)}", 'NeedChangeFrom' => true
|
462
|
end
|
463
|
|
464
|
def support_work(user,issue,msg,att)
|
465
|
set_language_if_valid(user.language)
|
466
|
@iid = "#"+issue.id.to_s
|
467
|
@pre = l(:support_mail_work_pre)
|
468
|
@subj = issue.subject
|
469
|
@post = l(:support_mail_work_post)
|
470
|
@avt = "#{l(:support_mail_work_avt)}: #{issue.author}"
|
471
|
@who = "#{l(:support_mail_work_who)}: #{issue.assigned_to}"
|
472
|
if (msg && msg.strip!="")
|
473
|
@txt = l(:support_mail_work_txt)
|
474
|
@msg = msg
|
475
|
end
|
476
|
mail :to => user.mail, :subject => "##{issue.id.to_s}: #{l(:support_mail_work_subj)}", 'NeedChangeFrom' => true
|
477
|
end
|
478
|
|
479
|
def support_note(user,issue,msg,journal)
|
480
|
set_language_if_valid(user.language)
|
481
|
|
482
|
redmine_headers 'Project' => issue.project.identifier,
|
483
|
'Issue-Id' => issue.id,
|
484
|
'Issue-Author' => issue.author.login
|
485
|
redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
|
486
|
message_id journal
|
487
|
references issue
|
488
|
# @author = journal.user
|
489
|
# s = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] "
|
490
|
# s << "(#{issue.status.name}) " if journal.new_value_for('status_id')
|
491
|
# s << issue.subject
|
492
|
# @issue = issue
|
493
|
# @users = to_users + cc_users
|
494
|
# @journal = journal
|
495
|
# @journal_details = journal.visible_details(@users.first)
|
496
|
# @issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue, :anchor => "change-#{journal.id}")
|
497
|
|
498
|
@iid = "#"+issue.id.to_s
|
499
|
@pre = l(:support_mail_note_pre)
|
500
|
@subj = issue.subject
|
501
|
@post = l(:support_mail_note_post)
|
502
|
@avt = "#{l(:support_mail_note_avt)}: #{issue.author}"
|
503
|
@who = "#{l(:support_mail_note_who)}: #{User.current}"
|
504
|
if (msg && msg.strip!="")
|
505
|
@txt = l(:support_mail_note_txt)
|
506
|
@msg = msg
|
507
|
end
|
508
|
mail :to => user.mail, :subject => "##{issue.id.to_s}: #{l(:support_mail_note_subj)}", 'NeedChangeFrom' => true
|
509
|
end
|
510
|
|
511
|
def support_close(user,issue,msg,att)
|
512
|
set_language_if_valid(user.language)
|
513
|
@iid = "#"+issue.id.to_s
|
514
|
@pre = l(:support_mail_close_pre)
|
515
|
@subj = issue.subject
|
516
|
@post = l(:support_mail_close_post)
|
517
|
@avt = "#{l(:support_mail_close_avt)}: #{issue.author}"
|
518
|
@who = "#{l(:support_mail_close_who)}: #{User.current}"
|
519
|
if (msg && msg.strip!="")
|
520
|
@txt = l(:support_mail_close_txt)
|
521
|
@msg = msg
|
522
|
end
|
523
|
mail :to => user.mail, :subject => "##{issue.id.to_s}: #{l(:support_mail_close_subj)}", 'NeedChangeFrom' => true
|
524
|
end
|
525
|
|
526
|
def support_cancel(user,issue,msg,att)
|
527
|
set_language_if_valid(user.language)
|
528
|
@iid = "#"+issue.id.to_s
|
529
|
@pre = l(:support_mail_cancel_pre)
|
530
|
@subj = issue.subject
|
531
|
@post = l(:support_mail_cancel_post)
|
532
|
@avt = "#{l(:support_mail_cancel_avt)}: #{issue.author}"
|
533
|
@who = "#{l(:support_mail_cancel_who)}: #{User.current}"
|
534
|
if (msg && msg.strip!="")
|
535
|
@txt = l(:support_mail_cancel_txt)
|
536
|
@msg = msg
|
537
|
end
|
538
|
mail :to => user.mail, :subject => "##{issue.id.to_s}: #{l(:support_mail_cancel_subj)}", 'NeedChangeFrom' => true
|
539
|
end
|
540
|
|
541
|
def support_analysis(user,issue,msg,att)
|
542
|
set_language_if_valid(user.language)
|
543
|
@iid = "#"+issue.id.to_s
|
544
|
@pre = l(:support_mail_analysis_pre)
|
545
|
@subj = issue.subject
|
546
|
@post = l(:support_mail_analysis_post)
|
547
|
@avt = "#{l(:support_mail_analysis_avt)}: #{issue.author}"
|
548
|
@who = "#{l(:support_mail_analysis_who)}: #{User.current}"
|
549
|
if (msg && msg.strip!="")
|
550
|
@txt = l(:support_mail_analysis_txt)
|
551
|
@msg = msg
|
552
|
end
|
553
|
mail :to => user.mail, :subject => "##{issue.id.to_s}: #{l(:support_mail_analysis_subj)}", 'NeedChangeFrom' => true
|
554
|
end
|
555
|
|
556
|
def support_send_to_users(issue, users_, type, notes="", journal)
|
557
|
Rails.logger.info "users: [#{users_}]"
|
558
|
users_n = Array.new
|
559
|
users_.each do |usr|
|
560
|
if usr.is_support?(issue.project)
|
561
|
Rails.logger.info ">>>usr: support (#{usr}) [#{issue.subject}], [#{issue.id}], type=#{type}"
|
562
|
if type == TYPE_CREATE
|
563
|
Mailer.support_create(usr, issue).deliver
|
564
|
Rails.logger.info "support_send_to_users: support_create notification was sended"
|
565
|
elsif type == TYPE_WORK
|
566
|
Mailer.support_work(usr, issue, notes).deliver
|
567
|
Rails.logger.info "support_send_to_users: support_work notification was sended"
|
568
|
elsif type == TYPE_NOTE
|
569
|
Mailer.support_note(usr, issue, notes, journal).deliver
|
570
|
Rails.logger.info "support_send_to_users: support_note notification was sended"
|
571
|
elsif type == TYPE_CLOSE
|
572
|
Mailer.support_close(usr, issue, notes).deliver
|
573
|
Rails.logger.info "support_send_to_users: support_close notification was sended"
|
574
|
elsif type == TYPE_CANCEL
|
575
|
Mailer.support_cancel(usr, issue, notes).deliver
|
576
|
Rails.logger.info "support_send_to_users: support_cancel notification was sended"
|
577
|
elsif type == TYPE_ANALYSIS
|
578
|
Mailer.support_analysis(usr, issue, notes).deliver
|
579
|
Rails.logger.info "support_send_to_users: support_analysis notification was sended"
|
580
|
else
|
581
|
Rails.logger.error "support_send_to_users: Unknown support-notification type (#{type})"
|
582
|
end
|
583
|
else
|
584
|
Rails.logger.info ">>>usr: not support (#{usr})"
|
585
|
users_n << usr
|
586
|
end
|
587
|
end
|
588
|
users_n.uniq!
|
589
|
Rails.logger.info "users_n: [#{users_n}]"
|
590
|
return users_n
|
591
|
end
|
592
|
#antropoff end
|
593
|
|
594
|
|
595
|
# Sends reminders to issue assignees
|
596
|
# Available options:
|
597
|
# * :days => how many days in the future to remind about (defaults to 7)
|
598
|
# * :tracker => id of tracker for filtering issues (defaults to all trackers)
|
599
|
# * :project => id or identifier of project to process (defaults to all projects)
|
600
|
# * :users => array of user/group ids who should be reminded
|
601
|
def self.reminders(options={})
|
602
|
days = options[:days] || 7
|
603
|
project = options[:project] ? Project.find(options[:project]) : nil
|
604
|
tracker = options[:tracker] ? Tracker.find(options[:tracker]) : nil
|
605
|
user_ids = options[:users]
|
606
|
|
607
|
scope = Issue.open.where("#{Issue.table_name}.assigned_to_id IS NOT NULL" +
|
608
|
" AND #{Project.table_name}.status = #{Project::STATUS_ACTIVE}" +
|
609
|
" AND #{Issue.table_name}.due_date <= ?", days.day.from_now.to_date
|
610
|
)
|
611
|
scope = scope.where(:assigned_to_id => user_ids) if user_ids.present?
|
612
|
scope = scope.where(:project_id => project.id) if project
|
613
|
scope = scope.where(:tracker_id => tracker.id) if tracker
|
614
|
issues_by_assignee = scope.includes(:status, :assigned_to, :project, :tracker).
|
615
|
group_by(&:assigned_to)
|
616
|
issues_by_assignee.keys.each do |assignee|
|
617
|
if assignee.is_a?(Group)
|
618
|
assignee.users.each do |user|
|
619
|
issues_by_assignee[user] ||= []
|
620
|
issues_by_assignee[user] += issues_by_assignee[assignee]
|
621
|
end
|
622
|
end
|
623
|
end
|
624
|
|
625
|
issues_by_assignee.each do |assignee, issues|
|
626
|
reminder(assignee, issues, days).deliver if assignee.is_a?(User) && assignee.active?
|
627
|
end
|
628
|
end
|
629
|
|
630
|
# Activates/desactivates email deliveries during +block+
|
631
|
def self.with_deliveries(enabled = true, &block)
|
632
|
was_enabled = ActionMailer::Base.perform_deliveries
|
633
|
ActionMailer::Base.perform_deliveries = !!enabled
|
634
|
yield
|
635
|
ensure
|
636
|
ActionMailer::Base.perform_deliveries = was_enabled
|
637
|
end
|
638
|
|
639
|
# Sends emails synchronously in the given block
|
640
|
def self.with_synched_deliveries(&block)
|
641
|
saved_method = ActionMailer::Base.delivery_method
|
642
|
if m = saved_method.to_s.match(%r{^async_(.+)$})
|
643
|
synched_method = m[1]
|
644
|
ActionMailer::Base.delivery_method = synched_method.to_sym
|
645
|
ActionMailer::Base.send "#{synched_method}_settings=", ActionMailer::Base.send("async_#{synched_method}_settings")
|
646
|
end
|
647
|
yield
|
648
|
ensure
|
649
|
ActionMailer::Base.delivery_method = saved_method
|
650
|
end
|
651
|
|
652
|
def mail(headers={}, &block)
|
653
|
headers.merge! 'X-Mailer' => 'Redmine',
|
654
|
'X-Redmine-Host' => Setting.host_name,
|
655
|
'X-Redmine-Site' => Setting.app_title,
|
656
|
'X-Auto-Response-Suppress' => 'OOF',
|
657
|
'Auto-Submitted' => 'auto-generated',
|
658
|
'From' => Setting.mail_from,
|
659
|
'List-Id' => "<#{Setting.mail_from.to_s.gsub('@', '.')}>"
|
660
|
#antropoff begin
|
661
|
if (headers['NeedChangeFrom'])
|
662
|
headers.merge! 'From' => "gatefaktura@r-style.com"
|
663
|
end
|
664
|
# Rails.logger.info "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
665
|
# Rails.logger.info "[#{headers}]"
|
666
|
# Rails.logger.info "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
|
667
|
#antropoff end
|
668
|
|
669
|
# Removes the author from the recipients and cc
|
670
|
# if the author does not want to receive notifications
|
671
|
# about what the author do
|
672
|
Rails.logger.info "1"
|
673
|
if @author && @author.logged? && @author.pref.no_self_notified
|
674
|
Rails.logger.info "1_"
|
675
|
headers[:to].delete(@author.mail) if headers[:to].is_a?(Array)
|
676
|
headers[:cc].delete(@author.mail) if headers[:cc].is_a?(Array)
|
677
|
end
|
678
|
|
679
|
Rails.logger.info "2"
|
680
|
if @author && @author.logged?
|
681
|
Rails.logger.info "2_"
|
682
|
redmine_headers 'Sender' => @author.login
|
683
|
end
|
684
|
|
685
|
Rails.logger.info "3"
|
686
|
# Blind carbon copy recipients
|
687
|
if Setting.bcc_recipients?
|
688
|
Rails.logger.info "3_"
|
689
|
headers[:bcc] = [headers[:to], headers[:cc]].flatten.uniq.reject(&:blank?)
|
690
|
headers[:to] = nil
|
691
|
headers[:cc] = nil
|
692
|
end
|
693
|
|
694
|
Rails.logger.info "4"
|
695
|
if @message_id_object
|
696
|
Rails.logger.info "4_"
|
697
|
headers[:message_id] = "<#{self.class.message_id_for(@message_id_object)}>"
|
698
|
end
|
699
|
Rails.logger.info "5"
|
700
|
if @references_objects
|
701
|
Rails.logger.info "5_"
|
702
|
headers[:references] = @references_objects.collect {|o| "<#{self.class.references_for(o)}>"}.join(' ')
|
703
|
end
|
704
|
|
705
|
Rails.logger.info "6"
|
706
|
m = if block_given?
|
707
|
Rails.logger.info "6_"
|
708
|
super headers, &block
|
709
|
else
|
710
|
Rails.logger.info "6__"
|
711
|
super headers do |format|
|
712
|
Rails.logger.info "6___"
|
713
|
format.text
|
714
|
format.html unless Setting.plain_text_mail?
|
715
|
end
|
716
|
end
|
717
|
Rails.logger.info "7"
|
718
|
set_language_if_valid @initial_language
|
719
|
Rails.logger.info "8"
|
720
|
|
721
|
m
|
722
|
end
|
723
|
|
724
|
def initialize(*args)
|
725
|
@initial_language = current_language
|
726
|
set_language_if_valid Setting.default_language
|
727
|
super
|
728
|
end
|
729
|
|
730
|
def self.deliver_mail(mail)
|
731
|
return false if mail.to.blank? && mail.cc.blank? && mail.bcc.blank?
|
732
|
begin
|
733
|
# Log errors when raise_delivery_errors is set to false, Rails does not
|
734
|
mail.raise_delivery_errors = true
|
735
|
super
|
736
|
rescue Exception => e
|
737
|
if ActionMailer::Base.raise_delivery_errors
|
738
|
raise e
|
739
|
else
|
740
|
Rails.logger.error "Email delivery error: #{e.message}"
|
741
|
end
|
742
|
end
|
743
|
end
|
744
|
|
745
|
def self.method_missing(method, *args, &block)
|
746
|
if m = method.to_s.match(%r{^deliver_(.+)$})
|
747
|
ActiveSupport::Deprecation.warn "Mailer.deliver_#{m[1]}(*args) is deprecated. Use Mailer.#{m[1]}(*args).deliver instead."
|
748
|
send(m[1], *args).deliver
|
749
|
else
|
750
|
super
|
751
|
end
|
752
|
end
|
753
|
|
754
|
private
|
755
|
|
756
|
# Appends a Redmine header field (name is prepended with 'X-Redmine-')
|
757
|
def redmine_headers(h)
|
758
|
h.each { |k,v| headers["X-Redmine-#{k}"] = v.to_s }
|
759
|
end
|
760
|
|
761
|
def self.token_for(object, rand=true)
|
762
|
timestamp = object.send(object.respond_to?(:created_on) ? :created_on : :updated_on)
|
763
|
hash = [
|
764
|
"redmine",
|
765
|
"#{object.class.name.demodulize.underscore}-#{object.id}",
|
766
|
timestamp.strftime("%Y%m%d%H%M%S")
|
767
|
]
|
768
|
if rand
|
769
|
hash << Redmine::Utils.random_hex(8)
|
770
|
end
|
771
|
host = Setting.mail_from.to_s.strip.gsub(%r{^.*@|>}, '')
|
772
|
host = "#{::Socket.gethostname}.redmine" if host.empty?
|
773
|
"#{hash.join('.')}@#{host}"
|
774
|
end
|
775
|
|
776
|
# Returns a Message-Id for the given object
|
777
|
def self.message_id_for(object)
|
778
|
token_for(object, true)
|
779
|
end
|
780
|
|
781
|
# Returns a uniq token for a given object referenced by all notifications
|
782
|
# related to this object
|
783
|
def self.references_for(object)
|
784
|
token_for(object, false)
|
785
|
end
|
786
|
|
787
|
def message_id(object)
|
788
|
@message_id_object = object
|
789
|
end
|
790
|
|
791
|
def references(object)
|
792
|
@references_objects ||= []
|
793
|
@references_objects << object
|
794
|
end
|
795
|
|
796
|
def mylogger
|
797
|
Rails.logger
|
798
|
end
|
799
|
end
|