Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bbe55e098a | ||
|
|
dd3bcd9dce | ||
|
|
a9dcecc838 | ||
|
|
f42b419bf3 | ||
|
|
8288455356 | ||
|
|
dc8c5eefd2 | ||
|
|
00453672c6 | ||
|
|
268b1b7107 | ||
|
|
25c3bf5898 | ||
|
|
4c3e6b6b6d | ||
|
|
b20ebe587b |
1
.github_origin
Normal file
1
.github_origin
Normal file
@@ -0,0 +1 @@
|
|||||||
|
https://github.com/edavis10/redmine_rate.git
|
||||||
4
Rakefile
4
Rakefile
@@ -19,7 +19,6 @@ begin
|
|||||||
s.homepage = "https://projects.littlestreamsoftware.com/projects/redmine-rate"
|
s.homepage = "https://projects.littlestreamsoftware.com/projects/redmine-rate"
|
||||||
s.description = "The Rate plugin stores billing rates for Users. It also provides an API that can be used to find the rate for a Member of a Project at a specific date."
|
s.description = "The Rate plugin stores billing rates for Users. It also provides an API that can be used to find the rate for a Member of a Project at a specific date."
|
||||||
s.authors = ["Eric Davis"]
|
s.authors = ["Eric Davis"]
|
||||||
s.rubyforge_project = "redmine_rate" # TODO
|
|
||||||
s.files = FileList[
|
s.files = FileList[
|
||||||
"[A-Z]*",
|
"[A-Z]*",
|
||||||
"init.rb",
|
"init.rb",
|
||||||
@@ -29,9 +28,6 @@ begin
|
|||||||
]
|
]
|
||||||
end
|
end
|
||||||
Jeweler::GemcutterTasks.new
|
Jeweler::GemcutterTasks.new
|
||||||
Jeweler::RubyforgeTasks.new do |rubyforge|
|
|
||||||
rubyforge.doc_task = "rdoc"
|
|
||||||
end
|
|
||||||
rescue LoadError
|
rescue LoadError
|
||||||
puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,12 +1,7 @@
|
|||||||
module RateSortHelperPatch
|
module RateHelper
|
||||||
def self.included(base) # :nodoc:
|
|
||||||
base.send(:include, InstanceMethods)
|
|
||||||
end
|
|
||||||
|
|
||||||
module InstanceMethods
|
|
||||||
# Allows more parameters than the standard sort_header_tag
|
# Allows more parameters than the standard sort_header_tag
|
||||||
def rate_sort_header_tag(column, options = {})
|
def rate_sort_header_tag(column, options = {})
|
||||||
caption = options.delete(:caption) || titleize(Inflector::humanize(column))
|
caption = options.delete(:caption) || titleize(ActiveSupport::Inflector::humanize(column))
|
||||||
default_order = options.delete(:default_order) || 'asc'
|
default_order = options.delete(:default_order) || 'asc'
|
||||||
options[:title]= l(:label_sort_by, "\"#{caption}\"") unless options[:title]
|
options[:title]= l(:label_sort_by, "\"#{caption}\"") unless options[:title]
|
||||||
content_tag('th',
|
content_tag('th',
|
||||||
@@ -80,7 +75,7 @@ module RateSortHelperPatch
|
|||||||
icon = nil
|
icon = nil
|
||||||
order = default_order
|
order = default_order
|
||||||
end
|
end
|
||||||
caption = titleize(Inflector::humanize(column)) unless caption
|
caption = titleize(ActiveSupport::Inflector::humanize(column)) unless caption
|
||||||
|
|
||||||
sort_options = { :sort_key => column, :sort_order => order }
|
sort_options = { :sort_key => column, :sort_order => order }
|
||||||
# don't reuse params if filters are present
|
# don't reuse params if filters are present
|
||||||
@@ -98,5 +93,4 @@ module RateSortHelperPatch
|
|||||||
(icon ? nbsp(2) + image_tag(icon) : '')
|
(icon ? nbsp(2) + image_tag(icon) : '')
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
@@ -151,6 +151,9 @@ class Rate < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
if Rails.env.test?
|
if Rails.env.test?
|
||||||
|
require 'object_daddy'
|
||||||
|
include ObjectDaddy
|
||||||
|
|
||||||
public
|
public
|
||||||
generator_for :date_in_effect => Date.today
|
generator_for :date_in_effect => Date.today
|
||||||
end
|
end
|
||||||
|
|||||||
18
config/locales/cs.yml
Normal file
18
config/locales/cs.yml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
cs:
|
||||||
|
rate_label_rates: Míra
|
||||||
|
rate_label_rate: Míra
|
||||||
|
rate_label_rate_history: Historie míry
|
||||||
|
rate_label_new_rate: Nová míra
|
||||||
|
rate_label_currency: Kč
|
||||||
|
rate_error_user_not_found: Uživatel nebyl nalezen
|
||||||
|
rate_label_set_rate: Nastavit míru
|
||||||
|
rate_label_default: Výchozí míra
|
||||||
|
rate_cost: Cena
|
||||||
|
text_rate_caches_panel: "Míra mezipaměti"
|
||||||
|
text_no_cache_run: "nebyla nalezena žádná běžící mezipaměť"
|
||||||
|
text_last_caching_run: "Poslední spuštěná mezipaměť: "
|
||||||
|
text_last_cache_clearing_run: "Poslední čištění mezipaměti: "
|
||||||
|
text_load_missing_caches: "Nahrát chybějící mezipaměť"
|
||||||
|
text_clear_and_load_all_caches: "Vyčistit a nahrát všechny mezipaměti"
|
||||||
|
text_caches_loaded_successfully: "Mezipaměti byly nahrány"
|
||||||
|
permission_view_rate: "Zobrazit míry"
|
||||||
7
init.rb
7
init.rb
@@ -6,8 +6,9 @@ require 'dispatcher'
|
|||||||
Dispatcher.to_prepare :redmine_rate do
|
Dispatcher.to_prepare :redmine_rate do
|
||||||
gem 'lockfile'
|
gem 'lockfile'
|
||||||
|
|
||||||
require_dependency 'sort_helper'
|
require_dependency 'application_controller'
|
||||||
SortHelper.send(:include, RateSortHelperPatch)
|
ApplicationController.send(:include, RateHelper)
|
||||||
|
ApplicationController.send(:helper, :rate)
|
||||||
|
|
||||||
require_dependency 'time_entry'
|
require_dependency 'time_entry'
|
||||||
TimeEntry.send(:include, RateTimeEntryPatch)
|
TimeEntry.send(:include, RateTimeEntryPatch)
|
||||||
@@ -26,7 +27,7 @@ Redmine::Plugin.register :redmine_rate do
|
|||||||
url 'https://projects.littlestreamsoftware.com/projects/redmine-rate'
|
url 'https://projects.littlestreamsoftware.com/projects/redmine-rate'
|
||||||
author_url 'http://www.littlestreamsoftware.com'
|
author_url 'http://www.littlestreamsoftware.com'
|
||||||
description "The Rate plugin provides an API that can be used to find the rate for a Member of a Project at a specific date. It also stores historical rate data so calculations will remain correct in the future."
|
description "The Rate plugin provides an API that can be used to find the rate for a Member of a Project at a specific date. It also stores historical rate data so calculations will remain correct in the future."
|
||||||
version '0.2.0'
|
version '0.2.1'
|
||||||
|
|
||||||
requires_redmine :version_or_higher => '1.0.0'
|
requires_redmine :version_or_higher => '1.0.0'
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ module RateTimeEntryPatch
|
|||||||
unloadable # Send unloadable so it will not be unloaded in development
|
unloadable # Send unloadable so it will not be unloaded in development
|
||||||
belongs_to :rate
|
belongs_to :rate
|
||||||
|
|
||||||
before_save :cost
|
before_save :recalculate_cost
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -32,7 +32,9 @@ module RateTimeEntryPatch
|
|||||||
# Returns the current cost of the TimeEntry based on it's rate and hours
|
# Returns the current cost of the TimeEntry based on it's rate and hours
|
||||||
#
|
#
|
||||||
# Is a read-through cache method
|
# Is a read-through cache method
|
||||||
def cost
|
def cost(options={})
|
||||||
|
store_to_db = options[:store] || false
|
||||||
|
|
||||||
unless read_attribute(:cost)
|
unless read_attribute(:cost)
|
||||||
if self.rate.nil?
|
if self.rate.nil?
|
||||||
amount = Rate.amount_for(self.user, self.project, self.spent_on.to_s)
|
amount = Rate.amount_for(self.user, self.project, self.spent_on.to_s)
|
||||||
@@ -43,8 +45,13 @@ module RateTimeEntryPatch
|
|||||||
if amount.nil?
|
if amount.nil?
|
||||||
write_attribute(:cost, 0.0)
|
write_attribute(:cost, 0.0)
|
||||||
else
|
else
|
||||||
# Write the cost to the database for caching
|
if store_to_db
|
||||||
update_attribute(:cost, amount.to_f * hours.to_f)
|
# Write the cost to the database for caching
|
||||||
|
update_attribute(:cost, amount.to_f * hours.to_f)
|
||||||
|
else
|
||||||
|
# Cache to object only
|
||||||
|
write_attribute(:cost, amount.to_f * hours.to_f)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -59,6 +66,12 @@ module RateTimeEntryPatch
|
|||||||
clear_cost_cache
|
clear_cost_cache
|
||||||
update_attribute(:cost, cost)
|
update_attribute(:cost, cost)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def recalculate_cost
|
||||||
|
clear_cost_cache
|
||||||
|
cost(:store => false)
|
||||||
|
true # for callback
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -5,11 +5,11 @@
|
|||||||
|
|
||||||
Gem::Specification.new do |s|
|
Gem::Specification.new do |s|
|
||||||
s.name = %q{redmine_rate}
|
s.name = %q{redmine_rate}
|
||||||
s.version = "0.2.0"
|
s.version = "0.2.1"
|
||||||
|
|
||||||
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
||||||
s.authors = ["Eric Davis"]
|
s.authors = ["Eric Davis"]
|
||||||
s.date = %q{2011-03-03}
|
s.date = %q{2011-04-28}
|
||||||
s.description = %q{The Rate plugin stores billing rates for Users. It also provides an API that can be used to find the rate for a Member of a Project at a specific date.}
|
s.description = %q{The Rate plugin stores billing rates for Users. It also provides an API that can be used to find the rate for a Member of a Project at a specific date.}
|
||||||
s.email = %q{edavis@littlestreamsoftware.com}
|
s.email = %q{edavis@littlestreamsoftware.com}
|
||||||
s.extra_rdoc_files = [
|
s.extra_rdoc_files = [
|
||||||
@@ -79,7 +79,6 @@ Gem::Specification.new do |s|
|
|||||||
s.homepage = %q{https://projects.littlestreamsoftware.com/projects/redmine-rate}
|
s.homepage = %q{https://projects.littlestreamsoftware.com/projects/redmine-rate}
|
||||||
s.rdoc_options = ["--charset=UTF-8"]
|
s.rdoc_options = ["--charset=UTF-8"]
|
||||||
s.require_paths = ["lib"]
|
s.require_paths = ["lib"]
|
||||||
s.rubyforge_project = %q{redmine_rate}
|
|
||||||
s.rubygems_version = %q{1.3.7}
|
s.rubygems_version = %q{1.3.7}
|
||||||
s.summary = %q{A Rate plugin for Redmine to store billing rate for user.}
|
s.summary = %q{A Rate plugin for Redmine to store billing rate for user.}
|
||||||
s.test_files = [
|
s.test_files = [
|
||||||
|
|||||||
@@ -71,6 +71,21 @@ class RateTimeEntryPatchTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
assert_equal 2000.0, @time_entry.read_attribute(:cost)
|
assert_equal 2000.0, @time_entry.read_attribute(:cost)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
should "clear and recalculate the cache when the attribute is already set but stale" do
|
||||||
|
# Set the cost
|
||||||
|
assert @time_entry.save
|
||||||
|
assert_equal 2000.0, @time_entry.read_attribute(:cost)
|
||||||
|
|
||||||
|
@time_entry.reload
|
||||||
|
@time_entry.hours = 20
|
||||||
|
assert @time_entry.save
|
||||||
|
|
||||||
|
assert_equal 4000.0, @time_entry.read_attribute(:cost)
|
||||||
|
assert_equal 4000.0, @time_entry.reload.cost
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user