Browse Source

Added agent limit support.

Martin Edenhofer 8 years ago
parent
commit
87aedd8cc5

+ 12 - 1
app/models/role.rb

@@ -6,7 +6,7 @@ class Role < ApplicationModel
   include LatestChangeObserved
 
   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, before_add: :validate_agent_limit
   validates               :name,  presence: true
   store                   :preferences
 
@@ -135,4 +135,15 @@ returns
     }
   end
 
+  def validate_agent_limit(permission)
+    return if !Setting.get('system_agent_limit')
+    return if permission.name != 'ticket.agent'
+
+    ticket_agent_role_ids = Role.joins(:permissions).where(permissions: { name: 'ticket.agent' }).pluck(:id)
+    ticket_agent_role_ids.push(id)
+    count = User.joins(:roles).where(roles: { id: ticket_agent_role_ids }, users: { active: true }).count
+
+    raise Exceptions::UnprocessableEntity, 'Agent limit exceeded, please check your account settings.' if count > Setting.get('system_agent_limit')
+  end
+
 end

+ 13 - 1
app/models/user.rb

@@ -45,7 +45,7 @@ class User < ApplicationModel
   after_destroy   :avatar_destroy
 
   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, before_add: :validate_agent_limit, class_name: 'Role'
   has_and_belongs_to_many :organizations,   after_add: :cache_update, after_remove: :cache_update, class_name: 'Organization'
   #has_many                :permissions,     class_name: 'Permission', through: :roles, class_name: 'Role'
   has_many                :tokens,          after_add: :cache_update, after_remove: :cache_update
@@ -860,6 +860,18 @@ returns
     }
   end
 
+  def validate_agent_limit(role)
+    return if !Setting.get('system_agent_limit')
+
+    ticket_agent_role_ids = Role.joins(:permissions).where(permissions: { name: 'ticket.agent' }).pluck(:id)
+    count                 = User.joins(:roles).where(roles: { id: ticket_agent_role_ids }, users: { active: true }).count
+    if ticket_agent_role_ids.include?(role.id)
+      count += 1
+    end
+
+    raise Exceptions::UnprocessableEntity, 'Agent limit exceeded, please check your account settings.' if count > Setting.get('system_agent_limit')
+  end
+
   def domain_based_assignment
     return if !email
     return if organization_id

+ 17 - 0
db/migrate/20170418000001_validate_agent_limit.rb

@@ -0,0 +1,17 @@
+class ValidateAgentLimit < ActiveRecord::Migration
+  def up
+    # return if it's a new setup
+    return if !Setting.find_by(name: 'system_init_done')
+
+    Setting.create_if_not_exists(
+      title: 'Set limit of agents',
+      name: 'system_agent_limit',
+      area: 'Core::Online',
+      description: 'Defines the limit of the agents.',
+      options: {},
+      state: false,
+      preferences: { online_service_disable: true },
+      frontend: false
+    )
+  end
+end

+ 10 - 0
db/seeds.rb

@@ -2719,6 +2719,16 @@ Setting.create_if_not_exists(
   ],
   frontend: false
 )
+Setting.create_if_not_exists(
+  title: 'Set limit of agents',
+  name: 'system_agent_limit',
+  area: 'Core::Online',
+  description: 'Defines the limit of the agents.',
+  options: {},
+  state: false,
+  preferences: { online_service_disable: true },
+  frontend: false
+)
 
 signature = Signature.create_if_not_exists(
   id: 1,

+ 62 - 0
test/unit/role_validate_agent_limit_test.rb

@@ -0,0 +1,62 @@
+# encoding: utf-8
+require 'test_helper'
+
+class RoleValidateAgentLimit < ActiveSupport::TestCase
+  test 'role_validate_agent_limit' do
+
+    users = User.of_role('Agent')
+    UserInfo.current_user_id = 1
+    Setting.set('system_agent_limit', users.count + 2)
+
+    permission_ticket_agent = Permission.where(name: 'ticket.agent')
+
+    role_agent_limit_success = Role.create(
+      name: 'agent-limit-test-success',
+      note: 'agent-limit-test-success Role.',
+      permissions: [],
+      updated_by_id: 1,
+      created_by_id: 1
+    )
+    role_agent_limit_fail = Role.create(
+      name: 'agent-limit-test-fail',
+      note: 'agent-limit-test-fail Role.',
+      permissions: [],
+      updated_by_id: 1,
+      created_by_id: 1
+    )
+
+    user1 = User.create(
+      firstname:   'Firstname',
+      lastname:    'Lastname',
+      email:       'some@example.com',
+      login:       'some-agentlimit@example.com',
+      roles:       [role_agent_limit_success],
+    )
+    user2 = User.create(
+      firstname:   'Firstname1',
+      lastname:    'Lastname1',
+      email:       'some-agentlimit-1@example.com',
+      login:       'some-agentlimit-1@example.com',
+      roles:       [role_agent_limit_success],
+    )
+    user3 = User.create(
+      firstname: 'Firstname2',
+      lastname:  'Lastname2',
+      email:     'some-agentlimit-2@example.com',
+      login:     'some-agentlimit-2@example.com',
+      roles:     [role_agent_limit_fail],
+    )
+
+    role_agent_limit_success.permissions = permission_ticket_agent
+    assert_raises(Exceptions::UnprocessableEntity) {
+      role_agent_limit_fail.permissions = permission_ticket_agent
+    }
+
+    user1.destroy
+    user2.destroy
+    user3.destroy
+    role_agent_limit_success.destroy
+    role_agent_limit_fail.destroy
+    Setting.set('system_agent_limit', nil)
+  end
+end

+ 55 - 0
test/unit/user_validate_agent_limit_test.rb

@@ -0,0 +1,55 @@
+# encoding: utf-8
+require 'test_helper'
+
+class UserValidateAgentLimit < ActiveSupport::TestCase
+  test 'user_validate_agent_limit' do
+
+    users = User.of_role('Agent')
+    UserInfo.current_user_id = 1
+    Setting.set('system_agent_limit', users.count + 2)
+    role_agent = Role.lookup(name: 'Agent')
+    role_customer = Role.lookup(name: 'Customer')
+
+    user1 = User.create(
+      firstname:   'Firstname',
+      lastname:    'Lastname',
+      email:       'some@example.com',
+      login:       'some-agentlimit@example.com',
+      roles:       [role_agent],
+    )
+    user2 = User.create(
+      firstname:   'Firstname1',
+      lastname:    'Lastname1',
+      email:       'some-agentlimit-1@example.com',
+      login:       'some-agentlimit-1@example.com',
+      roles:       [role_agent],
+    )
+
+    assert_raises(Exceptions::UnprocessableEntity) {
+      user3 = User.create(
+        firstname: 'Firstname2',
+        lastname:  'Lastname2',
+        email:     'some-agentlimit-2@example.com',
+        login:     'some-agentlimit-2@example.com',
+        roles:     [role_agent],
+      )
+    }
+
+    user3 = User.create(
+      firstname: 'Firstname2',
+      lastname:  'Lastname2',
+      email:     'some-agentlimit-2@example.com',
+      login:     'some-agentlimit-2@example.com',
+      roles:     [role_customer],
+    )
+
+    assert_raises(Exceptions::UnprocessableEntity) {
+      user3.roles = [role_agent]
+    }
+
+    user1.destroy
+    user2.destroy
+    user3.destroy
+    Setting.set('system_agent_limit', nil)
+  end
+end