Approval workflows #325 & #326

This commit is contained in:
Karel Pičman 2014-12-08 13:20:04 +01:00
parent ef11baad8e
commit 69dc408d2e
9 changed files with 154 additions and 83 deletions

View File

@ -38,6 +38,7 @@ class DmsfController < ApplicationController
@file_delete_allowed = User.current.allowed_to?(:file_delete, @project)
@force_file_unlock_allowed = User.current.allowed_to?(:force_file_unlock, @project)
@workflows_available = DmsfWorkflow.where(['project_id = ? OR project_id IS NULL', @project.id]).count > 0
@file_approval_allowed = User.current.allowed_to?(:file_approval, @project)
unless @folder
if params[:custom_field_id].present? && params[:custom_value].present?

View File

@ -27,11 +27,7 @@ class DmsfWorkflowsController < ApplicationController
layout :workflows_layout
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
@workflow_pages, @workflows = paginate DmsfWorkflow.global.sorted, :per_page => 25
end
def action
@ -210,22 +206,24 @@ class DmsfWorkflowsController < ApplicationController
@dmsf_workflow.name = params[:dmsf_workflow][:name]
elsif params[:dmsf_workflow_id].present?
wf = DmsfWorkflow.find_by_id params[:dmsf_workflow_id]
@dmsf_workflow.name = "#{wf.name}-#{@project.identifier}" if wf
@dmsf_workflow.name = wf.name if wf
end
render :layout => !request.xhr?
end
def create
if params[:dmsf_workflow_id] && params[:dmsf_workflow]
if params[:dmsf_workflow]
if (params[:dmsf_workflow_id].to_i > 0)
wf = DmsfWorkflow.find_by_id params[:dmsf_workflow_id]
@dmsf_workflow = wf.copy_to @project, params[:dmsf_workflow][:name]
@dmsf_workflow = wf.copy_to(@project, params[:dmsf_workflow][:name]) if wf
else
@dmsf_workflow = DmsfWorkflow.new(:name => params[:name],
:project_id => @project.id)
@dmsf_workflow = DmsfWorkflow.new(:name => params[:dmsf_workflow][:name])
@dmsf_workflow.project_id = @project.id if @project
@dmsf_workflow.save
end
if request.post? && @dmsf_workflow.valid?
end
if request.post? && @dmsf_workflow && @dmsf_workflow.valid?
flash[:notice] = l(:notice_successful_create)
if @project
redirect_to settings_project_path(@project, :tab => 'dmsf_workflow')

View File

@ -49,8 +49,12 @@ module DmsfWorkflowsHelper
def dmsf_workflows_for_select(project, dmsf_workflow_id)
options = Array.new
DmsfWorkflow.where(['project_id = ? OR project_id IS NULL', project.id]).each do |wf|
DmsfWorkflow.sorted.where(['project_id = ? OR project_id IS NULL', project.id]).each do |wf|
if wf.project_id
options << [wf.name, wf.id]
else
options << ["#{wf.name} (global)", wf.id]
end
end
options_for_select(options, :selected => dmsf_workflow_id)
end
@ -58,8 +62,19 @@ module DmsfWorkflowsHelper
def dmsf_all_workflows_for_select(dmsf_workflow_id)
options = Array.new
options << ['', 0]
DmsfWorkflow.where('project_id IS NOT NULL').each do |wf|
if User.current.allowed_to?(:manage_workflows, wf.project)
DmsfWorkflow.sorted.all.each do |wf|
if wf.project_id
prj = Project.find_by_id wf.project_id
if User.current.allowed_to?(:manage_workflows, prj)
# Local approval workflows
if prj
options << ["#{wf.name} (#{prj.name})", wf.id]
else
options << [wf.name, wf.id]
end
end
else
# Global approval workflows
options << [wf.name, wf.id]
end
end

View File

@ -19,10 +19,39 @@
class DmsfWorkflow < ActiveRecord::Base
has_many :dmsf_workflow_steps, :dependent => :destroy, :order => 'step ASC, operator DESC'
validates_uniqueness_of :name, :case_sensitive => false
scope :sorted, lambda { order('name ASC') }
scope :global, lambda { where('project_id IS NULL') }
validate :name_validation
validates :name, :presence => true
validates_length_of :name, :maximum => 255
def name_validation
if self.project_id
if self.id
if (DmsfWorkflow.where(['(project_id IS NULL OR (project_id = ? AND id != ?)) AND name = ?',
self.project_id, self.name, self.id]).count > 0)
errors.add(:name, l('activerecord.errors.messages.taken'))
end
else
if (DmsfWorkflow.where(['(project_id IS NULL OR project_id = ?) AND name = ?',
self.project_id, self.name]).count > 0)
errors.add(:name, l('activerecord.errors.messages.taken'))
end
end
else
if self.id
if DmsfWorkflow.where(['name = ? AND id != ?', self.name, self.id]).count > 0
errors.add(:name, l('activerecord.errors.messages.taken'))
end
else
if DmsfWorkflow.where(:name => self.name).count > 0
errors.add(:name, l('activerecord.errors.messages.taken'))
end
end
end
end
STATE_NONE = nil
STATE_ASSIGNED = 3
STATE_WAITING_FOR_APPROVAL = 1
@ -206,12 +235,8 @@ class DmsfWorkflow < ActiveRecord::Base
def copy_to(project, name = nil)
new_wf = self.dup
if name
new_wf.name = name
else
new_wf.name << "-#{project.identifier}"
end
new_wf.project_id = project.id
new_wf.name = name if name
new_wf.project_id = project ? project.id : nil
if new_wf.save
self.dmsf_workflow_steps.each do |step|
step.copy_to(new_wf)

View File

@ -55,7 +55,7 @@
</td>
<td class="version"><%= file.last_revision.version %></td>
<td class="workflow">
<% if wf && @file_manipulation_allowed %>
<% if wf && @file_approval_allowed %>
<%= link_to(
file.last_revision.workflow_str(false),
log_dmsf_workflow_path(
@ -70,8 +70,9 @@
</td>
<td class="author"><%= h(file.last_revision.user) %></td>
<td class="actions">
<% if @file_manipulation_allowed %>
<% if @file_manipulation_allowed || @file_approval_allowed %>
<div class="right_icon_box">
<% if @file_manipulation_allowed %>
<% unless locked %>
<%= link_to('',
dmsf_file_path(:id => file),
@ -124,6 +125,8 @@
<span class="icon icon-margin-left"></span>
<span class="icon"></span>
<% end %>
<% end %>
<% if @file_approval_allowed %>
<% case file.last_revision.workflow %>
<% when DmsfWorkflow::STATE_WAITING_FOR_APPROVAL %>
<% if wf %>
@ -179,6 +182,7 @@
:remote => true) %>
<% end %>
<% end %>
<% end %>
</div>
<% end %>
</td>

View File

@ -1,6 +1,6 @@
<%# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2013 Karel Pičman <karel.picman@kontron.com>
# Copyright (C) 2011-14 Karel Pičman <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
@ -16,7 +16,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.%>
<% @workflows = DmsfWorkflow.where(:project_id => @project.id) if @project && @workflows.nil? %>
<% @workflows = DmsfWorkflow.sorted.where(:project_id => @project.id) if @project && @workflows.nil? %>
<div class="contextual">
<% if @project %>

View File

@ -42,6 +42,6 @@
<script type="text/javascript">
$('#dmsf_workflow_id').change(function () {
$('#content').load("<%= url_for(:action => 'new', :project_id => @project.id) %>", $('#new_dmsf_workflow').serialize());
$('#content').load("<%= url_for(:action => 'new', :project_id => @project) %>", $('#new_dmsf_workflow').serialize());
});
</script>

View File

@ -0,0 +1,27 @@
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011-14 Karel Pičman <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 RemoveUniquenessFromWf < ActiveRecord::Migration
def up
remove_index :dmsf_workflows, :name
end
def down
add_index :dmsf_workflows, [:name], :unique => true
end
end

View File

@ -26,7 +26,7 @@ Redmine::Plugin.register :redmine_dmsf do
name 'DMSF'
author 'Vit Jonas / Daniel Munn / Karel Picman'
description 'Document Management System Features'
version '1.4.9 stable'
version '1.5.1 devel'
url 'http://www.redmine.org/plugins/dmsf'
author_url 'https://github.com/danmunn/redmine_dmsf/graphs/contributors'
@ -68,13 +68,14 @@ Redmine::Plugin.register :redmine_dmsf do
permission :file_manipulation,
{:dmsf_files => [:create_revision, :lock, :unlock, :delete_revision, :notify_activate, :notify_deactivate, :restore],
:dmsf_upload => [:upload_files, :upload_file, :commit_files],
:dmsf_workflows => [:action, :new_action, :autocomplete_for_user, :start, :assign, :assignment],
:dmsf_links => [:new, :create, :destroy, :restore]
}
permission :file_delete, { :dmsf => [:trash], :dmsf_files => [:delete]}
permission :force_file_unlock, {}
permission :file_approval,
{:dmsf_workflows => [:action, :new_action, :autocomplete_for_user, :start, :assign, :assignment]}
permission :manage_workflows,
{:dmsf_workflows => [:index, :new, :create, :destroy, :show, :add_step, :remove_step, :reorder_steps, :update]}
permission :force_file_unlock, {}
end
# Administration menu extension