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

2351 lines
57 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::System::ImportExport;
use strict;
use warnings;
our @ObjectDependencies = (
'Kernel::System::Cache',
'Kernel::Config',
'Kernel::System::CheckItem',
'Kernel::System::DB',
'Kernel::System::Log',
);
=head1 NAME
Kernel::System::ImportExport - import, export lib
=head1 DESCRIPTION
All import and export functions.
=head1 PUBLIC INTERFACE
=cut
=head2 new()
Create an object
use Kernel::System::ObjectManager;
local $Kernel::OM = Kernel::System::ObjectManager->new();
my $ImportExportObject = $Kernel::OM->Get('Kernel::System::ImportExport');
=cut
sub new {
my ( $Type, %Param ) = @_;
# allocate new hash for object
my $Self = {};
bless( $Self, $Type );
return $Self;
}
=head2 TemplateList()
Return a list of templates as array reference
my $TemplateList = $ImportExportObject->TemplateList(
Object => 'Ticket', # (optional)
Format => 'CSV' # (optional)
UserID => 1,
);
=cut
sub TemplateList {
my ( $Self, %Param ) = @_;
# check needed stuff
if ( !$Param{UserID} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => 'Need UserID!',
);
return;
}
# create sql string
my $SQL = 'SELECT id FROM imexport_template WHERE 1=1 ';
my @BIND;
if ( $Param{Object} ) {
$SQL .= 'AND imexport_object = ? ';
push @BIND, \$Param{Object};
}
if ( $Param{Format} ) {
$SQL .= 'AND imexport_format = ? ';
push @BIND, \$Param{Format};
}
# add order option
$SQL .= 'ORDER BY id';
# get DB object
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
# ask database
$DBObject->Prepare(
SQL => $SQL,
Bind => \@BIND,
);
# fetch the result
my @TemplateList;
while ( my @Row = $DBObject->FetchrowArray() ) {
push @TemplateList, $Row[0];
}
return \@TemplateList;
}
=head2 TemplateGet()
Get a import export template
Return
$TemplateData{TemplateID}
$TemplateData{Number}
$TemplateData{Object}
$TemplateData{Format}
$TemplateData{Name}
$TemplateData{ValidID}
$TemplateData{Comment}
$TemplateData{CreateTime}
$TemplateData{CreateBy}
$TemplateData{ChangeTime}
$TemplateData{ChangeBy}
my $TemplateDataRef = $ImportExportObject->TemplateGet(
TemplateID => 3,
UserID => 1,
);
=cut
sub TemplateGet {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(TemplateID UserID)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# check if result is already cached
return $Self->{Cache}->{TemplateGet}->{ $Param{TemplateID} }
if $Self->{Cache}->{TemplateGet}->{ $Param{TemplateID} };
# get DB object
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
# ask database
$DBObject->Prepare(
SQL => 'SELECT id, imexport_object, imexport_format, name, valid_id, comments, '
. 'create_time, create_by, change_time, change_by FROM imexport_template WHERE id = ?',
Bind => [ \$Param{TemplateID} ],
Limit => 1,
);
# fetch the result
my %TemplateData;
while ( my @Row = $DBObject->FetchrowArray() ) {
$TemplateData{TemplateID} = $Row[0];
$TemplateData{Object} = $Row[1];
$TemplateData{Format} = $Row[2];
$TemplateData{Name} = $Row[3];
$TemplateData{ValidID} = $Row[4];
$TemplateData{Comment} = $Row[5] || '';
$TemplateData{CreateTime} = $Row[6];
$TemplateData{CreateBy} = $Row[7];
$TemplateData{ChangeTime} = $Row[8];
$TemplateData{ChangeBy} = $Row[9];
$TemplateData{Number} = sprintf "%06d", $TemplateData{TemplateID};
}
# cache the result
$Self->{Cache}->{TemplateGet}->{ $Param{TemplateID} } = \%TemplateData;
return \%TemplateData;
}
=head2 TemplateAdd()
Add a new import/export template
my $TemplateID = $ImportExportObject->TemplateAdd(
Object => 'Ticket',
Format => 'CSV',
Name => 'Template Name',
ValidID => 1,
Comment => 'Comment', # (optional)
UserID => 1,
);
=cut
sub TemplateAdd {
my ( $Self, %Param ) = @_;
# get log object
my $LogObject = $Kernel::OM->Get('Kernel::System::Log');
# check needed stuff
for my $Argument (qw(Object Format Name ValidID UserID)) {
if ( !$Param{$Argument} ) {
$LogObject->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# set default values
$Param{Comment} ||= '';
# get CheckItem object
my $CheckItemObject = $Kernel::OM->Get('Kernel::System::CheckItem');
# cleanup given params
for my $Argument (qw(Object Format)) {
$CheckItemObject->StringClean(
StringRef => \$Param{$Argument},
RemoveAllNewlines => 1,
RemoveAllTabs => 1,
RemoveAllSpaces => 1,
);
}
for my $Argument (qw(Name Comment)) {
$CheckItemObject->StringClean(
StringRef => \$Param{$Argument},
RemoveAllNewlines => 1,
RemoveAllTabs => 1,
);
}
# get DB object
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
# find exiting template with same name
$DBObject->Prepare(
SQL => 'SELECT id FROM imexport_template WHERE imexport_object = ? AND name = ?',
Bind => [ \$Param{Object}, \$Param{Name} ],
Limit => 1,
);
# fetch the result
my $NoAdd;
while ( $DBObject->FetchrowArray() ) {
$NoAdd = 1;
}
# abort insert of new template, if template name already exists
if ($NoAdd) {
$LogObject->Log(
Priority => 'error',
Message =>
"Can't add new template! Template with same name already exists in this object.",
);
return;
}
# insert new template
return if !$DBObject->Do(
SQL => 'INSERT INTO imexport_template '
. '(imexport_object, imexport_format, name, valid_id, comments, '
. 'create_time, create_by, change_time, change_by) VALUES '
. '(?, ?, ?, ?, ?, current_timestamp, ?, current_timestamp, ?)',
Bind => [
\$Param{Object}, \$Param{Format}, \$Param{Name}, \$Param{ValidID},
\$Param{Comment}, \$Param{UserID}, \$Param{UserID},
],
);
# find id of new template
$DBObject->Prepare(
SQL => 'SELECT id FROM imexport_template WHERE imexport_object = ? AND name = ?',
Bind => [ \$Param{Object}, \$Param{Name} ],
Limit => 1,
);
# fetch the result
my $TemplateID;
while ( my @Row = $DBObject->FetchrowArray() ) {
$TemplateID = $Row[0];
}
return $TemplateID;
}
=head2 TemplateUpdate()
Update a existing import/export template
my $True = $ImportExportObject->TemplateUpdate(
TemplateID => 123,
Name => 'Template Name',
ValidID => 1,
Comment => 'Comment', # (optional)
UserID => 1,
);
=cut
sub TemplateUpdate {
my ( $Self, %Param ) = @_;
# get log object
my $LogObject = $Kernel::OM->Get('Kernel::System::Log');
# check needed stuff
for my $Argument (qw(TemplateID Name ValidID UserID)) {
if ( !$Param{$Argument} ) {
$LogObject->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# set default values
$Param{Comment} ||= '';
# cleanup given params
for my $Argument (qw(Name Comment)) {
$Kernel::OM->Get('Kernel::System::CheckItem')->StringClean(
StringRef => \$Param{$Argument},
RemoveAllNewlines => 1,
RemoveAllTabs => 1,
);
}
# get DB object
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
# get the object of this template id
$DBObject->Prepare(
SQL => 'SELECT imexport_object FROM imexport_template WHERE id = ?',
Bind => [ \$Param{TemplateID} ],
Limit => 1,
);
# fetch the result
my $Object;
while ( my @Row = $DBObject->FetchrowArray() ) {
$Object = $Row[0];
}
if ( !$Object ) {
$LogObject->Log(
Priority => 'error',
Message => "Can't update template because it hasn't been found!",
);
return;
}
# find exiting template with same name
$DBObject->Prepare(
SQL => 'SELECT id FROM imexport_template WHERE imexport_object = ? AND name = ?',
Bind => [ \$Object, \$Param{Name} ],
Limit => 1,
);
# fetch the result
my $Update = 1;
while ( my @Row = $DBObject->FetchrowArray() ) {
if ( $Param{TemplateID} ne $Row[0] ) {
$Update = 0;
}
}
if ( !$Update ) {
$LogObject->Log(
Priority => 'error',
Message =>
"Can't update template! Template with same name already exists in this object.",
);
return;
}
# reset cache
delete $Self->{Cache}->{TemplateGet}->{ $Param{TemplateID} };
# update template
return $DBObject->Do(
SQL => 'UPDATE imexport_template SET name = ?,'
. 'valid_id = ?, comments = ?, '
. 'change_time = current_timestamp, change_by = ? '
. 'WHERE id = ?',
Bind => [
\$Param{Name}, \$Param{ValidID}, \$Param{Comment},
\$Param{UserID}, \$Param{TemplateID},
],
);
}
=head2 TemplateDelete()
Delete existing import/export templates
my $True = $ImportExportObject->TemplateDelete(
TemplateID => 123,
UserID => 1,
);
or
my $True = $ImportExportObject->TemplateDelete(
TemplateID => [1,44,166,5],
UserID => 1,
);
=cut
sub TemplateDelete {
my ( $Self, %Param ) = @_;
# get log object
my $LogObject = $Kernel::OM->Get('Kernel::System::Log');
# check needed stuff
for my $Argument (qw(TemplateID UserID)) {
if ( !$Param{$Argument} ) {
$LogObject->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
if ( !ref $Param{TemplateID} ) {
$Param{TemplateID} = [ $Param{TemplateID} ];
}
elsif ( ref $Param{TemplateID} ne 'ARRAY' ) {
$LogObject->Log(
Priority => 'error',
Message => 'TemplateID must be an array reference or a string!',
);
return;
}
# delete existing search data
$Self->SearchDataDelete(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
# delete all mapping data
for my $TemplateID ( @{ $Param{TemplateID} } ) {
$Self->MappingDelete(
TemplateID => $TemplateID,
UserID => $Param{UserID},
);
}
# delete existing format data
$Self->FormatDataDelete(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
# delete existing object data
$Self->ObjectDataDelete(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
# create the template id string
my $TemplateIDString = join q{, }, map {'?'} @{ $Param{TemplateID} };
# create and add bind parameters
my @BIND = map { \$_ } @{ $Param{TemplateID} };
# reset cache
delete $Self->{Cache}->{TemplateGet};
# delete templates
return $Kernel::OM->Get('Kernel::System::DB')->Do(
SQL => "DELETE FROM imexport_template WHERE id IN ( $TemplateIDString )",
Bind => \@BIND,
);
}
=head2 ObjectList()
Return a list of available objects as hash reference
my $ObjectList = $ImportExportObject->ObjectList();
=cut
sub ObjectList {
my ( $Self, %Param ) = @_;
# get config
my $ModuleList = $Kernel::OM->Get('Kernel::Config')->Get('ImportExport::ObjectBackendRegistration');
return if !$ModuleList;
return if ref $ModuleList ne 'HASH';
# create the object list
my $ObjectList = {};
for my $Module ( sort keys %{$ModuleList} ) {
$ObjectList->{$Module} = $ModuleList->{$Module}->{Name};
}
return $ObjectList;
}
=head2 ObjectAttributesGet()
Get the attributes of an object backend as array/hash reference
my $Attributes = $ImportExportObject->ObjectAttributesGet(
TemplateID => 123,
UserID => 1,
);
=cut
sub ObjectAttributesGet {
my ( $Self, %Param ) = @_;
# get log object
my $LogObject = $Kernel::OM->Get('Kernel::System::Log');
# check needed stuff
for my $Argument (qw(TemplateID UserID)) {
if ( !$Param{$Argument} ) {
$LogObject->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# get template data
my $TemplateData = $Self->TemplateGet(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
# check template data
if ( !$TemplateData || !$TemplateData->{Object} ) {
$LogObject->Log(
Priority => 'error',
Message => "Template with ID $Param{TemplateID} is incomplete!",
);
return;
}
# load backend
my $Backend = $Kernel::OM->Get(
'Kernel::System::ImportExport::ObjectBackend::' . $TemplateData->{Object}
);
return if !$Backend;
# get an attribute list of the object
my $Attributes = $Backend->ObjectAttributesGet(
UserID => $Param{UserID},
);
return $Attributes;
}
=head2 ObjectDataGet()
Get the object data from a template
my $ObjectDataRef = $ImportExportObject->ObjectDataGet(
TemplateID => 3,
UserID => 1,
);
=cut
sub ObjectDataGet {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(TemplateID UserID)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# get DB object
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
# ask database
$DBObject->Prepare(
SQL => 'SELECT data_key, data_value FROM imexport_object WHERE template_id = ?',
Bind => [ \$Param{TemplateID} ],
);
# fetch the result
my %ObjectData;
while ( my @Row = $DBObject->FetchrowArray() ) {
$ObjectData{ $Row[0] } = $Row[1];
}
return \%ObjectData;
}
=head2 ObjectDataSave()
Save the object data of a template
my $True = $ImportExportObject->ObjectDataSave(
TemplateID => 123,
ObjectData => $HashRef,
UserID => 1,
);
=cut
sub ObjectDataSave {
my ( $Self, %Param ) = @_;
# get log object
my $LogObject = $Kernel::OM->Get('Kernel::System::Log');
# check needed stuff
for my $Argument (qw(TemplateID ObjectData UserID)) {
if ( !$Param{$Argument} ) {
$LogObject->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
if ( ref $Param{ObjectData} ne 'HASH' ) {
$LogObject->Log(
Priority => 'error',
Message => 'ObjectData must be a hash reference!',
);
return;
}
# delete existing object data
$Self->ObjectDataDelete(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
DATAKEY:
for my $DataKey ( sort keys %{ $Param{ObjectData} } ) {
my $DataValue = $Param{ObjectData}->{$DataKey};
next DATAKEY if !defined $DataKey;
next DATAKEY if !defined $DataValue;
# insert one row
$Kernel::OM->Get('Kernel::System::DB')->Do(
SQL => 'INSERT INTO imexport_object '
. '(template_id, data_key, data_value) VALUES '
. '(?, ?, ?)',
Bind => [ \$Param{TemplateID}, \$DataKey, \$DataValue ],
);
}
return 1;
}
=head2 ObjectDataDelete()
Delete the existing object data of a template
my $True = $ImportExportObject->ObjectDataDelete(
TemplateID => 123,
UserID => 1,
);
or
my $True = $ImportExportObject->ObjectDataDelete(
TemplateID => [1,44,166,5],
UserID => 1,
);
=cut
sub ObjectDataDelete {
my ( $Self, %Param ) = @_;
# get log object
my $LogObject = $Kernel::OM->Get('Kernel::System::Log');
# check needed stuff
for my $Argument (qw(TemplateID UserID)) {
if ( !$Param{$Argument} ) {
$LogObject->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
if ( !ref $Param{TemplateID} ) {
$Param{TemplateID} = [ $Param{TemplateID} ];
}
elsif ( ref $Param{TemplateID} ne 'ARRAY' ) {
$LogObject->Log(
Priority => 'error',
Message => 'TemplateID must be an array reference or a string!',
);
return;
}
# create the template id string
my $TemplateIDString = join q{, }, map {'?'} @{ $Param{TemplateID} };
# create and add bind parameters
my @BIND = map { \$_ } @{ $Param{TemplateID} };
# delete templates
return $Kernel::OM->Get('Kernel::System::DB')->Do(
SQL => "DELETE FROM imexport_object WHERE template_id IN ( $TemplateIDString )",
Bind => \@BIND,
);
}
=head2 FormatList()
Return a list of available formats as hash reference
my $FormatList = $ImportExportObject->FormatList();
=cut
sub FormatList {
my ( $Self, %Param ) = @_;
# get config
my $ModuleList = $Kernel::OM->Get('Kernel::Config')->Get('ImportExport::FormatBackendRegistration');
return if !$ModuleList;
return if ref $ModuleList ne 'HASH';
# create the format list
my $FormatList = {};
for my $Module ( sort keys %{$ModuleList} ) {
$FormatList->{$Module} = $ModuleList->{$Module}->{Name};
}
return $FormatList;
}
=head2 FormatAttributesGet()
Get the attributes of a format backend as array/hash reference
my $Attributes = $ImportExportObject->FormatAttributesGet(
TemplateID => 123,
UserID => 1,
);
=cut
sub FormatAttributesGet {
my ( $Self, %Param ) = @_;
# get log object
my $LogObject = $Kernel::OM->Get('Kernel::System::Log');
# check needed stuff
for my $Argument (qw(TemplateID UserID)) {
if ( !$Param{$Argument} ) {
$LogObject->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# get template data
my $TemplateData = $Self->TemplateGet(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
# check template data
if ( !$TemplateData || !$TemplateData->{Format} ) {
$LogObject->Log(
Priority => 'error',
Message => "Template with ID $Param{TemplateID} is incomplete!",
);
return;
}
# load backend
my $Backend = $Kernel::OM->Get(
'Kernel::System::ImportExport::FormatBackend::' . $TemplateData->{Format}
);
return if !$Backend;
# get an attribute list of the format
my $Attributes = $Backend->FormatAttributesGet(
UserID => $Param{UserID},
);
return $Attributes;
}
=head2 FormatDataGet()
Get the format data from a template
my $FormatDataRef = $ImportExportObject->FormatDataGet(
TemplateID => 3,
UserID => 1,
);
=cut
sub FormatDataGet {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(TemplateID UserID)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# get DB object
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
# ask database
$DBObject->Prepare(
SQL => 'SELECT data_key, data_value FROM imexport_format WHERE template_id = ?',
Bind => [ \$Param{TemplateID} ],
);
# fetch the result
my %FormatData;
while ( my @Row = $DBObject->FetchrowArray() ) {
$FormatData{ $Row[0] } = $Row[1];
}
return \%FormatData;
}
=head2 FormatDataSave()
Save the format data of a template
my $True = $ImportExportObject->FormatDataSave(
TemplateID => 123,
FormatData => $HashRef,
UserID => 1,
);
=cut
sub FormatDataSave {
my ( $Self, %Param ) = @_;
# get log object
my $LogObject = $Kernel::OM->Get('Kernel::System::Log');
# check needed stuff
for my $Argument (qw(TemplateID FormatData UserID)) {
if ( !$Param{$Argument} ) {
$LogObject->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
if ( ref $Param{FormatData} ne 'HASH' ) {
$LogObject->Log(
Priority => 'error',
Message => 'FormatData must be a hash reference!',
);
return;
}
# delete existing format data
$Self->FormatDataDelete(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
DATAKEY:
for my $DataKey ( sort keys %{ $Param{FormatData} } ) {
my $DataValue = $Param{FormatData}->{$DataKey};
next DATAKEY if !defined $DataKey;
next DATAKEY if !defined $DataValue;
# insert one row
$Kernel::OM->Get('Kernel::System::DB')->Do(
SQL => 'INSERT INTO imexport_format '
. '(template_id, data_key, data_value) VALUES (?, ?, ?)',
Bind => [ \$Param{TemplateID}, \$DataKey, \$DataValue ],
);
}
return 1;
}
=head2 FormatDataDelete()
Delete the existing format data of a template
my $True = $ImportExportObject->FormatDataDelete(
TemplateID => 123,
UserID => 1,
);
or
my $True = $ImportExportObject->FormatDataDelete(
TemplateID => [1,44,166,5],
UserID => 1,
);
=cut
sub FormatDataDelete {
my ( $Self, %Param ) = @_;
# get log object
my $LogObject = $Kernel::OM->Get('Kernel::System::Log');
# check needed stuff
for my $Argument (qw(TemplateID UserID)) {
if ( !$Param{$Argument} ) {
$LogObject->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
if ( !ref $Param{TemplateID} ) {
$Param{TemplateID} = [ $Param{TemplateID} ];
}
elsif ( ref $Param{TemplateID} ne 'ARRAY' ) {
$LogObject->Log(
Priority => 'error',
Message => 'TemplateID must be an array reference or a string!',
);
return;
}
# create the template id string
my $TemplateIDString = join q{, }, map {'?'} @{ $Param{TemplateID} };
# create and add bind parameters
my @BIND = map { \$_ } @{ $Param{TemplateID} };
# delete templates
return $Kernel::OM->Get('Kernel::System::DB')->Do(
SQL => "DELETE FROM imexport_format WHERE template_id IN ( $TemplateIDString )",
Bind => \@BIND,
);
}
=head2 MappingList()
Return a list of mapping data ids sorted by position as array reference
my $MappingList = $ImportExportObject->MappingList(
TemplateID => 123,
UserID => 1,
);
=cut
sub MappingList {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(TemplateID UserID)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# get DB object
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
# ask database
$DBObject->Prepare(
SQL => 'SELECT id FROM imexport_mapping WHERE template_id = ? ORDER BY position',
Bind => [ \$Param{TemplateID} ],
);
# fetch the result
my @MappingList;
while ( my @Row = $DBObject->FetchrowArray() ) {
push @MappingList, $Row[0];
}
return \@MappingList;
}
=head2 MappingAdd()
Add a new mapping data row
my $MappingID = $ImportExportObject->MappingAdd(
TemplateID => 123,
UserID => 1,
);
=cut
sub MappingAdd {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(TemplateID UserID)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# get DB object
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
# find maximum position
$DBObject->Prepare(
SQL => 'SELECT max(position) FROM imexport_mapping WHERE template_id = ?',
Bind => [ \$Param{TemplateID} ],
Limit => 1,
);
# fetch the result
my $NewPosition = 0;
while ( my @Row = $DBObject->FetchrowArray() ) {
if ( defined $Row[0] ) {
$NewPosition = $Row[0];
$NewPosition++;
}
}
# insert a new mapping data row
return if !$DBObject->Do(
SQL => 'INSERT INTO imexport_mapping (template_id, position) VALUES (?, ?)',
Bind => [ \$Param{TemplateID}, \$NewPosition ],
);
# find id of new mapping data row
$DBObject->Prepare(
SQL => 'SELECT id FROM imexport_mapping WHERE template_id = ? AND position = ?',
Bind => [ \$Param{TemplateID}, \$NewPosition ],
Limit => 1,
);
# fetch the result
my $MappingID;
while ( my @Row = $DBObject->FetchrowArray() ) {
$MappingID = $Row[0];
}
return $MappingID;
}
=head2 MappingDelete()
Delete existing mapping data rows
my $True = $ImportExportObject->MappingDelete(
MappingID => 123,
TemplateID => 321,
UserID => 1,
);
or
my $True = $ImportExportObject->MappingDelete(
TemplateID => 321,
UserID => 1,
);
=cut
sub MappingDelete {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(TemplateID UserID)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# get DB object
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
if ( defined $Param{MappingID} ) {
# delete existing object mapping data
$Self->MappingObjectDataDelete(
MappingID => $Param{MappingID},
UserID => $Param{UserID},
);
# delete existing format mapping data
$Self->MappingFormatDataDelete(
MappingID => $Param{MappingID},
UserID => $Param{UserID},
);
# delete one mapping row
$DBObject->Do(
SQL => 'DELETE FROM imexport_mapping WHERE id = ?',
Bind => [ \$Param{MappingID} ],
);
# rebuild mapping positions
$Self->MappingPositionRebuild(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
return 1;
}
else {
# get mapping list
my $MappingList = $Self->MappingList(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
for my $MappingID ( @{$MappingList} ) {
# delete existing object mapping data
$Self->MappingObjectDataDelete(
MappingID => $MappingID,
UserID => $Param{UserID},
);
# delete existing format mapping data
$Self->MappingFormatDataDelete(
MappingID => $MappingID,
UserID => $Param{UserID},
);
}
# delete all mapping rows of this template
return $DBObject->Do(
SQL => 'DELETE FROM imexport_mapping WHERE template_id = ?',
Bind => [ \$Param{TemplateID} ],
);
}
}
=head2 MappingUp()
Move an mapping data row up
my $True = $ImportExportObject->MappingUp(
MappingID => 123,
TemplateID => 321,
UserID => 1,
);
=cut
sub MappingUp {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(MappingID TemplateID UserID)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# get mapping data list
my $MappingList = $Self->MappingList(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
return 1 if $Param{MappingID} == $MappingList->[0];
# get DB object
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
# ask database
$DBObject->Prepare(
SQL => 'SELECT position FROM imexport_mapping WHERE id = ?',
Bind => [ \$Param{MappingID} ],
);
# fetch the result
my $Position;
while ( my @Row = $DBObject->FetchrowArray() ) {
$Position = $Row[0];
}
return 1 if !$Position;
my $PositionUpper = $Position - 1;
# update positions
$DBObject->Do(
SQL => 'UPDATE imexport_mapping SET position = ? WHERE template_id = ? AND position = ?',
Bind => [ \$Position, \$Param{TemplateID}, \$PositionUpper ],
);
$DBObject->Do(
SQL => 'UPDATE imexport_mapping SET position = ? WHERE id = ?',
Bind => [ \$PositionUpper, \$Param{MappingID} ],
);
return 1;
}
=head2 MappingDown()
Move an mapping data row down
my $True = $ImportExportObject->MappingDown(
MappingID => 123,
TemplateID => 321,
UserID => 1,
);
=cut
sub MappingDown {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(MappingID TemplateID UserID)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# get mapping data list
my $MappingList = $Self->MappingList(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
return 1 if $Param{MappingID} == $MappingList->[-1];
# get DB object
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
# ask database
$DBObject->Prepare(
SQL => 'SELECT position FROM imexport_mapping WHERE id = ?',
Bind => [ \$Param{MappingID} ],
);
# fetch the result
my $Position;
while ( my @Row = $DBObject->FetchrowArray() ) {
$Position = $Row[0];
}
my $PositionDown = $Position + 1;
# update positions
$DBObject->Do(
SQL => 'UPDATE imexport_mapping SET position = ? WHERE template_id = ? AND position = ?',
Bind => [ \$Position, \$Param{TemplateID}, \$PositionDown ],
);
$DBObject->Do(
SQL => 'UPDATE imexport_mapping SET position = ? WHERE id = ?',
Bind => [ \$PositionDown, \$Param{MappingID} ],
);
return 1;
}
=head2 MappingPositionRebuild()
Rebuild the positions of a mapping list
my $True = $ImportExportObject->MappingPositionRebuild(
TemplateID => 123,
UserID => 1,
);
=cut
sub MappingPositionRebuild {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(TemplateID UserID)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# get mapping data list
my $MappingList = $Self->MappingList(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
# update position
my $Counter = 0;
for my $MappingID ( @{$MappingList} ) {
$Kernel::OM->Get('Kernel::System::DB')->Do(
SQL => 'UPDATE imexport_mapping SET position = ? WHERE id = ?',
Bind => [ \$Counter, \$MappingID ],
);
$Counter++;
}
return 1;
}
=head2 MappingObjectAttributesGet()
Get the attributes of an object backend as array/hash reference
my $Attributes = $ImportExportObject->MappingObjectAttributesGet(
TemplateID => 123,
UserID => 1,
);
=cut
sub MappingObjectAttributesGet {
my ( $Self, %Param ) = @_;
# get log object
my $LogObject = $Kernel::OM->Get('Kernel::System::Log');
# check needed stuff
for my $Argument (qw(TemplateID UserID)) {
if ( !$Param{$Argument} ) {
$LogObject->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# get template data
my $TemplateData = $Self->TemplateGet(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
# check template data
if ( !$TemplateData || !$TemplateData->{Object} ) {
$LogObject->Log(
Priority => 'error',
Message => "Template with ID $Param{TemplateID} is incomplete!",
);
return;
}
# load backend
my $Backend = $Kernel::OM->Get(
'Kernel::System::ImportExport::ObjectBackend::' . $TemplateData->{Object}
);
return if !$Backend;
# get an attribute list of the object
my $Attributes = $Backend->MappingObjectAttributesGet(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
return $Attributes;
}
=head2 MappingObjectDataDelete()
Delete the existing object data of a mapping
my $True = $ImportExportObject->MappingObjectDataDelete(
MappingID => 123,
UserID => 1,
);
or
my $True = $ImportExportObject->MappingObjectDataDelete(
MappingID => [1,44,166,5],
UserID => 1,
);
=cut
sub MappingObjectDataDelete {
my ( $Self, %Param ) = @_;
# get log object
my $LogObject = $Kernel::OM->Get('Kernel::System::Log');
# check needed stuff
for my $Argument (qw(MappingID UserID)) {
if ( !$Param{$Argument} ) {
$LogObject->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
if ( !ref $Param{MappingID} ) {
$Param{MappingID} = [ $Param{MappingID} ];
}
elsif ( ref $Param{MappingID} ne 'ARRAY' ) {
$LogObject->Log(
Priority => 'error',
Message => 'MappingID must be an array reference or a string!',
);
return;
}
# create the template id string
my $MappingIDString = join q{, }, map {'?'} @{ $Param{MappingID} };
# create and add bind parameters
my @BIND = map { \$_ } @{ $Param{MappingID} };
# delete mapping object data
return $Kernel::OM->Get('Kernel::System::DB')->Do(
SQL => "DELETE FROM imexport_mapping_object WHERE mapping_id IN ( $MappingIDString )",
Bind => \@BIND,
);
}
=head2 MappingObjectDataSave()
Save the object data of a mapping
my $True = $ImportExportObject->MappingObjectDataSave(
MappingID => 123,
MappingObjectData => $HashRef,
UserID => 1,
);
=cut
sub MappingObjectDataSave {
my ( $Self, %Param ) = @_;
# get log object
my $LogObject = $Kernel::OM->Get('Kernel::System::Log');
# check needed stuff
for my $Argument (qw(MappingID MappingObjectData UserID)) {
if ( !$Param{$Argument} ) {
$LogObject->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
if ( ref $Param{MappingObjectData} ne 'HASH' ) {
$LogObject->Log(
Priority => 'error',
Message => 'MappingObjectData must be a hash reference!',
);
return;
}
# delete existing object mapping data
$Self->MappingObjectDataDelete(
MappingID => $Param{MappingID},
UserID => $Param{UserID},
);
DATAKEY:
for my $DataKey ( sort keys %{ $Param{MappingObjectData} } ) {
my $DataValue = $Param{MappingObjectData}->{$DataKey};
next DATAKEY if !defined $DataKey;
next DATAKEY if !defined $DataValue;
# insert one mapping object row
$Kernel::OM->Get('Kernel::System::DB')->Do(
SQL => 'INSERT INTO imexport_mapping_object '
. '(mapping_id, data_key, data_value) VALUES (?, ?, ?)',
Bind => [ \$Param{MappingID}, \$DataKey, \$DataValue ],
);
}
return 1;
}
=head2 MappingObjectDataGet()
Get the object data of a mapping
my $ObjectDataRef = $ImportExportObject->MappingObjectDataGet(
MappingID => 123,
UserID => 1,
);
=cut
sub MappingObjectDataGet {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(MappingID UserID)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# get DB object
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
# ask database
$DBObject->Prepare(
SQL => 'SELECT data_key, data_value FROM imexport_mapping_object WHERE mapping_id = ?',
Bind => [ \$Param{MappingID} ],
);
# fetch the result
my %MappingObjectData;
while ( my @Row = $DBObject->FetchrowArray() ) {
$MappingObjectData{ $Row[0] } = $Row[1];
}
return \%MappingObjectData;
}
=head2 MappingFormatAttributesGet()
Get the attributes of an format backend as array/hash reference
my $Attributes = $ImportExportObject->MappingFormatAttributesGet(
TemplateID => 123,
UserID => 1,
);
=cut
sub MappingFormatAttributesGet {
my ( $Self, %Param ) = @_;
# get log object
my $LogObject = $Kernel::OM->Get('Kernel::System::Log');
# check needed stuff
for my $Argument (qw(TemplateID UserID)) {
if ( !$Param{$Argument} ) {
$LogObject->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# get template data
my $TemplateData = $Self->TemplateGet(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
# check template data
if ( !$TemplateData || !$TemplateData->{Format} ) {
$LogObject->Log(
Priority => 'error',
Message => "Template with ID $Param{TemplateID} is incomplete!",
);
return;
}
# load backend
my $Backend = $Kernel::OM->Get(
'Kernel::System::ImportExport::FormatBackend::' . $TemplateData->{Format}
);
return if !$Backend;
# get an attribute list of the format
my $Attributes = $Backend->MappingFormatAttributesGet(
UserID => $Param{UserID},
);
return $Attributes;
}
=head2 MappingFormatDataDelete()
Delete the existing format data of a mapping
my $True = $ImportExportObject->MappingFormatDataDelete(
MappingID => 123,
UserID => 1,
);
or
my $True = $ImportExportObject->MappingFormatDataDelete(
MappingID => [1,44,166,5],
UserID => 1,
);
=cut
sub MappingFormatDataDelete {
my ( $Self, %Param ) = @_;
# get log object
my $LogObject = $Kernel::OM->Get('Kernel::System::Log');
# check needed stuff
for my $Argument (qw(MappingID UserID)) {
if ( !$Param{$Argument} ) {
$LogObject->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
if ( !ref $Param{MappingID} ) {
$Param{MappingID} = [ $Param{MappingID} ];
}
elsif ( ref $Param{MappingID} ne 'ARRAY' ) {
$LogObject->Log(
Priority => 'error',
Message => 'MappingID must be an array reference or a string!',
);
return;
}
# create the template id string
my $MappingIDString = join q{, }, map {'?'} @{ $Param{MappingID} };
# create and add bind parameters
my @BIND = map { \$_ } @{ $Param{MappingID} };
# delete mapping format data
return $Kernel::OM->Get('Kernel::System::DB')->Do(
SQL => "DELETE FROM imexport_mapping_format WHERE mapping_id IN ( $MappingIDString )",
Bind => \@BIND,
);
}
=head2 MappingFormatDataSave()
Save the format data of a mapping
my $True = $ImportExportObject->MappingFormatDataSave(
MappingID => 123,
MappingFormatData => $HashRef,
UserID => 1,
);
=cut
sub MappingFormatDataSave {
my ( $Self, %Param ) = @_;
# get log object
my $LogObject = $Kernel::OM->Get('Kernel::System::Log');
# check needed stuff
for my $Argument (qw(MappingID MappingFormatData UserID)) {
if ( !$Param{$Argument} ) {
$LogObject->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
if ( ref $Param{MappingFormatData} ne 'HASH' ) {
$LogObject->Log(
Priority => 'error',
Message => 'MappingFormatData must be a hash reference!',
);
return;
}
# delete existing format mapping data
$Self->MappingFormatDataDelete(
MappingID => $Param{MappingID},
UserID => $Param{UserID},
);
DATAKEY:
for my $DataKey ( sort keys %{ $Param{MappingFormatData} } ) {
my $DataValue = $Param{MappingFormatData}->{$DataKey};
next DATAKEY if !defined $DataKey;
next DATAKEY if !defined $DataValue;
# insert one mapping format row
$Kernel::OM->Get('Kernel::System::DB')->Do(
SQL => 'INSERT INTO imexport_mapping_format '
. '(mapping_id, data_key, data_value) VALUES (?, ?, ?)',
Bind => [ \$Param{MappingID}, \$DataKey, \$DataValue ],
);
}
return 1;
}
=head2 MappingFormatDataGet()
Get the format data of a mapping
my $ObjectDataRef = $ImportExportObject->MappingFormatDataGet(
MappingID => 123,
UserID => 1,
);
=cut
sub MappingFormatDataGet {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(MappingID UserID)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# get DB object
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
# ask database
$DBObject->Prepare(
SQL => 'SELECT data_key, data_value FROM imexport_mapping_format WHERE mapping_id = ?',
Bind => [ \$Param{MappingID} ],
);
# fetch the result
my %MappingFormatData;
while ( my @Row = $DBObject->FetchrowArray() ) {
$MappingFormatData{ $Row[0] } = $Row[1];
}
return \%MappingFormatData;
}
=head2 SearchAttributesGet()
Get the search attributes of a object backend as array/hash reference
my $Attributes = $ImportExportObject->SearchAttributesGet(
TemplateID => 123,
UserID => 1,
);
=cut
sub SearchAttributesGet {
my ( $Self, %Param ) = @_;
# get log object
my $LogObject = $Kernel::OM->Get('Kernel::System::Log');
# check needed stuff
for my $Argument (qw(TemplateID UserID)) {
if ( !$Param{$Argument} ) {
$LogObject->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# get template data
my $TemplateData = $Self->TemplateGet(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
# check template data
if ( !$TemplateData || !$TemplateData->{Object} ) {
$LogObject->Log(
Priority => 'error',
Message => "Template with ID $Param{TemplateID} is incomplete!",
);
return;
}
# load backend
my $Backend = $Kernel::OM->Get(
'Kernel::System::ImportExport::ObjectBackend::' . $TemplateData->{Object}
);
return if !$Backend;
# get an search attribute list of an object
my $Attributes = $Backend->SearchAttributesGet(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
return $Attributes;
}
=head2 SearchDataGet()
Get the search data from a template
my $SearchDataRef = $ImportExportObject->SearchDataGet(
TemplateID => 3,
UserID => 1,
);
=cut
sub SearchDataGet {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(TemplateID UserID)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# get DB object
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
# ask database
$DBObject->Prepare(
SQL => 'SELECT data_key, data_value FROM imexport_search WHERE template_id = ?',
Bind => [ \$Param{TemplateID} ],
);
# fetch the result
my %SearchData;
while ( my @Row = $DBObject->FetchrowArray() ) {
$SearchData{ $Row[0] } = $Row[1];
}
return \%SearchData;
}
=head2 SearchDataSave()
Save the search data of a template
my $True = $ImportExportObject->SearchDataSave(
TemplateID => 123,
SearchData => $HashRef,
UserID => 1,
);
=cut
sub SearchDataSave {
my ( $Self, %Param ) = @_;
# get log object
my $LogObject = $Kernel::OM->Get('Kernel::System::Log');
# check needed stuff
for my $Argument (qw(TemplateID SearchData UserID)) {
if ( !$Param{$Argument} ) {
$LogObject->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
if ( ref $Param{SearchData} ne 'HASH' ) {
$LogObject->Log(
Priority => 'error',
Message => 'SearchData must be a hash reference!',
);
return;
}
# delete existing search data
$Self->SearchDataDelete(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
DATAKEY:
for my $DataKey ( sort keys %{ $Param{SearchData} } ) {
# quote
my $DataValue = $Param{SearchData}->{$DataKey};
next DATAKEY if !$DataKey;
next DATAKEY if !$DataValue;
# insert one row
$Kernel::OM->Get('Kernel::System::DB')->Do(
SQL => 'INSERT INTO imexport_search '
. '(template_id, data_key, data_value) VALUES (?, ?, ?)',
Bind => [ \$Param{TemplateID}, \$DataKey, \$DataValue ],
);
}
return 1;
}
=head2 SearchDataDelete()
Delete the existing search data of a template
my $True = $ImportExportObject->SearchDataDelete(
TemplateID => 123,
UserID => 1,
);
or
my $True = $ImportExportObject->SearchDataDelete(
TemplateID => [1,44,166,5],
UserID => 1,
);
=cut
sub SearchDataDelete {
my ( $Self, %Param ) = @_;
# get log object
my $LogObject = $Kernel::OM->Get('Kernel::System::Log');
# check needed stuff
for my $Argument (qw(TemplateID UserID)) {
if ( !$Param{$Argument} ) {
$LogObject->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
if ( !ref $Param{TemplateID} ) {
$Param{TemplateID} = [ $Param{TemplateID} ];
}
elsif ( ref $Param{TemplateID} ne 'ARRAY' ) {
$LogObject->Log(
Priority => 'error',
Message => 'TemplateID must be an array reference or a string!',
);
return;
}
# create the template id string
my $TemplateIDString = join q{, }, map {'?'} @{ $Param{TemplateID} };
# create and add bind parameters
my @BIND = map { \$_ } @{ $Param{TemplateID} };
# delete templates
return $Kernel::OM->Get('Kernel::System::DB')->Do(
SQL => "DELETE FROM imexport_search WHERE template_id IN ( $TemplateIDString )",
Bind => \@BIND,
);
}
=head2 Export()
Export function
my $ResultRef = $ImportExportObject->Export(
TemplateID => 123,
UserID => 1,
);
returns something like
$ResultRef = {
Success => 2,
Failed => 0,
DestinationContent => [
[ 'Attr_1a', 'Attr_1b', 'Attr_1c', ],
[ 'Attr_2a', 'Attr_2b', 'Attr_3c', ],
],
};
=cut
sub Export {
my ( $Self, %Param ) = @_;
# get log object
my $LogObject = $Kernel::OM->Get('Kernel::System::Log');
# check needed stuff
for my $Argument (qw(TemplateID UserID)) {
if ( !$Param{$Argument} ) {
$LogObject->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# get template data
my $TemplateData = $Self->TemplateGet(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
# check template data
if ( !$TemplateData || !$TemplateData->{Object} || !$TemplateData->{Format} ) {
$LogObject->Log(
Priority => 'error',
Message => "Template with ID $Param{TemplateID} is incomplete!",
);
return;
}
# load object backend
my $ObjectBackend = $Kernel::OM->Get(
'Kernel::System::ImportExport::ObjectBackend::' . $TemplateData->{Object}
);
return if !$ObjectBackend;
# load format backend
my $FormatBackend = $Kernel::OM->Get(
'Kernel::System::ImportExport::FormatBackend::' . $TemplateData->{Format}
);
return if !$FormatBackend;
# get export data
my $ExportData = $ObjectBackend->ExportDataGet(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
# get format data
my $FormatData = $Self->FormatDataGet(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
# if column headers should be included in the export
if ( $FormatData->{IncludeColumnHeaders} ) {
# get object attributes (the name of the columns)
my $MappingObjectAttributes = $Self->MappingObjectAttributesGet(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
# create a lookup hash for the object attribute names
my %AttributeLookup = map { $_->{Key} => $_->{Value} } @{ $MappingObjectAttributes->[0]->{Input}->{Data} };
# get mapping data list
my $MappingList = $Self->MappingList(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
# get the column names
my @ColumnNames;
for my $MappingID ( @{$MappingList} ) {
# get mapping object data
my $MappingObjectData = $Self->MappingObjectDataGet(
MappingID => $MappingID,
UserID => $Param{UserID},
);
# get the column name
my $ColumnName = $AttributeLookup{ $MappingObjectData->{Key} };
push @ColumnNames, $ColumnName;
}
# add column headers as first row
unshift @{$ExportData}, \@ColumnNames;
}
my %Result = (
Success => 0,
Failed => 0,
DestinationContent => [],
);
EXPORTDATAROW:
for my $ExportDataRow ( @{$ExportData} ) {
# export one row
my $DestinationContentRow = $FormatBackend->ExportDataSave(
TemplateID => $Param{TemplateID},
ExportDataRow => $ExportDataRow,
UserID => $Param{UserID},
);
if ( !defined $DestinationContentRow ) {
$Result{Failed}++;
next EXPORTDATAROW;
}
# add row to destination content
push @{ $Result{DestinationContent} }, $DestinationContentRow;
$Result{Success}++;
}
# log result
$LogObject->Log(
Priority => 'notice',
Message => "Export of $Result{Failed} records ($TemplateData->{Object}): failed!",
);
$LogObject->Log(
Priority => 'notice',
Message => "Export of $Result{Success} records ($TemplateData->{Object}): successful!",
);
return \%Result;
}
=head2 Import()
Import function
my $ResultRef = $ImportExportObject->Import(
TemplateID => 123,
SourceContent => $StringRef, # (optional)
UserID => 1,
);
=cut
sub Import {
my ( $Self, %Param ) = @_;
my $CacheObject = $Kernel::OM->Get('Kernel::System::Cache');
# Disable the cache for faster import.
$CacheObject->Configure(
CacheInMemory => 0,
CacheInBackend => 0,
);
# get log object
my $LogObject = $Kernel::OM->Get('Kernel::System::Log');
# check needed stuff
for my $Argument (qw(TemplateID UserID)) {
if ( !$Param{$Argument} ) {
$LogObject->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# get template data
my $TemplateData = $Self->TemplateGet(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
# check template data
if ( !$TemplateData || !$TemplateData->{Object} || !$TemplateData->{Format} ) {
$LogObject->Log(
Priority => 'error',
Message => "Template with ID $Param{TemplateID} is incomplete!",
);
return;
}
# load object backend
my $ObjectBackend = $Kernel::OM->Get(
'Kernel::System::ImportExport::ObjectBackend::' . $TemplateData->{Object}
);
return if !$ObjectBackend;
# load format backend
my $FormatBackend = $Kernel::OM->Get(
'Kernel::System::ImportExport::FormatBackend::' . $TemplateData->{Format}
);
return if !$FormatBackend;
# get import data
my $ImportData = $FormatBackend->ImportDataGet(
TemplateID => $Param{TemplateID},
SourceContent => $Param{SourceContent},
UserID => $Param{UserID},
);
return if !$ImportData;
# get format data
my $FormatData = $Self->FormatDataGet(
TemplateID => $Param{TemplateID},
UserID => $Param{UserID},
);
# if column headers are activated, the first row must be removed
if ( $FormatData->{IncludeColumnHeaders} ) {
shift @{$ImportData};
}
# Number of successfully and not successfully imported rows
my %Result = (
Object => $TemplateData->{Object},
Success => 0,
Failed => 0,
RetCode => {},
Counter => 0,
);
IMPORTDATAROW:
for my $ImportDataRow ( @{$ImportData} ) {
$Result{Counter}++;
# import a single row
my ( $ID, $RetCode ) = $ObjectBackend->ImportDataSave(
TemplateID => $Param{TemplateID},
ImportDataRow => $ImportDataRow,
Counter => $Result{Counter},
UserID => $Param{UserID},
);
if ( !$ID ) {
# count DuplicateName entries as errors
if ( $RetCode && $RetCode =~ m{ \A DuplicateName }xms ) {
$Result{RetCode}->{$RetCode}++;
}
$Result{Failed}++;
}
else {
$Result{RetCode}->{$RetCode}++;
$Result{Success}++;
}
}
# log result
$LogObject->Log(
Priority => 'notice',
Message =>
"Import of $Result{Counter} $Result{Object} records: "
. "$Result{Failed} failed, $Result{Success} succeeded",
);
for my $RetCode ( sort keys %{ $Result{RetCode} } ) {
my $Count = $Result{RetCode}->{$RetCode} || 0;
$LogObject->Log(
Priority => 'notice',
Message =>
"Import of $Result{Counter} $Result{Object} records: $Count $RetCode",
);
}
if ( $Result{Failed} ) {
$LogObject->Log(
Priority => 'notice',
Message => "Last processed line number of import file: $Result{Counter}",
);
}
return \%Result;
}
1;
=head1 TERMS AND CONDITIONS
This Software is part of the OTRS project (L<http://otrs.org/>).
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 L<https://www.gnu.org/licenses/gpl-3.0.txt>.
=cut