diff --git a/app/models/deliverable.rb b/app/models/deliverable.rb
index e6a24ac..2e785ba 100644
--- a/app/models/deliverable.rb
+++ b/app/models/deliverable.rb
@@ -21,12 +21,16 @@ class Deliverable < ActiveRecord::Base
validates_presence_of :manager
validates_inclusion_of :status, :in => ["open","locked","closed"], :allow_blank => true, :allow_nil => true
validate_on_update :validate_status_changes
+ validate_on_update :validate_contract_status
# Accessors
include DollarizedAttribute
dollarized_attribute :total
delegate :name, :to => :contract, :prefix => true, :allow_nil => true
+ delegate "open?", :to => :contract, :prefix => true, :allow_nil => true
+ delegate "closed?", :to => :contract, :prefix => true, :allow_nil => true
+ delegate "locked?", :to => :contract, :prefix => true, :allow_nil => true
# Callbacks
def after_initialize
@@ -104,6 +108,14 @@ class Deliverable < ActiveRecord::Base
errors.add_to_base(:cant_update_closed_deliverable) if closed?
end
+ def validate_contract_status
+ return if contract_open?
+ return if change_to_status_only?
+
+ errors.add_to_base(:cant_update_locked_contract) if contract_locked?
+ errors.add_to_base(:cant_update_closed_contract) if contract_closed?
+ end
+
# No operation method, useful to clean up logic with an optional message
# for documentation
def noop(message="")
diff --git a/app/views/deliverables/_form.html.erb b/app/views/deliverables/_form.html.erb
index 54ddded..fdd4357 100644
--- a/app/views/deliverables/_form.html.erb
+++ b/app/views/deliverables/_form.html.erb
@@ -2,9 +2,14 @@
<%= javascript_tag("var i18nEndDateEmpty = '#{l(:text_end_date_empty)}'") %>
<%= javascript_tag("var i18nChangedPeriodMessage = '#{l(:text_changed_period_message)}'") %>
-<% if resource.locked? || resource.closed? %>
+<% if resource.locked? || resource.closed? || resource.contract_locked? || resource.contract_closed? %>
+ <% if resource.contract_locked? || resource.contract_closed? %>
+
<%= resource.contract_locked? ? l(:text_contract_locked_warning) : l(:text_contract_closed_warning) %>
+ <% end %>
+ <% if resource.locked? || resource.closed? %>
<%= resource.locked? ? l(:text_deliverable_locked_warning) : l(:text_deliverable_closed_warning) %>
+ <% end %>
<% end %>
diff --git a/test/integration/deliverables_edit_test.rb b/test/integration/deliverables_edit_test.rb
index 72c71f6..8d1b569 100644
--- a/test/integration/deliverables_edit_test.rb
+++ b/test/integration/deliverables_edit_test.rb
@@ -629,6 +629,86 @@ class DeliverablesEditTest < ActionController::IntegrationTest
end
end
+ context "a Deliverable on a locked Contract" do
+ setup do
+ assert @contract.lock!
+ end
+
+ should "be blocked from editing" do
+ visit_contract_page(@contract)
+ click_link_within "#deliverable_details_#{@fixed_deliverable.id}", 'Edit'
+ assert_response :success
+ within("#deliverable-details") do
+ fill_in "Title", :with => 'An updated title'
+ end
+
+ click_button "Save"
+
+ assert_response :success
+ assert_template 'deliverables/edit'
+
+ assert_not_equal "An updated title", @fixed_deliverable.reload.title
+ end
+
+ should "allow status only changes" do
+ visit_contract_page(@contract)
+ click_link_within "#deliverable_details_#{@fixed_deliverable.id}", 'Edit'
+ assert_response :success
+
+ within("#deliverable-details") do
+ select "Locked", :from => "Status"
+ end
+
+ click_button "Save"
+
+ assert_response :success
+ assert_template 'contracts/show'
+
+ assert @fixed_deliverable.reload.locked?
+ end
+
+ end
+
+ context "a Deliverable on a closed Contract" do
+ setup do
+ assert @contract.close!
+ end
+
+ should "be blocked from editing" do
+ visit_contract_page(@contract)
+ click_link_within "#deliverable_details_#{@fixed_deliverable.id}", 'Edit'
+ assert_response :success
+
+ within("#deliverable-details") do
+ fill_in "Title", :with => 'An updated title'
+ end
+
+ click_button "Save"
+
+ assert_response :success
+ assert_template 'deliverables/edit'
+
+ assert_not_equal "An updated title", @fixed_deliverable.reload.title
+ end
+
+ should "allow status only changes" do
+ visit_contract_page(@contract)
+ click_link_within "#deliverable_details_#{@fixed_deliverable.id}", 'Edit'
+ assert_response :success
+
+ within("#deliverable-details") do
+ select "Locked", :from => "Status"
+ end
+
+ click_button "Save"
+
+ assert_response :success
+ assert_template 'contracts/show'
+
+ assert @fixed_deliverable.reload.locked?
+ end
+
+ end
end