# --
# Copyright (C) 2001-2016 OTRS AG, http://otrs.com/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (AGPL). If you
# did not receive this file, see http://www.gnu.org/licenses/agpl.txt.
# --
package Kernel::Modules::AgentTicketProcess;
## nofilter(TidyAll::Plugin::OTRS::Perl::DBObject)
use strict;
use warnings;
use Kernel::Language qw(Translatable);
use Kernel::System::VariableCheck qw(:all);
our $ObjectManagerDisabled = 1;
sub new {
my ( $Type, %Param ) = @_;
# allocate new hash for object
my $Self = {%Param};
bless $Self, $Type;
# global config hash for id dissolution
$Self->{NameToID} = {
Title => 'Title',
State => 'StateID',
StateID => 'StateID',
Priority => 'PriorityID',
PriorityID => 'PriorityID',
Lock => 'LockID',
LockID => 'LockID',
Queue => 'QueueID',
QueueID => 'QueueID',
Customer => 'CustomerID',
CustomerID => 'CustomerID',
CustomerNo => 'CustomerID',
CustomerUserID => 'CustomerUserID',
Owner => 'OwnerID',
OwnerID => 'OwnerID',
Type => 'TypeID',
TypeID => 'TypeID',
SLA => 'SLAID',
SLAID => 'SLAID',
Service => 'ServiceID',
ServiceID => 'ServiceID',
Responsible => 'ResponsibleID',
ResponsibleID => 'ResponsibleID',
PendingTime => 'PendingTime',
Article => 'Article',
};
return $Self;
}
sub Run {
my ( $Self, %Param ) = @_;
# get param object
my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request');
my $TicketID = $ParamObject->GetParam( Param => 'TicketID' );
my $ActivityDialogEntityID = $ParamObject->GetParam( Param => 'ActivityDialogEntityID' );
my $ActivityDialogHashRef;
# get needed objects
my $ActivityDialogObject = $Kernel::OM->Get('Kernel::System::ProcessManagement::ActivityDialog');
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
if ($TicketID) {
# check if there is a configured required permission
# for the ActivityDialog (if there is one)
my $ActivityDialogPermission = 'rw';
if ($ActivityDialogEntityID) {
$ActivityDialogHashRef = $ActivityDialogObject->ActivityDialogGet(
ActivityDialogEntityID => $ActivityDialogEntityID,
Interface => 'AgentInterface',
);
if ( !IsHashRefWithData($ActivityDialogHashRef) ) {
return $LayoutObject->ErrorScreen(
Message => $LayoutObject->{LanguageObject}->Translate(
'Couldn\'t get ActivityDialogEntityID "%s"!',
$ActivityDialogEntityID,
),
Comment => Translatable('Please contact the admin.'),
);
}
if ( $ActivityDialogHashRef->{Permission} ) {
$ActivityDialogPermission = $ActivityDialogHashRef->{Permission};
}
}
# check permissions
my $Access = $TicketObject->TicketPermission(
Type => $ActivityDialogPermission,
TicketID => $Self->{TicketID},
UserID => $Self->{UserID}
);
# error screen, don't show ticket
if ( !$Access ) {
return $LayoutObject->NoPermission(
Message =>
$LayoutObject->{LanguageObject}->Translate( 'You need %s permissions!', $ActivityDialogPermission ),
WithHeader => 'yes',
);
}
# get ACL restrictions
my %PossibleActions = ( 1 => $Self->{Action} );
my $ACL = $TicketObject->TicketAcl(
Data => \%PossibleActions,
Action => $Self->{Action},
TicketID => $Self->{TicketID},
ReturnType => 'Action',
ReturnSubType => '-',
UserID => $Self->{UserID},
);
my %AclAction = $TicketObject->TicketAclActionData();
# check if ACL restrictions exist
if ( $ACL || IsHashRefWithData( \%AclAction ) ) {
my %AclActionLookup = reverse %AclAction;
# show error screen if ACL prohibits this action
if ( !$AclActionLookup{ $Self->{Action} } ) {
return $LayoutObject->NoPermission( WithHeader => 'yes' );
}
}
if ( IsHashRefWithData($ActivityDialogHashRef) ) {
# check if it's already locked by somebody else
if ( $ActivityDialogHashRef->{RequiredLock} ) {
if ( $TicketObject->TicketLockGet( TicketID => $TicketID ) ) {
my $AccessOk = $TicketObject->OwnerCheck(
TicketID => $TicketID,
OwnerID => $Self->{UserID},
);
if ( !$AccessOk ) {
my $Output = $LayoutObject->Header(
Type => 'Small',
);
$Output .= $LayoutObject->Warning(
Message => Translatable('Sorry, you need to be the ticket owner to perform this action.'),
Comment => Translatable('Please change the owner first.'),
);
$Output .= $LayoutObject->Footer(
Type => 'Small',
);
return $Output;
}
}
else {
# set lock
$TicketObject->TicketLockSet(
TicketID => $TicketID,
Lock => 'lock',
UserID => $Self->{UserID},
);
# set user id
$TicketObject->TicketOwnerSet(
TicketID => $TicketID,
UserID => $Self->{UserID},
NewUserID => $Self->{UserID},
);
# reload the parent window to show the updated lock state
$Param{ParentReload} = 1;
# show lock state link
$Param{RenderLocked} = 1;
my $TicketNumber = $TicketObject->TicketNumberLookup(
TicketID => $TicketID,
UserID => $Self->{UserID},
);
# notify the agent that the ticket was locked
push @{ $Param{Notify} }, "$TicketNumber: "
. $LayoutObject->{LanguageObject}->Translate("Ticket locked.");
}
}
my $PossibleActivityDialogs = { 1 => $ActivityDialogEntityID };
# get ACL restrictions
my $ACL = $TicketObject->TicketAcl(
Data => $PossibleActivityDialogs,
ActivityDialogEntityID => $ActivityDialogEntityID,
TicketID => $TicketID,
ReturnType => 'ActivityDialog',
ReturnSubType => '-',
UserID => $Self->{UserID},
);
if ($ACL) {
%{$PossibleActivityDialogs} = $TicketObject->TicketAclData();
}
# check if ACL resctictions exist
if ( !IsHashRefWithData($PossibleActivityDialogs) )
{
return $LayoutObject->NoPermission( WithHeader => 'yes' );
}
}
}
# list only Active processes by default
my @ProcessStates = ('Active');
# set IsMainWindow, IsAjaxRequest, IsProcessEnroll for proper error responses, screen display
# and process list
$Self->{IsMainWindow} = $ParamObject->GetParam( Param => 'IsMainWindow' ) || '';
$Self->{IsAjaxRequest} = $ParamObject->GetParam( Param => 'IsAjaxRequest' ) || '';
$Self->{IsProcessEnroll} = $ParamObject->GetParam( Param => 'IsProcessEnroll' ) || '';
# fetch also FadeAway processes to continue working with existing tickets, but not to start new
# ones
if ( !$Self->{IsMainWindow} && $Self->{Subaction} ) {
push @ProcessStates, 'FadeAway'
}
# create process object
$Kernel::OM->ObjectParamAdd(
'Kernel::System::ProcessManagement::Process' => {
ActivityObject => $Kernel::OM->Get('Kernel::System::ProcessManagement::Activity'),
ActivityDialogObject => $ActivityDialogObject,
TransitionObject => $Kernel::OM->Get('Kernel::System::ProcessManagement::Transition'),
TransitionActionObject => $Kernel::OM->Get('Kernel::System::ProcessManagement::TransitionAction'),
}
);
my $ProcessObject = $Kernel::OM->Get('Kernel::System::ProcessManagement::Process');
# get processes
my $ProcessList = $ProcessObject->ProcessList(
ProcessState => \@ProcessStates,
Interface => ['AgentInterface'],
);
# also get the list of processes initiated by customers, as an activity dialog might be
# configured for the agent interface
my $FollowupProcessList = $ProcessObject->ProcessList(
ProcessState => \@ProcessStates,
Interface => [ 'AgentInterface', 'CustomerInterface' ],
);
my $ProcessEntityID = $ParamObject->GetParam( Param => 'ProcessEntityID' );
if ( !IsHashRefWithData($ProcessList) && !IsHashRefWithData($FollowupProcessList) ) {
return $LayoutObject->ErrorScreen(
Message => Translatable('No Process configured!'),
Comment => Translatable('Please contact the admin.'),
);
}
# prepare process list for ACLs, use only entities instead of names, convert from
# P1 => Name to P1 => P1. As ACLs should work only against entities
my %ProcessListACL = map { $_ => $_ } sort keys %{$ProcessList};
# validate the ProcessList with stored ACLs
my $ACL = $TicketObject->TicketAcl(
ReturnType => 'Process',
ReturnSubType => '-',
Data => \%ProcessListACL,
UserID => $Self->{UserID},
);
if ( IsHashRefWithData($ProcessList) && $ACL ) {
# get ACL results
my %ACLData = $TicketObject->TicketAclData();
# recover process names
my %ReducedProcessList = map { $_ => $ProcessList->{$_} } sort keys %ACLData;
# replace original process list with the reduced one
$ProcessList = \%ReducedProcessList;
}
# get form id
$Self->{FormID} = $ParamObject->GetParam( Param => 'FormID' );
# create form id
if ( !$Self->{FormID} ) {
$Self->{FormID} = $Kernel::OM->Get('Kernel::System::Web::UploadCache')->FormIDCreate();
}
# if we have no subaction display the process list to start a new one
if ( !$Self->{Subaction} ) {
# to display the process list is mandatory to have processes that agent can start
if ( !IsHashRefWithData($ProcessList) ) {
return $LayoutObject->ErrorScreen(
Message => Translatable('No Process configured!'),
Comment => Translatable('Please contact the admin.'),
);
}
# get process id (if any, a process should be pre-selected)
$Param{ProcessID} = $ParamObject->GetParam( Param => 'ID' );
if ( $Param{ProcessID} ) {
$Param{PreSelectProcess} = 1;
}
return $Self->_DisplayProcessList(
%Param,
ProcessList => $ProcessList,
ProcessEntityID => $ProcessEntityID,
TicketID => $TicketID,
);
}
# check if the selected process from the list is valid, prevent tamper with process selection
# list (not existing, invalid an fade away processes must not be able to start a new process
# ticket)
elsif (
$Self->{Subaction} eq 'DisplayActivityDialogAJAX'
&& !$ProcessList->{$ProcessEntityID}
&& $Self->{IsMainWindow}
)
{
# translate the error message (as it will be injected in the HTML)
my $ErrorMessage = $LayoutObject->{LanguageObject}->Translate("The selected process is invalid!");
# return a predefined HTML structure as the AJAX call is expecting and HTML response
return $LayoutObject->Attachment(
ContentType => 'text/html; charset=' . $LayoutObject->{Charset},
Content => '
',
Type => 'inline',
NoCache => 1,
);
}
# if invalid process is detected on a ActivityDilog pop-up screen show an error message
elsif (
$Self->{Subaction} eq 'DisplayActivityDialog'
&& !$FollowupProcessList->{$ProcessEntityID}
&& !$Self->{IsMainWindow}
)
{
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate( 'Process %s is invalid!', $ProcessEntityID ),
Comment => Translatable('Please contact the admin.'),
);
}
# Get the necessary parameters
# collects a mixture of present values bottom to top:
# SysConfig DefaultValues, ActivityDialog DefaultValues, TicketValues, SubmittedValues
# including ActivityDialogEntityID and ProcessEntityID
# is used for:
# - Parameter checking before storing
# - will be used for ACL checking later on
my $GetParam = $Self->_GetParam(
ProcessEntityID => $ProcessEntityID,
);
if ( $Self->{Subaction} eq 'StoreActivityDialog' && $ProcessEntityID ) {
$LayoutObject->ChallengeTokenCheck();
return $Self->_StoreActivityDialog(
%Param,
ProcessName => $ProcessList->{$ProcessEntityID},
ProcessEntityID => $ProcessEntityID,
GetParam => $GetParam,
);
}
if ( $Self->{Subaction} eq 'DisplayActivityDialog' && $ProcessEntityID ) {
return $Self->_OutputActivityDialog(
%Param,
ProcessEntityID => $ProcessEntityID,
GetParam => $GetParam,
);
}
if ( $Self->{Subaction} eq 'DisplayActivityDialogAJAX' && $ProcessEntityID ) {
my $ActivityDialogHTML = $Self->_OutputActivityDialog(
%Param,
ProcessEntityID => $ProcessEntityID,
GetParam => $GetParam,
);
return $LayoutObject->Attachment(
ContentType => 'text/html; charset=' . $LayoutObject->{Charset},
Content => $ActivityDialogHTML,
Type => 'inline',
NoCache => 1,
);
}
elsif ( $Self->{Subaction} eq 'AJAXUpdate' ) {
return $Self->_RenderAjax(
%Param,
ProcessEntityID => $ProcessEntityID,
GetParam => $GetParam,
);
}
return $LayoutObject->ErrorScreen(
Message => Translatable('Subaction is invalid!'),
Comment => Translatable('Please contact the admin.'),
);
}
sub _RenderAjax {
# get layout object
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
# FatalError is safe because a JSON structure is expecting, then it will result into a
# communications error
my ( $Self, %Param ) = @_;
for my $Needed (qw(ProcessEntityID)) {
if ( !$Param{$Needed} ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', $Needed, '_RenderAjax' ),
);
}
}
my $ActivityDialogEntityID = $Param{GetParam}{ActivityDialogEntityID};
if ( !$ActivityDialogEntityID ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', 'ActivityDialogEntityID', '_RenderAjax' ),
);
}
my $ActivityDialog = $Kernel::OM->Get('Kernel::System::ProcessManagement::ActivityDialog')->ActivityDialogGet(
ActivityDialogEntityID => $ActivityDialogEntityID,
Interface => 'AgentInterface',
);
if ( !IsHashRefWithData($ActivityDialog) ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate(
'No ActivityDialog configured for %s in _RenderAjax!',
$ActivityDialogEntityID,
),
);
}
# get list type
my $TreeView = 0;
if ( $Kernel::OM->Get('Kernel::Config')->Get('Ticket::Frontend::ListType') eq 'tree' ) {
$TreeView = 1;
}
my %FieldsProcessed;
my @JSONCollector;
my $Services;
# All submitted DynamicFields
# get dynamic field values form http request
my %DynamicFieldValues;
my $DynamicField = $Kernel::OM->Get('Kernel::System::DynamicField')->DynamicFieldListGet(
Valid => 1,
ObjectType => 'Ticket',
);
# get needed object
my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request');
my $DynamicFieldBackendObject = $Kernel::OM->Get('Kernel::System::DynamicField::Backend');
# cycle trough the activated Dynamic Fields for this screen
DYNAMICFIELD:
for my $DynamicFieldConfig ( @{$DynamicField} ) {
next DYNAMICFIELD if !IsHashRefWithData($DynamicFieldConfig);
# extract the dynamic field value form the web request
$DynamicFieldValues{ $DynamicFieldConfig->{Name} } = $DynamicFieldBackendObject->EditFieldValueGet(
DynamicFieldConfig => $DynamicFieldConfig,
ParamObject => $ParamObject,
LayoutObject => $LayoutObject,
);
}
# convert dynamic field values into a structure for ACLs
my %DynamicFieldCheckParam;
DYNAMICFIELD:
for my $DynamicFieldItem ( sort keys %DynamicFieldValues ) {
next DYNAMICFIELD if !$DynamicFieldItem;
next DYNAMICFIELD if !$DynamicFieldValues{$DynamicFieldItem};
$DynamicFieldCheckParam{ 'DynamicField_' . $DynamicFieldItem } = $DynamicFieldValues{$DynamicFieldItem};
}
$Param{GetParam}->{DynamicField} = \%DynamicFieldCheckParam;
# Get the activity dialog's Submit Param's or Config Params
DIALOGFIELD:
for my $CurrentField ( @{ $ActivityDialog->{FieldOrder} } ) {
# Skip if we're working on a field that was already done with or without ID
if (
$Self->{NameToID}{$CurrentField}
&& $FieldsProcessed{ $Self->{NameToID}{$CurrentField} }
)
{
next DIALOGFIELD;
}
if ( $CurrentField =~ m{^DynamicField_(.*)}xms ) {
my $DynamicFieldName = $1;
my $DynamicFieldConfig = ( grep { $_->{Name} eq $DynamicFieldName } @{$DynamicField} )[0];
next DIALOGFIELD if !IsHashRefWithData($DynamicFieldConfig);
my $IsACLReducible = $DynamicFieldBackendObject->HasBehavior(
DynamicFieldConfig => $DynamicFieldConfig,
Behavior => 'IsACLReducible',
);
next DIALOGFIELD if !$IsACLReducible;
my $PossibleValues = $DynamicFieldBackendObject->PossibleValuesGet(
DynamicFieldConfig => $DynamicFieldConfig,
);
# convert possible values key => value to key => key for ACLs using a Hash slice
my %AclData = %{$PossibleValues};
@AclData{ keys %AclData } = keys %AclData;
# get ticket object
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
# set possible values filter from ACLs
my $ACL = $TicketObject->TicketAcl(
%{ $Param{GetParam} },
ReturnType => 'Ticket',
ReturnSubType => 'DynamicField_' . $DynamicFieldConfig->{Name},
Data => \%AclData,
UserID => $Self->{UserID},
);
if ($ACL) {
my %Filter = $TicketObject->TicketAclData();
# convert Filer key => key back to key => value using map
%{$PossibleValues} = map { $_ => $PossibleValues->{$_} } keys %Filter;
}
my $DataValues = $DynamicFieldBackendObject->BuildSelectionDataGet(
DynamicFieldConfig => $DynamicFieldConfig,
PossibleValues => $PossibleValues,
Value => $DynamicFieldValues{ $DynamicFieldConfig->{Name} },
) || $PossibleValues;
# add dynamic field to the JSONCollector
push(
@JSONCollector,
{
Name => 'DynamicField_' . $DynamicFieldConfig->{Name},
Data => $DataValues,
SelectedID => $DynamicFieldValues{ $DynamicFieldConfig->{Name} },
Translation => $DynamicFieldConfig->{Config}->{TranslatableValues} || 0,
Max => 100,
}
);
}
elsif ( $Self->{NameToID}{$CurrentField} eq 'OwnerID' ) {
next DIALOGFIELD if $FieldsProcessed{ $Self->{NameToID}{$CurrentField} };
my $Data = $Self->_GetOwners(
%{ $Param{GetParam} },
);
my $PossibleNone = 1;
if ( $ActivityDialog->{Fields}->{$CurrentField}->{Display} == 2 ) {
$PossibleNone = 0;
}
# add Owner to the JSONCollector
push(
@JSONCollector,
{
Name => $Self->{NameToID}{$CurrentField},
Data => $Data,
SelectedID => $Param{GetParam}{ $Self->{NameToID}{$CurrentField} },
PossibleNone => $PossibleNone,
Translation => 0,
Max => 100,
},
);
$FieldsProcessed{ $Self->{NameToID}{$CurrentField} } = 1;
}
elsif ( $Self->{NameToID}{$CurrentField} eq 'ResponsibleID' ) {
next DIALOGFIELD if $FieldsProcessed{ $Self->{NameToID}{$CurrentField} };
my $Data = $Self->_GetResponsibles(
%{ $Param{GetParam} },
);
my $PossibleNone = 1;
if ( $ActivityDialog->{Fields}->{$CurrentField}->{Display} == 2 ) {
$PossibleNone = 0;
}
# add Responsible to the JSONCollector
push(
@JSONCollector,
{
Name => $Self->{NameToID}{$CurrentField},
Data => $Data,
SelectedID => $Param{GetParam}{ $Self->{NameToID}{$CurrentField} },
PossibleNone => $PossibleNone,
Translation => 0,
Max => 100,
},
);
$FieldsProcessed{ $Self->{NameToID}{$CurrentField} } = 1;
}
elsif ( $Self->{NameToID}{$CurrentField} eq 'QueueID' ) {
next DIALOGFIELD if $FieldsProcessed{ $Self->{NameToID}{$CurrentField} };
my $Data = $Self->_GetQueues(
%{ $Param{GetParam} },
);
# add Queue to the JSONCollector
push(
@JSONCollector,
{
Name => $Self->{NameToID}{$CurrentField},
Data => $Data,
SelectedID => $Param{GetParam}{ $Self->{NameToID}{$CurrentField} },
PossibleNone => 1,
Translation => 0,
TreeView => $TreeView,
Max => 100,
},
);
$FieldsProcessed{ $Self->{NameToID}{$CurrentField} } = 1;
}
elsif ( $Self->{NameToID}{$CurrentField} eq 'StateID' ) {
next DIALOGFIELD if $FieldsProcessed{ $Self->{NameToID}{$CurrentField} };
my $Data = $Self->_GetStates(
%{ $Param{GetParam} },
);
# add State to the JSONCollector
push(
@JSONCollector,
{
Name => 'StateID',
Data => $Data,
SelectedID => $Param{GetParam}{ $Self->{NameToID}{$CurrentField} },
Translation => 1,
Max => 100,
},
);
$FieldsProcessed{ $Self->{NameToID}{$CurrentField} } = 1;
}
elsif ( $Self->{NameToID}{$CurrentField} eq 'PriorityID' ) {
next DIALOGFIELD if $FieldsProcessed{ $Self->{NameToID}{$CurrentField} };
my $Data = $Self->_GetPriorities(
%{ $Param{GetParam} },
);
# add Priority to the JSONCollector
push(
@JSONCollector,
{
Name => $Self->{NameToID}{$CurrentField},
Data => $Data,
SelectedID => $Param{GetParam}{ $Self->{NameToID}{$CurrentField} },
Translation => 1,
Max => 100,
},
);
$FieldsProcessed{ $Self->{NameToID}{$CurrentField} } = 1;
}
elsif ( $Self->{NameToID}{$CurrentField} eq 'ServiceID' ) {
next DIALOGFIELD if $FieldsProcessed{ $Self->{NameToID}{$CurrentField} };
my $Data = $Self->_GetServices(
%{ $Param{GetParam} },
);
$Services = $Data;
# add Service to the JSONCollector (Use ServiceID from web request)
push(
@JSONCollector,
{
Name => $Self->{NameToID}{$CurrentField},
Data => $Data,
SelectedID => $ParamObject->GetParam( Param => 'ServiceID' ) || '',
PossibleNone => 1,
Translation => 0,
TreeView => $TreeView,
Max => 100,
},
);
$FieldsProcessed{ $Self->{NameToID}{$CurrentField} } = 1;
}
elsif ( $Self->{NameToID}{$CurrentField} eq 'SLAID' ) {
next DIALOGFIELD if $FieldsProcessed{ $Self->{NameToID}{$CurrentField} };
# if SLA is render before service (by it order in the fields) it needs to create
# the service list
if ( !IsHashRefWithData($Services) ) {
$Services = $Self->_GetServices(
%{ $Param{GetParam} },
);
}
my $Data = $Self->_GetSLAs(
%{ $Param{GetParam} },
Services => $Services,
ServiceID => $ParamObject->GetParam( Param => 'ServiceID' ) || '',
);
# add SLA to the JSONCollector (Use SelectedID from web request)
push(
@JSONCollector,
{
Name => $Self->{NameToID}{$CurrentField},
Data => $Data,
SelectedID => $ParamObject->GetParam( Param => 'SLAID' ) || '',
PossibleNone => 1,
Translation => 0,
Max => 100,
},
);
$FieldsProcessed{ $Self->{NameToID}{$CurrentField} } = 1;
}
}
my $JSON = $LayoutObject->BuildSelectionJSON( [@JSONCollector] );
return $LayoutObject->Attachment(
ContentType => 'application/json; charset=' . $LayoutObject->{Charset},
Content => $JSON,
Type => 'inline',
NoCache => 1,
);
}
=cut
_GetParam()
returns the current data state of the submitted information
This contains the following data for the different callers:
Initial call with selected Process:
ProcessEntityID
ActivityDialogEntityID
DefaultValues for the configured Fields in that ActivityDialog
DefaultValues for the 4 required Fields Queue State Lock Priority
First Store call submitting an Activity Dialog:
ProcessEntityID
ActivityDialogEntityID
SubmittedValues for the current ActivityDialog
ActivityDialog DefaultValues for invisible fields of that ActivityDialog
DefaultValues for the 4 required Fields Queue State Lock Priority
if not configured in the ActivityDialog
ActivityDialog fillout request on existing Ticket:
ProcessEntityID
ActivityDialogEntityID
TicketValues
ActivityDialog store request or AjaxUpdate request on existing Tickets:
ProcessEntityID
ActivityDialogEntityID
TicketValues for all not-Submitted Values
Submitted Values
my $GetParam = _GetParam(
ProcessEntityID => $ProcessEntityID,
);
=cut
sub _GetParam {
my ( $Self, %Param ) = @_;
#my $IsAJAXUpdate = $Param{AJAX} || '';
# get layout object
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
for my $Needed (qw(ProcessEntityID)) {
if ( !$Param{$Needed} ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', $Needed, '_GetParam' ),
);
}
}
# get param object
my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request');
my %GetParam;
my %Ticket;
my $ProcessEntityID = $Param{ProcessEntityID};
my $TicketID = $ParamObject->GetParam( Param => 'TicketID' );
my $ActivityDialogEntityID = $ParamObject->GetParam(
Param => 'ActivityDialogEntityID',
);
my $ActivityEntityID;
my %ValuesGotten;
my $Value;
# get activity dialog object
my $ActivityDialogObject = $Kernel::OM->Get('Kernel::System::ProcessManagement::ActivityDialog');
# create process object
$Kernel::OM->ObjectParamAdd(
'Kernel::System::ProcessManagement::Process' => {
ActivityObject => $Kernel::OM->Get('Kernel::System::ProcessManagement::Activity'),
ActivityDialogObject => $ActivityDialogObject,
TransitionObject => $Kernel::OM->Get('Kernel::System::ProcessManagement::Transition'),
TransitionActionObject => $Kernel::OM->Get('Kernel::System::ProcessManagement::TransitionAction'),
}
);
my $ProcessObject = $Kernel::OM->Get('Kernel::System::ProcessManagement::Process');
# If we got no ActivityDialogEntityID and no TicketID
# we have to get the Processes' Startpoint
if ( !$ActivityDialogEntityID && ( !$TicketID || $Self->{IsProcessEnroll} ) ) {
my $ActivityActivityDialog = $ProcessObject->ProcessStartpointGet(
ProcessEntityID => $ProcessEntityID,
);
if (
!$ActivityActivityDialog->{ActivityDialog}
|| !$ActivityActivityDialog->{Activity}
)
{
my $Message = $LayoutObject->{LanguageObject}->Translate(
'Got no Start ActivityEntityID or Start ActivityDialogEntityID for Process: %s in _GetParam!',
$ProcessEntityID,
);
# does not show header and footer again
if ( $Self->{IsMainWindow} ) {
return $LayoutObject->Error(
Message => $Message,
);
}
$LayoutObject->FatalError(
Message => $Message,
);
}
$ActivityDialogEntityID = $ActivityActivityDialog->{ActivityDialog};
$ActivityEntityID = $ActivityActivityDialog->{Activity};
}
my $ActivityDialog = $ActivityDialogObject->ActivityDialogGet(
ActivityDialogEntityID => $ActivityDialogEntityID,
Interface => 'AgentInterface',
);
if ( !IsHashRefWithData($ActivityDialog) ) {
return $LayoutObject->ErrorScreen(
Message => $LayoutObject->{LanguageObject}->Translate(
'Couldn\'t get ActivityDialogEntityID "%s"!',
$ActivityDialogEntityID,
),
Comment => Translatable('Please contact the admin.'),
);
}
# get config object
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
# if there is a ticket then is not an AJAX request
if ($TicketID) {
%Ticket = $Kernel::OM->Get('Kernel::System::Ticket')->TicketGet(
TicketID => $TicketID,
UserID => $Self->{UserID},
DynamicFields => 1,
);
%GetParam = %Ticket;
if ( !IsHashRefWithData( \%GetParam ) ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate(
'Couldn\'t get Ticket for TicketID: %s in _GetParam!',
$TicketID,
),
);
}
if ( !$Self->{IsProcessEnroll} ) {
$ActivityEntityID = $Ticket{
'DynamicField_'
. $ConfigObject->Get("Process::DynamicFieldProcessManagementActivityID")
};
if ( !$ActivityEntityID ) {
$LayoutObject->FatalError(
Message => Translatable(
'Couldn\'t determine ActivityEntityID. DynamicField or Config isn\'t set properly!'
),
);
}
}
}
$GetParam{ActivityDialogEntityID} = $ActivityDialogEntityID;
$GetParam{ActivityEntityID} = $ActivityEntityID;
$GetParam{ProcessEntityID} = $ProcessEntityID;
# Get the activitydialogs's Submit Param's or Config Params
DIALOGFIELD:
for my $CurrentField ( @{ $ActivityDialog->{FieldOrder} } ) {
# Skip if we're working on a field that was already done with or without ID
if ( $Self->{NameToID}{$CurrentField} && $ValuesGotten{ $Self->{NameToID}{$CurrentField} } )
{
next DIALOGFIELD;
}
if ( $CurrentField =~ m{^DynamicField_(.*)}xms ) {
my $DynamicFieldName = $1;
my $DynamicField = $Kernel::OM->Get('Kernel::System::DynamicField')->DynamicFieldListGet(
Valid => 1,
ObjectType => 'Ticket',
);
# Get the Config of the current DynamicField (the first element of the grep result array)
my $DynamicFieldConfig = ( grep { $_->{Name} eq $DynamicFieldName } @{$DynamicField} )[0];
if ( !IsHashRefWithData($DynamicFieldConfig) ) {
my $Message = $LayoutObject->{LanguageObject}->Translate(
'DynamicFieldConfig missing for field: %s, or is not a Ticket Dynamic Field!',
$DynamicFieldName,
);
# log error but does not stop the execution as it could be an old Article
# DynamicField, see bug#11666
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => $Message,
);
next DIALOGFIELD;
}
# Get DynamicField Values
$Value = $Kernel::OM->Get('Kernel::System::DynamicField::Backend')->EditFieldValueGet(
DynamicFieldConfig => $DynamicFieldConfig,
ParamObject => $ParamObject,
LayoutObject => $LayoutObject,
);
# If we got a submitted param, take it and next out
if (
defined $Value
&& (
$Value eq ''
|| IsStringWithData($Value)
|| IsArrayRefWithData($Value)
|| IsHashRefWithData($Value)
)
)
{
$GetParam{$CurrentField} = $Value;
next DIALOGFIELD;
}
# If we didn't have a Param Value try the ticket Value
# next out if it was successful
if (
defined $Ticket{$CurrentField}
&& (
$Ticket{$CurrentField} eq ''
|| IsStringWithData( $Ticket{$CurrentField} )
|| IsArrayRefWithData( $Ticket{$CurrentField} )
|| IsHashRefWithData( $Ticket{$CurrentField} )
)
)
{
$GetParam{$CurrentField} = $Ticket{$CurrentField};
next DIALOGFIELD;
}
# If we had neighter submitted nor ticket param get the ActivityDialog's default Value
# next out if it was successful
$Value = $ActivityDialog->{Fields}{$CurrentField}{DefaultValue};
if ($Value) {
$GetParam{$CurrentField} = $Value;
next DIALOGFIELD;
}
# If we had no submitted, ticket or ActivityDialog default value
# use the DynamicField's default value and next out
$Value = $DynamicFieldConfig->{Config}{DefaultValue};
if ($Value) {
$GetParam{$CurrentField} = $Value;
next DIALOGFIELD;
}
# if all that failed then the field should not have a defined value otherwise
# if a value (even empty) is sent, fields like Date or DateTime will mark the field as
# used with the field display value, this could lead to unwanted field sets,
# see bug#9159
next DIALOGFIELD;
}
# get article fields
if ( $CurrentField eq 'Article' ) {
$GetParam{Subject} = $ParamObject->GetParam( Param => 'Subject' );
$GetParam{Body} = $ParamObject->GetParam( Param => 'Body' );
@{ $GetParam{InformUserID} } = $ParamObject->GetArray(
Param => 'InformUserID',
);
$ValuesGotten{Article} = 1 if ( $GetParam{Subject} && $GetParam{Body} );
$GetParam{TimeUnits} = $ParamObject->GetParam( Param => 'TimeUnits' );
}
if ( $CurrentField eq 'CustomerID' ) {
$GetParam{Customer} = $ParamObject->GetParam(
Param => 'SelectedCustomerUser',
) || '';
$GetParam{CustomerUserID} = $ParamObject->GetParam(
Param => 'SelectedCustomerUser',
) || '';
}
if ( $CurrentField eq 'PendingTime' ) {
my $Prefix = 'PendingTime';
# Ok, we need to try to find the target state now
my %StateData;
# get state object
my $StateObject = $Kernel::OM->Get('Kernel::System::State');
# Was something submitted from the GUI?
my $TargetStateID = $ParamObject->GetParam( Param => 'StateID' );
if ($TargetStateID) {
%StateData = $StateObject->StateGet(
ID => $TargetStateID,
);
}
# Fallback 1: default value of dialog field State
if ( !%StateData && $ActivityDialog->{Fields}{State}{DefaultValue} ) {
%StateData = $StateObject->StateGet(
Name => $ActivityDialog->{Fields}{State}{DefaultValue},
);
}
# Fallback 2: default value of dialog field StateID
if ( !%StateData && $ActivityDialog->{Fields}{StateID}{DefaultValue} ) {
%StateData = $StateObject->StateGet(
ID => $ActivityDialog->{Fields}{StateID}{DefaultValue},
);
}
# Fallback 3: existing ticket state
if ( !%StateData && %Ticket ) {
%StateData = $StateObject->StateGet(
ID => $Ticket{StateID},
);
}
# get pending time values
# depends on StateType containing '^pending'
if (
IsHashRefWithData( \%StateData )
&& $StateData{TypeName}
&& $StateData{TypeName} =~ /^pending/i
)
{
my %DateParam = ( Prefix => $Prefix );
# map the GetParam's Date Values to our DateParamHash
%DateParam = map {
( $Prefix . $_ )
=> $ParamObject->GetParam( Param => ( $Prefix . $_ ) )
}
qw(Year Month Day Hour Minute);
# if all values are present
if (
defined $DateParam{ $Prefix . 'Year' }
&& defined $DateParam{ $Prefix . 'Month' }
&& defined $DateParam{ $Prefix . 'Day' }
&& defined $DateParam{ $Prefix . 'Hour' }
&& defined $DateParam{ $Prefix . 'Minute' }
)
{
# recalculate time according to the user's timezone
%DateParam = $LayoutObject->TransformDateSelection(
%DateParam,
);
# reformat for storing (e.g. take out Prefix)
%{ $GetParam{$CurrentField} }
= map { $_ => $DateParam{ $Prefix . $_ } } qw(Year Month Day Hour Minute);
$ValuesGotten{PendingTime} = 1;
}
}
}
# Non DynamicFields
# 1. try to get the required param
my $Value = $ParamObject->GetParam( Param => $Self->{NameToID}{$CurrentField} );
if ($Value) {
# if we have an ID field make sure the value without ID won't be in the
# %GetParam Hash any more
if ( $Self->{NameToID}{$CurrentField} =~ m{(.*)ID$}xms ) {
$GetParam{$1} = undef;
}
$GetParam{ $Self->{NameToID}{$CurrentField} } = $Value;
$ValuesGotten{ $Self->{NameToID}{$CurrentField} } = 1;
next DIALOGFIELD;
}
# If we got ticket params, the GetParam Hash was already filled before the loop
# and we can next out
if ( $GetParam{ $Self->{NameToID}{$CurrentField} } ) {
$ValuesGotten{ $Self->{NameToID}{$CurrentField} } = 1;
next DIALOGFIELD;
}
# if no Submitted nore Ticket Param get ActivityDialog Config's Param
if ( $CurrentField ne 'CustomerID' ) {
$Value = $ActivityDialog->{Fields}{$CurrentField}{DefaultValue};
}
if ($Value) {
$ValuesGotten{ $Self->{NameToID}{$CurrentField} } = 1;
$GetParam{$CurrentField} = $Value;
next DIALOGFIELD;
}
}
REQUIREDFIELDLOOP:
for my $CurrentField (qw(Queue State Lock Priority)) {
$Value = undef;
if ( !$ValuesGotten{ $Self->{NameToID}{$CurrentField} } ) {
$Value = $ConfigObject->Get("Process::Default$CurrentField");
if ( !$Value ) {
my $Message = $LayoutObject->{LanguageObject}->Translate(
'Process::Default%s Config Value missing!',
$CurrentField,
);
# does not show header and footer again
if ( $Self->{IsMainWindow} ) {
return $LayoutObject->Error(
Message => $Message,
);
}
$LayoutObject->FatalError(
Message => $Message,
);
}
$GetParam{$CurrentField} = $Value;
$ValuesGotten{ $Self->{NameToID}{$CurrentField} } = 1;
}
}
# get also the IDs for the Required files (if they are not present)
if ( $GetParam{Queue} && !$GetParam{QueueID} ) {
$GetParam{QueueID} = $Kernel::OM->Get('Kernel::System::Queue')->QueueLookup( Queue => $GetParam{Queue} );
}
if ( $GetParam{State} && !$GetParam{StateID} ) {
$GetParam{StateID} = $Kernel::OM->Get('Kernel::System::State')->StateLookup( State => $GetParam{State} );
}
if ( $GetParam{Lock} && !$GetParam{LockID} ) {
$GetParam{LockID} = $Kernel::OM->Get('Kernel::System::Lock')->LockLookup( Lock => $GetParam{Lock} );
}
if ( $GetParam{Priority} && !$GetParam{PriorityID} ) {
$GetParam{PriorityID} = $Kernel::OM->Get('Kernel::System::Priority')->PriorityLookup(
Priority => $GetParam{Priority},
);
}
# and finally we'll have the special parameters:
$GetParam{ResponsibleAll} = $ParamObject->GetParam( Param => 'ResponsibleAll' );
$GetParam{OwnerAll} = $ParamObject->GetParam( Param => 'OwnerAll' );
$GetParam{ElementChanged} = $ParamObject->GetParam( Param => 'ElementChanged' );
return \%GetParam;
}
sub _OutputActivityDialog {
my ( $Self, %Param ) = @_;
my $TicketID = $Param{GetParam}{TicketID};
my $ActivityDialogEntityID = $Param{GetParam}{ActivityDialogEntityID};
# get layout object
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
# Check needed parameters:
# ProcessEntityID only
# TicketID ActivityDialogEntityID
if ( !$Param{ProcessEntityID} || ( !$TicketID && !$ActivityDialogEntityID ) ) {
my $Message = Translatable('Got no ProcessEntityID or TicketID and ActivityDialogEntityID!');
# does not show header and footer again
if ( $Self->{IsMainWindow} ) {
return $LayoutObject->Error(
Message => $Message,
);
}
$LayoutObject->FatalError(
Message => $Message,
);
}
my $ActivityActivityDialog;
my %Ticket;
my %Error = ();
my %ErrorMessages = ();
# If we had Errors, we got an Errorhash
%Error = %{ $Param{Error} } if ( IsHashRefWithData( $Param{Error} ) );
%ErrorMessages = %{ $Param{ErrorMessages} } if ( IsHashRefWithData( $Param{ErrorMessages} ) );
# get needed objects
my $ActivityObject = $Kernel::OM->Get('Kernel::System::ProcessManagement::Activity');
my $ActivityDialogObject = $Kernel::OM->Get('Kernel::System::ProcessManagement::ActivityDialog');
# create process object
$Kernel::OM->ObjectParamAdd(
'Kernel::System::ProcessManagement::Process' => {
ActivityObject => $ActivityObject,
ActivityDialogObject => $ActivityDialogObject,
TransitionObject => $Kernel::OM->Get('Kernel::System::ProcessManagement::Transition'),
TransitionActionObject => $Kernel::OM->Get('Kernel::System::ProcessManagement::TransitionAction'),
}
);
my $ProcessObject = $Kernel::OM->Get('Kernel::System::ProcessManagement::Process');
# get needed object
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
if ( !$TicketID || $Self->{IsProcessEnroll} ) {
$ActivityActivityDialog = $ProcessObject->ProcessStartpointGet(
ProcessEntityID => $Param{ProcessEntityID},
);
if ( !IsHashRefWithData($ActivityActivityDialog) ) {
my $Message = $LayoutObject->{LanguageObject}->Translate(
'Can\'t get StartActivityDialog and StartActivityDialog for the ProcessEntityID "%s"!',
$Param{ProcessEntityID},
);
# does not show header and footer again
if ( $Self->{IsMainWindow} ) {
return $LayoutObject->Error(
Message => $Message,
);
}
$LayoutObject->FatalError(
Message => $Message,
);
}
}
else {
# no AJAX update in this part
%Ticket = $TicketObject->TicketGet(
TicketID => $TicketID,
UserID => $Self->{UserID},
DynamicFields => 1,
);
if ( !IsHashRefWithData( \%Ticket ) ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate( 'Can\'t get Ticket "%s"!', $Param{TicketID} ),
);
}
my $DynamicFieldProcessID = 'DynamicField_'
. $ConfigObject->Get('Process::DynamicFieldProcessManagementProcessID');
my $DynamicFieldActivityID = 'DynamicField_'
. $ConfigObject->Get('Process::DynamicFieldProcessManagementActivityID');
if ( !$Ticket{$DynamicFieldProcessID} || !$Ticket{$DynamicFieldActivityID} ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate(
'Can\'t get ProcessEntityID or ActivityEntityID for Ticket "%s"!',
$Param{TicketID},
),
);
}
$ActivityActivityDialog = {
Activity => $Ticket{$DynamicFieldActivityID},
ActivityDialog => $ActivityDialogEntityID,
};
}
if ( !%Ticket && $Self->{IsProcessEnroll} ) {
%Ticket = $TicketObject->TicketGet(
TicketID => $TicketID,
UserID => $Self->{UserID},
DynamicFields => 1,
);
}
my $Activity = $ActivityObject->ActivityGet(
Interface => 'AgentInterface',
ActivityEntityID => $ActivityActivityDialog->{Activity}
);
if ( !$Activity ) {
my $Message = $LayoutObject->{LanguageObject}->Translate(
'Can\'t get Activity configuration for ActivityEntityID "%s"!',
$ActivityActivityDialog->{Activity},
);
# does not show header and footer again
if ( $Self->{IsMainWindow} ) {
return $LayoutObject->Error(
Message => $Message,
);
}
$LayoutObject->FatalError(
Message => $Message,
);
}
my $ActivityDialog = $ActivityDialogObject->ActivityDialogGet(
ActivityDialogEntityID => $ActivityActivityDialog->{ActivityDialog},
Interface => 'AgentInterface',
);
if ( !IsHashRefWithData($ActivityDialog) ) {
my $Message = $LayoutObject->{LanguageObject}->Translate(
'Can\'t get ActivityDialog configuration for ActivityDialogEntityID "%s"!',
$ActivityActivityDialog->{ActivityDialog},
);
# does not show header and footer again
if ( $Self->{IsMainWindow} ) {
return $LayoutObject->Error(
Message => $Message,
);
}
$LayoutObject->FatalError(
Message => $Message,
);
}
# grep out Overwrites if defined on the Activity
my @OverwriteActivityDialogNumber = grep {
ref $Activity->{ActivityDialog}{$_} eq 'HASH'
&& $Activity->{ActivityDialog}{$_}{ActivityDialogEntityID}
&& $Activity->{ActivityDialog}{$_}{ActivityDialogEntityID} eq
$ActivityActivityDialog->{ActivityDialog}
&& IsHashRefWithData( $Activity->{ActivityDialog}{$_}{Overwrite} )
} keys %{ $Activity->{ActivityDialog} };
# let the Overwrites Overwrite the ActivityDialog's Hashvalues
if ( $OverwriteActivityDialogNumber[0] ) {
%{$ActivityDialog} = (
%{$ActivityDialog},
%{ $Activity->{ActivityDialog}{ $OverwriteActivityDialogNumber[0] }{Overwrite} }
);
}
# Add PageHeader, Navbar, Formheader (Process/ActivityDialogHeader)
my $Output;
my $MainBoxClass;
if ( !$Self->{IsMainWindow} && !$Self->{IsProcessEnroll} ) {
$Output = $LayoutObject->Header(
Type => 'Small',
Value => $Ticket{Number},
);
# display given notify messages if this is not an ajax request
if ( IsArrayRefWithData( $Param{Notify} ) ) {
for my $NotifyString ( @{ $Param{Notify} } ) {
$Output .= $LayoutObject->Notify(
Data => $NotifyString,
);
}
}
$LayoutObject->Block(
Name => 'Header',
Data => {
Name =>
$LayoutObject->{LanguageObject}->Translate( $ActivityDialog->{Name} )
|| '',
}
);
}
elsif (
( $Self->{IsMainWindow} || $Self->{IsProcessEnroll} )
&& ( IsHashRefWithData( \%Error ) || $Param{IsUpload} )
)
{
# add rich text editor
if ( $LayoutObject->{BrowserRichText} ) {
# use height/width defined for this screen
$Param{RichTextHeight} = $Self->{Config}->{RichTextHeight} || 0;
$Param{RichTextWidth} = $Self->{Config}->{RichTextWidth} || 0;
$LayoutObject->Block(
Name => 'RichText',
Data => \%Param,
);
}
# display complete header and nav bar in ajax dialogs when there is a server error
# unless we are in a process enrollment (only when IsMainWindow is active)
my $Type = $Self->{IsMainWindow} ? '' : 'Small';
$Output = $LayoutObject->Header(
Type => $Type,
);
if ( $Self->{IsMainWindow} ) {
$Output .= $LayoutObject->NavigationBar();
}
# display original header texts (the process list maybe is not necessary)
$Output .= $LayoutObject->Output(
TemplateFile => 'AgentTicketProcess' . $Type,
Data => {
%Param,
FormID => $Self->{FormID},
IsProcessEnroll => $Self->{IsProcessEnroll},
},
);
# set the MainBox class to add correct borders to the screen
$MainBoxClass = 'MainBox';
}
# display process iformation
if ( $Self->{IsMainWindow} ) {
# get process data
my $Process = $ProcessObject->ProcessGet(
ProcessEntityID => $Param{ProcessEntityID},
);
# output main process information
$LayoutObject->Block(
Name => 'ProcessInfoSidebar',
Data => {
Process => $Process->{Name} || '',
Activity => $Activity->{Name} || '',
ActivityDialog => $ActivityDialog->{Name} || '',
},
);
# output activity dilalog short description (if any)
if (
defined $ActivityDialog->{DescriptionShort}
&& $ActivityDialog->{DescriptionShort} ne ''
)
{
$LayoutObject->Block(
Name => 'ProcessInfoSidebarActivityDialogDesc',
Data => {
ActivityDialogDescription => $ActivityDialog->{DescriptionShort} || '',
},
);
}
}
# show descriptions
if ( $ActivityDialog->{DescriptionShort} ) {
$LayoutObject->Block(
Name => 'DescriptionShort',
Data => {
DescriptionShort
=> $LayoutObject->{LanguageObject}->Translate(
$ActivityDialog->{DescriptionShort},
),
},
);
}
if ( $ActivityDialog->{DescriptionLong} ) {
$LayoutObject->Block(
Name => 'DescriptionLong',
Data => {
DescriptionLong
=> $LayoutObject->{LanguageObject}->Translate(
$ActivityDialog->{DescriptionLong},
),
},
);
}
# show close & cancel link if neccessary
if ( !$Self->{IsMainWindow} && !$Self->{IsProcessEnroll} ) {
if ( $Param{RenderLocked} ) {
$LayoutObject->Block(
Name => 'PropertiesLock',
Data => {
%Param,
TicketID => $TicketID,
},
);
}
else {
$LayoutObject->Block(
Name => 'CancelLink',
);
}
}
$Output .= $LayoutObject->Output(
TemplateFile => 'ProcessManagement/ActivityDialogHeader',
Data => {
FormName => 'ActivityDialogDialog' . $ActivityActivityDialog->{ActivityDialog},
FormID => $Self->{FormID},
Subaction => 'StoreActivityDialog',
TicketID => $Ticket{TicketID} || '',
ActivityDialogEntityID => $ActivityActivityDialog->{ActivityDialog},
ProcessEntityID => $Param{ProcessEntityID}
|| $Ticket{
'DynamicField_'
. $ConfigObject->Get(
'Process::DynamicFieldProcessManagementProcessID'
)
},
IsMainWindow => $Self->{IsMainWindow},
IsProcessEnroll => $Self->{IsProcessEnroll},
MainBoxClass => $MainBoxClass || '',
},
);
my %RenderedFields = ();
# get the list of fields where the AJAX loader icon should appear on AJAX updates triggered
# by ActivityDialog fields
my $AJAXUpdatableFields = $Self->_GetAJAXUpdatableFields(
ActivityDialogFields => $ActivityDialog->{Fields},
);
# Loop through ActivityDialogFields and render their output
DIALOGFIELD:
for my $CurrentField ( @{ $ActivityDialog->{FieldOrder} } ) {
if ( !IsHashRefWithData( $ActivityDialog->{Fields}{$CurrentField} ) ) {
my $Message = $LayoutObject->{LanguageObject}->Translate(
'Can\'t get data for Field "%s" of ActivityDialog "%s"!',
$CurrentField,
$ActivityActivityDialog->{ActivityDialog},
);
# does not show header and footer again
if ( $Self->{IsMainWindow} ) {
return $LayoutObject->Error(
Message => $Message,
);
}
$LayoutObject->FatalError(
Message => $Message,
);
}
my %FieldData = %{ $ActivityDialog->{Fields}{$CurrentField} };
# We render just visible ActivityDialogFields
next DIALOGFIELD if !$FieldData{Display};
# render DynamicFields
if ( $CurrentField =~ m{^DynamicField_(.*)}xms ) {
my $DynamicFieldName = $1;
my $Response = $Self->_RenderDynamicField(
ActivityDialogField => $ActivityDialog->{Fields}{$CurrentField},
FieldName => $DynamicFieldName,
DescriptionShort => $ActivityDialog->{Fields}{$CurrentField}{DescriptionShort},
DescriptionLong => $ActivityDialog->{Fields}{$CurrentField}{DescriptionLong},
Ticket => \%Ticket || {},
Error => \%Error || {},
ErrorMessages => \%ErrorMessages || {},
FormID => $Self->{FormID},
GetParam => $Param{GetParam},
AJAXUpdatableFields => $AJAXUpdatableFields,
);
if ( !$Response->{Success} ) {
# does not show header and footer again
if ( $Self->{IsMainWindow} ) {
return $LayoutObject->Error(
Message => $Response->{Message},
);
}
$LayoutObject->FatalError(
Message => $Response->{Message},
);
}
$Output .= $Response->{HTML};
$RenderedFields{$CurrentField} = 1;
}
# render State
elsif ( $Self->{NameToID}->{$CurrentField} eq 'StateID' )
{
# We don't render Fields twice,
# if there was already a Config without ID, skip this field
next DIALOGFIELD if $RenderedFields{ $Self->{NameToID}->{$CurrentField} };
my $Response = $Self->_RenderState(
ActivityDialogField => $ActivityDialog->{Fields}{$CurrentField},
FieldName => $CurrentField,
DescriptionShort => $ActivityDialog->{Fields}{$CurrentField}{DescriptionShort},
DescriptionLong => $ActivityDialog->{Fields}{$CurrentField}{DescriptionLong},
Ticket => \%Ticket || {},
Error => \%Error || {},
FormID => $Self->{FormID},
GetParam => $Param{GetParam},
AJAXUpdatableFields => $AJAXUpdatableFields,
);
if ( !$Response->{Success} ) {
# does not show header and footer again
if ( $Self->{IsMainWindow} ) {
return $LayoutObject->Error(
Message => $Response->{Message},
);
}
$LayoutObject->FatalError(
Message => $Response->{Message},
);
}
$Output .= $Response->{HTML};
$RenderedFields{ $Self->{NameToID}->{$CurrentField} } = 1;
}
# render Queue
elsif ( $Self->{NameToID}->{$CurrentField} eq 'QueueID' )
{
next DIALOGFIELD if $RenderedFields{ $Self->{NameToID}->{$CurrentField} };
my $Response = $Self->_RenderQueue(
ActivityDialogField => $ActivityDialog->{Fields}{$CurrentField},
FieldName => $CurrentField,
DescriptionShort => $ActivityDialog->{Fields}{$CurrentField}{DescriptionShort},
DescriptionLong => $ActivityDialog->{Fields}{$CurrentField}{DescriptionLong},
Ticket => \%Ticket || {},
Error => \%Error || {},
FormID => $Self->{FormID},
GetParam => $Param{GetParam},
AJAXUpdatableFields => $AJAXUpdatableFields,
);
if ( !$Response->{Success} ) {
# does not show header and footer again
if ( $Self->{IsMainWindow} ) {
return $LayoutObject->Error(
Message => $Response->{Message},
);
}
$LayoutObject->FatalError(
Message => $Response->{Message},
);
}
$Output .= $Response->{HTML};
$RenderedFields{ $Self->{NameToID}->{$CurrentField} } = 1;
}
# render Priority
elsif ( $Self->{NameToID}->{$CurrentField} eq 'PriorityID' )
{
next DIALOGFIELD if $RenderedFields{ $Self->{NameToID}->{$CurrentField} };
my $Response = $Self->_RenderPriority(
ActivityDialogField => $ActivityDialog->{Fields}{$CurrentField},
FieldName => $CurrentField,
DescriptionShort => $ActivityDialog->{Fields}{$CurrentField}{DescriptionShort},
DescriptionLong => $ActivityDialog->{Fields}{$CurrentField}{DescriptionLong},
Ticket => \%Ticket || {},
Error => \%Error || {},
FormID => $Self->{FormID},
GetParam => $Param{GetParam},
AJAXUpdatableFields => $AJAXUpdatableFields,
);
if ( !$Response->{Success} ) {
# does not show header and footer again
if ( $Self->{IsMainWindow} ) {
return $LayoutObject->Error(
Message => $Response->{Message},
);
}
$LayoutObject->FatalError(
Message => $Response->{Message},
);
}
$Output .= $Response->{HTML};
$RenderedFields{ $Self->{NameToID}->{$CurrentField} } = 1;
}
# render Lock
elsif ( $Self->{NameToID}->{$CurrentField} eq 'LockID' ) {
next DIALOGFIELD if $RenderedFields{ $Self->{NameToID}->{$CurrentField} };
my $Response = $Self->_RenderLock(
ActivityDialogField => $ActivityDialog->{Fields}{$CurrentField},
FieldName => $CurrentField,
DescriptionShort => $ActivityDialog->{Fields}{$CurrentField}{DescriptionShort},
DescriptionLong => $ActivityDialog->{Fields}{$CurrentField}{DescriptionLong},
Ticket => \%Ticket || {},
Error => \%Error || {},
FormID => $Self->{FormID},
GetParam => $Param{GetParam},
AJAXUpdatableFields => $AJAXUpdatableFields,
);
if ( !$Response->{Success} ) {
# does not show header and footer again
if ( $Self->{IsMainWindow} ) {
return $LayoutObject->Error(
Message => $Response->{Message},
);
}
$LayoutObject->FatalError(
Message => $Response->{Message},
);
}
$Output .= $Response->{HTML};
$RenderedFields{ $Self->{NameToID}->{$CurrentField} } = 1;
}
# render Service
elsif ( $Self->{NameToID}->{$CurrentField} eq 'ServiceID' ) {
next DIALOGFIELD if $RenderedFields{ $Self->{NameToID}->{$CurrentField} };
my $Response = $Self->_RenderService(
ActivityDialogField => $ActivityDialog->{Fields}{$CurrentField},
FieldName => $CurrentField,
DescriptionShort => $ActivityDialog->{Fields}{$CurrentField}{DescriptionShort},
DescriptionLong => $ActivityDialog->{Fields}{$CurrentField}{DescriptionLong},
Ticket => \%Ticket || {},
Error => \%Error || {},
FormID => $Self->{FormID},
GetParam => $Param{GetParam},
AJAXUpdatableFields => $AJAXUpdatableFields,
);
if ( !$Response->{Success} ) {
# does not show header and footer again
if ( $Self->{IsMainWindow} ) {
return $LayoutObject->Error(
Message => $Response->{Message},
);
}
$LayoutObject->FatalError(
Message => $Response->{Message},
);
}
$Output .= $Response->{HTML};
$RenderedFields{$CurrentField} = 1;
}
# render SLA
elsif ( $Self->{NameToID}->{$CurrentField} eq 'SLAID' ) {
next DIALOGFIELD if $RenderedFields{ $Self->{NameToID}->{$CurrentField} };
my $Response = $Self->_RenderSLA(
ActivityDialogField => $ActivityDialog->{Fields}{$CurrentField},
FieldName => $CurrentField,
DescriptionShort => $ActivityDialog->{Fields}{$CurrentField}{DescriptionShort},
DescriptionLong => $ActivityDialog->{Fields}{$CurrentField}{DescriptionLong},
Ticket => \%Ticket || {},
Error => \%Error || {},
FormID => $Self->{FormID},
GetParam => $Param{GetParam},
AJAXUpdatableFields => $AJAXUpdatableFields,
);
if ( !$Response->{Success} ) {
# does not show header and footer again
if ( $Self->{IsMainWindow} ) {
return $LayoutObject->Error(
Message => $Response->{Message},
);
}
$LayoutObject->FatalError(
Message => $Response->{Message},
);
}
$Output .= $Response->{HTML};
$RenderedFields{ $Self->{NameToID}->{$CurrentField} } = 1;
}
# render Owner
elsif ( $Self->{NameToID}->{$CurrentField} eq 'OwnerID' ) {
next DIALOGFIELD if $RenderedFields{ $Self->{NameToID}->{$CurrentField} };
my $Response = $Self->_RenderOwner(
ActivityDialogField => $ActivityDialog->{Fields}{$CurrentField},
FieldName => $CurrentField,
DescriptionShort => $ActivityDialog->{Fields}{$CurrentField}{DescriptionShort},
DescriptionLong => $ActivityDialog->{Fields}{$CurrentField}{DescriptionLong},
Ticket => \%Ticket || {},
Error => \%Error || {},
FormID => $Self->{FormID},
GetParam => $Param{GetParam},
AJAXUpdatableFields => $AJAXUpdatableFields,
);
if ( !$Response->{Success} ) {
# does not show header and footer again
if ( $Self->{IsMainWindow} ) {
return $LayoutObject->Error(
Message => $Response->{Message},
);
}
$LayoutObject->FatalError(
Message => $Response->{Message},
);
}
$Output .= $Response->{HTML};
$RenderedFields{ $Self->{NameToID}->{$CurrentField} } = 1;
}
# render responsible
elsif ( $Self->{NameToID}->{$CurrentField} eq 'ResponsibleID' ) {
next DIALOGFIELD if $RenderedFields{ $Self->{NameToID}->{$CurrentField} };
my $Response = $Self->_RenderResponsible(
ActivityDialogField => $ActivityDialog->{Fields}{$CurrentField},
FieldName => $CurrentField,
DescriptionShort => $ActivityDialog->{Fields}{$CurrentField}{DescriptionShort},
DescriptionLong => $ActivityDialog->{Fields}{$CurrentField}{DescriptionLong},
Ticket => \%Ticket || {},
Error => \%Error || {},
FormID => $Self->{FormID},
GetParam => $Param{GetParam},
AJAXUpdatableFields => $AJAXUpdatableFields,
);
if ( !$Response->{Success} ) {
# does not show header and footer again
if ( $Self->{IsMainWindow} ) {
return $LayoutObject->Error(
Message => $Response->{Message},
);
}
$LayoutObject->FatalError(
Message => $Response->{Message},
);
}
$Output .= $Response->{HTML};
$RenderedFields{ $Self->{NameToID}->{$CurrentField} } = 1;
}
# render CustomerID
elsif ( $Self->{NameToID}->{$CurrentField} eq 'CustomerID' ) {
next DIALOGFIELD if $RenderedFields{ $Self->{NameToID}->{$CurrentField} };
my $Response = $Self->_RenderCustomer(
ActivityDialogField => $ActivityDialog->{Fields}{$CurrentField},
FieldName => $CurrentField,
DescriptionShort => $ActivityDialog->{Fields}{$CurrentField}{DescriptionShort},
DescriptionLong => $ActivityDialog->{Fields}{$CurrentField}{DescriptionLong},
Ticket => \%Ticket || {},
Error => \%Error || {},
FormID => $Self->{FormID},
GetParam => $Param{GetParam},
AJAXUpdatableFields => $AJAXUpdatableFields,
);
if ( !$Response->{Success} ) {
# does not show header and footer again
if ( $Self->{IsMainWindow} ) {
return $LayoutObject->Error(
Message => $Response->{Message},
);
}
$LayoutObject->FatalError(
Message => $Response->{Message},
);
}
$Output .= $Response->{HTML};
$RenderedFields{ $Self->{NameToID}->{$CurrentField} } = 1;
}
elsif ( $CurrentField eq 'PendingTime' ) {
# PendingTime is just useful if we have State or StateID
if ( !grep {m{^(StateID|State)$}xms} @{ $ActivityDialog->{FieldOrder} } ) {
my $Message = $LayoutObject->{LanguageObject}->Translate(
'PendingTime can just be used if State or StateID is configured for the same ActivityDialog. ActivityDialog: %s!',
$ActivityActivityDialog->{ActivityDialog},
);
# does not show header and footer again
if ( $Self->{IsMainWindow} ) {
return $LayoutObject->Error(
Message => $Message,
);
}
$LayoutObject->FatalError(
Message => $Message,
);
}
next DIALOGFIELD if $RenderedFields{ $Self->{NameToID}->{$CurrentField} };
my $Response = $Self->_RenderPendingTime(
ActivityDialogField => $ActivityDialog->{Fields}{$CurrentField},
FieldName => $CurrentField,
DescriptionShort => $ActivityDialog->{Fields}{$CurrentField}{DescriptionShort},
DescriptionLong => $ActivityDialog->{Fields}{$CurrentField}{DescriptionLong},
Ticket => \%Ticket || {},
Error => \%Error || {},
FormID => $Self->{FormID},
GetParam => $Param{GetParam},
);
if ( !$Response->{Success} ) {
# does not show header and footer again
if ( $Self->{IsMainWindow} ) {
return $LayoutObject->Error(
Message => $Response->{Message},
);
}
$LayoutObject->FatalError(
Message => $Response->{Message},
);
}
$Output .= $Response->{HTML};
$RenderedFields{ $Self->{NameToID}->{$CurrentField} } = 1;
}
# render Title
elsif ( $Self->{NameToID}->{$CurrentField} eq 'Title' ) {
next DIALOGFIELD if $RenderedFields{ $Self->{NameToID}->{$CurrentField} };
my $Response = $Self->_RenderTitle(
ActivityDialogField => $ActivityDialog->{Fields}{$CurrentField},
FieldName => $CurrentField,
DescriptionShort => $ActivityDialog->{Fields}{$CurrentField}{DescriptionShort},
DescriptionLong => $ActivityDialog->{Fields}{$CurrentField}{DescriptionLong},
Ticket => \%Ticket || {},
Error => \%Error || {},
FormID => $Self->{FormID},
GetParam => $Param{GetParam},
);
if ( !$Response->{Success} ) {
# does not show header and footer again
if ( $Self->{IsMainWindow} ) {
return $LayoutObject->Error(
Message => $Response->{Message},
);
}
$LayoutObject->FatalError(
Message => $Response->{Message},
);
}
$Output .= $Response->{HTML};
$RenderedFields{$CurrentField} = 1;
}
# render Article
elsif ( $Self->{NameToID}->{$CurrentField} eq 'Article' ) {
next DIALOGFIELD if $RenderedFields{ $Self->{NameToID}->{$CurrentField} };
my $Response = $Self->_RenderArticle(
ActivityDialogField => $ActivityDialog->{Fields}{$CurrentField},
FieldName => $CurrentField,
DescriptionShort => $ActivityDialog->{Fields}{$CurrentField}{DescriptionShort},
DescriptionLong => $ActivityDialog->{Fields}{$CurrentField}{DescriptionLong},
Ticket => \%Ticket || {},
Error => \%Error || {},
FormID => $Self->{FormID},
GetParam => $Param{GetParam},
InformAgents => $ActivityDialog->{Fields}->{Article}->{Config}->{InformAgents},
);
if ( !$Response->{Success} ) {
# does not show header and footer again
if ( $Self->{IsMainWindow} ) {
return $LayoutObject->Error(
Message => $Response->{Message},
);
}
$LayoutObject->FatalError(
Message => $Response->{Message},
);
}
$Output .= $Response->{HTML};
$RenderedFields{$CurrentField} = 1;
}
# render Type
elsif ( $Self->{NameToID}->{$CurrentField} eq 'TypeID' ) {
# We don't render Fields twice,
# if there was already a Config without ID, skip this field
next DIALOGFIELD if $RenderedFields{ $Self->{NameToID}->{$CurrentField} };
my $Response = $Self->_RenderType(
ActivityDialogField => $ActivityDialog->{Fields}{$CurrentField},
FieldName => $CurrentField,
DescriptionShort => $ActivityDialog->{Fields}{$CurrentField}{DescriptionShort},
DescriptionLong => $ActivityDialog->{Fields}{$CurrentField}{DescriptionLong},
Ticket => \%Ticket || {},
Error => \%Error || {},
FormID => $Self->{FormID},
GetParam => $Param{GetParam},
AJAXUpdatableFields => $AJAXUpdatableFields,
);
if ( !$Response->{Success} ) {
# does not show header and footer again
if ( $Self->{IsMainWindow} ) {
return $LayoutObject->Error(
Message => $Response->{Message},
);
}
$LayoutObject->FatalError(
Message => $Response->{Message},
);
}
$Output .= $Response->{HTML};
$RenderedFields{ $Self->{NameToID}->{$CurrentField} } = 1;
}
}
my $FooterCSSClass = 'Footer';
if ( $Self->{IsAjaxRequest} ) {
# Due to the initial loading of
# the first ActivityDialog after Process selection
# we have to bind the AjaxUpdate Function on
# the selects, so we get the complete JSOnDocumentComplete code
# and deliver it in the FooterJS block.
# This Javascript Part is executed in
# AgentTicketProcess.tt
$LayoutObject->Block(
Name => 'FooterJS',
);
$FooterCSSClass = 'Centered';
}
# set submit button data
my $ButtonText = 'Submit';
my $ButtonTitle = 'Save';
my $ButtonID = 'Submit' . $ActivityActivityDialog->{ActivityDialog};
if ( $ActivityDialog->{SubmitButtonText} ) {
$ButtonText = $ActivityDialog->{SubmitButtonText};
$ButtonTitle = $ActivityDialog->{SubmitButtonText};
}
$LayoutObject->Block(
Name => 'Footer',
Data => {
FooterCSSClass => $FooterCSSClass,
ButtonText => $ButtonText,
ButtonTitle => $ButtonTitle,
ButtonID => $ButtonID
},
);
if ( $ActivityDialog->{SubmitAdviceText} ) {
$LayoutObject->Block(
Name => 'SubmitAdviceText',
Data => {
AdviceText => $ActivityDialog->{SubmitAdviceText},
},
);
}
# reload parent window
if ( $Param{ParentReload} ) {
$LayoutObject->Block(
Name => 'ParentReload',
);
}
# Add the FormFooter
$Output .= $LayoutObject->Output(
TemplateFile => 'ProcessManagement/ActivityDialogFooter',
Data => {},
);
# display regular footer only in non-ajax case
if ( !$Self->{IsAjaxRequest} ) {
$Output .= $LayoutObject->Footer( Type => $Self->{IsMainWindow} ? '' : 'Small' );
}
return $Output;
}
sub _RenderPendingTime {
my ( $Self, %Param ) = @_;
# get layout object
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
for my $Needed (qw(FormID)) {
if ( !$Param{$Needed} ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', $Needed, '_RenderResponsible' ),
};
}
}
if ( !IsHashRefWithData( $Param{ActivityDialogField} ) ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', 'ActivityDialogField', '_RenderPendingTime' ),
};
}
my %Data = (
Label => (
$LayoutObject->{LanguageObject}->Translate('Pending Date')
. ' ('
. $LayoutObject->{LanguageObject}->Translate('for pending* states') . ')'
),
FieldID => 'ResponsibleID',
FormID => $Param{FormID},
);
my $Error = '';
if ( IsHashRefWithData( $Param{Error} ) ) {
if ( $Param{Error}->{'PendingtTimeDay'} ) {
$Data{PendingtTimeDayError} = $LayoutObject->{LanguageObject}->Translate("Date invalid!");
$Error = $Param{Error}->{'PendingtTimeDay'};
}
if ( $Param{Error}->{'PendingtTimeHour'} ) {
$Data{PendingtTimeHourError} = $LayoutObject->{LanguageObject}->Translate("Date invalid!");
$Error = $Param{Error}->{'PendingtTimeDay'};
}
}
my $Calendar = '';
# get ticket object
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
# get used calendar if we have ticket data
if ( IsHashRefWithData( $Param{Ticket} ) ) {
$Calendar = $TicketObject->TicketCalendarGet(
%{ $Param{Ticket} },
);
}
$Data{Content} = $LayoutObject->BuildDateSelection(
Prefix => 'PendingTime',
PendingTimeRequired =>
(
$Param{ActivityDialogField}->{Display} && $Param{ActivityDialogField}->{Display} == 2
) ? 1 : 0,
Format => 'DateInputFormatLong',
YearPeriodPast => 0,
YearPeriodFuture => 5,
DiffTime => $Param{ActivityDialogField}->{DefaultValue}
|| $Kernel::OM->Get('Kernel::Config')->Get('Ticket::Frontend::PendingDiffTime')
|| 86400,
Class => $Error,
Validate => 1,
ValidateDateInFuture => 1,
Calendar => $Calendar,
);
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:PendingTime',
Data => \%Data,
);
if ( $Param{DescriptionShort} ) {
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:PendingTime:DescriptionShort',
Data => {
DescriptionShort => $Param{DescriptionShort},
},
);
}
if ( $Param{DescriptionLong} ) {
$LayoutObject->Block(
Name => 'rw:PendingTime:DescriptionLong',
Data => {
DescriptionLong => $Param{DescriptionLong},
},
);
}
return {
Success => 1,
HTML => $LayoutObject->Output( TemplateFile => 'ProcessManagement/PendingTime' ),
};
}
sub _RenderDynamicField {
my ( $Self, %Param ) = @_;
# get layout object
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
for my $Needed (qw(FormID FieldName)) {
if ( !$Param{$Needed} ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', $Needed, '_RenderDynamicField' ),
};
}
}
my $DynamicField = $Kernel::OM->Get('Kernel::System::DynamicField')->DynamicFieldListGet(
Valid => 1,
ObjectType => 'Ticket',
);
my $DynamicFieldConfig = ( grep { $_->{Name} eq $Param{FieldName} } @{$DynamicField} )[0];
if ( !IsHashRefWithData($DynamicFieldConfig) ) {
my $Message = "DynamicFieldConfig missing for field: $Param{FieldName}, or is not a Ticket Dynamic Field!";
# log error but does not stop the execution as it could be an old Article
# DynamicField, see bug#11666
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => $Message,
);
return {
Success => 1,
HTML => '',
};
}
my $PossibleValuesFilter;
# get dynamic field backend object
my $DynamicFieldBackendObject = $Kernel::OM->Get('Kernel::System::DynamicField::Backend');
my $IsACLReducible = $DynamicFieldBackendObject->HasBehavior(
DynamicFieldConfig => $DynamicFieldConfig,
Behavior => 'IsACLReducible',
);
# get ticket object
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
if ($IsACLReducible) {
# get PossibleValues
my $PossibleValues = $DynamicFieldBackendObject->PossibleValuesGet(
DynamicFieldConfig => $DynamicFieldConfig,
);
# All Ticket DynamicFields
# used for ACL checking
my %DynamicFieldCheckParam = map { $_ => $Param{GetParam}{$_} }
grep {m{^DynamicField_}xms} ( keys %{ $Param{GetParam} } );
# check if field has PossibleValues property in its configuration
if ( IsHashRefWithData($PossibleValues) ) {
# convert possible values key => value to key => key for ACLs using a Hash slice
my %AclData = %{$PossibleValues};
@AclData{ keys %AclData } = keys %AclData;
# set possible values filter from ACLs
my $ACL = $TicketObject->TicketAcl(
%{ $Param{GetParam} },
DynamicField => \%DynamicFieldCheckParam,
Action => $Self->{Action},
ReturnType => 'Ticket',
ReturnSubType => 'DynamicField_' . $DynamicFieldConfig->{Name},
Data => \%AclData,
UserID => $Self->{UserID},
);
if ($ACL) {
my %Filter = $TicketObject->TicketAclData();
# convert Filer key => key back to key => value using map
%{$PossibleValuesFilter} = map { $_ => $PossibleValues->{$_} } keys %Filter;
}
}
}
my $ServerError;
if ( IsHashRefWithData( $Param{Error} ) ) {
if (
defined $Param{Error}->{ $Param{FieldName} }
&& $Param{Error}->{ $Param{FieldName} } ne ''
)
{
$ServerError = 1;
}
}
my $ErrorMessage = '';
if ( IsHashRefWithData( $Param{ErrorMessages} ) ) {
if (
defined $Param{ErrorMessages}->{ $Param{FieldName} }
&& $Param{ErrorMessages}->{ $Param{FieldName} } ne ''
)
{
$ErrorMessage = $Param{ErrorMessages}->{ $Param{FieldName} };
}
}
my $DynamicFieldHTML = $DynamicFieldBackendObject->EditFieldRender(
DynamicFieldConfig => $DynamicFieldConfig,
PossibleValuesFilter => $PossibleValuesFilter,
Value => $Param{GetParam}{ 'DynamicField_' . $Param{FieldName} },
LayoutObject => $LayoutObject,
ParamObject => $Kernel::OM->Get('Kernel::System::Web::Request'),
AJAXUpdate => 1,
Mandatory => $Param{ActivityDialogField}->{Display} == 2,
UpdatableFields => $Param{AJAXUpdatableFields},
ServerError => $ServerError,
ErrorMessage => $ErrorMessage,
);
my %Data = (
Name => $DynamicFieldConfig->{Name},
Label => $DynamicFieldHTML->{Label},
Content => $DynamicFieldHTML->{Field},
);
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:DynamicField',
Data => \%Data,
);
if ( $Param{DescriptionShort} ) {
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock}
|| 'rw:DynamicField:DescriptionShort',
Data => {
DescriptionShort => $Param{DescriptionShort},
},
);
}
if ( $Param{DescriptionLong} ) {
$LayoutObject->Block(
Name => 'rw:DynamicField:DescriptionLong',
Data => {
DescriptionLong => $Param{DescriptionLong},
},
);
}
return {
Success => 1,
HTML => $LayoutObject->Output( TemplateFile => 'ProcessManagement/DynamicField' ),
};
}
sub _RenderTitle {
my ( $Self, %Param ) = @_;
# get layout object
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
for my $Needed (qw(FormID)) {
if ( !$Param{$Needed} ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', $Needed, '_RenderTitle' ),
};
}
}
if ( !IsHashRefWithData( $Param{ActivityDialogField} ) ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', 'ActivityDialogField', '_RenderTitle' ),
};
}
my %Data = (
Label => $LayoutObject->{LanguageObject}->Translate("Title"),
FieldID => 'Title',
FormID => $Param{FormID},
Value => $Param{GetParam}{Title},
Name => 'Title',
MandatoryClass => '',
ValidateRequired => '',
);
# If field is required put in the necessary variables for
# ValidateRequired class input field, Mandatory class for the label
if ( $Param{ActivityDialogField}->{Display} && $Param{ActivityDialogField}->{Display} == 2 ) {
$Data{ValidateRequired} = 'Validate_Required';
$Data{MandatoryClass} = 'Mandatory';
}
# output server errors
if ( IsHashRefWithData( $Param{Error} ) && $Param{Error}->{'Title'} ) {
$Data{ServerError} = 'ServerError';
}
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:Title',
Data => \%Data,
);
# set mandatory label marker
if ( $Data{MandatoryClass} && $Data{MandatoryClass} ne '' ) {
$LayoutObject->Block(
Name => 'LabelSpan',
Data => {},
);
}
if ( $Param{DescriptionShort} ) {
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:Title:DescriptionShort',
Data => {
DescriptionShort => $Param{DescriptionShort},
},
);
}
if ( $Param{DescriptionLong} ) {
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:Title:DescriptionLong',
Data => {
DescriptionLong => $Param{DescriptionLong},
},
);
}
return {
Success => 1,
HTML => $LayoutObject->Output( TemplateFile => 'ProcessManagement/Title' ),
};
}
sub _RenderArticle {
my ( $Self, %Param ) = @_;
# get layout object
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
for my $Needed (qw(FormID Ticket)) {
if ( !$Param{$Needed} ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', $Needed, '_RenderArticle' ),
};
}
}
if ( !IsHashRefWithData( $Param{ActivityDialogField} ) ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', 'ActivityDialogField', '_RenderArticle' ),
};
}
my %Data = (
Name => 'Article',
MandatoryClass => '',
ValidateRequired => '',
Subject => $Param{GetParam}{Subject},
Body => $Param{GetParam}{Body},
LabelSubject => $Param{ActivityDialogField}->{Config}->{LabelSubject}
|| $LayoutObject->{LanguageObject}->Translate("Subject"),
LabelBody => $Param{ActivityDialogField}->{Config}->{LabelBody}
|| $LayoutObject->{LanguageObject}->Translate("Text"),
);
# If field is required put in the necessary variables for
# ValidateRequired class input field, Mandatory class for the label
if ( $Param{ActivityDialogField}->{Display} && $Param{ActivityDialogField}->{Display} == 2 ) {
$Data{ValidateRequired} = 'Validate_Required';
$Data{MandatoryClass} = 'Mandatory';
}
# output server errors
if ( IsHashRefWithData( $Param{Error} ) && $Param{Error}->{'ArticleSubject'} ) {
$Data{SubjectServerError} = 'ServerError';
}
if ( IsHashRefWithData( $Param{Error} ) && $Param{Error}->{'ArticleBody'} ) {
$Data{BodyServerError} = 'ServerError';
}
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:Article',
Data => \%Data,
);
# set mandatory label marker
if ( $Data{MandatoryClass} && $Data{MandatoryClass} ne '' ) {
$LayoutObject->Block(
Name => 'LabelSpanSubject',
Data => {},
);
$LayoutObject->Block(
Name => 'LabelSpanBody',
Data => {},
);
}
# add rich text editor
if ( $LayoutObject->{BrowserRichText} ) {
# use height/width defined for this screen
$Param{RichTextHeight} = $Self->{Config}->{RichTextHeight} || 0;
$Param{RichTextWidth} = $Self->{Config}->{RichTextWidth} || 0;
$LayoutObject->Block(
Name => 'RichText',
Data => \%Param,
);
}
if ( $Param{DescriptionShort} ) {
$LayoutObject->Block(
Name => 'rw:Article:DescriptionShort',
Data => {
DescriptionShort => $Param{DescriptionShort},
},
);
}
if ( $Param{DescriptionLong} ) {
$LayoutObject->Block(
Name => 'rw:Article:DescriptionLong',
Data => {
DescriptionLong => $Param{DescriptionLong},
},
);
}
if ( $Param{InformAgents} ) {
my %ShownUsers;
my %AllGroupsMembers = $Kernel::OM->Get('Kernel::System::User')->UserList(
Type => 'Long',
Valid => 1,
);
my $GID = $Kernel::OM->Get('Kernel::System::Queue')->GetQueueGroupID( QueueID => $Param{Ticket}->{QueueID} );
my %MemberList = $Kernel::OM->Get('Kernel::System::Group')->PermissionGroupGet(
GroupID => $GID,
Type => 'note',
);
for my $UserID ( sort keys %MemberList ) {
$ShownUsers{$UserID} = $AllGroupsMembers{$UserID};
}
$Param{OptionStrg} = $LayoutObject->BuildSelection(
Data => \%ShownUsers,
SelectedID => '',
Name => 'InformUserID',
Multiple => 1,
Size => 3,
Class => 'Modernize',
);
$LayoutObject->Block(
Name => 'rw:Article:InformAgent',
Data => \%Param,
);
}
# get all attachments meta data
my @Attachments = $Kernel::OM->Get('Kernel::System::Web::UploadCache')->FormIDGetAllFilesMeta(
FormID => $Self->{FormID},
);
# show attachments
ATTACHMENT:
for my $Attachment (@Attachments) {
if (
$Attachment->{ContentID}
&& $LayoutObject->{BrowserRichText}
&& ( $Attachment->{ContentType} =~ /image/i )
&& ( $Attachment->{Disposition} eq 'inline' )
)
{
next ATTACHMENT;
}
$LayoutObject->Block(
Name => 'Attachment',
Data => $Attachment,
);
}
# output server errors
if ( IsHashRefWithData( $Param{Error} ) && $Param{Error}->{'TimeUnits'} ) {
$Param{TimeUnitsInvalid} = 'ServerError';
}
# get config object
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
# show time units
if (
$ConfigObject->Get('Ticket::Frontend::AccountTime')
&& $Param{ActivityDialogField}->{Config}->{TimeUnits}
)
{
if ( $ConfigObject->Get('Ticket::Frontend::NeedAccountedTime') ) {
$LayoutObject->Block(
Name => 'TimeUnitsLabelMandatory',
Data => \%Param,
);
$Param{TimeUnitsRequired} = 'Validate_Required';
}
elsif ( $Param{ActivityDialogField}->{Config}->{TimeUnits} == 1 ) {
$LayoutObject->Block(
Name => 'TimeUnitsLabel',
Data => \%Param,
);
$Param{TimeUnitsRequired} = '';
}
else {
$LayoutObject->Block(
Name => 'TimeUnitsLabelMandatory',
Data => \%Param,
);
$Param{TimeUnitsRequired} = 'Validate_Required';
}
$LayoutObject->Block(
Name => 'TimeUnits',
Data => \%Param,
);
}
return {
Success => 1,
HTML => $LayoutObject->Output( TemplateFile => 'ProcessManagement/Article' ),
};
}
sub _RenderCustomer {
my ( $Self, %Param ) = @_;
# get layout object
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
for my $Needed (qw(FormID)) {
if ( !$Param{$Needed} ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', $Needed, '_RenderResponsible' ),
};
}
}
if ( !IsHashRefWithData( $Param{ActivityDialogField} ) ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', 'ActivityDialogField', '_RenderCustomer' ),
};
}
my %CustomerUserData = ();
my $SubmittedCustomerUserID = $Param{GetParam}{CustomerUserID};
my %Data = (
LabelCustomerUser => $LayoutObject->{LanguageObject}->Translate("Customer user"),
LabelCustomerID => $LayoutObject->{LanguageObject}->Translate("CustomerID"),
FormID => $Param{FormID},
MandatoryClass => '',
ValidateRequired => '',
);
# If field is required put in the necessary variables for
# ValidateRequired class input field, Mandatory class for the label
if ( $Param{ActivityDialogField}->{Display} && $Param{ActivityDialogField}->{Display} == 2 ) {
$Data{ValidateRequired} = 'Validate_Required';
$Data{MandatoryClass} = 'Mandatory';
}
# output server errors
if ( IsHashRefWithData( $Param{Error} ) && $Param{Error}->{CustomerUserID} ) {
$Data{CustomerUserIDServerError} = 'ServerError';
}
if ( IsHashRefWithData( $Param{Error} ) && $Param{Error}->{CustomerID} ) {
$Data{CustomerIDServerError} = 'ServerError';
}
# set some customer search autocomplete properties
$LayoutObject->Block(
Name => 'CustomerSearchAutoComplete',
);
if (
( IsHashRefWithData( $Param{Ticket} ) && $Param{Ticket}->{CustomerUserID} )
|| $SubmittedCustomerUserID
)
{
%CustomerUserData = $Kernel::OM->Get('Kernel::System::CustomerUser')->CustomerUserDataGet(
User => $SubmittedCustomerUserID
|| $Param{Ticket}{CustomerUserID},
);
}
# show customer field as "FirstName Lastname"
if ( IsHashRefWithData( \%CustomerUserData ) ) {
$Data{CustomerUserID} = "\"$CustomerUserData{UserFirstname} " .
"$CustomerUserData{UserLastname}\" <$CustomerUserData{UserEmail}>";
$Data{CustomerID} = $CustomerUserData{UserCustomerID} || '';
$Data{SelectedCustomerUser} = $CustomerUserData{UserID} || '';
}
# set fields that will get an AJAX loader icon when this field changes
my $JSON = $LayoutObject->JSONEncode(
Data => $Param{AJAXUpdatableFields},
NoQuotes => 0,
);
$Data{FieldsToUpdate} = $JSON;
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:Customer',
Data => \%Data,
);
# set mandatory label marker
if ( $Data{MandatoryClass} && $Data{MandatoryClass} ne '' ) {
$LayoutObject->Block(
Name => 'LabelSpanCustomerUser',
Data => {},
);
}
if ( $Param{DescriptionShort} ) {
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:Customer:DescriptionShort',
Data => {
DescriptionShort => $Param{DescriptionShort},
},
);
}
if ( $Param{DescriptionLong} ) {
$LayoutObject->Block(
Name => 'rw:Customer:DescriptionLong',
Data => {
DescriptionLong => $Param{DescriptionLong},
},
);
}
return {
Success => 1,
HTML => $LayoutObject->Output( TemplateFile => 'ProcessManagement/Customer' ),
};
}
sub _RenderResponsible {
my ( $Self, %Param ) = @_;
# get layout object
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
for my $Needed (qw(FormID)) {
if ( !$Param{$Needed} ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', $Needed, '_RenderResponsible' ),
};
}
}
if ( !IsHashRefWithData( $Param{ActivityDialogField} ) ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', 'ActivityDialogField', '_RenderResponsible' ),
};
}
my $Responsibles = $Self->_GetResponsibles( %{ $Param{GetParam} } );
my %Data = (
Label => $LayoutObject->{LanguageObject}->Translate("Responsible"),
FieldID => 'ResponsibleID',
FormID => $Param{FormID},
ResponsibleAll => $Param{GetParam}{ResponsibleAll},
MandatoryClass => '',
ValidateRequired => '',
);
my $PossibleNone = 1;
# if field is required put in the necessary variables for
# ValidateRequired class input field, Mandatory class for the label
# do not allow empty selection
if ( $Param{ActivityDialogField}->{Display} && $Param{ActivityDialogField}->{Display} == 2 ) {
$Data{ValidateRequired} = 'Validate_Required';
$Data{MandatoryClass} = 'Mandatory';
$PossibleNone = 0;
}
my $SelectedValue;
# get user object
my $UserObject = $Kernel::OM->Get('Kernel::System::User');
my $ResponsibleIDParam = $Param{GetParam}{ResponsibleID};
$SelectedValue = $UserObject->UserLookup( UserID => $ResponsibleIDParam )
if $ResponsibleIDParam;
if ( $Param{ActivityDialogField}->{DefaultValue} ) {
if ( $Param{FieldName} eq 'Responsible' ) {
# Fetch DefaultValue from Config
if ( !$SelectedValue ) {
$SelectedValue = $UserObject->UserLookup(
User => $Param{ActivityDialogField}->{DefaultValue} || '',
);
if ($SelectedValue) {
$SelectedValue = $Param{ActivityDialogField}->{DefaultValue};
}
}
}
else {
if ( !$SelectedValue ) {
$SelectedValue = $UserObject->UserLookup(
UserID => $Param{ActivityDialogField}->{DefaultValue} || ''
);
}
}
}
# if there is no user from GetParam or default and the field is mandatory get it from the ticket
# (if any)
if (
!$SelectedValue
&& !$PossibleNone
&& IsHashRefWithData( $Param{Ticket} )
)
{
$SelectedValue = $Param{Ticket}->{Responsible};
}
# use current user as fallback, for all other cases where there is still no user
elsif ( !$SelectedValue ) {
$SelectedValue = $UserObject->UserLookup( UserID => $Self->{UserID} );
}
# if we have a user already and the field is not mandatory and it is the same as in ticket, then
# set it to none (as it doesn't need to be changed afterall)
elsif (
$SelectedValue
&& $PossibleNone
&& IsHashRefWithData( $Param{Ticket} )
&& $SelectedValue eq $Param{Ticket}->{Responsible}
)
{
$SelectedValue = '';
}
# set server errors
my $ServerError = '';
if ( IsHashRefWithData( $Param{Error} ) && $Param{Error}->{'ResponsibleID'} ) {
$ServerError = 'ServerError';
}
# look up $SelectedID
my $SelectedID;
if ($SelectedValue) {
$SelectedID = $UserObject->UserLookup(
UserLogin => $SelectedValue,
);
}
# build Responsible string
$Data{Content} = $LayoutObject->BuildSelection(
Data => $Responsibles,
Name => 'ResponsibleID',
Translation => 1,
SelectedID => $SelectedID,
Class => "Modernize $ServerError",
PossibleNone => $PossibleNone,
);
# set fields that will get an AJAX loader icon when this field changes
$Data{FieldsToUpdate} = $Self->_GetFieldsToUpdateStrg(
TriggerField => 'ResponsibleID',
AJAXUpdatableFields => $Param{AJAXUpdatableFields},
);
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:Responsible',
Data => \%Data,
);
# set mandatory label marker
if ( $Data{MandatoryClass} && $Data{MandatoryClass} ne '' ) {
$LayoutObject->Block(
Name => 'LabelSpan',
Data => {},
);
}
if ( $Param{DescriptionShort} ) {
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:Responsible:DescriptionShort',
Data => {
DescriptionShort => $Param{DescriptionShort},
},
);
}
if ( $Param{DescriptionLong} ) {
$LayoutObject->Block(
Name => 'rw:Responsible:DescriptionLong',
Data => {
DescriptionLong => $Param{DescriptionLong},
},
);
}
return {
Success => 1,
HTML => $LayoutObject->Output( TemplateFile => 'ProcessManagement/Responsible' ),
};
}
sub _RenderOwner {
my ( $Self, %Param ) = @_;
# get layout object
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
for my $Needed (qw(FormID)) {
if ( !$Param{$Needed} ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', $Needed, '_RenderOwner' ),
};
}
}
if ( !IsHashRefWithData( $Param{ActivityDialogField} ) ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', 'ActivityDialogField', '_RenderOwner' ),
};
}
my $Owners = $Self->_GetOwners( %{ $Param{GetParam} } );
my %Data = (
Label => $LayoutObject->{LanguageObject}->Translate("Owner"),
FieldID => 'OwnerID',
FormID => $Param{FormID},
OwnerAll => $Param{GetParam}{OwnerAll},
MandatoryClass => '',
ValidateRequired => '',
);
my $PossibleNone = 1;
# if field is required put in the necessary variables for
# ValidateRequired class input field, Mandatory class for the label
# do not allow empty selection
if ( $Param{ActivityDialogField}->{Display} && $Param{ActivityDialogField}->{Display} == 2 ) {
$Data{ValidateRequired} = 'Validate_Required';
$Data{MandatoryClass} = 'Mandatory';
$PossibleNone = 0;
}
my $SelectedValue;
# get user object
my $UserObject = $Kernel::OM->Get('Kernel::System::User');
my $OwnerIDParam = $Param{GetParam}{OwnerID};
if ($OwnerIDParam) {
$SelectedValue = $UserObject->UserLookup(
UserID => $OwnerIDParam,
);
}
if ( $Param{ActivityDialogField}->{DefaultValue} ) {
if ( $Param{FieldName} eq 'Owner' ) {
if ( !$SelectedValue ) {
# Fetch DefaultValue from Config
$SelectedValue = $UserObject->UserLookup(
User => $Param{ActivityDialogField}->{DefaultValue},
);
if ($SelectedValue) {
$SelectedValue = $Param{ActivityDialogField}->{DefaultValue};
}
}
}
else {
if ( !$SelectedValue ) {
$SelectedValue = $UserObject->UserLookup(
UserID => $Param{ActivityDialogField}->{DefaultValue},
);
}
}
}
# if there is no user from GetParam or default and the field is mandatory get it from the ticket
# (if any)
if (
!$SelectedValue
&& !$PossibleNone
&& IsHashRefWithData( $Param{Ticket} )
)
{
$SelectedValue = $Param{Ticket}->{Owner};
}
# use current user as fallback, for all other cases where there is still no user
elsif ( !$SelectedValue ) {
$SelectedValue = $UserObject->UserLookup( UserID => $Self->{UserID} );
}
# if we have a user already and the field is not mandatory and it is the same as in ticket, then
# set it to none (as it doesn't need to be changed afterall)
elsif (
$SelectedValue
&& $PossibleNone
&& IsHashRefWithData( $Param{Ticket} )
&& $SelectedValue eq $Param{Ticket}->{Owner}
)
{
$SelectedValue = '';
}
# set server errors
my $ServerError = '';
if ( IsHashRefWithData( $Param{Error} ) && $Param{Error}->{'OwnerID'} ) {
$ServerError = 'ServerError';
}
# look up $SelectedID
my $SelectedID;
if ($SelectedValue) {
$SelectedID = $UserObject->UserLookup(
UserLogin => $SelectedValue,
);
}
# build Owner string
$Data{Content} = $LayoutObject->BuildSelection(
Data => $Owners,
Name => 'OwnerID',
Translation => 1,
SelectedID => $SelectedID || '',
Class => "Modernize $ServerError",
PossibleNone => $PossibleNone,
);
# set fields that will get an AJAX loader icon when this field changes
$Data{FieldsToUpdate} = $Self->_GetFieldsToUpdateStrg(
TriggerField => 'OwnerID',
AJAXUpdatableFields => $Param{AJAXUpdatableFields},
);
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:Owner',
Data => \%Data,
);
# set mandatory label marker
if ( $Data{MandatoryClass} && $Data{MandatoryClass} ne '' ) {
$LayoutObject->Block(
Name => 'LabelSpan',
Data => {},
);
}
if ( $Param{DescriptionShort} ) {
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:Owner:DescriptionShort',
Data => {
DescriptionShort => $Param{DescriptionShort},
},
);
}
if ( $Param{DescriptionLong} ) {
$LayoutObject->Block(
Name => 'rw:Owner:DescriptionLong',
Data => {
DescriptionLong => $Param{DescriptionLong},
},
);
}
return {
Success => 1,
HTML => $LayoutObject->Output( TemplateFile => 'ProcessManagement/Owner' ),
};
}
sub _RenderSLA {
my ( $Self, %Param ) = @_;
# get layout object
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
for my $Needed (qw(FormID)) {
if ( !$Param{$Needed} ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', $Needed, '_RenderSLA' ),
};
}
}
if ( !IsHashRefWithData( $Param{ActivityDialogField} ) ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', 'ActivityDialogField', '_RenderSLA' ),
};
}
# create a local copy of the GetParam
my %GetServicesParam = %{ $Param{GetParam} };
# use ticket information as a fall back if customer was already set, otherwise when the
# activity dialog displays the service list will be initially empty, see bug#10059
if ( IsHashRefWithData( $Param{Ticket} ) ) {
$GetServicesParam{CustomerUserID} ||= $Param{Ticket}->{CustomerUserID} ||= '';
}
my $Services = $Self->_GetServices(
%GetServicesParam,
);
my $SLAs = $Self->_GetSLAs(
%{ $Param{GetParam} },
Services => $Services,
);
my %Data = (
Label => $LayoutObject->{LanguageObject}->Translate("SLA"),
FieldID => 'SLAID',
FormID => $Param{FormID},
MandatoryClass => '',
ValidateRequired => '',
);
# If field is required put in the necessary variables for
# ValidateRequired class input field, Mandatory class for the label
if ( $Param{ActivityDialogField}->{Display} && $Param{ActivityDialogField}->{Display} == 2 ) {
$Data{ValidateRequired} = 'Validate_Required';
$Data{MandatoryClass} = 'Mandatory';
}
my $SelectedValue;
# get SLA object
my $SLAObject = $Kernel::OM->Get('Kernel::System::SLA');
my $SLAIDParam = $Param{GetParam}{SLAID};
if ($SLAIDParam) {
$SelectedValue = $SLAObject->SLALookup( SLAID => $SLAIDParam );
}
if ( $Param{FieldName} eq 'SLA' ) {
if ( !$SelectedValue ) {
# Fetch DefaultValue from Config
if (
defined $Param{ActivityDialogField}->{DefaultValue}
&& $Param{ActivityDialogField}->{DefaultValue} ne ''
)
{
$SelectedValue = $SLAObject->SLALookup(
SLA => $Param{ActivityDialogField}->{DefaultValue},
);
}
if ($SelectedValue) {
$SelectedValue = $Param{ActivityDialogField}->{DefaultValue};
}
}
}
else {
if ( !$SelectedValue ) {
if (
defined $Param{ActivityDialogField}->{DefaultValue}
&& $Param{ActivityDialogField}->{DefaultValue} ne ''
)
{
$SelectedValue = $SLAObject->SLALookup(
SLA => $Param{ActivityDialogField}->{DefaultValue},
);
}
}
}
# Get TicketValue
if ( IsHashRefWithData( $Param{Ticket} ) && !$SelectedValue ) {
$SelectedValue = $Param{Ticket}->{SLA};
}
# set server errors
my $ServerError = '';
if ( IsHashRefWithData( $Param{Error} ) && $Param{Error}->{'SLAID'} ) {
$ServerError = 'ServerError';
}
# build SLA string
$Data{Content} = $LayoutObject->BuildSelection(
Data => $SLAs,
Name => 'SLAID',
SelectedValue => $SelectedValue,
PossibleNone => 1,
Sort => 'AlphanumericValue',
Translation => 0,
Class => "Modernize $ServerError",
Max => 200,
);
# set fields that will get an AJAX loader icon when this field changes
$Data{FieldsToUpdate} = $Self->_GetFieldsToUpdateStrg(
TriggerField => 'SLAID',
AJAXUpdatableFields => $Param{AJAXUpdatableFields},
);
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:SLA',
Data => \%Data,
);
# set mandatory label marker
if ( $Data{MandatoryClass} && $Data{MandatoryClass} ne '' ) {
$LayoutObject->Block(
Name => 'LabelSpan',
Data => {},
);
}
if ( $Param{DescriptionShort} ) {
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:SLA:DescriptionShort',
Data => {
DescriptionShort => $Param{DescriptionShort},
},
);
}
if ( $Param{DescriptionLong} ) {
$LayoutObject->Block(
Name => 'rw:SLA:DescriptionLong',
Data => {
DescriptionLong => $Param{DescriptionLong},
},
);
}
return {
Success => 1,
HTML => $LayoutObject->Output( TemplateFile => 'ProcessManagement/SLA' ),
};
}
sub _RenderService {
my ( $Self, %Param ) = @_;
# get layout object
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
for my $Needed (qw(FormID)) {
if ( !$Param{$Needed} ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', $Needed, '_RenderService' ),
};
}
}
if ( !IsHashRefWithData( $Param{ActivityDialogField} ) ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', 'ActivityDialogField', '_RenderService' ),
};
}
# create a local copy of the GetParam
my %GetServicesParam = %{ $Param{GetParam} };
# use ticket information as a fall back if customer was already set, otherwise when the
# activity dialog displays the service list will be initially empty, see bug#10059
if ( IsHashRefWithData( $Param{Ticket} ) ) {
$GetServicesParam{CustomerUserID} ||= $Param{Ticket}->{CustomerUserID} ||= '';
}
my $Services = $Self->_GetServices(
%GetServicesParam,
);
my %Data = (
Label => $LayoutObject->{LanguageObject}->Translate("Service"),
FieldID => 'ServiceID',
FormID => $Param{FormID},
MandatoryClass => '',
ValidateRequired => '',
);
# If field is required put in the necessary variables for
# ValidateRequired class input field, Mandatory class for the label
if ( $Param{ActivityDialogField}->{Display} && $Param{ActivityDialogField}->{Display} == 2 ) {
$Data{ValidateRequired} = 'Validate_Required';
$Data{MandatoryClass} = 'Mandatory';
}
my $SelectedValue;
# get service object
my $ServiceObject = $Kernel::OM->Get('Kernel::System::Service');
my $ServiceIDParam = $Param{GetParam}{ServiceID};
if ($ServiceIDParam) {
$SelectedValue = $ServiceObject->ServiceLookup(
ServiceID => $ServiceIDParam,
);
}
if ( $Param{FieldName} eq 'Service' ) {
if ( !$SelectedValue ) {
# Fetch DefaultValue from Config
if (
defined $Param{ActivityDialogField}->{DefaultValue}
&& $Param{ActivityDialogField}->{DefaultValue} ne ''
)
{
$SelectedValue = $ServiceObject->ServiceLookup(
Name => $Param{ActivityDialogField}->{DefaultValue},
);
}
if ($SelectedValue) {
$SelectedValue = $Param{ActivityDialogField}->{DefaultValue};
}
}
}
else {
if ( !$SelectedValue ) {
if (
defined $Param{ActivityDialogField}->{DefaultValue}
&& $Param{ActivityDialogField}->{DefaultValue} ne ''
)
{
$SelectedValue = $ServiceObject->ServiceLookup(
Service => $Param{ActivityDialogField}->{DefaultValue},
);
}
}
}
# Get TicketValue
if ( IsHashRefWithData( $Param{Ticket} ) && !$SelectedValue ) {
$SelectedValue = $Param{Ticket}->{Service};
}
# set server errors
my $ServerError = '';
if ( IsHashRefWithData( $Param{Error} ) && $Param{Error}->{'ServiceID'} ) {
$ServerError = 'ServerError';
}
# get list type
my $TreeView = 0;
if ( $Kernel::OM->Get('Kernel::Config')->Get('Ticket::Frontend::ListType') eq 'tree' ) {
$TreeView = 1;
}
# build Service string
$Data{Content} = $LayoutObject->BuildSelection(
Data => $Services,
Name => 'ServiceID',
Class => "Modernize $ServerError",
SelectedValue => $SelectedValue,
PossibleNone => 1,
TreeView => $TreeView,
Sort => 'TreeView',
Translation => 0,
Max => 200,
);
# set fields that will get an AJAX loader icon when this field changes
$Data{FieldsToUpdate} = $Self->_GetFieldsToUpdateStrg(
TriggerField => 'ServiceID',
AJAXUpdatableFields => $Param{AJAXUpdatableFields},
);
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:Service',
Data => \%Data,
);
# set mandatory label marker
if ( $Data{MandatoryClass} && $Data{MandatoryClass} ne '' ) {
$LayoutObject->Block(
Name => 'LabelSpan',
Data => {},
);
}
if ( $Param{DescriptionShort} ) {
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:Service:DescriptionShort',
Data => {
DescriptionShort => $Param{DescriptionShort},
},
);
}
if ( $Param{DescriptionLong} ) {
$LayoutObject->Block(
Name => 'rw:Service:DescriptionLong',
Data => {
DescriptionLong => $Param{DescriptionLong},
},
);
}
return {
Success => 1,
HTML => $LayoutObject->Output( TemplateFile => 'ProcessManagement/Service' ),
};
}
sub _RenderLock {
# for lock states there's no ACL checking yet implemented so no checking...
my ( $Self, %Param ) = @_;
# get layout object
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
for my $Needed (qw(FormID)) {
if ( !$Param{$Needed} ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', $Needed, '_RenderLock' ),
};
}
}
if ( !IsHashRefWithData( $Param{ActivityDialogField} ) ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', 'ActivityDialogField', '_RenderLock' ),
};
}
my $Locks = $Self->_GetLocks(
%{ $Param{GetParam} },
);
my %Data = (
Label => $LayoutObject->{LanguageObject}->Translate("Lock state"),
FieldID => 'LockID',
FormID => $Param{FormID},
MandatoryClass => '',
ValidateRequired => '',
);
# If field is required put in the necessary variables for
# ValidateRequired class input field, Mandatory class for the label
if ( $Param{ActivityDialogField}->{Display} && $Param{ActivityDialogField}->{Display} == 2 ) {
$Data{ValidateRequired} = 'Validate_Required';
$Data{MandatoryClass} = 'Mandatory';
}
my $SelectedValue;
# get lock object
my $LockObject = $Kernel::OM->Get('Kernel::System::Lock');
my $LockIDParam = $Param{GetParam}{LockID};
$SelectedValue = $LockObject->LockLookup( LockID => $LockIDParam )
if ($LockIDParam);
if ( $Param{FieldName} eq 'Lock' ) {
if ( !$SelectedValue ) {
# Fetch DefaultValue from Config
$SelectedValue = $LockObject->LockLookup(
Lock => $Param{ActivityDialogField}->{DefaultValue} || '',
);
if ($SelectedValue) {
$SelectedValue = $Param{ActivityDialogField}->{DefaultValue};
}
}
}
else {
$SelectedValue = $LockObject->LockLookup(
LockID => $Param{ActivityDialogField}->{DefaultValue} || ''
)
if !$SelectedValue;
}
# Get TicketValue
if ( IsHashRefWithData( $Param{Ticket} ) && !$SelectedValue ) {
$SelectedValue = $Param{Ticket}->{Lock};
}
# set server errors
my $ServerError = '';
if ( IsHashRefWithData( $Param{Error} ) && $Param{Error}->{'LockID'} ) {
$ServerError = 'ServerError';
}
# build lock string
$Data{Content} = $LayoutObject->BuildSelection(
Data => $Locks,
Name => 'LockID',
Translation => 1,
SelectedValue => $SelectedValue,
Class => "Modernize $ServerError",
);
# set fields that will get an AJAX loader icon when this field changes
$Data{FieldsToUpdate} = $Self->_GetFieldsToUpdateStrg(
TriggerField => 'LockID',
AJAXUpdatableFields => $Param{AJAXUpdatableFields},
);
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:Lock',
Data => \%Data,
);
# set mandatory label marker
if ( $Data{MandatoryClass} && $Data{MandatoryClass} ne '' ) {
$LayoutObject->Block(
Name => 'LabelSpan',
Data => {},
);
}
if ( $Param{DescriptionShort} ) {
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:Lock:DescriptionShort',
Data => {
DescriptionShort => $Param{DescriptionShort},
},
);
}
if ( $Param{DescriptionLong} ) {
$LayoutObject->Block(
Name => 'rw:Lock:DescriptionLong',
Data => {
DescriptionLong => $Param{DescriptionLong},
},
);
}
return {
Success => 1,
HTML => $LayoutObject->Output( TemplateFile => 'ProcessManagement/Lock' ),
};
}
sub _RenderPriority {
my ( $Self, %Param ) = @_;
# get layout object
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
for my $Needed (qw(FormID)) {
if ( !$Param{$Needed} ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', $Needed, '_RenderPriority' ),
};
}
}
if ( !IsHashRefWithData( $Param{ActivityDialogField} ) ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', 'ActivityDialogField', '_RenderPriority' ),
};
}
my $Priorities = $Self->_GetPriorities(
%{ $Param{GetParam} },
);
my %Data = (
Label => $LayoutObject->{LanguageObject}->Translate("Priority"),
FieldID => 'PriorityID',
FormID => $Param{FormID},
MandatoryClass => '',
ValidateRequired => '',
);
# If field is required put in the necessary variables for
# ValidateRequired class input field, Mandatory class for the label
if ( $Param{ActivityDialogField}->{Display} && $Param{ActivityDialogField}->{Display} == 2 ) {
$Data{ValidateRequired} = 'Validate_Required';
$Data{MandatoryClass} = 'Mandatory';
}
my $SelectedValue;
# get priority object
my $PriorityObject = $Kernel::OM->Get('Kernel::System::Priority');
my $PriorityIDParam = $Param{GetParam}{PriorityID};
if ($PriorityIDParam) {
$SelectedValue = $PriorityObject->PriorityLookup(
PriorityID => $PriorityIDParam,
);
}
if ( $Param{FieldName} eq 'Priority' ) {
if ( !$SelectedValue ) {
# Fetch DefaultValue from Config
$SelectedValue = $PriorityObject->PriorityLookup(
Priority => $Param{ActivityDialogField}->{DefaultValue} || '',
);
if ($SelectedValue) {
$SelectedValue = $Param{ActivityDialogField}->{DefaultValue};
}
}
}
else {
if ( !$SelectedValue ) {
$SelectedValue = $PriorityObject->PriorityLookup(
PriorityID => $Param{ActivityDialogField}->{DefaultValue} || '',
);
}
}
# Get TicketValue
if ( IsHashRefWithData( $Param{Ticket} ) && !$SelectedValue ) {
$SelectedValue = $Param{Ticket}->{Priority};
}
# set server errors
my $ServerError = '';
if ( IsHashRefWithData( $Param{Error} ) && $Param{Error}->{'PriorityID'} ) {
$ServerError = 'ServerError';
}
# build next Priorities string
$Data{Content} = $LayoutObject->BuildSelection(
Data => $Priorities,
Name => 'PriorityID',
Translation => 1,
SelectedValue => $SelectedValue,
Class => "Modernize $ServerError",
);
# set fields that will get an AJAX loader icon when this field changes
$Data{FieldsToUpdate} = $Self->_GetFieldsToUpdateStrg(
TriggerField => 'PriorityID',
AJAXUpdatableFields => $Param{AJAXUpdatableFields},
);
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:Priority',
Data => \%Data,
);
# set mandatory label marker
if ( $Data{MandatoryClass} && $Data{MandatoryClass} ne '' ) {
$LayoutObject->Block(
Name => 'LabelSpan',
Data => {},
);
}
if ( $Param{DescriptionShort} ) {
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:Priority:DescriptionShort',
Data => {
DescriptionShort => $Param{DescriptionShort},
},
);
}
if ( $Param{DescriptionLong} ) {
$LayoutObject->Block(
Name => 'rw:Priority:DescriptionLong',
Data => {
DescriptionLong => $Param{DescriptionLong},
},
);
}
return {
Success => 1,
HTML => $LayoutObject->Output( TemplateFile => 'ProcessManagement/Priority' ),
};
}
sub _RenderQueue {
my ( $Self, %Param ) = @_;
# get layout object
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
for my $Needed (qw(FormID)) {
if ( !$Param{$Needed} ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', $Needed, '_RenderQueue' ),
};
}
}
if ( !IsHashRefWithData( $Param{ActivityDialogField} ) ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', 'ActivityDialogField', '_RenderQueue' ),
};
}
my $Queues = $Self->_GetQueues(
%{ $Param{GetParam} },
);
my %Data = (
Label => $LayoutObject->{LanguageObject}->Translate("To queue"),
FieldID => 'QueueID',
FormID => $Param{FormID},
MandatoryClass => '',
ValidateRequired => '',
);
# If field is required put in the necessary variables for
# ValidateRequired class input field, Mandatory class for the label
if ( $Param{ActivityDialogField}->{Display} && $Param{ActivityDialogField}->{Display} == 2 ) {
$Data{ValidateRequired} = 'Validate_Required';
$Data{MandatoryClass} = 'Mandatory';
}
my $SelectedValue;
# get queue object
my $QueueObject = $Kernel::OM->Get('Kernel::System::Queue');
# if we got QueueID as Param from the GUI
my $QueueIDParam = $Param{GetParam}{QueueID};
if ($QueueIDParam) {
$SelectedValue = $QueueObject->QueueLookup(
QueueID => $QueueIDParam,
);
}
if ( $Param{FieldName} eq 'Queue' ) {
if ( !$SelectedValue ) {
# Fetch DefaultValue from Config
$SelectedValue = $QueueObject->QueueLookup(
Queue => $Param{ActivityDialogField}->{DefaultValue} || '',
);
if ($SelectedValue) {
$SelectedValue = $Param{ActivityDialogField}->{DefaultValue};
}
}
}
else {
if ( !$SelectedValue ) {
$SelectedValue = $QueueObject->QueueLookup(
QueueID => $Param{ActivityDialogField}->{DefaultValue} || '',
);
}
}
# Get TicketValue
if ( IsHashRefWithData( $Param{Ticket} ) && !$SelectedValue ) {
$SelectedValue = $Param{Ticket}->{Queue};
}
# set server errors
my $ServerError = '';
if ( IsHashRefWithData( $Param{Error} ) && $Param{Error}->{'QueueID'} ) {
$ServerError = 'ServerError';
}
# get list type
my $TreeView = 0;
if ( $Kernel::OM->Get('Kernel::Config')->Get('Ticket::Frontend::ListType') eq 'tree' ) {
$TreeView = 1;
}
# build next queues string
$Data{Content} = $LayoutObject->BuildSelection(
Data => $Queues,
Name => 'QueueID',
Translation => 1,
SelectedValue => $SelectedValue,
Class => "Modernize $ServerError",
TreeView => $TreeView,
Sort => 'TreeView',
PossibleNone => 1,
);
$Data{FieldsToUpdate} = $Self->_GetFieldsToUpdateStrg(
TriggerField => 'QueueID',
AJAXUpdatableFields => $Param{AJAXUpdatableFields},
);
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:Queue',
Data => \%Data,
);
# set mandatory label marker
if ( $Data{MandatoryClass} && $Data{MandatoryClass} ne '' ) {
$LayoutObject->Block(
Name => 'LabelSpan',
Data => {},
);
}
if ( $Param{DescriptionShort} ) {
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:Queue:DescriptionShort',
Data => {
DescriptionShort => $Param{DescriptionShort},
},
);
}
if ( $Param{DescriptionLong} ) {
$LayoutObject->Block(
Name => 'rw:Queue:DescriptionLong',
Data => {
DescriptionLong => $Param{DescriptionLong},
},
);
}
return {
Success => 1,
HTML => $LayoutObject->Output( TemplateFile => 'ProcessManagement/Queue' ),
};
}
sub _RenderState {
my ( $Self, %Param ) = @_;
# get layout object
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
for my $Needed (qw(FormID)) {
if ( !$Param{$Needed} ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', $Needed, '_RenderState' ),
};
}
}
if ( !IsHashRefWithData( $Param{ActivityDialogField} ) ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', 'ActivityDialogField', '_RenderState' ),
};
}
my $States = $Self->_GetStates( %{ $Param{GetParam} } );
my %Data = (
Label => $LayoutObject->{LanguageObject}->Translate("Next ticket state"),
FieldID => 'StateID',
FormID => $Param{FormID},
MandatoryClass => '',
ValidateRequired => '',
);
# If field is required put in the necessary variables for
# ValidateRequired class input field, Mandatory class for the label
if ( $Param{ActivityDialogField}->{Display} && $Param{ActivityDialogField}->{Display} == 2 ) {
$Data{ValidateRequired} = 'Validate_Required';
$Data{MandatoryClass} = 'Mandatory';
}
my $SelectedValue;
# get state object
my $StateObject = $Kernel::OM->Get('Kernel::System::State');
my $StateIDParam = $Param{GetParam}{StateID};
if ($StateIDParam) {
$SelectedValue = $StateObject->StateLookup( StateID => $StateIDParam );
}
if ( $Param{FieldName} eq 'State' ) {
if ( !$SelectedValue ) {
# Fetch DefaultValue from Config
$SelectedValue = $StateObject->StateLookup(
State => $Param{ActivityDialogField}->{DefaultValue} || '',
);
if ($SelectedValue) {
$SelectedValue = $Param{ActivityDialogField}->{DefaultValue};
}
}
}
else {
if ( !$SelectedValue ) {
$SelectedValue = $StateObject->StateLookup(
StateID => $Param{ActivityDialogField}->{DefaultValue} || '',
);
}
}
# Get TicketValue
if ( IsHashRefWithData( $Param{Ticket} ) && !$SelectedValue ) {
$SelectedValue = $Param{Ticket}->{State};
}
# set server errors
my $ServerError = '';
if ( IsHashRefWithData( $Param{Error} ) && $Param{Error}->{'StateID'} ) {
$ServerError = 'ServerError';
}
# build next states string
$Data{Content} = $LayoutObject->BuildSelection(
Data => $States,
Name => 'StateID',
Translation => 1,
SelectedValue => $SelectedValue,
Class => "Modernize $ServerError",
);
# set fields that will get an AJAX loader icon when this field changes
$Data{FieldsToUpdate} = $Self->_GetFieldsToUpdateStrg(
TriggerField => 'StateID',
AJAXUpdatableFields => $Param{AJAXUpdatableFields},
);
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:State',
Data => \%Data,
);
# set mandatory label marker
if ( $Data{MandatoryClass} && $Data{MandatoryClass} ne '' ) {
$LayoutObject->Block(
Name => 'LabelSpan',
Data => {},
);
}
if ( $Param{DescriptionShort} ) {
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:State:DescriptionShort',
Data => {
DescriptionShort => $Param{DescriptionShort},
},
);
}
if ( $Param{DescriptionLong} ) {
$LayoutObject->Block(
Name => 'rw:State:DescriptionLong',
Data => {
DescriptionLong => $Param{DescriptionLong},
},
);
}
return {
Success => 1,
HTML => $LayoutObject->Output( TemplateFile => 'ProcessManagement/State' ),
};
}
sub _RenderType {
my ( $Self, %Param ) = @_;
# get layout object
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
for my $Needed (qw(FormID)) {
if ( !$Param{$Needed} ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', $Needed, '_RenderType' ),
};
}
}
if ( !IsHashRefWithData( $Param{ActivityDialogField} ) ) {
return {
Success => 0,
Message => $LayoutObject->{LanguageObject}
->Translate( 'Parameter %s is missing in %s.', 'ActivityDialogField', '_RenderType' ),
};
}
my $Types = $Self->_GetTypes(
%{ $Param{GetParam} },
);
my %Data = (
Label => $LayoutObject->{LanguageObject}->Translate("Type"),
FieldID => 'TypeID',
FormID => $Param{FormID},
MandatoryClass => '',
ValidateRequired => '',
);
# If field is required put in the necessary variables for
# ValidateRequired class input field, Mandatory class for the label
if ( $Param{ActivityDialogField}->{Display} && $Param{ActivityDialogField}->{Display} == 2 ) {
$Data{ValidateRequired} = 'Validate_Required';
$Data{MandatoryClass} = 'Mandatory';
}
my $SelectedValue;
# get type object
my $TypeObject = $Kernel::OM->Get('Kernel::System::Type');
my $TypeIDParam = $Param{GetParam}{TypeID};
if ($TypeIDParam) {
$SelectedValue = $TypeObject->TypeLookup(
TypeID => $TypeIDParam,
);
}
if ( $Param{FieldName} eq 'Type' ) {
if ( !$SelectedValue ) {
# Fetch DefaultValue from Config
if (
defined $Param{ActivityDialogField}->{DefaultValue}
&& $Param{ActivityDialogField}->{DefaultValue} ne ''
)
{
$SelectedValue = $TypeObject->TypeLookup(
Type => $Param{ActivityDialogField}->{DefaultValue},
);
}
if ($SelectedValue) {
$SelectedValue = $Param{ActivityDialogField}->{DefaultValue};
}
}
}
else {
if ( !$SelectedValue ) {
if (
defined $Param{ActivityDialogField}->{DefaultValue}
&& $Param{ActivityDialogField}->{DefaultValue} ne ''
)
{
$SelectedValue = $TypeObject->TypeLookup(
Type => $Param{ActivityDialogField}->{DefaultValue},
);
}
}
}
# Get TicketValue
if ( IsHashRefWithData( $Param{Ticket} ) && !$SelectedValue ) {
$SelectedValue = $Param{Ticket}->{Type};
}
# set server errors
my $ServerError = '';
if ( IsHashRefWithData( $Param{Error} ) && $Param{Error}->{'TypeID'} ) {
$ServerError = 'ServerError';
}
# build Service string
$Data{Content} = $LayoutObject->BuildSelection(
Data => $Types,
Name => 'TypeID',
Class => "Modernize $ServerError",
SelectedValue => $SelectedValue,
PossibleNone => 1,
Sort => 'AlphanumericValue',
Translation => 0,
Max => 200,
);
# set fields that will get an AJAX loader icon when this field changes
$Data{FieldsToUpdate} = $Self->_GetFieldsToUpdateStrg(
TriggerField => 'TypeID',
AJAXUpdatableFields => $Param{AJAXUpdatableFields},
);
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:Type',
Data => \%Data,
);
# set mandatory label marker
if ( $Data{MandatoryClass} && $Data{MandatoryClass} ne '' ) {
$LayoutObject->Block(
Name => 'LabelSpan',
Data => {},
);
}
if ( $Param{DescriptionShort} ) {
$LayoutObject->Block(
Name => $Param{ActivityDialogField}->{LayoutBlock} || 'rw:Type:DescriptionShort',
Data => {
DescriptionShort => $Param{DescriptionShort},
},
);
}
if ( $Param{DescriptionLong} ) {
$LayoutObject->Block(
Name => 'rw:Type:DescriptionLong',
Data => {
DescriptionLong => $Param{DescriptionLong},
},
);
}
return {
Success => 1,
HTML => $LayoutObject->Output( TemplateFile => 'ProcessManagement/Type' ),
};
}
sub _StoreActivityDialog {
my ( $Self, %Param ) = @_;
my $TicketID = $Param{GetParam}{TicketID};
my $ProcessStartpoint;
my %Ticket;
my $ProcessEntityID;
my $ActivityEntityID;
my %Error;
my %ErrorMessages;
my %TicketParam;
# get layout object
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
my $ActivityDialogEntityID = $Param{GetParam}{ActivityDialogEntityID};
if ( !$ActivityDialogEntityID ) {
$LayoutObject->FatalError(
Message => Translatable('ActivityDialogEntityID missing!'),
);
}
# get activity dialog object
my $ActivityDialogObject = $Kernel::OM->Get('Kernel::System::ProcessManagement::ActivityDialog');
my $ActivityDialog = $ActivityDialogObject->ActivityDialogGet(
ActivityDialogEntityID => $ActivityDialogEntityID,
Interface => 'AgentInterface',
);
if ( !IsHashRefWithData($ActivityDialog) ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate(
'Couldn\'t get Config for ActivityDialogEntityID "%s"!',
$ActivityDialogEntityID,
),
);
}
# If is an action about attachments
my $IsUpload = 0;
# get param object
my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request');
# attachment delete
my @AttachmentIDs = map {
my ($ID) = $_ =~ m{ \A AttachmentDelete (\d+) \z }xms;
$ID ? $ID : ();
} $ParamObject->GetParamNames();
# get upload cache object
my $UploadCacheObject = $Kernel::OM->Get('Kernel::System::Web::UploadCache');
COUNT:
for my $Count ( reverse sort @AttachmentIDs ) {
my $Delete = $ParamObject->GetParam( Param => "AttachmentDelete$Count" );
next COUNT if !$Delete;
$UploadCacheObject->FormIDRemoveFile(
FormID => $Self->{FormID},
FileID => $Count,
);
$IsUpload = 1;
$Error{AttachmentDelete} = 1;
}
# attachment upload
if ( $ParamObject->GetParam( Param => 'AttachmentUpload' ) ) {
my %UploadStuff = $ParamObject->GetUploadAll(
Param => 'FileUpload',
);
$UploadCacheObject->FormIDAddFile(
FormID => $Self->{FormID},
Disposition => 'attachment',
%UploadStuff,
);
$IsUpload = 1;
$Error{AttachmentUpload} = 1;
}
my $DynamicField = $Kernel::OM->Get('Kernel::System::DynamicField')->DynamicFieldListGet(
Valid => 1,
ObjectType => 'Ticket',
);
# get dynamic field backend object
my $DynamicFieldBackendObject = $Kernel::OM->Get('Kernel::System::DynamicField::Backend');
if ( !$IsUpload ) {
# check each Field of an Activity Dialog and fill the error hash if something goes horribly wrong
my %CheckedFields;
DIALOGFIELD:
for my $CurrentField ( @{ $ActivityDialog->{FieldOrder} } ) {
if ( $CurrentField =~ m{^DynamicField_(.*)}xms ) {
my $DynamicFieldName = $1;
# Get the Config of the current DynamicField (the first element of the grep result array)
my $DynamicFieldConfig = ( grep { $_->{Name} eq $DynamicFieldName } @{$DynamicField} )[0];
if ( !IsHashRefWithData($DynamicFieldConfig) ) {
my $Message
= "DynamicFieldConfig missing for field: $Param{FieldName}, or is not a Ticket Dynamic Field!";
# log error but does not stop the execution as it could be an old Article
# DynamicField, see bug#11666
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => $Message,
);
next DIALOGFIELD;
}
# Will be extended later on for ACL Checking:
my $PossibleValuesFilter;
# if we have an invisible field, use config's default value
if ( $ActivityDialog->{Fields}{$CurrentField}{Display} == 0 ) {
$TicketParam{$CurrentField} = $ActivityDialog->{Fields}{$CurrentField}{DefaultValue}
|| '';
}
# only validate visible fields
else {
# Check DynamicField Values
my $ValidationResult = $DynamicFieldBackendObject->EditFieldValueValidate(
DynamicFieldConfig => $DynamicFieldConfig,
PossibleValuesFilter => $PossibleValuesFilter,
ParamObject => $ParamObject,
Mandatory => $ActivityDialog->{Fields}{$CurrentField}{Display} == 2,
);
if ( !IsHashRefWithData($ValidationResult) ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate(
'Could not perform validation on field %s!',
$DynamicFieldConfig->{Label},
),
);
}
if ( $ValidationResult->{ServerError} ) {
$Error{ $DynamicFieldConfig->{Name} } = 1;
$ErrorMessages{ $DynamicFieldConfig->{Name} } = $ValidationResult->{ErrorMessage};
}
$TicketParam{$CurrentField} =
$DynamicFieldBackendObject->EditFieldValueGet(
DynamicFieldConfig => $DynamicFieldConfig,
ParamObject => $ParamObject,
LayoutObject => $LayoutObject,
);
}
# In case of DynamicFields there is no NameToID translation
# so just take the DynamicField name
$CheckedFields{$CurrentField} = 1;
}
elsif (
$Self->{NameToID}->{$CurrentField} eq 'CustomerID'
|| $Self->{NameToID}->{$CurrentField} eq 'CustomerUserID'
)
{
next DIALOGFIELD if $CheckedFields{ $Self->{NameToID}{'CustomerID'} };
# is not possible to a have an invisible field for this particular value
# on agent interface
if ( $ActivityDialog->{Fields}{$CurrentField}{Display} == 0 ) {
my $InvisibleFieldMessage = Translatable(
'Couldn\'t use CustomerID as an invisible field. Please contact your system administrator!'
);
$LayoutObject->FatalError(
Message => $InvisibleFieldMessage,
);
}
# CustomerID should not be mandatory as in other screens
$TicketParam{CustomerID} = $Param{GetParam}{CustomerID} || '';
# Unfortunately TicketCreate needs 'CustomerUser' as param instead of 'CustomerUserID'
my $CustomerUserID = $ParamObject->GetParam( Param => 'SelectedCustomerUser' );
# fall-back, if customer auto-complete does not shown any results, then try to use
# the content of the original field as customer user id
if ( !$CustomerUserID ) {
$CustomerUserID = $ParamObject->GetParam( Param => 'CustomerUserID' );
# check email address
for my $Email ( Mail::Address->parse($CustomerUserID) ) {
if (
!$Kernel::OM->Get('Kernel::System::CheckItem')->CheckEmail( Address => $Email->address() )
)
{
$Error{'CustomerUserID'} = 1;
}
}
}
if ( !$CustomerUserID ) {
$Error{'CustomerUserID'} = 1;
}
else {
$TicketParam{CustomerUser} = $CustomerUserID;
}
$CheckedFields{ $Self->{NameToID}{'CustomerID'} } = 1;
$CheckedFields{ $Self->{NameToID}{'CustomerUserID'} } = 1;
}
elsif ( $CurrentField eq 'PendingTime' ) {
my $Prefix = 'PendingTime';
# Make sure we have Values otherwise take an empty string
if (
IsHashRefWithData( $Param{GetParam}{PendingTime} )
&& defined $Param{GetParam}{PendingTime}{Year}
&& defined $Param{GetParam}{PendingTime}{Month}
&& defined $Param{GetParam}{PendingTime}{Day}
&& defined $Param{GetParam}{PendingTime}{Hour}
&& defined $Param{GetParam}{PendingTime}{Minute}
)
{
$TicketParam{$CurrentField} = $Param{GetParam}{PendingTime};
}
# if we have no Pending status we have no time to set
else {
$TicketParam{$CurrentField} = '';
}
$CheckedFields{'PendingTime'} = 1;
}
else {
# skip if we've already checked ID or Name
next DIALOGFIELD if $CheckedFields{ $Self->{NameToID}->{$CurrentField} };
my $Result = $Self->_CheckField(
Field => $Self->{NameToID}->{$CurrentField},
%{ $ActivityDialog->{Fields}{$CurrentField} },
);
if ( !$Result && $ActivityDialog->{Fields}{$CurrentField}->{Display} == 2 ) {
# special case for Article (Subject & Body)
if ( $CurrentField eq 'Article' ) {
for my $ArticlePart (qw(Subject Body)) {
if ( !$Param{GetParam}->{$ArticlePart} ) {
# set error for each part (if any)
$Error{ 'Article' . $ArticlePart } = 1;
}
}
}
# all other fields
else {
$Error{ $Self->{NameToID}->{$CurrentField} } = 1;
}
}
if (
$CurrentField eq 'Article'
&& $ActivityDialog->{Fields}{$CurrentField}->{Config}->{TimeUnits}
&& $ActivityDialog->{Fields}{$CurrentField}->{Config}->{TimeUnits} == 2
)
{
if ( !$Param{GetParam}->{TimeUnits} ) {
# set error for the timeunits (if any)
$Error{'TimeUnits'} = 1;
}
}
elsif ($Result) {
$TicketParam{ $Self->{NameToID}->{$CurrentField} } = $Result;
}
$CheckedFields{ $Self->{NameToID}->{$CurrentField} } = 1;
}
}
}
# create process object
$Kernel::OM->ObjectParamAdd(
'Kernel::System::ProcessManagement::Process' => {
ActivityObject => $Kernel::OM->Get('Kernel::System::ProcessManagement::Activity'),
ActivityDialogObject => $ActivityDialogObject,
TransitionObject => $Kernel::OM->Get('Kernel::System::ProcessManagement::Transition'),
TransitionActionObject => $Kernel::OM->Get('Kernel::System::ProcessManagement::TransitionAction'),
}
);
my $ProcessObject = $Kernel::OM->Get('Kernel::System::ProcessManagement::Process');
# get ticket object
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
my $NewTicketID;
if ( !$TicketID ) {
$ProcessEntityID = $Param{GetParam}{ProcessEntityID};
if ( !$ProcessEntityID )
{
return $LayoutObject->FatalError(
Message => Translatable('Missing ProcessEntityID, check your ActivityDialogHeader.tt!'),
);
}
$ProcessStartpoint = $ProcessObject->ProcessStartpointGet(
ProcessEntityID => $Param{ProcessEntityID},
);
if (
!$ProcessStartpoint
|| !IsHashRefWithData($ProcessStartpoint)
|| !$ProcessStartpoint->{Activity} || !$ProcessStartpoint->{ActivityDialog}
)
{
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate(
'No StartActivityDialog or StartActivityDialog for Process "%s" configured!',
$Param{ProcessEntityID},
),
);
}
$ActivityEntityID = $ProcessStartpoint->{Activity};
NEEDEDLOOP:
for my $Needed (qw(Queue State Lock Priority)) {
if ( !$TicketParam{ $Self->{NameToID}->{$Needed} } ) {
# if a required field has no value call _CheckField as filed is hidden
# (No Display param = Display => 0) and no DefaultValue, to use global default as
# fallback. One reason for this to happen is that ActivityDialog DefaultValue tried
# to set before, was not valid.
my $Result = $Self->_CheckField(
Field => $Self->{NameToID}->{$Needed},
);
if ( !$Result ) {
$Error{ $Self->{NameToID}->{$Needed} } = ' ServerError';
}
elsif ($Result) {
$TicketParam{ $Self->{NameToID}->{$Needed} } = $Result;
}
}
}
# If we had no Errors, we can create the Ticket and Set ActivityEntityID as well as
# ProcessEntityID
if ( !IsHashRefWithData( \%Error ) ) {
$TicketParam{UserID} = $Self->{UserID};
if ( !$TicketParam{OwnerID} ) {
$TicketParam{OwnerID} = $Param{GetParam}{OwnerID} || 1;
}
# if StartActivityDialog does not provide a ticket title set a default value
if ( !$TicketParam{Title} ) {
# get the current server Time-stamp
my $CurrentTimeStamp = $Kernel::OM->Get('Kernel::System::Time')->CurrentTimestamp();
$TicketParam{Title} = "$Param{ProcessName} - $CurrentTimeStamp";
# use article subject from the web request if any
if ( IsStringWithData( $Param{GetParam}->{Subject} ) ) {
$TicketParam{Title} = $Param{GetParam}->{Subject};
}
}
# create a new ticket
$TicketID = $TicketObject->TicketCreate(%TicketParam);
if ( !$TicketID ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate(
'Couldn\'t create ticket for Process with ProcessEntityID "%s"!',
$Param{ProcessEntityID},
),
);
}
my $Success = $ProcessObject->ProcessTicketProcessSet(
ProcessEntityID => $Param{ProcessEntityID},
TicketID => $TicketID,
UserID => $Self->{UserID},
);
if ( !$Success ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate(
'Couldn\'t set ProcessEntityID "%s" on TicketID "%s"!',
$Param{ProcessEntityID},
$TicketID,
),
);
}
$Success = undef;
$Success = $ProcessObject->ProcessTicketActivitySet(
ProcessEntityID => $Param{ProcessEntityID},
ActivityEntityID => $ProcessStartpoint->{Activity},
TicketID => $TicketID,
UserID => $Self->{UserID},
);
if ( !$Success ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate(
'Couldn\'t set ActivityEntityID "%s" on TicketID "%s"!',
$Param{ProcessEntityID},
$TicketID,
),
Comment => Translatable('Please contact the admin.'),
);
}
%Ticket = $TicketObject->TicketGet(
TicketID => $TicketID,
UserID => $Self->{UserID},
DynamicFields => 1,
);
if ( !IsHashRefWithData( \%Ticket ) ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate(
'Could not store ActivityDialog, invalid TicketID: %s!',
$TicketID,
),
Comment => Translatable('Please contact the admin.'),
);
}
for my $DynamicFieldConfig (
# 2. remove "DynamicField_" from string
map {
my $Field = $_;
$Field =~ s{^DynamicField_(.*)}{$1}xms;
# 3. grep from the DynamicFieldConfigs the resulting DynamicFields without
# "DynamicField_"
grep { $_->{Name} eq $Field } @{$DynamicField}
}
# 1. grep all DynamicFields
grep {m{^DynamicField_(.*)}xms} @{ $ActivityDialog->{FieldOrder} }
)
{
# and now it's easy, just store the dynamic Field Values ;)
$DynamicFieldBackendObject->ValueSet(
DynamicFieldConfig => $DynamicFieldConfig,
ObjectID => $TicketID,
Value => $TicketParam{ 'DynamicField_' . $DynamicFieldConfig->{Name} },
UserID => $Self->{UserID},
);
}
# remember new created TicketID
$NewTicketID = $TicketID;
}
}
elsif ( $TicketID && $Self->{IsProcessEnroll} ) {
# use Error instead of FatalError as we are in a Pop-up window
# Get Ticket to check TicketID was valid
%Ticket = $TicketObject->TicketGet(
TicketID => $TicketID,
UserID => $Self->{UserID},
DynamicFields => 0,
);
if ( !IsHashRefWithData( \%Ticket ) ) {
$LayoutObject->Error(
Message => $LayoutObject->{LanguageObject}->Translate( 'Invalid TicketID: %s!', $TicketID ),
);
}
my $Success = $ProcessObject->ProcessTicketProcessSet(
ProcessEntityID => $Param{ProcessEntityID},
TicketID => $TicketID,
UserID => $Self->{UserID},
);
if ( !$Success ) {
$LayoutObject->Error(
Message => $LayoutObject->{LanguageObject}->Translate(
'Couldn\'t set ProcessEntityID "%s" on TicketID "%s"!',
$Param{ProcessEntityID},
$TicketID,
),
);
}
$Success = undef;
$ProcessStartpoint = $ProcessObject->ProcessStartpointGet(
ProcessEntityID => $Param{ProcessEntityID},
);
if (
!$ProcessStartpoint
|| !IsHashRefWithData($ProcessStartpoint)
|| !$ProcessStartpoint->{Activity} || !$ProcessStartpoint->{ActivityDialog}
)
{
$LayoutObject->Error(
Message => $LayoutObject->{LanguageObject}->Translate(
'No StartActivityDialog or StartActivityDialog for Process "%s" configured!',
$Param{ProcessEntityID},
),
);
}
$Success = $ProcessObject->ProcessTicketActivitySet(
ProcessEntityID => $Param{ProcessEntityID},
ActivityEntityID => $ProcessStartpoint->{Activity},
TicketID => $TicketID,
UserID => $Self->{UserID},
);
if ( !$Success ) {
$LayoutObject->Error(
Message => $LayoutObject->{LanguageObject}->Translate(
'Couldn\'t set ActivityEntityID "%s" on TicketID "%s"!',
$Param{ProcessEntityID},
$TicketID,
),
Comment => Translatable('Please contact the admin.'),
);
}
# use ProcessEntityID from the web request
$ProcessEntityID = $Param{ProcessEntityID};
# Check if we deal with a Ticket Update
my $UpdateTicketID = $TicketID;
}
# If we had a TicketID, get the Ticket
else {
# Get Ticket to check TicketID was valid
%Ticket = $TicketObject->TicketGet(
TicketID => $TicketID,
UserID => $Self->{UserID},
DynamicFields => 1,
);
if ( !IsHashRefWithData( \%Ticket ) ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate(
'Could not store ActivityDialog, invalid TicketID: %s!',
$TicketID,
),
);
}
# get config object
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
$ActivityEntityID = $Ticket{
'DynamicField_'
. $ConfigObject->Get('Process::DynamicFieldProcessManagementActivityID')
};
if ( !$ActivityEntityID )
{
return $LayoutObject->ErrorScreen(
Message => $LayoutObject->{LanguageObject}->Translate(
'Missing ActivityEntityID in Ticket %s!',
$Ticket{TicketID},
),
Comment => Translatable('Please contact the admin.'),
);
}
$ProcessEntityID = $Ticket{
'DynamicField_'
. $ConfigObject->Get('Process::DynamicFieldProcessManagementProcessID')
};
if ( !$ProcessEntityID )
{
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate(
'Missing ProcessEntityID in Ticket %s!',
$Ticket{TicketID},
),
);
}
}
# if we got errors go back to displaying the ActivityDialog
if ( $IsUpload || IsHashRefWithData( \%Error ) ) {
return $Self->_OutputActivityDialog(
ProcessEntityID => $ProcessEntityID,
TicketID => $TicketID || undef,
ActivityDialogEntityID => $ActivityDialogEntityID,
Error => \%Error,
ErrorMessages => \%ErrorMessages,
GetParam => $Param{GetParam},
IsUpload => $IsUpload,
);
}
# Check if we deal with a Ticket Update
my $UpdateTicketID = $Param{GetParam}{TicketID};
# We save only once, no matter if one or more configs are set for the same param
my %StoredFields;
# Save loop for storing Ticket Values that were not required on the initial TicketCreate
DIALOGFIELD:
for my $CurrentField ( @{ $ActivityDialog->{FieldOrder} } ) {
if ( !IsHashRefWithData( $ActivityDialog->{Fields}{$CurrentField} ) ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate(
'Can\'t get data for Field "%s" of ActivityDialog "%s"!',
$CurrentField,
$ActivityDialogEntityID,
),
);
}
if ( $CurrentField =~ m{^DynamicField_(.*)}xms ) {
my $DynamicFieldName = $1;
my $DynamicFieldConfig = ( grep { $_->{Name} eq $DynamicFieldName } @{$DynamicField} )[0];
if ( !IsHashRefWithData($DynamicFieldConfig) ) {
my $Message
= "DynamicFieldConfig missing for field: $Param{FieldName}, or is not a Ticket Dynamic Field!";
# log error but does not stop the execution as it could be an old Article
# DynamicField, see bug#11666
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => $Message,
);
next DIALOGFIELD;
}
my $Success = $DynamicFieldBackendObject->ValueSet(
DynamicFieldConfig => $DynamicFieldConfig,
ObjectID => $TicketID,
Value => $TicketParam{$CurrentField},
UserID => $Self->{UserID},
);
if ( !$Success ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate(
'Could not set DynamicField value for %s of Ticket with ID "%s" in ActivityDialog "%s"!',
$CurrentField,
$TicketID,
$ActivityDialogEntityID,
),
);
}
}
elsif ( $CurrentField eq 'PendingTime' ) {
# This Value is just set if Status was on a Pending state
# so it has to be possible to store the ticket if this one's empty
if ( IsHashRefWithData( $TicketParam{'PendingTime'} ) ) {
my $Success = $TicketObject->TicketPendingTimeSet(
UserID => $Self->{UserID},
TicketID => $TicketID,
%{ $TicketParam{'PendingTime'} },
);
if ( !$Success ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate(
'Could not set PendingTime for Ticket with ID "%s" in ActivityDialog "%s"!',
$TicketID,
$ActivityDialogEntityID,
),
);
}
}
}
elsif ( $CurrentField eq 'Article' && ( $UpdateTicketID || $NewTicketID ) ) {
my $TicketID = $UpdateTicketID || $NewTicketID;
if ( $Param{GetParam}{Subject} && $Param{GetParam}{Body} ) {
# add note
my $ArticleID = '';
my $MimeType = 'text/plain';
if ( $LayoutObject->{BrowserRichText} ) {
$MimeType = 'text/html';
# verify html document
$Param{GetParam}{Body} = $LayoutObject->RichTextDocumentComplete(
String => $Param{GetParam}{Body},
);
}
my $From = "$Self->{UserFirstname} $Self->{UserLastname} <$Self->{UserEmail}>";
$ArticleID = $TicketObject->ArticleCreate(
TicketID => $TicketID,
SenderType => 'agent',
From => $From,
MimeType => $MimeType,
Charset => $LayoutObject->{UserCharset},
UserID => $Self->{UserID},
HistoryType => 'AddNote',
HistoryComment => '%%Note',
Body => $Param{GetParam}{Body},
Subject => $Param{GetParam}{Subject},
ArticleType => $ActivityDialog->{Fields}->{Article}->{Config}->{ArticleType},
ForceNotificationToUserID => $ActivityDialog->{Fields}->{Article}->{Config}->{InformAgents}
? $Param{GetParam}{InformUserID}
: [],
);
if ( !$ArticleID ) {
return $LayoutObject->ErrorScreen();
}
# get pre loaded attachment
my @Attachments = $UploadCacheObject->FormIDGetAllFilesData(
FormID => $Self->{FormID},
);
# get submit attachment
my %UploadStuff = $ParamObject->GetUploadAll(
Param => 'FileUpload',
);
if (%UploadStuff) {
push @Attachments, \%UploadStuff;
}
# write attachments
ATTACHMENT:
for my $Attachment (@Attachments) {
# skip, deleted not used inline images
my $ContentID = $Attachment->{ContentID};
if (
$ContentID
&& ( $Attachment->{ContentType} =~ /image/i )
&& ( $Attachment->{Disposition} eq 'inline' )
)
{
my $ContentIDHTMLQuote = $LayoutObject->Ascii2Html(
Text => $ContentID,
);
# workaround for link encode of rich text editor, see bug#5053
my $ContentIDLinkEncode = $LayoutObject->LinkEncode($ContentID);
$Param{GetParam}{Body} =~ s/(ContentID=)$ContentIDLinkEncode/$1$ContentID/g;
# ignore attachment if not linked in body
if ( $Param{GetParam}{Body} !~ /(\Q$ContentIDHTMLQuote\E|\Q$ContentID\E)/i )
{
next ATTACHMENT;
}
}
# write existing file to backend
$TicketObject->ArticleWriteAttachment(
%{$Attachment},
ArticleID => $ArticleID,
UserID => $Self->{UserID},
);
}
# remove pre submitted attachments
$UploadCacheObject->FormIDRemove( FormID => $Self->{FormID} );
# time accounting
if ( $Param{GetParam}{TimeUnits} ) {
$TicketObject->TicketAccountTime(
TicketID => $TicketID,
ArticleID => $ArticleID,
TimeUnit => $Param{GetParam}{TimeUnits},
UserID => $Self->{UserID},
);
}
}
}
# If we have to Update a ticket, update the transmitted values
elsif ($UpdateTicketID) {
my $Success;
if ( $Self->{NameToID}{$CurrentField} eq 'Title' ) {
# if there is no title, nothing is needed to be done
if (
!defined $TicketParam{'Title'}
|| ( defined $TicketParam{'Title'} && $TicketParam{'Title'} eq '' )
)
{
$Success = 1;
}
# otherwise set the ticket title
else {
$Success = $TicketObject->TicketTitleUpdate(
Title => $TicketParam{'Title'},
TicketID => $TicketID,
UserID => $Self->{UserID},
);
}
}
elsif (
(
$Self->{NameToID}{$CurrentField} eq 'CustomerID'
|| $Self->{NameToID}{$CurrentField} eq 'CustomerUserID'
)
)
{
next DIALOGFIELD if $StoredFields{ $Self->{NameToID}{$CurrentField} };
if ( $ActivityDialog->{Fields}{$CurrentField}{Display} == 1 ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate(
'Wrong ActivityDialog Field config: %s can\'t be Display => 1 / Show field (Please change its configuration to be Display => 0 / Do not show field or Display => 2 / Show field as mandatory)!',
$CurrentField,
),
);
}
# skip TicketCustomerSet() if there is no change in the customer
if (
$Ticket{CustomerID} eq $TicketParam{CustomerID}
&& $Ticket{CustomerUserID} eq $TicketParam{CustomerUser}
)
{
# In this case we don't want to call any additional stores
# on Customer, CustomerNo, CustomerID or CustomerUserID
# so make sure both fields are set to "Stored" ;)
$StoredFields{ $Self->{NameToID}{'CustomerID'} } = 1;
$StoredFields{ $Self->{NameToID}{'CustomerUserID'} } = 1;
next DIALOGFIELD;
}
$Success = $TicketObject->TicketCustomerSet(
No => $TicketParam{CustomerID},
# here too: unfortunately TicketCreate takes Param 'CustomerUser'
# instead of CustomerUserID, so our TicketParam hash
# has the CustomerUser Key instead of 'CustomerUserID'
User => $TicketParam{CustomerUser},
TicketID => $TicketID,
UserID => $Self->{UserID},
);
# In this case we don't want to call any additional stores
# on Customer, CustomerNo, CustomerID or CustomerUserID
# so make sure both fields are set to "Stored" ;)
$StoredFields{ $Self->{NameToID}{'CustomerID'} } = 1;
$StoredFields{ $Self->{NameToID}{'CustomerUserID'} } = 1;
}
else {
next DIALOGFIELD if $StoredFields{ $Self->{NameToID}{$CurrentField} };
my $TicketFieldSetSub = $CurrentField;
$TicketFieldSetSub =~ s{ID$}{}xms;
$TicketFieldSetSub = 'Ticket' . $TicketFieldSetSub . 'Set';
if ( $TicketObject->can($TicketFieldSetSub) )
{
my $UpdateFieldName;
# sadly we need an exception for Owner(ID) and Responsible(ID), because the
# Ticket*Set subs need NewUserID as param
if (
scalar grep { $Self->{NameToID}{$CurrentField} eq $_ }
qw( OwnerID ResponsibleID )
)
{
$UpdateFieldName = 'NewUserID';
}
else {
$UpdateFieldName = $Self->{NameToID}{$CurrentField};
}
# to store if the field needs to be updated
my $FieldUpdate;
# only Service and SLA fields accepts empty values if the hash key is not
# defined set it to empty so the Ticket*Set function call will get the empty
# value
if (
( $UpdateFieldName eq 'ServiceID' || $UpdateFieldName eq 'SLAID' )
&& !defined $TicketParam{ $Self->{NameToID}{$CurrentField} }
)
{
$TicketParam{ $Self->{NameToID}{$CurrentField} } = '';
$FieldUpdate = 1;
}
# update Service an SLA fields if they have a defined value (even empty)
elsif ( $UpdateFieldName eq 'ServiceID' || $UpdateFieldName eq 'SLAID' )
{
$FieldUpdate = 1;
}
# update any other field that its value is defined and not empty
elsif (
$UpdateFieldName ne 'ServiceID'
&& $UpdateFieldName ne 'SLAID'
&& defined $TicketParam{ $Self->{NameToID}{$CurrentField} }
&& $TicketParam{ $Self->{NameToID}{$CurrentField} } ne ''
)
{
$FieldUpdate = 1;
}
$Success = 1;
# check if field needs to be updated
if ($FieldUpdate) {
$Success = $TicketObject->$TicketFieldSetSub(
$UpdateFieldName => $TicketParam{ $Self->{NameToID}{$CurrentField} },
TicketID => $TicketID,
UserID => $Self->{UserID},
);
# in case of a new service and no new SLA is to be set, check if current
# assigned SLA is still valid
if (
$UpdateFieldName eq 'ServiceID'
&& !defined $TicketParam{SLAID}
)
{
# get ticket details
my %Ticket = $TicketObject->TicketGet(
TicketID => $TicketID,
DynamicFields => 0,
UserID => $Self->{UserID},
);
# if ticket already have an SLA assigned get the list SLAs for the new
# service
if ( IsPositiveInteger( $Ticket{SLAID} ) ) {
my %SLAList = $Kernel::OM->Get('Kernel::System::SLA')->SLAList(
ServiceID => $TicketParam{ $Self->{NameToID}{$CurrentField} },
UserID => $Self->{UserID},
);
# if the current SLA is not in the list of SLA for new service
# remove SLA from ticket
if ( !$SLAList{ $Ticket{SLAID} } ) {
$TicketObject->TicketSLASet(
SLAID => '',
TicketID => $TicketID,
UserID => $Self->{UserID},
);
}
}
}
}
}
}
if ( !$Success ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate(
'Could not set %s for Ticket with ID "%s" in ActivityDialog "%s"!',
$CurrentField,
$TicketID,
$ActivityDialogEntityID,
),
);
}
}
}
# Transitions will be handled by ticket event module (TicketProcessTransitions.pm).
# if we were updating a ticket, close the pop-up and return to zoom
# else (new ticket) just go to zoom to show the new ticket
if ($UpdateTicketID) {
# load new URL in parent window and close pop-up
return $LayoutObject->PopupClose(
URL => "Action=AgentTicketZoom;TicketID=$UpdateTicketID",
);
}
return $LayoutObject->Redirect(
OP => "Action=AgentTicketZoom;TicketID=$TicketID",
);
}
sub _DisplayProcessList {
my ( $Self, %Param ) = @_;
# If we have a ProcessEntityID
$Param{Errors}->{ProcessEntityIDInvalid} = ' ServerError'
if ( $Param{ProcessEntityID} && !$Param{ProcessList}->{ $Param{ProcessEntityID} } );
# get layout object
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
$Param{ProcessList} = $LayoutObject->BuildSelection(
Class => 'Modernize Validate_Required' . ( $Param{Errors}->{ProcessEntityIDInvalid} || ' ' ),
Data => $Param{ProcessList},
Name => 'ProcessEntityID',
SelectedID => $Param{ProcessEntityID},
PossibleNone => 1,
Sort => 'AlphanumericValue',
Translation => 0,
AutoComplete => 'off',
);
# add rich text editor
if ( $LayoutObject->{BrowserRichText} ) {
# use height/width defined for this screen
$Param{RichTextHeight} = $Self->{Config}->{RichTextHeight} || 0;
$Param{RichTextWidth} = $Self->{Config}->{RichTextWidth} || 0;
$LayoutObject->Block(
Name => 'RichText',
Data => \%Param,
);
}
if ( $Param{PreSelectProcess} && $Param{ProcessID} ) {
$LayoutObject->Block(
Name => 'PreSelectProcess',
Data => {
ProcessID => $Param{ProcessID},
},
);
}
$LayoutObject->Block(
Name => 'ProcessList',
Data => {
%Param,
FormID => $Self->{FormID},
},
);
# on initial screen from navbar there is no IsMainWinow but also no IsProcessEnroll,
# then it must be a MainWindow
if ( !$Self->{IsMainWindow} && !$Self->{IsProcessEnroll} ) {
$Self->{IsMainWindow} = 1;
}
my $Type = $Self->{IsMainWindow} ? '' : 'Small';
my $Output = $LayoutObject->Header(
Type => $Type,
);
if ( $Self->{IsMainWindow} ) {
$Output .= $LayoutObject->NavigationBar();
}
$Output .= $LayoutObject->Output(
TemplateFile => 'AgentTicketProcess' . $Type,
Data => {
%Param,
FormID => $Self->{FormID},
IsProcessEnroll => $Self->{IsProcessEnroll},
},
);
# workaround when activity dialog is loaded by AJAX as first activity dialog, if there is
# a date field like Pending Time or Dynamic Fields Date/Time or Date, there is no way to set
# this options in the footer again
$LayoutObject->{HasDatepicker} = 1;
$Output .= $LayoutObject->Footer( Type => $Type );
return $Output;
}
=cut
_CheckField()
checks all the possible ticket fields and returns the ID (if possible) value of the field, if valid
and checks are successful
if Display param is set to 0 or not given, it uses ActivityDialog field default value for all fields
or global default value as fall-back only for certain fields
if Display param is set to 1 or 2 it uses the value from the web request
my $PriorityID = $AgentTicketProcessObject->_CheckField(
Field => 'PriorityID',
Display => 1, # optional, 0 or 1 or 2
DefaultValue => '3 normal', # ActivityDialog field default value (it uses global
# default value as fall back for mandatory fields
# (Queue, Sate, Lock and Priority)
);
Returns:
$PriorityID = 1; # if PriorityID is set to 1 in the web request
my $PriorityID = $AgentTicketProcessObject->_CheckField(
Field => 'PriorityID',
Display => 0,
DefaultValue => '3 normal',
);
Returns:
$PriorityID = 3; # since ActivityDialog default value is '3 normal' and
# field is hidden
=cut
sub _CheckField {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Needed (qw(Field)) {
if ( !$Param{$Needed} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Needed!"
);
return;
}
}
# remove the ID and check if the given field is required for creating a ticket
my $FieldWithoutID = $Param{Field};
$FieldWithoutID =~ s{ID$}{}xms;
my $TicketRequiredField = scalar grep { $_ eq $FieldWithoutID } qw(Queue State Lock Priority);
my $Value;
# get needed objects
my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request');
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
# if no Display (or Display == 0) is committed
if ( !$Param{Display} ) {
# Check if a DefaultValue is given
if ( $Param{DefaultValue} ) {
# check if the given field param is valid
$Value = $Self->_LookupValue(
Field => $FieldWithoutID,
Value => $Param{DefaultValue},
);
}
# if we got a required ticket field, check if we got a valid DefaultValue in the SysConfig
if ( !$Value && $TicketRequiredField ) {
$Value = $Kernel::OM->Get('Kernel::Config')->Get("Process::Default$FieldWithoutID");
if ( !$Value ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate(
'Default Config for Process::Default%s missing!',
$FieldWithoutID,
),
);
}
else {
# check if the given field param is valid
$Value = $Self->_LookupValue(
Field => $FieldWithoutID,
Value => $Value,
);
if ( !$Value ) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate(
'Default Config for Process::Default%s invalid!',
$FieldWithoutID,
),
);
}
}
}
}
elsif ( $Param{Display} == 1 ) {
# Display == 1 is logicality not possible for a ticket required field
if ($TicketRequiredField) {
$LayoutObject->FatalError(
Message => $LayoutObject->{LanguageObject}->Translate(
'Wrong ActivityDialog Field config: %s can\'t be Display => 1 / Show field (Please change its configuration to be Display => 0 / Do not show field or Display => 2 / Show field as mandatory)!',
$Param{Field},
),
);
}
# check if the given field param is valid
if ( $Param{Field} eq 'Article' ) {
# in case of article fields we need to fake a value
$Value = 1;
}
else {
$Value = $Self->_LookupValue(
Field => $Param{Field},
Value => $ParamObject->GetParam( Param => $Param{Field} ) || '',
);
}
}
elsif ( $Param{Display} == 2 ) {
# check if the given field param is valid
if ( $Param{Field} eq 'Article' ) {
my ( $Body, $Subject ) = (
$ParamObject->GetParam( Param => 'Body' ),
$ParamObject->GetParam( Param => 'Subject' )
);
$Value = 0;
if ( $Body && $Subject ) {
$Value = 1;
}
}
else {
$Value = $Self->_LookupValue(
Field => $Param{Field},
Value => $ParamObject->GetParam( Param => $Param{Field} ) || '',
);
}
}
return $Value;
}
=cut
_LookupValue()
returns the ID (if possible) of nearly all ticket fields and/or checks if its valid.
Can handle IDs or Strings.
Currently working with: State, Queue, Lock, Priority (possible more).
my $PriorityID = $AgentTicketProcessObject->_LookupValue(
PriorityID => 1,
);
$PriorityID = 1;
my $StateID = $AgentTicketProcessObject->_LookupValue(
State => 'open',
);
$StateID = 3;
my $PriorityID = $AgentTicketProcessObject->_LookupValue(
Priority => 'unknownpriority1234',
);
$PriorityID = undef;
=cut
sub _LookupValue {
my ( $Self, %Param ) = @_;
# get log object
my $LogObject = $Kernel::OM->Get('Kernel::System::Log');
# check needed stuff
for my $Needed (qw(Field Value)) {
if ( !defined $Param{$Needed} ) {
$LogObject->Log(
Priority => 'error',
Message => "Need $Needed!"
);
return;
}
}
if ( !$Param{Field} ) {
$LogObject->Log(
Priority => 'error',
Message => "Field should not be empty!"
);
return;
}
# if there is no value, there is nothing to do
return if !$Param{Value};
# remove the ID for function name purpose
my $FieldWithoutID = $Param{Field};
$FieldWithoutID =~ s{ID$}{}xms;
my $LookupFieldName;
my $ObjectName;
my $FunctionName;
# owner(ID) and responsible(ID) lookup needs UserID as parameter
if ( scalar grep { $Param{Field} eq $_ } qw( OwnerID ResponsibleID ) ) {
$LookupFieldName = 'UserID';
$ObjectName = 'User';
$FunctionName = 'UserLookup';
}
# owner and responsible lookup needs UserLogin as parameter
elsif ( scalar grep { $Param{Field} eq $_ } qw( Owner Responsible ) ) {
$LookupFieldName = 'UserLogin';
$ObjectName = 'User';
$FunctionName = 'UserLookup';
}
# service and SLA lookup needs Name as parameter (While ServiceID an SLAID uses standard)
elsif ( scalar grep { $Param{Field} eq $_ } qw( Service SLA ) ) {
$LookupFieldName = 'Name';
$ObjectName = $FieldWithoutID;
$FunctionName = $FieldWithoutID . 'Lookup';
}
# other fields can use standard parameter names as Priority or PriorityID
else {
$LookupFieldName = $Param{Field};
$ObjectName = $FieldWithoutID;
$FunctionName = $FieldWithoutID . 'Lookup';
}
# get appropriate object of field
my $FieldObject;
if ( $Kernel::OM->Get('Kernel::System::Main')->Require( 'Kernel::System::' . $ObjectName, Silent => 1 ) ) {
$FieldObject = $Kernel::OM->Get( 'Kernel::System::' . $ObjectName );
}
my $Value;
# check if the backend module has the needed *Lookup sub
if ( $FieldObject && $FieldObject->can($FunctionName) ) {
# call the *Lookup sub and get the value
$Value = $FieldObject->$FunctionName(
$LookupFieldName => $Param{Value},
);
}
# if we didn't have an object and the value has no ref a string e.g. Title and so on
# return true
elsif ( $Param{Field} eq $FieldWithoutID && !ref $Param{Value} ) {
return $Param{Value};
}
else {
$LogObject->Log(
Priority => 'error',
Message => "Error while checking with " . $FieldWithoutID . "Object!"
);
return;
}
return if ( !$Value );
# return the given ID value if the *Lookup result was a string
if ( $Param{Field} ne $FieldWithoutID ) {
return $Param{Value};
}
# return the *Lookup string return value
return $Value;
}
sub _GetResponsibles {
my ( $Self, %Param ) = @_;
# get users
my %ShownUsers;
my %AllGroupsMembers = $Kernel::OM->Get('Kernel::System::User')->UserList(
Type => 'Long',
Valid => 1,
);
# get needed objects
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
my $QueueObject = $Kernel::OM->Get('Kernel::System::Queue');
my $GroupObject = $Kernel::OM->Get('Kernel::System::Group');
# if we are updating a ticket show the full list of possible responsibles
if ( $Param{TicketID} ) {
if ( $Param{QueueID} && !$Param{AllUsers} ) {
my $GID = $QueueObject->GetQueueGroupID( QueueID => $Param{QueueID} );
my %MemberList = $GroupObject->PermissionGroupGet(
GroupID => $GID,
Type => 'responsible',
);
for my $UserID ( sort keys %MemberList ) {
$ShownUsers{$UserID} = $AllGroupsMembers{$UserID};
}
}
}
else {
# get config object
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
# the StartActivityDialog does not provide a TicketID and it could be that also there
# is no QueueID information. Get the default QueueID for this matters.
if ( !$Param{QueueID} ) {
my $Queue = $ConfigObject->Get("Process::DefaultQueue");
my $QueueID = $QueueObject->QueueLookup( Queue => $Queue );
if ($QueueID) {
$Param{QueueID} = $QueueID;
}
}
# just show only users with selected custom queue
if ( $Param{QueueID} && !$Param{ResponsibleAll} ) {
my @UserIDs = $TicketObject->GetSubscribedUserIDsByQueueID(%Param);
for my $KeyGroupMember ( sort keys %AllGroupsMembers ) {
my $Hit = 0;
for my $UID (@UserIDs) {
if ( $UID eq $KeyGroupMember ) {
$Hit = 1;
}
}
if ( !$Hit ) {
delete $AllGroupsMembers{$KeyGroupMember};
}
}
}
# show all system users
if ( $ConfigObject->Get('Ticket::ChangeOwnerToEveryone') ) {
%ShownUsers = %AllGroupsMembers;
}
# show all users who are rw in the queue group
elsif ( $Param{QueueID} ) {
my $GID = $QueueObject->GetQueueGroupID( QueueID => $Param{QueueID} );
my %MemberList = $GroupObject->PermissionGroupGet(
GroupID => $GID,
Type => 'responsible',
);
for my $KeyMember ( sort keys %MemberList ) {
if ( $AllGroupsMembers{$KeyMember} ) {
$ShownUsers{$KeyMember} = $AllGroupsMembers{$KeyMember};
}
}
}
}
# workflow
my $ACL = $TicketObject->TicketAcl(
%Param,
Action => $Self->{Action},
ReturnType => 'Ticket',
ReturnSubType => 'Responsible',
Data => \%ShownUsers,
UserID => $Self->{UserID},
);
return { $TicketObject->TicketAclData() } if $ACL;
return \%ShownUsers;
}
sub _GetOwners {
my ( $Self, %Param ) = @_;
# get users
my %ShownUsers;
my %AllGroupsMembers = $Kernel::OM->Get('Kernel::System::User')->UserList(
Type => 'Long',
Valid => 1,
);
# get needed objects
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
my $QueueObject = $Kernel::OM->Get('Kernel::System::Queue');
my $GroupObject = $Kernel::OM->Get('Kernel::System::Group');
# if we are updating a ticket show the full list of possible owners
if ( $Param{TicketID} ) {
if ( $Param{QueueID} && !$Param{AllUsers} ) {
my $GID = $QueueObject->GetQueueGroupID( QueueID => $Param{QueueID} );
my %MemberList = $GroupObject->PermissionGroupGet(
GroupID => $GID,
Type => 'owner',
);
for my $UserID ( sort keys %MemberList ) {
$ShownUsers{$UserID} = $AllGroupsMembers{$UserID};
}
}
}
else {
# get config object
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
# the StartActivityDialog does not provide a TicketID and it could be that also there
# is no QueueID information. Get the default QueueID for this matters.
if ( !$Param{QueueID} ) {
my $Queue = $ConfigObject->Get("Process::DefaultQueue");
my $QueueID = $QueueObject->QueueLookup( Queue => $Queue );
if ($QueueID) {
$Param{QueueID} = $QueueID;
}
}
# just show only users with selected custom queue
if ( $Param{QueueID} && !$Param{OwnerAll} ) {
my @UserIDs = $TicketObject->GetSubscribedUserIDsByQueueID(%Param);
for my $KeyGroupMember ( sort keys %AllGroupsMembers ) {
my $Hit = 0;
for my $UID (@UserIDs) {
if ( $UID eq $KeyGroupMember ) {
$Hit = 1;
}
}
if ( !$Hit ) {
delete $AllGroupsMembers{$KeyGroupMember};
}
}
}
# show all system users
if ( $ConfigObject->Get('Ticket::ChangeOwnerToEveryone') ) {
%ShownUsers = %AllGroupsMembers;
}
# show all users who are rw in the queue group
elsif ( $Param{QueueID} ) {
my $GID = $QueueObject->GetQueueGroupID( QueueID => $Param{QueueID} );
my %MemberList = $GroupObject->PermissionGroupGet(
GroupID => $GID,
Type => 'owner',
);
for my $KeyMember ( sort keys %MemberList ) {
if ( $AllGroupsMembers{$KeyMember} ) {
$ShownUsers{$KeyMember} = $AllGroupsMembers{$KeyMember};
}
}
}
}
# workflow
my $ACL = $TicketObject->TicketAcl(
%Param,
Action => $Self->{Action},
ReturnType => 'Ticket',
ReturnSubType => 'Owner',
Data => \%ShownUsers,
UserID => $Self->{UserID},
);
return { $TicketObject->TicketAclData() } if $ACL;
return \%ShownUsers;
}
sub _GetSLAs {
my ( $Self, %Param ) = @_;
# get sla
my %SLA;
if ( $Param{ServiceID} && $Param{Services} && %{ $Param{Services} } ) {
if ( $Param{Services}->{ $Param{ServiceID} } ) {
%SLA = $Kernel::OM->Get('Kernel::System::Ticket')->TicketSLAList(
%Param,
Action => $Self->{Action},
UserID => $Self->{UserID},
);
}
}
return \%SLA;
}
sub _GetServices {
my ( $Self, %Param ) = @_;
# get service
my %Service;
# check needed
return \%Service if !$Param{QueueID} && !$Param{TicketID};
# get options for default services for unknown customers
my $DefaultServiceUnknownCustomer
= $Kernel::OM->Get('Kernel::Config')->Get('Ticket::Service::Default::UnknownCustomer');
# check if no CustomerUserID is selected
# if $DefaultServiceUnknownCustomer = 0 leave CustomerUserID empty, it will not get any services
# if $DefaultServiceUnknownCustomer = 1 set CustomerUserID to get default services
if ( !$Param{CustomerUserID} && $DefaultServiceUnknownCustomer ) {
$Param{CustomerUserID} = '';
}
# get service list
if ( $Param{CustomerUserID} ) {
%Service = $Kernel::OM->Get('Kernel::System::Ticket')->TicketServiceList(
%Param,
Action => $Self->{Action},
UserID => $Self->{UserID},
);
}
return \%Service;
}
sub _GetLocks {
my ( $Self, %Param ) = @_;
my %Locks = $Kernel::OM->Get('Kernel::System::Lock')->LockList(
UserID => $Self->{UserID},
);
return \%Locks;
}
sub _GetPriorities {
my ( $Self, %Param ) = @_;
my %Priorities;
# Initially we have just the default Queue Parameter
# so make sure to get the ID in that case
my $QueueID;
if ( !$Param{QueueID} && $Param{Queue} ) {
$QueueID = $Kernel::OM->Get('Kernel::System::Queue')->QueueLookup( Queue => $Param{Queue} );
}
if ( $Param{QueueID} || $QueueID || $Param{TicketID} ) {
%Priorities = $Kernel::OM->Get('Kernel::System::Ticket')->TicketPriorityList(
%Param,
Action => $Self->{Action},
UserID => $Self->{UserID},
);
}
return \%Priorities;
}
sub _GetQueues {
my ( $Self, %Param ) = @_;
# check which type of permission is needed: if the process ticket
# already exists (= TicketID is present), we need the 'move_into'
# permission otherwise the 'create' permission
my $PermissionType = 'create';
if ( $Param{TicketID} ) {
$PermissionType = 'move_into';
}
# get config object
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
# check own selection
my %NewQueues;
if ( $ConfigObject->Get('Ticket::Frontend::NewQueueOwnSelection') ) {
%NewQueues = %{ $ConfigObject->Get('Ticket::Frontend::NewQueueOwnSelection') };
}
else {
# SelectionType Queue or SystemAddress?
my %Queues;
if ( $ConfigObject->Get('Ticket::Frontend::NewQueueSelectionType') eq 'Queue' ) {
%Queues = $Kernel::OM->Get('Kernel::System::Ticket')->MoveList(
%Param,
Type => $PermissionType,
Action => $Self->{Action},
QueueID => $Self->{QueueID},
UserID => $Self->{UserID},
);
}
else {
%Queues = $Kernel::OM->Get('Kernel::System::DB')->GetTableData(
Table => 'system_address',
What => 'queue_id, id',
Valid => 1,
Clamp => 1,
);
}
# get permission queues
my %UserGroups = $Kernel::OM->Get('Kernel::System::Group')->PermissionUserGet(
UserID => $Self->{UserID},
Type => $PermissionType,
);
# build selection string
QUEUEID:
for my $QueueID ( sort keys %Queues ) {
my %QueueData = $Kernel::OM->Get('Kernel::System::Queue')->QueueGet( ID => $QueueID );
# permission check, can we create new tickets in queue
next QUEUEID if !$UserGroups{ $QueueData{GroupID} };
my $String = $ConfigObject->Get('Ticket::Frontend::NewQueueSelectionString')
|| ' <> - Queue: ';
$String =~ s//$QueueData{Name}/g;
$String =~ s//$QueueData{Comment}/g;
if ( $ConfigObject->Get('Ticket::Frontend::NewQueueSelectionType') ne 'Queue' )
{
my %SystemAddressData = $Self->{SystemAddress}->SystemAddressGet(
ID => $Queues{$QueueID},
);
$String =~ s//$SystemAddressData{Realname}/g;
$String =~ s//$SystemAddressData{Name}/g;
}
$NewQueues{$QueueID} = $String;
}
}
return \%NewQueues;
}
sub _GetStates {
my ( $Self, %Param ) = @_;
my %States = $Kernel::OM->Get('Kernel::System::Ticket')->TicketStateList(
%Param,
# Set default values for new process ticket
QueueID => $Param{QueueID} || 1,
TicketID => $Param{TicketID} || '',
# remove type, since if Ticket::Type is active in sysconfig, the Type parameter will
# be sent and the TicketStateList will send the parameter as State Type
Type => undef,
Action => $Self->{Action},
UserID => $Self->{UserID},
);
return \%States;
}
sub _GetTypes {
my ( $Self, %Param ) = @_;
# get type
my %Type;
if ( $Param{QueueID} || $Param{TicketID} ) {
%Type = $Kernel::OM->Get('Kernel::System::Ticket')->TicketTypeList(
%Param,
Action => $Self->{Action},
UserID => $Self->{UserID},
);
}
return \%Type;
}
sub _GetAJAXUpdatableFields {
my ( $Self, %Param ) = @_;
my %DefaultUpdatableFields = (
PriorityID => 1,
QueueID => 1,
ResponsibleID => 1,
ServiceID => 1,
SLAID => 1,
StateID => 1,
OwnerID => 1,
LockID => 1,
);
my $DynamicField = $Kernel::OM->Get('Kernel::System::DynamicField')->DynamicFieldListGet(
Valid => 1,
ObjectType => 'Ticket',
);
# create a DynamicFieldLookupTable
my %DynamicFieldLookup = map { 'DynamicField_' . $_->{Name} => $_ } @{$DynamicField};
my @UpdatableFields;
FIELD:
for my $Field ( sort keys %{ $Param{ActivityDialogFields} } ) {
my $FieldData = $Param{ActivityDialogFields}->{$Field};
# skip hidden fields
next FIELD if !$FieldData->{Display};
# for Dynamic Fields check if is AJAXUpdatable
if ( $Field =~ m{^DynamicField_(.*)}xms ) {
my $DynamicFieldConfig = $DynamicFieldLookup{$Field};
# skip any field with wrong config
next FIELD if !IsHashRefWithData($DynamicFieldConfig);
# skip field if is not IsACLReducible (updatable)
my $IsACLReducible = $Kernel::OM->Get('Kernel::System::DynamicField::Backend')->HasBehavior(
DynamicFieldConfig => $DynamicFieldConfig,
Behavior => 'IsACLReducible',
);
next FIELD if !$IsACLReducible;
push @UpdatableFields, $Field;
}
# for all others use %DefaultUpdatableFields table
else {
# standarize the field name (e.g. use StateID for State field)
my $FieldName = $Self->{NameToID}->{$Field};
# skip if field name could not be converted (this means that field is unknown)
next FIELD if !$FieldName;
# skip if the field is not updatable via ajax
next FIELD if !$DefaultUpdatableFields{$FieldName};
push @UpdatableFields, $FieldName;
}
}
return \@UpdatableFields;
}
sub _GetFieldsToUpdateStrg {
my ( $Self, %Param ) = @_;
my $FieldsToUpdate = '';
if ( IsArrayRefWithData( $Param{AJAXUpdatableFields} ) ) {
my $FirstItem = 1;
FIELD:
for my $Field ( @{ $Param{AJAXUpdatableFields} } ) {
next FIELD if $Field eq $Param{TriggerField};
if ($FirstItem) {
$FirstItem = 0;
}
else {
$FieldsToUpdate .= ', ';
}
$FieldsToUpdate .= "'" . $Field . "'";
}
}
return $FieldsToUpdate;
}
1;