diff --git a/init.rb b/init.rb index f892d8a..335c213 100644 --- a/init.rb +++ b/init.rb @@ -1,15 +1,8 @@ require 'redmine' -require 'dispatcher' - -Dispatcher.to_prepare :redmine_redmine_user_pain do - require_dependency 'issue' - # Guards against including the module multiple time (like in tests) - # and registering multiple callbacks - unless Issue.included_modules.include? RedmineUserPain::IssuePatch - Issue.send(:include, RedmineUserPain::IssuePatch) - end -end +require 'issue_patch' +require 'query_patch' +require 'user_pain_issue_hook' Redmine::Plugin.register :redmine_redmine_user_pain do name 'Redmine User Pain plugin' @@ -20,4 +13,3 @@ author_url 'http://theodoreb.net' end -require 'redmine_user_pain/issue_patch' diff --git a/lang/en.yml b/lang/en.yml new file mode 100644 index 0000000..d1de179 --- /dev/null +++ b/lang/en.yml @@ -0,0 +1,2 @@ +field_user_pain: User Pain +text_user_pain: User Pain diff --git a/lang/fr.yml b/lang/fr.yml new file mode 100644 index 0000000..d1de179 --- /dev/null +++ b/lang/fr.yml @@ -0,0 +1,2 @@ +field_user_pain: User Pain +text_user_pain: User Pain diff --git a/lib/issue_patch.rb b/lib/issue_patch.rb new file mode 100644 index 0000000..efbf5c7 --- /dev/null +++ b/lib/issue_patch.rb @@ -0,0 +1,44 @@ +require_dependency 'issue' + +module RedmineUserPain + # Patches Redmine's Issues dynamically. Adds a +after_save+ filter. + module IssuePatch + def self.included(base) # :nodoc: + base.send(:include, InstanceMethods) + end + + module InstanceMethods + def user_pain + # get the last custom field + likelihood = CustomField.find_by_name("Likelihood") + likelihood_values_length = likelihood['possible_values'].length + pain = 1 + + # add likelihood value to total pain + self.custom_values.each do |x| + if x.custom_field_id == likelihood.id + pain *= likelihood_values_length - likelihood['possible_values'].index(x.value) + end + end + + tracker_pain = 0 + # get enabled tracker for the current project + @project.trackers.each do |t| + if self.tracker_id == t.id + pain *= @project.trackers.length - tracker_pain + end + tracker_pain += 1 + end + + # add type value to total pain + pain *= IssuePriority.all.length - (IssuePriority.find_by_id(self.priority_id).position - 1) + + max_pain = @project.trackers.length * IssuePriority.all.length * likelihood_values_length + return 100 * pain / max_pain + end + end + + end +end + +Issue.send(:include, RedmineUserPain::IssuePatch) diff --git a/lib/query_patch.rb b/lib/query_patch.rb new file mode 100644 index 0000000..8a33b6d --- /dev/null +++ b/lib/query_patch.rb @@ -0,0 +1,32 @@ +require_dependency 'query' + +module QueryPatch + def self.included(base) + base.extend(ClassMethods) + + # Same as typing in the class + base.class_eval do + unloadable # Send unloadable so it will not be unloaded in development + base.add_available_column(QueryColumn.new(:user_pain, { + :sortable => true + })) + + alias_method :redmine_available_filters, :available_filters + end + + end + + module ClassMethods + def available_columns=(v) + self.available_columns = (v) + end + + def add_available_column(column) + self.available_columns << (column) + end + end + +end + +# Add module to Query +Query.send(:include, QueryPatch) diff --git a/lib/user_pain_issue_hook.rb b/lib/user_pain_issue_hook.rb new file mode 100644 index 0000000..3af34ea --- /dev/null +++ b/lib/user_pain_issue_hook.rb @@ -0,0 +1,14 @@ +# Hooks to attach to the Redmine Issues. +class BudgetIssueHook < Redmine::Hook::ViewListener + + # Renders the Deliverable subject + # + # Context: + # * :issue => Issue being rendered + # + def view_issues_show_details_bottom(context = { }) + data = "#{l(:user_pain)}:#{context[:issue].user_pain}" + return "#{data}" + end + +end