diff --git a/app/controllers/ticket_overviews_controller.rb b/app/controllers/ticket_overviews_controller.rb index ac3cdeb09..97ff4b23f 100644 --- a/app/controllers/ticket_overviews_controller.rb +++ b/app/controllers/ticket_overviews_controller.rb @@ -8,7 +8,7 @@ class TicketOverviewsController < ApplicationController # get navbar overview data if !params[:view] - result = Ticket.overview( + result = Ticket::Overview.list( :current_user => current_user, ) render :json => result @@ -17,7 +17,7 @@ class TicketOverviewsController < ApplicationController # get real overview data if params[:array] - overview = Ticket.overview( + overview = Ticket::Overview.list( :view => params[:view], :current_user => current_user, :array => true, @@ -36,7 +36,7 @@ class TicketOverviewsController < ApplicationController } return end - overview = Ticket.overview( + overview = Ticket::Overview.list( :view => params[:view], # :view_mode => params[:view_mode], :current_user => User.find( current_user.id ), diff --git a/app/models/ticket.rb b/app/models/ticket.rb index b8ad95db8..a4c0ab51c 100644 --- a/app/models/ticket.rb +++ b/app/models/ticket.rb @@ -23,6 +23,7 @@ class Ticket < ApplicationModel belongs_to :create_article_sender, :class_name => 'Ticket::Article::Sender' include Ticket::Escalation + include Ticket::Subject attr_accessor :callback_loop @@ -122,7 +123,8 @@ class Ticket < ApplicationModel merge tickets - result = Ticket.find(123).merge_to( + ticket = Ticket.find(123) + result = ticket.merge_to( :ticket_id => 123, ) @@ -171,80 +173,6 @@ returns =begin -build new subject with ticket number in there - - ticket = Ticket.find(123) - result = ticket.subject_build('some subject') - -returns - - result = "[Ticket#1234567] some subject" - -=end - - def subject_build (subject) - - # clena subject - subject = self.subject_clean(subject) - - ticket_hook = Setting.get('ticket_hook') - ticket_hook_divider = Setting.get('ticket_hook_divider') - - # none position - if Setting.get('ticket_hook_position') == 'none' - return subject - end - - # right position - if Setting.get('ticket_hook_position') == 'right' - return subject + " [#{ticket_hook}#{ticket_hook_divider}#{self.number}] " - end - - # left position - return "[#{ticket_hook}#{ticket_hook_divider}#{self.number}] " + subject - end - -=begin - -clean subject remove ticket number and other not needed chars - - ticket = Ticket.find(123) - result = ticket.subject_clean('[Ticket#1234567] some subject') - -returns - - result = "some subject" - -=end - - def subject_clean (subject) - ticket_hook = Setting.get('ticket_hook') - ticket_hook_divider = Setting.get('ticket_hook_divider') - ticket_subject_size = Setting.get('ticket_subject_size') - - # remove all possible ticket hook formats with [] - subject = subject.gsub /\[#{ticket_hook}: #{self.number}\](\s+?|)/, '' - subject = subject.gsub /\[#{ticket_hook}:#{self.number}\](\s+?|)/, '' - subject = subject.gsub /\[#{ticket_hook}#{ticket_hook_divider}#{self.number}\](\s+?|)/, '' - - # remove all possible ticket hook formats without [] - subject = subject.gsub /#{ticket_hook}: #{self.number}(\s+?|)/, '' - subject = subject.gsub /#{ticket_hook}:#{self.number}(\s+?|)/, '' - subject = subject.gsub /#{ticket_hook}#{ticket_hook_divider}#{self.number}(\s+?|)/, '' - - # remove leading "..:\s" and "..[\d+]:\s" e. g. "Re: " or "Re[5]: " - subject = subject.gsub /^(..(\[\d+\])?:\s)+/, '' - - # resize subject based on config - if subject.length > ticket_subject_size.to_i - subject = subject[ 0, ticket_subject_size.to_i ] + '[...]' - end - - return subject - end - -=begin - check if user has access to ticket ticket = Ticket.find(123) @@ -342,249 +270,6 @@ returns return tickets end -=begin - -overview list - - result = Ticket.overview_list( - :current_user => User.find(123), - ) - -returns - - result = [overview1, overview2] - -=end - - def self.overview_list (data) - - # get customer overviews - if data[:current_user].is_role('Customer') - role = data[:current_user].is_role( 'Customer' ) - if data[:current_user].organization_id && data[:current_user].organization.shared - overviews = Overview.where( :role_id => role.id, :active => true ) - else - overviews = Overview.where( :role_id => role.id, :organization_shared => false, :active => true ) - end - return overviews - end - - # get agent overviews - role = data[:current_user].is_role( 'Agent' ) - overviews = Overview.where( :role_id => role.id, :active => true ) - return overviews - end - -=begin - -search tickets - - result = Ticket.overview_list( - :current_user => User.find(123), - :view => 'some_view_url', - ) - -returns - - result = { - :tickets => tickets, # [ticket1, ticket2, ticket3] - :tickets_count => tickets_count, # count of tickets - :overview => overview_selected_raw, # overview attributes - } - -=end - - def self.overview (data) - - overviews = self.overview_list(data) - - # build up attributes hash - overview_selected = nil - overview_selected_raw = nil - - overviews.each { |overview| - - # remember selected view - if data[:view] && data[:view] == overview.link - overview_selected = overview - overview_selected_raw = Marshal.load( Marshal.dump(overview.attributes) ) - end - - # replace e.g. 'current_user.id' with current_user.id - overview.condition.each { |item, value | - if value && value.class.to_s == 'String' - parts = value.split( '.', 2 ) - if parts[0] && parts[1] && parts[0] == 'current_user' - overview.condition[item] = data[:current_user][parts[1].to_sym] - end - end - } - } - - if data[:view] && !overview_selected - return - end - - # sortby - # prio - # state - # group - # customer - - # order - # asc - # desc - - # groupby - # prio - # state - # group - # customer - - # all = attributes[:myopenassigned] - # all.merge( { :group_id => groups } ) - - # @tickets = Ticket.where(:group_id => groups, attributes[:myopenassigned] ).limit(params[:limit]) - # get only tickets with permissions - if data[:current_user].is_role('Customer') - group_ids = Group.select( 'groups.id' ). - where( 'groups.active = ?', true ). - map( &:id ) - else - group_ids = Group.select( 'groups.id' ).joins(:users). - where( 'groups_users.user_id = ?', [ data[:current_user].id ] ). - where( 'groups.active = ?', true ). - map( &:id ) - end - - # overview meta for navbar - if !overview_selected - - # loop each overview - result = [] - overviews.each { |overview| - - # get count - count = Ticket.where( :group_id => group_ids ).where( self._condition( overview.condition ) ).count() - - # get meta info - all = { - :name => overview.name, - :prio => overview.prio, - :link => overview.link, - } - - # push to result data - result.push all.merge( { :count => count } ) - } - return result - end - - # get result list - if data[:array] - order_by = overview_selected[:order][:by].to_s + ' ' + overview_selected[:order][:direction].to_s - if overview_selected.group_by && !overview_selected.group_by.empty? - order_by = overview_selected.group_by + '_id, ' + order_by - end - tickets = Ticket.select( 'id' ). - where( :group_id => group_ids ). - where( self._condition( overview_selected.condition ) ). - order( order_by ). - limit( 500 ) - - ticket_ids = [] - tickets.each { |ticket| - ticket_ids.push ticket.id - } - - tickets_count = Ticket.where( :group_id => group_ids ). - where( self._condition( overview_selected.condition ) ). - count() - - return { - :ticket_list => ticket_ids, - :tickets_count => tickets_count, - :overview => overview_selected_raw, - } - end - - # get tickets for overview - data[:start_page] ||= 1 - tickets = Ticket.where( :group_id => group_ids ). - where( self._condition( overview_selected.condition ) ). - order( overview_selected[:order][:by].to_s + ' ' + overview_selected[:order][:direction].to_s )#. - # limit( overview_selected.view[ data[:view_mode].to_sym ][:per_page] ). - # offset( overview_selected.view[ data[:view_mode].to_sym ][:per_page].to_i * ( data[:start_page].to_i - 1 ) ) - - tickets_count = Ticket.where( :group_id => group_ids ). - where( self._condition( overview_selected.condition ) ). - count() - - return { - :tickets => tickets, - :tickets_count => tickets_count, - :overview => overview_selected_raw, - } - - end - def self._condition(condition) - sql = '' - bind = [nil] - condition.each {|key, value| - if sql != '' - sql += ' AND ' - end - if value.class == Array - sql += " #{key} IN (?)" - bind.push value - elsif value.class == Hash || value.class == ActiveSupport::HashWithIndifferentAccess - time = Time.now - if value['area'] == 'minute' - if value['direction'] == 'last' - time -= value['count'].to_i * 60 - else - time += value['count'].to_i * 60 - end - elsif value['area'] == 'hour' - if value['direction'] == 'last' - time -= value['count'].to_i * 60 * 60 - else - time += value['count'].to_i * 60 * 60 - end - elsif value['area'] == 'day' - if value['direction'] == 'last' - time -= value['count'].to_i * 60 * 60 * 24 - else - time += value['count'].to_i * 60 * 60 * 24 - end - elsif value['area'] == 'month' - if value['direction'] == 'last' - time -= value['count'].to_i * 60 * 60 * 24 * 31 - else - time += value['count'].to_i * 60 * 60 * 24 * 31 - end - elsif value['area'] == 'year' - if value['direction'] == 'last' - time -= value['count'].to_i * 60 * 60 * 24 * 365 - else - time += value['count'].to_i * 60 * 60 * 24 * 365 - end - end - if value['direction'] == 'last' - sql += " #{key} > ?" - bind.push time - else - sql += " #{key} < ?" - bind.push time - end - else - sql += " #{key} = ?" - bind.push value - end - } - bind[0] = sql - return bind - end =begin diff --git a/app/models/ticket/overview.rb b/app/models/ticket/overview.rb new file mode 100644 index 000000000..3bf731452 --- /dev/null +++ b/app/models/ticket/overview.rb @@ -0,0 +1,253 @@ +# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ + +require 'Overview' + +class Ticket::Overview + +=begin + +all overview by user + + result = Ticket::Overview.all( + :current_user => User.find(123), + ) + +returns + + result = [overview1, overview2] + +=end + + def self.all (data) + + # get customer overviews + if data[:current_user].is_role('Customer') + role = data[:current_user].is_role( 'Customer' ) + if data[:current_user].organization_id && data[:current_user].organization.shared + overviews = Overview.where( :role_id => role.id, :active => true ) + else + overviews = Overview.where( :role_id => role.id, :organization_shared => false, :active => true ) + end + return overviews + end + + # get agent overviews + role = data[:current_user].is_role( 'Agent' ) + overviews = Overview.where( :role_id => role.id, :active => true ) + return overviews + end + +=begin + +selected overview by user + + result = Ticket::Overview.list( + :current_user => User.find(123), + :view => 'some_view_url', + ) + +returns + + result = { + :tickets => tickets, # [ticket1, ticket2, ticket3] + :tickets_count => tickets_count, # count of tickets + :overview => overview_selected_raw, # overview attributes + } + +=end + + def self.list (data) + + overviews = self.all(data) + + # build up attributes hash + overview_selected = nil + overview_selected_raw = nil + + overviews.each { |overview| + + # remember selected view + if data[:view] && data[:view] == overview.link + overview_selected = overview + overview_selected_raw = Marshal.load( Marshal.dump(overview.attributes) ) + end + + # replace e.g. 'current_user.id' with current_user.id + overview.condition.each { |item, value | + if value && value.class.to_s == 'String' + parts = value.split( '.', 2 ) + if parts[0] && parts[1] && parts[0] == 'current_user' + overview.condition[item] = data[:current_user][parts[1].to_sym] + end + end + } + } + + if data[:view] && !overview_selected + raise "No such view '#{ data[:view] }'" + end + + # sortby + # prio + # state + # group + # customer + + # order + # asc + # desc + + # groupby + # prio + # state + # group + # customer + + # all = attributes[:myopenassigned] + # all.merge( { :group_id => groups } ) + + # @tickets = Ticket.where(:group_id => groups, attributes[:myopenassigned] ).limit(params[:limit]) + # get only tickets with permissions + if data[:current_user].is_role('Customer') + group_ids = Group.select( 'groups.id' ). + where( 'groups.active = ?', true ). + map( &:id ) + else + group_ids = Group.select( 'groups.id' ).joins(:users). + where( 'groups_users.user_id = ?', [ data[:current_user].id ] ). + where( 'groups.active = ?', true ). + map( &:id ) + end + + # overview meta for navbar + if !overview_selected + + # loop each overview + result = [] + overviews.each { |overview| + + # get count + count = Ticket.where( :group_id => group_ids ).where( _condition( overview.condition ) ).count() + + # get meta info + all = { + :name => overview.name, + :prio => overview.prio, + :link => overview.link, + } + + # push to result data + result.push all.merge( { :count => count } ) + } + return result + end + + # get result list + if data[:array] + order_by = overview_selected[:order][:by].to_s + ' ' + overview_selected[:order][:direction].to_s + if overview_selected.group_by && !overview_selected.group_by.empty? + order_by = overview_selected.group_by + '_id, ' + order_by + end + tickets = Ticket.select( 'id' ). + where( :group_id => group_ids ). + where( _condition( overview_selected.condition ) ). + order( order_by ). + limit( 500 ) + + ticket_ids = [] + tickets.each { |ticket| + ticket_ids.push ticket.id + } + + tickets_count = Ticket.where( :group_id => group_ids ). + where( _condition( overview_selected.condition ) ). + count() + + return { + :ticket_list => ticket_ids, + :tickets_count => tickets_count, + :overview => overview_selected_raw, + } + end + + # get tickets for overview + data[:start_page] ||= 1 + tickets = Ticket.where( :group_id => group_ids ). + where( _condition( overview_selected.condition ) ). + order( overview_selected[:order][:by].to_s + ' ' + overview_selected[:order][:direction].to_s )#. + # limit( overview_selected.view[ data[:view_mode].to_sym ][:per_page] ). + # offset( overview_selected.view[ data[:view_mode].to_sym ][:per_page].to_i * ( data[:start_page].to_i - 1 ) ) + + tickets_count = Ticket.where( :group_id => group_ids ). + where( _condition( overview_selected.condition ) ). + count() + + return { + :tickets => tickets, + :tickets_count => tickets_count, + :overview => overview_selected_raw, + } + + end + + private + def self._condition(condition) + sql = '' + bind = [nil] + condition.each {|key, value| + if sql != '' + sql += ' AND ' + end + if value.class == Array + sql += " #{key} IN (?)" + bind.push value + elsif value.class == Hash || value.class == ActiveSupport::HashWithIndifferentAccess + time = Time.now + if value['area'] == 'minute' + if value['direction'] == 'last' + time -= value['count'].to_i * 60 + else + time += value['count'].to_i * 60 + end + elsif value['area'] == 'hour' + if value['direction'] == 'last' + time -= value['count'].to_i * 60 * 60 + else + time += value['count'].to_i * 60 * 60 + end + elsif value['area'] == 'day' + if value['direction'] == 'last' + time -= value['count'].to_i * 60 * 60 * 24 + else + time += value['count'].to_i * 60 * 60 * 24 + end + elsif value['area'] == 'month' + if value['direction'] == 'last' + time -= value['count'].to_i * 60 * 60 * 24 * 31 + else + time += value['count'].to_i * 60 * 60 * 24 * 31 + end + elsif value['area'] == 'year' + if value['direction'] == 'last' + time -= value['count'].to_i * 60 * 60 * 24 * 365 + else + time += value['count'].to_i * 60 * 60 * 24 * 365 + end + end + if value['direction'] == 'last' + sql += " #{key} > ?" + bind.push time + else + sql += " #{key} < ?" + bind.push time + end + else + sql += " #{key} = ?" + bind.push value + end + } + bind[0] = sql + return bind + end + +end \ No newline at end of file diff --git a/app/models/ticket/subject.rb b/app/models/ticket/subject.rb new file mode 100644 index 000000000..ff3c491b1 --- /dev/null +++ b/app/models/ticket/subject.rb @@ -0,0 +1,78 @@ +# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ + +module Ticket::Subject + +=begin + +build new subject with ticket number in there + + ticket = Ticket.find(123) + result = ticket.subject_build('some subject') + +returns + + result = "[Ticket#1234567] some subject" + +=end + + def subject_build (subject) + + # clena subject + subject = self.subject_clean(subject) + + ticket_hook = Setting.get('ticket_hook') + ticket_hook_divider = Setting.get('ticket_hook_divider') + + # none position + if Setting.get('ticket_hook_position') == 'none' + return subject + end + + # right position + if Setting.get('ticket_hook_position') == 'right' + return subject + " [#{ticket_hook}#{ticket_hook_divider}#{self.number}] " + end + + # left position + return "[#{ticket_hook}#{ticket_hook_divider}#{self.number}] " + subject + end + +=begin + +clean subject remove ticket number and other not needed chars + + ticket = Ticket.find(123) + result = ticket.subject_clean('[Ticket#1234567] some subject') + +returns + + result = "some subject" + +=end + + def subject_clean (subject) + ticket_hook = Setting.get('ticket_hook') + ticket_hook_divider = Setting.get('ticket_hook_divider') + ticket_subject_size = Setting.get('ticket_subject_size') + + # remove all possible ticket hook formats with [] + subject = subject.gsub /\[#{ticket_hook}: #{self.number}\](\s+?|)/, '' + subject = subject.gsub /\[#{ticket_hook}:#{self.number}\](\s+?|)/, '' + subject = subject.gsub /\[#{ticket_hook}#{ticket_hook_divider}#{self.number}\](\s+?|)/, '' + + # remove all possible ticket hook formats without [] + subject = subject.gsub /#{ticket_hook}: #{self.number}(\s+?|)/, '' + subject = subject.gsub /#{ticket_hook}:#{self.number}(\s+?|)/, '' + subject = subject.gsub /#{ticket_hook}#{ticket_hook_divider}#{self.number}(\s+?|)/, '' + + # remove leading "..:\s" and "..[\d+]:\s" e. g. "Re: " or "Re[5]: " + subject = subject.gsub /^(..(\[\d+\])?:\s)+/, '' + + # resize subject based on config + if subject.length > ticket_subject_size.to_i + subject = subject[ 0, ticket_subject_size.to_i ] + '[...]' + end + + return subject + end +end \ No newline at end of file diff --git a/lib/session.rb b/lib/session.rb index 01a9ec569..333239b42 100644 --- a/lib/session.rb +++ b/lib/session.rb @@ -395,7 +395,7 @@ class UserState # overview cache_key = @cache_key + '_overview' if CacheIn.expired(cache_key) - overview = Ticket.overview( + overview = Ticket::Overview.list( :current_user => user, ) overview_cache = CacheIn.get( cache_key, { :re_expire => true } ) @@ -405,20 +405,19 @@ class UserState # puts overview.inspect # puts '------' # puts overview_cache.inspect - CacheIn.set( cache_key, overview, { :expires_in => 3.seconds } ) + CacheIn.set( cache_key, overview, { :expires_in => 4.seconds } ) end end # overview lists - overviews = Ticket.overview_list( + overviews = Ticket::Overview.all( :current_user => user, ) overviews.each { |overview| cache_key = @cache_key + '_overview_data_' + overview.link if CacheIn.expired(cache_key) - overview_data = Ticket.overview( + overview_data = Ticket::Overview.list( :view => overview.link, -# :view_mode => params[:view_mode], :current_user => user, :array => true, ) @@ -638,7 +637,7 @@ class ClientState end # overview_data - overviews = Ticket.overview_list( + overviews = Ticket::Overview.all( :current_user => user, ) overviews.each { |overview|