diff --git a/app/models/deliverable.rb b/app/models/deliverable.rb
index af6ce39..1a7ddef 100644
--- a/app/models/deliverable.rb
+++ b/app/models/deliverable.rb
@@ -21,7 +21,7 @@ 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
+ validate :validate_contract_status
# Accessors
include DollarizedAttribute
@@ -117,8 +117,21 @@ class Deliverable < ActiveRecord::Base
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?
+ if contract_locked?
+ if new_record?
+ errors.add_to_base(:cant_create_deliverable_on_locked_contract)
+ else
+ errors.add_to_base(:cant_update_locked_contract)
+ end
+ end
+
+ if contract_closed?
+ if new_record?
+ errors.add_to_base(:cant_create_deliverable_on_closed_contract)
+ else
+ errors.add_to_base(:cant_update_closed_contract)
+ end
+ end
end
# No operation method, useful to clean up logic with an optional message
diff --git a/app/views/contracts/show.html.erb b/app/views/contracts/show.html.erb
index aff2cda..79e0e81 100644
--- a/app/views/contracts/show.html.erb
+++ b/app/views/contracts/show.html.erb
@@ -102,7 +102,7 @@
diff --git a/config/locales/en.yml b/config/locales/en.yml
index f7e8c3a..acb3852 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -11,6 +11,8 @@ en:
cant_update_closed_deliverable: "Can't update a closed deliverable"
cant_update_locked_contract: "Can't update a locked contract"
cant_update_closed_contract: "Can't update a closed contract"
+ cant_create_deliverable_on_locked_contract: "Can't create a deliverable on a locked contract"
+ cant_create_deliverable_on_closed_contract: "Can't create a deliverable on a closed contract"
field_end_date: End Date
field_executed: Executed
diff --git a/test/integration/redmine_contracts/hooks/view_issues_bulk_edit_details_bottom_hook_test.rb b/test/integration/redmine_contracts/hooks/view_issues_bulk_edit_details_bottom_hook_test.rb
index 3c0d6a8..f33b8df 100644
--- a/test/integration/redmine_contracts/hooks/view_issues_bulk_edit_details_bottom_hook_test.rb
+++ b/test/integration/redmine_contracts/hooks/view_issues_bulk_edit_details_bottom_hook_test.rb
@@ -11,8 +11,8 @@ class RedmineContracts::Hooks::ViewIssuesBulkEditDetailsBottomHookTest < ActionC
@issue3 = Issue.generate_for_project!(@project)
@contract1 = Contract.generate!(:project => @project)
@contract2 = Contract.generate!(:project => @project)
- @locked_contract = Contract.generate!(:project => @project, :status => 'locked')
- @closed_contract = Contract.generate!(:project => @project, :status => 'closed')
+ @locked_contract = Contract.generate!(:project => @project)
+ @closed_contract = Contract.generate!(:project => @project)
@manager = User.generate!(:login => 'manager', :password => 'existing', :password_confirmation => 'existing')
@role = Role.generate!(:permissions => [:view_issues, :edit_issues])
@@ -26,6 +26,10 @@ class RedmineContracts::Hooks::ViewIssuesBulkEditDetailsBottomHookTest < ActionC
@deliverable_on_closed_contract = FixedDeliverable.generate!(:contract => @closed_contract, :manager => @manager, :title => 'Deliverable on closed contract')
@issue.deliverable = @deliverable1
+ # Set contract statuses now that all deliverables are created
+ assert @locked_contract.lock!
+ assert @closed_contract.close!
+
login_as('manager', 'existing')
end
diff --git a/test/integration/redmine_contracts/hooks/view_issues_form_details_bottom_hook_test.rb b/test/integration/redmine_contracts/hooks/view_issues_form_details_bottom_hook_test.rb
index 4f54296..b2995e8 100644
--- a/test/integration/redmine_contracts/hooks/view_issues_form_details_bottom_hook_test.rb
+++ b/test/integration/redmine_contracts/hooks/view_issues_form_details_bottom_hook_test.rb
@@ -9,8 +9,8 @@ class RedmineContracts::Hooks::ViewIssuesFormDetailsBottomTest < ActionControlle
@issue = Issue.generate_for_project!(@project)
@contract1 = Contract.generate!(:project => @project)
@contract2 = Contract.generate!(:project => @project)
- @locked_contract = Contract.generate!(:project => @project, :status => 'locked')
- @closed_contract = Contract.generate!(:project => @project, :status => 'closed')
+ @locked_contract = Contract.generate!(:project => @project)
+ @closed_contract = Contract.generate!(:project => @project)
@manager = User.generate!(:login => 'manager', :password => 'existing', :password_confirmation => 'existing')
@role = Role.generate!(:permissions => [:view_issues, :edit_issues])
@@ -25,6 +25,10 @@ class RedmineContracts::Hooks::ViewIssuesFormDetailsBottomTest < ActionControlle
@issue.deliverable = @deliverable1
assert @issue.save
+ # Set contract statuses now that all deliverables are created
+ assert @locked_contract.lock!
+ assert @closed_contract.close!
+
login_as('manager', 'existing')
end
diff --git a/test/unit/deliverable_test.rb b/test/unit/deliverable_test.rb
index 4cd7965..08b2d75 100644
--- a/test/unit/deliverable_test.rb
+++ b/test/unit/deliverable_test.rb
@@ -42,4 +42,23 @@ class DeliverableTest < ActiveSupport::TestCase
end
end
+ context "with a locked contract" do
+ should "block creating a new deliverable" do
+ contract = Contract.generate!(:status => "locked")
+ deliverable = FixedDeliverable.spawn(:contract => contract)
+
+ assert !deliverable.valid?
+ assert deliverable.errors.on_base.include?("Can't create a deliverable on a locked contract")
+ end
+ end
+
+ context "with a closed contract" do
+ should "block creating a new deliverable" do
+ contract = Contract.generate!(:status => "closed")
+ deliverable = FixedDeliverable.spawn(:contract => contract)
+
+ assert !deliverable.valid?
+ assert deliverable.errors.on_base.include?("Can't create a deliverable on a closed contract")
+ end
+ end
end