1# --
2# Copyright (C) 2001-2020 OTRS AG, https://otrs.com/
3# --
4# This software comes with ABSOLUTELY NO WARRANTY. For details, see
5# the enclosed file COPYING for license information (GPL). If you
6# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
7# --
8
9package Kernel::System::PostMaster::NewTicket;
10
11use strict;
12use warnings;
13
14our @ObjectDependencies = (
15    'Kernel::Config',
16    'Kernel::System::CustomerUser',
17    'Kernel::System::DynamicField',
18    'Kernel::System::DynamicField::Backend',
19    'Kernel::System::LinkObject',
20    'Kernel::System::Log',
21    'Kernel::System::Priority',
22    'Kernel::System::Queue',
23    'Kernel::System::State',
24    'Kernel::System::Ticket',
25    'Kernel::System::Ticket::Article',
26    'Kernel::System::DateTime',
27    'Kernel::System::Type',
28    'Kernel::System::User',
29    'Kernel::System::Service',
30);
31
32sub new {
33    my ( $Type, %Param ) = @_;
34
35    # allocate new hash for object
36    my $Self = {};
37    bless( $Self, $Type );
38
39    # get parser object
40    $Self->{ParserObject} = $Param{ParserObject} || die "Got no ParserObject!";
41
42    # Get communication log object.
43    $Self->{CommunicationLogObject} = $Param{CommunicationLogObject} || die "Got no CommunicationLogObject!";
44
45    return $Self;
46}
47
48sub Run {
49    my ( $Self, %Param ) = @_;
50
51    # check needed stuff
52    for my $Needed (qw(InmailUserID GetParam)) {
53        if ( !$Param{$Needed} ) {
54            $Self->{CommunicationLogObject}->ObjectLog(
55                ObjectLogType => 'Message',
56                Priority      => 'Error',
57                Key           => 'Kernel::System::PostMaster::NewTicket',
58                Value         => "Need $Needed!",
59            );
60            return;
61        }
62    }
63    my %GetParam         = %{ $Param{GetParam} };
64    my $Comment          = $Param{Comment} || '';
65    my $AutoResponseType = $Param{AutoResponseType} || '';
66
67    # get queue id and name
68    my $QueueID = $Param{QueueID} || die "need QueueID!";
69    my $Queue   = $Kernel::OM->Get('Kernel::System::Queue')->QueueLookup(
70        QueueID => $QueueID,
71    );
72
73    # get config object
74    my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
75
76    # get state
77    my $State = $ConfigObject->Get('PostmasterDefaultState') || 'new';
78    if ( $GetParam{'X-OTRS-State'} ) {
79
80        my $StateID = $Kernel::OM->Get('Kernel::System::State')->StateLookup(
81            State => $GetParam{'X-OTRS-State'},
82        );
83
84        if ($StateID) {
85            $State = $GetParam{'X-OTRS-State'};
86        }
87        else {
88            $Self->{CommunicationLogObject}->ObjectLog(
89                ObjectLogType => 'Message',
90                Priority      => 'Error',
91                Key           => 'Kernel::System::PostMaster::NewTicket',
92                Value         => "State $GetParam{'X-OTRS-State'} does not exist, falling back to $State!",
93            );
94        }
95    }
96
97    # get priority
98    my $Priority = $ConfigObject->Get('PostmasterDefaultPriority') || '3 normal';
99
100    if ( $GetParam{'X-OTRS-Priority'} ) {
101
102        my $PriorityID = $Kernel::OM->Get('Kernel::System::Priority')->PriorityLookup(
103            Priority => $GetParam{'X-OTRS-Priority'},
104        );
105
106        if ($PriorityID) {
107            $Priority = $GetParam{'X-OTRS-Priority'};
108        }
109        else {
110            $Self->{CommunicationLogObject}->ObjectLog(
111                ObjectLogType => 'Message',
112                Priority      => 'Error',
113                Key           => 'Kernel::System::PostMaster::NewTicket',
114                Value         => "Priority $GetParam{'X-OTRS-Priority'} does not exist, falling back to $Priority!",
115            );
116        }
117    }
118
119    my $TypeID;
120
121    if ( $GetParam{'X-OTRS-Type'} ) {
122
123        # Check if type exists
124        $TypeID = $Kernel::OM->Get('Kernel::System::Type')->TypeLookup( Type => $GetParam{'X-OTRS-Type'} );
125
126        if ( !$TypeID ) {
127            $Self->{CommunicationLogObject}->ObjectLog(
128                ObjectLogType => 'Message',
129                Priority      => 'Error',
130                Key           => 'Kernel::System::PostMaster::NewTicket',
131                Value         => "Type $GetParam{'X-OTRS-Type'} does not exist, falling back to default type.",
132            );
133        }
134    }
135
136    # get sender email
137    my @EmailAddresses = $Self->{ParserObject}->SplitAddressLine(
138        Line => $GetParam{From},
139    );
140    for my $Address (@EmailAddresses) {
141        $GetParam{SenderEmailAddress} = $Self->{ParserObject}->GetEmailAddress(
142            Email => $Address,
143        );
144    }
145
146    $GetParam{SenderEmailAddress} //= '';
147
148    # get customer id (sender email) if there is no customer id given
149    if ( !$GetParam{'X-OTRS-CustomerNo'} && $GetParam{'X-OTRS-CustomerUser'} ) {
150
151        # get customer user object
152        my $CustomerUserObject = $Kernel::OM->Get('Kernel::System::CustomerUser');
153
154        # get customer user data form X-OTRS-CustomerUser
155        my %CustomerData = $CustomerUserObject->CustomerUserDataGet(
156            User => $GetParam{'X-OTRS-CustomerUser'},
157        );
158
159        if (%CustomerData) {
160            $GetParam{'X-OTRS-CustomerNo'} = $CustomerData{UserCustomerID};
161        }
162    }
163
164    # get customer user data form From: (sender address)
165    if ( !$GetParam{'X-OTRS-CustomerUser'} ) {
166
167        my %CustomerData;
168        if ( $GetParam{From} ) {
169
170            my @EmailAddresses = $Self->{ParserObject}->SplitAddressLine(
171                Line => $GetParam{From},
172            );
173
174            for my $Address (@EmailAddresses) {
175                $GetParam{EmailFrom} = $Self->{ParserObject}->GetEmailAddress(
176                    Email => $Address,
177                );
178            }
179
180            if ( $GetParam{EmailFrom} ) {
181
182                # get customer user object
183                my $CustomerUserObject = $Kernel::OM->Get('Kernel::System::CustomerUser');
184
185                my %List = $CustomerUserObject->CustomerSearch(
186                    PostMasterSearch => lc( $GetParam{EmailFrom} ),
187                );
188
189                for my $UserLogin ( sort keys %List ) {
190                    %CustomerData = $CustomerUserObject->CustomerUserDataGet(
191                        User => $UserLogin,
192                    );
193                }
194            }
195        }
196
197        # take CustomerID from customer backend lookup or from from field
198        if ( $CustomerData{UserLogin} && !$GetParam{'X-OTRS-CustomerUser'} ) {
199            $GetParam{'X-OTRS-CustomerUser'} = $CustomerData{UserLogin};
200
201            # notice that UserLogin is from customer source backend
202            $Self->{CommunicationLogObject}->ObjectLog(
203                ObjectLogType => 'Message',
204                Priority      => 'Notice',
205                Key           => 'Kernel::System::PostMaster::NewTicket',
206                Value         => "Take UserLogin ($CustomerData{UserLogin}) from "
207                    . "customer source backend based on ($GetParam{'EmailFrom'}).",
208            );
209        }
210        if ( $CustomerData{UserCustomerID} && !$GetParam{'X-OTRS-CustomerNo'} ) {
211            $GetParam{'X-OTRS-CustomerNo'} = $CustomerData{UserCustomerID};
212
213            # notice that UserCustomerID is from customer source backend
214            $Self->{CommunicationLogObject}->ObjectLog(
215                ObjectLogType => 'Message',
216                Priority      => 'Notice',
217                Key           => 'Kernel::System::PostMaster::NewTicket',
218                Value         => "Take UserCustomerID ($CustomerData{UserCustomerID})"
219                    . " from customer source backend based on ($GetParam{'EmailFrom'}).",
220            );
221        }
222    }
223
224    # if there is no customer id found!
225    if (
226        !$GetParam{'X-OTRS-CustomerNo'}
227        && $ConfigObject->Get('PostMaster::NewTicket::AutoAssignCustomerIDForUnknownCustomers')
228        )
229    {
230        $GetParam{'X-OTRS-CustomerNo'} = $GetParam{SenderEmailAddress};
231    }
232
233    # if there is no customer user found!
234    if ( !$GetParam{'X-OTRS-CustomerUser'} ) {
235        $GetParam{'X-OTRS-CustomerUser'} = $GetParam{SenderEmailAddress};
236    }
237
238    # get ticket owner
239    my $OwnerID = $GetParam{'X-OTRS-OwnerID'} || $Param{InmailUserID};
240    if ( $GetParam{'X-OTRS-Owner'} ) {
241
242        my $TmpOwnerID = $Kernel::OM->Get('Kernel::System::User')->UserLookup(
243            UserLogin => $GetParam{'X-OTRS-Owner'},
244        );
245
246        $OwnerID = $TmpOwnerID || $OwnerID;
247    }
248
249    my %Opts;
250    if ( $GetParam{'X-OTRS-ResponsibleID'} ) {
251        $Opts{ResponsibleID} = $GetParam{'X-OTRS-ResponsibleID'};
252    }
253
254    if ( $GetParam{'X-OTRS-Responsible'} ) {
255
256        my $TmpResponsibleID = $Kernel::OM->Get('Kernel::System::User')->UserLookup(
257            UserLogin => $GetParam{'X-OTRS-Responsible'},
258        );
259
260        $Opts{ResponsibleID} = $TmpResponsibleID || $Opts{ResponsibleID};
261    }
262
263    # get ticket object
264    my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
265
266    $Self->{CommunicationLogObject}->ObjectLog(
267        ObjectLogType => 'Message',
268        Priority      => 'Debug',
269        Key           => 'Kernel::System::PostMaster::NewTicket',
270        Value         => "Going to create new ticket.",
271    );
272
273    if ( $GetParam{'X-OTRS-Service'} ) {
274        my $ServiceObject = $Kernel::OM->Get('Kernel::System::Service');
275
276        # Check if service exists.
277        my %ServiceData = $ServiceObject->ServiceGet(
278            Name   => $GetParam{'X-OTRS-Service'},
279            UserID => $Param{InmailUserID},
280        );
281
282        # Get all service list filtering by KeepChildren SysConfig if available.
283        my %ServiceList = $ServiceObject->ServiceList(
284            Valid        => 1,
285            KeepChildren => $ConfigObject->Get('Ticket::Service::KeepChildren') // 0,
286            UserID       => $Param{InmailUserID},
287        );
288
289        if ( $ServiceData{ServiceID} ne '' && !$ServiceList{ $ServiceData{ServiceID} } ) {
290            $Self->{CommunicationLogObject}->ObjectLog(
291                ObjectLogType => 'Message',
292                Priority      => 'Debug',
293                Key           => 'Kernel::System::PostMaster::NewTicket',
294                Value =>
295                    "Service $GetParam{'X-OTRS-Service'} does not exists or is invalid or is a child of invalid service.",
296            );
297            $GetParam{'X-OTRS-Service'} = '';
298        }
299    }
300
301    # create new ticket
302    my $NewTn    = $TicketObject->TicketCreateNumber();
303    my $TicketID = $TicketObject->TicketCreate(
304        TN           => $NewTn,
305        Title        => $GetParam{'X-OTRS-Title'} || $GetParam{Subject},
306        QueueID      => $QueueID,
307        Lock         => $GetParam{'X-OTRS-Lock'} || 'unlock',
308        Priority     => $Priority,
309        State        => $State,
310        TypeID       => $TypeID,
311        Service      => $GetParam{'X-OTRS-Service'} || '',
312        SLA          => $GetParam{'X-OTRS-SLA'} || '',
313        CustomerID   => $GetParam{'X-OTRS-CustomerNo'},
314        CustomerUser => $GetParam{'X-OTRS-CustomerUser'},
315        OwnerID      => $OwnerID,
316        UserID       => $Param{InmailUserID},
317        %Opts,
318    );
319
320    if ( !$TicketID ) {
321        $Self->{CommunicationLogObject}->ObjectLog(
322            ObjectLogType => 'Message',
323            Priority      => 'Error',
324            Key           => 'Kernel::System::PostMaster::NewTicket',
325            Value         => "Ticket could not be created!",
326        );
327        return;
328    }
329
330    my $TicketCreateMessage = <<"Message";
331New Ticket created:
332
333TicketNumber: $NewTn
334TicketID: $TicketID
335Priority: $Priority
336State: $State
337CustomerID: $GetParam{'X-OTRS-CustomerNo'}
338CustomerUser: $GetParam{'X-OTRS-CustomerUser'}
339
340Message
341
342    for my $Value (qw(Type Service SLA Lock)) {
343
344        if ( $GetParam{ 'X-OTRS-' . $Value } ) {
345            $TicketCreateMessage .= "$Value: " . $GetParam{ 'X-OTRS-' . $Value } . "\n";
346        }
347    }
348
349    $Self->{CommunicationLogObject}->ObjectLog(
350        ObjectLogType => 'Message',
351        Priority      => 'Debug',
352        Key           => 'Kernel::System::PostMaster::NewTicket',
353        Value         => $TicketCreateMessage,
354    );
355
356    # set pending time
357    if ( $GetParam{'X-OTRS-State-PendingTime'} ) {
358
359  # You can specify absolute dates like "2010-11-20 00:00:00" or relative dates, based on the arrival time of the email.
360  # Use the form "+ $Number $Unit", where $Unit can be 's' (seconds), 'm' (minutes), 'h' (hours) or 'd' (days).
361  # Only one unit can be specified. Examples of valid settings: "+50s" (pending in 50 seconds), "+30m" (30 minutes),
362  # "+12d" (12 days). Note that settings like "+1d 12h" are not possible. You can specify "+36h" instead.
363
364        my $TargetTimeStamp = $GetParam{'X-OTRS-State-PendingTime'};
365
366        my ( $Sign, $Number, $Unit ) = $TargetTimeStamp =~ m{^\s*([+-]?)\s*(\d+)\s*([smhd]?)\s*$}smx;
367
368        if ($Number) {
369            $Sign ||= '+';
370            $Unit ||= 's';
371
372            my $Seconds = $Sign eq '-' ? ( $Number * -1 ) : $Number;
373
374            my %UnitMultiplier = (
375                s => 1,
376                m => 60,
377                h => 60 * 60,
378                d => 60 * 60 * 24,
379            );
380
381            $Seconds = $Seconds * $UnitMultiplier{$Unit};
382
383            # get datetime object
384            my $DateTimeObject = $Kernel::OM->Create('Kernel::System::DateTime');
385            $DateTimeObject->Add( Seconds => $Seconds );
386            $TargetTimeStamp = $DateTimeObject->ToString();
387        }
388
389        my $Set = $TicketObject->TicketPendingTimeSet(
390            String   => $TargetTimeStamp,
391            TicketID => $TicketID,
392            UserID   => $Param{InmailUserID},
393        );
394
395        $Self->{CommunicationLogObject}->ObjectLog(
396            ObjectLogType => 'Message',
397            Priority      => 'Debug',
398            Key           => 'Kernel::System::PostMaster::NewTicket',
399            Value =>
400                "Pending time update via 'X-OTRS-State-PendingTime'! State-PendingTime: $GetParam{'X-OTRS-State-PendingTime'}.",
401        );
402    }
403
404    # get dynamic field objects
405    my $DynamicFieldObject        = $Kernel::OM->Get('Kernel::System::DynamicField');
406    my $DynamicFieldBackendObject = $Kernel::OM->Get('Kernel::System::DynamicField::Backend');
407
408    # dynamic fields
409    my $DynamicFieldList =
410        $DynamicFieldObject->DynamicFieldList(
411        Valid      => 1,
412        ResultType => 'HASH',
413        ObjectType => 'Ticket',
414        );
415
416    # set dynamic fields for Ticket object type
417    DYNAMICFIELDID:
418    for my $DynamicFieldID ( sort keys %{$DynamicFieldList} ) {
419        next DYNAMICFIELDID if !$DynamicFieldID;
420        next DYNAMICFIELDID if !$DynamicFieldList->{$DynamicFieldID};
421        my $Key = 'X-OTRS-DynamicField-' . $DynamicFieldList->{$DynamicFieldID};
422
423        if ( defined $GetParam{$Key} && length $GetParam{$Key} ) {
424
425            # get dynamic field config
426            my $DynamicFieldGet = $DynamicFieldObject->DynamicFieldGet(
427                ID => $DynamicFieldID,
428            );
429
430            $DynamicFieldBackendObject->ValueSet(
431                DynamicFieldConfig => $DynamicFieldGet,
432                ObjectID           => $TicketID,
433                Value              => $GetParam{$Key},
434                UserID             => $Param{InmailUserID},
435            );
436
437            $Self->{CommunicationLogObject}->ObjectLog(
438                ObjectLogType => 'Message',
439                Priority      => 'Debug',
440                Key           => 'Kernel::System::PostMaster::NewTicket',
441                Value         => "DynamicField update via '$Key'! Value: $GetParam{$Key}.",
442            );
443        }
444    }
445
446    # reverse dynamic field list
447    my %DynamicFieldListReversed = reverse %{$DynamicFieldList};
448
449    # set ticket free text
450    # for backward compatibility (should be removed in a future version)
451    my %Values =
452        (
453        'X-OTRS-TicketKey'   => 'TicketFreeKey',
454        'X-OTRS-TicketValue' => 'TicketFreeText',
455        );
456    for my $Item ( sort keys %Values ) {
457        for my $Count ( 1 .. 16 ) {
458            my $Key = $Item . $Count;
459            if (
460                defined $GetParam{$Key}
461                && length $GetParam{$Key}
462                && $DynamicFieldListReversed{ $Values{$Item} . $Count }
463                )
464            {
465                # get dynamic field config
466                my $DynamicFieldGet = $DynamicFieldObject->DynamicFieldGet(
467                    ID => $DynamicFieldListReversed{ $Values{$Item} . $Count },
468                );
469                if ($DynamicFieldGet) {
470                    my $Success = $DynamicFieldBackendObject->ValueSet(
471                        DynamicFieldConfig => $DynamicFieldGet,
472                        ObjectID           => $TicketID,
473                        Value              => $GetParam{$Key},
474                        UserID             => $Param{InmailUserID},
475                    );
476                }
477
478                $Self->{CommunicationLogObject}->ObjectLog(
479                    ObjectLogType => 'Message',
480                    Priority      => 'Debug',
481                    Key           => 'Kernel::System::PostMaster::NewTicket',
482                    Value         => "DynamicField (TicketKey$Count) update via '$Key'! Value: $GetParam{$Key}.",
483                );
484            }
485        }
486    }
487
488    # set ticket free time
489    # for backward compatibility (should be removed in a future version)
490    for my $Count ( 1 .. 6 ) {
491
492        my $Key = 'X-OTRS-TicketTime' . $Count;
493
494        if ( defined $GetParam{$Key} && length $GetParam{$Key} ) {
495
496            # get datetime object
497            my $DateTimeObject = $Kernel::OM->Create(
498                'Kernel::System::DateTime',
499                ObjectParams => {
500                    String => $GetParam{$Key}
501                }
502            );
503
504            if ( $DateTimeObject && $DynamicFieldListReversed{ 'TicketFreeTime' . $Count } ) {
505
506                # get dynamic field config
507                my $DynamicFieldGet = $DynamicFieldObject->DynamicFieldGet(
508                    ID => $DynamicFieldListReversed{ 'TicketFreeTime' . $Count },
509                );
510
511                if ($DynamicFieldGet) {
512                    my $Success = $DynamicFieldBackendObject->ValueSet(
513                        DynamicFieldConfig => $DynamicFieldGet,
514                        ObjectID           => $TicketID,
515                        Value              => $GetParam{$Key},
516                        UserID             => $Param{InmailUserID},
517                    );
518                }
519
520                $Self->{CommunicationLogObject}->ObjectLog(
521                    ObjectLogType => 'Message',
522                    Priority      => 'Debug',
523                    Key           => 'Kernel::System::PostMaster::NewTicket',
524                    Value         => "DynamicField (TicketTime$Count) update via '$Key'! Value: $GetParam{$Key}.",
525                );
526            }
527        }
528    }
529
530    my $ArticleObject        = $Kernel::OM->Get('Kernel::System::Ticket::Article');
531    my $ArticleBackendObject = $ArticleObject->BackendForChannel(
532        ChannelName => 'Email',
533    );
534
535    my $IsVisibleForCustomer = 1;
536    if ( length $GetParam{'X-OTRS-IsVisibleForCustomer'} ) {
537        $IsVisibleForCustomer = $GetParam{'X-OTRS-IsVisibleForCustomer'};
538    }
539
540    $Self->{CommunicationLogObject}->ObjectLog(
541        ObjectLogType => 'Message',
542        Priority      => 'Debug',
543        Key           => 'Kernel::System::PostMaster::NewTicket',
544        Value         => "Going to create new article for TicketID '$TicketID'.",
545    );
546
547    # Check if X-OTRS-SenderType exists, if not set default 'customer'.
548    if ( !$ArticleObject->ArticleSenderTypeLookup( SenderType => $GetParam{'X-OTRS-SenderType'} ) )
549    {
550        $Self->{CommunicationLogObject}->ObjectLog(
551            ObjectLogType => 'Message',
552            Priority      => 'Error',
553            Key           => 'Kernel::System::PostMaster::NewTicket',
554            Value         => "Can't find valid SenderType '$GetParam{'X-OTRS-SenderType'}' in DB, take 'customer'",
555        );
556        $GetParam{'X-OTRS-SenderType'} = 'customer';
557    }
558
559    # Create email article.
560    my $ArticleID = $ArticleBackendObject->ArticleCreate(
561        TicketID             => $TicketID,
562        SenderType           => $GetParam{'X-OTRS-SenderType'},
563        IsVisibleForCustomer => $IsVisibleForCustomer,
564        From                 => $GetParam{From},
565        ReplyTo              => $GetParam{ReplyTo},
566        To                   => $GetParam{To},
567        Cc                   => $GetParam{Cc},
568        Subject              => $GetParam{Subject},
569        MessageID            => $GetParam{'Message-ID'},
570        InReplyTo            => $GetParam{'In-Reply-To'},
571        References           => $GetParam{'References'},
572        ContentType          => $GetParam{'Content-Type'},
573        ContentDisposition   => $GetParam{'Content-Disposition'},
574        Body                 => $GetParam{Body},
575        UserID               => $Param{InmailUserID},
576        HistoryType          => 'EmailCustomer',
577        HistoryComment       => "\%\%$Comment",
578        OrigHeader           => \%GetParam,
579        AutoResponseType     => $AutoResponseType,
580        Queue                => $Queue,
581    );
582
583    # close ticket if article create failed!
584    if ( !$ArticleID ) {
585
586        $Self->{CommunicationLogObject}->ObjectLog(
587            ObjectLogType => 'Message',
588            Priority      => 'Error',
589            Key           => 'Kernel::System::PostMaster::NewTicket',
590            Value         => "Can't process email with MessageID <$GetParam{'Message-ID'}>! "
591                . "Please create a bug report with this email (From: $GetParam{From}, Located "
592                . "under var/spool/problem-email*) on http://bugs.otrs.org/!",
593        );
594
595        $Self->{CommunicationLogObject}->ObjectLog(
596            ObjectLogType => 'Message',
597            Priority      => 'Debug',
598            Key           => 'Kernel::System::PostMaster::NewTicket',
599            Value         => "TicketID '$TicketID' will be deleted again!",
600        );
601
602        $TicketObject->TicketDelete(
603            TicketID => $TicketID,
604            UserID   => $Param{InmailUserID},
605        );
606        return;
607    }
608
609    $Self->{CommunicationLogObject}->ObjectLookupSet(
610        ObjectLogType    => 'Message',
611        TargetObjectType => 'Article',
612        TargetObjectID   => $ArticleID,
613    );
614
615    if ( $Param{LinkToTicketID} ) {
616
617        my $SourceKey = $Param{LinkToTicketID};
618        my $TargetKey = $TicketID;
619
620        $Kernel::OM->Get('Kernel::System::LinkObject')->LinkAdd(
621            SourceObject => 'Ticket',
622            SourceKey    => $SourceKey,
623            TargetObject => 'Ticket',
624            TargetKey    => $TargetKey,
625            Type         => 'Normal',
626            State        => 'Valid',
627            UserID       => $Param{InmailUserID},
628        );
629    }
630
631    my %CommunicationLogSkipAttributes = (
632        Body       => 1,
633        Attachment => 1,
634    );
635
636    ATTRIBUTE:
637    for my $Attribute ( sort keys %GetParam ) {
638        next ATTRIBUTE if $CommunicationLogSkipAttributes{$Attribute};
639
640        my $Value = $GetParam{$Attribute};
641        next ATTRIBUTE if !( defined $Value ) || !( length $Value );
642
643        $Self->{CommunicationLogObject}->ObjectLog(
644            ObjectLogType => 'Message',
645            Priority      => 'Debug',
646            Key           => 'Kernel::System::PostMaster::NewTicket',
647            Value         => "$Attribute: $Value",
648        );
649    }
650
651    # dynamic fields
652    $DynamicFieldList =
653        $DynamicFieldObject->DynamicFieldList(
654        Valid      => 1,
655        ResultType => 'HASH',
656        ObjectType => 'Article',
657        );
658
659    # set dynamic fields for Article object type
660    DYNAMICFIELDID:
661    for my $DynamicFieldID ( sort keys %{$DynamicFieldList} ) {
662        next DYNAMICFIELDID if !$DynamicFieldID;
663        next DYNAMICFIELDID if !$DynamicFieldList->{$DynamicFieldID};
664        my $Key = 'X-OTRS-DynamicField-' . $DynamicFieldList->{$DynamicFieldID};
665        if ( defined $GetParam{$Key} && length $GetParam{$Key} ) {
666
667            # get dynamic field config
668            my $DynamicFieldGet = $DynamicFieldObject->DynamicFieldGet(
669                ID => $DynamicFieldID,
670            );
671
672            $DynamicFieldBackendObject->ValueSet(
673                DynamicFieldConfig => $DynamicFieldGet,
674                ObjectID           => $ArticleID,
675                Value              => $GetParam{$Key},
676                UserID             => $Param{InmailUserID},
677            );
678
679            $Self->{CommunicationLogObject}->ObjectLog(
680                ObjectLogType => 'Message',
681                Priority      => 'Debug',
682                Key           => 'Kernel::System::PostMaster::NewTicket',
683                Value         => "Article DynamicField update via '$Key'! Value: $GetParam{$Key}.",
684            );
685        }
686    }
687
688    # reverse dynamic field list
689    %DynamicFieldListReversed = reverse %{$DynamicFieldList};
690
691    # set free article text
692    # for backward compatibility (should be removed in a future version)
693    %Values =
694        (
695        'X-OTRS-ArticleKey'   => 'ArticleFreeKey',
696        'X-OTRS-ArticleValue' => 'ArticleFreeText',
697        );
698    for my $Item ( sort keys %Values ) {
699        for my $Count ( 1 .. 16 ) {
700            my $Key = $Item . $Count;
701            if (
702                defined $GetParam{$Key}
703                && length $GetParam{$Key}
704                && $DynamicFieldListReversed{ $Values{$Item} . $Count }
705                )
706            {
707                # get dynamic field config
708                my $DynamicFieldGet = $DynamicFieldObject->DynamicFieldGet(
709                    ID => $DynamicFieldListReversed{ $Values{$Item} . $Count },
710                );
711                if ($DynamicFieldGet) {
712                    my $Success = $DynamicFieldBackendObject->ValueSet(
713                        DynamicFieldConfig => $DynamicFieldGet,
714                        ObjectID           => $ArticleID,
715                        Value              => $GetParam{$Key},
716                        UserID             => $Param{InmailUserID},
717                    );
718                }
719
720                $Self->{CommunicationLogObject}->ObjectLog(
721                    ObjectLogType => 'Message',
722                    Priority      => 'Debug',
723                    Key           => 'Kernel::System::PostMaster::NewTicket',
724                    Value         => "Article DynamicField (ArticleKey) update via '$Key'! Value: $GetParam{$Key}.",
725                );
726            }
727        }
728    }
729
730    # write plain email to the storage
731    $ArticleBackendObject->ArticleWritePlain(
732        ArticleID => $ArticleID,
733        Email     => $Self->{ParserObject}->GetPlainEmail(),
734        UserID    => $Param{InmailUserID},
735    );
736
737    # write attachments to the storage
738    for my $Attachment ( $Self->{ParserObject}->GetAttachments() ) {
739        $ArticleBackendObject->ArticleWriteAttachment(
740            Filename           => $Attachment->{Filename},
741            Content            => $Attachment->{Content},
742            ContentType        => $Attachment->{ContentType},
743            ContentID          => $Attachment->{ContentID},
744            ContentAlternative => $Attachment->{ContentAlternative},
745            Disposition        => $Attachment->{Disposition},
746            ArticleID          => $ArticleID,
747            UserID             => $Param{InmailUserID},
748        );
749    }
750
751    return $TicketID;
752}
753
7541;
755