##// END OF EJS Templates
Workflow enhancement: editable and required fields configurable by role, tracker and status (#703, #3521)....
Jean-Philippe Lang -
r9794:d7b669e50b1c
parent child
Show More
@@ -0,0 +1,29
1 # Redmine - project management software
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 class WorkflowPermission < WorkflowRule
19 validates_inclusion_of :rule, :in => %w(readonly required)
20 validate :validate_field_name
21
22 protected
23
24 def validate_field_name
25 unless Tracker::CORE_FIELDS_ALL.include?(field_name) || field_name.to_s.match(/^\d+$/)
26 errors.add :field_name, :invalid
27 end
28 end
29 end
@@ -0,0 +1,39
1 # Redmine - project management software
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 class WorkflowTransition < WorkflowRule
19 validates_presence_of :new_status
20
21 # Returns workflow transitions count by tracker and role
22 def self.count_by_tracker_and_role
23 counts = connection.select_all("SELECT role_id, tracker_id, count(id) AS c FROM #{table_name} WHERE type = 'WorkflowTransition' GROUP BY role_id, tracker_id")
24 roles = Role.sorted.all
25 trackers = Tracker.sorted.all
26
27 result = []
28 trackers.each do |tracker|
29 t = []
30 roles.each do |role|
31 row = counts.detect {|c| c['role_id'].to_s == role.id.to_s && c['tracker_id'].to_s == tracker.id.to_s}
32 t << [role, (row.nil? ? 0 : row['c'].to_i)]
33 end
34 result << [tracker, t]
35 end
36
37 result
38 end
39 end
@@ -0,0 +1,91
1 <%= render :partial => 'action_menu' %>
2
3 <h2><%=l(:label_workflow)%></h2>
4
5 <div class="tabs">
6 <ul>
7 <li><%= link_to 'Status transitions', {:action => 'edit', :role_id => @role, :tracker_id => @tracker} %></li>
8 <li><%= link_to 'Fields permissions', {:action => 'permissions', :role_id => @role, :tracker_id => @tracker}, :class => 'selected' %></li>
9 </ul>
10 </div>
11
12 <p><%=l(:text_workflow_edit)%>:</p>
13
14 <%= form_tag({}, :method => 'get') do %>
15 <p>
16 <label><%=l(:label_role)%>:
17 <%= select_tag 'role_id', options_from_collection_for_select(@roles, "id", "name", @role && @role.id) %></label>
18
19 <label><%=l(:label_tracker)%>:
20 <%= select_tag 'tracker_id', options_from_collection_for_select(@trackers, "id", "name", @tracker && @tracker.id) %></label>
21
22 <%= submit_tag l(:button_edit), :name => nil %>
23 </p>
24 <% end %>
25
26 <% if @tracker && @role && @statuses.any? %>
27 <%= form_tag({}, :id => 'workflow_form' ) do %>
28 <%= hidden_field_tag 'tracker_id', @tracker.id %>
29 <%= hidden_field_tag 'role_id', @role.id %>
30 <div class="autoscroll">
31 <table class="list fields_permissions">
32 <thead>
33 <tr>
34 <th align="left">
35 </th>
36 <th align="center" colspan="<%= @statuses.length %>"><%=l(:label_issue_status)%></th>
37 </tr>
38 <tr>
39 <td></td>
40 <% for status in @statuses %>
41 <td width="<%= 75 / @statuses.size %>%" align="center">
42 <%=h status.name %>
43 </td>
44 <% end %>
45 </tr>
46 </thead>
47 <tbody>
48 <tr class="group open">
49 <td colspan="<%= @statuses.size + 1 %>">
50 <span class="expander" onclick="toggleRowGroup(this);">&nbsp;</span>
51 <%= l(:field_core_fields) %>
52 </td>
53 </tr>
54 <% @fields.each do |field, name| %>
55 <tr class="<%= cycle("odd", "even") %>">
56 <td>
57 <%=h name %>
58 </td>
59 <% for status in @statuses -%>
60 <td align="center" class="<%= @permissions[status.id][field] %>">
61 <%= field_permission_tag(@permissions, status, field) %>
62 </td>
63 <% end -%>
64 </tr>
65 <% end %>
66 <% if @custom_fields.any? %>
67 <tr class="group open">
68 <td colspan="<%= @statuses.size + 1 %>">
69 <span class="expander" onclick="toggleRowGroup(this);">&nbsp;</span>
70 <%= l(:label_custom_field_plural) %>
71 </td>
72 </tr>
73 <% @custom_fields.each do |field| %>
74 <tr class="<%= cycle("odd", "even") %>">
75 <td>
76 <%=h field.name %>
77 </td>
78 <% for status in @statuses -%>
79 <td align="center" class="<%= @permissions[status.id][field.id.to_s] %>">
80 <%= field_permission_tag(@permissions, status, field) %>
81 </td>
82 <% end -%>
83 </tr>
84 <% end %>
85 <% end %>
86 </tbody>
87 </table>
88 </div>
89 <%= submit_tag l(:button_save) %>
90 <% end %>
91 <% end %>
@@ -0,0 +1,9
1 class AddWorkflowsType < ActiveRecord::Migration
2 def up
3 add_column :workflows, :type, :string, :limit => 30
4 end
5
6 def down
7 remove_column :workflows, :type
8 end
9 end
@@ -0,0 +1,9
1 class UpdateWorkflowsToSti < ActiveRecord::Migration
2 def up
3 WorkflowRule.update_all "type = 'WorkflowTransition'"
4 end
5
6 def down
7 WorkflowRule.update_all "type = NULL"
8 end
9 end
@@ -0,0 +1,11
1 class AddWorkflowsRuleFields < ActiveRecord::Migration
2 def up
3 add_column :workflows, :field_name, :string, :limit => 30
4 add_column :workflows, :rule, :string, :limit => 30
5 end
6
7 def down
8 remove_column :workflows, :field_name
9 remove_column :workflows, :rule
10 end
11 end
@@ -129,11 +129,7 class IssuesController < ApplicationController
129 129 format.html { render :action => 'new', :layout => !request.xhr? }
130 130 format.js {
131 131 render(:update) { |page|
132 if params[:project_change]
133 page.replace_html 'all_attributes', :partial => 'form'
134 else
135 page.replace_html 'attributes', :partial => 'attributes'
136 end
132 page.replace_html 'all_attributes', :partial => 'form'
137 133 m = User.current.allowed_to?(:log_time, @issue.project) ? 'show' : 'hide'
138 134 page << "if ($('log_time')) {Element.#{m}('log_time');}"
139 135 }
@@ -46,7 +46,7 class RolesController < ApplicationController
46 46 if request.post? && @role.save
47 47 # workflow copy
48 48 if !params[:copy_workflow_from].blank? && (copy_from = Role.find_by_id(params[:copy_workflow_from]))
49 @role.workflows.copy(copy_from)
49 @role.workflow_rules.copy(copy_from)
50 50 end
51 51 flash[:notice] = l(:notice_successful_create)
52 52 redirect_to :action => 'index'
@@ -45,7 +45,7 class TrackersController < ApplicationController
45 45 if request.post? and @tracker.save
46 46 # workflow copy
47 47 if !params[:copy_workflow_from].blank? && (copy_from = Tracker.find_by_id(params[:copy_workflow_from]))
48 @tracker.workflows.copy(copy_from)
48 @tracker.workflow_rules.copy(copy_from)
49 49 end
50 50 flash[:notice] = l(:notice_successful_create)
51 51 redirect_to :action => 'index'
@@ -23,7 +23,7 class WorkflowsController < ApplicationController
23 23 before_filter :find_trackers
24 24
25 25 def index
26 @workflow_counts = Workflow.count_by_tracker_and_role
26 @workflow_counts = WorkflowTransition.count_by_tracker_and_role
27 27 end
28 28
29 29 def edit
@@ -31,16 +31,15 class WorkflowsController < ApplicationController
31 31 @tracker = Tracker.find_by_id(params[:tracker_id])
32 32
33 33 if request.post?
34 Workflow.destroy_all( ["role_id=? and tracker_id=?", @role.id, @tracker.id])
34 WorkflowTransition.destroy_all( ["role_id=? and tracker_id=?", @role.id, @tracker.id])
35 35 (params[:issue_status] || []).each { |status_id, transitions|
36 36 transitions.each { |new_status_id, options|
37 37 author = options.is_a?(Array) && options.include?('author') && !options.include?('always')
38 38 assignee = options.is_a?(Array) && options.include?('assignee') && !options.include?('always')
39 @role.workflows.build(:tracker_id => @tracker.id, :old_status_id => status_id, :new_status_id => new_status_id, :author => author, :assignee => assignee)
39 WorkflowTransition.create(:role_id => @role.id, :tracker_id => @tracker.id, :old_status_id => status_id, :new_status_id => new_status_id, :author => author, :assignee => assignee)
40 40 }
41 41 }
42 42 if @role.save
43 flash[:notice] = l(:notice_successful_update)
44 43 redirect_to :action => 'edit', :role_id => @role, :tracker_id => @tracker
45 44 return
46 45 end
@@ -53,7 +52,7 class WorkflowsController < ApplicationController
53 52 @statuses ||= IssueStatus.find(:all, :order => 'position')
54 53
55 54 if @tracker && @role && @statuses.any?
56 workflows = Workflow.all(:conditions => {:role_id => @role.id, :tracker_id => @tracker.id})
55 workflows = WorkflowTransition.all(:conditions => {:role_id => @role.id, :tracker_id => @tracker.id})
57 56 @workflows = {}
58 57 @workflows['always'] = workflows.select {|w| !w.author && !w.assignee}
59 58 @workflows['author'] = workflows.select {|w| w.author}
@@ -61,6 +60,37 class WorkflowsController < ApplicationController
61 60 end
62 61 end
63 62
63 def permissions
64 @role = Role.find_by_id(params[:role_id])
65 @tracker = Tracker.find_by_id(params[:tracker_id])
66
67 if @role && @tracker
68 if request.post?
69 WorkflowPermission.destroy_all({:role_id => @role.id, :tracker_id => @tracker.id})
70 (params[:permissions] || {}).each { |field, rule_by_status_id|
71 rule_by_status_id.each { |status_id, rule|
72 if rule.present?
73 WorkflowPermission.create(:role_id => @role.id, :tracker_id => @tracker.id, :old_status_id => status_id, :field_name => field, :rule => rule)
74 end
75 }
76 }
77 redirect_to :action => 'permissions', :role_id => @role, :tracker_id => @tracker
78 return
79 end
80
81 @statuses = @tracker.issue_statuses
82 @fields = (Tracker::CORE_FIELDS_ALL - @tracker.disabled_core_fields).map {|field| [field, l("field_"+field.sub(/_id$/, ''))]}
83 @custom_fields = @tracker.custom_fields
84
85 @permissions = WorkflowPermission.where(:tracker_id => @tracker.id, :role_id => @role.id).all.inject({}) do |h, w|
86 h[w.old_status_id] ||= {}
87 h[w.old_status_id][w.field_name] = w.rule
88 h
89 end
90 @statuses.each {|status| @permissions[status.id] ||= {}}
91 end
92 end
93
64 94 def copy
65 95
66 96 if params[:source_tracker_id].blank? || params[:source_tracker_id] == 'any'
@@ -83,7 +113,7 class WorkflowsController < ApplicationController
83 113 elsif @target_trackers.nil? || @target_roles.nil?
84 114 flash.now[:error] = l(:error_workflow_copy_target)
85 115 else
86 Workflow.copy(@source_tracker, @source_role, @target_trackers, @target_roles)
116 WorkflowRule.copy(@source_tracker, @source_role, @target_trackers, @target_roles)
87 117 flash[:notice] = l(:notice_successful_update)
88 118 redirect_to :action => 'copy', :source_tracker_id => @source_tracker, :source_role_id => @source_role
89 119 end
@@ -73,15 +73,17 module CustomFieldsHelper
73 73 end
74 74
75 75 # Return custom field label tag
76 def custom_field_label_tag(name, custom_value)
76 def custom_field_label_tag(name, custom_value, options={})
77 required = options[:required] || custom_value.custom_field.is_required?
78
77 79 content_tag "label", h(custom_value.custom_field.name) +
78 (custom_value.custom_field.is_required? ? " <span class=\"required\">*</span>".html_safe : ""),
79 :for => "#{name}_custom_field_values_#{custom_value.custom_field.id}"
80 (required ? " <span class=\"required\">*</span>".html_safe : ""),
81 :for => "#{name}_custom_field_values_#{custom_value.custom_field.id}"
80 82 end
81 83
82 84 # Return custom field tag with its label tag
83 def custom_field_tag_with_label(name, custom_value)
84 custom_field_label_tag(name, custom_value) + custom_field_tag(name, custom_value)
85 def custom_field_tag_with_label(name, custom_value, options={})
86 custom_field_label_tag(name, custom_value, options) + custom_field_tag(name, custom_value)
85 87 end
86 88
87 89 def custom_field_tag_for_bulk_edit(name, custom_field, projects=nil)
@@ -18,4 +18,10
18 18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 19
20 20 module WorkflowsHelper
21 def field_permission_tag(permissions, status, field)
22 name = field.is_a?(CustomField) ? field.id.to_s : field
23 select_tag("permissions[#{name}][#{status.id}]",
24 options_for_select([["", ""], ["Read-only", "readonly"], ["Required", "required"]], permissions[status.id][name])
25 )
26 end
21 27 end
@@ -58,7 +58,7 class Issue < ActiveRecord::Base
58 58 validates_length_of :subject, :maximum => 255
59 59 validates_inclusion_of :done_ratio, :in => 0..100
60 60 validates_numericality_of :estimated_hours, :allow_nil => true
61 validate :validate_issue
61 validate :validate_issue, :validate_required_fields
62 62
63 63 scope :visible,
64 64 lambda {|*args| { :include => :project,
@@ -146,6 +146,11 class Issue < ActiveRecord::Base
146 146 super
147 147 end
148 148
149 def reload(*args)
150 @workflow_rule_by_attribute = nil
151 super
152 end
153
149 154 # Overrides Redmine::Acts::Customizable::InstanceMethods#available_custom_fields
150 155 def available_custom_fields
151 156 (project && tracker) ? (project.all_issue_custom_fields & tracker.custom_fields.all) : []
@@ -208,7 +213,9 class Issue < ActiveRecord::Base
208 213
209 214 def status_id=(sid)
210 215 self.status = nil
211 write_attribute(:status_id, sid)
216 result = write_attribute(:status_id, sid)
217 @workflow_rule_by_attribute = nil
218 result
212 219 end
213 220
214 221 def priority_id=(pid)
@@ -230,6 +237,7 class Issue < ActiveRecord::Base
230 237 self.tracker = nil
231 238 result = write_attribute(:tracker_id, tid)
232 239 @custom_field_values = nil
240 @workflow_rule_by_attribute = nil
233 241 result
234 242 end
235 243
@@ -336,9 +344,10 class Issue < ActiveRecord::Base
336 344 :if => lambda {|issue, user| (issue.new_record? || user.allowed_to?(:edit_issues, issue.project)) &&
337 345 user.allowed_to?(:manage_subtasks, issue.project)}
338 346
339 def safe_attribute_names(*args)
340 names = super(*args)
347 def safe_attribute_names(user=nil)
348 names = super
341 349 names -= disabled_core_fields
350 names -= read_only_attribute_names(user)
342 351 names
343 352 end
344 353
@@ -362,15 +371,15 class Issue < ActiveRecord::Base
362 371 self.tracker_id = t
363 372 end
364 373
365 attrs = delete_unsafe_attributes(attrs, user)
366 return if attrs.empty?
367
368 if attrs['status_id']
369 unless new_statuses_allowed_to(user).collect(&:id).include?(attrs['status_id'].to_i)
370 attrs.delete('status_id')
374 if (s = attrs.delete('status_id')) && safe_attribute?('status_id')
375 if new_statuses_allowed_to(user).collect(&:id).include?(s.to_i)
376 self.status_id = s
371 377 end
372 378 end
373 379
380 attrs = delete_unsafe_attributes(attrs, user)
381 return if attrs.empty?
382
374 383 unless leaf?
375 384 attrs.reject! {|k,v| %w(priority_id done_ratio start_date due_date estimated_hours).include?(k)}
376 385 end
@@ -379,6 +388,14 class Issue < ActiveRecord::Base
379 388 attrs.delete('parent_issue_id') unless Issue.visible(user).exists?(attrs['parent_issue_id'].to_i)
380 389 end
381 390
391 if attrs['custom_field_values'].present?
392 attrs['custom_field_values'] = attrs['custom_field_values'].reject {|k, v| read_only_attribute_names(user).include? k.to_s}
393 end
394
395 if attrs['custom_fields'].present?
396 attrs['custom_fields'] = attrs['custom_fields'].reject {|c| read_only_attribute_names(user).include? c['id'].to_s}
397 end
398
382 399 # mass-assignment security bypass
383 400 assign_attributes attrs, :without_protection => true
384 401 end
@@ -387,6 +404,76 class Issue < ActiveRecord::Base
387 404 tracker ? tracker.disabled_core_fields : []
388 405 end
389 406
407 # Returns the custom_field_values that can be edited by the given user
408 def editable_custom_field_values(user=nil)
409 custom_field_values.reject do |value|
410 read_only_attribute_names(user).include?(value.custom_field_id.to_s)
411 end
412 end
413
414 # Returns the names of attributes that are read-only for user or the current user
415 # For users with multiple roles, the read-only fields are the intersection of
416 # read-only fields of each role
417 # The result is an array of strings where sustom fields are represented with their ids
418 #
419 # Examples:
420 # issue.read_only_attribute_names # => ['due_date', '2']
421 # issue.read_only_attribute_names(user) # => []
422 def read_only_attribute_names(user=nil)
423 workflow_rule_by_attribute(user).select {|attr, rule| rule == 'readonly'}.keys
424 end
425
426 # Returns the names of required attributes for user or the current user
427 # For users with multiple roles, the required fields are the intersection of
428 # required fields of each role
429 # The result is an array of strings where sustom fields are represented with their ids
430 #
431 # Examples:
432 # issue.required_attribute_names # => ['due_date', '2']
433 # issue.required_attribute_names(user) # => []
434 def required_attribute_names(user=nil)
435 workflow_rule_by_attribute(user).select {|attr, rule| rule == 'required'}.keys
436 end
437
438 # Returns true if the attribute is required for user
439 def required_attribute?(name, user=nil)
440 required_attribute_names(user).include?(name.to_s)
441 end
442
443 # Returns a hash of the workflow rule by attribute for the given user
444 #
445 # Examples:
446 # issue.workflow_rule_by_attribute # => {'due_date' => 'required', 'start_date' => 'readonly'}
447 def workflow_rule_by_attribute(user=nil)
448 return @workflow_rule_by_attribute if @workflow_rule_by_attribute && user.nil?
449
450 user_real = user || User.current
451 roles = user_real.admin ? Role.all : user_real.roles_for_project(project)
452 return {} if roles.empty?
453
454 result = {}
455 workflow_permissions = WorkflowPermission.where(:tracker_id => tracker_id, :old_status_id => status_id, :role_id => roles.map(&:id)).all
456 if workflow_permissions.any?
457 workflow_rules = workflow_permissions.inject({}) do |h, wp|
458 h[wp.field_name] ||= []
459 h[wp.field_name] << wp.rule
460 h
461 end
462 workflow_rules.each do |attr, rules|
463 next if rules.size < roles.size
464 uniq_rules = rules.uniq
465 if uniq_rules.size == 1
466 result[attr] = uniq_rules.first
467 else
468 result[attr] = 'required'
469 end
470 end
471 end
472 @workflow_rule_by_attribute = result if user.nil?
473 result
474 end
475 private :workflow_rule_by_attribute
476
390 477 def done_ratio
391 478 if Issue.use_status_for_done_ratio? && status && status.default_done_ratio
392 479 status.default_done_ratio
@@ -448,6 +535,25 class Issue < ActiveRecord::Base
448 535 end
449 536 end
450 537
538 # Validates the issue against additional workflow requirements
539 def validate_required_fields
540 user = new_record? ? author : current_journal.try(:user)
541
542 required_attribute_names(user).each do |attribute|
543 if attribute =~ /^\d+$/
544 attribute = attribute.to_i
545 v = custom_field_values.detect {|v| v.custom_field_id == attribute }
546 if v && v.value.blank?
547 errors.add :base, v.custom_field.name + ' ' + l('activerecord.errors.messages.blank')
548 end
549 else
550 if respond_to?(attribute) && send(attribute).blank?
551 errors.add attribute, :blank
552 end
553 end
554 end
555 end
556
451 557 # Set the done_ratio using the status if that setting is set. This will keep the done_ratios
452 558 # even if the user turns off the setting later
453 559 def update_done_ratio_from_issue_status
@@ -17,10 +17,10
17 17
18 18 class IssueStatus < ActiveRecord::Base
19 19 before_destroy :check_integrity
20 has_many :workflows, :foreign_key => "old_status_id"
20 has_many :workflows, :class_name => 'WorkflowTransition', :foreign_key => "old_status_id"
21 21 acts_as_list
22 22
23 before_destroy :delete_workflows
23 before_destroy :delete_workflow_rules
24 24 after_save :update_default
25 25
26 26 validates_presence_of :name
@@ -98,7 +98,7 private
98 98 end
99 99
100 100 # Deletes associated workflows
101 def delete_workflows
102 Workflow.delete_all(["old_status_id = :id OR new_status_id = :id", {:id => id}])
101 def delete_workflow_rules
102 WorkflowRule.delete_all(["old_status_id = :id OR new_status_id = :id", {:id => id}])
103 103 end
104 104 end
@@ -47,9 +47,9 class Role < ActiveRecord::Base
47 47 }
48 48
49 49 before_destroy :check_deletable
50 has_many :workflows, :dependent => :delete_all do
50 has_many :workflow_rules, :dependent => :delete_all do
51 51 def copy(source_role)
52 Workflow.copy(nil, source_role, nil, proxy_association.owner)
52 WorkflowRule.copy(nil, source_role, nil, proxy_association.owner)
53 53 end
54 54 end
55 55
@@ -17,14 +17,17
17 17
18 18 class Tracker < ActiveRecord::Base
19 19
20 # Other fields should be appended, not inserted!
21 CORE_FIELDS = %w(assigned_to_id category_id fixed_version_id parent_issue_id start_date due_date estimated_hours done_ratio)
20 CORE_FIELDS_UNDISABLABLE = %w(project_id tracker_id subject description priority_id is_private).freeze
21 # Fields that can be disabled
22 # Other (future) fields should be appended, not inserted!
23 CORE_FIELDS = %w(assigned_to_id category_id fixed_version_id parent_issue_id start_date due_date estimated_hours done_ratio).freeze
24 CORE_FIELDS_ALL = (CORE_FIELDS_UNDISABLABLE + CORE_FIELDS).freeze
22 25
23 26 before_destroy :check_integrity
24 27 has_many :issues
25 has_many :workflows, :dependent => :delete_all do
28 has_many :workflow_rules, :dependent => :delete_all do
26 29 def copy(source_tracker)
27 Workflow.copy(source_tracker, nil, proxy_association.owner, nil)
30 WorkflowRule.copy(source_tracker, nil, proxy_association.owner, nil)
28 31 end
29 32 end
30 33
@@ -56,8 +59,8 class Tracker < ActiveRecord::Base
56 59 return []
57 60 end
58 61
59 ids = Workflow.
60 connection.select_rows("SELECT DISTINCT old_status_id, new_status_id FROM #{Workflow.table_name} WHERE tracker_id = #{id}").
62 ids = WorkflowTransition.
63 connection.select_rows("SELECT DISTINCT old_status_id, new_status_id FROM #{WorkflowTransition.table_name} WHERE tracker_id = #{id} AND type = 'WorkflowTransition'").
61 64 flatten.
62 65 uniq
63 66
@@ -15,31 +15,15
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 class Workflow < ActiveRecord::Base
18 class WorkflowRule < ActiveRecord::Base
19 self.table_name = "#{table_name_prefix}workflows#{table_name_suffix}"
20
19 21 belongs_to :role
22 belongs_to :tracker
20 23 belongs_to :old_status, :class_name => 'IssueStatus', :foreign_key => 'old_status_id'
21 24 belongs_to :new_status, :class_name => 'IssueStatus', :foreign_key => 'new_status_id'
22 25
23 validates_presence_of :role, :old_status, :new_status
24
25 # Returns workflow transitions count by tracker and role
26 def self.count_by_tracker_and_role
27 counts = connection.select_all("SELECT role_id, tracker_id, count(id) AS c FROM #{Workflow.table_name} GROUP BY role_id, tracker_id")
28 roles = Role.sorted.all
29 trackers = Tracker.sorted.all
30
31 result = []
32 trackers.each do |tracker|
33 t = []
34 roles.each do |role|
35 row = counts.detect {|c| c['role_id'].to_s == role.id.to_s && c['tracker_id'].to_s == tracker.id.to_s}
36 t << [role, (row.nil? ? 0 : row['c'].to_i)]
37 end
38 result << [tracker, t]
39 end
40
41 result
42 end
26 validates_presence_of :role, :tracker, :old_status
43 27
44 28 # Copies workflows from source to targets
45 29 def self.copy(source_tracker, source_role, target_trackers, target_roles)
@@ -78,9 +62,9 class Workflow < ActiveRecord::Base
78 62 else
79 63 transaction do
80 64 delete_all :tracker_id => target_tracker.id, :role_id => target_role.id
81 connection.insert "INSERT INTO #{Workflow.table_name} (tracker_id, role_id, old_status_id, new_status_id, author, assignee)" +
82 " SELECT #{target_tracker.id}, #{target_role.id}, old_status_id, new_status_id, author, assignee" +
83 " FROM #{Workflow.table_name}" +
65 connection.insert "INSERT INTO #{WorkflowRule.table_name} (tracker_id, role_id, old_status_id, new_status_id, author, assignee, field_name, rule, type)" +
66 " SELECT #{target_tracker.id}, #{target_role.id}, old_status_id, new_status_id, author, assignee, field_name, rule, type" +
67 " FROM #{WorkflowRule.table_name}" +
84 68 " WHERE tracker_id = #{source_tracker.id} AND role_id = #{source_role.id}"
85 69 end
86 70 true
@@ -4,6 +4,9
4 4 <div class="splitcontentleft">
5 5 <% if @issue.safe_attribute? 'status_id' %>
6 6 <p><%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), :required => true %></p>
7 <%= observe_field :issue_status_id, :url => project_issue_form_path(@project, :id => @issue),
8 :with => "Form.serialize('issue-form')" %>
9
7 10 <% else %>
8 11 <p><label><%= l(:field_status) %></label> <%= h(@issue.status.name) %></p>
9 12 <% end %>
@@ -13,11 +16,11
13 16 <% end %>
14 17
15 18 <% if @issue.safe_attribute? 'assigned_to_id' %>
16 <p><%= f.select :assigned_to_id, principals_options_for_select(@issue.assignable_users, @issue.assigned_to), :include_blank => true %></p>
19 <p><%= f.select :assigned_to_id, principals_options_for_select(@issue.assignable_users, @issue.assigned_to), :include_blank => true, :required => @issue.required_attribute?('assigned_to_id') %></p>
17 20 <% end %>
18 21
19 22 <% if @issue.safe_attribute?('category_id') && @issue.project.issue_categories.any? %>
20 <p><%= f.select :category_id, (@issue.project.issue_categories.collect {|c| [c.name, c.id]}), :include_blank => true %>
23 <p><%= f.select :category_id, (@issue.project.issue_categories.collect {|c| [c.name, c.id]}), :include_blank => true, :required => @issue.required_attribute?('category_id') %>
21 24 <%= link_to_remote(image_tag('add.png', :style => 'vertical-align: middle;'),
22 25 {:url => new_project_issue_category_path(@issue.project), :method => 'get'},
23 26 :title => l(:label_issue_category_new),
@@ -25,7 +28,7
25 28 <% end %>
26 29
27 30 <% if @issue.safe_attribute?('fixed_version_id') && @issue.assignable_versions.any? %>
28 <p><%= f.select :fixed_version_id, version_options_for_select(@issue.assignable_versions, @issue.fixed_version), :include_blank => true %>
31 <p><%= f.select :fixed_version_id, version_options_for_select(@issue.assignable_versions, @issue.fixed_version), :include_blank => true, :required => @issue.required_attribute?('fixed_version_id') %>
29 32 <%= link_to_remote(image_tag('add.png', :style => 'vertical-align: middle;'),
30 33 {:url => new_project_version_path(@issue.project), :method => 'get'},
31 34 :title => l(:label_version_new),
@@ -36,25 +39,25
36 39
37 40 <div class="splitcontentright">
38 41 <% if @issue.safe_attribute? 'parent_issue_id' %>
39 <p id="parent_issue"><%= f.text_field :parent_issue_id, :size => 10 %></p>
42 <p id="parent_issue"><%= f.text_field :parent_issue_id, :size => 10, :required => @issue.required_attribute?('parent_issue_id') %></p>
40 43 <div id="parent_issue_candidates" class="autocomplete"></div>
41 44 <%= javascript_tag "observeParentIssueField('#{auto_complete_issues_path(:id => @issue, :project_id => @issue.project) }')" %>
42 45 <% end %>
43 46
44 47 <% if @issue.safe_attribute? 'start_date' %>
45 <p><%= f.text_field :start_date, :size => 10, :disabled => !@issue.leaf? %><%= calendar_for('issue_start_date') if @issue.leaf? %></p>
48 <p><%= f.text_field :start_date, :size => 10, :disabled => !@issue.leaf?, :required => @issue.required_attribute?('start_date') %><%= calendar_for('issue_start_date') if @issue.leaf? %></p>
46 49 <% end %>
47 50
48 51 <% if @issue.safe_attribute? 'due_date' %>
49 <p><%= f.text_field :due_date, :size => 10, :disabled => !@issue.leaf? %><%= calendar_for('issue_due_date') if @issue.leaf? %></p>
52 <p><%= f.text_field :due_date, :size => 10, :disabled => !@issue.leaf?, :required => @issue.required_attribute?('due_date') %><%= calendar_for('issue_due_date') if @issue.leaf? %></p>
50 53 <% end %>
51 54
52 55 <% if @issue.safe_attribute? 'estimated_hours' %>
53 <p><%= f.text_field :estimated_hours, :size => 3, :disabled => !@issue.leaf? %> <%= l(:field_hours) %></p>
56 <p><%= f.text_field :estimated_hours, :size => 3, :disabled => !@issue.leaf?, :required => @issue.required_attribute?('estimated_hours') %> <%= l(:field_hours) %></p>
54 57 <% end %>
55 58
56 59 <% if @issue.safe_attribute?('done_ratio') && @issue.leaf? && Issue.use_field_for_done_ratio? %>
57 <p><%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></p>
60 <p><%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }), :required => @issue.required_attribute?('done_ratio') %></p>
58 61 <% end %>
59 62 </div>
60 63 </div>
@@ -9,7 +9,7
9 9
10 10 <% if @issue.safe_attribute? 'project_id' %>
11 11 <p><%= f.select :project_id, project_tree_options_for_select(@issue.allowed_target_projects, :selected => @issue.project), :required => true %></p>
12 <%= observe_field :issue_project_id, :url => project_issue_form_path(@project, :id => @issue, :project_change => '1'),
12 <%= observe_field :issue_project_id, :url => project_issue_form_path(@project, :id => @issue),
13 13 :with => "Form.serialize('issue-form')" %>
14 14 <% end %>
15 15
@@ -25,7 +25,7
25 25
26 26 <% if @issue.safe_attribute? 'description' %>
27 27 <p>
28 <label><%= l(:field_description) %></label>
28 <%= f.label_for_field :description, :required => @issue.required_attribute?('description') %>
29 29 <%= link_to_function image_tag('edit.png'),
30 30 'Element.hide(this); Effect.toggle("issue_description_and_toolbar", "appear", {duration:0.3})' unless @issue.new_record? %>
31 31 <%= content_tag 'span', :id => "issue_description_and_toolbar", :style => (@issue.new_record? ? nil : 'display:none') do %>
@@ -2,8 +2,8
2 2 <div class="splitcontentleft">
3 3 <% i = 0 %>
4 4 <% split_on = (@issue.custom_field_values.size / 2.0).ceil - 1 %>
5 <% @issue.custom_field_values.each do |value| %>
6 <p><%= custom_field_tag_with_label :issue, value %></p>
5 <% @issue.editable_custom_field_values.each do |value| %>
6 <p><%= custom_field_tag_with_label :issue, value, :required => @issue.required_attribute?(value.custom_field_id) %></p>
7 7 <% if i == split_on -%>
8 8 </div><div class="splitcontentright">
9 9 <% end -%>
@@ -15,7 +15,7
15 15 <% for tracker in @trackers %>
16 16 <tr class="<%= cycle("odd", "even") %>">
17 17 <td><%= link_to h(tracker.name), edit_tracker_path(tracker) %></td>
18 <td align="center"><% unless tracker.workflows.count > 0 %><span class="icon icon-warning"><%= l(:text_tracker_no_workflow) %> (<%= link_to l(:button_edit), {:controller => 'workflows', :action => 'edit', :tracker_id => tracker} %>)</span><% end %></td>
18 <td align="center"><% unless tracker.workflow_rules.count > 0 %><span class="icon icon-warning"><%= l(:text_tracker_no_workflow) %> (<%= link_to l(:button_edit), {:controller => 'workflows', :action => 'edit', :tracker_id => tracker} %>)</span><% end %></td>
19 19 <td align="center" style="width:15%;"><%= reorder_links('tracker', {:action => 'update', :id => tracker}, :put) %></td>
20 20 <td class="buttons">
21 21 <%= delete_link tracker_path(tracker) %>
@@ -2,6 +2,13
2 2
3 3 <h2><%=l(:label_workflow)%></h2>
4 4
5 <div class="tabs">
6 <ul>
7 <li><%= link_to 'Status transitions', {:action => 'edit', :role_id => @role, :tracker_id => @tracker}, :class => 'selected' %></li>
8 <li><%= link_to 'Fields permissions', {:action => 'permissions', :role_id => @role, :tracker_id => @tracker} %></li>
9 </ul>
10 </div>
11
5 12 <p><%=l(:text_workflow_edit)%>:</p>
6 13
7 14 <%= form_tag({}, :method => 'get') do %>
@@ -12,11 +19,11
12 19 <label><%=l(:label_tracker)%>:
13 20 <%= select_tag 'tracker_id', options_from_collection_for_select(@trackers, "id", "name", @tracker && @tracker.id) %></label>
14 21
22 <%= submit_tag l(:button_edit), :name => nil %>
23
15 24 <%= hidden_field_tag 'used_statuses_only', '0' %>
16 25 <label><%= check_box_tag 'used_statuses_only', '1', @used_statuses_only %> <%= l(:label_display_used_statuses_only) %></label>
17 </p>
18 <p>
19 <%= submit_tag l(:button_edit), :name => nil %>
26
20 27 </p>
21 28 <% end %>
22 29
@@ -312,6 +312,7 RedmineApp::Application.routes.draw do
312 312
313 313 match 'workflows', :controller => 'workflows', :action => 'index', :via => :get
314 314 match 'workflows/edit', :controller => 'workflows', :action => 'edit', :via => [:get, :post]
315 match 'workflows/permissions', :controller => 'workflows', :action => 'permissions', :via => [:get, :post]
315 316 match 'workflows/copy', :controller => 'workflows', :action => 'copy', :via => [:get, :post]
316 317 match 'settings', :controller => 'settings', :action => 'index', :via => :get
317 318 match 'settings/edit', :controller => 'settings', :action => 'edit', :via => [:get, :post]
@@ -140,7 +140,7 module Redmine
140 140 Tracker.find(:all).each { |t|
141 141 IssueStatus.find(:all).each { |os|
142 142 IssueStatus.find(:all).each { |ns|
143 Workflow.create!(:tracker_id => t.id, :role_id => manager.id, :old_status_id => os.id, :new_status_id => ns.id) unless os == ns
143 WorkflowTransition.create!(:tracker_id => t.id, :role_id => manager.id, :old_status_id => os.id, :new_status_id => ns.id) unless os == ns
144 144 }
145 145 }
146 146 }
@@ -148,7 +148,7 module Redmine
148 148 Tracker.find(:all).each { |t|
149 149 [new, in_progress, resolved, feedback].each { |os|
150 150 [in_progress, resolved, feedback, closed].each { |ns|
151 Workflow.create!(:tracker_id => t.id, :role_id => developer.id, :old_status_id => os.id, :new_status_id => ns.id) unless os == ns
151 WorkflowTransition.create!(:tracker_id => t.id, :role_id => developer.id, :old_status_id => os.id, :new_status_id => ns.id) unless os == ns
152 152 }
153 153 }
154 154 }
@@ -156,10 +156,10 module Redmine
156 156 Tracker.find(:all).each { |t|
157 157 [new, in_progress, resolved, feedback].each { |os|
158 158 [closed].each { |ns|
159 Workflow.create!(:tracker_id => t.id, :role_id => reporter.id, :old_status_id => os.id, :new_status_id => ns.id) unless os == ns
159 WorkflowTransition.create!(:tracker_id => t.id, :role_id => reporter.id, :old_status_id => os.id, :new_status_id => ns.id) unless os == ns
160 160 }
161 161 }
162 Workflow.create!(:tracker_id => t.id, :role_id => reporter.id, :old_status_id => resolved.id, :new_status_id => feedback.id)
162 WorkflowTransition.create!(:tracker_id => t.id, :role_id => reporter.id, :old_status_id => resolved.id, :new_status_id => feedback.id)
163 163 }
164 164
165 165 # Enumerations
@@ -433,6 +433,9 ul.properties li span {font-style:italic;}
433 433 #user_login, #user_firstname, #user_lastname, #user_mail, #my_account_form select, #user_form select, #user_identity_url { width: 90%; }
434 434
435 435 #workflow_copy_form select { width: 200px; }
436 table.fields_permissions select {font-size:90%}
437 table.fields_permissions td.readonly {background:#ddd;}
438 table.fields_permissions td.required {background:#d88;}
436 439
437 440 textarea#custom_field_possible_values {width: 99%}
438 441 input#content_comments {width: 99%}
@@ -504,7 +507,7 input#time_entry_comments { width: 90%;}
504 507 fieldset.settings label { display: block; }
505 508 fieldset#notified_events .parent { padding-left: 20px; }
506 509
507 .required {color: #bb0000;}
510 span.required {color: #bb0000;}
508 511 .summary {font-style: italic;}
509 512
510 513 #attachments_fields input.description {margin-left: 8px; width:340px;}
This diff has been collapsed as it changes many lines, (807 lines changed) Show them Hide them
@@ -1,1615 +1,1884
1 1 ---
2 workflows_189:
2 WorkflowTransitions_189:
3 3 new_status_id: 5
4 4 role_id: 1
5 5 old_status_id: 2
6 6 id: 189
7 7 tracker_id: 3
8 workflows_001:
8 type: WorkflowTransition
9 WorkflowTransitions_001:
9 10 new_status_id: 2
10 11 role_id: 1
11 12 old_status_id: 1
12 13 id: 1
13 14 tracker_id: 1
14 workflows_002:
15 type: WorkflowTransition
16 WorkflowTransitions_002:
15 17 new_status_id: 3
16 18 role_id: 1
17 19 old_status_id: 1
18 20 id: 2
19 21 tracker_id: 1
20 workflows_003:
22 type: WorkflowTransition
23 WorkflowTransitions_003:
21 24 new_status_id: 4
22 25 role_id: 1
23 26 old_status_id: 1
24 27 id: 3
25 28 tracker_id: 1
26 workflows_110:
29 type: WorkflowTransition
30 WorkflowTransitions_110:
27 31 new_status_id: 6
28 32 role_id: 1
29 33 old_status_id: 4
30 34 id: 110
31 35 tracker_id: 2
32 workflows_004:
36 type: WorkflowTransition
37 WorkflowTransitions_004:
33 38 new_status_id: 5
34 39 role_id: 1
35 40 old_status_id: 1
36 41 id: 4
37 42 tracker_id: 1
38 workflows_030:
43 type: WorkflowTransition
44 WorkflowTransitions_030:
39 45 new_status_id: 5
40 46 role_id: 1
41 47 old_status_id: 6
42 48 id: 30
43 49 tracker_id: 1
44 workflows_111:
50 type: WorkflowTransition
51 WorkflowTransitions_111:
45 52 new_status_id: 1
46 53 role_id: 1
47 54 old_status_id: 5
48 55 id: 111
49 56 tracker_id: 2
50 workflows_005:
57 type: WorkflowTransition
58 WorkflowTransitions_005:
51 59 new_status_id: 6
52 60 role_id: 1
53 61 old_status_id: 1
54 62 id: 5
55 63 tracker_id: 1
56 workflows_031:
64 type: WorkflowTransition
65 WorkflowTransitions_031:
57 66 new_status_id: 2
58 67 role_id: 2
59 68 old_status_id: 1
60 69 id: 31
61 70 tracker_id: 1
62 workflows_112:
71 type: WorkflowTransition
72 WorkflowTransitions_112:
63 73 new_status_id: 2
64 74 role_id: 1
65 75 old_status_id: 5
66 76 id: 112
67 77 tracker_id: 2
68 workflows_006:
78 type: WorkflowTransition
79 WorkflowTransitions_006:
69 80 new_status_id: 1
70 81 role_id: 1
71 82 old_status_id: 2
72 83 id: 6
73 84 tracker_id: 1
74 workflows_032:
85 type: WorkflowTransition
86 WorkflowTransitions_032:
75 87 new_status_id: 3
76 88 role_id: 2
77 89 old_status_id: 1
78 90 id: 32
79 91 tracker_id: 1
80 workflows_113:
92 type: WorkflowTransition
93 WorkflowTransitions_113:
81 94 new_status_id: 3
82 95 role_id: 1
83 96 old_status_id: 5
84 97 id: 113
85 98 tracker_id: 2
86 workflows_220:
99 type: WorkflowTransition
100 WorkflowTransitions_220:
87 101 new_status_id: 6
88 102 role_id: 2
89 103 old_status_id: 2
90 104 id: 220
91 105 tracker_id: 3
92 workflows_007:
106 type: WorkflowTransition
107 WorkflowTransitions_007:
93 108 new_status_id: 3
94 109 role_id: 1
95 110 old_status_id: 2
96 111 id: 7
97 112 tracker_id: 1
98 workflows_033:
113 type: WorkflowTransition
114 WorkflowTransitions_033:
99 115 new_status_id: 4
100 116 role_id: 2
101 117 old_status_id: 1
102 118 id: 33
103 119 tracker_id: 1
104 workflows_060:
120 type: WorkflowTransition
121 WorkflowTransitions_060:
105 122 new_status_id: 5
106 123 role_id: 2
107 124 old_status_id: 6
108 125 id: 60
109 126 tracker_id: 1
110 workflows_114:
127 type: WorkflowTransition
128 WorkflowTransitions_114:
111 129 new_status_id: 4
112 130 role_id: 1
113 131 old_status_id: 5
114 132 id: 114
115 133 tracker_id: 2
116 workflows_140:
134 type: WorkflowTransition
135 WorkflowTransitions_140:
117 136 new_status_id: 6
118 137 role_id: 2
119 138 old_status_id: 4
120 139 id: 140
121 140 tracker_id: 2
122 workflows_221:
141 type: WorkflowTransition
142 WorkflowTransitions_221:
123 143 new_status_id: 1
124 144 role_id: 2
125 145 old_status_id: 3
126 146 id: 221
127 147 tracker_id: 3
128 workflows_008:
148 type: WorkflowTransition
149 WorkflowTransitions_008:
129 150 new_status_id: 4
130 151 role_id: 1
131 152 old_status_id: 2
132 153 id: 8
133 154 tracker_id: 1
134 workflows_034:
155 type: WorkflowTransition
156 WorkflowTransitions_034:
135 157 new_status_id: 5
136 158 role_id: 2
137 159 old_status_id: 1
138 160 id: 34
139 161 tracker_id: 1
140 workflows_115:
162 type: WorkflowTransition
163 WorkflowTransitions_115:
141 164 new_status_id: 6
142 165 role_id: 1
143 166 old_status_id: 5
144 167 id: 115
145 168 tracker_id: 2
146 workflows_141:
169 type: WorkflowTransition
170 WorkflowTransitions_141:
147 171 new_status_id: 1
148 172 role_id: 2
149 173 old_status_id: 5
150 174 id: 141
151 175 tracker_id: 2
152 workflows_222:
176 type: WorkflowTransition
177 WorkflowTransitions_222:
153 178 new_status_id: 2
154 179 role_id: 2
155 180 old_status_id: 3
156 181 id: 222
157 182 tracker_id: 3
158 workflows_223:
183 type: WorkflowTransition
184 WorkflowTransitions_223:
159 185 new_status_id: 4
160 186 role_id: 2
161 187 old_status_id: 3
162 188 id: 223
163 189 tracker_id: 3
164 workflows_009:
190 type: WorkflowTransition
191 WorkflowTransitions_009:
165 192 new_status_id: 5
166 193 role_id: 1
167 194 old_status_id: 2
168 195 id: 9
169 196 tracker_id: 1
170 workflows_035:
197 type: WorkflowTransition
198 WorkflowTransitions_035:
171 199 new_status_id: 6
172 200 role_id: 2
173 201 old_status_id: 1
174 202 id: 35
175 203 tracker_id: 1
176 workflows_061:
204 type: WorkflowTransition
205 WorkflowTransitions_061:
177 206 new_status_id: 2
178 207 role_id: 3
179 208 old_status_id: 1
180 209 id: 61
181 210 tracker_id: 1
182 workflows_116:
211 type: WorkflowTransition
212 WorkflowTransitions_116:
183 213 new_status_id: 1
184 214 role_id: 1
185 215 old_status_id: 6
186 216 id: 116
187 217 tracker_id: 2
188 workflows_142:
218 type: WorkflowTransition
219 WorkflowTransitions_142:
189 220 new_status_id: 2
190 221 role_id: 2
191 222 old_status_id: 5
192 223 id: 142
193 224 tracker_id: 2
194 workflows_250:
225 type: WorkflowTransition
226 WorkflowTransitions_250:
195 227 new_status_id: 6
196 228 role_id: 3
197 229 old_status_id: 2
198 230 id: 250
199 231 tracker_id: 3
200 workflows_224:
232 type: WorkflowTransition
233 WorkflowTransitions_224:
201 234 new_status_id: 5
202 235 role_id: 2
203 236 old_status_id: 3
204 237 id: 224
205 238 tracker_id: 3
206 workflows_036:
239 type: WorkflowTransition
240 WorkflowTransitions_036:
207 241 new_status_id: 1
208 242 role_id: 2
209 243 old_status_id: 2
210 244 id: 36
211 245 tracker_id: 1
212 workflows_062:
246 type: WorkflowTransition
247 WorkflowTransitions_062:
213 248 new_status_id: 3
214 249 role_id: 3
215 250 old_status_id: 1
216 251 id: 62
217 252 tracker_id: 1
218 workflows_117:
253 type: WorkflowTransition
254 WorkflowTransitions_117:
219 255 new_status_id: 2
220 256 role_id: 1
221 257 old_status_id: 6
222 258 id: 117
223 259 tracker_id: 2
224 workflows_143:
260 type: WorkflowTransition
261 WorkflowTransitions_143:
225 262 new_status_id: 3
226 263 role_id: 2
227 264 old_status_id: 5
228 265 id: 143
229 266 tracker_id: 2
230 workflows_170:
267 type: WorkflowTransition
268 WorkflowTransitions_170:
231 269 new_status_id: 6
232 270 role_id: 3
233 271 old_status_id: 4
234 272 id: 170
235 273 tracker_id: 2
236 workflows_251:
274 type: WorkflowTransition
275 WorkflowTransitions_251:
237 276 new_status_id: 1
238 277 role_id: 3
239 278 old_status_id: 3
240 279 id: 251
241 280 tracker_id: 3
242 workflows_225:
281 type: WorkflowTransition
282 WorkflowTransitions_225:
243 283 new_status_id: 6
244 284 role_id: 2
245 285 old_status_id: 3
246 286 id: 225
247 287 tracker_id: 3
248 workflows_063:
288 type: WorkflowTransition
289 WorkflowTransitions_063:
249 290 new_status_id: 4
250 291 role_id: 3
251 292 old_status_id: 1
252 293 id: 63
253 294 tracker_id: 1
254 workflows_090:
295 type: WorkflowTransition
296 WorkflowTransitions_090:
255 297 new_status_id: 5
256 298 role_id: 3
257 299 old_status_id: 6
258 300 id: 90
259 301 tracker_id: 1
260 workflows_118:
302 type: WorkflowTransition
303 WorkflowTransitions_118:
261 304 new_status_id: 3
262 305 role_id: 1
263 306 old_status_id: 6
264 307 id: 118
265 308 tracker_id: 2
266 workflows_144:
309 type: WorkflowTransition
310 WorkflowTransitions_144:
267 311 new_status_id: 4
268 312 role_id: 2
269 313 old_status_id: 5
270 314 id: 144
271 315 tracker_id: 2
272 workflows_252:
316 type: WorkflowTransition
317 WorkflowTransitions_252:
273 318 new_status_id: 2
274 319 role_id: 3
275 320 old_status_id: 3
276 321 id: 252
277 322 tracker_id: 3
278 workflows_226:
323 type: WorkflowTransition
324 WorkflowTransitions_226:
279 325 new_status_id: 1
280 326 role_id: 2
281 327 old_status_id: 4
282 328 id: 226
283 329 tracker_id: 3
284 workflows_038:
330 type: WorkflowTransition
331 WorkflowTransitions_038:
285 332 new_status_id: 4
286 333 role_id: 2
287 334 old_status_id: 2
288 335 id: 38
289 336 tracker_id: 1
290 workflows_064:
337 type: WorkflowTransition
338 WorkflowTransitions_064:
291 339 new_status_id: 5
292 340 role_id: 3
293 341 old_status_id: 1
294 342 id: 64
295 343 tracker_id: 1
296 workflows_091:
344 type: WorkflowTransition
345 WorkflowTransitions_091:
297 346 new_status_id: 2
298 347 role_id: 1
299 348 old_status_id: 1
300 349 id: 91
301 350 tracker_id: 2
302 workflows_119:
351 type: WorkflowTransition
352 WorkflowTransitions_119:
303 353 new_status_id: 4
304 354 role_id: 1
305 355 old_status_id: 6
306 356 id: 119
307 357 tracker_id: 2
308 workflows_145:
358 type: WorkflowTransition
359 WorkflowTransitions_145:
309 360 new_status_id: 6
310 361 role_id: 2
311 362 old_status_id: 5
312 363 id: 145
313 364 tracker_id: 2
314 workflows_171:
365 type: WorkflowTransition
366 WorkflowTransitions_171:
315 367 new_status_id: 1
316 368 role_id: 3
317 369 old_status_id: 5
318 370 id: 171
319 371 tracker_id: 2
320 workflows_253:
372 type: WorkflowTransition
373 WorkflowTransitions_253:
321 374 new_status_id: 4
322 375 role_id: 3
323 376 old_status_id: 3
324 377 id: 253
325 378 tracker_id: 3
326 workflows_227:
379 type: WorkflowTransition
380 WorkflowTransitions_227:
327 381 new_status_id: 2
328 382 role_id: 2
329 383 old_status_id: 4
330 384 id: 227
331 385 tracker_id: 3
332 workflows_039:
386 type: WorkflowTransition
387 WorkflowTransitions_039:
333 388 new_status_id: 5
334 389 role_id: 2
335 390 old_status_id: 2
336 391 id: 39
337 392 tracker_id: 1
338 workflows_065:
393 type: WorkflowTransition
394 WorkflowTransitions_065:
339 395 new_status_id: 6
340 396 role_id: 3
341 397 old_status_id: 1
342 398 id: 65
343 399 tracker_id: 1
344 workflows_092:
400 type: WorkflowTransition
401 WorkflowTransitions_092:
345 402 new_status_id: 3
346 403 role_id: 1
347 404 old_status_id: 1
348 405 id: 92
349 406 tracker_id: 2
350 workflows_146:
407 type: WorkflowTransition
408 WorkflowTransitions_146:
351 409 new_status_id: 1
352 410 role_id: 2
353 411 old_status_id: 6
354 412 id: 146
355 413 tracker_id: 2
356 workflows_172:
414 type: WorkflowTransition
415 WorkflowTransitions_172:
357 416 new_status_id: 2
358 417 role_id: 3
359 418 old_status_id: 5
360 419 id: 172
361 420 tracker_id: 2
362 workflows_254:
421 type: WorkflowTransition
422 WorkflowTransitions_254:
363 423 new_status_id: 5
364 424 role_id: 3
365 425 old_status_id: 3
366 426 id: 254
367 427 tracker_id: 3
368 workflows_228:
428 type: WorkflowTransition
429 WorkflowTransitions_228:
369 430 new_status_id: 3
370 431 role_id: 2
371 432 old_status_id: 4
372 433 id: 228
373 434 tracker_id: 3
374 workflows_066:
435 type: WorkflowTransition
436 WorkflowTransitions_066:
375 437 new_status_id: 1
376 438 role_id: 3
377 439 old_status_id: 2
378 440 id: 66
379 441 tracker_id: 1
380 workflows_093:
442 type: WorkflowTransition
443 WorkflowTransitions_093:
381 444 new_status_id: 4
382 445 role_id: 1
383 446 old_status_id: 1
384 447 id: 93
385 448 tracker_id: 2
386 workflows_147:
449 type: WorkflowTransition
450 WorkflowTransitions_147:
387 451 new_status_id: 2
388 452 role_id: 2
389 453 old_status_id: 6
390 454 id: 147
391 455 tracker_id: 2
392 workflows_173:
456 type: WorkflowTransition
457 WorkflowTransitions_173:
393 458 new_status_id: 3
394 459 role_id: 3
395 460 old_status_id: 5
396 461 id: 173
397 462 tracker_id: 2
398 workflows_255:
463 type: WorkflowTransition
464 WorkflowTransitions_255:
399 465 new_status_id: 6
400 466 role_id: 3
401 467 old_status_id: 3
402 468 id: 255
403 469 tracker_id: 3
404 workflows_229:
470 type: WorkflowTransition
471 WorkflowTransitions_229:
405 472 new_status_id: 5
406 473 role_id: 2
407 474 old_status_id: 4
408 475 id: 229
409 476 tracker_id: 3
410 workflows_067:
477 type: WorkflowTransition
478 WorkflowTransitions_067:
411 479 new_status_id: 3
412 480 role_id: 3
413 481 old_status_id: 2
414 482 id: 67
415 483 tracker_id: 1
416 workflows_148:
484 type: WorkflowTransition
485 WorkflowTransitions_148:
417 486 new_status_id: 3
418 487 role_id: 2
419 488 old_status_id: 6
420 489 id: 148
421 490 tracker_id: 2
422 workflows_174:
491 type: WorkflowTransition
492 WorkflowTransitions_174:
423 493 new_status_id: 4
424 494 role_id: 3
425 495 old_status_id: 5
426 496 id: 174
427 497 tracker_id: 2
428 workflows_256:
498 type: WorkflowTransition
499 WorkflowTransitions_256:
429 500 new_status_id: 1
430 501 role_id: 3
431 502 old_status_id: 4
432 503 id: 256
433 504 tracker_id: 3
434 workflows_068:
505 type: WorkflowTransition
506 WorkflowTransitions_068:
435 507 new_status_id: 4
436 508 role_id: 3
437 509 old_status_id: 2
438 510 id: 68
439 511 tracker_id: 1
440 workflows_094:
512 type: WorkflowTransition
513 WorkflowTransitions_094:
441 514 new_status_id: 5
442 515 role_id: 1
443 516 old_status_id: 1
444 517 id: 94
445 518 tracker_id: 2
446 workflows_149:
519 type: WorkflowTransition
520 WorkflowTransitions_149:
447 521 new_status_id: 4
448 522 role_id: 2
449 523 old_status_id: 6
450 524 id: 149
451 525 tracker_id: 2
452 workflows_175:
526 type: WorkflowTransition
527 WorkflowTransitions_175:
453 528 new_status_id: 6
454 529 role_id: 3
455 530 old_status_id: 5
456 531 id: 175
457 532 tracker_id: 2
458 workflows_257:
533 type: WorkflowTransition
534 WorkflowTransitions_257:
459 535 new_status_id: 2
460 536 role_id: 3
461 537 old_status_id: 4
462 538 id: 257
463 539 tracker_id: 3
464 workflows_069:
540 type: WorkflowTransition
541 WorkflowTransitions_069:
465 542 new_status_id: 5
466 543 role_id: 3
467 544 old_status_id: 2
468 545 id: 69
469 546 tracker_id: 1
470 workflows_095:
547 type: WorkflowTransition
548 WorkflowTransitions_095:
471 549 new_status_id: 6
472 550 role_id: 1
473 551 old_status_id: 1
474 552 id: 95
475 553 tracker_id: 2
476 workflows_176:
554 type: WorkflowTransition
555 WorkflowTransitions_176:
477 556 new_status_id: 1
478 557 role_id: 3
479 558 old_status_id: 6
480 559 id: 176
481 560 tracker_id: 2
482 workflows_258:
561 type: WorkflowTransition
562 WorkflowTransitions_258:
483 563 new_status_id: 3
484 564 role_id: 3
485 565 old_status_id: 4
486 566 id: 258
487 567 tracker_id: 3
488 workflows_096:
568 type: WorkflowTransition
569 WorkflowTransitions_096:
489 570 new_status_id: 1
490 571 role_id: 1
491 572 old_status_id: 2
492 573 id: 96
493 574 tracker_id: 2
494 workflows_177:
575 type: WorkflowTransition
576 WorkflowTransitions_177:
495 577 new_status_id: 2
496 578 role_id: 3
497 579 old_status_id: 6
498 580 id: 177
499 581 tracker_id: 2
500 workflows_259:
582 type: WorkflowTransition
583 WorkflowTransitions_259:
501 584 new_status_id: 5
502 585 role_id: 3
503 586 old_status_id: 4
504 587 id: 259
505 588 tracker_id: 3
506 workflows_097:
589 type: WorkflowTransition
590 WorkflowTransitions_097:
507 591 new_status_id: 3
508 592 role_id: 1
509 593 old_status_id: 2
510 594 id: 97
511 595 tracker_id: 2
512 workflows_178:
596 type: WorkflowTransition
597 WorkflowTransitions_178:
513 598 new_status_id: 3
514 599 role_id: 3
515 600 old_status_id: 6
516 601 id: 178
517 602 tracker_id: 2
518 workflows_098:
603 type: WorkflowTransition
604 WorkflowTransitions_098:
519 605 new_status_id: 4
520 606 role_id: 1
521 607 old_status_id: 2
522 608 id: 98
523 609 tracker_id: 2
524 workflows_179:
610 type: WorkflowTransition
611 WorkflowTransitions_179:
525 612 new_status_id: 4
526 613 role_id: 3
527 614 old_status_id: 6
528 615 id: 179
529 616 tracker_id: 2
530 workflows_099:
617 type: WorkflowTransition
618 WorkflowTransitions_099:
531 619 new_status_id: 5
532 620 role_id: 1
533 621 old_status_id: 2
534 622 id: 99
535 623 tracker_id: 2
536 workflows_100:
624 type: WorkflowTransition
625 WorkflowTransitions_100:
537 626 new_status_id: 6
538 627 role_id: 1
539 628 old_status_id: 2
540 629 id: 100
541 630 tracker_id: 2
542 workflows_020:
631 type: WorkflowTransition
632 WorkflowTransitions_020:
543 633 new_status_id: 6
544 634 role_id: 1
545 635 old_status_id: 4
546 636 id: 20
547 637 tracker_id: 1
548 workflows_101:
638 type: WorkflowTransition
639 WorkflowTransitions_101:
549 640 new_status_id: 1
550 641 role_id: 1
551 642 old_status_id: 3
552 643 id: 101
553 644 tracker_id: 2
554 workflows_021:
645 type: WorkflowTransition
646 WorkflowTransitions_021:
555 647 new_status_id: 1
556 648 role_id: 1
557 649 old_status_id: 5
558 650 id: 21
559 651 tracker_id: 1
560 workflows_102:
652 type: WorkflowTransition
653 WorkflowTransitions_102:
561 654 new_status_id: 2
562 655 role_id: 1
563 656 old_status_id: 3
564 657 id: 102
565 658 tracker_id: 2
566 workflows_210:
659 type: WorkflowTransition
660 WorkflowTransitions_210:
567 661 new_status_id: 5
568 662 role_id: 1
569 663 old_status_id: 6
570 664 id: 210
571 665 tracker_id: 3
572 workflows_022:
666 type: WorkflowTransition
667 WorkflowTransitions_022:
573 668 new_status_id: 2
574 669 role_id: 1
575 670 old_status_id: 5
576 671 id: 22
577 672 tracker_id: 1
578 workflows_103:
673 type: WorkflowTransition
674 WorkflowTransitions_103:
579 675 new_status_id: 4
580 676 role_id: 1
581 677 old_status_id: 3
582 678 id: 103
583 679 tracker_id: 2
584 workflows_023:
680 type: WorkflowTransition
681 WorkflowTransitions_023:
585 682 new_status_id: 3
586 683 role_id: 1
587 684 old_status_id: 5
588 685 id: 23
589 686 tracker_id: 1
590 workflows_104:
687 type: WorkflowTransition
688 WorkflowTransitions_104:
591 689 new_status_id: 5
592 690 role_id: 1
593 691 old_status_id: 3
594 692 id: 104
595 693 tracker_id: 2
596 workflows_130:
694 type: WorkflowTransition
695 WorkflowTransitions_130:
597 696 new_status_id: 6
598 697 role_id: 2
599 698 old_status_id: 2
600 699 id: 130
601 700 tracker_id: 2
602 workflows_211:
701 type: WorkflowTransition
702 WorkflowTransitions_211:
603 703 new_status_id: 2
604 704 role_id: 2
605 705 old_status_id: 1
606 706 id: 211
607 707 tracker_id: 3
608 workflows_024:
708 type: WorkflowTransition
709 WorkflowTransitions_024:
609 710 new_status_id: 4
610 711 role_id: 1
611 712 old_status_id: 5
612 713 id: 24
613 714 tracker_id: 1
614 workflows_050:
715 type: WorkflowTransition
716 WorkflowTransitions_050:
615 717 new_status_id: 6
616 718 role_id: 2
617 719 old_status_id: 4
618 720 id: 50
619 721 tracker_id: 1
620 workflows_105:
722 type: WorkflowTransition
723 WorkflowTransitions_105:
621 724 new_status_id: 6
622 725 role_id: 1
623 726 old_status_id: 3
624 727 id: 105
625 728 tracker_id: 2
626 workflows_131:
729 type: WorkflowTransition
730 WorkflowTransitions_131:
627 731 new_status_id: 1
628 732 role_id: 2
629 733 old_status_id: 3
630 734 id: 131
631 735 tracker_id: 2
632 workflows_212:
736 type: WorkflowTransition
737 WorkflowTransitions_212:
633 738 new_status_id: 3
634 739 role_id: 2
635 740 old_status_id: 1
636 741 id: 212
637 742 tracker_id: 3
638 workflows_025:
743 type: WorkflowTransition
744 WorkflowTransitions_025:
639 745 new_status_id: 6
640 746 role_id: 1
641 747 old_status_id: 5
642 748 id: 25
643 749 tracker_id: 1
644 workflows_051:
750 type: WorkflowTransition
751 WorkflowTransitions_051:
645 752 new_status_id: 1
646 753 role_id: 2
647 754 old_status_id: 5
648 755 id: 51
649 756 tracker_id: 1
650 workflows_106:
757 type: WorkflowTransition
758 WorkflowTransitions_106:
651 759 new_status_id: 1
652 760 role_id: 1
653 761 old_status_id: 4
654 762 id: 106
655 763 tracker_id: 2
656 workflows_132:
764 type: WorkflowTransition
765 WorkflowTransitions_132:
657 766 new_status_id: 2
658 767 role_id: 2
659 768 old_status_id: 3
660 769 id: 132
661 770 tracker_id: 2
662 workflows_213:
771 type: WorkflowTransition
772 WorkflowTransitions_213:
663 773 new_status_id: 4
664 774 role_id: 2
665 775 old_status_id: 1
666 776 id: 213
667 777 tracker_id: 3
668 workflows_240:
778 type: WorkflowTransition
779 WorkflowTransitions_240:
669 780 new_status_id: 5
670 781 role_id: 2
671 782 old_status_id: 6
672 783 id: 240
673 784 tracker_id: 3
674 workflows_026:
785 type: WorkflowTransition
786 WorkflowTransitions_026:
675 787 new_status_id: 1
676 788 role_id: 1
677 789 old_status_id: 6
678 790 id: 26
679 791 tracker_id: 1
680 workflows_052:
792 type: WorkflowTransition
793 WorkflowTransitions_052:
681 794 new_status_id: 2
682 795 role_id: 2
683 796 old_status_id: 5
684 797 id: 52
685 798 tracker_id: 1
686 workflows_107:
799 type: WorkflowTransition
800 WorkflowTransitions_107:
687 801 new_status_id: 2
688 802 role_id: 1
689 803 old_status_id: 4
690 804 id: 107
691 805 tracker_id: 2
692 workflows_133:
806 type: WorkflowTransition
807 WorkflowTransitions_133:
693 808 new_status_id: 4
694 809 role_id: 2
695 810 old_status_id: 3
696 811 id: 133
697 812 tracker_id: 2
698 workflows_214:
813 type: WorkflowTransition
814 WorkflowTransitions_214:
699 815 new_status_id: 5
700 816 role_id: 2
701 817 old_status_id: 1
702 818 id: 214
703 819 tracker_id: 3
704 workflows_241:
820 type: WorkflowTransition
821 WorkflowTransitions_241:
705 822 new_status_id: 2
706 823 role_id: 3
707 824 old_status_id: 1
708 825 id: 241
709 826 tracker_id: 3
710 workflows_027:
827 type: WorkflowTransition
828 WorkflowTransitions_027:
711 829 new_status_id: 2
712 830 role_id: 1
713 831 old_status_id: 6
714 832 id: 27
715 833 tracker_id: 1
716 workflows_053:
834 type: WorkflowTransition
835 WorkflowTransitions_053:
717 836 new_status_id: 3
718 837 role_id: 2
719 838 old_status_id: 5
720 839 id: 53
721 840 tracker_id: 1
722 workflows_080:
841 type: WorkflowTransition
842 WorkflowTransitions_080:
723 843 new_status_id: 6
724 844 role_id: 3
725 845 old_status_id: 4
726 846 id: 80
727 847 tracker_id: 1
728 workflows_108:
848 type: WorkflowTransition
849 WorkflowTransitions_108:
729 850 new_status_id: 3
730 851 role_id: 1
731 852 old_status_id: 4
732 853 id: 108
733 854 tracker_id: 2
734 workflows_134:
855 type: WorkflowTransition
856 WorkflowTransitions_134:
735 857 new_status_id: 5
736 858 role_id: 2
737 859 old_status_id: 3
738 860 id: 134
739 861 tracker_id: 2
740 workflows_160:
862 type: WorkflowTransition
863 WorkflowTransitions_160:
741 864 new_status_id: 6
742 865 role_id: 3
743 866 old_status_id: 2
744 867 id: 160
745 868 tracker_id: 2
746 workflows_215:
869 type: WorkflowTransition
870 WorkflowTransitions_215:
747 871 new_status_id: 6
748 872 role_id: 2
749 873 old_status_id: 1
750 874 id: 215
751 875 tracker_id: 3
752 workflows_242:
876 type: WorkflowTransition
877 WorkflowTransitions_242:
753 878 new_status_id: 3
754 879 role_id: 3
755 880 old_status_id: 1
756 881 id: 242
757 882 tracker_id: 3
758 workflows_028:
883 type: WorkflowTransition
884 WorkflowTransitions_028:
759 885 new_status_id: 3
760 886 role_id: 1
761 887 old_status_id: 6
762 888 id: 28
763 889 tracker_id: 1
764 workflows_054:
890 type: WorkflowTransition
891 WorkflowTransitions_054:
765 892 new_status_id: 4
766 893 role_id: 2
767 894 old_status_id: 5
768 895 id: 54
769 896 tracker_id: 1
770 workflows_081:
897 type: WorkflowTransition
898 WorkflowTransitions_081:
771 899 new_status_id: 1
772 900 role_id: 3
773 901 old_status_id: 5
774 902 id: 81
775 903 tracker_id: 1
776 workflows_109:
904 type: WorkflowTransition
905 WorkflowTransitions_109:
777 906 new_status_id: 5
778 907 role_id: 1
779 908 old_status_id: 4
780 909 id: 109
781 910 tracker_id: 2
782 workflows_135:
911 type: WorkflowTransition
912 WorkflowTransitions_135:
783 913 new_status_id: 6
784 914 role_id: 2
785 915 old_status_id: 3
786 916 id: 135
787 917 tracker_id: 2
788 workflows_161:
918 type: WorkflowTransition
919 WorkflowTransitions_161:
789 920 new_status_id: 1
790 921 role_id: 3
791 922 old_status_id: 3
792 923 id: 161
793 924 tracker_id: 2
794 workflows_216:
925 type: WorkflowTransition
926 WorkflowTransitions_216:
795 927 new_status_id: 1
796 928 role_id: 2
797 929 old_status_id: 2
798 930 id: 216
799 931 tracker_id: 3
800 workflows_243:
932 type: WorkflowTransition
933 WorkflowTransitions_243:
801 934 new_status_id: 4
802 935 role_id: 3
803 936 old_status_id: 1
804 937 id: 243
805 938 tracker_id: 3
806 workflows_029:
939 type: WorkflowTransition
940 WorkflowTransitions_029:
807 941 new_status_id: 4
808 942 role_id: 1
809 943 old_status_id: 6
810 944 id: 29
811 945 tracker_id: 1
812 workflows_055:
946 type: WorkflowTransition
947 WorkflowTransitions_055:
813 948 new_status_id: 6
814 949 role_id: 2
815 950 old_status_id: 5
816 951 id: 55
817 952 tracker_id: 1
818 workflows_082:
953 type: WorkflowTransition
954 WorkflowTransitions_082:
819 955 new_status_id: 2
820 956 role_id: 3
821 957 old_status_id: 5
822 958 id: 82
823 959 tracker_id: 1
824 workflows_136:
960 type: WorkflowTransition
961 WorkflowTransitions_136:
825 962 new_status_id: 1
826 963 role_id: 2
827 964 old_status_id: 4
828 965 id: 136
829 966 tracker_id: 2
830 workflows_162:
967 type: WorkflowTransition
968 WorkflowTransitions_162:
831 969 new_status_id: 2
832 970 role_id: 3
833 971 old_status_id: 3
834 972 id: 162
835 973 tracker_id: 2
836 workflows_217:
974 type: WorkflowTransition
975 WorkflowTransitions_217:
837 976 new_status_id: 3
838 977 role_id: 2
839 978 old_status_id: 2
840 979 id: 217
841 980 tracker_id: 3
842 workflows_270:
981 type: WorkflowTransition
982 WorkflowTransitions_270:
843 983 new_status_id: 5
844 984 role_id: 3
845 985 old_status_id: 6
846 986 id: 270
847 987 tracker_id: 3
848 workflows_244:
988 type: WorkflowTransition
989 WorkflowTransitions_244:
849 990 new_status_id: 5
850 991 role_id: 3
851 992 old_status_id: 1
852 993 id: 244
853 994 tracker_id: 3
854 workflows_056:
995 type: WorkflowTransition
996 WorkflowTransitions_056:
855 997 new_status_id: 1
856 998 role_id: 2
857 999 old_status_id: 6
858 1000 id: 56
859 1001 tracker_id: 1
860 workflows_137:
1002 type: WorkflowTransition
1003 WorkflowTransitions_137:
861 1004 new_status_id: 2
862 1005 role_id: 2
863 1006 old_status_id: 4
864 1007 id: 137
865 1008 tracker_id: 2
866 workflows_163:
1009 type: WorkflowTransition
1010 WorkflowTransitions_163:
867 1011 new_status_id: 4
868 1012 role_id: 3
869 1013 old_status_id: 3
870 1014 id: 163
871 1015 tracker_id: 2
872 workflows_190:
1016 type: WorkflowTransition
1017 WorkflowTransitions_190:
873 1018 new_status_id: 6
874 1019 role_id: 1
875 1020 old_status_id: 2
876 1021 id: 190
877 1022 tracker_id: 3
878 workflows_218:
1023 type: WorkflowTransition
1024 WorkflowTransitions_218:
879 1025 new_status_id: 4
880 1026 role_id: 2
881 1027 old_status_id: 2
882 1028 id: 218
883 1029 tracker_id: 3
884 workflows_245:
1030 type: WorkflowTransition
1031 WorkflowTransitions_245:
885 1032 new_status_id: 6
886 1033 role_id: 3
887 1034 old_status_id: 1
888 1035 id: 245
889 1036 tracker_id: 3
890 workflows_057:
1037 type: WorkflowTransition
1038 WorkflowTransitions_057:
891 1039 new_status_id: 2
892 1040 role_id: 2
893 1041 old_status_id: 6
894 1042 id: 57
895 1043 tracker_id: 1
896 workflows_083:
1044 type: WorkflowTransition
1045 WorkflowTransitions_083:
897 1046 new_status_id: 3
898 1047 role_id: 3
899 1048 old_status_id: 5
900 1049 id: 83
901 1050 tracker_id: 1
902 workflows_138:
1051 type: WorkflowTransition
1052 WorkflowTransitions_138:
903 1053 new_status_id: 3
904 1054 role_id: 2
905 1055 old_status_id: 4
906 1056 id: 138
907 1057 tracker_id: 2
908 workflows_164:
1058 type: WorkflowTransition
1059 WorkflowTransitions_164:
909 1060 new_status_id: 5
910 1061 role_id: 3
911 1062 old_status_id: 3
912 1063 id: 164
913 1064 tracker_id: 2
914 workflows_191:
1065 type: WorkflowTransition
1066 WorkflowTransitions_191:
915 1067 new_status_id: 1
916 1068 role_id: 1
917 1069 old_status_id: 3
918 1070 id: 191
919 1071 tracker_id: 3
920 workflows_219:
1072 type: WorkflowTransition
1073 WorkflowTransitions_219:
921 1074 new_status_id: 5
922 1075 role_id: 2
923 1076 old_status_id: 2
924 1077 id: 219
925 1078 tracker_id: 3
926 workflows_246:
1079 type: WorkflowTransition
1080 WorkflowTransitions_246:
927 1081 new_status_id: 1
928 1082 role_id: 3
929 1083 old_status_id: 2
930 1084 id: 246
931 1085 tracker_id: 3
932 workflows_058:
1086 type: WorkflowTransition
1087 WorkflowTransitions_058:
933 1088 new_status_id: 3
934 1089 role_id: 2
935 1090 old_status_id: 6
936 1091 id: 58
937 1092 tracker_id: 1
938 workflows_084:
1093 type: WorkflowTransition
1094 WorkflowTransitions_084:
939 1095 new_status_id: 4
940 1096 role_id: 3
941 1097 old_status_id: 5
942 1098 id: 84
943 1099 tracker_id: 1
944 workflows_139:
1100 type: WorkflowTransition
1101 WorkflowTransitions_139:
945 1102 new_status_id: 5
946 1103 role_id: 2
947 1104 old_status_id: 4
948 1105 id: 139
949 1106 tracker_id: 2
950 workflows_165:
1107 type: WorkflowTransition
1108 WorkflowTransitions_165:
951 1109 new_status_id: 6
952 1110 role_id: 3
953 1111 old_status_id: 3
954 1112 id: 165
955 1113 tracker_id: 2
956 workflows_192:
1114 type: WorkflowTransition
1115 WorkflowTransitions_192:
957 1116 new_status_id: 2
958 1117 role_id: 1
959 1118 old_status_id: 3
960 1119 id: 192
961 1120 tracker_id: 3
962 workflows_247:
1121 type: WorkflowTransition
1122 WorkflowTransitions_247:
963 1123 new_status_id: 3
964 1124 role_id: 3
965 1125 old_status_id: 2
966 1126 id: 247
967 1127 tracker_id: 3
968 workflows_059:
1128 type: WorkflowTransition
1129 WorkflowTransitions_059:
969 1130 new_status_id: 4
970 1131 role_id: 2
971 1132 old_status_id: 6
972 1133 id: 59
973 1134 tracker_id: 1
974 workflows_085:
1135 type: WorkflowTransition
1136 WorkflowTransitions_085:
975 1137 new_status_id: 6
976 1138 role_id: 3
977 1139 old_status_id: 5
978 1140 id: 85
979 1141 tracker_id: 1
980 workflows_166:
1142 type: WorkflowTransition
1143 WorkflowTransitions_166:
981 1144 new_status_id: 1
982 1145 role_id: 3
983 1146 old_status_id: 4
984 1147 id: 166
985 1148 tracker_id: 2
986 workflows_248:
1149 type: WorkflowTransition
1150 WorkflowTransitions_248:
987 1151 new_status_id: 4
988 1152 role_id: 3
989 1153 old_status_id: 2
990 1154 id: 248
991 1155 tracker_id: 3
992 workflows_086:
1156 type: WorkflowTransition
1157 WorkflowTransitions_086:
993 1158 new_status_id: 1
994 1159 role_id: 3
995 1160 old_status_id: 6
996 1161 id: 86
997 1162 tracker_id: 1
998 workflows_167:
1163 type: WorkflowTransition
1164 WorkflowTransitions_167:
999 1165 new_status_id: 2
1000 1166 role_id: 3
1001 1167 old_status_id: 4
1002 1168 id: 167
1003 1169 tracker_id: 2
1004 workflows_193:
1170 type: WorkflowTransition
1171 WorkflowTransitions_193:
1005 1172 new_status_id: 4
1006 1173 role_id: 1
1007 1174 old_status_id: 3
1008 1175 id: 193
1009 1176 tracker_id: 3
1010 workflows_249:
1177 type: WorkflowTransition
1178 WorkflowTransitions_249:
1011 1179 new_status_id: 5
1012 1180 role_id: 3
1013 1181 old_status_id: 2
1014 1182 id: 249
1015 1183 tracker_id: 3
1016 workflows_087:
1184 type: WorkflowTransition
1185 WorkflowTransitions_087:
1017 1186 new_status_id: 2
1018 1187 role_id: 3
1019 1188 old_status_id: 6
1020 1189 id: 87
1021 1190 tracker_id: 1
1022 workflows_168:
1191 type: WorkflowTransition
1192 WorkflowTransitions_168:
1023 1193 new_status_id: 3
1024 1194 role_id: 3
1025 1195 old_status_id: 4
1026 1196 id: 168
1027 1197 tracker_id: 2
1028 workflows_194:
1198 type: WorkflowTransition
1199 WorkflowTransitions_194:
1029 1200 new_status_id: 5
1030 1201 role_id: 1
1031 1202 old_status_id: 3
1032 1203 id: 194
1033 1204 tracker_id: 3
1034 workflows_088:
1205 type: WorkflowTransition
1206 WorkflowTransitions_088:
1035 1207 new_status_id: 3
1036 1208 role_id: 3
1037 1209 old_status_id: 6
1038 1210 id: 88
1039 1211 tracker_id: 1
1040 workflows_169:
1212 type: WorkflowTransition
1213 WorkflowTransitions_169:
1041 1214 new_status_id: 5
1042 1215 role_id: 3
1043 1216 old_status_id: 4
1044 1217 id: 169
1045 1218 tracker_id: 2
1046 workflows_195:
1219 type: WorkflowTransition
1220 WorkflowTransitions_195:
1047 1221 new_status_id: 6
1048 1222 role_id: 1
1049 1223 old_status_id: 3
1050 1224 id: 195
1051 1225 tracker_id: 3
1052 workflows_089:
1226 type: WorkflowTransition
1227 WorkflowTransitions_089:
1053 1228 new_status_id: 4
1054 1229 role_id: 3
1055 1230 old_status_id: 6
1056 1231 id: 89
1057 1232 tracker_id: 1
1058 workflows_196:
1233 type: WorkflowTransition
1234 WorkflowTransitions_196:
1059 1235 new_status_id: 1
1060 1236 role_id: 1
1061 1237 old_status_id: 4
1062 1238 id: 196
1063 1239 tracker_id: 3
1064 workflows_197:
1240 type: WorkflowTransition
1241 WorkflowTransitions_197:
1065 1242 new_status_id: 2
1066 1243 role_id: 1
1067 1244 old_status_id: 4
1068 1245 id: 197
1069 1246 tracker_id: 3
1070 workflows_198:
1247 type: WorkflowTransition
1248 WorkflowTransitions_198:
1071 1249 new_status_id: 3
1072 1250 role_id: 1
1073 1251 old_status_id: 4
1074 1252 id: 198
1075 1253 tracker_id: 3
1076 workflows_199:
1254 type: WorkflowTransition
1255 WorkflowTransitions_199:
1077 1256 new_status_id: 5
1078 1257 role_id: 1
1079 1258 old_status_id: 4
1080 1259 id: 199
1081 1260 tracker_id: 3
1082 workflows_010:
1261 type: WorkflowTransition
1262 WorkflowTransitions_010:
1083 1263 new_status_id: 6
1084 1264 role_id: 1
1085 1265 old_status_id: 2
1086 1266 id: 10
1087 1267 tracker_id: 1
1088 workflows_011:
1268 type: WorkflowTransition
1269 WorkflowTransitions_011:
1089 1270 new_status_id: 1
1090 1271 role_id: 1
1091 1272 old_status_id: 3
1092 1273 id: 11
1093 1274 tracker_id: 1
1094 workflows_012:
1275 type: WorkflowTransition
1276 WorkflowTransitions_012:
1095 1277 new_status_id: 2
1096 1278 role_id: 1
1097 1279 old_status_id: 3
1098 1280 id: 12
1099 1281 tracker_id: 1
1100 workflows_200:
1282 type: WorkflowTransition
1283 WorkflowTransitions_200:
1101 1284 new_status_id: 6
1102 1285 role_id: 1
1103 1286 old_status_id: 4
1104 1287 id: 200
1105 1288 tracker_id: 3
1106 workflows_013:
1289 type: WorkflowTransition
1290 WorkflowTransitions_013:
1107 1291 new_status_id: 4
1108 1292 role_id: 1
1109 1293 old_status_id: 3
1110 1294 id: 13
1111 1295 tracker_id: 1
1112 workflows_120:
1296 type: WorkflowTransition
1297 WorkflowTransitions_120:
1113 1298 new_status_id: 5
1114 1299 role_id: 1
1115 1300 old_status_id: 6
1116 1301 id: 120
1117 1302 tracker_id: 2
1118 workflows_201:
1303 type: WorkflowTransition
1304 WorkflowTransitions_201:
1119 1305 new_status_id: 1
1120 1306 role_id: 1
1121 1307 old_status_id: 5
1122 1308 id: 201
1123 1309 tracker_id: 3
1124 workflows_040:
1310 type: WorkflowTransition
1311 WorkflowTransitions_040:
1125 1312 new_status_id: 6
1126 1313 role_id: 2
1127 1314 old_status_id: 2
1128 1315 id: 40
1129 1316 tracker_id: 1
1130 workflows_121:
1317 type: WorkflowTransition
1318 WorkflowTransitions_121:
1131 1319 new_status_id: 2
1132 1320 role_id: 2
1133 1321 old_status_id: 1
1134 1322 id: 121
1135 1323 tracker_id: 2
1136 workflows_202:
1324 type: WorkflowTransition
1325 WorkflowTransitions_202:
1137 1326 new_status_id: 2
1138 1327 role_id: 1
1139 1328 old_status_id: 5
1140 1329 id: 202
1141 1330 tracker_id: 3
1142 workflows_014:
1331 type: WorkflowTransition
1332 WorkflowTransitions_014:
1143 1333 new_status_id: 5
1144 1334 role_id: 1
1145 1335 old_status_id: 3
1146 1336 id: 14
1147 1337 tracker_id: 1
1148 workflows_041:
1338 type: WorkflowTransition
1339 WorkflowTransitions_041:
1149 1340 new_status_id: 1
1150 1341 role_id: 2
1151 1342 old_status_id: 3
1152 1343 id: 41
1153 1344 tracker_id: 1
1154 workflows_122:
1345 type: WorkflowTransition
1346 WorkflowTransitions_122:
1155 1347 new_status_id: 3
1156 1348 role_id: 2
1157 1349 old_status_id: 1
1158 1350 id: 122
1159 1351 tracker_id: 2
1160 workflows_203:
1352 type: WorkflowTransition
1353 WorkflowTransitions_203:
1161 1354 new_status_id: 3
1162 1355 role_id: 1
1163 1356 old_status_id: 5
1164 1357 id: 203
1165 1358 tracker_id: 3
1166 workflows_015:
1359 type: WorkflowTransition
1360 WorkflowTransitions_015:
1167 1361 new_status_id: 6
1168 1362 role_id: 1
1169 1363 old_status_id: 3
1170 1364 id: 15
1171 1365 tracker_id: 1
1172 workflows_230:
1366 type: WorkflowTransition
1367 WorkflowTransitions_230:
1173 1368 new_status_id: 6
1174 1369 role_id: 2
1175 1370 old_status_id: 4
1176 1371 id: 230
1177 1372 tracker_id: 3
1178 workflows_123:
1373 type: WorkflowTransition
1374 WorkflowTransitions_123:
1179 1375 new_status_id: 4
1180 1376 role_id: 2
1181 1377 old_status_id: 1
1182 1378 id: 123
1183 1379 tracker_id: 2
1184 workflows_204:
1380 type: WorkflowTransition
1381 WorkflowTransitions_204:
1185 1382 new_status_id: 4
1186 1383 role_id: 1
1187 1384 old_status_id: 5
1188 1385 id: 204
1189 1386 tracker_id: 3
1190 workflows_016:
1387 type: WorkflowTransition
1388 WorkflowTransitions_016:
1191 1389 new_status_id: 1
1192 1390 role_id: 1
1193 1391 old_status_id: 4
1194 1392 id: 16
1195 1393 tracker_id: 1
1196 workflows_042:
1394 type: WorkflowTransition
1395 WorkflowTransitions_042:
1197 1396 new_status_id: 2
1198 1397 role_id: 2
1199 1398 old_status_id: 3
1200 1399 id: 42
1201 1400 tracker_id: 1
1202 workflows_231:
1401 type: WorkflowTransition
1402 WorkflowTransitions_231:
1203 1403 new_status_id: 1
1204 1404 role_id: 2
1205 1405 old_status_id: 5
1206 1406 id: 231
1207 1407 tracker_id: 3
1208 workflows_070:
1408 type: WorkflowTransition
1409 WorkflowTransitions_070:
1209 1410 new_status_id: 6
1210 1411 role_id: 3
1211 1412 old_status_id: 2
1212 1413 id: 70
1213 1414 tracker_id: 1
1214 workflows_124:
1415 type: WorkflowTransition
1416 WorkflowTransitions_124:
1215 1417 new_status_id: 5
1216 1418 role_id: 2
1217 1419 old_status_id: 1
1218 1420 id: 124
1219 1421 tracker_id: 2
1220 workflows_150:
1422 type: WorkflowTransition
1423 WorkflowTransitions_150:
1221 1424 new_status_id: 5
1222 1425 role_id: 2
1223 1426 old_status_id: 6
1224 1427 id: 150
1225 1428 tracker_id: 2
1226 workflows_205:
1429 type: WorkflowTransition
1430 WorkflowTransitions_205:
1227 1431 new_status_id: 6
1228 1432 role_id: 1
1229 1433 old_status_id: 5
1230 1434 id: 205
1231 1435 tracker_id: 3
1232 workflows_017:
1436 type: WorkflowTransition
1437 WorkflowTransitions_017:
1233 1438 new_status_id: 2
1234 1439 role_id: 1
1235 1440 old_status_id: 4
1236 1441 id: 17
1237 1442 tracker_id: 1
1238 workflows_043:
1443 type: WorkflowTransition
1444 WorkflowTransitions_043:
1239 1445 new_status_id: 4
1240 1446 role_id: 2
1241 1447 old_status_id: 3
1242 1448 id: 43
1243 1449 tracker_id: 1
1244 workflows_232:
1450 type: WorkflowTransition
1451 WorkflowTransitions_232:
1245 1452 new_status_id: 2
1246 1453 role_id: 2
1247 1454 old_status_id: 5
1248 1455 id: 232
1249 1456 tracker_id: 3
1250 workflows_125:
1457 type: WorkflowTransition
1458 WorkflowTransitions_125:
1251 1459 new_status_id: 6
1252 1460 role_id: 2
1253 1461 old_status_id: 1
1254 1462 id: 125
1255 1463 tracker_id: 2
1256 workflows_151:
1464 type: WorkflowTransition
1465 WorkflowTransitions_151:
1257 1466 new_status_id: 2
1258 1467 role_id: 3
1259 1468 old_status_id: 1
1260 1469 id: 151
1261 1470 tracker_id: 2
1262 workflows_206:
1471 type: WorkflowTransition
1472 WorkflowTransitions_206:
1263 1473 new_status_id: 1
1264 1474 role_id: 1
1265 1475 old_status_id: 6
1266 1476 id: 206
1267 1477 tracker_id: 3
1268 workflows_018:
1478 type: WorkflowTransition
1479 WorkflowTransitions_018:
1269 1480 new_status_id: 3
1270 1481 role_id: 1
1271 1482 old_status_id: 4
1272 1483 id: 18
1273 1484 tracker_id: 1
1274 workflows_044:
1485 type: WorkflowTransition
1486 WorkflowTransitions_044:
1275 1487 new_status_id: 5
1276 1488 role_id: 2
1277 1489 old_status_id: 3
1278 1490 id: 44
1279 1491 tracker_id: 1
1280 workflows_071:
1492 type: WorkflowTransition
1493 WorkflowTransitions_071:
1281 1494 new_status_id: 1
1282 1495 role_id: 3
1283 1496 old_status_id: 3
1284 1497 id: 71
1285 1498 tracker_id: 1
1286 workflows_233:
1499 type: WorkflowTransition
1500 WorkflowTransitions_233:
1287 1501 new_status_id: 3
1288 1502 role_id: 2
1289 1503 old_status_id: 5
1290 1504 id: 233
1291 1505 tracker_id: 3
1292 workflows_126:
1506 type: WorkflowTransition
1507 WorkflowTransitions_126:
1293 1508 new_status_id: 1
1294 1509 role_id: 2
1295 1510 old_status_id: 2
1296 1511 id: 126
1297 1512 tracker_id: 2
1298 workflows_152:
1513 type: WorkflowTransition
1514 WorkflowTransitions_152:
1299 1515 new_status_id: 3
1300 1516 role_id: 3
1301 1517 old_status_id: 1
1302 1518 id: 152
1303 1519 tracker_id: 2
1304 workflows_207:
1520 type: WorkflowTransition
1521 WorkflowTransitions_207:
1305 1522 new_status_id: 2
1306 1523 role_id: 1
1307 1524 old_status_id: 6
1308 1525 id: 207
1309 1526 tracker_id: 3
1310 workflows_019:
1527 type: WorkflowTransition
1528 WorkflowTransitions_019:
1311 1529 new_status_id: 5
1312 1530 role_id: 1
1313 1531 old_status_id: 4
1314 1532 id: 19
1315 1533 tracker_id: 1
1316 workflows_045:
1534 type: WorkflowTransition
1535 WorkflowTransitions_045:
1317 1536 new_status_id: 6
1318 1537 role_id: 2
1319 1538 old_status_id: 3
1320 1539 id: 45
1321 1540 tracker_id: 1
1322 workflows_260:
1541 type: WorkflowTransition
1542 WorkflowTransitions_260:
1323 1543 new_status_id: 6
1324 1544 role_id: 3
1325 1545 old_status_id: 4
1326 1546 id: 260
1327 1547 tracker_id: 3
1328 workflows_234:
1548 type: WorkflowTransition
1549 WorkflowTransitions_234:
1329 1550 new_status_id: 4
1330 1551 role_id: 2
1331 1552 old_status_id: 5
1332 1553 id: 234
1333 1554 tracker_id: 3
1334 workflows_127:
1555 type: WorkflowTransition
1556 WorkflowTransitions_127:
1335 1557 new_status_id: 3
1336 1558 role_id: 2
1337 1559 old_status_id: 2
1338 1560 id: 127
1339 1561 tracker_id: 2
1340 workflows_153:
1562 type: WorkflowTransition
1563 WorkflowTransitions_153:
1341 1564 new_status_id: 4
1342 1565 role_id: 3
1343 1566 old_status_id: 1
1344 1567 id: 153
1345 1568 tracker_id: 2
1346 workflows_180:
1569 type: WorkflowTransition
1570 WorkflowTransitions_180:
1347 1571 new_status_id: 5
1348 1572 role_id: 3
1349 1573 old_status_id: 6
1350 1574 id: 180
1351 1575 tracker_id: 2
1352 workflows_208:
1576 type: WorkflowTransition
1577 WorkflowTransitions_208:
1353 1578 new_status_id: 3
1354 1579 role_id: 1
1355 1580 old_status_id: 6
1356 1581 id: 208
1357 1582 tracker_id: 3
1358 workflows_046:
1583 type: WorkflowTransition
1584 WorkflowTransitions_046:
1359 1585 new_status_id: 1
1360 1586 role_id: 2
1361 1587 old_status_id: 4
1362 1588 id: 46
1363 1589 tracker_id: 1
1364 workflows_072:
1590 type: WorkflowTransition
1591 WorkflowTransitions_072:
1365 1592 new_status_id: 2
1366 1593 role_id: 3
1367 1594 old_status_id: 3
1368 1595 id: 72
1369 1596 tracker_id: 1
1370 workflows_261:
1597 type: WorkflowTransition
1598 WorkflowTransitions_261:
1371 1599 new_status_id: 1
1372 1600 role_id: 3
1373 1601 old_status_id: 5
1374 1602 id: 261
1375 1603 tracker_id: 3
1376 workflows_235:
1604 type: WorkflowTransition
1605 WorkflowTransitions_235:
1377 1606 new_status_id: 6
1378 1607 role_id: 2
1379 1608 old_status_id: 5
1380 1609 id: 235
1381 1610 tracker_id: 3
1382 workflows_154:
1611 type: WorkflowTransition
1612 WorkflowTransitions_154:
1383 1613 new_status_id: 5
1384 1614 role_id: 3
1385 1615 old_status_id: 1
1386 1616 id: 154
1387 1617 tracker_id: 2
1388 workflows_181:
1618 type: WorkflowTransition
1619 WorkflowTransitions_181:
1389 1620 new_status_id: 2
1390 1621 role_id: 1
1391 1622 old_status_id: 1
1392 1623 id: 181
1393 1624 tracker_id: 3
1394 workflows_209:
1625 type: WorkflowTransition
1626 WorkflowTransitions_209:
1395 1627 new_status_id: 4
1396 1628 role_id: 1
1397 1629 old_status_id: 6
1398 1630 id: 209
1399 1631 tracker_id: 3
1400 workflows_047:
1632 type: WorkflowTransition
1633 WorkflowTransitions_047:
1401 1634 new_status_id: 2
1402 1635 role_id: 2
1403 1636 old_status_id: 4
1404 1637 id: 47
1405 1638 tracker_id: 1
1406 workflows_073:
1639 type: WorkflowTransition
1640 WorkflowTransitions_073:
1407 1641 new_status_id: 4
1408 1642 role_id: 3
1409 1643 old_status_id: 3
1410 1644 id: 73
1411 1645 tracker_id: 1
1412 workflows_128:
1646 type: WorkflowTransition
1647 WorkflowTransitions_128:
1413 1648 new_status_id: 4
1414 1649 role_id: 2
1415 1650 old_status_id: 2
1416 1651 id: 128
1417 1652 tracker_id: 2
1418 workflows_262:
1653 type: WorkflowTransition
1654 WorkflowTransitions_262:
1419 1655 new_status_id: 2
1420 1656 role_id: 3
1421 1657 old_status_id: 5
1422 1658 id: 262
1423 1659 tracker_id: 3
1424 workflows_236:
1660 type: WorkflowTransition
1661 WorkflowTransitions_236:
1425 1662 new_status_id: 1
1426 1663 role_id: 2
1427 1664 old_status_id: 6
1428 1665 id: 236
1429 1666 tracker_id: 3
1430 workflows_155:
1667 type: WorkflowTransition
1668 WorkflowTransitions_155:
1431 1669 new_status_id: 6
1432 1670 role_id: 3
1433 1671 old_status_id: 1
1434 1672 id: 155
1435 1673 tracker_id: 2
1436 workflows_048:
1674 type: WorkflowTransition
1675 WorkflowTransitions_048:
1437 1676 new_status_id: 3
1438 1677 role_id: 2
1439 1678 old_status_id: 4
1440 1679 id: 48
1441 1680 tracker_id: 1
1442 workflows_074:
1681 type: WorkflowTransition
1682 WorkflowTransitions_074:
1443 1683 new_status_id: 5
1444 1684 role_id: 3
1445 1685 old_status_id: 3
1446 1686 id: 74
1447 1687 tracker_id: 1
1448 workflows_129:
1688 type: WorkflowTransition
1689 WorkflowTransitions_129:
1449 1690 new_status_id: 5
1450 1691 role_id: 2
1451 1692 old_status_id: 2
1452 1693 id: 129
1453 1694 tracker_id: 2
1454 workflows_263:
1695 type: WorkflowTransition
1696 WorkflowTransitions_263:
1455 1697 new_status_id: 3
1456 1698 role_id: 3
1457 1699 old_status_id: 5
1458 1700 id: 263
1459 1701 tracker_id: 3
1460 workflows_237:
1702 type: WorkflowTransition
1703 WorkflowTransitions_237:
1461 1704 new_status_id: 2
1462 1705 role_id: 2
1463 1706 old_status_id: 6
1464 1707 id: 237
1465 1708 tracker_id: 3
1466 workflows_182:
1709 type: WorkflowTransition
1710 WorkflowTransitions_182:
1467 1711 new_status_id: 3
1468 1712 role_id: 1
1469 1713 old_status_id: 1
1470 1714 id: 182
1471 1715 tracker_id: 3
1472 workflows_049:
1716 type: WorkflowTransition
1717 WorkflowTransitions_049:
1473 1718 new_status_id: 5
1474 1719 role_id: 2
1475 1720 old_status_id: 4
1476 1721 id: 49
1477 1722 tracker_id: 1
1478 workflows_075:
1723 type: WorkflowTransition
1724 WorkflowTransitions_075:
1479 1725 new_status_id: 6
1480 1726 role_id: 3
1481 1727 old_status_id: 3
1482 1728 id: 75
1483 1729 tracker_id: 1
1484 workflows_156:
1730 type: WorkflowTransition
1731 WorkflowTransitions_156:
1485 1732 new_status_id: 1
1486 1733 role_id: 3
1487 1734 old_status_id: 2
1488 1735 id: 156
1489 1736 tracker_id: 2
1490 workflows_264:
1737 type: WorkflowTransition
1738 WorkflowTransitions_264:
1491 1739 new_status_id: 4
1492 1740 role_id: 3
1493 1741 old_status_id: 5
1494 1742 id: 264
1495 1743 tracker_id: 3
1496 workflows_238:
1744 type: WorkflowTransition
1745 WorkflowTransitions_238:
1497 1746 new_status_id: 3
1498 1747 role_id: 2
1499 1748 old_status_id: 6
1500 1749 id: 238
1501 1750 tracker_id: 3
1502 workflows_183:
1751 type: WorkflowTransition
1752 WorkflowTransitions_183:
1503 1753 new_status_id: 4
1504 1754 role_id: 1
1505 1755 old_status_id: 1
1506 1756 id: 183
1507 1757 tracker_id: 3
1508 workflows_076:
1758 type: WorkflowTransition
1759 WorkflowTransitions_076:
1509 1760 new_status_id: 1
1510 1761 role_id: 3
1511 1762 old_status_id: 4
1512 1763 id: 76
1513 1764 tracker_id: 1
1514 workflows_157:
1765 type: WorkflowTransition
1766 WorkflowTransitions_157:
1515 1767 new_status_id: 3
1516 1768 role_id: 3
1517 1769 old_status_id: 2
1518 1770 id: 157
1519 1771 tracker_id: 2
1520 workflows_265:
1772 type: WorkflowTransition
1773 WorkflowTransitions_265:
1521 1774 new_status_id: 6
1522 1775 role_id: 3
1523 1776 old_status_id: 5
1524 1777 id: 265
1525 1778 tracker_id: 3
1526 workflows_239:
1779 type: WorkflowTransition
1780 WorkflowTransitions_239:
1527 1781 new_status_id: 4
1528 1782 role_id: 2
1529 1783 old_status_id: 6
1530 1784 id: 239
1531 1785 tracker_id: 3
1532 workflows_077:
1786 type: WorkflowTransition
1787 WorkflowTransitions_077:
1533 1788 new_status_id: 2
1534 1789 role_id: 3
1535 1790 old_status_id: 4
1536 1791 id: 77
1537 1792 tracker_id: 1
1538 workflows_158:
1793 type: WorkflowTransition
1794 WorkflowTransitions_158:
1539 1795 new_status_id: 4
1540 1796 role_id: 3
1541 1797 old_status_id: 2
1542 1798 id: 158
1543 1799 tracker_id: 2
1544 workflows_184:
1800 type: WorkflowTransition
1801 WorkflowTransitions_184:
1545 1802 new_status_id: 5
1546 1803 role_id: 1
1547 1804 old_status_id: 1
1548 1805 id: 184
1549 1806 tracker_id: 3
1550 workflows_266:
1807 type: WorkflowTransition
1808 WorkflowTransitions_266:
1551 1809 new_status_id: 1
1552 1810 role_id: 3
1553 1811 old_status_id: 6
1554 1812 id: 266
1555 1813 tracker_id: 3
1556 workflows_078:
1814 type: WorkflowTransition
1815 WorkflowTransitions_078:
1557 1816 new_status_id: 3
1558 1817 role_id: 3
1559 1818 old_status_id: 4
1560 1819 id: 78
1561 1820 tracker_id: 1
1562 workflows_159:
1821 type: WorkflowTransition
1822 WorkflowTransitions_159:
1563 1823 new_status_id: 5
1564 1824 role_id: 3
1565 1825 old_status_id: 2
1566 1826 id: 159
1567 1827 tracker_id: 2
1568 workflows_185:
1828 type: WorkflowTransition
1829 WorkflowTransitions_185:
1569 1830 new_status_id: 6
1570 1831 role_id: 1
1571 1832 old_status_id: 1
1572 1833 id: 185
1573 1834 tracker_id: 3
1574 workflows_267:
1835 type: WorkflowTransition
1836 WorkflowTransitions_267:
1575 1837 new_status_id: 2
1576 1838 role_id: 3
1577 1839 old_status_id: 6
1578 1840 id: 267
1579 1841 tracker_id: 3
1580 workflows_079:
1842 type: WorkflowTransition
1843 WorkflowTransitions_079:
1581 1844 new_status_id: 5
1582 1845 role_id: 3
1583 1846 old_status_id: 4
1584 1847 id: 79
1585 1848 tracker_id: 1
1586 workflows_186:
1849 type: WorkflowTransition
1850 WorkflowTransitions_186:
1587 1851 new_status_id: 1
1588 1852 role_id: 1
1589 1853 old_status_id: 2
1590 1854 id: 186
1591 1855 tracker_id: 3
1592 workflows_268:
1856 type: WorkflowTransition
1857 WorkflowTransitions_268:
1593 1858 new_status_id: 3
1594 1859 role_id: 3
1595 1860 old_status_id: 6
1596 1861 id: 268
1597 1862 tracker_id: 3
1598 workflows_187:
1863 type: WorkflowTransition
1864 WorkflowTransitions_187:
1599 1865 new_status_id: 3
1600 1866 role_id: 1
1601 1867 old_status_id: 2
1602 1868 id: 187
1603 1869 tracker_id: 3
1604 workflows_269:
1870 type: WorkflowTransition
1871 WorkflowTransitions_269:
1605 1872 new_status_id: 4
1606 1873 role_id: 3
1607 1874 old_status_id: 6
1608 1875 id: 269
1609 1876 tracker_id: 3
1610 workflows_188:
1877 type: WorkflowTransition
1878 WorkflowTransitions_188:
1611 1879 new_status_id: 4
1612 1880 role_id: 1
1613 1881 old_status_id: 2
1614 1882 id: 188
1615 1883 tracker_id: 3
1884 type: WorkflowTransition
@@ -823,7 +823,7 class IssuesControllerTest < ActionController::TestCase
823 823
824 824 def test_show_should_display_update_form_with_minimal_permissions
825 825 Role.find(1).update_attribute :permissions, [:view_issues, :add_issue_notes]
826 Workflow.delete_all :role_id => 1
826 WorkflowTransition.delete_all :role_id => 1
827 827
828 828 @request.session[:user_id] = 2
829 829 get :show, :id => 1
@@ -1300,7 +1300,7 class IssuesControllerTest < ActionController::TestCase
1300 1300
1301 1301 def test_get_new_with_minimal_permissions
1302 1302 Role.find(1).update_attribute :permissions, [:add_issues]
1303 Workflow.delete_all :role_id => 1
1303 WorkflowTransition.delete_all :role_id => 1
1304 1304
1305 1305 @request.session[:user_id] = 2
1306 1306 get :new, :project_id => 1, :tracker_id => 1
@@ -1426,6 +1426,50 class IssuesControllerTest < ActionController::TestCase
1426 1426 :attributes => {:name => 'issue[custom_field_values][2]', :value => 'Custom field value'}
1427 1427 end
1428 1428
1429 def test_get_new_should_mark_required_fields
1430 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1431 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1432 WorkflowPermission.delete_all
1433 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'required')
1434 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
1435 @request.session[:user_id] = 2
1436
1437 get :new, :project_id => 1
1438 assert_response :success
1439 assert_template 'new'
1440
1441 assert_select 'label[for=issue_start_date]' do
1442 assert_select 'span[class=required]', 0
1443 end
1444 assert_select 'label[for=issue_due_date]' do
1445 assert_select 'span[class=required]'
1446 end
1447 assert_select 'label[for=?]', "issue_custom_field_values_#{cf1.id}" do
1448 assert_select 'span[class=required]', 0
1449 end
1450 assert_select 'label[for=?]', "issue_custom_field_values_#{cf2.id}" do
1451 assert_select 'span[class=required]'
1452 end
1453 end
1454
1455 def test_get_new_should_not_display_readonly_fields
1456 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1457 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1458 WorkflowPermission.delete_all
1459 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
1460 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
1461 @request.session[:user_id] = 2
1462
1463 get :new, :project_id => 1
1464 assert_response :success
1465 assert_template 'new'
1466
1467 assert_select 'input[name=?]', 'issue[start_date]'
1468 assert_select 'input[name=?]', 'issue[due_date]', 0
1469 assert_select 'input[name=?]', "issue[custom_field_values][#{cf1.id}]"
1470 assert_select 'input[name=?]', "issue[custom_field_values][#{cf2.id}]", 0
1471 end
1472
1429 1473 def test_get_new_without_tracker_id
1430 1474 @request.session[:user_id] = 2
1431 1475 get :new, :project_id => 1
@@ -1463,7 +1507,7 class IssuesControllerTest < ActionController::TestCase
1463 1507 :description => 'This is the description',
1464 1508 :priority_id => 5}
1465 1509 assert_response :success
1466 assert_template 'attributes'
1510 assert_template 'form'
1467 1511
1468 1512 issue = assigns(:issue)
1469 1513 assert_kind_of Issue, issue
@@ -1474,10 +1518,10 class IssuesControllerTest < ActionController::TestCase
1474 1518
1475 1519 def test_update_new_form_should_propose_transitions_based_on_initial_status
1476 1520 @request.session[:user_id] = 2
1477 Workflow.delete_all
1478 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2)
1479 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5)
1480 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4)
1521 WorkflowTransition.delete_all
1522 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2)
1523 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5)
1524 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4)
1481 1525
1482 1526 xhr :post, :new, :project_id => 1,
1483 1527 :issue => {:tracker_id => 1,
@@ -1678,6 +1722,58 class IssuesControllerTest < ActionController::TestCase
1678 1722 assert_error_tag :content => /Database can't be blank/
1679 1723 end
1680 1724
1725 def test_create_should_validate_required_fields
1726 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1727 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1728 WorkflowPermission.delete_all
1729 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'required')
1730 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'required')
1731 @request.session[:user_id] = 2
1732
1733 assert_no_difference 'Issue.count' do
1734 post :create, :project_id => 1, :issue => {
1735 :tracker_id => 2,
1736 :status_id => 1,
1737 :subject => 'Test',
1738 :start_date => '',
1739 :due_date => '',
1740 :custom_field_values => {cf1.id.to_s => '', cf2.id.to_s => ''}
1741 }
1742 assert_response :success
1743 assert_template 'new'
1744 end
1745
1746 assert_error_tag :content => /Due date can't be blank/i
1747 assert_error_tag :content => /Bar can't be blank/i
1748 end
1749
1750 def test_create_should_ignore_readonly_fields
1751 cf1 = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1752 cf2 = IssueCustomField.create!(:name => 'Bar', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
1753 WorkflowPermission.delete_all
1754 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
1755 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
1756 @request.session[:user_id] = 2
1757
1758 assert_difference 'Issue.count' do
1759 post :create, :project_id => 1, :issue => {
1760 :tracker_id => 2,
1761 :status_id => 1,
1762 :subject => 'Test',
1763 :start_date => '2012-07-14',
1764 :due_date => '2012-07-16',
1765 :custom_field_values => {cf1.id.to_s => 'value1', cf2.id.to_s => 'value2'}
1766 }
1767 assert_response 302
1768 end
1769
1770 issue = Issue.first(:order => 'id DESC')
1771 assert_equal Date.parse('2012-07-14'), issue.start_date
1772 assert_nil issue.due_date
1773 assert_equal 'value1', issue.custom_field_value(cf1)
1774 assert_nil issue.custom_field_value(cf2)
1775 end
1776
1681 1777 def test_post_create_with_watchers
1682 1778 @request.session[:user_id] = 2
1683 1779 ActionMailer::Base.deliveries.clear
@@ -1917,7 +2013,7 class IssuesControllerTest < ActionController::TestCase
1917 2013
1918 2014 context "without workflow privilege" do
1919 2015 setup do
1920 Workflow.delete_all(["role_id = ?", Role.anonymous.id])
2016 WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
1921 2017 Role.anonymous.add_permission! :add_issues, :add_issue_notes
1922 2018 end
1923 2019
@@ -1976,9 +2072,9 class IssuesControllerTest < ActionController::TestCase
1976 2072
1977 2073 context "with workflow privilege" do
1978 2074 setup do
1979 Workflow.delete_all(["role_id = ?", Role.anonymous.id])
1980 Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
1981 Workflow.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
2075 WorkflowTransition.delete_all(["role_id = ?", Role.anonymous.id])
2076 WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
2077 WorkflowTransition.create!(:role => Role.anonymous, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
1982 2078 Role.anonymous.add_permission! :add_issues, :add_issue_notes
1983 2079 end
1984 2080
@@ -2286,7 +2382,7 class IssuesControllerTest < ActionController::TestCase
2286 2382 :description => 'This is the description',
2287 2383 :priority_id => 5}
2288 2384 assert_response :success
2289 assert_template 'attributes'
2385 assert_template 'form'
2290 2386
2291 2387 issue = assigns(:issue)
2292 2388 assert_kind_of Issue, issue
@@ -2298,10 +2394,10 class IssuesControllerTest < ActionController::TestCase
2298 2394
2299 2395 def test_update_edit_form_should_propose_transitions_based_on_initial_status
2300 2396 @request.session[:user_id] = 2
2301 Workflow.delete_all
2302 Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
2303 Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
2304 Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 5, :new_status_id => 4)
2397 WorkflowTransition.delete_all
2398 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
2399 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
2400 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 5, :new_status_id => 4)
2305 2401
2306 2402 xhr :put, :new, :project_id => 1,
2307 2403 :id => 2,
@@ -2317,7 +2413,6 class IssuesControllerTest < ActionController::TestCase
2317 2413 @request.session[:user_id] = 2
2318 2414 xhr :put, :new, :project_id => 1,
2319 2415 :id => 1,
2320 :project_change => '1',
2321 2416 :issue => {:project_id => 2,
2322 2417 :tracker_id => 2,
2323 2418 :subject => 'This is the test_new issue',
@@ -2845,13 +2940,13 class IssuesControllerTest < ActionController::TestCase
2845 2940 end
2846 2941
2847 2942 def test_bulk_edit_should_only_propose_statuses_allowed_for_all_issues
2848 Workflow.delete_all
2849 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 1)
2850 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
2851 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
2852 Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
2853 Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 3)
2854 Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
2943 WorkflowTransition.delete_all
2944 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 1)
2945 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3)
2946 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4)
2947 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
2948 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 3)
2949 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
2855 2950 @request.session[:user_id] = 2
2856 2951 get :bulk_edit, :ids => [1, 2]
2857 2952
@@ -77,7 +77,7 class RolesControllerTest < ActionController::TestCase
77 77 assert_redirected_to '/roles'
78 78 role = Role.find_by_name('RoleWithWorkflowCopy')
79 79 assert_not_nil role
80 assert_equal Role.find(1).workflows.size, role.workflows.size
80 assert_equal Role.find(1).workflow_rules.size, role.workflow_rules.size
81 81 end
82 82
83 83 def test_edit
@@ -66,7 +66,7 class TrackersControllerTest < ActionController::TestCase
66 66 assert_equal [1], tracker.project_ids.sort
67 67 assert_equal Tracker::CORE_FIELDS, tracker.core_fields
68 68 assert_equal [1, 6], tracker.custom_field_ids.sort
69 assert_equal 0, tracker.workflows.count
69 assert_equal 0, tracker.workflow_rules.count
70 70 end
71 71
72 72 def create_with_disabled_core_fields
@@ -86,7 +86,7 class TrackersControllerTest < ActionController::TestCase
86 86 assert_redirected_to :action => 'index'
87 87 tracker = Tracker.find_by_name('New tracker')
88 88 assert_equal 0, tracker.projects.count
89 assert_equal Tracker.find(1).workflows.count, tracker.workflows.count
89 assert_equal Tracker.find(1).workflow_rules.count, tracker.workflow_rules.count
90 90 end
91 91
92 92 def test_create_with_failure
@@ -37,7 +37,7 class WorkflowsControllerTest < ActionController::TestCase
37 37 assert_response :success
38 38 assert_template 'index'
39 39
40 count = Workflow.count(:all, :conditions => 'role_id = 1 AND tracker_id = 2')
40 count = WorkflowTransition.count(:all, :conditions => 'role_id = 1 AND tracker_id = 2')
41 41 assert_tag :tag => 'a', :content => count.to_s,
42 42 :attributes => { :href => '/workflows/edit?role_id=1&amp;tracker_id=2' }
43 43 end
@@ -51,9 +51,9 class WorkflowsControllerTest < ActionController::TestCase
51 51 end
52 52
53 53 def test_get_edit_with_role_and_tracker
54 Workflow.delete_all
55 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 2, :new_status_id => 3)
56 Workflow.create!(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 5)
54 WorkflowTransition.delete_all
55 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 2, :new_status_id => 3)
56 WorkflowTransition.create!(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 5)
57 57
58 58 get :edit, :role_id => 2, :tracker_id => 1
59 59 assert_response :success
@@ -79,7 +79,7 class WorkflowsControllerTest < ActionController::TestCase
79 79 end
80 80
81 81 def test_get_edit_with_role_and_tracker_and_all_statuses
82 Workflow.delete_all
82 WorkflowTransition.delete_all
83 83
84 84 get :edit, :role_id => 2, :tracker_id => 1, :used_statuses_only => '0'
85 85 assert_response :success
@@ -102,9 +102,9 class WorkflowsControllerTest < ActionController::TestCase
102 102 }
103 103 assert_redirected_to '/workflows/edit?role_id=2&tracker_id=1'
104 104
105 assert_equal 3, Workflow.count(:conditions => {:tracker_id => 1, :role_id => 2})
106 assert_not_nil Workflow.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2})
107 assert_nil Workflow.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4})
105 assert_equal 3, WorkflowTransition.count(:conditions => {:tracker_id => 1, :role_id => 2})
106 assert_not_nil WorkflowTransition.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2})
107 assert_nil WorkflowTransition.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4})
108 108 end
109 109
110 110 def test_post_edit_with_additional_transitions
@@ -115,27 +115,117 class WorkflowsControllerTest < ActionController::TestCase
115 115 }
116 116 assert_redirected_to '/workflows/edit?role_id=2&tracker_id=1'
117 117
118 assert_equal 4, Workflow.count(:conditions => {:tracker_id => 1, :role_id => 2})
118 assert_equal 4, WorkflowTransition.count(:conditions => {:tracker_id => 1, :role_id => 2})
119 119
120 w = Workflow.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 4, :new_status_id => 5})
120 w = WorkflowTransition.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 4, :new_status_id => 5})
121 121 assert ! w.author
122 122 assert ! w.assignee
123 w = Workflow.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 1})
123 w = WorkflowTransition.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 1})
124 124 assert w.author
125 125 assert ! w.assignee
126 w = Workflow.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2})
126 w = WorkflowTransition.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 2})
127 127 assert ! w.author
128 128 assert w.assignee
129 w = Workflow.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 4})
129 w = WorkflowTransition.find(:first, :conditions => {:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 4})
130 130 assert w.author
131 131 assert w.assignee
132 132 end
133 133
134 134 def test_clear_workflow
135 assert Workflow.count(:conditions => {:tracker_id => 1, :role_id => 2}) > 0
135 assert WorkflowTransition.count(:conditions => {:tracker_id => 1, :role_id => 2}) > 0
136 136
137 137 post :edit, :role_id => 2, :tracker_id => 1
138 assert_equal 0, Workflow.count(:conditions => {:tracker_id => 1, :role_id => 2})
138 assert_equal 0, WorkflowTransition.count(:conditions => {:tracker_id => 1, :role_id => 2})
139 end
140
141 def test_get_permissions
142 get :permissions
143
144 assert_response :success
145 assert_template 'permissions'
146 assert_not_nil assigns(:roles)
147 assert_not_nil assigns(:trackers)
148 end
149
150 def test_get_permissions_with_role_and_tracker
151 WorkflowPermission.delete_all
152 WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :field_name => 'assigned_to_id', :rule => 'required')
153 WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :field_name => 'fixed_version_id', :rule => 'required')
154 WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 3, :field_name => 'fixed_version_id', :rule => 'readonly')
155
156 get :permissions, :role_id => 1, :tracker_id => 2
157 assert_response :success
158 assert_template 'permissions'
159
160 assert_select 'input[name=role_id][value=1]'
161 assert_select 'input[name=tracker_id][value=2]'
162
163 # Required field
164 assert_select 'select[name=?]', 'permissions[assigned_to_id][2]' do
165 assert_select 'option[value=]'
166 assert_select 'option[value=][selected=selected]', 0
167 assert_select 'option[value=readonly]', :text => 'Read-only'
168 assert_select 'option[value=readonly][selected=selected]', 0
169 assert_select 'option[value=required]', :text => 'Required'
170 assert_select 'option[value=required][selected=selected]'
171 end
172
173 # Read-only field
174 assert_select 'select[name=?]', 'permissions[fixed_version_id][3]' do
175 assert_select 'option[value=]'
176 assert_select 'option[value=][selected=selected]', 0
177 assert_select 'option[value=readonly]', :text => 'Read-only'
178 assert_select 'option[value=readonly][selected=selected]'
179 assert_select 'option[value=required]', :text => 'Required'
180 assert_select 'option[value=required][selected=selected]', 0
181 end
182
183 # Other field
184 assert_select 'select[name=?]', 'permissions[due_date][3]' do
185 assert_select 'option[value=]'
186 assert_select 'option[value=][selected=selected]', 0
187 assert_select 'option[value=readonly]', :text => 'Read-only'
188 assert_select 'option[value=readonly][selected=selected]', 0
189 assert_select 'option[value=required]', :text => 'Required'
190 assert_select 'option[value=required][selected=selected]', 0
191 end
192 end
193
194 def test_post_permissions
195 WorkflowPermission.delete_all
196
197 post :permissions, :role_id => 1, :tracker_id => 2, :permissions => {
198 'assigned_to_id' => {'1' => '', '2' => 'readonly', '3' => ''},
199 'fixed_version_id' => {'1' => 'required', '2' => 'readonly', '3' => ''},
200 'due_date' => {'1' => '', '2' => '', '3' => ''},
201 }
202 assert_redirected_to '/workflows/permissions?role_id=1&tracker_id=2'
203
204 workflows = WorkflowPermission.all
205 assert_equal 3, workflows.size
206 workflows.each do |workflow|
207 assert_equal 1, workflow.role_id
208 assert_equal 2, workflow.tracker_id
209 end
210 assert workflows.detect {|wf| wf.old_status_id == 2 && wf.field_name == 'assigned_to_id' && wf.rule == 'readonly'}
211 assert workflows.detect {|wf| wf.old_status_id == 1 && wf.field_name == 'fixed_version_id' && wf.rule == 'required'}
212 assert workflows.detect {|wf| wf.old_status_id == 2 && wf.field_name == 'fixed_version_id' && wf.rule == 'readonly'}
213 end
214
215 def test_post_permissions_should_clear_permissions
216 WorkflowPermission.delete_all
217 WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :field_name => 'assigned_to_id', :rule => 'required')
218 WorkflowPermission.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :field_name => 'fixed_version_id', :rule => 'required')
219 wf1 = WorkflowPermission.create!(:role_id => 1, :tracker_id => 3, :old_status_id => 2, :field_name => 'fixed_version_id', :rule => 'required')
220 wf2 = WorkflowPermission.create!(:role_id => 2, :tracker_id => 2, :old_status_id => 3, :field_name => 'fixed_version_id', :rule => 'readonly')
221
222 post :permissions, :role_id => 1, :tracker_id => 2
223 assert_redirected_to '/workflows/permissions?role_id=1&tracker_id=2'
224
225 workflows = WorkflowPermission.all
226 assert_equal 2, workflows.size
227 assert wf1.reload
228 assert wf2.reload
139 229 end
140 230
141 231 def test_get_copy
@@ -192,7 +282,7 class WorkflowsControllerTest < ActionController::TestCase
192 282
193 283 # Returns an array of status transitions that can be compared
194 284 def status_transitions(conditions)
195 Workflow.find(:all, :conditions => conditions,
285 WorkflowTransition.find(:all, :conditions => conditions,
196 286 :order => 'tracker_id, role_id, old_status_id, new_status_id').collect {|w| [w.old_status, w.new_status_id]}
197 287 end
198 288 end
@@ -36,8 +36,8 class IssueStatusTest < ActiveSupport::TestCase
36 36 assert_difference 'IssueStatus.count', -1 do
37 37 assert status.destroy
38 38 end
39 assert_nil Workflow.first(:conditions => {:old_status_id => status.id})
40 assert_nil Workflow.first(:conditions => {:new_status_id => status.id})
39 assert_nil WorkflowTransition.first(:conditions => {:old_status_id => status.id})
40 assert_nil WorkflowTransition.first(:conditions => {:new_status_id => status.id})
41 41 end
42 42
43 43 def test_destroy_status_in_use
@@ -70,12 +70,12 class IssueStatusTest < ActiveSupport::TestCase
70 70 end
71 71
72 72 def test_new_statuses_allowed_to
73 Workflow.delete_all
73 WorkflowTransition.delete_all
74 74
75 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2, :author => false, :assignee => false)
76 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3, :author => true, :assignee => false)
77 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4, :author => false, :assignee => true)
78 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5, :author => true, :assignee => true)
75 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2, :author => false, :assignee => false)
76 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3, :author => true, :assignee => false)
77 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4, :author => false, :assignee => true)
78 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5, :author => true, :assignee => true)
79 79 status = IssueStatus.find(1)
80 80 role = Role.find(1)
81 81 tracker = Tracker.find(1)
@@ -31,6 +31,10 class IssueTest < ActiveSupport::TestCase
31 31
32 32 include Redmine::I18n
33 33
34 def teardown
35 User.current = nil
36 end
37
34 38 def test_create
35 39 issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3,
36 40 :status_id => 1, :priority => IssuePriority.all.first,
@@ -362,12 +366,12 class IssueTest < ActiveSupport::TestCase
362 366 end
363 367
364 368 def test_new_statuses_allowed_to
365 Workflow.delete_all
369 WorkflowTransition.delete_all
366 370
367 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2, :author => false, :assignee => false)
368 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3, :author => true, :assignee => false)
369 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4, :author => false, :assignee => true)
370 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5, :author => true, :assignee => true)
371 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2, :author => false, :assignee => false)
372 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 3, :author => true, :assignee => false)
373 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 4, :author => false, :assignee => true)
374 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5, :author => true, :assignee => true)
371 375 status = IssueStatus.find(1)
372 376 role = Role.find(1)
373 377 tracker = Tracker.find(1)
@@ -390,7 +394,7 class IssueTest < ActiveSupport::TestCase
390 394 admin = User.find(1)
391 395 issue = Issue.find(1)
392 396 assert !admin.member_of?(issue.project)
393 expected_statuses = [issue.status] + Workflow.find_all_by_old_status_id(issue.status_id).map(&:new_status).uniq.sort
397 expected_statuses = [issue.status] + WorkflowTransition.find_all_by_old_status_id(issue.status_id).map(&:new_status).uniq.sort
394 398
395 399 assert_equal expected_statuses, issue.new_statuses_allowed_to(admin)
396 400 end
@@ -403,7 +407,7 class IssueTest < ActiveSupport::TestCase
403 407 assert_equal [1, 2], issue.new_statuses_allowed_to(User.find(2)).map(&:id)
404 408 end
405 409
406 def test_safe_attributes_should_not_include_disabled_field
410 def test_safe_attributes_names_should_not_include_disabled_field
407 411 tracker = Tracker.new(:core_fields => %w(assigned_to_id fixed_version_id))
408 412
409 413 issue = Issue.new(:tracker => tracker)
@@ -435,7 +439,7 class IssueTest < ActiveSupport::TestCase
435 439 assert_equal Date.parse('2012-07-14'), issue.due_date
436 440 end
437 441
438 def test_safe_attributes_should_accept_target_tracker_fields
442 def test_safe_attributes_should_accept_target_tracker_enabled_fields
439 443 source = Tracker.find(1)
440 444 source.core_fields = []
441 445 source.save!
@@ -449,6 +453,165 class IssueTest < ActiveSupport::TestCase
449 453 assert_equal Date.parse('2012-07-14'), issue.due_date
450 454 end
451 455
456 def test_safe_attributes_should_not_include_readonly_fields
457 WorkflowPermission.delete_all
458 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
459 user = User.find(2)
460
461 issue = Issue.new(:project_id => 1, :tracker_id => 1)
462 assert_equal %w(due_date), issue.read_only_attribute_names(user)
463 assert_not_include 'due_date', issue.safe_attribute_names(user)
464
465 issue.send :safe_attributes=, {'start_date' => '2012-07-14', 'due_date' => '2012-07-14'}, user
466 assert_equal Date.parse('2012-07-14'), issue.start_date
467 assert_nil issue.due_date
468 end
469
470 def test_safe_attributes_should_not_include_readonly_custom_fields
471 cf1 = IssueCustomField.create!(:name => 'Writable field', :field_format => 'string', :is_for_all => true, :tracker_ids => [1])
472 cf2 = IssueCustomField.create!(:name => 'Readonly field', :field_format => 'string', :is_for_all => true, :tracker_ids => [1])
473
474 WorkflowPermission.delete_all
475 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
476 user = User.find(2)
477
478 issue = Issue.new(:project_id => 1, :tracker_id => 1)
479 assert_equal [cf2.id.to_s], issue.read_only_attribute_names(user)
480 assert_not_include cf2.id.to_s, issue.safe_attribute_names(user)
481
482 issue.send :safe_attributes=, {'custom_field_values' => {cf1.id.to_s => 'value1', cf2.id.to_s => 'value2'}}, user
483 assert_equal 'value1', issue.custom_field_value(cf1)
484 assert_nil issue.custom_field_value(cf2)
485
486 issue.send :safe_attributes=, {'custom_fields' => [{'id' => cf1.id.to_s, 'value' => 'valuea'}, {'id' => cf2.id.to_s, 'value' => 'valueb'}]}, user
487 assert_equal 'valuea', issue.custom_field_value(cf1)
488 assert_nil issue.custom_field_value(cf2)
489 end
490
491 def test_editable_custom_field_values_should_return_non_readonly_custom_values
492 cf1 = IssueCustomField.create!(:name => 'Writable field', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
493 cf2 = IssueCustomField.create!(:name => 'Readonly field', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
494
495 WorkflowPermission.delete_all
496 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf2.id.to_s, :rule => 'readonly')
497 user = User.find(2)
498
499 issue = Issue.new(:project_id => 1, :tracker_id => 1)
500 values = issue.editable_custom_field_values(user)
501 assert values.detect {|value| value.custom_field == cf1}
502 assert_nil values.detect {|value| value.custom_field == cf2}
503
504 issue.tracker_id = 2
505 values = issue.editable_custom_field_values(user)
506 assert values.detect {|value| value.custom_field == cf1}
507 assert values.detect {|value| value.custom_field == cf2}
508 end
509
510 def test_safe_attributes_should_accept_target_tracker_writable_fields
511 WorkflowPermission.delete_all
512 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
513 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'start_date', :rule => 'readonly')
514 user = User.find(2)
515
516 issue = Issue.new(:project_id => 1, :tracker_id => 1, :status_id => 1)
517
518 issue.send :safe_attributes=, {'start_date' => '2012-07-12', 'due_date' => '2012-07-14'}, user
519 assert_equal Date.parse('2012-07-12'), issue.start_date
520 assert_nil issue.due_date
521
522 issue.send :safe_attributes=, {'start_date' => '2012-07-15', 'due_date' => '2012-07-16', 'tracker_id' => 2}, user
523 assert_equal Date.parse('2012-07-12'), issue.start_date
524 assert_equal Date.parse('2012-07-16'), issue.due_date
525 end
526
527 def test_safe_attributes_should_accept_target_status_writable_fields
528 WorkflowPermission.delete_all
529 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
530 WorkflowPermission.create!(:old_status_id => 2, :tracker_id => 1, :role_id => 1, :field_name => 'start_date', :rule => 'readonly')
531 user = User.find(2)
532
533 issue = Issue.new(:project_id => 1, :tracker_id => 1, :status_id => 1)
534
535 issue.send :safe_attributes=, {'start_date' => '2012-07-12', 'due_date' => '2012-07-14'}, user
536 assert_equal Date.parse('2012-07-12'), issue.start_date
537 assert_nil issue.due_date
538
539 issue.send :safe_attributes=, {'start_date' => '2012-07-15', 'due_date' => '2012-07-16', 'status_id' => 2}, user
540 assert_equal Date.parse('2012-07-12'), issue.start_date
541 assert_equal Date.parse('2012-07-16'), issue.due_date
542 end
543
544 def test_required_attributes_should_be_validated
545 cf = IssueCustomField.create!(:name => 'Foo', :field_format => 'string', :is_for_all => true, :tracker_ids => [1, 2])
546
547 WorkflowPermission.delete_all
548 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'required')
549 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'category_id', :rule => 'required')
550 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => cf.id.to_s, :rule => 'required')
551
552 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => 'start_date', :rule => 'required')
553 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 2, :role_id => 1, :field_name => cf.id.to_s, :rule => 'required')
554 user = User.find(2)
555
556 issue = Issue.new(:project_id => 1, :tracker_id => 1, :status_id => 1, :subject => 'Required fields', :author => user)
557 assert_equal [cf.id.to_s, "category_id", "due_date"], issue.required_attribute_names(user).sort
558 assert !issue.save, "Issue was saved"
559 assert_equal ["Category can't be blank", "Due date can't be blank", "Foo can't be blank"], issue.errors.full_messages.sort
560
561 issue.tracker_id = 2
562 assert_equal [cf.id.to_s, "start_date"], issue.required_attribute_names(user).sort
563 assert !issue.save, "Issue was saved"
564 assert_equal ["Foo can't be blank", "Start date can't be blank"], issue.errors.full_messages.sort
565
566 issue.start_date = Date.today
567 issue.custom_field_values = {cf.id.to_s => 'bar'}
568 assert issue.save
569 end
570
571 def test_required_attribute_names_for_multiple_roles_should_intersect_rules
572 WorkflowPermission.delete_all
573 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'required')
574 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'start_date', :rule => 'required')
575 user = User.find(2)
576 member = Member.find(1)
577 issue = Issue.new(:project_id => 1, :tracker_id => 1, :status_id => 1)
578
579 assert_equal %w(due_date start_date), issue.required_attribute_names(user).sort
580
581 member.role_ids = [1, 2]
582 member.save!
583 assert_equal [], issue.required_attribute_names(user.reload)
584
585 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 2, :field_name => 'due_date', :rule => 'required')
586 assert_equal %w(due_date), issue.required_attribute_names(user)
587
588 member.role_ids = [1, 2, 3]
589 member.save!
590 assert_equal [], issue.required_attribute_names(user.reload)
591
592 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 2, :field_name => 'due_date', :rule => 'readonly')
593 # required + readonly => required
594 assert_equal %w(due_date), issue.required_attribute_names(user)
595 end
596
597 def test_read_only_attribute_names_for_multiple_roles_should_intersect_rules
598 WorkflowPermission.delete_all
599 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'due_date', :rule => 'readonly')
600 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 1, :field_name => 'start_date', :rule => 'readonly')
601 user = User.find(2)
602 member = Member.find(1)
603 issue = Issue.new(:project_id => 1, :tracker_id => 1, :status_id => 1)
604
605 assert_equal %w(due_date start_date), issue.read_only_attribute_names(user).sort
606
607 member.role_ids = [1, 2]
608 member.save!
609 assert_equal [], issue.read_only_attribute_names(user.reload)
610
611 WorkflowPermission.create!(:old_status_id => 1, :tracker_id => 1, :role_id => 2, :field_name => 'due_date', :rule => 'readonly')
612 assert_equal %w(due_date), issue.read_only_attribute_names(user)
613 end
614
452 615 def test_copy
453 616 issue = Issue.new.copy_from(1)
454 617 assert issue.copy?
@@ -35,13 +35,13 class RoleTest < ActiveSupport::TestCase
35 35
36 36 def test_copy_workflows
37 37 source = Role.find(1)
38 assert_equal 90, source.workflows.size
38 assert_equal 90, source.workflow_rules.size
39 39
40 40 target = Role.new(:name => 'Target')
41 41 assert target.save
42 target.workflows.copy(source)
42 target.workflow_rules.copy(source)
43 43 target.reload
44 assert_equal 90, target.workflows.size
44 assert_equal 90, target.workflow_rules.size
45 45 end
46 46
47 47 def test_permissions_should_be_unserialized_with_its_coder
@@ -30,20 +30,20 class TrackerTest < ActiveSupport::TestCase
30 30
31 31 def test_copy_workflows
32 32 source = Tracker.find(1)
33 assert_equal 89, source.workflows.size
33 assert_equal 89, source.workflow_rules.size
34 34
35 35 target = Tracker.new(:name => 'Target')
36 36 assert target.save
37 target.workflows.copy(source)
37 target.workflow_rules.copy(source)
38 38 target.reload
39 assert_equal 89, target.workflows.size
39 assert_equal 89, target.workflow_rules.size
40 40 end
41 41
42 42 def test_issue_statuses
43 43 tracker = Tracker.find(1)
44 Workflow.delete_all
45 Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 2, :new_status_id => 3)
46 Workflow.create!(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 5)
44 WorkflowTransition.delete_all
45 WorkflowTransition.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 2, :new_status_id => 3)
46 WorkflowTransition.create!(:role_id => 2, :tracker_id => 1, :old_status_id => 3, :new_status_id => 5)
47 47
48 48 assert_kind_of Array, tracker.issue_statuses
49 49 assert_kind_of IssueStatus, tracker.issue_statuses.first
@@ -51,7 +51,7 class TrackerTest < ActiveSupport::TestCase
51 51 end
52 52
53 53 def test_issue_statuses_empty
54 Workflow.delete_all("tracker_id = 1")
54 WorkflowTransition.delete_all("tracker_id = 1")
55 55 assert_equal [], Tracker.find(1).issue_statuses
56 56 end
57 57
@@ -21,17 +21,45 class WorkflowTest < ActiveSupport::TestCase
21 21 fixtures :roles, :trackers, :issue_statuses
22 22
23 23 def test_copy
24 Workflow.delete_all
25 Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 1, :new_status_id => 2)
26 Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 1, :new_status_id => 3, :assignee => true)
27 Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 1, :new_status_id => 4, :author => true)
24 WorkflowTransition.delete_all
25 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 1, :new_status_id => 2)
26 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 1, :new_status_id => 3, :assignee => true)
27 WorkflowTransition.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 1, :new_status_id => 4, :author => true)
28 28
29 assert_difference 'Workflow.count', 3 do
30 Workflow.copy(Tracker.find(2), Role.find(1), Tracker.find(3), Role.find(2))
29 assert_difference 'WorkflowTransition.count', 3 do
30 WorkflowTransition.copy(Tracker.find(2), Role.find(1), Tracker.find(3), Role.find(2))
31 31 end
32 32
33 assert Workflow.first(:conditions => {:role_id => 2, :tracker_id => 3, :old_status_id => 1, :new_status_id => 2, :author => false, :assignee => false})
34 assert Workflow.first(:conditions => {:role_id => 2, :tracker_id => 3, :old_status_id => 1, :new_status_id => 3, :author => false, :assignee => true})
35 assert Workflow.first(:conditions => {:role_id => 2, :tracker_id => 3, :old_status_id => 1, :new_status_id => 4, :author => true, :assignee => false})
33 assert WorkflowTransition.first(:conditions => {:role_id => 2, :tracker_id => 3, :old_status_id => 1, :new_status_id => 2, :author => false, :assignee => false})
34 assert WorkflowTransition.first(:conditions => {:role_id => 2, :tracker_id => 3, :old_status_id => 1, :new_status_id => 3, :author => false, :assignee => true})
35 assert WorkflowTransition.first(:conditions => {:role_id => 2, :tracker_id => 3, :old_status_id => 1, :new_status_id => 4, :author => true, :assignee => false})
36 end
37
38 def test_workflow_permission_should_validate_rule
39 wp = WorkflowPermission.new(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :field_name => 'due_date')
40 assert !wp.save
41
42 wp.rule = 'foo'
43 assert !wp.save
44
45 wp.rule = 'required'
46 assert wp.save
47
48 wp.rule = 'readonly'
49 assert wp.save
50 end
51
52 def test_workflow_permission_should_validate_field_name
53 wp = WorkflowPermission.new(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :rule => 'required')
54 assert !wp.save
55
56 wp.field_name = 'foo'
57 assert !wp.save
58
59 wp.field_name = 'due_date'
60 assert wp.save
61
62 wp.field_name = '1'
63 assert wp.save
36 64 end
37 65 end
General Comments 0
You need to be logged in to leave comments. Login now