444 lines
16 KiB
Ruby
444 lines
16 KiB
Ruby
class Admin::TicketsController < OrbitAdminController
|
|
|
|
include TicketsHelper
|
|
|
|
before_action :set_smart_tags
|
|
|
|
def index
|
|
mp = current_user.member_profile rescue nil
|
|
@tickets = {}
|
|
@urgent_tickets = {}
|
|
if !mp.nil?
|
|
authorizations = Authorization.where(:role_id.in => mp.roles.collect{|mm| mm.id})
|
|
if authorizations.count == 0
|
|
@categories = ModuleApp.find_by_key("ticket").categories rescue []
|
|
@categories.each do |category|
|
|
@tickets[category] = Ticket.where(:category_id => category.id).open.not_urgent.limit(5).asc(:created_at)
|
|
@urgent_tickets[category] = Ticket.where(:category_id => category.id).open.all_urgent.asc(:created_at)
|
|
end
|
|
else
|
|
@categories = authorizations.collect{|authorization| authorization.category}
|
|
@categories.delete(nil)
|
|
@categories.uniq!
|
|
@categories.each do |category|
|
|
temp = Ticket.where(:category_id => category.id).open.not_urgent.limit(5).asc(:created_at)
|
|
@tickets[category] = temp if temp.count > 0
|
|
temp = Ticket.where(:category_id => category.id).open.all_urgent.asc(:created_at)
|
|
@urgent_tickets[category] = temp if temp.count > 0
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def my_tickets
|
|
if params[:type] == "history"
|
|
if params[:keywords].present?
|
|
@tickets = search_tickets
|
|
@tickets = @tickets.where(:taken_by => current_user.id).closed.group_by(&:category)
|
|
else
|
|
@tickets = Ticket.where(:taken_by => current_user.id).closed.group_by(&:category)
|
|
end
|
|
else
|
|
if params[:keywords].present?
|
|
@tickets = search_tickets
|
|
@tickets = @tickets.where(:taken_by => current_user.id).commenced.desc(:urgent).group_by(&:category)
|
|
else
|
|
@tickets = Ticket.where(:taken_by => current_user.id).commenced.desc(:urgent).group_by(&:category)
|
|
end
|
|
end
|
|
@categories = @tickets.keys
|
|
end
|
|
|
|
def tagged_tickets
|
|
if params[:keywords].present?
|
|
statuses = ["open","commenced", "closed"]
|
|
else
|
|
statuses = ["open","commenced"]
|
|
end
|
|
tqrs = TicketQueryResponse.where(:user_tags.in => [current_user.id.to_s], :read_by.nin => [current_user.id.to_s])
|
|
@unread_tickets = []
|
|
@read_tickets = []
|
|
tqrs.each do |tqr|
|
|
@unread_tickets << tqr.ticket_query.ticket if !tqr.ticket_query.nil? && !tqr.ticket_query.ticket.nil? && statuses.include?(tqr.ticket_query.ticket.status)
|
|
end
|
|
tqrs = TicketQueryResponse.where(:user_tags.in => [current_user.id.to_s], :read_by.in => [current_user.id.to_s])
|
|
tqrs.each do |tqr|
|
|
@read_tickets << tqr.ticket_query.ticket if !tqr.ticket_query.nil? && !tqr.ticket_query.ticket.nil? && statuses.include?(tqr.ticket_query.ticket.status)
|
|
end
|
|
@read_tickets.uniq!
|
|
@unread_tickets.uniq!
|
|
if params[:keywords].present?
|
|
tickets = search_tickets
|
|
@read_tickets = @read_tickets & tickets
|
|
@unread_tickets = @unread_tickets & tickets
|
|
end
|
|
@unread_tickets = @unread_tickets.group_by(&:category)
|
|
@read_tickets = @read_tickets.group_by(&:category)
|
|
@unread_tickets_categories = @unread_tickets.keys
|
|
@read_tickets_categories = @read_tickets.keys
|
|
end
|
|
|
|
def show
|
|
@ticket = Ticket.find(params[:id]) rescue nil
|
|
@categories = ModuleApp.find_by_key("ticket").categories
|
|
@members = []
|
|
MemberProfile.all.each do |mp|
|
|
user = mp.user rescue nil
|
|
if !user.nil? && user.id.to_s != current_user.id.to_s
|
|
avatar = (mp.avatar.thumb.url == "thumb_person.png" ? "/assets/thumb_person.png" : mp.avatar.thumb.url rescue "/assets/thumb_person.png")
|
|
@members << {
|
|
"id" => user.id.to_s,
|
|
"user_name" => (user.user_name rescue ""),
|
|
"avatar" => avatar,
|
|
"name" => (mp.name_translations rescue {"en" => "","zh_tw" => ""})
|
|
}
|
|
end
|
|
end
|
|
end
|
|
|
|
def changecategory
|
|
ticket = Ticket.find(params[:ticket_id]) rescue nil
|
|
category = Category.find(params[:category_id]) rescue nil
|
|
if !category.nil?
|
|
ticket.category_id = category.id
|
|
ticket.save
|
|
end
|
|
redirect_to admin_ticket_path(ticket.id)
|
|
end
|
|
|
|
def start
|
|
ticket = Ticket.find(params[:ticket_id]) rescue nil
|
|
ticket.status = "commenced"
|
|
ticket.taken_by = current_user.id
|
|
ticket.save
|
|
redirect_to admin_ticket_path(ticket.id)
|
|
end
|
|
|
|
def close
|
|
ticket = Ticket.find(params[:ticket_id]) rescue nil
|
|
ticket.status = "closed"
|
|
ticket.urgent = false
|
|
ticket.save
|
|
redirect_to admin_ticket_path(ticket.id)
|
|
end
|
|
|
|
def leave
|
|
ticket = Ticket.find(params[:ticket_id]) rescue nil
|
|
ticket.status = "open"
|
|
ticket.taken_by = nil
|
|
ticket.save
|
|
redirect_to admin_ticket_path(ticket.id)
|
|
end
|
|
|
|
def reopen
|
|
ticket = Ticket.find(params[:ticket_id]) rescue nil
|
|
ticket.status = "open"
|
|
ticket.reopened_count = ticket.reopened_count + 1
|
|
tq = TicketQuery.new
|
|
tq.query = params[:ticket_query]
|
|
tq.ticket = ticket
|
|
tq.save
|
|
ticket.save
|
|
response = {}
|
|
response["success"] = true
|
|
render :json => response.to_json
|
|
end
|
|
|
|
def destroy
|
|
tick = Ticket.find(params[:id]) rescue nil
|
|
tick.destroy if !tick.nil?
|
|
redirect_to admin_tickets_path
|
|
end
|
|
|
|
|
|
def toggleurgent
|
|
mark_urgent = params[:mark_urgent]
|
|
if mark_urgent
|
|
ticket = Ticket.find(params[:ticket_id]) rescue nil
|
|
if !ticket.nil?
|
|
if mark_urgent == "true"
|
|
if can_mark_urgent?(ticket)
|
|
ticket.urgent = true
|
|
ticket.save
|
|
response = {"success" => true, "can_make_urgent" => true}
|
|
else
|
|
response = {"success" => true, "can_make_urgent" => false}
|
|
end
|
|
else
|
|
ticket.urgent = false
|
|
ticket.save
|
|
response = {"success" => true, "can_make_urgent" => true}
|
|
end
|
|
else
|
|
response = {"success" => false}
|
|
end
|
|
end
|
|
render :json => response.to_json
|
|
end
|
|
|
|
def search
|
|
@tickets = search_tickets
|
|
if !@tickets.nil?
|
|
@tickets = @tickets.group_by(&:category)
|
|
@categories = @tickets.keys
|
|
else
|
|
@tickets = {}
|
|
@categories = []
|
|
end
|
|
end
|
|
|
|
def submit_response
|
|
tq = TicketQuery.find(params[:ticket_query_id]) rescue nil
|
|
if !tq.nil?
|
|
response = TicketQueryResponse.new
|
|
response.response = smart_store_link_parser(params[:ticket_query_response])
|
|
response.response_by = current_user.id
|
|
response.internal_response = params[:internal_response] if params[:internal_response].present?
|
|
response.user_tags = params[:user_tags] if params[:user_tags].present?
|
|
response.save
|
|
if !response.internal_response
|
|
notify_response_to_client(tq.ticket) rescue nil
|
|
end
|
|
tq.ticket_query_responses << response
|
|
if params[:user_tags].present?
|
|
Thread.new do
|
|
begin
|
|
send_notification_emails(response, tq.ticket)
|
|
rescue e
|
|
end
|
|
end
|
|
# url = "/admin/tickets-manage/#{tq.ticket.id.to_s}#response_#{response.id.to_s}"
|
|
# Fiber.new{
|
|
# params[:user_tags].each do |user_id|
|
|
# WebsocketRails["tag_notifications_for_#{user_id}".to_sym].trigger(:new_notification_recieved, {"ticket_link" => "<a href='#{url}'>#{tq.ticket.subject}</a>", "total_ticket_count" => Ticket.get_ticket_unread_count_for_user(user_id), "blink_message" => "#{current_user.name} tagged you!"})
|
|
# end
|
|
# }.resume
|
|
end
|
|
render :partial => "response", :object => response
|
|
else
|
|
render :json => {"success" => true}.to_json
|
|
end
|
|
end
|
|
|
|
def mark_response_read
|
|
response = TicketQueryResponse.find(params[:response_id]) rescue nil
|
|
if !response.nil?
|
|
response.read_by << current_user.id.to_s if !response.read_by.include?(current_user.id.to_s)
|
|
response.save
|
|
data = {"success" => true, "user_id" => current_user.id.to_s, "total_ticket_count" => Ticket.get_ticket_unread_count_for_user(current_user)}
|
|
else
|
|
data = {"success" => false}
|
|
end
|
|
render :json => data.to_json
|
|
end
|
|
|
|
def delete_response
|
|
response = TicketQueryResponse.find(params[:response_id]) rescue nil
|
|
response.destroy if !response.nil?
|
|
render :json => {"success" => true}.to_json
|
|
end
|
|
|
|
def tickets_by_category
|
|
@table_fields = [:tagged, :ticket_number, :site_name, :subject, :created_at, :tags, :status, :taken_by, :urgent]
|
|
statuses = params["type"] == "history" ? ["closed"] : ["open","commenced"]
|
|
@category = Category.find(params[:category_id]) rescue nil
|
|
if params[:keywords].present?
|
|
keywords = params[:keywords]
|
|
type = (keywords.is_i? ? (keywords.length == 8 ? "number" : "text") : "text")
|
|
if type == "text"
|
|
regex = Regexp.new(/[a-z]+:/)
|
|
matches = keywords.scan(regex)
|
|
if !matches.blank?
|
|
smart_field = matches.first
|
|
if @smart_search_fields.include?(smart_field)
|
|
type = "smart"
|
|
keywords = keywords.sub(smart_field,"")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if type.nil?
|
|
@tickets = Ticket.where(:category_id => @category.id, :status.in => statuses).order_by(sort)
|
|
else
|
|
case type
|
|
when "number"
|
|
@tickets = Ticket.where(:category_id => @category.id, :status.in => statuses, :uid => keywords).order_by(sort)
|
|
when "text"
|
|
@tickets = Ticket.where(:category_id => @category.id, :status.in => statuses).order_by(sort)
|
|
@tickets = search_data(@tickets,[:subject, :uid, :status, :site_type, :ticket_creater_id, :ticket_creater_name])
|
|
regex = Regexp.new(".*"+keywords+".*", "i")
|
|
sites = RegisteredSite.any_of({:title => regex},{:site_domain => regex})
|
|
sites.each do |site|
|
|
@tickets = (@tickets | site.tickets.where(:category_id => @category.id, :status.in => statuses))
|
|
end
|
|
when "smart"
|
|
@tickets = smart_search(statuses,@category,smart_field,keywords)
|
|
@tickets = @tickets.order_by(sort) rescue @tickets
|
|
end
|
|
end if !@category.nil?
|
|
@tickets = @tickets.where(:taken_by => current_user.id) if params[:takenby].present?
|
|
@tickets = Kaminari.paginate_array(@tickets).page(params[:page]).per(15) if !@tickets.nil?
|
|
end
|
|
|
|
private
|
|
|
|
def search_tickets
|
|
statuses = ["open","commenced","closed"]
|
|
if params[:keywords].present?
|
|
keywords = params[:keywords]
|
|
type = (keywords.is_i? ? (keywords.length == 8 ? "number" : "text") : "text")
|
|
if type == "text"
|
|
regex = Regexp.new(/[a-z]+:/)
|
|
matches = keywords.scan(regex)
|
|
if !matches.blank?
|
|
smart_field = matches.first
|
|
if @smart_search_fields.include?(smart_field)
|
|
type = "smart"
|
|
keywords = keywords.sub(smart_field,"")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
case type
|
|
when "number"
|
|
tickets = Ticket.where(:status.in => statuses, :uid => keywords)
|
|
when "text"
|
|
tickets = Ticket.where(:status.in => statuses)
|
|
tickets = search_data(tickets,[:subject, :uid, :status, :site_type, :ticket_creater_id, :ticket_creater_name])
|
|
regex = Regexp.new(".*"+keywords+".*", "i")
|
|
sites = RegisteredSite.any_of({:title => regex},{:site_domain => regex})
|
|
sites.each do |site|
|
|
tickets = (tickets | site.tickets.where(:status.in => statuses))
|
|
end
|
|
when "smart"
|
|
tickets = smart_search(statuses,nil,smart_field,keywords)
|
|
end
|
|
tickets
|
|
end
|
|
|
|
def can_mark_urgent?(ticket)
|
|
tickets = Ticket.where(:category_id => ticket.category_id, :urgent => true).count
|
|
return tickets < 5
|
|
end
|
|
|
|
def set_smart_tags
|
|
@smart_search_fields = ["sitename:","domain:","subject:","ticket:","status:","query:","type:","takenby:","time:"]
|
|
end
|
|
|
|
def smart_search(statuses, category = nil, smart_field, keywords)
|
|
keywords = keywords.strip.nil? ? keywords : keywords.strip
|
|
regexes = keywords.split(/\s+(?=(?:[^"]*"[^"]*")*[^"]*$)/)
|
|
regex = Regexp.union(regexes.map{|word| Regexp.new(".*"+word+".*", "i")})
|
|
tickets = []
|
|
case smart_field
|
|
when "sitename:"
|
|
sites = RegisteredSite.where(:title => regex)
|
|
sites.each do |site|
|
|
if category.nil?
|
|
tickets = site.tickets.where(:status.in => statuses).limit(25)
|
|
else
|
|
tickets = site.tickets.where(:category_id => category.id, :status.in => statuses)
|
|
end
|
|
end
|
|
when "domain:"
|
|
sites = RegisteredSite.where(:site_domain => regex)
|
|
sites.each do |site|
|
|
if category.nil?
|
|
tickets = site.tickets.where(:status.in => statuses).limit(25)
|
|
else
|
|
tickets = site.tickets.where(:category_id => category.id, :status.in => statuses)
|
|
end
|
|
end
|
|
when "subject:"
|
|
if category.nil?
|
|
tickets = Ticket.where(:subject => regex, :status.in => statuses).limit(25)
|
|
else
|
|
tickets = Ticket.where(:subject => regex, :status.in => statuses, :category_id => category.id)
|
|
end
|
|
when "ticket:"
|
|
if category.nil?
|
|
tickets = Ticket.where(:uid => keywords)
|
|
else
|
|
tickets = Ticket.where(:uid => keywords, :category_id => category.id)
|
|
end
|
|
when "status:"
|
|
if category.nil?
|
|
tickets = Ticket.where(:status => keywords).limit(25)
|
|
else
|
|
tickets = Ticket.where(:status => keywords, :category_id => category.id)
|
|
end
|
|
when "type:"
|
|
category = Category.where(:"title.en" => regex).first rescue nil
|
|
if category.nil?
|
|
category = Category.where(:"title.zh_tw" => regex).first rescue nil
|
|
end
|
|
tickets = Ticket.where(:category_id => category.id, :status.in => statuses).limit(25) if !category.nil?
|
|
when "time:"
|
|
if keywords.include?("..")
|
|
times = keywords.split("..")
|
|
start_time = times.first
|
|
end_time = times.last
|
|
start_time = start_time + ".01" if start_time.length <= 7
|
|
end_time = end_time + ".#{Time.days_in_month(end_time.split(".").last.to_i, end_time.split(".").first.to_i)}" if end_time.length <= 7
|
|
start_date = DateTime.parse(start_time) - 1 rescue nil
|
|
end_date = DateTime.parse(end_time) + 1 rescue nil
|
|
else
|
|
if keywords.length <= 7
|
|
start_time = keywords + ".01"
|
|
end_time = keywords + ".#{Time.days_in_month(keywords.split(".").last.to_i, keywords.split(".").first.to_i)}"
|
|
start_date = DateTime.parse(start_time) - 1 rescue nil
|
|
end_date = DateTime.parse(end_time) + 1 rescue nil
|
|
else
|
|
start_time = keywords
|
|
start_date = DateTime.parse(start_time) rescue nil
|
|
end_date = DateTime.parse(start_time) + 1 rescue nil
|
|
end
|
|
end
|
|
return tickets if start_date.nil? || end_date.nil?
|
|
if category.nil?
|
|
tickets = Ticket.where(:created_at => (start_date..end_date), :status.in => statuses).limit(25)
|
|
else
|
|
tickets = Ticket.where(:created_at => (start_date..end_date), :status.in => statuses, :category_id => category.id)
|
|
end
|
|
when "takenby:"
|
|
profiles = MemberProfile.any_of({:"first_name.en" => regex},{:"first_name.zh_tw" => regex},{:"last_name.en" => regex},{:"last_name.zh_tw" => regex})
|
|
profiles.each do |profile|
|
|
user_id = profile.user.id
|
|
if category.nil?
|
|
tickets = (tickets | Ticket.where(:taken_by => user_id, :status.in => statuses))
|
|
else
|
|
tickets = (tickets | Ticket.where(:taken_by => user_id, :category_id => category.id, :status.in => statuses))
|
|
end
|
|
end
|
|
when "query:"
|
|
queries = TicketQuery.where(:query => regex).limit(25)
|
|
queries.each do |query|
|
|
if category.nil?
|
|
tickets << query.ticket if statuses.include?(query.ticket.status) && !tickets.include?(query.ticket)
|
|
else
|
|
tickets << query.ticket if statuses.include?(query.ticket.status) && query.ticket.category_id == category.id && !tickets.include?(query.ticket)
|
|
end
|
|
end
|
|
if params[:sort].present?
|
|
s = Sanitize.clean(params[:sort]).to_sym
|
|
if params[:order] == "desc"
|
|
tickets = tickets.sort{|a,b| b[s] <=> a[s]}
|
|
elsif params[:order] == "asc"
|
|
tickets = tickets.sort{|a,b| a[s] <=> b[s]}
|
|
end
|
|
end
|
|
end
|
|
tickets
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|