Browse Source

Fixes #4848 - Certain offered states can not be set (never) via the bulk action.

Co-authored-by: Dominik Klein <dk@zammad.com>
Rolf Schmidt 1 year ago
parent
commit
ecb9fbd221

+ 1 - 1
app/assets/javascripts/app/controllers/_application_controller/form.coffee

@@ -268,7 +268,7 @@ class App.ControllerForm extends App.Controller
     attribute.id = "#{idPrefix}_#{attribute.name}"
 
     # set label class name
-    attribute.label_class = @model.labelClass or attribute.label_class
+    attribute.label_class = @labelClass or attribute.label_class
 
     # set autofocus
     if @autofocus && attributeCount is 1

+ 9 - 30
app/assets/javascripts/app/controllers/widget/ticket_bulk_form.coffee

@@ -16,30 +16,10 @@ class App.TicketBulkForm extends App.Controller
 
     return if !@permissionCheck('ticket.agent')
 
-    @configure_attributes_ticket = []
+    bulkAttributes   = App.Ticket.attributesGet('overview_bulk')
+    hiddenAttributes = { ticket_ids: { name: 'ticket_ids', display: false, tag: 'input', type: 'hidden', limit: 100, null: false } }
 
-    used_attributes = ['state_id', 'pending_time', 'priority_id', 'group_id', 'owner_id']
-    attributesClean = App.Ticket.attributesGet('edit')
-    for attributeName, attribute of attributesClean
-      if _.contains(used_attributes, attributeName)
-        localAttribute = clone(attribute)
-        localAttribute.nulloption = true
-        localAttribute.default = ''
-        localAttribute.null = true
-
-        if localAttribute.name == 'group_id'
-          localAttribute.direction = 'up'
-
-        @configure_attributes_ticket.push localAttribute
-
-    # add field for ticket ids
-    ticket_ids_attribute = { name: 'ticket_ids', display: false, tag: 'input', type: 'hidden', limit: 100, null: false }
-    @configure_attributes_ticket.push ticket_ids_attribute
-
-    time_attribute = _.findWhere(@configure_attributes_ticket, {'name': 'pending_time'})
-    if time_attribute
-      time_attribute.orientation = 'top'
-      time_attribute.disableScroll = true
+    @configure_attributes_ticket = Object.assign({}, bulkAttributes, hiddenAttributes)
 
     @holder = @options.holder
     @visible = false
@@ -63,11 +43,10 @@ class App.TicketBulkForm extends App.Controller
 
     @controllerFormBulk = new App.ControllerForm(
       el: @$('#form-ticket-bulk')
-      model:
-        configure_attributes: @configure_attributes_ticket
-        className:            'Ticket'
-        labelClass:           'input-group-addon'
-      screen:         'overview_bulk'
+      mixedAttributes: @configure_attributes_ticket
+      model: App.Ticket
+      screen: 'overview_bulk'
+      labelClass: 'input-group-addon'
       handlersConfig: handlers
       params:         {}
       filter:         @formMeta.filter
@@ -82,7 +61,7 @@ class App.TicketBulkForm extends App.Controller
       model:
         configure_attributes: [{ name: 'body', display: __('Comment'), tag: 'textarea', rows: 4, null: true, upload: false, item_class: 'flex' }]
         className:            'Ticket'
-        labelClass:           'input-group-addon'
+      labelClass: 'input-group-addon'
       screen:     'overview_bulk_comment'
       noFieldset: true
     )
@@ -97,7 +76,7 @@ class App.TicketBulkForm extends App.Controller
       model:
         configure_attributes: @confirm_attributes
         className:            'Ticket'
-        labelClass:           'input-group-addon'
+      labelClass: 'input-group-addon'
       screen:     'overview_bulk_visibility'
       noFieldset: true
     )

+ 5 - 5
app/controllers/tickets_controller.rb

@@ -350,7 +350,7 @@ class TicketsController < ApplicationController
     # if we do not have open related tickets, search for any tickets
     tickets ||= TicketPolicy::ReadScope.new(current_user).resolve
                                        .where(customer_id: ticket.customer_id)
-                                       .where.not(state_id: Ticket::State.by_category(:merged).pluck(:id))
+                                       .where.not(state_id: Ticket::State.by_category_ids(:merged))
                                        .where.not(id: ticket.id)
                                        .reorder(created_at: :desc)
                                        .limit(6)
@@ -527,7 +527,7 @@ class TicketsController < ApplicationController
         closed_ids: {
           'ticket.state_id'    => {
             operator: 'is',
-            value:    Ticket::State.by_category(:closed).pluck(:id),
+            value:    Ticket::State.by_category_ids(:closed),
           },
           'ticket.customer_id' => {
             operator: 'is',
@@ -537,7 +537,7 @@ class TicketsController < ApplicationController
         open_ids:   {
           'ticket.state_id'    => {
             operator: 'is',
-            value:    Ticket::State.by_category(:open).pluck(:id),
+            value:    Ticket::State.by_category_ids(:open),
           },
           'ticket.customer_id' => {
             operator: 'is',
@@ -572,7 +572,7 @@ class TicketsController < ApplicationController
         closed_ids: {
           'ticket.state_id'        => {
             operator: 'is',
-            value:    Ticket::State.by_category(:closed).pluck(:id),
+            value:    Ticket::State.by_category_ids(:closed),
           },
           'ticket.organization_id' => {
             operator: 'is',
@@ -582,7 +582,7 @@ class TicketsController < ApplicationController
         open_ids:   {
           'ticket.state_id'        => {
             operator: 'is',
-            value:    Ticket::State.by_category(:open).pluck(:id),
+            value:    Ticket::State.by_category_ids(:open),
           },
           'ticket.organization_id' => {
             operator: 'is',

+ 1 - 1
app/models/core_workflow/custom/ticket_duplicate_detection.rb

@@ -54,7 +54,7 @@ class CoreWorkflow::Custom::TicketDuplicateDetection < CoreWorkflow::Custom::Bac
       if Setting.get('ticket_duplicate_detection_search') == 'open'
         where_condition_selector['ticket.state_id'] = {
           operator: 'is',
-          value:    Ticket::State.by_category(:open).pluck(:id).map(&:to_s),
+          value:    Ticket::State.by_category_ids(:open).map(&:to_s),
         }
       end
 

+ 1 - 1
app/models/recent_view.rb

@@ -58,7 +58,7 @@ class RecentView < ApplicationModel
 
       viewable_ticket_ids = Ticket.where('id IN (?) AND state_id in (?)',
                                          recent_views.map(&:o_id),
-                                         Ticket::State.by_category(:viewable_agent_new).pluck(:id)) # rubocop:disable Rails/PluckInWhere
+                                         Ticket::State.by_category_ids(:viewable_agent_new))
                                   .pluck(:id)
 
       recent_views = recent_views.select { |rv| viewable_ticket_ids.include?(rv.o_id) }

+ 1 - 1
app/models/ticket.rb

@@ -275,7 +275,7 @@ returns
   def self.process_auto_unassign
 
     # process pending action tickets
-    state_ids = Ticket::State.by_category(:work_on).pluck(:id)
+    state_ids = Ticket::State.by_category_ids(:work_on)
     return [] if state_ids.blank?
 
     result = []

+ 1 - 1
app/models/ticket/sets_last_owner_update_time.rb

@@ -37,7 +37,7 @@ module Ticket::SetsLastOwnerUpdateTime
 
     # check if state is not new/open
     if changes_to_save['state_id'].present?
-      state_ids = Ticket::State.by_category(:work_on).pluck(:id)
+      state_ids = Ticket::State.by_category_ids(:work_on)
       if state_ids.exclude?(changes_to_save['state_id'][1])
         self.last_owner_update_at = nil
         return true

+ 10 - 6
app/models/ticket/state.rb

@@ -42,6 +42,10 @@ returns:
       .where(ticket_state_types: { name: Ticket::StateType.names_in_category(category) })
   }
 
+  def self.by_category_ids(category)
+    by_category(category).pluck(:id)
+  end
+
   def ensure_defaults
     return if callback_loop
 
@@ -80,12 +84,12 @@ returns:
       name:   'state_id',
     )
 
-    attr.data_option[:filter] = Ticket::State.by_category(:viewable).pluck(:id)
-
-    attr.screens[:create_middle]['ticket.agent'][:filter]    = Ticket::State.by_category(:viewable_agent_new).pluck(:id)
-    attr.screens[:create_middle]['ticket.customer'][:filter] = Ticket::State.by_category(:viewable_customer_new).pluck(:id)
-    attr.screens[:edit]['ticket.agent'][:filter]             = Ticket::State.by_category(:viewable_agent_edit).pluck(:id)
-    attr.screens[:edit]['ticket.customer'][:filter]          = Ticket::State.by_category(:viewable_customer_edit).pluck(:id)
+    attr.data_option[:filter]                                = Ticket::State.by_category_ids(:viewable)
+    attr.screens[:create_middle]['ticket.agent'][:filter]    = Ticket::State.by_category_ids(:viewable_agent_new)
+    attr.screens[:create_middle]['ticket.customer'][:filter] = Ticket::State.by_category_ids(:viewable_customer_new)
+    attr.screens[:edit]['ticket.agent'][:filter]             = Ticket::State.by_category_ids(:viewable_agent_edit)
+    attr.screens[:edit]['ticket.customer'][:filter]          = Ticket::State.by_category_ids(:viewable_customer_edit)
+    attr.screens[:overview_bulk]['ticket.agent'][:filter]    = Ticket::State.by_category_ids(:viewable_agent_edit)
 
     attr.save!
   end

+ 49 - 0
db/migrate/20231122123502_issue_4848_fix_overview_bulk_screen.rb

@@ -0,0 +1,49 @@
+# Copyright (C) 2012-2023 Zammad Foundation, https://zammad-foundation.org/
+
+class Issue4848FixOverviewBulkScreen < ActiveRecord::Migration[7.0]
+  def change
+    # return if it's a new setup
+    return if !Setting.exists?(name: 'system_init_done')
+
+    ObjectManager::Attribute.for_object('Ticket').where(name: %w[state_id pending_time group_id owner_id priority_id]).each do |field|
+      field.screens[:overview_bulk] = {
+        'ticket.agent' => overview_bulk_configs[field.name],
+      }
+      field.save!
+    end
+  end
+
+  def overview_bulk_configs
+    @overview_bulk_configs ||= {
+      'state_id'     => {
+        nulloption: true,
+        null:       true,
+        default:    '',
+        filter:     Ticket::State.by_category(:viewable_agent_edit).pluck(:id),
+      },
+      'pending_time' => {
+        nulloption:    true,
+        null:          true,
+        default:       '',
+        orientation:   'top',
+        disableScroll: true,
+      },
+      'group_id'     => {
+        nulloption: true,
+        null:       true,
+        default:    '',
+        direction:  'up',
+      },
+      'owner_id'     => {
+        nulloption: true,
+        null:       true,
+        default:    '',
+      },
+      'priority_id'  => {
+        nulloption: true,
+        null:       true,
+        default:    '',
+      },
+    }
+  end
+end

+ 42 - 5
db/seeds/object_manager_attributes.rb

@@ -186,6 +186,14 @@ ObjectManager::Attribute.add(
         null: false,
       },
     },
+    overview_bulk: {
+      'ticket.agent' => {
+        nulloption: true,
+        null:       true,
+        default:    '',
+        direction:  'up',
+      },
+    },
   },
   to_create:   false,
   to_migrate:  false,
@@ -222,6 +230,11 @@ ObjectManager::Attribute.add(
         null: true,
       },
     },
+    overview_bulk: {
+      'ticket.agent' => {
+        null: true,
+      },
+    },
   },
   to_create:   false,
   to_migrate:  false,
@@ -241,7 +254,7 @@ ObjectManager::Attribute.add(
     null:       false,
     default:    Ticket::State.find_by(default_follow_up: true).id,
     translate:  true,
-    filter:     Ticket::State.by_category(:viewable).pluck(:id),
+    filter:     Ticket::State.by_category_ids(:viewable),
   },
   editable:    false,
   active:      true,
@@ -250,13 +263,13 @@ ObjectManager::Attribute.add(
       'ticket.agent'    => {
         null:       false,
         item_class: 'column',
-        filter:     Ticket::State.by_category(:viewable_agent_new).pluck(:id),
+        filter:     Ticket::State.by_category_ids(:viewable_agent_new),
       },
       'ticket.customer' => {
         item_class: 'column',
         nulloption: false,
         null:       true,
-        filter:     Ticket::State.by_category(:viewable_customer_new).pluck(:id),
+        filter:     Ticket::State.by_category_ids(:viewable_customer_new),
         default:    Ticket::State.find_by(default_create: true).id,
       },
     },
@@ -264,15 +277,23 @@ ObjectManager::Attribute.add(
       'ticket.agent'    => {
         nulloption: false,
         null:       false,
-        filter:     Ticket::State.by_category(:viewable_agent_edit).pluck(:id),
+        filter:     Ticket::State.by_category_ids(:viewable_agent_edit),
       },
       'ticket.customer' => {
         nulloption: false,
         null:       true,
-        filter:     Ticket::State.by_category(:viewable_customer_edit).pluck(:id),
+        filter:     Ticket::State.by_category_ids(:viewable_customer_edit),
         default:    Ticket::State.find_by(default_follow_up: true).id,
       },
     },
+    overview_bulk: {
+      'ticket.agent' => {
+        nulloption: true,
+        null:       true,
+        default:    '',
+        filter:     Ticket::State.by_category_ids(:viewable_agent_edit),
+      },
+    }
   },
   to_create:   false,
   to_migrate:  false,
@@ -307,6 +328,15 @@ ObjectManager::Attribute.add(
         null: false,
       },
     },
+    overview_bulk: {
+      'ticket.agent' => {
+        nulloption:    true,
+        null:          true,
+        default:       '',
+        orientation:   'top',
+        disableScroll: true,
+      },
+    },
   },
   to_create:   false,
   to_migrate:  false,
@@ -341,6 +371,13 @@ ObjectManager::Attribute.add(
         null: false,
       },
     },
+    overview_bulk: {
+      'ticket.agent' => {
+        nulloption: true,
+        null:       true,
+        default:    '',
+      },
+    },
   },
   to_create:   false,
   to_migrate:  false,

Some files were not shown because too many files changed in this diff