Added shared organization feature. Customers will be able to watch organization ticket.

This commit is contained in:
Martin Edenhofer 2012-11-13 11:34:45 +01:00
parent 0ecad4aaa8
commit 5b1c7d77c3
7 changed files with 111 additions and 35 deletions

View file

@ -10,7 +10,7 @@ class TicketArticlesController < ApplicationController
# GET /articles/1 # GET /articles/1
def show def show
@article = Ticket::Article.find(params[:id]) @article = Ticket::Article.find( params[:id] )
render :json => @article render :json => @article
end end
@ -19,7 +19,8 @@ class TicketArticlesController < ApplicationController
def create def create
@article = Ticket::Article.new(params[:ticket_article]) @article = Ticket::Article.new(params[:ticket_article])
@article.created_by_id = current_user.id @article.created_by_id = current_user.id
@article.updated_by_id = current_user.id
# find attachments in upload cache # find attachments in upload cache
@article['attachments'] = Store.list( @article['attachments'] = Store.list(
:object => 'UploadCache::TicketZoom::' + current_user.id.to_s, :object => 'UploadCache::TicketZoom::' + current_user.id.to_s,
@ -33,7 +34,7 @@ class TicketArticlesController < ApplicationController
:object => 'UploadCache::TicketZoom::' + current_user.id.to_s, :object => 'UploadCache::TicketZoom::' + current_user.id.to_s,
:o_id => @article.ticket_id :o_id => @article.ticket_id
) )
render :json => @article, :status => :created render :json => @article, :status => :created
else else
render :json => @article.errors, :status => :unprocessable_entity render :json => @article.errors, :status => :unprocessable_entity
@ -42,7 +43,8 @@ class TicketArticlesController < ApplicationController
# PUT /articles/1 # PUT /articles/1
def update def update
@article = Ticket::Article.find(params[:id]) @article = Ticket::Article.find( params[:id] )
params[:ticket_article][:updated_by_id] = current_user.id
if @article.update_attributes(params[:ticket_article]) if @article.update_attributes(params[:ticket_article])
render :json => @article, :status => :ok render :json => @article, :status => :ok
@ -53,7 +55,7 @@ class TicketArticlesController < ApplicationController
# DELETE /articles/1 # DELETE /articles/1
def destroy def destroy
@article = Ticket::Article.find(params[:id]) @article = Ticket::Article.find( params[:id] )
@article.destroy @article.destroy
head :ok head :ok

View file

@ -10,7 +10,7 @@ class TicketsController < ApplicationController
# GET /tickets/1 # GET /tickets/1
def show def show
@ticket = Ticket.find(params[:id]) @ticket = Ticket.find( params[:id] )
# permissin check # permissin check
return if !ticket_permission(@ticket) return if !ticket_permission(@ticket)
@ -20,7 +20,7 @@ class TicketsController < ApplicationController
# POST /tickets # POST /tickets
def create def create
@ticket = Ticket.new(params[:ticket]) @ticket = Ticket.new( params[:ticket] )
@ticket.updated_by_id = current_user.id @ticket.updated_by_id = current_user.id
@ticket.created_by_id = current_user.id @ticket.created_by_id = current_user.id
@ -70,7 +70,9 @@ class TicketsController < ApplicationController
# permissin check # permissin check
return if !ticket_permission(@ticket) return if !ticket_permission(@ticket)
if @ticket.update_attributes(params[:ticket]) params[:ticket][:updated_by_id] = current_user.id
if @ticket.update_attributes( params[:ticket] )
render :json => @ticket, :status => :ok render :json => @ticket, :status => :ok
else else
render :json => @ticket.errors, :status => :unprocessable_entity render :json => @ticket.errors, :status => :unprocessable_entity
@ -79,7 +81,7 @@ class TicketsController < ApplicationController
# DELETE /tickets/1 # DELETE /tickets/1
def destroy def destroy
@ticket = Ticket.find(params[:id]) @ticket = Ticket.find( params[:id] )
# permissin check # permissin check
return if !ticket_permission(@ticket) return if !ticket_permission(@ticket)

View file

@ -1,9 +1,11 @@
class Ticket < ApplicationModel class Ticket < ApplicationModel
before_create :number_generate, :check_defaults before_create :number_generate, :check_defaults
before_update :check_defaults
before_destroy :destroy_dependencies before_destroy :destroy_dependencies
belongs_to :group belongs_to :group
has_many :articles, :after_add => :cache_update, :after_remove => :cache_update has_many :articles, :after_add => :cache_update, :after_remove => :cache_update
belongs_to :organization
belongs_to :ticket_state, :class_name => 'Ticket::State' belongs_to :ticket_state, :class_name => 'Ticket::State'
belongs_to :ticket_priority, :class_name => 'Ticket::Priority' belongs_to :ticket_priority, :class_name => 'Ticket::Priority'
belongs_to :owner, :class_name => 'User' belongs_to :owner, :class_name => 'User'
@ -141,7 +143,16 @@ class Ticket < ApplicationModel
# check customer # check customer
if data[:current_user].is_role('Customer') if data[:current_user].is_role('Customer')
# access ok if its own ticket
return true if self.customer_id == data[:current_user].id return true if self.customer_id == data[:current_user].id
# access ok if its organization ticket
if data[:current_user].organization_id && self.organization_id
return true if self.organization_id == data[:current_user].organization_id
end
# no access
return false return false
end end
@ -157,13 +168,22 @@ class Ticket < ApplicationModel
# :current_user => 123, # :current_user => 123,
# ) # )
def self.overview_list (data) def self.overview_list (data)
# get user role
# get customer overviews
if data[:current_user].is_role('Customer') if data[:current_user].is_role('Customer')
role = data[:current_user].is_role( 'Customer' ) role = data[:current_user].is_role( 'Customer' )
else if data[:current_user].organization_id && data[:current_user].organization.shared
role = data[:current_user].is_role( 'Agent' ) overviews = Overview.where( :role_id => role.id )
else
overviews = Overview.where( :role_id => role.id, :organization_shared => false )
end
return overviews
end end
Overview.where( :role_id => role.id )
# get agent overviews
role = data[:current_user].is_role( 'Agent' )
overviews = Overview.where( :role_id => role.id )
return overviews
end end
# Ticket.overview( # Ticket.overview(
@ -172,25 +192,13 @@ class Ticket < ApplicationModel
# ) # )
def self.overview (data) def self.overview (data)
# get user role overviews = self.overview_list(data)
if data[:current_user].is_role('Customer')
role = data[:current_user].is_role( 'Customer' )
else
role = data[:current_user].is_role( 'Agent' )
end
# build up attributes hash # build up attributes hash
overview_selected = nil overview_selected = nil
overview_selected_raw = nil overview_selected_raw = nil
overviews = Overview.where( :role_id => role.id )
overviews.each { |overview|
# for cleanup reasons, remove me later! overviews.each { |overview|
overview.condition.each { |item, value |
if item == 'owner_id' && overview.condition[item] != 1
overview.condition[item] = 'current_user.id'
end
}
# remember selected view # remember selected view
if data[:view] && data[:view] == overview.meta[:url] if data[:view] && data[:view] == overview.meta[:url]
@ -198,10 +206,13 @@ class Ticket < ApplicationModel
overview_selected_raw = Marshal.load( Marshal.dump(overview.attributes) ) overview_selected_raw = Marshal.load( Marshal.dump(overview.attributes) )
end end
# replace 'current_user.id' with current_user.id # replace e.g. 'current_user.id' with current_user.id
overview.condition.each { |item, value | overview.condition.each { |item, value |
if value == 'current_user.id' if value && value.class.to_s == 'String'
overview.condition[item] = data[:current_user].id parts = value.split( '.', 2 )
if parts[0] && parts[1] && parts[0] == 'current_user'
overview.condition[item] = data[:current_user][parts[1].to_sym]
end
end end
} }
} }
@ -211,11 +222,11 @@ class Ticket < ApplicationModel
# state # state
# group # group
# customer # customer
# order # order
# asc # asc
# desc # desc
# groupby # groupby
# prio # prio
# state # state
@ -383,9 +394,17 @@ class Ticket < ApplicationModel
end end
end end
def check_defaults def check_defaults
if !self.owner_id then if !self.owner_id
self.owner_id = 1 self.owner_id = 1
end end
# if self.customer_id && ( !self.organization_id || self.organization_id.empty? )
if self.customer_id
customer = User.find( self.customer_id )
if self.organization_id != customer.organization_id
self.organization_id = customer.organization_id
end
end
end end
def destroy_dependencies def destroy_dependencies

View file

@ -34,6 +34,7 @@ class CreateTicket < ActiveRecord::Migration
t.references :group, :null => false t.references :group, :null => false
t.references :ticket_priority, :null => false t.references :ticket_priority, :null => false
t.references :ticket_state, :null => false t.references :ticket_state, :null => false
t.references :organization, :null => true
t.column :number, :string, :limit => 60, :null => false t.column :number, :string, :limit => 60, :null => false
t.column :title, :string, :limit => 250, :null => false t.column :title, :string, :limit => 250, :null => false
t.column :owner_id, :integer, :null => false t.column :owner_id, :integer, :null => false
@ -44,7 +45,7 @@ class CreateTicket < ActiveRecord::Migration
t.column :last_contact_agent, :timestamp, :null => true t.column :last_contact_agent, :timestamp, :null => true
t.column :last_contact_customer, :timestamp, :null => true t.column :last_contact_customer, :timestamp, :null => true
t.column :close_time, :timestamp, :null => true t.column :close_time, :timestamp, :null => true
t.column :updated_by_id, :integer, :null => false t.column :updated_by_id, :integer, :null => false
t.column :created_by_id, :integer, :null => false t.column :created_by_id, :integer, :null => false
t.timestamps t.timestamps
end end
@ -153,6 +154,7 @@ class CreateTicket < ActiveRecord::Migration
t.column :condition, :string, :limit => 2500, :null => false t.column :condition, :string, :limit => 2500, :null => false
t.column :order, :string, :limit => 2500, :null => false t.column :order, :string, :limit => 2500, :null => false
t.column :group_by, :string, :limit => 250, :null => true t.column :group_by, :string, :limit => 250, :null => true
t.column :organization_shared, :boolean, :null => false, :default => false
t.column :view, :string, :limit => 1000, :null => false t.column :view, :string, :limit => 1000, :null => false
t.column :active, :boolean, :null => false, :default => true t.column :active, :boolean, :null => false, :default => true
t.column :updated_by_id, :integer, :null => false t.column :updated_by_id, :integer, :null => false

View file

@ -1,5 +1,6 @@
class TicketOrganization < ActiveRecord::Migration class TicketOrganization < ActiveRecord::Migration
def up def up
add_column :tickets, :organization_id, :integer, :null => true
end end
def down def down

View file

@ -0,0 +1,8 @@
class OrganizationShared < ActiveRecord::Migration
def up
add_column :overviews, :organization_shared, :boolean, :null => false, :default => false
end
def down
end
end

View file

@ -1436,7 +1436,7 @@ Overview.create(
}, },
:order => { :order => {
:by => 'created_at', :by => 'created_at',
:direction => 'ASC', :direction => 'DESC',
}, },
:meta => { :meta => {
:url => 'my_tickets', :url => 'my_tickets',
@ -1467,6 +1467,46 @@ Overview.create(
:updated_by_id => 1, :updated_by_id => 1,
:created_by_id => 1 :created_by_id => 1
) )
Overview.create(
:name => 'my_organization_tickets',
:role_id => overview_role.id,
:organization_shared => true,
:condition => {
:organization_id => 'current_user.organization_id',
},
:order => {
:by => 'created_at',
:direction => 'DESC',
},
:meta => {
:url => 'my_organization_tickets',
:name => 'My Organization Tickets',
:prio => 1100,
},
:view => {
:d => {
:overview => [
'title', 'customer', 'ticket_state', 'created_at'
],
:per_page => 5,
},
:s => {
:overview => [
'number', 'title', 'ticket_state', 'ticket_priority', 'created_at'
],
:per_page => 30,
},
:m => {
:overview => [
'number', 'title', 'ticket_state', 'ticket_priority', 'created_at'
],
:per_page => 20,
},
:view_mode_default => 's',
},
:updated_by_id => 1,
:created_by_id => 1
)
Channel.create( Channel.create(
:adapter => 'SMTP', :adapter => 'SMTP',
@ -1751,6 +1791,8 @@ Translation.create( :locale => 'de', :source => "Linked Objects", :target => "Ve
Translation.create( :locale => 'de', :source => "Links", :target => "Verknüpftungen", :updated_by_id => 1, :created_by_id => 1 ) Translation.create( :locale => 'de', :source => "Links", :target => "Verknüpftungen", :updated_by_id => 1, :created_by_id => 1 )
Translation.create( :locale => 'de', :source => "Change Customer", :target => "Kunden ändern", :updated_by_id => 1, :created_by_id => 1 ) Translation.create( :locale => 'de', :source => "Change Customer", :target => "Kunden ändern", :updated_by_id => 1, :created_by_id => 1 )
Translation.create( :locale => 'de', :source => "My Tickets", :target => "Meine Tickets", :updated_by_id => 1, :created_by_id => 1 ) Translation.create( :locale => 'de', :source => "My Tickets", :target => "Meine Tickets", :updated_by_id => 1, :created_by_id => 1 )
Translation.create( :locale => 'de', :source => "My Organization Tickets", :target => "Meine Organisations Tickets", :updated_by_id => 1, :created_by_id => 1 )
Translation.create( :locale => 'de', :source => "My Organization", :target => "Meine Organisation", :updated_by_id => 1, :created_by_id => 1 )
Translation.create( :locale => 'de', :source => "Assignment Timout", :target => "Zeitliche Zuweisungsüberschritung", :updated_by_id => 1, :created_by_id => 1 ) Translation.create( :locale => 'de', :source => "Assignment Timout", :target => "Zeitliche Zuweisungsüberschritung", :updated_by_id => 1, :created_by_id => 1 )
Translation.create( :locale => 'de', :source => "We've sent password reset instructions to your email address.", :target => "Wir haben Ihnen die Anleitung zum zurücksetzesn Ihres Passworts an Ihre E-Mail-Adresse gesendet.", :updated_by_id => 1, :created_by_id => 1 ) Translation.create( :locale => 'de', :source => "We've sent password reset instructions to your email address.", :target => "Wir haben Ihnen die Anleitung zum zurücksetzesn Ihres Passworts an Ihre E-Mail-Adresse gesendet.", :updated_by_id => 1, :created_by_id => 1 )
Translation.create( :locale => 'de', :source => "Enter your username or email address", :target => "Bitte geben Sie Ihren Benutzernamen oder E-Mail-Adresse ein", :updated_by_id => 1, :created_by_id => 1 ) Translation.create( :locale => 'de', :source => "Enter your username or email address", :target => "Bitte geben Sie Ihren Benutzernamen oder E-Mail-Adresse ein", :updated_by_id => 1, :created_by_id => 1 )