From b797fd6d306d7f1010b41ddbb2d70b3cd95b747d Mon Sep 17 00:00:00 2001 From: Thorsten Eckel Date: Tue, 13 Sep 2016 10:53:16 +0200 Subject: [PATCH 1/2] Added import of OTRS DynamicFields into Zammads ObjectManager attributes. --- lib/import/otrs.rb | 140 ++++++++++++++++++++++++++- test/integration/otrs_import_test.rb | 26 +++++ 2 files changed, 165 insertions(+), 1 deletion(-) diff --git a/lib/import/otrs.rb b/lib/import/otrs.rb index ba9c1157a..eaf1e7eb9 100644 --- a/lib/import/otrs.rb +++ b/lib/import/otrs.rb @@ -317,7 +317,7 @@ module Import::OTRS # dynamic fields dynamic_fields = load('DynamicField') - #settings(dynamic_fields, settings) + object_manager(dynamic_fields) # email accounts #accounts = load('PostMasterAccount') @@ -608,6 +608,19 @@ module Import::OTRS ticket_new[value] = record[key.to_s] } + record.keys.each { |key| + + key_string = key.to_s + + next if !key_string.start_with?('DynamicField_') + dynamic_field_name = key_string[13, key_string.length] + + next if skip_fields.include?( dynamic_field_name ) + dynamic_field_name = convert_df_name(dynamic_field_name) + + ticket_new[dynamic_field_name.to_sym] = record[key_string] + } + # find owner if ticket_new[:owner] user = User.find_by(login: ticket_new[:owner].downcase) @@ -1345,6 +1358,127 @@ module Import::OTRS } end + # dynamic fields + def self.object_manager(dynamic_fields) + + dynamic_fields.each { |dynamic_field| + + if dynamic_field['ObjectType'] != 'Ticket' + log "ERROR: Unsupported dynamic field object type '#{dynamic_field['ObjectType']}' for dynamic field '#{dynamic_field['Name']}'" + next + end + + next if skip_fields.include?( dynamic_field['Name'] ) + + internal_name = convert_df_name(dynamic_field['Name']) + + attribute = ObjectManager::Attribute.get( + object: dynamic_field['ObjectType'], + name: internal_name, + ) + next if !attribute.nil? + + object_manager_config = { + object: dynamic_field['ObjectType'], + name: internal_name, + display: dynamic_field['Label'], + screens: { + view: { + '-all-' => { + shown: true, + }, + }, + }, + active: true, + editable: dynamic_field['InternalField'] == '0', + position: dynamic_field['FieldOrder'], + created_by_id: 1, + updated_by_id: 1, + } + + if dynamic_field['FieldType'] == 'Text' + + object_manager_config[:data_type] = 'input' + object_manager_config[:data_option] = { + default: dynamic_field['Config']['DefaultValue'], + type: 'text', + maxlength: 255, + null: false, + } + elsif dynamic_field['FieldType'] == 'TextArea' + + object_manager_config[:data_type] = 'textarea' + object_manager_config[:data_option] = { + default: dynamic_field['Config']['DefaultValue'], + rows: dynamic_field['Config']['Rows'], + null: false, + } + elsif dynamic_field['FieldType'] == 'Checkbox' + + object_manager_config[:data_type] = 'boolean' + object_manager_config[:data_option] = { + default: dynamic_field['Config']['DefaultValue'] == '1', + options: { + true => 'Yes', + false => 'No', + }, + null: false, + translate: true, + } + elsif dynamic_field['FieldType'] == 'DateTime' + + object_manager_config[:data_type] = 'datetime' + object_manager_config[:data_option] = { + future: dynamic_field['Config']['YearsInFuture'] != '0', + past: dynamic_field['Config']['YearsInPast'] != '0', + diff: dynamic_field['Config']['DefaultValue'].to_i / 60 / 60, + null: false, + } + elsif dynamic_field['FieldType'] == 'Date' + + object_manager_config[:data_type] = 'date' + object_manager_config[:data_option] = { + future: dynamic_field['Config']['YearsInFuture'] != '0', + past: dynamic_field['Config']['YearsInPast'] != '0', + diff: dynamic_field['Config']['DefaultValue'].to_i / 60 / 60 / 24, + null: false, + } + elsif dynamic_field['FieldType'] == 'Dropdown' + + object_manager_config[:data_type] = 'select' + object_manager_config[:data_option] = { + default: '', + multiple: false, + options: dynamic_field['Config']['PossibleValues'], + null: dynamic_field['Config']['PossibleNone'] == '1', + translate: dynamic_field['Config']['TranslatableValues'] == '1', + } + elsif dynamic_field['FieldType'] == 'Multiselect' + + object_manager_config[:data_type] = 'select' + object_manager_config[:data_option] = { + default: '', + multiple: true, + options: dynamic_field['Config']['PossibleValues'], + null: dynamic_field['Config']['PossibleNone'] == '1', + translate: dynamic_field['Config']['TranslatableValues'] == '1', + } + else + log "ERROR: Unsupported dynamic field field type '#{dynamic_field['FieldType']}' for dynamic field '#{dynamic_field['Name']}'" + next + end + + ObjectManager::Attribute.add( object_manager_config ) + ObjectManager::Attribute.migration_execute(false) + } + + end + + def self.convert_df_name(dynamic_field_name) + new_name = dynamic_field_name.underscore + new_name.sub(/\_id(s)?\z/, "_no#{$1}") + end + # log def self.log(message) thread_no = Thread.current[:thread_no] || '-' @@ -1460,4 +1594,8 @@ module Import::OTRS true end + def self.skip_fields + %w(ProcessManagementProcessID ProcessManagementActivityID ZammadMigratorChanged ZammadMigratorChangedOld) + end + end diff --git a/test/integration/otrs_import_test.rb b/test/integration/otrs_import_test.rb index fe0eb33c3..2a6c2d93a 100644 --- a/test/integration/otrs_import_test.rb +++ b/test/integration/otrs_import_test.rb @@ -30,7 +30,21 @@ class OtrsImportTest < ActiveSupport::TestCase assert_equal( fqdn, Setting.get('fqdn'), 'fqdn' ) assert_equal( http, Setting.get('http_type'), 'http_type' ) assert_equal( 'Example Company', Setting.get('organization'), 'organization' ) + end + test 'check dynamic fields' do + local_objects = ObjectManager::Attribute.list_full + + assert_equal(75, local_objects.size, 'dynamic field count') + + object_attribute_names = local_objects.reject { |local_object| + local_object[:object] != 'Ticket' + }.collect { |local_object| + local_object['name'] + } + expected_object_attribute_names = %w(vertriebsweg te_test sugar_crm_remote_no sugar_crm_company_selected_no sugar_crm_company_selection combine itsm_criticality customer_id itsm_impact itsm_review_required itsm_decision_result itsm_repair_start_time itsm_recovery_start_time itsm_decision_date title itsm_due_date topic_no open_exchange_ticket_number hostname ticket_free_key11 type ticket_free_text11 open_exchange_tn topic zarafa_tn group_id scom_hostname checkbox_example scom_uuid scom_state scom_service location owner_id department customer_location state_id pending_time priority_id tags) + + assert_equal(expected_object_attribute_names, object_attribute_names, 'dynamic field names') end # check count of imported items @@ -205,6 +219,18 @@ class OtrsImportTest < ActiveSupport::TestCase assert_equal( Time.zone.parse('2014-11-21 00:17:40 +0000').gmtime.to_s, ticket.created_at.to_s ) assert_equal( Time.zone.parse('2014-11-21 00:21:08 +0000').gmtime.to_s, ticket.close_time.to_s ) + # ticket dynamic fields + ticket = Ticket.find(591) + assert_equal( 'Some other smart subject!', ticket.title ) + assert_equal( '488', ticket.vertriebsweg ) + assert_equal( '["193"]', ticket.te_test ) # TODO: multiselect + assert_equal( '358', ticket.sugar_crm_remote_no ) + assert_equal( '69', ticket.sugar_crm_company_selected_no ) + assert_equal( '["382"]', ticket.sugar_crm_company_selection ) # TODO: multiselect + assert_equal( '310', ticket.topic_no ) + assert_equal( '495', ticket.open_exchange_ticket_number ) + assert_equal( '208', ticket.hostname ) + # check history # - create entry # - state change entry From 4e81bcd90ee8690d6c9f75fb3a8716ceb6367356 Mon Sep 17 00:00:00 2001 From: Thorsten Eckel Date: Tue, 13 Sep 2016 11:39:08 +0200 Subject: [PATCH 2/2] Removed count check in favour of regular array diff. --- test/integration/otrs_import_test.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/integration/otrs_import_test.rb b/test/integration/otrs_import_test.rb index 2a6c2d93a..da1fa9ba5 100644 --- a/test/integration/otrs_import_test.rb +++ b/test/integration/otrs_import_test.rb @@ -35,8 +35,6 @@ class OtrsImportTest < ActiveSupport::TestCase test 'check dynamic fields' do local_objects = ObjectManager::Attribute.list_full - assert_equal(75, local_objects.size, 'dynamic field count') - object_attribute_names = local_objects.reject { |local_object| local_object[:object] != 'Ticket' }.collect { |local_object|