diff --git a/app/models/channel/driver/smtp.rb b/app/models/channel/driver/smtp.rb
index 8a05decc5..23d6d5256 100644
--- a/app/models/channel/driver/smtp.rb
+++ b/app/models/channel/driver/smtp.rb
@@ -49,16 +49,21 @@ class Channel::Driver::Smtp
options[:openssl_verify_mode] = 'none'
end
mail = Channel::EmailBuild.build(attr, notification)
- mail.delivery_method :smtp, {
+ smtp_params = {
openssl_verify_mode: options[:openssl_verify_mode],
address: options[:host],
port: options[:port],
domain: options[:domain],
- user_name: options[:user],
- password: options[:password],
enable_starttls_auto: options[:enable_starttls_auto],
- authentication: options[:authentication],
}
+
+ # add authentication only if needed
+ if options[:user] && !options[:user].empty?
+ smtp_params[:user_name] = options[:user]
+ smtp_params[:password] = options[:password]
+ smtp_params[:authentication] = options[:authentication]
+ end
+ mail.delivery_method :smtp, smtp_params
mail.deliver
end
end
diff --git a/app/models/channel/email_parser.rb b/app/models/channel/email_parser.rb
index 7f80d5ede..571f64645 100644
--- a/app/models/channel/email_parser.rb
+++ b/app/models/channel/email_parser.rb
@@ -394,6 +394,7 @@ returns
p 'ERROR: ' + e.inspect # rubocop:disable Rails/Output
Rails.logger.error message
Rails.logger.error 'ERROR: ' + e.inspect
+ Rails.logger.error 'ERROR: ' + e.backtrace.inspect
File.open(filename, 'wb') { |file|
file.write msg
}
diff --git a/app/models/channel/filter/auto_response_check.rb b/app/models/channel/filter/auto_response_check.rb
index 51baadb69..c6481beca 100644
--- a/app/models/channel/filter/auto_response_check.rb
+++ b/app/models/channel/filter/auto_response_check.rb
@@ -15,7 +15,7 @@ module Channel::Filter::AutoResponseCheck
mail[ 'x-zammad-article-preferences'.to_sym ]['is-auto-response'] = true
return if mail[ 'x-loop'.to_sym ] && mail[ 'x-loop'.to_sym ] =~ /(yes|true)/i
- return if mail[ 'precedence'.to_sym ] && mail[ 'precedence'.to_sym ] =~ /bulk/i
+ return if mail[ 'precedence'.to_sym ] && mail[ 'precedence'.to_sym ] =~ /(bulk|list|junk)/i
return if mail[ 'auto-submitted'.to_sym ] && mail[ 'auto-submitted'.to_sym ] =~ /auto-(generated|replied)/i
return if mail[ 'x-auto-response-suppress'.to_sym ] && mail[ 'x-auto-response-suppress'.to_sym ] =~ /all/i
diff --git a/app/models/observer/transaction.rb b/app/models/observer/transaction.rb
index 385263676..e62b7e788 100644
--- a/app/models/observer/transaction.rb
+++ b/app/models/observer/transaction.rb
@@ -29,6 +29,7 @@ class Observer::Transaction < ActiveRecord::Observer
sync_backends = []
Setting.where(area: 'Transaction::Backend::Sync').order(:name).each { |setting|
backend = Setting.get(setting.name)
+ next if params[:disable] && params[:disable].include?(backend)
sync_backends.push Kernel.const_get(backend)
}
diff --git a/app/models/ticket.rb b/app/models/ticket.rb
index 220935ae2..5ad23f19c 100644
--- a/app/models/ticket.rb
+++ b/app/models/ticket.rb
@@ -844,6 +844,22 @@ result
references
end
+=begin
+
+get all articles of a ticket in correct order (overwrite active record default method)
+
+ artilces = ticket.articles
+
+result
+
+ [article1, articl2]
+
+=end
+
+ def articles
+ Ticket::Article.where(ticket_id: id).order(:created_at, :id)
+ end
+
private
def check_generate
diff --git a/app/models/ticket/number.rb b/app/models/ticket/number.rb
index 4dcbba8b6..6617da1b0 100644
--- a/app/models/ticket/number.rb
+++ b/app/models/ticket/number.rb
@@ -20,7 +20,7 @@ returns
# generate number
49_999.times {
number = adapter.generate
- ticket = Ticket.find_by( number: number )
+ ticket = Ticket.find_by(number: number)
return number if !ticket
}
raise "Can't generate new ticket number!"
diff --git a/app/models/ticket/number/date.rb b/app/models/ticket/number/date.rb
index a8cddca8c..609488532 100644
--- a/app/models/ticket/number/date.rb
+++ b/app/models/ticket/number/date.rb
@@ -43,6 +43,14 @@ module Ticket::Number::Date
# vehikel number. The modulus to 10 of this sum is substracted from
# 10. See: http://www.pruefziffernberechnung.de/F/Fahrzeugnummer.shtml
# (german)
+
+ # fix for https://github.com/zammad/zammad/issues/413 - can be removed later
+ if config.class == FalseClass || config.class == TrueClass
+ config = {
+ checksum: config
+ }
+ end
+
if config[:checksum]
chksum = 0
mult = 1
diff --git a/app/models/ticket/overviews.rb b/app/models/ticket/overviews.rb
index 7ce24fc3c..05f502deb 100644
--- a/app/models/ticket/overviews.rb
+++ b/app/models/ticket/overviews.rb
@@ -90,13 +90,36 @@ returns
# get only tickets with permissions
access_condition = Ticket.access_condition(user)
+ ticket_attributes = Ticket.new.attributes
list = []
overviews.each { |overview|
query_condition, bind_condition, tables = Ticket.selector2sql(overview.condition, user)
- order_by = "#{overview.order[:by]} #{overview.order[:direction]}"
+ # validate direction
+ raise "Invalid order direction '#{overview.order[:direction]}'" if overview.order[:direction] && overview.order[:direction] !~ /^(ASC|DESC)$/i
+
+ # check if order by exists
+ order_by = overview.order[:by]
+ if !ticket_attributes.key?(order_by)
+ order_by = if ticket_attributes.key?("#{order_by}_id")
+ "#{order_by}_id"
+ else
+ 'created_at'
+ end
+ end
+ order_by = "tickets.#{order_by} #{overview.order[:direction]}"
+
+ # check if group by exists
if overview.group_by && !overview.group_by.empty?
- order_by = "#{overview.group_by}_id, #{order_by}"
+ group_by = overview.group_by
+ if !ticket_attributes.key?(group_by)
+ group_by = if ticket_attributes.key?("#{group_by}_id")
+ "#{group_by}_id"
+ end
+ end
+ if group_by
+ order_by = "tickets.#{group_by}, #{order_by}"
+ end
end
ticket_result = Ticket.select('id, updated_at')
@@ -115,9 +138,10 @@ returns
}
tickets.push ticket_item
}
- count = Ticket.where(access_condition).where(query_condition, *bind_condition).count()
+ count = Ticket.where(access_condition).where(query_condition, *bind_condition).joins(tables).count()
item = {
overview: {
+ name: overview.name,
id: overview.id,
view: overview.link,
updated_at: overview.updated_at,
diff --git a/app/models/transaction.rb b/app/models/transaction.rb
index 23e1641d1..25b94fa55 100644
--- a/app/models/transaction.rb
+++ b/app/models/transaction.rb
@@ -13,7 +13,10 @@ class Transaction
if options[:interface_handle]
ApplicationHandleInfo.current = original_interface_handle
end
- Observer::Transaction.commit(disable_notification: options[:disable_notification])
+ Observer::Transaction.commit(
+ disable_notification: options[:disable_notification],
+ disable: options[:disable],
+ )
PushMessages.finish
end
end
diff --git a/app/models/transaction/background_job.rb b/app/models/transaction/background_job.rb
index e8a71ef2b..57a649b1a 100644
--- a/app/models/transaction/background_job.rb
+++ b/app/models/transaction/background_job.rb
@@ -24,7 +24,9 @@ class Transaction::BackgroundJob
def perform
Setting.where(area: 'Transaction::Backend::Async').order(:name).each { |setting|
- backend = Kernel.const_get(Setting.get(setting.name))
+ backend = Setting.get(setting.name)
+ next if @params[:disable] && @params[:disable].include?(backend)
+ backend = Kernel.const_get(backend)
Observer::Transaction.execute_singel_backend(backend, @item, @params)
}
end
diff --git a/app/models/transaction/trigger.rb b/app/models/transaction/trigger.rb
index 90fff8c26..7b2b6ad5d 100644
--- a/app/models/transaction/trigger.rb
+++ b/app/models/transaction/trigger.rb
@@ -29,7 +29,7 @@ class Transaction::Trigger
return if @item[:object] != 'Ticket'
- triggers = Trigger.where(active: true)
+ triggers = Trigger.where(active: true).order('LOWER(name)')
return if triggers.empty?
ticket = Ticket.lookup(id: @item[:object_id])
@@ -39,86 +39,94 @@ class Transaction::Trigger
end
original_user_id = UserInfo.current_user_id
- UserInfo.current_user_id = 1
- triggers.each { |trigger|
- condition = trigger.condition
+ Transaction.execute(reset_user_id: true, disable: ['Transaction::Trigger']) do
+ triggers.each { |trigger|
+ condition = trigger.condition
- # check action
- if condition['ticket.action']
- next if condition['ticket.action']['operator'] == 'is' && condition['ticket.action']['value'] != @item[:type]
- next if condition['ticket.action']['operator'] != 'is' && condition['ticket.action']['value'] == @item[:type]
- condition.delete('ticket.action')
- end
-
- # check "has changed" options
- has_changed_condition_exists = false
- has_changed = false
- condition.each do |key, value|
- next if !value
- next if !value['operator']
- next if !value['operator']['has changed']
- has_changed_condition_exists = true
-
- # next if has changed? && !@item[:changes][attribute]
- (object_name, attribute) = key.split('.', 2)
-
- # remove condition item, because it has changed
- if @item[:changes][attribute]
- has_changed = true
- condition.delete(key)
- next
+ # check action
+ if condition['ticket.action']
+ next if condition['ticket.action']['operator'] == 'is' && condition['ticket.action']['value'] != @item[:type]
+ next if condition['ticket.action']['operator'] != 'is' && condition['ticket.action']['value'] == @item[:type]
+ condition.delete('ticket.action')
end
- break
- end
- next if has_changed_condition_exists && !has_changed
+ # check action
+ if condition['article.action']
+ next if !article
+ condition.delete('article.action')
+ end
- # check if selector is matching
- condition['ticket.id'] = {
- operator: 'is',
- value: ticket.id,
- }
- if article
- condition['article.id'] = {
- operator: 'is',
- value: article.id,
- }
- end
+ # check "has changed" options
+ has_changed_condition_exists = false
+ has_changed = false
+ condition.each do |key, value|
+ next if !value
+ next if !value['operator']
+ next if !value['operator']['has changed']
+ has_changed_condition_exists = true
- ticket_count, tickets = Ticket.selectors(condition, 1)
- next if ticket_count.zero?
- next if tickets.first.id != ticket.id
+ # next if has changed? && !@item[:changes][attribute]
+ (object_name, attribute) = key.split('.', 2)
- # check if min one article attribute is used
- article_selector = false
- trigger.condition.each do |key, _value|
- (object_name, attribute) = key.split('.', 2)
- next if object_name != 'article'
- next if attribute == 'id'
- article_selector = true
- end
-
- # check in min one attribute has changed
- if @item[:type] == 'update' && !article_selector
- match = false
- if has_changed_condition_exists && has_changed
- match = true
- else
- trigger.condition.each do |key, _value|
- (object_name, attribute) = key.split('.', 2)
- next if object_name != 'ticket'
- next if !@item[:changes][attribute]
- match = true
- break
+ # remove condition item, because it has changed
+ if @item[:changes][attribute]
+ has_changed = true
+ condition.delete(key)
+ next
end
+ break
end
- next if !match
- end
- Transaction.execute do
+
+ next if has_changed_condition_exists && !has_changed
+
+ # check if selector is matching
+ condition['ticket.id'] = {
+ operator: 'is',
+ value: ticket.id,
+ }
+
+ # check if min one article attribute is used
+ article_selector = false
+ trigger.condition.each do |key, _value|
+ (object_name, attribute) = key.split('.', 2)
+ next if object_name != 'article'
+ next if attribute == 'id'
+ article_selector = true
+ end
+
+ next if article_selector && !article
+ if article_selector
+ condition['article.id'] = {
+ operator: 'is',
+ value: article.id,
+ }
+ end
+
+ ticket_count, tickets = Ticket.selectors(condition, 1)
+ next if ticket_count.zero?
+ next if tickets.first.id != ticket.id
+
+ # check in min one attribute has changed
+ if @item[:type] == 'update' && !article_selector
+ match = false
+ if has_changed_condition_exists && has_changed
+ match = true
+ else
+ trigger.condition.each do |key, _value|
+ (object_name, attribute) = key.split('.', 2)
+ next if object_name != 'ticket'
+ next if !@item[:changes][attribute]
+ match = true
+ break
+ end
+ end
+ next if !match
+ end
+
ticket.perform_changes(trigger.perform, 'trigger', @item)
- end
- }
+ }
+ end
UserInfo.current_user_id = original_user_id
end
diff --git a/contrib/apache2/zammad.conf b/contrib/apache2/zammad.conf
index 7926d1fa9..4226b7166 100644
--- a/contrib/apache2/zammad.conf
+++ b/contrib/apache2/zammad.conf
@@ -4,7 +4,7 @@
# replace 'localhost' with your fqdn if you want to use zammad from remote
- ServerName localhost
+ ServerName ubuntu.local
## don't loose time with IP address lookups
HostnameLookups Off
@@ -18,9 +18,8 @@
ProxyRequests Off
ProxyPreserveHost On
-
- Order deny,allow
- Allow from localhost
+
+ Require local
ProxyPass /assets !
@@ -38,8 +37,7 @@
Options FollowSymLinks
- Order allow,deny
- Allow from all
+ Require all granted
diff --git a/db/migrate/20120101000001_create_base.rb b/db/migrate/20120101000001_create_base.rb
index 9acd58459..125a59af3 100644
--- a/db/migrate/20120101000001_create_base.rb
+++ b/db/migrate/20120101000001_create_base.rb
@@ -577,7 +577,7 @@ class CreateBase < ActiveRecord::Migration
t.string :key, limit: 250, null: true
t.integer :related_o_id, null: true
t.integer :related_stats_store_object_id, null: true
- t.string :data, limit: 2500, null: true
+ t.string :data, limit: 5000, null: true
t.integer :created_by_id, null: false
t.timestamps limit: 3, null: false
end
diff --git a/db/migrate/20120101000010_create_ticket.rb b/db/migrate/20120101000010_create_ticket.rb
index 04aee9bbe..ad4578604 100644
--- a/db/migrate/20120101000010_create_ticket.rb
+++ b/db/migrate/20120101000010_create_ticket.rb
@@ -186,18 +186,18 @@ class CreateTicket < ActiveRecord::Migration
add_index :ticket_counters, [:generator], unique: true
create_table :overviews do |t|
- t.references :role, null: false
- t.column :name, :string, limit: 250, null: false
- t.column :link, :string, limit: 250, null: false
- t.column :prio, :integer, null: false
- t.column :condition, :string, limit: 2500, null: false
- t.column :order, :string, limit: 2500, null: false
- t.column :group_by, :string, limit: 250, null: true
- t.column :organization_shared, :boolean, null: false, default: false
- t.column :view, :string, limit: 1000, null: false
- t.column :active, :boolean, null: false, default: true
- t.column :updated_by_id, :integer, null: false
- t.column :created_by_id, :integer, null: false
+ t.references :role, null: false
+ t.column :name, :string, limit: 250, null: false
+ t.column :link, :string, limit: 250, null: false
+ t.column :prio, :integer, null: false
+ t.column :condition, :text, limit: 500.kilobytes + 1, null: false
+ t.column :order, :string, limit: 2500, null: false
+ t.column :group_by, :string, limit: 250, null: true
+ t.column :organization_shared, :boolean, null: false, default: false
+ t.column :view, :string, limit: 1000, null: false
+ t.column :active, :boolean, null: false, default: true
+ t.column :updated_by_id, :integer, null: false
+ t.column :created_by_id, :integer, null: false
t.timestamps limit: 3, null: false
end
add_index :overviews, [:name]
@@ -217,34 +217,34 @@ class CreateTicket < ActiveRecord::Migration
add_index :overviews_groups, [:group_id]
create_table :triggers do |t|
- t.column :name, :string, limit: 250, null: false
- t.column :condition, :string, limit: 2500, null: false
- t.column :perform, :string, limit: 2500, null: false
- t.column :disable_notification, :boolean, null: false, default: true
- t.column :note, :string, limit: 250, null: true
- t.column :active, :boolean, null: false, default: true
- t.column :updated_by_id, :integer, null: false
- t.column :created_by_id, :integer, null: false
+ t.column :name, :string, limit: 250, null: false
+ t.column :condition, :text, limit: 500.kilobytes + 1, null: false
+ t.column :perform, :text, limit: 500.kilobytes + 1, null: false
+ t.column :disable_notification, :boolean, null: false, default: true
+ t.column :note, :string, limit: 250, null: true
+ t.column :active, :boolean, null: false, default: true
+ t.column :updated_by_id, :integer, null: false
+ t.column :created_by_id, :integer, null: false
t.timestamps limit: 3, null: false
end
add_index :triggers, [:name], unique: true
create_table :jobs do |t|
- t.column :name, :string, limit: 250, null: false
- t.column :timeplan, :string, limit: 1000, null: false
- t.column :condition, :string, limit: 2500, null: false
- t.column :perform, :string, limit: 2500, null: false
- t.column :disable_notification, :boolean, null: false, default: true
- t.column :last_run_at, :timestamp, limit: 3, null: true
- t.column :next_run_at, :timestamp, limit: 3, null: true
- t.column :running, :boolean, null: false, default: false
- t.column :processed, :integer, null: false, default: 0
- t.column :matching, :integer, null: false
- t.column :pid, :string, limit: 250, null: true
- t.column :note, :string, limit: 250, null: true
- t.column :active, :boolean, null: false, default: false
- t.column :updated_by_id, :integer, null: false
- t.column :created_by_id, :integer, null: false
+ t.column :name, :string, limit: 250, null: false
+ t.column :timeplan, :string, limit: 2500, null: false
+ t.column :condition, :text, limit: 500.kilobytes + 1, null: false
+ t.column :perform, :text, limit: 500.kilobytes + 1, null: false
+ t.column :disable_notification, :boolean, null: false, default: true
+ t.column :last_run_at, :timestamp, limit: 3, null: true
+ t.column :next_run_at, :timestamp, limit: 3, null: true
+ t.column :running, :boolean, null: false, default: false
+ t.column :processed, :integer, null: false, default: 0
+ t.column :matching, :integer, null: false
+ t.column :pid, :string, limit: 250, null: true
+ t.column :note, :string, limit: 250, null: true
+ t.column :active, :boolean, null: false, default: false
+ t.column :updated_by_id, :integer, null: false
+ t.column :created_by_id, :integer, null: false
t.timestamps limit: 3, null: false
end
add_index :jobs, [:name], unique: true
@@ -285,14 +285,14 @@ class CreateTicket < ActiveRecord::Migration
add_index :links, [:link_object_source_id, :link_object_source_value, :link_object_target_id, :link_object_target_value, :link_type_id], unique: true, name: 'links_uniq_total'
create_table :postmaster_filters do |t|
- t.column :name, :string, limit: 250, null: false
- t.column :channel, :string, limit: 250, null: false
- t.column :match, :string, limit: 5000, null: false
- t.column :perform, :string, limit: 5000, null: false
- t.column :active, :boolean, null: false, default: true
- t.column :note, :string, limit: 250, null: true
- t.column :updated_by_id, :integer, null: false
- t.column :created_by_id, :integer, null: false
+ t.column :name, :string, limit: 250, null: false
+ t.column :channel, :string, limit: 250, null: false
+ t.column :match, :text, limit: 500.kilobytes + 1, null: false
+ t.column :perform, :text, limit: 500.kilobytes + 1, null: false
+ t.column :active, :boolean, null: false, default: true
+ t.column :note, :string, limit: 250, null: true
+ t.column :updated_by_id, :integer, null: false
+ t.column :created_by_id, :integer, null: false
t.timestamps limit: 3, null: false
end
add_index :postmaster_filters, [:channel]
@@ -359,7 +359,7 @@ class CreateTicket < ActiveRecord::Migration
t.column :first_response_time, :integer, null: true
t.column :update_time, :integer, null: true
t.column :solution_time, :integer, null: true
- t.column :condition, :string, limit: 5000, null: true
+ t.column :condition, :text, limit: 500.kilobytes + 1, null: true
t.column :updated_by_id, :integer, null: false
t.column :created_by_id, :integer, null: false
t.timestamps limit: 3, null: false
@@ -367,12 +367,12 @@ class CreateTicket < ActiveRecord::Migration
add_index :slas, [:name], unique: true
create_table :macros do |t|
- t.string :name, limit: 250, null: true
- t.string :perform, limit: 5000, null: false
- t.boolean :active, null: false, default: true
- t.string :note, limit: 250, null: true
- t.integer :updated_by_id, null: false
- t.integer :created_by_id, null: false
+ t.string :name, limit: 250, null: true
+ t.text :perform, limit: 500.kilobytes + 1, null: false
+ t.boolean :active, null: false, default: true
+ t.string :note, limit: 250, null: true
+ t.integer :updated_by_id, null: false
+ t.integer :created_by_id, null: false
t.timestamps limit: 3, null: false
end
add_index :macros, [:name], unique: true
@@ -436,11 +436,11 @@ class CreateTicket < ActiveRecord::Migration
add_index :chat_agents, [:created_by_id], unique: true
create_table :report_profiles do |t|
- t.column :name, :string, limit: 150, null: true
- t.column :condition, :string, limit: 6000, null: true
- t.column :active, :boolean, null: false, default: true
- t.column :updated_by_id, :integer, null: false
- t.column :created_by_id, :integer, null: false
+ t.column :name, :string, limit: 150, null: true
+ t.column :condition, :text, limit: 500.kilobytes + 1, null: true
+ t.column :active, :boolean, null: false, default: true
+ t.column :updated_by_id, :integer, null: false
+ t.column :created_by_id, :integer, null: false
t.timestamps limit: 3, null: false
end
add_index :report_profiles, [:name], unique: true
diff --git a/db/migrate/20161117000001_job_unable_to_create_issue_432.rb b/db/migrate/20161117000001_job_unable_to_create_issue_432.rb
new file mode 100644
index 000000000..db88c4348
--- /dev/null
+++ b/db/migrate/20161117000001_job_unable_to_create_issue_432.rb
@@ -0,0 +1,44 @@
+class JobUnableToCreateIssue432 < ActiveRecord::Migration
+ def up
+ # return if it's a new setup
+ return if !Setting.find_by(name: 'system_init_done')
+
+ ActiveRecord::Migration.change_table :jobs do |t|
+ t.change :timeplan, :string, limit: 2500
+ t.change :condition, :text, limit: 500.kilobytes + 1
+ t.change :perform, :text, limit: 500.kilobytes + 1
+ end
+
+ ActiveRecord::Migration.change_table :triggers do |t|
+ t.change :condition, :text, limit: 500.kilobytes + 1
+ t.change :perform, :text, limit: 500.kilobytes + 1
+ end
+
+ ActiveRecord::Migration.change_table :overviews do |t|
+ t.change :condition, :text, limit: 500.kilobytes + 1
+ end
+
+ ActiveRecord::Migration.change_table :report_profiles do |t|
+ t.change :condition, :text, limit: 500.kilobytes + 1
+ end
+ ActiveRecord::Migration.change_table :slas do |t|
+ t.change :condition, :text, limit: 500.kilobytes + 1
+ end
+
+ ActiveRecord::Migration.change_table :macros do |t|
+ t.change :perform, :text, limit: 500.kilobytes + 1
+ end
+
+ ActiveRecord::Migration.change_table :postmaster_filters do |t|
+ t.change :match, :text, limit: 500.kilobytes + 1
+ t.change :perform, :text, limit: 500.kilobytes + 1
+ end
+
+ ActiveRecord::Migration.change_table :stats_stores do |t|
+ t.change :data, :string, limit: 5000
+ end
+
+ Cache.clear
+
+ end
+end
diff --git a/db/migrate/20161117000002_ticket_number_generator_issue_427.rb b/db/migrate/20161117000002_ticket_number_generator_issue_427.rb
new file mode 100644
index 000000000..a0617ce04
--- /dev/null
+++ b/db/migrate/20161117000002_ticket_number_generator_issue_427.rb
@@ -0,0 +1,55 @@
+class TicketNumberGeneratorIssue427 < ActiveRecord::Migration
+ def up
+ # return if it's a new setup
+ return if !Setting.find_by(name: 'system_init_done')
+
+ setting = Setting.find_by(name: 'ticket_number')
+ setting.preferences = {
+ settings_included: %w(ticket_number_increment ticket_number_date),
+ controller: 'SettingsAreaTicketNumber',
+ permission: ['admin.ticket'],
+ }
+ setting.save!
+ setting = Setting.find_by(name: 'ticket_number_increment')
+ setting.preferences = {
+ permission: ['admin.ticket'],
+ hidden: true,
+ }
+ setting.save!
+ setting = Setting.find_by(name: 'ticket_number_date')
+ setting.preferences = {
+ permission: ['admin.ticket'],
+ hidden: true,
+ }
+
+ # just to make sure that value is saved correctly - https://github.com/zammad/zammad/issues/413
+ if setting.state_current['value'] == true || setting.state_current['value'] == false
+ setting.state_current['value'] = { 'checksum' => setting.state_current['value'] }
+ end
+ setting.save!
+
+ setting = Setting.find_by(name: 'ticket_hook_position')
+ setting.preferences = {
+ controller: 'SettingsAreaTicketHookPosition',
+ permission: ['admin.ticket'],
+ }
+ setting.options = {
+ form: [
+ {
+ display: '',
+ null: true,
+ name: 'ticket_hook_position',
+ tag: 'select',
+ translate: true,
+ options: {
+ 'left' => 'left',
+ 'right' => 'right',
+ 'none' => 'none',
+ },
+ },
+ ],
+ }
+ setting.save!
+
+ end
+end
diff --git a/db/migrate/20161117000003_store_config_name_update_issue_428.rb b/db/migrate/20161117000003_store_config_name_update_issue_428.rb
new file mode 100644
index 000000000..a8146c853
--- /dev/null
+++ b/db/migrate/20161117000003_store_config_name_update_issue_428.rb
@@ -0,0 +1,30 @@
+class StoreConfigNameUpdateIssue428 < ActiveRecord::Migration
+ def up
+ # return if it's a new setup
+ return if !Setting.find_by(name: 'system_init_done')
+ setting = Setting.find_by(name: 'storage')
+ return if !Setting
+ setting.name = 'storage_provider'
+ setting.options = {
+ form: [
+ {
+ display: '',
+ null: true,
+ name: 'storage_provider',
+ tag: 'select',
+ tranlate: true,
+ options: {
+ 'DB' => 'Database',
+ 'File' => 'Filesystem',
+ },
+ },
+ ],
+ }
+ setting.preferences = {
+ controller: 'SettingsAreaStorageProvider',
+ online_service_disable: true,
+ permission: ['admin.system'],
+ }
+ setting.save!
+ end
+end
diff --git a/db/seeds.rb b/db/seeds.rb
index 52b61445c..b584368de 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -259,7 +259,7 @@ Setting.create_if_not_exists(
Setting.create_if_not_exists(
title: 'Storage Mechanism',
- name: 'storage',
+ name: 'storage_provider',
area: 'System::Storage',
description: '"Database" stores all attachments in the database (not recommended for storing large amounts of data). "Filesystem" stores the data on the filesystem. You can switch between the modules even on a system that is already in production without any loss of data.',
options: {
@@ -267,17 +267,19 @@ Setting.create_if_not_exists(
{
display: '',
null: true,
- name: 'storage',
+ name: 'storage_provider',
tag: 'select',
+ tranlate: true,
options: {
'DB' => 'Database',
- 'FS' => 'Filesystem',
+ 'File' => 'Filesystem',
},
},
],
},
state: 'DB',
preferences: {
+ controller: 'SettingsAreaStorageProvider',
online_service_disable: true,
permission: ['admin.system'],
},
@@ -1137,10 +1139,10 @@ Setting.create_if_not_exists(
title: 'Ticket Hook Position',
name: 'ticket_hook_position',
area: 'Ticket::Base',
- description: "@T('The format of the subject.')
-* @T('**Right** means **Some Subject [Ticket#12345]**')
-* @T('**Left** means **[Ticket#12345] Some Subject**')
-* @T('**None** means **Some Subject** (without ticket number). In the last case you should enable *postmaster_follow_up_search_in* to recognize followups based on email headers and/or body.')",
+ description: "The format of the subject.
+* **Right** means **Some Subject [Ticket#12345]**
+* **Left** means **[Ticket#12345] Some Subject**
+* **None** means **Some Subject** (without ticket number). In the last case you should enable *postmaster_follow_up_search_in* to recognize followups based on email headers and/or body.",
options: {
form: [
{
@@ -1148,6 +1150,7 @@ Setting.create_if_not_exists(
null: true,
name: 'ticket_hook_position',
tag: 'select',
+ translate: true,
options: {
'left' => 'left',
'right' => 'right',
@@ -1158,6 +1161,7 @@ Setting.create_if_not_exists(
},
state: 'right',
preferences: {
+ controller: 'SettingsAreaTicketHookPosition',
permission: ['admin.ticket'],
},
frontend: false
@@ -1166,11 +1170,9 @@ Setting.create_if_not_exists(
title: 'Ticket Number Format',
name: 'ticket_number',
area: 'Ticket::Number',
- description: "@T('Selects the ticket number generator module.')
-* @T('**Increment** increments the ticket number, the SystemID and the counter are used with SystemID.Counter format (e.g. 1010138, 1010139).')
-* @T('With **Date** the ticket numbers will be generated by the current date, the SystemID and the counter. The format looks like Year.Month.Day.SystemID.counter (e.g. 201206231010138, 201206231010139).')
-
-@T('With param 'Checksum => true' the counter will be appended as checksum to the string. The format looks like SystemID.Counter.CheckSum (e. g. 10101384, 10101392) or Year.Month.Day.SystemID.Counter.CheckSum (e.g. 2012070110101520, 2012070110101535).')",
+ description: "Selects the ticket number generator module.
+* **Increment** increments the ticket number, the SystemID and the counter are used with SystemID.Counter format (e.g. 1010138, 1010139).
+* With **Date** the ticket numbers will be generated by the current date, the SystemID and the counter. The format looks like Year.Month.Day.SystemID.counter (e.g. 201206231010138, 201206231010139).",
options: {
form: [
{
@@ -1178,6 +1180,7 @@ Setting.create_if_not_exists(
null: true,
name: 'ticket_number',
tag: 'select',
+ translate: true,
options: {
'Ticket::Number::Increment' => 'Increment (SystemID.Counter)',
'Ticket::Number::Date' => 'Date (Year.Month.Day.SystemID.Counter)',
@@ -1187,6 +1190,8 @@ Setting.create_if_not_exists(
},
state: 'Ticket::Number::Increment',
preferences: {
+ settings_included: %w(ticket_number_increment ticket_number_date),
+ controller: 'SettingsAreaTicketNumber',
permission: ['admin.ticket'],
},
frontend: false
@@ -1244,6 +1249,7 @@ Setting.create_if_not_exists(
},
preferences: {
permission: ['admin.ticket'],
+ hidden: true,
},
frontend: false
)
@@ -1267,10 +1273,11 @@ Setting.create_if_not_exists(
],
},
state: {
- checksum: false,
+ checksum: false
},
preferences: {
permission: ['admin.ticket'],
+ hidden: true,
},
frontend: false
)
diff --git a/lib/import/otrs.rb b/lib/import/otrs.rb
index 0bc0fd7f2..eb5a6971e 100644
--- a/lib/import/otrs.rb
+++ b/lib/import/otrs.rb
@@ -632,13 +632,20 @@ module Import::OTRS
ticket_new.delete(:owner)
end
+ record['Articles'].each { |article|
+ # utf8 encode
+ _utf8_encode(article)
+ # lookup customers to create first
+ _article_based_customers(article)
+ }
+
# find customer
if ticket_new[:customer]
user = User.lookup(login: ticket_new[:customer].downcase)
ticket_new[:customer_id] = if user
user.id
else
- 1
+ _first_customer_id(record['Articles'])
end
ticket_new.delete(:customer)
else
@@ -664,16 +671,6 @@ module Import::OTRS
end
end
- # utf8 encode
- record['Articles'].each { |article|
- _utf8_encode(article)
- }
-
- # lookup customers to create first
- record['Articles'].each { |article|
- _article_based_customers(article)
- }
-
record['Articles'].each do |article|
retries = 3
@@ -1598,4 +1595,16 @@ module Import::OTRS
%w(ProcessManagementProcessID ProcessManagementActivityID ZammadMigratorChanged ZammadMigratorChangedOld)
end
+ def self._first_customer_id(articles)
+ user_id = 1
+ articles.each { |article|
+ next if article['sender'] != 'customer'
+ next if article['from'].empty?
+
+ user_id = article['created_by_id'].to_i
+ break
+ }
+
+ user_id
+ end
end
diff --git a/lib/search_index_backend.rb b/lib/search_index_backend.rb
index 321d81f38..819db77ce 100644
--- a/lib/search_index_backend.rb
+++ b/lib/search_index_backend.rb
@@ -339,8 +339,6 @@ get count of tickets and tickets which match on selector
end
def self.selector2query(selector, _current_user, aggs_interval, limit)
- filter_must = []
- filter_must_not = []
query_must = []
query_must_not = []
if selector && !selector.empty?
@@ -355,9 +353,9 @@ get count of tickets and tickets which match on selector
t[:term][key_tmp] = data['value']
end
if data['operator'] == 'is'
- filter_must.push t
+ query_must.push t
elsif data['operator'] == 'is not'
- filter_must_not.push t
+ query_must_not.push t
elsif data['operator'] == 'contains'
query_must.push t
elsif data['operator'] == 'contains not'
@@ -391,43 +389,18 @@ get count of tickets and tickets which match on selector
from: aggs_interval[:from],
to: aggs_interval[:to],
}
- filter_must.push r
+ query_must.push r
end
- if !query_must.empty? || !query_must_not.empty?
- if !data[:query][:filtered]
- data[:query][:filtered] = {}
- end
- if !data[:query][:filtered][:query]
- data[:query][:filtered][:query] = {}
- end
- if !data[:query][:filtered][:query][:bool]
- data[:query][:filtered][:query][:bool] = {}
- end
+ if !data[:query][:bool]
+ data[:query][:bool] = {}
end
+
if !query_must.empty?
- data[:query][:filtered][:query][:bool][:must] = query_must
+ data[:query][:bool][:must] = query_must
end
if !query_must_not.empty?
- data[:query][:filtered][:query][:bool][:must_not] = query_must_not
- end
-
- if !filter_must.empty? || !filter_must.empty?
- if !data[:query][:filtered]
- data[:query][:filtered] = {}
- end
- if !data[:query][:filtered][:filter]
- data[:query][:filtered][:filter] = {}
- end
- if !data[:query][:filtered][:filter][:bool]
- data[:query][:filtered][:filter][:bool] = {}
- end
- end
- if !filter_must.empty?
- data[:query][:filtered][:filter][:bool][:must] = filter_must
- end
- if !filter_must_not.empty?
- data[:query][:filtered][:filter][:bool][:must_not] = filter_must_not
+ data[:query][:bool][:must_not] = query_must_not
end
# add sort
diff --git a/public/assets/tests/form.js b/public/assets/tests/form.js
index 2343a2ccc..e2971e153 100644
--- a/public/assets/tests/form.js
+++ b/public/assets/tests/form.js
@@ -715,13 +715,14 @@ test("form postmaster filter", function() {
},
},
set: {
- 'x-zammad-ticket-customer': {
- value: 'customer'
+ 'x-zammad-ticket-customer_id': {
+ value: 'customer',
+ value_completion: ''
},
'x-zammad-ticket-group_id': {
value: '1'
},
- 'x-zammad-ticket-owner': {
+ 'x-zammad-ticket-owner_id': {
value: 'owner',
value_completion: ''
},
@@ -757,13 +758,14 @@ test("form postmaster filter", function() {
}
},
set: {
- 'x-zammad-ticket-customer': {
- value: 'customer'
+ 'x-zammad-ticket-customer_id': {
+ value: 'customer',
+ value_completion: ''
},
'x-zammad-ticket-group_id': {
value: '1'
},
- 'x-zammad-ticket-owner': {
+ 'x-zammad-ticket-owner_id': {
value: 'owner',
value_completion: ''
},
@@ -774,7 +776,7 @@ test("form postmaster filter", function() {
};
deepEqual(params, test_params, 'form param check')
el.find('[name="set::x-zammad-ticket-priority_id::value"]').closest('.js-filterElement').find('.js-remove').click()
- el.find('[name="set::x-zammad-ticket-customer::value"]').closest('.js-filterElement').find('.js-remove').click()
+ el.find('[name="set::x-zammad-ticket-customer_id::value"]').closest('.js-filterElement').find('.js-remove').click()
App.Delay.set(function() {
test("form param check after remove click", function() {
params = App.ControllerForm.params(el)
@@ -792,7 +794,7 @@ test("form postmaster filter", function() {
}
},
set: {
- 'x-zammad-ticket-owner': {
+ 'x-zammad-ticket-owner_id': {
value: 'owner',
value_completion: ''
},
diff --git a/test/unit/ticket_overview_test.rb b/test/unit/ticket_overview_test.rb
index a31a5076d..44476dd4b 100644
--- a/test/unit/ticket_overview_test.rb
+++ b/test/unit/ticket_overview_test.rb
@@ -8,6 +8,14 @@ class TicketOverviewTest < ActiveSupport::TestCase
customer1 = nil
customer2 = nil
customer3 = nil
+ overview1 = nil
+ overview2 = nil
+ overview3 = nil
+ overview4 = nil
+ overview5 = nil
+ overview6 = nil
+ overview7 = nil
+ overview8 = nil
test 'aaa - setup' do
# create base
@@ -93,7 +101,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
Overview.destroy_all
UserInfo.current_user_id = 1
overview_role = Role.find_by(name: 'Agent')
- Overview.create_or_update(
+ overview1 = Overview.create_or_update(
name: 'My assigned Tickets',
link: 'my_assigned',
prio: 1000,
@@ -120,7 +128,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
},
)
- Overview.create_or_update(
+ overview2 = Overview.create_or_update(
name: 'Unassigned & Open',
link: 'all_unassigned',
prio: 1010,
@@ -146,7 +154,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
view_mode_default: 's',
},
)
- Overview.create_or_update(
+ overview3 = Overview.create_or_update(
name: 'My Tickets 2',
link: 'my_tickets_2',
prio: 1020,
@@ -173,9 +181,36 @@ class TicketOverviewTest < ActiveSupport::TestCase
view_mode_default: 's',
},
)
+ overview4 = Overview.create_or_update(
+ name: 'My Tickets only with Note',
+ link: 'my_tickets_onyl_with_note',
+ prio: 1030,
+ role_id: overview_role.id,
+ user_ids: [agent1.id],
+ condition: {
+ 'article.type_id' => {
+ operator: 'is',
+ value: Ticket::Article::Type.find_by(name: 'note').id,
+ },
+ 'ticket.owner_id' => {
+ operator: 'is',
+ pre_condition: 'current_user.id',
+ },
+ },
+ order: {
+ by: 'created_at',
+ direction: 'ASC',
+ },
+ view: {
+ d: %w(title customer group created_at),
+ s: %w(title customer group created_at),
+ m: %w(number title customer group created_at),
+ view_mode_default: 's',
+ },
+ )
overview_role = Role.find_by(name: 'Customer')
- Overview.create_or_update(
+ overview5 = Overview.create_or_update(
name: 'My Tickets',
link: 'my_tickets',
prio: 1100,
@@ -201,7 +236,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
view_mode_default: 's',
},
)
- Overview.create_or_update(
+ overview6 = Overview.create_or_update(
name: 'My Organization Tickets',
link: 'my_organization_tickets',
prio: 1200,
@@ -228,7 +263,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
view_mode_default: 's',
},
)
- Overview.create_or_update(
+ overview7 = Overview.create_or_update(
name: 'My Organization Tickets (open)',
link: 'my_organization_tickets_open',
prio: 1200,
@@ -258,7 +293,7 @@ class TicketOverviewTest < ActiveSupport::TestCase
)
overview_role = Role.find_by(name: 'Admin')
- Overview.create_or_update(
+ overview8 = Overview.create_or_update(
name: 'Not Shown Admin',
link: 'not_shown_admin',
prio: 9900,
@@ -282,14 +317,15 @@ class TicketOverviewTest < ActiveSupport::TestCase
)
end
- test 'ticket create' do
+ test 'bbb overiview index' do
result = Ticket::Overviews.all(
current_user: agent1,
)
- assert_equal(2, result.count)
+ assert_equal(3, result.count)
assert_equal('My assigned Tickets', result[0].name)
assert_equal('Unassigned & Open', result[1].name)
+ assert_equal('My Tickets only with Note', result[2].name)
result = Ticket::Overviews.all(
current_user: agent2,
@@ -322,4 +358,501 @@ class TicketOverviewTest < ActiveSupport::TestCase
end
+ test 'ccc overiview content' do
+
+ Ticket.destroy_all
+
+ result = Ticket::Overviews.index(agent1)
+ assert_equal(result[0][:overview][:name], 'My assigned Tickets')
+ assert_equal(result[0][:overview][:view], 'my_assigned')
+ assert_equal(result[0][:count], 0)
+ assert_equal(result[0][:tickets].class, Array)
+ assert(result[0][:tickets].empty?)
+ assert_equal(result[1][:overview][:name], 'Unassigned & Open')
+ assert_equal(result[1][:overview][:view], 'all_unassigned')
+ assert_equal(result[1][:tickets].class, Array)
+ assert(result[1][:tickets].empty?)
+ assert_equal(result[1][:count], 0)
+ assert_equal(result[2][:overview][:name], 'My Tickets only with Note')
+ assert_equal(result[2][:overview][:view], 'my_tickets_onyl_with_note')
+ assert_equal(result[2][:tickets].class, Array)
+ assert(result[2][:tickets].empty?)
+ assert_equal(result[2][:count], 0)
+
+ result = Ticket::Overviews.index(agent2)
+ assert_equal(result[0][:overview][:name], 'My assigned Tickets')
+ assert_equal(result[0][:overview][:view], 'my_assigned')
+ assert_equal(result[0][:count], 0)
+ assert_equal(result[0][:tickets].class, Array)
+ assert(result[0][:tickets].empty?)
+ assert_equal(result[1][:overview][:name], 'Unassigned & Open')
+ assert_equal(result[1][:overview][:view], 'all_unassigned')
+ assert_equal(result[1][:tickets].class, Array)
+ assert(result[1][:tickets].empty?)
+ assert_equal(result[1][:count], 0)
+ assert_equal(result[2][:overview][:name], 'My Tickets 2')
+ assert_equal(result[2][:overview][:view], 'my_tickets_2')
+ assert_equal(result[2][:tickets].class, Array)
+ assert(result[2][:tickets].empty?)
+
+ ticket1 = Ticket.create(
+ title: 'overview test 1',
+ group: Group.lookup(name: 'OverviewTest'),
+ customer_id: 2,
+ state: Ticket::State.lookup(name: 'new'),
+ priority: Ticket::Priority.lookup(name: '2 normal'),
+ updated_by_id: 1,
+ created_by_id: 1,
+ )
+ article1 = Ticket::Article.create(
+ ticket_id: ticket1.id,
+ from: 'some_sender@example.com',
+ to: 'some_recipient@example.com',
+ subject: 'some subject',
+ message_id: 'some@id',
+ body: 'some message... 123',
+ internal: false,
+ sender: Ticket::Article::Sender.find_by(name: 'Customer'),
+ type: Ticket::Article::Type.find_by(name: 'email'),
+ updated_by_id: 1,
+ created_by_id: 1,
+ )
+
+ result = Ticket::Overviews.index(agent1)
+ assert_equal(result[0][:overview][:name], 'My assigned Tickets')
+ assert_equal(result[0][:overview][:view], 'my_assigned')
+ assert_equal(result[0][:count], 0)
+ assert_equal(result[0][:tickets].class, Array)
+ assert(result[0][:tickets].empty?)
+ assert_equal(result[1][:overview][:name], 'Unassigned & Open')
+ assert_equal(result[1][:overview][:view], 'all_unassigned')
+ assert_equal(result[1][:tickets].class, Array)
+ assert_not(result[1][:tickets].empty?)
+ assert_equal(result[1][:tickets][0][:id], ticket1.id)
+ assert_equal(result[1][:count], 1)
+ assert_equal(result[2][:overview][:name], 'My Tickets only with Note')
+ assert_equal(result[2][:overview][:view], 'my_tickets_onyl_with_note')
+ assert_equal(result[2][:tickets].class, Array)
+ assert(result[2][:tickets].empty?)
+ assert_equal(result[2][:count], 0)
+
+ result = Ticket::Overviews.index(agent2)
+ assert_equal(result[0][:overview][:name], 'My assigned Tickets')
+ assert_equal(result[0][:overview][:view], 'my_assigned')
+ assert_equal(result[0][:count], 0)
+ assert_equal(result[0][:tickets].class, Array)
+ assert(result[0][:tickets].empty?)
+ assert_equal(result[1][:overview][:name], 'Unassigned & Open')
+ assert_equal(result[1][:overview][:view], 'all_unassigned')
+ assert_equal(result[1][:tickets].class, Array)
+ assert(result[1][:tickets].empty?)
+ assert_equal(result[1][:count], 0)
+ assert_equal(result[2][:overview][:name], 'My Tickets 2')
+ assert_equal(result[2][:overview][:view], 'my_tickets_2')
+ assert_equal(result[2][:tickets].class, Array)
+ assert(result[2][:tickets].empty?)
+
+ ticket2 = Ticket.create(
+ title: 'overview test 2',
+ group: Group.lookup(name: 'OverviewTest'),
+ customer_id: 2,
+ state: Ticket::State.lookup(name: 'new'),
+ priority: Ticket::Priority.lookup(name: '3 high'),
+ updated_by_id: 1,
+ created_by_id: 1,
+ )
+ article2 = Ticket::Article.create(
+ ticket_id: ticket2.id,
+ from: 'some_sender@example.com',
+ to: 'some_recipient@example.com',
+ subject: 'some subject',
+ message_id: 'some@id',
+ body: 'some message... 123',
+ internal: false,
+ sender: Ticket::Article::Sender.find_by(name: 'Agent'),
+ type: Ticket::Article::Type.find_by(name: 'note'),
+ updated_by_id: 1,
+ created_by_id: 1,
+ )
+
+ result = Ticket::Overviews.index(agent1)
+ assert_equal(result[0][:overview][:name], 'My assigned Tickets')
+ assert_equal(result[0][:overview][:view], 'my_assigned')
+ assert_equal(result[0][:count], 0)
+ assert_equal(result[0][:tickets].class, Array)
+ assert(result[0][:tickets].empty?)
+ assert_equal(result[1][:overview][:name], 'Unassigned & Open')
+ assert_equal(result[1][:overview][:view], 'all_unassigned')
+ assert_equal(result[1][:tickets].class, Array)
+ assert_not(result[1][:tickets].empty?)
+ assert_equal(result[1][:tickets][0][:id], ticket1.id)
+ assert_equal(result[1][:tickets][1][:id], ticket2.id)
+ assert_equal(result[1][:count], 2)
+ assert_equal(result[2][:overview][:name], 'My Tickets only with Note')
+ assert_equal(result[2][:overview][:view], 'my_tickets_onyl_with_note')
+ assert_equal(result[2][:tickets].class, Array)
+ assert(result[2][:tickets].empty?)
+ assert_equal(result[2][:count], 0)
+
+ result = Ticket::Overviews.index(agent2)
+ assert_equal(result[0][:overview][:name], 'My assigned Tickets')
+ assert_equal(result[0][:overview][:view], 'my_assigned')
+ assert_equal(result[0][:count], 0)
+ assert_equal(result[0][:tickets].class, Array)
+ assert(result[0][:tickets].empty?)
+ assert_equal(result[1][:overview][:name], 'Unassigned & Open')
+ assert_equal(result[1][:overview][:view], 'all_unassigned')
+ assert_equal(result[1][:tickets].class, Array)
+ assert(result[1][:tickets].empty?)
+ assert_equal(result[1][:count], 0)
+ assert_equal(result[2][:overview][:name], 'My Tickets 2')
+ assert_equal(result[2][:overview][:view], 'my_tickets_2')
+ assert_equal(result[2][:tickets].class, Array)
+ assert(result[2][:tickets].empty?)
+
+ ticket2.owner_id = agent1.id
+ ticket2.save!
+
+ result = Ticket::Overviews.index(agent1)
+ assert_equal(result[0][:overview][:name], 'My assigned Tickets')
+ assert_equal(result[0][:overview][:view], 'my_assigned')
+ assert_equal(result[0][:tickets].class, Array)
+ assert_equal(result[0][:tickets][0][:id], ticket2.id)
+ assert_equal(result[0][:count], 1)
+ assert_equal(result[0][:tickets].class, Array)
+ assert_equal(result[1][:overview][:name], 'Unassigned & Open')
+ assert_equal(result[1][:overview][:view], 'all_unassigned')
+ assert_equal(result[1][:tickets].class, Array)
+ assert_not(result[1][:tickets].empty?)
+ assert_equal(result[1][:tickets][0][:id], ticket1.id)
+ assert_equal(result[1][:count], 1)
+ assert_equal(result[2][:overview][:name], 'My Tickets only with Note')
+ assert_equal(result[2][:overview][:view], 'my_tickets_onyl_with_note')
+ assert_equal(result[2][:tickets].class, Array)
+ assert_equal(result[2][:tickets][0][:id], ticket2.id)
+ assert_equal(result[2][:count], 1)
+
+ result = Ticket::Overviews.index(agent2)
+ assert_equal(result[0][:overview][:name], 'My assigned Tickets')
+ assert_equal(result[0][:overview][:view], 'my_assigned')
+ assert_equal(result[0][:count], 0)
+ assert_equal(result[0][:tickets].class, Array)
+ assert(result[0][:tickets].empty?)
+ assert_equal(result[1][:overview][:name], 'Unassigned & Open')
+ assert_equal(result[1][:overview][:view], 'all_unassigned')
+ assert_equal(result[1][:tickets].class, Array)
+ assert(result[1][:tickets].empty?)
+ assert_equal(result[1][:count], 0)
+ assert_equal(result[2][:overview][:name], 'My Tickets 2')
+ assert_equal(result[2][:overview][:view], 'my_tickets_2')
+ assert_equal(result[2][:tickets].class, Array)
+ assert(result[2][:tickets].empty?)
+
+ ticket3 = Ticket.create(
+ title: 'overview test 3',
+ group: Group.lookup(name: 'OverviewTest'),
+ customer_id: 2,
+ state: Ticket::State.lookup(name: 'new'),
+ priority: Ticket::Priority.lookup(name: '1 low'),
+ updated_by_id: 1,
+ created_by_id: 1,
+ )
+ article3 = Ticket::Article.create(
+ ticket_id: ticket3.id,
+ from: 'some_sender@example.com',
+ to: 'some_recipient@example.com',
+ subject: 'some subject',
+ message_id: 'some@id',
+ body: 'some message... 123',
+ internal: false,
+ sender: Ticket::Article::Sender.find_by(name: 'Customer'),
+ type: Ticket::Article::Type.find_by(name: 'email'),
+ updated_by_id: 1,
+ created_by_id: 1,
+ )
+
+ result = Ticket::Overviews.index(agent1)
+ assert_equal(result[0][:overview][:id], overview1.id)
+ assert_equal(result[0][:overview][:name], 'My assigned Tickets')
+ assert_equal(result[0][:overview][:view], 'my_assigned')
+ assert_equal(result[0][:tickets].class, Array)
+ assert_equal(result[0][:tickets][0][:id], ticket2.id)
+ assert_equal(result[0][:count], 1)
+ assert_equal(result[0][:tickets].class, Array)
+ assert_equal(result[1][:overview][:id], overview2.id)
+ assert_equal(result[1][:overview][:name], 'Unassigned & Open')
+ assert_equal(result[1][:overview][:view], 'all_unassigned')
+ assert_equal(result[1][:tickets].class, Array)
+ assert_not(result[1][:tickets].empty?)
+ assert_equal(result[1][:tickets][0][:id], ticket1.id)
+ assert_equal(result[1][:tickets][1][:id], ticket3.id)
+ assert_equal(result[1][:count], 2)
+ assert_equal(result[2][:overview][:id], overview4.id)
+ assert_equal(result[2][:overview][:name], 'My Tickets only with Note')
+ assert_equal(result[2][:overview][:view], 'my_tickets_onyl_with_note')
+ assert_equal(result[2][:tickets].class, Array)
+ assert_equal(result[2][:tickets][0][:id], ticket2.id)
+ assert_equal(result[2][:count], 1)
+
+ result = Ticket::Overviews.index(agent2)
+ assert_equal(result[0][:overview][:id], overview1.id)
+ assert_equal(result[0][:overview][:name], 'My assigned Tickets')
+ assert_equal(result[0][:overview][:view], 'my_assigned')
+ assert_equal(result[0][:count], 0)
+ assert_equal(result[0][:tickets].class, Array)
+ assert(result[0][:tickets].empty?)
+ assert_equal(result[1][:overview][:id], overview2.id)
+ assert_equal(result[1][:overview][:name], 'Unassigned & Open')
+ assert_equal(result[1][:overview][:view], 'all_unassigned')
+ assert_equal(result[1][:tickets].class, Array)
+ assert(result[1][:tickets].empty?)
+ assert_equal(result[1][:count], 0)
+ assert_equal(result[2][:overview][:id], overview3.id)
+ assert_equal(result[2][:overview][:name], 'My Tickets 2')
+ assert_equal(result[2][:overview][:view], 'my_tickets_2')
+ assert_equal(result[2][:tickets].class, Array)
+ assert(result[2][:tickets].empty?)
+
+ overview2.order = {
+ by: 'created_at',
+ direction: 'DESC',
+ }
+ overview2.save!
+
+ result = Ticket::Overviews.index(agent1)
+ assert_equal(result[0][:overview][:id], overview1.id)
+ assert_equal(result[0][:overview][:name], 'My assigned Tickets')
+ assert_equal(result[0][:overview][:view], 'my_assigned')
+ assert_equal(result[0][:tickets].class, Array)
+ assert_equal(result[0][:tickets][0][:id], ticket2.id)
+ assert_equal(result[0][:count], 1)
+ assert_equal(result[0][:tickets].class, Array)
+ assert_equal(result[1][:overview][:id], overview2.id)
+ assert_equal(result[1][:overview][:name], 'Unassigned & Open')
+ assert_equal(result[1][:overview][:view], 'all_unassigned')
+ assert_equal(result[1][:tickets].class, Array)
+ assert_not(result[1][:tickets].empty?)
+ assert_equal(result[1][:tickets][0][:id], ticket3.id)
+ assert_equal(result[1][:tickets][1][:id], ticket1.id)
+ assert_equal(result[1][:count], 2)
+ assert_equal(result[2][:overview][:id], overview4.id)
+ assert_equal(result[2][:overview][:name], 'My Tickets only with Note')
+ assert_equal(result[2][:overview][:view], 'my_tickets_onyl_with_note')
+ assert_equal(result[2][:tickets].class, Array)
+ assert_equal(result[2][:tickets][0][:id], ticket2.id)
+ assert_equal(result[2][:count], 1)
+
+ result = Ticket::Overviews.index(agent2)
+ assert_equal(result[0][:overview][:id], overview1.id)
+ assert_equal(result[0][:overview][:name], 'My assigned Tickets')
+ assert_equal(result[0][:overview][:view], 'my_assigned')
+ assert_equal(result[0][:count], 0)
+ assert_equal(result[0][:tickets].class, Array)
+ assert(result[0][:tickets].empty?)
+ assert_equal(result[1][:overview][:id], overview2.id)
+ assert_equal(result[1][:overview][:name], 'Unassigned & Open')
+ assert_equal(result[1][:overview][:view], 'all_unassigned')
+ assert_equal(result[1][:tickets].class, Array)
+ assert(result[1][:tickets].empty?)
+ assert_equal(result[1][:count], 0)
+ assert_equal(result[2][:overview][:id], overview3.id)
+ assert_equal(result[2][:overview][:name], 'My Tickets 2')
+ assert_equal(result[2][:overview][:view], 'my_tickets_2')
+ assert_equal(result[2][:tickets].class, Array)
+ assert(result[2][:tickets].empty?)
+
+ overview2.order = {
+ by: 'priority_id',
+ direction: 'DESC',
+ }
+ overview2.save!
+
+ result = Ticket::Overviews.index(agent1)
+ assert_equal(result[0][:overview][:id], overview1.id)
+ assert_equal(result[0][:overview][:name], 'My assigned Tickets')
+ assert_equal(result[0][:overview][:view], 'my_assigned')
+ assert_equal(result[0][:tickets].class, Array)
+ assert_equal(result[0][:tickets][0][:id], ticket2.id)
+ assert_equal(result[0][:count], 1)
+ assert_equal(result[0][:tickets].class, Array)
+ assert_equal(result[1][:overview][:id], overview2.id)
+ assert_equal(result[1][:overview][:name], 'Unassigned & Open')
+ assert_equal(result[1][:overview][:view], 'all_unassigned')
+ assert_equal(result[1][:tickets].class, Array)
+ assert_not(result[1][:tickets].empty?)
+ assert_equal(result[1][:tickets][0][:id], ticket1.id)
+ assert_equal(result[1][:tickets][1][:id], ticket3.id)
+ assert_equal(result[1][:count], 2)
+ assert_equal(result[2][:overview][:id], overview4.id)
+ assert_equal(result[2][:overview][:name], 'My Tickets only with Note')
+ assert_equal(result[2][:overview][:view], 'my_tickets_onyl_with_note')
+ assert_equal(result[2][:tickets].class, Array)
+ assert_equal(result[2][:tickets][0][:id], ticket2.id)
+ assert_equal(result[2][:count], 1)
+
+ result = Ticket::Overviews.index(agent2)
+ assert_equal(result[0][:overview][:id], overview1.id)
+ assert_equal(result[0][:overview][:name], 'My assigned Tickets')
+ assert_equal(result[0][:overview][:view], 'my_assigned')
+ assert_equal(result[0][:count], 0)
+ assert_equal(result[0][:tickets].class, Array)
+ assert(result[0][:tickets].empty?)
+ assert_equal(result[1][:overview][:id], overview2.id)
+ assert_equal(result[1][:overview][:name], 'Unassigned & Open')
+ assert_equal(result[1][:overview][:view], 'all_unassigned')
+ assert_equal(result[1][:tickets].class, Array)
+ assert(result[1][:tickets].empty?)
+ assert_equal(result[1][:count], 0)
+ assert_equal(result[2][:overview][:id], overview3.id)
+ assert_equal(result[2][:overview][:name], 'My Tickets 2')
+ assert_equal(result[2][:overview][:view], 'my_tickets_2')
+ assert_equal(result[2][:tickets].class, Array)
+ assert(result[2][:tickets].empty?)
+
+ overview2.order = {
+ by: 'priority_id',
+ direction: 'ASC',
+ }
+ overview2.save!
+
+ result = Ticket::Overviews.index(agent1)
+ assert_equal(result[0][:overview][:id], overview1.id)
+ assert_equal(result[0][:overview][:name], 'My assigned Tickets')
+ assert_equal(result[0][:overview][:view], 'my_assigned')
+ assert_equal(result[0][:tickets].class, Array)
+ assert_equal(result[0][:tickets][0][:id], ticket2.id)
+ assert_equal(result[0][:count], 1)
+ assert_equal(result[0][:tickets].class, Array)
+ assert_equal(result[1][:overview][:id], overview2.id)
+ assert_equal(result[1][:overview][:name], 'Unassigned & Open')
+ assert_equal(result[1][:overview][:view], 'all_unassigned')
+ assert_equal(result[1][:tickets].class, Array)
+ assert_not(result[1][:tickets].empty?)
+ assert_equal(result[1][:tickets][0][:id], ticket3.id)
+ assert_equal(result[1][:tickets][1][:id], ticket1.id)
+ assert_equal(result[1][:count], 2)
+ assert_equal(result[2][:overview][:id], overview4.id)
+ assert_equal(result[2][:overview][:name], 'My Tickets only with Note')
+ assert_equal(result[2][:overview][:view], 'my_tickets_onyl_with_note')
+ assert_equal(result[2][:tickets].class, Array)
+ assert_equal(result[2][:tickets][0][:id], ticket2.id)
+ assert_equal(result[2][:count], 1)
+
+ result = Ticket::Overviews.index(agent2)
+ assert_equal(result[0][:overview][:id], overview1.id)
+ assert_equal(result[0][:overview][:name], 'My assigned Tickets')
+ assert_equal(result[0][:overview][:view], 'my_assigned')
+ assert_equal(result[0][:count], 0)
+ assert_equal(result[0][:tickets].class, Array)
+ assert(result[0][:tickets].empty?)
+ assert_equal(result[1][:overview][:id], overview2.id)
+ assert_equal(result[1][:overview][:name], 'Unassigned & Open')
+ assert_equal(result[1][:overview][:view], 'all_unassigned')
+ assert_equal(result[1][:tickets].class, Array)
+ assert(result[1][:tickets].empty?)
+ assert_equal(result[1][:count], 0)
+ assert_equal(result[2][:overview][:id], overview3.id)
+ assert_equal(result[2][:overview][:name], 'My Tickets 2')
+ assert_equal(result[2][:overview][:view], 'my_tickets_2')
+ assert_equal(result[2][:tickets].class, Array)
+ assert(result[2][:tickets].empty?)
+
+ overview2.order = {
+ by: 'priority',
+ direction: 'DESC',
+ }
+ overview2.save!
+
+ result = Ticket::Overviews.index(agent1)
+ assert_equal(result[0][:overview][:id], overview1.id)
+ assert_equal(result[0][:overview][:name], 'My assigned Tickets')
+ assert_equal(result[0][:overview][:view], 'my_assigned')
+ assert_equal(result[0][:tickets].class, Array)
+ assert_equal(result[0][:tickets][0][:id], ticket2.id)
+ assert_equal(result[0][:count], 1)
+ assert_equal(result[0][:tickets].class, Array)
+ assert_equal(result[1][:overview][:id], overview2.id)
+ assert_equal(result[1][:overview][:name], 'Unassigned & Open')
+ assert_equal(result[1][:overview][:view], 'all_unassigned')
+ assert_equal(result[1][:tickets].class, Array)
+ assert_not(result[1][:tickets].empty?)
+ assert_equal(result[1][:tickets][0][:id], ticket1.id)
+ assert_equal(result[1][:tickets][1][:id], ticket3.id)
+ assert_equal(result[1][:count], 2)
+ assert_equal(result[2][:overview][:id], overview4.id)
+ assert_equal(result[2][:overview][:name], 'My Tickets only with Note')
+ assert_equal(result[2][:overview][:view], 'my_tickets_onyl_with_note')
+ assert_equal(result[2][:tickets].class, Array)
+ assert_equal(result[2][:tickets][0][:id], ticket2.id)
+ assert_equal(result[2][:count], 1)
+
+ result = Ticket::Overviews.index(agent2)
+ assert_equal(result[0][:overview][:id], overview1.id)
+ assert_equal(result[0][:overview][:name], 'My assigned Tickets')
+ assert_equal(result[0][:overview][:view], 'my_assigned')
+ assert_equal(result[0][:count], 0)
+ assert_equal(result[0][:tickets].class, Array)
+ assert(result[0][:tickets].empty?)
+ assert_equal(result[1][:overview][:id], overview2.id)
+ assert_equal(result[1][:overview][:name], 'Unassigned & Open')
+ assert_equal(result[1][:overview][:view], 'all_unassigned')
+ assert_equal(result[1][:tickets].class, Array)
+ assert(result[1][:tickets].empty?)
+ assert_equal(result[1][:count], 0)
+ assert_equal(result[2][:overview][:id], overview3.id)
+ assert_equal(result[2][:overview][:name], 'My Tickets 2')
+ assert_equal(result[2][:overview][:view], 'my_tickets_2')
+ assert_equal(result[2][:tickets].class, Array)
+ assert(result[2][:tickets].empty?)
+
+ overview2.order = {
+ by: 'priority',
+ direction: 'ASC',
+ }
+ overview2.save!
+
+ result = Ticket::Overviews.index(agent1)
+ assert_equal(result[0][:overview][:id], overview1.id)
+ assert_equal(result[0][:overview][:name], 'My assigned Tickets')
+ assert_equal(result[0][:overview][:view], 'my_assigned')
+ assert_equal(result[0][:tickets].class, Array)
+ assert_equal(result[0][:tickets][0][:id], ticket2.id)
+ assert_equal(result[0][:count], 1)
+ assert_equal(result[0][:tickets].class, Array)
+ assert_equal(result[1][:overview][:id], overview2.id)
+ assert_equal(result[1][:overview][:name], 'Unassigned & Open')
+ assert_equal(result[1][:overview][:view], 'all_unassigned')
+ assert_equal(result[1][:tickets].class, Array)
+ assert_not(result[1][:tickets].empty?)
+ assert_equal(result[1][:tickets][0][:id], ticket3.id)
+ assert_equal(result[1][:tickets][1][:id], ticket1.id)
+ assert_equal(result[1][:count], 2)
+ assert_equal(result[2][:overview][:id], overview4.id)
+ assert_equal(result[2][:overview][:name], 'My Tickets only with Note')
+ assert_equal(result[2][:overview][:view], 'my_tickets_onyl_with_note')
+ assert_equal(result[2][:tickets].class, Array)
+ assert_equal(result[2][:tickets][0][:id], ticket2.id)
+ assert_equal(result[2][:count], 1)
+
+ result = Ticket::Overviews.index(agent2)
+ assert_equal(result[0][:overview][:id], overview1.id)
+ assert_equal(result[0][:overview][:name], 'My assigned Tickets')
+ assert_equal(result[0][:overview][:view], 'my_assigned')
+ assert_equal(result[0][:count], 0)
+ assert_equal(result[0][:tickets].class, Array)
+ assert(result[0][:tickets].empty?)
+ assert_equal(result[1][:overview][:id], overview2.id)
+ assert_equal(result[1][:overview][:name], 'Unassigned & Open')
+ assert_equal(result[1][:overview][:view], 'all_unassigned')
+ assert_equal(result[1][:tickets].class, Array)
+ assert(result[1][:tickets].empty?)
+ assert_equal(result[1][:count], 0)
+ assert_equal(result[2][:overview][:id], overview3.id)
+ assert_equal(result[2][:overview][:name], 'My Tickets 2')
+ assert_equal(result[2][:overview][:view], 'my_tickets_2')
+ assert_equal(result[2][:tickets].class, Array)
+ assert(result[2][:tickets].empty?)
+
+ end
+
end
diff --git a/test/unit/ticket_trigger_test.rb b/test/unit/ticket_trigger_test.rb
index 5d86c2659..91ac530d3 100644
--- a/test/unit/ticket_trigger_test.rb
+++ b/test/unit/ticket_trigger_test.rb
@@ -4,8 +4,37 @@ require 'test_helper'
class TicketTriggerTest < ActiveSupport::TestCase
test '1 basic' do
trigger1 = Trigger.create_or_update(
+ name: 'aaa loop check',
+ condition: {
+ 'article.subject' => {
+ 'operator' => 'contains',
+ 'value' => 'Thanks for your inquiry',
+ },
+ },
+ perform: {
+ 'ticket.tags' => {
+ 'operator' => 'add',
+ 'value' => 'should_not_loop',
+ },
+ 'notification.email' => {
+ 'body' => 'some lala',
+ 'recipient' => 'ticket_customer',
+ 'subject' => 'Thanks for your inquiry - loop check (#{ticket.title})!',
+ },
+ },
+ disable_notification: true,
+ active: true,
+ created_by_id: 1,
+ updated_by_id: 1,
+ )
+
+ trigger2 = Trigger.create_or_update(
name: 'auto reply',
condition: {
+ 'ticket.action' => {
+ 'operator' => 'is',
+ 'value' => 'create',
+ },
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'new').id.to_s,
@@ -31,7 +60,54 @@ class TicketTriggerTest < ActiveSupport::TestCase
updated_by_id: 1,
)
- trigger2 = Trigger.create_or_update(
+ trigger3 = Trigger.create_or_update(
+ name: 'auto tag 1',
+ condition: {
+ 'ticket.action' => {
+ 'operator' => 'is',
+ 'value' => 'update',
+ },
+ 'ticket.state_id' => {
+ 'operator' => 'is',
+ 'value' => Ticket::State.lookup(name: 'new').id.to_s,
+ }
+ },
+ perform: {
+ 'ticket.priority_id' => {
+ 'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
+ },
+ 'ticket.tags' => {
+ 'operator' => 'remove',
+ 'value' => 'kk',
+ },
+ },
+ disable_notification: true,
+ active: true,
+ created_by_id: 1,
+ updated_by_id: 1,
+ )
+
+ trigger4 = Trigger.create_or_update(
+ name: 'auto tag 2',
+ condition: {
+ 'ticket.state_id' => {
+ 'operator' => 'is',
+ 'value' => Ticket::State.lookup(name: 'new').id.to_s,
+ }
+ },
+ perform: {
+ 'ticket.tags' => {
+ 'operator' => 'add',
+ 'value' => 'abc',
+ },
+ },
+ disable_notification: true,
+ active: true,
+ created_by_id: 1,
+ updated_by_id: 1,
+ )
+
+ trigger5 = Trigger.create_or_update(
name: 'not matching',
condition: {
'ticket.state_id' => {
@@ -50,6 +126,31 @@ class TicketTriggerTest < ActiveSupport::TestCase
updated_by_id: 1,
)
+ trigger6 = Trigger.create_or_update(
+ name: 'zzz last',
+ condition: {
+ 'article.subject' => {
+ 'operator' => 'contains',
+ 'value' => 'some subject 1234',
+ },
+ },
+ perform: {
+ 'ticket.tags' => {
+ 'operator' => 'add',
+ 'value' => 'article_create_trigger',
+ },
+ 'notification.email' => {
+ 'body' => 'some lala',
+ 'recipient' => 'ticket_customer',
+ 'subject' => 'Thanks for your inquiry - 1234 check (#{ticket.title})!',
+ },
+ },
+ disable_notification: true,
+ active: true,
+ created_by_id: 1,
+ updated_by_id: 1,
+ )
+
ticket1 = Ticket.create(
title: "some
title\n äöüß",
group: Group.lookup(name: 'Users'),
@@ -89,7 +190,7 @@ class TicketTriggerTest < ActiveSupport::TestCase
assert_equal('new', ticket1.state.name, 'ticket1.state verify')
assert_equal('3 high', ticket1.priority.name, 'ticket1.priority verify')
assert_equal(2, ticket1.articles.count, 'ticket1.articles verify')
- assert_equal(%w(aa kk), Tag.tag_list(object: 'Ticket', o_id: ticket1.id))
+ assert_equal(%w(aa kk abc), Tag.tag_list(object: 'Ticket', o_id: ticket1.id))
article1 = ticket1.articles.last
assert_match('Zammad
', article1.from)
assert_match('nicole.braun@zammad.org', article1.to)
@@ -108,7 +209,7 @@ class TicketTriggerTest < ActiveSupport::TestCase
assert_equal('new', ticket1.state.name, 'ticket1.state verify')
assert_equal('2 normal', ticket1.priority.name, 'ticket1.priority verify')
assert_equal(2, ticket1.articles.count, 'ticket1.articles verify')
- assert_equal(%w(aa kk), Tag.tag_list(object: 'Ticket', o_id: ticket1.id))
+ assert_equal(%w(aa kk abc), Tag.tag_list(object: 'Ticket', o_id: ticket1.id))
ticket1.state = Ticket::State.lookup(name: 'open')
ticket1.save
@@ -120,7 +221,7 @@ class TicketTriggerTest < ActiveSupport::TestCase
assert_equal('open', ticket1.state.name, 'ticket1.state verify')
assert_equal('2 normal', ticket1.priority.name, 'ticket1.priority verify')
assert_equal(2, ticket1.articles.count, 'ticket1.articles verify')
- assert_equal(%w(aa kk), Tag.tag_list(object: 'Ticket', o_id: ticket1.id))
+ assert_equal(%w(aa kk abc), Tag.tag_list(object: 'Ticket', o_id: ticket1.id))
ticket1.state = Ticket::State.lookup(name: 'new')
ticket1.save
@@ -132,14 +233,8 @@ class TicketTriggerTest < ActiveSupport::TestCase
assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
assert_equal('new', ticket1.state.name, 'ticket1.state verify')
assert_equal('3 high', ticket1.priority.name, 'ticket1.priority verify')
- assert_equal(3, ticket1.articles.count, 'ticket1.articles verify')
- assert_equal(%w(aa kk), Tag.tag_list(object: 'Ticket', o_id: ticket1.id))
- article1 = ticket1.articles.last
- assert_match('Zammad ', article1.from)
- assert_match('nicole.braun@zammad.org', article1.to)
- assert_match('Thanks for your inquiry (some title äöüß)!', article1.subject)
- assert_match('Braun
some <b>title</b>', article1.body)
- assert_equal('text/html', article1.content_type)
+ assert_equal(2, ticket1.articles.count, 'ticket1.articles verify')
+ assert_equal(%w(aa abc), Tag.tag_list(object: 'Ticket', o_id: ticket1.id))
ticket2 = Ticket.create(
title: "some title\n äöüß",
@@ -179,11 +274,12 @@ class TicketTriggerTest < ActiveSupport::TestCase
created_by_id: 1,
)
assert(ticket3, 'ticket3 created')
+
Ticket::Article.create(
ticket_id: ticket3.id,
from: 'some_sender@example.com',
to: 'some_recipient@example.com',
- subject: 'some subject',
+ subject: 'some subject 1234',
message_id: 'some@id',
content_type: 'text/html',
body: 'some message note
new line',
@@ -208,9 +304,9 @@ class TicketTriggerTest < ActiveSupport::TestCase
assert_equal('Users', ticket3.group.name, 'ticket3.group verify')
assert_equal('new', ticket3.state.name, 'ticket3.state verify')
assert_equal('3 high', ticket3.priority.name, 'ticket3.priority verify')
- assert_equal(2, ticket3.articles.count, 'ticket3.articles verify')
- assert_equal(%w(aa kk), Tag.tag_list(object: 'Ticket', o_id: ticket3.id))
- article3 = ticket3.articles.last
+ assert_equal(3, ticket3.articles.count, 'ticket3.articles verify')
+ assert_equal(%w(aa kk abc article_create_trigger), Tag.tag_list(object: 'Ticket', o_id: ticket3.id))
+ article3 = ticket3.articles[1]
assert_match('Zammad ', article3.from)
assert_match('nicole.braun@zammad.org', article3.to)
assert_match('Thanks for your inquiry (some title äöüß3)!', article3.subject)
@@ -218,6 +314,61 @@ class TicketTriggerTest < ActiveSupport::TestCase
assert_match('> some message note
> new line', article3.body)
assert_no_match('> some message <b>note</b>
> new line', article3.body)
assert_equal('text/html', article3.content_type)
+ article3 = ticket3.articles[2]
+ assert_match('Zammad ', article3.from)
+ assert_match('nicole.braun@zammad.org', article3.to)
+ assert_match('Thanks for your inquiry - 1234 check (some title äöüß3)!', article3.subject)
+ assert_equal('text/html', article3.content_type)
+
+ Ticket::Article.create(
+ ticket_id: ticket3.id,
+ from: 'some_sender@example.com',
+ to: 'some_recipient@example.com',
+ subject: 'some subject - not 1234',
+ message_id: 'some@id',
+ content_type: 'text/html',
+ body: 'some message note
new line',
+ internal: false,
+ sender: Ticket::Article::Sender.find_by(name: 'Agent'),
+ type: Ticket::Article::Type.find_by(name: 'note'),
+ updated_by_id: 1,
+ created_by_id: 1,
+ )
+
+ Observer::Transaction.commit
+
+ ticket3 = Ticket.lookup(id: ticket3.id)
+ assert_equal('some title äöüß3', ticket3.title, 'ticket3.title verify')
+ assert_equal('Users', ticket3.group.name, 'ticket3.group verify')
+ assert_equal('new', ticket3.state.name, 'ticket3.state verify')
+ assert_equal('3 high', ticket3.priority.name, 'ticket3.priority verify')
+ assert_equal(4, ticket3.articles.count, 'ticket3.articles verify')
+ assert_equal(%w(aa kk abc article_create_trigger), Tag.tag_list(object: 'Ticket', o_id: ticket3.id))
+
+ Ticket::Article.create(
+ ticket_id: ticket3.id,
+ from: 'some_sender@example.com',
+ to: 'some_recipient@example.com',
+ subject: 'some subject 1234',
+ message_id: 'some@id',
+ content_type: 'text/html',
+ body: 'some message note
new line',
+ internal: false,
+ sender: Ticket::Article::Sender.find_by(name: 'Agent'),
+ type: Ticket::Article::Type.find_by(name: 'note'),
+ updated_by_id: 1,
+ created_by_id: 1,
+ )
+
+ Observer::Transaction.commit
+
+ ticket3 = Ticket.lookup(id: ticket3.id)
+ assert_equal('some title äöüß3', ticket3.title, 'ticket3.title verify')
+ assert_equal('Users', ticket3.group.name, 'ticket3.group verify')
+ assert_equal('new', ticket3.state.name, 'ticket3.state verify')
+ assert_equal('3 high', ticket3.priority.name, 'ticket3.priority verify')
+ assert_equal(5, ticket3.articles.count, 'ticket3.articles verify')
+ assert_equal(%w(aa kk abc article_create_trigger), Tag.tag_list(object: 'Ticket', o_id: ticket3.id))
Trigger.destroy_all
end