diff --git a/app/models/dmsf_file_revision.rb b/app/models/dmsf_file_revision.rb index bae02049..8f7e12fb 100644 --- a/app/models/dmsf_file_revision.rb +++ b/app/models/dmsf_file_revision.rb @@ -167,12 +167,12 @@ class DmsfFileRevision < ActiveRecord::Base str + l(:title_waiting_for_approval) when DmsfWorkflow::STATE_APPROVED str + l(:title_approved) - when DmsfWorkflow::STATE_DRAFT - str + l(:title_draft) + when DmsfWorkflow::STATE_ASSIGNED + str + l(:title_assigned) when DmsfWorkflow::STATE_REJECTED str + l(:title_rejected) else - str + str + l(:title_none) end end @@ -183,7 +183,7 @@ class DmsfFileRevision < ActiveRecord::Base self.dmsf_workflow_started_by = User.current.id if User.current self.dmsf_workflow_started_at = DateTime.now else - self.workflow = DmsfWorkflow::STATE_DRAFT + self.workflow = DmsfWorkflow::STATE_ASSIGNED self.dmsf_workflow_assigned_by = User.current.id if User.current self.dmsf_workflow_assigned_at = DateTime.now end diff --git a/app/models/dmsf_workflow.rb b/app/models/dmsf_workflow.rb index 875d37be..0efcea00 100644 --- a/app/models/dmsf_workflow.rb +++ b/app/models/dmsf_workflow.rb @@ -24,7 +24,7 @@ class DmsfWorkflow < ActiveRecord::Base validates_length_of :name, :maximum => 255 STATE_NONE = nil - STATE_DRAFT = 3 + STATE_ASSIGNED = 3 STATE_WAITING_FOR_APPROVAL = 1 STATE_APPROVED = 2 STATE_REJECTED = 4 diff --git a/app/models/dmsf_workflow_step_action.rb b/app/models/dmsf_workflow_step_action.rb index 2e5f49aa..ce653771 100644 --- a/app/models/dmsf_workflow_step_action.rb +++ b/app/models/dmsf_workflow_step_action.rb @@ -24,6 +24,7 @@ class DmsfWorkflowStepAction < ActiveRecord::Base validates :action, :presence => true validates :note, :presence => true, :unless => lambda { self.action == DmsfWorkflowStepAction::ACTION_APPROVE } validates :author_id, :presence => true + validates_uniqueness_of :dmsf_workflow_step_assignment_id, :scope => [:action], :unless => lambda {self.action == DmsfWorkflowStepAction::ACTION_DELEGATE} ACTION_APPROVE = 1 ACTION_REJECT = 2 @@ -49,15 +50,30 @@ class DmsfWorkflowStepAction < ActiveRecord::Base if action case action.to_i when ACTION_APPROVE - l(:title_approved) + l(:title_approval) when ACTION_REJECT - l(:title_rejected) + l(:title_rejection) when ACTION_DELEGATE - l(:title_delegated) + l(:title_delegation) + when ACTION_ASSIGN + l(:title_assignment) + when ACTION_START + l(:title_start) + end + end + end + + def self.workflow_str(action) + if action + case action.to_i + when ACTION_REJECT + l(:title_rejected) when ACTION_ASSIGN l(:title_assigned) - when ACTION_START - l(:title_started) + when ACTION_START, ACTION_DELEGATE, ACTION_APPROVE + l(:title_waiting_for_approval) + else + l(:title_none) end end end diff --git a/app/models/dmsf_workflow_step_assignment.rb b/app/models/dmsf_workflow_step_assignment.rb index 32c4e370..1a86ed6c 100644 --- a/app/models/dmsf_workflow_step_assignment.rb +++ b/app/models/dmsf_workflow_step_assignment.rb @@ -23,6 +23,7 @@ class DmsfWorkflowStepAssignment < ActiveRecord::Base validates :dmsf_workflow_step_id, :presence => true validates :dmsf_file_revision_id, :presence => true + validates_uniqueness_of :dmsf_workflow_step_id, :scope => [:dmsf_file_revision_id] def step DmsfWorkflowStep.find_by_id self.dmsf_workflow_step_id diff --git a/app/views/dmsf/show.html.erb b/app/views/dmsf/show.html.erb index bc022dca..11fb1dd0 100644 --- a/app/views/dmsf/show.html.erb +++ b/app/views/dmsf/show.html.erb @@ -185,6 +185,8 @@ :dmsf_file_revision_id => file.last_revision.id), :title => DmsfWorkflow.assignments_to_users_str(wf.next_assignments(file.last_revision.id)), :remote => true) %> + <% else %> + <%= file.last_revision.workflow_str(false) %> <% end %> <%= h(file.last_revision.user) %> @@ -221,15 +223,15 @@ <% end %> <% when DmsfWorkflow::STATE_APPROVED %> <%= image_tag('approved.png', :title => l(:title_approved), :plugin => :redmine_dmsf) %> - <% when DmsfWorkflow::STATE_DRAFT %> + <% when DmsfWorkflow::STATE_ASSIGNED %> <% if User.current && (file.last_revision.dmsf_workflow_assigned_by == User.current.id) %> - <%= link_to_function(image_tag('draft.png', :plugin => :redmine_dmsf), + <%= link_to_function(image_tag('assigned.png', :plugin => :redmine_dmsf), "manipulation_link('#{start_dmsf_workflow_path( :id => file.last_revision.dmsf_workflow_id, :dmsf_file_revision_id => file.last_revision.id)}')", :title => l(:label_dmsf_wokflow_action_start)) %> <% else %> - <%= image_tag('draft.png', :title => l(:label_dmsf_wokflow_action_start), :plugin => :redmine_dmsf) %> + <%= image_tag('assigned.png', :title => l(:label_dmsf_wokflow_action_start), :plugin => :redmine_dmsf) %> <% end %> <% when DmsfWorkflow::STATE_REJECTED %> <%= image_tag('rejected.png', :title => l(:title_rejected), :plugin => :redmine_dmsf) %> @@ -325,15 +327,15 @@ sUrl = "jquery.dataTables/#{I18n.locale.to_s.downcase}.json" if I18n.locale && ! "oLanguage": { 'sUrl': '<%= plugin_asset_path(:redmine_dmsf, 'javascripts', sUrl) %>' }, - "bAutoWidth": false, - "bPaginate": false, - "aaSorting": [[1,'asc']], - "aaSortingFixed": [[7,'asc']], - "aoColumnDefs": [ - { "bSearchable": false, "aTargets": [0, 7, 8, 9] }, - { "bSortable": false, "aTargets": [0, 7, 8] }, - { "iDataSort": 9, "aTargets": [ 2 ] } - ], + "bAutoWidth": false, + "bPaginate": false, + "aaSorting": [[1,'asc']], + "aaSortingFixed": [[8,'asc']], + "aoColumnDefs": [ + { "bSearchable": false, "aTargets": [0, 7, 8, 9] }, + { "bSortable": false, "aTargets": [0, 7, 8] }, + { "iDataSort": 9, "aTargets": [ 2 ] } + ], "fnInitComplete": function() { jQuery("div.controls").prependTo(jQuery("#browser_wrapper div.fg-toolbar")[0]); }, diff --git a/app/views/dmsf_workflows/_log.html.erb b/app/views/dmsf_workflows/_log.html.erb index eb649cdc..9b9f48c7 100644 --- a/app/views/dmsf_workflows/_log.html.erb +++ b/app/views/dmsf_workflows/_log.html.erb @@ -5,7 +5,7 @@ <% if revision %>
- <%= label_tag 'workflow_name', "#{l(:field_name)}: " %> + <%= label_tag 'workflow_name', "#{l(:link_workflow)} #{l(:field_name).downcase}: " %> <%= link_to @workflow.name, edit_dmsf_workflow_path(@workflow) %>
@@ -19,35 +19,55 @@ <%= l(:label_dmsf_workflow_step) %> <%= l(:label_user) %> <%= l(:label_action) %> + <%= l(:label_workflow) %> <%= l(:label_note) %> - <%=l(:label_date)%> + <%= l(:label_date)%> - - - - <%= link_to_user User.find_by_id(revision.dmsf_workflow_assigned_by) if revision.dmsf_workflow_assigned_by %> - <%= DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_ASSIGN) %> + + + + + + <%= DmsfWorkflowStepAction.workflow_str(0) %> - <%= format_time(revision.dmsf_workflow_assigned_at) if revision.dmsf_workflow_assigned_at %> - - - - <%= link_to_user User.find_by_id(revision.dmsf_workflow_started_by) if revision.dmsf_workflow_started_by %> - <%= DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_START) %> - - <%= format_time(revision.dmsf_workflow_started_at) if revision.dmsf_workflow_started_at %> + - <% sql = "SELECT c.action, c.note, c.created_at, c.author_id, a.user_id, s.step FROM dmsf_workflow_step_actions c RIGHT JOIN dmsf_workflow_step_assignments a ON a.id = c.dmsf_workflow_step_assignment_id JOIN dmsf_workflow_steps s ON s.id = a.dmsf_workflow_step_id WHERE a.dmsf_file_revision_id = #{revision.id} ORDER BY s.step, c.created_at" %> - <% result = DmsfWorkflowStep.connection.execute sql %> + + + <%= link_to_user User.find_by_id(revision.dmsf_workflow_assigned_by) if revision.dmsf_workflow_assigned_by %> + <%= DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_ASSIGN) %> + <%= DmsfWorkflowStepAction.workflow_str(DmsfWorkflowStepAction::ACTION_ASSIGN) %> + + <%= format_time(revision.dmsf_workflow_assigned_at) if revision.dmsf_workflow_assigned_at %> + + + + <%= link_to_user User.find_by_id(revision.dmsf_workflow_started_by) if revision.dmsf_workflow_started_by %> + <%= DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_START) %> + <%= DmsfWorkflowStepAction.workflow_str(DmsfWorkflowStepAction::ACTION_START) if revision.dmsf_workflow_started_by %> + + <%= format_time(revision.dmsf_workflow_started_at) if revision.dmsf_workflow_started_at %> + + <% sql = "SELECT c.action, c.note, c.created_at, c.author_id, a.user_id, s.step FROM dmsf_workflow_step_actions c RIGHT JOIN dmsf_workflow_step_assignments a ON a.id = c.dmsf_workflow_step_assignment_id RIGHT JOIN dmsf_workflow_steps s ON s.id = a.dmsf_workflow_step_id WHERE a.dmsf_file_revision_id = #{revision.id} ORDER BY s.step, c.action DESC, c.created_at" %> + <% result = DmsfWorkflowStep.connection.execute sql %> <% result.each_with_index do |row, i| %> - + <%= row[5] %> - <%= link_to_user User.find_by_id(row[3].present? ? row[3] : row[4]) %> - <%= DmsfWorkflowStepAction.action_str(row[0]) %> + <%= link_to_user User.find_by_id(row[3].present? ? row[3] : row[4]) %> + <%= DmsfWorkflowStepAction.action_str(row[0]) %> + + <% s = @workflow.dmsf_workflow_steps.last.step %> + <% s1 = row[5] %> + <% if((row[5].to_i == @workflow.dmsf_workflow_steps.last.step) && (revision.workflow == DmsfWorkflow::STATE_APPROVED)) %> + <%= l(:title_approved) %> + <% else %> + <%= DmsfWorkflowStepAction.workflow_str(row[0]) %> + <% end %> + <%= row[1] %> - <%= format_time(row[2]) if row[2].present? %> + <%= format_time(row[2]) if row[2].present? %> - <% end; reset_cycle %> + <% end %>
diff --git a/app/views/dmsf_workflows/log.js.erb b/app/views/dmsf_workflows/log.js.erb index de409eaa..9034c98b 100644 --- a/app/views/dmsf_workflows/log.js.erb +++ b/app/views/dmsf_workflows/log.js.erb @@ -1,3 +1,3 @@ $('#ajax-modal').html('<%= escape_javascript(render :partial => 'log', :locals => {:workflow => @workflow}) %>'); -showModal('ajax-modal', '640px'); +showModal('ajax-modal', '800px'); $('#ajax-modal').addClass('workflow-log'); \ No newline at end of file diff --git a/assets/images/draft.png b/assets/images/assigned.png similarity index 100% rename from assets/images/draft.png rename to assets/images/assigned.png diff --git a/assets/stylesheets/dmsf.css b/assets/stylesheets/dmsf.css index 6b647302..d827fb57 100644 --- a/assets/stylesheets/dmsf.css +++ b/assets/stylesheets/dmsf.css @@ -256,12 +256,12 @@ div.revision_box .ui-widget-header { font-weight: normal; } -table.list td.note { - width: 30%; +table.list th { + text-align: left; } -table.list td.date { - text-align: center; +table.list td.note { + width: 20%; } table.list td.reorder { diff --git a/config/locales/en.yml b/config/locales/en.yml index f345e9b1..fd1423ad 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -213,7 +213,7 @@ en: error_cannot_start_workflow: "Workflow can't be started" error_cannot_renumber_steps: "Steps can't be renumbered" label_dmsf_workflow_new: 'New approval workflow' - label_dmsf_workflow: 'Approval workflow' + label_dmsf_workflow: 'Approval Workflow' label_dmsf_workflow_plural: 'Approval workflows' label_dmsf_workflow_step: Step label_dmsf_workflow_step_plural: Steps @@ -227,12 +227,15 @@ en: label_dmsf_wokflow_action_start: 'Start workflow' label_action: Action label_note: Note - title_draft: Draft - title_rejected: Rejected - title_delegated: Delegated + title_none: None + title_rejection: Rejection + title_delegation: Delegation + title_assignment: Assignment + title_start: Start + title_dmsf_workflow_log: 'Approval Workflow Log' title_assigned: Assigned - title_started: Started - title_dmsf_workflow_log: 'Approval workflow log' + title_approval: Approval + title_rejected: Rejected dmsf_and: AND dmsf_or: OR dmsf_new_step: New step diff --git a/db/migrate/20120822100402_create_dmsf_workflow_steps.rb b/db/migrate/20120822100402_create_dmsf_workflow_steps.rb index 8d8b3c3a..9ae922e1 100644 --- a/db/migrate/20120822100402_create_dmsf_workflow_steps.rb +++ b/db/migrate/20120822100402_create_dmsf_workflow_steps.rb @@ -25,6 +25,11 @@ class CreateDmsfWorkflowSteps < ActiveRecord::Migration t.integer :operator, :null => false end add_index :dmsf_workflow_steps, :dmsf_workflow_id + add_index :dmsf_workflow_steps, + [:user_id, :dmsf_workflow_id, :step], + # The default index name exceeds the index name limit + :name => 'index_dmsf_wrkfl_steps_on_usr_id_and_dmsf_wrkfl_id_and_step', + :unique => true end def self.down diff --git a/db/migrate/20120822100403_create_dmsf_workflow_step_assignments.rb b/db/migrate/20120822100403_create_dmsf_workflow_step_assignments.rb index aff1e31f..c0f4bd06 100644 --- a/db/migrate/20120822100403_create_dmsf_workflow_step_assignments.rb +++ b/db/migrate/20120822100403_create_dmsf_workflow_step_assignments.rb @@ -26,7 +26,8 @@ class CreateDmsfWorkflowStepAssignments < ActiveRecord::Migration add_index :dmsf_workflow_step_assignments, [:dmsf_workflow_step_id, :dmsf_file_revision_id], # The default index name exceeds the index name limit - {:name => 'index_dmsf_wrkfl_step_assigns_on_wrkfl_step_id_and_frev_id'} + :name => 'index_dmsf_wrkfl_step_assigns_on_wrkfl_step_id_and_frev_id', + :unique => true end def self.down diff --git a/test/fixtures/dmsf_workflow_step_assignments.yml b/test/fixtures/dmsf_workflow_step_assignments.yml index 9db487ac..a231c65c 100644 --- a/test/fixtures/dmsf_workflow_step_assignments.yml +++ b/test/fixtures/dmsf_workflow_step_assignments.yml @@ -7,7 +7,7 @@ wfsa1: wfsa2: id: 2 - dmsf_workflow_step_id: 1 + dmsf_workflow_step_id: 4 user_id: 2 dmsf_file_revision_id: 2 @@ -19,7 +19,7 @@ wfsa3: wfsa4: id: 4 - dmsf_workflow_step_id: 2 + dmsf_workflow_step_id: 3 user_id: 2 dmsf_file_revision_id: 2 @@ -31,7 +31,7 @@ wfsa5: wfsa6: id: 6 - dmsf_workflow_step_id: 1 + dmsf_workflow_step_id: 4 user_id: 2 dmsf_file_revision_id: 1 @@ -43,6 +43,6 @@ wfsa7: wfsa8: id: 8 - dmsf_workflow_step_id: 2 + dmsf_workflow_step_id: 3 user_id: 2 dmsf_file_revision_id: 1 \ No newline at end of file diff --git a/test/unit/dmsf_workflow_step_action_test.rb b/test/unit/dmsf_workflow_step_action_test.rb index 9a299f3b..089ebe5a 100644 --- a/test/unit/dmsf_workflow_step_action_test.rb +++ b/test/unit/dmsf_workflow_step_action_test.rb @@ -21,8 +21,8 @@ class DmsfWorkflowStepActionTest < RedmineDmsf::Test::UnitTest def test_create wfsac = DmsfWorkflowStepAction.new( :dmsf_workflow_step_assignment_id => 1, - :action => 1, - :note => 'Approvement') + :action => DmsfWorkflowStepAction::ACTION_DELEGATE, + :note => 'Approval') assert wfsac.save wfsac.reload assert wfsac.created_at @@ -30,14 +30,14 @@ class DmsfWorkflowStepActionTest < RedmineDmsf::Test::UnitTest def test_update @wfsac1.dmsf_workflow_step_assignment_id = 2 - @wfsac1.action = 2 + @wfsac1.action = DmsfWorkflowStepAction::ACTION_REJECT @wfsac1.note = 'Rejection' assert @wfsac1.save @wfsac1.reload assert_equal 2, @wfsac1.dmsf_workflow_step_assignment_id - assert_equal 2, @wfsac1.action + assert_equal DmsfWorkflowStepAction::ACTION_REJECT, @wfsac1.action assert_equal 'Rejection', @wfsac1.note end @@ -77,6 +77,22 @@ class DmsfWorkflowStepActionTest < RedmineDmsf::Test::UnitTest assert_equal 1, @wfsac1.errors.count end + def test_validate_dmsf_workflow_step_assignment_id_uniqueness + @wfsac2.dmsf_workflow_step_assignment_id = @wfsac1.dmsf_workflow_step_assignment_id; + @wfsac2.action = @wfsac1.action; + assert !@wfsac2.save + assert_equal 1, @wfsac2.errors.count + @wfsac1.action = DmsfWorkflowStepAction::ACTION_REJECT + @wfsac2.action = @wfsac1.action; + assert @wfsac1.save + assert !@wfsac2.save + assert_equal 1, @wfsac2.errors.count + @wfsac1.action = DmsfWorkflowStepAction::ACTION_DELEGATE + assert @wfsac1.save + @wfsac2.action = @wfsac1.action; + assert @wfsac2.save + end + def test_destroy @wfsac1.destroy assert_nil DmsfWorkflowStepAction.find_by_id(1) @@ -92,10 +108,10 @@ class DmsfWorkflowStepActionTest < RedmineDmsf::Test::UnitTest end def test_action_str - assert_equal DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_APPROVE), l(:title_approved) - assert_equal DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_REJECT), l(:title_rejected) - assert_equal DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_DELEGATE), l(:title_delegated) - assert_equal DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_ASSIGN), l(:title_assigned) - assert_equal DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_START), l(:title_started) + assert_equal DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_APPROVE), l(:title_approval) + assert_equal DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_REJECT), l(:title_rejection) + assert_equal DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_DELEGATE), l(:title_delegation) + assert_equal DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_ASSIGN), l(:title_assignment) + assert_equal DmsfWorkflowStepAction.action_str(DmsfWorkflowStepAction::ACTION_START), l(:title_start) end end diff --git a/test/unit/dmsf_workflow_step_assignment_test.rb b/test/unit/dmsf_workflow_step_assignment_test.rb index b5f097e1..e95e4ec4 100644 --- a/test/unit/dmsf_workflow_step_assignment_test.rb +++ b/test/unit/dmsf_workflow_step_assignment_test.rb @@ -6,6 +6,7 @@ class WorkflowStepAssignmentTest < RedmineDmsf::Test::UnitTest def setup @wfsa1 = DmsfWorkflowStepAssignment.find(1) + @wfsa2 = DmsfWorkflowStepAssignment.find(2) end def test_truth @@ -21,14 +22,14 @@ class WorkflowStepAssignmentTest < RedmineDmsf::Test::UnitTest end def test_update - @wfsa1.dmsf_workflow_step_id = 2 + @wfsa1.dmsf_workflow_step_id = 5 @wfsa1.user_id = 2 @wfsa1.dmsf_file_revision_id = 2 assert @wfsa1.save @wfsa1.reload - assert_equal 2, @wfsa1.dmsf_workflow_step_id + assert_equal 5, @wfsa1.dmsf_workflow_step_id assert_equal 2, @wfsa1.user_id assert_equal 2, @wfsa1.dmsf_file_revision_id end @@ -45,6 +46,13 @@ class WorkflowStepAssignmentTest < RedmineDmsf::Test::UnitTest assert_equal 1, @wfsa1.errors.count end + def test_validate_dmsf_workflow_step_id_uniqueness + @wfsa1.dmsf_workflow_step_id = @wfsa2.dmsf_workflow_step_id + @wfsa1.dmsf_file_revision_id = @wfsa2.dmsf_file_revision_id + assert !@wfsa1.save + assert_equal 1, @wfsa1.errors.count + end + def test_destroy @wfsa1.destroy assert_nil DmsfWorkflowStepAssignment.find_by_id(1)