123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429 |
- class Ticket < ApplicationModel
- before_create :number_generate, :check_defaults
- before_update :check_defaults
- before_destroy :destroy_dependencies
- belongs_to :group
- has_many :articles, :class_name => 'Ticket::Article', :after_add => :cache_update, :after_remove => :cache_update
- belongs_to :organization
- belongs_to :ticket_state, :class_name => 'Ticket::State'
- belongs_to :ticket_priority, :class_name => 'Ticket::Priority'
- belongs_to :owner, :class_name => 'User'
- belongs_to :customer, :class_name => 'User'
- belongs_to :created_by, :class_name => 'User'
- belongs_to :create_article_type, :class_name => 'Ticket::Article::Type'
- belongs_to :create_article_sender, :class_name => 'Ticket::Article::Sender'
- def self.number_check (string)
- self.number_adapter.number_check_item(string)
- end
- def agent_of_group
- Group.find( self.group_id ).users.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
- def merge_to(data)
- # update articles
- Ticket::Article.where( :ticket_id => self.id ).update_all( ['ticket_id = ?', data[:ticket_id] ] )
- # update history
- # create new merge article
- Ticket::Article.create(
- :created_by_id => data[:created_by_id],
- :ticket_id => self.id,
- :ticket_article_type_id => Ticket::Article::Type.lookup( :name => 'note' ).id,
- :ticket_article_sender_id => Ticket::Article::Sender.lookup( :name => 'Agent' ).id,
- :body => 'merged',
- :internal => false
- )
- # add history to both
- # link tickets
- Link.add(
- :link_type => 'parent',
- :link_object_source => 'Ticket',
- :link_object_source_value => data[:ticket_id],
- :link_object_target => 'Ticket',
- :link_object_target_value => self.id
- )
- # set state to 'merged'
- self.ticket_state_id = Ticket::State.lookup( :name => 'merged' ).id
- # rest owner
- self.owner_id = User.where( :login => '-' ).first.id
- # save ticket
- self.save
- end
- # def self.agent
- # Role.where( :name => ['Agent'], :active => true ).first.users.where( :active => true ).uniq()
- # 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
- 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
- # ticket.permission(
- # :current_user => 123
- # )
- def permission (data)
- # 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 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
- end
- # check agent
- return true if self.owner_id == data[:current_user].id
- data[:current_user].groups.each {|group|
- return true if self.group.id == group.id
- }
- return false
- end
- # Ticket.overview_list(
- # :current_user => 123,
- # )
- 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 )
- else
- overviews = Overview.where( :role_id => role.id, :organization_shared => false )
- end
- return overviews
- end
- # get agent overviews
- role = data[:current_user].is_role( 'Agent' )
- overviews = Overview.where( :role_id => role.id )
- return overviews
- end
- # Ticket.overview(
- # :view => 'some_view_url',
- # :current_user => OBJECT,
- # )
- 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.meta[:url]
- 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( overview.condition ).count()
- # get meta info
- all = overview.meta
- # 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( 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( 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( 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( overview_selected.condition ).
- count()
- return {
- :tickets => tickets,
- :tickets_count => tickets_count,
- :overview => overview_selected_raw,
- }
- end
- # Ticket.create_attributes(
- # :current_user_id => 123,
- # )
- def self.create_attributes (data)
- # get groups
- group_ids = []
- Group.where( :active => true ).each { |group|
- group_ids.push group.id
- }
- # get related users
- # users = {}
- user_ids = []
- agents = {}
- Ticket.agents.each { |user|
- agents[ user.id ] = 1
- user_ids.push user.id
- }
- groups_users = {}
- group_ids.each {|group_id|
- groups_users[ group_id ] = []
- Group.find(group_id).users.each {|user|
- next if !agents[ user.id ]
- groups_users[ group_id ].push user.id
- # if !users[user.id]
- # users[user.id] = User.user_data_full(user.id)
- # end
- }
- }
- # get states
- ticket_state_ids = []
- Ticket::State.where( :active => true ).each { |state|
- ticket_state_ids.push state.id
- }
- # get priorities
- ticket_priority_ids = []
- Ticket::Priority.where( :active => true ).each { |priority|
- ticket_priority_ids.push priority.id
- }
- return {
- # :users => users,
- :owner_id => user_ids,
- :group_id__owner_id => groups_users,
- :group_id => group_ids,
- :ticket_state_id => ticket_state_ids,
- :ticket_priority_id => ticket_priority_ids,
- }
- end
- def self.number_adapter
- # load backend based on config
- adapter_name = Setting.get('ticket_number')
- adapter = nil
- case adapter_name
- when Symbol, String
- require "ticket/number/#{adapter_name.to_s.downcase}"
- adapter = Ticket::Number.const_get("#{adapter_name.to_s.capitalize}")
- else
- raise "Missing number_adapter '#{adapter_name}'"
- end
- return adapter
- end
- private
- def number_generate
- # generate number
- (1..25_000).each do |i|
- number = Ticket.number_adapter.number_generate_item()
- ticket = Ticket.where( :number => number ).first
- if ticket != nil
- number = Ticket.number_adapter.number_generate_item()
- else
- self.number = number
- return number
- end
- end
- end
- def check_defaults
- if !self.owner_id
- self.owner_id = 1
- end
- # if self.customer_id && ( !self.organization_id || self.organization_id.empty? )
- if self.customer_id
- customer = User.find( self.customer_id )
- if self.organization_id != customer.organization_id
- self.organization_id = customer.organization_id
- end
- end
- end
- def destroy_dependencies
- # delete history
- History.history_destroy( 'Ticket', self.id )
- # delete articles
- self.articles.destroy_all
- end
- class Number
- end
- class Flag < ApplicationModel
- end
- class Priority < ApplicationModel
- self.table_name = 'ticket_priorities'
- validates :name, :presence => true
- end
- class StateType < ApplicationModel
- has_many :states, :class_name => 'Ticket::State'
- validates :name, :presence => true
- end
- class State < ApplicationModel
- belongs_to :state_type, :class_name => 'Ticket::StateType'
- validates :name, :presence => true
- end
- end
|