diff --git a/app/assets/javascripts/app/controllers/_application_controller_form.coffee b/app/assets/javascripts/app/controllers/_application_controller_form.coffee index 4d62d72be..c29b98950 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_form.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_form.coffee @@ -226,67 +226,6 @@ class App.ControllerForm extends App.Controller if App.UiElement[attribute.tag] item = App.UiElement[attribute.tag].render(attribute, @params, @) - ### - else if key is 'tickets.owner_id' || key is 'tickets.customer_id' - display = 'Owner' - name = 'owner_id' - if key is 'customer_id' - display = 'Customer' - name = 'customer_id' - attribute_config = { - name: attribute.name + '::tickets.' + name - display: display - tag: 'select' - multiple: true - null: false - nulloption: false - relation: 'User' - value: value || null - remove: true - filter: ( all, type ) -> - return all if type isnt 'collection' - all = _.filter( all, (item) -> - return if item.id is 1 - return item - ) - all.unshift( { - id: '' - name: '--' - } ) - all.unshift( { - id: 1 - name: '*** not set ***' - } ) - all.unshift( { - id: 'current_user.id' - name: '*** current user ***' - } ) - all - } - else if key is 'tickets.organization_id' - attribute_config = { - name: attribute.name + '::tickets.organization_id' - display: 'Organization' - tag: 'select' - multiple: true - null: false - nulloption: false - relation: 'Organization' - value: value || null - remove: true - filter: ( all, type ) -> - return all if type isnt 'collection' - all.unshift( { - id: '' - name: '--' - } ) - all.unshift( { - id: 'current_user.organization_id' - name: '*** organization of current user ***' - } ) - all - } - ### else throw "Invalid UiElement.#{attribute.tag}" diff --git a/app/assets/javascripts/app/controllers/_ui_element/autocompletion_ajax.coffee b/app/assets/javascripts/app/controllers/_ui_element/autocompletion_ajax.coffee index 3b67ab688..09316dd44 100644 --- a/app/assets/javascripts/app/controllers/_ui_element/autocompletion_ajax.coffee +++ b/app/assets/javascripts/app/controllers/_ui_element/autocompletion_ajax.coffee @@ -1,17 +1,18 @@ # coffeelint: disable=camel_case_classes class App.UiElement.autocompletion_ajax @render: (attribute, params = {}) -> - if params[attribute.name] - object = App[attribute.relation].find(params[attribute.name]) + + if params[attribute.name] || attribute.value + object = App[attribute.relation].find(params[attribute.name] || attribute.value) valueName = object.displayName() # selectable search searchableAjaxSelectObject = new App.SearchableAjaxSelect( attribute: - value: params[attribute.name] + value: params[attribute.name] || attribute.value valueName: valueName name: attribute.name - id: params.organization_id + id: params.organization_id || attribute.value placeholder: App.i18n.translateInline('Search...') limt: 10 object: attribute.relation diff --git a/app/assets/javascripts/app/controllers/_ui_element/ticket_perform_action.coffee b/app/assets/javascripts/app/controllers/_ui_element/ticket_perform_action.coffee index 3d4f54140..a59572b8f 100644 --- a/app/assets/javascripts/app/controllers/_ui_element/ticket_perform_action.coffee +++ b/app/assets/javascripts/app/controllers/_ui_element/ticket_perform_action.coffee @@ -57,7 +57,6 @@ class App.UiElement.ticket_perform_action ) # build inital params - console.log('initial', params[attribute.name]) if !_.isEmpty(params[attribute.name]) selectorExists = false diff --git a/app/assets/javascripts/app/controllers/_ui_element/ticket_selector.coffee b/app/assets/javascripts/app/controllers/_ui_element/ticket_selector.coffee index 388e43a54..4feafa450 100644 --- a/app/assets/javascripts/app/controllers/_ui_element/ticket_selector.coffee +++ b/app/assets/javascripts/app/controllers/_ui_element/ticket_selector.coffee @@ -85,7 +85,6 @@ class App.UiElement.ticket_selector ) # build inital params - console.log('initial', params[attribute.name]) if !_.isEmpty(params[attribute.name]) selectorExists = false @@ -166,7 +165,6 @@ class App.UiElement.ticket_selector ) @buildValue: (elementFull, elementRow, groupAndAttribute, elements, value, operator, attribute) -> - console.log('buildValue', elementFull, elementRow, groupAndAttribute, elements, value, operator, attribute) # do nothing if item already exists operator = elementRow.find('.js-operator option:selected').attr('value') @@ -176,9 +174,16 @@ class App.UiElement.ticket_selector attributeConfig = elements[groupAndAttribute] config = _.clone(attributeConfig) - # force to use auto compition on user lookup + # force to use auto complition on user lookup + config.preCondition = false if config.relation is 'User' + config.preCondition = 'user' config.tag = 'user_autocompletion' + if config.relation is 'Organization' + config.tag = 'autocompletion_ajax' + config.preCondition = 'org' + + @buildPreCondition(config, elementFull, elementRow, groupAndAttribute, attribute) # render ui element item = '' @@ -204,6 +209,47 @@ class App.UiElement.ticket_selector elementRow.find('.js-value').html(item) + @buildPreCondition: (config, elementFull, elementRow, groupAndAttribute, attribute) -> + if !config.preCondition + elementRow.find('.js-preCondition').addClass('hide') + return + + name = "#{attribute.name}::#{groupAndAttribute}::pre_condition" + preConditionCurrent = elementRow.find('.js-preCondition option:selected').attr('value') + if !preCondition && attribute.value && attribute.value[groupAndAttribute] + preCondition = attribute.value[groupAndAttribute].pre_condition + selection = $("") + options = {} + if config.preCondition is 'user' + options = + 'set': App.i18n.translateInline('set') + 'current_user.id': App.i18n.translateInline('current user') + 'specific': App.i18n.translateInline('specific user') + else if config.preCondition is 'org' + options = + 'set': App.i18n.translateInline('set') + 'current_user.organization_id': App.i18n.translateInline('current user organization') + 'specific': App.i18n.translateInline('specific organization') + for key, value of options + selected = preConditionCurrent + if key is preCondition + selected = 'selected="selected"' + selection.append("") + elementRow.find('.js-preCondition').removeClass('hide') + elementRow.find('.js-preCondition select').replaceWith(selection) + + toggle = -> + preCondition = elementRow.find('.js-preCondition option:selected').attr('value') + if preCondition is 'specific' + elementRow.find('.js-value').removeClass('hide') + else + elementRow.find('.js-value').addClass('hide') + toggle() + + elementRow.find('.js-preCondition select').bind('change', (e) => + toggle() + ) + @buildAttributeSelector: (groups, elements) -> selection = $('') for groupKey, groupMeta of groups diff --git a/app/assets/javascripts/app/lib/app_post/user_organization_autocompletion.coffee b/app/assets/javascripts/app/lib/app_post/user_organization_autocompletion.coffee index ed69cfe64..197cfcfc6 100644 --- a/app/assets/javascripts/app/lib/app_post/user_organization_autocompletion.coffee +++ b/app/assets/javascripts/app/lib/app_post/user_organization_autocompletion.coffee @@ -5,7 +5,7 @@ class App.UserOrganizationAutocompletion extends App.Controller 'click .js-organization': 'showOrganizationMembers' 'click .js-back': 'hideOrganizationMembers' 'click .js-user': 'selectUser' - 'click .js-user-new': 'newUser' + 'click .js-userNew': 'newUser' 'focus input': 'open' constructor: (params) -> @@ -17,6 +17,10 @@ class App.UserOrganizationAutocompletion extends App.Controller @attribute.source = @apiPath + '/search/user-organization' @build() + # set current value + if @attribute.value + @setUser(@attribute.value) + element: => @el diff --git a/app/assets/javascripts/app/views/generic/ticket_selector.jst.eco b/app/assets/javascripts/app/views/generic/ticket_selector.jst.eco index 927796e5f..ccd1bff97 100644 --- a/app/assets/javascripts/app/views/generic/ticket_selector.jst.eco +++ b/app/assets/javascripts/app/views/generic/ticket_selector.jst.eco @@ -12,6 +12,12 @@ <%- @Icon('arrow-down', 'dropdown-arrow') %> +
+
+ + <%- @Icon('arrow-down', 'dropdown-arrow') %> +
+
diff --git a/app/assets/javascripts/app/views/generic/user_search/new_user.jst.eco b/app/assets/javascripts/app/views/generic/user_search/new_user.jst.eco index 520e60951..c12a8efbd 100644 --- a/app/assets/javascripts/app/views/generic/user_search/new_user.jst.eco +++ b/app/assets/javascripts/app/views/generic/user_search/new_user.jst.eco @@ -1,4 +1,4 @@ -
  • +
  • <%- @Icon('plus', 'recipientList-icon') %>
    diff --git a/app/models/ticket.rb b/app/models/ticket.rb index 3e9623271..aa70501a7 100644 --- a/app/models/ticket.rb +++ b/app/models/ticket.rb @@ -295,7 +295,7 @@ get count of tickets and tickets which match on selector def self.selectors(selectors, limit = 10, current_user = nil) fail 'no selectors given' if !selectors - query, bind_params, tables = selector2sql(selectors) + query, bind_params, tables = selector2sql(selectors, current_user) return [] if !query if !current_user @@ -314,7 +314,7 @@ get count of tickets and tickets which match on selector generate condition query to search for tickets based on condition - query_condition, bind_condition = selector2sql(params[:condition]) + query_condition, bind_condition = selector2sql(params[:condition], current_user) condition example @@ -332,15 +332,31 @@ condition example range: 'day', # minute|hour|day|month|year value: '25', }, + 'ticket.owner_id' => { + operator: 'is', # is not + pre_condition: 'current_user.id', + }, + 'ticket.owner_id' => { + operator: 'is', # is not + pre_condition: 'specific', + value: 4711, + }, } =end - def self.selector2sql(selectors) + def self.selector2sql(selectors, current_user = nil) + current_user_id = UserInfo.current_user_id + if current_user + current_user_id = current_user.id + end return if !selectors + + # remember query and bind params query = '' bind_params = [] + # get tables to join tables = '' selectors.each {|attribute, selector| selector = attribute.split(/\./) @@ -364,24 +380,71 @@ condition example end } + # add conditions selectors.each {|attribute, selector_raw| - if query != '' - query += ' AND ' - end + + # validation fail "Invalid selector #{selector_raw.inspect}" if !selector_raw fail "Invalid selector #{selector_raw.inspect}" if !selector_raw.respond_to?(:key?) selector = selector_raw.stringify_keys fail "Invalid selector, operator missing #{selector.inspect}" if !selector['operator'] - return nil if selector['value'].nil? - return nil if selector['value'].respond_to?(:empty?) && selector['value'].empty? + + # validate value / allow empty but only if pre_condition eyists + if selector['value'].nil? || (selector['value'].respond_to?(:empty?) && selector['value'].empty?) + return nil if selector['pre_condition'].nil? || (selector['pre_condition'].respond_to?(:empty?) && selector['pre_condition'].empty?) + end + + # validate pre_condition values + return nil if selector['pre_condition'] && selector['pre_condition'] !~ /^(set|current_user\.|specific)/ + + # get attributes attributes = attribute.split(/\./) attribute = "#{attributes[0]}s.#{attributes[1]}" + + if query != '' + query += ' AND ' + end + if selector['operator'] == 'is' - query += "#{attribute} IN (?)" - bind_params.push selector['value'] + if selector['pre_condition'] == 'set' + if attributes[1] =~ /^(created_by|updated_by|owner|customer|user)_id/ + query += "#{attribute} NOT IN (?)" + bind_params.push 1 + else + query += "#{attribute} IS NOT NULL" + end + elsif selector['pre_condition'] == 'current_user.id' + fail "Use current_user.id in selector, but no current_user is set #{selector.inspect}" if !current_user_id + query += "#{attribute} IN (?)" + bind_params.push current_user_id + elsif selector['pre_condition'] == 'current_user.organization_id' + fail "Use current_user.id in selector, but no current_user is set #{selector.inspect}" if !current_user_id + query += "#{attribute} IN (?)" + user = User.lookup(id: current_user_id) + bind_params.push user.organization_id + else + query += "#{attribute} IN (?)" + bind_params.push selector['value'] + end elsif selector['operator'] == 'is not' - query += "#{attribute} NOT IN (?)" - bind_params.push selector['value'] + if selector['pre_condition'] == 'set' + if attributes[1] =~ /^(created_by|updated_by|owner|customer|user)_id/ + query += "#{attribute} IN (?)" + bind_params.push 1 + else + query += "#{attribute} IS NULL" + end + elsif selector['pre_condition'] == 'current_user.id' + query += "#{attribute} NOT IN (?)" + bind_params.push current_user_id + elsif selector['pre_condition'] == 'current_user.organization_id' + query += "#{attribute} NOT IN (?)" + user = User.lookup(id: current_user_id) + bind_params.push user.organization_id + else + query += "#{attribute} NOT IN (?)" + bind_params.push selector['value'] + end elsif selector['operator'] == 'contains' query += "#{attribute} LIKE (?)" value = "%#{selector['value']}%" diff --git a/app/models/ticket/overviews.rb b/app/models/ticket/overviews.rb index e5eb059ce..d7d12c8f1 100644 --- a/app/models/ticket/overviews.rb +++ b/app/models/ticket/overviews.rb @@ -69,32 +69,6 @@ returns overview_selected = overview overview_selected_raw = Marshal.load( Marshal.dump(overview.attributes) ) end - - # replace e.g. 'current_user.id' with current_user.id - overview.condition.each { |attribute, content| - next if !content - next if !content.respond_to?(:key?) - next if !content['value'] - next if content['value'].class != String && content['value'].class != Array - - if content['value'].class == String - parts = content['value'].split( '.', 2 ) - next if !parts[0] - next if !parts[1] - next if parts[0] != 'current_user' - overview.condition[attribute]['value'] = data[:current_user][parts[1].to_sym] - next - end - - content['value'].each {|item| - next if item.class != String - parts = item.split('.', 2) - next if !parts[0] - next if !parts[1] - next if parts[0] != 'current_user' - item = data[:current_user][parts[1].to_sym] - } - } } if data[:view] && !overview_selected @@ -111,7 +85,7 @@ returns result = [] overviews.each { |overview| - query_condition, bind_condition = Ticket.selector2sql(overview.condition) + query_condition, bind_condition = Ticket.selector2sql(overview.condition, data[:current_user]) # get count count = Ticket.where( access_condition ).where( query_condition, *bind_condition ).count() @@ -136,7 +110,7 @@ returns order_by = overview_selected.group_by + '_id, ' + order_by end - query_condition, bind_condition = Ticket.selector2sql(overview_selected.condition) + query_condition, bind_condition = Ticket.selector2sql(overview_selected.condition, data[:current_user]) tickets = Ticket.select('id') .where( access_condition ) @@ -160,7 +134,7 @@ returns # get tickets for overview data[:start_page] ||= 1 - query_condition, bind_condition = Ticket.selector2sql(overview_selected.condition) + query_condition, bind_condition = Ticket.selector2sql(overview_selected.condition, data[:current_user]) tickets = Ticket.where( access_condition ) .where( query_condition, *bind_condition ) .order( overview_selected[:order][:by].to_s + ' ' + overview_selected[:order][:direction].to_s ) diff --git a/contrib/systemd/zammad.service b/contrib/systemd/zammad.service new file mode 100644 index 000000000..4bd2f53d3 --- /dev/null +++ b/contrib/systemd/zammad.service @@ -0,0 +1,19 @@ +[Unit] +Description=Zammad +After=syslog.target +After=network.target + +[Service] +Type=simple +User= { + operator: 'is', + value: [ 1, 2, 3, 7 ], + }, + 'ticket.owner_id' => { + operator: 'is', + pre_condition: 'current_user.id', + }, + }, + order: { + by: 'created_at', + direction: 'ASC', + }, + view: { + d: %w(title customer group created_at), + s: %w(title customer group created_at), + m: %w(number title customer group created_at), + view_mode_default: 's', + }, + ) + + Overview.create_or_update( + name: 'My pending reached Tickets', + link: 'my_pending_reached', + prio: 1010, + role_id: overview_role.id, + condition: { + 'ticket.state_id' => { + operator: 'is', + value: 3, + }, + 'ticket.owner_id' => { + operator: 'is', + pre_condition: 'current_user.id', + }, + 'ticket.pending_time' => { + operator: 'within next (relative)', + value: 0, + range: 'minute', + }, + }, + order: { + by: 'created_at', + direction: 'ASC', + }, + view: { + d: %w(title customer group created_at), + s: %w(title customer group created_at), + m: %w(number title customer group created_at), + view_mode_default: 's', + }, + ) + + Overview.create_or_update( + name: 'Unassigned & Open Tickets', + link: 'all_unassigned', + prio: 1020, + role_id: overview_role.id, + condition: { + 'ticket.state_id' => { + operator: 'is', + value: [1, 2, 3], + }, + 'ticket.owner_id' => { + operator: 'is', + value: 1, + }, + }, + order: { + by: 'created_at', + direction: 'ASC', + }, + view: { + d: %w(title customer group created_at), + s: %w(title customer group created_at), + m: %w(number title customer group created_at), + view_mode_default: 's', + }, + ) + + Overview.create_or_update( + name: 'All Open Tickets', + link: 'all_open', + prio: 1030, + role_id: overview_role.id, + condition: { + 'ticket.state_id' => { + operator: 'is', + value: [1, 2, 3], + }, + }, + order: { + by: 'created_at', + direction: 'ASC', + }, + view: { + d: %w(title customer group state owner created_at), + s: %w(title customer group state owner created_at), + m: %w(number title customer group state owner created_at), + view_mode_default: 's', + }, + ) + + Overview.create_or_update( + name: 'All pending reached Tickets', + link: 'all_pending_reached', + prio: 1035, + role_id: overview_role.id, + condition: { + 'ticket.state_id' => { + operator: 'is', + value: [3], + }, + 'ticket.pending_time' => { + operator: 'within next (relative)', + value: 0, + range: 'minute', + }, + }, + order: { + by: 'created_at', + direction: 'ASC', + }, + view: { + d: %w(title customer group owner created_at), + s: %w(title customer group owner created_at), + m: %w(number title customer group owner created_at), + view_mode_default: 's', + }, + ) + + Overview.create_or_update( + name: 'Escalated Tickets', + link: 'all_escalated', + prio: 1040, + role_id: overview_role.id, + condition: { + 'ticket.escalation_time' => { + operator: 'within next (relative)', + value: '10', + range: 'minute', + }, + }, + order: { + by: 'escalation_time', + direction: 'ASC', + }, + view: { + d: %w(title customer group owner escalation_time), + s: %w(title customer group owner escalation_time), + m: %w(number title customer group owner escalation_time), + view_mode_default: 's', + }, + ) + + overview_role = Role.where( name: 'Customer' ).first + Overview.create_or_update( + name: 'My Tickets', + link: 'my_tickets', + prio: 1000, + role_id: overview_role.id, + condition: { + 'ticket.state_id' => { + operator: 'is', + value: [ 1, 2, 3, 4, 6, 7 ], + }, + 'ticket.customer_id' => { + operator: 'is', + pre_condition: 'current_user.id', + }, + }, + order: { + by: 'created_at', + direction: 'DESC', + }, + view: { + d: %w(title customer state created_at), + s: %w(number title state created_at), + m: %w(number title state created_at), + view_mode_default: 's', + }, + ) + Overview.create_or_update( + name: 'My Organization Tickets', + link: 'my_organization_tickets', + prio: 1100, + role_id: overview_role.id, + organization_shared: true, + condition: { + 'ticket.state_id' => { + operator: 'is', + value: [ 1, 2, 3, 4, 6, 7 ], + }, + 'ticket.organization_id' => { + operator: 'is', + pre_condition: 'current_user.organization_id', + }, + }, + order: { + by: 'created_at', + direction: 'DESC', + }, + view: { + d: %w(title customer state created_at), + s: %w(number title customer state created_at), + m: %w(number title customer state created_at), + view_mode_default: 's', + }, + ) + + end +end diff --git a/db/seeds.rb b/db/seeds.rb index e0ca60de6..920750e30 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -1615,7 +1615,7 @@ Overview.create_if_not_exists( }, 'ticket.owner_id' => { operator: 'is', - value: 'current_user.id', + pre_condition: 'current_user.id', }, }, order: { @@ -1642,7 +1642,7 @@ Overview.create_if_not_exists( }, 'ticket.owner_id' => { operator: 'is', - value: 'current_user.id', + pre_condition: 'current_user.id', }, 'ticket.pending_time' => { operator: 'within next (relative)', @@ -1777,7 +1777,7 @@ Overview.create_if_not_exists( }, 'ticket.customer_id' => { operator: 'is', - value: 'current_user.id', + pre_condition: 'current_user.id', }, }, order: { @@ -1804,7 +1804,7 @@ Overview.create_if_not_exists( }, 'ticket.organization_id' => { operator: 'is', - value: 'current_user.organization_id', + pre_condition: 'current_user.organization_id', }, }, order: { diff --git a/extras/zammad_nginx.conf b/extras/zammad_nginx.conf new file mode 100644 index 000000000..a1046892b --- /dev/null +++ b/extras/zammad_nginx.conf @@ -0,0 +1,22 @@ +server { + listen 80; + server_name SERVER_NAME; + root /opt/zammad/zammad/public; + + location ~ ^/(assets/|robots.txt|humans.txt|favicon.ico) { + expires max; + } + + location /ws { + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_pass http://localhost:6042; + } + + location / { + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_pass http://localhost:3000; + } +} diff --git a/public/assets/tests/form-extended.js b/public/assets/tests/form-extended.js index 4113b3486..c68906182 100644 --- a/public/assets/tests/form-extended.js +++ b/public/assets/tests/form-extended.js @@ -2,7 +2,7 @@ // form test( 'form checks', function() { - App.TicketPriority.refresh( [ + App.TicketPriority.refresh([ { id: 1, name: '1 low', @@ -31,7 +31,28 @@ test( 'form checks', function() { active: true, created_at: '2014-06-10T10:17:54.000Z', }, - ] ) + ]) + + App.User.refresh([ + { + id: 47, + login: 'bod@example.com', + email: 'bod@example.com', + firstname: 'Bob', + lastname: 'Smith', + active: true, + created_at: '2014-06-10T11:17:34.000Z', + }, + ]) + + App.Organization.refresh([ + { + id: 12, + name: 'Org 1', + active: true, + created_at: '2014-06-10T11:19:34.000Z', + }, + ]) $('#forms').append('

    form time check

    ') @@ -98,6 +119,16 @@ test( 'form checks', function() { operator: 'before (absolute)', value: '2015-09-20T03:41:00.000Z', }, + 'ticket.organization_id': { + operator: 'is not', + pre_condition: 'specific', + value: 12, + }, + 'ticket.owner_id': { + operator: 'is', + pre_condition: 'specific', + value: 47, + }, }, executions: { 'ticket.title': { @@ -143,6 +174,17 @@ test( 'form checks', function() { operator: 'before (absolute)', value: '2015-09-20T03:41:00.000Z', }, + 'ticket.organization_id': { + operator: 'is not', + pre_condition: 'specific', + value: '12', + }, + 'ticket.owner_id': { + operator: 'is', + pre_condition: 'specific', + value: '47', + value_completion: 'Bob Smith ', + }, }, executions: { 'ticket.title': { @@ -270,6 +312,17 @@ test( 'form checks', function() { operator: 'before (absolute)', value: '2015-09-20T03:41:00.000Z', }, + 'ticket.organization_id': { + operator: 'is not', + pre_condition: 'specific', + value: '12', + }, + 'ticket.owner_id': { + operator: 'is', + pre_condition: 'specific', + value: '47', + value_completion: 'Bob Smith ', + }, }, executions: { 'ticket.priority_id': { diff --git a/test/browser/agent_user_manage_test.rb b/test/browser/agent_user_manage_test.rb index d3b0311ba..82521be00 100644 --- a/test/browser/agent_user_manage_test.rb +++ b/test/browser/agent_user_manage_test.rb @@ -29,7 +29,7 @@ class AgentUserManageTest < TestCase sleep 1 sendkey( value: :arrow_down ) sleep 0.5 - click( css: '.active .newTicket .recipientList-entry.js-user-new' ) + click( css: '.active .newTicket .recipientList-entry.js-userNew' ) sleep 1 set( diff --git a/test/unit/ticket_selector_test.rb b/test/unit/ticket_selector_test.rb index b6da0727d..75714001f 100644 --- a/test/unit/ticket_selector_test.rb +++ b/test/unit/ticket_selector_test.rb @@ -621,6 +621,230 @@ class TicketSelectorTest < ActiveSupport::TestCase ticket_count, tickets = Ticket.selectors(condition, 10, customer2) assert_equal( ticket_count, 0 ) + # with owner/customer/org + condition = { + 'ticket.group_id' => { + operator: 'is', + value: group.id, + }, + 'ticket.owner_id' => { + operator: 'is', + pre_condition: 'specific', + value: agent1.id, + }, + } + ticket_count, tickets = Ticket.selectors(condition, 10, agent1) + assert_equal( ticket_count, 1 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, agent2) + assert_equal( ticket_count, 0 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, customer1) + assert_equal( ticket_count, 1 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, customer2) + assert_equal( ticket_count, 0 ) + + condition = { + 'ticket.group_id' => { + operator: 'is', + value: group.id, + }, + 'ticket.owner_id' => { + operator: 'is', + pre_condition: 'set', + }, + } + ticket_count, tickets = Ticket.selectors(condition, 10, agent1) + assert_equal( ticket_count, 1 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, agent2) + assert_equal( ticket_count, 0 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, customer1) + assert_equal( ticket_count, 1 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, customer2) + assert_equal( ticket_count, 0 ) + + condition = { + 'ticket.group_id' => { + operator: 'is', + value: group.id, + }, + 'ticket.owner_id' => { + operator: 'is not', + pre_condition: 'set', + }, + } + ticket_count, tickets = Ticket.selectors(condition, 10, agent1) + assert_equal( ticket_count, 1 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, agent2) + assert_equal( ticket_count, 0 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, customer1) + assert_equal( ticket_count, 0 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, customer2) + assert_equal( ticket_count, 1 ) + + UserInfo.current_user_id = agent1.id + condition = { + 'ticket.group_id' => { + operator: 'is', + value: group.id, + }, + 'ticket.owner_id' => { + operator: 'is', + pre_condition: 'current_user.id', + }, + } + ticket_count, tickets = Ticket.selectors(condition, 10, agent1) + assert_equal( ticket_count, 1 ) + + ticket_count, tickets = Ticket.selectors(condition, 10) + assert_equal( ticket_count, 1 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, agent2) + assert_equal( ticket_count, 0 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, customer1) + assert_equal( ticket_count, 0 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, customer2) + assert_equal( ticket_count, 0 ) + + UserInfo.current_user_id = agent2.id + condition = { + 'ticket.group_id' => { + operator: 'is', + value: group.id, + }, + 'ticket.owner_id' => { + operator: 'is', + pre_condition: 'current_user.id', + }, + } + ticket_count, tickets = Ticket.selectors(condition, 10, agent1) + assert_equal( ticket_count, 1 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, agent2) + assert_equal( ticket_count, 0 ) + + ticket_count, tickets = Ticket.selectors(condition, 10) + assert_equal( ticket_count, 0 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, customer1) + assert_equal( ticket_count, 0 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, customer2) + assert_equal( ticket_count, 0 ) + + UserInfo.current_user_id = customer1.id + condition = { + 'ticket.group_id' => { + operator: 'is', + value: group.id, + }, + 'ticket.customer_id' => { + operator: 'is', + pre_condition: 'current_user.id', + }, + } + ticket_count, tickets = Ticket.selectors(condition, 10, agent1) + assert_equal( ticket_count, 0 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, agent2) + assert_equal( ticket_count, 0 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, customer1) + assert_equal( ticket_count, 1 ) + + ticket_count, tickets = Ticket.selectors(condition, 10) + assert_equal( ticket_count, 1 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, customer2) + assert_equal( ticket_count, 1 ) + + UserInfo.current_user_id = customer2.id + condition = { + 'ticket.group_id' => { + operator: 'is', + value: group.id, + }, + 'ticket.customer_id' => { + operator: 'is', + pre_condition: 'current_user.id', + }, + } + ticket_count, tickets = Ticket.selectors(condition, 10, agent1) + assert_equal( ticket_count, 0 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, agent2) + assert_equal( ticket_count, 0 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, customer1) + assert_equal( ticket_count, 1 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, customer2) + assert_equal( ticket_count, 1 ) + + ticket_count, tickets = Ticket.selectors(condition, 10) + assert_equal( ticket_count, 1 ) + + UserInfo.current_user_id = customer1.id + condition = { + 'ticket.group_id' => { + operator: 'is', + value: group.id, + }, + 'ticket.organization_id' => { + operator: 'is', + pre_condition: 'current_user.organization_id', + }, + } + ticket_count, tickets = Ticket.selectors(condition, 10, agent1) + assert_equal( ticket_count, 0 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, agent2) + assert_equal( ticket_count, 0 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, customer1) + assert_equal( ticket_count, 1 ) + + ticket_count, tickets = Ticket.selectors(condition, 10) + assert_equal( ticket_count, 1 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, customer2) + assert_equal( ticket_count, 0 ) + + UserInfo.current_user_id = customer2.id + condition = { + 'ticket.group_id' => { + operator: 'is', + value: group.id, + }, + 'ticket.organization_id' => { + operator: 'is', + pre_condition: 'current_user.organization_id', + }, + } + ticket_count, tickets = Ticket.selectors(condition, 10, agent1) + assert_equal( ticket_count, 0 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, agent2) + assert_equal( ticket_count, 0 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, customer1) + assert_equal( ticket_count, 1 ) + + ticket_count, tickets = Ticket.selectors(condition, 10, customer2) + assert_equal( ticket_count, 0 ) + + ticket_count, tickets = Ticket.selectors(condition, 10) + assert_equal( ticket_count, 0 ) + end end