diff --git a/app/models/contract.rb b/app/models/contract.rb
index 8552893..c121369 100644
--- a/app/models/contract.rb
+++ b/app/models/contract.rb
@@ -124,6 +124,18 @@ class Contract < ActiveRecord::Base
end
end
+ def orphaned_time
+ cost_of_time_without_issue = project.time_entries.all(:conditions => {:issue_id => nil}).inject(0) do |total, time_entry|
+ total += time_entry.cost
+ end
+
+ cost_of_time_without_deliverable = project.issues.all(:include => 'time_entries', :conditions => {:deliverable_id => nil}).collect(&:time_entries).flatten.inject(0) do |total, time_entry|
+ total += time_entry.cost
+ end
+
+ cost_of_time_without_issue + cost_of_time_without_deliverable
+ end
+
def to_s
name
end
diff --git a/app/views/contracts/show.html.erb b/app/views/contracts/show.html.erb
index df434b1..6b6f71f 100644
--- a/app/views/contracts/show.html.erb
+++ b/app/views/contracts/show.html.erb
@@ -1,5 +1,14 @@
<%= render :partial => 'title', :locals => {:contract => resource} %>
+<% if resource.orphaned_time && resource.orphaned_time > 0 %>
+
+
+ <%= l(:text_error_message_orphaned_time, :amount => format_value_field_for_contracts(resource.orphaned_time)) %>
+ <%= link_to_issue_list_with_filter(l(:text_error_message_update_orphaned_time), :deliverable_id => '!*') %>
+
+
+<% end %>
+
<% div_for(resource) do %>
<%= avatar(resource.account_executive, :size => 40) %>
diff --git a/assets/stylesheets/redmine_contracts.css b/assets/stylesheets/redmine_contracts.css
index c1cf483..fae9acd 100644
--- a/assets/stylesheets/redmine_contracts.css
+++ b/assets/stylesheets/redmine_contracts.css
@@ -63,13 +63,13 @@ input.financial{
#content .error_msg p{
padding: 6px;
+ color: #a40000;
}
+ #content .error_msg p a {
+ color: #a40000;
+ text-decoration: underline;
+ }
- #content .error_msg p span{
- font-weight: bold;
- text-decoration: underline;
- }
-
.contract .gravatar{
float: left;
border: 1px solid #b4d1d9;
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 9cccff6..98cd683 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -73,3 +73,5 @@ en:
field_budget: Budget
field_markup: Markup
field_paid: Paid
+ text_error_message_orphaned_time: "There is {{amount}} worth of time clocked to issues that are not assigned to any deliverables."
+ text_error_message_update_orphaned_time: "Please update the orphaned issues."
diff --git a/test/integration/contracts_show_test.rb b/test/integration/contracts_show_test.rb
index a019f32..e99997b 100644
--- a/test/integration/contracts_show_test.rb
+++ b/test/integration/contracts_show_test.rb
@@ -426,7 +426,59 @@ class ContractsShowTest < ActionController::IntegrationTest
end
end
end
-
+
+ should "show an alert if there is orphaned time or issues" do
+ configure_overhead_plugin
+
+ @manager = User.generate!
+
+ @deliverable1 = FixedDeliverable.generate!(:contract => @contract, :manager => @manager)
+
+ @issue1 = Issue.generate_for_project!(@project)
+ @time_entry1 = TimeEntry.generate!(:issue => @issue1,
+ :project => @project,
+ :activity => @billable_activity,
+ :spent_on => Date.today,
+ :hours => 10,
+ :user => @manager)
+ @time_entry2 = TimeEntry.generate!(:issue => @issue1,
+ :project => @project,
+ :activity => @non_billable_activity,
+ :spent_on => Date.today,
+ :hours => 5,
+ :user => @manager)
+ @deliverable1.issues << @issue1
+
+ @orphaned_issue = Issue.generate_for_project!(@project)
+ @time_entry_on_orphaned_issue = TimeEntry.generate!(:issue => @orphaned_issue,
+ :project => @project,
+ :activity => @billable_activity,
+ :spent_on => Date.today,
+ :hours => 10,
+ :user => @manager)
+
+ @time_entry_on_project = TimeEntry.generate!(:issue => nil,
+ :project => @project,
+ :activity => @billable_activity,
+ :spent_on => Date.today,
+ :hours => 10,
+ :user => @manager)
+
+ @rate = Rate.generate!(:project => @project,
+ :user => @manager,
+ :date_in_effect => Date.yesterday,
+ :amount => 100)
+
+
+ assert_equal 1, @deliverable1.issues.count
+
+ visit_contract_page(@contract)
+ assert_select "div.error_msg" do
+ assert_select "p", :text => /2,000/
+ assert_select "a", :text => /update/i
+ end
+
+ end
should "show the current period for a Retainer" do
today_mock = Date.new(2010,2,15)