123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786 |
- module Import
- end
- module Import::OTRS
- def self.request(part)
- url = Setting.get('import_otrs_endpoint') + '/' + part + ';Key=' + Setting.get('import_otrs_endpoint_key')
- puts 'GET: ' + url
- response = UserAgent.request(
- url,
- {
- :user => Setting.get('import_otrs_user'),
- :password => Setting.get('import_otrs_password'),
- },
- )
- if !response.success?
- puts "ERROR: #{response.error}"
- return
- end
- return response
- end
- def self.post(base, data)
- url = Setting.get('import_otrs_endpoint') + '/' + base
- data['Key'] = Setting.get('import_otrs_endpoint_key')
- puts 'POST: ' + url
- response = UserAgent.request(
- url,
- {
- :method => 'post',
- :user => Setting.get('import_otrs_user'),
- :password => Setting.get('import_otrs_password'),
- },
- )
- if !response.success?
- puts "ERROR: #{response.error}"
- return
- end
- return response
- end
- def self.json(response)
- data = Encode.conv( 'utf8', response.body.to_s )
- JSON.parse( data )
- end
- def self.auth(username, password)
- response = post( "public.pl", { :Action => 'Export', :Type => 'Auth', :User => username, :Pw => password } )
- return if !response
- return if !response.success?
- result = json(response)
- return result
- end
- def self.session(session_id)
- response = post( "public.pl", { :Action => 'Export', :Type => 'SessionCheck', :SessionID => session_id } )
- return if !response
- return if !response.success?
- result = json(response)
- return result
- end
- def self.start
- puts 'Start import...'
- # # set system in import mode
- # Setting.set('import_mode', true)
- # check if system is in import mode
- if !Setting.get('import_mode')
- raise "System is not in import mode!"
- end
- response = request("public.pl?Action=Export")
- return if !response
- return if !response.success?
- #self.ticket('156115')
- #return
- # create states
- ticket_state
- # create priorities
- ticket_priority
- # create groups
- ticket_group
- # create agents
- user
- # create customers
- # customer
- result = JSON.parse( response.body )
- result = result.reverse
- Thread.abort_on_exception = true
- thread_count = 4
- threads = {}
- (1..thread_count).each {|thread|
- threads[thread] = Thread.new {
- sleep thread * 3
- puts "Started import thread# #{thread} ..."
- run = true
- while run
- ticket_ids = result.pop(20)
- if !ticket_ids.empty?
- self.ticket(ticket_ids)
- else
- puts "... thread# #{thread}, no more work."
- run = false
- end
- end
- }
- }
- (1..thread_count).each {|thread|
- threads[thread].join
- }
- return
- end
- def self.diff_worker
- return if !Setting.get('import_mode')
- return if Setting.get('import_otrs_endpoint') == 'http://otrs_host/otrs'
- self.diff
- end
- def self.diff
- puts 'Start diff...'
- # check if system is in import mode
- if !Setting.get('import_mode')
- raise "System is not in import mode!"
- end
- # create states
- ticket_state
- # create priorities
- ticket_priority
- # create groups
- ticket_group
- # create agents
- user
- self.ticket_diff()
- return
- end
- def self.ticket_diff()
- url = "public.pl?Action=Export;Type=TicketDiff;Limit=30"
- response = request( url )
- return if !response
- return if !response.success?
- result = json(response)
- self._ticket_result(result)
- end
- def self.ticket(ticket_ids)
- url = "public.pl?Action=Export;Type=Ticket;"
- ticket_ids.each {|ticket_id|
- url = url + "TicketID=#{CGI::escape ticket_id};"
- }
- response = request( url )
- return if !response
- return if !response.success?
- result = json(response)
- self._ticket_result(result)
- end
- def self._ticket_result(result)
- # puts result.inspect
- map = {
- :Ticket => {
- :Changed => :updated_at,
- :Created => :created_at,
- :CreateBy => :created_by_id,
- :TicketNumber => :number,
- :QueueID => :group_id,
- :StateID => :ticket_state_id,
- :PriorityID => :ticket_priority_id,
- :Owner => :owner,
- :CustomerUserID => :customer,
- :Title => :title,
- :TicketID => :id,
- :FirstResponse => :first_response,
- # :FirstResponseTimeDestinationDate => :first_response_escal_date,
- # :FirstResponseInMin => :first_response_in_min,
- # :FirstResponseDiffInMin => :first_response_diff_in_min,
- :Closed => :close_time,
- # :SoltutionTimeDestinationDate => :close_time_escal_date,
- # :CloseTimeInMin => :close_time_in_min,
- # :CloseTimeDiffInMin => :close_time_diff_in_min,
- },
- :Article => {
- :SenderType => :ticket_article_sender,
- :ArticleType => :ticket_article_type,
- :TicketID => :ticket_id,
- :ArticleID => :id,
- :Body => :body,
- :From => :from,
- :To => :to,
- :Cc => :cc,
- :Subject => :subject,
- :InReplyTo => :in_reply_to,
- :MessageID => :message_id,
- # :ReplyTo => :reply_to,
- :References => :references,
- :Changed => :updated_at,
- :Created => :created_at,
- :ChangedBy => :updated_by_id,
- :CreatedBy => :created_by_id,
- },
- }
- result.each {|record|
- # use transaction
- ActiveRecord::Base.transaction do
- ticket_new = {
- :title => '',
- :created_by_id => 1,
- :updated_by_id => 1,
- }
- map[:Ticket].each { |key,value|
- if record['Ticket'][key.to_s] && record['Ticket'][key.to_s].class == String
- ticket_new[value] = Encode.conv( 'utf8', record['Ticket'][key.to_s] )
- else
- ticket_new[value] = record['Ticket'][key.to_s]
- end
- }
- # puts key.to_s
- # puts value.to_s
- #puts 'new ticket data ' + ticket_new.inspect
- # check if state already exists
- ticket_old = Ticket.where( :id => ticket_new[:id] ).first
- #puts 'TICKET OLD ' + ticket_old.inspect
- # find user
- if ticket_new[:owner]
- user = User.lookup( :login => ticket_new[:owner] )
- if user
- ticket_new[:owner_id] = user.id
- else
- ticket_new[:owner_id] = 1
- end
- ticket_new.delete(:owner)
- end
- if ticket_new[:customer]
- user = User.lookup( :login => ticket_new[:customer] )
- if user
- ticket_new[:customer_id] = user.id
- else
- ticket_new[:customer_id] = 1
- end
- ticket_new.delete(:customer)
- else
- ticket_new[:customer_id] = 1
- end
- # puts 'ttt' + ticket_new.inspect
- # set state types
- if ticket_old
- puts "update Ticket.find(#{ticket_new[:id]})"
- ticket_old.update_attributes(ticket_new)
- else
- puts "add Ticket.find(#{ticket_new[:id]})"
- ticket = Ticket.new(ticket_new)
- ticket.id = ticket_new[:id]
- ticket.save
- end
- record['Articles'].each { |article|
- # get article values
- article_new = {
- :created_by_id => 1,
- :updated_by_id => 1,
- }
- map[:Article].each { |key,value|
- if article[key.to_s]
- article_new[value] = Encode.conv( 'utf8', article[key.to_s] )
- end
- }
- # create customer/sender if needed
- if article_new[:ticket_article_sender] == 'customer' && article_new[:created_by_id].to_i == 1 && !article_new[:from].empty?
- # set extra headers
- begin
- email = Mail::Address.new( article_new[:from] ).address
- rescue
- email = article_new[:from]
- if article_new[:from] =~ /<(.+?)>/
- email = $1
- end
- end
- user = User.where( :email => email ).first
- if !user
- user = User.where( :login => email ).first
- end
- if !user
- begin
- display_name = Mail::Address.new( article_new[:from] ).display_name ||
- ( Mail::Address.new( article_new[:from] ).comments && Mail::Address.new( article_new[:from] ).comments[0] )
- rescue
- display_name = article_new[:from]
- end
- # do extra decoding because we needed to use field.value
- display_name = Mail::Field.new( 'X-From', display_name ).to_s
- roles = Role.lookup( :name => 'Customer' )
- user = User.create(
- :login => email,
- :firstname => display_name,
- :lastname => '',
- :email => email,
- :password => '',
- :active => true,
- :role_ids => [roles.id],
- :updated_by_id => 1,
- :created_by_id => 1,
- )
- end
- article_new[:created_by_id] = user.id
- end
- if article_new[:ticket_article_sender] == 'customer'
- article_new[:ticket_article_sender_id] = Ticket::Article::Sender.lookup( :name => 'Customer' ).id
- article_new.delete( :ticket_article_sender )
- end
- if article_new[:ticket_article_sender] == 'agent'
- article_new[:ticket_article_sender_id] = Ticket::Article::Sender.lookup( :name => 'Agent' ).id
- article_new.delete( :ticket_article_sender )
- end
- if article_new[:ticket_article_sender] == 'system'
- article_new[:ticket_article_sender_id] = Ticket::Article::Sender.lookup( :name => 'System' ).id
- article_new.delete( :ticket_article_sender )
- end
- if article_new[:ticket_article_type] == 'email-external'
- article_new[:ticket_article_type_id] = Ticket::Article::Type.lookup( :name => 'email' ).id
- article_new[:internal] = false
- elsif article_new[:ticket_article_type] == 'email-internal'
- article_new[:ticket_article_type_id] = Ticket::Article::Type.lookup( :name => 'email' ).id
- article_new[:internal] = true
- elsif article_new[:ticket_article_type] == 'note-external'
- article_new[:ticket_article_type_id] = Ticket::Article::Type.lookup( :name => 'note' ).id
- article_new[:internal] = false
- elsif article_new[:ticket_article_type] == 'note-internal'
- article_new[:ticket_article_type_id] = Ticket::Article::Type.lookup( :name => 'note' ).id
- article_new[:internal] = true
- elsif article_new[:ticket_article_type] == 'phone'
- article_new[:ticket_article_type_id] = Ticket::Article::Type.lookup( :name => 'phone' ).id
- article_new[:internal] = false
- elsif article_new[:ticket_article_type] == 'webrequest'
- article_new[:ticket_article_type_id] = Ticket::Article::Type.lookup( :name => 'web' ).id
- article_new[:internal] = false
- else
- article_new[:ticket_article_type_id] = 9
- end
- article_new.delete( :ticket_article_type )
- article_old = Ticket::Article.where( :id => article_new[:id] ).first
- #puts 'ARTICLE OLD ' + article_old.inspect
- # set state types
- if article_old
- puts "update Ticket::Article.find(#{article_new[:id]})"
- # puts article_new.inspect
- article_old.update_attributes(article_new)
- else
- puts "add Ticket::Article.find(#{article_new[:id]})"
- article = Ticket::Article.new(article_new)
- article.id = article_new[:id]
- article.save
- end
- }
- record['History'].each { |history|
- # puts '-------'
- # puts history.inspect
- if history['HistoryType'] == 'NewTicket'
- History.add(
- :id => history['HistoryID'],
- :o_id => history['TicketID'],
- :history_type => 'created',
- :history_object => 'Ticket',
- :created_at => history['CreateTime'],
- :created_by_id => history['CreateBy']
- )
- end
- if history['HistoryType'] == 'StateUpdate'
- data = history['Name']
- # "%%new%%open%%"
- from = nil
- to = nil
- if data =~ /%%(.+?)%%(.+?)%%/
- from = $1
- to = $2
- state_from = Ticket::State.lookup( :name => from )
- state_to = Ticket::State.lookup( :name => to )
- if state_from
- from_id = state_from.id
- end
- if state_to
- to_id = state_to.id
- end
- end
- # puts "STATE UPDATE (#{history['HistoryID']}): -> #{from}->#{to}"
- History.add(
- :id => history['HistoryID'],
- :o_id => history['TicketID'],
- :history_type => 'updated',
- :history_object => 'Ticket',
- :history_attribute => 'ticket_state',
- :value_from => from,
- :id_from => from_id,
- :value_to => to,
- :id_to => to_id,
- :created_at => history['CreateTime'],
- :created_by_id => history['CreateBy']
- )
- end
- if history['HistoryType'] == 'Move'
- data = history['Name']
- # "%%Queue1%%5%%Postmaster%%1"
- from = nil
- to = nil
- if data =~ /%%(.+?)%%(.+?)%%(.+?)%%(.+?)$/
- from = $1
- from_id = $2
- to = $3
- to_id = $4
- end
- History.add(
- :id => history['HistoryID'],
- :o_id => history['TicketID'],
- :history_type => 'updated',
- :history_object => 'Ticket',
- :history_attribute => 'group',
- :value_from => from,
- :value_to => to,
- :id_from => from_id,
- :id_to => to_id,
- :created_at => history['CreateTime'],
- :created_by_id => history['CreateBy']
- )
- end
- if history['HistoryType'] == 'PriorityUpdate'
- data = history['Name']
- # "%%3 normal%%3%%5 very high%%5"
- from = nil
- to = nil
- if data =~ /%%(.+?)%%(.+?)%%(.+?)%%(.+?)$/
- from = $1
- from_id = $2
- to = $3
- to_id = $4
- end
- History.add(
- :id => history['HistoryID'],
- :o_id => history['TicketID'],
- :history_type => 'updated',
- :history_object => 'Ticket',
- :history_attribute => 'ticket_priority',
- :value_from => from,
- :value_to => to,
- :id_from => from_id,
- :id_to => to_id,
- :created_at => history['CreateTime'],
- :created_by_id => history['CreateBy']
- )
- end
- if history['ArticleID'] && history['ArticleID'] != 0
- History.add(
- :id => history['HistoryID'],
- :o_id => history['ArticleID'],
- :history_type => 'created',
- :history_object => 'Ticket::Article',
- :related_o_id => history['TicketID'],
- :related_history_object => 'Ticket',
- :created_at => history['CreateTime'],
- :created_by_id => history['CreateBy']
- )
- end
- }
- end
- }
- end
- def self.ticket_state
- response = request( "public.pl?Action=Export;Type=State" )
- return if !response
- return if !response.success?
- result = json(response)
- # puts result.inspect
- map = {
- :ChangeTime => :updated_at,
- :CreateTime => :created_at,
- :CreateBy => :created_by_id,
- :ChangeBy => :updated_by_id,
- :Name => :name,
- :ID => :id,
- :ValidID => :active,
- :Comment => :note,
- };
- Ticket::State.all.each {|state|
- state.name = state.name + '_tmp'
- state.save
- }
- result.each { |state|
- _set_valid(state)
- # get new attributes
- state_new = {
- :created_by_id => 1,
- :updated_by_id => 1,
- }
- map.each { |key,value|
- if state[key.to_s]
- state_new[value] = state[key.to_s]
- end
- }
- # check if state already exists
- state_old = Ticket::State.where( :id => state_new[:id] ).first
- # puts 'st: ' + state['TypeName']
- # set state types
- if state['TypeName'] == 'pending auto'
- state['TypeName'] = 'pending action'
- end
- ticket_state_type = Ticket::StateType.where( :name => state['TypeName'] ).first
- state_new[:state_type_id] = ticket_state_type.id
- if state_old
- # puts 'TS: ' + state_new.inspect
- state_old.update_attributes(state_new)
- else
- state = Ticket::State.new(state_new)
- state.id = state_new[:id]
- state.save
- end
- }
- end
- def self.ticket_priority
- response = request( "public.pl?Action=Export;Type=Priority" )
- return if !response
- return if !response.success?
- result = json(response)
- map = {
- :ChangeTime => :updated_at,
- :CreateTime => :created_at,
- :CreateBy => :created_by_id,
- :ChangeBy => :updated_by_id,
- :Name => :name,
- :ID => :id,
- :ValidID => :active,
- :Comment => :note,
- };
- result.each { |priority|
- _set_valid(priority)
- # get new attributes
- priority_new = {
- :created_by_id => 1,
- :updated_by_id => 1,
- }
- map.each { |key,value|
- if priority[key.to_s]
- priority_new[value] = priority[key.to_s]
- end
- }
- # check if state already exists
- priority_old = Ticket::Priority.where( :id => priority_new[:id] ).first
- # set state types
- if priority_old
- priority_old.update_attributes(priority_new)
- else
- priority = Ticket::Priority.new(priority_new)
- priority.id = priority_new[:id]
- priority.save
- end
- }
- end
- def self.ticket_group
- response = request( "public.pl?Action=Export;Type=Queue" )
- return if !response
- return if !response.success?
- result = json(response)
- map = {
- :ChangeTime => :updated_at,
- :CreateTime => :created_at,
- :CreateBy => :created_by_id,
- :ChangeBy => :updated_by_id,
- :Name => :name,
- :QueueID => :id,
- :ValidID => :active,
- :Comment => :note,
- };
- result.each { |group|
- _set_valid(group)
- # get new attributes
- group_new = {
- :created_by_id => 1,
- :updated_by_id => 1,
- }
- map.each { |key,value|
- if group[key.to_s]
- group_new[value] = group[key.to_s]
- end
- }
- # check if state already exists
- group_old = Group.where( :id => group_new[:id] ).first
- # set state types
- if group_old
- group_old.update_attributes(group_new)
- else
- group = Group.new(group_new)
- group.id = group_new[:id]
- group.save
- end
- }
- end
- def self.user
- response = request( "public.pl?Action=Export;Type=User" )
- return if !response
- return if !response.success?
- result = json(response)
- map = {
- :ChangeTime => :updated_at,
- :CreateTime => :created_at,
- :CreateBy => :created_by_id,
- :ChangeBy => :updated_by_id,
- :UserID => :id,
- :ValidID => :active,
- :Comment => :note,
- :UserEmail => :email,
- :UserFirstname => :firstname,
- :UserLastname => :lastname,
- # :UserTitle =>
- :UserLogin => :login,
- :UserPw => :password,
- };
- result.each { |user|
- # puts 'USER: ' + user.inspect
- _set_valid(user)
- role = Role.lookup( :name => 'Agent' )
- # get new attributes
- user_new = {
- :created_by_id => 1,
- :updated_by_id => 1,
- :source => 'OTRS Import',
- :role_ids => [ role.id ],
- }
- map.each { |key,value|
- if user[key.to_s]
- user_new[value] = user[key.to_s]
- end
- }
- # check if state already exists
- # user_old = User.where( :login => user_new[:login] ).first
- user_old = User.where( :id => user_new[:id] ).first
- # set state types
- if user_old
- puts "update User.find(#{user_new[:id]})"
- # puts 'Update User' + user_new.inspect
- user_new.delete( :role_ids )
- user_old.update_attributes(user_new)
- else
- puts "add User.find(#{user_new[:id]})"
- # puts 'Add User' + user_new.inspect
- user = User.new(user_new)
- user.id = user_new[:id]
- user.save
- end
- # end
- }
- end
- def self.customer
- done = false
- count = 0
- while done == false
- sleep 2
- puts "Count=#{count};Offset=#{count}"
- response = request( "public.pl?Action=Export;Type=Customer;Count=100;Offset=#{count}" )
- return if !response
- count = count + 3000
- return if !response.success?
- result = json(response)
- map = {
- :ChangeTime => :updated_at,
- :CreateTime => :created_at,
- :CreateBy => :created_by_id,
- :ChangeBy => :updated_by_id,
- :ValidID => :active,
- :UserComment => :note,
- :UserEmail => :email,
- :UserFirstname => :firstname,
- :UserLastname => :lastname,
- # :UserTitle =>
- :UserLogin => :login,
- :UserPassword => :password,
- :UserPhone => :phone,
- :UserFax => :fax,
- :UserMobile => :mobile,
- :UserStreet => :street,
- :UserZip => :zip,
- :UserCity => :city,
- :UserCountry => :country,
- };
- done = true
- result.each { |user|
- done = false
- _set_valid(user)
- role = Role.lookup( :name => 'Customer' )
- # get new attributes
- user_new = {
- :created_by_id => 1,
- :updated_by_id => 1,
- :source => 'OTRS Import',
- :role_ids => [role.id],
- }
- map.each { |key,value|
- if user[key.to_s]
- user_new[value] = user[key.to_s]
- end
- }
- # check if state already exists
- # user_old = User.where( :login => user_new[:login] ).first
- user_old = User.where( :login => user_new[:login] ).first
- # set state types
- if user_old
- puts "update User.find(#{user_new[:id]})"
- # puts 'Update User' + user_new.inspect
- user_old.update_attributes(user_new)
- else
- # puts 'Add User' + user_new.inspect
- puts "add User.find(#{user_new[:id]})"
- user = User.new(user_new)
- user.save
- end
- }
- end
- end
- def self._set_valid(record)
- # map
- if record['ValidID'] == '3'
- record['ValidID'] = '2'
- end
- if record['ValidID'] == '2'
- record['ValidID'] = false
- end
- if record['ValidID'] == '1'
- record['ValidID'] = true
- end
- if record['ValidID'] == '0'
- record['ValidID'] = false
- end
- end
- end
|