Fixes #3698 - Import for kayako during the setup.
This commit is contained in:
parent
d4f997f0fd
commit
dd30b18285
145 changed files with 10489 additions and 6 deletions
|
@ -17,7 +17,7 @@ module RuboCop
|
||||||
PATTERN
|
PATTERN
|
||||||
|
|
||||||
def_node_matcher :has_reset?, <<-PATTERN
|
def_node_matcher :has_reset?, <<-PATTERN
|
||||||
$(send _ {:describe :context :it} (_ ...) (hash ... (pair (sym :db_strategy) (sym {:reset :reset_all}))))
|
$(send _ {:describe :context :it :shared_examples} (_ ...) (hash ... (pair (sym :db_strategy) (sym {:reset :reset_all}))))
|
||||||
PATTERN
|
PATTERN
|
||||||
|
|
||||||
MSG = 'Add a `db_strategy: :reset` to your context/decribe when you are creating object manager attributes!'.freeze
|
MSG = 'Add a `db_strategy: :reset` to your context/decribe when you are creating object manager attributes!'.freeze
|
||||||
|
|
|
@ -8,7 +8,6 @@ class ImportFreshdesk extends App.ControllerWizardFullScreen
|
||||||
'#freshdesk-subdomain-addon': 'freshdeskSubdomainAddon'
|
'#freshdesk-subdomain-addon': 'freshdeskSubdomainAddon'
|
||||||
'.freshdesk-subdomain-error': 'linkErrorMessage'
|
'.freshdesk-subdomain-error': 'linkErrorMessage'
|
||||||
'.freshdesk-api-token-error': 'apiTokenErrorMessage'
|
'.freshdesk-api-token-error': 'apiTokenErrorMessage'
|
||||||
'#freshdesk-email': 'freshdeskEmail'
|
|
||||||
'#freshdesk-api-token': 'freshdeskApiToken'
|
'#freshdesk-api-token': 'freshdeskApiToken'
|
||||||
'.js-ticket-count-info': 'ticketCountInfo'
|
'.js-ticket-count-info': 'ticketCountInfo'
|
||||||
updateMigrationDisplayLoop: 0
|
updateMigrationDisplayLoop: 0
|
||||||
|
|
194
app/assets/javascripts/app/controllers/import_kayako.coffee
Normal file
194
app/assets/javascripts/app/controllers/import_kayako.coffee
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
class ImportKayako extends App.ControllerWizardFullScreen
|
||||||
|
className: 'getstarted fit'
|
||||||
|
elements:
|
||||||
|
'.input-feedback': 'urlStatus'
|
||||||
|
'[data-target=kayako-credentials]': 'nextEnterCredentials'
|
||||||
|
'[data-target=kayako-start-migration]': 'nextStartMigration'
|
||||||
|
'#kayako-subdomain': 'kayakoSubdomain'
|
||||||
|
'#kayako-subdomain-addon': 'kayakoSubdomainAddon'
|
||||||
|
'.kayako-subdomain-error': 'linkErrorMessage'
|
||||||
|
'.kayako-password-error': 'apiTokenErrorMessage'
|
||||||
|
'#kayako-email': 'kayakoEmail'
|
||||||
|
'#kayako-password': 'kayakoPassword'
|
||||||
|
'.js-ticket-count-info': 'ticketCountInfo'
|
||||||
|
updateMigrationDisplayLoop: 0
|
||||||
|
|
||||||
|
events:
|
||||||
|
'click .js-kayako-credentials': 'showCredentials'
|
||||||
|
'click .js-migration-start': 'startMigration'
|
||||||
|
'keyup #kayako-subdomain': 'updateUrl'
|
||||||
|
'keyup #kayako-password': 'updateCredentials'
|
||||||
|
|
||||||
|
constructor: ->
|
||||||
|
super
|
||||||
|
|
||||||
|
# set title
|
||||||
|
@title 'Import'
|
||||||
|
|
||||||
|
@kayakoDomain = '.kayako.com'
|
||||||
|
|
||||||
|
# redirect to login if admin user already exists
|
||||||
|
if @Config.get('system_init_done')
|
||||||
|
@navigate '#login'
|
||||||
|
return
|
||||||
|
|
||||||
|
@fetch()
|
||||||
|
|
||||||
|
fetch: ->
|
||||||
|
|
||||||
|
# get data
|
||||||
|
@ajax(
|
||||||
|
id: 'getting_started'
|
||||||
|
type: 'GET'
|
||||||
|
url: "#{@apiPath}/getting_started"
|
||||||
|
processData: true
|
||||||
|
success: (data, status, xhr) =>
|
||||||
|
|
||||||
|
# check if import is active
|
||||||
|
if data.import_mode == true && data.import_backend != 'kayako'
|
||||||
|
@navigate "#import/#{data.import_backend}", { emptyEl: true }
|
||||||
|
return
|
||||||
|
|
||||||
|
# render page
|
||||||
|
@render()
|
||||||
|
|
||||||
|
if data.import_mode == true
|
||||||
|
@showImportState()
|
||||||
|
@updateMigration()
|
||||||
|
)
|
||||||
|
|
||||||
|
render: ->
|
||||||
|
@replaceWith App.view('import/kayako')(
|
||||||
|
kayakoDomain: @kayakoDomain
|
||||||
|
)
|
||||||
|
|
||||||
|
updateUrl: (e) =>
|
||||||
|
@urlStatus.attr('data-state', 'loading')
|
||||||
|
@kayakoSubdomainAddon.attr('style', 'padding-right: 42px')
|
||||||
|
@linkErrorMessage.text('')
|
||||||
|
|
||||||
|
# get data
|
||||||
|
callback = =>
|
||||||
|
@ajax(
|
||||||
|
id: 'import_kayako_url'
|
||||||
|
type: 'POST'
|
||||||
|
url: "#{@apiPath}/import/kayako/url_check"
|
||||||
|
data: JSON.stringify(url: "https://#{@kayakoSubdomain.val()}#{@kayakoDomain}")
|
||||||
|
processData: true
|
||||||
|
success: (data, status, xhr) =>
|
||||||
|
|
||||||
|
# validate form
|
||||||
|
if data.result is 'ok'
|
||||||
|
@urlStatus.attr('data-state', 'success')
|
||||||
|
@linkErrorMessage.text('')
|
||||||
|
@nextEnterCredentials.removeClass('hide')
|
||||||
|
else
|
||||||
|
@urlStatus.attr('data-state', 'error')
|
||||||
|
@linkErrorMessage.text( data.message_human || data.message)
|
||||||
|
@nextEnterCredentials.addClass('hide')
|
||||||
|
|
||||||
|
)
|
||||||
|
@delay( callback, 700, 'import_kayako_url' )
|
||||||
|
|
||||||
|
updateCredentials: (e) =>
|
||||||
|
@urlStatus.attr('data-state', 'loading')
|
||||||
|
@apiTokenErrorMessage.text('')
|
||||||
|
|
||||||
|
# get data
|
||||||
|
callback = =>
|
||||||
|
@ajax(
|
||||||
|
id: 'import_kayako_api_token'
|
||||||
|
type: 'POST'
|
||||||
|
url: "#{@apiPath}/import/kayako/credentials_check"
|
||||||
|
data: JSON.stringify(username: @kayakoEmail.val(), password: @kayakoPassword.val())
|
||||||
|
processData: true
|
||||||
|
success: (data, status, xhr) =>
|
||||||
|
|
||||||
|
# validate form
|
||||||
|
if data.result is 'ok'
|
||||||
|
@urlStatus.attr('data-state', 'success')
|
||||||
|
@apiTokenErrorMessage.text('')
|
||||||
|
@nextStartMigration.removeClass('hide')
|
||||||
|
else
|
||||||
|
@urlStatus.attr('data-state', 'error')
|
||||||
|
@apiTokenErrorMessage.text(data.message_human || data.message)
|
||||||
|
@nextStartMigration.addClass('hide')
|
||||||
|
|
||||||
|
)
|
||||||
|
@delay(callback, 700, 'import_kayako_api_token')
|
||||||
|
|
||||||
|
showCredentials: (e) =>
|
||||||
|
e.preventDefault()
|
||||||
|
@urlStatus.attr('data-state', '')
|
||||||
|
@$('[data-slide=kayako-subdomain]').toggleClass('hide')
|
||||||
|
@$('[data-slide=kayako-credentials]').toggleClass('hide')
|
||||||
|
|
||||||
|
showImportState: =>
|
||||||
|
@$('[data-slide=kayako-subdomain]').addClass('hide')
|
||||||
|
@$('[data-slide=kayako-credentials]').addClass('hide')
|
||||||
|
@$('[data-slide=kayako-import]').removeClass('hide')
|
||||||
|
|
||||||
|
startMigration: (e) =>
|
||||||
|
e.preventDefault()
|
||||||
|
@showImportState()
|
||||||
|
@ajax(
|
||||||
|
id: 'import_start'
|
||||||
|
type: 'POST'
|
||||||
|
url: "#{@apiPath}/import/kayako/import_start"
|
||||||
|
processData: true
|
||||||
|
success: (data, status, xhr) =>
|
||||||
|
|
||||||
|
# validate form
|
||||||
|
if data.result is 'ok'
|
||||||
|
@delay(@updateMigration, 3000)
|
||||||
|
)
|
||||||
|
|
||||||
|
updateMigration: =>
|
||||||
|
@updateMigrationDisplayLoop += 1
|
||||||
|
@showImportState()
|
||||||
|
@ajax(
|
||||||
|
id: 'import_status'
|
||||||
|
type: 'GET'
|
||||||
|
url: "#{@apiPath}/import/kayako/import_status"
|
||||||
|
processData: true
|
||||||
|
success: (data, status, xhr) =>
|
||||||
|
|
||||||
|
if _.isEmpty(data.result) && @updateMigrationDisplayLoop > 16
|
||||||
|
@$('.js-error').removeClass('hide')
|
||||||
|
@$('.js-error').html(App.i18n.translateContent('Background process did not start or has not finished! Please contact your support.'))
|
||||||
|
return
|
||||||
|
|
||||||
|
if !_.isEmpty(data.result['error'])
|
||||||
|
@$('.js-error').removeClass('hide')
|
||||||
|
@$('.js-error').html(App.i18n.translateContent(data.result['error']))
|
||||||
|
else
|
||||||
|
@$('.js-error').addClass('hide')
|
||||||
|
|
||||||
|
if !_.isEmpty(data.finished_at) && _.isEmpty(data.result['error'])
|
||||||
|
window.location.reload()
|
||||||
|
return
|
||||||
|
|
||||||
|
if !_.isEmpty(data.result)
|
||||||
|
for model, stats of data.result
|
||||||
|
if stats.sum > stats.total
|
||||||
|
stats.sum = stats.total
|
||||||
|
|
||||||
|
element = @$('.js-' + model.toLowerCase() )
|
||||||
|
element.find('.js-done').text(stats.sum)
|
||||||
|
element.find('.js-total').text(stats.total)
|
||||||
|
element.find('progress').attr('max', stats.total )
|
||||||
|
element.find('progress').attr('value', stats.sum )
|
||||||
|
if stats.total <= stats.sum
|
||||||
|
element.addClass('is-done')
|
||||||
|
else
|
||||||
|
element.removeClass('is-done')
|
||||||
|
@delay(@updateMigration, 5000)
|
||||||
|
)
|
||||||
|
|
||||||
|
App.Config.set('import/kayako', ImportKayako, 'Routes')
|
||||||
|
App.Config.set('kayako', {
|
||||||
|
title: 'Kayako'
|
||||||
|
name: 'Kayako'
|
||||||
|
class: 'js-kayako'
|
||||||
|
url: '#import/kayako'
|
||||||
|
}, 'ImportPlugins')
|
113
app/assets/javascripts/app/views/import/kayako.jst.eco
Normal file
113
app/assets/javascripts/app/views/import/kayako.jst.eco
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
<div class="main flex vertical centered darkBackground">
|
||||||
|
<%- @Icon('full-logo', 'wizard-logo') %>
|
||||||
|
<div class="import wizard">
|
||||||
|
<div class="wizard-slide vertical" data-slide="kayako-subdomain">
|
||||||
|
<h2><%- @T('%s URL', 'Kayako') %></h2>
|
||||||
|
<div class="wizard-body flex vertical justified">
|
||||||
|
<p>
|
||||||
|
<%- @T('Enter the Subdomain of your %s system', 'Kayako') %>:
|
||||||
|
</p>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="kayako-subdomain"><%- @T('%s Subdomain', 'Kayako') %></label>
|
||||||
|
<div class="u-positionOrigin">
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" id="kayako-subdomain" class="form-control" placeholder="example" name="kayako-subdomain" aria-describedby="kayako-subdomain-addon">
|
||||||
|
<span class="input-group-addon" id="kayako-subdomain-addon"><%- @kayakoDomain %></span>
|
||||||
|
</div>
|
||||||
|
<div class="input-feedback input-feedback--no-background centered">
|
||||||
|
<div class="small loading icon"></div>
|
||||||
|
<%- @Icon('diagonal-cross', 'icon-error') %>
|
||||||
|
<%- @Icon('checkmark') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="error kayako-subdomain-error"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wizard-controls horizontal center">
|
||||||
|
<a class="btn btn--text btn--secondary" href="#import"><%- @T('Go Back') %></a>
|
||||||
|
<div class="btn btn--primary align-right hide js-kayako-credentials" data-target="kayako-credentials"><%- @T('Enter credentials') %></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wizard-slide vertical hide" data-slide="kayako-credentials">
|
||||||
|
<h2><%- @T('%s credentials', 'Kayako') %></h2>
|
||||||
|
<div class="wizard-body flex vertical justified">
|
||||||
|
<p>
|
||||||
|
<%- @T('Enter your email address and password from your %s account which should be used for the import.', 'Kayako') %>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<%- @T('Attention: These will also your login password after the import is completed.') %>
|
||||||
|
</p>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="kayako-email"><%- @T('Email') %></label>
|
||||||
|
<div class="u-positionOrigin">
|
||||||
|
<input type="email" id="kayako-email" class="form-control" placeholder="admin@example.com" name="kayako-email">
|
||||||
|
</div>
|
||||||
|
<label for="kayako-password"><%- @T('Password') %></label>
|
||||||
|
<div class="u-positionOrigin">
|
||||||
|
<input type="password" id="kayako-password" class="form-control" name="kayako-password">
|
||||||
|
<div class="input-feedback centered">
|
||||||
|
<div class="small loading icon"></div>
|
||||||
|
<%- @Icon('diagonal-cross', 'icon-error') %>
|
||||||
|
<%- @Icon('checkmark') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="error kayako-password-error"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wizard-controls horizontal center">
|
||||||
|
<a class="btn btn--text btn--secondary" href="#import"><%- @T('Go Back') %></a>
|
||||||
|
<div class="btn btn--primary align-right hide js-migration-start" data-target="kayako-start-migration"><%- @T('Migrate %s Data', 'Kayako') %></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wizard-slide vertical hide" data-slide="kayako-import">
|
||||||
|
<h2><%- @T('%s Migration', 'Kayako') %></h2>
|
||||||
|
<div class="alert alert--danger hide js-error" role="alert"></div>
|
||||||
|
<div class="wizard-body flex vertical justified">
|
||||||
|
<table class="progressTable">
|
||||||
|
<tr class="js-groups">
|
||||||
|
<td><span class="js-done">-</span>/<span class="js-total">-</span>
|
||||||
|
<td><span><%- @T('Groups') %></span>
|
||||||
|
<td class="progressTable-progressCell">
|
||||||
|
<div class="horizontal center">
|
||||||
|
<div class="flex"><progress max="42" value="42"></progress></div>
|
||||||
|
<%- @Icon('checkmark') %>
|
||||||
|
</div>
|
||||||
|
</tr>
|
||||||
|
<tr class="js-organizations">
|
||||||
|
<td><span class="js-done">-</span>/<span class="js-total">-</span>
|
||||||
|
<td><span><%- @T('Organizations') %></span>
|
||||||
|
<td class="progressTable-progressCell">
|
||||||
|
<div class="horizontal center">
|
||||||
|
<div class="flex"><progress max="42" value="42"></progress></div>
|
||||||
|
<%- @Icon('checkmark') %>
|
||||||
|
</div>
|
||||||
|
</tr>
|
||||||
|
<tr class="js-users">
|
||||||
|
<td><span class="js-done">-</span>/<span class="js-total">-</span>
|
||||||
|
<td><span><%- @T('Users') %></span>
|
||||||
|
<td class="progressTable-progressCell">
|
||||||
|
<div class="horizontal center">
|
||||||
|
<div class="flex"><progress max="42" value="42"></progress></div>
|
||||||
|
<%- @Icon('checkmark') %>
|
||||||
|
</div>
|
||||||
|
</tr>
|
||||||
|
<tr class="js-tickets">
|
||||||
|
<td><span class="js-done">-</span>/<span class="js-total">-</span>
|
||||||
|
<td><span><%- @T('Tickets') %></span>
|
||||||
|
<td class="progressTable-progressCell">
|
||||||
|
<div class="horizontal center">
|
||||||
|
<div class="flex"><progress max="42" value="42"></progress></div>
|
||||||
|
<%- @Icon('checkmark') %>
|
||||||
|
</div>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="wizard-controls horizontal center">
|
||||||
|
<a href="#" class="btn btn--primary align-right hide js-finished"><%- @T('done') %></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
146
app/controllers/import_kayako_controller.rb
Normal file
146
app/controllers/import_kayako_controller.rb
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class ImportKayakoController < ApplicationController
|
||||||
|
def url_check
|
||||||
|
return if setup_done_response
|
||||||
|
|
||||||
|
url = params[:url]
|
||||||
|
|
||||||
|
# validate
|
||||||
|
if !valid_url_syntax?(url)
|
||||||
|
render json: {
|
||||||
|
result: 'invalid',
|
||||||
|
message: 'Invalid URL!',
|
||||||
|
}
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
endpoint = build_endpoint_url(url)
|
||||||
|
|
||||||
|
return if !valid_endpoint?(endpoint)
|
||||||
|
|
||||||
|
Setting.set('import_kayako_endpoint', endpoint)
|
||||||
|
|
||||||
|
render json: {
|
||||||
|
result: 'ok',
|
||||||
|
url: url,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def credentials_check
|
||||||
|
return if setup_done_response
|
||||||
|
|
||||||
|
if !params[:username] || !params[:password]
|
||||||
|
render json: {
|
||||||
|
result: 'invalid',
|
||||||
|
message_human: 'Incomplete credentials',
|
||||||
|
}
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
save_endpoint_settings(params[:username], params[:password])
|
||||||
|
|
||||||
|
return if !valid_connection?
|
||||||
|
|
||||||
|
render json: {
|
||||||
|
result: 'ok',
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def import_start
|
||||||
|
return if setup_done_response
|
||||||
|
|
||||||
|
Setting.set('import_mode', true)
|
||||||
|
Setting.set('import_backend', 'kayako')
|
||||||
|
|
||||||
|
job = ImportJob.create(name: 'Import::Kayako')
|
||||||
|
AsyncImportJob.perform_later(job)
|
||||||
|
|
||||||
|
render json: {
|
||||||
|
result: 'ok',
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def import_status
|
||||||
|
job = ImportJob.find_by(name: 'Import::Kayako')
|
||||||
|
|
||||||
|
if job.finished_at.present?
|
||||||
|
Setting.reload
|
||||||
|
end
|
||||||
|
|
||||||
|
model_show_render_item(job)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def setup_done
|
||||||
|
count = User.all.count()
|
||||||
|
done = true
|
||||||
|
if count <= 2
|
||||||
|
done = false
|
||||||
|
end
|
||||||
|
done
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup_done_response
|
||||||
|
if !setup_done
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
render json: {
|
||||||
|
setup_done: true,
|
||||||
|
}
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def valid_url_syntax?(url)
|
||||||
|
return false if url.blank? || url !~ %r{^(http|https)://.+?$}
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def valid_endpoint?(endpoint)
|
||||||
|
response = UserAgent.request("#{endpoint}/teams", verify_ssl: true)
|
||||||
|
|
||||||
|
if response.header.nil? || !response.header['x-api-version']
|
||||||
|
render json: {
|
||||||
|
result: 'invalid',
|
||||||
|
message: response.error.to_s,
|
||||||
|
message_human: 'Hostname not found!',
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_endpoint_url(url)
|
||||||
|
endpoint = "#{url}/api/v1"
|
||||||
|
endpoint.gsub(%r{([^:])//+}, '\\1/')
|
||||||
|
end
|
||||||
|
|
||||||
|
def valid_connection?
|
||||||
|
result = Sequencer.process('Import::Kayako::ConnectionTest')
|
||||||
|
|
||||||
|
if !result[:connected]
|
||||||
|
reset_endpoint_settings
|
||||||
|
|
||||||
|
render json: {
|
||||||
|
result: 'invalid',
|
||||||
|
message_human: 'Invalid credentials!',
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def save_endpoint_settings(username, possword)
|
||||||
|
Setting.set('import_kayako_endpoint_username', username)
|
||||||
|
Setting.set('import_kayako_endpoint_password', possword)
|
||||||
|
end
|
||||||
|
|
||||||
|
def reset_endpoint_settings
|
||||||
|
save_endpoint_settings(nil, nil)
|
||||||
|
end
|
||||||
|
end
|
12
config/routes/import_kayako.rb
Normal file
12
config/routes/import_kayako.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
Zammad::Application.routes.draw do
|
||||||
|
api_path = Rails.configuration.api_path
|
||||||
|
|
||||||
|
# import kayako
|
||||||
|
match api_path + '/import/kayako/url_check', to: 'import_kayako#url_check', via: :post
|
||||||
|
match api_path + '/import/kayako/credentials_check', to: 'import_kayako#credentials_check', via: :post
|
||||||
|
match api_path + '/import/kayako/import_start', to: 'import_kayako#import_start', via: :post
|
||||||
|
match api_path + '/import/kayako/import_status', to: 'import_kayako#import_status', via: :get
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,15 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class AddTicketArticleTypeFacebookDirectMessage < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
# return if it's a new setup
|
||||||
|
return if !Setting.exists?(name: 'system_init_done')
|
||||||
|
|
||||||
|
Ticket::Article::Type.create_if_not_exists(
|
||||||
|
name: 'facebook direct-message',
|
||||||
|
communication: true,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
|
@ -3282,6 +3282,61 @@ Setting.create_if_not_exists(
|
||||||
frontend: false
|
frontend: false
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Setting.create_if_not_exists(
|
||||||
|
title: 'Import Endpoint',
|
||||||
|
name: 'import_kayako_endpoint',
|
||||||
|
area: 'Import::Kayako',
|
||||||
|
description: 'Defines Kayako endpoint to import users, ticket, states and articles.',
|
||||||
|
options: {
|
||||||
|
form: [
|
||||||
|
{
|
||||||
|
display: '',
|
||||||
|
null: false,
|
||||||
|
name: 'import_kayako_endpoint',
|
||||||
|
tag: 'input',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
state: 'https://yours.kayako.com/api/v1',
|
||||||
|
frontend: false
|
||||||
|
)
|
||||||
|
Setting.create_if_not_exists(
|
||||||
|
title: 'Import User for requesting the Kayako API',
|
||||||
|
name: 'import_kayako_endpoint_username',
|
||||||
|
area: 'Import::Kayako',
|
||||||
|
description: 'Defines Kayako endpoint authentication user.',
|
||||||
|
options: {
|
||||||
|
form: [
|
||||||
|
{
|
||||||
|
display: '',
|
||||||
|
null: false,
|
||||||
|
name: 'import_kayako_endpoint_username',
|
||||||
|
tag: 'input',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
state: '',
|
||||||
|
frontend: false
|
||||||
|
)
|
||||||
|
Setting.create_if_not_exists(
|
||||||
|
title: 'Import Password for requesting the Kayako API',
|
||||||
|
name: 'import_kayako_endpoint_password',
|
||||||
|
area: 'Import::Kayako',
|
||||||
|
description: 'Defines Kayako endpoint authentication password.',
|
||||||
|
options: {
|
||||||
|
form: [
|
||||||
|
{
|
||||||
|
display: '',
|
||||||
|
null: false,
|
||||||
|
name: 'import_kayako_endpoint_password',
|
||||||
|
tag: 'input',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
state: '',
|
||||||
|
frontend: false
|
||||||
|
)
|
||||||
|
|
||||||
Setting.create_if_not_exists(
|
Setting.create_if_not_exists(
|
||||||
title: 'Import Backends',
|
title: 'Import Backends',
|
||||||
name: 'import_backends',
|
name: 'import_backends',
|
||||||
|
|
|
@ -12,3 +12,4 @@ Ticket::Article::Type.create_if_not_exists(id: 9, name: 'facebook feed comment',
|
||||||
Ticket::Article::Type.create_if_not_exists(id: 10, name: 'note', communication: false)
|
Ticket::Article::Type.create_if_not_exists(id: 10, name: 'note', communication: false)
|
||||||
Ticket::Article::Type.create_if_not_exists(id: 11, name: 'web', communication: true)
|
Ticket::Article::Type.create_if_not_exists(id: 11, name: 'web', communication: true)
|
||||||
Ticket::Article::Type.create_if_not_exists(id: 12, name: 'telegram personal-message', communication: true)
|
Ticket::Article::Type.create_if_not_exists(id: 12, name: 'telegram personal-message', communication: true)
|
||||||
|
Ticket::Article::Type.create_if_not_exists(id: 13, name: 'facebook direct-message', communication: true)
|
||||||
|
|
15
lib/import/kayako.rb
Normal file
15
lib/import/kayako.rb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
module Import
|
||||||
|
class Kayako < Import::Base
|
||||||
|
include Import::Mixin::Sequence
|
||||||
|
|
||||||
|
def start
|
||||||
|
process
|
||||||
|
end
|
||||||
|
|
||||||
|
def sequence_name
|
||||||
|
'Import::Kayako::Full'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
45
lib/sequencer/sequence/import/kayako/case.rb
Normal file
45
lib/sequencer/sequence/import/kayako/case.rb
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Sequence
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class Case < Sequencer::Sequence::Base
|
||||||
|
|
||||||
|
def self.sequence
|
||||||
|
[
|
||||||
|
'Common::ModelClass::Ticket',
|
||||||
|
'Import::Kayako::Case::Skip::Deleted',
|
||||||
|
'Import::Kayako::Case::Skip::Suspended',
|
||||||
|
'Import::Kayako::Common::CreatedById',
|
||||||
|
'Import::Kayako::Common::ArticleSenderId',
|
||||||
|
'Import::Kayako::Case::UpdatedById',
|
||||||
|
'Import::Kayako::Case::CustomerId',
|
||||||
|
'Import::Kayako::Case::OwnerId',
|
||||||
|
'Import::Kayako::Case::GroupId',
|
||||||
|
'Import::Kayako::Case::OrganizationId',
|
||||||
|
'Import::Kayako::Case::PriorityId',
|
||||||
|
'Import::Kayako::Case::StateId',
|
||||||
|
'Import::Kayako::Case::Type',
|
||||||
|
'Import::Kayako::Common::ArticleSourceChannel',
|
||||||
|
'Import::Kayako::Case::Mapping',
|
||||||
|
'Import::Kayako::Mapping::Timestamps',
|
||||||
|
'Import::Kayako::Mapping::CustomFields',
|
||||||
|
'Import::Common::Model::FindBy::Id',
|
||||||
|
'Import::Common::Model::Update',
|
||||||
|
'Import::Common::Model::Create',
|
||||||
|
'Import::Common::Model::Save',
|
||||||
|
'Import::Common::Model::ResetPrimaryKeySequence',
|
||||||
|
'Import::Kayako::MapId',
|
||||||
|
'Import::Kayako::Case::Tags',
|
||||||
|
'Import::Kayako::Case::Posts',
|
||||||
|
'Import::Common::Model::Statistics::Diff::ModelKey',
|
||||||
|
'Import::Common::ImportJob::Statistics::Update',
|
||||||
|
'Import::Common::ImportJob::Statistics::Store',
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
24
lib/sequencer/sequence/import/kayako/case_field.rb
Normal file
24
lib/sequencer/sequence/import/kayako/case_field.rb
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Sequence
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class CaseField < Sequencer::Sequence::Base
|
||||||
|
|
||||||
|
def self.sequence
|
||||||
|
[
|
||||||
|
'Common::ModelClass::Ticket',
|
||||||
|
'Import::Kayako::ObjectAttribute::Skip',
|
||||||
|
'Import::Kayako::ObjectAttribute::SanitizedName',
|
||||||
|
'Import::Kayako::ObjectAttribute::Config',
|
||||||
|
'Import::Kayako::ObjectAttribute::Add',
|
||||||
|
'Import::Kayako::ObjectAttribute::MigrationExecute',
|
||||||
|
'Import::Kayako::ObjectAttribute::FieldMap',
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
21
lib/sequencer/sequence/import/kayako/connection_test.rb
Normal file
21
lib/sequencer/sequence/import/kayako/connection_test.rb
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Sequence
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class ConnectionTest < Sequencer::Sequence::Base
|
||||||
|
def self.expecting
|
||||||
|
[:connected]
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.sequence
|
||||||
|
[
|
||||||
|
'Kayako::Connected',
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
34
lib/sequencer/sequence/import/kayako/full.rb
Normal file
34
lib/sequencer/sequence/import/kayako/full.rb
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Sequence
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class Full < Sequencer::Sequence::Base
|
||||||
|
|
||||||
|
def self.sequence
|
||||||
|
[
|
||||||
|
'Import::Common::ImportMode::Check',
|
||||||
|
'Import::Common::SystemInitDone::Check',
|
||||||
|
'Import::Common::ImportJob::DryRun',
|
||||||
|
'Import::Kayako::DefaultLanguage',
|
||||||
|
'Import::Kayako::IdMap',
|
||||||
|
'Import::Kayako::Teams',
|
||||||
|
'Import::Kayako::FieldMap',
|
||||||
|
'Import::Kayako::OrganizationFields',
|
||||||
|
'Import::Kayako::Organizations',
|
||||||
|
'Import::Kayako::UserFields',
|
||||||
|
'Import::Kayako::Users',
|
||||||
|
'Import::Kayako::CaseFields',
|
||||||
|
'Import::Kayako::Cases',
|
||||||
|
'Import::Kayako::TimeEntries',
|
||||||
|
'Import::Common::SystemInitDone::Set',
|
||||||
|
'Import::Kayako::ImportSettingsUnset',
|
||||||
|
'Import::Common::ImportMode::Unset',
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
20
lib/sequencer/sequence/import/kayako/generic_field.rb
Normal file
20
lib/sequencer/sequence/import/kayako/generic_field.rb
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Sequence
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class GenericField < Sequencer::Sequence::Base
|
||||||
|
|
||||||
|
def self.sequence
|
||||||
|
[
|
||||||
|
'Import::Kayako::Request',
|
||||||
|
'Import::Kayako::Resources',
|
||||||
|
'Import::Kayako::Perform',
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
24
lib/sequencer/sequence/import/kayako/generic_object.rb
Normal file
24
lib/sequencer/sequence/import/kayako/generic_object.rb
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Sequence
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class GenericObject < Sequencer::Sequence::Base
|
||||||
|
|
||||||
|
def self.sequence
|
||||||
|
[
|
||||||
|
'Import::Kayako::Request',
|
||||||
|
'Import::Kayako::Resources',
|
||||||
|
'Import::Kayako::ModelClass',
|
||||||
|
'Import::Kayako::ObjectCount',
|
||||||
|
'Import::Common::ImportJob::Statistics::Update',
|
||||||
|
'Import::Common::ImportJob::Statistics::Store',
|
||||||
|
'Import::Kayako::Perform',
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
29
lib/sequencer/sequence/import/kayako/organization.rb
Normal file
29
lib/sequencer/sequence/import/kayako/organization.rb
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Sequence
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class Organization < Sequencer::Sequence::Base
|
||||||
|
|
||||||
|
def self.sequence
|
||||||
|
[
|
||||||
|
'Common::ModelClass::Organization',
|
||||||
|
'Import::Kayako::Organization::Mapping',
|
||||||
|
'Import::Kayako::Mapping::CustomFields',
|
||||||
|
'Import::Common::Model::Attributes::AddByIds',
|
||||||
|
'Import::Common::Model::FindBy::Name',
|
||||||
|
'Import::Common::Model::Update',
|
||||||
|
'Import::Common::Model::Create',
|
||||||
|
'Import::Common::Model::Save',
|
||||||
|
'Import::Kayako::MapId',
|
||||||
|
'Import::Common::Model::Statistics::Diff::ModelKey',
|
||||||
|
'Import::Common::ImportJob::Statistics::Update',
|
||||||
|
'Import::Common::ImportJob::Statistics::Store',
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
24
lib/sequencer/sequence/import/kayako/organization_field.rb
Normal file
24
lib/sequencer/sequence/import/kayako/organization_field.rb
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Sequence
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class OrganizationField < Sequencer::Sequence::Base
|
||||||
|
|
||||||
|
def self.sequence
|
||||||
|
[
|
||||||
|
'Common::ModelClass::Organization',
|
||||||
|
'Import::Kayako::ObjectAttribute::Skip',
|
||||||
|
'Import::Kayako::ObjectAttribute::SanitizedName',
|
||||||
|
'Import::Kayako::ObjectAttribute::Config',
|
||||||
|
'Import::Kayako::ObjectAttribute::Add',
|
||||||
|
'Import::Kayako::ObjectAttribute::MigrationExecute',
|
||||||
|
'Import::Kayako::ObjectAttribute::FieldMap',
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
30
lib/sequencer/sequence/import/kayako/post.rb
Normal file
30
lib/sequencer/sequence/import/kayako/post.rb
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Sequence
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class Post < Sequencer::Sequence::Base
|
||||||
|
def self.sequence
|
||||||
|
[
|
||||||
|
'Common::ModelClass::Ticket::Article',
|
||||||
|
'Import::Kayako::Common::CreatedById',
|
||||||
|
'Import::Kayako::Common::ArticleSenderId',
|
||||||
|
'Import::Kayako::Common::ArticleSourceChannel',
|
||||||
|
'Import::Kayako::Post::Mapping',
|
||||||
|
'Import::Kayako::Post::InlineImages',
|
||||||
|
'Import::Kayako::Mapping::Timestamps',
|
||||||
|
'Import::Kayako::Post::UnsetInstance',
|
||||||
|
'Import::Common::Model::FindBy::MessageId',
|
||||||
|
'Import::Common::Model::Update',
|
||||||
|
'Import::Common::Model::Create',
|
||||||
|
'Import::Common::Model::Save',
|
||||||
|
'Import::Kayako::MapId',
|
||||||
|
'Import::Kayako::Post::Attachments',
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
21
lib/sequencer/sequence/import/kayako/posts.rb
Normal file
21
lib/sequencer/sequence/import/kayako/posts.rb
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Sequence
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class Posts < Sequencer::Sequence::Base
|
||||||
|
|
||||||
|
def self.sequence
|
||||||
|
[
|
||||||
|
'Import::Kayako::Request',
|
||||||
|
'Import::Kayako::Resources',
|
||||||
|
'Import::Kayako::ModelClass',
|
||||||
|
'Import::Kayako::Perform',
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
28
lib/sequencer/sequence/import/kayako/team.rb
Normal file
28
lib/sequencer/sequence/import/kayako/team.rb
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Sequence
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class Team < Sequencer::Sequence::Base
|
||||||
|
|
||||||
|
def self.sequence
|
||||||
|
[
|
||||||
|
'Common::ModelClass::Group',
|
||||||
|
'Import::Kayako::Team::Mapping',
|
||||||
|
'Import::Common::Model::Attributes::AddByIds',
|
||||||
|
'Import::Common::Model::FindBy::Name',
|
||||||
|
'Import::Common::Model::Update',
|
||||||
|
'Import::Common::Model::Create',
|
||||||
|
'Import::Common::Model::Save',
|
||||||
|
'Import::Kayako::MapId',
|
||||||
|
'Import::Common::Model::Statistics::Diff::ModelKey',
|
||||||
|
'Import::Common::ImportJob::Statistics::Update',
|
||||||
|
'Import::Common::ImportJob::Statistics::Store',
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
21
lib/sequencer/sequence/import/kayako/time_entries.rb
Normal file
21
lib/sequencer/sequence/import/kayako/time_entries.rb
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Sequence
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class TimeEntries < Sequencer::Sequence::Base
|
||||||
|
|
||||||
|
def self.sequence
|
||||||
|
[
|
||||||
|
'Import::Kayako::Request',
|
||||||
|
'Import::Kayako::Resources',
|
||||||
|
'Import::Kayako::ModelClass',
|
||||||
|
'Import::Kayako::Perform',
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
26
lib/sequencer/sequence/import/kayako/time_entry.rb
Normal file
26
lib/sequencer/sequence/import/kayako/time_entry.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Sequence
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class TimeEntry < Sequencer::Sequence::Base
|
||||||
|
|
||||||
|
def self.sequence
|
||||||
|
[
|
||||||
|
'Common::ModelClass::Ticket::TimeAccounting',
|
||||||
|
'Import::Kayako::TimeEntry::Skip',
|
||||||
|
'Import::Kayako::Common::CreatedById',
|
||||||
|
'Import::Kayako::TimeEntry::Mapping',
|
||||||
|
'Import::Kayako::Mapping::Timestamps',
|
||||||
|
'Import::Common::Model::FindBy::TimeAccountingAttributes',
|
||||||
|
'Import::Common::Model::Update',
|
||||||
|
'Import::Common::Model::Create',
|
||||||
|
'Import::Common::Model::Save',
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
37
lib/sequencer/sequence/import/kayako/user.rb
Normal file
37
lib/sequencer/sequence/import/kayako/user.rb
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Sequence
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class User < Sequencer::Sequence::Base
|
||||||
|
|
||||||
|
def self.sequence
|
||||||
|
[
|
||||||
|
'Import::Kayako::User::Identifier',
|
||||||
|
'Import::Kayako::User::Login',
|
||||||
|
'Import::Kayako::User::Initiator',
|
||||||
|
'Import::Kayako::User::Password',
|
||||||
|
'Import::Kayako::User::Roles',
|
||||||
|
'Import::Kayako::User::GroupIds',
|
||||||
|
'Import::Kayako::User::OrganizationId',
|
||||||
|
'Common::ModelClass::User',
|
||||||
|
'Import::Kayako::User::Mapping',
|
||||||
|
'Import::Kayako::Mapping::Timestamps',
|
||||||
|
'Import::Kayako::Mapping::CustomFields',
|
||||||
|
'Import::Common::Model::Attributes::AddByIds',
|
||||||
|
'Import::Common::Model::FindBy::UserAttributes',
|
||||||
|
'Import::Common::Model::Update',
|
||||||
|
'Import::Common::Model::Create',
|
||||||
|
'Import::Common::Model::Save',
|
||||||
|
'Import::Kayako::MapId',
|
||||||
|
'Import::Common::Model::Statistics::Diff::ModelKey',
|
||||||
|
'Import::Common::ImportJob::Statistics::Update',
|
||||||
|
'Import::Common::ImportJob::Statistics::Store',
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
24
lib/sequencer/sequence/import/kayako/user_field.rb
Normal file
24
lib/sequencer/sequence/import/kayako/user_field.rb
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Sequence
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class UserField < Sequencer::Sequence::Base
|
||||||
|
|
||||||
|
def self.sequence
|
||||||
|
[
|
||||||
|
'Common::ModelClass::User',
|
||||||
|
'Import::Kayako::ObjectAttribute::Skip',
|
||||||
|
'Import::Kayako::ObjectAttribute::SanitizedName',
|
||||||
|
'Import::Kayako::ObjectAttribute::Config',
|
||||||
|
'Import::Kayako::ObjectAttribute::Add',
|
||||||
|
'Import::Kayako::ObjectAttribute::MigrationExecute',
|
||||||
|
'Import::Kayako::ObjectAttribute::FieldMap',
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,14 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Common
|
||||||
|
module ModelClass
|
||||||
|
module ObjectManager
|
||||||
|
class Attribute < Sequencer::Unit::Common::ModelClass::Base
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -14,10 +14,6 @@ class Sequencer
|
||||||
|
|
||||||
uses :resource
|
uses :resource
|
||||||
|
|
||||||
def object
|
|
||||||
'Conversation'
|
|
||||||
end
|
|
||||||
|
|
||||||
def sequence_name
|
def sequence_name
|
||||||
'Sequencer::Sequence::Import::Freshdesk::Conversations'.freeze
|
'Sequencer::Sequence::Import::Freshdesk::Conversations'.freeze
|
||||||
end
|
end
|
||||||
|
|
22
lib/sequencer/unit/import/kayako/case/customer_id.rb
Normal file
22
lib/sequencer/unit/import/kayako/case/customer_id.rb
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Case
|
||||||
|
class CustomerId < Sequencer::Unit::Common::Provider::Named
|
||||||
|
|
||||||
|
uses :resource, :id_map
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def customer_id
|
||||||
|
id_map['User'].fetch(resource['requester']&.fetch('id'), 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
22
lib/sequencer/unit/import/kayako/case/group_id.rb
Normal file
22
lib/sequencer/unit/import/kayako/case/group_id.rb
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Case
|
||||||
|
class GroupId < Sequencer::Unit::Common::Provider::Named
|
||||||
|
|
||||||
|
uses :resource, :id_map
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def group_id
|
||||||
|
id_map['Group'].fetch(resource['assigned_team']&.fetch('id'), 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
37
lib/sequencer/unit/import/kayako/case/mapping.rb
Normal file
37
lib/sequencer/unit/import/kayako/case/mapping.rb
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Case
|
||||||
|
class Mapping < Sequencer::Unit::Base
|
||||||
|
include ::Sequencer::Unit::Import::Common::Mapping::Mixin::ProvideMapped
|
||||||
|
|
||||||
|
uses :resource, :customer_id, :owner_id, :group_id, :organization_id, :priority_id, :state_id,
|
||||||
|
:created_by_id, :updated_by_id, :type
|
||||||
|
|
||||||
|
def process
|
||||||
|
provide_mapped do
|
||||||
|
{
|
||||||
|
id: resource['id'],
|
||||||
|
number: resource['id'],
|
||||||
|
title: resource['subject'],
|
||||||
|
owner_id: owner_id,
|
||||||
|
group_id: group_id,
|
||||||
|
customer_id: customer_id,
|
||||||
|
organization_id: organization_id,
|
||||||
|
priority_id: priority_id,
|
||||||
|
state_id: state_id,
|
||||||
|
type: type,
|
||||||
|
updated_by_id: updated_by_id,
|
||||||
|
created_by_id: created_by_id,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
28
lib/sequencer/unit/import/kayako/case/organization_id.rb
Normal file
28
lib/sequencer/unit/import/kayako/case/organization_id.rb
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Case
|
||||||
|
class OrganizationId < Sequencer::Unit::Common::Provider::Named
|
||||||
|
|
||||||
|
uses :resource, :id_map
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def organization_id
|
||||||
|
return if organization.nil?
|
||||||
|
|
||||||
|
id_map['Organization'][organization['id']]
|
||||||
|
end
|
||||||
|
|
||||||
|
def organization
|
||||||
|
resource['requester']&.fetch('organization')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
22
lib/sequencer/unit/import/kayako/case/owner_id.rb
Normal file
22
lib/sequencer/unit/import/kayako/case/owner_id.rb
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Case
|
||||||
|
class OwnerId < Sequencer::Unit::Common::Provider::Named
|
||||||
|
|
||||||
|
uses :resource, :id_map
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def owner_id
|
||||||
|
id_map['User'].fetch(resource['assigned_agent']&.fetch('id'), 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
35
lib/sequencer/unit/import/kayako/case/posts.rb
Normal file
35
lib/sequencer/unit/import/kayako/case/posts.rb
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Case
|
||||||
|
class Posts < Sequencer::Unit::Import::Kayako::SubSequence::SubObject
|
||||||
|
prepend ::Sequencer::Unit::Import::Common::Model::Mixin::Skip::Action
|
||||||
|
|
||||||
|
optional :action
|
||||||
|
|
||||||
|
skip_action :skipped, :failed
|
||||||
|
|
||||||
|
uses :resource
|
||||||
|
|
||||||
|
def object
|
||||||
|
'Post'
|
||||||
|
end
|
||||||
|
|
||||||
|
def sequence_name
|
||||||
|
'Sequencer::Sequence::Import::Kayako::Posts'.freeze
|
||||||
|
end
|
||||||
|
|
||||||
|
def request_params
|
||||||
|
super.merge(
|
||||||
|
ticket: resource,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
36
lib/sequencer/unit/import/kayako/case/priority_id.rb
Normal file
36
lib/sequencer/unit/import/kayako/case/priority_id.rb
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Case
|
||||||
|
class PriorityId < Sequencer::Unit::Common::Provider::Named
|
||||||
|
|
||||||
|
uses :resource
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def priority_id
|
||||||
|
::Ticket::Priority.select(:id).find_by(name: local).id
|
||||||
|
end
|
||||||
|
|
||||||
|
def local
|
||||||
|
mapping.fetch(resource['priority']&.fetch('level'), mapping[nil])
|
||||||
|
end
|
||||||
|
|
||||||
|
def mapping
|
||||||
|
{
|
||||||
|
1 => '1 low',
|
||||||
|
nil => '2 normal',
|
||||||
|
2 => '2 normal',
|
||||||
|
3 => '3 high',
|
||||||
|
4 => '3 high',
|
||||||
|
}.freeze
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
26
lib/sequencer/unit/import/kayako/case/skip/deleted.rb
Normal file
26
lib/sequencer/unit/import/kayako/case/skip/deleted.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Case
|
||||||
|
module Skip
|
||||||
|
class Deleted < Sequencer::Unit::Base
|
||||||
|
|
||||||
|
uses :resource
|
||||||
|
provides :action
|
||||||
|
|
||||||
|
def process
|
||||||
|
return if resource['state'] != 'TRASH'
|
||||||
|
|
||||||
|
logger.info { "Skipping. Kayako Case ID '#{resource['id']}' is in 'TRASH' state." }
|
||||||
|
state.provide(:action, :skipped)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
26
lib/sequencer/unit/import/kayako/case/skip/suspended.rb
Normal file
26
lib/sequencer/unit/import/kayako/case/skip/suspended.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Case
|
||||||
|
module Skip
|
||||||
|
class Suspended < Sequencer::Unit::Base
|
||||||
|
|
||||||
|
uses :resource
|
||||||
|
provides :action
|
||||||
|
|
||||||
|
def process
|
||||||
|
return if resource['state'] != 'SUSPENDED'
|
||||||
|
|
||||||
|
logger.info { "Skipping. Kayako Case ID '#{resource['id']}' is in 'SUSPENDED' state." }
|
||||||
|
state.provide(:action, :skipped)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
37
lib/sequencer/unit/import/kayako/case/state_id.rb
Normal file
37
lib/sequencer/unit/import/kayako/case/state_id.rb
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Case
|
||||||
|
class StateId < Sequencer::Unit::Common::Provider::Named
|
||||||
|
|
||||||
|
uses :resource
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def state_id
|
||||||
|
::Ticket::State.select(:id).find_by(name: local).id
|
||||||
|
end
|
||||||
|
|
||||||
|
def local
|
||||||
|
mapping.fetch(resource['status']['type'], 'open')
|
||||||
|
end
|
||||||
|
|
||||||
|
def mapping
|
||||||
|
{
|
||||||
|
'NEW' => 'new',
|
||||||
|
'OPEN' => 'open',
|
||||||
|
'PENDING' => 'pending reminder',
|
||||||
|
'COMPLETED' => 'closed',
|
||||||
|
'CLOSED' => 'closed',
|
||||||
|
'CUSTOM' => 'open',
|
||||||
|
}.freeze
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
22
lib/sequencer/unit/import/kayako/case/tags.rb
Normal file
22
lib/sequencer/unit/import/kayako/case/tags.rb
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Case
|
||||||
|
class Tags < Sequencer::Unit::Common::Model::Tags
|
||||||
|
|
||||||
|
uses :resource
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def tags
|
||||||
|
resource['tags']&.map { |tag| tag['name'] }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
23
lib/sequencer/unit/import/kayako/case/type.rb
Normal file
23
lib/sequencer/unit/import/kayako/case/type.rb
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Case
|
||||||
|
class Type < Sequencer::Unit::Common::Provider::Named
|
||||||
|
|
||||||
|
uses :resource
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def type
|
||||||
|
type = resource['type']&.fetch('type')
|
||||||
|
type&.capitalize
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
22
lib/sequencer/unit/import/kayako/case/updated_by_id.rb
Normal file
22
lib/sequencer/unit/import/kayako/case/updated_by_id.rb
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Case
|
||||||
|
class UpdatedById < Sequencer::Unit::Common::Provider::Named
|
||||||
|
|
||||||
|
uses :resource, :id_map, :created_by_id
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def updated_by_id
|
||||||
|
id_map['User'].fetch(resource['last_updated_by']&.fetch('id'), created_by_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
12
lib/sequencer/unit/import/kayako/case_fields.rb
Normal file
12
lib/sequencer/unit/import/kayako/case_fields.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class CaseFields < Sequencer::Unit::Import::Kayako::SubSequence::Field
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
12
lib/sequencer/unit/import/kayako/cases.rb
Normal file
12
lib/sequencer/unit/import/kayako/cases.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class Cases < Sequencer::Unit::Import::Kayako::SubSequence::Object
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
33
lib/sequencer/unit/import/kayako/common/article_sender_id.rb
Normal file
33
lib/sequencer/unit/import/kayako/common/article_sender_id.rb
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Common
|
||||||
|
class ArticleSenderId < Sequencer::Unit::Common::Provider::Named
|
||||||
|
|
||||||
|
uses :created_by_id
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def article_sender_id
|
||||||
|
return article_sender('Customer') if author.role?('Customer')
|
||||||
|
return article_sender('Agent') if author.role?('Agent')
|
||||||
|
|
||||||
|
article_sender('System')
|
||||||
|
end
|
||||||
|
|
||||||
|
def author
|
||||||
|
@author ||= ::User.find(created_by_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def article_sender(name)
|
||||||
|
::Ticket::Article::Sender.select(:id).find_by(name: name).id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,26 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Common
|
||||||
|
class ArticleSourceChannel < Sequencer::Unit::Common::Provider::Named
|
||||||
|
|
||||||
|
uses :resource, :id_map
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def article_source_channel
|
||||||
|
channel = resource['source_channel']&.fetch('type')
|
||||||
|
|
||||||
|
return if !channel
|
||||||
|
|
||||||
|
"Sequencer::Unit::Import::Kayako::Post::Channel::#{channel.capitalize}".constantize.new(resource)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
22
lib/sequencer/unit/import/kayako/common/created_by_id.rb
Normal file
22
lib/sequencer/unit/import/kayako/common/created_by_id.rb
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Common
|
||||||
|
class CreatedById < Sequencer::Unit::Common::Provider::Named
|
||||||
|
|
||||||
|
uses :resource, :id_map
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def created_by_id
|
||||||
|
id_map['User'].fetch(resource['creator']&.fetch('id'), 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
43
lib/sequencer/unit/import/kayako/default_language.rb
Normal file
43
lib/sequencer/unit/import/kayako/default_language.rb
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class DefaultLanguage < Sequencer::Unit::Base
|
||||||
|
include ::Sequencer::Unit::Import::Kayako::Requester
|
||||||
|
|
||||||
|
provides :default_language
|
||||||
|
|
||||||
|
def process
|
||||||
|
state.provide(:default_language, default_language)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def default_language
|
||||||
|
settings = fetch_settings
|
||||||
|
|
||||||
|
default_language_setting = settings.detect { |item| item['name'] == 'default_language' }
|
||||||
|
|
||||||
|
default_language_setting['value'] || 'en-us'
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch_settings
|
||||||
|
response = request(
|
||||||
|
api_path: 'settings'
|
||||||
|
)
|
||||||
|
|
||||||
|
body = JSON.parse(response.body)
|
||||||
|
body['data']
|
||||||
|
rescue => e
|
||||||
|
logger.error 'Error when fetching settings for default language'
|
||||||
|
logger.error e
|
||||||
|
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
16
lib/sequencer/unit/import/kayako/field_map.rb
Normal file
16
lib/sequencer/unit/import/kayako/field_map.rb
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class FieldMap < Sequencer::Unit::Common::Provider::Named
|
||||||
|
|
||||||
|
def field_map
|
||||||
|
{}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
16
lib/sequencer/unit/import/kayako/id_map.rb
Normal file
16
lib/sequencer/unit/import/kayako/id_map.rb
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class IdMap < Sequencer::Unit::Common::Provider::Named
|
||||||
|
|
||||||
|
def id_map
|
||||||
|
{}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
16
lib/sequencer/unit/import/kayako/import_settings_unset.rb
Normal file
16
lib/sequencer/unit/import/kayako/import_settings_unset.rb
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class ImportSettingsUnset < Sequencer::Unit::Base
|
||||||
|
def process
|
||||||
|
Setting.set('import_kayako_endpoint_username', nil)
|
||||||
|
Setting.set('import_kayako_endpoint_password', nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
24
lib/sequencer/unit/import/kayako/map_id.rb
Normal file
24
lib/sequencer/unit/import/kayako/map_id.rb
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class MapId < Sequencer::Unit::Base
|
||||||
|
prepend ::Sequencer::Unit::Import::Common::Model::Mixin::Skip::Action
|
||||||
|
|
||||||
|
optional :action
|
||||||
|
|
||||||
|
skip_action :skipped, :failed
|
||||||
|
|
||||||
|
uses :id_map, :model_class, :resource, :instance
|
||||||
|
|
||||||
|
def process
|
||||||
|
id_map[model_class.name] ||= {}
|
||||||
|
id_map[model_class.name][resource['id']] = instance.id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
48
lib/sequencer/unit/import/kayako/mapping/custom_fields.rb
Normal file
48
lib/sequencer/unit/import/kayako/mapping/custom_fields.rb
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Mapping
|
||||||
|
class CustomFields < Sequencer::Unit::Base
|
||||||
|
include ::Sequencer::Unit::Import::Common::Mapping::Mixin::ProvideMapped
|
||||||
|
|
||||||
|
uses :resource, :field_map, :model_class, :default_language
|
||||||
|
|
||||||
|
def process
|
||||||
|
provide_mapped do
|
||||||
|
custom_fields || {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def custom_fields
|
||||||
|
resource['custom_fields']&.each_with_object({}) do |item, result|
|
||||||
|
field = item['field']
|
||||||
|
local_name = custom_fields_map[field['key']]
|
||||||
|
|
||||||
|
next if local_name.nil? || item['value'].empty?
|
||||||
|
|
||||||
|
field_type_instance = attribute_type_instance(field)
|
||||||
|
|
||||||
|
result[ local_name.to_sym ] = field_type_instance.local_value(item['value'])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def custom_fields_map
|
||||||
|
@custom_fields_map ||= field_map[model_class.name]
|
||||||
|
end
|
||||||
|
|
||||||
|
def attribute_type_instance(field)
|
||||||
|
"Sequencer::Unit::Import::Kayako::ObjectAttribute::AttributeType::#{field['type'].capitalize}".constantize.new(field, default_language)
|
||||||
|
rescue
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
26
lib/sequencer/unit/import/kayako/mapping/timestamps.rb
Normal file
26
lib/sequencer/unit/import/kayako/mapping/timestamps.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Mapping
|
||||||
|
class Timestamps < Sequencer::Unit::Base
|
||||||
|
include ::Sequencer::Unit::Import::Common::Mapping::Mixin::ProvideMapped
|
||||||
|
|
||||||
|
uses :resource
|
||||||
|
|
||||||
|
def process
|
||||||
|
provide_mapped do
|
||||||
|
{
|
||||||
|
created_at: resource['created_at'],
|
||||||
|
updated_at: resource['updated_at'],
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
29
lib/sequencer/unit/import/kayako/model_class.rb
Normal file
29
lib/sequencer/unit/import/kayako/model_class.rb
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class ModelClass < Sequencer::Unit::Common::Provider::Named
|
||||||
|
|
||||||
|
uses :object
|
||||||
|
|
||||||
|
MAP = {
|
||||||
|
'Organization' => ::Organization,
|
||||||
|
'User' => ::User,
|
||||||
|
'Team' => ::Group,
|
||||||
|
'Case' => ::Ticket,
|
||||||
|
'Post' => ::Ticket::Article,
|
||||||
|
'TimeEntry' => ::Ticket::TimeAccounting,
|
||||||
|
}.freeze
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def model_class
|
||||||
|
MAP[object]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
23
lib/sequencer/unit/import/kayako/object_attribute/add.rb
Normal file
23
lib/sequencer/unit/import/kayako/object_attribute/add.rb
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module ObjectAttribute
|
||||||
|
class Add < Sequencer::Unit::Base
|
||||||
|
prepend ::Sequencer::Unit::Import::Common::Model::Mixin::Skip::Action
|
||||||
|
|
||||||
|
skip_any_action
|
||||||
|
|
||||||
|
uses :config
|
||||||
|
|
||||||
|
def process
|
||||||
|
ObjectManager::Attribute.add(config)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,91 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module ObjectAttribute
|
||||||
|
module AttributeType
|
||||||
|
class Base
|
||||||
|
attr_reader :attribute, :default_language
|
||||||
|
|
||||||
|
def initialize(attribute, default_language)
|
||||||
|
@attribute = attribute
|
||||||
|
@default_language = default_language
|
||||||
|
end
|
||||||
|
|
||||||
|
def config
|
||||||
|
{
|
||||||
|
display: attribute['title'],
|
||||||
|
data_type: data_type,
|
||||||
|
data_option: data_option,
|
||||||
|
editable: true,
|
||||||
|
active: attribute['is_enabled'],
|
||||||
|
screens: screens,
|
||||||
|
position: attribute['sort_order'],
|
||||||
|
created_by_id: 1,
|
||||||
|
updated_by_id: 1,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def local_value(value)
|
||||||
|
value
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def screens
|
||||||
|
default = {
|
||||||
|
view: {
|
||||||
|
'-all-' => {
|
||||||
|
shown: true,
|
||||||
|
null: true,
|
||||||
|
},
|
||||||
|
Customer: {
|
||||||
|
shown: attribute['is_visible_to_customers'],
|
||||||
|
null: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
edit: {
|
||||||
|
'-all-' => {
|
||||||
|
shown: true,
|
||||||
|
null: true,
|
||||||
|
},
|
||||||
|
Customer: {
|
||||||
|
shown: attribute['is_customer_editable'],
|
||||||
|
null: !attribute['is_required_for_customers'],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if attribute['is_required_for_agents']
|
||||||
|
default[:edit]['ticket.agent'] = {
|
||||||
|
shown: true,
|
||||||
|
required: true,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
default
|
||||||
|
end
|
||||||
|
|
||||||
|
def data_option
|
||||||
|
{
|
||||||
|
null: true,
|
||||||
|
note: '',
|
||||||
|
}.merge(data_type_specific_options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def data_type_specific_options
|
||||||
|
{}
|
||||||
|
end
|
||||||
|
|
||||||
|
def data_type
|
||||||
|
attribute['type'].downcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,64 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module ObjectAttribute
|
||||||
|
module AttributeType
|
||||||
|
class Cascadingselect < Sequencer::Unit::Import::Kayako::ObjectAttribute::AttributeType::Select
|
||||||
|
def local_value(value)
|
||||||
|
super.gsub('\\', '::')
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def data_type
|
||||||
|
'tree_select'
|
||||||
|
end
|
||||||
|
|
||||||
|
def options
|
||||||
|
result = []
|
||||||
|
|
||||||
|
attribute['options'].each do |item|
|
||||||
|
locale_item = item['values'].detect { |value| value['locale'] == default_language }
|
||||||
|
|
||||||
|
next if locale_item['translation'].nil?
|
||||||
|
|
||||||
|
transformed_tree_path = locale_item['translation'].gsub('\\', '::')
|
||||||
|
|
||||||
|
process_option(transformed_tree_path, result)
|
||||||
|
end
|
||||||
|
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
def process_option(tree_path, current_options, parent_tree_path = nil)
|
||||||
|
fragments = tree_path.split('::')
|
||||||
|
|
||||||
|
current_fragment = fragments.shift
|
||||||
|
|
||||||
|
current_tree_path = parent_tree_path.nil? ? current_fragment : "#{parent_tree_path}::#{current_fragment}"
|
||||||
|
|
||||||
|
current_option = current_options.detect { |option| option[:value] == current_tree_path }
|
||||||
|
|
||||||
|
remaining_tree_path = fragments.join('::')
|
||||||
|
|
||||||
|
if current_option.nil?
|
||||||
|
current_options.push({ name: current_fragment, value: current_tree_path })
|
||||||
|
|
||||||
|
current_option = current_options.last
|
||||||
|
end
|
||||||
|
|
||||||
|
return if remaining_tree_path.empty?
|
||||||
|
|
||||||
|
current_option[:children] ||= []
|
||||||
|
process_option(remaining_tree_path, current_option[:children], current_tree_path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,25 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module ObjectAttribute
|
||||||
|
module AttributeType
|
||||||
|
class Date < Sequencer::Unit::Import::Kayako::ObjectAttribute::AttributeType::Base
|
||||||
|
private
|
||||||
|
|
||||||
|
def data_type_specific_options
|
||||||
|
{
|
||||||
|
future: true,
|
||||||
|
past: true,
|
||||||
|
diff: 0,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,16 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module ObjectAttribute
|
||||||
|
module AttributeType
|
||||||
|
class Decimal < Sequencer::Unit::Import::Kayako::ObjectAttribute::AttributeType::Text
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,28 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module ObjectAttribute
|
||||||
|
module AttributeType
|
||||||
|
class Numeric < Sequencer::Unit::Import::Kayako::ObjectAttribute::AttributeType::Base
|
||||||
|
private
|
||||||
|
|
||||||
|
def data_type
|
||||||
|
'integer'
|
||||||
|
end
|
||||||
|
|
||||||
|
def data_type_specific_options
|
||||||
|
{
|
||||||
|
min: 0,
|
||||||
|
max: 999_999_999,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,16 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module ObjectAttribute
|
||||||
|
module AttributeType
|
||||||
|
class Radio < Sequencer::Unit::Import::Kayako::ObjectAttribute::AttributeType::Select
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module ObjectAttribute
|
||||||
|
module AttributeType
|
||||||
|
class Regex < Sequencer::Unit::Import::Kayako::ObjectAttribute::AttributeType::Text
|
||||||
|
private
|
||||||
|
|
||||||
|
def data_type_specific_options
|
||||||
|
super.merge(
|
||||||
|
regex: attribute['regular_expression'],
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,44 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module ObjectAttribute
|
||||||
|
module AttributeType
|
||||||
|
class Select < Sequencer::Unit::Import::Kayako::ObjectAttribute::AttributeType::Base
|
||||||
|
def local_value(value)
|
||||||
|
option_value = attribute['options'].detect { |option| option['id'] == value.to_i }
|
||||||
|
value_locale = option_value['values'].detect { |locale_item| locale_item['locale'] == default_language }
|
||||||
|
|
||||||
|
value_locale['translation']
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def data_type
|
||||||
|
'select'
|
||||||
|
end
|
||||||
|
|
||||||
|
def data_type_specific_options
|
||||||
|
{
|
||||||
|
default: '',
|
||||||
|
options: options,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def options
|
||||||
|
result = {}
|
||||||
|
attribute['options'].each do |item|
|
||||||
|
locale_item = item['values'].detect { |value| value['locale'] == default_language }
|
||||||
|
result[ locale_item['translation'] ] = locale_item['translation']
|
||||||
|
end
|
||||||
|
result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,28 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module ObjectAttribute
|
||||||
|
module AttributeType
|
||||||
|
class Text < Sequencer::Unit::Import::Kayako::ObjectAttribute::AttributeType::Base
|
||||||
|
private
|
||||||
|
|
||||||
|
def data_type
|
||||||
|
'input'
|
||||||
|
end
|
||||||
|
|
||||||
|
def data_type_specific_options
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
maxlength: 255,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,24 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module ObjectAttribute
|
||||||
|
module AttributeType
|
||||||
|
class Textarea < Sequencer::Unit::Import::Kayako::ObjectAttribute::AttributeType::Base
|
||||||
|
private
|
||||||
|
|
||||||
|
def data_type_specific_options
|
||||||
|
{
|
||||||
|
type: 'textarea',
|
||||||
|
maxlength: 255,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,26 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module ObjectAttribute
|
||||||
|
module AttributeType
|
||||||
|
class Type < Sequencer::Unit::Import::Kayako::ObjectAttribute::AttributeType::Select
|
||||||
|
private
|
||||||
|
|
||||||
|
def options
|
||||||
|
super.merge(
|
||||||
|
'Question' => 'Question',
|
||||||
|
'Task' => 'Task',
|
||||||
|
'Problem' => 'Problem',
|
||||||
|
'Incident' => 'Incident',
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,35 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module ObjectAttribute
|
||||||
|
module AttributeType
|
||||||
|
class Yesno < Sequencer::Unit::Import::Kayako::ObjectAttribute::AttributeType::Base
|
||||||
|
def local_value(value)
|
||||||
|
value == 'yes'
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def data_type
|
||||||
|
'boolean'
|
||||||
|
end
|
||||||
|
|
||||||
|
def data_type_specific_options
|
||||||
|
{
|
||||||
|
default: false,
|
||||||
|
options: {
|
||||||
|
true => 'yes',
|
||||||
|
false => 'no',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
41
lib/sequencer/unit/import/kayako/object_attribute/config.rb
Normal file
41
lib/sequencer/unit/import/kayako/object_attribute/config.rb
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module ObjectAttribute
|
||||||
|
class Config < Sequencer::Unit::Base
|
||||||
|
prepend ::Sequencer::Unit::Import::Common::Model::Mixin::Skip::Action
|
||||||
|
include ::Sequencer::Unit::Import::Common::Model::Mixin::HandleFailure
|
||||||
|
|
||||||
|
skip_any_action
|
||||||
|
|
||||||
|
uses :resource, :sanitized_name, :model_class, :default_language
|
||||||
|
provides :config
|
||||||
|
|
||||||
|
def process
|
||||||
|
attribute_config = attribute_type.config
|
||||||
|
|
||||||
|
state.provide(:config) do
|
||||||
|
{
|
||||||
|
object: model_class.to_s,
|
||||||
|
name: sanitized_name,
|
||||||
|
}.merge(attribute_config)
|
||||||
|
end
|
||||||
|
rescue => e
|
||||||
|
logger.error "The custom field type '#{resource['type']}' can not be mapped to an internal field."
|
||||||
|
handle_failure(e)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def attribute_type
|
||||||
|
"Sequencer::Unit::Import::Kayako::ObjectAttribute::AttributeType::#{resource['type'].capitalize}".constantize.new(resource, default_language)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,26 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module ObjectAttribute
|
||||||
|
class FieldMap < Sequencer::Unit::Base
|
||||||
|
prepend ::Sequencer::Unit::Import::Common::Model::Mixin::Skip::Action
|
||||||
|
|
||||||
|
skip_any_action
|
||||||
|
|
||||||
|
optional :action
|
||||||
|
|
||||||
|
uses :field_map, :model_class, :resource, :sanitized_name
|
||||||
|
|
||||||
|
def process
|
||||||
|
field_map[model_class.name] ||= {}
|
||||||
|
field_map[model_class.name][ resource['key'] ] = sanitized_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,21 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module ObjectAttribute
|
||||||
|
class MigrationExecute < Sequencer::Unit::Base
|
||||||
|
prepend ::Sequencer::Unit::Import::Common::Model::Mixin::Skip::Action
|
||||||
|
|
||||||
|
skip_any_action
|
||||||
|
|
||||||
|
def process
|
||||||
|
ObjectManager::Attribute.migration_execute(false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,25 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module ObjectAttribute
|
||||||
|
class SanitizedName < Sequencer::Unit::Import::Common::ObjectAttribute::SanitizedName
|
||||||
|
prepend ::Sequencer::Unit::Import::Common::Model::Mixin::Skip::Action
|
||||||
|
|
||||||
|
skip_any_action
|
||||||
|
|
||||||
|
uses :resource
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def unsanitized_name
|
||||||
|
resource['key']
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
33
lib/sequencer/unit/import/kayako/object_attribute/skip.rb
Normal file
33
lib/sequencer/unit/import/kayako/object_attribute/skip.rb
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module ObjectAttribute
|
||||||
|
class Skip < Sequencer::Unit::Base
|
||||||
|
|
||||||
|
uses :resource
|
||||||
|
provides :action
|
||||||
|
|
||||||
|
def process
|
||||||
|
return if (!resource['is_system'] && skip_attribute_types.exclude?(resource['type'])) || allowed_system_attributes.include?(resource['key'])
|
||||||
|
|
||||||
|
state.provide(:action, :skipped)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def skip_attribute_types
|
||||||
|
@skip_attribute_types ||= %w[FILE CHECKBOX]
|
||||||
|
end
|
||||||
|
|
||||||
|
def allowed_system_attributes
|
||||||
|
@allowed_system_attributes ||= %w[type]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
32
lib/sequencer/unit/import/kayako/object_count.rb
Normal file
32
lib/sequencer/unit/import/kayako/object_count.rb
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class ObjectCount < Sequencer::Unit::Common::Provider::Attribute
|
||||||
|
include ::Sequencer::Unit::Import::Common::Model::Statistics::Mixin::EmptyDiff
|
||||||
|
prepend ::Sequencer::Unit::Import::Common::Model::Mixin::Skip::Action
|
||||||
|
|
||||||
|
skip_action :skipped, :failed
|
||||||
|
|
||||||
|
uses :model_class, :resources
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def statistics_diff
|
||||||
|
{
|
||||||
|
model_key => empty_diff.merge!(
|
||||||
|
total: resources.count
|
||||||
|
)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def model_key
|
||||||
|
model_class.name.pluralize.to_sym
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
36
lib/sequencer/unit/import/kayako/organization/mapping.rb
Normal file
36
lib/sequencer/unit/import/kayako/organization/mapping.rb
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Organization
|
||||||
|
class Mapping < Sequencer::Unit::Base
|
||||||
|
include ::Sequencer::Unit::Import::Common::Mapping::Mixin::ProvideMapped
|
||||||
|
|
||||||
|
uses :resource
|
||||||
|
|
||||||
|
def process
|
||||||
|
provide_mapped do
|
||||||
|
{
|
||||||
|
name: resource['name'],
|
||||||
|
domain: domain,
|
||||||
|
domain_assignment: domain.present?,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def domain
|
||||||
|
@domain ||= begin
|
||||||
|
primary_domain = resource['domains']&.detect { |item| item['is_primary'] }
|
||||||
|
primary_domain&.fetch('domain')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
12
lib/sequencer/unit/import/kayako/organization_fields.rb
Normal file
12
lib/sequencer/unit/import/kayako/organization_fields.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class OrganizationFields < Sequencer::Unit::Import::Kayako::SubSequence::Field
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
12
lib/sequencer/unit/import/kayako/organizations.rb
Normal file
12
lib/sequencer/unit/import/kayako/organizations.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class Organizations < Sequencer::Unit::Import::Kayako::SubSequence::Object
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
33
lib/sequencer/unit/import/kayako/perform.rb
Normal file
33
lib/sequencer/unit/import/kayako/perform.rb
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class Perform < Sequencer::Unit::Base
|
||||||
|
prepend ::Sequencer::Unit::Import::Common::Model::Mixin::Skip::Action
|
||||||
|
|
||||||
|
skip_action :skipped, :failed
|
||||||
|
|
||||||
|
uses :resources, :object, :import_job, :dry_run, :field_map, :id_map, :default_language
|
||||||
|
optional :instance
|
||||||
|
|
||||||
|
def process
|
||||||
|
resources.each do |resource|
|
||||||
|
::Sequencer.process("Import::Kayako::#{object}",
|
||||||
|
parameters: {
|
||||||
|
import_job: import_job,
|
||||||
|
dry_run: dry_run,
|
||||||
|
resource: resource,
|
||||||
|
default_language: default_language,
|
||||||
|
field_map: field_map,
|
||||||
|
id_map: id_map,
|
||||||
|
instance: instance,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
71
lib/sequencer/unit/import/kayako/post/attachments.rb
Normal file
71
lib/sequencer/unit/import/kayako/post/attachments.rb
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Post
|
||||||
|
class Attachments < Sequencer::Unit::Base
|
||||||
|
include ::Sequencer::Unit::Import::Kayako::Requester
|
||||||
|
prepend ::Sequencer::Unit::Import::Common::Model::Mixin::Skip::Action
|
||||||
|
|
||||||
|
optional :action
|
||||||
|
|
||||||
|
skip_action :skipped, :failed
|
||||||
|
|
||||||
|
uses :resource, :instance, :model_class, :dry_run
|
||||||
|
|
||||||
|
def self.mutex
|
||||||
|
@mutex ||= Mutex.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def process
|
||||||
|
return if resource['attachments'].blank?
|
||||||
|
|
||||||
|
download_threads.each(&:join)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def download_threads
|
||||||
|
resource['attachments'].map do |attachment|
|
||||||
|
Thread.new do
|
||||||
|
sync(attachment)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def sync(attachment)
|
||||||
|
logger.debug { "Downloading attachment #{attachment}" }
|
||||||
|
|
||||||
|
response = request(
|
||||||
|
api_path: attachment['url_download'].gsub("#{Setting.get('import_kayako_endpoint')}/", ''),
|
||||||
|
)
|
||||||
|
|
||||||
|
return if dry_run
|
||||||
|
|
||||||
|
store_attachment(attachment, response)
|
||||||
|
rescue => e
|
||||||
|
logger.error(e)
|
||||||
|
end
|
||||||
|
|
||||||
|
def store_attachment(attachment, response)
|
||||||
|
self.class.mutex.synchronize do
|
||||||
|
::Store.add(
|
||||||
|
object: model_class.name,
|
||||||
|
o_id: instance.id,
|
||||||
|
data: response.body,
|
||||||
|
filename: attachment['name'],
|
||||||
|
preferences: {
|
||||||
|
'Content-Type' => attachment['type']
|
||||||
|
},
|
||||||
|
created_by_id: 1
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
60
lib/sequencer/unit/import/kayako/post/channel/base.rb
Normal file
60
lib/sequencer/unit/import/kayako/post/channel/base.rb
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Post
|
||||||
|
module Channel
|
||||||
|
class Base
|
||||||
|
attr_reader :resource
|
||||||
|
|
||||||
|
def initialize(resource)
|
||||||
|
@resource = resource
|
||||||
|
end
|
||||||
|
|
||||||
|
def mapping
|
||||||
|
{
|
||||||
|
message_id: resource['id'],
|
||||||
|
internal: internal?,
|
||||||
|
from: from,
|
||||||
|
type_id: article_type_id,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def article_type_id
|
||||||
|
return if article_type_name.nil?
|
||||||
|
|
||||||
|
::Ticket::Article::Type.select(:id).find_by(name: article_type_name).id
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def internal?
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def original_post
|
||||||
|
resource['original']
|
||||||
|
end
|
||||||
|
|
||||||
|
def article_type_name
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
|
||||||
|
def identify_key
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
|
||||||
|
def from
|
||||||
|
return if resource['identity'].nil?
|
||||||
|
|
||||||
|
resource['identity'][identify_key]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
42
lib/sequencer/unit/import/kayako/post/channel/facebook.rb
Normal file
42
lib/sequencer/unit/import/kayako/post/channel/facebook.rb
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Post
|
||||||
|
module Channel
|
||||||
|
class Facebook < Sequencer::Unit::Import::Kayako::Post::Channel::Base
|
||||||
|
def mapping
|
||||||
|
super.merge(
|
||||||
|
message_id: original_post['id'],
|
||||||
|
to: to,
|
||||||
|
body: original_post['contents'],
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def article_type_name
|
||||||
|
return 'facebook direct-message' if original_post['resource_type'] == 'facebook_message'
|
||||||
|
return 'facebook feed comment' if original_post['resource_type'] == 'facebook_post_comment'
|
||||||
|
|
||||||
|
'facebook feed post'
|
||||||
|
end
|
||||||
|
|
||||||
|
def identify_key
|
||||||
|
'facebook_id'
|
||||||
|
end
|
||||||
|
|
||||||
|
def to
|
||||||
|
return if original_post['recipient'].nil?
|
||||||
|
|
||||||
|
original_post['recipient'][identify_key]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
21
lib/sequencer/unit/import/kayako/post/channel/helpcenter.rb
Normal file
21
lib/sequencer/unit/import/kayako/post/channel/helpcenter.rb
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Post
|
||||||
|
module Channel
|
||||||
|
class Helpcenter < Sequencer::Unit::Import::Kayako::Post::Channel::Mail
|
||||||
|
private
|
||||||
|
|
||||||
|
def article_type_name
|
||||||
|
'web'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
65
lib/sequencer/unit/import/kayako/post/channel/mail.rb
Normal file
65
lib/sequencer/unit/import/kayako/post/channel/mail.rb
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Post
|
||||||
|
module Channel
|
||||||
|
class Mail < Sequencer::Unit::Import::Kayako::Post::Channel::Base
|
||||||
|
def mapping
|
||||||
|
super.merge(
|
||||||
|
to: to,
|
||||||
|
cc: cc,
|
||||||
|
body: original_post['body_html'] || original_post['body_text'] || '',
|
||||||
|
content_type: 'text/html',
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def article_type_name
|
||||||
|
'email'
|
||||||
|
end
|
||||||
|
|
||||||
|
def identify_key
|
||||||
|
'email'
|
||||||
|
end
|
||||||
|
|
||||||
|
def from
|
||||||
|
return super if resource['is_requester'] || original_post['mailbox'].blank?
|
||||||
|
|
||||||
|
original_post['mailbox']['address']
|
||||||
|
end
|
||||||
|
|
||||||
|
def to
|
||||||
|
recipients = build_recipients('TO')
|
||||||
|
|
||||||
|
# Add the mailbox address to the 'TO' field if it's a requester post.
|
||||||
|
if resource['is_requester'] && original_post['mailbox'].present?
|
||||||
|
recipients = "#{original_post['mailbox']['address']}#{", #{recipients}" if recipients.present?}"
|
||||||
|
end
|
||||||
|
|
||||||
|
recipients
|
||||||
|
end
|
||||||
|
|
||||||
|
def cc
|
||||||
|
build_recipients('CC')
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_recipients(field_type)
|
||||||
|
return if !original_post.key?('recipients') || original_post['recipients'].empty?
|
||||||
|
|
||||||
|
original_post['recipients'].filter_map do |recipient|
|
||||||
|
next if recipient['type'] != field_type
|
||||||
|
|
||||||
|
recipient[identify_key]
|
||||||
|
end.join(', ')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
21
lib/sequencer/unit/import/kayako/post/channel/messenger.rb
Normal file
21
lib/sequencer/unit/import/kayako/post/channel/messenger.rb
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Post
|
||||||
|
module Channel
|
||||||
|
class Messenger < Sequencer::Unit::Import::Kayako::Post::Channel::Mail
|
||||||
|
private
|
||||||
|
|
||||||
|
def article_type_name
|
||||||
|
'chat'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
36
lib/sequencer/unit/import/kayako/post/channel/note.rb
Normal file
36
lib/sequencer/unit/import/kayako/post/channel/note.rb
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Post
|
||||||
|
module Channel
|
||||||
|
class Note < Sequencer::Unit::Import::Kayako::Post::Channel::Base
|
||||||
|
def mapping
|
||||||
|
super.merge(
|
||||||
|
body: original_post['body_html'] || original_post['body_text'] || '',
|
||||||
|
content_type: 'text/html',
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def identify_key
|
||||||
|
'email'
|
||||||
|
end
|
||||||
|
|
||||||
|
def article_type_name
|
||||||
|
'note'
|
||||||
|
end
|
||||||
|
|
||||||
|
def internal?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
41
lib/sequencer/unit/import/kayako/post/channel/twitter.rb
Normal file
41
lib/sequencer/unit/import/kayako/post/channel/twitter.rb
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Post
|
||||||
|
module Channel
|
||||||
|
class Twitter < Sequencer::Unit::Import::Kayako::Post::Channel::Base
|
||||||
|
def mapping
|
||||||
|
super.merge(
|
||||||
|
message_id: original_post['id'],
|
||||||
|
to: to,
|
||||||
|
body: original_post['contents'],
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def article_type_name
|
||||||
|
return 'twitter direct-message' if original_post['resource_type'] == 'twitter_message'
|
||||||
|
|
||||||
|
'twitter status'
|
||||||
|
end
|
||||||
|
|
||||||
|
def identify_key
|
||||||
|
'screen_name'
|
||||||
|
end
|
||||||
|
|
||||||
|
def to
|
||||||
|
return if original_post['recipient'].nil?
|
||||||
|
|
||||||
|
original_post['recipient'][identify_key]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,24 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Post
|
||||||
|
class EmailAddressFields < Sequencer::Unit::Base
|
||||||
|
|
||||||
|
uses :resource, :id_map
|
||||||
|
provides :from, :to, :cc
|
||||||
|
|
||||||
|
def process
|
||||||
|
state.provide(:user_id) do
|
||||||
|
user_map.fetch(resource.author_id, 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
77
lib/sequencer/unit/import/kayako/post/inline_images.rb
Normal file
77
lib/sequencer/unit/import/kayako/post/inline_images.rb
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Post
|
||||||
|
class InlineImages < Sequencer::Unit::Base
|
||||||
|
include ::Sequencer::Unit::Import::Common::Mapping::Mixin::ProvideMapped
|
||||||
|
|
||||||
|
uses :mapped
|
||||||
|
|
||||||
|
def process
|
||||||
|
return if !contains_inline_image?(mapped[:body])
|
||||||
|
|
||||||
|
provide_mapped do
|
||||||
|
{
|
||||||
|
body: replaced_inline_images,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.inline_data(kayako_url)
|
||||||
|
@cache ||= {}
|
||||||
|
return @cache[kayako_url] if @cache[kayako_url]
|
||||||
|
|
||||||
|
image_data = download(kayako_url)
|
||||||
|
return if image_data.blank?
|
||||||
|
|
||||||
|
@cache[kayako_url] = "data:image/png;base64,#{Base64.strict_encode64(image_data)}"
|
||||||
|
@cache[kayako_url]
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.download(kayako_url)
|
||||||
|
logger.debug { "Downloading inline image from #{kayako_url}" }
|
||||||
|
|
||||||
|
response = UserAgent.get(
|
||||||
|
kayako_url,
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
open_timeout: 20,
|
||||||
|
read_timeout: 240,
|
||||||
|
verify_ssl: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
return response.body if response.success?
|
||||||
|
|
||||||
|
logger.error response.error
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def contains_inline_image?(string)
|
||||||
|
return false if string.blank?
|
||||||
|
|
||||||
|
string.include?('kayako.com/media/url')
|
||||||
|
end
|
||||||
|
|
||||||
|
def replaced_inline_images
|
||||||
|
body_html = Nokogiri::HTML(mapped[:body])
|
||||||
|
|
||||||
|
body_html.css('img').each do |node|
|
||||||
|
next if !contains_inline_image?(node['src'])
|
||||||
|
|
||||||
|
node.attributes['src'].value = self.class.inline_data(node['src'])
|
||||||
|
end
|
||||||
|
|
||||||
|
body_html.to_html
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
29
lib/sequencer/unit/import/kayako/post/mapping.rb
Normal file
29
lib/sequencer/unit/import/kayako/post/mapping.rb
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Post
|
||||||
|
class Mapping < Sequencer::Unit::Base
|
||||||
|
include ::Sequencer::Unit::Import::Common::Mapping::Mixin::ProvideMapped
|
||||||
|
|
||||||
|
uses :instance, :resource, :created_by_id, :article_sender_id, :article_source_channel
|
||||||
|
provides :mapped
|
||||||
|
|
||||||
|
def process
|
||||||
|
provide_mapped do
|
||||||
|
{
|
||||||
|
ticket_id: instance.id,
|
||||||
|
sender_id: article_sender_id,
|
||||||
|
created_by_id: created_by_id,
|
||||||
|
updated_by_id: created_by_id,
|
||||||
|
}.merge(article_source_channel.mapping)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
15
lib/sequencer/unit/import/kayako/post/unset_instance.rb
Normal file
15
lib/sequencer/unit/import/kayako/post/unset_instance.rb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Post
|
||||||
|
class UnsetInstance < Sequencer::Unit::Common::UnsetAttributes
|
||||||
|
uses :instance
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
40
lib/sequencer/unit/import/kayako/request.rb
Normal file
40
lib/sequencer/unit/import/kayako/request.rb
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class Request < Sequencer::Unit::Common::Provider::Attribute
|
||||||
|
extend ::Sequencer::Unit::Import::Kayako::Requester
|
||||||
|
|
||||||
|
uses :object, :request_params
|
||||||
|
provides :response
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def response
|
||||||
|
|
||||||
|
builder = backend.new(
|
||||||
|
object: object,
|
||||||
|
request_params: request_params
|
||||||
|
)
|
||||||
|
|
||||||
|
self.class.request(
|
||||||
|
api_path: builder.api_path,
|
||||||
|
params: builder.params,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def backend
|
||||||
|
request_class = "::Sequencer::Unit::Import::Kayako::Request::#{object}".safe_constantize
|
||||||
|
|
||||||
|
return request_class if request_class.present?
|
||||||
|
return ::Sequencer::Unit::Import::Kayako::Request::GenericField if object.include?('Field')
|
||||||
|
|
||||||
|
::Sequencer::Unit::Import::Kayako::Request::Generic
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
20
lib/sequencer/unit/import/kayako/request/case.rb
Normal file
20
lib/sequencer/unit/import/kayako/request/case.rb
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class Request < Sequencer::Unit::Common::Provider::Attribute
|
||||||
|
class Case < Sequencer::Unit::Import::Kayako::Request::Generic
|
||||||
|
def params
|
||||||
|
super.merge(
|
||||||
|
include: 'user,case_priority,case_status,channel,tag,case_type',
|
||||||
|
fields: '+tags',
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
30
lib/sequencer/unit/import/kayako/request/generic.rb
Normal file
30
lib/sequencer/unit/import/kayako/request/generic.rb
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class Request < Sequencer::Unit::Common::Provider::Attribute
|
||||||
|
class Generic
|
||||||
|
attr_reader :object, :request_params
|
||||||
|
|
||||||
|
def initialize(object:, request_params:)
|
||||||
|
@object = object
|
||||||
|
@request_params = request_params
|
||||||
|
end
|
||||||
|
|
||||||
|
def api_path
|
||||||
|
object.underscore.split('_').map(&:pluralize).join('/')
|
||||||
|
end
|
||||||
|
|
||||||
|
def params
|
||||||
|
request_params.merge(
|
||||||
|
limit: 100,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
19
lib/sequencer/unit/import/kayako/request/generic_field.rb
Normal file
19
lib/sequencer/unit/import/kayako/request/generic_field.rb
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class Request < Sequencer::Unit::Common::Provider::Attribute
|
||||||
|
class GenericField < Sequencer::Unit::Import::Kayako::Request::Generic
|
||||||
|
def params
|
||||||
|
super.merge(
|
||||||
|
include: 'field_option,locale_field',
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
19
lib/sequencer/unit/import/kayako/request/organization.rb
Normal file
19
lib/sequencer/unit/import/kayako/request/organization.rb
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class Request < Sequencer::Unit::Common::Provider::Attribute
|
||||||
|
class Organization < Sequencer::Unit::Import::Kayako::Request::Generic
|
||||||
|
def params
|
||||||
|
super.merge(
|
||||||
|
include: 'organization_field,field_option,locale_field,identity_domain',
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
30
lib/sequencer/unit/import/kayako/request/post.rb
Normal file
30
lib/sequencer/unit/import/kayako/request/post.rb
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class Request < Sequencer::Unit::Common::Provider::Attribute
|
||||||
|
class Post < Sequencer::Unit::Import::Kayako::Request::Generic
|
||||||
|
attr_reader :ticket
|
||||||
|
|
||||||
|
def initialize(...)
|
||||||
|
super
|
||||||
|
@ticket = request_params.delete(:ticket)
|
||||||
|
end
|
||||||
|
|
||||||
|
def api_path
|
||||||
|
"cases/#{ticket['id']}/posts"
|
||||||
|
end
|
||||||
|
|
||||||
|
def params
|
||||||
|
super.merge(
|
||||||
|
include: 'mailbox,message_recipient,channel,attachment,case_message,note,chat_message,identity_email,identity_twitter,identity_facebook,facebook_message,facebook_post,facebook_post_comment,twitter_message,twitter_tweet',
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
17
lib/sequencer/unit/import/kayako/request/time_entry.rb
Normal file
17
lib/sequencer/unit/import/kayako/request/time_entry.rb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class Request < Sequencer::Unit::Common::Provider::Attribute
|
||||||
|
class TimeEntry < Sequencer::Unit::Import::Kayako::Request::Generic
|
||||||
|
def api_path
|
||||||
|
'timetracking'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
19
lib/sequencer/unit/import/kayako/request/user.rb
Normal file
19
lib/sequencer/unit/import/kayako/request/user.rb
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class Request < Sequencer::Unit::Common::Provider::Attribute
|
||||||
|
class User < Sequencer::Unit::Import::Kayako::Request::Generic
|
||||||
|
def params
|
||||||
|
super.merge(
|
||||||
|
include: 'user_field,field_option,locale_field,identity_email,identify_phone,identity_twitter,identity_facebook,role',
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
86
lib/sequencer/unit/import/kayako/requester.rb
Normal file
86
lib/sequencer/unit/import/kayako/requester.rb
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module Requester
|
||||||
|
mattr_accessor :session_id
|
||||||
|
|
||||||
|
def request(api_path:, params: nil)
|
||||||
|
10.times do |iteration|
|
||||||
|
response = perform_request(
|
||||||
|
api_path: api_path,
|
||||||
|
params: params,
|
||||||
|
)
|
||||||
|
|
||||||
|
if response.is_a? Net::HTTPOK
|
||||||
|
refresh_session_id(response)
|
||||||
|
return response
|
||||||
|
end
|
||||||
|
|
||||||
|
handle_error response, iteration
|
||||||
|
rescue Net::HTTPClientError => e
|
||||||
|
handle_exception e, iteration
|
||||||
|
end
|
||||||
|
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_error(response, iteration)
|
||||||
|
reset_session_id if response.is_a? Net::HTTPUnauthorized
|
||||||
|
|
||||||
|
sleep_for = 10
|
||||||
|
case response
|
||||||
|
when Net::HTTPTooManyRequests
|
||||||
|
sleep_for = response.header['retry-after'].to_i + 10
|
||||||
|
logger.info "Rate limit: #{response.header.to_hash} (429 Too Many Requests). Sleeping #{sleep_for} seconds and retry (##{iteration + 1}/10)."
|
||||||
|
else
|
||||||
|
logger.info "Unknown response: #{response.inspect}. Sleeping 10 seconds and retry (##{iteration + 1}/10)."
|
||||||
|
end
|
||||||
|
sleep sleep_for
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_exception(e, iteration)
|
||||||
|
logger.error e
|
||||||
|
logger.info "Sleeping 10 seconds after #{e.class.name} and retry (##{iteration + 1}/10)."
|
||||||
|
sleep 10
|
||||||
|
end
|
||||||
|
|
||||||
|
def refresh_session_id(response)
|
||||||
|
return if response.header['content-type'] != 'application/json'
|
||||||
|
|
||||||
|
body = JSON.parse(response.body)
|
||||||
|
|
||||||
|
return if body['session_id'].blank?
|
||||||
|
|
||||||
|
self.session_id = body['session_id']
|
||||||
|
end
|
||||||
|
|
||||||
|
def reset_session_id
|
||||||
|
self.session_id = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def perform_request(api_path:, params: nil)
|
||||||
|
uri = URI("#{Setting.get('import_kayako_endpoint')}/#{api_path}")
|
||||||
|
uri.query = URI.encode_www_form(params) if params.present?
|
||||||
|
headers = {
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
'X-Session-ID' => session_id
|
||||||
|
}
|
||||||
|
|
||||||
|
Net::HTTP.start(uri.host, uri.port, use_ssl: true, read_timeout: 600) do |http|
|
||||||
|
# for those special moments...
|
||||||
|
# http.set_debug_output($stdout)
|
||||||
|
request = Net::HTTP::Get.new(uri, headers)
|
||||||
|
if session_id.blank?
|
||||||
|
request.basic_auth(Setting.get('import_kayako_endpoint_username'), Setting.get('import_kayako_endpoint_password'))
|
||||||
|
end
|
||||||
|
return http.request(request)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
26
lib/sequencer/unit/import/kayako/resources.rb
Normal file
26
lib/sequencer/unit/import/kayako/resources.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
class Resources < Sequencer::Unit::Common::Provider::Named
|
||||||
|
include ::Sequencer::Unit::Import::Common::Model::Mixin::HandleFailure
|
||||||
|
|
||||||
|
uses :response
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def resources
|
||||||
|
body = JSON.parse(response.body)
|
||||||
|
|
||||||
|
body['data']
|
||||||
|
rescue => e
|
||||||
|
logger.error "Won't be continued, because no response is available."
|
||||||
|
handle_failure(e)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
18
lib/sequencer/unit/import/kayako/sub_sequence/field.rb
Normal file
18
lib/sequencer/unit/import/kayako/sub_sequence/field.rb
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module SubSequence
|
||||||
|
class Field < Sequencer::Unit::Import::Kayako::SubSequence::Generic
|
||||||
|
|
||||||
|
def sequence_name
|
||||||
|
'Sequencer::Sequence::Import::Kayako::GenericField'.freeze
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
99
lib/sequencer/unit/import/kayako/sub_sequence/generic.rb
Normal file
99
lib/sequencer/unit/import/kayako/sub_sequence/generic.rb
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
|
class Sequencer
|
||||||
|
class Unit
|
||||||
|
module Import
|
||||||
|
module Kayako
|
||||||
|
module SubSequence
|
||||||
|
class Generic < Sequencer::Unit::Base
|
||||||
|
|
||||||
|
uses :dry_run, :import_job, :field_map, :id_map, :default_language
|
||||||
|
|
||||||
|
attr_accessor :iteration, :result
|
||||||
|
|
||||||
|
EXPECTING = %i[action response].freeze
|
||||||
|
|
||||||
|
def process
|
||||||
|
loop.each_with_index do |_, iteration|
|
||||||
|
@iteration = iteration
|
||||||
|
@result = ::Sequencer.process(sequence_name,
|
||||||
|
parameters: sequence_params,
|
||||||
|
expecting: self.class.const_get(:EXPECTING))
|
||||||
|
break if iteration_should_stop?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def sequence_params
|
||||||
|
{
|
||||||
|
request_params: request_params,
|
||||||
|
import_job: import_job,
|
||||||
|
dry_run: dry_run,
|
||||||
|
object: object,
|
||||||
|
default_language: default_language,
|
||||||
|
field_map: field_map,
|
||||||
|
id_map: id_map,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def request_params
|
||||||
|
return {} if iteration.zero?
|
||||||
|
|
||||||
|
if cursor_pagination?
|
||||||
|
return cursor_pagination
|
||||||
|
end
|
||||||
|
|
||||||
|
offset_pagination
|
||||||
|
end
|
||||||
|
|
||||||
|
def object
|
||||||
|
@object ||= self.class.name.demodulize.singularize
|
||||||
|
end
|
||||||
|
|
||||||
|
def sequence_name
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def offset_pagination
|
||||||
|
{
|
||||||
|
offset: offset,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def offset
|
||||||
|
iteration * 5 # TODO: only ddebug, normally 100
|
||||||
|
end
|
||||||
|
|
||||||
|
def cursor_pagination?
|
||||||
|
return if result.nil?
|
||||||
|
|
||||||
|
@cursor_pagination ||= result[:response].header['link'].include?('after_id')
|
||||||
|
end
|
||||||
|
|
||||||
|
def cursor_pagination
|
||||||
|
{
|
||||||
|
after_id: cursor_after_id
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def cursor_after_id
|
||||||
|
unescaped_header_next_link.match(%r{after_id=(\d+)})[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
def unescaped_header_next_link
|
||||||
|
CGI.unescape(CGI.unescape(result[:response].header['link']))
|
||||||
|
end
|
||||||
|
|
||||||
|
def iteration_should_stop?
|
||||||
|
return true if result[:action] == :failed
|
||||||
|
return true if result[:response].header['link'].blank? || result[:response].header['link'].exclude?('rel="next"')
|
||||||
|
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue