[#4289] Ported the billing plugin's timesheet hooks.

This commit is contained in:
Eric Davis
2010-07-23 10:16:41 -07:00
parent 7192adb231
commit e541270461
14 changed files with 180 additions and 15 deletions

View File

@@ -100,4 +100,9 @@ class Rate < ActiveRecord::Base
raise Rate::InvalidParameterException.new("date must be a valid Date string (e.g. YYYY-MM-DD)")
end
end
if Rails.env.test?
public
generator_for :date_in_effect => Date.today
end
end

View File

@@ -7,3 +7,4 @@ en:
rate_error_user_not_found: User not found
rate_label_set_rate: Set Rate
rate_label_default: Default Rate
rate_cost: Cost

View File

@@ -31,7 +31,9 @@ Redmine::Plugin.register :redmine_rate do
permission :view_rate, { }
end
require 'redmine_rate/hooks/timesheet_hook_helper'
require 'redmine_rate/hooks/plugin_timesheet_views_timesheets_time_entry_row_class_hook'
require 'redmine_rate/hooks/plugin_timesheet_views_timesheet_group_header_hook'
require 'redmine_rate/hooks/plugin_timesheet_views_timesheet_time_entry_hook'
require 'redmine_rate/hooks/plugin_timesheet_views_timesheet_time_entry_sum_hook'
require 'redmine_rate/hooks/plugin_timesheet_view_timesheets_report_header_tags_hook'

View File

@@ -0,0 +1,11 @@
module RedmineRate
module Hooks
class PluginTimesheetViewTimesheetsReportHeaderTagsHook < Redmine::Hook::ViewListener
def plugin_timesheet_view_timesheets_report_header_tags(context={})
return content_tag(:style,
'tr.missing-rate td.cost { color: red; }',
:type => 'text/css')
end
end
end
end

View File

@@ -2,7 +2,7 @@ module RedmineRate
module Hooks
class PluginTimesheetViewsTimesheetGroupHeaderHook < Redmine::Hook::ViewListener
def plugin_timesheet_views_timesheet_group_header(context={})
return ''
return content_tag(:th, l(:rate_cost), :width => '8%')
end
end
end

View File

@@ -1,9 +1,18 @@
module RedmineRate
module Hooks
class PluginTimesheetViewsTimesheetTimeEntryHook < Redmine::Hook::ViewListener
include TimesheetHookHelper
def plugin_timesheet_views_timesheet_time_entry(context={})
return ''
cost = cost_item(context[:time_entry])
if cost
td_cell(number_to_currency(cost))
else
td_cell('&nbsp;')
end
end
end
end
end

View File

@@ -1,8 +1,16 @@
module RedmineRate
module Hooks
class PluginTimesheetViewsTimesheetTimeEntrySumHook < Redmine::Hook::ViewListener
include TimesheetHookHelper
def plugin_timesheet_views_timesheet_time_entry_sum(context={})
return ''
time_entries = context[:time_entries]
costs = time_entries.collect {|time_entry| cost_item(time_entry)}.compact.sum
if costs >= 0
return td_cell(number_to_currency(costs))
else
return td_cell('&nbsp;')
end
end
end
end

View File

@@ -1,8 +1,20 @@
module RedmineRate
module Hooks
class PluginTimesheetViewsTimesheetsTimeEntryRowClassHook < Redmine::Hook::ViewListener
include TimesheetHookHelper
def plugin_timesheet_views_timesheets_time_entry_row_class(context={})
return ''
time_entry = context[:time_entry]
return "" unless time_entry
cost = cost_item(time_entry)
return "" unless cost # Permissions
if cost && cost <= 0
return "missing-rate"
else
return ""
end
end
end
end

View File

@@ -0,0 +1,14 @@
module TimesheetHookHelper
# Returns the cost of a time entry, checking user permissions
def cost_item(time_entry)
if User.current.logged? && (User.current.allowed_to?(:view_rate, time_entry.project) || User.current.admin?)
return time_entry.cost
else
return nil
end
end
def td_cell(html)
return content_tag(:td, html, :align => 'right', :class => 'cost')
end
end

View File

@@ -0,0 +1,26 @@
require File.dirname(__FILE__) + '/../../../../test_helper'
class RedmineRate::Hooks::PluginTimesheetViewTimesheetsReportHeaderTagsTest < ActionController::TestCase
include Redmine::Hook::Helper
def controller
@controller ||= ApplicationController.new
@controller.response ||= ActionController::TestResponse.new
@controller
end
def request
@request ||= ActionController::TestRequest.new
end
def hook(args={})
call_hook :plugin_timesheet_view_timesheets_report_header_tags, args
end
context "#plugin_timesheet_view_timesheets_report_header_tags" do
should "return a css string" do
@response.body = hook
assert_select "style", :text => /missing-rate/
end
end
end

View File

@@ -18,9 +18,9 @@ class RedmineRate::Hooks::PluginTimesheetViewsTimesheetGroupHeaderTest < ActionC
end
context "#plugin_timesheet_views_timesheet_group_header" do
should "return an empty string" do
should "render the cost table header" do
@response.body = hook
assert @response.body.blank?
assert_select "th", :text => "Cost"
end
end
end

View File

@@ -18,9 +18,30 @@ class RedmineRate::Hooks::PluginTimesheetViewsTimesheetTimeEntryTest < ActionCon
end
context "#plugin_timesheet_views_timesheet_time_entry" do
should "return an empty string" do
@response.body = hook
assert @response.body.blank?
context "for users with view rate permission" do
should "render a cost cell showing the cost for the time entry" do
User.current = User.generate!(:admin => true)
rate = Rate.generate!(:amount => 100)
time_entry = TimeEntry.generate!(:hours => 2, :rate => rate)
@response.body = hook(:time_entry => time_entry)
assert_select 'td', :text => "$200.00"
end
end
context "for users without view rate permission" do
should "render an empty cost cell" do
User.current = nil
rate = Rate.generate!(:amount => 100)
time_entry = TimeEntry.generate!(:hours => 2, :rate => rate)
@response.body = hook(:time_entry => time_entry)
assert_select 'td', :text => '&nbsp;'
end
end
end
end

View File

@@ -18,9 +18,31 @@ class RedmineRate::Hooks::PluginTimesheetViewsTimesheetTimeEntrySumTest < Action
end
context "#plugin_timesheet_views_timesheet_time_entry_sum" do
should "return an empty string" do
@response.body = hook
assert @response.body.blank?
context "for users with view rate permission" do
should "render a cost cell showing the total cost for the time entries" do
User.current = User.generate!(:admin => true)
rate = Rate.generate!(:amount => 100)
time_entry1 = TimeEntry.generate!(:hours => 2, :rate => rate)
time_entry2 = TimeEntry.generate!(:hours => 10, :rate => rate)
@response.body = hook(:time_entries => [time_entry1, time_entry2])
assert_select 'td', :text => "$1,200.00"
end
end
context "for users without view rate permission" do
should "render an empty cost cell" do
User.current = nil
rate = Rate.generate!(:amount => 100)
time_entry = TimeEntry.generate!(:hours => 2, :rate => rate)
@response.body = hook(:time_entries => [time_entry])
assert_select 'td', :text => '$0.00'
end
end
end
end

View File

@@ -18,9 +18,43 @@ class RedmineRate::Hooks::PluginTimesheetViewsTimesheetsTimeEntryRowClassTest <
end
context "#plugin_timesheet_views_timesheets_time_entry_row_class" do
should "return an empty string" do
@response.body = hook
assert @response.body.blank?
context "for users with view rate permission" do
setup do
User.current = User.generate!(:admin => true)
end
should "render a missing rate css class if the time entry has no cost" do
time_entry = TimeEntry.generate!(:hours => 2, :rate => nil)
assert_equal "missing-rate", hook(:time_entry => time_entry)
end
should "render nothing if the time entry has a cost" do
rate = Rate.generate!(:amount => 100)
time_entry = TimeEntry.generate!(:hours => 2, :rate => rate)
assert_equal "", hook(:time_entry => time_entry)
end
end
context "for users without view rate permission" do
setup do
User.current = nil
end
should "render nothing if the time entry has no cost" do
time_entry = TimeEntry.generate!(:hours => 2, :rate => nil)
assert_equal "", hook(:time_entry => time_entry)
end
should "render nothing if the time entry has a cost" do
rate = Rate.generate!(:amount => 100)
time_entry = TimeEntry.generate!(:hours => 2, :rate => rate)
assert_equal "", hook(:time_entry => time_entry)
end
end
end
end