Approval workflows copied fron 1.5.0 devel
This commit is contained in:
parent
c2534d97c5
commit
0b40abb821
171
app/controllers/dmsf_workflows_controller.rb
Normal file
171
app/controllers/dmsf_workflows_controller.rb
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
# Redmine plugin for Document Management System "Features"
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 Karel Picman <karel.picman@kontron.com>
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class DmsfWorkflowsController < ApplicationController
|
||||||
|
unloadable
|
||||||
|
layout :workflows_layout
|
||||||
|
|
||||||
|
before_filter :find_workflow, :except => [:create, :new, :index]
|
||||||
|
before_filter :find_project
|
||||||
|
before_filter :authorize_global, :except => [:action, :new_action]
|
||||||
|
|
||||||
|
def index
|
||||||
|
if @project
|
||||||
|
@workflow_pages, @workflows = paginate DmsfWorkflow.where(:project_id => @project.id), :per_page => 25
|
||||||
|
else
|
||||||
|
@workflow_pages, @workflows = paginate DmsfWorkflow.where(:project_id => nil), :per_page => 25
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def action
|
||||||
|
end
|
||||||
|
|
||||||
|
def new_action
|
||||||
|
logger.info '>>>>>>>>>>>>>>>>>>>>>>> YES!'
|
||||||
|
end
|
||||||
|
|
||||||
|
def log
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@workflow = DmsfWorkflow.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@workflow = DmsfWorkflow.new(:name => params[:dmsf_workflow][:name], :project_id => params[:project_id])
|
||||||
|
if request.post? && @workflow.save
|
||||||
|
flash[:notice] = l(:notice_successful_create)
|
||||||
|
if @project
|
||||||
|
redirect_to settings_project_path(@project, :tab => 'dmsf')
|
||||||
|
else
|
||||||
|
redirect_to dmsf_workflows_path
|
||||||
|
end
|
||||||
|
else
|
||||||
|
render :action => 'new'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if request.put? && @workflow.update_attributes({:name => params[:dmsf_workflow][:name]})
|
||||||
|
flash[:notice] = l(:notice_successful_update)
|
||||||
|
if @project
|
||||||
|
redirect_to settings_project_path(@project, :tab => 'dmsf')
|
||||||
|
else
|
||||||
|
redirect_to dmsf_workflows_path
|
||||||
|
end
|
||||||
|
else
|
||||||
|
render :action => 'edit'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
begin
|
||||||
|
@workflow.destroy
|
||||||
|
rescue
|
||||||
|
flash[:error] = l(:error_unable_delete_dmsf_workflow)
|
||||||
|
end
|
||||||
|
if @project
|
||||||
|
redirect_to settings_project_path(@project, :tab => 'dmsf')
|
||||||
|
else
|
||||||
|
redirect_to dmsf_workflows_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def autocomplete_for_user
|
||||||
|
respond_to do |format|
|
||||||
|
format.js
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_step
|
||||||
|
if request.post?
|
||||||
|
users = User.find_all_by_id(params[:user_ids])
|
||||||
|
if params[:step] == '0'
|
||||||
|
if @workflow.steps.count > 0
|
||||||
|
step = @workflow.steps.last + 1
|
||||||
|
else
|
||||||
|
step = 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
step = params[:step].to_i
|
||||||
|
end
|
||||||
|
operator = 1 ? params[:commit] == l(:dmsf_and) : 0
|
||||||
|
users.each do |user|
|
||||||
|
@workflow.dmsf_workflow_steps << DmsfWorkflowStep.new(
|
||||||
|
:dmsf_workflow_id => @workflow.id,
|
||||||
|
:step => step,
|
||||||
|
:user_id => user.id,
|
||||||
|
:operator => operator)
|
||||||
|
end
|
||||||
|
@workflow.save
|
||||||
|
end
|
||||||
|
respond_to do |format|
|
||||||
|
format.html
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_step
|
||||||
|
if request.delete?
|
||||||
|
DmsfWorkflowStep.where(:dmsf_workflow_id => @workflow.id, :step => params[:step]).each do |ws|
|
||||||
|
@workflow.dmsf_workflow_steps.delete(ws)
|
||||||
|
end
|
||||||
|
@workflow.dmsf_workflow_steps.each do |ws|
|
||||||
|
n = ws.step.to_i
|
||||||
|
if n > params[:step].to_i
|
||||||
|
ws.step = n - 1
|
||||||
|
ws.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
respond_to do |format|
|
||||||
|
format.html
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def reorder_steps
|
||||||
|
if request.put?
|
||||||
|
@workflow.reorder_steps params[:step].to_i, params[:workflow_step][:move_to]
|
||||||
|
end
|
||||||
|
respond_to do |format|
|
||||||
|
format.html
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def find_workflow
|
||||||
|
@workflow = DmsfWorkflow.find_by_id(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_project
|
||||||
|
if @workflow
|
||||||
|
@project = @workflow.project
|
||||||
|
elsif params[:project_id].present?
|
||||||
|
@project = Project.find_by_id params[:project_id]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def workflows_layout
|
||||||
|
find_workflow
|
||||||
|
find_project
|
||||||
|
@project ? 'base' : 'admin'
|
||||||
|
end
|
||||||
|
end
|
||||||
45
app/helpers/dmsf_workflows_helper.rb
Normal file
45
app/helpers/dmsf_workflows_helper.rb
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# Redmine plugin for Document Management System "Features"
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 Karel Picman <karel.picman@kontron.com>
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
module DmsfWorkflowsHelper
|
||||||
|
|
||||||
|
def render_principals_for_new_dmsf_workflow_users(workflow)
|
||||||
|
scope = User.active.sorted.like(params[:q])
|
||||||
|
principal_count = scope.count
|
||||||
|
principal_pages = Redmine::Pagination::Paginator.new principal_count, 100, params['page']
|
||||||
|
principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).all
|
||||||
|
|
||||||
|
s = content_tag('div', principals_check_box_tags('user_ids[]', principals), :id => 'principals')
|
||||||
|
|
||||||
|
links = pagination_links_full(principal_pages, principal_count, :per_page_links => false) {|text, parameters, options|
|
||||||
|
link_to text, autocomplete_for_user_dmsf_workflow_path(workflow, parameters.merge(:q => params[:q], :format => 'js')), :remote => true
|
||||||
|
}
|
||||||
|
|
||||||
|
s + content_tag('p', links, :class => 'pagination')
|
||||||
|
end
|
||||||
|
|
||||||
|
def dmsf_workflow_steps_options_for_select(steps)
|
||||||
|
options = Array.new
|
||||||
|
options << [l(:dmsf_new_step), 0]
|
||||||
|
steps.each do |step|
|
||||||
|
options << [step.to_s, step]
|
||||||
|
end
|
||||||
|
options_for_select(options, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
110
app/models/dmsf_workflow.rb
Normal file
110
app/models/dmsf_workflow.rb
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
# Redmine plugin for Document Management System "Features"
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 Karel Picman <karel.picman@kontron.com>
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class DmsfWorkflow < ActiveRecord::Base
|
||||||
|
belongs_to :project
|
||||||
|
|
||||||
|
has_many :dmsf_workflow_steps, :dependent => :destroy
|
||||||
|
|
||||||
|
validates_uniqueness_of :name
|
||||||
|
validates :name, :presence => true
|
||||||
|
validates_length_of :name, :maximum => 255
|
||||||
|
|
||||||
|
def self.workflows(project)
|
||||||
|
project ? where(:project_id => project) : where('project_id IS NULL')
|
||||||
|
end
|
||||||
|
|
||||||
|
def project
|
||||||
|
@project = Project.find_by_id(project_id) unless @project
|
||||||
|
@project
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
name
|
||||||
|
end
|
||||||
|
|
||||||
|
def approvals(step)
|
||||||
|
wa = Array.new
|
||||||
|
dmsf_workflow_steps.each do |s|
|
||||||
|
if s.step == step
|
||||||
|
wa << s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
wa.sort_by { |obj| -obj.operator }
|
||||||
|
end
|
||||||
|
|
||||||
|
def steps
|
||||||
|
ws = Array.new
|
||||||
|
dmsf_workflow_steps.each do |s|
|
||||||
|
unless ws.include? s.step
|
||||||
|
ws << s.step
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ws.sort
|
||||||
|
end
|
||||||
|
|
||||||
|
def reorder_steps(step, move_to)
|
||||||
|
case move_to
|
||||||
|
when 'highest'
|
||||||
|
unless step == 1
|
||||||
|
dmsf_workflow_steps.each do |ws|
|
||||||
|
if ws.step < step
|
||||||
|
ws.update_attribute('step', ws.step + 1)
|
||||||
|
elsif ws.step == step
|
||||||
|
ws.update_attribute('step', 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
when 'higher'
|
||||||
|
unless step == 1
|
||||||
|
dmsf_workflow_steps.each do |ws|
|
||||||
|
if ws.step == step - 1
|
||||||
|
ws.update_attribute('step', step)
|
||||||
|
elsif ws.step == step
|
||||||
|
ws.update_attribute('step', step - 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
when 'lower'
|
||||||
|
unless step == steps.count
|
||||||
|
dmsf_workflow_steps.each do |ws|
|
||||||
|
if ws.step == step + 1
|
||||||
|
ws.update_attribute('step', step)
|
||||||
|
elsif ws.step == step
|
||||||
|
ws.update_attribute('step', step + 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
when 'lowest'
|
||||||
|
size = steps.count
|
||||||
|
unless step == size
|
||||||
|
dmsf_workflow_steps.each do |ws|
|
||||||
|
if ws.step > step
|
||||||
|
ws.update_attribute('step', ws.step - 1)
|
||||||
|
elsif ws.step == step
|
||||||
|
ws.update_attribute('step', size)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def delegates
|
||||||
|
User.all
|
||||||
|
end
|
||||||
|
end
|
||||||
37
app/models/dmsf_workflow_step.rb
Normal file
37
app/models/dmsf_workflow_step.rb
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# Redmine plugin for Document Management System "Features"
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 Karel Picman <karel.picman@kontron.com>
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class DmsfWorkflowStep < ActiveRecord::Base
|
||||||
|
belongs_to :workflow
|
||||||
|
|
||||||
|
has_many :dmsf_workflow_step_assignments, :dependent => :destroy
|
||||||
|
|
||||||
|
validates :dmsf_workflow_id, :presence => true
|
||||||
|
validates :step, :presence => true
|
||||||
|
validates :user_id, :presence => true
|
||||||
|
validates :operator, :presence => true
|
||||||
|
validates_uniqueness_of :user_id, :scope => [:dmsf_workflow_id, :step]
|
||||||
|
|
||||||
|
def soperator
|
||||||
|
operator == 1 ? l(:dmsf_and) : l(:dmsf_or)
|
||||||
|
end
|
||||||
|
|
||||||
|
def user
|
||||||
|
User.find(user_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
24
app/models/dmsf_workflow_step_action.rb
Normal file
24
app/models/dmsf_workflow_step_action.rb
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Redmine plugin for Document Management System "Features"
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 Karel Picman <karel.picman@kontron.com>
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class DmsfWorkflowStepAction < ActiveRecord::Base
|
||||||
|
belongs_to :dmsf_workflow_step_assignment
|
||||||
|
|
||||||
|
validates :dmsf_workflow_step_assignment_id, :presence => true
|
||||||
|
validates :action, :presence => true
|
||||||
|
end
|
||||||
26
app/models/dmsf_workflow_step_assignment.rb
Normal file
26
app/models/dmsf_workflow_step_assignment.rb
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Redmine plugin for Document Management System "Features"
|
||||||
|
#
|
||||||
|
# Copyright (C) 2013 Karel Picman <karel.picman@kontron.com>
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class DmsfWorkflowStepAssignment < ActiveRecord::Base
|
||||||
|
belongs_to :dmsf_workflow_step
|
||||||
|
|
||||||
|
has_many :dmsf_workflow_step_actions, :dependent => :destroy
|
||||||
|
|
||||||
|
validates :dmsf_workflow_step_id, :presence => true
|
||||||
|
validates :dmsf_file_revision_id, :presence => true
|
||||||
|
end
|
||||||
33
app/views/dmsf_workflows/_action.html.erb
Normal file
33
app/views/dmsf_workflows/_action.html.erb
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<h3 class="title"><%= l(:label_dmsf_workflow) %></h3>
|
||||||
|
|
||||||
|
<%= form_tag({:controller => 'dmsf_workflows',
|
||||||
|
:action => 'new_action',
|
||||||
|
:object_type => DmsfWorkflow,
|
||||||
|
:object_id => @workflow,
|
||||||
|
:project_id => @project},
|
||||||
|
:remote => true,
|
||||||
|
:method => :post,
|
||||||
|
:id => 'new-action-form') do %>
|
||||||
|
<p><label><%= radio_button_tag 'action', 'approve', true %> <%= l(:label_dmsf_wokflow_action_approve) %></label><br/></p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<label><%= radio_button_tag 'action', 'reject' %> <%= l(:label_dmsf_wokflow_action_reject) %></label><br/>
|
||||||
|
<%= text_area_tag :note, '', :placeholder => l(:message_dmsf_wokflow_note), :size => '38x2' %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<label><%= radio_button_tag 'action', 'delegate' %> <%= l(:label_dmsf_wokflow_action_delegate) %></label><br/>
|
||||||
|
<%= text_field_tag 'user_search', nil %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<%= javascript_tag "observeSearchfield('user_search', 'users_for_delegate', '#{ escape_javascript autocomplete_for_user_dmsf_workflow_path(@workflow) }')" %>
|
||||||
|
|
||||||
|
<div id="users_for_delegate">
|
||||||
|
<%= principals_check_box_tags 'watcher[user_ids][]', @workflow.delegates %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="buttons">
|
||||||
|
<%= submit_tag l(:button_add), :name => nil, :onclick => "hideModal(this);" %>
|
||||||
|
<%= submit_tag l(:button_cancel), :name => nil, :onclick => "hideModal(this);", :type => 'button' %>
|
||||||
|
</p>
|
||||||
|
<% end %>
|
||||||
32
app/views/dmsf_workflows/_main.html.erb
Normal file
32
app/views/dmsf_workflows/_main.html.erb
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<% @workflows = DmsfWorkflow.where(:project_id => @project.id) if @project && @workflows.nil? %>
|
||||||
|
|
||||||
|
<div class="contextual">
|
||||||
|
<% if @project %>
|
||||||
|
<%= link_to l(:label_dmsf_workflow_new), new_dmsf_workflow_path(:project_id => @project.id), :class => 'icon icon-add' %>
|
||||||
|
<% else %>
|
||||||
|
<%= link_to l(:label_dmsf_workflow_new), new_dmsf_workflow_path, :class => 'icon icon-add' %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2><%=l(:label_dmsf_workflow_plural)%></h2>
|
||||||
|
|
||||||
|
<table class="list">
|
||||||
|
<thead><tr>
|
||||||
|
<th><%=l(:field_name)%></th>
|
||||||
|
<th></th>
|
||||||
|
</tr></thead>
|
||||||
|
<tbody>
|
||||||
|
<% for workflow in @workflows %>
|
||||||
|
<tr id="workflow-<%= workflow.id %>" class="<%= cycle('odd', 'even') %>">
|
||||||
|
<td><%= link_to(h(workflow.name), edit_dmsf_workflow_path(workflow)) %></td>
|
||||||
|
<td class="buttons">
|
||||||
|
<%= delete_link dmsf_workflow_path(workflow) %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<% if @workflow_pages %>
|
||||||
|
<p class="pagination"><%= pagination_links_full @workflow_pages %></p>
|
||||||
|
<% end %>
|
||||||
81
app/views/dmsf_workflows/_steps.html.erb
Normal file
81
app/views/dmsf_workflows/_steps.html.erb
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<% if @workflow.project %>
|
||||||
|
<h2><%= link_to l(:label_dmsf_workflow_plural), settings_project_path(@project, :tab => 'dmsf') %> » <%=h @workflow %></h2>
|
||||||
|
<% else %>
|
||||||
|
<h2><%= link_to l(:label_dmsf_workflow_plural), dmsf_workflows_path %> » <%=h @workflow %></h2>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if @project %>
|
||||||
|
<div class="contextual">
|
||||||
|
<%= link_to 'Action', action_dmsf_workflow_path(:project_id => @project.id, :id => @workflow, :step => 1), :remote => true %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= labelled_form_for @workflow do |f| %>
|
||||||
|
<%= error_messages_for 'workflow' %>
|
||||||
|
<div class="box tabular">
|
||||||
|
<p><%= f.text_field :name, :required => true %><%= submit_tag l(:button_save) %></p>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="tab-content" id="tab-content-members">
|
||||||
|
|
||||||
|
<div class="splitcontentleft">
|
||||||
|
<% if @workflow.steps.any? %>
|
||||||
|
<table class="list steps">
|
||||||
|
<thead><tr>
|
||||||
|
<th><%= l(:label_dmsf_workflow_step) %></th>
|
||||||
|
<th><%= l(:label_dmsf_workflow_approval_plural) %></th>
|
||||||
|
<th><%=l(:button_sort)%></th>
|
||||||
|
<th style="width:15%"></th>
|
||||||
|
</tr></thead>
|
||||||
|
<tbody>
|
||||||
|
<% @workflow.steps.each do |step| %>
|
||||||
|
<tr id="step-<%= step %>" class="<%= cycle 'odd', 'even' %> step">
|
||||||
|
<td class="step"><%= step %></td>
|
||||||
|
<td class="approval">
|
||||||
|
<% @workflow.approvals(step).each_with_index do |approval, i| %>
|
||||||
|
<% if i != 0 %>
|
||||||
|
<b><%= approval.soperator %></b> 
|
||||||
|
<% end %>
|
||||||
|
<%= link_to_user approval.user %>
|
||||||
|
<% end %>
|
||||||
|
</td>
|
||||||
|
<td align="center" style="width:15%;">
|
||||||
|
<%= reorder_links('workflow_step', {:action => 'edit', :id => @workflow, :step => step}, :put) %>
|
||||||
|
</td>
|
||||||
|
<td class="buttons">
|
||||||
|
<%= delete_link edit_dmsf_workflow_path(@workflow, :step => step) %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% end; reset_cycle %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<% else %>
|
||||||
|
<p class="nodata"><%= l(:label_no_data) %></p>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="splitcontentright">
|
||||||
|
<%= form_for(@workflow, :url => edit_dmsf_workflow_path(@workflow),
|
||||||
|
:html => {:method => :post}) do |f| %>
|
||||||
|
<fieldset><legend><%=l(:label_user_new)%></legend>
|
||||||
|
|
||||||
|
<p><%= label_tag 'user_search', l(:label_user_search) %><%= text_field_tag 'user_search', nil %></p>
|
||||||
|
<%= javascript_tag "observeSearchfield('user_search', null, '#{ escape_javascript autocomplete_for_user_dmsf_workflow_path(@workflow) }')" %>
|
||||||
|
|
||||||
|
<div id="users">
|
||||||
|
<%= render_principals_for_new_dmsf_workflow_users(@workflow) %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= l(:label_dmsf_workflow_step) %>
|
||||||
|
<%= select_tag 'step',
|
||||||
|
dmsf_workflow_steps_options_for_select(@workflow.steps),
|
||||||
|
:id => 'selected_step', :style => "width:100px" %>
|
||||||
|
</p>
|
||||||
|
<p><%= submit_tag l(:dmsf_and) %> <%= submit_tag l(:dmsf_or) %></p>
|
||||||
|
</fieldset>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
1
app/views/dmsf_workflows/action.html.erb
Normal file
1
app/views/dmsf_workflows/action.html.erb
Normal file
@ -0,0 +1 @@
|
|||||||
|
<h2>WorkflowController#action</h2>
|
||||||
3
app/views/dmsf_workflows/action.js.erb
Normal file
3
app/views/dmsf_workflows/action.js.erb
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
$('#ajax-modal').html('<%= escape_javascript(render :partial => 'action', :locals => {:workflow => @workflow}) %>');
|
||||||
|
showModal('ajax-modal', '400px');
|
||||||
|
$('#ajax-modal').addClass('new-action');
|
||||||
1
app/views/dmsf_workflows/add_step.html.erb
Normal file
1
app/views/dmsf_workflows/add_step.html.erb
Normal file
@ -0,0 +1 @@
|
|||||||
|
<%= render 'steps' %>
|
||||||
1
app/views/dmsf_workflows/autocomplete_for_user.js.erb
Normal file
1
app/views/dmsf_workflows/autocomplete_for_user.js.erb
Normal file
@ -0,0 +1 @@
|
|||||||
|
$('#users').html('<%= escape_javascript(render_principals_for_new_dmsf_workflow_users(@workflow)) %>');
|
||||||
1
app/views/dmsf_workflows/edit.html.erb
Normal file
1
app/views/dmsf_workflows/edit.html.erb
Normal file
@ -0,0 +1 @@
|
|||||||
|
<%= render 'steps' %>
|
||||||
1
app/views/dmsf_workflows/index.html.erb
Normal file
1
app/views/dmsf_workflows/index.html.erb
Normal file
@ -0,0 +1 @@
|
|||||||
|
<%= render 'main' %>
|
||||||
1
app/views/dmsf_workflows/log.html.erb
Normal file
1
app/views/dmsf_workflows/log.html.erb
Normal file
@ -0,0 +1 @@
|
|||||||
|
<h2>WorkflowController#log</h2>
|
||||||
12
app/views/dmsf_workflows/new.html.erb
Normal file
12
app/views/dmsf_workflows/new.html.erb
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<h2><%= link_to l(:label_dmsf_workflow_plural), dmsf_workflows_path %> » <%=l(:label_dmsf_workflow_new)%></h2>
|
||||||
|
|
||||||
|
<%= labelled_form_for @workflow do |f| %>
|
||||||
|
<%= error_messages_for 'workflow' %>
|
||||||
|
<div class="box tabular">
|
||||||
|
<p><%= f.text_field :name, :required => true %></p>
|
||||||
|
<% if params[:project_id] %>
|
||||||
|
<p><%= hidden_field_tag :project_id, params[:project_id] %></p>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<%= submit_tag l(:button_create) %>
|
||||||
|
<% end %>
|
||||||
1
app/views/dmsf_workflows/remove_step.html.erb
Normal file
1
app/views/dmsf_workflows/remove_step.html.erb
Normal file
@ -0,0 +1 @@
|
|||||||
|
<%= render 'steps' %>
|
||||||
1
app/views/dmsf_workflows/reorder_steps.html.erb
Normal file
1
app/views/dmsf_workflows/reorder_steps.html.erb
Normal file
@ -0,0 +1 @@
|
|||||||
|
<%= render 'steps' %>
|
||||||
BIN
assets/images/ticket_go.png
Normal file
BIN
assets/images/ticket_go.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 608 B |
50
assets/javascripts/dmsf.css
Normal file
50
assets/javascripts/dmsf.css
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/* An image next to the approval workflow item in the administration menu */
|
||||||
|
#admin-menu a.workflow { background-image: url(../images/ticket_go.png); }
|
||||||
|
|
||||||
|
.dmsf-entity-container {
|
||||||
|
padding: 0% 2%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dmsf-entity-container .dmsf-entity {
|
||||||
|
padding: 5px;
|
||||||
|
line-height: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
li.dmsf-entity-file,
|
||||||
|
li.dmsf-entity-folder {
|
||||||
|
border: 1px solid #628DB6;
|
||||||
|
border-width: 1px 0;
|
||||||
|
list-style: none;
|
||||||
|
zoom: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dmsf-entity-container .dmsf-entity .dmsf-col {
|
||||||
|
float: left;
|
||||||
|
padding-top: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dmsf-entity-container .dmsf-entity .dmsf-col.dmsf-entity-name {
|
||||||
|
width: 30%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dmsf-entity-container .dmsf-entity .dmsf-col.dmsf-entity-cat {
|
||||||
|
width: 15%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dmsf-entity-container .dmsf-entity .dmsf-col.dmsf-entity-lock {
|
||||||
|
width: 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dmsf-entity-container .dmsf-entity .dmsf-col.dmsf-entity-size {
|
||||||
|
width: 10%;
|
||||||
|
}
|
||||||
|
.dmsf-entity-container .dmsf-entity .dmsf-col.dmsf-entity-modified {
|
||||||
|
width: 10%;
|
||||||
|
}
|
||||||
|
.dmsf-entity-container .dmsf-entity .dmsf-col.dmsf-entity-action {
|
||||||
|
width: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#users_for_delegate {height: 200px; overflow:auto;}
|
||||||
|
#users_for_delegate label {display: block;}
|
||||||
@ -233,3 +233,8 @@ table.access-table tbody td, table.access-table tbody tr:hover td {
|
|||||||
display: block;
|
display: block;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Approval workflow */
|
||||||
|
#admin-menu a.approvalworkflows { background-image: url(../images/ticket_go.png); }
|
||||||
|
#users_for_delegate {height: 200px; overflow:auto;}
|
||||||
|
#users_for_delegate label {display: block;}
|
||||||
@ -208,3 +208,20 @@ en:
|
|||||||
:select_option_webdav_readwrite: "Read/Write"
|
:select_option_webdav_readwrite: "Read/Write"
|
||||||
:label_webdav_strategy: "Webdav strategy"
|
:label_webdav_strategy: "Webdav strategy"
|
||||||
:note_webdav_strategy: "Enables the administrator to decide if webdav is a read-only or read-write platform for end users."
|
:note_webdav_strategy: "Enables the administrator to decide if webdav is a read-only or read-write platform for end users."
|
||||||
|
|
||||||
|
label_dmsf_workflow_new: New approval workflow
|
||||||
|
label_dmsf_workflow: Approval workflow
|
||||||
|
label_dmsf_workflow_plural: Approval workflows
|
||||||
|
error_unable_delete_dmsf_workflow: Unable to delete the workflow
|
||||||
|
label_dmsf_workflow_step: Step
|
||||||
|
label_dmsf_workflow_step_plural: Steps
|
||||||
|
label_dmsf_workflow_approval: Approval
|
||||||
|
label_dmsf_workflow_approval_plural: Approvals
|
||||||
|
dmsf_and: AND
|
||||||
|
dmsf_or: OR
|
||||||
|
dmsf_new_step: New step
|
||||||
|
label_dmsf: DMSF
|
||||||
|
label_dmsf_wokflow_action_approve: Approve
|
||||||
|
label_dmsf_wokflow_action_reject: Reject
|
||||||
|
label_dmsf_wokflow_action_delegate: 'Delegate to:'
|
||||||
|
message_dmsf_wokflow_note: Your note...
|
||||||
|
|||||||
@ -100,4 +100,17 @@ RedmineApp::Application.routes.draw do
|
|||||||
:resource_class => RedmineDmsf::Webdav::ResourceProxy,
|
:resource_class => RedmineDmsf::Webdav::ResourceProxy,
|
||||||
:controller_class => RedmineDmsf::Webdav::Controller
|
:controller_class => RedmineDmsf::Webdav::Controller
|
||||||
), :at => "/dmsf/webdav"
|
), :at => "/dmsf/webdav"
|
||||||
|
|
||||||
|
# Approval workflow
|
||||||
|
resources :dmsf_workflows do
|
||||||
|
member do
|
||||||
|
get 'autocomplete_for_user'
|
||||||
|
get 'action'
|
||||||
|
post 'new_action'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
match 'dmsf_workflows/:id/edit', :controller => 'dmsf_workflows', :action => 'add_step', :id => /\d+/, :via => :post
|
||||||
|
match 'dmsf_workflows/:id/edit', :controller => 'dmsf_workflows', :action => 'remove_step', :id => /\d+/, :via => :delete
|
||||||
|
match 'dmsf_workflows/:id/edit', :controller => 'dmsf_workflows', :action => 'reorder_steps', :id => /\d+/, :via => :put
|
||||||
end
|
end
|
||||||
|
|||||||
13
db/migrate/20120822100401_create_dmsf_workflows.rb
Normal file
13
db/migrate/20120822100401_create_dmsf_workflows.rb
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
class CreateDmsfWorkflows < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
create_table :dmsf_workflows do |t|
|
||||||
|
t.string :name, :null => false
|
||||||
|
t.references :project
|
||||||
|
end
|
||||||
|
add_index :dmsf_workflows, [:name], :unique => true
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
drop_table :dmsf_workflows
|
||||||
|
end
|
||||||
|
end
|
||||||
15
db/migrate/20120822100402_create_dmsf_workflow_steps.rb
Normal file
15
db/migrate/20120822100402_create_dmsf_workflow_steps.rb
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
class CreateDmsfWorkflowSteps < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
create_table :dmsf_workflow_steps do |t|
|
||||||
|
t.references :dmsf_workflow, :null => false
|
||||||
|
t.integer :step, :null => false
|
||||||
|
t.references :user, :null => false
|
||||||
|
t.integer :operator, :null => false
|
||||||
|
end
|
||||||
|
add_index :dmsf_workflow_steps, :dmsf_workflow_id
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
drop_table :dmsf_workflow_steps
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
class CreateDmsfWorkflowStepAssignments < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
create_table :dmsf_workflow_step_assignments do |t|
|
||||||
|
t.references :dmsf_workflow_step, :null => false
|
||||||
|
t.references :user, :null => false
|
||||||
|
t.references :dmsf_file_revision, :null => false
|
||||||
|
end
|
||||||
|
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'}
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
drop_table :dmsf_workflow_step_assignments
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
class CreateDmsfWorkflowStepActions < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
create_table :dmsf_workflow_step_actions do |t|
|
||||||
|
t.references :dmsf_workflow_step_assignment, :null => false
|
||||||
|
t.integer :action, :null => false
|
||||||
|
t.text :note
|
||||||
|
t.timestamp :created_at
|
||||||
|
end
|
||||||
|
add_index :dmsf_workflow_step_actions,
|
||||||
|
:dmsf_workflow_step_assignment_id,
|
||||||
|
# The default index name exceeds the index name limit
|
||||||
|
{:name => 'index_dmsf_workflow_step_actions_on_workflow_step_assignment_id'}
|
||||||
|
end
|
||||||
|
def self.down
|
||||||
|
drop_table :dmsf_workflow_step_actions
|
||||||
|
end
|
||||||
|
end
|
||||||
13
init.rb
13
init.rb
@ -58,6 +58,19 @@ Redmine::Plugin.register :redmine_dmsf do
|
|||||||
permission :file_approval, {:dmsf_files => [:delete_revision, :notify_activate, :notify_deactivate],
|
permission :file_approval, {:dmsf_files => [:delete_revision, :notify_activate, :notify_deactivate],
|
||||||
:dmsf => [:notify_activate, :notify_deactivate]}
|
:dmsf => [:notify_activate, :notify_deactivate]}
|
||||||
permission :force_file_unlock, {}
|
permission :force_file_unlock, {}
|
||||||
|
permission :approval_workflows, {:dmsf_workflows => [:new, :create, :destroy, :edit, :add_step, :remove_step, :reorder_steps, :update]}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Administration menu extension
|
||||||
|
Redmine::MenuManager.map :admin_menu do |menu|
|
||||||
|
menu.push :approvalworkflows, {:controller => 'dmsf_workflows', :action => 'index'}, :caption => :label_dmsf_workflow_plural
|
||||||
|
end
|
||||||
|
|
||||||
|
# Adds javascript and stylesheet tags for project tree view
|
||||||
|
class DmsfViewListener < Redmine::Hook::ViewListener
|
||||||
|
def view_layouts_base_html_head(context)
|
||||||
|
stylesheet_link_tag('dmsf', :plugin => :redmine_dmsf)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Redmine::WikiFormatting::Macros.register do
|
Redmine::WikiFormatting::Macros.register do
|
||||||
|
|||||||
@ -33,7 +33,7 @@ module RedmineDmsf
|
|||||||
has_many :dmsf_files, :class_name => "DmsfFile", :foreign_key => "project_id", :conditions => { :dmsf_folder_id => nil }
|
has_many :dmsf_files, :class_name => "DmsfFile", :foreign_key => "project_id", :conditions => { :dmsf_folder_id => nil }
|
||||||
#Fix: should only be root folders not, all folders
|
#Fix: should only be root folders not, all folders
|
||||||
has_many :dmsf_folders, :class_name => "DmsfFolder", :foreign_key => "project_id", :conditions => {:dmsf_folder_id => nil}, :dependent => :destroy
|
has_many :dmsf_folders, :class_name => "DmsfFolder", :foreign_key => "project_id", :conditions => {:dmsf_folder_id => nil}, :dependent => :destroy
|
||||||
|
has_many :dmsf_workflows, :dependent => :destroy
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -39,8 +39,9 @@ module RedmineDmsf
|
|||||||
|
|
||||||
def project_settings_tabs_with_dmsf
|
def project_settings_tabs_with_dmsf
|
||||||
tabs = project_settings_tabs_without_dmsf
|
tabs = project_settings_tabs_without_dmsf
|
||||||
if @project.module_enabled?("dmsf")
|
if @project.module_enabled? 'dmsf'
|
||||||
tabs.push({:name => 'dmsf', :controller => :dmsf_state, :action => :user_pref_save, :partial => 'dmsf_state/user_pref', :label => :dmsf})
|
#tabs.push({:name => 'dmsf', :controller => :dmsf_state, :action => :user_pref_save, :partial => 'dmsf_state/user_pref', :label => :dmsf})
|
||||||
|
tabs << {:name => 'dmsf', :controller => 'dmsf_workflows', :action => 'index', :partial => 'dmsf_workflows/main', :label => 'label_dmsf'}
|
||||||
end
|
end
|
||||||
return tabs
|
return tabs
|
||||||
end
|
end
|
||||||
|
|||||||
22
test/fixtures/dmsf_workflow_step_actions.yml
vendored
Normal file
22
test/fixtures/dmsf_workflow_step_actions.yml
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
---
|
||||||
|
wfsac1:
|
||||||
|
id: 1
|
||||||
|
dmsf_workflow_step_assignment_id: 1
|
||||||
|
action: 1
|
||||||
|
note: 'Approval'
|
||||||
|
created_at: '2013-05-03 10:45:35'
|
||||||
|
|
||||||
|
wfsac2:
|
||||||
|
id: 2
|
||||||
|
dmsf_workflow_step_assignment_id: 1
|
||||||
|
action: 2
|
||||||
|
note: 'Rejection'
|
||||||
|
created_at: '2013-05-03 10:45:36'
|
||||||
|
|
||||||
|
wfsac3:
|
||||||
|
id: 3
|
||||||
|
dmsf_workflow_step_assignment_id: 1
|
||||||
|
action: 3
|
||||||
|
note: 'Delegation'
|
||||||
|
created_at: '2013-05-03 10:45:37'
|
||||||
6
test/fixtures/dmsf_workflow_step_assignments.yml
vendored
Normal file
6
test/fixtures/dmsf_workflow_step_assignments.yml
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
wfsa1:
|
||||||
|
id: 1
|
||||||
|
dmsf_workflow_step_id: 1
|
||||||
|
user_id: 1
|
||||||
|
dmsf_file_revision_id: 2
|
||||||
21
test/fixtures/dmsf_workflow_steps.yml
vendored
Normal file
21
test/fixtures/dmsf_workflow_steps.yml
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
wfs1:
|
||||||
|
id: 1
|
||||||
|
dmsf_workflow_id: 1
|
||||||
|
step: 1
|
||||||
|
user_id: 1
|
||||||
|
operator: 1
|
||||||
|
|
||||||
|
wfs2:
|
||||||
|
id: 2
|
||||||
|
dmsf_workflow_id: 1
|
||||||
|
step: 2
|
||||||
|
user_id: 2
|
||||||
|
operator: 1
|
||||||
|
|
||||||
|
wfs3:
|
||||||
|
id: 3
|
||||||
|
dmsf_workflow_id: 1
|
||||||
|
step: 3
|
||||||
|
user_id: 1
|
||||||
|
operator: 1
|
||||||
8
test/fixtures/dmsf_workflows.yml
vendored
Normal file
8
test/fixtures/dmsf_workflows.yml
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
wf1:
|
||||||
|
id: 1
|
||||||
|
name: wf1
|
||||||
|
|
||||||
|
wf2:
|
||||||
|
id: 2
|
||||||
|
name: wf2
|
||||||
171
test/functional/dmsf_workflow_controller_test.rb
Normal file
171
test/functional/dmsf_workflow_controller_test.rb
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
require File.expand_path('../../test_helper', __FILE__)
|
||||||
|
|
||||||
|
class DmsfWorkflowsControllerTest < RedmineDmsf::Test::TestCase
|
||||||
|
fixtures :users, :dmsf_workflows, :dmsf_workflow_steps, :projects, :roles,
|
||||||
|
:members, :member_roles
|
||||||
|
|
||||||
|
def setup
|
||||||
|
User.current = nil
|
||||||
|
|
||||||
|
@manager_role = Role.find_by_name('Manager')
|
||||||
|
@project = Project.find(5)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_index_admin
|
||||||
|
@request.session[:user_id] = 1 # admin
|
||||||
|
get :index
|
||||||
|
assert_response :success
|
||||||
|
assert_template 'index'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_index_user
|
||||||
|
@request.session[:user_id] = 2 # non admin
|
||||||
|
get :index
|
||||||
|
assert_response :forbidden
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_index_member
|
||||||
|
old_controller = @controller
|
||||||
|
@controller = ProjectsController.new
|
||||||
|
|
||||||
|
@request.session[:user_id] = 2
|
||||||
|
get :settings, :id => @project.id
|
||||||
|
assert_response :success
|
||||||
|
assert_template 'settings'
|
||||||
|
|
||||||
|
@controller = old_controller
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_new_admin
|
||||||
|
@request.session[:user_id] = 1 # admin
|
||||||
|
get :new
|
||||||
|
assert_response :success
|
||||||
|
assert_template 'new'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_new_member_no_permission
|
||||||
|
@project.enable_module!(:dmsf)
|
||||||
|
@manager_role.remove_permission! :approval_workflows
|
||||||
|
@request.session[:user_id] = 2
|
||||||
|
get :new, {:project_id => @project.id}
|
||||||
|
assert_response :forbidden
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_new_member_no_module
|
||||||
|
@project.disable_module!(:dmsf)
|
||||||
|
@manager_role.add_permission! :approval_workflows
|
||||||
|
@request.session[:user_id] = 2
|
||||||
|
get :new, {:project_id => @project.id}
|
||||||
|
assert_response :forbidden
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_new_member
|
||||||
|
@manager_role.add_permission! :approval_workflows
|
||||||
|
@request.session[:user_id] = 2
|
||||||
|
@project.enable_module!(:dmsf)
|
||||||
|
get :new, {:project_id => @project.id}
|
||||||
|
assert_response :success
|
||||||
|
assert_template 'new'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_new_no_member
|
||||||
|
@manager_role.add_permission! :approval_workflows
|
||||||
|
@request.session[:user_id] = 3
|
||||||
|
@project.enable_module!(:dmsf)
|
||||||
|
get :new, {:project_id => @project.id}
|
||||||
|
assert_response :forbidden
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_edit
|
||||||
|
@request.session[:user_id] = 1 # admin
|
||||||
|
get :edit, :id => 1
|
||||||
|
assert_response :success
|
||||||
|
assert_template 'edit'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_create
|
||||||
|
@request.session[:user_id] = 1 # admin
|
||||||
|
assert_difference 'DmsfWorkflow.count', +1 do
|
||||||
|
post :create, :dmsf_workflow => {:name => 'wf3'}
|
||||||
|
end
|
||||||
|
workflow = DmsfWorkflow.first(:order => 'id DESC')
|
||||||
|
assert_redirected_to dmsf_workflows_path
|
||||||
|
assert_equal 'wf3', workflow.name
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_update
|
||||||
|
@request.session[:user_id] = 1 # admin
|
||||||
|
put :update, :id => 1, :dmsf_workflow => {:name => 'wf1a'}
|
||||||
|
workflow = DmsfWorkflow.find(1)
|
||||||
|
assert_equal 'wf1a', workflow.name
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_destroy
|
||||||
|
@request.session[:user_id] = 1 # admin
|
||||||
|
assert_difference 'DmsfWorkflow.count', -1 do
|
||||||
|
delete :destroy, :id => 1
|
||||||
|
end
|
||||||
|
assert_redirected_to dmsf_workflows_path
|
||||||
|
assert_nil DmsfWorkflow.find_by_id(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_add_step
|
||||||
|
@request.session[:user_id] = 1 # admin
|
||||||
|
assert_difference 'DmsfWorkflowStep.count', +1 do
|
||||||
|
post :add_step, :commit => 'OR', :step => 1, :id => 1, :user_ids =>[3]
|
||||||
|
end
|
||||||
|
assert_response :success
|
||||||
|
ws = DmsfWorkflowStep.first(:order => 'id DESC')
|
||||||
|
assert_equal 1, ws.dmsf_workflow_id
|
||||||
|
assert_equal 1, ws.step
|
||||||
|
assert_equal 3, ws.user_id
|
||||||
|
assert_equal 0, ws.operator
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_remove_step
|
||||||
|
@request.session[:user_id] = 1 # admin
|
||||||
|
n = DmsfWorkflowStep.where(:dmsf_workflow_id => 1, :step => 1).count
|
||||||
|
assert_difference 'DmsfWorkflowStep.count', -n do
|
||||||
|
delete :remove_step, :step => 1, :id => 1
|
||||||
|
end
|
||||||
|
assert_response :success
|
||||||
|
ws = DmsfWorkflowStep.where(:dmsf_workflow_id => 1).first(:order => 'id ASC')
|
||||||
|
assert_equal 1, ws.step
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_reorder_steps_to_lower
|
||||||
|
@request.session[:user_id] = 1 # admin
|
||||||
|
put :reorder_steps, :step => 1, :id => 1, :workflow_step => {:move_to => 'lower'}
|
||||||
|
assert_response :success
|
||||||
|
assert_equal 2, DmsfWorkflowStep.find(1).step
|
||||||
|
assert_equal 1, DmsfWorkflowStep.find(2).step
|
||||||
|
assert_equal 3, DmsfWorkflowStep.find(3).step
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_reorder_steps_to_lowest
|
||||||
|
@request.session[:user_id] = 1 # admin
|
||||||
|
put :reorder_steps, :step => 1, :id => 1, :workflow_step => {:move_to => 'lowest'}
|
||||||
|
assert_response :success
|
||||||
|
assert_equal 3, DmsfWorkflowStep.find(1).step
|
||||||
|
assert_equal 1, DmsfWorkflowStep.find(2).step
|
||||||
|
assert_equal 2, DmsfWorkflowStep.find(3).step
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_reorder_steps_to_higher
|
||||||
|
@request.session[:user_id] = 1 # admin
|
||||||
|
put :reorder_steps, :step => 2, :id => 1, :workflow_step => {:move_to => 'higher'}
|
||||||
|
assert_response :success
|
||||||
|
assert_equal 2, DmsfWorkflowStep.find(1).step
|
||||||
|
assert_equal 1, DmsfWorkflowStep.find(2).step
|
||||||
|
assert_equal 3, DmsfWorkflowStep.find(3).step
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_reorder_steps_to_highest
|
||||||
|
@request.session[:user_id] = 1 # admin
|
||||||
|
put :reorder_steps, :step => 3, :id => 1, :workflow_step => {:move_to => 'highest'}
|
||||||
|
assert_response :success
|
||||||
|
assert_equal 2, DmsfWorkflowStep.find(1).step
|
||||||
|
assert_equal 3, DmsfWorkflowStep.find(2).step
|
||||||
|
assert_equal 1, DmsfWorkflowStep.find(3).step
|
||||||
|
end
|
||||||
|
end
|
||||||
60
test/unit/dmsf_workflow_step_action_test.rb
Normal file
60
test/unit/dmsf_workflow_step_action_test.rb
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
require File.expand_path('../../test_helper', __FILE__)
|
||||||
|
|
||||||
|
class DmsfWorkflowStepActionTest < RedmineDmsf::Test::UnitTest
|
||||||
|
|
||||||
|
|
||||||
|
fixtures :dmsf_workflow_steps
|
||||||
|
fixtures :dmsf_workflow_step_actions
|
||||||
|
|
||||||
|
def setup
|
||||||
|
@wfsac1 = DmsfWorkflowStepAction.find(1)
|
||||||
|
@wfsac2 = DmsfWorkflowStepAction.find(2)
|
||||||
|
@wfsac3 = DmsfWorkflowStepAction.find(3)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_truth
|
||||||
|
assert_kind_of DmsfWorkflowStepAction, @wfsac1
|
||||||
|
assert_kind_of DmsfWorkflowStepAction, @wfsac2
|
||||||
|
assert_kind_of DmsfWorkflowStepAction, @wfsac3
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_create
|
||||||
|
wfsac = DmsfWorkflowStepAction.new(
|
||||||
|
:dmsf_workflow_step_assignment_id => 1,
|
||||||
|
:action => 1,
|
||||||
|
:note => 'Approvement')
|
||||||
|
assert wfsac.save
|
||||||
|
wfsac.reload
|
||||||
|
assert wfsac.created_at
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_update
|
||||||
|
@wfsac1.dmsf_workflow_step_assignment_id = 2
|
||||||
|
@wfsac1.action = 2
|
||||||
|
@wfsac1.note = 'Rejection'
|
||||||
|
|
||||||
|
assert @wfsac1.save
|
||||||
|
@wfsac1.reload
|
||||||
|
|
||||||
|
assert_equal 2, @wfsac1.dmsf_workflow_step_assignment_id
|
||||||
|
assert_equal 2, @wfsac1.action
|
||||||
|
assert_equal 'Rejection', @wfsac1.note
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_validate_workflow_step_assignment_id_presence
|
||||||
|
@wfsac1.dmsf_workflow_step_assignment_id = nil
|
||||||
|
assert !@wfsac1.save
|
||||||
|
assert_equal 1, @wfsac1.errors.count
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_validate_action_presence
|
||||||
|
@wfsac1.action = nil
|
||||||
|
assert !@wfsac1.save
|
||||||
|
assert_equal 1, @wfsac1.errors.count
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_destroy
|
||||||
|
@wfsac1.destroy
|
||||||
|
assert_nil DmsfWorkflowStepAction.find_by_id(1)
|
||||||
|
end
|
||||||
|
end
|
||||||
53
test/unit/dmsf_workflow_step_assignment_test.rb
Normal file
53
test/unit/dmsf_workflow_step_assignment_test.rb
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
require File.expand_path('../../test_helper', __FILE__)
|
||||||
|
|
||||||
|
class WorkflowStepAssignmentTest < RedmineDmsf::Test::UnitTest
|
||||||
|
|
||||||
|
fixtures :users, :dmsf_file_revisions, :dmsf_workflow_steps, :dmsf_workflow_step_assignments
|
||||||
|
|
||||||
|
def setup
|
||||||
|
@wfsa1 = DmsfWorkflowStepAssignment.find(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_truth
|
||||||
|
assert_kind_of DmsfWorkflowStepAssignment, @wfsa1
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_create
|
||||||
|
wfsa = DmsfWorkflowStepAssignment.new(
|
||||||
|
:dmsf_workflow_step_id => 2,
|
||||||
|
:user_id => 2,
|
||||||
|
:dmsf_file_revision_id => 2)
|
||||||
|
assert wfsa.save
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_update
|
||||||
|
@wfsa1.dmsf_workflow_step_id = 2
|
||||||
|
@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 2, @wfsa1.user_id
|
||||||
|
assert_equal 2, @wfsa1.dmsf_file_revision_id
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_validate_workflow_step_id_presence
|
||||||
|
@wfsa1.dmsf_workflow_step_id = nil
|
||||||
|
assert !@wfsa1.save
|
||||||
|
assert_equal 1, @wfsa1.errors.count
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_validate_workflow_entity_id_presence
|
||||||
|
@wfsa1.dmsf_file_revision_id = nil
|
||||||
|
assert !@wfsa1.save
|
||||||
|
assert_equal 1, @wfsa1.errors.count
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_destroy
|
||||||
|
@wfsa1.destroy
|
||||||
|
assert_nil DmsfWorkflowStepAssignment.find_by_id(1)
|
||||||
|
assert_nil DmsfWorkflowStepAction.find_by_id(1)
|
||||||
|
end
|
||||||
|
end
|
||||||
76
test/unit/dmsf_workflow_step_test.rb
Normal file
76
test/unit/dmsf_workflow_step_test.rb
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
require File.expand_path('../../test_helper', __FILE__)
|
||||||
|
|
||||||
|
class DmsfWorkflowStepTest < RedmineDmsf::Test::UnitTest
|
||||||
|
|
||||||
|
fixtures :users, :dmsf_workflows, :dmsf_workflow_steps
|
||||||
|
|
||||||
|
def setup
|
||||||
|
@wfs1 = DmsfWorkflowStep.find(1)
|
||||||
|
@wfs2 = DmsfWorkflowStep.find(2)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_truth
|
||||||
|
assert_kind_of DmsfWorkflowStep, @wfs1
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_create
|
||||||
|
wfs = DmsfWorkflowStep.new(
|
||||||
|
:dmsf_workflow_id => 1,
|
||||||
|
:step => 2,
|
||||||
|
:user_id => 1,
|
||||||
|
:operator => 1)
|
||||||
|
assert wfs.save
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_update
|
||||||
|
@wfs1.dmsf_workflow_id = 2
|
||||||
|
@wfs1.step = 2
|
||||||
|
@wfs1.user_id = 2
|
||||||
|
@wfs1.operator = 2
|
||||||
|
|
||||||
|
assert @wfs1.save
|
||||||
|
@wfs1.reload
|
||||||
|
|
||||||
|
assert_equal 2, @wfs1.dmsf_workflow_id
|
||||||
|
assert_equal 2, @wfs1.step
|
||||||
|
assert_equal 2, @wfs1.user_id
|
||||||
|
assert_equal 2, @wfs1.operator
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_validate_workflow_id_presence
|
||||||
|
@wfs1.dmsf_workflow_id = nil
|
||||||
|
assert !@wfs1.save
|
||||||
|
assert_equal 1, @wfs1.errors.count
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_validate_step_presence
|
||||||
|
@wfs1.step = nil
|
||||||
|
assert !@wfs1.save
|
||||||
|
assert_equal 1, @wfs1.errors.count
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_validate_user_id_presence
|
||||||
|
@wfs1.user_id = nil
|
||||||
|
assert !@wfs1.save
|
||||||
|
assert_equal 1, @wfs1.errors.count
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_validate_operator_presence
|
||||||
|
@wfs1.operator = nil
|
||||||
|
assert !@wfs1.save
|
||||||
|
assert_equal 1, @wfs1.errors.count
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_validate_user_id_uniqueness
|
||||||
|
@wfs2.user_id = @wfs1.user_id
|
||||||
|
@wfs2.dmsf_workflow_id = @wfs1.dmsf_workflow_id
|
||||||
|
@wfs2.step = @wfs1.step
|
||||||
|
assert !@wfs2.save
|
||||||
|
assert_equal 1, @wfs2.errors.count
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_destroy
|
||||||
|
@wfs2.destroy
|
||||||
|
assert_nil DmsfWorkflowStep.find_by_id(2)
|
||||||
|
end
|
||||||
|
end
|
||||||
54
test/unit/dmsf_workflow_test.rb
Normal file
54
test/unit/dmsf_workflow_test.rb
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
require File.expand_path('../../test_helper', __FILE__)
|
||||||
|
|
||||||
|
class DmsfWorkflowTest < RedmineDmsf::Test::UnitTest
|
||||||
|
|
||||||
|
fixtures :projects, :dmsf_workflows, :dmsf_workflow_steps
|
||||||
|
|
||||||
|
def setup
|
||||||
|
@wf1 = DmsfWorkflow.find(1)
|
||||||
|
@wf2 = DmsfWorkflow.find(2)
|
||||||
|
@wfs1 = DmsfWorkflowStep.find(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_truth
|
||||||
|
assert_kind_of DmsfWorkflow, @wf1
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_create
|
||||||
|
workflow = DmsfWorkflow.new(:name => 'wf')
|
||||||
|
assert workflow.save
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_update
|
||||||
|
@wf1.name = 'wf1a'
|
||||||
|
@wf1.project_id = 5
|
||||||
|
assert @wf1.save
|
||||||
|
@wf1.reload
|
||||||
|
assert_equal 'wf1a', @wf1.name
|
||||||
|
assert_equal 5, @wf1.project_id
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_validate_name_length
|
||||||
|
@wf1.name = 'a' * 256
|
||||||
|
assert !@wf1.save
|
||||||
|
assert_equal 1, @wf1.errors.count
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_validate_name_presence
|
||||||
|
@wf1.name = ''
|
||||||
|
assert !@wf1.save
|
||||||
|
assert_equal 1, @wf1.errors.count
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_validate_name_uniqueness
|
||||||
|
@wf2.name = @wf1.name
|
||||||
|
assert !@wf2.save
|
||||||
|
assert_equal 1, @wf2.errors.count
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_destroy
|
||||||
|
@wf1.destroy
|
||||||
|
assert_nil DmsfWorkflow.find_by_id(1)
|
||||||
|
assert_nil DmsfWorkflowStep.find_by_id(@wfs1.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
x
Reference in New Issue
Block a user