
######
Ticket
######


****
NAME
****


Kernel::System::Ticket - Functions to create, modify and delete tickets as well as related helper functions


********
SYNOPSIS
********


Create ticket object


.. code-block:: perl

     use Kernel::System::ObjectManager;
     local $Kernel::OM = Kernel::System::ObjectManager->new();
     my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');


Create a new ticket


.. code-block:: perl

     my $TicketID = $TicketObject->TicketCreate(
         Title        => 'Some Ticket Title',
         Queue        => 'Raw',
         Lock         => 'unlock',
         Priority     => '3 normal',
         State        => 'new',
         CustomerID   => '12345',
         CustomerUser => 'customer@example.com',
         OwnerID      => 1,
         UserID       => 1,
     );


Lock the ticket


.. code-block:: perl

     my $Success = $TicketObject->TicketLockSet(
         Lock     => 'lock',
         TicketID => $TicketID,
         UserID   => 1,
     );


Update the title


.. code-block:: perl

     my $Success = $TicketObject->TicketTitleUpdate(
         Title    => 'Some Title',
         TicketID => $TicketID,
         UserID   => 1,
     );


Move ticket to another queue


.. code-block:: perl

     my $Success = $TicketObject->TicketQueueSet(
         Queue    => 'Some Queue Name',
         TicketID => $TicketID,
         UserID   => 1,
     );


Set a ticket type


.. code-block:: perl

     my $Success = $TicketObject->TicketTypeSet(
         Type     => 'Incident',
         TicketID => $TicketID,
         UserID   => 1,
     );


Assign another customer


.. code-block:: perl

     my $Success = $TicketObject->TicketCustomerSet(
         No       => '12345',
         User     => 'customer@company.org',
         TicketID => $TicketID,
         UserID   => 1,
     );


Update the state


.. code-block:: perl

     my $Success = $TicketObject->TicketStateSet(
         State     => 'pending reminder',
         TicketID => $TicketID,
         UserID   => 1,
     );


Update pending time (only for pending states)


.. code-block:: perl

     my $Success = $TicketObject->TicketPendingTimeSet(
         String   => '2019-08-14 22:05:00',
         TicketID => $TicketID,
         UserID   => 1,
     );


Set a new priority


.. code-block:: perl

     my $Success = $TicketObject->TicketPrioritySet(
         TicketID => $TicketID,
         Priority => 'low',
         UserID   => 1,
     );


Assign to another agent


.. code-block:: perl

     my $Success = $TicketObject->TicketOwnerSet(
         TicketID  => $TicketID,
         NewUserID => 2,
         UserID    => 1,
     );


Set a responsible


.. code-block:: perl

     my $Success = $TicketObject->TicketResponsibleSet(
         TicketID  => $TicketID,
         NewUserID => 3,
         UserID    => 1,
     );


Add something to the history


.. code-block:: perl

     my $Success = $TicketObject->HistoryAdd(
         Name         => 'Some Comment',
         HistoryType  => 'Move',
         TicketID     => $TicketID,
         CreateUserID => 1,
     );


Get the complete ticket history


.. code-block:: perl

     my @HistoryLines = $TicketObject->HistoryGet(
         TicketID => $TicketID,
         UserID   => 1,
     );


Get current ticket attributes


.. code-block:: perl

     my %Ticket = $TicketObject->TicketGet(
         TicketID => $TicketID,
         UserID   => 1,
     );


Delete the ticket


.. code-block:: perl

     my $Success = $TicketObject->TicketDelete(
         TicketID => $TicketID,
         UserID   => 1,
     );



****************
PUBLIC INTERFACE
****************


new()
=====


Don't use the constructor directly, use the ObjectManager instead:


.. code-block:: perl

     my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');



TicketCreateNumber()
====================


creates a new ticket number


.. code-block:: perl

     my $TicketNumber = $TicketObject->TicketCreateNumber();



GetTNByString()
===============


creates a new ticket number


.. code-block:: perl

     my $TicketNumber = $TicketObject->GetTNByString($Subject);



TicketCheckNumber()
===================


checks if ticket number exists, returns ticket id if number exists.

returns the merged ticket id if ticket was merged.
only into a depth of maximum 10 merges


.. code-block:: perl

     my $TicketID = $TicketObject->TicketCheckNumber(
         Tn => '200404051004575',
     );



TicketCreate()
==============


creates a new ticket


.. code-block:: perl

     my $TicketID = $TicketObject->TicketCreate(
         Title        => 'Some Ticket Title',
         Queue        => 'Raw',            # or QueueID => 123,
         Lock         => 'unlock',
         Priority     => '3 normal',       # or PriorityID => 2,
         State        => 'new',            # or StateID => 5,
         CustomerID   => '123465',
         CustomerUser => 'customer@example.com',
         OwnerID      => 123,
         UserID       => 123,
     );


or


.. code-block:: perl

     my $TicketID = $TicketObject->TicketCreate(
         TN            => $TicketObject->TicketCreateNumber(), # optional
         Title         => 'Some Ticket Title',
         Queue         => 'Raw',              # or QueueID => 123,
         Lock          => 'unlock',
         Priority      => '3 normal',         # or PriorityID => 2,
         State         => 'new',              # or StateID => 5,
         Type          => 'Incident',         # or TypeID = 1 or Ticket type default (Ticket::Type::Default), not required
         Service       => 'Service A',        # or ServiceID => 1, not required
         SLA           => 'SLA A',            # or SLAID => 1, not required
         CustomerID    => '123465',
         CustomerUser  => 'customer@example.com',
         OwnerID       => 123,
         ResponsibleID => 123,                # not required
         ArchiveFlag   => 'y',                # (y|n) not required
         UserID        => 123,
     );


Events:
    TicketCreate


TicketDelete()
==============


deletes a ticket with articles from storage


.. code-block:: perl

     my $Success = $TicketObject->TicketDelete(
         TicketID => 123,
         UserID   => 123,
     );


Events:
    TicketDelete


TicketIDLookup()
================


ticket id lookup by ticket number


.. code-block:: perl

     my $TicketID = $TicketObject->TicketIDLookup(
         TicketNumber => '2004040510440485',
     );



TicketNumberLookup()
====================


ticket number lookup by ticket id


.. code-block:: perl

     my $TicketNumber = $TicketObject->TicketNumberLookup(
         TicketID => 123,
     );



TicketSubjectBuild()
====================


rebuild a new ticket subject

This will generate a subject like \ ``RE: [Ticket# 2004040510440485] Some subject``\ 


.. code-block:: perl

     my $NewSubject = $TicketObject->TicketSubjectBuild(
         TicketNumber => '2004040510440485',
         Subject      => $OldSubject,
         Action       => 'Reply',
     );


This will generate a subject like \ ``[Ticket# 2004040510440485] Some subject``\ 
(so without RE: )


.. code-block:: perl

     my $NewSubject = $TicketObject->TicketSubjectBuild(
         TicketNumber => '2004040510440485',
         Subject      => $OldSubject,
         Type         => 'New',
         Action       => 'Reply',
     );


This will generate a subject like \ ``FWD: [Ticket# 2004040510440485] Some subject``\ 


.. code-block:: perl

     my $NewSubject = $TicketObject->TicketSubjectBuild(
         TicketNumber => '2004040510440485',
         Subject      => $OldSubject,
         Action       => 'Forward', # Possible values are Reply and Forward, Reply is default.
     );


This will generate a subject like \ ``[Ticket# 2004040510440485] Re: Some subject``\ 
(so without clean-up of subject)


.. code-block:: perl

     my $NewSubject = $TicketObject->TicketSubjectBuild(
         TicketNumber => '2004040510440485',
         Subject      => $OldSubject,
         Type         => 'New',
         NoCleanup    => 1,
     );



TicketSubjectClean()
====================


strip/clean up a ticket subject


.. code-block:: perl

     my $NewSubject = $TicketObject->TicketSubjectClean(
         TicketNumber => '2004040510440485',
         Subject      => $OldSubject,
         Size         => $SubjectSizeToBeDisplayed   # optional, if 0 do not cut subject
     );



TicketGet()
===========


Get ticket info


.. code-block:: perl

     my %Ticket = $TicketObject->TicketGet(
         TicketID      => 123,
         DynamicFields => 0,         # Optional, default 0. To include the dynamic field values for this ticket on the return structure.
         UserID        => 123,
         Silent        => 0,         # Optional, default 0. To suppress the warning if the ticket does not exist.
     );


Returns:


.. code-block:: perl

     %Ticket = (
         TicketNumber       => '20101027000001',
         Title              => 'some title',
         TicketID           => 123,
         State              => 'some state',
         StateID            => 123,
         StateType          => 'some state type',
         Priority           => 'some priority',
         PriorityID         => 123,
         Lock               => 'lock',
         LockID             => 123,
         Queue              => 'some queue',
         QueueID            => 123,
         CustomerID         => 'customer_id_123',
         CustomerUserID     => 'customer_user_id_123',
         Owner              => 'some_owner_login',
         OwnerID            => 123,
         Type               => 'some ticket type',
         TypeID             => 123,
         SLA                => 'some sla',
         SLAID              => 123,
         Service            => 'some service',
         ServiceID          => 123,
         Responsible        => 'some_responsible_login',
         ResponsibleID      => 123,
         Age                => 3456,
         Created            => '2010-10-27 20:15:00',
         CreateBy           => 123,
         Changed            => '2010-10-27 20:15:15',
         ChangeBy           => 123,
         ArchiveFlag        => 'y',
 
         # If DynamicFields => 1 was passed, you'll get an entry like this for each dynamic field:
         DynamicField_X     => 'value_x',
 
         # (time stamps of expected escalations)
         EscalationResponseTime           (unix time stamp of response time escalation)
         EscalationUpdateTime             (unix time stamp of update time escalation)
         EscalationSolutionTime           (unix time stamp of solution time escalation)
 
         # (general escalation info of nearest escalation type)
         EscalationDestinationIn          (escalation in e. g. 1h 4m)
         EscalationDestinationTime        (date of escalation in unix time, e. g. 72193292)
         EscalationDestinationDate        (date of escalation, e. g. "2009-02-14 18:00:00")
         EscalationTimeWorkingTime        (seconds of working/service time till escalation, e. g. "1800")
         EscalationTime                   (seconds total till escalation of nearest escalation time type - response, update or solution time, e. g. "3600")
 
         # (detailed escalation info about first response, update and solution time)
         FirstResponseTimeEscalation      (if true, ticket is escalated)
         FirstResponseTimeNotification    (if true, notify - x% of escalation has reached)
         FirstResponseTimeDestinationTime (date of escalation in unix time, e. g. 72193292)
         FirstResponseTimeDestinationDate (date of escalation, e. g. "2009-02-14 18:00:00")
         FirstResponseTimeWorkingTime     (seconds of working/service time till escalation, e. g. "1800")
         FirstResponseTime                (seconds total till escalation, e. g. "3600")
 
         UpdateTimeEscalation             (if true, ticket is escalated)
         UpdateTimeNotification           (if true, notify - x% of escalation has reached)
         UpdateTimeDestinationTime        (date of escalation in unix time, e. g. 72193292)
         UpdateTimeDestinationDate        (date of escalation, e. g. "2009-02-14 18:00:00")
         UpdateTimeWorkingTime            (seconds of working/service time till escalation, e. g. "1800")
         UpdateTime                       (seconds total till escalation, e. g. "3600")
 
         SolutionTimeEscalation           (if true, ticket is escalated)
         SolutionTimeNotification         (if true, notify - x% of escalation has reached)
         SolutionTimeDestinationTime      (date of escalation in unix time, e. g. 72193292)
         SolutionTimeDestinationDate      (date of escalation, e. g. "2009-02-14 18:00:00")
         SolutionTimeWorkingTime          (seconds of working/service time till escalation, e. g. "1800")
         SolutionTime                     (seconds total till escalation, e. g. "3600")
     );


To get extended ticket attributes, use \ ``Extended``\ 


.. code-block:: perl

     my %Ticket = $TicketObject->TicketGet(
         TicketID => 123,
         UserID   => 123,
         Extended => 1,
     );


Additional parameters are:


.. code-block:: perl

     %Ticket = (
         FirstResponse                   (timestamp of first response, first contact with customer)
         FirstResponseInMin              (minutes till first response)
         FirstResponseDiffInMin          (minutes till or over first response)
 
         SolutionInMin                   (minutes till solution time)
         SolutionDiffInMin               (minutes till or over solution time)
 
         FirstLock                       (timestamp of first lock)
     );



TicketDeepGet()
===============


Returns ticket data with all resolved dependent data like (customer) user data, etc.
It also contains all articles and a separate hash of the requested article by parameter.


.. code-block:: perl

     my %Ticket = $TicketObject->TicketDeepGet(
         TicketID  => 123,
         ArticleID => 123, # optional
         UserID    => 53,
 
         # Also fetch all attachments for all articles of the given ticket.
         GetAllArticleAttachments => 1, # defaults to 0
     );


Returns:


.. code-block:: perl

     my %Ticket = (
         # ticket attributes
 
         %Ticket,
         Articles        => [
             # ...
         ],
         CustomerUser    => {
             # ...
         },
         CustomerCompany => {
             # ...
         },
         QueueData       => {
             # ...
         },
         TypeData        => {
             # ...
         },
         PriorityData    => {
             # ...
         },
         ServiceData     => {
             # ...
         },
         SLAData         => {
             # ...
         },
         OwnerData       => {
             # ...
         },
         ResponsibleData => {
             # ...
         },
         CreateByData    => {
             # ...
         },
         Article         => {
             # ...
         },
     );



_GetBase64EncodedArticleAttachments()
=====================================


Returns all attachments of the the article with the given ID (base-64 encoded).


.. code-block:: perl

     my $Attachments = $TicketObject->_GetBase64EncodedArticleAttachments(
         TicketID  => 123,
         ArticleID => 123,
     );


Returns:


.. code-block:: perl

     my $Attachments = [
         {
             Content            => '...', # base-64 encoded
             ContentAlternative => '',
             ContentID          => '',
             ContentType        => 'application/pdf',
             Filename           => 'StdAttachment-Test1.pdf',
             FilesizeRaw        => 4722,
             Disposition        => 'attachment',
             FileID             => 2,
         },
         # ...
     ];



_TicketDeepGetDataCleanUp()
===========================


Cleans up the given hash by removing possible given passwords, tokens, etc.


.. code-block:: perl

     my $CleanedUpData = $TicketObject->_TicketDeepGetDataCleanUp(
         Data => {
             Test   => 'ok',
             config => 'removed',
             secret => 'removed',
             passw  => 'removed',
             userpw => 'removed',
             auth   => 'removed',
             token  => 'removed',
             Field  => 'ok',
         }
     );


Returns:


.. code-block:: perl

     my $CleanedUpData = {
         Test  => 'ok',
         Field => 'ok',
     };



TicketTitleUpdate()
===================


update ticket title


.. code-block:: perl

     my $Success = $TicketObject->TicketTitleUpdate(
         Title    => 'Some Title',
         TicketID => 123,
         UserID   => 1,
     );


Events:
    TicketTitleUpdate


TicketUnlockTimeoutUpdate()
===========================


set the ticket unlock time to the passed time


.. code-block:: perl

     my $Success = $TicketObject->TicketUnlockTimeoutUpdate(
         UnlockTimeout => $Epoch,
         TicketID      => 123,
         UserID        => 143,
     );


Events:
    TicketUnlockTimeoutUpdate


TicketQueueID()
===============


get ticket queue id


.. code-block:: perl

     my $QueueID = $TicketObject->TicketQueueID(
         TicketID => 123,
     );



TicketMoveList()
================


to get the move queue list for a ticket (depends on workflow, if configured)


.. code-block:: perl

     my %Queues = $TicketObject->TicketMoveList(
         Type   => 'create',
         UserID => 123,
     );
 
     my %Queues = $TicketObject->TicketMoveList(
         Type           => 'create',
         CustomerUserID => 'customer_user_id_123',
     );
 
 
     my %Queues = $TicketObject->TicketMoveList(
         QueueID => 123,
         UserID  => 123,
     );
 
     my %Queues = $TicketObject->TicketMoveList(
         TicketID => 123,
         UserID   => 123,
     );



TicketQueueSet()
================


to move a ticket (sends notification to agents of selected my queues, if ticket is not closed)


.. code-block:: perl

     my $Success = $TicketObject->TicketQueueSet(
         QueueID  => 123,
         TicketID => 123,
         UserID   => 123,
     );
 
     my $Success = $TicketObject->TicketQueueSet(
         Queue    => 'Some Queue Name',
         TicketID => 123,
         UserID   => 123,
     );
 
     my $Success = $TicketObject->TicketQueueSet(
         Queue    => 'Some Queue Name',
         TicketID => 123,
         Comment  => 'some comment', # optional
         ForceNotificationToUserID => [1,43,56], # if you want to force somebody
         UserID   => 123,
     );


Optional attribute:
SendNoNotification disables or enables agent and customer notification for this
action.

For example:


.. code-block:: perl

         SendNoNotification => 0, # optional 1|0 (send no agent and customer notification)


Events:
    TicketQueueUpdate


TicketMoveQueueList()
=====================


returns a list of used queue ids / names


.. code-block:: perl

     my @QueueIDList = $TicketObject->TicketMoveQueueList(
         TicketID => 123,
         Type     => 'ID',
     );


Returns:


.. code-block:: perl

     @QueueIDList = ( 1, 2, 3 );
 
     my @QueueList = $TicketObject->TicketMoveQueueList(
         TicketID => 123,
         Type     => 'Name',
     );


Returns:


.. code-block:: perl

     @QueueList = ( 'QueueA', 'QueueB', 'QueueC' );



TicketTypeList()
================


to get all possible types for a ticket (depends on workflow, if configured)


.. code-block:: perl

     my %Types = $TicketObject->TicketTypeList(
         UserID => 123,
     );
 
     my %Types = $TicketObject->TicketTypeList(
         CustomerUserID => 'customer_user_id_123',
     );
 
     my %Types = $TicketObject->TicketTypeList(
         QueueID => 123,
         UserID  => 123,
     );
 
     my %Types = $TicketObject->TicketTypeList(
         TicketID => 123,
         UserID   => 123,
     );


Returns:


.. code-block:: perl

     %Types = (
         1 => 'default',
         2 => 'request',
         3 => 'offer',
     );



TicketTypeSet()
===============


to set a ticket type


.. code-block:: perl

     my $Success = $TicketObject->TicketTypeSet(
         TypeID   => 123,
         TicketID => 123,
         UserID   => 123,
     );
 
     my $Success = $TicketObject->TicketTypeSet(
         Type     => 'normal',
         TicketID => 123,
         UserID   => 123,
     );


Events:
    TicketTypeUpdate


TicketServiceList()
===================


to get all possible services for a ticket (depends on workflow, if configured)


.. code-block:: perl

     my %Services = $TicketObject->TicketServiceList(
         QueueID        => 123,
         UserID         => 123,
     );
 
     my %Services = $TicketObject->TicketServiceList(
         CustomerUserID => 123,
         QueueID        => 123,
     );
 
     my %Services = $TicketObject->TicketServiceList(
         CustomerUserID => 123,
         TicketID       => 123,
         UserID         => 123,
     );


Returns:


.. code-block:: perl

     %Services = (
         1 => 'ServiceA',
         2 => 'ServiceB',
         3 => 'ServiceC',
     );



TicketServiceSet()
==================


to set a ticket service


.. code-block:: perl

     my $Success = $TicketObject->TicketServiceSet(
         ServiceID => 123,
         TicketID  => 123,
         UserID    => 123,
     );
 
     my $Success = $TicketObject->TicketServiceSet(
         Service  => 'Service A',
         TicketID => 123,
         UserID   => 123,
     );


Events:
    TicketServiceUpdate


TicketEscalationPreferences()
=============================


get escalation preferences of a ticket (e. g. from SLA or from Queue based settings)


.. code-block:: perl

     my %Escalation = $TicketObject->TicketEscalationPreferences(
         Ticket => $Param{Ticket},
         UserID => $Param{UserID},
     );



TicketEscalationDateCalculation()
=================================


get escalation properties of a ticket


.. code-block:: perl

     my %Escalation = $TicketObject->TicketEscalationDateCalculation(
         Ticket => $Param{Ticket},
         UserID => $Param{UserID},
     );


returns


.. code-block:: perl

     (general escalation info)
     EscalationDestinationIn          (escalation in e. g. 1h 4m)
     EscalationDestinationTime        (date of escalation in unix time, e. g. 72193292)
     EscalationDestinationDate        (date of escalation, e. g. "2009-02-14 18:00:00")
     EscalationTimeWorkingTime        (seconds of working/service time till escalation, e. g. "1800")
     EscalationTime                   (seconds total till escalation, e. g. "3600")
 
     (detail escalation info about first response, update and solution time)
     FirstResponseTimeEscalation      (if true, ticket is escalated)
     FirstResponseTimeNotification    (if true, notify - x% of escalation has reached)
     FirstResponseTimeDestinationTime (date of escalation in unix time, e. g. 72193292)
     FirstResponseTimeDestinationDate (date of escalation, e. g. "2009-02-14 18:00:00")
     FirstResponseTimeWorkingTime     (seconds of working/service time till escalation, e. g. "1800")
     FirstResponseTime                (seconds total till escalation, e. g. "3600")
 
     UpdateTimeEscalation             (if true, ticket is escalated)
     UpdateTimeNotification           (if true, notify - x% of escalation has reached)
     UpdateTimeDestinationTime        (date of escalation in unix time, e. g. 72193292)
     UpdateTimeDestinationDate        (date of escalation, e. g. "2009-02-14 18:00:00")
     UpdateTimeWorkingTime            (seconds of working/service time till escalation, e. g. "1800")
     UpdateTime                       (seconds total till escalation, e. g. "3600")
 
     SolutionTimeEscalation           (if true, ticket is escalated)
     SolutionTimeNotification         (if true, notify - x% of escalation has reached)
     SolutionTimeDestinationTime      (date of escalation in unix time, e. g. 72193292)
     SolutionTimeDestinationDate      (date of escalation, e. g. "2009-02-14 18:00:00")
     SolutionTimeWorkingTime          (seconds of working/service time till escalation, e. g. "1800")
     SolutionTime                     (seconds total till escalation, e. g. "3600")



TicketEscalationIndexBuild()
============================


build escalation index of one ticket with current settings (SLA, Queue, Calendar...)


.. code-block:: perl

     my $Success = $TicketObject->TicketEscalationIndexBuild(
         TicketID => $Param{TicketID},
         UserID   => $Param{UserID},
     );



TicketSLAList()
===============


to get all possible SLAs for a ticket (depends on workflow, if configured)


.. code-block:: perl

     my %SLAs = $TicketObject->TicketSLAList(
         ServiceID => 1,
         UserID    => 123,
     );
 
     my %SLAs = $TicketObject->TicketSLAList(
         ServiceID      => 1,
         CustomerUserID => 'customer_user_id_123',
     );
 
 
     my %SLAs = $TicketObject->TicketSLAList(
         QueueID   => 123,
         ServiceID => 1,
         UserID    => 123,
     );
 
     my %SLAs = $TicketObject->TicketSLAList(
         TicketID  => 123,
         ServiceID => 1,
         UserID    => 123,
     );


Returns:


.. code-block:: perl

     %SLAs = (
         1 => 'SLA A',
         2 => 'SLA B',
         3 => 'SLA C',
     );



TicketSLASet()
==============


to set a ticket service level agreement


.. code-block:: perl

     my $Success = $TicketObject->TicketSLASet(
         SLAID    => 123,
         TicketID => 123,
         UserID   => 123,
     );
 
     my $Success = $TicketObject->TicketSLASet(
         SLA      => 'SLA A',
         TicketID => 123,
         UserID   => 123,
     );


Events:
    TicketSLAUpdate


TicketCustomerSet()
===================


Set customer data of ticket. Can set 'No' (CustomerID),
'User' (CustomerUserID), or both.


.. code-block:: perl

     my $Success = $TicketObject->TicketCustomerSet(
         No       => 'client123',
         User     => 'client-user-123',
         TicketID => 123,
         UserID   => 23,
     );


Events:
    TicketCustomerUpdate


TicketPermission()
==================


returns whether or not the agent has permission on a ticket


.. code-block:: perl

     my $Access = $TicketObject->TicketPermission(
         Type     => 'ro',
         TicketID => 123,
         UserID   => 123,
     );


or without logging, for example for to check if a link/action should be shown


.. code-block:: perl

     my $Access = $TicketObject->TicketPermission(
         Type     => 'ro',
         TicketID => 123,
         LogNo    => 1,
         UserID   => 123,
     );



TicketCustomerPermission()
==========================


returns whether or not a customer has permission to a ticket


.. code-block:: perl

     my $Access = $TicketObject->TicketCustomerPermission(
         Type     => 'ro',
         TicketID => 123,
         UserID   => 123,
     );


or without logging, for example for to check if a link/action should be displayed


.. code-block:: perl

     my $Access = $TicketObject->TicketCustomerPermission(
         Type     => 'ro',
         TicketID => 123,
         LogNo    => 1,
         UserID   => 123,
     );



GetSubscribedUserIDsByQueueID()
===============================


returns an array of user ids which selected the given queue id as
custom queue.


.. code-block:: perl

     my @UserIDs = $TicketObject->GetSubscribedUserIDsByQueueID(
         QueueID => 123,
     );


Returns:


.. code-block:: perl

     @UserIDs = ( 1, 2, 3 );



GetSubscribedUserIDsByServiceID()
=================================


returns an array of user ids which selected the given service id as
custom service.


.. code-block:: perl

     my @UserIDs = $TicketObject->GetSubscribedUserIDsByServiceID(
         ServiceID => 123,
     );


Returns:


.. code-block:: perl

     @UserIDs = ( 1, 2, 3 );



TicketPendingTimeSet()
======================


set ticket pending time:


.. code-block:: perl

     my $Success = $TicketObject->TicketPendingTimeSet(
         Year     => 2003,
         Month    => 08,
         Day      => 14,
         Hour     => 22,
         Minute   => 05,
         TicketID => 123,
         UserID   => 23,
     );


or use a time stamp:


.. code-block:: perl

     my $Success = $TicketObject->TicketPendingTimeSet(
         String   => '2003-08-14 22:05:00',
         TicketID => 123,
         UserID   => 23,
     );


or use a diff (set pending time to "now" + diff minutes)


.. code-block:: perl

     my $Success = $TicketObject->TicketPendingTimeSet(
         Diff     => ( 7 * 24 * 60 ),  # minutes (here: 10080 minutes - 7 days)
         TicketID => 123,
         UserID   => 23,
     );


If you want to set the pending time to null, just supply zeros:


.. code-block:: perl

     my $Success = $TicketObject->TicketPendingTimeSet(
         Year     => 0000,
         Month    => 00,
         Day      => 00,
         Hour     => 00,
         Minute   => 00,
         TicketID => 123,
         UserID   => 23,
     );


or use a time stamp:


.. code-block:: perl

     my $Success = $TicketObject->TicketPendingTimeSet(
         String   => '0000-00-00 00:00:00',
         TicketID => 123,
         UserID   => 23,
     );


Events:
    TicketPendingTimeUpdate


TicketLockGet()
===============


check if a ticket is locked or not


.. code-block:: perl

     if ($TicketObject->TicketLockGet(TicketID => 123)) {
         print "Ticket is locked!\n";
     }
     else {
         print "Ticket is not locked!\n";
     }



TicketLockSet()
===============


to lock or unlock a ticket


.. code-block:: perl

     my $Success = $TicketObject->TicketLockSet(
         Lock     => 'lock',
         TicketID => 123,
         UserID   => 123,
     );
 
     my $Success = $TicketObject->TicketLockSet(
         LockID   => 1,
         TicketID => 123,
         UserID   => 123,
     );


Optional attribute:
SendNoNotification, disable or enable agent and customer notification for this
action. Otherwise a notification will be sent to agent and customer.

For example:


.. code-block:: perl

         SendNoNotification => 0, # optional 1|0 (send no agent and customer notification)


Events:
    TicketLockUpdate


TicketArchiveFlagSet()
======================


to set the ticket archive flag


.. code-block:: perl

     my $Success = $TicketObject->TicketArchiveFlagSet(
         ArchiveFlag => 'y',  # (y|n)
         TicketID    => 123,
         UserID      => 123,
     );


Events:
    TicketArchiveFlagUpdate


TicketArchiveFlagGet()
======================


check if a ticket is archived or not


.. code-block:: perl

     if ( $TicketObject->TicketArchiveFlagGet( TicketID => 123 ) ) {
         print "Ticket is archived!\n";
     }
     else {
         print "Ticket is not archived!\n";
     }



TicketStateSet()
================


to set a ticket state


.. code-block:: perl

     my $Success = $TicketObject->TicketStateSet(
         State     => 'open',
         TicketID  => 123,
         ArticleID => 123, #optional, for history
         UserID    => 123,
     );
 
     my $Success = $TicketObject->TicketStateSet(
         StateID  => 3,
         TicketID => 123,
         UserID   => 123,
     );


Optional attribute:
SendNoNotification, disable or enable agent and customer notification for this
action. Otherwise a notification will be sent to agent and customer.

For example:


.. code-block:: perl

         SendNoNotification => 0, # optional 1|0 (send no agent and customer notification)


Events:
    TicketStateUpdate


TicketStateList()
=================


to get the state list for a ticket (depends on workflow, if configured)


.. code-block:: perl

     my %States = $TicketObject->TicketStateList(
         TicketID => 123,
         UserID   => 123,
     );
 
     my %States = $TicketObject->TicketStateList(
         TicketID       => 123,
         CustomerUserID => 'customer_user_id_123',
     );
 
     my %States = $TicketObject->TicketStateList(
         QueueID => 123,
         UserID  => 123,
     );
 
     my %States = $TicketObject->TicketStateList(
         TicketID => 123,
         Type     => 'open',
         UserID   => 123,
     );


Returns:


.. code-block:: perl

     %States = (
         1 => 'State A',
         2 => 'State B',
         3 => 'State C',
     );



OwnerCheck()
============


to get the ticket owner


.. code-block:: perl

     my ($OwnerID, $Owner) = $TicketObject->OwnerCheck(
         TicketID => 123,
     );


or for access control


.. code-block:: perl

     my $AccessOk = $TicketObject->OwnerCheck(
         TicketID => 123,
         OwnerID  => 321,
     );



TicketOwnerSet()
================


to set the ticket owner (notification to the new owner will be sent)

by using user id


.. code-block:: perl

     my $Success = $TicketObject->TicketOwnerSet(
         TicketID  => 123,
         NewUserID => 555,
         UserID    => 123,
     );


by using user login


.. code-block:: perl

     my $Success = $TicketObject->TicketOwnerSet(
         TicketID => 123,
         NewUser  => 'some-user-login',
         UserID   => 123,
     );


Return:
    1 = owner has been set
    2 = this owner is already set, no update needed

Optional attribute:
SendNoNotification, disable or enable agent and customer notification for this
action. Otherwise a notification will be sent to agent and customer.

For example:


.. code-block:: perl

         SendNoNotification => 0, # optional 1|0 (send no agent and customer notification)


Events:
    TicketOwnerUpdate


TicketOwnerList()
=================


returns the owner in the past as array with hash ref of the owner data
(name, email, ...)


.. code-block:: perl

     my @Owner = $TicketObject->TicketOwnerList(
         TicketID => 123,
     );


Returns:


.. code-block:: perl

     @Owner = (
         {
             UserFirstname => 'SomeName',
             UserLastname  => 'SomeName',
             UserEmail     => 'some@example.com',
             # custom attributes
         },
         {
             UserFirstname => 'SomeName',
             UserLastname  => 'SomeName',
             UserEmail     => 'some@example.com',
             # custom attributes
         },
     );



TicketResponsibleSet()
======================


to set the ticket responsible (notification to the new responsible will be sent)

by using user id


.. code-block:: perl

     my $Success = $TicketObject->TicketResponsibleSet(
         TicketID  => 123,
         NewUserID => 555,
         UserID    => 213,
     );


by using user login


.. code-block:: perl

     my $Success = $TicketObject->TicketResponsibleSet(
         TicketID  => 123,
         NewUser   => 'some-user-login',
         UserID    => 213,
     );


Return:
    1 = responsible has been set
    2 = this responsible is already set, no update needed

Optional attribute:
SendNoNotification, disable or enable agent and customer notification for this
action. Otherwise a notification will be sent to agent and customer.

For example:


.. code-block:: perl

         SendNoNotification => 0, # optional 1|0 (send no agent and customer notification)


Events:
    TicketResponsibleUpdate


TicketResponsibleList()
=======================


returns the responsible in the past as array with hash ref of the owner data
(name, email, ...)


.. code-block:: perl

     my @Responsible = $TicketObject->TicketResponsibleList(
         TicketID => 123,
     );


Returns:


.. code-block:: perl

     @Responsible = (
         {
             UserFirstname => 'SomeName',
             UserLastname  => 'SomeName',
             UserEmail     => 'some@example.com',
             # custom attributes
         },
         {
             UserFirstname => 'SomeName',
             UserLastname  => 'SomeName',
             UserEmail     => 'some@example.com',
             # custom attributes
         },
     );



TicketInvolvedAgentsList()
==========================


returns an array with hash ref of agents which have been involved with a ticket.
It is guaranteed that no agent is returned twice.


.. code-block:: perl

     my @InvolvedAgents = $TicketObject->TicketInvolvedAgentsList(
         TicketID => 123,
     );


Returns:


.. code-block:: perl

     @InvolvedAgents = (
         {
             UserFirstname => 'SomeName',
             UserLastname  => 'SomeName',
             UserEmail     => 'some@example.com',
             # custom attributes
         },
         {
             UserFirstname => 'AnotherName',
             UserLastname  => 'AnotherName',
             UserEmail     => 'another@example.com',
             # custom attributes
         },
     );



TicketPrioritySet()
===================


to set the ticket priority


.. code-block:: perl

     my $Success = $TicketObject->TicketPrioritySet(
         TicketID => 123,
         Priority => 'low',
         UserID   => 213,
     );
 
     my $Success = $TicketObject->TicketPrioritySet(
         TicketID   => 123,
         PriorityID => 2,
         UserID     => 213,
     );


Events:
    TicketPriorityUpdate


TicketPriorityList()
====================


to get the priority list for a ticket (depends on workflow, if configured)


.. code-block:: perl

     my %Priorities = $TicketObject->TicketPriorityList(
         TicketID => 123,
         UserID   => 123,
     );
 
     my %Priorities = $TicketObject->TicketPriorityList(
         TicketID       => 123,
         CustomerUserID => 'customer_user_id_123',
     );
 
     my %Priorities = $TicketObject->TicketPriorityList(
         QueueID => 123,
         UserID  => 123,
     );


Returns:


.. code-block:: perl

     %Priorities = (
         1 => 'Priority A',
         2 => 'Priority B',
         3 => 'Priority C',
     );



HistoryTicketStatusGet()
========================


get a hash with ticket id as key and a hash ref (result of HistoryTicketGet)
of all affected tickets in this time area.


.. code-block:: perl

     my %Tickets = $TicketObject->HistoryTicketStatusGet(
         StartDay   => 12,
         StartMonth => 1,
         StartYear  => 2006,
         StopDay    => 18,
         StopMonth  => 1,
         StopYear   => 2006,
         Force      => 0,
     );



HistoryTicketGet()
==================


returns a hash of some of the ticket data
calculated based on ticket history info at the given date.


.. code-block:: perl

     my %HistoryData = $TicketObject->HistoryTicketGet(
         StopYear   => 2003,
         StopMonth  => 12,
         StopDay    => 24,
         StopHour   => 10, (optional, default 23)
         StopMinute => 0,  (optional, default 59)
         StopSecond => 0,  (optional, default 59)
         TicketID   => 123,
         Force      => 0,     # 1: don't use cache
     );


returns


.. code-block:: perl

     TicketNumber
     TicketID
     Type
     TypeID
     Queue
     QueueID
     Priority
     PriorityID
     State
     StateID
     Owner
     OwnerID
     CreateUserID
     CreateTime (timestamp)
     CreateOwnerID
     CreatePriority
     CreatePriorityID
     CreateState
     CreateStateID
     CreateQueue
     CreateQueueID
     LockFirst (timestamp)
     LockLast (timestamp)
     UnlockFirst (timestamp)
     UnlockLast (timestamp)



HistoryTypeLookup()
===================


returns the id of the requested history type.


.. code-block:: perl

     my $ID = $TicketObject->HistoryTypeLookup( Type => 'Move' );



HistoryAdd()
============


add a history entry to an ticket


.. code-block:: perl

     my $Success = $TicketObject->HistoryAdd(
         Name         => 'Some Comment',
         HistoryType  => 'Move', # see system tables
         TicketID     => 123,
         ArticleID    => 1234, # not required!
         QueueID      => 123, # not required!
         TypeID       => 123, # not required!
         CreateUserID => 123,
     );


Events:
    HistoryAdd


HistoryGet()
============


get ticket history as array with hashes
(TicketID, ArticleID, Name, CreateBy, CreateTime, HistoryType, QueueID,
OwnerID, PriorityID, StateID, HistoryTypeID and TypeID)


.. code-block:: perl

     my @HistoryLines = $TicketObject->HistoryGet(
         TicketID => 123,
         UserID   => 123,
     );



HistoryDelete()
===============


delete a ticket history (from storage)


.. code-block:: perl

     my $Success = $TicketObject->HistoryDelete(
         TicketID => 123,
         UserID   => 123,
     );


Events:
    HistoryDelete


TicketAccountedTimeGet()
========================


returns the accounted time of a ticket.


.. code-block:: perl

     my $AccountedTime = $TicketObject->TicketAccountedTimeGet(TicketID => 1234);



TicketAccountTime()
===================


account time to a ticket.


.. code-block:: perl

     my $Success = $TicketObject->TicketAccountTime(
         TicketID  => 1234,
         ArticleID => 23542,
         TimeUnit  => '4.5',
         UserID    => 1,
     );


Events:
    TicketAccountTime


TicketMerge()
=============


merge two tickets


.. code-block:: perl

     my $Success = $TicketObject->TicketMerge(
         MainTicketID  => 412,
         MergeTicketID => 123,
         UserID        => 123,
     );


Events:
    TicketMerge


TicketMergeDynamicFields()
==========================


merge dynamic fields from one ticket into another, that is, copy
them from the merge ticket to the main ticket if the value is empty
in the main ticket.


.. code-block:: perl

     my $Success = $TicketObject->TicketMergeDynamicFields(
         MainTicketID  => 123,
         MergeTicketID => 42,
         UserID        => 1,
         DynamicFields => ['DynamicField_TicketFreeText1'], # optional
     );


If DynamicFields is not present, it is taken from the Ticket::MergeDynamicFields
configuration.


TicketMergeLinkedObjects()
==========================


merge linked objects from one ticket into another, that is, move
them from the merge ticket to the main ticket in the link_relation table.


.. code-block:: perl

     my $Success = $TicketObject->TicketMergeLinkedObjects(
         MainTicketID  => 123,
         MergeTicketID => 42,
         UserID        => 1,
     );



TicketWatchGet()
================


to get all user ids and additional attributes of an watched ticket


.. code-block:: perl

     my %Watch = $TicketObject->TicketWatchGet(
         TicketID => 123,
     );


get list of users to notify


.. code-block:: perl

     my %Watch = $TicketObject->TicketWatchGet(
         TicketID => 123,
         Notify   => 1,
     );


get list of users as array


.. code-block:: perl

     my @Watch = $TicketObject->TicketWatchGet(
         TicketID => 123,
         Result   => 'ARRAY',
     );



TicketWatchSubscribe()
======================


to subscribe a ticket to watch it


.. code-block:: perl

     my $Success = $TicketObject->TicketWatchSubscribe(
         TicketID    => 111,
         WatchUserID => 123,
         UserID      => 123,
     );


Events:
    TicketSubscribe


TicketWatchUnsubscribe()
========================


to remove a subscription of a ticket


.. code-block:: perl

     my $Success = $TicketObject->TicketWatchUnsubscribe(
         TicketID    => 111,
         WatchUserID => 123,
         UserID      => 123,
     );


Events:
    TicketUnsubscribe


TicketFlagSet()
===============


set ticket flags


.. code-block:: perl

     my $Success = $TicketObject->TicketFlagSet(
         TicketID => 123,
         Key      => 'Seen',
         Value    => 1,
         UserID   => 123, # apply to this user
     );


Events:
    TicketFlagSet


TicketFlagDelete()
==================


delete ticket flag


.. code-block:: perl

     my $Success = $TicketObject->TicketFlagDelete(
         TicketID => 123,
         Key      => 'Seen',
         UserID   => 123,
     );
 
     my $Success = $TicketObject->TicketFlagDelete(
         TicketID => 123,
         Key      => 'Seen',
         AllUsers => 1,
     );


Events:
    TicketFlagDelete


TicketFlagGet()
===============


get ticket flags


.. code-block:: perl

     my %Flags = $TicketObject->TicketFlagGet(
         TicketID => 123,
         UserID   => 123,  # to get flags of one user
     );
 
     my @Flags = $TicketObject->TicketFlagGet(
         TicketID => 123,
         AllUsers => 1,    # to get flags of all users
     );



TicketArticleStorageSwitch()
============================


move article storage from one backend to other backend


.. code-block:: perl

     my $Success = $TicketObject->TicketArticleStorageSwitch(
         TicketID    => 123,
         Source      => 'ArticleStorageDB',
         Destination => 'ArticleStorageFS',
         UserID      => 1,
     );



TicketCheckForProcessType()
===========================



.. code-block:: perl

     checks whether or not the ticket is of a process type.
 
     $TicketObject->TicketCheckForProcessType(
         TicketID => 123,
     );



TicketCalendarGet()
===================


checks calendar to be used for ticket based on sla and queue


.. code-block:: perl

     my $Calendar = $TicketObject->TicketCalendarGet(
         QueueID => 1,
         SLAID   => 1,   # optional
     );


returns calendar number or empty string for default calendar


SearchUnknownTicketCustomers()
==============================


search customer users that are not saved in any backend


.. code-block:: perl

     my $UnknownTicketCustomerList = $TicketObject->SearchUnknownTicketCustomers(
         SearchTerm => 'SomeSearchTerm',
     );


Returns:


.. code-block:: perl

     %UnknownTicketCustomerList = (
         {
             CustomerID    => 'SomeCustomerID',
             CustomerUser  => 'SomeCustomerUser',
         },
         {
             CustomerID    => 'SomeCustomerID',
             CustomerUser  => 'SomeCustomerUser',
         },
     );




*****************
PRIVATE FUNCTIONS
*****************


_TicketCacheClear()
===================


Remove all caches related to specified ticket.


.. code-block:: perl

     my $Success = $TicketObject->_TicketCacheClear(
         TicketID => 123,
     );



_TicketGetExtended()
====================


Collect extended attributes for given ticket,
namely first response, first lock and close data.


.. code-block:: perl

     my %TicketExtended = $TicketObject->_TicketGetExtended(
         TicketID => $Param{TicketID},
         Ticket   => \%Ticket,
     );



_TicketGetFirstResponse()
=========================


Collect attributes of first response for given ticket.


.. code-block:: perl

     my %FirstResponse = $TicketObject->_TicketGetFirstResponse(
         TicketID => $Param{TicketID},
         Ticket   => \%Ticket,
     );



_TicketGetClosed()
==================


Collect attributes of (last) closing for given ticket.


.. code-block:: perl

     my %TicketGetClosed = $TicketObject->_TicketGetClosed(
         TicketID => $Param{TicketID},
         Ticket   => \%Ticket,
     );



_TicketGetFirstLock()
=====================


Collect first lock time for given ticket.


.. code-block:: perl

     my %FirstLock = $TicketObject->_TicketGetFirstLock(
         TicketID => $Param{TicketID},
         Ticket   => \%Ticket,
     );





