@@ -241,6 +241,11 class Issue < ActiveRecord::Base | |||
|
241 | 241 | recipients.compact.uniq |
|
242 | 242 | end |
|
243 | 243 | |
|
244 | # Returns the total number of hours spent on this issue. | |
|
245 | # | |
|
246 | # Example: | |
|
247 | # spent_hours => 0 | |
|
248 | # spent_hours => 50 | |
|
244 | 249 | def spent_hours |
|
245 | 250 | @spent_hours ||= time_entries.sum(:hours) || 0 |
|
246 | 251 | end |
@@ -269,6 +274,11 class Issue < ActiveRecord::Base | |||
|
269 | 274 | due_date || (fixed_version ? fixed_version.effective_date : nil) |
|
270 | 275 | end |
|
271 | 276 | |
|
277 | # Returns the time scheduled for this issue. | |
|
278 | # | |
|
279 | # Example: | |
|
280 | # Start Date: 2/26/09, End Date: 3/04/09 | |
|
281 | # duration => 6 | |
|
272 | 282 | def duration |
|
273 | 283 | (start_date && due_date) ? due_date - start_date : 0 |
|
274 | 284 | end |
@@ -29,6 +29,11 class Mailer < ActionMailer::Base | |||
|
29 | 29 | { :host => h, :protocol => Setting.protocol } |
|
30 | 30 | end |
|
31 | 31 | |
|
32 | # Builds a tmail object used to email recipients of the added issue. | |
|
33 | # | |
|
34 | # Example: | |
|
35 | # issue_add(issue) => tmail object | |
|
36 | # Mailer.deliver_issue_add(issue) => sends an email to issue recipients | |
|
32 | 37 | def issue_add(issue) |
|
33 | 38 | redmine_headers 'Project' => issue.project.identifier, |
|
34 | 39 | 'Issue-Id' => issue.id, |
@@ -42,6 +47,11 class Mailer < ActionMailer::Base | |||
|
42 | 47 | :issue_url => url_for(:controller => 'issues', :action => 'show', :id => issue) |
|
43 | 48 | end |
|
44 | 49 | |
|
50 | # Builds a tmail object used to email recipients of the edited issue. | |
|
51 | # | |
|
52 | # Example: | |
|
53 | # issue_edit(journal) => tmail object | |
|
54 | # Mailer.deliver_issue_edit(journal) => sends an email to issue recipients | |
|
45 | 55 | def issue_edit(journal) |
|
46 | 56 | issue = journal.journalized |
|
47 | 57 | redmine_headers 'Project' => issue.project.identifier, |
@@ -72,6 +82,11 class Mailer < ActionMailer::Base | |||
|
72 | 82 | :issues_url => url_for(:controller => 'issues', :action => 'index', :set_filter => 1, :assigned_to_id => user.id, :sort_key => 'due_date', :sort_order => 'asc') |
|
73 | 83 | end |
|
74 | 84 | |
|
85 | # Builds a tmail object used to email users belonging to the added document's project. | |
|
86 | # | |
|
87 | # Example: | |
|
88 | # document_added(document) => tmail object | |
|
89 | # Mailer.deliver_document_added(document) => sends an email to the document's project recipients | |
|
75 | 90 | def document_added(document) |
|
76 | 91 | redmine_headers 'Project' => document.project.identifier |
|
77 | 92 | recipients document.project.recipients |
@@ -80,6 +95,11 class Mailer < ActionMailer::Base | |||
|
80 | 95 | :document_url => url_for(:controller => 'documents', :action => 'show', :id => document) |
|
81 | 96 | end |
|
82 | 97 | |
|
98 | # Builds a tmail object used to email recipients of a project when an attachements are added. | |
|
99 | # | |
|
100 | # Example: | |
|
101 | # attachments_added(attachments) => tmail object | |
|
102 | # Mailer.deliver_attachments_added(attachments) => sends an email to the project's recipients | |
|
83 | 103 | def attachments_added(attachments) |
|
84 | 104 | container = attachments.first.container |
|
85 | 105 | added_to = '' |
@@ -102,7 +122,12 class Mailer < ActionMailer::Base | |||
|
102 | 122 | :added_to => added_to, |
|
103 | 123 | :added_to_url => added_to_url |
|
104 | 124 | end |
|
105 | ||
|
125 | ||
|
126 | # Builds a tmail object used to email recipients of a news' project when a news item is added. | |
|
127 | # | |
|
128 | # Example: | |
|
129 | # news_added(news) => tmail object | |
|
130 | # Mailer.deliver_news_added(news) => sends an email to the news' project recipients | |
|
106 | 131 | def news_added(news) |
|
107 | 132 | redmine_headers 'Project' => news.project.identifier |
|
108 | 133 | message_id news |
@@ -112,6 +137,11 class Mailer < ActionMailer::Base | |||
|
112 | 137 | :news_url => url_for(:controller => 'news', :action => 'show', :id => news) |
|
113 | 138 | end |
|
114 | 139 | |
|
140 | # Builds a tmail object used to email the specified recipients of the specified message that was posted. | |
|
141 | # | |
|
142 | # Example: | |
|
143 | # message_posted(message, recipients) => tmail object | |
|
144 | # Mailer.deliver_message_posted(message, recipients) => sends an email to the recipients | |
|
115 | 145 | def message_posted(message, recipients) |
|
116 | 146 | redmine_headers 'Project' => message.project.identifier, |
|
117 | 147 | 'Topic-Id' => (message.parent_id || message.id) |
@@ -123,6 +153,11 class Mailer < ActionMailer::Base | |||
|
123 | 153 | :message_url => url_for(:controller => 'messages', :action => 'show', :board_id => message.board_id, :id => message.root) |
|
124 | 154 | end |
|
125 | 155 | |
|
156 | # Builds a tmail object used to email the specified user their account information. | |
|
157 | # | |
|
158 | # Example: | |
|
159 | # account_information(user, password) => tmail object | |
|
160 | # Mailer.deliver_account_information(user, password) => sends account information to the user | |
|
126 | 161 | def account_information(user, password) |
|
127 | 162 | set_language_if_valid user.language |
|
128 | 163 | recipients user.mail |
@@ -132,6 +167,11 class Mailer < ActionMailer::Base | |||
|
132 | 167 | :login_url => url_for(:controller => 'account', :action => 'login') |
|
133 | 168 | end |
|
134 | 169 | |
|
170 | # Builds a tmail object used to email all active administrators of an account activation request. | |
|
171 | # | |
|
172 | # Example: | |
|
173 | # account_activation_request(user) => tmail object | |
|
174 | # Mailer.deliver_account_activation_request(user)=> sends an email to all active administrators | |
|
135 | 175 | def account_activation_request(user) |
|
136 | 176 | # Send the email to all active administrators |
|
137 | 177 | recipients User.active.find(:all, :conditions => {:admin => true}).collect { |u| u.mail }.compact |
@@ -140,7 +180,11 class Mailer < ActionMailer::Base | |||
|
140 | 180 | :url => url_for(:controller => 'users', :action => 'index', :status => User::STATUS_REGISTERED, :sort_key => 'created_on', :sort_order => 'desc') |
|
141 | 181 | end |
|
142 | 182 | |
|
143 |
# |
|
|
183 | # Builds a tmail object used to email the specified user that their account was activated by an administrator. | |
|
184 | # | |
|
185 | # Example: | |
|
186 | # account_activated(user) => tmail object | |
|
187 | # Mailer.deliver_account_activated(user) => sends an email to the registered user | |
|
144 | 188 | def account_activated(user) |
|
145 | 189 | set_language_if_valid user.language |
|
146 | 190 | recipients user.mail |
@@ -99,6 +99,11 class Project < ActiveRecord::Base | |||
|
99 | 99 | find(:all, :limit => count, :conditions => visible_by(user), :order => "created_on DESC") |
|
100 | 100 | end |
|
101 | 101 | |
|
102 | # Returns a SQL :conditions string used to find all active projects for the specified user. | |
|
103 | # | |
|
104 | # Examples: | |
|
105 | # Projects.visible_by(admin) => "projects.status = 1" | |
|
106 | # Projects.visible_by(normal_user) => "projects.status = 1 AND projects.is_public = 1" | |
|
102 | 107 | def self.visible_by(user=nil) |
|
103 | 108 | user ||= User.current |
|
104 | 109 | if user && user.admin? |
@@ -141,7 +146,12 class Project < ActiveRecord::Base | |||
|
141 | 146 | end |
|
142 | 147 | statements.empty? ? base_statement : "((#{base_statement}) AND (#{statements.join(' OR ')}))" |
|
143 | 148 | end |
|
144 | ||
|
149 | ||
|
150 | # Returns a :conditions SQL string that can be used to find the issues associated with this project. | |
|
151 | # | |
|
152 | # Examples: | |
|
153 | # project.project_condition(true) => "(projects.id = 1 OR (projects.lft > 1 AND projects.rgt < 10))" | |
|
154 | # project.project_condition(false) => "projects.id = 1" | |
|
145 | 155 | def project_condition(with_subprojects) |
|
146 | 156 | cond = "#{Project.table_name}.id = #{id}" |
|
147 | 157 | cond = "(#{cond} OR (#{Project.table_name}.lft > #{lft} AND #{Project.table_name}.rgt < #{rgt}))" if with_subprojects |
@@ -273,6 +283,10 class Project < ActiveRecord::Base | |||
|
273 | 283 | description.gsub(/^(.{#{length}}[^\n\r]*).*$/m, '\1...').strip if description |
|
274 | 284 | end |
|
275 | 285 | |
|
286 | # Return true if this project is allowed to do the specified action. | |
|
287 | # action can be: | |
|
288 | # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit') | |
|
289 | # * a permission Symbol (eg. :edit_project) | |
|
276 | 290 | def allows_to?(action) |
|
277 | 291 | if action.is_a? Hash |
|
278 | 292 | allowed_actions.include? "#{action[:controller]}/#{action[:action]}" |
@@ -286,6 +286,8 class User < ActiveRecord::Base | |||
|
286 | 286 | @current_user ||= User.anonymous |
|
287 | 287 | end |
|
288 | 288 | |
|
289 | # Returns the anonymous user. If the anonymous user does not exist, it is created. There can be only | |
|
290 | # one anonymous user per database. | |
|
289 | 291 | def self.anonymous |
|
290 | 292 | anonymous_user = AnonymousUser.find(:first) |
|
291 | 293 | if anonymous_user.nil? |
@@ -50,6 +50,8 class Version < ActiveRecord::Base | |||
|
50 | 50 | effective_date && (effective_date <= Date.today) && (open_issues_count == 0) |
|
51 | 51 | end |
|
52 | 52 | |
|
53 | # Returns the completion percentage of this version based on the amount of open/closed issues | |
|
54 | # and the time spent on the open issues. | |
|
53 | 55 | def completed_pourcent |
|
54 | 56 | if issues_count == 0 |
|
55 | 57 | 0 |
@@ -60,6 +62,7 class Version < ActiveRecord::Base | |||
|
60 | 62 | end |
|
61 | 63 | end |
|
62 | 64 | |
|
65 | # Returns the percentage of issues that have been marked as 'closed'. | |
|
63 | 66 | def closed_pourcent |
|
64 | 67 | if issues_count == 0 |
|
65 | 68 | 0 |
@@ -78,10 +81,12 class Version < ActiveRecord::Base | |||
|
78 | 81 | @issue_count ||= fixed_issues.count |
|
79 | 82 | end |
|
80 | 83 | |
|
84 | # Returns the total amount of open issues for this version. | |
|
81 | 85 | def open_issues_count |
|
82 | 86 | @open_issues_count ||= Issue.count(:all, :conditions => ["fixed_version_id = ? AND is_closed = ?", self.id, false], :include => :status) |
|
83 | 87 | end |
|
84 | 88 | |
|
89 | # Returns the total amount of closed issues for this version. | |
|
85 | 90 | def closed_issues_count |
|
86 | 91 | @closed_issues_count ||= Issue.count(:all, :conditions => ["fixed_version_id = ? AND is_closed = ?", self.id, true], :include => :status) |
|
87 | 92 | end |
@@ -124,17 +129,22 private | |||
|
124 | 129 | @estimated_average |
|
125 | 130 | end |
|
126 | 131 | |
|
127 | # Returns the total progress of open or closed issues | |
|
132 | # Returns the total progress of open or closed issues. The returned percentage takes into account | |
|
133 | # the amount of estimated time set for this version. | |
|
134 | # | |
|
135 | # Examples: | |
|
136 | # issues_progress(true) => returns the progress percentage for open issues. | |
|
137 | # issues_progress(false) => returns the progress percentage for closed issues. | |
|
128 | 138 | def issues_progress(open) |
|
129 | 139 | @issues_progress ||= {} |
|
130 | 140 | @issues_progress[open] ||= begin |
|
131 | 141 | progress = 0 |
|
132 | 142 | if issues_count > 0 |
|
133 | 143 | ratio = open ? 'done_ratio' : 100 |
|
144 | ||
|
134 | 145 | done = fixed_issues.sum("COALESCE(estimated_hours, #{estimated_average}) * #{ratio}", |
|
135 | 146 | :include => :status, |
|
136 | 147 | :conditions => ["is_closed = ?", !open]).to_f |
|
137 | ||
|
138 | 148 | progress = done / (estimated_average * issues_count) |
|
139 | 149 | end |
|
140 | 150 | progress |
General Comments 0
You need to be logged in to leave comments.
Login now