socialforge/app/controllers/training_tasks_controller.rb

706 lines
24 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# encoding: utf-8
class TrainingTasksController < ApplicationController
layout 'base_projects'
before_filter :find_project, :only => [:index, :new, :create, :update_form, :issue_commits, :commit_for_issue, :issue_commit_delete]
before_filter :allow_manager, :only => []
before_filter :allow_members, :only => [:new, :create]
before_filter :build_new_task_from_params, :only => [:new, :create, :update_form]
before_filter :find_training_task, :only => [:show, :edit, :update, :add_journal, :complete_training_task]
# before_filter :find_issues, :only => [:bulk_edit, :bulk_update, :destroy]
# before_filter :authorize, :except => [:index, :show]
# before_filter :authorize, :except => [:new, :index,:add_journal, :add_journal_in_org,:delete_journal,:reply,:add_reply, :issue_commits, :commit_for_issue, :issue_commit_delete]
before_filter :check_for_default_issue_status, :only => [:new, :create]
before_filter :build_new_task_from_params, :only => [:new, :create, :update_form]
accept_rss_auth :index, :show
accept_api_auth :index, :show, :create, :update, :destroy
rescue_from Query::StatementInvalid, :with => :query_statement_invalid
helper :journals
helper :projects
include ProjectsHelper
helper :custom_fields
include CustomFieldsHelper
helper :issue_relations
include IssueRelationsHelper
helper :watchers
include WatchersHelper
helper :attachments
include AttachmentsHelper
helper :queries
include QueriesHelper
helper :repositories
include RepositoriesHelper
helper :sort
include SortHelper
include IssuesHelper
helper :timelog
include Redmine::Export::PDF
helper :project_score
include ApplicationHelper
def issue_commit_delete
commit_id = params[:commit_id].split(",")
issue_commit_ids = params[:issue_commit_ids]
# issue_id存在则为issue详情或者编辑的时候否则为新建Issue
# 编辑和详情的时候需要在数据库中删除记录,新建的时候在内存中删除
if params[:issue_id]
commit_issue = CommitIssues.where(:commit_id => commit_id, :issue_id => params[:issue_id], :project_id => @project.id).first
commit_issue.delete if commit_issue
end
@issue_commit_ids = issue_commit_ids - commit_id
end
# over
def index
# 顶部导航
@project_menu_type = 11
@training_tasks = TrainingTask.where(:project_id => @project.id).order('position desc')
@training_tasks_count = @training_tasks.count
@limit = 10
@is_remote = true
@training_tasks_pages = Paginator.new @training_tasks_count, @limit, params['page'] || 1
@offset ||= @training_tasks_pages.offset
@training_tasks = paginateHelper @training_tasks, @limit
respond_to do |format|
format.js
format.html
end
rescue ActiveRecord::RecordNotFound
render_404
end
def show
# 顶部导航
@project_menu_type = 11
# 打开编辑内容
@is_edit = true unless params[:edit].nil?
@jour_reply = Journal.new
@journals = @training_task.journals.includes(:user, :details).reorder("#{Journal.table_name}.id desc").all
@journals = get_no_children_comments_all @journals
@journals.each_with_index {|j,i| j.indice = i+1}
@journals.reject!(&:private_notes?) unless User.current.allowed_to?(:view_private_notes, @training_task.project)
@journals.reverse! if User.current.wants_comments_in_reverse_order?
@journal = Journal.new(:journalized => @training_task)
respond_to do |format|
format.html
format.js
end
end
# Add a new issue
# The new issue will be created from an existing one if copy_from parameter is given
def new
# 顶部导航
@project_menu_type = 11
respond_to do |format|
format.html { render :action => 'new', :layout => 'base_projects' }
end
end
# 用户发布新任务
def create
@training_task.save_attachments(params[:attachments] || (params[:training_task] && params[:training_task][:uploads]))
@training_task.subject = params[:training_task][:subject]
@training_task.description = params[:training_task][:description]
@training_task.tracker_id = params[:training_task][:tracker_id]
@training_task.position = params[:training_task][:position].to_i
if @training_task.save
respond_to do |format|
format.html {
render_attachment_warning_if_needed(@training_task)
redirect_to training_task_url(@training_task)
}
end
return
else
respond_to do |format|
format.html { render :action => 'new' }
end
end
end
def complete_training_task
taskId = @training_task.position
end
def edit
@project_menu_type = 11
# 修改实例变量的值
return unless build_new_task_from_params
respond_to do |format|
format.html {render :layout => 'base_projects' }
format.xml { }
end
end
# 用户编辑更改issue
def update
return unless build_new_task_from_params
@training_task.save_attachments(params[:attachments] || (params[:training_task] && params[:training_task][:uploads]))
if @training_task.update_attributes(params[:training_task])
respond_to do |format|
format.js
format.html{redirect_to training_task_url(@training_task)}
end
end
end
def update_user_issue_detail(issue, params)
case params[:type]
when "status"
issue.update_attribute(:status_id, params[:status_id])
when "assigned"
issue.update_attribute(:assigned_to_id, params[:assigned_to_id])
when "ratio"
issue.update_attribute(:done_ratio, params[:done_ratio])
when "prior"
issue.update_attribute(:priority_id, params[:priority_id])
end
end
# Updates the issue form when changing the project, status or tracker
# on issue creation/update
def update_form
end
# Bulk edit/copy a set of issues
def bulk_edit
@issues.sort!
@copy = params[:copy].present?
@notes = params[:notes]
if User.current.allowed_to?(:move_issues, @projects)
@allowed_projects = Issue.allowed_target_projects_on_move
if params[:issue]
@target_project = @allowed_projects.detect {|p| p.id.to_s == params[:issue][:project_id].to_s}
if @target_project
target_projects = [@target_project]
end
end
end
target_projects ||= @projects
if @copy
@available_statuses = [IssueStatus.default]
else
@available_statuses = @issues.map(&:new_statuses_allowed_to).reduce(:&)
end
@custom_fields = target_projects.map{|p|p.all_issue_custom_fields}.reduce(:&)
@assignables = target_projects.map(&:assignable_users).reduce(:&)
@trackers = target_projects.map(&:trackers).reduce(:&)
@versions = target_projects.map {|p| p.shared_versions.open}.reduce(:&)
@categories = target_projects.map {|p| p.issue_categories}.reduce(:&)
if @copy
@attachments_present = @issues.detect {|i| i.attachments.any?}.present?
@subtasks_present = @issues.detect {|i| !i.leaf?}.present?
end
@safe_attributes = @issues.map(&:safe_attribute_names).reduce(:&)
render :layout => false if request.xhr?
end
def bulk_update
@issues.sort!
@copy = params[:copy].present?
attributes = parse_params_for_bulk_issue_attributes(params)
unsaved_issue_ids = []
moved_issues = []
if @copy && params[:copy_subtasks].present?
# Descendant issues will be copied with the parent task
# Don't copy them twice
@issues.reject! {|issue| @issues.detect {|other| issue.is_descendant_of?(other)}}
end
@issues.each do |issue|
issue.reload
if @copy
issue = issue.copy({},
:attachments => params[:copy_attachments].present?,
:subtasks => params[:copy_subtasks].present?
)
end
journal = issue.init_journal(User.current, params[:notes])
issue.safe_attributes = attributes
call_hook(:controller_issues_bulk_edit_before_save, { :params => params, :issue => issue })
if issue.save
moved_issues << issue
else
# Keep unsaved issue ids to display them in flash error
unsaved_issue_ids << issue.id
end
end
set_flash_from_bulk_issue_save(@issues, unsaved_issue_ids)
if params[:follow]
if @issues.size == 1 && moved_issues.size == 1
redirect_to issue_url(moved_issues.first)
elsif moved_issues.map(&:project).uniq.size == 1
redirect_to project_issues_url(moved_issues.map(&:project).first)
end
else
redirect_back_or_default _project_issues_path(@project)
end
end
def destroy
# 增加删除页面类型,如果是个人主页,则返回该主页,项目动态则返回项目动态页眉
page_classify = params[:page_classify] unless params[:page_classify].nil?
page_id = params[:page_id] unless params[:page_id].nil?
@hours = TimeEntry.sum(:hours, :conditions => ['issue_id IN (?)', @issues]).to_f
if @hours > 0
case params[:todo]
when 'destroy'
# nothing to do
when 'nullify'
TimeEntry.update_all('issue_id = NULL', ['issue_id IN (?)', @issues])
when 'reassign'
reassign_to = @project.issues.find_by_id(params[:reassign_to_id])
if reassign_to.nil?
flash.now[:error] = l(:error_issue_not_found_in_project)
return
else
TimeEntry.update_all("issue_id = #{reassign_to.id}", ['issue_id IN (?)', @issues])
end
else
# display the destroy form if it's a user request
return unless api_request?
end
end
@issues.each do |issue|
begin
issue.reload.destroy
rescue ::ActiveRecord::RecordNotFound # raised by #reload if issue no longer exists
# nothing to do, issue was already deleted (eg. by a parent)
end
end
respond_to do |format|
if page_classify
format.html { redirect_back_or_default _project_issues_path(@project, page_classify, page_id) }
else
format.html { redirect_back_or_default _project_issues_path(@project) }
end
format.api { render_api_ok }
end
end
def add_journal
if User.current.logged?
jour = Journal.new
jour.user_id = User.current.id
jour.notes = params[:notes]
jour.journalized = @training_task
jour.save_attachments(params[:attachments])
jour.save
update_user_activity(@training_task.class, @training_task.id)
update_forge_activity(@training_task.class, @training_task.id)
# @allowed_statuses = @training_task.new_statuses_allowed_to(User.current)
@user_activity_id = params[:user_activity_id]
@priorities = IssuePriority.active
respond_to do |format|
# Issue详情单独处理
if params[:is_issue_show]
format.js{ redirect_to training_task_path(@training_task) }
else
format.js
end
end
end
end
def add_journal_in_org
if User.current.logged?
jour = Journal.new
jour.user_id = User.current.id
jour.notes = params[:notes]
jour.journalized = @issue
jour.save
org_activity = OrgActivity.where("org_act_type='Issue' and org_act_id =#{@issue.id}").first
org_activity.updated_at = jour.created_on
org_activity.save
@user_activity_id = params[:user_activity_id]
respond_to do |format|
format.js
end
end
end
#对某个journ回复,显示回复框
def reply
@training_task = TrainingTask.find(params[:id])
@jour = Journal.find(params[:journal_id])
respond_to do |format|
format.js
end
end
#给issue添加journ。回复内容包含 对某个被回复的journ的内容
def add_reply
if User.current.logged?
jour = Journal.find(params[:journal_id])
@training_task = TrainingTask.find params[:id]
@project = @training_task.project
# @allowed_statuses = @training_task.new_statuses_allowed_to(User.current)
@priorities = IssuePriority.active
new_jour = Journal.new
new_jour.user_id = User.current.id
new_jour.reply_id = params[:journal_id]
new_jour.parent_id = jour.id
new_jour.notes = params[:content]
new_jour.journalized = @training_task
new_jour.save_attachments(params[:attachments])
# new_jour = @issue.journals.build(:user_id => User.current.id, :reply_id => params[:journal_id], :notes => params[:content], :parent_id => jour.id)
@user_activity_id = params[:user_activity_id]
if new_jour.save
update_user_activity(@training_task.class, @training_task.id)
update_forge_activity(@training_task.class, @training_task.id)
respond_to do |format|
if params[:is_issue_show]
format.js{ redirect_to training_task_path(@training_task) }
else
format.js
end
end
end
=begin
@journals = @training_task.journals.includes(:user, :details).reorder("#{Journal.table_name}.id desc").all
@journals = get_no_children_comments_all @journals
@journals.each_with_index {|j,i| j.indice = i+1}
@journals.reject!(&:private_notes?) unless User.current.allowed_to?(:view_private_notes, @training_task.project)
@journals.reverse! if User.current.wants_comments_in_reverse_order?
@journal = Journal.new(:journalized => @training_task)
respond_to do |format|
#if params[:is_issue_show]
# format.js{ redirect_to training_task_path(@training_task) }
#else
format.js
#end
end
=end
end
end
# 需要刷新详情页面,代码同步一致
# 获取project和issue状态是为了刷新页面
# 值所以用delete是因为issue和journal在act_as_attachment中是同一个类型
# 非动态页面直接刷新,动态页面手动刷新
def delete_journal
@is_project = params[:is_project]
@training_task = TrainingTask.find(params[:id])
begin
forge_acts = ForgeMessage.where(:forge_message_type => "Journal", :forge_message_id => params[:journal_id])
forge_acts.destroy_all unless forge_acts.empty?
at_message = AtMessage.where(:at_message_type => "Journal", :at_message_id => params[:journal_id])
at_message.destroy_all unless at_message.empty?
Journal.delete(params[:journal_id])
rescue Exception => e
puts e
end
@user_activity_id = params[:user_activity_id]
respond_to do |format|
if @user_activity_id
format.js
else
format.js{ redirect_to training_task_path(@training_task)}
end
end
end
def statistics
@project = Project.find(params[:id])
params[:author_id].to_i != 0 ? (@author = User.find(params[:author_id].to_i).show_name) : @author = 0
case params[:tracker_id].to_i
when 1
@tracker = "缺陷"
when 2
@tracker = "功能"
when 3
@tracker = "支持"
when 4
@tracker = "任务"
when 5
@tracker = "周报"
when 0
@tracker = 0
end
params[:subject].blank? ? @search = 0 : @search = params[:subject]
params[:assigned_to_id].to_i != 0 ? (@assigned = User.find(params[:assigned_to_id].to_i).show_name) : @assigned = 0
params[:fixed_version_id].to_i != 0 ? (@version = Version.find(params[:fixed_version_id].to_i).name) : @version = 0
params[:done_ratio].to_i != -1 ? (@done = params[:done_ratio].to_i) : @done = -1
case params[:priority_id].to_i
when 1
@prior = ""
when 2
@prior = "正常"
when 3
@prior = ""
when 4
@prior = "紧急"
when 5
@prior = "立刻"
when 0
@prior = 0
end
case params[:status_id].to_i
when 1
@status = "新增"
when 2
@status = "正在解决"
when 3
@status = "已解决"
when 4
@status = "反馈"
when 5
@status = "关闭"
when 6
@status = "拒绝"
when 0
@status = 0
end
params[:issue_create_date_start].blank? ? @start_time = 0 : @start_time = params[:issue_create_date_start]
params[:issue_create_date_end].blank? ? @end_time = 0 : @end_time = params[:issue_create_date_end]
@filter_condition = true
@filter_condition = false if (@author == 0 && @tracker == 0 && @search == 0 && @assigned == 0 && @version == 0 && @done == -1 && @prior ==0 && @status == 0 && @start_time ==0 && @end_time)
if @project.nil?
render_404
end
retrieve_query
sort_init(@query.sort_criteria.empty? ? [['id', 'desc']] : @query.sort_criteria)
sort_update(@query.sortable_columns)
@query.sort_criteria = sort_criteria.to_a
@project_base_tag = 'base_projects'
if @query.valid?
@tracker_id = params[:tracker_id]
@assign_to_id = params[:assigned_to_id]
@author_id = params[:author_id]
@priority_id = params[:priority_id]
@status_id = params[:status_id]
@subject = params[:subject]
@done_ratio = params[:done_ratio]
@fixed_version_id = params[:fixed_version_id]
@issue_count = @query.issue_count
@test = params[:test]
@project_sort = 'issues.updated_on desc'
if params[:test] != "0"
case @test
when "1"
@project_sort = 'issues.created_on desc'
when "2"
@project_sort = 'issues.created_on asc'
when "3"
@project_sort = 'issues.updated_on desc'
when "4"
@project_sort = 'issues.updated_on asc'
end
end
# 搜索结果
# SELECT assigned_to_id, count(*) as ac FROM `issues` where project_id = @project.id group by assigned_to_id order by ac desc;
@issues_filter = @query.issues.sort_by{ |i| Issue.where(:project_id => @project.id , :assigned_to_id => i.assigned_to_id).count }.reverse
# @issues_filter = @query.issues(:order => @project_sort)
# if params[:type] == 1 || params[:type].nil?
# @results = @issues_filter
# elsif params[:type] == "2"
# @results = @issues_filter.collect{|result| result.status_id !=5 }
# elsif params[:type] == "3"
# @results = @issues_filter.collect{|result| result.status_id !=5 }
# end
#统计
@results = {}
#统计total
@alltotal = {}
for i in 0..5 do
@alltotal[i] = 0
end
@opentotal = {}
for i in 0..5 do
@opentotal[i] = 0
end
@closetotal = {}
for i in 0..5 do
@closetotal[i] = 0
end
#开启关闭
@issue_open_count = 0
@issue_close_count = 0
@issues_filter.each do |issue|
@alltotal[0] = @alltotal[0] + 1
@alltotal[issue.tracker_id.to_i] = @alltotal[issue.tracker_id.to_i] + 1
user_id = issue.assigned_to_id
if issue.assigned_to_id.nil?
user_id = 0
end
if !@results[user_id].nil?
@results[user_id][0] = @results[user_id][0] + 1
@results[user_id][issue.tracker_id.to_i] = @results[user_id][issue.tracker_id.to_i] + 1
if issue.status_id.to_i == 5
@issue_close_count = @issue_close_count + 1
@results[user_id][12] = @results[user_id][12]+1
@results[user_id][12+issue.tracker_id.to_i] = @results[user_id][12+issue.tracker_id.to_i]+1
@closetotal[0] = @closetotal[0] + 1
@closetotal[issue.tracker_id.to_i] = @closetotal[issue.tracker_id.to_i] + 1
else
@issue_open_count = @issue_open_count + 1
@results[user_id][6] = @results[user_id][6]+1
@results[user_id][6+issue.tracker_id.to_i] = @results[user_id][6+issue.tracker_id.to_i]+1
@opentotal[0] = @opentotal[0] + 1
@opentotal[issue.tracker_id.to_i] = @opentotal[issue.tracker_id.to_i] + 1
end
else
@results[user_id] = {}
tmpuser = User.find(user_id)
@results[user_id][:name] = tmpuser.nil? ? "" : tmpuser.show_name
#所有的
@results[user_id][0] = 1
for i in 1..17 do
@results[user_id][i] = 0
end
# @results[user_id][1] = 0
# @results[user_id][2] = 0
# @results[user_id][3] = 0
# @results[user_id][4] = 0
# @results[user_id][5] = 0
@results[user_id][issue.tracker_id.to_i] = 1
#开启的 status_id = 12346
# @results[user_id][6] = 0
# @results[user_id][7] = 0
# @results[user_id][8] = 0
# @results[user_id][9] = 0
# @results[user_id][10] = 0
# @results[user_id][11] = 0
#关闭的 status_id = 5
# @results[user_id][12] = 0
# @results[user_id][13] = 0
# @results[user_id][14] = 0
# @results[user_id][15] = 0
# @results[user_id][16] = 0
# @results[user_id][17] = 0
if issue.status_id.to_i == 5
@results[user_id][12] = 1
@results[user_id][12+issue.tracker_id.to_i] = 1
@issue_close_count = @issue_close_count+1
@closetotal[0] = @closetotal[0] + 1
@closetotal[issue.tracker_id.to_i] = @closetotal[issue.tracker_id.to_i] + 1
else
@issue_open_count = @issue_open_count+1
@results[user_id][6] = 1
@results[user_id][6+issue.tracker_id.to_i] = 1
@opentotal[0] = @opentotal[0] + 1
@opentotal[issue.tracker_id.to_i] = @opentotal[issue.tracker_id.to_i] + 1
end
end
end
respond_to do |format|
format.js
end
else
render_404
end
end
private
def find_project
project_id = params[:project_id] || (params[:issue] && params[:issue][:project_id])
@project = Project.find(project_id)
rescue ActiveRecord::RecordNotFound
render_404
end
def allow_members
if !(User.current.member_of?(@project) || User.current.admin?)
render_403
end
end
def retrieve_previous_and_next_issue_ids
retrieve_query_from_session
if @query
sort_init(@query.sort_criteria.empty? ? [['id', 'desc']] : @query.sort_criteria)
sort_update(@query.sortable_columns, 'issues_index_sort')
limit = 500
issue_ids = @query.issue_ids(:order => sort_clause, :limit => (limit + 1), :include => [:assigned_to, :tracker, :priority, :category, :fixed_version])
if (idx = issue_ids.index(@issue.id)) && idx < limit
if issue_ids.size < 500
@issue_position = idx + 1
@issue_count = issue_ids.size
end
@prev_issue_id = issue_ids[idx - 1] if idx > 0
@next_issue_id = issue_ids[idx + 1] if idx < (issue_ids.size - 1)
end
end
end
def build_new_task_from_params
if params[:id].blank?
@training_task = TrainingTask.new
@training_task.project = @project
else
@training_task = @project.training_tasks.find(params[:id])
end
@training_task.project = @project
@training_task.author ||= User.current
end
def check_for_default_issue_status
if IssueStatus.default.nil?
render_error l(:error_no_default_issue_status)
return false
end
end
def parse_params_for_bulk_issue_attributes(params)
attributes = (params[:issue] || {}).reject {|k,v| v.blank?}
attributes.keys.each {|k| attributes[k] = '' if attributes[k] == 'none'}
if custom = attributes[:custom_field_values]
custom.reject! {|k,v| v.blank?}
custom.keys.each do |k|
if custom[k].is_a?(Array)
custom[k] << '' if custom[k].delete('__none__')
else
custom[k] = '' if custom[k] == '__none__'
end
end
end
attributes
end
# Find the issue whose id is the :id parameter
# Raises a Unauthorized exception if the issue is not visible
def find_training_task
@training_task = TrainingTask.find(params[:id])
@project = @training_task.project
rescue ActiveRecord::RecordNotFound
render_404
end
end