|
1 | NO CONTENT: new file 100644, binary diff hidden |
@@ -174,6 +174,7 class IssuesController < ApplicationController | |||
|
174 | 174 | @assignables << @issue.assigned_to if @issue.assigned_to && !@assignables.include?(@issue.assigned_to) |
|
175 | 175 | @can = {:edit => User.current.allowed_to?(:edit_issues, @project), |
|
176 | 176 | :change_status => User.current.allowed_to?(:change_issue_status, @project), |
|
177 | :add => User.current.allowed_to?(:add_issues, @project), | |
|
177 | 178 | :move => User.current.allowed_to?(:move_issues, @project), |
|
178 | 179 | :delete => User.current.allowed_to?(:delete_issues, @project)} |
|
179 | 180 | render :layout => false |
@@ -192,43 +192,45 class ProjectsController < ApplicationController | |||
|
192 | 192 | end |
|
193 | 193 | |
|
194 | 194 | # Add a new issue to @project |
|
195 | # The new issue will be created from an existing one if copy_from parameter is given | |
|
195 | 196 | def add_issue |
|
196 | @tracker = Tracker.find(params[:tracker_id]) | |
|
197 | @priorities = Enumeration::get_values('IPRI') | |
|
197 | @issue = params[:copy_from] ? Issue.new.copy_from(params[:copy_from]) : Issue.new(params[:issue]) | |
|
198 | @issue.project = @project | |
|
199 | @issue.author = User.current | |
|
200 | @issue.tracker ||= Tracker.find(params[:tracker_id]) | |
|
198 | 201 | |
|
199 | 202 | default_status = IssueStatus.default |
|
200 | 203 | unless default_status |
|
201 | flash.now[:error] = 'No default issue status defined. Please check your configuration.' | |
|
204 | flash.now[:error] = 'No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").' | |
|
202 | 205 | render :nothing => true, :layout => true |
|
203 | 206 | return |
|
204 | end | |
|
205 | @issue = Issue.new(:project => @project, :tracker => @tracker) | |
|
207 | end | |
|
206 | 208 | @issue.status = default_status |
|
207 | 209 | @allowed_statuses = ([default_status] + default_status.find_new_statuses_allowed_to(logged_in_user.role_for_project(@project), @issue.tracker))if logged_in_user |
|
210 | ||
|
208 | 211 | if request.get? |
|
209 | @issue.start_date = Date.today | |
|
210 | @custom_values = @project.custom_fields_for_issues(@tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue) } | |
|
212 | @issue.start_date ||= Date.today | |
|
213 | @custom_values = @issue.custom_values.empty? ? | |
|
214 | @project.custom_fields_for_issues(@issue.tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue) } : | |
|
215 | @issue.custom_values | |
|
211 | 216 | else |
|
212 | @issue.attributes = params[:issue] | |
|
213 | ||
|
214 | 217 | requested_status = IssueStatus.find_by_id(params[:issue][:status_id]) |
|
218 | # Check that the user is allowed to apply the requested status | |
|
215 | 219 | @issue.status = (@allowed_statuses.include? requested_status) ? requested_status : default_status |
|
216 | ||
|
217 | @issue.author_id = self.logged_in_user.id if self.logged_in_user | |
|
218 | # Multiple file upload | |
|
219 | @attachments = [] | |
|
220 | params[:attachments].each { |a| | |
|
221 | @attachments << Attachment.new(:container => @issue, :file => a, :author => logged_in_user) unless a.size == 0 | |
|
222 | } if params[:attachments] and params[:attachments].is_a? Array | |
|
223 | @custom_values = @project.custom_fields_for_issues(@tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue, :value => params["custom_fields"][x.id.to_s]) } | |
|
220 | @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]) } | |
|
224 | 221 | @issue.custom_values = @custom_values |
|
225 | 222 | if @issue.save |
|
226 | @attachments.each(&:save) | |
|
223 | if params[:attachments] && params[:attachments].is_a?(Array) | |
|
224 | # Save attachments | |
|
225 | params[:attachments].each {|a| Attachment.create(:container => @issue, :file => a, :author => User.current) unless a.size == 0} | |
|
226 | end | |
|
227 | 227 | flash[:notice] = l(:notice_successful_create) |
|
228 | 228 | Mailer.deliver_issue_add(@issue) if Setting.notified_events.include?('issue_added') |
|
229 | 229 | redirect_to :action => 'list_issues', :id => @project |
|
230 | return | |
|
230 | 231 | end |
|
231 | 232 | end |
|
233 | @priorities = Enumeration::get_values('IPRI') | |
|
232 | 234 | end |
|
233 | 235 | |
|
234 | 236 | # Show filtered/sorted issues list of @project |
@@ -54,6 +54,13 class Issue < ActiveRecord::Base | |||
|
54 | 54 | end |
|
55 | 55 | end |
|
56 | 56 | |
|
57 | def copy_from(arg) | |
|
58 | issue = arg.is_a?(Issue) ? arg : Issue.find(arg) | |
|
59 | self.attributes = issue.attributes.dup | |
|
60 | self.custom_values = issue.custom_values.collect {|v| v.clone} | |
|
61 | self | |
|
62 | end | |
|
63 | ||
|
57 | 64 | def priority_id=(pid) |
|
58 | 65 | self.priority = nil |
|
59 | 66 | write_attribute(:priority_id, pid) |
@@ -31,6 +31,8 | |||
|
31 | 31 | :selected => @issue.assigned_to.nil?, :disabled => !(@can[:edit] || @can[:change_status]) %></li> |
|
32 | 32 | </ul> |
|
33 | 33 | </li> |
|
34 | <li><%= context_menu_link l(:button_copy), {:controller => 'projects', :action => 'add_issue', :id => @project, :copy_from => @issue}, | |
|
35 | :class => 'icon-copy', :disabled => !@can[:add] %></li> | |
|
34 | 36 | <li><%= context_menu_link l(:button_move), {:controller => 'projects', :action => 'move_issues', :id => @project, "issue_ids[]" => @issue.id }, |
|
35 | 37 | :class => 'icon-move', :disabled => !@can[:move] %> |
|
36 | 38 | <li><%= context_menu_link l(:button_delete), {:controller => 'issues', :action => 'destroy', :id => @issue}, |
@@ -3,6 +3,7 | |||
|
3 | 3 | <%= link_to_if_authorized l(:button_edit), {:controller => 'issues', :action => 'edit', :id => @issue}, :class => 'icon icon-edit', :accesskey => accesskey(:edit) %> |
|
4 | 4 | <%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'edit', :issue_id => @issue}, :class => 'icon icon-time' %> |
|
5 | 5 | <%= watcher_tag(@issue, User.current) %> |
|
6 | <%= link_to_if_authorized l(:button_copy), {:controller => 'projects', :action => 'add_issue', :id => @project, :copy_from => @issue }, :class => 'icon icon-copy' %> | |
|
6 | 7 | <%= link_to_if_authorized l(:button_move), {:controller => 'projects', :action => 'move_issues', :id => @project, "issue_ids[]" => @issue.id }, :class => 'icon icon-move' %> |
|
7 | 8 | <%= link_to_if_authorized l(:button_delete), {:controller => 'issues', :action => 'destroy', :id => @issue}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %> |
|
8 | 9 | </div> |
@@ -1,10 +1,10 | |||
|
1 |
<h2><%=l(:label_issue_new)%>: <%= @ |
|
|
1 | <h2><%=l(:label_issue_new)%>: <%= @issue.tracker %></h2> | |
|
2 | 2 | |
|
3 | 3 | <% labelled_tabular_form_for :issue, @issue, |
|
4 | 4 | :url => {:action => 'add_issue'}, |
|
5 | 5 | :html => {:multipart => true, :id => 'issue-form'} do |f| %> |
|
6 |
<%= hidden_field |
|
|
7 |
<%= render :partial => 'issues/form', :locals => {:f => f} %> |
|
|
6 | <%= f.hidden_field :tracker_id %> | |
|
7 | <%= render :partial => 'issues/form', :locals => {:f => f} %> | |
|
8 | 8 | <%= submit_tag l(:button_create) %> |
|
9 | 9 | <%= link_to_remote l(:label_preview), |
|
10 | 10 | { :url => { :controller => 'issues', :action => 'preview', :id => @issue }, |
@@ -476,6 +476,7 button_unarchive: Unarchive | |||
|
476 | 476 | button_reset: Reset |
|
477 | 477 | button_rename: Rename |
|
478 | 478 | button_change_password: Change password |
|
479 | button_copy: Copy | |
|
479 | 480 | |
|
480 | 481 | status_active: active |
|
481 | 482 | status_registered: registered |
@@ -476,6 +476,7 button_unarchive: Désarchiver | |||
|
476 | 476 | button_reset: Réinitialiser |
|
477 | 477 | button_rename: Renommer |
|
478 | 478 | button_change_password: Changer de mot de passe |
|
479 | button_copy: Copier | |
|
479 | 480 | |
|
480 | 481 | status_active: actif |
|
481 | 482 | status_registered: enregistré |
@@ -421,6 +421,7 vertical-align: middle; | |||
|
421 | 421 | |
|
422 | 422 | .icon-add { background-image: url(../images/add.png); } |
|
423 | 423 | .icon-edit { background-image: url(../images/edit.png); } |
|
424 | .icon-copy { background-image: url(../images/copy.png); } | |
|
424 | 425 | .icon-del { background-image: url(../images/delete.png); } |
|
425 | 426 | .icon-move { background-image: url(../images/move.png); } |
|
426 | 427 | .icon-save { background-image: url(../images/save.png); } |
@@ -22,7 +22,7 require 'projects_controller' | |||
|
22 | 22 | class ProjectsController; def rescue_action(e) raise e end; end |
|
23 | 23 | |
|
24 | 24 | class ProjectsControllerTest < Test::Unit::TestCase |
|
25 | fixtures :projects, :users, :roles, :enabled_modules, :enumerations | |
|
25 | fixtures :projects, :users, :roles, :members, :issues, :enabled_modules, :enumerations | |
|
26 | 26 | |
|
27 | 27 | def setup |
|
28 | 28 | @controller = ProjectsController.new |
@@ -143,4 +143,23 class ProjectsControllerTest < Test::Unit::TestCase | |||
|
143 | 143 | assert_redirected_to 'admin/projects' |
|
144 | 144 | assert Project.find(1).active? |
|
145 | 145 | end |
|
146 | ||
|
147 | def test_add_issue | |
|
148 | @request.session[:user_id] = 2 | |
|
149 | get :add_issue, :id => 1, :tracker_id => 1 | |
|
150 | assert_response :success | |
|
151 | assert_template 'add_issue' | |
|
152 | post :add_issue, :id => 1, :issue => {:tracker_id => 1, :subject => 'This is the test_add_issue issue', :description => 'This is the description', :priority_id => 5} | |
|
153 | assert_redirected_to 'projects/list_issues' | |
|
154 | assert Issue.find_by_subject('This is the test_add_issue issue') | |
|
155 | end | |
|
156 | ||
|
157 | def test_copy_issue | |
|
158 | @request.session[:user_id] = 2 | |
|
159 | get :add_issue, :id => 1, :copy_from => 1 | |
|
160 | assert_template 'add_issue' | |
|
161 | assert_not_nil assigns(:issue) | |
|
162 | orig = Issue.find(1) | |
|
163 | assert_equal orig.subject, assigns(:issue).subject | |
|
164 | end | |
|
146 | 165 | end |
@@ -18,13 +18,23 | |||
|
18 | 18 | require File.dirname(__FILE__) + '/../test_helper' |
|
19 | 19 | |
|
20 | 20 | class IssueTest < Test::Unit::TestCase |
|
21 | fixtures :projects, :users, :members, :trackers, :issue_statuses, :issue_categories, :enumerations, :issues | |
|
21 | fixtures :projects, :users, :members, :trackers, :issue_statuses, :issue_categories, :enumerations, :issues, :custom_fields, :custom_values | |
|
22 | 22 | |
|
23 | 23 | def test_category_based_assignment |
|
24 | 24 | issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => Enumeration.get_values('IPRI').first, :subject => 'Assignment test', :description => 'Assignment test', :category_id => 1) |
|
25 | 25 | assert_equal IssueCategory.find(1).assigned_to, issue.assigned_to |
|
26 | 26 | end |
|
27 | 27 | |
|
28 | def test_copy | |
|
29 | issue = Issue.new.copy_from(1) | |
|
30 | assert issue.save | |
|
31 | issue.reload | |
|
32 | orig = Issue.find(1) | |
|
33 | assert_equal orig.subject, issue.subject | |
|
34 | assert_equal orig.tracker, issue.tracker | |
|
35 | assert_equal orig.custom_values.first.value, issue.custom_values.first.value | |
|
36 | end | |
|
37 | ||
|
28 | 38 | def test_close_duplicates |
|
29 | 39 | # Create 3 issues |
|
30 | 40 | issue1 = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :priority => Enumeration.get_values('IPRI').first, :subject => 'Duplicates test', :description => 'Duplicates test') |
General Comments 0
You need to be logged in to leave comments.
Login now