Refactoring: Splitted ApplicationModel into multiple concerns. Notice: Includes object some method name changes.
This commit is contained in:
parent
f7e9b570ae
commit
ef6fbe8f2a
68 changed files with 2211 additions and 2277 deletions
|
@ -394,7 +394,7 @@ class ApplicationController < ActionController::Base
|
||||||
# remember time accounting
|
# remember time accounting
|
||||||
time_unit = params[:time_unit]
|
time_unit = params[:time_unit]
|
||||||
|
|
||||||
clean_params = Ticket::Article.param_association_lookup(params)
|
clean_params = Ticket::Article.association_name_to_id_convert(params)
|
||||||
clean_params = Ticket::Article.param_cleanup(clean_params, true)
|
clean_params = Ticket::Article.param_cleanup(clean_params, true)
|
||||||
|
|
||||||
# overwrite params
|
# overwrite params
|
||||||
|
@ -514,7 +514,7 @@ class ApplicationController < ActionController::Base
|
||||||
# model helper
|
# model helper
|
||||||
def model_create_render(object, params)
|
def model_create_render(object, params)
|
||||||
|
|
||||||
clean_params = object.param_association_lookup(params)
|
clean_params = object.association_name_to_id_convert(params)
|
||||||
clean_params = object.param_cleanup(clean_params, true)
|
clean_params = object.param_cleanup(clean_params, true)
|
||||||
|
|
||||||
# create object
|
# create object
|
||||||
|
@ -524,10 +524,10 @@ class ApplicationController < ActionController::Base
|
||||||
generic_object.save!
|
generic_object.save!
|
||||||
|
|
||||||
# set relations
|
# set relations
|
||||||
generic_object.param_set_associations(params)
|
generic_object.associations_from_param(params)
|
||||||
|
|
||||||
if params[:expand]
|
if params[:expand]
|
||||||
render json: generic_object.attributes_with_relation_names, status: :created
|
render json: generic_object.attributes_with_association_names, status: :created
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -535,7 +535,7 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def model_create_render_item(generic_object)
|
def model_create_render_item(generic_object)
|
||||||
render json: generic_object.attributes_with_associations, status: :created
|
render json: generic_object.attributes_with_association_ids, status: :created
|
||||||
end
|
end
|
||||||
|
|
||||||
def model_update_render(object, params)
|
def model_update_render(object, params)
|
||||||
|
@ -543,7 +543,7 @@ class ApplicationController < ActionController::Base
|
||||||
# find object
|
# find object
|
||||||
generic_object = object.find(params[:id])
|
generic_object = object.find(params[:id])
|
||||||
|
|
||||||
clean_params = object.param_association_lookup(params)
|
clean_params = object.association_name_to_id_convert(params)
|
||||||
clean_params = object.param_cleanup(clean_params, true)
|
clean_params = object.param_cleanup(clean_params, true)
|
||||||
|
|
||||||
generic_object.with_lock do
|
generic_object.with_lock do
|
||||||
|
@ -552,11 +552,11 @@ class ApplicationController < ActionController::Base
|
||||||
generic_object.update_attributes!(clean_params)
|
generic_object.update_attributes!(clean_params)
|
||||||
|
|
||||||
# set relations
|
# set relations
|
||||||
generic_object.param_set_associations(params)
|
generic_object.associations_from_param(params)
|
||||||
end
|
end
|
||||||
|
|
||||||
if params[:expand]
|
if params[:expand]
|
||||||
render json: generic_object.attributes_with_relation_names, status: :ok
|
render json: generic_object.attributes_with_association_names, status: :ok
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -564,7 +564,7 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def model_update_render_item(generic_object)
|
def model_update_render_item(generic_object)
|
||||||
render json: generic_object.attributes_with_associations, status: :ok
|
render json: generic_object.attributes_with_association_ids, status: :ok
|
||||||
end
|
end
|
||||||
|
|
||||||
def model_destroy_render(object, params)
|
def model_destroy_render(object, params)
|
||||||
|
@ -581,7 +581,7 @@ class ApplicationController < ActionController::Base
|
||||||
|
|
||||||
if params[:expand]
|
if params[:expand]
|
||||||
generic_object = object.find(params[:id])
|
generic_object = object.find(params[:id])
|
||||||
render json: generic_object.attributes_with_relation_names, status: :ok
|
render json: generic_object.attributes_with_association_names, status: :ok
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -596,7 +596,7 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def model_show_render_item(generic_object)
|
def model_show_render_item(generic_object)
|
||||||
render json: generic_object.attributes_with_associations, status: :ok
|
render json: generic_object.attributes_with_association_ids, status: :ok
|
||||||
end
|
end
|
||||||
|
|
||||||
def model_index_render(object, params)
|
def model_index_render(object, params)
|
||||||
|
@ -620,7 +620,7 @@ class ApplicationController < ActionController::Base
|
||||||
if params[:expand]
|
if params[:expand]
|
||||||
list = []
|
list = []
|
||||||
generic_objects.each { |generic_object|
|
generic_objects.each { |generic_object|
|
||||||
list.push generic_object.attributes_with_relation_names
|
list.push generic_object.attributes_with_association_names
|
||||||
}
|
}
|
||||||
render json: list, status: :ok
|
render json: list, status: :ok
|
||||||
return
|
return
|
||||||
|
@ -642,7 +642,7 @@ class ApplicationController < ActionController::Base
|
||||||
|
|
||||||
generic_objects_with_associations = []
|
generic_objects_with_associations = []
|
||||||
generic_objects.each { |item|
|
generic_objects.each { |item|
|
||||||
generic_objects_with_associations.push item.attributes_with_associations
|
generic_objects_with_associations.push item.attributes_with_association_ids
|
||||||
}
|
}
|
||||||
model_index_render_result(generic_objects_with_associations)
|
model_index_render_result(generic_objects_with_associations)
|
||||||
end
|
end
|
||||||
|
|
|
@ -43,7 +43,7 @@ class ObjectManagerAttributesController < ApplicationController
|
||||||
position: 1550,
|
position: 1550,
|
||||||
editable: true,
|
editable: true,
|
||||||
)
|
)
|
||||||
render json: object_manager_attribute.attributes_with_associations, status: :created
|
render json: object_manager_attribute.attributes_with_association_ids, status: :created
|
||||||
rescue => e
|
rescue => e
|
||||||
raise Exceptions::UnprocessableEntity, e
|
raise Exceptions::UnprocessableEntity, e
|
||||||
end
|
end
|
||||||
|
@ -64,7 +64,7 @@ class ObjectManagerAttributesController < ApplicationController
|
||||||
position: 1550,
|
position: 1550,
|
||||||
editable: true,
|
editable: true,
|
||||||
)
|
)
|
||||||
render json: object_manager_attribute.attributes_with_associations, status: :ok
|
render json: object_manager_attribute.attributes_with_association_ids, status: :ok
|
||||||
rescue => e
|
rescue => e
|
||||||
raise Exceptions::UnprocessableEntity, e
|
raise Exceptions::UnprocessableEntity, e
|
||||||
end
|
end
|
||||||
|
|
|
@ -72,7 +72,7 @@ curl http://localhost/api/v1/organizations -v -u #{login}:#{password}
|
||||||
if params[:expand]
|
if params[:expand]
|
||||||
list = []
|
list = []
|
||||||
organizations.each { |organization|
|
organizations.each { |organization|
|
||||||
list.push organization.attributes_with_relation_names
|
list.push organization.attributes_with_association_names
|
||||||
}
|
}
|
||||||
render json: list, status: :ok
|
render json: list, status: :ok
|
||||||
return
|
return
|
||||||
|
@ -124,7 +124,7 @@ curl http://localhost/api/v1/organizations/#{id} -v -u #{login}:#{password}
|
||||||
end
|
end
|
||||||
|
|
||||||
if params[:expand]
|
if params[:expand]
|
||||||
organization = Organization.find(params[:id]).attributes_with_relation_names
|
organization = Organization.find(params[:id]).attributes_with_association_names
|
||||||
render json: organization, status: :ok
|
render json: organization, status: :ok
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -256,7 +256,7 @@ curl http://localhost/api/v1/organization/{id} -v -u #{login}:#{password} -H "Co
|
||||||
if params[:expand]
|
if params[:expand]
|
||||||
list = []
|
list = []
|
||||||
organization_all.each { |organization|
|
organization_all.each { |organization|
|
||||||
list.push organization.attributes_with_relation_names
|
list.push organization.attributes_with_association_names
|
||||||
}
|
}
|
||||||
render json: list, status: :ok
|
render json: list, status: :ok
|
||||||
return
|
return
|
||||||
|
|
|
@ -17,7 +17,7 @@ class TicketArticlesController < ApplicationController
|
||||||
article_permission(article)
|
article_permission(article)
|
||||||
|
|
||||||
if params[:expand]
|
if params[:expand]
|
||||||
result = article.attributes_with_relation_names
|
result = article.attributes_with_association_names
|
||||||
result[:attachments] = article.attachments
|
result[:attachments] = article.attachments
|
||||||
render json: result, status: :ok
|
render json: result, status: :ok
|
||||||
return
|
return
|
||||||
|
@ -29,7 +29,7 @@ class TicketArticlesController < ApplicationController
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
render json: article.attributes_with_relation_names
|
render json: article.attributes_with_association_names
|
||||||
end
|
end
|
||||||
|
|
||||||
# GET /ticket_articles/by_ticket/1
|
# GET /ticket_articles/by_ticket/1
|
||||||
|
@ -46,7 +46,7 @@ class TicketArticlesController < ApplicationController
|
||||||
|
|
||||||
# ignore internal article if customer is requesting
|
# ignore internal article if customer is requesting
|
||||||
next if article.internal == true && current_user.permissions?('ticket.customer')
|
next if article.internal == true && current_user.permissions?('ticket.customer')
|
||||||
result = article.attributes_with_relation_names
|
result = article.attributes_with_association_names
|
||||||
|
|
||||||
# add attachments
|
# add attachments
|
||||||
result[:attachments] = article.attachments
|
result[:attachments] = article.attachments
|
||||||
|
@ -79,7 +79,7 @@ class TicketArticlesController < ApplicationController
|
||||||
|
|
||||||
# ignore internal article if customer is requesting
|
# ignore internal article if customer is requesting
|
||||||
next if article.internal == true && current_user.permissions?('ticket.customer')
|
next if article.internal == true && current_user.permissions?('ticket.customer')
|
||||||
articles.push article.attributes_with_relation_names
|
articles.push article.attributes_with_association_names
|
||||||
}
|
}
|
||||||
render json: articles
|
render json: articles
|
||||||
end
|
end
|
||||||
|
@ -91,7 +91,7 @@ class TicketArticlesController < ApplicationController
|
||||||
article = article_create(ticket, params)
|
article = article_create(ticket, params)
|
||||||
|
|
||||||
if params[:expand]
|
if params[:expand]
|
||||||
result = article.attributes_with_relation_names
|
result = article.attributes_with_association_names
|
||||||
result[:attachments] = article.attachments
|
result[:attachments] = article.attachments
|
||||||
render json: result, status: :created
|
render json: result, status: :created
|
||||||
return
|
return
|
||||||
|
@ -103,7 +103,7 @@ class TicketArticlesController < ApplicationController
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
render json: article.attributes_with_relation_names, status: :created
|
render json: article.attributes_with_association_names, status: :created
|
||||||
end
|
end
|
||||||
|
|
||||||
# PUT /articles/1
|
# PUT /articles/1
|
||||||
|
@ -117,13 +117,13 @@ class TicketArticlesController < ApplicationController
|
||||||
raise Exceptions::NotAuthorized, 'Not authorized (ticket.agent or admin permission required)!'
|
raise Exceptions::NotAuthorized, 'Not authorized (ticket.agent or admin permission required)!'
|
||||||
end
|
end
|
||||||
|
|
||||||
clean_params = Ticket::Article.param_association_lookup(params)
|
clean_params = Ticket::Article.association_name_to_id_convert(params)
|
||||||
clean_params = Ticket::Article.param_cleanup(clean_params, true)
|
clean_params = Ticket::Article.param_cleanup(clean_params, true)
|
||||||
|
|
||||||
article.update_attributes!(clean_params)
|
article.update_attributes!(clean_params)
|
||||||
|
|
||||||
if params[:expand]
|
if params[:expand]
|
||||||
result = article.attributes_with_relation_names
|
result = article.attributes_with_association_names
|
||||||
result[:attachments] = article.attachments
|
result[:attachments] = article.attachments
|
||||||
render json: result, status: :ok
|
render json: result, status: :ok
|
||||||
return
|
return
|
||||||
|
@ -135,7 +135,7 @@ class TicketArticlesController < ApplicationController
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
render json: article.attributes_with_relation_names, status: :ok
|
render json: article.attributes_with_association_names, status: :ok
|
||||||
end
|
end
|
||||||
|
|
||||||
# DELETE /articles/1
|
# DELETE /articles/1
|
||||||
|
|
|
@ -23,7 +23,7 @@ class TicketsController < ApplicationController
|
||||||
if params[:expand]
|
if params[:expand]
|
||||||
list = []
|
list = []
|
||||||
tickets.each { |ticket|
|
tickets.each { |ticket|
|
||||||
list.push ticket.attributes_with_relation_names
|
list.push ticket.attributes_with_association_names
|
||||||
}
|
}
|
||||||
render json: list, status: :ok
|
render json: list, status: :ok
|
||||||
return
|
return
|
||||||
|
@ -54,7 +54,7 @@ class TicketsController < ApplicationController
|
||||||
ticket_permission(ticket)
|
ticket_permission(ticket)
|
||||||
|
|
||||||
if params[:expand]
|
if params[:expand]
|
||||||
result = ticket.attributes_with_relation_names
|
result = ticket.attributes_with_association_names
|
||||||
render json: result, status: :ok
|
render json: result, status: :ok
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -75,7 +75,7 @@ class TicketsController < ApplicationController
|
||||||
|
|
||||||
# POST /api/v1/tickets
|
# POST /api/v1/tickets
|
||||||
def create
|
def create
|
||||||
clean_params = Ticket.param_association_lookup(params)
|
clean_params = Ticket.association_name_to_id_convert(params)
|
||||||
|
|
||||||
# overwrite params
|
# overwrite params
|
||||||
if !current_user.permissions?('ticket.agent')
|
if !current_user.permissions?('ticket.agent')
|
||||||
|
@ -166,7 +166,7 @@ class TicketsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
if params[:expand]
|
if params[:expand]
|
||||||
result = ticket.reload.attributes_with_relation_names
|
result = ticket.reload.attributes_with_association_names
|
||||||
render json: result, status: :created
|
render json: result, status: :created
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -186,7 +186,7 @@ class TicketsController < ApplicationController
|
||||||
ticket = Ticket.find(params[:id])
|
ticket = Ticket.find(params[:id])
|
||||||
ticket_permission(ticket)
|
ticket_permission(ticket)
|
||||||
|
|
||||||
clean_params = Ticket.param_association_lookup(params)
|
clean_params = Ticket.association_name_to_id_convert(params)
|
||||||
clean_params = Ticket.param_cleanup(clean_params, true)
|
clean_params = Ticket.param_cleanup(clean_params, true)
|
||||||
|
|
||||||
# overwrite params
|
# overwrite params
|
||||||
|
@ -204,7 +204,7 @@ class TicketsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
if params[:expand]
|
if params[:expand]
|
||||||
result = ticket.reload.attributes_with_relation_names
|
result = ticket.reload.attributes_with_association_names
|
||||||
render json: result, status: :ok
|
render json: result, status: :ok
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -430,7 +430,7 @@ class TicketsController < ApplicationController
|
||||||
if params[:expand]
|
if params[:expand]
|
||||||
list = []
|
list = []
|
||||||
tickets.each { |ticket|
|
tickets.each { |ticket|
|
||||||
list.push ticket.attributes_with_relation_names
|
list.push ticket.attributes_with_association_names
|
||||||
}
|
}
|
||||||
render json: list, status: :ok
|
render json: list, status: :ok
|
||||||
return
|
return
|
||||||
|
|
|
@ -34,7 +34,7 @@ class UsersController < ApplicationController
|
||||||
if params[:expand]
|
if params[:expand]
|
||||||
list = []
|
list = []
|
||||||
users.each { |user|
|
users.each { |user|
|
||||||
list.push user.attributes_with_relation_names
|
list.push user.attributes_with_association_names
|
||||||
}
|
}
|
||||||
render json: list, status: :ok
|
render json: list, status: :ok
|
||||||
return
|
return
|
||||||
|
@ -56,7 +56,7 @@ class UsersController < ApplicationController
|
||||||
|
|
||||||
users_all = []
|
users_all = []
|
||||||
users.each { |user|
|
users.each { |user|
|
||||||
users_all.push User.lookup(id: user.id).attributes_with_associations
|
users_all.push User.lookup(id: user.id).attributes_with_association_ids
|
||||||
}
|
}
|
||||||
render json: users_all, status: :ok
|
render json: users_all, status: :ok
|
||||||
end
|
end
|
||||||
|
@ -79,7 +79,7 @@ class UsersController < ApplicationController
|
||||||
permission_check_local
|
permission_check_local
|
||||||
|
|
||||||
if params[:expand]
|
if params[:expand]
|
||||||
user = User.find(params[:id]).attributes_with_relation_names
|
user = User.find(params[:id]).attributes_with_association_names
|
||||||
render json: user, status: :ok
|
render json: user, status: :ok
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -90,7 +90,7 @@ class UsersController < ApplicationController
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
user = User.find(params[:id]).attributes_with_associations
|
user = User.find(params[:id]).attributes_with_association_ids
|
||||||
user.delete('password')
|
user.delete('password')
|
||||||
render json: user
|
render json: user
|
||||||
end
|
end
|
||||||
|
@ -109,10 +109,10 @@ class UsersController < ApplicationController
|
||||||
# in case of authentication, set current_user to access later
|
# in case of authentication, set current_user to access later
|
||||||
authentication_check_only({})
|
authentication_check_only({})
|
||||||
|
|
||||||
clean_params = User.param_association_lookup(params)
|
clean_params = User.association_name_to_id_convert(params)
|
||||||
clean_params = User.param_cleanup(clean_params, true)
|
clean_params = User.param_cleanup(clean_params, true)
|
||||||
user = User.new(clean_params)
|
user = User.new(clean_params)
|
||||||
user.param_set_associations(params)
|
user.associations_from_param(params)
|
||||||
|
|
||||||
# check if it's first user, the admin user
|
# check if it's first user, the admin user
|
||||||
# inital admin account
|
# inital admin account
|
||||||
|
@ -227,12 +227,12 @@ class UsersController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
if params[:expand]
|
if params[:expand]
|
||||||
user = User.find(user.id).attributes_with_relation_names
|
user = User.find(user.id).attributes_with_association_names
|
||||||
render json: user, status: :created
|
render json: user, status: :created
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
user_new = User.find(user.id).attributes_with_associations
|
user_new = User.find(user.id).attributes_with_association_ids
|
||||||
user_new.delete('password')
|
user_new.delete('password')
|
||||||
render json: user_new, status: :created
|
render json: user_new, status: :created
|
||||||
end
|
end
|
||||||
|
@ -253,7 +253,7 @@ class UsersController < ApplicationController
|
||||||
permission_check_local
|
permission_check_local
|
||||||
|
|
||||||
user = User.find(params[:id])
|
user = User.find(params[:id])
|
||||||
clean_params = User.param_association_lookup(params)
|
clean_params = User.association_name_to_id_convert(params)
|
||||||
clean_params = User.param_cleanup(clean_params, true)
|
clean_params = User.param_cleanup(clean_params, true)
|
||||||
|
|
||||||
# permission check
|
# permission check
|
||||||
|
@ -264,29 +264,29 @@ class UsersController < ApplicationController
|
||||||
# only allow Admin's
|
# only allow Admin's
|
||||||
if current_user.permissions?('admin.user') && (params[:role_ids] || params[:roles])
|
if current_user.permissions?('admin.user') && (params[:role_ids] || params[:roles])
|
||||||
user.role_ids = params[:role_ids]
|
user.role_ids = params[:role_ids]
|
||||||
user.param_set_associations({ role_ids: params[:role_ids], roles: params[:roles] })
|
user.associations_from_param({ role_ids: params[:role_ids], roles: params[:roles] })
|
||||||
end
|
end
|
||||||
|
|
||||||
# only allow Admin's
|
# only allow Admin's
|
||||||
if current_user.permissions?('admin.user') && (params[:group_ids] || params[:groups])
|
if current_user.permissions?('admin.user') && (params[:group_ids] || params[:groups])
|
||||||
user.group_ids = params[:group_ids]
|
user.group_ids = params[:group_ids]
|
||||||
user.param_set_associations({ group_ids: params[:group_ids], groups: params[:groups] })
|
user.associations_from_param({ group_ids: params[:group_ids], groups: params[:groups] })
|
||||||
end
|
end
|
||||||
|
|
||||||
# only allow Admin's and Agent's
|
# only allow Admin's and Agent's
|
||||||
if current_user.permissions?(['admin.user', 'ticket.agent']) && (params[:organization_ids] || params[:organizations])
|
if current_user.permissions?(['admin.user', 'ticket.agent']) && (params[:organization_ids] || params[:organizations])
|
||||||
user.param_set_associations({ organization_ids: params[:organization_ids], organizations: params[:organizations] })
|
user.associations_from_param({ organization_ids: params[:organization_ids], organizations: params[:organizations] })
|
||||||
end
|
end
|
||||||
|
|
||||||
if params[:expand]
|
if params[:expand]
|
||||||
user = User.find(user.id).attributes_with_relation_names
|
user = User.find(user.id).attributes_with_association_names
|
||||||
render json: user, status: :ok
|
render json: user, status: :ok
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# get new data
|
# get new data
|
||||||
user_new = User.find(user.id).attributes_with_associations
|
user_new = User.find(user.id).attributes_with_association_ids
|
||||||
user_new.delete('password')
|
user_new.delete('password')
|
||||||
render json: user_new, status: :ok
|
render json: user_new, status: :ok
|
||||||
end
|
end
|
||||||
|
@ -318,7 +318,7 @@ class UsersController < ApplicationController
|
||||||
def me
|
def me
|
||||||
|
|
||||||
if params[:expand]
|
if params[:expand]
|
||||||
user = current_user.attributes_with_relation_names
|
user = current_user.attributes_with_association_names
|
||||||
render json: user, status: :ok
|
render json: user, status: :ok
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -329,7 +329,7 @@ class UsersController < ApplicationController
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
user = current_user.attributes_with_associations
|
user = current_user.attributes_with_association_ids
|
||||||
user.delete('password')
|
user.delete('password')
|
||||||
render json: user
|
render json: user
|
||||||
end
|
end
|
||||||
|
@ -390,7 +390,7 @@ class UsersController < ApplicationController
|
||||||
if params[:expand]
|
if params[:expand]
|
||||||
list = []
|
list = []
|
||||||
user_all.each { |user|
|
user_all.each { |user|
|
||||||
list.push user.attributes_with_relation_names
|
list.push user.attributes_with_association_names
|
||||||
}
|
}
|
||||||
render json: list, status: :ok
|
render json: list, status: :ok
|
||||||
return
|
return
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,6 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
module ApplicationModel::ActivityStreamBase
|
module ApplicationModel::ActivityStreamLoggable
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
|
@ -25,19 +26,31 @@ returns
|
||||||
# return if we run on init mode
|
# return if we run on init mode
|
||||||
return if !Setting.get('system_init_done')
|
return if !Setting.get('system_init_done')
|
||||||
|
|
||||||
permission = self.class.activity_stream_support_config[:permission]
|
permission = self.class.instance_variable_get(:@activity_stream_permission)
|
||||||
updated_at = self.updated_at
|
updated_at = self.updated_at
|
||||||
if force
|
if force
|
||||||
updated_at = Time.zone.now
|
updated_at = Time.zone.now
|
||||||
end
|
end
|
||||||
ActivityStream.add(
|
|
||||||
o_id: self['id'],
|
attributes = {
|
||||||
type: type,
|
o_id: self['id'],
|
||||||
object: self.class.name,
|
type: type,
|
||||||
group_id: self['group_id'],
|
object: self.class.name,
|
||||||
permission: permission,
|
group_id: self['group_id'],
|
||||||
created_at: updated_at,
|
permission: permission,
|
||||||
|
created_at: updated_at,
|
||||||
created_by_id: user_id,
|
created_by_id: user_id,
|
||||||
)
|
}.merge(activity_stream_log_attributes)
|
||||||
|
|
||||||
|
ActivityStream.add(attributes)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# callback function to overwrite
|
||||||
|
# default history stream log attributes
|
||||||
|
# gets called from activity_stream_log
|
||||||
|
def activity_stream_log_attributes
|
||||||
|
{}
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -1,44 +0,0 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
|
||||||
module ApplicationModel::Assets
|
|
||||||
|
|
||||||
=begin
|
|
||||||
|
|
||||||
get all assets / related models for this user
|
|
||||||
|
|
||||||
user = User.find(123)
|
|
||||||
result = user.assets(assets_if_exists)
|
|
||||||
|
|
||||||
returns
|
|
||||||
|
|
||||||
result = {
|
|
||||||
:User => {
|
|
||||||
123 => user_model_123,
|
|
||||||
1234 => user_model_1234,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
=end
|
|
||||||
|
|
||||||
def assets(data = {})
|
|
||||||
|
|
||||||
app_model = self.class.to_app_model
|
|
||||||
|
|
||||||
if !data[ app_model ]
|
|
||||||
data[ app_model ] = {}
|
|
||||||
end
|
|
||||||
if !data[ app_model ][ id ]
|
|
||||||
data[ app_model ][ id ] = attributes_with_associations
|
|
||||||
end
|
|
||||||
|
|
||||||
return data if !self['created_by_id'] && !self['updated_by_id']
|
|
||||||
app_model_user = User.to_app_model
|
|
||||||
%w(created_by_id updated_by_id).each { |local_user_id|
|
|
||||||
next if !self[ local_user_id ]
|
|
||||||
next if data[ app_model_user ] && data[ app_model_user ][ self[ local_user_id ] ]
|
|
||||||
user = User.lookup(id: self[ local_user_id ])
|
|
||||||
next if !user
|
|
||||||
data = user.assets(data)
|
|
||||||
}
|
|
||||||
data
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,16 +0,0 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
|
||||||
class ApplicationModel::BackgroundJobSearchIndex
|
|
||||||
def initialize(object, o_id)
|
|
||||||
@object = object
|
|
||||||
@o_id = o_id
|
|
||||||
end
|
|
||||||
|
|
||||||
def perform
|
|
||||||
record = Object.const_get(@object).lookup(id: @o_id)
|
|
||||||
if !record
|
|
||||||
Rails.logger.info "Can't index #{@object}.find(#{@o_id}), no such record found"
|
|
||||||
return
|
|
||||||
end
|
|
||||||
record.search_index_update_backend
|
|
||||||
end
|
|
||||||
end
|
|
70
app/models/application_model/cacheable.rb
Normal file
70
app/models/application_model/cacheable.rb
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
module ApplicationModel::Cacheable
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
before_create :cache_delete
|
||||||
|
|
||||||
|
after_create :cache_delete
|
||||||
|
after_update :cache_delete
|
||||||
|
after_touch :cache_delete
|
||||||
|
after_destroy :cache_delete
|
||||||
|
end
|
||||||
|
|
||||||
|
def cache_update(o)
|
||||||
|
cache_delete if respond_to?('cache_delete')
|
||||||
|
o.cache_delete if o.respond_to?('cache_delete')
|
||||||
|
end
|
||||||
|
|
||||||
|
def cache_delete
|
||||||
|
keys = []
|
||||||
|
|
||||||
|
# delete by id caches
|
||||||
|
keys.push "#{self.class}::#{id}"
|
||||||
|
|
||||||
|
# delete by id with attributes_with_association_ids caches
|
||||||
|
keys.push "#{self.class}::aws::#{id}"
|
||||||
|
|
||||||
|
# delete by name caches
|
||||||
|
if self[:name]
|
||||||
|
keys.push "#{self.class}::#{name}"
|
||||||
|
end
|
||||||
|
|
||||||
|
# delete by login caches
|
||||||
|
if self[:login]
|
||||||
|
keys.push "#{self.class}::#{login}"
|
||||||
|
end
|
||||||
|
|
||||||
|
keys.each { |key|
|
||||||
|
Cache.delete(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
# delete old name / login caches
|
||||||
|
if changed?
|
||||||
|
if changes.key?('name')
|
||||||
|
name = changes['name'][0]
|
||||||
|
key = "#{self.class}::#{name}"
|
||||||
|
Cache.delete(key)
|
||||||
|
end
|
||||||
|
if changes.key?('login')
|
||||||
|
name = changes['login'][0]
|
||||||
|
key = "#{self.class}::#{name}"
|
||||||
|
Cache.delete(key)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# methods defined here are going to extend the class, not the instance of it
|
||||||
|
class_methods do
|
||||||
|
|
||||||
|
def cache_set(data_id, data)
|
||||||
|
key = "#{self}::#{data_id}"
|
||||||
|
Cache.write(key, data)
|
||||||
|
end
|
||||||
|
|
||||||
|
def cache_get(data_id)
|
||||||
|
key = "#{self}::#{data_id}"
|
||||||
|
Cache.get(key)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
87
app/models/application_model/can_lookup.rb
Normal file
87
app/models/application_model/can_lookup.rb
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
module ApplicationModel::CanLookup
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
# methods defined here are going to extend the class, not the instance of it
|
||||||
|
class_methods do
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
lookup model from cache (if exists) or retrieve it from db, id, name, login or email possible
|
||||||
|
|
||||||
|
result = Model.lookup(id: 123)
|
||||||
|
result = Model.lookup(name: 'some name')
|
||||||
|
result = Model.lookup(login: 'some login')
|
||||||
|
result = Model.lookup(email: 'some login')
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
result = model # with all attributes
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def lookup(data)
|
||||||
|
if data[:id]
|
||||||
|
cache = cache_get(data[:id])
|
||||||
|
return cache if cache
|
||||||
|
|
||||||
|
record = find_by(id: data[:id])
|
||||||
|
cache_set(data[:id], record)
|
||||||
|
return record
|
||||||
|
elsif data[:name]
|
||||||
|
cache = cache_get(data[:name])
|
||||||
|
return cache if cache
|
||||||
|
|
||||||
|
# do lookup with == to handle case insensitive databases
|
||||||
|
records = if Rails.application.config.db_case_sensitive
|
||||||
|
where('LOWER(name) = LOWER(?)', data[:name])
|
||||||
|
else
|
||||||
|
where(name: data[:name])
|
||||||
|
end
|
||||||
|
records.each { |loop_record|
|
||||||
|
if loop_record.name == data[:name]
|
||||||
|
cache_set(data[:name], loop_record)
|
||||||
|
return loop_record
|
||||||
|
end
|
||||||
|
}
|
||||||
|
return
|
||||||
|
elsif data[:login]
|
||||||
|
cache = cache_get(data[:login])
|
||||||
|
return cache if cache
|
||||||
|
|
||||||
|
# do lookup with == to handle case insensitive databases
|
||||||
|
records = if Rails.application.config.db_case_sensitive
|
||||||
|
where('LOWER(login) = LOWER(?)', data[:login])
|
||||||
|
else
|
||||||
|
where(login: data[:login])
|
||||||
|
end
|
||||||
|
records.each { |loop_record|
|
||||||
|
if loop_record.login == data[:login]
|
||||||
|
cache_set(data[:login], loop_record)
|
||||||
|
return loop_record
|
||||||
|
end
|
||||||
|
}
|
||||||
|
return
|
||||||
|
elsif data[:email]
|
||||||
|
cache = cache_get(data[:email])
|
||||||
|
return cache if cache
|
||||||
|
|
||||||
|
# do lookup with == to handle case insensitive databases
|
||||||
|
records = if Rails.application.config.db_case_sensitive
|
||||||
|
where('LOWER(email) = LOWER(?)', data[:email])
|
||||||
|
else
|
||||||
|
where(email: data[:email])
|
||||||
|
end
|
||||||
|
records.each { |loop_record|
|
||||||
|
if loop_record.email == data[:email]
|
||||||
|
cache_set(data[:email], loop_record)
|
||||||
|
return loop_record
|
||||||
|
end
|
||||||
|
}
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
raise ArgumentError, 'Need name, id, login or email for lookup()'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,66 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
module ApplicationModel::CanLookupSearchIndexAttributes
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
lookup name of ref. objects
|
||||||
|
|
||||||
|
ticket = Ticket.find(3)
|
||||||
|
attributes = ticket.search_index_attribute_lookup
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
attributes # object with lookup data
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def search_index_attribute_lookup
|
||||||
|
|
||||||
|
attributes = self.attributes
|
||||||
|
self.attributes.each { |key, value|
|
||||||
|
next if !value
|
||||||
|
|
||||||
|
# get attribute name
|
||||||
|
attribute_name_with_id = key.to_s
|
||||||
|
attribute_name = key.to_s
|
||||||
|
next if attribute_name[-3, 3] != '_id'
|
||||||
|
attribute_name = attribute_name[ 0, attribute_name.length - 3 ]
|
||||||
|
|
||||||
|
# check if attribute method exists
|
||||||
|
next if !respond_to?(attribute_name)
|
||||||
|
|
||||||
|
# check if method has own class
|
||||||
|
relation_class = send(attribute_name).class
|
||||||
|
next if !relation_class
|
||||||
|
|
||||||
|
# lookup ref object
|
||||||
|
relation_model = relation_class.lookup(id: value)
|
||||||
|
next if !relation_model
|
||||||
|
|
||||||
|
# get name of ref object
|
||||||
|
value = nil
|
||||||
|
if relation_model.respond_to?('search_index_data')
|
||||||
|
value = relation_model.send('search_index_data')
|
||||||
|
end
|
||||||
|
|
||||||
|
if relation_model.respond_to?('name')
|
||||||
|
value = relation_model.send('name')
|
||||||
|
end
|
||||||
|
|
||||||
|
next if !value
|
||||||
|
|
||||||
|
# save name of ref object
|
||||||
|
attributes[ attribute_name ] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
ignored_attributes = self.class.instance_variable_get(:@search_index_attributes_ignored) || []
|
||||||
|
return attributes if ignored_attributes.empty?
|
||||||
|
|
||||||
|
ignored_attributes.each { |attribute|
|
||||||
|
attributes.delete(attribute.to_s)
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes
|
||||||
|
end
|
||||||
|
end
|
38
app/models/application_model/checks_attribute_length.rb
Normal file
38
app/models/application_model/checks_attribute_length.rb
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
module ApplicationModel::ChecksAttributeLength
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
before_create :check_attribute_length
|
||||||
|
before_update :check_attribute_length
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
check string/varchar size and cut them if needed
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def check_attribute_length
|
||||||
|
attributes.each { |attribute|
|
||||||
|
next if !self[ attribute[0] ]
|
||||||
|
next if !self[ attribute[0] ].instance_of?(String)
|
||||||
|
next if self[ attribute[0] ].empty?
|
||||||
|
column = self.class.columns_hash[ attribute[0] ]
|
||||||
|
next if !column
|
||||||
|
limit = column.limit
|
||||||
|
if column && limit
|
||||||
|
current_length = attribute[1].to_s.length
|
||||||
|
if limit < current_length
|
||||||
|
logger.warn "WARNING: cut string because of database length #{self.class}.#{attribute[0]}(#{limit} but is #{current_length}:#{attribute[1]})"
|
||||||
|
self[ attribute[0] ] = attribute[1][ 0, limit ]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# strip 4 bytes utf8 chars if needed
|
||||||
|
if column && self[ attribute[0] ]
|
||||||
|
self[attribute[0]] = self[ attribute[0] ].utf8_to_3bytesutf8
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
90
app/models/application_model/cleans_param.rb
Normal file
90
app/models/application_model/cleans_param.rb
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
module ApplicationModel::CleansParam
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
# methods defined here are going to extend the class, not the instance of it
|
||||||
|
class_methods do
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
remove all not used model attributes of params
|
||||||
|
|
||||||
|
result = Model.param_cleanup(params)
|
||||||
|
|
||||||
|
for object creation, ignore id's
|
||||||
|
|
||||||
|
result = Model.param_cleanup(params, true)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
result = params # params with valid attributes of model
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def param_cleanup(params, new_object = false)
|
||||||
|
|
||||||
|
if params.respond_to?('permit!')
|
||||||
|
params.permit!
|
||||||
|
end
|
||||||
|
|
||||||
|
if params.nil?
|
||||||
|
raise ArgumentError, "No params for #{self}!"
|
||||||
|
end
|
||||||
|
|
||||||
|
data = {}
|
||||||
|
params.each { |key, value|
|
||||||
|
data[key.to_sym] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
# ignore id for new objects
|
||||||
|
if new_object && params[:id]
|
||||||
|
data.delete(:id)
|
||||||
|
end
|
||||||
|
|
||||||
|
# only use object attributes
|
||||||
|
clean_params = {}
|
||||||
|
new.attributes.each { |attribute, _value|
|
||||||
|
next if !data.key?(attribute.to_sym)
|
||||||
|
|
||||||
|
# check reference records, referenced by _id attributes
|
||||||
|
reflect_on_all_associations.map { |assoc|
|
||||||
|
class_name = assoc.options[:class_name]
|
||||||
|
next if !class_name
|
||||||
|
name = "#{assoc.name}_id".to_sym
|
||||||
|
next if !data.key?(name)
|
||||||
|
next if data[name].blank?
|
||||||
|
next if assoc.klass.lookup(id: data[name])
|
||||||
|
raise ArgumentError, "Invalid value for param '#{name}': #{data[name].inspect}"
|
||||||
|
}
|
||||||
|
clean_params[attribute.to_sym] = data[attribute.to_sym]
|
||||||
|
}
|
||||||
|
|
||||||
|
# we do want to set this via database
|
||||||
|
filter_unused_params(clean_params)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
remove all not used params of object (per default :updated_at, :created_at, :updated_by_id and :created_by_id)
|
||||||
|
|
||||||
|
result = Model.filter_unused_params(params)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
result = params # params without listed attributes
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def filter_unused_params(data)
|
||||||
|
|
||||||
|
# we do want to set this via database
|
||||||
|
[:action, :controller, :updated_at, :created_at, :updated_by_id, :created_by_id, :updated_by, :created_by].each { |key|
|
||||||
|
data.delete(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
data
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
21
app/models/application_model/cleans_recent_view.rb
Normal file
21
app/models/application_model/cleans_recent_view.rb
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
module ApplicationModel::CleansRecentView
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
before_destroy :recent_view_destroy
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
delete object recent viewed list, will be executed automatically
|
||||||
|
|
||||||
|
model = Model.find(123)
|
||||||
|
model.recent_view_destroy
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def recent_view_destroy
|
||||||
|
RecentView.log_destroy(self.class.to_s, id)
|
||||||
|
end
|
||||||
|
end
|
64
app/models/application_model/fills_by_user_columns.rb
Normal file
64
app/models/application_model/fills_by_user_columns.rb
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
module ApplicationModel::FillsByUserColumns
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
before_create :fill_up_user_create
|
||||||
|
before_update :fill_up_user_update
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
set created_by_id & updated_by_id if not given based on UserInfo (current session)
|
||||||
|
|
||||||
|
Used as before_create callback, no own use needed
|
||||||
|
|
||||||
|
result = Model.fill_up_user_create(params)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
result = params # params with updated_by_id & created_by_id if not given based on UserInfo (current session)
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def fill_up_user_create
|
||||||
|
if self.class.column_names.include? 'updated_by_id'
|
||||||
|
if UserInfo.current_user_id
|
||||||
|
if updated_by_id && updated_by_id != UserInfo.current_user_id
|
||||||
|
logger.info "NOTICE create - self.updated_by_id is different: #{updated_by_id}/#{UserInfo.current_user_id}"
|
||||||
|
end
|
||||||
|
self.updated_by_id = UserInfo.current_user_id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return if !self.class.column_names.include? 'created_by_id'
|
||||||
|
|
||||||
|
return if !UserInfo.current_user_id
|
||||||
|
|
||||||
|
if created_by_id && created_by_id != UserInfo.current_user_id
|
||||||
|
logger.info "NOTICE create - self.created_by_id is different: #{created_by_id}/#{UserInfo.current_user_id}"
|
||||||
|
end
|
||||||
|
self.created_by_id = UserInfo.current_user_id
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
set updated_by_id if not given based on UserInfo (current session)
|
||||||
|
|
||||||
|
Used as before_update callback, no own use needed
|
||||||
|
|
||||||
|
result = Model.fill_up_user_update(params)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
result = params # params with updated_by_id & created_by_id if not given based on UserInfo (current session)
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def fill_up_user_update
|
||||||
|
return if !self.class.column_names.include? 'updated_by_id'
|
||||||
|
return if !UserInfo.current_user_id
|
||||||
|
|
||||||
|
self.updated_by_id = UserInfo.current_user_id
|
||||||
|
end
|
||||||
|
end
|
201
app/models/application_model/handles_creates_and_updates.rb
Normal file
201
app/models/application_model/handles_creates_and_updates.rb
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
module ApplicationModel::HandlesCreatesAndUpdates
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
# methods defined here are going to extend the class, not the instance of it
|
||||||
|
class_methods do
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
create model if not exists (check exists based on id, name, login, email or locale)
|
||||||
|
|
||||||
|
result = Model.create_if_not_exists(attributes)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
result = model # with all attributes
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def create_if_not_exists(data)
|
||||||
|
if data[:id]
|
||||||
|
record = find_by(id: data[:id])
|
||||||
|
return record if record
|
||||||
|
elsif data[:name]
|
||||||
|
|
||||||
|
# do lookup with == to handle case insensitive databases
|
||||||
|
records = if Rails.application.config.db_case_sensitive
|
||||||
|
where('LOWER(name) = LOWER(?)', data[:name])
|
||||||
|
else
|
||||||
|
where(name: data[:name])
|
||||||
|
end
|
||||||
|
records.each { |loop_record|
|
||||||
|
return loop_record if loop_record.name == data[:name]
|
||||||
|
}
|
||||||
|
elsif data[:login]
|
||||||
|
|
||||||
|
# do lookup with == to handle case insensitive databases
|
||||||
|
records = if Rails.application.config.db_case_sensitive
|
||||||
|
where('LOWER(login) = LOWER(?)', data[:login])
|
||||||
|
else
|
||||||
|
where(login: data[:login])
|
||||||
|
end
|
||||||
|
records.each { |loop_record|
|
||||||
|
return loop_record if loop_record.login == data[:login]
|
||||||
|
}
|
||||||
|
elsif data[:email]
|
||||||
|
|
||||||
|
# do lookup with == to handle case insensitive databases
|
||||||
|
records = if Rails.application.config.db_case_sensitive
|
||||||
|
where('LOWER(email) = LOWER(?)', data[:email])
|
||||||
|
else
|
||||||
|
where(email: data[:email])
|
||||||
|
end
|
||||||
|
records.each { |loop_record|
|
||||||
|
return loop_record if loop_record.email == data[:email]
|
||||||
|
}
|
||||||
|
elsif data[:locale] && data[:source]
|
||||||
|
|
||||||
|
# do lookup with == to handle case insensitive databases
|
||||||
|
records = if Rails.application.config.db_case_sensitive
|
||||||
|
where('LOWER(locale) = LOWER(?) AND LOWER(source) = LOWER(?)', data[:locale], data[:source])
|
||||||
|
else
|
||||||
|
where(locale: data[:locale], source: data[:source])
|
||||||
|
end
|
||||||
|
records.each { |loop_record|
|
||||||
|
return loop_record if loop_record.source == data[:source]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
create(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
Model.create_or_update with ref lookups
|
||||||
|
|
||||||
|
result = Model.create_or_update(attributes)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
result = model # with all attributes
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def create_or_update_with_ref(data)
|
||||||
|
data = association_name_to_id_convert(data)
|
||||||
|
create_or_update(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
Model.create_if_not_exists with ref lookups
|
||||||
|
|
||||||
|
result = Model.create_if_not_exists_with_ref(attributes)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
result = model # with all attributes
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def create_if_not_exists_with_ref(data)
|
||||||
|
data = association_name_to_id_convert(data)
|
||||||
|
create_or_update(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
create or update model (check exists based on id, name, login, email or locale)
|
||||||
|
|
||||||
|
result = Model.create_or_update(attributes)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
result = model # with all attributes
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def create_or_update(data)
|
||||||
|
if data[:id]
|
||||||
|
record = find_by(id: data[:id])
|
||||||
|
if record
|
||||||
|
record.update_attributes(data)
|
||||||
|
return record
|
||||||
|
end
|
||||||
|
record = new(data)
|
||||||
|
record.save
|
||||||
|
return record
|
||||||
|
elsif data[:name]
|
||||||
|
|
||||||
|
# do lookup with == to handle case insensitive databases
|
||||||
|
records = if Rails.application.config.db_case_sensitive
|
||||||
|
where('LOWER(name) = LOWER(?)', data[:name])
|
||||||
|
else
|
||||||
|
where(name: data[:name])
|
||||||
|
end
|
||||||
|
records.each { |loop_record|
|
||||||
|
if loop_record.name == data[:name]
|
||||||
|
loop_record.update_attributes(data)
|
||||||
|
return loop_record
|
||||||
|
end
|
||||||
|
}
|
||||||
|
record = new(data)
|
||||||
|
record.save
|
||||||
|
return record
|
||||||
|
elsif data[:login]
|
||||||
|
|
||||||
|
# do lookup with == to handle case insensitive databases
|
||||||
|
records = if Rails.application.config.db_case_sensitive
|
||||||
|
where('LOWER(login) = LOWER(?)', data[:login])
|
||||||
|
else
|
||||||
|
where(login: data[:login])
|
||||||
|
end
|
||||||
|
records.each { |loop_record|
|
||||||
|
if loop_record.login.casecmp(data[:login]).zero?
|
||||||
|
loop_record.update_attributes(data)
|
||||||
|
return loop_record
|
||||||
|
end
|
||||||
|
}
|
||||||
|
record = new(data)
|
||||||
|
record.save
|
||||||
|
return record
|
||||||
|
elsif data[:email]
|
||||||
|
|
||||||
|
# do lookup with == to handle case insensitive databases
|
||||||
|
records = if Rails.application.config.db_case_sensitive
|
||||||
|
where('LOWER(email) = LOWER(?)', data[:email])
|
||||||
|
else
|
||||||
|
where(email: data[:email])
|
||||||
|
end
|
||||||
|
records.each { |loop_record|
|
||||||
|
if loop_record.email.casecmp(data[:email]).zero?
|
||||||
|
loop_record.update_attributes(data)
|
||||||
|
return loop_record
|
||||||
|
end
|
||||||
|
}
|
||||||
|
record = new(data)
|
||||||
|
record.save
|
||||||
|
return record
|
||||||
|
elsif data[:locale]
|
||||||
|
|
||||||
|
# do lookup with == to handle case insensitive databases
|
||||||
|
records = if Rails.application.config.db_case_sensitive
|
||||||
|
where('LOWER(locale) = LOWER(?)', data[:locale])
|
||||||
|
else
|
||||||
|
where(locale: data[:locale])
|
||||||
|
end
|
||||||
|
records.each { |loop_record|
|
||||||
|
if loop_record.locale.casecmp(data[:locale]).zero?
|
||||||
|
loop_record.update_attributes(data)
|
||||||
|
return loop_record
|
||||||
|
end
|
||||||
|
}
|
||||||
|
record = new(data)
|
||||||
|
record.save
|
||||||
|
return record
|
||||||
|
else
|
||||||
|
raise ArgumentError, 'Need name, login, email or locale for create_or_update()'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
153
app/models/application_model/has_assets.rb
Normal file
153
app/models/application_model/has_assets.rb
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
module ApplicationModel::HasAssets
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
get all assets / related models for this user
|
||||||
|
|
||||||
|
user = User.find(123)
|
||||||
|
result = user.assets(assets_if_exists)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
result = {
|
||||||
|
:User => {
|
||||||
|
123 => user_model_123,
|
||||||
|
1234 => user_model_1234,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def assets(data = {})
|
||||||
|
|
||||||
|
app_model = self.class.to_app_model
|
||||||
|
|
||||||
|
if !data[ app_model ]
|
||||||
|
data[ app_model ] = {}
|
||||||
|
end
|
||||||
|
if !data[ app_model ][ id ]
|
||||||
|
data[ app_model ][ id ] = attributes_with_association_ids
|
||||||
|
end
|
||||||
|
|
||||||
|
return data if !self['created_by_id'] && !self['updated_by_id']
|
||||||
|
app_model_user = User.to_app_model
|
||||||
|
%w(created_by_id updated_by_id).each { |local_user_id|
|
||||||
|
next if !self[ local_user_id ]
|
||||||
|
next if data[ app_model_user ] && data[ app_model_user ][ self[ local_user_id ] ]
|
||||||
|
user = User.lookup(id: self[ local_user_id ])
|
||||||
|
next if !user
|
||||||
|
data = user.assets(data)
|
||||||
|
}
|
||||||
|
data
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
get assets and record_ids of selector
|
||||||
|
|
||||||
|
model = Model.find(123)
|
||||||
|
|
||||||
|
assets = model.assets_of_selector('attribute_name_of_selector', assets)
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def assets_of_selector(selector, assets = {})
|
||||||
|
|
||||||
|
# get assets of condition
|
||||||
|
models = Models.all
|
||||||
|
send(selector).each { |item, content|
|
||||||
|
attribute = item.split(/\./)
|
||||||
|
next if !attribute[1]
|
||||||
|
begin
|
||||||
|
attribute_class = attribute[0].to_classname.constantize
|
||||||
|
rescue => e
|
||||||
|
logger.error "Unable to get asset for '#{attribute[0]}': #{e.inspect}"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
reflection = attribute[1].sub(/_id$/, '')
|
||||||
|
#reflection = reflection.to_sym
|
||||||
|
next if !models[attribute_class]
|
||||||
|
next if !models[attribute_class][:reflections]
|
||||||
|
next if !models[attribute_class][:reflections][reflection]
|
||||||
|
next if !models[attribute_class][:reflections][reflection].klass
|
||||||
|
attribute_ref_class = models[attribute_class][:reflections][reflection].klass
|
||||||
|
if content['value'].instance_of?(Array)
|
||||||
|
content['value'].each { |item_id|
|
||||||
|
attribute_object = attribute_ref_class.find_by(id: item_id)
|
||||||
|
if attribute_object
|
||||||
|
assets = attribute_object.assets(assets)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
else
|
||||||
|
attribute_object = attribute_ref_class.find_by(id: content['value'])
|
||||||
|
if attribute_object
|
||||||
|
assets = attribute_object.assets(assets)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
assets
|
||||||
|
end
|
||||||
|
|
||||||
|
# methods defined here are going to extend the class, not the instance of it
|
||||||
|
class_methods do
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
return object and assets
|
||||||
|
|
||||||
|
data = Model.full(123)
|
||||||
|
data = {
|
||||||
|
id: 123,
|
||||||
|
assets: assets,
|
||||||
|
}
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def full(id)
|
||||||
|
object = find(id)
|
||||||
|
assets = object.assets({})
|
||||||
|
{
|
||||||
|
id: id,
|
||||||
|
assets: assets,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
get assets of object list
|
||||||
|
|
||||||
|
list = [
|
||||||
|
{
|
||||||
|
object => 'Ticket',
|
||||||
|
o_id => 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
object => 'User',
|
||||||
|
o_id => 121,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
assets = Model.assets_of_object_list(list, assets)
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def assets_of_object_list(list, assets = {})
|
||||||
|
list.each { |item|
|
||||||
|
require item['object'].to_filename
|
||||||
|
record = Kernel.const_get(item['object']).find(item['o_id'])
|
||||||
|
assets = record.assets(assets)
|
||||||
|
if item['created_by_id']
|
||||||
|
user = User.find(item['created_by_id'])
|
||||||
|
assets = user.assets(assets)
|
||||||
|
end
|
||||||
|
if item['updated_by_id']
|
||||||
|
user = User.find(item['updated_by_id'])
|
||||||
|
assets = user.assets(assets)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
assets
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
357
app/models/application_model/has_associations.rb
Normal file
357
app/models/application_model/has_associations.rb
Normal file
|
@ -0,0 +1,357 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
module ApplicationModel::HasAssociations
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
set relations of model based on params
|
||||||
|
|
||||||
|
model = Model.find(1)
|
||||||
|
result = model.associations_from_param(params)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
result = true|false
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def associations_from_param(params)
|
||||||
|
|
||||||
|
# set relations by id/verify if ref exists
|
||||||
|
self.class.reflect_on_all_associations.map { |assoc|
|
||||||
|
assoc_name = assoc.name
|
||||||
|
real_ids = assoc_name[0, assoc_name.length - 1] + '_ids'
|
||||||
|
real_ids = real_ids.to_sym
|
||||||
|
next if !params.key?(real_ids)
|
||||||
|
list_of_items = params[real_ids]
|
||||||
|
if !params[real_ids].instance_of?(Array)
|
||||||
|
list_of_items = [ params[real_ids] ]
|
||||||
|
end
|
||||||
|
list = []
|
||||||
|
list_of_items.each { |item_id|
|
||||||
|
next if !item_id
|
||||||
|
lookup = assoc.klass.lookup(id: item_id)
|
||||||
|
|
||||||
|
# complain if we found no reference
|
||||||
|
if !lookup
|
||||||
|
raise ArgumentError, "No value found for '#{assoc_name}' with id #{item_id.inspect}"
|
||||||
|
end
|
||||||
|
list.push item_id
|
||||||
|
}
|
||||||
|
send("#{real_ids}=", list)
|
||||||
|
}
|
||||||
|
|
||||||
|
# set relations by name/lookup
|
||||||
|
self.class.reflect_on_all_associations.map { |assoc|
|
||||||
|
assoc_name = assoc.name
|
||||||
|
real_ids = assoc_name[0, assoc_name.length - 1] + '_ids'
|
||||||
|
next if !respond_to?(real_ids)
|
||||||
|
real_values = assoc_name[0, assoc_name.length - 1] + 's'
|
||||||
|
real_values = real_values.to_sym
|
||||||
|
next if !respond_to?(real_values)
|
||||||
|
next if !params[real_values]
|
||||||
|
next if !params[real_values].instance_of?(Array)
|
||||||
|
list = []
|
||||||
|
class_object = assoc.klass
|
||||||
|
params[real_values].each { |value|
|
||||||
|
lookup = nil
|
||||||
|
if class_object == User
|
||||||
|
if !lookup
|
||||||
|
lookup = class_object.lookup(login: value)
|
||||||
|
end
|
||||||
|
if !lookup
|
||||||
|
lookup = class_object.lookup(email: value)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
lookup = class_object.lookup(name: value)
|
||||||
|
end
|
||||||
|
|
||||||
|
# complain if we found no reference
|
||||||
|
if !lookup
|
||||||
|
raise ArgumentError, "No lookup value found for '#{assoc_name}': #{value.inspect}"
|
||||||
|
end
|
||||||
|
list.push lookup.id
|
||||||
|
}
|
||||||
|
send("#{real_ids}=", list)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
get relations of model based on params
|
||||||
|
|
||||||
|
model = Model.find(1)
|
||||||
|
attributes = model.attributes_with_association_ids
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
hash with attributes and association ids
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def attributes_with_association_ids
|
||||||
|
|
||||||
|
key = "#{self.class}::aws::#{id}"
|
||||||
|
cache = Cache.get(key)
|
||||||
|
return cache if cache
|
||||||
|
|
||||||
|
ignored_attributes = self.class.instance_variable_get(:@association_attributes_ignored) || []
|
||||||
|
|
||||||
|
# get relations
|
||||||
|
attributes = self.attributes
|
||||||
|
self.class.reflect_on_all_associations.map { |assoc|
|
||||||
|
real_ids = assoc.name.to_s[0, assoc.name.to_s.length - 1] + '_ids'
|
||||||
|
next if ignored_attributes.include?(real_ids.to_sym)
|
||||||
|
next if !respond_to?(real_ids)
|
||||||
|
attributes[real_ids] = send(real_ids)
|
||||||
|
}
|
||||||
|
Cache.write(key, attributes)
|
||||||
|
attributes
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
get relation name of model based on params
|
||||||
|
|
||||||
|
model = Model.find(1)
|
||||||
|
attributes = model.attributes_with_association_names
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
hash with attributes, association ids, association names and relation name
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def attributes_with_association_names
|
||||||
|
|
||||||
|
# get relations
|
||||||
|
attributes = attributes_with_association_ids
|
||||||
|
self.class.reflect_on_all_associations.map { |assoc|
|
||||||
|
next if !respond_to?(assoc.name)
|
||||||
|
ref = send(assoc.name)
|
||||||
|
next if !ref
|
||||||
|
if ref.respond_to?(:first)
|
||||||
|
attributes[assoc.name.to_s] = []
|
||||||
|
ref.each { |item|
|
||||||
|
if item[:login]
|
||||||
|
attributes[assoc.name.to_s].push item[:login]
|
||||||
|
next
|
||||||
|
end
|
||||||
|
next if !item[:name]
|
||||||
|
attributes[assoc.name.to_s].push item[:name]
|
||||||
|
}
|
||||||
|
if ref.count.positive? && attributes[assoc.name.to_s].empty?
|
||||||
|
attributes.delete(assoc.name.to_s)
|
||||||
|
end
|
||||||
|
next
|
||||||
|
end
|
||||||
|
if ref[:login]
|
||||||
|
attributes[assoc.name.to_s] = ref[:login]
|
||||||
|
next
|
||||||
|
end
|
||||||
|
next if !ref[:name]
|
||||||
|
attributes[assoc.name.to_s] = ref[:name]
|
||||||
|
}
|
||||||
|
|
||||||
|
# fill created_by/updated_by
|
||||||
|
{
|
||||||
|
'created_by_id' => 'created_by',
|
||||||
|
'updated_by_id' => 'updated_by',
|
||||||
|
}.each { |source, destination|
|
||||||
|
next if !attributes[source]
|
||||||
|
user = User.lookup(id: attributes[source])
|
||||||
|
next if !user
|
||||||
|
attributes[destination] = user.login
|
||||||
|
}
|
||||||
|
|
||||||
|
# remove forbitten attributes
|
||||||
|
%w(password token tokens token_ids).each { |item|
|
||||||
|
attributes.delete(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
reference if association id check
|
||||||
|
|
||||||
|
model = Model.find(123)
|
||||||
|
attributes = model.association_id_validation('attribute_id', value)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
true | false
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def association_id_validation(attribute_id, value)
|
||||||
|
return true if value.nil?
|
||||||
|
|
||||||
|
attributes.each { |key, _value|
|
||||||
|
next if key != attribute_id
|
||||||
|
|
||||||
|
# check if id is assigned
|
||||||
|
next if !key.end_with?('_id')
|
||||||
|
key_short = key.chomp('_id')
|
||||||
|
|
||||||
|
self.class.reflect_on_all_associations.map { |assoc|
|
||||||
|
next if assoc.name.to_s != key_short
|
||||||
|
item = assoc.class_name.constantize
|
||||||
|
return false if !item.respond_to?(:find_by)
|
||||||
|
ref_object = item.find_by(id: value)
|
||||||
|
return false if !ref_object
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
# methods defined here are going to extend the class, not the instance of it
|
||||||
|
class_methods do
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
serve methode to ignore model attribute associations
|
||||||
|
|
||||||
|
class Model < ApplicationModel
|
||||||
|
include AssociationConcern
|
||||||
|
association_attributes_ignored :user_ids
|
||||||
|
end
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def association_attributes_ignored(*attributes)
|
||||||
|
@association_attributes_ignored = attributes
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
do name/login/email based lookup for associations
|
||||||
|
|
||||||
|
params = {
|
||||||
|
login: 'some login',
|
||||||
|
firstname: 'some firstname',
|
||||||
|
lastname: 'some lastname',
|
||||||
|
email: 'some email',
|
||||||
|
organization: 'some organization',
|
||||||
|
roles: ['Agent', 'Admin'],
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes = Model.association_name_to_id_convert(params)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
attributes = params # params with possible lookups
|
||||||
|
|
||||||
|
attributes = {
|
||||||
|
login: 'some login',
|
||||||
|
firstname: 'some firstname',
|
||||||
|
lastname: 'some lastname',
|
||||||
|
email: 'some email',
|
||||||
|
organization_id: 123,
|
||||||
|
role_ids: [2,1],
|
||||||
|
}
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def association_name_to_id_convert(params)
|
||||||
|
|
||||||
|
data = {}
|
||||||
|
params.each { |key, value|
|
||||||
|
data[key.to_sym] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
data.symbolize_keys!
|
||||||
|
available_attributes = attribute_names
|
||||||
|
reflect_on_all_associations.map { |assoc|
|
||||||
|
|
||||||
|
assoc_name = assoc.name
|
||||||
|
value = data[assoc_name]
|
||||||
|
next if !value # next if we do not have a value
|
||||||
|
ref_name = "#{assoc_name}_id"
|
||||||
|
|
||||||
|
# handle _id values
|
||||||
|
if available_attributes.include?(ref_name) # if we do have an _id attribute
|
||||||
|
next if data[ref_name.to_sym] # next if we have already the _id filled
|
||||||
|
|
||||||
|
# get association class and do lookup
|
||||||
|
class_object = assoc.klass
|
||||||
|
lookup = nil
|
||||||
|
if class_object == User
|
||||||
|
if value.instance_of?(String)
|
||||||
|
if !lookup
|
||||||
|
lookup = class_object.lookup(login: value)
|
||||||
|
end
|
||||||
|
if !lookup
|
||||||
|
lookup = class_object.lookup(email: value)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
raise ArgumentError, "String is needed as ref value #{value.inspect} for '#{assoc_name}'"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
lookup = class_object.lookup(name: value)
|
||||||
|
end
|
||||||
|
|
||||||
|
# complain if we found no reference
|
||||||
|
if !lookup
|
||||||
|
raise ArgumentError, "No lookup value found for '#{assoc_name}': #{value.inspect}"
|
||||||
|
end
|
||||||
|
|
||||||
|
# release data value
|
||||||
|
data.delete(assoc_name)
|
||||||
|
|
||||||
|
# remember id reference
|
||||||
|
data[ref_name.to_sym] = lookup.id
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
next if !value.instance_of?(Array)
|
||||||
|
next if value.empty?
|
||||||
|
next if !value[0].instance_of?(String)
|
||||||
|
|
||||||
|
# handle _ids values
|
||||||
|
next if !assoc_name.to_s.end_with?('s')
|
||||||
|
ref_names = "#{assoc_name.to_s.chomp('s')}_ids"
|
||||||
|
generic_object_tmp = new
|
||||||
|
next unless generic_object_tmp.respond_to?(ref_names) # if we do have an _ids attribute
|
||||||
|
next if data[ref_names.to_sym] # next if we have already the _ids filled
|
||||||
|
|
||||||
|
# get association class and do lookup
|
||||||
|
class_object = assoc.klass
|
||||||
|
lookup_ids = []
|
||||||
|
value.each { |item|
|
||||||
|
lookup = nil
|
||||||
|
if class_object == User
|
||||||
|
if item.instance_of?(String)
|
||||||
|
if !lookup
|
||||||
|
lookup = class_object.lookup(login: item)
|
||||||
|
end
|
||||||
|
if !lookup
|
||||||
|
lookup = class_object.lookup(email: item)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
raise ArgumentError, "String is needed in array ref as ref value #{value.inspect} for '#{assoc_name}'"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
lookup = class_object.lookup(name: item)
|
||||||
|
end
|
||||||
|
|
||||||
|
# complain if we found no reference
|
||||||
|
if !lookup
|
||||||
|
raise ArgumentError, "No lookup value found for '#{assoc_name}': #{item.inspect}"
|
||||||
|
end
|
||||||
|
lookup_ids.push lookup.id
|
||||||
|
}
|
||||||
|
|
||||||
|
# release data value
|
||||||
|
data.delete(assoc_name)
|
||||||
|
|
||||||
|
# remember id reference
|
||||||
|
data[ref_names.to_sym] = lookup_ids
|
||||||
|
}
|
||||||
|
|
||||||
|
data
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
74
app/models/application_model/has_attachments.rb
Normal file
74
app/models/application_model/has_attachments.rb
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
module ApplicationModel::HasAttachments
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
after_create :attachments_buffer_check
|
||||||
|
after_update :attachments_buffer_check
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
get list of attachments of this object
|
||||||
|
|
||||||
|
item = Model.find(123)
|
||||||
|
list = item.attachments
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
# array with Store model objects
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def attachments
|
||||||
|
Store.list(object: self.class.to_s, o_id: id)
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
store attachments for this object
|
||||||
|
|
||||||
|
item = Model.find(123)
|
||||||
|
item.attachments = [ Store-Object1, Store-Object2 ]
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def attachments=(attachments)
|
||||||
|
self.attachments_buffer = attachments
|
||||||
|
|
||||||
|
# update if object already exists
|
||||||
|
return if !(id && id.nonzero?)
|
||||||
|
|
||||||
|
attachments_buffer_check
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def attachments_buffer
|
||||||
|
@attachments_buffer_data
|
||||||
|
end
|
||||||
|
|
||||||
|
def attachments_buffer=(attachments)
|
||||||
|
@attachments_buffer_data = attachments
|
||||||
|
end
|
||||||
|
|
||||||
|
def attachments_buffer_check
|
||||||
|
|
||||||
|
# do nothing if no attachment exists
|
||||||
|
return 1 if attachments_buffer.nil?
|
||||||
|
|
||||||
|
# store attachments
|
||||||
|
article_store = []
|
||||||
|
attachments_buffer.each do |attachment|
|
||||||
|
article_store.push Store.add(
|
||||||
|
object: self.class.to_s,
|
||||||
|
o_id: id,
|
||||||
|
data: attachment.content,
|
||||||
|
filename: attachment.filename,
|
||||||
|
preferences: attachment.preferences,
|
||||||
|
created_by_id: created_by_id,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
attachments_buffer = nil
|
||||||
|
end
|
||||||
|
end
|
46
app/models/application_model/has_latest_change_timestamp.rb
Normal file
46
app/models/application_model/has_latest_change_timestamp.rb
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
module ApplicationModel::HasLatestChangeTimestamp
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
# methods defined here are going to extend the class, not the instance of it
|
||||||
|
class_methods do
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
get latest updated_at object timestamp
|
||||||
|
|
||||||
|
latest_change = Ticket.latest_change
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
result = timestamp
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def latest_change
|
||||||
|
key = "#{new.class.name}_latest_change"
|
||||||
|
updated_at = Cache.get(key)
|
||||||
|
|
||||||
|
# if we do not have it cached, do lookup
|
||||||
|
if !updated_at
|
||||||
|
o = select(:updated_at).order(updated_at: :desc).limit(1).first
|
||||||
|
if o
|
||||||
|
updated_at = o.updated_at
|
||||||
|
latest_change_set(updated_at)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
updated_at
|
||||||
|
end
|
||||||
|
|
||||||
|
def latest_change_set(updated_at)
|
||||||
|
key = "#{new.class.name}_latest_change"
|
||||||
|
expires_in = 31_536_000 # 1 year
|
||||||
|
|
||||||
|
if updated_at.nil?
|
||||||
|
Cache.delete(key)
|
||||||
|
else
|
||||||
|
Cache.write(key, updated_at, { expires_in: expires_in })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,5 +1,6 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
module ApplicationModel::HistoryLogBase
|
module ApplicationModel::HistoryLoggable
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
|
@ -14,16 +15,27 @@ returns
|
||||||
|
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def history_log (type, user_id, data = {})
|
def history_log(type, user_id, attributes = {})
|
||||||
data[:o_id] = self['id']
|
|
||||||
data[:history_type] = type
|
attributes.merge!(
|
||||||
data[:history_object] = self.class.name
|
o_id: self['id'],
|
||||||
data[:related_o_id] = nil
|
history_type: type,
|
||||||
data[:related_history_object] = nil
|
history_object: self.class.name,
|
||||||
data[:created_by_id] = user_id
|
related_o_id: nil,
|
||||||
data[:updated_at] = updated_at
|
related_history_object: nil,
|
||||||
data[:created_at] = updated_at
|
created_by_id: user_id,
|
||||||
History.add(data)
|
updated_at: updated_at,
|
||||||
|
created_at: updated_at,
|
||||||
|
).merge!(history_log_attributes)
|
||||||
|
|
||||||
|
History.add(attributes)
|
||||||
|
end
|
||||||
|
|
||||||
|
# callback function to overwrite
|
||||||
|
# default history log attributes
|
||||||
|
# gets called from history_log
|
||||||
|
def history_log_attributes
|
||||||
|
{}
|
||||||
end
|
end
|
||||||
|
|
||||||
=begin
|
=begin
|
19
app/models/application_model/importable.rb
Normal file
19
app/models/application_model/importable.rb
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
module ApplicationModel::Importable
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
before_create :check_attributes_protected
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_attributes_protected
|
||||||
|
|
||||||
|
import_class_list = ['Ticket', 'Ticket::Article', 'History', 'Ticket::State', 'Ticket::StateType', 'Ticket::Priority', 'Group', 'User', 'Role' ]
|
||||||
|
|
||||||
|
# do noting, use id as it is
|
||||||
|
return if !Setting.get('system_init_done')
|
||||||
|
return if Setting.get('import_mode') && import_class_list.include?(self.class.to_s)
|
||||||
|
|
||||||
|
self[:id] = nil
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,127 +0,0 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
|
||||||
module ApplicationModel::SearchIndexBase
|
|
||||||
|
|
||||||
=begin
|
|
||||||
|
|
||||||
collect data to index and send to backend
|
|
||||||
|
|
||||||
ticket = Ticket.find(123)
|
|
||||||
result = ticket.search_index_update_backend
|
|
||||||
|
|
||||||
returns
|
|
||||||
|
|
||||||
result = true # false
|
|
||||||
|
|
||||||
=end
|
|
||||||
|
|
||||||
def search_index_update_backend
|
|
||||||
return if !self.class.search_index_support_config
|
|
||||||
|
|
||||||
# fill up with search data
|
|
||||||
attributes = search_index_attribute_lookup
|
|
||||||
return if !attributes
|
|
||||||
|
|
||||||
# update backend
|
|
||||||
SearchIndexBackend.add(self.class.to_s, attributes)
|
|
||||||
end
|
|
||||||
|
|
||||||
=begin
|
|
||||||
|
|
||||||
get data to store in search index
|
|
||||||
|
|
||||||
ticket = Ticket.find(123)
|
|
||||||
result = ticket.search_index_data
|
|
||||||
|
|
||||||
returns
|
|
||||||
|
|
||||||
result = {
|
|
||||||
attribute1: 'some value',
|
|
||||||
attribute2: ['value 1', 'value 2'],
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
=end
|
|
||||||
|
|
||||||
def search_index_data
|
|
||||||
attributes = {}
|
|
||||||
%w(name note).each { |key|
|
|
||||||
next if !self[key]
|
|
||||||
next if self[key].respond_to?('empty?') && self[key].empty?
|
|
||||||
attributes[key] = self[key]
|
|
||||||
}
|
|
||||||
return if attributes.empty?
|
|
||||||
attributes
|
|
||||||
end
|
|
||||||
|
|
||||||
=begin
|
|
||||||
|
|
||||||
lookup name of ref. objects
|
|
||||||
|
|
||||||
ticket = Ticket.find(3)
|
|
||||||
attributes = ticket.search_index_attribute_lookup
|
|
||||||
|
|
||||||
returns
|
|
||||||
|
|
||||||
attributes # object with lookup data
|
|
||||||
|
|
||||||
=end
|
|
||||||
|
|
||||||
def search_index_attribute_lookup
|
|
||||||
|
|
||||||
attributes = self.attributes
|
|
||||||
self.attributes.each { |key, value|
|
|
||||||
next if !value
|
|
||||||
|
|
||||||
# get attribute name
|
|
||||||
attribute_name_with_id = key.to_s
|
|
||||||
attribute_name = key.to_s
|
|
||||||
next if attribute_name[-3, 3] != '_id'
|
|
||||||
attribute_name = attribute_name[ 0, attribute_name.length - 3 ]
|
|
||||||
|
|
||||||
# check if attribute method exists
|
|
||||||
next if !respond_to?(attribute_name)
|
|
||||||
|
|
||||||
# check if method has own class
|
|
||||||
relation_class = send(attribute_name).class
|
|
||||||
next if !relation_class
|
|
||||||
|
|
||||||
# lookup ref object
|
|
||||||
relation_model = relation_class.lookup(id: value)
|
|
||||||
next if !relation_model
|
|
||||||
|
|
||||||
# get name of ref object
|
|
||||||
value = nil
|
|
||||||
if relation_model.respond_to?('search_index_data')
|
|
||||||
value = relation_model.send('search_index_data')
|
|
||||||
end
|
|
||||||
|
|
||||||
if relation_model.respond_to?('name')
|
|
||||||
value = relation_model.send('name')
|
|
||||||
end
|
|
||||||
|
|
||||||
next if !value
|
|
||||||
|
|
||||||
# save name of ref object
|
|
||||||
attributes[ attribute_name ] = value
|
|
||||||
}
|
|
||||||
|
|
||||||
# default ignored attributes
|
|
||||||
config = self.class.search_index_support_config
|
|
||||||
if config
|
|
||||||
ignore_attributes = {}
|
|
||||||
if config[:ignore_attributes]
|
|
||||||
config[:ignore_attributes].each { |key, value|
|
|
||||||
ignore_attributes[key] = value
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
# remove ignored attributes
|
|
||||||
ignore_attributes.each { |key, value|
|
|
||||||
next if value != true
|
|
||||||
attributes.delete(key.to_s)
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
attributes
|
|
||||||
end
|
|
||||||
end
|
|
30
app/models/application_model/touches_references.rb
Normal file
30
app/models/application_model/touches_references.rb
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
module ApplicationModel::TouchesReferences
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
# methods defined here are going to extend the class, not the instance of it
|
||||||
|
class_methods do
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
touch references by params
|
||||||
|
|
||||||
|
Model.touch_reference_by_params(
|
||||||
|
object: 'Ticket',
|
||||||
|
o_id: 123,
|
||||||
|
)
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def touch_reference_by_params(data)
|
||||||
|
|
||||||
|
object_class = Kernel.const_get(data[:object])
|
||||||
|
object = object_class.lookup(id: data[:o_id])
|
||||||
|
return if !object
|
||||||
|
object.touch
|
||||||
|
rescue => e
|
||||||
|
logger.error e.message
|
||||||
|
logger.error e.backtrace.inspect
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,6 +1,9 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
class Calendar < ApplicationModel
|
class Calendar < ApplicationModel
|
||||||
|
include NotifiesClients
|
||||||
|
include UniqNamed
|
||||||
|
|
||||||
store :business_hours
|
store :business_hours
|
||||||
store :public_holidays
|
store :public_holidays
|
||||||
|
|
||||||
|
@ -10,8 +13,6 @@ class Calendar < ApplicationModel
|
||||||
after_update :sync_default, :min_one_check
|
after_update :sync_default, :min_one_check
|
||||||
after_destroy :min_one_check
|
after_destroy :min_one_check
|
||||||
|
|
||||||
notify_clients_support
|
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
set inital default calendar
|
set inital default calendar
|
||||||
|
@ -38,7 +39,7 @@ returns calendar object
|
||||||
calendar_details = Service::GeoCalendar.location(ip)
|
calendar_details = Service::GeoCalendar.location(ip)
|
||||||
return if !calendar_details
|
return if !calendar_details
|
||||||
|
|
||||||
calendar_details['name'] = Calendar.genrate_uniq_name(calendar_details['name'])
|
calendar_details['name'] = Calendar.generate_uniq_name(calendar_details['name'])
|
||||||
calendar_details['default'] = true
|
calendar_details['default'] = true
|
||||||
calendar_details['created_by_id'] = 1
|
calendar_details['created_by_id'] = 1
|
||||||
calendar_details['updated_by_id'] = 1
|
calendar_details['updated_by_id'] = 1
|
||||||
|
|
|
@ -29,7 +29,7 @@ returns
|
||||||
data[ app_model ] = {}
|
data[ app_model ] = {}
|
||||||
end
|
end
|
||||||
if !data[ app_model ][ id ]
|
if !data[ app_model ][ id ]
|
||||||
attributes = attributes_with_associations
|
attributes = attributes_with_association_ids
|
||||||
|
|
||||||
# remove passwords if use is no admin
|
# remove passwords if use is no admin
|
||||||
access = false
|
access = false
|
||||||
|
|
|
@ -602,7 +602,7 @@ returns
|
||||||
return if !class_object
|
return if !class_object
|
||||||
class_instance = class_object.new
|
class_instance = class_object.new
|
||||||
|
|
||||||
return false if !class_instance.association_id_check(attribute, value)
|
return false if !class_instance.association_id_validation(attribute, value)
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
140
app/models/concerns/historisable.rb
Normal file
140
app/models/concerns/historisable.rb
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
module Historisable
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
attr_accessor :history_changes_last_done
|
||||||
|
|
||||||
|
after_create :history_create
|
||||||
|
after_update :history_update
|
||||||
|
after_destroy :history_destroy
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
log object create history, if configured - will be executed automatically
|
||||||
|
|
||||||
|
model = Model.find(123)
|
||||||
|
model.history_create
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def history_create
|
||||||
|
history_log('created', created_by_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
log object update history with all updated attributes, if configured - will be executed automatically
|
||||||
|
|
||||||
|
model = Model.find(123)
|
||||||
|
model.history_update
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def history_update
|
||||||
|
return if !changed?
|
||||||
|
|
||||||
|
# return if it's no update
|
||||||
|
return if new_record?
|
||||||
|
|
||||||
|
# new record also triggers update, so ignore new records
|
||||||
|
changes = self.changes
|
||||||
|
if history_changes_last_done
|
||||||
|
history_changes_last_done.each { |key, value|
|
||||||
|
if changes.key?(key) && changes[key] == value
|
||||||
|
changes.delete(key)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
self.history_changes_last_done = changes
|
||||||
|
#logger.info 'updated ' + self.changes.inspect
|
||||||
|
|
||||||
|
return if changes['id'] && !changes['id'][0]
|
||||||
|
|
||||||
|
ignored_attributes = self.class.instance_variable_get(:@history_attributes_ignored) || []
|
||||||
|
ignored_attributes += %i(created_at updated_at created_by_id updated_by_id)
|
||||||
|
|
||||||
|
changes.each { |key, value|
|
||||||
|
|
||||||
|
next if ignored_attributes.include?(key.to_sym)
|
||||||
|
|
||||||
|
# get attribute name
|
||||||
|
attribute_name = key.to_s
|
||||||
|
if attribute_name[-3, 3] == '_id'
|
||||||
|
attribute_name = attribute_name[ 0, attribute_name.length - 3 ]
|
||||||
|
end
|
||||||
|
|
||||||
|
value_id = []
|
||||||
|
value_str = [ value[0], value[1] ]
|
||||||
|
if key.to_s[-3, 3] == '_id'
|
||||||
|
value_id[0] = value[0]
|
||||||
|
value_id[1] = value[1]
|
||||||
|
|
||||||
|
if respond_to?(attribute_name) && send(attribute_name)
|
||||||
|
relation_class = send(attribute_name).class
|
||||||
|
if relation_class && value_id[0]
|
||||||
|
relation_model = relation_class.lookup(id: value_id[0])
|
||||||
|
if relation_model
|
||||||
|
if relation_model['name']
|
||||||
|
value_str[0] = relation_model['name']
|
||||||
|
elsif relation_model.respond_to?('fullname')
|
||||||
|
value_str[0] = relation_model.send('fullname')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if relation_class && value_id[1]
|
||||||
|
relation_model = relation_class.lookup(id: value_id[1])
|
||||||
|
if relation_model
|
||||||
|
if relation_model['name']
|
||||||
|
value_str[1] = relation_model['name']
|
||||||
|
elsif relation_model.respond_to?('fullname')
|
||||||
|
value_str[1] = relation_model.send('fullname')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
data = {
|
||||||
|
history_attribute: attribute_name,
|
||||||
|
value_from: value_str[0].to_s,
|
||||||
|
value_to: value_str[1].to_s,
|
||||||
|
id_from: value_id[0],
|
||||||
|
id_to: value_id[1],
|
||||||
|
}
|
||||||
|
#logger.info "HIST NEW #{self.class.to_s}.find(#{self.id}) #{data.inspect}"
|
||||||
|
history_log('updated', updated_by_id, data)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
delete object history, will be executed automatically
|
||||||
|
|
||||||
|
model = Model.find(123)
|
||||||
|
model.history_destroy
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def history_destroy
|
||||||
|
History.remove(self.class.to_s, id)
|
||||||
|
end
|
||||||
|
|
||||||
|
# methods defined here are going to extend the class, not the instance of it
|
||||||
|
class_methods do
|
||||||
|
=begin
|
||||||
|
|
||||||
|
serve methode to ignore model attributes in historization
|
||||||
|
|
||||||
|
class Model < ApplicationModel
|
||||||
|
include Historisable
|
||||||
|
history_attributes_ignored :create_article_type_id, :preferences
|
||||||
|
end
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def history_attributes_ignored(*attributes)
|
||||||
|
@history_attributes_ignored = attributes
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
19
app/models/concerns/latest_change_observed.rb
Normal file
19
app/models/concerns/latest_change_observed.rb
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
module LatestChangeObserved
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
after_create :latest_change_set_from_observer
|
||||||
|
after_update :latest_change_set_from_observer
|
||||||
|
after_touch :latest_change_set_from_observer
|
||||||
|
after_destroy :latest_change_set_from_observer_destroy
|
||||||
|
end
|
||||||
|
|
||||||
|
def latest_change_set_from_observer
|
||||||
|
self.class.latest_change_set(updated_at)
|
||||||
|
end
|
||||||
|
|
||||||
|
def latest_change_set_from_observer_destroy
|
||||||
|
self.class.latest_change_set(nil)
|
||||||
|
end
|
||||||
|
end
|
87
app/models/concerns/logs_activity_stream.rb
Normal file
87
app/models/concerns/logs_activity_stream.rb
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
module LogsActivityStream
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
after_create :activity_stream_create
|
||||||
|
after_update :activity_stream_update
|
||||||
|
before_destroy :activity_stream_destroy
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
log object create activity stream, if configured - will be executed automatically
|
||||||
|
|
||||||
|
model = Model.find(123)
|
||||||
|
model.activity_stream_create
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def activity_stream_create
|
||||||
|
activity_stream_log('create', self['created_by_id'])
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
log object update activity stream, if configured - will be executed automatically
|
||||||
|
|
||||||
|
model = Model.find(123)
|
||||||
|
model.activity_stream_update
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def activity_stream_update
|
||||||
|
return if !changed?
|
||||||
|
|
||||||
|
ignored_attributes = self.class.instance_variable_get(:@activity_stream_attributes_ignored) || []
|
||||||
|
ignored_attributes += %i(created_at updated_at created_by_id updated_by_id)
|
||||||
|
|
||||||
|
log = false
|
||||||
|
changes.each { |key, _value|
|
||||||
|
next if ignored_attributes.include?(key.to_sym)
|
||||||
|
|
||||||
|
log = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return if !log
|
||||||
|
|
||||||
|
activity_stream_log('update', self['updated_by_id'])
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
delete object activity stream, will be executed automatically
|
||||||
|
|
||||||
|
model = Model.find(123)
|
||||||
|
model.activity_stream_destroy
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def activity_stream_destroy
|
||||||
|
ActivityStream.remove(self.class.to_s, id)
|
||||||
|
end
|
||||||
|
|
||||||
|
# methods defined here are going to extend the class, not the instance of it
|
||||||
|
class_methods do
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
serve methode to ignore model attributes in activity stream and/or limit activity stream permission
|
||||||
|
|
||||||
|
class Model < ApplicationModel
|
||||||
|
include LogsActivityStream
|
||||||
|
activity_stream_permission 'admin.user'
|
||||||
|
activity_stream_attributes_ignored :create_article_type_id, :preferences
|
||||||
|
end
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def activity_stream_attributes_ignored(*attributes)
|
||||||
|
@activity_stream_attributes_ignored = attributes
|
||||||
|
end
|
||||||
|
|
||||||
|
def activity_stream_permission(permission)
|
||||||
|
@activity_stream_permission = permission
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
138
app/models/concerns/notifies_clients.rb
Normal file
138
app/models/concerns/notifies_clients.rb
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
module NotifiesClients
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
after_create :notify_clients_after_create
|
||||||
|
after_update :notify_clients_after_update
|
||||||
|
after_touch :notify_clients_after_touch
|
||||||
|
after_destroy :notify_clients_after_destroy
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
notify_clients_after_create after model got created
|
||||||
|
|
||||||
|
used as callback in model file
|
||||||
|
|
||||||
|
class OwnModel < ApplicationModel
|
||||||
|
after_create :notify_clients_after_create
|
||||||
|
after_update :notify_clients_after_update
|
||||||
|
after_touch :notify_clients_after_touch
|
||||||
|
after_destroy :notify_clients_after_destroy
|
||||||
|
|
||||||
|
[...]
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def notify_clients_after_create
|
||||||
|
|
||||||
|
# return if we run import mode
|
||||||
|
return if Setting.get('import_mode')
|
||||||
|
logger.debug "#{self.class.name}.find(#{id}) notify created " + created_at.to_s
|
||||||
|
class_name = self.class.name
|
||||||
|
class_name.gsub!(/::/, '')
|
||||||
|
PushMessages.send(
|
||||||
|
message: {
|
||||||
|
event: class_name + ':create',
|
||||||
|
data: { id: id, updated_at: updated_at }
|
||||||
|
},
|
||||||
|
type: 'authenticated',
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
notify_clients_after_update after model got updated
|
||||||
|
|
||||||
|
used as callback in model file
|
||||||
|
|
||||||
|
class OwnModel < ApplicationModel
|
||||||
|
after_create :notify_clients_after_create
|
||||||
|
after_update :notify_clients_after_update
|
||||||
|
after_touch :notify_clients_after_touch
|
||||||
|
after_destroy :notify_clients_after_destroy
|
||||||
|
|
||||||
|
[...]
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def notify_clients_after_update
|
||||||
|
|
||||||
|
# return if we run import mode
|
||||||
|
return if Setting.get('import_mode')
|
||||||
|
logger.debug "#{self.class.name}.find(#{id}) notify UPDATED " + updated_at.to_s
|
||||||
|
class_name = self.class.name
|
||||||
|
class_name.gsub!(/::/, '')
|
||||||
|
PushMessages.send(
|
||||||
|
message: {
|
||||||
|
event: class_name + ':update',
|
||||||
|
data: { id: id, updated_at: updated_at }
|
||||||
|
},
|
||||||
|
type: 'authenticated',
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
notify_clients_after_touch after model got touched
|
||||||
|
|
||||||
|
used as callback in model file
|
||||||
|
|
||||||
|
class OwnModel < ApplicationModel
|
||||||
|
after_create :notify_clients_after_create
|
||||||
|
after_update :notify_clients_after_update
|
||||||
|
after_touch :notify_clients_after_touch
|
||||||
|
after_destroy :notify_clients_after_destroy
|
||||||
|
|
||||||
|
[...]
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def notify_clients_after_touch
|
||||||
|
|
||||||
|
# return if we run import mode
|
||||||
|
return if Setting.get('import_mode')
|
||||||
|
logger.debug "#{self.class.name}.find(#{id}) notify TOUCH " + updated_at.to_s
|
||||||
|
class_name = self.class.name
|
||||||
|
class_name.gsub!(/::/, '')
|
||||||
|
PushMessages.send(
|
||||||
|
message: {
|
||||||
|
event: class_name + ':touch',
|
||||||
|
data: { id: id, updated_at: updated_at }
|
||||||
|
},
|
||||||
|
type: 'authenticated',
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
notify_clients_after_destroy after model got destroyed
|
||||||
|
|
||||||
|
used as callback in model file
|
||||||
|
|
||||||
|
class OwnModel < ApplicationModel
|
||||||
|
after_create :notify_clients_after_create
|
||||||
|
after_update :notify_clients_after_update
|
||||||
|
after_touch :notify_clients_after_touch
|
||||||
|
after_destroy :notify_clients_after_destroy
|
||||||
|
|
||||||
|
[...]
|
||||||
|
|
||||||
|
=end
|
||||||
|
def notify_clients_after_destroy
|
||||||
|
|
||||||
|
# return if we run import mode
|
||||||
|
return if Setting.get('import_mode')
|
||||||
|
logger.debug "#{self.class.name}.find(#{id}) notify DESTOY " + updated_at.to_s
|
||||||
|
class_name = self.class.name
|
||||||
|
class_name.gsub!(/::/, '')
|
||||||
|
PushMessages.send(
|
||||||
|
message: {
|
||||||
|
event: class_name + ':destroy',
|
||||||
|
data: { id: id, updated_at: updated_at }
|
||||||
|
},
|
||||||
|
type: 'authenticated',
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
138
app/models/concerns/search_indexed.rb
Normal file
138
app/models/concerns/search_indexed.rb
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
module SearchIndexed
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
after_create :search_index_update
|
||||||
|
after_update :search_index_update
|
||||||
|
after_touch :search_index_update
|
||||||
|
after_destroy :search_index_destroy
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
update search index, if configured - will be executed automatically
|
||||||
|
|
||||||
|
model = Model.find(123)
|
||||||
|
model.search_index_update
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def search_index_update
|
||||||
|
return if ignore_search_indexing?(:update)
|
||||||
|
|
||||||
|
# start background job to transfer data to search index
|
||||||
|
return if !SearchIndexBackend.enabled?
|
||||||
|
Delayed::Job.enqueue(BackgroundJobSearchIndex.new(self.class.to_s, id))
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
delete search index object, will be executed automatically
|
||||||
|
|
||||||
|
model = Model.find(123)
|
||||||
|
model.search_index_destroy
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def search_index_destroy
|
||||||
|
return if ignore_search_indexing?(:destroy)
|
||||||
|
SearchIndexBackend.remove(self.class.to_s, id)
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
collect data to index and send to backend
|
||||||
|
|
||||||
|
ticket = Ticket.find(123)
|
||||||
|
result = ticket.search_index_update_backend
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
result = true # false
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def search_index_update_backend
|
||||||
|
# fill up with search data
|
||||||
|
attributes = search_index_attribute_lookup
|
||||||
|
return if !attributes
|
||||||
|
|
||||||
|
# update backend
|
||||||
|
SearchIndexBackend.add(self.class.to_s, attributes)
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
get data to store in search index
|
||||||
|
|
||||||
|
ticket = Ticket.find(123)
|
||||||
|
result = ticket.search_index_data
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
result = {
|
||||||
|
attribute1: 'some value',
|
||||||
|
attribute2: ['value 1', 'value 2'],
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def search_index_data
|
||||||
|
attributes = {}
|
||||||
|
%w(name note).each { |key|
|
||||||
|
next if !self[key]
|
||||||
|
next if self[key].respond_to?('empty?') && self[key].empty?
|
||||||
|
attributes[key] = self[key]
|
||||||
|
}
|
||||||
|
return if attributes.empty?
|
||||||
|
attributes
|
||||||
|
end
|
||||||
|
|
||||||
|
def ignore_search_indexing?(_action)
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
# methods defined here are going to extend the class, not the instance of it
|
||||||
|
class_methods do
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
serve methode to ignore model attributes in search index
|
||||||
|
|
||||||
|
class Model < ApplicationModel
|
||||||
|
include SearchIndexed
|
||||||
|
search_index_attributes_ignored :password, :image
|
||||||
|
end
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def search_index_attributes_ignored(*attributes)
|
||||||
|
@search_index_attributes_ignored = attributes
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
reload search index with full data
|
||||||
|
|
||||||
|
Model.search_index_reload
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def search_index_reload
|
||||||
|
tolerance = 5
|
||||||
|
tolerance_count = 0
|
||||||
|
all.order('created_at DESC').each { |item|
|
||||||
|
next if item.ignore_search_indexing?(:destroy)
|
||||||
|
begin
|
||||||
|
item.search_index_update_backend
|
||||||
|
rescue => e
|
||||||
|
logger.error "Unable to send #{item.class}.find(#{item.id}) backend: #{e.inspect}"
|
||||||
|
tolerance_count += 1
|
||||||
|
raise "Unable to send #{item.class}.find(#{item.id}) backend: #{e.inspect}" if tolerance_count == tolerance
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
31
app/models/concerns/uniq_named.rb
Normal file
31
app/models/concerns/uniq_named.rb
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
module UniqNamed
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
# methods defined here are going to extend the class, not the instance of it
|
||||||
|
class_methods do
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
generate uniq name (will check name of model and generates _1 sequenze)
|
||||||
|
|
||||||
|
Used as before_update callback, no own use needed
|
||||||
|
|
||||||
|
name = Model.generate_uniq_name('some name')
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
result = 'some name_X'
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def generate_uniq_name(name)
|
||||||
|
return name if !exists?(name: name)
|
||||||
|
(1..100).each { |counter|
|
||||||
|
name = "#{name}_#{counter}"
|
||||||
|
break if !exists?(name: name)
|
||||||
|
}
|
||||||
|
name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,6 +1,8 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
class EmailAddress < ApplicationModel
|
class EmailAddress < ApplicationModel
|
||||||
|
include LatestChangeObserved
|
||||||
|
|
||||||
has_many :groups, after_add: :cache_update, after_remove: :cache_update
|
has_many :groups, after_add: :cache_update, after_remove: :cache_update
|
||||||
belongs_to :channel
|
belongs_to :channel
|
||||||
validates :realname, presence: true
|
validates :realname, presence: true
|
||||||
|
@ -12,8 +14,6 @@ class EmailAddress < ApplicationModel
|
||||||
after_update :update_email_address_id
|
after_update :update_email_address_id
|
||||||
after_destroy :delete_group_reference
|
after_destroy :delete_group_reference
|
||||||
|
|
||||||
latest_change_support
|
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
check and if channel not exists reset configured channels for email addresses
|
check and if channel not exists reset configured channels for email addresses
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
class Group < ApplicationModel
|
class Group < ApplicationModel
|
||||||
|
include LogsActivityStream
|
||||||
|
include NotifiesClients
|
||||||
|
include LatestChangeObserved
|
||||||
|
include Historisable
|
||||||
|
|
||||||
has_and_belongs_to_many :users, after_add: :cache_update, after_remove: :cache_update
|
has_and_belongs_to_many :users, after_add: :cache_update, after_remove: :cache_update
|
||||||
belongs_to :email_address
|
belongs_to :email_address
|
||||||
belongs_to :signature
|
belongs_to :signature
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
|
|
||||||
activity_stream_support permission: 'admin.group'
|
activity_stream_permission 'admin.group'
|
||||||
history_support
|
|
||||||
notify_clients_support
|
|
||||||
latest_change_support
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -308,17 +308,6 @@ returns
|
||||||
history_attribute
|
history_attribute
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
=begin
|
|
||||||
|
|
||||||
nothing to do on destroying history entries
|
|
||||||
|
|
||||||
=end
|
|
||||||
|
|
||||||
def destroy_dependencies
|
|
||||||
end
|
|
||||||
|
|
||||||
class Object < ApplicationModel
|
class Object < ApplicationModel
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
class Job < ApplicationModel
|
class Job < ApplicationModel
|
||||||
|
include NotifiesClients
|
||||||
|
|
||||||
load 'job/assets.rb'
|
load 'job/assets.rb'
|
||||||
include Job::Assets
|
include Job::Assets
|
||||||
|
|
||||||
|
@ -12,8 +14,6 @@ class Job < ApplicationModel
|
||||||
before_create :updated_matching, :update_next_run_at
|
before_create :updated_matching, :update_next_run_at
|
||||||
before_update :updated_matching, :update_next_run_at
|
before_update :updated_matching, :update_next_run_at
|
||||||
|
|
||||||
notify_clients_support
|
|
||||||
|
|
||||||
def self.run
|
def self.run
|
||||||
jobs = Job.where(active: true, running: false)
|
jobs = Job.where(active: true, running: false)
|
||||||
jobs.each do |job|
|
jobs.each do |job|
|
||||||
|
|
|
@ -32,7 +32,7 @@ returns
|
||||||
data[ User.to_app_model ] = {}
|
data[ User.to_app_model ] = {}
|
||||||
end
|
end
|
||||||
if !data[ app_model ][ id ]
|
if !data[ app_model ][ id ]
|
||||||
data[ app_model ][ id ] = attributes_with_associations
|
data[ app_model ][ id ] = attributes_with_association_ids
|
||||||
data = assets_of_selector('condition', data)
|
data = assets_of_selector('condition', data)
|
||||||
data = assets_of_selector('perform', data)
|
data = assets_of_selector('perform', data)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
class Macro < ApplicationModel
|
class Macro < ApplicationModel
|
||||||
|
include NotifiesClients
|
||||||
|
include LatestChangeObserved
|
||||||
|
|
||||||
store :perform
|
store :perform
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
|
|
||||||
notify_clients_support
|
|
||||||
latest_change_support
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
class ObjectManager::Attribute < ApplicationModel
|
class ObjectManager::Attribute < ApplicationModel
|
||||||
|
include NotifiesClients
|
||||||
|
|
||||||
self.table_name = 'object_manager_attributes'
|
self.table_name = 'object_manager_attributes'
|
||||||
|
|
||||||
belongs_to :object_lookup, class_name: 'ObjectLookup'
|
belongs_to :object_lookup, class_name: 'ObjectLookup'
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
store :screens
|
store :screens
|
||||||
store :data_option
|
store :data_option
|
||||||
store :data_option_new
|
store :data_option_new
|
||||||
|
|
||||||
notify_clients_support
|
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
list of all attributes
|
list of all attributes
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
class Organization < ApplicationModel
|
class Organization < ApplicationModel
|
||||||
|
include LogsActivityStream
|
||||||
|
include NotifiesClients
|
||||||
|
include LatestChangeObserved
|
||||||
|
include Historisable
|
||||||
|
include SearchIndexed
|
||||||
|
|
||||||
load 'organization/permission.rb'
|
load 'organization/permission.rb'
|
||||||
include Organization::Permission
|
include Organization::Permission
|
||||||
load 'organization/assets.rb'
|
load 'organization/assets.rb'
|
||||||
|
@ -16,11 +22,7 @@ class Organization < ApplicationModel
|
||||||
before_create :domain_cleanup
|
before_create :domain_cleanup
|
||||||
before_update :domain_cleanup
|
before_update :domain_cleanup
|
||||||
|
|
||||||
activity_stream_support permission: 'admin.role'
|
activity_stream_permission 'admin.role'
|
||||||
history_support
|
|
||||||
search_index_support
|
|
||||||
notify_clients_support
|
|
||||||
latest_change_support
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
class Overview < ApplicationModel
|
class Overview < ApplicationModel
|
||||||
|
include NotifiesClients
|
||||||
|
include LatestChangeObserved
|
||||||
|
|
||||||
load 'overview/assets.rb'
|
load 'overview/assets.rb'
|
||||||
include Overview::Assets
|
include Overview::Assets
|
||||||
|
|
||||||
|
@ -13,9 +16,6 @@ class Overview < ApplicationModel
|
||||||
before_create :fill_link_on_create, :fill_prio
|
before_create :fill_link_on_create, :fill_prio
|
||||||
before_update :fill_link_on_update
|
before_update :fill_link_on_update
|
||||||
|
|
||||||
notify_clients_support
|
|
||||||
latest_change_support
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def fill_prio
|
def fill_prio
|
||||||
|
|
|
@ -33,7 +33,7 @@ returns
|
||||||
data[ app_model_user ] = {}
|
data[ app_model_user ] = {}
|
||||||
end
|
end
|
||||||
if !data[ app_model_overview ][ id ]
|
if !data[ app_model_overview ][ id ]
|
||||||
data[ app_model_overview ][ id ] = attributes_with_associations
|
data[ app_model_overview ][ id ] = attributes_with_association_ids
|
||||||
if user_ids
|
if user_ids
|
||||||
user_ids.each { |local_user_id|
|
user_ids.each { |local_user_id|
|
||||||
next if data[ app_model_user ][ local_user_id ]
|
next if data[ app_model_user ][ local_user_id ]
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
class Permission < ApplicationModel
|
class Permission < ApplicationModel
|
||||||
|
include NotifiesClients
|
||||||
|
include LatestChangeObserved
|
||||||
|
|
||||||
has_and_belongs_to_many :roles
|
has_and_belongs_to_many :roles
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
store :preferences
|
store :preferences
|
||||||
notify_clients_support
|
|
||||||
latest_change_support
|
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
class Role < ApplicationModel
|
class Role < ApplicationModel
|
||||||
|
include LogsActivityStream
|
||||||
|
include NotifiesClients
|
||||||
|
include LatestChangeObserved
|
||||||
|
|
||||||
has_and_belongs_to_many :users, after_add: :cache_update, after_remove: :cache_update
|
has_and_belongs_to_many :users, after_add: :cache_update, after_remove: :cache_update
|
||||||
has_and_belongs_to_many :permissions, after_add: :cache_update, after_remove: :cache_update
|
has_and_belongs_to_many :permissions, after_add: :cache_update, after_remove: :cache_update
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
|
@ -9,10 +13,9 @@ class Role < ApplicationModel
|
||||||
before_create :validate_permissions
|
before_create :validate_permissions
|
||||||
before_update :validate_permissions
|
before_update :validate_permissions
|
||||||
|
|
||||||
attributes_with_associations_support ignore: { user_ids: true }
|
association_attributes_ignored :user_ids
|
||||||
activity_stream_support permission: 'admin.role'
|
|
||||||
notify_clients_support
|
activity_stream_permission 'admin.role'
|
||||||
latest_change_support
|
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
class Signature < ApplicationModel
|
class Signature < ApplicationModel
|
||||||
has_many :groups, after_add: :cache_update, after_remove: :cache_update
|
include LatestChangeObserved
|
||||||
validates :name, presence: true
|
|
||||||
latest_change_support
|
has_many :groups, after_add: :cache_update, after_remove: :cache_update
|
||||||
|
validates :name, presence: true
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
class Sla < ApplicationModel
|
class Sla < ApplicationModel
|
||||||
|
include NotifiesClients
|
||||||
|
|
||||||
load 'sla/assets.rb'
|
load 'sla/assets.rb'
|
||||||
include Sla::Assets
|
include Sla::Assets
|
||||||
|
|
||||||
|
@ -8,7 +10,4 @@ class Sla < ApplicationModel
|
||||||
store :data
|
store :data
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
belongs_to :calendar
|
belongs_to :calendar
|
||||||
|
|
||||||
notify_clients_support
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -33,7 +33,7 @@ returns
|
||||||
data[ app_model_user ] = {}
|
data[ app_model_user ] = {}
|
||||||
end
|
end
|
||||||
if !data[ app_model_sla ][ id ]
|
if !data[ app_model_sla ][ id ]
|
||||||
data[ app_model_sla ][ id ] = attributes_with_associations
|
data[ app_model_sla ][ id ] = attributes_with_association_ids
|
||||||
data = assets_of_selector('condition', data)
|
data = assets_of_selector('condition', data)
|
||||||
if calendar_id
|
if calendar_id
|
||||||
calendar = Calendar.lookup(id: calendar_id)
|
calendar = Calendar.lookup(id: calendar_id)
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
class Template < ApplicationModel
|
class Template < ApplicationModel
|
||||||
store :options
|
include NotifiesClients
|
||||||
validates :name, presence: true
|
|
||||||
notify_clients_support
|
store :options
|
||||||
|
validates :name, presence: true
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
class TextModule < ApplicationModel
|
class TextModule < ApplicationModel
|
||||||
validates :name, presence: true
|
include NotifiesClients
|
||||||
validates :content, presence: true
|
|
||||||
notify_clients_support
|
validates :name, presence: true
|
||||||
|
validates :content, presence: true
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
|
|
|
@ -1,68 +1,57 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
|
||||||
class Ticket < ApplicationModel
|
class Ticket < ApplicationModel
|
||||||
|
include LogsActivityStream
|
||||||
|
include NotifiesClients
|
||||||
|
include LatestChangeObserved
|
||||||
|
include Historisable
|
||||||
|
include SearchIndexed
|
||||||
|
|
||||||
include Ticket::Escalation
|
include Ticket::Escalation
|
||||||
include Ticket::Subject
|
include Ticket::Subject
|
||||||
load 'ticket/permission.rb'
|
load 'ticket/permission.rb'
|
||||||
include Ticket::Permission
|
include Ticket::Permission
|
||||||
load 'ticket/assets.rb'
|
load 'ticket/assets.rb'
|
||||||
include Ticket::Assets
|
include Ticket::Assets
|
||||||
load 'ticket/history_log.rb'
|
|
||||||
include Ticket::HistoryLog
|
|
||||||
load 'ticket/activity_stream_log.rb'
|
|
||||||
include Ticket::ActivityStreamLog
|
|
||||||
load 'ticket/search_index.rb'
|
load 'ticket/search_index.rb'
|
||||||
include Ticket::SearchIndex
|
include Ticket::SearchIndex
|
||||||
extend Ticket::Search
|
extend Ticket::Search
|
||||||
|
|
||||||
store :preferences
|
store :preferences
|
||||||
before_create :check_generate, :check_defaults, :check_title, :check_escalation_update
|
before_create :check_generate, :check_defaults, :check_title, :check_escalation_update
|
||||||
before_update :check_defaults, :check_title, :reset_pending_time, :check_escalation_update
|
before_update :check_defaults, :check_title, :reset_pending_time, :check_escalation_update
|
||||||
before_destroy :destroy_dependencies
|
before_destroy :destroy_dependencies
|
||||||
|
|
||||||
validates :group_id, presence: true
|
validates :group_id, presence: true
|
||||||
validates :priority_id, presence: true
|
validates :priority_id, presence: true
|
||||||
validates :state_id, presence: true
|
validates :state_id, presence: true
|
||||||
|
|
||||||
notify_clients_support
|
activity_stream_permission 'ticket.agent'
|
||||||
|
|
||||||
latest_change_support
|
activity_stream_attributes_ignored :organization_id, # organization_id will channge automatically on user update
|
||||||
|
:create_article_type_id,
|
||||||
|
:create_article_sender_id,
|
||||||
|
:article_count,
|
||||||
|
:first_response_at,
|
||||||
|
:first_response_escalation_at,
|
||||||
|
:first_response_in_min,
|
||||||
|
:first_response_diff_in_min,
|
||||||
|
:close_at,
|
||||||
|
:close_escalation_at,
|
||||||
|
:close_in_min,
|
||||||
|
:close_diff_in_min,
|
||||||
|
:update_escalation_at,
|
||||||
|
:update_in_min,
|
||||||
|
:update_diff_in_min,
|
||||||
|
:last_contact_at,
|
||||||
|
:last_contact_agent_at,
|
||||||
|
:last_contact_customer_at,
|
||||||
|
:preferences
|
||||||
|
|
||||||
activity_stream_support(
|
history_attributes_ignored :create_article_type_id,
|
||||||
permission: 'ticket.agent',
|
:create_article_sender_id,
|
||||||
ignore_attributes: {
|
:article_count,
|
||||||
organization_id: true, # organization_id will channge automatically on user update
|
:preferences
|
||||||
create_article_type_id: true,
|
|
||||||
create_article_sender_id: true,
|
|
||||||
article_count: true,
|
|
||||||
first_response_at: true,
|
|
||||||
first_response_escalation_at: true,
|
|
||||||
first_response_in_min: true,
|
|
||||||
first_response_diff_in_min: true,
|
|
||||||
close_at: true,
|
|
||||||
close_escalation_at: true,
|
|
||||||
close_in_min: true,
|
|
||||||
close_diff_in_min: true,
|
|
||||||
update_escalation_at: true,
|
|
||||||
update_in_min: true,
|
|
||||||
update_diff_in_min: true,
|
|
||||||
last_contact_at: true,
|
|
||||||
last_contact_agent_at: true,
|
|
||||||
last_contact_customer_at: true,
|
|
||||||
preferences: true,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
history_support(
|
|
||||||
ignore_attributes: {
|
|
||||||
create_article_type_id: true,
|
|
||||||
create_article_sender_id: true,
|
|
||||||
article_count: true,
|
|
||||||
preferences: true,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
search_index_support
|
|
||||||
|
|
||||||
belongs_to :group, class_name: 'Group'
|
belongs_to :group, class_name: 'Group'
|
||||||
has_many :articles, class_name: 'Ticket::Article', after_add: :cache_update, after_remove: :cache_update
|
has_many :articles, class_name: 'Ticket::Article', after_add: :cache_update, after_remove: :cache_update
|
||||||
|
@ -861,6 +850,27 @@ result
|
||||||
Ticket::Article.where(ticket_id: id).order(:created_at, :id)
|
Ticket::Article.where(ticket_id: id).order(:created_at, :id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def history_get(fulldata = false)
|
||||||
|
list = History.list(self.class.name, self['id'], 'Ticket::Article')
|
||||||
|
return list if !fulldata
|
||||||
|
|
||||||
|
# get related objects
|
||||||
|
assets = {}
|
||||||
|
list.each { |item|
|
||||||
|
record = Kernel.const_get(item['object']).find(item['o_id'])
|
||||||
|
assets = record.assets(assets)
|
||||||
|
|
||||||
|
if item['related_object']
|
||||||
|
record = Kernel.const_get(item['related_object']).find( item['related_o_id'])
|
||||||
|
assets = record.assets(assets)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
{
|
||||||
|
history: list,
|
||||||
|
assets: assets,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def check_generate
|
def check_generate
|
||||||
|
@ -915,5 +925,4 @@ result
|
||||||
# destroy online notifications
|
# destroy online notifications
|
||||||
OnlineNotification.remove(self.class.to_s, id)
|
OnlineNotification.remove(self.class.to_s, id)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
|
||||||
module Ticket::ActivityStreamLog
|
|
||||||
|
|
||||||
=begin
|
|
||||||
|
|
||||||
log activity for this object
|
|
||||||
|
|
||||||
ticket = Ticket.find(123)
|
|
||||||
result = ticket.activity_stream_log('create', user_id)
|
|
||||||
|
|
||||||
returns
|
|
||||||
|
|
||||||
result = true # false
|
|
||||||
|
|
||||||
=end
|
|
||||||
|
|
||||||
def activity_stream_log(type, user_id)
|
|
||||||
|
|
||||||
# return if we run import mode
|
|
||||||
return if Setting.get('import_mode')
|
|
||||||
|
|
||||||
# return if we run on init mode
|
|
||||||
return if !Setting.get('system_init_done')
|
|
||||||
|
|
||||||
return if !self.class.activity_stream_support_config
|
|
||||||
permission = self.class.activity_stream_support_config[:permission]
|
|
||||||
ActivityStream.add(
|
|
||||||
o_id: self['id'],
|
|
||||||
type: type,
|
|
||||||
object: self.class.name,
|
|
||||||
group_id: self['group_id'],
|
|
||||||
permission: permission,
|
|
||||||
created_at: updated_at,
|
|
||||||
created_by_id: user_id,
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,11 +1,11 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
class Ticket::Article < ApplicationModel
|
class Ticket::Article < ApplicationModel
|
||||||
|
include LogsActivityStream
|
||||||
|
include NotifiesClients
|
||||||
|
include Historisable
|
||||||
|
|
||||||
load 'ticket/article/assets.rb'
|
load 'ticket/article/assets.rb'
|
||||||
include Ticket::Article::Assets
|
include Ticket::Article::Assets
|
||||||
load 'ticket/article/history_log.rb'
|
|
||||||
include Ticket::Article::HistoryLog
|
|
||||||
load 'ticket/article/activity_stream_log.rb'
|
|
||||||
include Ticket::Article::ActivityStreamLog
|
|
||||||
|
|
||||||
belongs_to :ticket
|
belongs_to :ticket
|
||||||
belongs_to :type, class_name: 'Ticket::Article::Type'
|
belongs_to :type, class_name: 'Ticket::Article::Type'
|
||||||
|
@ -16,28 +16,19 @@ class Ticket::Article < ApplicationModel
|
||||||
before_create :check_subject, :check_message_id_md5
|
before_create :check_subject, :check_message_id_md5
|
||||||
before_update :check_subject, :check_message_id_md5
|
before_update :check_subject, :check_message_id_md5
|
||||||
|
|
||||||
notify_clients_support
|
activity_stream_permission 'ticket.agent'
|
||||||
|
|
||||||
activity_stream_support(
|
activity_stream_attributes_ignored :type_id,
|
||||||
permission: 'ticket.agent',
|
:sender_id,
|
||||||
ignore_attributes: {
|
:preferences
|
||||||
type_id: true,
|
|
||||||
sender_id: true,
|
|
||||||
preferences: true,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
history_support(
|
history_attributes_ignored :type_id,
|
||||||
ignore_attributes: {
|
:sender_id,
|
||||||
type_id: true,
|
:preferences,
|
||||||
sender_id: true,
|
:message_id,
|
||||||
preferences: true,
|
:from,
|
||||||
message_id: true,
|
:to,
|
||||||
from: true,
|
:cc
|
||||||
to: true,
|
|
||||||
cc: true,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
# fillup md5 of message id to search easier on very long message ids
|
# fillup md5 of message id to search easier on very long message ids
|
||||||
def check_message_id_md5
|
def check_message_id_md5
|
||||||
|
@ -220,16 +211,32 @@ returns:
|
||||||
subject.gsub!(/\s|\t|\r/, ' ')
|
subject.gsub!(/\s|\t|\r/, ' ')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def history_log_attributes
|
||||||
|
{
|
||||||
|
related_o_id: self['ticket_id'],
|
||||||
|
related_history_object: 'Ticket',
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
# callback function to overwrite
|
||||||
|
# default history stream log attributes
|
||||||
|
# gets called from activity_stream_log
|
||||||
|
def activity_stream_log_attributes
|
||||||
|
{
|
||||||
|
group_id: Ticket.find(ticket_id).group_id,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
class Flag < ApplicationModel
|
class Flag < ApplicationModel
|
||||||
end
|
end
|
||||||
|
|
||||||
class Sender < ApplicationModel
|
class Sender < ApplicationModel
|
||||||
|
include LatestChangeObserved
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
latest_change_support
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class Type < ApplicationModel
|
class Type < ApplicationModel
|
||||||
|
include LatestChangeObserved
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
latest_change_support
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
|
||||||
module Ticket::Article::ActivityStreamLog
|
|
||||||
|
|
||||||
=begin
|
|
||||||
|
|
||||||
log activity for this object
|
|
||||||
|
|
||||||
article = Ticket::Article.find(123)
|
|
||||||
result = article.activity_stream_log('create', user_id)
|
|
||||||
|
|
||||||
returns
|
|
||||||
|
|
||||||
result = true # false
|
|
||||||
|
|
||||||
=end
|
|
||||||
|
|
||||||
def activity_stream_log(type, user_id)
|
|
||||||
|
|
||||||
# return if we run import mode
|
|
||||||
return if Setting.get('import_mode')
|
|
||||||
|
|
||||||
# return if we run on init mode
|
|
||||||
return if !Setting.get('system_init_done')
|
|
||||||
|
|
||||||
return if !self.class.activity_stream_support_config
|
|
||||||
permission = self.class.activity_stream_support_config[:permission]
|
|
||||||
ticket = Ticket.lookup(id: ticket_id)
|
|
||||||
ActivityStream.add(
|
|
||||||
o_id: self['id'],
|
|
||||||
type: type,
|
|
||||||
object: self.class.name,
|
|
||||||
group_id: ticket.group_id,
|
|
||||||
permission: permission,
|
|
||||||
created_at: updated_at,
|
|
||||||
created_by_id: user_id,
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,32 +0,0 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
|
||||||
|
|
||||||
module Ticket::Article::HistoryLog
|
|
||||||
|
|
||||||
=begin
|
|
||||||
|
|
||||||
create log activity for this article
|
|
||||||
|
|
||||||
article = Ticket::Article.find(123)
|
|
||||||
result = article.history_create( 'created', user_id )
|
|
||||||
|
|
||||||
returns
|
|
||||||
|
|
||||||
result = true # false
|
|
||||||
|
|
||||||
=end
|
|
||||||
|
|
||||||
def history_log (type, user_id, data = {})
|
|
||||||
|
|
||||||
# if Ticketdata[:data[:Article has changed, remember related ticket to be able
|
|
||||||
# to show article changes in ticket history
|
|
||||||
data[:o_id] = self['id']
|
|
||||||
data[:history_type] = type
|
|
||||||
data[:history_object] = self.class.name
|
|
||||||
data[:related_o_id] = self['ticket_id']
|
|
||||||
data[:related_history_object] = 'Ticket'
|
|
||||||
data[:created_by_id] = user_id
|
|
||||||
data[:updated_at] = updated_at
|
|
||||||
data[:created_at] = updated_at
|
|
||||||
History.add(data)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -29,7 +29,7 @@ returns
|
||||||
data[ app_model_ticket ] = {}
|
data[ app_model_ticket ] = {}
|
||||||
end
|
end
|
||||||
if !data[ app_model_ticket ][ id ]
|
if !data[ app_model_ticket ][ id ]
|
||||||
data[ app_model_ticket ][ id ] = attributes_with_associations
|
data[ app_model_ticket ][ id ] = attributes_with_association_ids
|
||||||
end
|
end
|
||||||
%w(created_by_id updated_by_id owner_id customer_id).each { |local_user_id|
|
%w(created_by_id updated_by_id owner_id customer_id).each { |local_user_id|
|
||||||
next if !self[ local_user_id ]
|
next if !self[ local_user_id ]
|
||||||
|
|
|
@ -1,81 +0,0 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
|
||||||
module Ticket::HistoryLog
|
|
||||||
|
|
||||||
=begin
|
|
||||||
|
|
||||||
create log activity for this ticket
|
|
||||||
|
|
||||||
ticket = Ticket.find(123)
|
|
||||||
result = ticket.history_create('created', user_id)
|
|
||||||
|
|
||||||
returns
|
|
||||||
|
|
||||||
result = true # false
|
|
||||||
|
|
||||||
=end
|
|
||||||
|
|
||||||
def history_log(type, user_id, data = {})
|
|
||||||
data[:o_id] = self['id']
|
|
||||||
data[:history_type] = type
|
|
||||||
data[:history_object] = self.class.name
|
|
||||||
data[:related_o_id] = nil
|
|
||||||
data[:related_history_object] = nil
|
|
||||||
data[:created_by_id] = user_id
|
|
||||||
data[:updated_at] = updated_at
|
|
||||||
data[:created_at] = updated_at
|
|
||||||
History.add(data)
|
|
||||||
end
|
|
||||||
|
|
||||||
=begin
|
|
||||||
|
|
||||||
get log activity for this ticket
|
|
||||||
|
|
||||||
ticket = Ticket.find(123)
|
|
||||||
result = ticket.history_get()
|
|
||||||
|
|
||||||
returns
|
|
||||||
|
|
||||||
result = [
|
|
||||||
{
|
|
||||||
type: 'created',
|
|
||||||
object: 'Ticket',
|
|
||||||
created_by_id: 3,
|
|
||||||
created_at: "2013-08-19 20:41:33",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'updated',
|
|
||||||
object: 'Ticket',
|
|
||||||
attribute: 'priority',
|
|
||||||
o_id: 1,
|
|
||||||
id_to: 3,
|
|
||||||
id_from: 2,
|
|
||||||
value_from: "low",
|
|
||||||
value_to: "high",
|
|
||||||
created_by_id: 3,
|
|
||||||
created_at: "2013-08-19 20:41:33",
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
=end
|
|
||||||
|
|
||||||
def history_get(fulldata = false)
|
|
||||||
list = History.list(self.class.name, self['id'], 'Ticket::Article')
|
|
||||||
return list if !fulldata
|
|
||||||
|
|
||||||
# get related objects
|
|
||||||
assets = {}
|
|
||||||
list.each { |item|
|
|
||||||
record = Kernel.const_get(item['object']).find(item['o_id'])
|
|
||||||
assets = record.assets(assets)
|
|
||||||
|
|
||||||
if item['related_object']
|
|
||||||
record = Kernel.const_get(item['related_object']).find( item['related_o_id'])
|
|
||||||
assets = record.assets(assets)
|
|
||||||
end
|
|
||||||
}
|
|
||||||
{
|
|
||||||
history: list,
|
|
||||||
assets: assets,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,11 +1,11 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
class Ticket::State < ApplicationModel
|
class Ticket::State < ApplicationModel
|
||||||
|
include LatestChangeObserved
|
||||||
|
|
||||||
belongs_to :state_type, class_name: 'Ticket::StateType'
|
belongs_to :state_type, class_name: 'Ticket::StateType'
|
||||||
belongs_to :next_state, class_name: 'Ticket::State'
|
belongs_to :next_state, class_name: 'Ticket::State'
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
|
|
||||||
latest_change_support
|
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
list tickets by customer
|
list tickets by customer
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
class Ticket::StateType < ApplicationModel
|
class Ticket::StateType < ApplicationModel
|
||||||
has_many :states, class_name: 'Ticket::State'
|
include LatestChangeObserved
|
||||||
validates :name, presence: true
|
|
||||||
latest_change_support
|
has_many :states, class_name: 'Ticket::State'
|
||||||
|
validates :name, presence: true
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,6 +24,11 @@ require 'digest/md5'
|
||||||
# @property active [Boolean] The flag that shows the active state of the User.
|
# @property active [Boolean] The flag that shows the active state of the User.
|
||||||
# @property note [String] The note or comment stored to the User.
|
# @property note [String] The note or comment stored to the User.
|
||||||
class User < ApplicationModel
|
class User < ApplicationModel
|
||||||
|
include LogsActivityStream
|
||||||
|
include NotifiesClients
|
||||||
|
include Historisable
|
||||||
|
include SearchIndexed
|
||||||
|
|
||||||
load 'user/permission.rb'
|
load 'user/permission.rb'
|
||||||
include User::Permission
|
include User::Permission
|
||||||
load 'user/assets.rb'
|
load 'user/assets.rb'
|
||||||
|
@ -38,7 +43,6 @@ class User < ApplicationModel
|
||||||
after_create :avatar_for_email_check
|
after_create :avatar_for_email_check
|
||||||
after_update :avatar_for_email_check
|
after_update :avatar_for_email_check
|
||||||
after_destroy :avatar_destroy
|
after_destroy :avatar_destroy
|
||||||
notify_clients_support
|
|
||||||
|
|
||||||
has_and_belongs_to_many :groups, after_add: :cache_update, after_remove: :cache_update, class_name: 'Group'
|
has_and_belongs_to_many :groups, after_add: :cache_update, after_remove: :cache_update, class_name: 'Group'
|
||||||
has_and_belongs_to_many :roles, after_add: [:cache_update, :check_notifications], after_remove: :cache_update, class_name: 'Role'
|
has_and_belongs_to_many :roles, after_add: [:cache_update, :check_notifications], after_remove: :cache_update, class_name: 'Role'
|
||||||
|
@ -50,35 +54,31 @@ class User < ApplicationModel
|
||||||
|
|
||||||
store :preferences
|
store :preferences
|
||||||
|
|
||||||
activity_stream_support(
|
activity_stream_permission 'admin.user'
|
||||||
permission: 'admin.user',
|
|
||||||
ignore_attributes: {
|
activity_stream_attributes_ignored :last_login,
|
||||||
last_login: true,
|
:login_failed,
|
||||||
login_failed: true,
|
:image,
|
||||||
image: true,
|
:image_source,
|
||||||
image_source: true,
|
:preferences
|
||||||
preferences: true,
|
|
||||||
}
|
history_attributes_ignored :password,
|
||||||
)
|
:image,
|
||||||
history_support(
|
:image_source,
|
||||||
ignore_attributes: {
|
:preferences
|
||||||
password: true,
|
|
||||||
image: true,
|
search_index_attributes_ignored :password,
|
||||||
image_source: true,
|
:image,
|
||||||
preferences: true,
|
:image_source,
|
||||||
}
|
:source,
|
||||||
)
|
:login_failed,
|
||||||
search_index_support(
|
:preferences
|
||||||
ignore_attributes: {
|
|
||||||
password: true,
|
def ignore_search_indexing?(_action)
|
||||||
image: true,
|
# ignore internal user
|
||||||
image_source: true,
|
return true if id == 1
|
||||||
source: true,
|
false
|
||||||
login_failed: true,
|
end
|
||||||
preferences: true,
|
|
||||||
},
|
|
||||||
ignore_ids: [1],
|
|
||||||
)
|
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ returns
|
||||||
data[ app_model ] = {}
|
data[ app_model ] = {}
|
||||||
end
|
end
|
||||||
if !data[ app_model ][ id ]
|
if !data[ app_model ][ id ]
|
||||||
local_attributes = attributes_with_associations
|
local_attributes = attributes_with_association_ids
|
||||||
|
|
||||||
# do not transfer crypted pw
|
# do not transfer crypted pw
|
||||||
local_attributes['password'] = ''
|
local_attributes['password'] = ''
|
||||||
|
|
21
lib/background_job_search_index.rb
Normal file
21
lib/background_job_search_index.rb
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
class BackgroundJobSearchIndex
|
||||||
|
def initialize(object, o_id)
|
||||||
|
@object = object
|
||||||
|
@o_id = o_id
|
||||||
|
end
|
||||||
|
|
||||||
|
def perform
|
||||||
|
record = @object.constantize.lookup(id: @o_id)
|
||||||
|
return if !exists?(record)
|
||||||
|
record.search_index_update_backend
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def exists?(record)
|
||||||
|
return true if record
|
||||||
|
Rails.logger.info "Can't index #{@object}.lookup(id: #{@o_id}), no such record found"
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
|
@ -32,6 +32,8 @@ returns
|
||||||
next if entry =~ %r{channel/}i
|
next if entry =~ %r{channel/}i
|
||||||
next if entry =~ %r{observer/}i
|
next if entry =~ %r{observer/}i
|
||||||
next if entry =~ %r{store/provider/}i
|
next if entry =~ %r{store/provider/}i
|
||||||
|
next if entry =~ %r{models/concerns/}i
|
||||||
|
|
||||||
entry.gsub!(dir, '')
|
entry.gsub!(dir, '')
|
||||||
entry = entry.to_classname
|
entry = entry.to_classname
|
||||||
model_class = load_adapter(entry)
|
model_class = load_adapter(entry)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
class Sessions::Backend::Base
|
class Sessions::Backend::Base
|
||||||
|
|
||||||
def initialize(user, asset_lookup, client, client_id, ttl = 30)
|
def initialize(user, asset_lookup, client, client_id, ttl = 30)
|
||||||
@user = user
|
@user = user
|
||||||
@client = client
|
@client = client
|
||||||
|
|
|
@ -47,7 +47,7 @@ class Sessions::Backend::Collections::Base < Sessions::Backend::Base
|
||||||
# get relations of data
|
# get relations of data
|
||||||
all = []
|
all = []
|
||||||
items.each { |item|
|
items.each { |item|
|
||||||
all.push item.attributes_with_associations
|
all.push item.attributes_with_association_ids
|
||||||
}
|
}
|
||||||
|
|
||||||
# collect assets
|
# collect assets
|
||||||
|
|
|
@ -55,12 +55,12 @@ class AssetsTest < ActiveSupport::TestCase
|
||||||
assets = user3.assets({})
|
assets = user3.assets({})
|
||||||
|
|
||||||
org1 = Organization.find(org1.id)
|
org1 = Organization.find(org1.id)
|
||||||
attributes = org1.attributes_with_associations
|
attributes = org1.attributes_with_association_ids
|
||||||
attributes.delete('user_ids')
|
attributes.delete('user_ids')
|
||||||
assert( diff(attributes, assets[:Organization][org1.id]), 'check assets')
|
assert( diff(attributes, assets[:Organization][org1.id]), 'check assets')
|
||||||
|
|
||||||
user1 = User.find(user1.id)
|
user1 = User.find(user1.id)
|
||||||
attributes = user1.attributes_with_associations
|
attributes = user1.attributes_with_association_ids
|
||||||
attributes['accounts'] = {}
|
attributes['accounts'] = {}
|
||||||
attributes['password'] = ''
|
attributes['password'] = ''
|
||||||
attributes.delete('token_ids')
|
attributes.delete('token_ids')
|
||||||
|
@ -68,7 +68,7 @@ class AssetsTest < ActiveSupport::TestCase
|
||||||
assert( diff(attributes, assets[:User][user1.id]), 'check assets' )
|
assert( diff(attributes, assets[:User][user1.id]), 'check assets' )
|
||||||
|
|
||||||
user2 = User.find(user2.id)
|
user2 = User.find(user2.id)
|
||||||
attributes = user2.attributes_with_associations
|
attributes = user2.attributes_with_association_ids
|
||||||
attributes['accounts'] = {}
|
attributes['accounts'] = {}
|
||||||
attributes['password'] = ''
|
attributes['password'] = ''
|
||||||
attributes.delete('token_ids')
|
attributes.delete('token_ids')
|
||||||
|
@ -76,7 +76,7 @@ class AssetsTest < ActiveSupport::TestCase
|
||||||
assert( diff(attributes, assets[:User][user2.id]), 'check assets' )
|
assert( diff(attributes, assets[:User][user2.id]), 'check assets' )
|
||||||
|
|
||||||
user3 = User.find(user3.id)
|
user3 = User.find(user3.id)
|
||||||
attributes = user3.attributes_with_associations
|
attributes = user3.attributes_with_association_ids
|
||||||
attributes['accounts'] = {}
|
attributes['accounts'] = {}
|
||||||
attributes['password'] = ''
|
attributes['password'] = ''
|
||||||
attributes.delete('token_ids')
|
attributes.delete('token_ids')
|
||||||
|
@ -89,12 +89,12 @@ class AssetsTest < ActiveSupport::TestCase
|
||||||
org2.note = "some note...#{rand(9_999_999_999_999)}"
|
org2.note = "some note...#{rand(9_999_999_999_999)}"
|
||||||
org2.save
|
org2.save
|
||||||
|
|
||||||
attributes = org2.attributes_with_associations
|
attributes = org2.attributes_with_association_ids
|
||||||
attributes.delete('user_ids')
|
attributes.delete('user_ids')
|
||||||
assert( !diff(attributes, assets[:Organization][org2.id]), 'check assets' )
|
assert( !diff(attributes, assets[:Organization][org2.id]), 'check assets' )
|
||||||
|
|
||||||
user1_new = User.find(user1.id)
|
user1_new = User.find(user1.id)
|
||||||
attributes = user1_new.attributes_with_associations
|
attributes = user1_new.attributes_with_association_ids
|
||||||
attributes['accounts'] = {}
|
attributes['accounts'] = {}
|
||||||
attributes['password'] = ''
|
attributes['password'] = ''
|
||||||
attributes.delete('token_ids')
|
attributes.delete('token_ids')
|
||||||
|
@ -103,12 +103,12 @@ class AssetsTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
# check new assets lookup
|
# check new assets lookup
|
||||||
assets = user3.assets({})
|
assets = user3.assets({})
|
||||||
attributes = org2.attributes_with_associations
|
attributes = org2.attributes_with_association_ids
|
||||||
attributes.delete('user_ids')
|
attributes.delete('user_ids')
|
||||||
assert( diff(attributes, assets[:Organization][org1.id]), 'check assets')
|
assert( diff(attributes, assets[:Organization][org1.id]), 'check assets')
|
||||||
|
|
||||||
user1 = User.find(user1.id)
|
user1 = User.find(user1.id)
|
||||||
attributes = user1.attributes_with_associations
|
attributes = user1.attributes_with_association_ids
|
||||||
attributes['accounts'] = {}
|
attributes['accounts'] = {}
|
||||||
attributes['password'] = ''
|
attributes['password'] = ''
|
||||||
attributes.delete('token_ids')
|
attributes.delete('token_ids')
|
||||||
|
@ -116,7 +116,7 @@ class AssetsTest < ActiveSupport::TestCase
|
||||||
assert( diff(attributes, assets[:User][user1.id]), 'check assets' )
|
assert( diff(attributes, assets[:User][user1.id]), 'check assets' )
|
||||||
|
|
||||||
user2 = User.find(user2.id)
|
user2 = User.find(user2.id)
|
||||||
attributes = user2.attributes_with_associations
|
attributes = user2.attributes_with_association_ids
|
||||||
attributes['accounts'] = {}
|
attributes['accounts'] = {}
|
||||||
attributes['password'] = ''
|
attributes['password'] = ''
|
||||||
attributes.delete('token_ids')
|
attributes.delete('token_ids')
|
||||||
|
@ -124,7 +124,7 @@ class AssetsTest < ActiveSupport::TestCase
|
||||||
assert( diff(attributes, assets[:User][user2.id]), 'check assets' )
|
assert( diff(attributes, assets[:User][user2.id]), 'check assets' )
|
||||||
|
|
||||||
user3 = User.find(user3.id)
|
user3 = User.find(user3.id)
|
||||||
attributes = user3.attributes_with_associations
|
attributes = user3.attributes_with_association_ids
|
||||||
attributes['accounts'] = {}
|
attributes['accounts'] = {}
|
||||||
attributes['password'] = ''
|
attributes['password'] = ''
|
||||||
attributes.delete('token_ids')
|
attributes.delete('token_ids')
|
||||||
|
@ -202,12 +202,12 @@ class AssetsTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
org = Organization.find(org.id)
|
org = Organization.find(org.id)
|
||||||
assets = org.assets({})
|
assets = org.assets({})
|
||||||
attributes = org.attributes_with_associations
|
attributes = org.attributes_with_association_ids
|
||||||
attributes.delete('user_ids')
|
attributes.delete('user_ids')
|
||||||
assert( diff(attributes, assets[:Organization][org.id]), 'check assets' )
|
assert( diff(attributes, assets[:Organization][org.id]), 'check assets' )
|
||||||
|
|
||||||
admin1 = User.find(admin1.id)
|
admin1 = User.find(admin1.id)
|
||||||
attributes = admin1.attributes_with_associations
|
attributes = admin1.attributes_with_association_ids
|
||||||
attributes['accounts'] = {}
|
attributes['accounts'] = {}
|
||||||
attributes['password'] = ''
|
attributes['password'] = ''
|
||||||
attributes.delete('token_ids')
|
attributes.delete('token_ids')
|
||||||
|
@ -215,7 +215,7 @@ class AssetsTest < ActiveSupport::TestCase
|
||||||
assert( diff(attributes, assets[:User][admin1.id]), 'check assets' )
|
assert( diff(attributes, assets[:User][admin1.id]), 'check assets' )
|
||||||
|
|
||||||
user1 = User.find(user1.id)
|
user1 = User.find(user1.id)
|
||||||
attributes = user1.attributes_with_associations
|
attributes = user1.attributes_with_association_ids
|
||||||
attributes['accounts'] = {}
|
attributes['accounts'] = {}
|
||||||
attributes['password'] = ''
|
attributes['password'] = ''
|
||||||
attributes.delete('token_ids')
|
attributes.delete('token_ids')
|
||||||
|
@ -223,7 +223,7 @@ class AssetsTest < ActiveSupport::TestCase
|
||||||
assert( diff(attributes, assets[:User][user1.id]), 'check assets' )
|
assert( diff(attributes, assets[:User][user1.id]), 'check assets' )
|
||||||
|
|
||||||
user2 = User.find(user2.id)
|
user2 = User.find(user2.id)
|
||||||
attributes = user2.attributes_with_associations
|
attributes = user2.attributes_with_association_ids
|
||||||
attributes['accounts'] = {}
|
attributes['accounts'] = {}
|
||||||
attributes['password'] = ''
|
attributes['password'] = ''
|
||||||
attributes.delete('token_ids')
|
attributes.delete('token_ids')
|
||||||
|
@ -231,7 +231,7 @@ class AssetsTest < ActiveSupport::TestCase
|
||||||
assert( diff(attributes, assets[:User][user2.id]), 'check assets' )
|
assert( diff(attributes, assets[:User][user2.id]), 'check assets' )
|
||||||
|
|
||||||
user3 = User.find(user3.id)
|
user3 = User.find(user3.id)
|
||||||
attributes = user3.attributes_with_associations
|
attributes = user3.attributes_with_association_ids
|
||||||
attributes['accounts'] = {}
|
attributes['accounts'] = {}
|
||||||
attributes['password'] = ''
|
attributes['password'] = ''
|
||||||
attributes.delete('token_ids')
|
attributes.delete('token_ids')
|
||||||
|
@ -245,11 +245,11 @@ class AssetsTest < ActiveSupport::TestCase
|
||||||
user_new_2.save
|
user_new_2.save
|
||||||
|
|
||||||
org_new = Organization.find(org.id)
|
org_new = Organization.find(org.id)
|
||||||
attributes = org_new.attributes_with_associations
|
attributes = org_new.attributes_with_association_ids
|
||||||
attributes.delete('user_ids')
|
attributes.delete('user_ids')
|
||||||
assert( !diff(attributes, assets[:Organization][org_new.id]), 'check assets' )
|
assert( !diff(attributes, assets[:Organization][org_new.id]), 'check assets' )
|
||||||
|
|
||||||
attributes = user_new_2.attributes_with_associations
|
attributes = user_new_2.attributes_with_association_ids
|
||||||
attributes['accounts'] = {}
|
attributes['accounts'] = {}
|
||||||
attributes['password'] = ''
|
attributes['password'] = ''
|
||||||
attributes.delete('token_ids')
|
attributes.delete('token_ids')
|
||||||
|
@ -258,11 +258,11 @@ class AssetsTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
# check new assets lookup
|
# check new assets lookup
|
||||||
assets = org_new.assets({})
|
assets = org_new.assets({})
|
||||||
attributes = org_new.attributes_with_associations
|
attributes = org_new.attributes_with_association_ids
|
||||||
attributes.delete('user_ids')
|
attributes.delete('user_ids')
|
||||||
assert( diff(attributes, assets[:Organization][org_new.id]), 'check assets' )
|
assert( diff(attributes, assets[:Organization][org_new.id]), 'check assets' )
|
||||||
|
|
||||||
attributes = user_new_2.attributes_with_associations
|
attributes = user_new_2.attributes_with_association_ids
|
||||||
attributes['accounts'] = {}
|
attributes['accounts'] = {}
|
||||||
attributes['password'] = ''
|
attributes['password'] = ''
|
||||||
attributes.delete('token_ids')
|
attributes.delete('token_ids')
|
||||||
|
|
Loading…
Reference in a new issue