Merge branch 'develop' of git.znuny.com:zammad/zammad into develop
This commit is contained in:
commit
e497bd0105
17 changed files with 398 additions and 1 deletions
|
@ -42,7 +42,8 @@ function backup_db () {
|
||||||
if [ "${DB_ADAPTER}" == "mysql2" ]; then
|
if [ "${DB_ADAPTER}" == "mysql2" ]; then
|
||||||
mysqldump --opt --single-transaction -u${DB_USER} -p${DB_PASS} ${DB_NAME} | gzip > ${BACKUP_DIR}/${TIMESTAMP}_zammad_db.mysql.gz
|
mysqldump --opt --single-transaction -u${DB_USER} -p${DB_PASS} ${DB_NAME} | gzip > ${BACKUP_DIR}/${TIMESTAMP}_zammad_db.mysql.gz
|
||||||
elif [ "${DB_ADAPTER}" == "postgresql" ]; then
|
elif [ "${DB_ADAPTER}" == "postgresql" ]; then
|
||||||
su -c "pg_dump -c ${DB_NAME} | gzip > ${BACKUP_DIR}/${TIMESTAMP}_zammad_db.psql.gz" postgres
|
su -c "pg_dump -c ${DB_NAME} | gzip > /tmp/${TIMESTAMP}_zammad_db.psql.gz" postgres
|
||||||
|
mv /tmp/${TIMESTAMP}_zammad_db.psql.gz ${BACKUP_DIR}
|
||||||
else
|
else
|
||||||
echo "DB ADAPTER not found. if its sqlite backup is already saved in filebackup"
|
echo "DB ADAPTER not found. if its sqlite backup is already saved in filebackup"
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -9,6 +9,11 @@ module Import
|
||||||
diff
|
diff
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def diff?
|
||||||
|
return true if @diff
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def diff_import_possible?
|
def diff_import_possible?
|
||||||
|
@ -20,6 +25,8 @@ module Import
|
||||||
def diff
|
def diff
|
||||||
log 'Start diff...'
|
log 'Start diff...'
|
||||||
|
|
||||||
|
@diff = true
|
||||||
|
|
||||||
check_import_mode
|
check_import_mode
|
||||||
|
|
||||||
updateable_objects
|
updateable_objects
|
||||||
|
|
|
@ -2,6 +2,32 @@ module Import
|
||||||
module OTRS
|
module OTRS
|
||||||
module PriorityFactory
|
module PriorityFactory
|
||||||
extend Import::Factory
|
extend Import::Factory
|
||||||
|
|
||||||
|
# rubocop:disable Style/ModuleFunction
|
||||||
|
extend self
|
||||||
|
|
||||||
|
def import_loop(records, *_args, &import_block)
|
||||||
|
super
|
||||||
|
update_attribute_settings
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_attribute_settings
|
||||||
|
return if Import::OTRS.diff?
|
||||||
|
update_attribute
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_attribute
|
||||||
|
priority = ::Ticket::Priority.find_by(
|
||||||
|
name: Import::OTRS::SysConfigFactory.postmaster_default_lookup(:priority_default_create),
|
||||||
|
active: true
|
||||||
|
)
|
||||||
|
return if !priority
|
||||||
|
|
||||||
|
priority.default_create = true
|
||||||
|
priority.callback_loop = true
|
||||||
|
|
||||||
|
priority.save
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,6 +17,113 @@ module Import
|
||||||
state.save
|
state.save
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def import_loop(records, *_args, &import_block)
|
||||||
|
super
|
||||||
|
update_attribute_settings
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_attribute_settings
|
||||||
|
return if Import::OTRS.diff?
|
||||||
|
|
||||||
|
update_attribute
|
||||||
|
update_ticket_attributes
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_attribute
|
||||||
|
update_default_create
|
||||||
|
update_default_follow_up
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_default_create
|
||||||
|
state = ::Ticket::State.find_by(
|
||||||
|
name: Import::OTRS::SysConfigFactory.postmaster_default_lookup(:state_default_create),
|
||||||
|
active: true
|
||||||
|
)
|
||||||
|
return if !state
|
||||||
|
|
||||||
|
state.default_create = true
|
||||||
|
state.callback_loop = true
|
||||||
|
|
||||||
|
state.save
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_default_follow_up
|
||||||
|
state = ::Ticket::State.find_by(
|
||||||
|
name: Import::OTRS::SysConfigFactory.postmaster_default_lookup(:state_default_follow_up),
|
||||||
|
active: true
|
||||||
|
)
|
||||||
|
return if !state
|
||||||
|
|
||||||
|
state.default_follow_up = true
|
||||||
|
state.callback_loop = true
|
||||||
|
|
||||||
|
state.save
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_ticket_attributes
|
||||||
|
update_ticket_state
|
||||||
|
update_ticket_pending_time
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_ticket_state
|
||||||
|
agent_new = ::Ticket::State.where(
|
||||||
|
state_type_id: ::Ticket::StateType.where.not(name: %w(merged removed))
|
||||||
|
).pluck(:id)
|
||||||
|
|
||||||
|
agent_edit = ::Ticket::State.where(
|
||||||
|
state_type_id: ::Ticket::StateType.where.not(name: %w(new merged removed))
|
||||||
|
).pluck(:id)
|
||||||
|
|
||||||
|
customer_new = ::Ticket::State.where(
|
||||||
|
state_type_id: ::Ticket::StateType.where.not(name: %w(new closed))
|
||||||
|
).pluck(:id)
|
||||||
|
|
||||||
|
customer_edit = ::Ticket::State.where(
|
||||||
|
state_type_id: ::Ticket::StateType.where.not(name: %w(open closed))
|
||||||
|
).pluck(:id)
|
||||||
|
|
||||||
|
ticket_state_id = ::ObjectManager::Attribute.get(
|
||||||
|
object: 'Ticket',
|
||||||
|
name: 'state_id',
|
||||||
|
)
|
||||||
|
|
||||||
|
ticket_state_id[:data_option][:filter] = agent_new
|
||||||
|
ticket_state_id[:screens][:create_middle][:Customer] = customer_new
|
||||||
|
ticket_state_id[:screens][:edit][:Agent] = agent_edit
|
||||||
|
ticket_state_id[:screens][:edit][:Customer] = customer_edit
|
||||||
|
|
||||||
|
update_ticket_attribute(ticket_state_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_ticket_pending_time
|
||||||
|
pending_state_ids = ::Ticket::State.where(
|
||||||
|
state_type_id: ::Ticket::StateType.where(name: ['pending reminder', 'pending action'])
|
||||||
|
).pluck(:id)
|
||||||
|
|
||||||
|
ticket_pending_time = ::ObjectManager::Attribute.get(
|
||||||
|
object: 'Ticket',
|
||||||
|
name: 'pending_time',
|
||||||
|
)
|
||||||
|
|
||||||
|
ticket_pending_time[:data_option][:required_if][:state_id] = pending_state_ids
|
||||||
|
ticket_pending_time[:data_option][:required_if][:state_id] = pending_state_ids
|
||||||
|
|
||||||
|
update_ticket_attribute(ticket_pending_time)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_ticket_attribute(attribute)
|
||||||
|
::ObjectManager::Attribute.add(
|
||||||
|
object_lookup_id: attribute[:object_lookup_id],
|
||||||
|
name: attribute[:name],
|
||||||
|
display: attribute[:display],
|
||||||
|
data_type: attribute[:data_type],
|
||||||
|
data_option: attribute[:data_option],
|
||||||
|
active: attribute[:active],
|
||||||
|
screens: attribute[:screens],
|
||||||
|
force: true # otherwise _id as a name is not permitted
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,9 +9,15 @@ module Import
|
||||||
settings.each do |setting|
|
settings.each do |setting|
|
||||||
next if direct_copy?(setting)
|
next if direct_copy?(setting)
|
||||||
next if number_generator?(setting)
|
next if number_generator?(setting)
|
||||||
|
next if postmaster_default?(setting)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def postmaster_default_lookup(key)
|
||||||
|
@postmaster_defaults ||= {}
|
||||||
|
@postmaster_defaults[key]
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def direct_settings
|
def direct_settings
|
||||||
|
@ -46,6 +52,22 @@ module Import
|
||||||
|
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def postmaster_default?(setting)
|
||||||
|
|
||||||
|
relevant_configs = %w(PostmasterDefaultPriority PostmasterDefaultState PostmasterFollowUpState)
|
||||||
|
return false if !relevant_configs.include?(setting['Key'])
|
||||||
|
|
||||||
|
map = {
|
||||||
|
'PostmasterDefaultPriority' => :priority_default_create,
|
||||||
|
'PostmasterDefaultState' => :state_default_create,
|
||||||
|
'PostmasterFollowUpState' => :state_default_follow_up,
|
||||||
|
}
|
||||||
|
|
||||||
|
@postmaster_defaults ||= {}
|
||||||
|
@postmaster_defaults[ map[setting['Key']] ] = setting['Value']
|
||||||
|
true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
10
spec/fixtures/import/otrs/state/closed_successful.json
vendored
Normal file
10
spec/fixtures/import/otrs/state/closed_successful.json
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"ChangeTime": "2014-04-28 10:53:18",
|
||||||
|
"ID": "2",
|
||||||
|
"ValidID": "1",
|
||||||
|
"TypeID": "3",
|
||||||
|
"CreateTime": "2014-04-28 10:53:18",
|
||||||
|
"TypeName": "closed",
|
||||||
|
"Comment": "Ticket is closed successful.",
|
||||||
|
"Name": "closed successful"
|
||||||
|
}
|
10
spec/fixtures/import/otrs/state/closed_unsuccessful.json
vendored
Normal file
10
spec/fixtures/import/otrs/state/closed_unsuccessful.json
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"ChangeTime": "2014-04-28 10:53:18",
|
||||||
|
"ID": "3",
|
||||||
|
"ValidID": "1",
|
||||||
|
"TypeID": "3",
|
||||||
|
"CreateTime": "2014-04-28 10:53:18",
|
||||||
|
"TypeName": "closed",
|
||||||
|
"Comment": "Ticket is closed unsuccessful.",
|
||||||
|
"Name": "closed unsuccessful"
|
||||||
|
}
|
10
spec/fixtures/import/otrs/state/merged.json
vendored
Normal file
10
spec/fixtures/import/otrs/state/merged.json
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"ChangeTime": "2014-04-28 10:53:18",
|
||||||
|
"ID": "9",
|
||||||
|
"ValidID": "1",
|
||||||
|
"TypeID": "7",
|
||||||
|
"CreateTime": "2014-04-28 10:53:18",
|
||||||
|
"TypeName": "merged",
|
||||||
|
"Comment": "State for merged tickets.",
|
||||||
|
"Name": "merged"
|
||||||
|
}
|
10
spec/fixtures/import/otrs/state/new.json
vendored
Normal file
10
spec/fixtures/import/otrs/state/new.json
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"ChangeTime": "2014-04-28 10:53:18",
|
||||||
|
"ID": "1",
|
||||||
|
"ValidID": "1",
|
||||||
|
"TypeID": "1",
|
||||||
|
"CreateTime": "2014-04-28 10:53:18",
|
||||||
|
"TypeName": "new",
|
||||||
|
"Comment": "New ticket created by customer.",
|
||||||
|
"Name": "new"
|
||||||
|
}
|
10
spec/fixtures/import/otrs/state/open.json
vendored
Normal file
10
spec/fixtures/import/otrs/state/open.json
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"ChangeTime": "2014-04-28 10:53:18",
|
||||||
|
"ID": "4",
|
||||||
|
"ValidID": "1",
|
||||||
|
"TypeID": "2",
|
||||||
|
"CreateTime": "2014-04-28 10:53:18",
|
||||||
|
"TypeName": "open",
|
||||||
|
"Comment": "Open tickets.",
|
||||||
|
"Name": "open"
|
||||||
|
}
|
10
spec/fixtures/import/otrs/state/pending_auto_close_n.json
vendored
Normal file
10
spec/fixtures/import/otrs/state/pending_auto_close_n.json
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"ChangeTime": "2014-04-28 10:53:18",
|
||||||
|
"ID": "8",
|
||||||
|
"ValidID": "1",
|
||||||
|
"TypeID": "5",
|
||||||
|
"CreateTime": "2014-04-28 10:53:18",
|
||||||
|
"TypeName": "pending auto",
|
||||||
|
"Comment": "Ticket is pending for automatic close.",
|
||||||
|
"Name": "pending auto close-"
|
||||||
|
}
|
10
spec/fixtures/import/otrs/state/pending_auto_close_p.json
vendored
Normal file
10
spec/fixtures/import/otrs/state/pending_auto_close_p.json
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"ChangeTime": "2014-04-28 10:53:18",
|
||||||
|
"ID": "7",
|
||||||
|
"ValidID": "1",
|
||||||
|
"TypeID": "5",
|
||||||
|
"CreateTime": "2014-04-28 10:53:18",
|
||||||
|
"TypeName": "pending auto",
|
||||||
|
"Comment": "Ticket is pending for automatic close.",
|
||||||
|
"Name": "pending auto close+"
|
||||||
|
}
|
10
spec/fixtures/import/otrs/state/pending_reminder.json
vendored
Normal file
10
spec/fixtures/import/otrs/state/pending_reminder.json
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"ChangeTime": "2014-04-28 10:53:18",
|
||||||
|
"ID": "6",
|
||||||
|
"ValidID": "1",
|
||||||
|
"TypeID": "4",
|
||||||
|
"CreateTime": "2014-04-28 10:53:18",
|
||||||
|
"TypeName": "pending reminder",
|
||||||
|
"Comment": "Ticket is pending for agent reminder.",
|
||||||
|
"Name": "pending reminder"
|
||||||
|
}
|
10
spec/fixtures/import/otrs/state/removed.json
vendored
Normal file
10
spec/fixtures/import/otrs/state/removed.json
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"ChangeTime": "2014-04-28 10:53:18",
|
||||||
|
"ID": "5",
|
||||||
|
"ValidID": "1",
|
||||||
|
"TypeID": "6",
|
||||||
|
"CreateTime": "2014-04-28 10:53:18",
|
||||||
|
"TypeName": "removed",
|
||||||
|
"Comment": "Customer removed ticket.",
|
||||||
|
"Name": "removed"
|
||||||
|
}
|
|
@ -12,4 +12,32 @@ RSpec.describe Import::OTRS::PriorityFactory do
|
||||||
expect(::Import::OTRS::Priority).to receive(:new).with(import_data)
|
expect(::Import::OTRS::Priority).to receive(:new).with(import_data)
|
||||||
described_class.import([import_data])
|
described_class.import([import_data])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'sets default create Priority' do
|
||||||
|
priority = ::Ticket::Priority.first
|
||||||
|
priority.default_create = false
|
||||||
|
priority.callback_loop = true
|
||||||
|
priority.save
|
||||||
|
|
||||||
|
expect(Import::OTRS::SysConfigFactory).to receive(:postmaster_default_lookup).with(:priority_default_create).and_return(priority.name)
|
||||||
|
|
||||||
|
described_class.update_attribute_settings
|
||||||
|
priority.reload
|
||||||
|
|
||||||
|
expect(priority.default_create).to be true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't set default create Priority in diff import" do
|
||||||
|
priority = ::Ticket::Priority.first
|
||||||
|
priority.default_create = false
|
||||||
|
priority.callback_loop = true
|
||||||
|
priority.save
|
||||||
|
|
||||||
|
expect(Import::OTRS).to receive(:diff?).and_return(true)
|
||||||
|
|
||||||
|
described_class.update_attribute_settings
|
||||||
|
priority.reload
|
||||||
|
|
||||||
|
expect(priority.default_create).to be false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
require 'import/transaction_factory_examples'
|
require 'import/transaction_factory_examples'
|
||||||
|
|
||||||
|
RSpec::Matchers.define_negated_matcher :not_change, :change
|
||||||
|
|
||||||
RSpec.describe Import::OTRS::StateFactory do
|
RSpec.describe Import::OTRS::StateFactory do
|
||||||
it_behaves_like 'Import::TransactionFactory'
|
it_behaves_like 'Import::TransactionFactory'
|
||||||
|
|
||||||
|
@ -8,4 +10,102 @@ RSpec.describe Import::OTRS::StateFactory do
|
||||||
expect(described_class).to receive(:backup)
|
expect(described_class).to receive(:backup)
|
||||||
described_class.pre_import_hook([])
|
described_class.pre_import_hook([])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def load_state_json(file)
|
||||||
|
json_fixture("import/otrs/state/#{file}")
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'updates ObjectManager Ticket state_id and pending_time filter' do
|
||||||
|
|
||||||
|
states = %w(new open merged pending_reminder pending_auto_close_p pending_auto_close_n pending_auto_close_p closed_successful closed_unsuccessful closed_successful removed)
|
||||||
|
|
||||||
|
state_backend_param = []
|
||||||
|
states.each do |state|
|
||||||
|
state_backend_param.push(load_state_json(state))
|
||||||
|
end
|
||||||
|
|
||||||
|
ticket_state_id = ::ObjectManager::Attribute.get(
|
||||||
|
object: 'Ticket',
|
||||||
|
name: 'state_id',
|
||||||
|
)
|
||||||
|
ticket_pending_time = ::ObjectManager::Attribute.get(
|
||||||
|
object: 'Ticket',
|
||||||
|
name: 'pending_time',
|
||||||
|
)
|
||||||
|
|
||||||
|
expect {
|
||||||
|
described_class.import(state_backend_param)
|
||||||
|
|
||||||
|
# sync changes
|
||||||
|
ticket_state_id.reload
|
||||||
|
ticket_pending_time.reload
|
||||||
|
}.to change {
|
||||||
|
ticket_state_id.data_option
|
||||||
|
}.and change {
|
||||||
|
ticket_state_id.screens
|
||||||
|
}.and change {
|
||||||
|
ticket_pending_time.data_option
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't update ObjectManager Ticket state_id and pending_time filter in diff import" do
|
||||||
|
|
||||||
|
ticket_state_id = ::ObjectManager::Attribute.get(
|
||||||
|
object: 'Ticket',
|
||||||
|
name: 'state_id',
|
||||||
|
)
|
||||||
|
ticket_pending_time = ::ObjectManager::Attribute.get(
|
||||||
|
object: 'Ticket',
|
||||||
|
name: 'pending_time',
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(Import::OTRS).to receive(:diff?).and_return(true)
|
||||||
|
|
||||||
|
expect {
|
||||||
|
described_class.update_attribute_settings
|
||||||
|
|
||||||
|
# sync changes
|
||||||
|
ticket_state_id.reload
|
||||||
|
ticket_pending_time.reload
|
||||||
|
}.to not_change {
|
||||||
|
ticket_state_id.data_option
|
||||||
|
}.and not_change {
|
||||||
|
ticket_state_id.screens
|
||||||
|
}.and not_change {
|
||||||
|
ticket_pending_time.data_option
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets default create and update State' do
|
||||||
|
state = ::Ticket::State.first
|
||||||
|
state.default_create = false
|
||||||
|
state.default_follow_up = false
|
||||||
|
state.callback_loop = true
|
||||||
|
state.save
|
||||||
|
|
||||||
|
expect(Import::OTRS::SysConfigFactory).to receive(:postmaster_default_lookup).with(:state_default_create).and_return(state.name)
|
||||||
|
expect(Import::OTRS::SysConfigFactory).to receive(:postmaster_default_lookup).with(:state_default_follow_up).and_return(state.name)
|
||||||
|
|
||||||
|
described_class.update_attribute
|
||||||
|
state.reload
|
||||||
|
|
||||||
|
expect(state.default_create).to be true
|
||||||
|
expect(state.default_follow_up).to be true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't set default create and update State in diff import" do
|
||||||
|
state = ::Ticket::State.first
|
||||||
|
state.default_create = false
|
||||||
|
state.default_follow_up = false
|
||||||
|
state.callback_loop = true
|
||||||
|
state.save
|
||||||
|
|
||||||
|
expect(Import::OTRS).to receive(:diff?).and_return(true)
|
||||||
|
|
||||||
|
described_class.update_attribute_settings
|
||||||
|
state.reload
|
||||||
|
|
||||||
|
expect(state.default_create).to be false
|
||||||
|
expect(state.default_follow_up).to be false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,4 +3,20 @@ require 'import/import_factory_examples'
|
||||||
|
|
||||||
RSpec.describe Import::OTRS::SysConfigFactory do
|
RSpec.describe Import::OTRS::SysConfigFactory do
|
||||||
it_behaves_like 'Import factory'
|
it_behaves_like 'Import factory'
|
||||||
|
|
||||||
|
it 'stores default postmaster values' do
|
||||||
|
|
||||||
|
value = 'new'
|
||||||
|
|
||||||
|
settings = [
|
||||||
|
{
|
||||||
|
'Key' => 'PostmasterDefaultState',
|
||||||
|
'Value' => value
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
described_class.import(settings)
|
||||||
|
|
||||||
|
expect(described_class.postmaster_default_lookup(:state_default_create)).to eq(value)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue