Merge branch 'develop' of github.com:martini/zammad into develop
This commit is contained in:
commit
a872f78e24
35 changed files with 568 additions and 626 deletions
|
@ -118,4 +118,21 @@ return all activity entries of an user
|
||||||
list
|
list
|
||||||
end
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
cleanup old stream messages
|
||||||
|
|
||||||
|
ActivityStream.cleanup
|
||||||
|
|
||||||
|
optional you can parse the max oldest stream entries
|
||||||
|
|
||||||
|
ActivityStream.cleanup(3.months)
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def self.cleanup(diff = 3.months)
|
||||||
|
ActivityStream.where('created_at < ?', Time.zone.now - diff).delete_all
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
class OnlineNotification < ApplicationModel
|
class OnlineNotification < ApplicationModel
|
||||||
belongs_to :type_lookup, class_name: 'TypeLookup'
|
belongs_to :type_lookup, class_name: 'TypeLookup'
|
||||||
belongs_to :object_lookup, class_name: 'ObjectLookup'
|
belongs_to :object_lookup, class_name: 'ObjectLookup'
|
||||||
|
belongs_to :user
|
||||||
|
|
||||||
after_create :notify_clients_after_change
|
after_create :notify_clients_after_change
|
||||||
after_update :notify_clients_after_change
|
after_update :notify_clients_after_change
|
||||||
|
@ -188,4 +189,32 @@ returns:
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
cleanup old online notifications
|
||||||
|
|
||||||
|
OnlineNotification.cleanup
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def self.cleanup
|
||||||
|
OnlineNotification.where('created_at < ?', Time.zone.now - 12.months).delete_all
|
||||||
|
OnlineNotification.where('seen = ? AND created_at < ?', true, Time.zone.now - 1.days).delete_all
|
||||||
|
|
||||||
|
# notify all agents
|
||||||
|
users = Ticket::ScreenOptions.agents
|
||||||
|
users.each {|user|
|
||||||
|
Sessions.send_to(
|
||||||
|
user.id,
|
||||||
|
{
|
||||||
|
event: 'OnlineNotification::changed',
|
||||||
|
data: {}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
sleep 2 # slow down client requests
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -98,4 +98,22 @@ class RecentView < ApplicationModel
|
||||||
return if !record.respond_to?(:permission)
|
return if !record.respond_to?(:permission)
|
||||||
record.permission( current_user: user )
|
record.permission( current_user: user )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
cleanup old entries
|
||||||
|
|
||||||
|
RecentView.cleanup
|
||||||
|
|
||||||
|
optional you can parse the max oldest entries
|
||||||
|
|
||||||
|
RecentView.cleanup(1.month)
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def self.cleanup(diff = 1.month)
|
||||||
|
RecentView.where('created_at < ?', Time.zone.now - diff).delete_all
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -26,7 +26,7 @@ class Scheduler < ApplicationModel
|
||||||
end
|
end
|
||||||
|
|
||||||
# read/load jobs and check if it is alredy started
|
# read/load jobs and check if it is alredy started
|
||||||
jobs = Scheduler.where( 'active = ?', true )
|
jobs = Scheduler.where( 'active = ?', true ).order('prio ASC')
|
||||||
jobs.each {|job|
|
jobs.each {|job|
|
||||||
|
|
||||||
# ignore job is still running
|
# ignore job is still running
|
||||||
|
@ -37,14 +37,14 @@ class Scheduler < ApplicationModel
|
||||||
|
|
||||||
# run job as own thread
|
# run job as own thread
|
||||||
@@jobs_started[ job.id ] = true
|
@@jobs_started[ job.id ] = true
|
||||||
start_job( job )
|
start_job(job)
|
||||||
|
sleep 10
|
||||||
}
|
}
|
||||||
sleep 60
|
sleep 60
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.start_job( job )
|
def self.start_job( job )
|
||||||
sleep 4
|
|
||||||
|
|
||||||
Thread.new {
|
Thread.new {
|
||||||
|
|
||||||
|
@ -53,8 +53,8 @@ class Scheduler < ApplicationModel
|
||||||
# start loop for periods under 5 minutes
|
# start loop for periods under 5 minutes
|
||||||
if job.period && job.period <= 300
|
if job.period && job.period <= 300
|
||||||
loop do
|
loop do
|
||||||
_start_job( job )
|
_start_job(job)
|
||||||
job = Scheduler.lookup( id: job.id )
|
job = Scheduler.lookup(id: job.id)
|
||||||
|
|
||||||
# exit is job got deleted
|
# exit is job got deleted
|
||||||
break if !job
|
break if !job
|
||||||
|
@ -69,7 +69,7 @@ class Scheduler < ApplicationModel
|
||||||
sleep job.period
|
sleep job.period
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
_start_job( job )
|
_start_job(job)
|
||||||
end
|
end
|
||||||
job.pid = ''
|
job.pid = ''
|
||||||
job.save
|
job.save
|
||||||
|
@ -82,7 +82,6 @@ class Scheduler < ApplicationModel
|
||||||
end
|
end
|
||||||
|
|
||||||
def self._start_job( job, try_count = 0, try_run_time = Time.zone.now )
|
def self._start_job( job, try_count = 0, try_run_time = Time.zone.now )
|
||||||
sleep 5
|
|
||||||
begin
|
begin
|
||||||
job.last_run = Time.zone.now
|
job.last_run = Time.zone.now
|
||||||
job.pid = Thread.current.object_id
|
job.pid = Thread.current.object_id
|
||||||
|
|
|
@ -6,7 +6,7 @@ module Ticket::ScreenOptions
|
||||||
|
|
||||||
list of active agents
|
list of active agents
|
||||||
|
|
||||||
result = Ticket::ScreenOptions.agents()
|
result = Ticket::ScreenOptions.agents
|
||||||
|
|
||||||
returns
|
returns
|
||||||
|
|
||||||
|
@ -23,21 +23,21 @@ returns
|
||||||
list attributes
|
list attributes
|
||||||
|
|
||||||
result = Ticket::ScreenOptions.attributes_to_change(
|
result = Ticket::ScreenOptions.attributes_to_change(
|
||||||
:ticket_id => 123,
|
ticket_id: 123,
|
||||||
:article_id => 123,
|
article_id: 123,
|
||||||
|
|
||||||
:ticket => ticket_model,
|
ticket: ticket_model,
|
||||||
)
|
)
|
||||||
|
|
||||||
returns
|
returns
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
:type_id => type_ids,
|
type_id: type_ids,
|
||||||
:state_id => state_ids,
|
state_id: state_ids,
|
||||||
:priority_id => priority_ids,
|
priority_id: priority_ids,
|
||||||
:owner_id => owner_ids,
|
owner_id: owner_ids,
|
||||||
:group_id => group_ids,
|
group_id: group_ids,
|
||||||
:group_id__owner_id => groups_users,
|
group_id__owner_id: groups_users,
|
||||||
}
|
}
|
||||||
|
|
||||||
=end
|
=end
|
||||||
|
@ -126,16 +126,16 @@ returns
|
||||||
list tickets by customer groupd in state categroie open and closed
|
list tickets by customer groupd in state categroie open and closed
|
||||||
|
|
||||||
result = Ticket::ScreenOptions.list_by_customer(
|
result = Ticket::ScreenOptions.list_by_customer(
|
||||||
:customer_id => 123,
|
customer_id: 123,
|
||||||
:limit => 15, # optional, default 15
|
limit: 15, # optional, default 15
|
||||||
)
|
)
|
||||||
|
|
||||||
returns
|
returns
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
:ticket_ids_open => tickets_open,
|
ticket_ids_open: tickets_open,
|
||||||
:ticket_ids_closed => tickets_closed,
|
ticket_ids_closed: tickets_closed,
|
||||||
:assets => { ...list of assets... },
|
assets: { ...list of assets... },
|
||||||
}
|
}
|
||||||
|
|
||||||
=end
|
=end
|
||||||
|
|
|
@ -7,9 +7,9 @@ module Ticket::Search
|
||||||
search tickets via search index
|
search tickets via search index
|
||||||
|
|
||||||
result = Ticket.search(
|
result = Ticket.search(
|
||||||
:current_user => User.find(123),
|
current_user: User.find(123),
|
||||||
:query => 'search something',
|
query: 'search something',
|
||||||
:limit => 15,
|
limit: 15,
|
||||||
)
|
)
|
||||||
|
|
||||||
returns
|
returns
|
||||||
|
@ -19,10 +19,10 @@ returns
|
||||||
search tickets via search index
|
search tickets via search index
|
||||||
|
|
||||||
result = Ticket.search(
|
result = Ticket.search(
|
||||||
:current_user => User.find(123),
|
current_user: User.find(123),
|
||||||
:query => 'search something',
|
query: 'search something',
|
||||||
:limit => 15,
|
limit: 15,
|
||||||
:full => false,
|
full: false,
|
||||||
)
|
)
|
||||||
|
|
||||||
returns
|
returns
|
||||||
|
@ -32,8 +32,8 @@ returns
|
||||||
search tickets via database
|
search tickets via database
|
||||||
|
|
||||||
result = Ticket.search(
|
result = Ticket.search(
|
||||||
:current_user => User.find(123),
|
current_user: User.find(123),
|
||||||
:condition => {
|
condition: {
|
||||||
'tickets.owner_id' => user.id,
|
'tickets.owner_id' => user.id,
|
||||||
'tickets.state_id' => Ticket::State.where(
|
'tickets.state_id' => Ticket::State.where(
|
||||||
state_type_id: Ticket::StateType.where(
|
state_type_id: Ticket::StateType.where(
|
||||||
|
@ -44,8 +44,8 @@ search tickets via database
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
:limit => 15,
|
limit: 15,
|
||||||
:full => false,
|
full: false,
|
||||||
)
|
)
|
||||||
|
|
||||||
returns
|
returns
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
|
||||||
|
|
||||||
class TimeAccounting < ActiveRecord::Base
|
|
||||||
end
|
|
|
@ -27,6 +27,7 @@ class CreateBase < ActiveRecord::Migration
|
||||||
t.column :zip, :string, limit: 100, null: true, default: ''
|
t.column :zip, :string, limit: 100, null: true, default: ''
|
||||||
t.column :city, :string, limit: 100, null: true, default: ''
|
t.column :city, :string, limit: 100, null: true, default: ''
|
||||||
t.column :country, :string, limit: 100, null: true, default: ''
|
t.column :country, :string, limit: 100, null: true, default: ''
|
||||||
|
t.column :vip, :boolean, default: false
|
||||||
t.column :verified, :boolean, null: false, default: false
|
t.column :verified, :boolean, null: false, default: false
|
||||||
t.column :active, :boolean, null: false, default: true
|
t.column :active, :boolean, null: false, default: true
|
||||||
t.column :note, :string, limit: 250, null: true, default: ''
|
t.column :note, :string, limit: 250, null: true, default: ''
|
||||||
|
@ -41,6 +42,7 @@ class CreateBase < ActiveRecord::Migration
|
||||||
add_index :users, [:login], unique: true
|
add_index :users, [:login], unique: true
|
||||||
add_index :users, [:email]
|
add_index :users, [:email]
|
||||||
#add_index :users, [:email], unique: => true
|
#add_index :users, [:email], unique: => true
|
||||||
|
add_index :users, [:organization_id]
|
||||||
add_index :users, [:image]
|
add_index :users, [:image]
|
||||||
add_index :users, [:department]
|
add_index :users, [:department]
|
||||||
add_index :users, [:phone]
|
add_index :users, [:phone]
|
||||||
|
@ -111,16 +113,22 @@ class CreateBase < ActiveRecord::Migration
|
||||||
t.integer :user_id
|
t.integer :user_id
|
||||||
t.integer :role_id
|
t.integer :role_id
|
||||||
end
|
end
|
||||||
|
add_index :roles_users, [:user_id]
|
||||||
|
add_index :roles_users, [:role_id]
|
||||||
|
|
||||||
create_table :groups_users, id: false do |t|
|
create_table :groups_users, id: false do |t|
|
||||||
t.integer :user_id
|
t.integer :user_id
|
||||||
t.integer :group_id
|
t.integer :group_id
|
||||||
end
|
end
|
||||||
|
add_index :groups_users, [:user_id]
|
||||||
|
add_index :groups_users, [:group_id]
|
||||||
|
|
||||||
create_table :organizations_users, id: false do |t|
|
create_table :organizations_users, id: false do |t|
|
||||||
t.integer :user_id
|
t.integer :user_id
|
||||||
t.integer :organization_id
|
t.integer :organization_id
|
||||||
end
|
end
|
||||||
|
add_index :organizations_users, [:user_id]
|
||||||
|
add_index :organizations_users, [:organization_id]
|
||||||
|
|
||||||
create_table :authorizations do |t|
|
create_table :authorizations do |t|
|
||||||
t.string :provider, limit: 250, null: false
|
t.string :provider, limit: 250, null: false
|
||||||
|
@ -309,5 +317,39 @@ class CreateBase < ActiveRecord::Migration
|
||||||
add_index :settings, [:area]
|
add_index :settings, [:area]
|
||||||
add_index :settings, [:frontend]
|
add_index :settings, [:frontend]
|
||||||
|
|
||||||
|
create_table :stores do |t|
|
||||||
|
t.references :store_object, null: false
|
||||||
|
t.references :store_file, null: false
|
||||||
|
t.column :o_id, :integer, limit: 8, null: false
|
||||||
|
t.column :preferences, :string, limit: 2500, null: true
|
||||||
|
t.column :size, :string, limit: 50, null: true
|
||||||
|
t.column :filename, :string, limit: 250, null: false
|
||||||
|
t.column :created_by_id, :integer, null: false
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
add_index :stores, [:store_object_id, :o_id]
|
||||||
|
|
||||||
|
create_table :store_objects do |t|
|
||||||
|
t.column :name, :string, limit: 250, null: false
|
||||||
|
t.column :note, :string, limit: 250, null: true
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
add_index :store_objects, [:name], unique: true
|
||||||
|
|
||||||
|
create_table :store_files do |t|
|
||||||
|
t.column :sha, :string, limit: 128, null: false
|
||||||
|
t.column :provider, :string, limit: 20, null: true
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
add_index :store_files, [:sha], unique: true
|
||||||
|
add_index :store_files, [:provider]
|
||||||
|
|
||||||
|
create_table :store_provider_dbs do |t|
|
||||||
|
t.column :sha, :string, limit: 128, null: false
|
||||||
|
t.column :data, :binary, limit: 200.megabytes, null: true
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
add_index :store_provider_dbs, [:sha], unique: true
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -145,6 +145,7 @@ class CreateTicket < ActiveRecord::Migration
|
||||||
t.column :message_id, :string, limit: 3000, null: true
|
t.column :message_id, :string, limit: 3000, null: true
|
||||||
t.column :message_id_md5, :string, limit: 32, null: true
|
t.column :message_id_md5, :string, limit: 32, null: true
|
||||||
t.column :in_reply_to, :string, limit: 3000, null: true
|
t.column :in_reply_to, :string, limit: 3000, null: true
|
||||||
|
t.column :content_type, :string, limit: 20, null: false, default: 'text/plain'
|
||||||
t.column :references, :string, limit: 3200, null: true
|
t.column :references, :string, limit: 3200, null: true
|
||||||
t.column :body, :text, limit: 4.megabytes + 1
|
t.column :body, :text, limit: 4.megabytes + 1
|
||||||
t.column :internal, :boolean, null: false, default: false
|
t.column :internal, :boolean, null: false, default: false
|
||||||
|
@ -248,9 +249,67 @@ class CreateTicket < ActiveRecord::Migration
|
||||||
t.timestamps
|
t.timestamps
|
||||||
end
|
end
|
||||||
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'
|
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.timestamps
|
||||||
|
end
|
||||||
|
add_index :postmaster_filters, [:channel]
|
||||||
|
|
||||||
|
create_table :text_modules do |t|
|
||||||
|
t.references :user, null: true
|
||||||
|
t.column :name, :string, limit: 250, null: false
|
||||||
|
t.column :keywords, :string, limit: 500, null: true
|
||||||
|
t.column :content, :string, limit: 5000, null: false
|
||||||
|
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
|
||||||
|
end
|
||||||
|
add_index :text_modules, [:user_id]
|
||||||
|
add_index :text_modules, [:name]
|
||||||
|
|
||||||
|
create_table :text_modules_groups, id: false do |t|
|
||||||
|
t.integer :text_module_id
|
||||||
|
t.integer :group_id
|
||||||
|
end
|
||||||
|
add_index :text_modules_groups, [:text_module_id]
|
||||||
|
add_index :text_modules_groups, [:group_id]
|
||||||
|
|
||||||
|
create_table :templates do |t|
|
||||||
|
t.references :user, null: true
|
||||||
|
t.column :name, :string, limit: 250, null: false
|
||||||
|
t.column :options, :string, limit: 2500, null: false
|
||||||
|
t.column :updated_by_id, :integer, null: false
|
||||||
|
t.column :created_by_id, :integer, null: false
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
add_index :templates, [:user_id]
|
||||||
|
add_index :templates, [:name]
|
||||||
|
|
||||||
|
create_table :templates_groups, id: false do |t|
|
||||||
|
t.integer :template_id
|
||||||
|
t.integer :group_id
|
||||||
|
end
|
||||||
|
add_index :templates_groups, [:template_id]
|
||||||
|
add_index :templates_groups, [:group_id]
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.down
|
def self.down
|
||||||
|
drop_table :templates_groups
|
||||||
|
drop_table :templates
|
||||||
|
drop_table :text_modules_groups
|
||||||
|
drop_table :text_modules
|
||||||
|
drop_table :postmaster_filters
|
||||||
drop_table :notifications
|
drop_table :notifications
|
||||||
drop_table :triggers
|
drop_table :triggers
|
||||||
drop_table :links
|
drop_table :links
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
class CreateStorage < ActiveRecord::Migration
|
|
||||||
def up
|
|
||||||
create_table :stores do |t|
|
|
||||||
t.references :store_object, null: false
|
|
||||||
t.references :store_file, null: false
|
|
||||||
t.column :o_id, :integer, limit: 8, null: false
|
|
||||||
t.column :preferences, :string, limit: 2500, null: true
|
|
||||||
t.column :size, :string, limit: 50, null: true
|
|
||||||
t.column :filename, :string, limit: 250, null: false
|
|
||||||
t.column :created_by_id, :integer, null: false
|
|
||||||
t.timestamps
|
|
||||||
end
|
|
||||||
add_index :stores, [:store_object_id, :o_id]
|
|
||||||
|
|
||||||
create_table :store_objects do |t|
|
|
||||||
t.column :name, :string, limit: 250, null: false
|
|
||||||
t.column :note, :string, limit: 250, null: true
|
|
||||||
t.timestamps
|
|
||||||
end
|
|
||||||
add_index :store_objects, [:name], unique: true
|
|
||||||
|
|
||||||
create_table :store_files do |t|
|
|
||||||
t.column :sha, :string, limit: 128, null: false
|
|
||||||
t.column :provider, :string, limit: 20, null: true
|
|
||||||
t.timestamps
|
|
||||||
end
|
|
||||||
add_index :store_files, [:sha], unique: true
|
|
||||||
add_index :store_files, [:provider]
|
|
||||||
|
|
||||||
create_table :store_provider_dbs do |t|
|
|
||||||
t.column :sha, :string, limit: 128, null: false
|
|
||||||
t.column :data, :binary, limit: 200.megabytes, null: true
|
|
||||||
t.timestamps
|
|
||||||
end
|
|
||||||
add_index :store_provider_dbs, [:sha], unique: true
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def down
|
|
||||||
drop_table :stores
|
|
||||||
drop_table :store_objects
|
|
||||||
drop_table :store_files
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,26 +0,0 @@
|
||||||
class CreateTemplate < ActiveRecord::Migration
|
|
||||||
def up
|
|
||||||
create_table :templates do |t|
|
|
||||||
t.references :user, null: true
|
|
||||||
t.column :name, :string, limit: 250, null: false
|
|
||||||
t.column :options, :string, limit: 2500, null: false
|
|
||||||
t.column :updated_by_id, :integer, null: false
|
|
||||||
t.column :created_by_id, :integer, null: false
|
|
||||||
t.timestamps
|
|
||||||
end
|
|
||||||
add_index :templates, [:user_id]
|
|
||||||
add_index :templates, [:name]
|
|
||||||
|
|
||||||
create_table :templates_groups, id: false do |t|
|
|
||||||
t.integer :template_id
|
|
||||||
t.integer :group_id
|
|
||||||
end
|
|
||||||
add_index :templates_groups, [:template_id]
|
|
||||||
add_index :templates_groups, [:group_id]
|
|
||||||
end
|
|
||||||
|
|
||||||
def down
|
|
||||||
drop_table :templates_groups
|
|
||||||
drop_table :templates
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,19 +0,0 @@
|
||||||
class PostmasterFilterCreate < ActiveRecord::Migration
|
|
||||||
def up
|
|
||||||
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.timestamps
|
|
||||||
end
|
|
||||||
add_index :postmaster_filters, [:channel]
|
|
||||||
end
|
|
||||||
|
|
||||||
def down
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,30 +0,0 @@
|
||||||
class TextModuleCreate < ActiveRecord::Migration
|
|
||||||
def up
|
|
||||||
create_table :text_modules do |t|
|
|
||||||
t.references :user, null: true
|
|
||||||
t.column :name, :string, limit: 250, null: false
|
|
||||||
t.column :keywords, :string, limit: 500, null: true
|
|
||||||
t.column :content, :string, limit: 5000, null: false
|
|
||||||
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
|
|
||||||
end
|
|
||||||
add_index :text_modules, [:user_id]
|
|
||||||
add_index :text_modules, [:name]
|
|
||||||
|
|
||||||
create_table :text_modules_groups, id: false do |t|
|
|
||||||
t.integer :text_module_id
|
|
||||||
t.integer :group_id
|
|
||||||
end
|
|
||||||
add_index :text_modules_groups, [:text_module_id]
|
|
||||||
add_index :text_modules_groups, [:group_id]
|
|
||||||
end
|
|
||||||
|
|
||||||
def down
|
|
||||||
drop_table :text_modules_groups
|
|
||||||
drop_table :text_modules
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,34 +0,0 @@
|
||||||
class UpdateTicketNumber < ActiveRecord::Migration
|
|
||||||
def up
|
|
||||||
Setting.create_or_update(
|
|
||||||
title: 'Ticket Number Format',
|
|
||||||
name: 'ticket_number',
|
|
||||||
area: 'Ticket::Number',
|
|
||||||
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).
|
|
||||||
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).',
|
|
||||||
options: {
|
|
||||||
form: [
|
|
||||||
{
|
|
||||||
display: '',
|
|
||||||
null: true,
|
|
||||||
name: 'ticket_number',
|
|
||||||
tag: 'select',
|
|
||||||
options: {
|
|
||||||
'Ticket::Number::Increment' => 'Increment (SystemID.Counter)',
|
|
||||||
'Ticket::Number::Date' => 'Date (Year.Month.Day.SystemID.Counter)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
state: 'Ticket::Number::Increment',
|
|
||||||
frontend: false
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def down
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,53 +0,0 @@
|
||||||
class UpdateAuth < ActiveRecord::Migration
|
|
||||||
def up
|
|
||||||
Setting.create_or_update(
|
|
||||||
title: 'Authentication via OTRS',
|
|
||||||
name: 'auth_otrs',
|
|
||||||
area: 'Security::Authentication',
|
|
||||||
description: 'Enables user authentication via OTRS.',
|
|
||||||
state: {
|
|
||||||
adapter: 'Auth::Otrs',
|
|
||||||
required_group_ro: 'stats',
|
|
||||||
group_rw_role_map: {
|
|
||||||
'admin' => 'Admin',
|
|
||||||
'stats' => 'Report',
|
|
||||||
},
|
|
||||||
group_ro_role_map: {
|
|
||||||
'stats' => 'Report',
|
|
||||||
},
|
|
||||||
always_role: {
|
|
||||||
'Agent' => true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
frontend: false
|
|
||||||
)
|
|
||||||
Setting.create_or_update(
|
|
||||||
title: 'Authentication via LDAP',
|
|
||||||
name: 'auth_ldap',
|
|
||||||
area: 'Security::Authentication',
|
|
||||||
description: 'Enables user authentication via LDAP.',
|
|
||||||
state: {
|
|
||||||
adapter: 'Auth::Ldap',
|
|
||||||
host: 'localhost',
|
|
||||||
port: 389,
|
|
||||||
bind_dn: 'cn=Manager,dc=example,dc=org',
|
|
||||||
bind_pw: 'example',
|
|
||||||
uid: 'mail',
|
|
||||||
base: 'dc=example,dc=org',
|
|
||||||
always_filter: '',
|
|
||||||
always_roles: %w(Admin Agent),
|
|
||||||
always_groups: ['Users'],
|
|
||||||
sync_params: {
|
|
||||||
firstname: 'sn',
|
|
||||||
lastname: 'givenName',
|
|
||||||
email: 'mail',
|
|
||||||
login: 'mail',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
frontend: false
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def down
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,59 +0,0 @@
|
||||||
class AddSearchIndex < ActiveRecord::Migration
|
|
||||||
def up
|
|
||||||
Setting.create_or_update(
|
|
||||||
title: 'Elasticsearch Endpoint URL',
|
|
||||||
name: 'es_url',
|
|
||||||
area: 'SearchIndex::Elasticsearch',
|
|
||||||
description: 'Define endpoint of Elastic Search.',
|
|
||||||
state: '',
|
|
||||||
frontend: false
|
|
||||||
)
|
|
||||||
Setting.create_or_update(
|
|
||||||
title: 'Elasticsearch Endpoint User',
|
|
||||||
name: 'es_user',
|
|
||||||
area: 'SearchIndex::Elasticsearch',
|
|
||||||
description: 'Define http basic auth user of Elasticsearch.',
|
|
||||||
state: '',
|
|
||||||
frontend: false
|
|
||||||
)
|
|
||||||
Setting.create_or_update(
|
|
||||||
title: 'Elastic Search Endpoint Password',
|
|
||||||
name: 'es_password',
|
|
||||||
area: 'SearchIndex::Elasticsearch',
|
|
||||||
description: 'Define http basic auth password of Elasticsearch.',
|
|
||||||
state: '',
|
|
||||||
frontend: false
|
|
||||||
)
|
|
||||||
Setting.create_or_update(
|
|
||||||
title: 'Elastic Search Endpoint Index',
|
|
||||||
name: 'es_index',
|
|
||||||
area: 'SearchIndex::Elasticsearch',
|
|
||||||
description: 'Define Elasticsearch index name.',
|
|
||||||
state: 'zammad',
|
|
||||||
frontend: false
|
|
||||||
)
|
|
||||||
Setting.create_or_update(
|
|
||||||
title: 'Elastic Search Attachment Extentions',
|
|
||||||
name: 'es_attachment_ignore',
|
|
||||||
area: 'SearchIndex::Elasticsearch',
|
|
||||||
description: 'Define attachment extentions which are ignored for Elasticsearch.',
|
|
||||||
state: [ '.png', '.jpg', '.jpeg', '.mpeg', '.mpg', '.mov', '.bin', '.exe', '.box', '.mbox' ],
|
|
||||||
frontend: false
|
|
||||||
)
|
|
||||||
Setting.create_or_update(
|
|
||||||
title: 'Elastic Search Attachment Size',
|
|
||||||
name: 'es_attachment_max_size_in_mb',
|
|
||||||
area: 'SearchIndex::Elasticsearch',
|
|
||||||
description: 'Define max. attachment size for Elasticsearch.',
|
|
||||||
state: 50,
|
|
||||||
frontend: false
|
|
||||||
)
|
|
||||||
|
|
||||||
Ticket.search_index_reload
|
|
||||||
User.search_index_reload
|
|
||||||
Organization.search_index_reload
|
|
||||||
end
|
|
||||||
|
|
||||||
def down
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,51 +0,0 @@
|
||||||
class UpdateSetting1 < ActiveRecord::Migration
|
|
||||||
def up
|
|
||||||
Setting.create_if_not_exists(
|
|
||||||
title: 'Send client stats',
|
|
||||||
name: 'ui_send_client_stats',
|
|
||||||
area: 'System::UI',
|
|
||||||
description: 'Send client stats to central server.',
|
|
||||||
options: {
|
|
||||||
form: [
|
|
||||||
{
|
|
||||||
display: '',
|
|
||||||
null: true,
|
|
||||||
name: 'ui_send_client_stats',
|
|
||||||
tag: 'boolean',
|
|
||||||
options: {
|
|
||||||
true => 'yes',
|
|
||||||
false => 'no',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
state: true,
|
|
||||||
frontend: true
|
|
||||||
)
|
|
||||||
Setting.create_if_not_exists(
|
|
||||||
title: 'Client storage',
|
|
||||||
name: 'ui_client_storage',
|
|
||||||
area: 'System::UI',
|
|
||||||
description: 'Use client storage to cache data to perform speed of application.',
|
|
||||||
options: {
|
|
||||||
form: [
|
|
||||||
{
|
|
||||||
display: '',
|
|
||||||
null: true,
|
|
||||||
name: 'ui_client_storage',
|
|
||||||
tag: 'boolean',
|
|
||||||
options: {
|
|
||||||
true => 'yes',
|
|
||||||
false => 'no',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
state: false,
|
|
||||||
frontend: true
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def down
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,8 +0,0 @@
|
||||||
class UpdateTicketArticleSize < ActiveRecord::Migration
|
|
||||||
def up
|
|
||||||
change_column :ticket_articles, :body, :text, limit: 4.megabytes + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
def down
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,25 +0,0 @@
|
||||||
class UpdateSetting2 < ActiveRecord::Migration
|
|
||||||
def up
|
|
||||||
Setting.create_if_not_exists(
|
|
||||||
title: 'Logo',
|
|
||||||
name: 'product_logo',
|
|
||||||
area: 'System::CI',
|
|
||||||
description: 'Defines the logo of the application, shown in the web interface.',
|
|
||||||
options: {
|
|
||||||
form: [
|
|
||||||
{
|
|
||||||
display: '',
|
|
||||||
null: false,
|
|
||||||
name: 'product_logo',
|
|
||||||
tag: 'input',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
state: 'logo.svg',
|
|
||||||
frontend: true
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def down
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,16 +0,0 @@
|
||||||
class UpdateSetting3 < ActiveRecord::Migration
|
|
||||||
def up
|
|
||||||
Setting.create_if_not_exists(
|
|
||||||
title: 'Online Service',
|
|
||||||
name: 'system_online_service',
|
|
||||||
area: 'Core',
|
|
||||||
description: 'Defines if application is used as online service.',
|
|
||||||
options: {},
|
|
||||||
state: false,
|
|
||||||
frontend: true
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def down
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -5,7 +5,7 @@ class CreateAvatar < ActiveRecord::Migration
|
||||||
t.column :object_lookup_id, :integer, null: false
|
t.column :object_lookup_id, :integer, null: false
|
||||||
t.column :default, :boolean, null: false, default: false
|
t.column :default, :boolean, null: false, default: false
|
||||||
t.column :deletable, :boolean, null: false, default: true
|
t.column :deletable, :boolean, null: false, default: true
|
||||||
t.column :inital, :boolean, null: false, default: false
|
t.column :initial, :boolean, null: false, default: false
|
||||||
t.column :store_full_id, :integer, null: true
|
t.column :store_full_id, :integer, null: true
|
||||||
t.column :store_resize_id, :integer, null: true
|
t.column :store_resize_id, :integer, null: true
|
||||||
t.column :store_hash, :string, limit: 32, null: true
|
t.column :store_hash, :string, limit: 32, null: true
|
||||||
|
|
|
@ -487,6 +487,44 @@ class UpdateObjectManager2 < ActiveRecord::Migration
|
||||||
updated_by_id: 1,
|
updated_by_id: 1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ObjectManager::Attribute.add(
|
||||||
|
object: 'User',
|
||||||
|
name: 'vip',
|
||||||
|
display: 'VIP',
|
||||||
|
data_type: 'boolean',
|
||||||
|
data_option: {
|
||||||
|
null: true,
|
||||||
|
default: false,
|
||||||
|
item_class: 'formGroup--halfSize',
|
||||||
|
options: {
|
||||||
|
false: 'no',
|
||||||
|
true: 'yes',
|
||||||
|
},
|
||||||
|
translate: true,
|
||||||
|
},
|
||||||
|
editable: false,
|
||||||
|
active: true,
|
||||||
|
screens: {
|
||||||
|
edit: {
|
||||||
|
Admin: {
|
||||||
|
null: true,
|
||||||
|
},
|
||||||
|
Agent: {
|
||||||
|
null: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
view: {
|
||||||
|
'-all-' => {
|
||||||
|
shown: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pending_migration: false,
|
||||||
|
position: 1490,
|
||||||
|
created_by_id: 1,
|
||||||
|
updated_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
ObjectManager::Attribute.add(
|
ObjectManager::Attribute.add(
|
||||||
object: 'User',
|
object: 'User',
|
||||||
name: 'note',
|
name: 'note',
|
||||||
|
@ -594,7 +632,6 @@ class UpdateObjectManager2 < ActiveRecord::Migration
|
||||||
display: 'Active',
|
display: 'Active',
|
||||||
data_type: 'active',
|
data_type: 'active',
|
||||||
data_option: {
|
data_option: {
|
||||||
null: true,
|
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
editable: false,
|
editable: false,
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
class UpdateTicketArticle < ActiveRecord::Migration
|
|
||||||
def up
|
|
||||||
add_column :ticket_articles, :content_type, :string, limit: 20, null: false, default: 'text/plain'
|
|
||||||
end
|
|
||||||
|
|
||||||
def down
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,16 +0,0 @@
|
||||||
class AddDevelopMode < ActiveRecord::Migration
|
|
||||||
def up
|
|
||||||
Setting.create_if_not_exists(
|
|
||||||
title: 'Develop System',
|
|
||||||
name: 'developer_mode',
|
|
||||||
area: 'Core::Develop',
|
|
||||||
description: 'Defines if application is in developer mode (useful for developer, all users have the same password, password reset will work without email delivery).',
|
|
||||||
options: {},
|
|
||||||
state: false,
|
|
||||||
frontend: true
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def down
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,47 +0,0 @@
|
||||||
class CreateVip < ActiveRecord::Migration
|
|
||||||
def up
|
|
||||||
add_column :users, :vip, :boolean, default: false
|
|
||||||
|
|
||||||
ObjectManager::Attribute.add(
|
|
||||||
object: 'User',
|
|
||||||
name: 'vip',
|
|
||||||
display: 'VIP',
|
|
||||||
data_type: 'boolean',
|
|
||||||
data_option: {
|
|
||||||
null: true,
|
|
||||||
default: false,
|
|
||||||
item_class: 'formGroup--halfSize',
|
|
||||||
options: {
|
|
||||||
false: 'no',
|
|
||||||
true: 'yes',
|
|
||||||
},
|
|
||||||
translate: true,
|
|
||||||
},
|
|
||||||
editable: false,
|
|
||||||
active: true,
|
|
||||||
screens: {
|
|
||||||
edit: {
|
|
||||||
Admin: {
|
|
||||||
null: true,
|
|
||||||
},
|
|
||||||
Agent: {
|
|
||||||
null: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
view: {
|
|
||||||
'-all-' => {
|
|
||||||
shown: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
pending_migration: false,
|
|
||||||
position: 1490,
|
|
||||||
created_by_id: 1,
|
|
||||||
updated_by_id: 1,
|
|
||||||
)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def down
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,100 +0,0 @@
|
||||||
class UpdateObjectManager3 < ActiveRecord::Migration
|
|
||||||
def up
|
|
||||||
|
|
||||||
ObjectManager::Attribute.add(
|
|
||||||
object: 'User',
|
|
||||||
name: 'active',
|
|
||||||
display: 'Active',
|
|
||||||
data_type: 'active',
|
|
||||||
data_option: {
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
editable: false,
|
|
||||||
active: true,
|
|
||||||
screens: {
|
|
||||||
signup: {},
|
|
||||||
invite_agent: {},
|
|
||||||
edit: {
|
|
||||||
Admin: {
|
|
||||||
null: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
view: {
|
|
||||||
'-all-' => {
|
|
||||||
shown: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
pending_migration: false,
|
|
||||||
position: 1800,
|
|
||||||
created_by_id: 1,
|
|
||||||
updated_by_id: 1,
|
|
||||||
)
|
|
||||||
|
|
||||||
ObjectManager::Attribute.add(
|
|
||||||
object: 'Organization',
|
|
||||||
name: 'active',
|
|
||||||
display: 'Active',
|
|
||||||
data_type: 'active',
|
|
||||||
data_option: {
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
editable: false,
|
|
||||||
active: true,
|
|
||||||
screens: {
|
|
||||||
edit: {
|
|
||||||
Admin: {
|
|
||||||
null: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
view: {
|
|
||||||
'-all-' => {
|
|
||||||
shown: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
pending_migration: false,
|
|
||||||
position: 1800,
|
|
||||||
created_by_id: 1,
|
|
||||||
updated_by_id: 1,
|
|
||||||
)
|
|
||||||
|
|
||||||
ObjectManager::Attribute.add(
|
|
||||||
object: 'User',
|
|
||||||
name: 'password',
|
|
||||||
display: 'Password',
|
|
||||||
data_type: 'input',
|
|
||||||
data_option: {
|
|
||||||
type: 'password',
|
|
||||||
maxlength: 100,
|
|
||||||
null: true,
|
|
||||||
autocomplete: 'off',
|
|
||||||
item_class: 'formGroup--halfSize',
|
|
||||||
},
|
|
||||||
editable: false,
|
|
||||||
active: true,
|
|
||||||
screens: {
|
|
||||||
signup: {
|
|
||||||
'-all-' => {
|
|
||||||
null: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
invite_agent: {},
|
|
||||||
edit: {
|
|
||||||
Admin: {
|
|
||||||
null: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
view: {}
|
|
||||||
},
|
|
||||||
pending_migration: false,
|
|
||||||
position: 1400,
|
|
||||||
created_by_id: 1,
|
|
||||||
updated_by_id: 1,
|
|
||||||
)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def down
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,9 +0,0 @@
|
||||||
class RenameAvatarTypo < ActiveRecord::Migration
|
|
||||||
def up
|
|
||||||
rename_column :avatars, :inital, :initial
|
|
||||||
end
|
|
||||||
|
|
||||||
def down
|
|
||||||
rename_column :avatars, :initial, :inital
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,30 +0,0 @@
|
||||||
class UpdateGeoIpConfig < ActiveRecord::Migration
|
|
||||||
def up
|
|
||||||
Setting.create_or_update(
|
|
||||||
title: 'Geo IP Backend',
|
|
||||||
name: 'geo_ip_backend',
|
|
||||||
area: 'System::Geo',
|
|
||||||
description: 'Defines the backend for geo ip lookups.',
|
|
||||||
options: {
|
|
||||||
form: [
|
|
||||||
{
|
|
||||||
display: '',
|
|
||||||
null: true,
|
|
||||||
name: 'geo_ip_backend',
|
|
||||||
tag: 'select',
|
|
||||||
options: {
|
|
||||||
'' => '-',
|
|
||||||
'GeoIp::ZammadGeoIp' => 'Zammad GeoIP Service',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
state: 'GeoIp::ZammadGeoIp',
|
|
||||||
frontend: false
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def down
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,12 +0,0 @@
|
||||||
class AddBaseIndexes < ActiveRecord::Migration
|
|
||||||
def change
|
|
||||||
add_index :users, [:organization_id]
|
|
||||||
add_index :roles_users, [:user_id]
|
|
||||||
add_index :roles_users, [:role_id]
|
|
||||||
add_index :groups_users, [:user_id]
|
|
||||||
add_index :groups_users, [:group_id]
|
|
||||||
add_index :organizations_users, [:user_id]
|
|
||||||
add_index :organizations_users, [:organization_id]
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
33
db/migrate/20150701000001_add_cleanup.rb
Normal file
33
db/migrate/20150701000001_add_cleanup.rb
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
class AddCleanup < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
|
||||||
|
# delete old entries
|
||||||
|
Scheduler.create_or_update(
|
||||||
|
name: 'Delete old activity stream entries.',
|
||||||
|
method: 'ActivityStream.cleanup',
|
||||||
|
period: 1.day,
|
||||||
|
prio: 2,
|
||||||
|
active: true,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
Scheduler.create_or_update(
|
||||||
|
name: 'Delete old online notification entries.',
|
||||||
|
method: 'OnlineNotification.cleanup',
|
||||||
|
period: 1.day,
|
||||||
|
prio: 2,
|
||||||
|
active: true,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
Scheduler.create_or_update(
|
||||||
|
name: 'Delete old entries.',
|
||||||
|
method: 'RecentView.cleanup',
|
||||||
|
period: 1.day,
|
||||||
|
prio: 2,
|
||||||
|
active: true,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
49
db/seeds.rb
49
db/seeds.rb
|
@ -1130,6 +1130,55 @@ Setting.create_if_not_exists(
|
||||||
frontend: true
|
frontend: true
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Setting.create_if_not_exists(
|
||||||
|
title: 'Elasticsearch Endpoint URL',
|
||||||
|
name: 'es_url',
|
||||||
|
area: 'SearchIndex::Elasticsearch',
|
||||||
|
description: 'Define endpoint of Elastic Search.',
|
||||||
|
state: '',
|
||||||
|
frontend: false
|
||||||
|
)
|
||||||
|
Setting.create_if_not_exists(
|
||||||
|
title: 'Elasticsearch Endpoint User',
|
||||||
|
name: 'es_user',
|
||||||
|
area: 'SearchIndex::Elasticsearch',
|
||||||
|
description: 'Define http basic auth user of Elasticsearch.',
|
||||||
|
state: '',
|
||||||
|
frontend: false
|
||||||
|
)
|
||||||
|
Setting.create_if_not_exists(
|
||||||
|
title: 'Elastic Search Endpoint Password',
|
||||||
|
name: 'es_password',
|
||||||
|
area: 'SearchIndex::Elasticsearch',
|
||||||
|
description: 'Define http basic auth password of Elasticsearch.',
|
||||||
|
state: '',
|
||||||
|
frontend: false
|
||||||
|
)
|
||||||
|
Setting.create_if_not_exists(
|
||||||
|
title: 'Elastic Search Endpoint Index',
|
||||||
|
name: 'es_index',
|
||||||
|
area: 'SearchIndex::Elasticsearch',
|
||||||
|
description: 'Define Elasticsearch index name.',
|
||||||
|
state: 'zammad',
|
||||||
|
frontend: false
|
||||||
|
)
|
||||||
|
Setting.create_if_not_exists(
|
||||||
|
title: 'Elastic Search Attachment Extentions',
|
||||||
|
name: 'es_attachment_ignore',
|
||||||
|
area: 'SearchIndex::Elasticsearch',
|
||||||
|
description: 'Define attachment extentions which are ignored for Elasticsearch.',
|
||||||
|
state: [ '.png', '.jpg', '.jpeg', '.mpeg', '.mpg', '.mov', '.bin', '.exe', '.box', '.mbox' ],
|
||||||
|
frontend: false
|
||||||
|
)
|
||||||
|
Setting.create_if_not_exists(
|
||||||
|
title: 'Elastic Search Attachment Size',
|
||||||
|
name: 'es_attachment_max_size_in_mb',
|
||||||
|
area: 'SearchIndex::Elasticsearch',
|
||||||
|
description: 'Define max. attachment size for Elasticsearch.',
|
||||||
|
state: 50,
|
||||||
|
frontend: false
|
||||||
|
)
|
||||||
|
|
||||||
Setting.create_if_not_exists(
|
Setting.create_if_not_exists(
|
||||||
title: 'Import Mode',
|
title: 'Import Mode',
|
||||||
name: 'import_mode',
|
name: 'import_mode',
|
||||||
|
|
|
@ -35,6 +35,21 @@ class String
|
||||||
camel_cased_word.gsub(/::/, '/').downcase
|
camel_cased_word.gsub(/::/, '/').downcase
|
||||||
end
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
filename = 'some/module.rb'.to_classname
|
||||||
|
|
||||||
|
returns
|
||||||
|
'Some::Module'
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def to_classname
|
||||||
|
camel_cased_word = "#{self}"
|
||||||
|
camel_cased_word.gsub!(/\.rb$/, '')
|
||||||
|
camel_cased_word.split('/').map(&:camelize).join('::')
|
||||||
|
end
|
||||||
|
|
||||||
# because of mysql inno_db limitations, strip 4 bytes utf8 chars (e. g. emojis)
|
# because of mysql inno_db limitations, strip 4 bytes utf8 chars (e. g. emojis)
|
||||||
# unfortunaly UTF8mb4 will raise other limitaions of max varchar and lower index sizes
|
# unfortunaly UTF8mb4 will raise other limitaions of max varchar and lower index sizes
|
||||||
# More details: http://pjambet.github.io/blog/emojis-and-mysql/
|
# More details: http://pjambet.github.io/blog/emojis-and-mysql/
|
||||||
|
|
121
lib/models.rb
Normal file
121
lib/models.rb
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
class Models
|
||||||
|
include ApplicationLib
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
get list of models
|
||||||
|
|
||||||
|
result = Models.all
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
{
|
||||||
|
'Some::Classname1' => {
|
||||||
|
attributes: ['id', 'name', '...']
|
||||||
|
reflections: ...model.reflections...
|
||||||
|
},
|
||||||
|
'Some::Classname2' => {
|
||||||
|
attributes: ['id', 'name', '...']
|
||||||
|
reflections: ...model.reflections...
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def self.all
|
||||||
|
all = {}
|
||||||
|
dir = "#{Rails.root}/app/models/"
|
||||||
|
Dir.glob( "#{dir}**/*.rb" ) do |entry|
|
||||||
|
next if entry =~ /application_model/i
|
||||||
|
next if entry =~ /channel\//i
|
||||||
|
next if entry =~ /observer\//i
|
||||||
|
next if entry =~ /store\/provider\//i
|
||||||
|
entry.gsub!(dir, '')
|
||||||
|
entry = entry.to_classname
|
||||||
|
model_class = load_adapter(entry)
|
||||||
|
next if !model_class
|
||||||
|
next if !model_class.respond_to? :new
|
||||||
|
model_object = model_class.new
|
||||||
|
next if !model_object.respond_to? :attributes
|
||||||
|
all[model_class] = {}
|
||||||
|
all[model_class][:attributes] = model_class.attribute_names
|
||||||
|
all[model_class][:reflections] = model_class.reflections
|
||||||
|
#puts "rrrr #{all[model_class][:attributes]}"
|
||||||
|
#puts model.class
|
||||||
|
#puts " #{model.attribute_names.inspect}"
|
||||||
|
end
|
||||||
|
all
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
get reference list of a models
|
||||||
|
|
||||||
|
result = Models.references('User', 2)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
{
|
||||||
|
'Some::Classname1' => {
|
||||||
|
attributes: ['id', 'name', '...']
|
||||||
|
reflections: ...model.reflections...
|
||||||
|
},
|
||||||
|
'Some::Classname2' => {
|
||||||
|
attributes: ['id', 'name', '...']
|
||||||
|
reflections: ...model.reflections...
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def self.references(object_name, object_id)
|
||||||
|
object_model = load_adapter(object_name)
|
||||||
|
object_model.find(object_id)
|
||||||
|
list = all
|
||||||
|
references = {
|
||||||
|
model: {},
|
||||||
|
total: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
# find relations via attributes
|
||||||
|
list.each {|model_class, model_attributes|
|
||||||
|
references[:model][model_class.to_s] = 0
|
||||||
|
next if !model_attributes[:attributes]
|
||||||
|
['created_by_id', 'updated_by_id'].each {|item|
|
||||||
|
if model_attributes[:attributes].include?(item)
|
||||||
|
count = model_class.where("#{item} = ?", object_id).count
|
||||||
|
next if count == 0
|
||||||
|
Rails.logger.debug "FOUND (by id) #{model_class}->#{item} #{count}!"
|
||||||
|
references[:model][model_class.to_s] += count
|
||||||
|
end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# find relations via reflections
|
||||||
|
list.each {|model_class, model_attributes|
|
||||||
|
next if !model_attributes[:reflections]
|
||||||
|
model_attributes[:reflections].each{|reflection_key, reflection_value|
|
||||||
|
next if reflection_value.macro != :belongs_to
|
||||||
|
if reflection_value.options[:class_name] == object_name
|
||||||
|
count = model_class.where("#{reflection_value.name}_id = ?", object_id).count
|
||||||
|
next if count == 0
|
||||||
|
Rails.logger.debug "FOUND (by ref without class) #{model_class}->#{reflection_value.name} #{count}!"
|
||||||
|
references[:model][model_class.to_s] += count
|
||||||
|
end
|
||||||
|
if !reflection_value.options[:class_name] && reflection_value.name == object_name.downcase.to_sym
|
||||||
|
count = model_class.where("#{reflection_value.name}_id = ?", object_id).count
|
||||||
|
next if count == 0
|
||||||
|
Rails.logger.debug "FOUND (by ref with class) #{model_class}->#{reflection_value.name} #{count}!"
|
||||||
|
references[:model][model_class.to_s] += count
|
||||||
|
end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
references[:model].each {|k, v|
|
||||||
|
next if v == 0
|
||||||
|
references[:total] += v
|
||||||
|
}
|
||||||
|
references
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -25,6 +25,36 @@ class AaaStringTest < ActiveSupport::TestCase
|
||||||
assert_equal( result, modul.to_filename )
|
assert_equal( result, modul.to_filename )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test 'to_classname ref' do
|
||||||
|
modul = 'test'
|
||||||
|
result = 'test'
|
||||||
|
modul.to_filename
|
||||||
|
assert_equal( result, modul )
|
||||||
|
|
||||||
|
modul = 'some/file'
|
||||||
|
result = 'some/file'
|
||||||
|
modul.to_filename
|
||||||
|
assert_equal( result, modul )
|
||||||
|
end
|
||||||
|
|
||||||
|
test 'to_classname function' do
|
||||||
|
modul = 'test'
|
||||||
|
result = 'Test'
|
||||||
|
assert_equal( result, modul.to_classname )
|
||||||
|
|
||||||
|
modul = 'some/file'
|
||||||
|
result = 'Some::File'
|
||||||
|
assert_equal( result, modul.to_classname )
|
||||||
|
|
||||||
|
modul = 'some/files'
|
||||||
|
result = 'Some::Files'
|
||||||
|
assert_equal( result, modul.to_classname )
|
||||||
|
|
||||||
|
modul = 'some_test/files'
|
||||||
|
result = 'SomeTest::Files'
|
||||||
|
assert_equal( result, modul.to_classname )
|
||||||
|
end
|
||||||
|
|
||||||
test 'html2text ref' do
|
test 'html2text ref' do
|
||||||
html = 'test'
|
html = 'test'
|
||||||
result = 'test'
|
result = 'test'
|
||||||
|
|
84
test/unit/model_test.rb
Normal file
84
test/unit/model_test.rb
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
# encoding: utf-8
|
||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class ModelTest < ActiveSupport::TestCase
|
||||||
|
test 'references test' do
|
||||||
|
|
||||||
|
# create base
|
||||||
|
groups = Group.where( name: 'Users' )
|
||||||
|
roles = Role.where( name: ['Agent', 'Admin'] )
|
||||||
|
agent1 = User.create_or_update(
|
||||||
|
login: 'model-agent1@example.com',
|
||||||
|
firstname: 'Model',
|
||||||
|
lastname: 'Agent1',
|
||||||
|
email: 'model-agent1@example.com',
|
||||||
|
password: 'agentpw',
|
||||||
|
active: true,
|
||||||
|
roles: roles,
|
||||||
|
groups: groups,
|
||||||
|
updated_at: '2015-02-05 16:37:00',
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
organization1 = Organization.create_if_not_exists(
|
||||||
|
name: 'Model Org 1',
|
||||||
|
updated_at: '2015-02-05 16:37:00',
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
organization2 = Organization.create_if_not_exists(
|
||||||
|
name: 'Model Org 2',
|
||||||
|
updated_at: '2015-02-05 16:37:00',
|
||||||
|
updated_by_id: agent1.id,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
roles = Role.where( name: 'Customer' )
|
||||||
|
customer1 = User.create_or_update(
|
||||||
|
login: 'model-customer1@example.com',
|
||||||
|
firstname: 'Model',
|
||||||
|
lastname: 'Customer1',
|
||||||
|
email: 'model-customer1@example.com',
|
||||||
|
password: 'customerpw',
|
||||||
|
active: true,
|
||||||
|
organization_id: organization1.id,
|
||||||
|
roles: roles,
|
||||||
|
updated_at: '2015-02-05 16:37:00',
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
customer2 = User.create_or_update(
|
||||||
|
login: 'model-customer2@example.com',
|
||||||
|
firstname: 'Model',
|
||||||
|
lastname: 'Customer2',
|
||||||
|
email: 'model-customer2@example.com',
|
||||||
|
password: 'customerpw',
|
||||||
|
active: true,
|
||||||
|
organization_id: nil,
|
||||||
|
roles: roles,
|
||||||
|
updated_at: '2015-02-05 16:37:00',
|
||||||
|
updated_by_id: agent1.id,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
customer3 = User.create_or_update(
|
||||||
|
login: 'model-customer3@example.com',
|
||||||
|
firstname: 'Model',
|
||||||
|
lastname: 'Customer3',
|
||||||
|
email: 'model-customer3@example.com',
|
||||||
|
password: 'customerpw',
|
||||||
|
active: true,
|
||||||
|
organization_id: nil,
|
||||||
|
roles: roles,
|
||||||
|
updated_at: '2015-02-05 16:37:00',
|
||||||
|
updated_by_id: agent1.id,
|
||||||
|
created_by_id: agent1.id,
|
||||||
|
)
|
||||||
|
|
||||||
|
references = Models.references('User', agent1.id)
|
||||||
|
|
||||||
|
assert_equal(references[:model]['User'], 3)
|
||||||
|
assert_equal(references[:model]['Organization'], 1)
|
||||||
|
assert_equal(references[:model]['Group'], 0)
|
||||||
|
assert_equal(references[:total], 6)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in a new issue