CustomStatusesInRt4

From Request Tracker Wiki
Revision as of 08:16, 26 July 2011 by 80.95.70.19 (talk) (Sample 1 - from RT_Config.pm)
Jump to navigation Jump to search

Custom Status in RT 4

to see how it is handled in prior versions refer to this article: CustomStatuses

in RT4 a new lifecycle managebility is introduced, of which the statuses are a part of.

WARNING. DO NOT DELETE ANY OF THE DEFAULT STATUSES.

If you do, RT will break horribly.

From RTConfig.pm in RT 4.0.1:

Lifecycles

Lifecycle definitions

Each lifecycle is a list of possible statuses split into three logic sets: initial, active and inactive. Each status in a lifecycle must be unique. (Statuses may not be repeated across sets.)

Each set may have any number of statuses.

For example:

    default => {

        initial  => ['new'],

        active   => ['open', 'stalled'],

        inactive => ['resolved', 'rejected', 'deleted'],

        ...

    },

Status names can be from 1 to 64 ASCII characters. Statuses are localized using RT's standard internationalization and localization system.

initial

You can define multiple initial statuses for tickets in a given lifecycle.

RT will automatically set its Started date when you change a ticket's status from an initial state to an active or inactive status.

active

active tickets are "currently in play" - they're things that are being worked on and not yet complete.

inactive

inactive tickets are typically in their "final resting state".

While you're free to implement a workflow that ignores that description, typically once a ticket enters an inactive state, it will never again enter an active state.

RT will automatically set the Resolved date when a ticket's status is changed from an initial or active status to an inactive status.

deleted is still a special status and protected by the DeleteTicket right, unless you re-defined rights (read below). If you don't want to allow ticket deletion at any time simply don't include it in your lifecycle.

Statuses in each set are ordered and listed in the UI in the defined order.

Changes between statuses are constrained by transition rules, as described below.

Default values

In some cases a default value is used to display in UI or in API when value is not provided. You can configure defaults using the following syntax:

    default => {

        ...

        defaults => {

            on_create => 'new',

            on_resolve => 'resolved',

            ...

        },

    },

The following defaults are used.

on_create

If you (or your code) doesn't specify a status when creating a ticket, RT will use the this status. See also Statuses available during ticket creation topic in this article.

on_merge

When tickets are merged, the status of the ticket that was merged away is forced to this value. It should be one of inactive statuses; 'resolved' or its equivalent is most probably the best candidate.

approved

When an approval is accepted, the status of depending tickets will be changed to this value.

denied

When an approval is denied, the status of depending tickets will be changed to this value.

Transitions between statuses and UI actions

A Transition is a change of status from A to B. You should define all possible transitions in each lifecycle using the following format:

    default => {

        ...

        transitions => {

                   => [qw(new open resolved)],

            new      => [qw(open resolved rejected deleted)],

            open     => [qw(stalled resolved rejected deleted)],

            stalled  => [qw(open)],

            resolved => [qw(open)],

            rejected => [qw(open)],

            deleted  => [qw(open)],

        },

        ...

    },

Statuses available during ticket creation

By default users can create tickets with any status, except deleted. If you want to restrict statuses available during creation then describe transition from (empty string), like in the example above.

Protecting status changes with rights

A transition or group of transitions can be protected by a specific right. Additionally, you can name new right names, which will be added to the system to control that transition. For example, if you wished to create a lesser right than ModifyTicket for rejecting tickets, you could write:

    default => {

        ...

        rights => {

            '* -> deleted'  => 'DeleteTicket',

            '* -> rejected' => 'RejectTicket',

            '* -> *'        => 'ModifyTicket',

        },

        ...

    },

This would create a new C right in the system which you could assign to whatever groups you choose. On the left hand side you can have the following variants:

    ' -> '

    '* -> '

    ' -> *'

    '* -> *'

Valid transitions are listed in order of priority. If a user attempts to change a ticket's status from new to open then the lifecycle is checked for presence of an exact match, then for 'any to open ', new to any' and finally 'any to any'.

If you don't define any rights, or there is no match for a transition, RT will use the DeleteTicket or ModifyTicket as appropriate.

Labeling and defining actions

For each transition you can define an action that will be shown in the UI; each action annotated with a label and an update type.

Each action may provide a default update type, which can be Comment, Respond, or absent. For example, you may want your staff to write a reply to the end user when they change status from new to open, and thus set the update to Respond. Neither Comment nor Respond are mandatory, and user may leave the message empty, regardless of the update type.

This configuration can be used to accomplish what $ResolveDefaultUpdateType was used for in RT 3.8.

Use the following format to define labels and actions of transitions:

    default => {

        ...

        actions => [

            'new -> open'     => { label => 'Open it', update => 'Respond' },

            'new -> resolved' => { label => 'Resolve', update => 'Comment' },

            'new -> rejected' => { label => 'Reject',  update => 'Respond' },

            'new -> deleted'  => { label => 'Delete' },


            'open -> stalled'  => { label => 'Stall',   update => 'Comment' },

            'open -> resolved' => { label => 'Resolve', update => 'Comment' },

            'open -> rejected' => { label => 'Reject',  update => 'Respond' },


            'stalled -> open'  => { label => 'Open it' },

            'resolved -> open' => { label => 'Re-open', update => 'Comment' },

            'rejected -> open' => { label => 'Re-open', update => 'Comment' },

            'deleted -> open'  => { label => 'Undelete' },

        ],

        ...

    },

In addition, you may define multiple actions for the same transition.

Alternately, you may use '* -> x' to match more than one transition.

For example:

    default => {

        ...

        actions => [

            ...

            'new -> rejected' => { label => 'Reject', update => 'Respond' },

            'new -> rejected' => { label => 'Quick Reject' },

            ...

            '* -> deleted' => { label => 'Delete' },

            ...

        ],

        ...

    },

Moving tickets between queues with different lifecycles

Unless there is an explicit mapping between statuses in two different lifecycles, you can not move tickets between queues with these lifecycles. Such a mapping is defined as follows:

    __maps__ => {

        'from lifecycle -> to lifecycle' => {

            'status in left lifecycle' => 'status in right lifecycle',

            ...

        },

        ...

    },

Sample 1 - from RT_Config.pm

Set(%Lifecycles,

    default => {

        initial         => [ 'new' ],

        active          => [ 'open', 'stalled' ],

        inactive        => [ 'resolved', 'rejected', 'deleted' ],


        defaults => {

            on_create => 'new',

            on_merge  => 'resolved',

            approved  => 'open',

            denied    => 'rejected',

        },


        transitions => {

                   => [qw(new open resolved)],


            # from   => [ to list ],

            new      => [qw(open stalled resolved rejected deleted)],

            open     => [qw(new stalled resolved rejected deleted)],

            stalled  => [qw(new open rejected resolved deleted)],

            resolved => [qw(new open stalled rejected deleted)],

            rejected => [qw(new open stalled resolved deleted)],

            deleted  => [qw(new open stalled rejected resolved)],

        },

        rights => {

            '* -> deleted'  => 'DeleteTicket',

            '* -> *'        => 'ModifyTicket',

        },

        actions => [

            'new -> open'      => { label => 'Open It',  update => 'Respond' },

            'new -> resolved'  => { label => 'Resolve',  update => 'Comment' },

            'new -> rejected'  => { label => 'Reject',   update => 'Respond' },

            'new -> deleted'   => { label => 'Delete'                        },


            'open -> stalled'  => { label => 'Stall',    update => 'Comment' },

            'open -> resolved' => { label => 'Resolve',  update => 'Comment' },

            'open -> rejected' => { label => 'Reject',   update => 'Respond' },


            'stalled -> open'  => { label => 'Open It'                       },

            'resolved -> open' => { label => 'Re-open',  update => 'Comment' },

            'rejected -> open' => { label => 'Re-open',  update => 'Comment' },

            'deleted -> open'  => { label => 'Undelete'                      },

        ],

    },

# don't change lifecyle of the approvals, they are not capable to deal with

# custom statuses

    approvals => {

        initial         => [ 'new' ],

        active          => [ 'open', 'stalled' ],

        inactive        => [ 'resolved', 'rejected', 'deleted' ],


        defaults => {

            on_create => 'new',

            on_merge => 'resolved',

        },


        transitions => {

                   => [qw(new open resolved)],


            # from   => [ to list ],

            new      => [qw(open stalled resolved rejected deleted)],

            open     => [qw(new stalled resolved rejected deleted)],

            stalled  => [qw(new open rejected resolved deleted)],

            resolved => [qw(new open stalled rejected deleted)],

            rejected => [qw(new open stalled resolved deleted)],

            deleted  => [qw(new open stalled rejected resolved)],

        },

        rights => {

            '* -> deleted'  => 'DeleteTicket',

            '* -> rejected' => 'ModifyTicket',

            '* -> *'        => 'ModifyTicket',

        },

        actions => [

            'new -> open'      => { label => 'Open It',  update => 'Respond' },

            'new -> resolved'  => { label => 'Resolve',  update => 'Comment' },

            'new -> rejected'  => { label => 'Reject',   update => 'Respond' },

            'new -> deleted'   => { label => 'Delete'                        },


            'open -> stalled'  => { label => 'Stall',    update => 'Comment' },

            'open -> resolved' => { label => 'Resolve',  update => 'Comment' },

            'open -> rejected' => { label => 'Reject',   update => 'Respond' },


            'stalled -> open'  => { label => 'Open It'                       },

            'resolved -> open' => { label => 'Re-open',  update => 'Comment' },

            'rejected -> open' => { label => 'Re-open',  update => 'Comment' },

            'deleted -> open'  => { label => 'Undelete'                      },

        ],

    },

);

Sample 2 - adding custom statuses

(this is our own prod RTSiteConfig, its not much, but added ABC, ABC-E,Developing and At_client statuses)

Set(%Lifecycles,

    default => {

        initial => [ 'new' ],

        active  => [ 'open', 'ABC', 'At_Client', 'ABC-E', 'Developing', 'stalled' ],

        inactive => [ 'resolved', 'rejected', 'deleted' ],


        defaults => {

            on_create => 'new',

            on_merge  => 'resolved',

            approved  => 'open',

            denied    => 'rejected',

        },


        transitions => {

                   => [qw(new open resolved)],


            # from   => [ to list ],

            new      => [qw(open stalled ABC At_Client ABC-E Developing resolved rejected deleted)],

            open     => [qw(stalled ABC At_Client ABC-E Developing resolved rejected deleted)],

            ABC   => [qw(open stalled At_Client ABC-E Developing resolved rejected deleted)],

            At_Client => [qw(open stalled ABC ABC-E Developing resolved rejected deleted)],

            'ABC-E'    => [qw(open stalled ABC At_Client Developing resolved rejected deleted)],

            Developing => [qw(open stalled ABC At_Client ABC-E resolved rejected deleted)],

            stalled  => [qw(open ABC At_Client ABC-E Developing rejected resolved deleted)],

            resolved => [qw(open ABC At_Client ABC-E Developing stalled rejected deleted)],

            rejected => [qw(open ABC At_Client ABC-E Developing stalled resolved deleted)],

            deleted  => [qw(open ABC At_Client ABC-E Developing stalled rejected resolved)],

        },

        rights => {

            '* -> deleted'  => 'DeleteTicket',

            '* -> *'        => 'ModifyTicket',

        },

        actions => [

        'new -> open'      => { label => 'Open It',  update => 'Respond' },

        'new -> resolved'  => { label => 'Resolve',  update => 'Comment' },

        'new -> rejected'  => { label => 'Reject',   update => 'Respond' },

        'new -> deleted'   => { label => 'Delete'                        },

        'open -> stalled'  => { label => 'Stall',    update => 'Comment' },

        'open -> resolved' => { label => 'Resolve',  update => 'Comment' },

        'open -> rejected' => { label => 'Reject',   update => 'Respond' },

        'stalled -> open'  => { label => 'Open It'                       },

        'resolved -> open' => { label => 'Re-open',  update => 'Comment' },

        'rejected -> open' => { label => 'Re-open',  update => 'Comment' },

        'deleted -> open'  => { label => 'Undelete'                      },

        ],

    },

);

Hints

(here you can add your hints, tips or anything you thing helpfull)

  • At lifecycle from->to you may notice the " ' " around ABC-E at the from part as 'ABC-E' . This is due unless you do this the " - " breaks the code
  • If you don't define the transactions part, you won't be able to chose your new statuses in the ticket's basic field: status.


80.95.70.19 12:15, July 26, 2011 (UTC)

Most of it: BestPractical: RT_Config.pm

Little bits: Daniel O.T