approval email notifications implemented
This commit is contained in:
parent
a4a200510a
commit
91221f26d5
@ -40,13 +40,72 @@ class DmsfWorkflowsController < ApplicationController
|
||||
if params[:commit] == l(:button_submit)
|
||||
action = DmsfWorkflowStepAction.new(
|
||||
:dmsf_workflow_step_assignment_id => params[:dmsf_workflow_step_assignment_id],
|
||||
:action => params[:step_action],
|
||||
:action => (params[:step_action].to_i >= 10) ? DmsfWorkflowStepAction::ACTION_DELEGATE : params[:step_action],
|
||||
:note => params[:note])
|
||||
if request.post?
|
||||
if action.save
|
||||
if @workflow.try_finish params[:dmsf_file_revision_id], action, params[:user_id]
|
||||
file = DmsfFile.joins(:revisions).where(:dmsf_file_revisions => {:id => params[:dmsf_file_revision_id]}).first
|
||||
file.unlock! if file
|
||||
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.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
|
||||
# TODO: Find the real delegate
|
||||
delegate = User.current
|
||||
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
|
||||
@ -190,11 +249,19 @@ class DmsfWorkflowsController < ApplicationController
|
||||
|
||||
def start
|
||||
revision = DmsfFileRevision.find_by_id(params[:dmsf_file_revision_id])
|
||||
if revision
|
||||
revision.set_workflow(@workflow.id, params[:action])
|
||||
if request.post?
|
||||
if revision.save
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
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
|
||||
@ -202,9 +269,8 @@ class DmsfWorkflowsController < ApplicationController
|
||||
end
|
||||
redirect_to :back
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
|
||||
private
|
||||
def find_workflow
|
||||
@workflow = DmsfWorkflow.find_by_id(params[:id])
|
||||
end
|
||||
|
||||
@ -49,7 +49,7 @@ module DmsfWorkflowsHelper
|
||||
|
||||
def dmsf_workflows_for_select(project, dmsf_workflow_id)
|
||||
options = Array.new
|
||||
options << [l(:option_workflow_none), nil]
|
||||
#options << [l(:option_workflow_none), nil]
|
||||
DmsfWorkflow.where(['project_id = ? OR project_id IS NULL', project.id]).each do |wf|
|
||||
options << [wf.name, wf.id]
|
||||
end
|
||||
@ -59,7 +59,7 @@ module DmsfWorkflowsHelper
|
||||
def principals_radio_button_tags(name, principals)
|
||||
s = ''
|
||||
principals.each do |principal|
|
||||
s << "<label>#{ radio_button_tag name, principal.id, false, :id => nil } #{h principal}</label>\n"
|
||||
s << "<label>#{ radio_button_tag name, principal.id * 10, false, :id => nil } #{h principal}</label>\n"
|
||||
end
|
||||
s.html_safe
|
||||
end
|
||||
|
||||
@ -57,6 +57,20 @@ class DmsfMailer < Mailer
|
||||
mail(:to => email_to, :cc => email_cc, :subject => email_subject, :from => user.mail)
|
||||
end
|
||||
|
||||
def workflow_notification(to, workflow, revision, subject, text1, text2)
|
||||
set_language_if_valid User.current.language
|
||||
@workflow = workflow
|
||||
@revision = revision
|
||||
@text1 = "The approval workflow '#{@workflow.name}' assigned to '#{@revision.file.name}' document has just #{text1}."
|
||||
unless @revision.folder
|
||||
url = url_for(:controller => 'dmsf', :action => 'edit_root', :id => @revision.project, :only_path => false)
|
||||
else
|
||||
url = url_for(:controller => 'dmsf', :action => 'edit', :id => @project, :folder_id => @revision.folder, :only_path => false)
|
||||
end
|
||||
@text2 = "#{text2} #{url}."
|
||||
mail :to => to, :subject => subject
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_notify_user_emails(user, files)
|
||||
@ -93,5 +107,5 @@ class DmsfMailer < Mailer
|
||||
|
||||
notify_members.collect {|m| m.user.mail }
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
@ -28,6 +28,14 @@ class DmsfWorkflow < ActiveRecord::Base
|
||||
STATE_WAITING_FOR_APPROVAL = 1
|
||||
STATE_APPROVED = 2
|
||||
STATE_REJECTED = 4
|
||||
|
||||
def participiants
|
||||
users = Array.new
|
||||
self.dmsf_workflow_steps.each do |step|
|
||||
users << step.user
|
||||
end
|
||||
users
|
||||
end
|
||||
|
||||
def self.workflows(project)
|
||||
project ? where(:project_id => project) : where('project_id IS NULL')
|
||||
@ -110,7 +118,7 @@ class DmsfWorkflow < ActiveRecord::Base
|
||||
def next_assignments(dmsf_file_revision_id)
|
||||
results = Array.new
|
||||
self.dmsf_workflow_steps.each do |step|
|
||||
break unless results.empty? || results[0].step.step == step.step
|
||||
break unless results.empty? || results[0].dmsf_workflow_step.step == step.step
|
||||
step.dmsf_workflow_step_assignments.each do |assignment|
|
||||
if assignment.dmsf_file_revision_id == dmsf_file_revision_id
|
||||
if assignment.dmsf_workflow_step_actions.empty?
|
||||
@ -134,14 +142,11 @@ class DmsfWorkflow < ActiveRecord::Base
|
||||
def self.assignments_to_users_str(assignments)
|
||||
str = ''
|
||||
if assignments
|
||||
assignments.each_with_index do |assignment, index|
|
||||
user = User.find_by_id assignment.user_id
|
||||
if user
|
||||
if index > 0
|
||||
str << ', '
|
||||
end
|
||||
str << user.name
|
||||
assignments.each_with_index do |assignment, index|
|
||||
if index > 0
|
||||
str << ', '
|
||||
end
|
||||
str << assignment.user.name
|
||||
end
|
||||
end
|
||||
str
|
||||
@ -153,33 +158,38 @@ class DmsfWorkflow < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
def try_finish(dmsf_file_revision_id, action, user_id)
|
||||
revision = DmsfFileRevision.find_by_id dmsf_file_revision_id
|
||||
if revision
|
||||
case action.action
|
||||
when DmsfWorkflowStepAction::ACTION_APPROVE
|
||||
self.dmsf_workflow_steps.each do |step|
|
||||
step.dmsf_workflow_step_assignments.each do |assignment|
|
||||
if assignment.dmsf_file_revision_id == dmsf_file_revision_id.to_i
|
||||
if assignment.dmsf_workflow_step_actions.empty?
|
||||
return false
|
||||
end
|
||||
assignment.dmsf_workflow_step_actions.each do |act|
|
||||
return false unless act.is_finished?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
revision.update_attribute(:workflow, DmsfWorkflow::STATE_APPROVED)
|
||||
return true
|
||||
when DmsfWorkflowStepAction::ACTION_REJECT
|
||||
revision.update_attribute(:workflow, DmsfWorkflow::STATE_REJECTED)
|
||||
return true
|
||||
when DmsfWorkflowStepAction::ACTION_DELEGATE
|
||||
assignment = DmsfWorkflowStepAssignment.find_by_id(action.dmsf_workflow_step_assignment_id)
|
||||
assignment.update_attribute(:user_id, user_id) if assignment
|
||||
end
|
||||
def try_finish(revision, action, user_id)
|
||||
case action.action
|
||||
when DmsfWorkflowStepAction::ACTION_APPROVE
|
||||
self.dmsf_workflow_steps.each do |step|
|
||||
step.dmsf_workflow_step_assignments.each do |assignment|
|
||||
if assignment.dmsf_file_revision_id == revision.id
|
||||
if assignment.dmsf_workflow_step_actions.empty?
|
||||
return false
|
||||
end
|
||||
assignment.dmsf_workflow_step_actions.each do |act|
|
||||
return false unless act.is_finished?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
revision.update_attribute(:workflow, DmsfWorkflow::STATE_APPROVED)
|
||||
return true
|
||||
when DmsfWorkflowStepAction::ACTION_REJECT
|
||||
revision.update_attribute(:workflow, DmsfWorkflow::STATE_REJECTED)
|
||||
return true
|
||||
when DmsfWorkflowStepAction::ACTION_DELEGATE
|
||||
#assignment = DmsfWorkflowStepAssignment.find_by_id(action.dmsf_workflow_step_assignment_id)
|
||||
#assignment.update_attribute(:user_id, user_id) if assignment
|
||||
self.dmsf_workflow_steps.each do |step|
|
||||
step.dmsf_workflow_step_assignments.each do |assignment|
|
||||
if assignment.id == action.dmsf_workflow_step_assignment_id
|
||||
assignment.update_attribute(:user_id, user_id)
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -18,14 +18,9 @@
|
||||
|
||||
class DmsfWorkflowStepAssignment < ActiveRecord::Base
|
||||
belongs_to :dmsf_workflow_step
|
||||
|
||||
belongs_to :user
|
||||
has_many :dmsf_workflow_step_actions, :dependent => :destroy
|
||||
|
||||
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
|
||||
end
|
||||
end
|
||||
15
app/views/dmsf_mailer/workflow_notification.html.erb
Normal file
15
app/views/dmsf_mailer/workflow_notification.html.erb
Normal file
@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
|
||||
</head>
|
||||
<body>
|
||||
<p>Dear user,</p>
|
||||
<p>
|
||||
<%= @text1 %>
|
||||
</p>
|
||||
<p>
|
||||
<%= @text2 %>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
4
app/views/dmsf_mailer/workflow_notification.text.erb
Normal file
4
app/views/dmsf_mailer/workflow_notification.text.erb
Normal file
@ -0,0 +1,4 @@
|
||||
Dear user,
|
||||
<%= @text1 %>
|
||||
|
||||
<%= @text2 %>
|
||||
@ -241,4 +241,5 @@ en:
|
||||
dmsf_new_step: New step
|
||||
message_dmsf_wokflow_note: Your note...
|
||||
info_revision: "r%{rev}"
|
||||
link_workflow: Workflow
|
||||
link_workflow: Workflow
|
||||
notice_workflow_started: 'Approval workflow successfully started'
|
||||
54
lib/tasks/dmsf_alert_approvals.rake
Normal file
54
lib/tasks/dmsf_alert_approvals.rake
Normal file
@ -0,0 +1,54 @@
|
||||
# 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.
|
||||
|
||||
desc <<-END_DESC
|
||||
Alert all users who are expected to do an approval in the current approval steps
|
||||
|
||||
Available options:
|
||||
|
||||
Example:
|
||||
rake redmine:dmsf_alert_approvals RAILS_ENV="production"
|
||||
END_DESC
|
||||
require File.expand_path(File.dirname(__FILE__) + "/../../../../config/environment")
|
||||
|
||||
class DmsfAlertApprovals
|
||||
|
||||
def self.alert
|
||||
revisions = DmsfFileRevision.where(:workflow => 1)
|
||||
revisions.each do |revision|
|
||||
next unless revision.file.last_revision == revision
|
||||
workflow = DmsfWorkflow.find_by_id revision.dmsf_workflow_id
|
||||
next unless workflow
|
||||
assignments = workflow.next_assignments revision.id
|
||||
DmsfMailer.workflow_notification(
|
||||
assignments.collect{|a| a.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
|
||||
Rails.logger.info "#{assignments.collect{|a| a.user.login}.join(',')} were alerted in order to do an approval of [workflow = #{workflow.id}, revision = #{revision.id}]"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
namespace :redmine do
|
||||
task :dmsf_alert_approvals => :environment do
|
||||
DmsfAlertApprovals.alert
|
||||
end
|
||||
end
|
||||
@ -58,8 +58,4 @@ class WorkflowStepAssignmentTest < RedmineDmsf::Test::UnitTest
|
||||
assert_nil DmsfWorkflowStepAssignment.find_by_id(1)
|
||||
assert_nil DmsfWorkflowStepAction.find_by_id(1)
|
||||
end
|
||||
|
||||
def test_step
|
||||
assert_equal @wfsa1.step, DmsfWorkflowStep.find_by_id(@wfsa1.dmsf_workflow_step_id)
|
||||
end
|
||||
end
|
||||
|
||||
@ -175,4 +175,9 @@ class DmsfWorkflowTest < RedmineDmsf::Test::UnitTest
|
||||
# assert_equal @revision2.workflow, DmsfWorkflow::STATE_WAITING_FOR_APPROVAL
|
||||
assert true
|
||||
end
|
||||
|
||||
def test_participiants
|
||||
# TODO:
|
||||
assert true
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user