Moved back to compact module/class definition to prevent "superclass mismatch for class Ticket (TypeError)".
This commit is contained in:
parent
95e27b0994
commit
ba1d7abf91
22 changed files with 1119 additions and 1173 deletions
|
@ -1,7 +1,6 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Ticket
|
||||
module ActivityStreamLog
|
||||
# rubocop:disable ClassAndModuleChildren
|
||||
module Ticket::ActivityStreamLog
|
||||
|
||||
=begin
|
||||
|
||||
|
@ -16,25 +15,24 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def activity_stream_log (type, user_id)
|
||||
def activity_stream_log (type, user_id)
|
||||
|
||||
# return if we run import mode
|
||||
return if Setting.get('import_mode')
|
||||
# return if we run import mode
|
||||
return if Setting.get('import_mode')
|
||||
|
||||
# return if we run on init mode
|
||||
return if !Setting.get('system_init_done')
|
||||
# return if we run on init mode
|
||||
return if !Setting.get('system_init_done')
|
||||
|
||||
return if !self.class.activity_stream_support_config
|
||||
role = self.class.activity_stream_support_config[:role]
|
||||
ActivityStream.add(
|
||||
o_id: self['id'],
|
||||
type: type,
|
||||
object: self.class.name,
|
||||
group_id: self['group_id'],
|
||||
role: role,
|
||||
created_at: self.updated_at,
|
||||
created_by_id: user_id,
|
||||
)
|
||||
end
|
||||
return if !self.class.activity_stream_support_config
|
||||
role = self.class.activity_stream_support_config[:role]
|
||||
ActivityStream.add(
|
||||
o_id: self['id'],
|
||||
type: type,
|
||||
object: self.class.name,
|
||||
group_id: self['group_id'],
|
||||
role: role,
|
||||
created_at: self.updated_at,
|
||||
created_by_id: user_id,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,52 +1,50 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
# rubocop:disable ClassAndModuleChildren
|
||||
class Ticket::Article < ApplicationModel
|
||||
load 'ticket/article/assets.rb'
|
||||
include Ticket::Article::Assets
|
||||
load 'ticket/article/history_log.rb'
|
||||
include Ticket::Article::HistoryLog
|
||||
load 'ticket/article/activity_stream_log.rb'
|
||||
include Ticket::Article::ActivityStreamLog
|
||||
|
||||
class Ticket
|
||||
class Article < ApplicationModel
|
||||
load 'ticket/article/assets.rb'
|
||||
include Ticket::Article::Assets
|
||||
load 'ticket/article/history_log.rb'
|
||||
include Ticket::Article::HistoryLog
|
||||
load 'ticket/article/activity_stream_log.rb'
|
||||
include Ticket::Article::ActivityStreamLog
|
||||
belongs_to :ticket
|
||||
belongs_to :type, class_name: 'Ticket::Article::Type'
|
||||
belongs_to :sender, class_name: 'Ticket::Article::Sender'
|
||||
belongs_to :created_by, class_name: 'User'
|
||||
belongs_to :updated_by, class_name: 'User'
|
||||
before_create :check_subject
|
||||
before_update :check_subject
|
||||
notify_clients_support
|
||||
|
||||
belongs_to :ticket
|
||||
belongs_to :type, class_name: 'Ticket::Article::Type'
|
||||
belongs_to :sender, class_name: 'Ticket::Article::Sender'
|
||||
belongs_to :created_by, class_name: 'User'
|
||||
belongs_to :updated_by, class_name: 'User'
|
||||
before_create :check_subject
|
||||
before_update :check_subject
|
||||
notify_clients_support
|
||||
activity_stream_support ignore_attributes: {
|
||||
type_id: true,
|
||||
sender_id: true,
|
||||
}
|
||||
|
||||
activity_stream_support ignore_attributes: {
|
||||
type_id: true,
|
||||
sender_id: true,
|
||||
}
|
||||
history_support ignore_attributes: {
|
||||
type_id: true,
|
||||
sender_id: true,
|
||||
}
|
||||
|
||||
history_support ignore_attributes: {
|
||||
type_id: true,
|
||||
sender_id: true,
|
||||
}
|
||||
private
|
||||
|
||||
private
|
||||
|
||||
def check_subject
|
||||
if self.subject
|
||||
self.subject.gsub!(/\s|\t|\r/, ' ')
|
||||
end
|
||||
end
|
||||
|
||||
class Flag < ApplicationModel
|
||||
end
|
||||
|
||||
class Sender < ApplicationModel
|
||||
validates :name, presence: true
|
||||
latest_change_support
|
||||
end
|
||||
|
||||
class Type < ApplicationModel
|
||||
validates :name, presence: true
|
||||
latest_change_support
|
||||
def check_subject
|
||||
if self.subject
|
||||
self.subject.gsub!(/\s|\t|\r/, ' ')
|
||||
end
|
||||
end
|
||||
|
||||
class Flag < ApplicationModel
|
||||
end
|
||||
|
||||
class Sender < ApplicationModel
|
||||
validates :name, presence: true
|
||||
latest_change_support
|
||||
end
|
||||
|
||||
class Type < ApplicationModel
|
||||
validates :name, presence: true
|
||||
latest_change_support
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Ticket
|
||||
class Article
|
||||
module ActivityStreamLog
|
||||
# rubocop:disable ClassAndModuleChildren
|
||||
module Ticket::Article::ActivityStreamLog
|
||||
|
||||
=begin
|
||||
|
||||
|
@ -17,27 +15,25 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def activity_stream_log (type, user_id)
|
||||
def activity_stream_log (type, user_id)
|
||||
|
||||
# return if we run import mode
|
||||
return if Setting.get('import_mode')
|
||||
# return if we run import mode
|
||||
return if Setting.get('import_mode')
|
||||
|
||||
# return if we run on init mode
|
||||
return if !Setting.get('system_init_done')
|
||||
# return if we run on init mode
|
||||
return if !Setting.get('system_init_done')
|
||||
|
||||
return if !self.class.activity_stream_support_config
|
||||
role = self.class.activity_stream_support_config[:role]
|
||||
ticket = Ticket.lookup( id: self.ticket_id )
|
||||
ActivityStream.add(
|
||||
o_id: self['id'],
|
||||
type: type,
|
||||
object: self.class.name,
|
||||
group_id: ticket.group_id,
|
||||
role: role,
|
||||
created_at: self.updated_at,
|
||||
created_by_id: user_id,
|
||||
)
|
||||
end
|
||||
end
|
||||
return if !self.class.activity_stream_support_config
|
||||
role = self.class.activity_stream_support_config[:role]
|
||||
ticket = Ticket.lookup( id: self.ticket_id )
|
||||
ActivityStream.add(
|
||||
o_id: self['id'],
|
||||
type: type,
|
||||
object: self.class.name,
|
||||
group_id: ticket.group_id,
|
||||
role: role,
|
||||
created_at: self.updated_at,
|
||||
created_by_id: user_id,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Ticket
|
||||
class Article
|
||||
module Assets
|
||||
module Ticket::Article::Assets
|
||||
|
||||
=begin
|
||||
|
||||
|
@ -23,35 +21,33 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def assets (data)
|
||||
def assets (data)
|
||||
|
||||
if !data[ Ticket.to_app_model ]
|
||||
data[ Ticket.to_app_model ] = {}
|
||||
end
|
||||
if !data[ Ticket.to_app_model ][ self.ticket_id ]
|
||||
ticket = Ticket.find( self.ticket_id )
|
||||
data = ticket.assets(data)
|
||||
end
|
||||
|
||||
if !data[ Ticket::Article.to_app_model ]
|
||||
data[ Ticket::Article.to_app_model ] = {}
|
||||
end
|
||||
if !data[ Ticket::Article.to_app_model ][ self.id ]
|
||||
data[ Ticket::Article.to_app_model ][ self.id ] = self.attributes
|
||||
|
||||
# add attachment list to article
|
||||
data[ Ticket::Article.to_app_model ][ self.id ]['attachments'] = self.attachments
|
||||
end
|
||||
|
||||
['created_by_id', 'updated_by_id'].each {|item|
|
||||
next if !self[ item ]
|
||||
if !data[ User.to_app_model ] || !data[ User.to_app_model ][ self[ item ] ]
|
||||
user = User.lookup( id: self[ item ] )
|
||||
data = user.assets( data )
|
||||
end
|
||||
}
|
||||
data
|
||||
end
|
||||
if !data[ Ticket.to_app_model ]
|
||||
data[ Ticket.to_app_model ] = {}
|
||||
end
|
||||
if !data[ Ticket.to_app_model ][ self.ticket_id ]
|
||||
ticket = Ticket.find( self.ticket_id )
|
||||
data = ticket.assets(data)
|
||||
end
|
||||
|
||||
if !data[ Ticket::Article.to_app_model ]
|
||||
data[ Ticket::Article.to_app_model ] = {}
|
||||
end
|
||||
if !data[ Ticket::Article.to_app_model ][ self.id ]
|
||||
data[ Ticket::Article.to_app_model ][ self.id ] = self.attributes
|
||||
|
||||
# add attachment list to article
|
||||
data[ Ticket::Article.to_app_model ][ self.id ]['attachments'] = self.attachments
|
||||
end
|
||||
|
||||
['created_by_id', 'updated_by_id'].each {|item|
|
||||
next if !self[ item ]
|
||||
if !data[ User.to_app_model ] || !data[ User.to_app_model ][ self[ item ] ]
|
||||
user = User.lookup( id: self[ item ] )
|
||||
data = user.assets( data )
|
||||
end
|
||||
}
|
||||
data
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Ticket
|
||||
class Article
|
||||
module HistoryLog
|
||||
module Ticket::Article::HistoryLog
|
||||
|
||||
=begin
|
||||
|
||||
|
@ -17,18 +15,16 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def history_log (type, user_id, data = {})
|
||||
def history_log (type, user_id, data = {})
|
||||
|
||||
# if Ticketdata[:data[:Article has changed, remember related ticket to be able
|
||||
# to show article changes in ticket history
|
||||
data[:o_id] = self['id']
|
||||
data[:history_type] = type
|
||||
data[:history_object] = self.class.name
|
||||
data[:related_o_id] = self['ticket_id']
|
||||
data[:related_history_object] = 'Ticket'
|
||||
data[:created_by_id] = user_id
|
||||
History.add(data)
|
||||
end
|
||||
end
|
||||
# if Ticketdata[:data[:Article has changed, remember related ticket to be able
|
||||
# to show article changes in ticket history
|
||||
data[:o_id] = self['id']
|
||||
data[:history_type] = type
|
||||
data[:history_object] = self.class.name
|
||||
data[:related_o_id] = self['ticket_id']
|
||||
data[:related_history_object] = 'Ticket'
|
||||
data[:created_by_id] = user_id
|
||||
History.add(data)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Ticket
|
||||
module Assets
|
||||
# rubocop:disable ClassAndModuleChildren
|
||||
module Ticket::Assets
|
||||
|
||||
=begin
|
||||
|
||||
|
@ -22,22 +21,21 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def assets (data)
|
||||
def assets (data)
|
||||
|
||||
if !data[ Ticket.to_app_model ]
|
||||
data[ Ticket.to_app_model ] = {}
|
||||
end
|
||||
if !data[ Ticket.to_app_model ][ self.id ]
|
||||
data[ Ticket.to_app_model ][ self.id ] = self.attributes_with_associations
|
||||
end
|
||||
['created_by_id', 'updated_by_id', 'owner_id', 'customer_id'].each {|item|
|
||||
next if !self[ item ]
|
||||
if !data[ User.to_app_model ] || !data[ User.to_app_model ][ self[ item ] ]
|
||||
user = User.lookup( id: self[ item ] )
|
||||
data = user.assets( data )
|
||||
end
|
||||
}
|
||||
data
|
||||
if !data[ Ticket.to_app_model ]
|
||||
data[ Ticket.to_app_model ] = {}
|
||||
end
|
||||
if !data[ Ticket.to_app_model ][ self.id ]
|
||||
data[ Ticket.to_app_model ][ self.id ] = self.attributes_with_associations
|
||||
end
|
||||
['created_by_id', 'updated_by_id', 'owner_id', 'customer_id'].each {|item|
|
||||
next if !self[ item ]
|
||||
if !data[ User.to_app_model ] || !data[ User.to_app_model ][ self[ item ] ]
|
||||
user = User.lookup( id: self[ item ] )
|
||||
data = user.assets( data )
|
||||
end
|
||||
}
|
||||
data
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Ticket
|
||||
class Counter < ApplicationModel
|
||||
end
|
||||
# rubocop:disable ClassAndModuleChildren
|
||||
class Ticket::Counter < ApplicationModel
|
||||
end
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Ticket
|
||||
module Escalation
|
||||
# rubocop:disable ClassAndModuleChildren
|
||||
module Ticket::Escalation
|
||||
|
||||
=begin
|
||||
|
||||
|
@ -15,14 +14,14 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def self.rebuild_all
|
||||
state_list_open = Ticket::State.by_category( 'open' )
|
||||
def self.rebuild_all
|
||||
state_list_open = Ticket::State.by_category( 'open' )
|
||||
|
||||
tickets = Ticket.where( state_id: state_list_open )
|
||||
tickets.each {|ticket|
|
||||
ticket.escalation_calculation
|
||||
}
|
||||
end
|
||||
tickets = Ticket.where( state_id: state_list_open )
|
||||
tickets.each {|ticket|
|
||||
ticket.escalation_calculation
|
||||
}
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
|
@ -37,128 +36,128 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def escalation_calculation
|
||||
def escalation_calculation
|
||||
|
||||
# set escalation off if ticket is already closed
|
||||
state = Ticket::State.lookup( id: self.state_id )
|
||||
if state.ignore_escalation?
|
||||
# set escalation off if ticket is already closed
|
||||
state = Ticket::State.lookup( id: self.state_id )
|
||||
if state.ignore_escalation?
|
||||
|
||||
# nothing to change
|
||||
return true if !self.escalation_time
|
||||
# nothing to change
|
||||
return true if !self.escalation_time
|
||||
|
||||
self.escalation_time = nil
|
||||
# self.first_response_escal_date = nil
|
||||
# self.close_time_escal_date = nil
|
||||
self.callback_loop = true
|
||||
self.save
|
||||
return true
|
||||
end
|
||||
|
||||
# get sla for ticket
|
||||
sla_selected = escalation_calculation_get_sla
|
||||
|
||||
# reset escalation if no sla is set
|
||||
if !sla_selected
|
||||
|
||||
# nothing to change
|
||||
return true if !self.escalation_time
|
||||
|
||||
self.escalation_time = nil
|
||||
# self.first_response_escal_date = nil
|
||||
# self.close_time_escal_date = nil
|
||||
self.callback_loop = true
|
||||
self.save
|
||||
return true
|
||||
end
|
||||
|
||||
# puts sla_selected.inspect
|
||||
# puts days.inspect
|
||||
self.escalation_time = nil
|
||||
self.first_response_escal_date = nil
|
||||
self.update_time_escal_date = nil
|
||||
self.close_time_escal_date = nil
|
||||
|
||||
# first response
|
||||
if sla_selected.first_response_time
|
||||
|
||||
# get escalation date without pending time
|
||||
self.first_response_escal_date = TimeCalculation.dest_time( self.created_at, sla_selected.first_response_time, sla_selected.data, sla_selected.timezone )
|
||||
|
||||
# get pending time between created and first response escal. time
|
||||
time_in_pending = escalation_suspend( self.created_at, self.first_response_escal_date, 'relative', sla_selected, sla_selected.first_response_time )
|
||||
|
||||
# get new escalation time (original escal_date + time_in_pending)
|
||||
self.first_response_escal_date = TimeCalculation.dest_time( self.first_response_escal_date, time_in_pending.to_i, sla_selected.data, sla_selected.timezone )
|
||||
|
||||
# set ticket escalation
|
||||
self.escalation_time = calculation_higher_time( self.escalation_time, self.first_response_escal_date, self.first_response )
|
||||
end
|
||||
if self.first_response# && !self.first_response_in_min
|
||||
|
||||
# get response time in min between created and first response
|
||||
self.first_response_in_min = escalation_suspend( self.created_at, self.first_response, 'real', sla_selected )
|
||||
|
||||
end
|
||||
|
||||
# set time to show if sla is raised ot in
|
||||
if sla_selected.first_response_time && self.first_response_in_min
|
||||
self.first_response_diff_in_min = sla_selected.first_response_time - self.first_response_in_min
|
||||
end
|
||||
|
||||
# update time
|
||||
last_update = self.last_contact_agent
|
||||
if !last_update
|
||||
last_update = self.created_at
|
||||
end
|
||||
if sla_selected.update_time
|
||||
self.update_time_escal_date = TimeCalculation.dest_time( last_update, sla_selected.update_time, sla_selected.data, sla_selected.timezone )
|
||||
|
||||
# get pending time between created and update escal. time
|
||||
time_in_pending = escalation_suspend( last_update, self.update_time_escal_date, 'relative', sla_selected, sla_selected.update_time )
|
||||
|
||||
# get new escalation time (original escal_date + time_in_pending)
|
||||
self.update_time_escal_date = TimeCalculation.dest_time( self.update_time_escal_date, time_in_pending.to_i, sla_selected.data, sla_selected.timezone )
|
||||
|
||||
# set ticket escalation
|
||||
self.escalation_time = calculation_higher_time( self.escalation_time, self.update_time_escal_date, false )
|
||||
end
|
||||
if self.last_contact_agent
|
||||
self.update_time_in_min = TimeCalculation.business_time_diff( self.created_at, self.last_contact_agent, sla_selected.data, sla_selected.timezone )
|
||||
end
|
||||
|
||||
# set sla time
|
||||
if sla_selected.update_time && self.update_time_in_min
|
||||
self.update_time_diff_in_min = sla_selected.update_time - self.update_time_in_min
|
||||
end
|
||||
|
||||
# close time
|
||||
if sla_selected.close_time
|
||||
|
||||
# get escalation date without pending time
|
||||
self.close_time_escal_date = TimeCalculation.dest_time( self.created_at, sla_selected.close_time, sla_selected.data, sla_selected.timezone )
|
||||
|
||||
# get pending time between created and close escal. time
|
||||
extended_escalation = escalation_suspend( self.created_at, self.close_time_escal_date, 'relative', sla_selected, sla_selected.close_time )
|
||||
|
||||
# get new escalation time (original escal_date + time_in_pending)
|
||||
self.close_time_escal_date = TimeCalculation.dest_time( self.close_time_escal_date, extended_escalation.to_i, sla_selected.data, sla_selected.timezone )
|
||||
|
||||
# set ticket escalation
|
||||
self.escalation_time = calculation_higher_time( self.escalation_time, self.close_time_escal_date, self.close_time )
|
||||
end
|
||||
if self.close_time # && !self.close_time_in_min
|
||||
self.close_time_in_min = escalation_suspend( self.created_at, self.close_time, 'real', sla_selected )
|
||||
end
|
||||
# set sla time
|
||||
if sla_selected.close_time && self.close_time_in_min
|
||||
self.close_time_diff_in_min = sla_selected.close_time - self.close_time_in_min
|
||||
end
|
||||
if self.changed?
|
||||
self.callback_loop = true
|
||||
self.save
|
||||
end
|
||||
# self.first_response_escal_date = nil
|
||||
# self.close_time_escal_date = nil
|
||||
self.callback_loop = true
|
||||
self.save
|
||||
return true
|
||||
end
|
||||
|
||||
# get sla for ticket
|
||||
sla_selected = escalation_calculation_get_sla
|
||||
|
||||
# reset escalation if no sla is set
|
||||
if !sla_selected
|
||||
|
||||
# nothing to change
|
||||
return true if !self.escalation_time
|
||||
|
||||
self.escalation_time = nil
|
||||
# self.first_response_escal_date = nil
|
||||
# self.close_time_escal_date = nil
|
||||
self.callback_loop = true
|
||||
self.save
|
||||
return true
|
||||
end
|
||||
|
||||
# puts sla_selected.inspect
|
||||
# puts days.inspect
|
||||
self.escalation_time = nil
|
||||
self.first_response_escal_date = nil
|
||||
self.update_time_escal_date = nil
|
||||
self.close_time_escal_date = nil
|
||||
|
||||
# first response
|
||||
if sla_selected.first_response_time
|
||||
|
||||
# get escalation date without pending time
|
||||
self.first_response_escal_date = TimeCalculation.dest_time( self.created_at, sla_selected.first_response_time, sla_selected.data, sla_selected.timezone )
|
||||
|
||||
# get pending time between created and first response escal. time
|
||||
time_in_pending = escalation_suspend( self.created_at, self.first_response_escal_date, 'relative', sla_selected, sla_selected.first_response_time )
|
||||
|
||||
# get new escalation time (original escal_date + time_in_pending)
|
||||
self.first_response_escal_date = TimeCalculation.dest_time( self.first_response_escal_date, time_in_pending.to_i, sla_selected.data, sla_selected.timezone )
|
||||
|
||||
# set ticket escalation
|
||||
self.escalation_time = calculation_higher_time( self.escalation_time, self.first_response_escal_date, self.first_response )
|
||||
end
|
||||
if self.first_response# && !self.first_response_in_min
|
||||
|
||||
# get response time in min between created and first response
|
||||
self.first_response_in_min = escalation_suspend( self.created_at, self.first_response, 'real', sla_selected )
|
||||
|
||||
end
|
||||
|
||||
# set time to show if sla is raised ot in
|
||||
if sla_selected.first_response_time && self.first_response_in_min
|
||||
self.first_response_diff_in_min = sla_selected.first_response_time - self.first_response_in_min
|
||||
end
|
||||
|
||||
# update time
|
||||
last_update = self.last_contact_agent
|
||||
if !last_update
|
||||
last_update = self.created_at
|
||||
end
|
||||
if sla_selected.update_time
|
||||
self.update_time_escal_date = TimeCalculation.dest_time( last_update, sla_selected.update_time, sla_selected.data, sla_selected.timezone )
|
||||
|
||||
# get pending time between created and update escal. time
|
||||
time_in_pending = escalation_suspend( last_update, self.update_time_escal_date, 'relative', sla_selected, sla_selected.update_time )
|
||||
|
||||
# get new escalation time (original escal_date + time_in_pending)
|
||||
self.update_time_escal_date = TimeCalculation.dest_time( self.update_time_escal_date, time_in_pending.to_i, sla_selected.data, sla_selected.timezone )
|
||||
|
||||
# set ticket escalation
|
||||
self.escalation_time = calculation_higher_time( self.escalation_time, self.update_time_escal_date, false )
|
||||
end
|
||||
if self.last_contact_agent
|
||||
self.update_time_in_min = TimeCalculation.business_time_diff( self.created_at, self.last_contact_agent, sla_selected.data, sla_selected.timezone )
|
||||
end
|
||||
|
||||
# set sla time
|
||||
if sla_selected.update_time && self.update_time_in_min
|
||||
self.update_time_diff_in_min = sla_selected.update_time - self.update_time_in_min
|
||||
end
|
||||
|
||||
# close time
|
||||
if sla_selected.close_time
|
||||
|
||||
# get escalation date without pending time
|
||||
self.close_time_escal_date = TimeCalculation.dest_time( self.created_at, sla_selected.close_time, sla_selected.data, sla_selected.timezone )
|
||||
|
||||
# get pending time between created and close escal. time
|
||||
extended_escalation = escalation_suspend( self.created_at, self.close_time_escal_date, 'relative', sla_selected, sla_selected.close_time )
|
||||
|
||||
# get new escalation time (original escal_date + time_in_pending)
|
||||
self.close_time_escal_date = TimeCalculation.dest_time( self.close_time_escal_date, extended_escalation.to_i, sla_selected.data, sla_selected.timezone )
|
||||
|
||||
# set ticket escalation
|
||||
self.escalation_time = calculation_higher_time( self.escalation_time, self.close_time_escal_date, self.close_time )
|
||||
end
|
||||
if self.close_time # && !self.close_time_in_min
|
||||
self.close_time_in_min = escalation_suspend( self.created_at, self.close_time, 'real', sla_selected )
|
||||
end
|
||||
# set sla time
|
||||
if sla_selected.close_time && self.close_time_in_min
|
||||
self.close_time_diff_in_min = sla_selected.close_time - self.close_time_in_min
|
||||
end
|
||||
if self.changed?
|
||||
self.callback_loop = true
|
||||
self.save
|
||||
end
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
return sla for ticket
|
||||
|
@ -172,154 +171,153 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def escalation_calculation_get_sla
|
||||
sla_selected = nil
|
||||
sla_list = Cache.get( 'SLA::List::Active' )
|
||||
if sla_list == nil
|
||||
sla_list = Sla.where( active: true )
|
||||
Cache.write( 'SLA::List::Active', sla_list, { expires_in: 1.hour } )
|
||||
end
|
||||
sla_list.each {|sla|
|
||||
if !sla.condition || sla.condition.empty?
|
||||
sla_selected = sla
|
||||
elsif sla.condition
|
||||
hit = false
|
||||
map = [
|
||||
[ 'tickets.priority_id', 'priority_id' ],
|
||||
[ 'tickets.group_id', 'group_id' ]
|
||||
]
|
||||
map.each {|item|
|
||||
if sla.condition[ item[0] ]
|
||||
if sla.condition[ item[0] ].class == String
|
||||
sla.condition[ item[0] ] = [ sla.condition[ item[0] ] ]
|
||||
end
|
||||
if sla.condition[ item[0] ].include?( self[ item[1] ].to_s )
|
||||
hit = true
|
||||
else
|
||||
hit = false
|
||||
end
|
||||
def escalation_calculation_get_sla
|
||||
sla_selected = nil
|
||||
sla_list = Cache.get( 'SLA::List::Active' )
|
||||
if sla_list == nil
|
||||
sla_list = Sla.where( active: true )
|
||||
Cache.write( 'SLA::List::Active', sla_list, { expires_in: 1.hour } )
|
||||
end
|
||||
sla_list.each {|sla|
|
||||
if !sla.condition || sla.condition.empty?
|
||||
sla_selected = sla
|
||||
elsif sla.condition
|
||||
hit = false
|
||||
map = [
|
||||
[ 'tickets.priority_id', 'priority_id' ],
|
||||
[ 'tickets.group_id', 'group_id' ]
|
||||
]
|
||||
map.each {|item|
|
||||
if sla.condition[ item[0] ]
|
||||
if sla.condition[ item[0] ].class == String
|
||||
sla.condition[ item[0] ] = [ sla.condition[ item[0] ] ]
|
||||
end
|
||||
if sla.condition[ item[0] ].include?( self[ item[1] ].to_s )
|
||||
hit = true
|
||||
else
|
||||
hit = false
|
||||
end
|
||||
}
|
||||
if hit
|
||||
sla_selected = sla
|
||||
end
|
||||
}
|
||||
if hit
|
||||
sla_selected = sla
|
||||
end
|
||||
}
|
||||
sla_selected
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
#type could be:
|
||||
# real - time without supsend state
|
||||
# relative - only suspend time
|
||||
|
||||
def escalation_suspend (start_time, end_time, type, sla_selected, sla_time = 0)
|
||||
if type == 'relative'
|
||||
end_time += sla_time * 60
|
||||
end
|
||||
total_time_without_pending = 0
|
||||
total_time = 0
|
||||
#get history for ticket
|
||||
history_list = self.history_get
|
||||
}
|
||||
sla_selected
|
||||
end
|
||||
|
||||
#loop through hist. changes and get time
|
||||
last_state = nil
|
||||
last_state_change = nil
|
||||
last_state_is_pending = false
|
||||
history_list.each { |history_item|
|
||||
private
|
||||
|
||||
# ignore if it isn't a state change
|
||||
next if !history_item['attribute']
|
||||
next if history_item['attribute'] != 'state'
|
||||
#type could be:
|
||||
# real - time without supsend state
|
||||
# relative - only suspend time
|
||||
|
||||
# ignore all newer state before start_time
|
||||
next if history_item['created_at'] < start_time
|
||||
def escalation_suspend (start_time, end_time, type, sla_selected, sla_time = 0)
|
||||
if type == 'relative'
|
||||
end_time += sla_time * 60
|
||||
end
|
||||
total_time_without_pending = 0
|
||||
total_time = 0
|
||||
#get history for ticket
|
||||
history_list = self.history_get
|
||||
|
||||
# ignore all older state changes after end_time
|
||||
next if last_state_change && last_state_change > end_time
|
||||
#loop through hist. changes and get time
|
||||
last_state = nil
|
||||
last_state_change = nil
|
||||
last_state_is_pending = false
|
||||
history_list.each { |history_item|
|
||||
|
||||
# if created_at is later then end_time, use end_time as last time
|
||||
if history_item['created_at'] > end_time
|
||||
history_item['created_at'] = end_time
|
||||
end
|
||||
# ignore if it isn't a state change
|
||||
next if !history_item['attribute']
|
||||
next if history_item['attribute'] != 'state'
|
||||
|
||||
# get initial state and time
|
||||
if !last_state
|
||||
last_state = history_item['value_from']
|
||||
last_state_change = start_time
|
||||
end
|
||||
# ignore all newer state before start_time
|
||||
next if history_item['created_at'] < start_time
|
||||
|
||||
# check if time need to be counted
|
||||
counted = true
|
||||
if history_item['value_from'] == 'pending reminder'
|
||||
counted = false
|
||||
elsif history_item['value_from'] == 'close'
|
||||
counted = false
|
||||
end
|
||||
# ignore all older state changes after end_time
|
||||
next if last_state_change && last_state_change > end_time
|
||||
|
||||
diff = escalation_time_diff( last_state_change, history_item['created_at'], sla_selected )
|
||||
if counted
|
||||
# puts "Diff count #{history_item['value_from']} -> #{history_item['value_to']} / #{last_state_change} -> #{history_item['created_at']}"
|
||||
total_time_without_pending = total_time_without_pending + diff
|
||||
else
|
||||
# puts "Diff not count #{history_item['value_from']} -> #{history_item['value_to']} / #{last_state_change} -> #{history_item['created_at']}"
|
||||
end
|
||||
total_time = total_time + diff
|
||||
# if created_at is later then end_time, use end_time as last time
|
||||
if history_item['created_at'] > end_time
|
||||
history_item['created_at'] = end_time
|
||||
end
|
||||
|
||||
if history_item['value_to'] == 'pending reminder'
|
||||
last_state_is_pending = true
|
||||
else
|
||||
last_state_is_pending = false
|
||||
end
|
||||
# get initial state and time
|
||||
if !last_state
|
||||
last_state = history_item['value_from']
|
||||
last_state_change = start_time
|
||||
end
|
||||
|
||||
# remember for next loop last state
|
||||
last_state = history_item['value_to']
|
||||
last_state_change = history_item['created_at']
|
||||
}
|
||||
# check if time need to be counted
|
||||
counted = true
|
||||
if history_item['value_from'] == 'pending reminder'
|
||||
counted = false
|
||||
elsif history_item['value_from'] == 'close'
|
||||
counted = false
|
||||
end
|
||||
|
||||
# if last state isnt pending, count rest
|
||||
if !last_state_is_pending && last_state_change && last_state_change < end_time
|
||||
diff = escalation_time_diff( last_state_change, end_time, sla_selected )
|
||||
# puts "Diff count last state was not pending #{diff.to_s} - #{last_state_change} - #{end_time}"
|
||||
diff = escalation_time_diff( last_state_change, history_item['created_at'], sla_selected )
|
||||
if counted
|
||||
# puts "Diff count #{history_item['value_from']} -> #{history_item['value_to']} / #{last_state_change} -> #{history_item['created_at']}"
|
||||
total_time_without_pending = total_time_without_pending + diff
|
||||
total_time = total_time + diff
|
||||
end
|
||||
|
||||
# if we have not had any state change
|
||||
if !last_state_change
|
||||
diff = escalation_time_diff( start_time, end_time, sla_selected )
|
||||
# puts 'Diff state has not changed ' + diff.to_s
|
||||
total_time_without_pending = total_time_without_pending + diff
|
||||
total_time = total_time + diff
|
||||
end
|
||||
|
||||
#return sum
|
||||
if type == 'real'
|
||||
return total_time_without_pending
|
||||
elsif type == 'relative'
|
||||
relative = total_time - total_time_without_pending
|
||||
return relative
|
||||
else
|
||||
raise "ERROR: Unknown type #{type}"
|
||||
# puts "Diff not count #{history_item['value_from']} -> #{history_item['value_to']} / #{last_state_change} -> #{history_item['created_at']}"
|
||||
end
|
||||
total_time = total_time + diff
|
||||
|
||||
if history_item['value_to'] == 'pending reminder'
|
||||
last_state_is_pending = true
|
||||
else
|
||||
last_state_is_pending = false
|
||||
end
|
||||
|
||||
# remember for next loop last state
|
||||
last_state = history_item['value_to']
|
||||
last_state_change = history_item['created_at']
|
||||
}
|
||||
|
||||
# if last state isnt pending, count rest
|
||||
if !last_state_is_pending && last_state_change && last_state_change < end_time
|
||||
diff = escalation_time_diff( last_state_change, end_time, sla_selected )
|
||||
# puts "Diff count last state was not pending #{diff.to_s} - #{last_state_change} - #{end_time}"
|
||||
total_time_without_pending = total_time_without_pending + diff
|
||||
total_time = total_time + diff
|
||||
end
|
||||
|
||||
def escalation_time_diff( start_time, end_time, sla_selected )
|
||||
if sla_selected
|
||||
diff = TimeCalculation.business_time_diff( start_time, end_time, sla_selected.data, sla_selected.timezone)
|
||||
else
|
||||
diff = TimeCalculation.business_time_diff( start_time, end_time )
|
||||
end
|
||||
diff
|
||||
# if we have not had any state change
|
||||
if !last_state_change
|
||||
diff = escalation_time_diff( start_time, end_time, sla_selected )
|
||||
# puts 'Diff state has not changed ' + diff.to_s
|
||||
total_time_without_pending = total_time_without_pending + diff
|
||||
total_time = total_time + diff
|
||||
end
|
||||
|
||||
def calculation_higher_time(escalation_time, check_time, done_time)
|
||||
return escalation_time if done_time
|
||||
return check_time if !escalation_time
|
||||
return escalation_time if !check_time
|
||||
return check_time if escalation_time > check_time
|
||||
escalation_time
|
||||
#return sum
|
||||
if type == 'real'
|
||||
return total_time_without_pending
|
||||
elsif type == 'relative'
|
||||
relative = total_time - total_time_without_pending
|
||||
return relative
|
||||
else
|
||||
raise "ERROR: Unknown type #{type}"
|
||||
end
|
||||
end
|
||||
|
||||
def escalation_time_diff( start_time, end_time, sla_selected )
|
||||
if sla_selected
|
||||
diff = TimeCalculation.business_time_diff( start_time, end_time, sla_selected.data, sla_selected.timezone)
|
||||
else
|
||||
diff = TimeCalculation.business_time_diff( start_time, end_time )
|
||||
end
|
||||
diff
|
||||
end
|
||||
|
||||
def calculation_higher_time(escalation_time, check_time, done_time)
|
||||
return escalation_time if done_time
|
||||
return check_time if !escalation_time
|
||||
return escalation_time if !check_time
|
||||
return check_time if escalation_time > check_time
|
||||
escalation_time
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Ticket
|
||||
class Flag < ApplicationModel
|
||||
end
|
||||
class Ticket::Flag < ApplicationModel
|
||||
end
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Ticket
|
||||
module HistoryLog
|
||||
# rubocop:disable ClassAndModuleChildren
|
||||
module Ticket::HistoryLog
|
||||
|
||||
=begin
|
||||
|
||||
|
@ -16,15 +15,15 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def history_log (type, user_id, data = {})
|
||||
data[:o_id] = self['id']
|
||||
data[:history_type] = type
|
||||
data[:history_object] = self.class.name
|
||||
data[:related_o_id] = nil
|
||||
data[:related_history_object] = nil
|
||||
data[:created_by_id] = user_id
|
||||
History.add(data)
|
||||
end
|
||||
def history_log (type, user_id, data = {})
|
||||
data[:o_id] = self['id']
|
||||
data[:history_type] = type
|
||||
data[:history_object] = self.class.name
|
||||
data[:related_o_id] = nil
|
||||
data[:related_history_object] = nil
|
||||
data[:created_by_id] = user_id
|
||||
History.add(data)
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
|
@ -58,25 +57,24 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def history_get(fulldata = false)
|
||||
list = History.list( self.class.name, self['id'], 'Ticket::Article' )
|
||||
return list if !fulldata
|
||||
def history_get(fulldata = false)
|
||||
list = History.list( self.class.name, self['id'], 'Ticket::Article' )
|
||||
return list if !fulldata
|
||||
|
||||
# get related objects
|
||||
assets = {}
|
||||
list.each {|item|
|
||||
record = Kernel.const_get( item['object'] ).find( item['o_id'] )
|
||||
# get related objects
|
||||
assets = {}
|
||||
list.each {|item|
|
||||
record = Kernel.const_get( item['object'] ).find( item['o_id'] )
|
||||
assets = record.assets(assets)
|
||||
|
||||
if item['related_object']
|
||||
record = Kernel.const_get( item['related_object'] ).find( item['related_o_id'] )
|
||||
assets = record.assets(assets)
|
||||
|
||||
if item['related_object']
|
||||
record = Kernel.const_get( item['related_object'] ).find( item['related_o_id'] )
|
||||
assets = record.assets(assets)
|
||||
end
|
||||
}
|
||||
{
|
||||
history: list,
|
||||
assets: assets,
|
||||
}
|
||||
end
|
||||
end
|
||||
}
|
||||
{
|
||||
history: list,
|
||||
assets: assets,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Ticket
|
||||
class Number
|
||||
include ApplicationLib
|
||||
class Ticket::Number
|
||||
include ApplicationLib
|
||||
|
||||
=begin
|
||||
|
||||
|
@ -16,16 +15,16 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def self.generate
|
||||
def self.generate
|
||||
|
||||
# generate number
|
||||
(1..50_000).each { |i|
|
||||
number = adapter.generate
|
||||
ticket = Ticket.where( number: number ).first
|
||||
return number if !ticket
|
||||
}
|
||||
raise "Can't generate new ticket number!"
|
||||
end
|
||||
# generate number
|
||||
(1..50_000).each { |i|
|
||||
number = adapter.generate
|
||||
ticket = Ticket.where( number: number ).first
|
||||
return number if !ticket
|
||||
}
|
||||
raise "Can't generate new ticket number!"
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
|
@ -39,22 +38,21 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def self.check(string)
|
||||
adapter.check(string)
|
||||
end
|
||||
def self.check(string)
|
||||
adapter.check(string)
|
||||
end
|
||||
|
||||
def self.adapter
|
||||
def self.adapter
|
||||
|
||||
# load backend based on config
|
||||
adapter_name = Setting.get('ticket_number')
|
||||
if !adapter_name
|
||||
raise 'Missing ticket_number setting option'
|
||||
end
|
||||
adapter = load_adapter(adapter_name)
|
||||
if !adapter
|
||||
raise "Can't load ticket_number adapter '#{adapter_name}'"
|
||||
end
|
||||
adapter
|
||||
# load backend based on config
|
||||
adapter_name = Setting.get('ticket_number')
|
||||
if !adapter_name
|
||||
raise 'Missing ticket_number setting option'
|
||||
end
|
||||
adapter = load_adapter(adapter_name)
|
||||
if !adapter
|
||||
raise "Can't load ticket_number adapter '#{adapter_name}'"
|
||||
end
|
||||
adapter
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,88 +1,84 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
# rubocop:disable ClassAndModuleChildren
|
||||
module Ticket::Number::Date
|
||||
extend self
|
||||
|
||||
class Ticket
|
||||
class Number
|
||||
module Date
|
||||
extend self
|
||||
def generate
|
||||
|
||||
def generate
|
||||
# get config
|
||||
config = Setting.get('ticket_number_date')
|
||||
|
||||
# get config
|
||||
config = Setting.get('ticket_number_date')
|
||||
t = Time.zone.now
|
||||
date = t.strftime('%Y-%m-%d')
|
||||
|
||||
t = Time.zone.now
|
||||
date = t.strftime('%Y-%m-%d')
|
||||
|
||||
# read counter
|
||||
counter_increment = nil
|
||||
Ticket::Counter.transaction do
|
||||
counter = Ticket::Counter.where( generator: 'Date' ).lock(true).first
|
||||
if !counter
|
||||
counter = Ticket::Counter.new( generator: 'Date', content: '0' )
|
||||
end
|
||||
|
||||
# increase counter
|
||||
counter_increment, date_file = counter.content.to_s.split(';')
|
||||
if date_file == date
|
||||
counter_increment = counter_increment.to_i + 1
|
||||
else
|
||||
counter_increment = 1
|
||||
end
|
||||
|
||||
# store new counter value
|
||||
counter.content = counter_increment.to_s + ';' + date
|
||||
counter.save
|
||||
end
|
||||
|
||||
system_id = Setting.get('system_id') || ''
|
||||
number = t.strftime('%Y%m%d') + system_id.to_s + sprintf( '%04d', counter_increment)
|
||||
|
||||
# calculate a checksum
|
||||
# The algorithm to calculate the checksum is derived from the one
|
||||
# Deutsche Bundesbahn (german railway company) uses for calculation
|
||||
# of the check digit of their vehikel numbering.
|
||||
# The checksum is calculated by alternately multiplying the digits
|
||||
# with 1 and 2 and adding the resulsts from left to right of the
|
||||
# vehikel number. The modulus to 10 of this sum is substracted from
|
||||
# 10. See: http://www.pruefziffernberechnung.de/F/Fahrzeugnummer.shtml
|
||||
# (german)
|
||||
if config[:checksum]
|
||||
chksum = 0
|
||||
mult = 1
|
||||
(1..number.length).each do |i|
|
||||
digit = number.to_s[i, 1]
|
||||
chksum = chksum + ( mult * digit.to_i )
|
||||
mult += 1
|
||||
if mult == 3
|
||||
mult = 1
|
||||
end
|
||||
end
|
||||
chksum %= 10
|
||||
chksum = 10 - chksum
|
||||
if chksum == 10
|
||||
chksum = 1
|
||||
end
|
||||
number += chksum.to_s
|
||||
end
|
||||
number
|
||||
# read counter
|
||||
counter_increment = nil
|
||||
Ticket::Counter.transaction do
|
||||
counter = Ticket::Counter.where( generator: 'Date' ).lock(true).first
|
||||
if !counter
|
||||
counter = Ticket::Counter.new( generator: 'Date', content: '0' )
|
||||
end
|
||||
|
||||
def check(string)
|
||||
|
||||
# get config
|
||||
system_id = Setting.get('system_id') || ''
|
||||
ticket_hook = Setting.get('ticket_hook')
|
||||
ticket_hook_divider = Setting.get('ticket_hook_divider') || ''
|
||||
ticket = nil
|
||||
|
||||
# probe format
|
||||
if string =~ /#{ticket_hook}#{ticket_hook_divider}(#{system_id}\d{2,50})/i
|
||||
ticket = Ticket.where( number: $1 ).first
|
||||
elsif string =~ /#{ticket_hook}\s{0,2}(#{system_id}\d{2,50})/i
|
||||
ticket = Ticket.where( number: $1 ).first
|
||||
end
|
||||
ticket
|
||||
# increase counter
|
||||
counter_increment, date_file = counter.content.to_s.split(';')
|
||||
if date_file == date
|
||||
counter_increment = counter_increment.to_i + 1
|
||||
else
|
||||
counter_increment = 1
|
||||
end
|
||||
|
||||
# store new counter value
|
||||
counter.content = counter_increment.to_s + ';' + date
|
||||
counter.save
|
||||
end
|
||||
|
||||
system_id = Setting.get('system_id') || ''
|
||||
number = t.strftime('%Y%m%d') + system_id.to_s + sprintf( '%04d', counter_increment)
|
||||
|
||||
# calculate a checksum
|
||||
# The algorithm to calculate the checksum is derived from the one
|
||||
# Deutsche Bundesbahn (german railway company) uses for calculation
|
||||
# of the check digit of their vehikel numbering.
|
||||
# The checksum is calculated by alternately multiplying the digits
|
||||
# with 1 and 2 and adding the resulsts from left to right of the
|
||||
# vehikel number. The modulus to 10 of this sum is substracted from
|
||||
# 10. See: http://www.pruefziffernberechnung.de/F/Fahrzeugnummer.shtml
|
||||
# (german)
|
||||
if config[:checksum]
|
||||
chksum = 0
|
||||
mult = 1
|
||||
(1..number.length).each do |i|
|
||||
digit = number.to_s[i, 1]
|
||||
chksum = chksum + ( mult * digit.to_i )
|
||||
mult += 1
|
||||
if mult == 3
|
||||
mult = 1
|
||||
end
|
||||
end
|
||||
chksum %= 10
|
||||
chksum = 10 - chksum
|
||||
if chksum == 10
|
||||
chksum = 1
|
||||
end
|
||||
number += chksum.to_s
|
||||
end
|
||||
number
|
||||
end
|
||||
|
||||
def check(string)
|
||||
|
||||
# get config
|
||||
system_id = Setting.get('system_id') || ''
|
||||
ticket_hook = Setting.get('ticket_hook')
|
||||
ticket_hook_divider = Setting.get('ticket_hook_divider') || ''
|
||||
ticket = nil
|
||||
|
||||
# probe format
|
||||
if string =~ /#{ticket_hook}#{ticket_hook_divider}(#{system_id}\d{2,50})/i
|
||||
ticket = Ticket.where( number: $1 ).first
|
||||
elsif string =~ /#{ticket_hook}\s{0,2}(#{system_id}\d{2,50})/i
|
||||
ticket = Ticket.where( number: $1 ).first
|
||||
end
|
||||
ticket
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,91 +1,87 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Ticket
|
||||
class Number
|
||||
module Increment
|
||||
extend self
|
||||
module Ticket::Number::Increment
|
||||
extend self
|
||||
|
||||
def generate
|
||||
def generate
|
||||
|
||||
# get config
|
||||
config = Setting.get('ticket_number_increment')
|
||||
# get config
|
||||
config = Setting.get('ticket_number_increment')
|
||||
|
||||
# read counter
|
||||
min_digs = config[:min_size] || 4
|
||||
counter_increment = nil
|
||||
Ticket::Counter.transaction do
|
||||
counter = Ticket::Counter.where( generator: 'Increment' ).lock(true).first
|
||||
if !counter
|
||||
counter = Ticket::Counter.new( generator: 'Increment', content: '0' )
|
||||
end
|
||||
counter_increment = counter.content.to_i
|
||||
|
||||
# increase counter
|
||||
counter_increment += 1
|
||||
|
||||
# store new counter value
|
||||
counter.content = counter_increment.to_s
|
||||
counter.save
|
||||
end
|
||||
|
||||
# fill up number counter
|
||||
if config[:checksum]
|
||||
min_digs = min_digs.to_i - 1
|
||||
end
|
||||
fillup = Setting.get('system_id') || '1'
|
||||
( 1..100 ).each do |i|
|
||||
if ( fillup.length.to_i + counter_increment.to_s.length.to_i ) < min_digs.to_i
|
||||
fillup = fillup + '0'
|
||||
end
|
||||
end
|
||||
number = fillup.to_s + counter_increment.to_s
|
||||
|
||||
# calculate a checksum
|
||||
# The algorithm to calculate the checksum is derived from the one
|
||||
# Deutsche Bundesbahn (german railway company) uses for calculation
|
||||
# of the check digit of their vehikel numbering.
|
||||
# The checksum is calculated by alternately multiplying the digits
|
||||
# with 1 and 2 and adding the resulsts from left to right of the
|
||||
# vehikel number. The modulus to 10 of this sum is substracted from
|
||||
# 10. See: http://www.pruefziffernberechnung.de/F/Fahrzeugnummer.shtml
|
||||
# (german)
|
||||
if config[:checksum]
|
||||
chksum = 0
|
||||
mult = 1
|
||||
(1..number.length).each do |i|
|
||||
digit = number.to_s[i, 1]
|
||||
chksum = chksum + ( mult * digit.to_i )
|
||||
mult += 1
|
||||
if mult == 3
|
||||
mult = 1
|
||||
end
|
||||
end
|
||||
chksum %= 10
|
||||
chksum = 10 - chksum
|
||||
if chksum == 10
|
||||
chksum = 1
|
||||
end
|
||||
number += chksum.to_s
|
||||
end
|
||||
number
|
||||
# read counter
|
||||
min_digs = config[:min_size] || 4
|
||||
counter_increment = nil
|
||||
Ticket::Counter.transaction do
|
||||
counter = Ticket::Counter.where( generator: 'Increment' ).lock(true).first
|
||||
if !counter
|
||||
counter = Ticket::Counter.new( generator: 'Increment', content: '0' )
|
||||
end
|
||||
counter_increment = counter.content.to_i
|
||||
|
||||
def check(string)
|
||||
# increase counter
|
||||
counter_increment += 1
|
||||
|
||||
# get config
|
||||
system_id = Setting.get('system_id') || ''
|
||||
ticket_hook = Setting.get('ticket_hook')
|
||||
ticket_hook_divider = Setting.get('ticket_hook_divider') || ''
|
||||
ticket = nil
|
||||
# store new counter value
|
||||
counter.content = counter_increment.to_s
|
||||
counter.save
|
||||
end
|
||||
|
||||
# probe format
|
||||
if string =~ /#{ticket_hook}#{ticket_hook_divider}(#{system_id}\d{2,48})/i
|
||||
ticket = Ticket.where( number: $1 ).first
|
||||
elsif string =~ /#{ticket_hook}\s{0,2}(#{system_id}\d{2,48})/i
|
||||
ticket = Ticket.where( number: $1 ).first
|
||||
end
|
||||
ticket
|
||||
# fill up number counter
|
||||
if config[:checksum]
|
||||
min_digs = min_digs.to_i - 1
|
||||
end
|
||||
fillup = Setting.get('system_id') || '1'
|
||||
( 1..100 ).each do |i|
|
||||
if ( fillup.length.to_i + counter_increment.to_s.length.to_i ) < min_digs.to_i
|
||||
fillup = fillup + '0'
|
||||
end
|
||||
end
|
||||
number = fillup.to_s + counter_increment.to_s
|
||||
|
||||
# calculate a checksum
|
||||
# The algorithm to calculate the checksum is derived from the one
|
||||
# Deutsche Bundesbahn (german railway company) uses for calculation
|
||||
# of the check digit of their vehikel numbering.
|
||||
# The checksum is calculated by alternately multiplying the digits
|
||||
# with 1 and 2 and adding the resulsts from left to right of the
|
||||
# vehikel number. The modulus to 10 of this sum is substracted from
|
||||
# 10. See: http://www.pruefziffernberechnung.de/F/Fahrzeugnummer.shtml
|
||||
# (german)
|
||||
if config[:checksum]
|
||||
chksum = 0
|
||||
mult = 1
|
||||
(1..number.length).each do |i|
|
||||
digit = number.to_s[i, 1]
|
||||
chksum = chksum + ( mult * digit.to_i )
|
||||
mult += 1
|
||||
if mult == 3
|
||||
mult = 1
|
||||
end
|
||||
end
|
||||
chksum %= 10
|
||||
chksum = 10 - chksum
|
||||
if chksum == 10
|
||||
chksum = 1
|
||||
end
|
||||
number += chksum.to_s
|
||||
end
|
||||
number
|
||||
end
|
||||
|
||||
def check(string)
|
||||
|
||||
# get config
|
||||
system_id = Setting.get('system_id') || ''
|
||||
ticket_hook = Setting.get('ticket_hook')
|
||||
ticket_hook_divider = Setting.get('ticket_hook_divider') || ''
|
||||
ticket = nil
|
||||
|
||||
# probe format
|
||||
if string =~ /#{ticket_hook}#{ticket_hook_divider}(#{system_id}\d{2,48})/i
|
||||
ticket = Ticket.where( number: $1 ).first
|
||||
elsif string =~ /#{ticket_hook}\s{0,2}(#{system_id}\d{2,48})/i
|
||||
ticket = Ticket.where( number: $1 ).first
|
||||
end
|
||||
ticket
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Ticket
|
||||
module Overviews
|
||||
# rubocop:disable ClassAndModuleChildren
|
||||
module Ticket::Overviews
|
||||
|
||||
=begin
|
||||
|
||||
|
@ -17,25 +16,25 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def self.all (data)
|
||||
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
|
||||
# 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
|
||||
|
||||
# get agent overviews
|
||||
role = data[:current_user].is_role( 'Agent' )
|
||||
return if !role
|
||||
Overview.where( role_id: role.id, active: true )
|
||||
return overviews
|
||||
end
|
||||
|
||||
# get agent overviews
|
||||
role = data[:current_user].is_role( 'Agent' )
|
||||
return if !role
|
||||
Overview.where( role_id: role.id, active: true )
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
selected overview by user
|
||||
|
@ -55,199 +54,198 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def self.list (data)
|
||||
def self.list (data)
|
||||
|
||||
overviews = self.all(data)
|
||||
return if !overviews
|
||||
overviews = self.all(data)
|
||||
return if !overviews
|
||||
|
||||
# build up attributes hash
|
||||
overview_selected = nil
|
||||
overview_selected_raw = nil
|
||||
# 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|
|
||||
|
||||
# remember selected view
|
||||
if data[:view] && data[:view] == overview.link
|
||||
overview_selected = overview
|
||||
overview_selected_raw = Marshal.load( Marshal.dump(overview.attributes) )
|
||||
end
|
||||
# get count
|
||||
count = Ticket.where( group_id: group_ids ).where( _condition( overview.condition ) ).count()
|
||||
|
||||
# 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
|
||||
# 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
|
||||
|
||||
if data[:view] && !overview_selected
|
||||
raise "No such view '#{ data[:view] }'"
|
||||
# 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
|
||||
|
||||
# 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_ids: 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 ).
|
||||
tickets = Ticket.select( 'id' ).
|
||||
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 ) )
|
||||
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()
|
||||
|
||||
{
|
||||
tickets: tickets,
|
||||
return {
|
||||
ticket_ids: ticket_ids,
|
||||
tickets_count: tickets_count,
|
||||
overview: overview_selected_raw,
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
# 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 ) )
|
||||
|
||||
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
|
||||
tickets_count = Ticket.where( group_id: group_ids ).
|
||||
where( _condition( overview_selected.condition ) ).
|
||||
count()
|
||||
|
||||
{
|
||||
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'
|
||||
sql += " #{key} > ?"
|
||||
bind.push time
|
||||
time -= value['count'].to_i * 60
|
||||
else
|
||||
sql += " #{key} < ?"
|
||||
bind.push time
|
||||
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
|
||||
else
|
||||
sql += " #{key} = ?"
|
||||
bind.push value
|
||||
end
|
||||
}
|
||||
bind[0] = sql
|
||||
bind
|
||||
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
|
||||
bind
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Ticket
|
||||
module Permission
|
||||
# rubocop:disable ClassAndModuleChildren
|
||||
module Ticket::Permission
|
||||
|
||||
=begin
|
||||
|
||||
|
@ -16,33 +15,32 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def permission (data)
|
||||
def permission (data)
|
||||
|
||||
# check customer
|
||||
if data[:current_user].is_role('Customer')
|
||||
# check customer
|
||||
if data[:current_user].is_role('Customer')
|
||||
|
||||
# access ok if its own ticket
|
||||
return true if self.customer_id == data[:current_user].id
|
||||
# access ok if its own ticket
|
||||
return true if self.customer_id == data[:current_user].id
|
||||
|
||||
# access ok if its organization ticket
|
||||
if data[:current_user].organization_id && self.organization_id
|
||||
return true if self.organization_id == data[:current_user].organization_id
|
||||
end
|
||||
|
||||
# no access
|
||||
return false
|
||||
# access ok if its organization ticket
|
||||
if data[:current_user].organization_id && self.organization_id
|
||||
return true if self.organization_id == data[:current_user].organization_id
|
||||
end
|
||||
|
||||
# check agent
|
||||
|
||||
# access if requestor is owner
|
||||
return true if self.owner_id == data[:current_user].id
|
||||
|
||||
# access if requestor is in group
|
||||
data[:current_user].groups.each {|group|
|
||||
return true if self.group.id == group.id
|
||||
}
|
||||
false
|
||||
# no access
|
||||
return false
|
||||
end
|
||||
|
||||
# check agent
|
||||
|
||||
# access if requestor is owner
|
||||
return true if self.owner_id == data[:current_user].id
|
||||
|
||||
# access if requestor is in group
|
||||
data[:current_user].groups.each {|group|
|
||||
return true if self.group.id == group.id
|
||||
}
|
||||
false
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Ticket
|
||||
class Priority < ApplicationModel
|
||||
self.table_name = 'ticket_priorities'
|
||||
validates :name, presence: true
|
||||
end
|
||||
# rubocop:disable ClassAndModuleChildren
|
||||
class Ticket::Priority < ApplicationModel
|
||||
self.table_name = 'ticket_priorities'
|
||||
validates :name, presence: true
|
||||
end
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Ticket
|
||||
module ScreenOptions
|
||||
# rubocop:disable ClassAndModuleChildren
|
||||
module Ticket::ScreenOptions
|
||||
|
||||
=begin
|
||||
|
||||
|
@ -15,9 +14,9 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def self.agents
|
||||
User.where( active: true ).joins(:roles).where( 'roles.name' => 'Agent', 'roles.active' => true ).uniq()
|
||||
end
|
||||
def self.agents
|
||||
User.where( active: true ).joins(:roles).where( 'roles.name' => 'Agent', 'roles.active' => true ).uniq()
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
|
@ -43,83 +42,83 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def self.attributes_to_change(params)
|
||||
if params[:ticket_id]
|
||||
params[:ticket] = Ticket.find( params[:ticket_id] )
|
||||
end
|
||||
if params[:article_id]
|
||||
params[:article] = Ticket::Article.find( params[:article_id] )
|
||||
end
|
||||
def self.attributes_to_change(params)
|
||||
if params[:ticket_id]
|
||||
params[:ticket] = Ticket.find( params[:ticket_id] )
|
||||
end
|
||||
if params[:article_id]
|
||||
params[:article] = Ticket::Article.find( params[:article_id] )
|
||||
end
|
||||
|
||||
filter = {}
|
||||
assets = {}
|
||||
filter = {}
|
||||
assets = {}
|
||||
|
||||
# get ticket states
|
||||
state_ids = []
|
||||
if params[:ticket]
|
||||
state_type = params[:ticket].state.state_type
|
||||
end
|
||||
state_types = ['open', 'closed', 'pending action', 'pending reminder']
|
||||
if state_type && !state_types.include?(state_type.name)
|
||||
state_ids.push params[:ticket].state.id
|
||||
end
|
||||
state_types.each {|type|
|
||||
state_type = Ticket::StateType.where( name: type ).first
|
||||
if state_type
|
||||
state_type.states.each {|state|
|
||||
assets = state.assets(assets)
|
||||
state_ids.push state.id
|
||||
}
|
||||
end
|
||||
}
|
||||
filter[:state_id] = state_ids
|
||||
|
||||
# get priorities
|
||||
priority_ids = []
|
||||
Ticket::Priority.where( active: true ).each { |priority|
|
||||
assets = priority.assets(assets)
|
||||
priority_ids.push priority.id
|
||||
}
|
||||
filter[:priority_id] = priority_ids
|
||||
|
||||
type_ids = []
|
||||
if params[:ticket]
|
||||
types = ['note', 'phone']
|
||||
if params[:ticket].group.email_address_id
|
||||
types.push 'email'
|
||||
end
|
||||
types.each {|type_name|
|
||||
type = Ticket::Article::Type.lookup( name: type_name )
|
||||
if type
|
||||
type_ids.push type.id
|
||||
end
|
||||
# get ticket states
|
||||
state_ids = []
|
||||
if params[:ticket]
|
||||
state_type = params[:ticket].state.state_type
|
||||
end
|
||||
state_types = ['open', 'closed', 'pending action', 'pending reminder']
|
||||
if state_type && !state_types.include?(state_type.name)
|
||||
state_ids.push params[:ticket].state.id
|
||||
end
|
||||
state_types.each {|type|
|
||||
state_type = Ticket::StateType.where( name: type ).first
|
||||
if state_type
|
||||
state_type.states.each {|state|
|
||||
assets = state.assets(assets)
|
||||
state_ids.push state.id
|
||||
}
|
||||
end
|
||||
filter[:type_id] = type_ids
|
||||
}
|
||||
filter[:state_id] = state_ids
|
||||
|
||||
# get group / user relations
|
||||
agents = {}
|
||||
Ticket::ScreenOptions.agents.each { |user|
|
||||
agents[ user.id ] = 1
|
||||
}
|
||||
# get priorities
|
||||
priority_ids = []
|
||||
Ticket::Priority.where( active: true ).each { |priority|
|
||||
assets = priority.assets(assets)
|
||||
priority_ids.push priority.id
|
||||
}
|
||||
filter[:priority_id] = priority_ids
|
||||
|
||||
dependencies = { group_id: { '' => { owner_id: [] } } }
|
||||
Group.where( active: true ).each { |group|
|
||||
assets = group.assets(assets)
|
||||
dependencies[:group_id][group.id] = { owner_id: [] }
|
||||
group.users.each {|user|
|
||||
next if !agents[ user.id ]
|
||||
assets = user.assets(assets)
|
||||
dependencies[:group_id][ group.id ][ :owner_id ].push user.id
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
assets: assets,
|
||||
filter: filter,
|
||||
dependencies: dependencies,
|
||||
type_ids = []
|
||||
if params[:ticket]
|
||||
types = ['note', 'phone']
|
||||
if params[:ticket].group.email_address_id
|
||||
types.push 'email'
|
||||
end
|
||||
types.each {|type_name|
|
||||
type = Ticket::Article::Type.lookup( name: type_name )
|
||||
if type
|
||||
type_ids.push type.id
|
||||
end
|
||||
}
|
||||
end
|
||||
filter[:type_id] = type_ids
|
||||
|
||||
# get group / user relations
|
||||
agents = {}
|
||||
Ticket::ScreenOptions.agents.each { |user|
|
||||
agents[ user.id ] = 1
|
||||
}
|
||||
|
||||
dependencies = { group_id: { '' => { owner_id: [] } } }
|
||||
Group.where( active: true ).each { |group|
|
||||
assets = group.assets(assets)
|
||||
dependencies[:group_id][group.id] = { owner_id: [] }
|
||||
group.users.each {|user|
|
||||
next if !agents[ user.id ]
|
||||
assets = user.assets(assets)
|
||||
dependencies[:group_id][ group.id ][ :owner_id ].push user.id
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
assets: assets,
|
||||
filter: filter,
|
||||
dependencies: dependencies,
|
||||
}
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
|
@ -140,39 +139,38 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def self.list_by_customer(data)
|
||||
def self.list_by_customer(data)
|
||||
|
||||
# get closed/open states
|
||||
state_list_open = Ticket::State.by_category( 'open' )
|
||||
state_list_closed = Ticket::State.by_category( 'closed' )
|
||||
# get closed/open states
|
||||
state_list_open = Ticket::State.by_category( 'open' )
|
||||
state_list_closed = Ticket::State.by_category( 'closed' )
|
||||
|
||||
# get tickets
|
||||
tickets_open = Ticket.where(
|
||||
customer_id: data[:customer_id],
|
||||
state_id: state_list_open
|
||||
).limit( data[:limit] || 15 ).order('created_at DESC')
|
||||
assets = {}
|
||||
ticket_ids_open = []
|
||||
tickets_open.each {|ticket|
|
||||
ticket_ids_open.push ticket.id
|
||||
assets = ticket.assets(assets)
|
||||
}
|
||||
# get tickets
|
||||
tickets_open = Ticket.where(
|
||||
customer_id: data[:customer_id],
|
||||
state_id: state_list_open
|
||||
).limit( data[:limit] || 15 ).order('created_at DESC')
|
||||
assets = {}
|
||||
ticket_ids_open = []
|
||||
tickets_open.each {|ticket|
|
||||
ticket_ids_open.push ticket.id
|
||||
assets = ticket.assets(assets)
|
||||
}
|
||||
|
||||
tickets_closed = Ticket.where(
|
||||
customer_id: data[:customer_id],
|
||||
state_id: state_list_closed
|
||||
).limit( data[:limit] || 15 ).order('created_at DESC')
|
||||
ticket_ids_closed = []
|
||||
tickets_closed.each {|ticket|
|
||||
ticket_ids_closed.push ticket.id
|
||||
assets = ticket.assets(assets)
|
||||
}
|
||||
tickets_closed = Ticket.where(
|
||||
customer_id: data[:customer_id],
|
||||
state_id: state_list_closed
|
||||
).limit( data[:limit] || 15 ).order('created_at DESC')
|
||||
ticket_ids_closed = []
|
||||
tickets_closed.each {|ticket|
|
||||
ticket_ids_closed.push ticket.id
|
||||
assets = ticket.assets(assets)
|
||||
}
|
||||
|
||||
{
|
||||
ticket_ids_open: ticket_ids_open,
|
||||
ticket_ids_closed: ticket_ids_closed,
|
||||
assets: assets,
|
||||
}
|
||||
end
|
||||
{
|
||||
ticket_ids_open: ticket_ids_open,
|
||||
ticket_ids_closed: ticket_ids_closed,
|
||||
assets: assets,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Ticket
|
||||
module Search
|
||||
# rubocop:disable ClassAndModuleChildren
|
||||
module Ticket::Search
|
||||
|
||||
=begin
|
||||
|
||||
|
@ -46,102 +45,101 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def search (params)
|
||||
def search (params)
|
||||
|
||||
# get params
|
||||
query = params[:query]
|
||||
limit = params[:limit] || 12
|
||||
current_user = params[:current_user]
|
||||
full = false
|
||||
if params[:full] || !params.key?(:full)
|
||||
full = true
|
||||
end
|
||||
# get params
|
||||
query = params[:query]
|
||||
limit = params[:limit] || 12
|
||||
current_user = params[:current_user]
|
||||
full = false
|
||||
if params[:full] || !params.key?(:full)
|
||||
full = true
|
||||
end
|
||||
|
||||
# try search index backend
|
||||
if !params[:detail] && SearchIndexBackend.enabled?
|
||||
query_extention = {}
|
||||
query_extention['bool'] = {}
|
||||
query_extention['bool']['must'] = []
|
||||
# try search index backend
|
||||
if !params[:detail] && SearchIndexBackend.enabled?
|
||||
query_extention = {}
|
||||
query_extention['bool'] = {}
|
||||
query_extention['bool']['must'] = []
|
||||
|
||||
if current_user.is_role('Agent')
|
||||
groups = Group.joins(:users)
|
||||
.where( 'groups_users.user_id = ?', current_user.id )
|
||||
.where( 'groups.active = ?', true )
|
||||
group_condition = []
|
||||
groups.each {|group|
|
||||
group_condition.push group.name
|
||||
}
|
||||
access_condition = {
|
||||
'query_string' => { 'default_field' => 'Ticket.group.name', 'query' => "\"#{group_condition.join('" OR "')}\"" }
|
||||
}
|
||||
query_extention['bool']['must'].push access_condition
|
||||
else
|
||||
if !current_user.organization || ( !current_user.organization.shared || current_user.organization.shared == false )
|
||||
access_condition = {
|
||||
'query_string' => { 'default_field' => 'Ticket.customer_id', 'query' => current_user.id }
|
||||
}
|
||||
# customer_id: XXX
|
||||
# conditions = [ 'customer_id = ?', current_user.id ]
|
||||
else
|
||||
access_condition = {
|
||||
'query_string' => { 'query' => "Ticket.customer_id:#{current_user.id} OR Ticket.organization_id:#{current_user.organization.id}" }
|
||||
}
|
||||
# customer_id: XXX OR organization_id: XXX
|
||||
# conditions = [ '( customer_id = ? OR organization_id = ? )', current_user.id, current_user.organization.id ]
|
||||
end
|
||||
query_extention['bool']['must'].push access_condition
|
||||
end
|
||||
|
||||
items = SearchIndexBackend.search( query, limit, 'Ticket', query_extention )
|
||||
if !full
|
||||
ids = []
|
||||
items.each {|item|
|
||||
ids.push item[:id]
|
||||
}
|
||||
return ids
|
||||
end
|
||||
tickets = []
|
||||
items.each { |item|
|
||||
tickets.push Ticket.lookup( id: item[:id] )
|
||||
if current_user.is_role('Agent')
|
||||
groups = Group.joins(:users)
|
||||
.where( 'groups_users.user_id = ?', current_user.id )
|
||||
.where( 'groups.active = ?', true )
|
||||
group_condition = []
|
||||
groups.each {|group|
|
||||
group_condition.push group.name
|
||||
}
|
||||
return tickets
|
||||
end
|
||||
|
||||
# fallback do sql query
|
||||
access_condition = Ticket.access_condition( current_user )
|
||||
|
||||
# do query
|
||||
# - stip out * we already search for *query* -
|
||||
if query
|
||||
query.gsub! '*', ''
|
||||
tickets_all = Ticket.select('DISTINCT(tickets.id)')
|
||||
.where(access_condition)
|
||||
.where( '( `tickets`.`title` LIKE ? OR `tickets`.`number` LIKE ? OR `ticket_articles`.`body` LIKE ? OR `ticket_articles`.`from` LIKE ? OR `ticket_articles`.`to` LIKE ? OR `ticket_articles`.`subject` LIKE ?)', "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%" )
|
||||
.joins(:articles)
|
||||
.order('`tickets`.`created_at` DESC')
|
||||
.limit(limit)
|
||||
access_condition = {
|
||||
'query_string' => { 'default_field' => 'Ticket.group.name', 'query' => "\"#{group_condition.join('" OR "')}\"" }
|
||||
}
|
||||
query_extention['bool']['must'].push access_condition
|
||||
else
|
||||
tickets_all = Ticket.select('DISTINCT(tickets.id)')
|
||||
.where(access_condition)
|
||||
.where(params[:condition])
|
||||
.order('`tickets`.`created_at` DESC')
|
||||
.limit(limit)
|
||||
if !current_user.organization || ( !current_user.organization.shared || current_user.organization.shared == false )
|
||||
access_condition = {
|
||||
'query_string' => { 'default_field' => 'Ticket.customer_id', 'query' => current_user.id }
|
||||
}
|
||||
# customer_id: XXX
|
||||
# conditions = [ 'customer_id = ?', current_user.id ]
|
||||
else
|
||||
access_condition = {
|
||||
'query_string' => { 'query' => "Ticket.customer_id:#{current_user.id} OR Ticket.organization_id:#{current_user.organization.id}" }
|
||||
}
|
||||
# customer_id: XXX OR organization_id: XXX
|
||||
# conditions = [ '( customer_id = ? OR organization_id = ? )', current_user.id, current_user.organization.id ]
|
||||
end
|
||||
query_extention['bool']['must'].push access_condition
|
||||
end
|
||||
|
||||
# build result list
|
||||
items = SearchIndexBackend.search( query, limit, 'Ticket', query_extention )
|
||||
if !full
|
||||
ids = []
|
||||
tickets_all.each { |ticket|
|
||||
ids.push ticket.id
|
||||
items.each {|item|
|
||||
ids.push item[:id]
|
||||
}
|
||||
return ids
|
||||
end
|
||||
|
||||
tickets = []
|
||||
tickets_all.each { |ticket|
|
||||
tickets.push Ticket.lookup( id: ticket.id )
|
||||
items.each { |item|
|
||||
tickets.push Ticket.lookup( id: item[:id] )
|
||||
}
|
||||
tickets
|
||||
return tickets
|
||||
end
|
||||
|
||||
# fallback do sql query
|
||||
access_condition = Ticket.access_condition( current_user )
|
||||
|
||||
# do query
|
||||
# - stip out * we already search for *query* -
|
||||
if query
|
||||
query.gsub! '*', ''
|
||||
tickets_all = Ticket.select('DISTINCT(tickets.id)')
|
||||
.where(access_condition)
|
||||
.where( '( `tickets`.`title` LIKE ? OR `tickets`.`number` LIKE ? OR `ticket_articles`.`body` LIKE ? OR `ticket_articles`.`from` LIKE ? OR `ticket_articles`.`to` LIKE ? OR `ticket_articles`.`subject` LIKE ?)', "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%" )
|
||||
.joins(:articles)
|
||||
.order('`tickets`.`created_at` DESC')
|
||||
.limit(limit)
|
||||
else
|
||||
tickets_all = Ticket.select('DISTINCT(tickets.id)')
|
||||
.where(access_condition)
|
||||
.where(params[:condition])
|
||||
.order('`tickets`.`created_at` DESC')
|
||||
.limit(limit)
|
||||
end
|
||||
|
||||
# build result list
|
||||
if !full
|
||||
ids = []
|
||||
tickets_all.each { |ticket|
|
||||
ids.push ticket.id
|
||||
}
|
||||
return ids
|
||||
end
|
||||
|
||||
tickets = []
|
||||
tickets_all.each { |ticket|
|
||||
tickets.push Ticket.lookup( id: ticket.id )
|
||||
}
|
||||
tickets
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Ticket
|
||||
module SearchIndex
|
||||
# rubocop:disable ClassAndModuleChildren
|
||||
module Ticket::SearchIndex
|
||||
|
||||
=begin
|
||||
|
||||
|
@ -16,95 +15,94 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def search_index_update_backend
|
||||
return if !self.class.search_index_support_config
|
||||
def search_index_update_backend
|
||||
return if !self.class.search_index_support_config
|
||||
|
||||
# default ignored attributes
|
||||
ignore_attributes = {
|
||||
created_by_id: true,
|
||||
updated_by_id: true,
|
||||
active: true,
|
||||
# default ignored attributes
|
||||
ignore_attributes = {
|
||||
created_by_id: true,
|
||||
updated_by_id: true,
|
||||
active: true,
|
||||
}
|
||||
if self.class.search_index_support_config[:ignore_attributes]
|
||||
self.class.search_index_support_config[:ignore_attributes].each {|key, value|
|
||||
ignore_attributes[key] = value
|
||||
}
|
||||
if self.class.search_index_support_config[:ignore_attributes]
|
||||
self.class.search_index_support_config[:ignore_attributes].each {|key, value|
|
||||
ignore_attributes[key] = value
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
# for performance reasons, Model.search_index_reload will only collect if of object
|
||||
# get whole data here
|
||||
ticket = self.class.find(self.id)
|
||||
# for performance reasons, Model.search_index_reload will only collect if of object
|
||||
# get whole data here
|
||||
ticket = self.class.find(self.id)
|
||||
|
||||
# remove ignored attributes
|
||||
attributes = ticket.attributes
|
||||
ignore_attributes.each {|key, value|
|
||||
next if value != true
|
||||
attributes.delete( key.to_s )
|
||||
# remove ignored attributes
|
||||
attributes = ticket.attributes
|
||||
ignore_attributes.each {|key, value|
|
||||
next if value != true
|
||||
attributes.delete( key.to_s )
|
||||
}
|
||||
|
||||
# add tags
|
||||
tags = Tag.tag_list( object: 'Ticket', o_id: self.id )
|
||||
if tags && !tags.empty?
|
||||
attributes[:tag] = tags
|
||||
end
|
||||
|
||||
# lookup attributes of ref. objects (normally name and note)
|
||||
attributes = search_index_attribute_lookup( attributes, ticket )
|
||||
|
||||
# list ignored file extentions
|
||||
attachments_ignore = Setting.get('es_attachment_ignore') || [ '.png', '.jpg', '.jpeg', '.mpeg', '.mpg', '.mov', '.bin', '.exe' ]
|
||||
|
||||
# max attachment size
|
||||
attachment_max_size_in_mb = Setting.get('es_attachment_max_size_in_mb') || 40
|
||||
|
||||
# collect article data
|
||||
articles = Ticket::Article.where( ticket_id: self.id )
|
||||
attributes['articles'] = []
|
||||
articles.each {|article|
|
||||
article_attributes = article.attributes
|
||||
|
||||
# remove note needed attributes
|
||||
ignore = ['created_by_id', 'updated_by_id', 'updated_at', 'references', 'message_id_md5', 'message_id', 'in_reply_to', 'ticket_id']
|
||||
ignore.each {|attribute|
|
||||
article_attributes.delete( attribute )
|
||||
}
|
||||
|
||||
# add tags
|
||||
tags = Tag.tag_list( object: 'Ticket', o_id: self.id )
|
||||
if tags && !tags.empty?
|
||||
attributes[:tag] = tags
|
||||
end
|
||||
|
||||
# lookup attributes of ref. objects (normally name and note)
|
||||
attributes = search_index_attribute_lookup( attributes, ticket )
|
||||
article_attributes = search_index_attribute_lookup( article_attributes, article )
|
||||
|
||||
# list ignored file extentions
|
||||
attachments_ignore = Setting.get('es_attachment_ignore') || [ '.png', '.jpg', '.jpeg', '.mpeg', '.mpg', '.mov', '.bin', '.exe' ]
|
||||
# index raw text body
|
||||
if article_attributes['content_type'] && article_attributes['content_type'] == 'text/html' && article_attributes['body']
|
||||
article_attributes['body'] = article_attributes['body'].html2text
|
||||
end
|
||||
|
||||
# max attachment size
|
||||
attachment_max_size_in_mb = Setting.get('es_attachment_max_size_in_mb') || 40
|
||||
|
||||
# collect article data
|
||||
articles = Ticket::Article.where( ticket_id: self.id )
|
||||
attributes['articles'] = []
|
||||
articles.each {|article|
|
||||
article_attributes = article.attributes
|
||||
|
||||
# remove note needed attributes
|
||||
ignore = ['created_by_id', 'updated_by_id', 'updated_at', 'references', 'message_id_md5', 'message_id', 'in_reply_to', 'ticket_id']
|
||||
ignore.each {|attribute|
|
||||
article_attributes.delete( attribute )
|
||||
}
|
||||
|
||||
# lookup attributes of ref. objects (normally name and note)
|
||||
article_attributes = search_index_attribute_lookup( article_attributes, article )
|
||||
|
||||
# index raw text body
|
||||
if article_attributes['content_type'] && article_attributes['content_type'] == 'text/html' && article_attributes['body']
|
||||
article_attributes['body'] = article_attributes['body'].html2text
|
||||
# lookup attachments
|
||||
article.attachments.each {|attachment|
|
||||
if !article_attributes['attachments']
|
||||
article_attributes['attachments'] = []
|
||||
end
|
||||
|
||||
# lookup attachments
|
||||
article.attachments.each {|attachment|
|
||||
if !article_attributes['attachments']
|
||||
article_attributes['attachments'] = []
|
||||
end
|
||||
# check file size
|
||||
if attachment.content && attachment.content.size / 1024 <= attachment_max_size_in_mb * 1024
|
||||
|
||||
# check file size
|
||||
if attachment.content && attachment.content.size / 1024 <= attachment_max_size_in_mb * 1024
|
||||
|
||||
# check ignored files
|
||||
if attachment.filename
|
||||
filename_extention = attachment.filename.downcase
|
||||
filename_extention.gsub!(/^.*(\..+?)$/, '\\1')
|
||||
if !attachments_ignore.include?( filename_extention.downcase )
|
||||
data = {
|
||||
'_name' => attachment.filename,
|
||||
'_content' => Base64.encode64( attachment.content )
|
||||
}
|
||||
article_attributes['attachments'].push data
|
||||
end
|
||||
# check ignored files
|
||||
if attachment.filename
|
||||
filename_extention = attachment.filename.downcase
|
||||
filename_extention.gsub!(/^.*(\..+?)$/, '\\1')
|
||||
if !attachments_ignore.include?( filename_extention.downcase )
|
||||
data = {
|
||||
'_name' => attachment.filename,
|
||||
'_content' => Base64.encode64( attachment.content )
|
||||
}
|
||||
article_attributes['attachments'].push data
|
||||
end
|
||||
end
|
||||
}
|
||||
attributes['articles'].push article_attributes
|
||||
end
|
||||
}
|
||||
attributes['articles'].push article_attributes
|
||||
}
|
||||
|
||||
return if !attributes
|
||||
SearchIndexBackend.add(self.class.to_s, attributes)
|
||||
end
|
||||
return if !attributes
|
||||
SearchIndexBackend.add(self.class.to_s, attributes)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
# rubocop:disable ClassAndModuleChildren
|
||||
class Ticket::State < ApplicationModel
|
||||
belongs_to :state_type, class_name: 'Ticket::StateType'
|
||||
validates :name, presence: true
|
||||
|
||||
class Ticket
|
||||
class State < ApplicationModel
|
||||
belongs_to :state_type, class_name: 'Ticket::StateType'
|
||||
validates :name, presence: true
|
||||
|
||||
latest_change_support
|
||||
latest_change_support
|
||||
|
||||
=begin
|
||||
|
||||
|
@ -19,18 +18,18 @@ returns:
|
|||
|
||||
=end
|
||||
|
||||
def self.by_category(category)
|
||||
if category == 'open'
|
||||
return Ticket::State.where(
|
||||
state_type_id: Ticket::StateType.where( name: ['new', 'open', 'pending reminder', 'pending action'] )
|
||||
)
|
||||
elsif category == 'closed'
|
||||
return Ticket::State.where(
|
||||
state_type_id: Ticket::StateType.where( name: ['closed'] )
|
||||
)
|
||||
end
|
||||
raise "Unknown category '#{category}'"
|
||||
def self.by_category(category)
|
||||
if category == 'open'
|
||||
return Ticket::State.where(
|
||||
state_type_id: Ticket::StateType.where( name: ['new', 'open', 'pending reminder', 'pending action'] )
|
||||
)
|
||||
elsif category == 'closed'
|
||||
return Ticket::State.where(
|
||||
state_type_id: Ticket::StateType.where( name: ['closed'] )
|
||||
)
|
||||
end
|
||||
raise "Unknown category '#{category}'"
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
|
@ -46,10 +45,9 @@ returns:
|
|||
|
||||
=end
|
||||
|
||||
def ignore_escalation?
|
||||
ignore_escalation = ['removed', 'closed', 'merged']
|
||||
return true if ignore_escalation.include?( self.name )
|
||||
false
|
||||
end
|
||||
def ignore_escalation?
|
||||
ignore_escalation = ['removed', 'closed', 'merged']
|
||||
return true if ignore_escalation.include?( self.name )
|
||||
false
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Ticket
|
||||
class StateType < ApplicationModel
|
||||
has_many :states, class_name: 'Ticket::State'
|
||||
validates :name, presence: true
|
||||
latest_change_support
|
||||
end
|
||||
# rubocop:disable ClassAndModuleChildren
|
||||
class Ticket::StateType < ApplicationModel
|
||||
has_many :states, class_name: 'Ticket::State'
|
||||
validates :name, presence: true
|
||||
latest_change_support
|
||||
end
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Ticket
|
||||
module Subject
|
||||
# rubocop:disable ClassAndModuleChildren
|
||||
module Ticket::Subject
|
||||
|
||||
=begin
|
||||
|
||||
|
@ -16,28 +15,28 @@ returns
|
|||
|
||||
=end
|
||||
|
||||
def subject_build (subject)
|
||||
def subject_build (subject)
|
||||
|
||||
# clena subject
|
||||
subject = self.subject_clean(subject)
|
||||
# clena subject
|
||||
subject = self.subject_clean(subject)
|
||||
|
||||
ticket_hook = Setting.get('ticket_hook')
|
||||
ticket_hook_divider = Setting.get('ticket_hook_divider')
|
||||
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
|
||||
# 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
|
||||
|
@ -51,30 +50,29 @@ returns
|
|||
|
||||
=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')
|
||||
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 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 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)+/, ''
|
||||
# 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
|
||||
|
||||
subject
|
||||
# resize subject based on config
|
||||
if subject.length > ticket_subject_size.to_i
|
||||
subject = subject[ 0, ticket_subject_size.to_i ] + '[...]'
|
||||
end
|
||||
|
||||
subject
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue