2014-10-23 11:30:34 +08:00
# Redmine - project management software
# Copyright (C) 2006-2013 Jean-Philippe Lang
#
# 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 IssuesController < ApplicationController
layout 'base_projects' #Added by young
default_search_scope :issues
2015-01-14 16:08:56 +08:00
before_filter :authorize1 , :only = > [ :show ]
2015-11-16 17:21:26 +08:00
before_filter :find_issue , :only = > [ :show , :edit , :update , :add_journal , :add_journal_in_org ]
2014-10-23 11:30:34 +08:00
before_filter :find_issues , :only = > [ :bulk_edit , :bulk_update , :destroy ]
before_filter :find_project , :only = > [ :new , :create , :update_form ]
2015-01-13 18:24:14 +08:00
#before_filter :authorize, :except => [:index, :show]
2015-12-18 09:46:28 +08:00
before_filter :authorize , :except = > [ :index , :add_journal , :add_journal_in_org , :delete_journal , :reply , :add_reply ]
2015-01-13 18:24:14 +08:00
2014-10-23 11:30:34 +08:00
before_filter :find_optional_project , :only = > [ :index ]
before_filter :check_for_default_issue_status , :only = > [ :new , :create ]
before_filter :build_new_issue_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
2016-01-14 16:58:40 +08:00
include ApplicationHelper
2014-10-23 11:30:34 +08:00
def index
2016-10-10 10:41:41 +08:00
# 顶部导航
@project_menu_type = 2
2016-09-28 10:40:56 +08:00
# 为了性能所有用了两种模式, issue的@query查询所有的没有优势
# 但是对过滤条件很有有时
2016-09-27 18:01:26 +08:00
if params [ :set_filter ] != " 1 "
@project_base_tag = ( params [ :project_id ] || @issue . project ) ? 'base_projects' :'base'
2016-09-28 10:40:56 +08:00
if User . current . member_of? ( @project )
@issues_filter = Issue . where ( :project_id = > @project . id ) . order ( 'updated_on desc' )
else
@issues_filter = Issue . where ( :project_id = > @project . id , :is_private = > 0 ) . order ( 'updated_on desc' )
end
open_and_close_num ( @project )
2016-09-27 19:44:24 +08:00
@issue_count = @issues_filter . count
2016-09-22 14:38:45 +08:00
@limit = 10
@is_remote = true
@issue_pages = Paginator . new @issue_count , @limit , params [ 'page' ] || 1
2014-10-23 11:30:34 +08:00
@offset || = @issue_pages . offset
2016-09-27 19:44:24 +08:00
@issues = paginateHelper @issues_filter , @limit
2014-10-23 11:30:34 +08:00
respond_to do | format |
2015-03-06 14:55:21 +08:00
format . js
2014-10-23 11:30:34 +08:00
format . html { render :template = > 'issues/index' , :layout = > @project_base_tag } #by young
2016-09-21 10:18:40 +08:00
format . api { Issue . load_visible_relations ( @issues ) if include_in_api_response? ( 'relations' ) }
format . xls { filename = " #{ @project . name . to_s } _ #{ l ( :label_issue_list_xls ) } .xls "
2016-09-27 18:01:26 +08:00
send_data ( issue_list_xls ( @issues_filter ) , :type = > 'application/octet-stream' , :filename = > filename_for_content_disposition ( filename ) )
2016-09-21 10:18:40 +08:00
}
2014-10-23 11:30:34 +08:00
end
else
2016-09-27 18:01:26 +08:00
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 = ( params [ :project_id ] || @issue . project ) ? 'base_projects' :'base'
if @query . valid?
@tracker_id = params [ :tracker_id ]
@assign_to_id = params [ :assigned_to_id ]
@author_id = params [ :author_id ]
2016-10-12 16:27:50 +08:00
@priority_id = params [ :priority_id ]
2016-09-27 18:01:26 +08:00
@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'
2016-11-23 17:18:12 +08:00
2016-09-27 18:01:26 +08:00
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
2016-09-28 10:40:56 +08:00
open_and_close_num ( @project )
2016-09-27 18:01:26 +08:00
@issues_filter_assign_count = @query . issues . select { | issue | issue . assigned_to_id == User . current . id } . count
@issues_filter_author_count = @query . issues . select { | issue | issue . author_id == User . current . id } . count
@issues_filter = @query . issues ( :order = > @project_sort )
@limit = 10
@is_remote = true
@issue_pages = Paginator . new @issue_count , @limit , params [ 'page' ] || 1
@offset || = @issue_pages . offset
@issues = paginateHelper @issues_filter , @limit
2016-09-28 10:40:56 +08:00
respond_to do | format |
format . js
format . html { render :template = > 'issues/index' , :layout = > @project_base_tag } #by young
format . api { Issue . load_visible_relations ( @issues ) if include_in_api_response? ( 'relations' ) }
# format.json { render :json => @issues.map { |issue| issue.to_json}} #:json => @issues.map { |issue| issue.to_json}
format . atom { render_feed ( @issues , :title = > " #{ @project || Setting . app_title } : #{ l ( :label_issue_plural ) } " ) }
format . csv { send_data ( query_to_csv ( @issues , @query , params ) , :type = > 'text/csv; header=present' , :filename = > 'issues.csv' ) }
format . pdf { send_data ( issues_to_pdf ( @issues , @project , @query ) , :type = > 'application/pdf' , :filename = > 'issues.pdf' ) }
format . xls { filename = " #{ @project . name . to_s } _ #{ l ( :label_issue_list_xls ) } .xls "
send_data ( issue_list_xls ( @issues_filter ) , :type = > 'application/octet-stream' , :filename = > filename_for_content_disposition ( filename ) )
}
2016-09-27 18:01:26 +08:00
end
else
respond_to do | format |
format . html { render ( :template = > 'issues/index' , :layout = > @project_base_tag ) } #by young
format . any ( :atom , :csv , :pdf ) { render ( :nothing = > true ) }
format . api { render_validation_errors ( @query ) }
format . js
end
2014-10-23 11:30:34 +08:00
end
end
rescue ActiveRecord :: RecordNotFound
render_404
end
2016-09-28 10:40:56 +08:00
# 获取issue的开启统计数
def open_and_close_num project
if User . current . member_of? ( project )
@issue_open_count = Issue . where ( " project_id= #{ project . id } and status_id in (1,2,3,4,6) " ) . count
@issue_close_count = Issue . where ( :project_id = > project . id , :status_id = > 5 ) . count
else
@issue_open_count = Issue . where ( " project_id= #{ project . id } and status_id in (1,2,3,4,6) and is_private = 0 " ) . count
@issue_close_count = Issue . where ( :project_id = > project . id , :status_id = > 5 , :is_private = > 0 ) . count
end
end
2014-10-23 11:30:34 +08:00
def show
2016-10-27 16:33:00 +08:00
# 顶部导航
@project_menu_type = 2
2016-03-16 16:03:53 +08:00
# 打开编辑内容
@is_edit = true unless params [ :edit ] . nil?
2015-08-13 10:10:01 +08:00
# 当前用户查看指派给他的缺陷消息,则设置消息为已读
2015-10-08 17:42:48 +08:00
query = ForgeMessage . where ( " forge_message_type =? and user_id =? and forge_message_id =? " , " Issue " , User . current , @issue ) . first
query . update_attribute ( :viewed , true ) unless query . nil?
2015-12-17 15:14:52 +08:00
# issue 新建的at消息
User . current . at_messages . unviewed ( 'Issue' , @issue . id ) . each { | x | x . viewed! }
# 回复的at消息
@issue . journals . each do | j |
User . current . at_messages . unviewed ( 'Journal' , j . id ) . each { | x | x . viewed! }
end
2016-09-09 15:56:40 +08:00
# 缺陷状态消息更新
query_journals_ids = @issue . journals . map { | journal | journal . id }
if query_journals_ids . length > 0
query_journals = ForgeMessage . where ( " user_id =? and forge_message_type =? and forge_message_id in ( #{ query_journals_ids . join ( " , " ) } ) " , User . current . id , " Journal " )
query_journals . update_all ( :viewed = > true )
end
2015-12-31 17:08:27 +08:00
@jour_reply = Journal . new
2014-10-23 11:30:34 +08:00
@journals = @issue . journals . includes ( :user , :details ) . reorder ( " #{ Journal . table_name } .id ASC " ) . all
@journals . each_with_index { | j , i | j . indice = i + 1 }
@journals . reject! ( & :private_notes? ) unless User . current . allowed_to? ( :view_private_notes , @issue . project )
@journals . reverse! if User . current . wants_comments_in_reverse_order?
@changesets = @issue . changesets . visible . all
@changesets . reverse! if User . current . wants_comments_in_reverse_order?
@relations = @issue . relations . select { | r | r . other_issue ( @issue ) && r . other_issue ( @issue ) . visible? }
@allowed_statuses = @issue . new_statuses_allowed_to ( User . current )
@edit_allowed = User . current . allowed_to? ( :edit_issues , @project )
@priorities = IssuePriority . active
@time_entry = TimeEntry . new ( :issue = > @issue , :project = > @issue . project )
2015-05-25 15:33:52 +08:00
2014-10-23 11:30:34 +08:00
@project_base_tag = ( params [ :project_id ] || @issue . project ) ? 'base_projects' :'base' #by young
@available_watchers = ( @issue . project . users . sort + @issue . watcher_users ) . uniq
2015-12-31 17:08:27 +08:00
@journal = Journal . new ( :journalized = > @issue )
2015-05-25 15:33:52 +08:00
2015-12-09 09:59:13 +08:00
respond_to do | format |
format . html {
retrieve_previous_and_next_issue_ids
render :template = > 'issues/show' , :layout = > @project_base_tag #by young
}
format . api
format . atom { render :template = > 'journals/index' , :layout = > false , :content_type = > 'application/atom+xml' }
format . pdf {
pdf = issue_to_pdf ( @issue , :journals = > @journals )
send_data ( pdf , :type = > 'application/pdf' , :filename = > filename_for_content_disposition ( " #{ @project . identifier } - #{ @issue . id } .pdf " ) )
}
2014-10-23 11:30:34 +08:00
end
end
# Add a new issue
# The new issue will be created from an existing one if copy_from parameter is given
def new
2016-10-27 16:33:00 +08:00
# 顶部导航
@project_menu_type = 2
2014-10-23 11:30:34 +08:00
respond_to do | format |
format . html { render :action = > 'new' , :layout = > 'base_projects' }
end
end
2016-09-09 09:16:22 +08:00
# 用户发布新issue
2014-10-23 11:30:34 +08:00
def create
call_hook ( :controller_issues_new_before_save , { :params = > params , :issue = > @issue } )
@issue . save_attachments ( params [ :attachments ] || ( params [ :issue ] && params [ :issue ] [ :uploads ] ) )
2015-03-04 15:32:00 +08:00
# 给该issue在它所在的项目中所有的issues中所在的位置给一个序号
2015-03-06 11:53:16 +08:00
@issue . project_issues_index = @issue . project . issues . last . nil? ? 1 : @issue . project . issues . last . project_issues_index + 1
2016-11-07 13:28:50 +08:00
@issue . fixed_version_id = nil if @issue . fixed_version_id == 0
2016-11-10 11:11:28 +08:00
@issue . assigned_to_id = nil if @issue . assigned_to_id == 0
2014-10-23 11:30:34 +08:00
if @issue . save
2016-11-10 11:11:28 +08:00
#params[:issue][:assigned_to_id] = nil if params[:issue][:assigned_to_id].to_i == 0
2016-08-24 11:28:50 +08:00
senduser = User . find ( params [ :issue ] [ :assigned_to_id ] )
issue_id = @issue . id
issue_title = params [ :issue ] [ :subject ]
priority_id = params [ :issue ] [ :priority_id ]
ps = ProjectsService . new
2016-09-02 14:40:40 +08:00
if senduser . id != User . current . id
ps . send_wechat_project_issue_notice senduser , @issue . project , issue_id , issue_title , priority_id
end
2014-10-23 11:30:34 +08:00
call_hook ( :controller_issues_new_after_save , { :params = > params , :issue = > @issue } )
respond_to do | format |
format . html {
render_attachment_warning_if_needed ( @issue )
2015-12-21 10:30:39 +08:00
#flash[:notice] = l(:label_successful_create)
2015-03-20 11:37:09 +08:00
#flash[:notice] = l(:notice_issue_successful_create, :id => view_context.link_to("#{@issue.subject}", issue_path(@issue), :title => @issue.subject))
2014-10-23 11:30:34 +08:00
#flash[:notice] = l(:notice_issue_successful_create, :id => view_context.link_to("##{@issue.id}", issue_path(@issue), :title => @issue.subject))
if params [ :continue ]
attrs = { :tracker_id = > @issue . tracker , :parent_issue_id = > @issue . parent_issue_id } . reject { | k , v | v . nil? }
redirect_to new_project_issue_url ( @issue . project , :issue = > attrs )
else
2015-05-23 10:10:38 +08:00
redirect_to issue_url ( @issue . id )
2014-10-23 11:30:34 +08:00
end
}
format . api { render :action = > 'show' , :status = > :created , :location = > issue_url ( @issue ) }
end
return
else
respond_to do | format |
format . html { render :action = > 'new' }
format . api { render_validation_errors ( @issue ) }
end
end
end
def edit
2016-09-09 09:16:22 +08:00
# 修改实例变量的值
2014-10-23 11:30:34 +08:00
return unless update_issue_from_params
respond_to do | format |
format . html { render :layout = > 'base_projects' } #added by young
format . xml { }
end
end
2016-09-09 09:16:22 +08:00
# 用户编辑更改issue
2014-10-23 11:30:34 +08:00
def update
2016-11-21 17:21:15 +08:00
# params[:assigned_to_id] = nil if params[:assigned_to_id].to_i == 0
# params[:fixed_version_id] = nil if params[:fixed_version_id].to_i == 0
2016-01-22 14:21:17 +08:00
if params [ :issue_detail ]
2016-01-22 18:48:40 +08:00
issue = Issue . find ( params [ :id ] )
2016-01-22 14:21:17 +08:00
issue = update_user_issue_detail ( issue , params )
@saved = update_user_issue_detail ( issue , params )
return
else
2016-09-09 09:16:22 +08:00
# 修改实例变量的值
2016-01-22 14:21:17 +08:00
return unless update_issue_from_params
@issue . save_attachments ( params [ :attachments ] || ( params [ :issue ] && params [ :issue ] [ :uploads ] ) )
2016-11-10 11:11:28 +08:00
@issue . assigned_to_id = nil if @issue . assigned_to_id == 0
2016-11-21 17:21:15 +08:00
@issue . fixed_version_id = nil if @issue . fixed_version_id == 0
2016-01-22 14:21:17 +08:00
saved = false
begin
@saved = @issue . save_issue_with_child_records ( params , @time_entry )
rescue ActiveRecord :: StaleObjectError
@conflict = true
if params [ :last_journal_id ]
@conflict_journals = @issue . journals_after ( params [ :last_journal_id ] ) . all
@conflict_journals . reject! ( & :private_notes? ) unless User . current . allowed_to? ( :view_private_notes , @issue . project )
end
2014-10-23 11:30:34 +08:00
end
end
2016-01-22 14:21:17 +08:00
2015-12-17 09:22:01 +08:00
if @saved
2014-10-23 11:30:34 +08:00
#修改界面增加跟踪者
watcherlist = @issue . watcher_users
select_users = [ ]
if params [ :issue ]
if params [ :issue ] [ :watcher_user_ids ]
params [ :issue ] [ :watcher_user_ids ] . each do | user_id |
select_users << User . find ( user_id )
end
end
end
select_users . each do | user |
if watcherlist . include? user
else
@issue . add_watcher user
end
end
watcherlist . each do | user |
if select_users . include? user
else
@issue . remove_watcher user
end
end
render_attachment_warning_if_needed ( @issue )
reply_id = params [ :reference_user_id ] . to_i
if reply_id > 0
JournalReply . add_reply ( @issue . current_journal . id , reply_id , User . current . id )
end
2015-12-16 10:19:48 +08:00
#flash[:notice] = l(:notice_successful_update) unless @issue.current_journal.new_record? 去掉这个notice, 因为现在更新都是ajax操作
2014-10-23 11:30:34 +08:00
respond_to do | format |
2015-12-15 18:43:58 +08:00
format . js
2015-05-23 11:26:36 +08:00
format . html { redirect_to issue_url ( @issue . id ) }
2014-10-23 11:30:34 +08:00
format . api { render_api_ok }
end
else
respond_to do | format |
2015-12-17 09:22:01 +08:00
format . js
2014-10-23 11:30:34 +08:00
format . html { render :action = > 'edit' }
format . api { render_validation_errors ( @issue ) }
end
end
end
2016-01-22 14:21:17 +08:00
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
2014-10-23 11:30:34 +08:00
# 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 ( { } ,
2015-09-01 16:37:43 +08:00
:attachments = > params [ :copy_attachments ] . present? ,
:subtasks = > params [ :copy_subtasks ] . present?
2014-10-23 11:30:34 +08:00
)
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
2016-03-17 14:13:29 +08:00
# 增加删除页面类型,如果是个人主页,则返回该主页,项目动态则返回项目动态页眉
page_classify = params [ :page_classify ] unless params [ :page_classify ] . nil?
page_id = params [ :page_id ] unless params [ :page_id ] . nil?
2014-10-23 11:30:34 +08:00
@hours = TimeEntry . sum ( :hours , :conditions = > [ 'issue_id IN (?)' , @issues ] ) . to_f
if @hours > 0
case params [ :todo ]
2015-09-01 16:37:43 +08:00
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
2014-10-23 11:30:34 +08:00
else
2015-09-01 16:37:43 +08:00
# display the destroy form if it's a user request
return unless api_request?
2014-10-23 11:30:34 +08:00
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 |
2016-03-17 14:13:29 +08:00
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
2014-10-23 11:30:34 +08:00
format . api { render_api_ok }
end
end
2015-09-01 16:37:43 +08:00
def add_journal
2015-09-06 16:31:15 +08:00
if User . current . logged?
jour = Journal . new
jour . user_id = User . current . id
jour . notes = params [ :notes ]
jour . journalized = @issue
2015-12-31 17:08:27 +08:00
jour . save_attachments ( params [ :attachments ] )
2015-09-06 16:31:15 +08:00
jour . save
2016-01-12 15:53:15 +08:00
update_user_activity ( @issue . class , @issue . id )
update_forge_activity ( @issue . class , @issue . id )
2016-07-28 15:11:04 +08:00
@allowed_statuses = @issue . new_statuses_allowed_to ( User . current )
2015-09-06 16:31:15 +08:00
@user_activity_id = params [ :user_activity_id ]
2015-12-15 18:43:58 +08:00
if params [ :issue_id ]
@issue_id = params [ :issue_id ]
end
2016-01-08 21:18:08 +08:00
@priorities = IssuePriority . active
2015-09-06 16:31:15 +08:00
respond_to do | format |
format . js
end
2015-09-01 16:37:43 +08:00
end
end
2015-11-16 17:21:26 +08:00
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
2015-12-17 18:12:38 +08:00
#对某个journ回复,显示回复框
2015-12-17 17:15:03 +08:00
def reply
2015-12-17 18:12:38 +08:00
@issue = Issue . find ( params [ :id ] )
@jour = Journal . find ( params [ :journal_id ] )
respond_to do | format |
format . js
end
end
2015-12-17 17:15:03 +08:00
2015-12-17 18:12:38 +08:00
#给issue添加journ。回复内容包含 对某个被回复的journ的内容
def add_reply
if User . current . logged?
2016-07-21 10:30:48 +08:00
jour = Journal . find ( params [ :journal_id ] )
2015-12-17 18:12:38 +08:00
@issue = Issue . find params [ :id ]
2016-07-28 15:11:04 +08:00
@project = @issue . project
@allowed_statuses = @issue . 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 = @issue
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)
2016-07-21 10:30:48 +08:00
@user_activity_id = params [ :user_activity_id ]
if new_jour . save
update_user_activity ( @issue . class , @issue . id )
update_forge_activity ( @issue . class , @issue . id )
respond_to do | format |
format . js
end
2015-12-17 18:12:38 +08:00
end
end
2015-12-17 17:15:03 +08:00
end
2016-07-28 15:11:04 +08:00
# 需要刷新详情页面,代码同步一致
# 获取project和issue状态是为了刷新页面
# 值所以用delete是因为issue和journal在act_as_attachment中是同一个类型
# 非动态页面直接刷新,动态页面手动刷新
2015-12-17 17:15:03 +08:00
def delete_journal
2016-10-21 11:26:15 +08:00
@is_project = params [ :is_project ]
2015-12-17 17:15:03 +08:00
@issue = Issue . find ( params [ :id ] )
2016-07-28 15:11:04 +08:00
begin
2016-08-30 17:11:22 +08:00
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?
2016-07-28 15:11:04 +08:00
Journal . delete ( params [ :journal_id ] )
rescue Exception = > e
puts e
end
2016-07-21 10:30:48 +08:00
@user_activity_id = params [ :user_activity_id ]
respond_to do | format |
2016-07-28 15:11:04 +08:00
if @user_activity_id
format . js
else
format . html { redirect_to issue_url ( @issue ) }
end
2015-12-17 17:15:03 +08:00
end
end
2016-10-21 14:06:45 +08:00
def statistics
@project = Project . find ( params [ :id ] )
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
2016-10-28 18:04:49 +08:00
# 搜索结果
2016-11-23 17:18:12 +08:00
# 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)
2016-10-21 14:06:45 +08:00
2016-10-28 18:04:49 +08:00
# 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
2016-10-21 14:06:45 +08:00
#统计
@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?
2016-11-23 17:18:12 +08:00
user_id = 0
2016-10-21 14:06:45 +08:00
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 )
2016-11-23 17:18:12 +08:00
@results [ user_id ] [ :name ] = tmpuser . nil? ? " " : tmpuser . show_name
2016-10-21 14:06:45 +08:00
#所有的
@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
2014-10-23 11:30:34 +08:00
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 retrieve_previous_and_next_issue_ids
retrieve_query_from_session
if @query
2015-05-13 09:45:09 +08:00
sort_init ( @query . sort_criteria . empty? ? [ [ 'id' , 'desc' ] ] : @query . sort_criteria )
2014-10-23 11:30:34 +08:00
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
# Used by #edit and #update to set some common instance variables
# from the params
# TODO: Refactor, not everything in here is needed by #edit
def update_issue_from_params
@edit_allowed = User . current . allowed_to? ( :edit_issues , @project )
@time_entry = TimeEntry . new ( :issue = > @issue , :project = > @issue . project )
@time_entry . attributes = params [ :time_entry ]
2016-09-09 09:16:22 +08:00
# 更新issue状态时, journal表产生记录, 返回@current_journal
2014-10-23 11:30:34 +08:00
@issue . init_journal ( User . current )
issue_attributes = params [ :issue ]
if issue_attributes && params [ :conflict_resolution ]
case params [ :conflict_resolution ]
2015-09-01 16:37:43 +08:00
when 'overwrite'
issue_attributes = issue_attributes . dup
issue_attributes . delete ( :lock_version )
when 'add_notes'
issue_attributes = issue_attributes . slice ( :notes )
when 'cancel'
redirect_to issue_url ( @issue )
return false
2014-10-23 11:30:34 +08:00
end
end
2016-08-24 11:03:38 +08:00
2016-08-24 11:28:50 +08:00
senduser = User . find ( params [ :issue ] [ :assigned_to_id ] )
2016-08-30 15:01:26 +08:00
if senduser . id != User . current . id && @issue . assigned_to_id != params [ :issue ] [ :assigned_to_id ] . to_i
2016-08-24 11:28:50 +08:00
issue_id = @issue . id
issue_title = params [ :issue ] [ :subject ]
priority_id = params [ :issue ] [ :priority_id ]
ps = ProjectsService . new
ps . send_wechat_project_issue_notice senduser , @issue . project , issue_id , issue_title , priority_id
end
2016-08-24 11:03:38 +08:00
2016-08-30 14:08:10 +08:00
@issue . safe_attributes = issue_attributes
2014-10-23 11:30:34 +08:00
@priorities = IssuePriority . active
@allowed_statuses = @issue . new_statuses_allowed_to ( User . current )
true
end
# TODO: Refactor, lots of extra code in here
# TODO: Changing tracker on an existing issue should not trigger this
def build_new_issue_from_params
if params [ :id ] . blank?
@issue = Issue . new
if params [ :copy_from ]
begin
@copy_from = Issue . visible . find ( params [ :copy_from ] )
@copy_attachments = params [ :copy_attachments ] . present? || request . get?
@copy_subtasks = params [ :copy_subtasks ] . present? || request . get?
@issue . copy_from ( @copy_from , :attachments = > @copy_attachments , :subtasks = > @copy_subtasks )
rescue ActiveRecord :: RecordNotFound
render_404
return
end
end
@issue . project = @project
else
@issue = @project . issues . visible . find ( params [ :id ] )
end
@issue . project = @project
@issue . author || = User . current
# Tracker must be set before custom field values
@issue . tracker || = @project . trackers . find ( ( params [ :issue ] && params [ :issue ] [ :tracker_id ] ) || params [ :tracker_id ] || :first )
if @issue . tracker . nil?
render_error l ( :error_no_tracker_in_project )
return false
end
@issue . start_date || = Date . today if Setting . default_issue_start_date_to_creation_date?
@issue . safe_attributes = params [ :issue ]
@priorities = IssuePriority . active
@allowed_statuses = @issue . new_statuses_allowed_to ( User . current , true )
@available_watchers = ( @issue . project . users . sort + @issue . watcher_users ) . uniq
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
end