1354 lines
49 KiB
Perl
1354 lines
49 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::AgentITSMConfigItemSearch;
|
|
|
|
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 );
|
|
|
|
return $Self;
|
|
}
|
|
|
|
sub Run {
|
|
my ( $Self, %Param ) = @_;
|
|
my $Output;
|
|
|
|
# get config object
|
|
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
|
|
|
|
# get config of frontend module
|
|
$Self->{Config} = $ConfigObject->Get("ITSMConfigItem::Frontend::$Self->{Action}");
|
|
|
|
# get param object
|
|
my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request');
|
|
|
|
# get config data
|
|
$Self->{StartHit} = int( $ParamObject->GetParam( Param => 'StartHit' ) || 1 );
|
|
$Self->{SearchLimit} = $Self->{Config}->{SearchLimit} || 10000;
|
|
$Self->{SortBy} = $ParamObject->GetParam( Param => 'SortBy' )
|
|
|| $Self->{Config}->{'SortBy::Default'}
|
|
|| 'Number';
|
|
$Self->{OrderBy} = $ParamObject->GetParam( Param => 'OrderBy' )
|
|
|| $Self->{Config}->{'Order::Default'}
|
|
|| 'Down';
|
|
$Self->{Profile} = $ParamObject->GetParam( Param => 'Profile' ) || '';
|
|
$Self->{SaveProfile} = $ParamObject->GetParam( Param => 'SaveProfile' ) || '';
|
|
$Self->{TakeLastSearch} = $ParamObject->GetParam( Param => 'TakeLastSearch' );
|
|
|
|
# get general catalog object
|
|
my $GeneralCatalogObject = $Kernel::OM->Get('Kernel::System::GeneralCatalog');
|
|
|
|
# get class list
|
|
my $ClassList = $GeneralCatalogObject->ItemList(
|
|
Class => 'ITSM::ConfigItem::Class',
|
|
);
|
|
|
|
# get config item object
|
|
my $ConfigItemObject = $Kernel::OM->Get('Kernel::System::ITSMConfigItem');
|
|
|
|
# check for access rights on the classes
|
|
for my $ClassID ( sort keys %{$ClassList} ) {
|
|
my $HasAccess = $ConfigItemObject->Permission(
|
|
Type => $Self->{Config}->{Permission},
|
|
Scope => 'Class',
|
|
ClassID => $ClassID,
|
|
UserID => $Self->{UserID},
|
|
);
|
|
|
|
delete $ClassList->{$ClassID} if !$HasAccess;
|
|
}
|
|
|
|
# get class id
|
|
my $ClassID = $ParamObject->GetParam( Param => 'ClassID' );
|
|
|
|
# get layout object
|
|
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
|
|
|
|
# check if class id is valid
|
|
if ( $ClassID && !$ClassList->{$ClassID} ) {
|
|
return $LayoutObject->ErrorScreen(
|
|
Message => Translatable('Invalid ClassID!'),
|
|
Comment => Translatable('Please contact the administrator.'),
|
|
);
|
|
}
|
|
|
|
# get single params
|
|
my %GetParam;
|
|
|
|
# get search profile object
|
|
my $SearchProfileObject = $Kernel::OM->Get('Kernel::System::SearchProfile');
|
|
|
|
# load profiles string params
|
|
if ( ( $ClassID && $Self->{Profile} ) && $Self->{TakeLastSearch} ) {
|
|
%GetParam = $SearchProfileObject->SearchProfileGet(
|
|
Base => 'ConfigItemSearch' . $ClassID,
|
|
Name => $Self->{Profile},
|
|
UserLogin => $Self->{UserLogin},
|
|
);
|
|
}
|
|
|
|
# ------------------------------------------------------------ #
|
|
# delete search profiles
|
|
# ------------------------------------------------------------ #
|
|
if ( $Self->{Subaction} eq 'AJAXProfileDelete' ) {
|
|
|
|
# remove old profile stuff
|
|
$SearchProfileObject->SearchProfileDelete(
|
|
Base => 'ConfigItemSearch' . $ClassID,
|
|
Name => $Self->{Profile},
|
|
UserLogin => $Self->{UserLogin},
|
|
);
|
|
my $Output = $LayoutObject->JSONEncode(
|
|
Data => 1,
|
|
);
|
|
return $LayoutObject->Attachment(
|
|
NoCache => 1,
|
|
ContentType => 'text/html',
|
|
Content => $Output,
|
|
Type => 'inline',
|
|
);
|
|
}
|
|
|
|
# ------------------------------------------------------------ #
|
|
# init search dialog (select class)
|
|
# ------------------------------------------------------------ #
|
|
elsif ( $Self->{Subaction} eq 'AJAX' ) {
|
|
|
|
# generate dropdown for selecting the class
|
|
# automatically show search mask after selecting a class via AJAX
|
|
my $ClassOptionStrg = $LayoutObject->BuildSelection(
|
|
Data => $ClassList,
|
|
Name => 'SearchClassID',
|
|
PossibleNone => 1,
|
|
SelectedID => $ClassID || '',
|
|
Translation => 1,
|
|
Class => 'Modernize',
|
|
);
|
|
|
|
# html search mask output
|
|
$LayoutObject->Block(
|
|
Name => 'SearchAJAX',
|
|
Data => {
|
|
ClassOptionStrg => $ClassOptionStrg,
|
|
Profile => $Self->{Profile},
|
|
ClassID => $ClassID,
|
|
},
|
|
);
|
|
|
|
# output template
|
|
$Output = $LayoutObject->Output(
|
|
TemplateFile => 'AgentITSMConfigItemSearch',
|
|
);
|
|
|
|
return $LayoutObject->Attachment(
|
|
NoCache => 1,
|
|
ContentType => 'text/html',
|
|
Content => $Output,
|
|
Type => 'inline',
|
|
);
|
|
}
|
|
|
|
# ------------------------------------------------------------ #
|
|
# set search fields for selected class
|
|
# ------------------------------------------------------------ #
|
|
elsif ( $Self->{Subaction} eq 'AJAXUpdate' ) {
|
|
|
|
# ClassID is required for the search mask and for actual searching
|
|
if ( !$ClassID ) {
|
|
return $LayoutObject->ErrorScreen(
|
|
Message => Translatable('No ClassID is given!'),
|
|
Comment => Translatable('Please contact the administrator.'),
|
|
);
|
|
}
|
|
|
|
# check if user is allowed to search class
|
|
my $HasAccess = $ConfigItemObject->Permission(
|
|
Type => $Self->{Config}->{Permission},
|
|
Scope => 'Class',
|
|
ClassID => $ClassID,
|
|
UserID => $Self->{UserID},
|
|
);
|
|
|
|
# show error screen
|
|
if ( !$HasAccess ) {
|
|
return $LayoutObject->ErrorScreen(
|
|
Message => Translatable('No access rights for this class given!'),
|
|
Comment => Translatable('Please contact the administrator.'),
|
|
);
|
|
}
|
|
|
|
# get current definition
|
|
my $XMLDefinition = $ConfigItemObject->DefinitionGet(
|
|
ClassID => $ClassID,
|
|
);
|
|
|
|
# abort, if no definition is defined
|
|
if ( !$XMLDefinition->{DefinitionID} ) {
|
|
return $LayoutObject->ErrorScreen(
|
|
Message =>
|
|
$LayoutObject->{LanguageObject}->Translate( 'No definition was defined for class %s!', $ClassID ),
|
|
Comment => Translatable('Please contact the administrator.'),
|
|
);
|
|
}
|
|
|
|
my @XMLAttributes = (
|
|
{
|
|
Key => 'Number',
|
|
Value => Translatable('Number'),
|
|
},
|
|
{
|
|
Key => 'Name',
|
|
Value => Translatable('Name'),
|
|
},
|
|
{
|
|
Key => 'DeplStateIDs',
|
|
Value => Translatable('Deployment State'),
|
|
},
|
|
{
|
|
Key => 'InciStateIDs',
|
|
Value => Translatable('Incident State'),
|
|
},
|
|
);
|
|
|
|
my %GetParam = $SearchProfileObject->SearchProfileGet(
|
|
Base => 'ConfigItemSearch' . $ClassID,
|
|
Name => $Self->{Profile},
|
|
UserLogin => $Self->{UserLogin},
|
|
);
|
|
|
|
# get attributes to include in attributes string
|
|
if ( $XMLDefinition->{Definition} ) {
|
|
$Self->_XMLSearchAttributesGet(
|
|
XMLDefinition => $XMLDefinition->{DefinitionRef},
|
|
XMLAttributes => \@XMLAttributes,
|
|
);
|
|
}
|
|
|
|
# build attributes string for attributes list
|
|
$Param{AttributesStrg} = $LayoutObject->BuildSelection(
|
|
PossibleNone => 1,
|
|
Data => \@XMLAttributes,
|
|
Name => 'Attribute',
|
|
Multiple => 0,
|
|
Class => 'Modernize',
|
|
);
|
|
|
|
# build attributes string for recovery on add or subtract search fields
|
|
$Param{AttributesOrigStrg} = $LayoutObject->BuildSelection(
|
|
PossibleNone => 1,
|
|
Data => \@XMLAttributes,
|
|
Name => 'AttributeOrig',
|
|
Multiple => 0,
|
|
Class => 'Modernize',
|
|
);
|
|
|
|
my %Profiles = $SearchProfileObject->SearchProfileList(
|
|
Base => 'ConfigItemSearch' . $ClassID,
|
|
UserLogin => $Self->{UserLogin},
|
|
);
|
|
|
|
$Param{ProfilesStrg} = $LayoutObject->BuildSelection(
|
|
Data => \%Profiles,
|
|
Name => 'Profile',
|
|
ID => 'SearchProfile',
|
|
SelectedID => $Self->{Profile},
|
|
Class => 'Modernize',
|
|
PossibleNone => 1,
|
|
);
|
|
|
|
# get deployment state list
|
|
my $DeplStateList = $GeneralCatalogObject->ItemList(
|
|
Class => 'ITSM::ConfigItem::DeploymentState',
|
|
);
|
|
|
|
# generate dropdown for selecting the wanted deployment states
|
|
my $CurDeplStateOptionStrg = $LayoutObject->BuildSelection(
|
|
Data => $DeplStateList,
|
|
Name => 'DeplStateIDs',
|
|
SelectedID => $GetParam{DeplStateIDs} || [],
|
|
Size => 5,
|
|
Multiple => 1,
|
|
Class => 'Modernize',
|
|
);
|
|
|
|
# get incident state list
|
|
my $InciStateList = $GeneralCatalogObject->ItemList(
|
|
Class => 'ITSM::Core::IncidentState',
|
|
);
|
|
|
|
# generate dropdown for selecting the wanted incident states
|
|
my $CurInciStateOptionStrg = $LayoutObject->BuildSelection(
|
|
Data => $InciStateList,
|
|
Name => 'InciStateIDs',
|
|
SelectedID => $GetParam{InciStateIDs} || [],
|
|
Size => 5,
|
|
Multiple => 1,
|
|
Class => 'Modernize',
|
|
);
|
|
|
|
# generate PreviousVersionOptionStrg
|
|
my $PreviousVersionOptionStrg = $LayoutObject->BuildSelection(
|
|
Name => 'PreviousVersionSearch',
|
|
Data => {
|
|
0 => Translatable('No'),
|
|
1 => Translatable('Yes'),
|
|
},
|
|
SelectedID => $GetParam{PreviousVersionSearch} || '0',
|
|
Class => 'Modernize',
|
|
);
|
|
|
|
# build output format string
|
|
$Param{ResultFormStrg} = $LayoutObject->BuildSelection(
|
|
Data => {
|
|
Normal => Translatable('Normal'),
|
|
Print => Translatable('Print'),
|
|
CSV => Translatable('CSV'),
|
|
Excel => Translatable('Excel'),
|
|
},
|
|
Name => 'ResultForm',
|
|
SelectedID => $GetParam{ResultForm} || 'Normal',
|
|
Class => 'Modernize',
|
|
);
|
|
|
|
$LayoutObject->Block(
|
|
Name => 'AJAXContent',
|
|
Data => {
|
|
ClassID => $ClassID,
|
|
CurDeplStateOptionStrg => $CurDeplStateOptionStrg,
|
|
CurInciStateOptionStrg => $CurInciStateOptionStrg,
|
|
PreviousVersionOptionStrg => $PreviousVersionOptionStrg,
|
|
AttributesStrg => $Param{AttributesStrg},
|
|
AttributesOrigStrg => $Param{AttributesOrigStrg},
|
|
ResultFormStrg => $Param{ResultFormStrg},
|
|
ProfilesStrg => $Param{ProfilesStrg},
|
|
Number => $GetParam{Number} || '',
|
|
Name => $GetParam{Name} || '',
|
|
},
|
|
);
|
|
|
|
# output xml search form
|
|
if ( $XMLDefinition->{Definition} ) {
|
|
$Self->_XMLSearchFormOutput(
|
|
XMLDefinition => $XMLDefinition->{DefinitionRef},
|
|
XMLAttributes => \@XMLAttributes,
|
|
GetParam => \%GetParam,
|
|
);
|
|
}
|
|
|
|
my @ProfileAttributes;
|
|
|
|
# show attributes
|
|
my $AttributeIsUsed = 0;
|
|
KEY:
|
|
for my $Key ( sort keys %GetParam ) {
|
|
next KEY if !$Key;
|
|
next KEY if !defined $GetParam{$Key};
|
|
next KEY if $GetParam{$Key} eq '';
|
|
|
|
$AttributeIsUsed = 1;
|
|
|
|
push @ProfileAttributes, $Key;
|
|
}
|
|
|
|
# if no attribute is shown, show configitem number
|
|
if ( !$Self->{Profile} ) {
|
|
push @ProfileAttributes, 'Number';
|
|
}
|
|
|
|
$LayoutObject->AddJSData(
|
|
Key => 'ITSMSearchProfileAttributes',
|
|
Value => \@ProfileAttributes,
|
|
);
|
|
|
|
# output template
|
|
$Output = $LayoutObject->Output(
|
|
TemplateFile => 'AgentITSMConfigItemSearch',
|
|
AJAX => 1,
|
|
);
|
|
|
|
return $LayoutObject->Attachment(
|
|
NoCache => 1,
|
|
ContentType => 'text/html',
|
|
Content => $Output,
|
|
Type => 'inline',
|
|
);
|
|
}
|
|
|
|
# ------------------------------------------------------------ #
|
|
# perform search
|
|
# ------------------------------------------------------------ #
|
|
elsif ( $Self->{Subaction} eq 'Search' ) {
|
|
|
|
my $SearchDialog = $ParamObject->GetParam( Param => 'SearchDialog' );
|
|
|
|
# fill up profile name (e.g. with last-search)
|
|
if ( !$Self->{Profile} || !$Self->{SaveProfile} ) {
|
|
$Self->{Profile} = 'last-search';
|
|
}
|
|
|
|
# store last overview screen
|
|
my $URL = "Action=AgentITSMConfigItemSearch;Profile=$Self->{Profile};"
|
|
. "TakeLastSearch=1;StartHit=$Self->{StartHit};Subaction=Search;"
|
|
. "OrderBy=$Self->{OrderBy};SortBy=$Self->{SortBy}";
|
|
|
|
if ($ClassID) {
|
|
$URL .= ";ClassID=$ClassID";
|
|
}
|
|
|
|
# get session object
|
|
my $SessionObject = $Kernel::OM->Get('Kernel::System::AuthSession');
|
|
|
|
$SessionObject->UpdateSessionID(
|
|
SessionID => $Self->{SessionID},
|
|
Key => 'LastScreenOverview',
|
|
Value => $URL,
|
|
);
|
|
$SessionObject->UpdateSessionID(
|
|
SessionID => $Self->{SessionID},
|
|
Key => 'LastScreenView',
|
|
Value => $URL,
|
|
);
|
|
|
|
# ClassID is required for the search mask and for actual searching
|
|
if ( !$ClassID ) {
|
|
return $LayoutObject->ErrorScreen(
|
|
Message => Translatable('No ClassID is given!'),
|
|
Comment => Translatable('Please contact the administrator.'),
|
|
);
|
|
}
|
|
|
|
# check if user is allowed to search class
|
|
my $HasAccess = $ConfigItemObject->Permission(
|
|
Type => $Self->{Config}->{Permission},
|
|
Scope => 'Class',
|
|
ClassID => $ClassID,
|
|
UserID => $Self->{UserID},
|
|
);
|
|
|
|
# show error screen
|
|
if ( !$HasAccess ) {
|
|
return $LayoutObject->ErrorScreen(
|
|
Message => Translatable('No access rights for this class given!'),
|
|
Comment => Translatable('Please contact the administrator.'),
|
|
);
|
|
}
|
|
|
|
# get current definition
|
|
my $XMLDefinition = $ConfigItemObject->DefinitionGet(
|
|
ClassID => $ClassID,
|
|
);
|
|
|
|
# abort, if no definition is defined
|
|
if ( !$XMLDefinition->{DefinitionID} ) {
|
|
return $LayoutObject->ErrorScreen(
|
|
Message =>
|
|
$LayoutObject->{LanguageObject}->Translate( 'No definition was defined for class %s!', $ClassID ),
|
|
Comment => Translatable('Please contact the administrator.'),
|
|
);
|
|
}
|
|
|
|
# get scalar search attributes (special handling for Number and Name)
|
|
FORMVALUE:
|
|
for my $FormValue (qw(Number Name)) {
|
|
|
|
my $Value = $ParamObject->GetParam( Param => $FormValue );
|
|
|
|
# must be defined and not be an empty string
|
|
# BUT the number 0 is an allowed value
|
|
next FORMVALUE if !defined $Value;
|
|
next FORMVALUE if $Value eq '';
|
|
|
|
$GetParam{$FormValue} = $Value;
|
|
}
|
|
|
|
# get ther scalar search attributes
|
|
FORMVALUE:
|
|
for my $FormValue (qw(PreviousVersionSearch ResultForm)) {
|
|
|
|
my $Value = $ParamObject->GetParam( Param => $FormValue );
|
|
|
|
next FORMVALUE if !$Value;
|
|
|
|
$GetParam{$FormValue} = $Value;
|
|
}
|
|
|
|
# get array search attributes
|
|
FORMARRAY:
|
|
for my $FormArray (qw(DeplStateIDs InciStateIDs)) {
|
|
|
|
my @Array = $ParamObject->GetArray( Param => $FormArray );
|
|
|
|
next FORMARRAY if !@Array;
|
|
|
|
$GetParam{$FormArray} = \@Array;
|
|
}
|
|
|
|
# get xml search form
|
|
my $XMLFormData = [];
|
|
my $XMLGetParam = [];
|
|
$Self->_XMLSearchFormGet(
|
|
XMLDefinition => $XMLDefinition->{DefinitionRef},
|
|
XMLFormData => $XMLFormData,
|
|
XMLGetParam => $XMLGetParam,
|
|
%GetParam,
|
|
);
|
|
|
|
if ( @{$XMLFormData} ) {
|
|
$GetParam{What} = $XMLFormData;
|
|
}
|
|
|
|
# save search profile (under last-search or real profile name)
|
|
$Self->{SaveProfile} = 1;
|
|
|
|
# remember last search values only if search is called from a search dialog
|
|
# not from results page
|
|
if ( $Self->{SaveProfile} && $Self->{Profile} && $SearchDialog ) {
|
|
|
|
# remove old profile stuff
|
|
$SearchProfileObject->SearchProfileDelete(
|
|
Base => 'ConfigItemSearch' . $ClassID,
|
|
Name => $Self->{Profile},
|
|
UserLogin => $Self->{UserLogin},
|
|
);
|
|
|
|
# insert new profile params
|
|
for my $Key ( sort keys %GetParam ) {
|
|
if ( $GetParam{$Key} && $Key ne 'What' ) {
|
|
$SearchProfileObject->SearchProfileAdd(
|
|
Base => 'ConfigItemSearch' . $ClassID,
|
|
Name => $Self->{Profile},
|
|
Key => $Key,
|
|
Value => $GetParam{$Key},
|
|
UserLogin => $Self->{UserLogin},
|
|
);
|
|
}
|
|
}
|
|
|
|
# insert new profile params also from XMLform
|
|
if ( @{$XMLGetParam} ) {
|
|
for my $Parameter ( @{$XMLGetParam} ) {
|
|
for my $Key ( sort keys %{$Parameter} ) {
|
|
if ( $Parameter->{$Key} ) {
|
|
|
|
$SearchProfileObject->SearchProfileAdd(
|
|
Base => 'ConfigItemSearch' . $ClassID,
|
|
Name => $Self->{Profile},
|
|
Key => $Key,
|
|
Value => $Parameter->{$Key},
|
|
UserLogin => $Self->{UserLogin},
|
|
);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
my $SearchResultList = [];
|
|
|
|
# start search if called from a search dialog or from a results page
|
|
if ( $SearchDialog || $Self->{TakeLastSearch} ) {
|
|
|
|
# start search
|
|
$SearchResultList = $ConfigItemObject->ConfigItemSearchExtended(
|
|
%GetParam,
|
|
OrderBy => [ $Self->{SortBy} ],
|
|
OrderByDirection => [ $Self->{OrderBy} ],
|
|
Limit => $Self->{SearchLimit},
|
|
ClassIDs => [$ClassID],
|
|
);
|
|
}
|
|
|
|
# get param only if called from a search dialog, otherwise it must be already in %GetParam
|
|
# from a loaded profile
|
|
if ($SearchDialog) {
|
|
$GetParam{ResultForm} = $ParamObject->GetParam( Param => 'ResultForm' );
|
|
}
|
|
|
|
# CSV output
|
|
if (
|
|
$GetParam{ResultForm} eq 'CSV'
|
|
||
|
|
$GetParam{ResultForm} eq 'Excel'
|
|
)
|
|
{
|
|
my @CSVData;
|
|
my @CSVHead;
|
|
|
|
# mapping between header name and data field
|
|
my %Header2Data = (
|
|
'Class' => 'Class',
|
|
'Incident State' => 'InciState',
|
|
'Name' => 'Name',
|
|
'ConfigItemNumber' => 'Number',
|
|
'Deployment State' => 'DeplState',
|
|
'Version' => 'VersionID',
|
|
'Create Time' => 'CreateTime',
|
|
);
|
|
|
|
CONFIGITEMID:
|
|
for my $ConfigItemID ( @{$SearchResultList} ) {
|
|
|
|
# check for access rights
|
|
my $HasAccess = $ConfigItemObject->Permission(
|
|
Scope => 'Item',
|
|
ItemID => $ConfigItemID,
|
|
UserID => $Self->{UserID},
|
|
Type => $Self->{Config}->{Permission},
|
|
);
|
|
|
|
next CONFIGITEMID if !$HasAccess;
|
|
|
|
# get version
|
|
my $LastVersion = $ConfigItemObject->VersionGet(
|
|
ConfigItemID => $ConfigItemID,
|
|
XMLDataGet => 0,
|
|
);
|
|
|
|
# csv quote
|
|
if ( !@CSVHead ) {
|
|
@CSVHead = @{ $Self->{Config}->{SearchCSVData} };
|
|
}
|
|
|
|
# store data
|
|
my @Data;
|
|
for my $Header (@CSVHead) {
|
|
push @Data, $LastVersion->{ $Header2Data{$Header} };
|
|
}
|
|
push @CSVData, \@Data;
|
|
}
|
|
|
|
# csv quote
|
|
# translate non existing header may result in a garbage file
|
|
if ( !@CSVHead ) {
|
|
@CSVHead = @{ $Self->{Config}->{SearchCSVData} };
|
|
}
|
|
|
|
# translate headers
|
|
for my $Header (@CSVHead) {
|
|
|
|
# replace ConfigItemNumber header with the current ConfigItemNumber hook from sysconfig
|
|
if ( $Header eq 'ConfigItemNumber' ) {
|
|
$Header = $ConfigObject->Get('ITSMConfigItem::Hook');
|
|
}
|
|
else {
|
|
$Header = $LayoutObject->{LanguageObject}->Translate($Header);
|
|
}
|
|
}
|
|
|
|
my $CSVObject = $Kernel::OM->Get('Kernel::System::CSV');
|
|
my $CurSysDTObject = $Kernel::OM->Create('Kernel::System::DateTime');
|
|
if ( $GetParam{ResultForm} eq 'CSV' ) {
|
|
|
|
# Assemble CSV data.
|
|
my $CSV = $CSVObject->Array2CSV(
|
|
Head => \@CSVHead,
|
|
Data => \@CSVData,
|
|
Separator => $Self->{UserCSVSeparator},
|
|
);
|
|
|
|
# Return CSV to download.
|
|
return $LayoutObject->Attachment(
|
|
Filename => sprintf(
|
|
'change_search_%s.csv',
|
|
$CurSysDTObject->Format(
|
|
Format => '%F_%H-%M',
|
|
),
|
|
),
|
|
ContentType => "text/csv; charset=" . $LayoutObject->{UserCharset},
|
|
Content => $CSV,
|
|
);
|
|
}
|
|
elsif ( $GetParam{ResultForm} eq 'Excel' ) {
|
|
|
|
# Assemble Excel data.
|
|
my $Excel = $CSVObject->Array2CSV(
|
|
Head => \@CSVHead,
|
|
Data => \@CSVData,
|
|
Format => 'Excel',
|
|
);
|
|
|
|
# Return Excel to download.
|
|
return $LayoutObject->Attachment(
|
|
Filename => sprintf(
|
|
'change_search_%s.xlsx',
|
|
$CurSysDTObject->Format(
|
|
Format => '%F_%H-%M',
|
|
),
|
|
),
|
|
ContentType => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset="
|
|
. $LayoutObject->{UserCharset},
|
|
Content => $Excel,
|
|
);
|
|
}
|
|
}
|
|
|
|
# print PDF output
|
|
elsif ( $GetParam{ResultForm} eq 'Print' ) {
|
|
|
|
my @PDFData;
|
|
|
|
# get pdf object
|
|
my $PDFObject = $Kernel::OM->Get('Kernel::System::PDF');
|
|
|
|
CONFIGITEMID:
|
|
for my $ConfigItemID ( @{$SearchResultList} ) {
|
|
|
|
# check for access rights
|
|
my $HasAccess = $ConfigItemObject->Permission(
|
|
Scope => 'Item',
|
|
ItemID => $ConfigItemID,
|
|
UserID => $Self->{UserID},
|
|
Type => $Self->{Config}->{Permission},
|
|
);
|
|
|
|
next CONFIGITEMID if !$HasAccess;
|
|
|
|
# get version
|
|
my $LastVersion = $ConfigItemObject->VersionGet(
|
|
ConfigItemID => $ConfigItemID,
|
|
XMLDataGet => 0,
|
|
);
|
|
|
|
# set pdf rows
|
|
my @PDFRow;
|
|
for my $StoreData (qw(Class InciState Name Number DeplState VersionID CreateTime)) {
|
|
push @PDFRow, $LastVersion->{$StoreData};
|
|
}
|
|
push @PDFData, \@PDFRow;
|
|
|
|
}
|
|
|
|
# PDF Output
|
|
my $Title = $LayoutObject->{LanguageObject}->Translate('Configuration Item') . ' '
|
|
. $LayoutObject->{LanguageObject}->Translate('Search');
|
|
my $PrintedBy = $LayoutObject->{LanguageObject}->Translate('printed by');
|
|
my $Page = $LayoutObject->{LanguageObject}->Translate('Page');
|
|
my $Time = $LayoutObject->{Time};
|
|
|
|
# get maximum number of pages
|
|
my $MaxPages = $ConfigObject->Get('PDF::MaxPages');
|
|
if ( !$MaxPages || $MaxPages < 1 || $MaxPages > 1000 ) {
|
|
$MaxPages = 100;
|
|
}
|
|
|
|
# create the header
|
|
my $CellData;
|
|
|
|
# output 'No Result', if no content was given
|
|
if (@PDFData) {
|
|
$CellData->[0]->[0]->{Content} = $LayoutObject->{LanguageObject}->Translate('Class');
|
|
$CellData->[0]->[0]->{Font} = 'ProportionalBold';
|
|
$CellData->[0]->[1]->{Content} = $LayoutObject->{LanguageObject}->Translate('Incident State');
|
|
$CellData->[0]->[1]->{Font} = 'ProportionalBold';
|
|
$CellData->[0]->[2]->{Content} = $LayoutObject->{LanguageObject}->Translate('Name');
|
|
$CellData->[0]->[2]->{Font} = 'ProportionalBold';
|
|
$CellData->[0]->[3]->{Content} = $LayoutObject->{LanguageObject}->Translate('Number');
|
|
$CellData->[0]->[3]->{Font} = 'ProportionalBold';
|
|
$CellData->[0]->[4]->{Content} = $LayoutObject->{LanguageObject}->Translate('Deployment State');
|
|
$CellData->[0]->[4]->{Font} = 'ProportionalBold';
|
|
$CellData->[0]->[5]->{Content} = $LayoutObject->{LanguageObject}->Translate('Version');
|
|
$CellData->[0]->[5]->{Font} = 'ProportionalBold';
|
|
$CellData->[0]->[6]->{Content} = $LayoutObject->{LanguageObject}->Translate('Create Time');
|
|
$CellData->[0]->[6]->{Font} = 'ProportionalBold';
|
|
|
|
# create the content array
|
|
my $CounterRow = 1;
|
|
for my $Row (@PDFData) {
|
|
my $CounterColumn = 0;
|
|
for my $Content ( @{$Row} ) {
|
|
$CellData->[$CounterRow]->[$CounterColumn]->{Content} = $Content;
|
|
$CounterColumn++;
|
|
}
|
|
$CounterRow++;
|
|
}
|
|
}
|
|
else {
|
|
$CellData->[0]->[0]->{Content} = $LayoutObject->{LanguageObject}->Translate('No Result!');
|
|
}
|
|
|
|
# page params
|
|
my %PageParam;
|
|
$PageParam{PageOrientation} = 'landscape';
|
|
$PageParam{MarginTop} = 30;
|
|
$PageParam{MarginRight} = 40;
|
|
$PageParam{MarginBottom} = 40;
|
|
$PageParam{MarginLeft} = 40;
|
|
$PageParam{HeaderRight} = $Title;
|
|
|
|
# table params
|
|
my %TableParam;
|
|
$TableParam{CellData} = $CellData;
|
|
$TableParam{Type} = 'Cut';
|
|
$TableParam{FontSize} = 6;
|
|
$TableParam{Border} = 0;
|
|
$TableParam{BackgroundColorEven} = '#DDDDDD';
|
|
$TableParam{Padding} = 1;
|
|
$TableParam{PaddingTop} = 3;
|
|
$TableParam{PaddingBottom} = 3;
|
|
|
|
# create new pdf document
|
|
$PDFObject->DocumentNew(
|
|
Title => $ConfigObject->Get('Product') . ': ' . $Title,
|
|
Encode => $LayoutObject->{UserCharset},
|
|
);
|
|
|
|
# start table output
|
|
$PDFObject->PageNew(
|
|
%PageParam,
|
|
FooterRight => $Page . ' 1',
|
|
);
|
|
|
|
$PDFObject->PositionSet(
|
|
Move => 'relativ',
|
|
Y => -6,
|
|
);
|
|
|
|
# output title
|
|
$PDFObject->Text(
|
|
Text => $Title,
|
|
FontSize => 13,
|
|
);
|
|
|
|
$PDFObject->PositionSet(
|
|
Move => 'relativ',
|
|
Y => -6,
|
|
);
|
|
|
|
# output "printed by"
|
|
$PDFObject->Text(
|
|
Text => $PrintedBy . ' '
|
|
. $Self->{UserFullname} . ' '
|
|
. $Time,
|
|
FontSize => 9,
|
|
);
|
|
|
|
$PDFObject->PositionSet(
|
|
Move => 'relativ',
|
|
Y => -14,
|
|
);
|
|
|
|
PAGE:
|
|
for my $Count ( 2 .. $MaxPages ) {
|
|
|
|
# output table (or a fragment of it)
|
|
%TableParam = $PDFObject->Table(%TableParam);
|
|
|
|
# stop output or another page
|
|
if ( $TableParam{State} ) {
|
|
last PAGE;
|
|
}
|
|
else {
|
|
$PDFObject->PageNew(
|
|
%PageParam,
|
|
FooterRight => $Page . ' ' . $Count,
|
|
);
|
|
}
|
|
}
|
|
|
|
# return the pdf document
|
|
my $CurrentSystemDTObj = $Kernel::OM->Create('Kernel::System::DateTime');
|
|
my $PDFString = $PDFObject->DocumentOutput();
|
|
return $LayoutObject->Attachment(
|
|
Filename => sprintf(
|
|
'configitem_search_%s_%s.pdf',
|
|
$CurrentSystemDTObj->Format( Format => '%F_%H-%M' ),
|
|
),
|
|
ContentType => "application/pdf",
|
|
Content => $PDFString,
|
|
Type => 'inline',
|
|
);
|
|
}
|
|
|
|
# normal HTML output
|
|
else {
|
|
|
|
# start html page
|
|
my $Output = $LayoutObject->Header();
|
|
$Output .= $LayoutObject->NavigationBar();
|
|
$LayoutObject->Print( Output => \$Output );
|
|
$Output = '';
|
|
|
|
$Self->{Filter} = $ParamObject->GetParam( Param => 'Filter' ) || '';
|
|
$Self->{View} = $ParamObject->GetParam( Param => 'View' ) || '';
|
|
|
|
# show config items
|
|
my $LinkPage = 'Filter='
|
|
. $LayoutObject->Ascii2Html( Text => $Self->{Filter} )
|
|
. ';View=' . $LayoutObject->Ascii2Html( Text => $Self->{View} )
|
|
. ';SortBy=' . $LayoutObject->Ascii2Html( Text => $Self->{SortBy} )
|
|
. ';OrderBy='
|
|
. $LayoutObject->Ascii2Html( Text => $Self->{OrderBy} )
|
|
. ';Profile=' . $Self->{Profile} . ';TakeLastSearch=1;Subaction=Search'
|
|
. ';ClassID=' . $ClassID
|
|
. ';';
|
|
my $LinkSort = 'Filter='
|
|
. $LayoutObject->Ascii2Html( Text => $Self->{Filter} )
|
|
. ';View=' . $LayoutObject->Ascii2Html( Text => $Self->{View} )
|
|
. ';Profile=' . $Self->{Profile} . ';TakeLastSearch=1;Subaction=Search'
|
|
. ';ClassID=' . $ClassID
|
|
. ';';
|
|
my $LinkFilter = 'TakeLastSearch=1;Subaction=Search;Profile='
|
|
. $LayoutObject->Ascii2Html( Text => $Self->{Profile} )
|
|
. ';ClassID='
|
|
. $LayoutObject->Ascii2Html( Text => $ClassID )
|
|
. ';';
|
|
my $LinkBack = 'Subaction=LoadProfile;Profile='
|
|
. $LayoutObject->Ascii2Html( Text => $Self->{Profile} )
|
|
. ';ClassID='
|
|
. $LayoutObject->Ascii2Html( Text => $ClassID )
|
|
. ';TakeLastSearch=1;';
|
|
|
|
# find out which columns should be shown
|
|
my @ShowColumns;
|
|
if ( $Self->{Config}->{ShowColumns} ) {
|
|
|
|
# get all possible columns from config
|
|
my %PossibleColumn = %{ $Self->{Config}->{ShowColumns} };
|
|
|
|
# get the column names that should be shown
|
|
COLUMNNAME:
|
|
for my $Name ( sort keys %PossibleColumn ) {
|
|
next COLUMNNAME if !$PossibleColumn{$Name};
|
|
push @ShowColumns, $Name;
|
|
}
|
|
}
|
|
|
|
# get the configured columns and reorganize them by class name
|
|
if (
|
|
IsArrayRefWithData( $Self->{Config}->{ShowColumnsByClass} )
|
|
&& $ClassID
|
|
)
|
|
{
|
|
|
|
my %ColumnByClass;
|
|
|
|
NAME:
|
|
for my $Name ( @{ $Self->{Config}->{ShowColumnsByClass} } ) {
|
|
my ( $Class, $Column ) = split /::/, $Name, 2;
|
|
|
|
next NAME if !$Column;
|
|
|
|
push @{ $ColumnByClass{$Class} }, $Column;
|
|
}
|
|
|
|
# check if there is a specific column config for the selected class
|
|
my $SelectedClass = $ClassList->{$ClassID};
|
|
if ( $ColumnByClass{$SelectedClass} ) {
|
|
@ShowColumns = @{ $ColumnByClass{$SelectedClass} };
|
|
}
|
|
}
|
|
|
|
my $ClassName = $ClassList->{$ClassID};
|
|
my $Title = $LayoutObject->{LanguageObject}->Translate('Config Item Search Results')
|
|
. ' '
|
|
. $LayoutObject->{LanguageObject}->Translate('Class')
|
|
. ' '
|
|
. $LayoutObject->{LanguageObject}->Translate($ClassName);
|
|
|
|
$Output .= $LayoutObject->ITSMConfigItemListShow(
|
|
ConfigItemIDs => $SearchResultList,
|
|
Total => scalar @{$SearchResultList},
|
|
View => $Self->{View},
|
|
Filter => $ClassID,
|
|
Env => $Self,
|
|
LinkPage => $LinkPage,
|
|
LinkSort => $LinkSort,
|
|
LinkFilter => $LinkFilter,
|
|
LinkBack => $LinkBack,
|
|
Profile => $Self->{Profile},
|
|
TitleName => $Title,
|
|
ShowColumns => \@ShowColumns,
|
|
SortBy => $LayoutObject->Ascii2Html( Text => $Self->{SortBy} ),
|
|
OrderBy => $LayoutObject->Ascii2Html( Text => $Self->{OrderBy} ),
|
|
ClassID => $ClassID,
|
|
RequestURL => $Self->{RequestedURL},
|
|
);
|
|
|
|
$LayoutObject->AddJSData(
|
|
Key => 'ITSMConfigItemSearch',
|
|
Value => {
|
|
Profile => $Self->{Profile},
|
|
ClassID => $ClassID,
|
|
Action => $Self->{Action},
|
|
},
|
|
);
|
|
|
|
# build footer
|
|
$Output .= $LayoutObject->Footer();
|
|
|
|
return $Output;
|
|
}
|
|
}
|
|
|
|
# ------------------------------------------------------------ #
|
|
# call search dialog from search empty screen
|
|
# ------------------------------------------------------------ #
|
|
else {
|
|
|
|
# show default search screen
|
|
$Output = $LayoutObject->Header();
|
|
$Output .= $LayoutObject->NavigationBar();
|
|
|
|
$LayoutObject->AddJSData(
|
|
Key => 'ITSMConfigItemOpenSearchDialog',
|
|
Value => {
|
|
Profile => $Self->{Profile},
|
|
ClassID => $ClassID,
|
|
Action => $Self->{Action},
|
|
},
|
|
);
|
|
|
|
# output template
|
|
$Output .= $LayoutObject->Output(
|
|
TemplateFile => 'AgentITSMConfigItemSearch',
|
|
);
|
|
|
|
# output footer
|
|
$Output .= $LayoutObject->Footer();
|
|
|
|
return $Output;
|
|
}
|
|
}
|
|
|
|
sub _XMLSearchFormOutput {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
my %GetParam = %{ $Param{GetParam} };
|
|
|
|
# check needed stuff
|
|
return if !$Param{XMLDefinition};
|
|
return if ref $Param{XMLDefinition} ne 'ARRAY';
|
|
return if ref $Param{XMLAttributes} ne 'ARRAY';
|
|
|
|
$Param{Level} ||= 0;
|
|
ITEM:
|
|
for my $Item ( @{ $Param{XMLDefinition} } ) {
|
|
|
|
# set prefix
|
|
my $InputKey = $Item->{Key};
|
|
my $Name = $Item->{Name};
|
|
if ( $Param{Prefix} ) {
|
|
$InputKey = $Param{Prefix} . '::' . $InputKey;
|
|
$Name = $Param{PrefixName} . '::' . $Name;
|
|
}
|
|
|
|
# output attribute, if marked as searchable
|
|
if ( $Item->{Searchable} ) {
|
|
my $Value;
|
|
|
|
# date type fields must to get all date parameters
|
|
if ( $Item->{Input}->{Type} eq 'Date' ) {
|
|
$Value =
|
|
{
|
|
$InputKey => $GetParam{$InputKey},
|
|
$InputKey . '::TimeStart::Day' => $GetParam{ $InputKey . '::TimeStart::Day' },
|
|
$InputKey
|
|
. '::TimeStart::Month' => $GetParam{ $InputKey . '::TimeStart::Month' },
|
|
$InputKey . '::TimeStart::Year' => $GetParam{ $InputKey . '::TimeStart::Year' },
|
|
$InputKey . '::TimeStop::Day' => $GetParam{ $InputKey . '::TimeStop::Day' },
|
|
$InputKey . '::TimeStop::Month' => $GetParam{ $InputKey . '::TimeStop::Month' },
|
|
$InputKey . '::TimeStop::Year' => $GetParam{ $InputKey . '::TimeStop::Year' },
|
|
} || '';
|
|
}
|
|
|
|
# date-time type fields must get all date and time parameters
|
|
elsif ( $Item->{Input}->{Type} eq 'DateTime' ) {
|
|
$Value =
|
|
{
|
|
$InputKey => $GetParam{$InputKey},
|
|
$InputKey
|
|
. '::TimeStart::Minute' => $GetParam{ $InputKey . '::TimeStart::Minute' },
|
|
$InputKey . '::TimeStart::Hour' => $GetParam{ $InputKey . '::TimeStart::Hour' },
|
|
$InputKey . '::TimeStart::Day' => $GetParam{ $InputKey . '::TimeStart::Day' },
|
|
$InputKey
|
|
. '::TimeStart::Month' => $GetParam{ $InputKey . '::TimeStart::Month' },
|
|
$InputKey . '::TimeStart::Year' => $GetParam{ $InputKey . '::TimeStart::Year' },
|
|
$InputKey
|
|
. '::TimeStop::Minute' => $GetParam{ $InputKey . '::TimeStop::Minute' },
|
|
$InputKey . '::TimeStop::Hour' => $GetParam{ $InputKey . '::TimeStop::Hour' },
|
|
$InputKey . '::TimeStop::Day' => $GetParam{ $InputKey . '::TimeStop::Day' },
|
|
$InputKey . '::TimeStop::Month' => $GetParam{ $InputKey . '::TimeStop::Month' },
|
|
$InputKey . '::TimeStop::Year' => $GetParam{ $InputKey . '::TimeStop::Year' },
|
|
} || '';
|
|
}
|
|
|
|
# other kinds of fields can get its value directly
|
|
else {
|
|
$Value = $GetParam{$InputKey} || '';
|
|
}
|
|
|
|
# get layout object
|
|
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
|
|
|
|
# create search input element
|
|
my $InputString = $LayoutObject->ITSMConfigItemSearchInputCreate(
|
|
Key => $InputKey,
|
|
Item => $Item,
|
|
Value => $Value,
|
|
);
|
|
|
|
# output attribute row
|
|
$LayoutObject->Block(
|
|
Name => 'AttributeRow',
|
|
Data => {
|
|
Key => $InputKey,
|
|
Name => $Name,
|
|
Description => $Item->{Description} || $Item->{Name},
|
|
InputString => $InputString,
|
|
},
|
|
);
|
|
|
|
push @{ $Param{XMLAttributes} }, {
|
|
Key => $InputKey,
|
|
Value => $Name,
|
|
};
|
|
}
|
|
|
|
next ITEM if !$Item->{Sub};
|
|
|
|
# start recursion, if "Sub" was found
|
|
$Self->_XMLSearchFormOutput(
|
|
XMLDefinition => $Item->{Sub},
|
|
XMLAttributes => $Param{XMLAttributes},
|
|
Level => $Param{Level} + 1,
|
|
Prefix => $InputKey,
|
|
PrefixName => $Name,
|
|
GetParam => \%GetParam,
|
|
);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
sub _XMLSearchFormGet {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
# check needed stuff
|
|
return if !$Param{XMLDefinition};
|
|
return if !$Param{XMLFormData};
|
|
return if !$Param{XMLGetParam};
|
|
return if ref $Param{XMLDefinition} ne 'ARRAY';
|
|
return if ref $Param{XMLFormData} ne 'ARRAY';
|
|
return if ref $Param{XMLGetParam} ne 'ARRAY';
|
|
|
|
$Param{Level} ||= 0;
|
|
|
|
ITEM:
|
|
for my $Item ( @{ $Param{XMLDefinition} } ) {
|
|
|
|
# create inputkey
|
|
my $InputKey = $Item->{Key};
|
|
if ( $Param{Prefix} ) {
|
|
$InputKey = $Param{Prefix} . '::' . $InputKey;
|
|
}
|
|
|
|
# Date type fields must to get all date parameters.
|
|
if ( $Item->{Input}->{Type} eq 'Date' && $Param{$InputKey} ) {
|
|
$Param{$InputKey} =
|
|
{
|
|
$InputKey => $Param{$InputKey},
|
|
$InputKey . '::TimeStart::Day' => $Param{ $InputKey . '::TimeStart::Day' },
|
|
$InputKey
|
|
. '::TimeStart::Month' => $Param{ $InputKey . '::TimeStart::Month' },
|
|
$InputKey . '::TimeStart::Year' => $Param{ $InputKey . '::TimeStart::Year' },
|
|
$InputKey . '::TimeStop::Day' => $Param{ $InputKey . '::TimeStop::Day' },
|
|
$InputKey . '::TimeStop::Month' => $Param{ $InputKey . '::TimeStop::Month' },
|
|
$InputKey . '::TimeStop::Year' => $Param{ $InputKey . '::TimeStop::Year' },
|
|
} || '';
|
|
}
|
|
|
|
# Date-time type fields must get all date and time parameters.
|
|
elsif ( $Item->{Input}->{Type} eq 'DateTime' && $Param{$InputKey} ) {
|
|
$Param{$InputKey} =
|
|
{
|
|
$InputKey => $Param{$InputKey},
|
|
$InputKey
|
|
. '::TimeStart::Minute' => $Param{ $InputKey . '::TimeStart::Minute' },
|
|
$InputKey . '::TimeStart::Hour' => $Param{ $InputKey . '::TimeStart::Hour' },
|
|
$InputKey . '::TimeStart::Day' => $Param{ $InputKey . '::TimeStart::Day' },
|
|
$InputKey
|
|
. '::TimeStart::Month' => $Param{ $InputKey . '::TimeStart::Month' },
|
|
$InputKey . '::TimeStart::Year' => $Param{ $InputKey . '::TimeStart::Year' },
|
|
$InputKey
|
|
. '::TimeStop::Minute' => $Param{ $InputKey . '::TimeStop::Minute' },
|
|
$InputKey . '::TimeStop::Hour' => $Param{ $InputKey . '::TimeStop::Hour' },
|
|
$InputKey . '::TimeStop::Day' => $Param{ $InputKey . '::TimeStop::Day' },
|
|
$InputKey . '::TimeStop::Month' => $Param{ $InputKey . '::TimeStop::Month' },
|
|
$InputKey . '::TimeStop::Year' => $Param{ $InputKey . '::TimeStop::Year' },
|
|
} || '';
|
|
}
|
|
|
|
# get search form data
|
|
my $Values = $Kernel::OM->Get('Kernel::Output::HTML::Layout')->ITSMConfigItemSearchFormDataGet(
|
|
Key => $InputKey,
|
|
Item => $Item,
|
|
Value => $Param{$InputKey},
|
|
);
|
|
|
|
# create search key
|
|
my $SearchKey = $InputKey;
|
|
$SearchKey =~ s{ :: }{\'\}[%]\{\'}xmsg;
|
|
$SearchKey = "[1]{'Version'}[1]{'$SearchKey'}[%]{'Content'}";
|
|
|
|
# ITSMConfigItemSearchFormDataGet() can return string, arrayref or hashref
|
|
if ( ref $Values eq 'ARRAY' ) {
|
|
|
|
# filter empty elements
|
|
my @SearchValues = grep {$_} @{$Values};
|
|
|
|
if (@SearchValues) {
|
|
push @{ $Param{XMLFormData} }, {
|
|
$SearchKey => \@SearchValues,
|
|
};
|
|
|
|
push @{ $Param{XMLGetParam} }, {
|
|
$InputKey => \@SearchValues,
|
|
};
|
|
}
|
|
|
|
}
|
|
elsif ($Values) {
|
|
|
|
# e.g. for Date between searches
|
|
push @{ $Param{XMLFormData} }, {
|
|
$SearchKey => $Values,
|
|
};
|
|
|
|
if ( ref $Values eq 'HASH' ) {
|
|
if ( $Item->{Input}->{Type} eq 'Date' ) {
|
|
if ( $Values->{'-between'} ) {
|
|
|
|
# get time elemet values
|
|
my ( $StartDate, $StopDate ) = @{ $Values->{'-between'} };
|
|
my ( $StartYear, $StartMonth, $StartDay ) = split( /-/, $StartDate );
|
|
my ( $StopYear, $StopMonth, $StopDay ) = split( /-/, $StopDate );
|
|
|
|
# store time elment values
|
|
push @{ $Param{XMLGetParam} }, {
|
|
$InputKey => 1,
|
|
$InputKey . '::TimeStart::Day' => $StartDay,
|
|
$InputKey . '::TimeStart::Month' => $StartMonth,
|
|
$InputKey . '::TimeStart::Year' => $StartYear,
|
|
$InputKey . '::TimeStop::Day' => $StopDay,
|
|
$InputKey . '::TimeStop::Month' => $StopMonth,
|
|
$InputKey . '::TimeStop::Year' => $StopYear,
|
|
};
|
|
}
|
|
}
|
|
elsif ( $Item->{Input}->{Type} eq 'DateTime' ) {
|
|
if ( $Values->{'-between'} ) {
|
|
|
|
# get time elemet values
|
|
my ( $StartDateTime, $StopDateTime ) = @{ $Values->{'-between'} };
|
|
my ( $StartDate, $StartTime ) = split( /\s/, $StartDateTime );
|
|
my ( $StartYear, $StartMonth, $StartDay ) = split( /-/, $StartDate );
|
|
my ( $StartHour, $StartMinute, $StartSecond ) = split( /\:/, $StartTime );
|
|
|
|
my ( $StopDate, $StopTime ) = split( /\s/, $StopDateTime );
|
|
my ( $StopYear, $StopMonth, $StopDay ) = split( /-/, $StopDate );
|
|
my ( $StopHour, $StopMinute, $StopSecond ) = split( /\:/, $StopTime );
|
|
|
|
# store time elment values
|
|
push @{ $Param{XMLGetParam} }, {
|
|
$InputKey => 1,
|
|
$InputKey . '::TimeStart::Minute' => $StartMinute,
|
|
$InputKey . '::TimeStart::Hour' => $StartHour,
|
|
$InputKey . '::TimeStart::Day' => $StartDay,
|
|
$InputKey . '::TimeStart::Month' => $StartMonth,
|
|
$InputKey . '::TimeStart::Year' => $StartYear,
|
|
$InputKey . '::TimeStop::Minute' => $StopMinute,
|
|
$InputKey . '::TimeStop::Hour' => $StopHour,
|
|
$InputKey . '::TimeStop::Day' => $StopDay,
|
|
$InputKey . '::TimeStop::Month' => $StopMonth,
|
|
$InputKey . '::TimeStop::Year' => $StopYear,
|
|
};
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
push @{ $Param{XMLGetParam} }, {
|
|
$InputKey => $Values,
|
|
};
|
|
}
|
|
|
|
}
|
|
|
|
next ITEM if !$Item->{Sub};
|
|
|
|
# start recursion, if "Sub" was found
|
|
$Self->_XMLSearchFormGet(
|
|
%Param,
|
|
XMLDefinition => $Item->{Sub},
|
|
XMLFormData => $Param{XMLFormData},
|
|
XMLGetParam => $Param{XMLGetParam},
|
|
Level => $Param{Level} + 1,
|
|
Prefix => $InputKey,
|
|
);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
sub _XMLSearchAttributesGet {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
# check needed stuff
|
|
return if !$Param{XMLDefinition};
|
|
return if ref $Param{XMLDefinition} ne 'ARRAY';
|
|
return if ref $Param{XMLAttributes} ne 'ARRAY';
|
|
|
|
$Param{Level} ||= 0;
|
|
ITEM:
|
|
for my $Item ( @{ $Param{XMLDefinition} } ) {
|
|
|
|
# set prefix
|
|
my $InputKey = $Item->{Key};
|
|
my $Name = $Item->{Name};
|
|
if ( $Param{Prefix} ) {
|
|
$InputKey = $Param{Prefix} . '::' . $InputKey;
|
|
$Name = $Param{PrefixName} . '::' . $Name;
|
|
}
|
|
|
|
# store attribute, if marked as searchable
|
|
if ( $Item->{Searchable} ) {
|
|
push @{ $Param{XMLAttributes} }, {
|
|
Key => $InputKey,
|
|
Value => $Name,
|
|
};
|
|
}
|
|
|
|
next ITEM if !$Item->{Sub};
|
|
|
|
# start recursion, if "Sub" was found
|
|
$Self->_XMLSearchAttributesGet(
|
|
XMLDefinition => $Item->{Sub},
|
|
XMLAttributes => $Param{XMLAttributes},
|
|
Level => $Param{Level} + 1,
|
|
Prefix => $InputKey,
|
|
PrefixName => $Name,
|
|
);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
1;
|