Files
scripts/Perl OTRS/Kernel/Modules/AgentITSMTemplateEditCAB.pm
2024-10-14 00:08:40 +02:00

454 lines
13 KiB
Perl

# --
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
# --
package Kernel::Modules::AgentITSMTemplateEditCAB;
use strict;
use warnings;
use Kernel::Language qw(Translatable);
our $ObjectManagerDisabled = 1;
## nofilter(TidyAll::Plugin::OTRS::Perl::Dumper)
use Data::Dumper;
sub new {
my ( $Type, %Param ) = @_;
# allocate new hash for object
my $Self = {%Param};
bless( $Self, $Type );
return $Self;
}
sub Run {
my ( $Self, %Param ) = @_;
# get config of frontend module
$Self->{Config} = $Kernel::OM->Get('Kernel::Config')->Get("ITSMChange::Frontend::$Self->{Action}");
# check permissions
my $Access = $Kernel::OM->Get('Kernel::System::ITSMChange')->Permission(
Type => $Self->{Config}->{Permission},
Action => $Self->{Action},
UserID => $Self->{UserID},
);
# get layout object
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
# error screen
if ( !$Access ) {
return $LayoutObject->NoPermission(
Message =>
$LayoutObject->{LanguageObject}->Translate( 'You need %s permission!', $Self->{Config}->{Permission} ),
WithHeader => 'yes',
);
}
# store all needed parameters in %GetParam to make it reloadable
my %GetParam;
for my $ParamName (
qw(TemplateID TemplateContent NewCABMember NewCABMemberSelected NewCABMemberType AddCABMember)
)
{
$GetParam{$ParamName} = $Kernel::OM->Get('Kernel::System::Web::Request')->GetParam( Param => $ParamName );
}
# check needed stuff
if ( !$GetParam{TemplateID} ) {
return $LayoutObject->ErrorScreen(
Message => Translatable('No TemplateID is given!'),
Comment => Translatable('Please contact the administrator.'),
);
}
# get template object
my $TemplateObject = $Kernel::OM->Get('Kernel::System::ITSMChange::Template');
# get template data
my $Template = $TemplateObject->TemplateGet(
TemplateID => $GetParam{TemplateID},
UserID => $Self->{UserID},
);
# check error
if ( !$Template ) {
return $LayoutObject->ErrorScreen(
Message => $LayoutObject->{LanguageObject}
->Translate( 'Template "%s" not found in database!', $GetParam{TemplateID} ),
Comment => Translatable('Please contact the administrator.'),
);
}
# on first page load we fill the template content string parameter from the template
if ( !$Self->{Subaction} ) {
$GetParam{TemplateContent} = $Template->{Content};
}
# de-serialize the CAB content
my $CABReference = $Self->_CABDeSerialize(
Content => $GetParam{TemplateContent},
UserID => $Self->{UserID},
);
# is cab member delete requested
my %DeleteMember = $Self->_IsMemberDeletion(
CABReference => $CABReference,
);
if (%DeleteMember) {
# find users who are still member of CAB
my $Type = $DeleteMember{Type};
my @StillMembers = grep { $_ ne $DeleteMember{ID} } @{ $CABReference->{CABAdd}->{$Type} };
# store the remaining members
$CABReference->{CABAdd}->{$Type} = \@StillMembers;
# reset the "save" subaction, because we only want to show the updated member list
$Self->{Subaction} = '';
}
# server error hash, to store the items with ServerError class
my %ServerError;
# Remember the reason why saving was not attempted.
# The entries are the names of the dtl validation error blocks.
my @ValidationErrors;
# add a CAB member
if ( $GetParam{AddCABMember} && $GetParam{NewCABMember} ) {
# add a member
my %CABUpdateInfo = $Self->_IsNewCABMemberOk(
CABReference => $CABReference,
%GetParam,
);
# if member is valid
if (%CABUpdateInfo) {
# add new member
$CABReference->{CABAdd}->{ $GetParam{NewCABMemberType} } = $CABUpdateInfo{ $GetParam{NewCABMemberType} };
# do not display a name in autocomplete field
# and do not set values in hidden fields as the
# user was already added
delete @GetParam{qw(NewCABMember NewCABMemberSelected NewCABMemberType)};
}
# if member is invalid
else {
$ServerError{NewCABMemberError} = 'ServerError';
}
# reset the "save" subaction, because we only want to show the updated member list
$Self->{Subaction} = '';
}
# save the CAB template
if ( $Self->{Subaction} eq 'Save' ) {
# update the template
my $UpdateSuccess = $TemplateObject->TemplateUpdate(
TemplateID => $GetParam{TemplateID},
Content => $GetParam{TemplateContent},
UserID => $Self->{UserID},
);
if ($UpdateSuccess) {
# redirect to template overview
# load new URL in parent window and close popup
return $LayoutObject->PopupClose(
URL => "Action=AgentITSMTemplateOverview",
);
}
else {
# show error message
return $LayoutObject->ErrorScreen(
Message => $LayoutObject->{LanguageObject}
->Translate( 'Was not able to update Template "%s"!', $GetParam{TemplateID} ),
Comment => Translatable('Please contact the administrator.'),
);
}
}
# check if CAB contains anyone
if ( @{ $CABReference->{CABAdd}->{CABAgents} } || @{ $CABReference->{CABAdd}->{CABCustomers} } )
{
$LayoutObject->Block( Name => 'CABMemberTable' );
}
USERID:
for my $UserID ( @{ $CABReference->{CABAdd}->{CABAgents} } ) {
# get user data
my %UserData = $Kernel::OM->Get('Kernel::System::User')->GetUserData(
UserID => $UserID,
);
# next if no user data can be found
next USERID if !%UserData;
# display cab member info
$LayoutObject->Block(
Name => 'CABMemberRow',
Data => {
UserType => 'Agent',
InternalUserType => 'CABAgents',
%UserData,
},
);
}
# show all customer members of CAB
CUSTOMERLOGIN:
for my $CustomerLogin ( @{ $CABReference->{CABAdd}->{CABCustomers} } ) {
# get user data
my %CustomerUserData = $Kernel::OM->Get('Kernel::System::CustomerUser')->CustomerUserDataGet(
User => $CustomerLogin,
Valid => 1,
);
# next if no user data can be found
next CUSTOMERLOGIN if !%CustomerUserData;
# display cab member info
$LayoutObject->Block(
Name => 'CABMemberRow',
Data => {
UserType => 'Customer',
InternalUserType => 'CABCustomers',
%CustomerUserData,
},
);
}
# serialize the CAB to be used as parameter in hidden field
$GetParam{TemplateContent} = $Self->_CABSerialize(
Content => $CABReference,
UserID => 1,
);
# output header and navigation
my $Output = $LayoutObject->Header(
Title => Translatable('Edit CAB Template'),
Type => 'Small',
);
# start template output
$Output .= $LayoutObject->Output(
TemplateFile => 'AgentITSMTemplateEditCAB',
Data => {
%Param,
%{$Template},
%GetParam,
%ServerError,
},
);
# add footer
$Output .= $LayoutObject->Footer( Type => 'Small' );
return $Output;
}
sub _IsMemberDeletion {
my ( $Self, %Param ) = @_;
# do not detect deletion when no subaction is given
return if !$Self->{Subaction};
# info about what to delete
my %DeleteInfo;
# get param object
my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request');
if ( my $ID = $ParamObject->GetParam( Param => 'DeleteCABMember' ) ) {
if ( $ID =~ m{^CABCustomers(.+)} ) {
# save info
%DeleteInfo = (
Type => 'CABCustomers',
ID => $1,
);
}
elsif ( $ID =~ m{^CABAgents(.+)} ) {
# save info
%DeleteInfo = (
Type => 'CABAgents',
ID => $1,
);
}
}
return %DeleteInfo;
}
sub _IsNewCABMemberOk {
my ( $Self, %Param ) = @_;
# The member info will be returned.
my %MemberInfo;
# CABCustomers or CABAgents?
my $MemberType = $Param{NewCABMemberType};
# member lookup
my %CurrentMemberLookup;
# an agent is requested to be added
if ( $MemberType eq 'CABAgents' ) {
# get user object
my $UserObject = $Kernel::OM->Get('Kernel::System::User');
my %User = $UserObject->GetUserData(
UserID => $Param{NewCABMemberSelected},
);
if (%User) {
# check current users
USERID:
for my $UserID ( @{ $Param{CABReference}->{CABAdd}->{$MemberType} } ) {
# get user data
my %UserData = $UserObject->GetUserData(
UserID => $UserID,
Valid => 1,
);
# remove invalid users from CAB
next USERID if !$UserData{UserID};
# store in lookup
$CurrentMemberLookup{$UserID} = 1;
}
# Compare input value with user data.
# Look for exact match at beginning,
# as $User{UserLastname} might contain a trailing 'out of office' note.
# Note that this won't catch deletions of $Param{NewCABMember} at the end.
my $CheckString = sprintf '"%s" <%s>',
$User{UserFullname},
$User{UserEmail};
if ( index( $CheckString, $Param{NewCABMember} ) == 0 ) {
$CurrentMemberLookup{ $User{UserID} } = 1;
# save member infos
%MemberInfo = (
$MemberType => [ sort keys %CurrentMemberLookup ],
);
}
}
}
# an customer is requested to be added
else {
# get customer user object
my $CustomerUserObject = $Kernel::OM->Get('Kernel::System::CustomerUser');
# check current customer users
CUSTOMERUSER:
for my $CustomerUser ( @{ $Param{CABReference}->{CABAdd}->{$MemberType} } ) {
# get customer user data
my %CustomerUserData = $CustomerUserObject->CustomerUserDataGet(
User => $CustomerUser,
Valid => 1,
);
# remove invalid customer users from CAB
next CUSTOMERUSER if !%CustomerUserData;
# store in lookup
$CurrentMemberLookup{$CustomerUser} = 1;
}
# check if customer can be found
my %CustomerUser = $CustomerUserObject->CustomerSearch(
UserLogin => $Param{NewCABMemberSelected},
);
if ( $CustomerUser{ $Param{NewCABMemberSelected} } ) {
$CurrentMemberLookup{ $Param{NewCABMemberSelected} } = 1;
# save member infos
%MemberInfo = (
$MemberType => [ sort keys %CurrentMemberLookup ],
);
}
}
return %MemberInfo;
}
sub _CABDeSerialize {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(UserID Content)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# get the Perl datastructure
my $VAR1;
return if !eval "\$VAR1 = $Param{Content}; 1;"; ## no critic
return if !$VAR1;
return if ref $VAR1 ne 'HASH';
return $VAR1;
}
sub _CABSerialize {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(UserID Content)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# no indentation (saves space)
local $Data::Dumper::Indent = 0;
# do not use cross-referencing
local $Data::Dumper::Deepcopy = 1;
# serialize the data (do not use $VAR1, but $TemplateData for Dumper output)
my $SerializedData = $Kernel::OM->Get('Kernel::System::Main')->Dump( $Param{Content}, 'binary' );
return $SerializedData;
}
1;