#48 Approval workflow available when aploading a file

This commit is contained in:
Karel Picman 2017-06-01 13:04:59 +02:00
parent 84d971404c
commit c2f9b9f117
13 changed files with 249 additions and 51 deletions

View File

@ -187,6 +187,8 @@ class DmsfWorkflowsController < ApplicationController
def assignment
if (params[:commit] == l(:button_submit)) &&
params[:dmsf_workflow_id].present? && (params[:dmsf_workflow_id] != '-1')
# DMS file
if params[:dmsf_file_revision_id].present? && params[:dmsf_link_id].blank? && params[:attachment_id].blank?
revision = DmsfFileRevision.find_by_id params[:dmsf_file_revision_id]
if revision
revision.set_workflow(params[:dmsf_workflow_id], params[:action])
@ -198,7 +200,7 @@ class DmsfWorkflowsController < ApplicationController
begin
file.lock!
rescue DmsfLockError => e
logger.warn e.message
Rails.logger.warn e.message
end
flash[:notice] = l(:notice_successful_update)
end
@ -207,8 +209,25 @@ class DmsfWorkflowsController < ApplicationController
end
end
end
end
redirect_to :back
return
# DMS link (attached)
elsif params[:dmsf_link_id].present?
@dmsf_link_id = params[:dmsf_link_id]
@dmsf_workflow_id = params[:dmsf_workflow_id]
# Attachment (attached)
elsif params[:attachment_id].present?
@attachment_id = params[:attachment_id]
@dmsf_workflow_id = params[:dmsf_workflow_id]
end
else
redirect_to :back
return
end
respond_to do |format|
format.html
format.js
end
end
def log

View File

@ -135,7 +135,7 @@ module DmsfHelper
i += 1
tree << [x, pos + (step * i)]
else
tree << [x, pos + step + i]
tree << [x, pos + (step * (i + 1))]
end
end
tree

View File

@ -111,7 +111,28 @@ module DmsfUploadHelper
else
failed_uploads.push(commited_file)
end
# Approval workflow
if commited_file[:workflow_id].present?
wf = DmsfWorkflow.find_by_id commited_file[:workflow_id]
if wf
# Assign the workflow
new_revision.set_workflow(wf.id, 'assign')
new_revision.assign_workflow(wf.id)
# Start the workflow
new_revision.set_workflow(wf.id, 'start')
if new_revision.save
begin
file.lock!
rescue DmsfLockError => e
Rails.logger.warn e.message
end
else
Rails.logger.error l(:error_workflow_assign)
end
end
end
end
# Notifications
if ((folder && folder.notification?) || (!folder && project.dmsf_notification?))
begin
recipients = DmsfMailer.get_notify_users(project, files)

View File

@ -135,7 +135,7 @@
<% end %>
<%= render(:partial => 'dmsf_files/approval_workflow_button',
:locals => {:file => file, :file_approval_allowed => @file_approval_allowed,
:workflows_available => @workflows_available, :project => project, :wf => wf }) %>
:workflows_available => @workflows_available, :project => project, :wf => wf, :dmsf_link_id => nil }) %>
</td>
<td class="hol"><%= position %></td>
<td class="hol"><%= file.last_revision.size %></td>

View File

@ -36,7 +36,11 @@
:title => l(:title_waiting_for_approval),
:remote => true,
:class => 'icon icon-wf-waiting') %>
<% else %>
<span class="icon"></span>
<% end %>
<% else %>
<span class="icon"></span>
<% end %>
<% when DmsfWorkflow::STATE_ASSIGNED %>
<% if User.current && (file.last_revision.dmsf_workflow_assigned_by == User.current.id) && wf %>
@ -46,17 +50,28 @@
:dmsf_file_revision_id => file.last_revision.id),
:title => l(:label_dmsf_wokflow_action_start),
:class => 'icon icon-wf-assigned') %>
<% else %>
<span class="icon"></span>
<% end %>
<% when DmsfWorkflow::STATE_APPROVED, DmsfWorkflow::STATE_REJECTED %>
<span class="icon"></span>
<% else %>
<% if workflows_available %>
<%= link_to('',
dmsf_link_id ?
assign_dmsf_workflow_path(
:id => project.id,
:project_id => project.id,
:dmsf_link_id => dmsf_link_id) :
assign_dmsf_workflow_path(
:id => project.id,
:project_id => project.id,
:dmsf_file_revision_id => file.last_revision.id),
:title => l(:label_dmsf_wokflow_action_assign),
:remote => true,
:class => 'icon icon-wf-none') %>
<% else %>
<span class="icon"></span>
<% end %>
<% end %>
<% end %>

View File

@ -96,6 +96,6 @@
:locals => {:file => dmsf_file,
:file_approval_allowed => User.current.allowed_to?(:file_approval, dmsf_file.project),
:workflows_available => DmsfWorkflow.where(['project_id = ? OR project_id IS NULL', dmsf_file.project.id]).exists?,
:project => dmsf_file.project, :wf => wf }) %>
:project => dmsf_file.project, :wf => wf, :dmsf_link_id => nil }) %>
</span>
</p>

View File

@ -23,5 +23,15 @@
var linksSpan = $("#dmsf_links_fields");
var linkId = "<%= @dmsf_link.id %>";
var linkName = "<%= @dmsf_link.name %>";
var title = "<%= l(:label_dmsf_wokflow_action_assign) %>";
var awf = false;
dmsfAddLink(linksSpan, linkId, linkName);
<% file = @dmsf_link.target_file %>
<% if file && !file.locked? && User.current.allowed_to?(:file_approval, file.project) %>
<% revision = file.last_revision %>
<% if revision && (revision.workflow == DmsfWorkflow::STATE_NONE) %>
awf = true;
<% end %>
<% end %>
dmsfAddLink(linksSpan, linkId, linkName, title, awf);

View File

@ -25,9 +25,20 @@
<% container.saved_dmsf_attachments.each_with_index do |attachment, i| %>
<span id="dmsf_attachments_p<%= i %>">
<%= text_field_tag("dmsf_attachments[p#{i}][filename]", attachment.filename, :class => 'filename') +
text_field_tag("dmsf_attachments[p#{i}][description]", attachment.description, :maxlength => 255, :placeholder => l(:label_optional_description), :class => 'description') +
link_to('&nbsp;'.html_safe, dmsf_attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), :method => 'delete', :remote => true, :class => 'remove-upload icon icon-del') %>
text_field_tag("dmsf_attachments[p#{i}][description]", attachment.description, :maxlength => 255,
:placeholder => l(:label_optional_description), :class => 'description') +
link_to('&nbsp;'.html_safe, dmsf_attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'),
:method => 'delete', :remote => true, :class => 'remove-upload icon icon-del') %>
<%= hidden_field_tag "dmsf_attachments[p#{i}][token]", "#{attachment.token}" %>
<% wf = container.saved_dmsf_attachments_wfs[attachment.id] %>
<% if wf %>
<a href="javascript:void(0);" title="<%= l(:title_assigned) %>" class="icon icon-wf-assigned"></a>
<%= hidden_field_tag("dmsf_attachments_wfs[p#{i}]", wf.id) if wf %>
<% else %>
<%= link_to('', assign_dmsf_workflow_path(:id => container.project.id, :project_id => container.project.id,
:attachment_id => i + 1), :title => l(:label_dmsf_wokflow_action_assign),
:remote => true, :class => 'icon icon-wf-none') %>
<% end %>
</span>
<% end %>
<% end %>
@ -40,7 +51,8 @@
:onchange => "dmsfAddInputFiles(this);",
:data => {
:max_file_size => Setting.attachment_max_size.to_i.kilobytes,
:max_file_size_message => l(:error_attachment_too_big, :max_size => number_to_human_size(Setting.attachment_max_size.to_i.kilobytes)),
:max_file_size_message => l(:error_attachment_too_big,
:max_size => number_to_human_size(Setting.attachment_max_size.to_i.kilobytes)),
:max_concurrent_uploads => Redmine::Configuration['max_concurrent_ajax_uploads'].to_i,
:upload_path => dmsf_uploads_path(:format => 'js'),
:description_placeholder => l(:label_optional_description)
@ -56,6 +68,18 @@
<input name="dmsf_links[<%= index %>]" value="<%= dmsf_link.id %>" type="hidden">
<input type="text" class='filename readonly' value="<%= dmsf_link.name %>">
<a href="#" class="remove-upload icon icon-del" onclick="$(this).parent('span').remove();return false;">&nbsp;</a>
<% wf = container.saved_dmsf_links_wfs[dmsf_link.id] %>
<% if wf %>
<a href="javascript:void(0);" title="<%= l(:title_assigned) %>" class="icon icon-wf-assigned"></a>
<%= hidden_field_tag("dmsf_links_wfs[#{dmsf_link.id}]", wf.id) if wf %>
<% else %>
<%= render(:partial => 'dmsf_files/approval_workflow_button',
:locals => {:file => dmsf_link.target_file,
:file_approval_allowed => User.current.allowed_to?(:file_approval, dmsf_link.target_file.project),
:workflows_available => DmsfWorkflow.where(
['project_id = ? OR project_id IS NULL', dmsf_link.target_file.project]).exists?,
:project => dmsf_link.target_file.project, :wf => wf, :dmsf_link_id => dmsf_link.id }) %>
<% end %>
<br/>
</span>
<% end %>

View File

@ -21,9 +21,10 @@
<h3 class="title"><%= l(:field_label_dmsf_workflow) %></h3>
<%= form_tag({:controller => 'dmsf_workflows', :action => 'assignment'},
:method => :post,
:id => 'assignment-form') do %>
:method => :post, :id => 'assignment-form', :remote => params[:dmsf_link_id] || params[:attachment_id]) do %>
<%= hidden_field_tag :dmsf_file_revision_id, params[:dmsf_file_revision_id] %>
<%= hidden_field_tag :dmsf_link_id, params[:dmsf_link_id] %>
<%= hidden_field_tag :attachment_id, params[:attachment_id] %>
<p>
<%= label_tag('workflow', "#{l(:link_workflow)}:") %>
<%= select_tag(

View File

@ -0,0 +1,45 @@
<%
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright (C) 2011-17 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.
%>
var input;
<% if @dmsf_link_id %>
input = $('input[value="<%= @dmsf_link_id %>"]');
<% else %>
input = $('input[name="dmsf_attachments[<%= @attachment_id %>][token]"]');
<% end %>
var span = input.parent();
<% if @dmsf_link_id %>
span.append(
"<input name='dmsf_links_wfs[<%= @dmsf_link_id %>]' value='<%= @dmsf_workflow_id %>' type='hidden'>");
<% else %>
span.append(
"<input name='dmsf_attachments_wfs[<%= @attachment_id %>]' value='<%= @dmsf_workflow_id %>' type='hidden'>");
<% end %>
var a = span.children("a.icon-wf-none");
a.attr("class", "icon icon-wf-assigned");
a.attr("href", "javascript:void(0);");
a.attr("title", "<%= l(:title_assigned) %>");

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
function dmsfAddLink(linksSpan, linkId, linkName) {
function dmsfAddLink(linksSpan, linkId, linkName, title, awf) {
if (linksSpan.children().length < 10) {
@ -29,9 +29,19 @@ function dmsfAddLink(linksSpan, linkId, linkName) {
linkSpan.append(
"<input name='dmsf_links[" + nextLinkId + "]' value='" + linkId + "' type='hidden'>",
"<input type='text' class='filename readonly' value='" + linkName + "'>",
$('<a>&nbsp;</a>').attr({href: "#", 'class': 'remove-upload icon icon-del'}).click(dmsfRemoveFile),
"<br/>"
).appendTo(linksSpan);
$('<a>&nbsp;</a>').attr({href: "#", 'class': 'remove-upload icon icon-del'}).click(dmsfRemoveFile)
);
if(awf) {
linkSpan.append($('<a>&nbsp;</a>').attr({
href: "/dmsf_workflows/c1/assign?dmsf_link_id=" + linkId,
'class': 'icon icon-wf-none', 'data-remote': 'true', 'title': title
}));
}
linkSpan.append("<br/>");
linkSpan.appendTo(linksSpan);
}
}
@ -42,7 +52,6 @@ function dmsfAddFile(inputEl, file, eagerUpload) {
if ($('#dmsf_attachments_fields').children().length < 10) {
var attachmentId = dmsfAddFile.nextAttachmentId++;
var fileSpan = $('<span>', { id: 'dmsf_attachments_' + attachmentId });
if($(inputEl).attr('multiple') == 'multiple') {
@ -60,7 +69,9 @@ function dmsfAddFile(inputEl, file, eagerUpload) {
maxlength: 255,
placeholder: $(inputEl).data('description-placeholder')
}).toggle(!eagerUpload),
$('<a>&nbsp</a>').attr({href: "#", 'class': 'remove-upload icon icon-del'}).click(dmsfRemoveFile).toggle(!eagerUpload)
$('<a>&nbsp;</a>').attr({href: "#", 'class': 'remove-upload icon icon-del'}).click(dmsfRemoveFile).toggle(!eagerUpload),
$('<a>&nbsp;</a>').attr({href: "/dmsf_workflows/c1/assign?attachment_id=" + attachmentId,
'class': 'icon icon-wf-none', 'data-remote': 'true'})
).appendTo('#dmsf_attachments_fields');
}
else{

View File

@ -60,18 +60,20 @@ module RedmineDmsf
params = context[:params]
issue.save_dmsf_attachments(params[:dmsf_attachments])
issue.save_dmsf_links(params[:dmsf_links])
issue.save_dmsf_attachments_wfs(params[:dmsf_attachments_wfs], params[:dmsf_attachments])
issue.save_dmsf_links_wfs(params[:dmsf_links_wfs])
end
end
def controller_issues_after_save(context)
# Create attached documents
if context.is_a?(Hash)
issue = context[:issue]
params = context[:params]
# Attach DMS documents
uploaded_files = params[:dmsf_attachments]
if uploaded_files && uploaded_files.is_a?(Hash)
system_folder = issue.system_folder(true)
uploaded_files.each_value do |uploaded_file|
uploaded_files.each do |key, uploaded_file|
upload = DmsfUpload.create_from_uploaded_attachment(issue.project, system_folder, uploaded_file)
if upload
uploaded_file[:disk_filename] = upload.disk_filename
@ -81,22 +83,40 @@ module RedmineDmsf
uploaded_file[:size] = upload.size
uploaded_file[:mime_type] = upload.mime_type
uploaded_file[:tempfile_path] = upload.tempfile_path
if params[:dmsf_attachments_wfs].present? && params[:dmsf_attachments_wfs][key].present?
uploaded_file[:workflow_id] = params[:dmsf_attachments_wfs][key].to_i
end
end
end
DmsfUploadHelper.commit_files_internal uploaded_files, issue.project, system_folder,
context[:controller]
end
dmsf_links = params[:dmsf_links]
if dmsf_links && dmsf_links.is_a?(Hash)
# Attach DMS links
issue.saved_dmsf_links.each do |l|
file = l.target_file
revision = file.last_revision
system_folder = issue.system_folder(true)
ids = dmsf_links.map(&:last)
ids.each do |id|
l = DmsfLink.find_by_id(id)
if l
if system_folder
l.project_id = system_folder.project_id
l.dmsf_folder_id = system_folder.id
if l.save
issue.dmsf_file_added l.target_file
issue.dmsf_file_added file
end
wf = issue.saved_dmsf_links_wfs[l.id]
if wf
# Assign the workflow
revision.set_workflow(wf.id, 'assign')
revision.assign_workflow(wf.id)
# Start the workflow
revision.set_workflow(wf.id, 'start')
if revision.save
begin
file.lock!
rescue DmsfLockError => e
Rails.logger.warn e.message
end
else
Rails.logger.error l(:error_workflow_assign)
end
end
end

View File

@ -62,6 +62,38 @@ module RedmineDmsf
@saved_dmsf_links || []
end
def save_dmsf_attachments_wfs(dmsf_attachments_wfs, dmsf_attachments)
if dmsf_attachments_wfs
@dmsf_attachments_wfs = {}
dmsf_attachments_wfs.each do |attachment_id, approval_workflow_id|
attachment = dmsf_attachments[attachment_id]
if attachment
a = Attachment.find_by_token(attachment[:token])
wf = DmsfWorkflow.find_by_id approval_workflow_id
@dmsf_attachments_wfs[a.id] = wf if wf && a
end
end
end
end
def saved_dmsf_attachments_wfs
@dmsf_attachments_wfs || []
end
def save_dmsf_links_wfs(dmsf_links_wfs)
if dmsf_links_wfs
@saved_dmsf_links_wfs = {}
dmsf_links_wfs.each do |dmsf_link_id, approval_workflow_id|
wf = DmsfWorkflow.find_by_id approval_workflow_id
@saved_dmsf_links_wfs[dmsf_link_id.to_i] = wf if wf
end
end
end
def saved_dmsf_links_wfs
@saved_dmsf_links_wfs || {}
end
def system_folder(create = false)
parent = DmsfFolder.system.where(:project_id => self.project_id, :title => '.Issues').first
if create && !parent