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 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/#{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" => "#{tq.ticket.subject}", "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