2015-07-21 13:46:01 +00:00
|
|
|
require 'base64'
|
|
|
|
|
2013-02-01 19:58:53 +00:00
|
|
|
module Import
|
|
|
|
end
|
2013-01-07 08:46:38 +00:00
|
|
|
module Import::OTRS
|
2015-05-07 11:57:19 +00:00
|
|
|
|
|
|
|
=begin
|
|
|
|
|
2016-01-24 15:58:02 +00:00
|
|
|
result = request_json(Subaction: 'List', 1)
|
2015-05-07 11:57:19 +00:00
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
{ some json structure }
|
|
|
|
|
2016-01-24 15:58:02 +00:00
|
|
|
result = request_json(Subaction: 'List')
|
2015-05-07 11:57:19 +00:00
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
"some data string"
|
|
|
|
|
|
|
|
=end
|
|
|
|
|
|
|
|
def self.request_json(data, data_only = false)
|
|
|
|
response = post(data)
|
|
|
|
if !response
|
2016-03-01 14:26:46 +00:00
|
|
|
raise "Can't connect to Zammad Migrator"
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
|
|
|
if !response.success?
|
2016-03-01 14:26:46 +00:00
|
|
|
raise "Can't connect to Zammad Migrator"
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
|
|
|
result = json(response)
|
|
|
|
if !result
|
2016-03-01 14:26:46 +00:00
|
|
|
raise 'Invalid response'
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
|
|
|
if data_only
|
|
|
|
result['Result']
|
|
|
|
else
|
|
|
|
result
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
=begin
|
|
|
|
|
|
|
|
start get request to backend, add auth data automatically
|
|
|
|
|
|
|
|
result = request('Subaction=List')
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
"some data string"
|
|
|
|
|
|
|
|
=end
|
|
|
|
|
2013-01-07 08:46:38 +00:00
|
|
|
def self.request(part)
|
2015-05-07 11:57:19 +00:00
|
|
|
url = Setting.get('import_otrs_endpoint') + part + ';Key=' + Setting.get('import_otrs_endpoint_key')
|
|
|
|
log 'GET: ' + url
|
|
|
|
response = UserAgent.get(
|
2013-09-19 14:17:25 +00:00
|
|
|
url,
|
2015-05-07 11:57:19 +00:00
|
|
|
{},
|
2013-09-19 14:17:25 +00:00
|
|
|
{
|
2015-05-07 11:57:19 +00:00
|
|
|
open_timeout: 10,
|
|
|
|
read_timeout: 60,
|
2016-01-21 01:07:50 +00:00
|
|
|
total_timeout: 180,
|
2015-04-27 13:42:53 +00:00
|
|
|
user: Setting.get('import_otrs_user'),
|
|
|
|
password: Setting.get('import_otrs_password'),
|
2013-09-19 14:17:25 +00:00
|
|
|
},
|
|
|
|
)
|
|
|
|
if !response.success?
|
2015-05-07 11:57:19 +00:00
|
|
|
log "ERROR: #{response.error}"
|
2013-01-25 22:17:50 +00:00
|
|
|
return
|
|
|
|
end
|
2015-04-30 17:20:27 +00:00
|
|
|
response
|
2013-01-07 08:46:38 +00:00
|
|
|
end
|
2015-05-07 11:57:19 +00:00
|
|
|
|
|
|
|
=begin
|
|
|
|
|
|
|
|
start post request to backend, add auth data automatically
|
|
|
|
|
|
|
|
result = request('Subaction=List')
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
"some data string"
|
|
|
|
|
|
|
|
=end
|
|
|
|
|
|
|
|
def self.post(data, url = nil)
|
|
|
|
if !url
|
|
|
|
url = Setting.get('import_otrs_endpoint')
|
|
|
|
data['Action'] = 'ZammadMigrator'
|
|
|
|
end
|
2013-01-23 23:53:39 +00:00
|
|
|
data['Key'] = Setting.get('import_otrs_endpoint_key')
|
2015-05-07 11:57:19 +00:00
|
|
|
log 'POST: ' + url
|
|
|
|
log 'PARAMS: ' + data.inspect
|
|
|
|
open_timeout = 10
|
|
|
|
read_timeout = 120
|
2016-01-21 01:07:50 +00:00
|
|
|
total_timeout = 360
|
2015-05-07 11:57:19 +00:00
|
|
|
if data.empty?
|
|
|
|
open_timeout = 6
|
|
|
|
read_timeout = 20
|
2016-01-21 01:07:50 +00:00
|
|
|
total_timeout = 120
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
|
|
|
response = UserAgent.post(
|
2013-09-19 14:17:25 +00:00
|
|
|
url,
|
2015-05-07 11:57:19 +00:00
|
|
|
data,
|
2013-09-19 14:17:25 +00:00
|
|
|
{
|
2015-05-07 11:57:19 +00:00
|
|
|
open_timeout: open_timeout,
|
|
|
|
read_timeout: read_timeout,
|
2016-01-21 01:07:50 +00:00
|
|
|
total_timeout: total_timeout,
|
2015-04-27 13:42:53 +00:00
|
|
|
user: Setting.get('import_otrs_user'),
|
|
|
|
password: Setting.get('import_otrs_password'),
|
2013-09-19 14:17:25 +00:00
|
|
|
},
|
|
|
|
)
|
|
|
|
if !response.success?
|
2015-05-07 11:57:19 +00:00
|
|
|
log "ERROR: #{response.error}"
|
2013-09-19 14:17:25 +00:00
|
|
|
return
|
2013-04-15 21:33:11 +00:00
|
|
|
end
|
2015-04-30 17:20:27 +00:00
|
|
|
response
|
2013-01-23 23:53:39 +00:00
|
|
|
end
|
2013-01-07 08:46:38 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
=begin
|
|
|
|
|
|
|
|
start post request to backend, add auth data automatically
|
|
|
|
|
|
|
|
result = json('some response string')
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
=end
|
|
|
|
|
2013-01-07 08:46:38 +00:00
|
|
|
def self.json(response)
|
2016-01-24 15:58:02 +00:00
|
|
|
data = Encode.conv('utf8', response.body.to_s)
|
|
|
|
JSON.parse(data)
|
2013-01-07 08:46:38 +00:00
|
|
|
end
|
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
=begin
|
|
|
|
|
|
|
|
start auth on OTRS - just for experimental reasons
|
|
|
|
|
|
|
|
result = auth(username, password)
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
{ ..user structure.. }
|
|
|
|
|
|
|
|
=end
|
|
|
|
|
2013-01-23 23:53:39 +00:00
|
|
|
def self.auth(username, password)
|
2015-05-07 11:57:19 +00:00
|
|
|
url = Setting.get('import_otrs_endpoint')
|
|
|
|
url.gsub!('ZammadMigrator', 'ZammadSSO')
|
|
|
|
response = post( { Action: 'ZammadSSO', Subaction: 'Auth', User: username, Pw: password }, url )
|
2013-01-25 22:17:50 +00:00
|
|
|
return if !response
|
2013-09-19 14:17:25 +00:00
|
|
|
return if !response.success?
|
2013-01-23 23:53:39 +00:00
|
|
|
|
|
|
|
result = json(response)
|
2015-04-30 17:20:27 +00:00
|
|
|
result
|
2013-01-23 23:53:39 +00:00
|
|
|
end
|
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
=begin
|
|
|
|
|
|
|
|
request session data - just for experimental reasons
|
|
|
|
|
|
|
|
result = session(session_id)
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
{ ..session structure.. }
|
|
|
|
|
|
|
|
=end
|
|
|
|
|
2013-02-17 18:28:32 +00:00
|
|
|
def self.session(session_id)
|
2015-05-07 11:57:19 +00:00
|
|
|
url = Setting.get('import_otrs_endpoint')
|
|
|
|
url.gsub!('ZammadMigrator', 'ZammadSSO')
|
|
|
|
response = post( { Action: 'ZammadSSO', Subaction: 'SessionCheck', SessionID: session_id }, url )
|
2013-02-17 18:28:32 +00:00
|
|
|
return if !response
|
2013-09-19 14:17:25 +00:00
|
|
|
return if !response.success?
|
2013-02-17 18:28:32 +00:00
|
|
|
result = json(response)
|
2015-04-30 17:20:27 +00:00
|
|
|
result
|
2013-02-17 18:28:32 +00:00
|
|
|
end
|
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
=begin
|
2014-03-11 09:23:56 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
load objects from otrs
|
|
|
|
|
|
|
|
result = load('SysConfig')
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
[
|
|
|
|
{ ..object1.. },
|
|
|
|
{ ..object2.. },
|
|
|
|
{ ..object3.. },
|
|
|
|
]
|
|
|
|
|
|
|
|
=end
|
|
|
|
|
|
|
|
def self.load( object, limit = '', offset = '', diff = 0 )
|
|
|
|
request_json( { Subaction: 'Export', Object: object, Limit: limit, Offset: offset, Diff: diff }, 1 )
|
|
|
|
end
|
|
|
|
|
|
|
|
=begin
|
|
|
|
|
|
|
|
start get request to backend to check connection
|
|
|
|
|
|
|
|
result = connection_test
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
true | false
|
|
|
|
|
|
|
|
=end
|
|
|
|
|
|
|
|
def self.connection_test
|
2015-05-07 12:10:38 +00:00
|
|
|
request_json({})
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
2014-03-11 09:23:56 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
=begin
|
|
|
|
|
2016-01-13 19:45:51 +00:00
|
|
|
get object statistic from remote server ans save it in cache
|
2015-05-07 11:57:19 +00:00
|
|
|
|
|
|
|
result = statistic('Subaction=List')
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
{
|
|
|
|
'Ticket' => 1234,
|
|
|
|
'User' => 123,
|
|
|
|
'SomeObject' => 999,
|
|
|
|
}
|
|
|
|
|
|
|
|
=end
|
|
|
|
|
|
|
|
def self.statistic
|
|
|
|
|
|
|
|
# check cache
|
|
|
|
cache = Cache.get('import_otrs_stats')
|
|
|
|
if cache
|
|
|
|
return cache
|
2014-03-11 09:23:56 +00:00
|
|
|
end
|
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
# retrive statistic
|
2015-05-07 12:10:38 +00:00
|
|
|
statistic = request_json( { Subaction: 'List' }, 1)
|
2015-05-07 11:57:19 +00:00
|
|
|
if statistic
|
|
|
|
Cache.write('import_otrs_stats', statistic)
|
2014-03-11 09:23:56 +00:00
|
|
|
end
|
2015-05-07 11:57:19 +00:00
|
|
|
statistic
|
|
|
|
end
|
2014-03-11 09:23:56 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
=begin
|
|
|
|
|
|
|
|
return current import state
|
|
|
|
|
|
|
|
result = current_state
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
{
|
2016-01-24 15:58:02 +00:00
|
|
|
Ticket: {
|
|
|
|
total: 1234,
|
|
|
|
done: 13,
|
2015-05-07 11:57:19 +00:00
|
|
|
},
|
2016-01-24 15:58:02 +00:00
|
|
|
Base: {
|
|
|
|
total: 1234,
|
|
|
|
done: 13,
|
2015-05-07 11:57:19 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
=end
|
|
|
|
|
|
|
|
def self.current_state
|
2015-05-07 12:10:38 +00:00
|
|
|
data = statistic
|
2015-05-07 11:57:19 +00:00
|
|
|
base = Group.count + Ticket::State.count + Ticket::Priority.count
|
|
|
|
base_total = data['Queue'] + data['State'] + data['Priority']
|
|
|
|
user = User.count
|
|
|
|
user_total = data['User'] + data['CustomerUser']
|
|
|
|
data = {
|
|
|
|
Base: {
|
|
|
|
done: base,
|
|
|
|
total: base_total || 0,
|
|
|
|
},
|
|
|
|
User: {
|
|
|
|
done: user,
|
|
|
|
total: user_total || 0,
|
|
|
|
},
|
|
|
|
Ticket: {
|
|
|
|
done: Ticket.count,
|
|
|
|
total: data['Ticket'] || 0,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
data
|
2014-03-11 09:23:56 +00:00
|
|
|
end
|
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
#
|
|
|
|
# start import
|
|
|
|
#
|
|
|
|
# Import::OTRS.start
|
|
|
|
#
|
2013-01-07 08:46:38 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
def self.start
|
|
|
|
log 'Start import...'
|
2013-01-07 08:46:38 +00:00
|
|
|
|
|
|
|
# check if system is in import mode
|
|
|
|
if !Setting.get('import_mode')
|
2016-03-01 14:26:46 +00:00
|
|
|
raise 'System is not in import mode!'
|
2013-01-07 08:46:38 +00:00
|
|
|
end
|
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
result = request_json({})
|
|
|
|
if !result['Success']
|
2016-03-01 14:26:46 +00:00
|
|
|
raise 'API key not valid!'
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# set settings
|
|
|
|
settings = load('SysConfig')
|
|
|
|
setting(settings)
|
|
|
|
|
|
|
|
# dynamic fields
|
|
|
|
dynamic_fields = load('DynamicField')
|
2016-09-13 08:53:16 +00:00
|
|
|
object_manager(dynamic_fields)
|
2015-05-07 11:57:19 +00:00
|
|
|
|
|
|
|
# email accounts
|
|
|
|
#accounts = load('PostMasterAccount')
|
|
|
|
#account(accounts)
|
|
|
|
|
|
|
|
# email filter
|
|
|
|
#filters = load('PostMasterFilter')
|
|
|
|
#filter(filters)
|
2013-01-07 08:46:38 +00:00
|
|
|
|
|
|
|
# create states
|
2015-05-07 11:57:19 +00:00
|
|
|
states = load('State')
|
|
|
|
ActiveRecord::Base.transaction do
|
|
|
|
state(states)
|
|
|
|
end
|
2013-01-07 08:46:38 +00:00
|
|
|
|
|
|
|
# create priorities
|
2015-05-07 11:57:19 +00:00
|
|
|
priorities = load('Priority')
|
|
|
|
ActiveRecord::Base.transaction do
|
|
|
|
priority(priorities)
|
|
|
|
end
|
2013-01-07 08:46:38 +00:00
|
|
|
|
|
|
|
# create groups
|
2015-05-07 11:57:19 +00:00
|
|
|
queues = load('Queue')
|
|
|
|
ActiveRecord::Base.transaction do
|
|
|
|
ticket_group(queues)
|
|
|
|
end
|
|
|
|
|
|
|
|
# get agents groups
|
|
|
|
groups = load('Group')
|
|
|
|
|
|
|
|
# get agents roles
|
|
|
|
roles = load('Role')
|
2013-01-07 08:46:38 +00:00
|
|
|
|
|
|
|
# create agents
|
2015-05-07 11:57:19 +00:00
|
|
|
users = load('User')
|
|
|
|
ActiveRecord::Base.transaction do
|
|
|
|
user(users, groups, roles, queues)
|
|
|
|
end
|
2013-01-07 08:46:38 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
# create organizations
|
|
|
|
organizations = load('Customer')
|
|
|
|
ActiveRecord::Base.transaction do
|
|
|
|
organization(organizations)
|
|
|
|
end
|
2013-01-07 08:46:38 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
# create customers
|
|
|
|
count = 0
|
|
|
|
steps = 50
|
|
|
|
run = true
|
|
|
|
while run
|
|
|
|
count += steps
|
|
|
|
records = load('CustomerUser', steps, count - steps)
|
|
|
|
if !records || !records[0]
|
|
|
|
log 'all customers imported.'
|
|
|
|
run = false
|
|
|
|
next
|
|
|
|
end
|
|
|
|
customer(records, organizations)
|
|
|
|
end
|
2013-01-25 23:06:21 +00:00
|
|
|
|
2013-02-01 19:58:53 +00:00
|
|
|
Thread.abort_on_exception = true
|
2015-05-07 11:57:19 +00:00
|
|
|
thread_count = 8
|
|
|
|
threads = {}
|
2015-07-24 09:57:45 +00:00
|
|
|
steps = 20
|
2015-07-24 10:01:12 +00:00
|
|
|
(1..thread_count).each { |thread|
|
2015-07-24 09:57:45 +00:00
|
|
|
|
2013-01-25 23:06:21 +00:00
|
|
|
threads[thread] = Thread.new {
|
2015-07-24 09:57:45 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
log "Started import thread# #{thread} ..."
|
2015-07-24 09:57:45 +00:00
|
|
|
Thread.current[:thread_no] = thread
|
|
|
|
Thread.current[:loop_count] = 0
|
|
|
|
|
2015-07-21 11:14:44 +00:00
|
|
|
loop do
|
2015-07-24 09:57:45 +00:00
|
|
|
# get the offset for the current thread and loop count
|
|
|
|
thread_offset_base = (Thread.current[:thread_no] - 1) * steps
|
|
|
|
thread_step = thread_count * steps
|
|
|
|
offset = Thread.current[:loop_count] * thread_step + thread_offset_base
|
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
log "loading... thread# #{thread} ..."
|
2015-07-24 09:57:45 +00:00
|
|
|
records = load( 'Ticket', steps, offset)
|
2015-05-07 11:57:19 +00:00
|
|
|
if !records || !records[0]
|
|
|
|
log "... thread# #{thread}, no more work."
|
2015-07-21 11:14:44 +00:00
|
|
|
break
|
2013-02-17 20:59:57 +00:00
|
|
|
end
|
2015-07-24 10:00:03 +00:00
|
|
|
_ticket_result(records, thread)
|
2015-07-24 09:57:45 +00:00
|
|
|
|
|
|
|
Thread.current[:loop_count] += 1
|
2013-01-25 23:06:21 +00:00
|
|
|
end
|
2015-05-07 11:57:19 +00:00
|
|
|
ActiveRecord::Base.connection.close
|
2013-01-25 23:06:21 +00:00
|
|
|
}
|
|
|
|
}
|
2016-06-30 20:04:48 +00:00
|
|
|
(1..thread_count).each { |thread|
|
2013-01-25 23:06:21 +00:00
|
|
|
threads[thread].join
|
|
|
|
}
|
|
|
|
|
2016-01-13 19:45:51 +00:00
|
|
|
true
|
|
|
|
end
|
|
|
|
|
|
|
|
=begin
|
|
|
|
start import in background
|
|
|
|
|
2016-01-13 21:21:34 +00:00
|
|
|
Import::OTRS.start_bg
|
2016-01-13 19:45:51 +00:00
|
|
|
=end
|
|
|
|
|
2016-01-13 21:21:34 +00:00
|
|
|
def self.start_bg
|
|
|
|
Setting.reload
|
2016-01-13 19:45:51 +00:00
|
|
|
|
2016-01-13 21:21:34 +00:00
|
|
|
Import::OTRS.connection_test
|
|
|
|
|
|
|
|
# start thread to observe current state
|
2016-01-13 19:45:51 +00:00
|
|
|
status_update_thread = Thread.new {
|
|
|
|
loop do
|
|
|
|
result = {
|
|
|
|
data: current_state,
|
|
|
|
result: 'in_progress',
|
|
|
|
}
|
|
|
|
Cache.write('import:state', result, expires_in: 10.minutes)
|
|
|
|
sleep 8
|
|
|
|
end
|
|
|
|
}
|
2016-01-13 21:21:34 +00:00
|
|
|
sleep 2
|
2016-01-13 19:45:51 +00:00
|
|
|
|
2016-02-09 00:32:55 +00:00
|
|
|
# start import data
|
2016-01-13 19:45:51 +00:00
|
|
|
begin
|
2016-02-09 00:32:55 +00:00
|
|
|
Import::OTRS.start
|
2016-01-13 19:45:51 +00:00
|
|
|
rescue => e
|
|
|
|
status_update_thread.exit
|
|
|
|
status_update_thread.join
|
|
|
|
Rails.logger.error e.message
|
|
|
|
Rails.logger.error e.backtrace.inspect
|
|
|
|
result = {
|
|
|
|
message: e.message,
|
|
|
|
result: 'error',
|
|
|
|
}
|
|
|
|
Cache.write('import:state', result, expires_in: 10.hours)
|
2016-01-13 21:21:34 +00:00
|
|
|
return false
|
2016-01-13 19:45:51 +00:00
|
|
|
end
|
2016-02-09 00:32:55 +00:00
|
|
|
sleep 16 # wait until new finished import state is on client
|
2016-01-13 19:45:51 +00:00
|
|
|
status_update_thread.exit
|
|
|
|
status_update_thread.join
|
|
|
|
|
2016-01-13 21:21:34 +00:00
|
|
|
result = {
|
|
|
|
result: 'import_done',
|
|
|
|
}
|
|
|
|
Cache.write('import:state', result, expires_in: 10.hours)
|
|
|
|
|
2016-01-13 13:12:05 +00:00
|
|
|
Setting.set('system_init_done', true)
|
|
|
|
Setting.set('import_mode', false)
|
2016-01-13 19:45:51 +00:00
|
|
|
end
|
2015-05-07 11:57:19 +00:00
|
|
|
|
2016-01-13 19:45:51 +00:00
|
|
|
=begin
|
2016-01-13 16:33:08 +00:00
|
|
|
|
2016-01-13 19:45:51 +00:00
|
|
|
get import state from background process
|
|
|
|
|
|
|
|
result = Import::OTRS.status_bg
|
|
|
|
|
|
|
|
=end
|
|
|
|
|
|
|
|
def self.status_bg
|
|
|
|
state = Cache.get('import:state')
|
|
|
|
return state if state
|
|
|
|
{
|
|
|
|
message: 'not running',
|
|
|
|
}
|
2015-05-04 14:21:13 +00:00
|
|
|
end
|
2013-01-07 08:46:38 +00:00
|
|
|
|
2013-05-07 20:45:00 +00:00
|
|
|
def self.diff_worker
|
2013-03-05 06:45:14 +00:00
|
|
|
return if !Setting.get('import_mode')
|
2013-03-10 16:45:48 +00:00
|
|
|
return if Setting.get('import_otrs_endpoint') == 'http://otrs_host/otrs'
|
2015-05-07 12:10:38 +00:00
|
|
|
diff
|
2013-02-19 19:04:35 +00:00
|
|
|
end
|
|
|
|
|
2013-02-17 20:59:57 +00:00
|
|
|
def self.diff
|
2015-05-07 11:57:19 +00:00
|
|
|
log 'Start diff...'
|
2013-02-17 20:59:57 +00:00
|
|
|
|
|
|
|
# check if system is in import mode
|
|
|
|
if !Setting.get('import_mode')
|
2016-03-01 14:26:46 +00:00
|
|
|
raise 'System is not in import mode!'
|
2013-02-17 20:59:57 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# create states
|
2015-05-07 11:57:19 +00:00
|
|
|
states = load('State')
|
|
|
|
state(states)
|
2013-02-17 20:59:57 +00:00
|
|
|
|
|
|
|
# create priorities
|
2015-05-07 11:57:19 +00:00
|
|
|
priorities = load('Priority')
|
|
|
|
priority(priorities)
|
2013-02-17 20:59:57 +00:00
|
|
|
|
|
|
|
# create groups
|
2015-05-07 11:57:19 +00:00
|
|
|
queues = load('Queue')
|
|
|
|
ticket_group(queues)
|
|
|
|
|
|
|
|
# get agents groups
|
|
|
|
groups = load('Group')
|
|
|
|
|
|
|
|
# get agents roles
|
|
|
|
roles = load('Role')
|
2013-02-17 20:59:57 +00:00
|
|
|
|
|
|
|
# create agents
|
2015-05-07 11:57:19 +00:00
|
|
|
users = load('User')
|
|
|
|
user(users, groups, roles, queues)
|
2013-02-17 20:59:57 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
# create organizations
|
|
|
|
organizations = load('Customer')
|
|
|
|
organization(organizations)
|
2013-02-17 20:59:57 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
# get changed tickets
|
2015-05-07 12:10:38 +00:00
|
|
|
ticket_diff
|
2013-02-17 20:59:57 +00:00
|
|
|
|
|
|
|
end
|
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
def self.ticket_diff
|
|
|
|
count = 0
|
|
|
|
run = true
|
|
|
|
steps = 20
|
|
|
|
while run
|
|
|
|
count += steps
|
|
|
|
log 'loading... diff ...'
|
|
|
|
records = load( 'Ticket', steps, count - steps, 1 )
|
|
|
|
if !records || !records[0]
|
|
|
|
log '... no more work.'
|
|
|
|
run = false
|
|
|
|
next
|
|
|
|
end
|
2015-07-24 10:00:03 +00:00
|
|
|
_ticket_result(records)
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
2013-01-07 08:46:38 +00:00
|
|
|
|
2013-02-17 20:59:57 +00:00
|
|
|
end
|
2013-06-04 12:52:56 +00:00
|
|
|
|
2015-07-24 10:00:03 +00:00
|
|
|
def self._ticket_result(result, _thread = '-')
|
2013-01-07 08:46:38 +00:00
|
|
|
map = {
|
2015-04-27 13:42:53 +00:00
|
|
|
Ticket: {
|
|
|
|
Changed: :updated_at,
|
|
|
|
Created: :created_at,
|
|
|
|
CreateBy: :created_by_id,
|
|
|
|
TicketNumber: :number,
|
|
|
|
QueueID: :group_id,
|
|
|
|
StateID: :state_id,
|
|
|
|
PriorityID: :priority_id,
|
|
|
|
Owner: :owner,
|
|
|
|
CustomerUserID: :customer,
|
|
|
|
Title: :title,
|
|
|
|
TicketID: :id,
|
2016-09-14 07:15:30 +00:00
|
|
|
FirstResponse: :first_response_at,
|
|
|
|
#FirstResponseTimeDestinationDate: :first_response_escalation_at,
|
2015-05-07 20:49:15 +00:00
|
|
|
#FirstResponseInMin: :first_response_in_min,
|
|
|
|
#FirstResponseDiffInMin: :first_response_diff_in_min,
|
2016-09-14 07:15:30 +00:00
|
|
|
Closed: :close_at,
|
|
|
|
#SoltutionTimeDestinationDate: :close_escalation_at,
|
|
|
|
#CloseTimeInMin: :close_in_min,
|
|
|
|
#CloseTimeDiffInMin: :close_diff_in_min,
|
2013-01-07 08:46:38 +00:00
|
|
|
},
|
2015-04-27 13:42:53 +00:00
|
|
|
Article: {
|
|
|
|
SenderType: :sender,
|
|
|
|
ArticleType: :type,
|
|
|
|
TicketID: :ticket_id,
|
|
|
|
ArticleID: :id,
|
|
|
|
Body: :body,
|
|
|
|
From: :from,
|
|
|
|
To: :to,
|
|
|
|
Cc: :cc,
|
|
|
|
Subject: :subject,
|
|
|
|
InReplyTo: :in_reply_to,
|
|
|
|
MessageID: :message_id,
|
2015-05-07 20:49:15 +00:00
|
|
|
#ReplyTo: :reply_to,
|
2015-04-27 13:42:53 +00:00
|
|
|
References: :references,
|
|
|
|
Changed: :updated_at,
|
|
|
|
Created: :created_at,
|
|
|
|
ChangedBy: :updated_by_id,
|
|
|
|
CreatedBy: :created_by_id,
|
2013-01-07 08:46:38 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2016-06-30 20:04:48 +00:00
|
|
|
result.each { |record|
|
2013-02-01 19:58:53 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
# cleanup values
|
|
|
|
_cleanup(record)
|
2013-02-01 19:58:53 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
_utf8_encode(record)
|
|
|
|
|
|
|
|
ticket_new = {
|
|
|
|
title: '',
|
|
|
|
created_by_id: 1,
|
|
|
|
updated_by_id: 1,
|
|
|
|
}
|
|
|
|
map[:Ticket].each { |key, value|
|
|
|
|
next if !record.key?(key.to_s)
|
|
|
|
ticket_new[value] = record[key.to_s]
|
|
|
|
}
|
|
|
|
|
2016-09-13 08:53:16 +00:00
|
|
|
record.keys.each { |key|
|
|
|
|
|
|
|
|
key_string = key.to_s
|
|
|
|
|
|
|
|
next if !key_string.start_with?('DynamicField_')
|
|
|
|
dynamic_field_name = key_string[13, key_string.length]
|
|
|
|
|
|
|
|
next if skip_fields.include?( dynamic_field_name )
|
|
|
|
dynamic_field_name = convert_df_name(dynamic_field_name)
|
|
|
|
|
|
|
|
ticket_new[dynamic_field_name.to_sym] = record[key_string]
|
|
|
|
}
|
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
# find owner
|
|
|
|
if ticket_new[:owner]
|
2016-01-24 15:58:02 +00:00
|
|
|
user = User.find_by(login: ticket_new[:owner].downcase)
|
2016-01-15 17:22:57 +00:00
|
|
|
ticket_new[:owner_id] = if user
|
|
|
|
user.id
|
|
|
|
else
|
|
|
|
1
|
|
|
|
end
|
2015-05-07 11:57:19 +00:00
|
|
|
ticket_new.delete(:owner)
|
|
|
|
end
|
|
|
|
|
|
|
|
# find customer
|
|
|
|
if ticket_new[:customer]
|
2016-01-24 15:58:02 +00:00
|
|
|
user = User.lookup(login: ticket_new[:customer].downcase)
|
2016-01-15 17:22:57 +00:00
|
|
|
ticket_new[:customer_id] = if user
|
|
|
|
user.id
|
|
|
|
else
|
|
|
|
1
|
|
|
|
end
|
2015-05-07 11:57:19 +00:00
|
|
|
ticket_new.delete(:customer)
|
|
|
|
else
|
|
|
|
ticket_new[:customer_id] = 1
|
|
|
|
end
|
2013-01-07 08:46:38 +00:00
|
|
|
|
2015-07-24 10:13:12 +00:00
|
|
|
# update or create ticket
|
2015-07-24 13:20:22 +00:00
|
|
|
ticket_old = Ticket.find_by(id: ticket_new[:id])
|
2015-05-07 11:57:19 +00:00
|
|
|
if ticket_old
|
|
|
|
log "update Ticket.find(#{ticket_new[:id]})"
|
|
|
|
ticket_old.update_attributes(ticket_new)
|
|
|
|
else
|
|
|
|
log "add Ticket.find(#{ticket_new[:id]})"
|
2015-07-24 10:13:12 +00:00
|
|
|
|
|
|
|
begin
|
|
|
|
ticket = Ticket.new(ticket_new)
|
|
|
|
ticket.id = ticket_new[:id]
|
|
|
|
ticket.save
|
2016-01-20 01:00:02 +00:00
|
|
|
_reset_pk('tickets')
|
2015-07-24 10:13:12 +00:00
|
|
|
rescue ActiveRecord::RecordNotUnique
|
|
|
|
log "Ticket #{ticket_new[:id]} is handled by another thead, skipping."
|
|
|
|
next
|
|
|
|
end
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# utf8 encode
|
|
|
|
record['Articles'].each { |article|
|
|
|
|
_utf8_encode(article)
|
|
|
|
}
|
|
|
|
|
|
|
|
# lookup customers to create first
|
|
|
|
record['Articles'].each { |article|
|
2015-07-24 10:00:03 +00:00
|
|
|
_article_based_customers(article)
|
2015-05-07 11:57:19 +00:00
|
|
|
}
|
|
|
|
|
2015-07-24 10:03:28 +00:00
|
|
|
record['Articles'].each do |article|
|
2013-06-04 12:52:56 +00:00
|
|
|
|
2015-07-27 15:46:43 +00:00
|
|
|
retries = 3
|
|
|
|
begin
|
|
|
|
|
|
|
|
ActiveRecord::Base.transaction do
|
|
|
|
|
|
|
|
# get article values
|
|
|
|
article_new = {
|
|
|
|
created_by_id: 1,
|
|
|
|
updated_by_id: 1,
|
|
|
|
}
|
|
|
|
|
|
|
|
map[:Article].each { |key, value|
|
|
|
|
next if !article.key?(key.to_s)
|
|
|
|
article_new[value] = article[key.to_s]
|
|
|
|
}
|
|
|
|
|
|
|
|
if article_new[:sender] == 'customer'
|
2016-01-24 15:58:02 +00:00
|
|
|
article_new[:sender_id] = Ticket::Article::Sender.lookup(name: 'Customer').id
|
|
|
|
article_new.delete(:sender)
|
2015-07-27 15:46:43 +00:00
|
|
|
end
|
|
|
|
if article_new[:sender] == 'agent'
|
2016-01-24 15:58:02 +00:00
|
|
|
article_new[:sender_id] = Ticket::Article::Sender.lookup(name: 'Agent').id
|
|
|
|
article_new.delete(:sender)
|
2015-07-27 15:46:43 +00:00
|
|
|
end
|
|
|
|
if article_new[:sender] == 'system'
|
2016-01-24 15:58:02 +00:00
|
|
|
article_new[:sender_id] = Ticket::Article::Sender.lookup(name: 'System').id
|
|
|
|
article_new.delete(:sender)
|
2015-07-27 15:46:43 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
if article_new[:type] == 'email-external'
|
2016-01-24 15:58:02 +00:00
|
|
|
article_new[:type_id] = Ticket::Article::Type.lookup(name: 'email').id
|
2015-07-27 15:46:43 +00:00
|
|
|
article_new[:internal] = false
|
|
|
|
elsif article_new[:type] == 'email-internal'
|
2016-01-24 15:58:02 +00:00
|
|
|
article_new[:type_id] = Ticket::Article::Type.lookup(name: 'email').id
|
2015-07-27 15:46:43 +00:00
|
|
|
article_new[:internal] = true
|
|
|
|
elsif article_new[:type] == 'note-external'
|
2016-01-24 15:58:02 +00:00
|
|
|
article_new[:type_id] = Ticket::Article::Type.lookup(name: 'note').id
|
2015-07-27 15:46:43 +00:00
|
|
|
article_new[:internal] = false
|
|
|
|
elsif article_new[:type] == 'note-internal'
|
2016-01-24 15:58:02 +00:00
|
|
|
article_new[:type_id] = Ticket::Article::Type.lookup(name: 'note').id
|
2015-07-27 15:46:43 +00:00
|
|
|
article_new[:internal] = true
|
|
|
|
elsif article_new[:type] == 'phone'
|
2016-01-24 15:58:02 +00:00
|
|
|
article_new[:type_id] = Ticket::Article::Type.lookup(name: 'phone').id
|
2015-07-27 15:46:43 +00:00
|
|
|
article_new[:internal] = false
|
|
|
|
elsif article_new[:type] == 'webrequest'
|
2016-01-24 15:58:02 +00:00
|
|
|
article_new[:type_id] = Ticket::Article::Type.lookup(name: 'web').id
|
2015-07-27 15:46:43 +00:00
|
|
|
article_new[:internal] = false
|
|
|
|
else
|
|
|
|
article_new[:type_id] = 9
|
|
|
|
end
|
2016-01-24 15:58:02 +00:00
|
|
|
article_new.delete(:type)
|
|
|
|
article_object = Ticket::Article.find_by(id: article_new[:id])
|
2015-07-27 15:46:43 +00:00
|
|
|
|
|
|
|
# set state types
|
|
|
|
if article_object
|
|
|
|
log "update Ticket::Article.find(#{article_new[:id]})"
|
|
|
|
article_object.update_attributes(article_new)
|
|
|
|
else
|
|
|
|
log "add Ticket::Article.find(#{article_new[:id]})"
|
|
|
|
begin
|
|
|
|
article_object = Ticket::Article.new(article_new)
|
|
|
|
article_object.id = article_new[:id]
|
|
|
|
article_object.save
|
2016-01-20 01:00:02 +00:00
|
|
|
_reset_pk('ticket_articles')
|
2015-07-27 15:46:43 +00:00
|
|
|
rescue ActiveRecord::RecordNotUnique
|
|
|
|
log "Ticket #{ticket_new[:id]} (article #{article_new[:id]}) is handled by another thead, skipping."
|
|
|
|
next
|
|
|
|
end
|
2015-07-24 10:17:42 +00:00
|
|
|
end
|
2015-07-21 13:46:01 +00:00
|
|
|
|
2015-07-27 15:46:43 +00:00
|
|
|
next if !article['Attachments']
|
|
|
|
next if article['Attachments'].empty?
|
2015-07-21 13:46:01 +00:00
|
|
|
|
2015-07-27 15:46:43 +00:00
|
|
|
# TODO: refactor
|
|
|
|
# check if there are attachments present
|
|
|
|
if !article_object.attachments.empty?
|
2015-07-21 13:46:01 +00:00
|
|
|
|
2015-07-27 15:46:43 +00:00
|
|
|
# skip attachments if count is equal
|
|
|
|
next if article_object.attachments.count == article['Attachments'].count
|
2015-07-21 13:46:01 +00:00
|
|
|
|
2015-07-27 15:46:43 +00:00
|
|
|
# if the count differs delete all so we
|
|
|
|
# can have a fresh start
|
|
|
|
article_object.attachments.each(&:delete)
|
|
|
|
end
|
2015-07-21 13:46:01 +00:00
|
|
|
|
2015-07-27 15:46:43 +00:00
|
|
|
# import article attachments
|
|
|
|
article['Attachments'].each { |attachment|
|
2015-07-24 13:21:49 +00:00
|
|
|
|
2015-07-27 15:46:43 +00:00
|
|
|
filename = Base64.decode64(attachment['Filename'])
|
2015-07-24 13:21:49 +00:00
|
|
|
|
2015-07-24 10:10:36 +00:00
|
|
|
Store.add(
|
|
|
|
object: 'Ticket::Article',
|
|
|
|
o_id: article_object.id,
|
2015-07-24 13:21:49 +00:00
|
|
|
filename: filename,
|
2015-07-24 10:10:36 +00:00
|
|
|
data: Base64.decode64(attachment['Content']),
|
|
|
|
preferences: {
|
|
|
|
'Mime-Type' => attachment['ContentType'],
|
|
|
|
'Content-ID' => attachment['ContentID'],
|
|
|
|
'content-alternative' => attachment['ContentAlternative'],
|
|
|
|
},
|
|
|
|
created_by_id: 1,
|
|
|
|
)
|
2015-07-27 15:46:43 +00:00
|
|
|
}
|
|
|
|
end
|
|
|
|
rescue ActiveRecord::RecordNotUnique => e
|
|
|
|
log "Ticket #{ticket_new[:id]} - RecordNotUnique: #{e}"
|
|
|
|
sleep rand 3
|
|
|
|
retry if !(retries -= 1).zero?
|
|
|
|
raise
|
2015-07-24 10:03:28 +00:00
|
|
|
end
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
2013-06-04 12:52:56 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
#puts "HS: #{record['History'].inspect}"
|
|
|
|
record['History'].each { |history|
|
2015-07-24 10:06:46 +00:00
|
|
|
|
|
|
|
begin
|
|
|
|
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']
|
|
|
|
)
|
|
|
|
elsif history['HistoryType'] == 'StateUpdate'
|
|
|
|
data = history['Name']
|
|
|
|
# "%%new%%open%%"
|
|
|
|
from = nil
|
|
|
|
to = nil
|
|
|
|
if data =~ /%%(.+?)%%(.+?)%%/
|
|
|
|
from = $1
|
|
|
|
to = $2
|
2016-01-24 15:58:02 +00:00
|
|
|
state_from = Ticket::State.lookup(name: from)
|
|
|
|
state_to = Ticket::State.lookup(name: to)
|
2015-07-24 10:06:46 +00:00
|
|
|
if state_from
|
|
|
|
from_id = state_from.id
|
|
|
|
end
|
|
|
|
if state_to
|
|
|
|
to_id = state_to.id
|
|
|
|
end
|
2013-02-01 19:58:53 +00:00
|
|
|
end
|
2015-07-24 10:06:46 +00:00
|
|
|
History.add(
|
|
|
|
id: history['HistoryID'],
|
|
|
|
o_id: history['TicketID'],
|
|
|
|
history_type: 'updated',
|
|
|
|
history_object: 'Ticket',
|
|
|
|
history_attribute: 'state',
|
|
|
|
value_from: from,
|
|
|
|
id_from: from_id,
|
|
|
|
value_to: to,
|
|
|
|
id_to: to_id,
|
|
|
|
created_at: history['CreateTime'],
|
|
|
|
created_by_id: history['CreateBy']
|
|
|
|
)
|
|
|
|
elsif 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
|
2015-07-23 15:42:51 +00:00
|
|
|
end
|
2015-07-24 10:06:46 +00:00
|
|
|
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']
|
|
|
|
)
|
|
|
|
elsif 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: 'priority',
|
|
|
|
value_from: from,
|
|
|
|
value_to: to,
|
|
|
|
id_from: from_id,
|
|
|
|
id_to: to_id,
|
|
|
|
created_at: history['CreateTime'],
|
|
|
|
created_by_id: history['CreateBy']
|
|
|
|
)
|
2015-07-24 13:20:22 +00:00
|
|
|
elsif history['ArticleID'] && !history['ArticleID'].to_i.zero?
|
2015-07-24 10:06:46 +00:00
|
|
|
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']
|
|
|
|
)
|
2013-02-01 19:58:53 +00:00
|
|
|
end
|
2015-07-24 07:04:09 +00:00
|
|
|
|
2015-07-24 10:06:46 +00:00
|
|
|
rescue ActiveRecord::RecordNotUnique
|
|
|
|
log "Ticket #{ticket_new[:id]} (history #{history['HistoryID']}) is handled by another thead, skipping."
|
|
|
|
next
|
|
|
|
end
|
2015-05-07 11:57:19 +00:00
|
|
|
}
|
2013-01-07 08:46:38 +00:00
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
# sync ticket states
|
|
|
|
def self.state(records)
|
2013-01-07 08:46:38 +00:00
|
|
|
map = {
|
2015-04-27 13:42:53 +00:00
|
|
|
ChangeTime: :updated_at,
|
|
|
|
CreateTime: :created_at,
|
|
|
|
CreateBy: :created_by_id,
|
|
|
|
ChangeBy: :updated_by_id,
|
|
|
|
Name: :name,
|
|
|
|
ID: :id,
|
|
|
|
ValidID: :active,
|
|
|
|
Comment: :note,
|
2015-04-30 17:54:08 +00:00
|
|
|
}
|
2013-01-07 08:46:38 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
# rename states to handle not uniq issues
|
2016-06-30 20:04:48 +00:00
|
|
|
Ticket::State.all.each { |state|
|
2013-01-07 08:46:38 +00:00
|
|
|
state.name = state.name + '_tmp'
|
|
|
|
state.save
|
|
|
|
}
|
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
records.each { |state|
|
2013-01-07 08:46:38 +00:00
|
|
|
_set_valid(state)
|
|
|
|
|
|
|
|
# get new attributes
|
|
|
|
state_new = {
|
2015-04-27 13:42:53 +00:00
|
|
|
created_by_id: 1,
|
|
|
|
updated_by_id: 1,
|
2013-01-07 08:46:38 +00:00
|
|
|
}
|
2015-04-27 14:53:29 +00:00
|
|
|
map.each { |key, value|
|
2015-05-07 11:57:19 +00:00
|
|
|
next if !state.key?(key.to_s)
|
|
|
|
state_new[value] = state[key.to_s]
|
2013-01-07 08:46:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
# check if state already exists
|
2016-01-24 15:58:02 +00:00
|
|
|
state_old = Ticket::State.lookup(id: state_new[:id])
|
2013-01-07 08:46:38 +00:00
|
|
|
|
|
|
|
# set state types
|
|
|
|
if state['TypeName'] == 'pending auto'
|
|
|
|
state['TypeName'] = 'pending action'
|
|
|
|
end
|
2016-01-24 15:58:02 +00:00
|
|
|
state_type = Ticket::StateType.lookup(name: state['TypeName'])
|
2014-06-08 22:01:20 +00:00
|
|
|
state_new[:state_type_id] = state_type.id
|
2013-01-07 08:46:38 +00:00
|
|
|
if state_old
|
|
|
|
state_old.update_attributes(state_new)
|
|
|
|
else
|
|
|
|
state = Ticket::State.new(state_new)
|
|
|
|
state.id = state_new[:id]
|
|
|
|
state.save
|
2016-01-20 01:00:02 +00:00
|
|
|
_reset_pk('ticket_states')
|
2013-01-07 08:46:38 +00:00
|
|
|
end
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
# sync ticket priorities
|
|
|
|
def self.priority(records)
|
|
|
|
|
2013-01-07 08:46:38 +00:00
|
|
|
map = {
|
2015-04-27 13:42:53 +00:00
|
|
|
ChangeTime: :updated_at,
|
|
|
|
CreateTime: :created_at,
|
|
|
|
CreateBy: :created_by_id,
|
|
|
|
ChangeBy: :updated_by_id,
|
|
|
|
Name: :name,
|
|
|
|
ID: :id,
|
|
|
|
ValidID: :active,
|
|
|
|
Comment: :note,
|
2015-04-30 17:54:08 +00:00
|
|
|
}
|
2013-01-07 08:46:38 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
records.each { |priority|
|
2013-01-07 08:46:38 +00:00
|
|
|
_set_valid(priority)
|
|
|
|
|
|
|
|
# get new attributes
|
|
|
|
priority_new = {
|
2015-04-27 13:42:53 +00:00
|
|
|
created_by_id: 1,
|
|
|
|
updated_by_id: 1,
|
2013-01-07 08:46:38 +00:00
|
|
|
}
|
2015-04-27 14:53:29 +00:00
|
|
|
map.each { |key, value|
|
2015-05-07 11:57:19 +00:00
|
|
|
next if !priority.key?(key.to_s)
|
|
|
|
priority_new[value] = priority[key.to_s]
|
2013-01-07 08:46:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
# check if state already exists
|
2016-01-24 15:58:02 +00:00
|
|
|
priority_old = Ticket::Priority.lookup(id: priority_new[:id])
|
2013-01-07 08:46:38 +00:00
|
|
|
|
|
|
|
# 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
|
2016-01-20 01:00:02 +00:00
|
|
|
_reset_pk('ticket_priorities')
|
2013-01-07 08:46:38 +00:00
|
|
|
end
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
# sync ticket groups / queues
|
|
|
|
def self.ticket_group(records)
|
2013-01-07 08:46:38 +00:00
|
|
|
map = {
|
2015-04-27 13:42:53 +00:00
|
|
|
ChangeTime: :updated_at,
|
|
|
|
CreateTime: :created_at,
|
|
|
|
CreateBy: :created_by_id,
|
|
|
|
ChangeBy: :updated_by_id,
|
|
|
|
Name: :name,
|
|
|
|
QueueID: :id,
|
|
|
|
ValidID: :active,
|
|
|
|
Comment: :note,
|
2015-04-30 17:54:08 +00:00
|
|
|
}
|
2013-01-07 08:46:38 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
records.each { |group|
|
2013-01-07 08:46:38 +00:00
|
|
|
_set_valid(group)
|
|
|
|
|
|
|
|
# get new attributes
|
|
|
|
group_new = {
|
2015-04-27 13:42:53 +00:00
|
|
|
created_by_id: 1,
|
|
|
|
updated_by_id: 1,
|
2013-01-07 08:46:38 +00:00
|
|
|
}
|
2015-04-27 14:53:29 +00:00
|
|
|
map.each { |key, value|
|
2015-05-07 11:57:19 +00:00
|
|
|
next if !group.key?(key.to_s)
|
|
|
|
group_new[value] = group[key.to_s]
|
2013-01-07 08:46:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
# check if state already exists
|
2016-01-24 15:58:02 +00:00
|
|
|
group_old = Group.lookup(id: group_new[:id])
|
2013-01-07 08:46:38 +00:00
|
|
|
|
|
|
|
# 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
|
2016-01-20 01:00:02 +00:00
|
|
|
_reset_pk('groups')
|
2013-01-07 08:46:38 +00:00
|
|
|
end
|
|
|
|
}
|
|
|
|
end
|
2015-05-07 11:57:19 +00:00
|
|
|
|
|
|
|
# sync agents
|
|
|
|
def self.user(records, groups, roles, queues)
|
|
|
|
|
2013-01-07 08:46:38 +00:00
|
|
|
map = {
|
2015-04-27 13:42:53 +00:00
|
|
|
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,
|
|
|
|
UserLogin: :login,
|
|
|
|
UserPw: :password,
|
2015-04-30 17:54:08 +00:00
|
|
|
}
|
2013-01-07 08:46:38 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
records.each { |user|
|
2015-04-30 17:14:51 +00:00
|
|
|
_set_valid(user)
|
2013-01-07 08:46:38 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
# get roles
|
|
|
|
role_ids = get_roles_ids(user, groups, roles, queues)
|
|
|
|
|
|
|
|
# get groups
|
|
|
|
group_ids = get_queue_ids(user, groups, roles, queues)
|
|
|
|
|
2015-04-30 17:14:51 +00:00
|
|
|
# get new attributes
|
|
|
|
user_new = {
|
|
|
|
created_by_id: 1,
|
|
|
|
updated_by_id: 1,
|
|
|
|
source: 'OTRS Import',
|
2015-05-07 11:57:19 +00:00
|
|
|
role_ids: role_ids,
|
|
|
|
group_ids: group_ids,
|
2015-04-30 17:14:51 +00:00
|
|
|
}
|
|
|
|
map.each { |key, value|
|
2015-05-07 11:57:19 +00:00
|
|
|
next if !user.key?(key.to_s)
|
|
|
|
user_new[value] = user[key.to_s]
|
2015-04-30 17:14:51 +00:00
|
|
|
}
|
2013-01-07 08:46:38 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
# set pw
|
|
|
|
if user_new[:password]
|
|
|
|
user_new[:password] = "{sha2}#{user_new[:password]}"
|
|
|
|
end
|
|
|
|
|
|
|
|
# check if agent already exists
|
2016-01-24 15:58:02 +00:00
|
|
|
user_old = User.lookup(id: user_new[:id])
|
2013-01-07 08:46:38 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
# check if login is already used
|
|
|
|
login_in_use = User.where( "login = ? AND id != #{user_new[:id]}", user_new[:login].downcase ).count
|
|
|
|
if login_in_use > 0
|
|
|
|
user_new[:login] = "#{user_new[:login]}_#{user_new[:id]}"
|
|
|
|
end
|
|
|
|
|
|
|
|
# create / update agent
|
2015-04-30 17:14:51 +00:00
|
|
|
if user_old
|
2015-05-07 11:57:19 +00:00
|
|
|
log "update User.find(#{user_old[:id]})"
|
|
|
|
|
|
|
|
# only update roles if different (reduce sql statements)
|
|
|
|
if user_old.role_ids == user_new[:role_ids]
|
2016-01-24 15:58:02 +00:00
|
|
|
user_new.delete(:role_ids)
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
|
|
|
|
2015-04-30 17:14:51 +00:00
|
|
|
user_old.update_attributes(user_new)
|
|
|
|
else
|
2015-05-07 11:57:19 +00:00
|
|
|
log "add User.find(#{user_new[:id]})"
|
2015-04-30 17:14:51 +00:00
|
|
|
user = User.new(user_new)
|
|
|
|
user.id = user_new[:id]
|
|
|
|
user.save
|
2016-01-20 01:00:02 +00:00
|
|
|
_reset_pk('users')
|
2015-04-30 17:14:51 +00:00
|
|
|
end
|
2013-01-07 08:46:38 +00:00
|
|
|
}
|
|
|
|
end
|
2015-05-07 11:57:19 +00:00
|
|
|
|
|
|
|
def self.get_queue_ids(user, _groups, _roles, queues)
|
|
|
|
queue_ids = []
|
|
|
|
|
|
|
|
# lookup by groups
|
2016-06-30 20:04:48 +00:00
|
|
|
user['GroupIDs'].each { |group_id, permissions|
|
|
|
|
queues.each { |queue_lookup|
|
2015-05-07 11:57:19 +00:00
|
|
|
|
|
|
|
next if queue_lookup['GroupID'] != group_id
|
|
|
|
next if !permissions
|
|
|
|
next if !permissions.include?('rw')
|
|
|
|
|
|
|
|
queue_ids.push queue_lookup['QueueID']
|
2015-04-30 17:54:08 +00:00
|
|
|
}
|
2015-05-07 11:57:19 +00:00
|
|
|
}
|
2013-01-07 08:46:38 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
# lookup by roles
|
2013-01-07 08:46:38 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
# roles of user
|
2015-05-07 20:49:15 +00:00
|
|
|
# groups of roles
|
|
|
|
# queues of group
|
2013-01-25 23:06:21 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
queue_ids
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.get_roles_ids(user, groups, roles, _queues)
|
2015-10-29 12:08:06 +00:00
|
|
|
local_roles = ['Agent']
|
|
|
|
local_role_ids = []
|
|
|
|
|
|
|
|
# apply group permissions
|
2016-06-30 20:04:48 +00:00
|
|
|
user['GroupIDs'].each { |group_id, permissions|
|
|
|
|
groups.each { |group_lookup|
|
2015-05-07 11:57:19 +00:00
|
|
|
|
|
|
|
next if group_id != group_lookup['ID']
|
|
|
|
next if !permissions
|
|
|
|
|
|
|
|
if group_lookup['Name'] == 'admin' && permissions.include?('rw')
|
2015-10-29 12:08:06 +00:00
|
|
|
local_roles.push 'Admin'
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
next if group_lookup['Name'] !~ /^(stats|report)/
|
|
|
|
next if !( permissions.include?('ro') || permissions.include?('rw') )
|
|
|
|
|
2015-10-29 12:08:06 +00:00
|
|
|
local_roles.push 'Report'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# apply role permissions
|
2016-06-30 20:04:48 +00:00
|
|
|
user['RoleIDs'].each { |role_id|
|
2015-10-29 12:08:06 +00:00
|
|
|
|
|
|
|
# get groups of role
|
2016-06-30 20:04:48 +00:00
|
|
|
roles.each { |role|
|
2015-10-29 12:08:06 +00:00
|
|
|
next if role['ID'] != role_id
|
|
|
|
|
|
|
|
# verify group names
|
2016-06-30 20:04:48 +00:00
|
|
|
role['GroupIDs'].each { |group_id, permissions|
|
|
|
|
groups.each { |group_lookup|
|
2015-10-29 12:08:06 +00:00
|
|
|
|
|
|
|
next if group_id != group_lookup['ID']
|
|
|
|
next if !permissions
|
|
|
|
|
|
|
|
if group_lookup['Name'] == 'admin' && permissions.include?('rw')
|
|
|
|
local_roles.push 'Admin'
|
|
|
|
end
|
|
|
|
|
|
|
|
next if group_lookup['Name'] !~ /^(stats|report)/
|
|
|
|
next if !( permissions.include?('ro') || permissions.include?('rw') )
|
|
|
|
|
|
|
|
local_roles.push 'Report'
|
|
|
|
}
|
|
|
|
}
|
2015-05-07 11:57:19 +00:00
|
|
|
}
|
|
|
|
}
|
2015-10-29 12:08:06 +00:00
|
|
|
|
2016-06-30 20:04:48 +00:00
|
|
|
local_roles.each { |role|
|
2016-01-24 15:58:02 +00:00
|
|
|
role_lookup = Role.lookup(name: role)
|
2015-05-07 11:57:19 +00:00
|
|
|
next if !role_lookup
|
2015-10-29 17:55:59 +00:00
|
|
|
local_role_ids.push role_lookup.id
|
2015-05-07 11:57:19 +00:00
|
|
|
}
|
2015-10-29 12:08:06 +00:00
|
|
|
local_role_ids
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# sync customers
|
|
|
|
|
|
|
|
def self.customer(records, organizations)
|
|
|
|
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,
|
|
|
|
UserLogin: :login,
|
|
|
|
UserPassword: :password,
|
|
|
|
UserPhone: :phone,
|
|
|
|
UserFax: :fax,
|
|
|
|
UserMobile: :mobile,
|
|
|
|
UserStreet: :street,
|
|
|
|
UserZip: :zip,
|
|
|
|
UserCity: :city,
|
|
|
|
UserCountry: :country,
|
|
|
|
}
|
|
|
|
|
2016-01-24 15:58:02 +00:00
|
|
|
role_agent = Role.lookup(name: 'Agent')
|
|
|
|
role_customer = Role.lookup(name: 'Customer')
|
2015-05-07 11:57:19 +00:00
|
|
|
|
|
|
|
records.each { |user|
|
|
|
|
_set_valid(user)
|
|
|
|
|
|
|
|
# get new attributes
|
|
|
|
user_new = {
|
|
|
|
created_by_id: 1,
|
|
|
|
updated_by_id: 1,
|
|
|
|
source: 'OTRS Import',
|
|
|
|
organization_id: get_organization_id(user, organizations),
|
|
|
|
role_ids: [ role_customer.id ],
|
|
|
|
}
|
|
|
|
map.each { |key, value|
|
|
|
|
next if !user.key?(key.to_s)
|
|
|
|
user_new[value] = user[key.to_s]
|
|
|
|
}
|
|
|
|
|
|
|
|
# check if customer already exists
|
2016-01-24 15:58:02 +00:00
|
|
|
user_old = User.lookup(login: user_new[:login])
|
2013-01-07 08:46:38 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
# create / update agent
|
|
|
|
if user_old
|
|
|
|
|
|
|
|
# do not update user if it is already agent
|
2016-01-24 15:58:02 +00:00
|
|
|
if !user_old.role_ids.include?(role_agent.id)
|
2013-01-07 08:46:38 +00:00
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
# only update roles if different (reduce sql statements)
|
|
|
|
if user_old.role_ids == user_new[:role_ids]
|
2016-01-24 15:58:02 +00:00
|
|
|
user_new.delete(:role_ids)
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
|
|
|
log "update User.find(#{user_old[:id]})"
|
2013-01-07 08:46:38 +00:00
|
|
|
user_old.update_attributes(user_new)
|
|
|
|
end
|
2015-05-07 11:57:19 +00:00
|
|
|
else
|
|
|
|
log "add User.find(#{user_new[:id]})"
|
|
|
|
user = User.new(user_new)
|
|
|
|
user.save
|
2016-01-20 01:00:02 +00:00
|
|
|
_reset_pk('users')
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.get_organization_id(user, organizations)
|
|
|
|
organization_id = nil
|
|
|
|
if user['UserCustomerID']
|
2016-06-30 20:04:48 +00:00
|
|
|
organizations.each { |organization|
|
2015-05-07 11:57:19 +00:00
|
|
|
next if user['UserCustomerID'] != organization['CustomerID']
|
2016-01-24 15:58:02 +00:00
|
|
|
organization = Organization.lookup(name: organization['CustomerCompanyName'])
|
2015-05-07 11:57:19 +00:00
|
|
|
organization_id = organization.id
|
2013-01-07 08:46:38 +00:00
|
|
|
}
|
|
|
|
end
|
2015-05-07 11:57:19 +00:00
|
|
|
organization_id
|
|
|
|
end
|
|
|
|
|
|
|
|
# sync organizations
|
|
|
|
def self.organization(records)
|
|
|
|
map = {
|
|
|
|
ChangeTime: :updated_at,
|
|
|
|
CreateTime: :created_at,
|
|
|
|
CreateBy: :created_by_id,
|
|
|
|
ChangeBy: :updated_by_id,
|
|
|
|
CustomerCompanyName: :name,
|
|
|
|
ValidID: :active,
|
|
|
|
CustomerCompanyComment: :note,
|
|
|
|
}
|
|
|
|
|
|
|
|
records.each { |organization|
|
|
|
|
_set_valid(organization)
|
|
|
|
|
|
|
|
# get new attributes
|
|
|
|
organization_new = {
|
|
|
|
created_by_id: 1,
|
|
|
|
updated_by_id: 1,
|
|
|
|
}
|
|
|
|
map.each { |key, value|
|
|
|
|
next if !organization.key?(key.to_s)
|
|
|
|
organization_new[value] = organization[key.to_s]
|
|
|
|
}
|
|
|
|
|
|
|
|
# check if state already exists
|
2016-01-24 15:58:02 +00:00
|
|
|
organization_old = Organization.lookup(name: organization_new[:name])
|
2015-05-07 11:57:19 +00:00
|
|
|
|
|
|
|
# set state types
|
|
|
|
if organization_old
|
|
|
|
organization_old.update_attributes(organization_new)
|
|
|
|
else
|
|
|
|
organization = Organization.new(organization_new)
|
|
|
|
organization.id = organization_new[:id]
|
|
|
|
organization.save
|
2016-01-20 01:00:02 +00:00
|
|
|
_reset_pk('organizations')
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
# sync settings
|
|
|
|
def self.setting(records)
|
|
|
|
|
|
|
|
records.each { |setting|
|
|
|
|
|
|
|
|
# fqdn
|
|
|
|
if setting['Key'] == 'FQDN'
|
2016-01-24 15:58:02 +00:00
|
|
|
Setting.set('fqdn', setting['Value'])
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# http type
|
|
|
|
if setting['Key'] == 'HttpType'
|
2016-01-24 15:58:02 +00:00
|
|
|
Setting.set('http_type', setting['Value'])
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# system id
|
|
|
|
if setting['Key'] == 'SystemID'
|
2016-01-24 15:58:02 +00:00
|
|
|
Setting.set('system_id', setting['Value'])
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# organization
|
|
|
|
if setting['Key'] == 'Organization'
|
2016-01-24 15:58:02 +00:00
|
|
|
Setting.set('organization', setting['Value'])
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# sending emails
|
|
|
|
if setting['Key'] == 'SendmailModule'
|
|
|
|
# TODO
|
|
|
|
end
|
|
|
|
|
|
|
|
# number generater
|
|
|
|
if setting['Key'] == 'Ticket::NumberGenerator'
|
|
|
|
if setting['Value'] == 'Kernel::System::Ticket::Number::DateChecksum'
|
2016-01-24 15:58:02 +00:00
|
|
|
Setting.set('ticket_number', 'Ticket::Number::Date')
|
|
|
|
Setting.set('ticket_number_date', { checksum: true })
|
2015-05-07 11:57:19 +00:00
|
|
|
elsif setting['Value'] == 'Kernel::System::Ticket::Number::Date'
|
2016-01-24 15:58:02 +00:00
|
|
|
Setting.set('ticket_number', 'Ticket::Number::Date')
|
|
|
|
Setting.set('ticket_number_date', { checksum: false })
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# ticket hook
|
|
|
|
if setting['Key'] == 'Ticket::Hook'
|
2016-01-24 15:58:02 +00:00
|
|
|
Setting.set('ticket_hook', setting['Value'])
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
|
|
|
}
|
2013-01-07 08:46:38 +00:00
|
|
|
end
|
2015-05-07 11:57:19 +00:00
|
|
|
|
2016-09-13 08:53:16 +00:00
|
|
|
# dynamic fields
|
|
|
|
def self.object_manager(dynamic_fields)
|
|
|
|
|
|
|
|
dynamic_fields.each { |dynamic_field|
|
|
|
|
|
|
|
|
if dynamic_field['ObjectType'] != 'Ticket'
|
|
|
|
log "ERROR: Unsupported dynamic field object type '#{dynamic_field['ObjectType']}' for dynamic field '#{dynamic_field['Name']}'"
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
|
|
|
next if skip_fields.include?( dynamic_field['Name'] )
|
|
|
|
|
|
|
|
internal_name = convert_df_name(dynamic_field['Name'])
|
|
|
|
|
|
|
|
attribute = ObjectManager::Attribute.get(
|
|
|
|
object: dynamic_field['ObjectType'],
|
|
|
|
name: internal_name,
|
|
|
|
)
|
|
|
|
next if !attribute.nil?
|
|
|
|
|
|
|
|
object_manager_config = {
|
|
|
|
object: dynamic_field['ObjectType'],
|
|
|
|
name: internal_name,
|
|
|
|
display: dynamic_field['Label'],
|
|
|
|
screens: {
|
|
|
|
view: {
|
|
|
|
'-all-' => {
|
|
|
|
shown: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
active: true,
|
|
|
|
editable: dynamic_field['InternalField'] == '0',
|
|
|
|
position: dynamic_field['FieldOrder'],
|
|
|
|
created_by_id: 1,
|
|
|
|
updated_by_id: 1,
|
|
|
|
}
|
|
|
|
|
|
|
|
if dynamic_field['FieldType'] == 'Text'
|
|
|
|
|
|
|
|
object_manager_config[:data_type] = 'input'
|
|
|
|
object_manager_config[:data_option] = {
|
|
|
|
default: dynamic_field['Config']['DefaultValue'],
|
|
|
|
type: 'text',
|
|
|
|
maxlength: 255,
|
|
|
|
null: false,
|
|
|
|
}
|
|
|
|
elsif dynamic_field['FieldType'] == 'TextArea'
|
|
|
|
|
|
|
|
object_manager_config[:data_type] = 'textarea'
|
|
|
|
object_manager_config[:data_option] = {
|
|
|
|
default: dynamic_field['Config']['DefaultValue'],
|
|
|
|
rows: dynamic_field['Config']['Rows'],
|
|
|
|
null: false,
|
|
|
|
}
|
|
|
|
elsif dynamic_field['FieldType'] == 'Checkbox'
|
|
|
|
|
|
|
|
object_manager_config[:data_type] = 'boolean'
|
|
|
|
object_manager_config[:data_option] = {
|
|
|
|
default: dynamic_field['Config']['DefaultValue'] == '1',
|
|
|
|
options: {
|
|
|
|
true => 'Yes',
|
|
|
|
false => 'No',
|
|
|
|
},
|
|
|
|
null: false,
|
|
|
|
translate: true,
|
|
|
|
}
|
|
|
|
elsif dynamic_field['FieldType'] == 'DateTime'
|
|
|
|
|
|
|
|
object_manager_config[:data_type] = 'datetime'
|
|
|
|
object_manager_config[:data_option] = {
|
|
|
|
future: dynamic_field['Config']['YearsInFuture'] != '0',
|
|
|
|
past: dynamic_field['Config']['YearsInPast'] != '0',
|
|
|
|
diff: dynamic_field['Config']['DefaultValue'].to_i / 60 / 60,
|
|
|
|
null: false,
|
|
|
|
}
|
|
|
|
elsif dynamic_field['FieldType'] == 'Date'
|
|
|
|
|
|
|
|
object_manager_config[:data_type] = 'date'
|
|
|
|
object_manager_config[:data_option] = {
|
|
|
|
future: dynamic_field['Config']['YearsInFuture'] != '0',
|
|
|
|
past: dynamic_field['Config']['YearsInPast'] != '0',
|
|
|
|
diff: dynamic_field['Config']['DefaultValue'].to_i / 60 / 60 / 24,
|
|
|
|
null: false,
|
|
|
|
}
|
|
|
|
elsif dynamic_field['FieldType'] == 'Dropdown'
|
|
|
|
|
|
|
|
object_manager_config[:data_type] = 'select'
|
|
|
|
object_manager_config[:data_option] = {
|
|
|
|
default: '',
|
|
|
|
multiple: false,
|
|
|
|
options: dynamic_field['Config']['PossibleValues'],
|
|
|
|
null: dynamic_field['Config']['PossibleNone'] == '1',
|
|
|
|
translate: dynamic_field['Config']['TranslatableValues'] == '1',
|
|
|
|
}
|
|
|
|
elsif dynamic_field['FieldType'] == 'Multiselect'
|
|
|
|
|
|
|
|
object_manager_config[:data_type] = 'select'
|
|
|
|
object_manager_config[:data_option] = {
|
|
|
|
default: '',
|
|
|
|
multiple: true,
|
|
|
|
options: dynamic_field['Config']['PossibleValues'],
|
|
|
|
null: dynamic_field['Config']['PossibleNone'] == '1',
|
|
|
|
translate: dynamic_field['Config']['TranslatableValues'] == '1',
|
|
|
|
}
|
|
|
|
else
|
|
|
|
log "ERROR: Unsupported dynamic field field type '#{dynamic_field['FieldType']}' for dynamic field '#{dynamic_field['Name']}'"
|
|
|
|
next
|
|
|
|
end
|
|
|
|
|
|
|
|
ObjectManager::Attribute.add( object_manager_config )
|
|
|
|
ObjectManager::Attribute.migration_execute(false)
|
|
|
|
}
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.convert_df_name(dynamic_field_name)
|
|
|
|
new_name = dynamic_field_name.underscore
|
|
|
|
new_name.sub(/\_id(s)?\z/, "_no#{$1}")
|
|
|
|
end
|
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
# log
|
|
|
|
def self.log(message)
|
|
|
|
thread_no = Thread.current[:thread_no] || '-'
|
2015-07-24 07:04:09 +00:00
|
|
|
Rails.logger.info "thread##{thread_no}: #{message}"
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# set translate valid ids to active = true|false
|
2013-01-07 08:46:38 +00:00
|
|
|
def self._set_valid(record)
|
2015-05-07 11:57:19 +00:00
|
|
|
|
|
|
|
# map
|
2016-01-15 17:22:57 +00:00
|
|
|
record['ValidID'] = if record['ValidID'].to_s == '3'
|
|
|
|
false
|
|
|
|
elsif record['ValidID'].to_s == '2'
|
|
|
|
false
|
|
|
|
elsif record['ValidID'].to_s == '1'
|
|
|
|
true
|
|
|
|
elsif record['ValidID'].to_s == '0'
|
|
|
|
false
|
|
|
|
|
|
|
|
# fallback
|
|
|
|
else
|
|
|
|
true
|
|
|
|
end
|
2013-01-07 08:46:38 +00:00
|
|
|
end
|
2015-05-07 11:57:19 +00:00
|
|
|
|
|
|
|
# cleanup invalid values
|
|
|
|
def self._cleanup(record)
|
2016-06-30 20:04:48 +00:00
|
|
|
record.each { |key, value|
|
2015-05-07 11:57:19 +00:00
|
|
|
if value == '0000-00-00 00:00:00'
|
|
|
|
record[key] = nil
|
|
|
|
end
|
|
|
|
}
|
|
|
|
|
|
|
|
# fix OTRS 3.1 bug, no close time if ticket is created
|
2016-01-24 15:58:02 +00:00
|
|
|
if record['StateType'] == 'closed' && (!record['Closed'] || record['Closed'].empty?)
|
2015-05-07 11:57:19 +00:00
|
|
|
record['Closed'] = record['Created']
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# utf8 convert
|
|
|
|
def self._utf8_encode(data)
|
|
|
|
data.each { |key, value|
|
|
|
|
next if !value
|
|
|
|
next if value.class != String
|
2016-01-24 15:58:02 +00:00
|
|
|
data[key] = Encode.conv('utf8', value)
|
2015-05-07 11:57:19 +00:00
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2016-01-20 01:00:02 +00:00
|
|
|
# reset primary key sequences
|
|
|
|
def self._reset_pk(table)
|
|
|
|
return if ActiveRecord::Base.connection_config[:adapter] != 'postgresql'
|
|
|
|
ActiveRecord::Base.connection.reset_pk_sequence!(table)
|
|
|
|
end
|
|
|
|
|
2015-05-07 11:57:19 +00:00
|
|
|
# create customers for article
|
2015-07-24 10:00:03 +00:00
|
|
|
def self._article_based_customers(article)
|
2015-05-07 11:57:19 +00:00
|
|
|
|
|
|
|
# create customer/sender if needed
|
|
|
|
return if article['sender'] != 'customer'
|
|
|
|
return if article['created_by_id'].to_i != 1
|
|
|
|
return if article['from'].empty?
|
|
|
|
|
|
|
|
email = nil
|
|
|
|
begin
|
2016-01-24 15:58:02 +00:00
|
|
|
email = Mail::Address.new(article['from']).address
|
2015-05-07 11:57:19 +00:00
|
|
|
rescue
|
|
|
|
email = article['from']
|
|
|
|
if article['from'] =~ /<(.+?)>/
|
|
|
|
email = $1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-01-24 11:50:29 +00:00
|
|
|
user = User.lookup(email: email)
|
2015-05-07 11:57:19 +00:00
|
|
|
if !user
|
2016-01-24 11:50:29 +00:00
|
|
|
user = User.lookup(login: email)
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
|
|
|
if !user
|
|
|
|
begin
|
|
|
|
display_name = Mail::Address.new( article['from'] ).display_name ||
|
|
|
|
( Mail::Address.new( article['from'] ).comments && Mail::Address.new( article['from'] ).comments[0] )
|
|
|
|
rescue
|
|
|
|
display_name = article['from']
|
|
|
|
end
|
|
|
|
|
|
|
|
# do extra decoding because we needed to use field.value
|
2016-01-24 15:58:02 +00:00
|
|
|
display_name = Mail::Field.new('X-From', display_name).to_s
|
2015-05-07 11:57:19 +00:00
|
|
|
|
2016-01-24 15:58:02 +00:00
|
|
|
roles = Role.lookup(name: 'Customer')
|
2015-07-24 10:08:54 +00:00
|
|
|
begin
|
|
|
|
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,
|
|
|
|
)
|
|
|
|
rescue ActiveRecord::RecordNotUnique
|
|
|
|
log "User #{email} was handled by another thread, taking this."
|
2016-01-24 11:50:29 +00:00
|
|
|
user = User.lookup(login: email)
|
2015-07-24 10:08:54 +00:00
|
|
|
if !user
|
|
|
|
log "User #{email} wasn't created sleep and retry."
|
|
|
|
sleep rand 3
|
|
|
|
retry
|
|
|
|
end
|
|
|
|
end
|
2015-05-07 11:57:19 +00:00
|
|
|
end
|
|
|
|
article['created_by_id'] = user.id
|
|
|
|
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
2016-09-13 08:53:16 +00:00
|
|
|
def self.skip_fields
|
|
|
|
%w(ProcessManagementProcessID ProcessManagementActivityID ZammadMigratorChanged ZammadMigratorChangedOld)
|
|
|
|
end
|
|
|
|
|
2013-01-07 08:46:38 +00:00
|
|
|
end
|