redmine_dmsf/app/controllers/dmsf_workflows_controller.rb
2013-09-25 15:50:34 +02:00

296 lines
10 KiB
Ruby

# 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, :assign, :assignment]
before_filter :find_project, :except => [:start]
before_filter :authorize_global
before_filter :authorize_custom
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
if params[:commit] == l(:button_submit)
action = DmsfWorkflowStepAction.new(
:dmsf_workflow_step_assignment_id => params[:dmsf_workflow_step_assignment_id],
:action => (params[:step_action].to_i >= 10) ? DmsfWorkflowStepAction::ACTION_DELEGATE : params[:step_action],
:note => params[:note])
if request.post?
if action.save
revision = DmsfFileRevision.find_by_id params[:dmsf_file_revision_id]
if revision
if @workflow.try_finish revision, action, (params[:step_action].to_i / 10)
file = DmsfFile.joins(:revisions).where(:dmsf_file_revisions => {:id => revision.id}).first
file.unlock! if file
if revision.workflow == DmsfWorkflow::STATE_APPROVED
# Just approved
DmsfMailer.workflow_notification(
revision.file.project.members.collect{ |member| member.user.mail},
@workflow,
revision,
"Approval workflow #{@workflow.name} approved",
'been finished and the document has been approved',
'To see the approval history click on the workflow status of the document in').deliver
else
# Just rejected
owner = User.find_by_id revision.dmsf_workflow_assigned_by
DmsfMailer.workflow_notification(
@workflow.participiants.collect{ |user| user.mail} << owner.mail,
@workflow,
revision,
"Approval workflow #{@workflow.name} rejected",
"been finished and the document has been rejected because of '#{action.note}'",
'To see the approval history click on the workflow status of the document in').deliver
end
else
if action.action == DmsfWorkflowStepAction::ACTION_DELEGATE
# Delegation
delegate = User.find_by_id params[:step_action].to_i / 10
DmsfMailer.workflow_notification(
delegate.mail,
@workflow,
revision,
"Approval workflow #{@workflow.name} step delegated",
"been delegated because of '#{action.note}' and you are expected to do an approval in the current approval step",
'To proceed click on the check box icon next to the document in').deliver
else
# Next step
assignments = @workflow.next_assignments revision.id
unless assignments.empty?
if assignments.first.dmsf_workflow_step.step != action.dmsf_workflow_step_assignment.dmsf_workflow_step.step
# Next step
DmsfMailer.workflow_notification(
assignments.collect{ |assignment| assignment.user.mail},
@workflow,
revision,
"Approval workflow #{@workflow.name} requires your approval",
'finished one of the approval steps and you are expected to do an approval in the next approval step',
'To proceed click on the check box icon next to the document in the').deliver
owner = User.find_by_id revision.dmsf_workflow_assigned_by
DmsfMailer.workflow_notification(
owner.mail,
@workflow,
revision,
"Approval workflow #{@workflow.name} updated",
'finished one of the approval steps',
'To see the current status of the approval workflow click on the workflow status the document in').deliver
end
end
end
end
end
flash[:notice] = l(:notice_successful_update)
else
flash[:error] = l(:error_empty_note)
end
end
end
redirect_to :back
end
def assign
end
def assignment
if params[:commit] == l(:button_submit)
revision = DmsfFileRevision.find_by_id params[:dmsf_file_revision_id]
if revision
revision.set_workflow(params[:dmsf_workflow_id], params[:action])
if params[:dmsf_workflow_id].present?
revision.assign_workflow(params[:dmsf_workflow_id])
if request.post?
if revision.save
file = DmsfFile.find_by_id revision.dmsf_file_id
file.lock! if file
flash[:notice] = l(:notice_successful_update)
else
flash[:error] = l(:error_workflow_assign)
end
end
end
end
end
redirect_to :back
end
def log
end
def new
@workflow = DmsfWorkflow.new
end
def create
@workflow = DmsfWorkflow.new(:name => params[: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_workflow')
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[:name]})
flash[:notice] = l(:notice_successful_update)
if @project
redirect_to settings_project_path(@project, :tab => 'dmsf_workflow')
else
redirect_to dmsf_workflows_path
end
else
render :action => 'edit'
end
end
def destroy
begin
@workflow.destroy
flash[:notice] = l(:notice_successful_delete)
rescue
flash[:error] = l(:error_unable_delete_dmsf_workflow)
end
if @project
redirect_to settings_project_path(@project, :tab => 'dmsf_workflow')
else
redirect_to dmsf_workflows_path
end
end
def autocomplete_for_user
render :layout => false
end
def add_step
if request.post?
users = User.find_all_by_id(params[:user_ids])
if params[:step] == '0'
step = @workflow.dmsf_workflow_steps.collect{|s| s.step}.uniq.count + 1
else
step = params[:step].to_i
end
operator = (params[:commit] == l(:dmsf_and)) ? DmsfWorkflowStep::OPERATOR_AND : DmsfWorkflowStep::OPERATOR_OR
users.each do |user|
@workflow.dmsf_workflow_steps << DmsfWorkflowStep.new(
:dmsf_workflow_id => @workflow.id,
:step => step,
:user_id => user.id,
:operator => operator)
end
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
unless ws.save
flash[:error] = l(:notice_cannot_renumber_steps)
end
end
end
end
respond_to do |format|
format.html
end
end
def reorder_steps
if request.put?
unless @workflow.reorder_steps(params[:step].to_i, params[:workflow_step][:move_to])
flash[:error] = l(:notice_cannot_renumber_steps)
end
end
respond_to do |format|
format.html
end
end
def start
revision = DmsfFileRevision.find_by_id(params[:dmsf_file_revision_id])
if revision
if request.post?
revision.set_workflow(@workflow.id, params[:action])
if revision.save
assignments = @workflow.next_assignments revision.id
DmsfMailer.workflow_notification(
assignments.collect{ |assignment| assignment.user.mail},
@workflow,
revision,
"Approval workflow #{@workflow.name} started",
'been started and you are expected to do an approval in the current approval step',
'To proceed click on the check box icon next to the document in').deliver
flash[:notice] = l(:notice_workflow_started)
else
flash[:error] = l(:notice_cannot_start_workflow)
end
end
end
redirect_to :back
end
private
def find_workflow
@workflow = DmsfWorkflow.find_by_id(params[:id])
end
def find_project
if @workflow && @workflow.project
@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
def authorize_custom
require_admin unless @project
end
end