Improved checks on 'Follow Up Possible' on frontend/backend API if set in user group
This commit is contained in:
parent
956525fd55
commit
4c38d7a719
6 changed files with 120 additions and 19 deletions
|
@ -3,9 +3,9 @@
|
||||||
Zammad is a web based open source helpdesk/customer support system with many
|
Zammad is a web based open source helpdesk/customer support system with many
|
||||||
features to manage customer communication via several channels like telephone,
|
features to manage customer communication via several channels like telephone,
|
||||||
facebook, twitter, chat and e-mails. It is distributed under the GNU AFFERO
|
facebook, twitter, chat and e-mails. It is distributed under the GNU AFFERO
|
||||||
General Public License (AGPL) and tested on Linux, Solaris, AIX, FreeBSD,
|
General Public License (AGPL).
|
||||||
OpenBSD and Mac OS 10.x. Do you receive many e-mails and want to answer them
|
|
||||||
with a team of agents?
|
Do you receive many e-mails and want to answer them with a team of agents?
|
||||||
|
|
||||||
You're going to love Zammad!
|
You're going to love Zammad!
|
||||||
|
|
||||||
|
|
|
@ -848,7 +848,7 @@ class App.TicketZoom extends App.Controller
|
||||||
error: (settings, details) =>
|
error: (settings, details) =>
|
||||||
App.Event.trigger 'notify', {
|
App.Event.trigger 'notify', {
|
||||||
type: 'error'
|
type: 'error'
|
||||||
msg: App.i18n.translateContent(details.error_human || details.error || 'Unable to update!')
|
msg: App.i18n.translateContent(details.error_human || details.error || settings.responseJSON.error || 'Unable to update!')
|
||||||
timeout: 2000
|
timeout: 2000
|
||||||
}
|
}
|
||||||
@autosaveStart()
|
@autosaveStart()
|
||||||
|
|
|
@ -8,11 +8,17 @@ class Edit extends App.ObserverController
|
||||||
render: (ticket, diff) =>
|
render: (ticket, diff) =>
|
||||||
defaults = ticket.attributes()
|
defaults = ticket.attributes()
|
||||||
delete defaults.article # ignore article infos
|
delete defaults.article # ignore article infos
|
||||||
|
followUpPossible = App.Group.find(defaults.group_id).follow_up_possible
|
||||||
|
ticketState = App.TicketState.find(defaults.state_id).name
|
||||||
|
|
||||||
taskState = @taskGet('ticket')
|
taskState = @taskGet('ticket')
|
||||||
|
|
||||||
if !_.isEmpty(taskState)
|
if !_.isEmpty(taskState)
|
||||||
defaults = _.extend(defaults, taskState)
|
defaults = _.extend(defaults, taskState)
|
||||||
|
|
||||||
|
if followUpPossible == 'new_ticket' && ticketState != 'closed' ||
|
||||||
|
followUpPossible != 'new_ticket' ||
|
||||||
|
@permissionCheck('admin') || @permissionCheck('ticket.agent')
|
||||||
new App.ControllerForm(
|
new App.ControllerForm(
|
||||||
elReplace: @el
|
elReplace: @el
|
||||||
model: App.Ticket
|
model: App.Ticket
|
||||||
|
@ -25,6 +31,19 @@ class Edit extends App.ObserverController
|
||||||
isDisabled: !ticket.editable()
|
isDisabled: !ticket.editable()
|
||||||
#bookmarkable: true
|
#bookmarkable: true
|
||||||
)
|
)
|
||||||
|
else
|
||||||
|
new App.ControllerForm(
|
||||||
|
elReplace: @el
|
||||||
|
model: App.Ticket
|
||||||
|
screen: 'edit'
|
||||||
|
handlers: [
|
||||||
|
@ticketFormChanges
|
||||||
|
]
|
||||||
|
filter: @formMeta.filter
|
||||||
|
params: defaults
|
||||||
|
isDisabled: ticket.editable()
|
||||||
|
#bookmarkable: true
|
||||||
|
)
|
||||||
|
|
||||||
@markForm(true)
|
@markForm(true)
|
||||||
|
|
||||||
|
|
|
@ -964,8 +964,8 @@ class App.Utils
|
||||||
senders = App.Utils.parseAddressListLocal(article.from)
|
senders = App.Utils.parseAddressListLocal(article.from)
|
||||||
if senders
|
if senders
|
||||||
for sender in senders
|
for sender in senders
|
||||||
if sender && sender.address && sender.address.match('@')
|
if sender && sender.match('@')
|
||||||
senderIsLocal = isLocalAddress(sender.address)
|
senderIsLocal = isLocalAddress(sender)
|
||||||
|
|
||||||
# check if article recipient is local
|
# check if article recipient is local
|
||||||
recipientIsLocal = false
|
recipientIsLocal = false
|
||||||
|
|
|
@ -7,6 +7,7 @@ class TicketsController < ApplicationController
|
||||||
include TicketStats
|
include TicketStats
|
||||||
|
|
||||||
prepend_before_action :authentication_check
|
prepend_before_action :authentication_check
|
||||||
|
before_action :follow_up_possible_check, only: :update
|
||||||
|
|
||||||
# GET /api/v1/tickets
|
# GET /api/v1/tickets
|
||||||
def index
|
def index
|
||||||
|
@ -124,7 +125,7 @@ class TicketsController < ApplicationController
|
||||||
if !local_customer && clean_customer[:id].present?
|
if !local_customer && clean_customer[:id].present?
|
||||||
local_customer = User.find_by(id: clean_customer[:id])
|
local_customer = User.find_by(id: clean_customer[:id])
|
||||||
end
|
end
|
||||||
if clean_customer[:email].present?
|
if !local_customer && clean_customer[:email].present?
|
||||||
local_customer = User.find_by(email: clean_customer[:email].downcase)
|
local_customer = User.find_by(email: clean_customer[:email].downcase)
|
||||||
end
|
end
|
||||||
if !local_customer && clean_customer[:login].present?
|
if !local_customer && clean_customer[:login].present?
|
||||||
|
@ -599,6 +600,14 @@ class TicketsController < ApplicationController
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def follow_up_possible_check
|
||||||
|
ticket = Ticket.find(params[:id])
|
||||||
|
|
||||||
|
return true if ticket.group.follow_up_possible != 'new_ticket' # check if the setting for follow_up_possible is disabled
|
||||||
|
return true if ticket.state.name != 'closed' # check if the ticket state is already closed
|
||||||
|
raise Exceptions::UnprocessableEntity, 'Cannot follow up on a closed ticket. Please create a new ticket.'
|
||||||
|
end
|
||||||
|
|
||||||
def ticket_all(ticket)
|
def ticket_all(ticket)
|
||||||
|
|
||||||
# get attributes to update
|
# get attributes to update
|
||||||
|
|
|
@ -48,6 +48,7 @@ class TicketsControllerTest < ActionDispatch::IntegrationTest
|
||||||
roles: roles,
|
roles: roles,
|
||||||
)
|
)
|
||||||
UserInfo.current_user_id = nil
|
UserInfo.current_user_id = nil
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test '01.01 ticket create with agent - missing group' do
|
test '01.01 ticket create with agent - missing group' do
|
||||||
|
@ -1733,4 +1734,76 @@ AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test '06.01 - ticket with follow up possible set to new_ticket' do
|
||||||
|
group = Group.create_or_update(
|
||||||
|
name: "GroupWithNoFollowUp-#{rand(9_999_999_999)}",
|
||||||
|
active: true,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
follow_up_possible: 'new_ticket' # disable follow up possible
|
||||||
|
)
|
||||||
|
|
||||||
|
ticket = Ticket.create!(
|
||||||
|
title: 'ticket with wrong ticket id',
|
||||||
|
group_id: group.id,
|
||||||
|
customer_id: @customer_without_org.id,
|
||||||
|
state: Ticket::State.lookup(name: 'closed'), # set the ticket to closed
|
||||||
|
priority: Ticket::Priority.lookup(name: '2 normal'),
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
state = Ticket::State.find_by(name: 'open') # try to open a ticket from a closed state
|
||||||
|
|
||||||
|
# customer
|
||||||
|
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-customer1@example.com', 'customer1pw')
|
||||||
|
params = {
|
||||||
|
state_id: state.id, # set the state id
|
||||||
|
}
|
||||||
|
|
||||||
|
put "/api/v1/tickets/#{ticket.id}", params: params.to_json, headers: @headers.merge('Authorization' => credentials)
|
||||||
|
assert_response(422)
|
||||||
|
result = JSON.parse(@response.body)
|
||||||
|
assert_equal(Hash, result.class)
|
||||||
|
assert_equal('Cannot follow up on a closed ticket. Please create a new ticket.', result['error'])
|
||||||
|
|
||||||
|
ticket = Ticket.create!(
|
||||||
|
title: 'ticket with wrong ticket id',
|
||||||
|
group_id: group.id,
|
||||||
|
customer_id: @customer_without_org.id,
|
||||||
|
state: Ticket::State.lookup(name: 'closed'), # set the ticket to closed
|
||||||
|
priority: Ticket::Priority.lookup(name: '2 normal'),
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
# admin
|
||||||
|
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-admin@example.com', 'adminpw')
|
||||||
|
|
||||||
|
put "/api/v1/tickets/#{ticket.id}", params: params.to_json, headers: @headers.merge('Authorization' => credentials)
|
||||||
|
assert_response(422)
|
||||||
|
result = JSON.parse(@response.body)
|
||||||
|
assert_equal(Hash, result.class)
|
||||||
|
assert_equal('Cannot follow up on a closed ticket. Please create a new ticket.', result['error'])
|
||||||
|
|
||||||
|
ticket = Ticket.create!(
|
||||||
|
title: 'ticket with wrong ticket id',
|
||||||
|
group_id: group.id,
|
||||||
|
customer_id: @customer_without_org.id,
|
||||||
|
state: Ticket::State.lookup(name: 'closed'), # set the ticket to closed
|
||||||
|
priority: Ticket::Priority.lookup(name: '2 normal'),
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
# agent
|
||||||
|
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw')
|
||||||
|
|
||||||
|
put "/api/v1/tickets/#{ticket.id}", params: params.to_json, headers: @headers.merge('Authorization' => credentials)
|
||||||
|
assert_response(422)
|
||||||
|
result = JSON.parse(@response.body)
|
||||||
|
assert_equal(Hash, result.class)
|
||||||
|
assert_equal('Cannot follow up on a closed ticket. Please create a new ticket.', result['error'])
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue