Patch #13400 » 0001-patch.diff
| app/models/issue.rb | ||
|---|---|---|
| 49 | 49 |
acts_as_activity_provider :find_options => {:include => [:project, :author, :tracker]},
|
| 50 | 50 |
:author_key => :author_id |
| 51 | 51 | |
| 52 |
DONE_RATIO_OPTIONS = %w(issue_field issue_status) |
|
| 52 |
DONE_RATIO_OPTIONS = %w(issue_field issue_status logged_time)
|
|
| 53 | 53 | |
| 54 | 54 |
attr_reader :current_journal |
| 55 | 55 | |
| ... | ... | |
| 74 | 74 |
:conditions => ["#{Project.table_name}.status=#{Project::STATUS_ACTIVE}"]
|
| 75 | 75 | |
| 76 | 76 |
before_create :default_assign |
| 77 |
before_save :close_duplicates, :update_done_ratio_from_issue_status
|
|
| 77 |
before_save :close_duplicates, :update_done_ratio |
|
| 78 | 78 |
after_save {|issue| issue.send :after_project_change if !issue.id_changed? && issue.project_id_changed?}
|
| 79 | 79 |
after_save :reschedule_following_issues, :update_nested_set_attributes, :update_parent_attributes, :create_journal |
| 80 | 80 |
after_destroy :update_parent_attributes |
| ... | ... | |
| 376 | 376 |
end |
| 377 | 377 | |
| 378 | 378 |
def done_ratio |
| 379 |
if Issue.use_status_for_done_ratio? && status && status.default_done_ratio
|
|
| 379 |
if use_status_for_done_ratio?
|
|
| 380 | 380 |
status.default_done_ratio |
| 381 |
elsif use_time_for_done_ratio? |
|
| 382 |
if estimated_hours && estimated_hours.to_f > 0 |
|
| 383 |
ratio = (total_spent_hours.to_f / estimated_hours.to_f) * 100 |
|
| 384 |
[ratio, 100].min.to_i |
|
| 385 |
else |
|
| 386 |
0.0 |
|
| 387 |
end |
|
| 381 | 388 |
else |
| 382 | 389 |
read_attribute(:done_ratio) |
| 383 | 390 |
end |
| ... | ... | |
| 386 | 393 |
def self.use_status_for_done_ratio? |
| 387 | 394 |
Setting.issue_done_ratio == 'issue_status' |
| 388 | 395 |
end |
| 396 |
def use_status_for_done_ratio? |
|
| 397 |
Issue.use_status_for_done_ratio? && status && status.default_done_ratio |
|
| 398 |
end |
|
| 399 | ||
| 400 |
def self.use_time_for_done_ratio? |
|
| 401 |
Setting.issue_done_ratio == 'logged_time' |
|
| 402 |
end |
|
| 403 |
def use_time_for_done_ratio? |
|
| 404 |
Issue.use_time_for_done_ratio? |
|
| 405 |
end |
|
| 389 | 406 | |
| 390 | 407 |
def self.use_field_for_done_ratio? |
| 391 | 408 |
Setting.issue_done_ratio == 'issue_field' |
| 392 | 409 |
end |
| 410 |
def use_field_for_done_ratio? |
|
| 411 |
!(use_status_for_done_ratio? || use_time_for_done_ratio?) |
|
| 412 |
end |
|
| 393 | 413 | |
| 394 | 414 |
def validate_issue |
| 395 | 415 |
if self.due_date.nil? && @attributes['due_date'] && !@attributes['due_date'].empty? |
| ... | ... | |
| 438 | 458 | |
| 439 | 459 |
# Set the done_ratio using the status if that setting is set. This will keep the done_ratios |
| 440 | 460 |
# even if the user turns off the setting later |
| 441 |
def update_done_ratio_from_issue_status
|
|
| 442 |
if Issue.use_status_for_done_ratio? && status && status.default_done_ratio
|
|
| 443 |
self.done_ratio = status.default_done_ratio
|
|
| 461 |
def update_done_ratio |
|
| 462 |
unless use_field_for_done_ratio?
|
|
| 463 |
self.done_ratio = self.done_ratio
|
|
| 444 | 464 |
end |
| 445 | 465 |
end |
| 446 | 466 | |
| 467 |
def update_done_ratio! |
|
| 468 |
self.init_journal(User.current, "") |
|
| 469 |
self.update_done_ratio |
|
| 470 |
self.save |
|
| 471 |
end |
|
| 472 | ||
| 447 | 473 |
def init_journal(user, notes = "") |
| 448 | 474 |
@current_journal ||= Journal.new(:journalized => self, :user => user, :notes => notes) |
| 449 | 475 |
if new_record? |
| ... | ... | |
| 955 | 981 |
end |
| 956 | 982 | |
| 957 | 983 |
# done ratio = weighted average ratio of leaves |
| 958 |
unless Issue.use_status_for_done_ratio? && p.status && p.status.default_done_ratio
|
|
| 984 |
if p.use_field_for_done_ratio
|
|
| 959 | 985 |
leaves_count = p.leaves.count |
| 960 | 986 |
if leaves_count > 0 |
| 961 | 987 |
average = p.leaves.average(:estimated_hours).to_f |
| app/models/time_entry.rb | ||
|---|---|---|
| 40 | 40 |
validates_numericality_of :hours, :allow_nil => true, :message => :invalid |
| 41 | 41 |
validates_length_of :comments, :maximum => 255, :allow_nil => true |
| 42 | 42 |
before_validation :set_project_if_nil |
| 43 |
after_save :update_done_ratio |
|
| 44 |
after_destroy :update_done_ratio |
|
| 43 | 45 |
validate :validate_time_entry |
| 44 | 46 | |
| 45 | 47 |
named_scope :visible, lambda {|*args| {
|
| ... | ... | |
| 88 | 90 |
errors.add :issue_id, :invalid if (issue_id && !issue) || (issue && project!=issue.project) |
| 89 | 91 |
end |
| 90 | 92 | |
| 93 |
def update_done_ratio |
|
| 94 |
if issue && Issue.use_time_for_done_ratio? |
|
| 95 |
issue.update_done_ratio! |
|
| 96 |
end |
|
| 97 |
end |
|
| 98 | ||
| 91 | 99 |
def hours=(h) |
| 92 | 100 |
write_attribute :hours, (h.is_a?(String) ? (h.to_hours || h) : h) |
| 93 | 101 |
end |
| config/locales/ar.yml | ||
|---|---|---|
| 1068 | 1068 |
field_author_role: Author's role |
| 1069 | 1069 |
button_mail_link: Send by e-mail |
| 1070 | 1070 |
label_add_to_all_workflows: Add to all workflows |
| 1071 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/bg.yml | ||
|---|---|---|
| 1065 | 1065 |
field_author_role: Author's role |
| 1066 | 1066 |
button_mail_link: Send by e-mail |
| 1067 | 1067 |
label_add_to_all_workflows: Add to all workflows |
| 1068 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/bs.yml | ||
|---|---|---|
| 1082 | 1082 |
field_author_role: Author's role |
| 1083 | 1083 |
button_mail_link: Send by e-mail |
| 1084 | 1084 |
label_add_to_all_workflows: Add to all workflows |
| 1085 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/ca.yml | ||
|---|---|---|
| 1070 | 1070 |
field_author_role: Author's role |
| 1071 | 1071 |
button_mail_link: Send by e-mail |
| 1072 | 1072 |
label_add_to_all_workflows: Add to all workflows |
| 1073 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/cs.yml | ||
|---|---|---|
| 1071 | 1071 |
field_author_role: Author's role |
| 1072 | 1072 |
button_mail_link: Send by e-mail |
| 1073 | 1073 |
label_add_to_all_workflows: Add to all workflows |
| 1074 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/da.yml | ||
|---|---|---|
| 1085 | 1085 |
field_author_role: Author's role |
| 1086 | 1086 |
button_mail_link: Send by e-mail |
| 1087 | 1087 |
label_add_to_all_workflows: Add to all workflows |
| 1088 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/de.yml | ||
|---|---|---|
| 1082 | 1082 |
label_required: Required |
| 1083 | 1083 |
label_attribute_of_project: Project's %{name}
|
| 1084 | 1084 |
label_status_transitions: Status transitions |
| 1085 |
setting_issue_done_ratio_logged_time: Geschätzter und gebuchter Zeit |
|
| config/locales/el.yml | ||
|---|---|---|
| 1068 | 1068 |
field_author_role: Author's role |
| 1069 | 1069 |
button_mail_link: Send by e-mail |
| 1070 | 1070 |
label_add_to_all_workflows: Add to all workflows |
| 1071 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/en-GB.yml | ||
|---|---|---|
| 1070 | 1070 |
label_attribute_of_project: Project's %{name}
|
| 1071 | 1071 |
label_status_transitions: Status transitions |
| 1072 | 1072 |
button_mail_link: Send by e-mail |
| 1073 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/en.yml | ||
|---|---|---|
| 385 | 385 |
setting_issue_done_ratio: Calculate the issue done ratio with |
| 386 | 386 |
setting_issue_done_ratio_issue_field: Use the issue field |
| 387 | 387 |
setting_issue_done_ratio_issue_status: Use the issue status |
| 388 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| 388 | 389 |
setting_start_of_week: Start calendars on |
| 389 | 390 |
setting_rest_api_enabled: Enable REST web service |
| 390 | 391 |
setting_cache_formatted_text: Cache formatted text |
| config/locales/es.yml | ||
|---|---|---|
| 1105 | 1105 |
field_author_role: Author's role |
| 1106 | 1106 |
button_mail_link: Send by e-mail |
| 1107 | 1107 |
label_add_to_all_workflows: Add to all workflows |
| 1108 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/et.yml | ||
|---|---|---|
| 1084 | 1084 |
field_author_role: Author's role |
| 1085 | 1085 |
button_mail_link: Send by e-mail |
| 1086 | 1086 |
label_add_to_all_workflows: Add to all workflows |
| 1087 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/eu.yml | ||
|---|---|---|
| 1071 | 1071 |
field_author_role: Author's role |
| 1072 | 1072 |
button_mail_link: Send by e-mail |
| 1073 | 1073 |
label_add_to_all_workflows: Add to all workflows |
| 1074 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/fa.yml | ||
|---|---|---|
| 1070 | 1070 |
field_author_role: Author's role |
| 1071 | 1071 |
button_mail_link: Send by e-mail |
| 1072 | 1072 |
label_add_to_all_workflows: Add to all workflows |
| 1073 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/fi.yml | ||
|---|---|---|
| 1089 | 1089 |
field_author_role: Author's role |
| 1090 | 1090 |
button_mail_link: Send by e-mail |
| 1091 | 1091 |
label_add_to_all_workflows: Add to all workflows |
| 1092 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/fr.yml | ||
|---|---|---|
| 1081 | 1081 |
field_author_role: Author's role |
| 1082 | 1082 |
button_mail_link: Send by e-mail |
| 1083 | 1083 |
label_add_to_all_workflows: Add to all workflows |
| 1084 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/gl.yml | ||
|---|---|---|
| 1079 | 1079 |
field_author_role: Author's role |
| 1080 | 1080 |
button_mail_link: Send by e-mail |
| 1081 | 1081 |
label_add_to_all_workflows: Add to all workflows |
| 1082 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/he.yml | ||
|---|---|---|
| 1073 | 1073 |
field_author_role: Author's role |
| 1074 | 1074 |
button_mail_link: Send by e-mail |
| 1075 | 1075 |
label_add_to_all_workflows: Add to all workflows |
| 1076 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/hr.yml | ||
|---|---|---|
| 1071 | 1071 |
field_author_role: Author's role |
| 1072 | 1072 |
button_mail_link: Send by e-mail |
| 1073 | 1073 |
label_add_to_all_workflows: Add to all workflows |
| 1074 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/hu.yml | ||
|---|---|---|
| 1087 | 1087 |
field_author_role: Author's role |
| 1088 | 1088 |
button_mail_link: Send by e-mail |
| 1089 | 1089 |
label_add_to_all_workflows: Add to all workflows |
| 1090 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/id.yml | ||
|---|---|---|
| 1074 | 1074 |
field_author_role: Author's role |
| 1075 | 1075 |
button_mail_link: Send by e-mail |
| 1076 | 1076 |
label_add_to_all_workflows: Add to all workflows |
| 1077 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/it.yml | ||
|---|---|---|
| 1069 | 1069 |
field_author_role: Author's role |
| 1070 | 1070 |
button_mail_link: Send by e-mail |
| 1071 | 1071 |
label_add_to_all_workflows: Add to all workflows |
| 1072 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/ja.yml | ||
|---|---|---|
| 1098 | 1098 |
field_author_role: Author's role |
| 1099 | 1099 |
button_mail_link: Send by e-mail |
| 1100 | 1100 |
label_add_to_all_workflows: Add to all workflows |
| 1101 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/ko.yml | ||
|---|---|---|
| 1118 | 1118 |
field_author_role: Author's role |
| 1119 | 1119 |
button_mail_link: Send by e-mail |
| 1120 | 1120 |
label_add_to_all_workflows: Add to all workflows |
| 1121 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/lt.yml | ||
|---|---|---|
| 1128 | 1128 |
field_author_role: Author's role |
| 1129 | 1129 |
button_mail_link: Send by e-mail |
| 1130 | 1130 |
label_add_to_all_workflows: Add to all workflows |
| 1131 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/lv.yml | ||
|---|---|---|
| 1062 | 1062 |
field_author_role: Author's role |
| 1063 | 1063 |
button_mail_link: Send by e-mail |
| 1064 | 1064 |
label_add_to_all_workflows: Add to all workflows |
| 1065 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/mk.yml | ||
|---|---|---|
| 1068 | 1068 |
field_author_role: Author's role |
| 1069 | 1069 |
button_mail_link: Send by e-mail |
| 1070 | 1070 |
label_add_to_all_workflows: Add to all workflows |
| 1071 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/mn.yml | ||
|---|---|---|
| 1068 | 1068 |
field_author_role: Author's role |
| 1069 | 1069 |
button_mail_link: Send by e-mail |
| 1070 | 1070 |
label_add_to_all_workflows: Add to all workflows |
| 1071 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/nl.yml | ||
|---|---|---|
| 1053 | 1053 |
field_author_role: Author's role |
| 1054 | 1054 |
button_mail_link: Send by e-mail |
| 1055 | 1055 |
label_add_to_all_workflows: Add to all workflows |
| 1056 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/no.yml | ||
|---|---|---|
| 1059 | 1059 |
field_author_role: Author's role |
| 1060 | 1060 |
button_mail_link: Send by e-mail |
| 1061 | 1061 |
label_add_to_all_workflows: Add to all workflows |
| 1062 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/pl.yml | ||
|---|---|---|
| 1085 | 1085 |
field_author_role: Author's role |
| 1086 | 1086 |
button_mail_link: Send by e-mail |
| 1087 | 1087 |
label_add_to_all_workflows: Add to all workflows |
| 1088 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/pt-BR.yml | ||
|---|---|---|
| 1090 | 1090 |
field_author_role: Author's role |
| 1091 | 1091 |
button_mail_link: Send by e-mail |
| 1092 | 1092 |
label_add_to_all_workflows: Add to all workflows |
| 1093 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/pt.yml | ||
|---|---|---|
| 1073 | 1073 |
field_author_role: Author's role |
| 1074 | 1074 |
button_mail_link: Send by e-mail |
| 1075 | 1075 |
label_add_to_all_workflows: Add to all workflows |
| 1076 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/ro.yml | ||
|---|---|---|
| 1065 | 1065 |
field_author_role: Author's role |
| 1066 | 1066 |
button_mail_link: Send by e-mail |
| 1067 | 1067 |
label_add_to_all_workflows: Add to all workflows |
| 1068 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/ru.yml | ||
|---|---|---|
| 1181 | 1181 |
field_author_role: Author's role |
| 1182 | 1182 |
button_mail_link: Send by e-mail |
| 1183 | 1183 |
label_add_to_all_workflows: Add to all workflows |
| 1184 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/sk.yml | ||
|---|---|---|
| 1068 | 1068 |
field_author_role: Author's role |
| 1069 | 1069 |
button_mail_link: Send by e-mail |
| 1070 | 1070 |
label_add_to_all_workflows: Add to all workflows |
| 1071 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/sl.yml | ||
|---|---|---|
| 1068 | 1068 |
field_author_role: Author's role |
| 1069 | 1069 |
button_mail_link: Send by e-mail |
| 1070 | 1070 |
label_add_to_all_workflows: Add to all workflows |
| 1071 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/sq.yml | ||
|---|---|---|
| 1072 | 1072 |
field_author_role: Author's role |
| 1073 | 1073 |
button_mail_link: Send by e-mail |
| 1074 | 1074 |
label_add_to_all_workflows: Add to all workflows |
| 1075 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/sr-YU.yml | ||
|---|---|---|
| 1068 | 1068 |
field_author_role: Author's role |
| 1069 | 1069 |
button_mail_link: Send by e-mail |
| 1070 | 1070 |
label_add_to_all_workflows: Add to all workflows |
| 1071 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/sr.yml | ||
|---|---|---|
| 1069 | 1069 |
field_author_role: Author's role |
| 1070 | 1070 |
button_mail_link: Send by e-mail |
| 1071 | 1071 |
label_add_to_all_workflows: Add to all workflows |
| 1072 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/sv.yml | ||
|---|---|---|
| 1106 | 1106 |
field_author_role: Author's role |
| 1107 | 1107 |
button_mail_link: Send by e-mail |
| 1108 | 1108 |
label_add_to_all_workflows: Add to all workflows |
| 1109 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/th.yml | ||
|---|---|---|
| 1065 | 1065 |
field_author_role: Author's role |
| 1066 | 1066 |
button_mail_link: Send by e-mail |
| 1067 | 1067 |
label_add_to_all_workflows: Add to all workflows |
| 1068 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/tr.yml | ||
|---|---|---|
| 1087 | 1087 |
field_author_role: Author's role |
| 1088 | 1088 |
button_mail_link: Send by e-mail |
| 1089 | 1089 |
label_add_to_all_workflows: Add to all workflows |
| 1090 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/uk.yml | ||
|---|---|---|
| 1063 | 1063 |
field_author_role: Author's role |
| 1064 | 1064 |
button_mail_link: Send by e-mail |
| 1065 | 1065 |
label_add_to_all_workflows: Add to all workflows |
| 1066 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/vi.yml | ||
|---|---|---|
| 1119 | 1119 |
field_author_role: Author's role |
| 1120 | 1120 |
button_mail_link: Send by e-mail |
| 1121 | 1121 |
label_add_to_all_workflows: Add to all workflows |
| 1122 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/zh-TW.yml | ||
|---|---|---|
| 1148 | 1148 |
field_author_role: Author's role |
| 1149 | 1149 |
button_mail_link: Send by e-mail |
| 1150 | 1150 |
label_add_to_all_workflows: Add to all workflows |
| 1151 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| config/locales/zh.yml | ||
|---|---|---|
| 1070 | 1070 |
field_author_role: Author's role |
| 1071 | 1071 |
button_mail_link: Send by e-mail |
| 1072 | 1072 |
label_add_to_all_workflows: Add to all workflows |
| 1073 |
setting_issue_done_ratio_logged_time: Use the logged and estimated time |
|
| test/unit/issue_test.rb | ||
|---|---|---|
| 1127 | 1127 |
end |
| 1128 | 1128 |
end |
| 1129 | 1129 | |
| 1130 |
context "#update_done_ratio_from_issue_status" do
|
|
| 1130 |
context "#update_done_ratio" do |
|
| 1131 | 1131 |
setup do |
| 1132 | 1132 |
@issue = Issue.find(1) |
| 1133 | 1133 |
@issue_status = IssueStatus.find(1) |
| ... | ... | |
| 1143 | 1143 |
end |
| 1144 | 1144 | |
| 1145 | 1145 |
should "not change the issue" do |
| 1146 |
@issue.update_done_ratio_from_issue_status
|
|
| 1147 |
@issue2.update_done_ratio_from_issue_status
|
|
| 1146 |
@issue.update_done_ratio |
|
| 1147 |
@issue2.update_done_ratio |
|
| 1148 | 1148 | |
| 1149 | 1149 |
assert_equal 0, @issue.read_attribute(:done_ratio) |
| 1150 | 1150 |
assert_equal 30, @issue2.read_attribute(:done_ratio) |
| ... | ... | |
| 1157 | 1157 |
end |
| 1158 | 1158 | |
| 1159 | 1159 |
should "change the issue's done ratio" do |
| 1160 |
@issue.update_done_ratio_from_issue_status
|
|
| 1161 |
@issue2.update_done_ratio_from_issue_status
|
|
| 1160 |
@issue.update_done_ratio |
|
| 1161 |
@issue2.update_done_ratio |
|
| 1162 | 1162 | |
| 1163 | 1163 |
assert_equal 50, @issue.read_attribute(:done_ratio) |
| 1164 | 1164 |
assert_equal 0, @issue2.read_attribute(:done_ratio) |