summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2006-09-09 16:07:02 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2006-09-09 16:07:02 +0000
commit5f185b6c0532595e4a165600db9f99c5475289bb (patch)
tree943ad5fc8d033df2a79d3a680fefa916aa23bf43
parent893a433165489ddd5029e430f5a225d330e42e66 (diff)
downloadredmine-5f185b6c0532595e4a165600db9f99c5475289bb.tar.gz
redmine-5f185b6c0532595e4a165600db9f99c5475289bb.zip
data locking for issues
git-svn-id: http://redmine.rubyforge.org/svn/trunk@23 e93f8b46-1217-0410-a6f0-8f06a7374b81
-rw-r--r--redmine/app/controllers/issues_controller.rb107
-rw-r--r--redmine/app/views/issues/change_status.rhtml3
-rw-r--r--redmine/app/views/issues/edit.rhtml2
-rw-r--r--redmine/app/views/issues/show.rhtml2
-rw-r--r--redmine/db/migrate/001_setup.rb3
-rw-r--r--redmine/lang/de.yml1
-rw-r--r--redmine/lang/en.yml1
-rw-r--r--redmine/lang/es.yml1
-rw-r--r--redmine/lang/fr.yml1
9 files changed, 66 insertions, 55 deletions
diff --git a/redmine/app/controllers/issues_controller.rb b/redmine/app/controllers/issues_controller.rb
index 07f2c7736..9452995fb 100644
--- a/redmine/app/controllers/issues_controller.rb
+++ b/redmine/app/controllers/issues_controller.rb
@@ -16,61 +16,66 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class IssuesController < ApplicationController
- layout 'base'
- before_filter :find_project, :authorize
+ layout 'base'
+ before_filter :find_project, :authorize
- helper :custom_fields
- include CustomFieldsHelper
-
- def show
- @status_options = @issue.status.workflows.find(:all, :conditions => ["role_id=? and tracker_id=?", self.logged_in_user.role_for_project(@project.id), @issue.tracker.id]).collect{ |w| w.new_status } if self.logged_in_user
+ helper :custom_fields
+ include CustomFieldsHelper
+
+ def show
+ @status_options = @issue.status.workflows.find(:all, :include => :new_status, :conditions => ["role_id=? and tracker_id=?", self.logged_in_user.role_for_project(@project.id), @issue.tracker.id]).collect{ |w| w.new_status } if self.logged_in_user
@custom_values = @issue.custom_values.find(:all, :include => :custom_field)
- end
+ end
- def edit
- @priorities = Enumeration::get_values('IPRI')
-
- if request.get?
- @custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| @issue.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x, :customized => @issue) }
- else
- # Retrieve custom fields and values
- @custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue, :value => params["custom_fields"][x.id.to_s]) }
- @issue.custom_values = @custom_values
- @issue.attributes = params[:issue]
- if @issue.save
- flash[:notice] = l(:notice_successful_update)
- redirect_to :action => 'show', :id => @issue
- end
- end
- end
-
- def change_status
- @history = @issue.histories.build(params[:history])
+ def edit
+ @priorities = Enumeration::get_values('IPRI')
+ if request.get?
+ @custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| @issue.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x, :customized => @issue) }
+ else
+ begin
+ # Retrieve custom fields and values
+ @custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue, :value => params["custom_fields"][x.id.to_s]) }
+ @issue.custom_values = @custom_values
+ @issue.attributes = params[:issue]
+ if @issue.save
+ flash[:notice] = l(:notice_successful_update)
+ redirect_to :action => 'show', :id => @issue
+ end
+ rescue ActiveRecord::StaleObjectError
+ # Optimistic locking exception
+ flash[:notice] = l(:notice_locking_conflict)
+ end
+ end
+ end
+
+ def change_status
+ @history = @issue.histories.build(params[:history])
@status_options = @issue.status.workflows.find(:all, :conditions => ["role_id=? and tracker_id=?", self.logged_in_user.role_for_project(@project.id), @issue.tracker.id]).collect{ |w| w.new_status } if self.logged_in_user
-
- if params[:confirm]
- @history.author_id = self.logged_in_user.id if self.logged_in_user
-
- if @history.save
- @issue.status = @history.status
- @issue.fixed_version_id = (params[:issue][:fixed_version_id])
- @issue.assigned_to_id = (params[:issue][:assigned_to_id])
- if @issue.save
- flash[:notice] = l(:notice_successful_update)
- Mailer.deliver_issue_change_status(@issue) if Permission.find_by_controller_and_action(@params[:controller], @params[:action]).mail_enabled?
- redirect_to :action => 'show', :id => @issue
- end
- end
- end
+ if params[:confirm]
+ begin
+ @history.author_id = self.logged_in_user.id if self.logged_in_user
+ @issue.status = @history.status
+ @issue.fixed_version_id = (params[:issue][:fixed_version_id])
+ @issue.assigned_to_id = (params[:issue][:assigned_to_id])
+ @issue.lock_version = (params[:issue][:lock_version])
+ if @issue.save
+ flash[:notice] = l(:notice_successful_update)
+ Mailer.deliver_issue_change_status(@issue) if Permission.find_by_controller_and_action(@params[:controller], @params[:action]).mail_enabled?
+ redirect_to :action => 'show', :id => @issue
+ end
+ rescue ActiveRecord::StaleObjectError
+ # Optimistic locking exception
+ flash[:notice] = l(:notice_locking_conflict)
+ end
+ end
@assignable_to = @project.members.find(:all, :include => :user).collect{ |m| m.user }
-
- end
-
- def destroy
- @issue.destroy
- redirect_to :controller => 'projects', :action => 'list_issues', :id => @project
- end
-
+ end
+
+ def destroy
+ @issue.destroy
+ redirect_to :controller => 'projects', :action => 'list_issues', :id => @project
+ end
+
def add_attachment
# Save the attachment
if params[:attachment][:file].size > 0
@@ -94,7 +99,7 @@ class IssuesController < ApplicationController
private
def find_project
- @issue = Issue.find(params[:id])
+ @issue = Issue.find(params[:id], :include => [:project, :tracker, :status, :author, :priority, :category])
@project = @issue.project
end
end
diff --git a/redmine/app/views/issues/change_status.rhtml b/redmine/app/views/issues/change_status.rhtml
index 9c14bdb88..e525de60d 100644
--- a/redmine/app/views/issues/change_status.rhtml
+++ b/redmine/app/views/issues/change_status.rhtml
@@ -24,6 +24,7 @@
<p><label for="history_notes"><%=l(:field_notes)%></label>
<%= text_area 'history', 'notes', :cols => 60, :rows => 10 %></p>
</div>
-
+
+<%= hidden_field 'issue', 'lock_version' %>
<%= submit_tag l(:button_save) %>
<%= end_form_tag %>
diff --git a/redmine/app/views/issues/edit.rhtml b/redmine/app/views/issues/edit.rhtml
index 5a118f893..13f9e4399 100644
--- a/redmine/app/views/issues/edit.rhtml
+++ b/redmine/app/views/issues/edit.rhtml
@@ -21,6 +21,6 @@
</select></p>
<!--[eoform:issue]-->
</div>
-
+<%= f.hidden_field :lock_version %>
<%= submit_tag l(:button_save) %>
<% end %> \ No newline at end of file
diff --git a/redmine/app/views/issues/show.rhtml b/redmine/app/views/issues/show.rhtml
index acba6af0c..fc48e47a1 100644
--- a/redmine/app/views/issues/show.rhtml
+++ b/redmine/app/views/issues/show.rhtml
@@ -49,7 +49,7 @@
<div class="box">
<h3><%=l(:label_history)%></h3>
<table width="100%">
-<% for history in @issue.histories.find(:all, :include => :author) %>
+<% for history in @issue.histories.find(:all, :include => [:author, :status]) %>
<tr>
<td><%= format_date(history.created_on) %></td>
<td><%= history.author.display_name %></td>
diff --git a/redmine/db/migrate/001_setup.rb b/redmine/db/migrate/001_setup.rb
index 65fd23422..00d788bec 100644
--- a/redmine/db/migrate/001_setup.rb
+++ b/redmine/db/migrate/001_setup.rb
@@ -120,7 +120,8 @@ class Setup < ActiveRecord::Migration
t.column "assigned_to_id", :integer
t.column "priority_id", :integer, :default => 0, :null => false
t.column "fixed_version_id", :integer
- t.column "author_id", :integer, :default => 0, :null => false
+ t.column "author_id", :integer, :default => 0, :null => false
+ t.column "lock_version", :integer, :default => 0, :null => false
t.column "created_on", :timestamp
t.column "updated_on", :timestamp
end
diff --git a/redmine/lang/de.yml b/redmine/lang/de.yml
index cdfffabde..7fcecca94 100644
--- a/redmine/lang/de.yml
+++ b/redmine/lang/de.yml
@@ -58,6 +58,7 @@ notice_successful_update: Erfolgreiches Update.
notice_successful_delete: Erfolgreiche Auslassung.
notice_successful_connection: Erfolgreicher Anschluß.
notice_file_not_found: Erbetene Akte besteht nicht oder ist gelöscht worden.
+notice_locking_conflict: Data have been updated by another user.
gui_validation_error: 1 Störung
gui_validation_error_plural: %d Störungen
diff --git a/redmine/lang/en.yml b/redmine/lang/en.yml
index 7fd806362..780d06c34 100644
--- a/redmine/lang/en.yml
+++ b/redmine/lang/en.yml
@@ -58,6 +58,7 @@ notice_successful_update: Successful update.
notice_successful_delete: Successful deletion.
notice_successful_connection: Successful connection.
notice_file_not_found: Requested file doesn't exist or has been deleted.
+notice_locking_conflict: Data have been updated by another user.
gui_validation_error: 1 error
gui_validation_error_plural: %d errors
diff --git a/redmine/lang/es.yml b/redmine/lang/es.yml
index a9806b3e3..85d78d31e 100644
--- a/redmine/lang/es.yml
+++ b/redmine/lang/es.yml
@@ -58,6 +58,7 @@ notice_successful_update: Successful update.
notice_successful_delete: Successful deletion.
notice_successful_connection: Successful connection.
notice_file_not_found: Requested file doesn't exist or has been deleted.
+notice_locking_conflict: Data have been updated by another user.
gui_validation_error: 1 error
gui_validation_error_plural: %d errores
diff --git a/redmine/lang/fr.yml b/redmine/lang/fr.yml
index 5c2936801..a321b7dae 100644
--- a/redmine/lang/fr.yml
+++ b/redmine/lang/fr.yml
@@ -58,6 +58,7 @@ notice_successful_update: Mise à jour effectuée avec succès.
notice_successful_delete: Suppression effectuée avec succès.
notice_successful_connection: Connection réussie.
notice_file_not_found: Le fichier demandé n'existe pas ou a été supprimé.
+notice_locking_conflict: Les données ont été mises à jour par un autre utilisateur. Mise à jour impossible.
gui_validation_error: 1 erreur
gui_validation_error_plural: %d erreurs